commit 93c6ea683ddb00440365993897de0ad158a7eeb9 Author: Tobias Springer Date: Sat May 9 16:45:23 2020 +0200 Initial commit diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..d899f655 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.wav filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..230ccaf3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,111 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.env.test + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# Next.js build output +.next + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and *not* Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + + +# Buildfiles +build + + +res_built diff --git a/.prettierrc.yaml b/.prettierrc.yaml new file mode 100644 index 00000000..643afe72 --- /dev/null +++ b/.prettierrc.yaml @@ -0,0 +1,11 @@ +# .prettierrc or .prettierrc.yaml +trailingComma: "es5" +tabWidth: 4 +semi: true +singleQuote: false +printWidth: 110 +useTabs: false +quoteProps: "consistent" +bracketSpacing: true +arrowParens: avoid +endOfLine: "lf" diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..335f886a --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "editor.defaultFormatter": "esbenp.prettier-vscode" +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 00000000..ce84173c --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# shapez.io +shapez.io source code diff --git a/buildutils.js b/buildutils.js new file mode 100644 index 00000000..5342650f --- /dev/null +++ b/buildutils.js @@ -0,0 +1,44 @@ +const glob = require("glob"); +const execSync = require("child_process").execSync; +const trim = require("trim"); +const fs = require("fs"); +const path = require("path"); + +module.exports = { + getRevision: function (useLast = false) { + const commitHash = execSync("git rev-parse --short " + (useLast ? "HEAD^1" : "HEAD")).toString("ascii"); + return commitHash.replace(/^\s+|\s+$/g, ""); + }, + getAllResourceImages() { + return glob + .sync("res/**/*.@(png|svg|jpg)", { cwd: ".." }) + .map((f) => f.replace(/^res\//gi, "")) + .filter((f) => { + if (f.indexOf("ui") >= 0) { + // We drop all ui images except for the noinline ones + return f.indexOf("noinline") >= 0; + } + return true; + }); + }, + + getAllAtlasImages() { + return glob.sync("res_built/atlas/*.png", { cwd: ".." }).map((s) => s.replace("res_built/atlas/", "res/")); + }, + + getAllSounds() { + return glob.sync("res_built/sounds/**/*.mp3", { cwd: ".." }).map((s) => s.replace("res_built/sounds/", "res/sounds/")); + }, + + getVersion() { + return trim(fs.readFileSync(path.join(__dirname, "version")).toString()); + }, + + /** + * @param {string} url + * @param {string} commitHash + */ + cachebust(url, commitHash) { + return "/v/" + commitHash + "/" + url; + }, +}; diff --git a/gulp/.gitattributes b/gulp/.gitattributes new file mode 100644 index 00000000..d899f655 --- /dev/null +++ b/gulp/.gitattributes @@ -0,0 +1 @@ +*.wav filter=lfs diff=lfs merge=lfs -text diff --git a/gulp/.gitignore b/gulp/.gitignore new file mode 100644 index 00000000..efd974cc --- /dev/null +++ b/gulp/.gitignore @@ -0,0 +1 @@ +additional_build_files diff --git a/gulp/babel-es6.config.js b/gulp/babel-es6.config.js new file mode 100644 index 00000000..e687f070 --- /dev/null +++ b/gulp/babel-es6.config.js @@ -0,0 +1,48 @@ +module.exports = function (api) { + api.cache(true); + const presets = [ + [ + "@babel/preset-env", + { + targets: "> 5%", + useBuiltIns: "usage", + corejs: 3, + loose: true, + spec: false, + modules: "auto", + // debug: true + }, + ], + ]; + const plugins = [ + "closure-elimination", + // var is faster than let and const! + [ + "@babel/plugin-transform-block-scoping", + { + throwIfClosureRequired: false, + }, + ], + [ + "@babel/plugin-transform-classes", + { + loose: true, + }, + ], + ]; + return { + presets, + plugins, + highlightCode: true, + sourceType: "module", + sourceMaps: false, + parserOpts: {}, + only: ["../src/js"], + generatorOpts: { + retainLines: false, + compact: true, + minified: true, + comments: true, + }, + }; +}; diff --git a/gulp/babel.config.js b/gulp/babel.config.js new file mode 100644 index 00000000..0552a94b --- /dev/null +++ b/gulp/babel.config.js @@ -0,0 +1,41 @@ +module.exports = function (api) { + api.cache(true); + const presets = [ + [ + "@babel/preset-env", + { + targets: "android >= 4.4.4", + useBuiltIns: "usage", + corejs: 3, + loose: true, + spec: false, + modules: "auto", + // debug: true + }, + ], + ]; + const plugins = [ + "closure-elimination", + [ + "@babel/plugin-transform-classes", + { + loose: true, + }, + ], + ]; + return { + presets, + plugins, + highlightCode: true, + sourceType: "module", + sourceMaps: false, + parserOpts: {}, + only: ["../src/js"], + generatorOpts: { + retainLines: false, + compact: true, + minified: true, + comments: true, + }, + }; +}; diff --git a/gulp/buildutils.js b/gulp/buildutils.js new file mode 100644 index 00000000..1fb2a9a3 --- /dev/null +++ b/gulp/buildutils.js @@ -0,0 +1,50 @@ +const glob = require("glob"); +const execSync = require("child_process").execSync; +const trim = require("trim"); +const fs = require("fs"); +const path = require("path"); + +module.exports = { + getRevision: function (useLast = false) { + const commitHash = execSync("git rev-parse --short " + (useLast ? "HEAD^1" : "HEAD")).toString( + "ascii" + ); + return commitHash.replace(/^\s+|\s+$/g, ""); + }, + getAllResourceImages() { + return glob + .sync("res/**/*.@(png|svg|jpg)", { cwd: ".." }) + .map(f => f.replace(/^res\//gi, "")) + .filter(f => { + if (f.indexOf("ui") >= 0) { + // We drop all ui images except for the noinline ones + return f.indexOf("noinline") >= 0; + } + return true; + }); + }, + + getAllAtlasImages() { + return glob + .sync("res_built/atlas/*.png", { cwd: ".." }) + .map(s => s.replace("res_built/atlas/", "res/")); + }, + + getAllSounds() { + return glob + .sync("res_built/sounds/**/*.mp3", { cwd: ".." }) + .map(s => s.replace("res_built/sounds/", "res/sounds/")); + }, + + getVersion() { + return trim(fs.readFileSync(path.join(__dirname, "..", "version")).toString()); + }, + + /** + * @param {string} url + * @param {string} commitHash + */ + cachebust(url, commitHash) { + return "/v/" + commitHash + "/" + url; + }, +}; diff --git a/gulp/bundle-loader.js b/gulp/bundle-loader.js new file mode 100644 index 00000000..d8bb8c24 --- /dev/null +++ b/gulp/bundle-loader.js @@ -0,0 +1,112 @@ +/** + * ES6 Bundle Loader + * + * Attempts to load the game code, and if that fails tries with the transpiled + * version. Also handles errors during load. + */ + +(function () { + var loadTimeout = null; + var callbackDone = false; + + // Catch load errors + + function errorHandler(event, source, lineno, colno, error) { + console.error("👀 Init Error:", event, source, lineno, colno, error); + var element = document.createElement("div"); + element.style.position = "fixed"; + element.style.top = "0"; + element.style.right = "0"; + element.style.bottom = "0"; + element.style.left = "0"; + element.style.zIndex = "29999"; + element.style.backgroundColor = "#222429"; + element.style.display = "flex"; + element.style.justifyContent = "center"; + element.style.alignItems = "center"; + + var inner = document.createElement("div"); + inner.style.color = "#fff"; + inner.style.fontFamily = "GameFont, sans-serif"; + inner.style.fontSize = "15px"; + inner.style.padding = "30px"; + inner.style.textAlign = "center"; + element.appendChild(inner); + + var heading = document.createElement("h3"); + heading.style.color = "#ef5072"; + heading.innerText = "Error"; + heading.style.marginBottom = "40px"; + heading.style.fontSize = "45px"; + inner.appendChild(heading); + + var content = document.createElement("p"); + content.style.color = "#eee"; + content.innerText = error || (event && event.message) || event || "Unknown Error"; + inner.appendChild(content); + + if (source) { + var sourceElement = document.createElement("p"); + sourceElement.style.color = "#777"; + sourceElement.innerText = sourceElement + ":" + lineno + ":" + colno; + inner.appendChild(sourceElement); + } + + document.documentElement.appendChild(element); + } + window.addEventListener("error", errorHandler); + window.addEventListener("unhandledrejection", errorHandler); + + function makeJsTag(src, integrity) { + var script = document.createElement("script"); + script.src = src; + script.type = "text/javascript"; + script.charset = "utf-8"; + script.defer = true; + if (integrity) { + script.setAttribute("integrity", integrity); + } + return script; + } + + function loadFallbackJs(error) { + console.warn("👀 ES6 Script not supported, loading transpiled code."); + console.warn("👀 Error was:", error); + var scriptTransp = makeJsTag(bundleSrcTranspiled, bundleIntegrityTranspiled); + scriptTransp.addEventListener("error", scriptFail); + scriptTransp.addEventListener("load", onJsLoaded); + document.head.appendChild(scriptTransp); + } + + function scriptFail(error) { + console.error("👀 Failed to load bundle!"); + console.error("👀 Error was:", error); + throw new Error("Core load failed."); + } + + function expectJsParsed() { + if (!callbackDone) { + console.error("👀 Got no core callback"); + throw new Error("Core thread failed to respond within time."); + } + } + + function onJsLoaded() { + console.log("👀 Core loaded at", Math.floor(performance.now()), "ms"); + loadTimeout = setTimeout(expectJsParsed, 15000); + window.removeEventListener("error", errorHandler); + window.removeEventListener("unhandledrejection", errorHandler); + } + + window.coreThreadLoadedCb = function () { + console.log("👀 Core responded at", Math.floor(performance.now()), "ms"); + clearTimeout(loadTimeout); + loadTimeout = null; + callbackDone = true; + }; + + var scriptEs6 = makeJsTag(bundleSrc, bundleIntegrity); + scriptEs6.addEventListener("error", loadFallbackJs); + scriptEs6.addEventListener("load", onJsLoaded); + document.head.appendChild(scriptEs6); +})(); diff --git a/gulp/convert_atlas.js b/gulp/convert_atlas.js new file mode 100644 index 00000000..8e0ba990 --- /dev/null +++ b/gulp/convert_atlas.js @@ -0,0 +1,96 @@ +// Converts the atlas description to a JSON file + +String.prototype.replaceAll = function (search, replacement) { + var target = this; + return target.split(search).join(replacement); +}; + +const fs = require("fs"); +const path = require("path"); + +const folder = path.join(__dirname, "res_built", "atlas"); +const files = fs.readdirSync(folder); + +const metadata = []; + +files.forEach(filename => { + if (filename.endsWith(".atlas")) { + // Read content + + const content = fs.readFileSync(path.join(folder, filename), "ascii"); + + const lines = content.replaceAll("\r", "").replaceAll("\t", "").split("\n"); + + const readLine = () => lines.splice(0, 1)[0]; + const readValue = () => readLine().replaceAll(" ", "").split(":")[1]; + const readVector = () => + readValue() + .split(",") + .map(d => parseInt(d, 10)); + + let maxAtlas = 100; + + atlasLoop: while (maxAtlas-- > 0 && lines.length >= 7) { + const result = { + entries: [], + }; + + // Extract header + const header_fileStart = readLine(); + const header_fileName = readLine(); + const header_size = readVector(); + const header_format = readLine(); + const header_filter = readLine(); + const header_repeat = readLine(); + const baseAtlasName = header_fileName.replace(".png", ""); + + // Store size + result.size = header_size; + + lineLoop: while (lines.length >= 7) { + const entryResult = {}; + + const nextLine = lines[0]; + if (nextLine.length === 0) { + break; + } + + const entry_fileName = readLine() + ".png"; + + const entry_rotate = readValue(); + const entry_xy = readVector(); + const entry_size = readVector(); + const entry_orig = readVector(); + const entry_offset = readVector(); + const entry_index = readValue(); + + entryResult.filename = entry_fileName; + entryResult.xy = entry_xy; + entryResult.size = entry_size; + // entryResult.offset = entry_offset; + + entryResult.origSize = entry_orig; + + let offset = [0, 0]; + + // GDX Atlas packer uses 1 - y coordinates. This sucks, and we have to convert it + offset[0] = entry_offset[0]; + offset[1] = entry_orig[1] - entry_offset[1] - entry_size[1]; + + entryResult.offset = offset; + + result.entries.push(entryResult); + } + + console.log("[Atlas]", "'" + baseAtlasName + "'", "has", result.entries.length, "entries"); + // fs.writeFileSync(path.join(folder, baseAtlasName + ".gen.json"), JSON.stringify(result)); + + metadata.push({ + filename: baseAtlasName + ".png", + entries: result, + }); + } + } +}); + +fs.writeFileSync(path.join(folder, "meta.gen.json"), JSON.stringify(metadata, null, 4)); diff --git a/gulp/cordova.js b/gulp/cordova.js new file mode 100644 index 00000000..408691cf --- /dev/null +++ b/gulp/cordova.js @@ -0,0 +1,153 @@ +const path = require("path"); +const fs = require("fs"); +const buildUtils = require("./buildutils"); + +export function gulptasksCordova($, gulp, buildFolder) { + const cdvRes = path.join("..", "..", "res"); + + // Cleans up the app assets + // Removes all temporary folders used while optimizing the assets + gulp.task("cleanupAppAssetsBuiltFolder", () => { + return gulp.src(path.join(cdvRes, "built"), { read: false }).pipe($.clean({ force: true })); + }); + + // Optimizes all built assets + gulp.task("optimizeBuiltAppAssets", () => { + return gulp + .src(path.join(cdvRes, "built", "**", "*.png")) + .pipe($.flatten()) + .pipe($.imagemin([$.imagemin.optipng({ optimizationLevel: 1 })])) + .pipe(gulp.dest(path.join(cdvRes, "built"))); + }); + + // Scales the icon resources + gulp.task("scaleIconIos", async () => { + const sizes = [ + 180, + 60, + 120, + 76, + 152, + 40, + 80, + 57, + 114, + 72, + 144, + 167, + 29, + 58, + 87, + 50, + 100, + 167, + 20, + 1024, + 24, + 48, + 55, + 172, + 196, + ]; + for (let i = 0; i < sizes.length; ++i) { + const size = sizes[i]; + console.log("Scaling icon to", size, "x", size); + const img = await $.jimp.read(path.join(cdvRes, "ios", "icon-prefab.png")); + await img.resize(size, size).write(path.join(cdvRes, "built", "ios", "icon@" + size + ".png")); + } + }); + + gulp.task("copyOtherIosResources", () => { + return gulp + .src(path.join(cdvRes, "ios", "splash-prefab.png")) + .pipe($.rename("Default@2x~universal~anyany.png")) + .pipe(gulp.dest(path.join(cdvRes, "built", "ios"))); + }); + + gulp.task("prepareIosRes", ["scaleIconIos", "copyOtherIosResources"]); + + gulp.task("copyAndroidResources", () => { + return gulp + .src(path.join(cdvRes, "android", "**", "*.*")) + .pipe(gulp.dest(path.join(cdvRes, "built", "android"))); + }); + + gulp.task("prepareAndroidRes", ["copyAndroidResources"]); + + gulp.task("prepareCordovaAssets", cb => { + return $.sequence( + "cleanupAppAssetsBuiltFolder", + ["prepareIosRes", "prepareAndroidRes"], + "optimizeBuiltAppAssets" + )(cb); + }); + + // Patches the config.xml by replacing the app id to app_beta + + gulp.task("patchConfigXML", () => { + const configUrl = path.join("..", "..", "config.xml"); + let configContent = fs.readFileSync(configUrl).toString(); + const version = buildUtils.getVersion(); + configContent = configContent.replace("%VERSION%", version); + configContent = configContent.replace(' id="io.shapez.app" ', ' id="io.shapez.app_beta" '); + configContent = configContent.replace("Shapez.io", "Shapez.io BETA"); + fs.writeFileSync(configUrl, configContent); + }); + + gulp.task("patchConfigXMLChangeStagingToProd", () => { + const configUrl = path.join("..", "..", "config.xml"); + let configContent = fs.readFileSync(configUrl).toString(); + configContent = configContent.replace(' id="io.shapez.app_beta" ', ' id="io.shapez.app" '); + configContent = configContent.replace("Shapez.io BETA", "Shapez.io"); + fs.writeFileSync(configUrl, configContent); + }); + + // Triggers a new build on phonegap + gulp.task("triggerPhonegapBuild", () => { + return gulp + .src("src/html/", { dot: false }) + .pipe( + $.phonegapBuild({ + isRepository: true, + appId: "3339820", + platforms: ["android", "ios"], + user: { + token: process.env.SHAPEZ_CLI_PHONEGAP_KEY, + }, + }) + ) + .pipe( + $.phonegapBuild({ + isRepository: true, + appId: "3537816", + platforms: ["android", "ios"], + user: { + token: process.env.SHAPEZ_CLI_PHONEGAP_KEY, + }, + }) + ); + }); + + // gulp.task("pushToStagingRepo", (cb) => { + // var cmd = spawn('../push-pgb.sh', ['https://TOKEN@github.com/tobspr/shapezapp-cordova-buildslave.git'], + // { stdio: 'inherit', stdout: 'inherit', stderr: 'inherit', shell: true }); + // cmd.on('close', function (code) { + // console.log('push staging exited with code ' + code + " / " + cmd.stdout + " / " + cmd.stderr); + // cb(code); + // }); + + // }); + + // gulp.task("pushToProdRepo", (cb) => { + // var cmd = spawn('../push-pgb.sh', ['https://TOKEN@github.com/tobspr/shapezapp-cordova-buildslave-release.git'], + // { stdio: 'inherit', stdout: 'inherit', stderr: 'inherit', shell: true }); + // cmd.on('close', function (code) { + // console.log('push prod exited with code ' + code + " / " + cmd.stdout + " / " + cmd.stderr); + // cb(code); + // }); + // }); +} + +module.exports = { + gulptasksCordova, +}; diff --git a/gulp/css.js b/gulp/css.js new file mode 100644 index 00000000..729d0432 --- /dev/null +++ b/gulp/css.js @@ -0,0 +1,101 @@ +const path = require("path"); +const buildUtils = require("./buildutils"); + +function gulptasksCSS($, gulp, buildFolder, browserSync) { + // The assets plugin copies the files + const commitHash = buildUtils.getRevision(); + const postcssAssetsPlugin = cachebust => + $.postcssAssets({ + loadPaths: [path.join(buildFolder, "res", "ui")], + basePath: buildFolder, + baseUrl: ".", + cachebuster: cachebust + ? (filePath, urlPathname) => ({ + pathname: buildUtils.cachebust(urlPathname, commitHash), + }) + : "", + }); + + // Postcss configuration + const postcssPlugins = (prod, { cachebust = false }) => { + const plugins = [postcssAssetsPlugin(cachebust)]; + if (prod) { + plugins.unshift( + $.postcssUnprefix(), + $.postcssPresetEnv({ + browsers: ["> 0.1%"], + }) + ); + + plugins.push( + $.cssMqpacker({ + sort: true, + }), + $.cssnano({ + preset: [ + "advanced", + { + cssDeclarationSorter: false, + discardUnused: true, + mergeIdents: false, + reduceIdents: true, + zindex: true, + }, + ], + }), + $.postcssRoundSubpixels() + ); + } + return plugins; + }; + + // Performs linting on css + gulp.task("css.lint", () => { + return gulp + .src(["../src/css/**/*.scss"]) + .pipe($.sassLint({ configFile: ".sasslint.yml" })) + .pipe($.sassLint.format()) + .pipe($.sassLint.failOnError()); + }); + + // Builds the css in dev mode + gulp.task("css.dev", () => { + return gulp + .src(["../src/css/main.scss"]) + .pipe($.plumber()) + .pipe($.sass.sync().on("error", $.sass.logError)) + .pipe($.postcss(postcssPlugins(false, {}))) + .pipe(gulp.dest(buildFolder)) + .pipe(browserSync.stream()); + }); + + // Builds the css in production mode (=minified) + gulp.task("css.prod", () => { + return ( + gulp + .src("../src/css/main.scss", { cwd: __dirname }) + .pipe($.plumber()) + .pipe($.sass.sync({ outputStyle: "compressed" }).on("error", $.sass.logError)) + .pipe($.postcss(postcssPlugins(true, { cachebust: true }))) + // .pipe($.cssbeautify()) + .pipe(gulp.dest(buildFolder)) + ); + }); + + // Builds the css in production mode (=minified), without cachebusting + gulp.task("css.prod-standalone", () => { + return ( + gulp + .src("../src/css/main.scss", { cwd: __dirname }) + .pipe($.plumber()) + .pipe($.sass.sync({ outputStyle: "compressed" }).on("error", $.sass.logError)) + .pipe($.postcss(postcssPlugins(true, { cachebust: false }))) + // .pipe($.cssbeautify()) + .pipe(gulp.dest(buildFolder)) + ); + }); +} + +module.exports = { + gulptasksCSS, +}; diff --git a/gulp/docs.js b/gulp/docs.js new file mode 100644 index 00000000..68e3f0ea --- /dev/null +++ b/gulp/docs.js @@ -0,0 +1,38 @@ +const path = require("path"); +const fs = require("fs"); + +function gulptasksDocs($, gulp, buildFolder) { + gulp.task("docs.convertJsToTs", () => { + return gulp + .src(path.join("..", "src", "js", "**", "*.js")) + .pipe( + $.rename(path => { + path.extname = ".ts"; + }) + ) + .pipe(gulp.dest(path.join("..", "tsc_temp"))); + }); + + gulp.task("docs.copyTsconfigForHints", () => { + const src = fs.readFileSync(path.join("..", "src", "js", "tsconfig.json")).toString(); + const baseConfig = JSON.parse($.stripJsonComments(src)); + + baseConfig.allowJs = false; + baseConfig.checkJs = false; + baseConfig.declaration = true; + baseConfig.noEmit = false; + baseConfig.strict = false; + baseConfig.strictFunctionTypes = false; + baseConfig.strictBindCallApply = false; + baseConfig.alwaysStrict = false; + baseConfig.composite = true; + baseConfig.outFile = "bundled-ts.js"; + fs.writeFileSync(path.join("..", "tsc_temp", "tsconfig.json"), JSON.stringify(baseConfig)); + }); + + gulp.task("main.prepareDocs", $.sequence("docs.convertJsToTs", "docs.copyTsconfigForHints")); +} + +module.exports = { + gulptasksDocs, +}; diff --git a/gulp/ftp.js b/gulp/ftp.js new file mode 100644 index 00000000..2ab905e2 --- /dev/null +++ b/gulp/ftp.js @@ -0,0 +1,104 @@ +const path = require("path"); +const fs = require("fs"); + +const buildUtils = require("./buildutils"); + +function gulptasksFTP($, gulp, buildFolder) { + const commitHash = buildUtils.getRevision(); + + // Write the "commit.txt" file + gulp.task("ftp.writeVersion", () => { + fs.writeFileSync( + path.join(buildFolder, "version.json"), + JSON.stringify( + { + commit: buildUtils.getRevision(), + appVersion: buildUtils.getVersion(), + buildTime: new Date().getTime(), + }, + null, + 4 + ) + ); + }); + + // Copies additional files (like .htaccess) which should be deployed when running + // on the ftp server + // gulp.task("ftp.copyServerFiles", () => { + // return gulp.src(["../ftp_upload/*.*", "../ftp_upload/.*", "../ftp_upload/*"]) + // .pipe(gulp.dest(buildFolder)); + // }); + + const gameSrcGlobs = [ + path.join(buildFolder, "**/*.*"), + path.join(buildFolder, "**/.*"), + path.join(buildFolder, "**/*"), + path.join(buildFolder, "!**/index.html"), + ]; + + gulp.task("ftp.upload.staging.game", () => { + return gulp + .src(gameSrcGlobs, { base: buildFolder }) + .pipe( + $.rename(pth => { + pth.dirname = path.join("v", commitHash, pth.dirname); + }) + ) + .pipe( + $.sftp({ + host: process.env.SHAPEZ_CLI_SERVER_HOST, + user: process.env.SHAPEZ_CLI_STAGING_FTP_USER, + pass: process.env.SHAPEZ_CLI_STAGING_FTP_PW, + }) + ); + }); + + gulp.task("ftp.upload.staging.indexHtml", () => { + return gulp.src(path.join(buildFolder, "index.html"), { base: buildFolder }).pipe( + $.sftp({ + host: process.env.SHAPEZ_CLI_SERVER_HOST, + user: process.env.SHAPEZ_CLI_STAGING_FTP_USER, + pass: process.env.SHAPEZ_CLI_STAGING_FTP_PW, + }) + ); + }); + + gulp.task("ftp.upload.staging", cb => { + $.sequence("ftp.writeVersion", "ftp.upload.staging.game", "ftp.upload.staging.indexHtml")(cb); + }); + + gulp.task("ftp.upload.prod.game", () => { + return gulp + .src(gameSrcGlobs, { base: buildFolder }) + .pipe( + $.rename(pth => { + pth.dirname = path.join("v", commitHash, pth.dirname); + }) + ) + .pipe( + $.sftp({ + host: process.env.SHAPEZ_CLI_SERVER_HOST, + user: process.env.SHAPEZ_CLI_LIVE_FTP_USER, + pass: process.env.SHAPEZ_CLI_LIVE_FTP_PW, + }) + ); + }); + + gulp.task("ftp.upload.prod.indexHtml", () => { + return gulp.src(path.join(buildFolder, "index.html"), { base: buildFolder }).pipe( + $.sftp({ + host: process.env.SHAPEZ_CLI_SERVER_HOST, + user: process.env.SHAPEZ_CLI_LIVE_FTP_USER, + pass: process.env.SHAPEZ_CLI_LIVE_FTP_PW, + }) + ); + }); + + gulp.task("ftp.upload.prod", cb => { + $.sequence("ftp.writeVersion", "ftp.upload.prod.game", "ftp.upload.prod.indexHtml")(cb); + }); +} + +module.exports = { + gulptasksFTP, +}; diff --git a/gulp/gulpfile.js b/gulp/gulpfile.js new file mode 100644 index 00000000..72d5b699 --- /dev/null +++ b/gulp/gulpfile.js @@ -0,0 +1,274 @@ +/* eslint-disable */ + +require("colors"); + +const gulp = require("gulp"); +const browserSync = require("browser-sync").create({}); +const path = require("path"); +const deleteEmpty = require("delete-empty"); +const execSync = require("child_process").execSync; + +// Load other plugins dynamically +const $ = require("gulp-load-plugins")({ + scope: ["devDependencies"], + pattern: "*", +}); + +// Check environment variables + +const envVars = [ + "SHAPEZ_CLI_SERVER_HOST", + // "SHAPEZ_CLI_PHONEGAP_KEY", + "SHAPEZ_CLI_STAGING_FTP_USER", + "SHAPEZ_CLI_STAGING_FTP_PW", + "SHAPEZ_CLI_LIVE_FTP_USER", + "SHAPEZ_CLI_LIVE_FTP_PW", + // "SHAPEZ_CLI_TRANSREPORT_FTP_USER", + // "SHAPEZ_CLI_TRANSREPORT_FTP_PW", +]; + +for (let i = 0; i < envVars.length; ++i) { + if (!process.env[envVars[i]]) { + console.warn("Please set", envVars[i]); + // process.exit(1); + } +} + +const baseDir = path.join(__dirname, ".."); +const buildFolder = path.join(baseDir, "build"); + +const imgres = require("./image-resources"); +imgres.gulptasksImageResources($, gulp, buildFolder); + +const css = require("./css"); +css.gulptasksCSS($, gulp, buildFolder, browserSync); + +const sounds = require("./sounds"); +sounds.gulptasksSounds($, gulp, buildFolder); + +const js = require("./js"); +js.gulptasksJS($, gulp, buildFolder, browserSync); + +const html = require("./html"); +html.gulptasksHTML($, gulp, buildFolder, browserSync); + +const ftp = require("./ftp"); +ftp.gulptasksFTP($, gulp, buildFolder); + +const docs = require("./docs"); +docs.gulptasksDocs($, gulp, buildFolder); + +const standalone = require("./standalone"); +standalone.gulptasksStandalone($, gulp, buildFolder); + +// FIXME +// const cordova = require("./cordova"); +// cordova.gulptasksCordova($, gulp, buildFolder); + +///////////////////// BUILD TASKS ///////////////////// + +// Cleans up everything +gulp.task("utils.cleanup", () => { + return gulp.src(buildFolder, { read: false }).pipe($.clean({ force: true })); +}); + +// Requires no uncomitted files +gulp.task("utils.requireCleanWorkingTree", cb => { + const output = $.trim(execSync("git status -su").toString("ascii")); + if (output.length > 0) { + console.error("\n\nYou have unstaged changes, please commit everything first!"); + process.exit(1); + } + cb(); +}); + +gulp.task("utils.copyAdditionalBuildFiles", cb => { + const additionalFolder = path.join("additional_build_files"); + const additionalSrcGlobs = [ + path.join(additionalFolder, "**/*.*"), + path.join(additionalFolder, "**/.*"), + path.join(additionalFolder, "**/*"), + ]; + + return gulp.src(additionalSrcGlobs).pipe(gulp.dest(buildFolder)); +}); + +// Starts a webserver on the built directory (useful for testing prod build) +gulp.task("main.webserver", () => { + return gulp.src(buildFolder).pipe( + $.webserver({ + livereload: { + enable: true, + }, + directoryListing: false, + open: true, + port: 3005, + }) + ); +}); + +function serve({ standalone }) { + browserSync.init({ + server: buildFolder, + port: 3005, + ghostMode: { + clicks: false, + scroll: false, + location: false, + forms: false, + }, + logLevel: "info", + logPrefix: "BS", + online: false, + xip: false, + notify: false, + reloadDebounce: 100, + reloadOnRestart: true, + watchEvents: ["add", "change"], + }); + + // Watch .scss files, those trigger a css rebuild + gulp.watch(["../src/**/*.scss"], ["css.dev"]); + + // Watch .html files, those trigger a html rebuild + gulp.watch("../src/**/*.html", [standalone ? "html.standalone-dev" : "html.dev"]); + + // Watch sound files + // gulp.watch(["../res_raw/sounds/**/*.mp3", "../res_raw/sounds/**/*.wav"], ["sounds.dev"]); + + gulp.watch( + ["../res_raw/sounds/ui/*.mp3", "../res_raw/sounds/ui/*.wav"], + $.sequence("sounds.encodeUi", "sounds.copy") + ); + gulp.watch( + ["../res_raw/sounds/game/*.mp3", "../res_raw/sounds/game/*.wav"], + $.sequence("sounds.encodeGame", "sounds.copy") + ); + gulp.watch( + ["../res_raw/sounds/music/*.mp3", "../res_raw/sounds/music/*.wav"], + $.sequence("sounds.encodeMusic", "sounds.copy") + ); + + // Watch resource files and copy them on change + gulp.watch(imgres.nonImageResourcesGlobs, ["imgres.copyNonImageResources"]); + gulp.watch(imgres.imageResourcesGlobs, ["imgres.copyImageResources"]); + + // Watch .atlas files and recompile the atlas on change + gulp.watch("../res_built/atlas/*.json", ["imgres.atlas"]); + + // Watch the build folder and reload when anything changed + const extensions = ["html", "js", "png", "jpg", "svg", "mp3", "ico", "woff2"]; + gulp.watch(extensions.map(ext => path.join(buildFolder, "**", "*." + ext))).on("change", function (e) { + return gulp.src(e.path).pipe(browserSync.reload({ stream: true })); + }); + + // Start the webpack watching server (Will never return) + if (standalone) { + $.sequence("js.standalone-dev.watch")(() => true); + } else { + $.sequence("js.dev.watch")(() => true); + } +} + +// Live-development +gulp.task("main.serveDev", ["build.dev"], () => serve({ standalone: false })); +gulp.task("main.serveStandalone", ["build.standalone.dev"], () => serve({ standalone: true })); + +gulp.task("default", ["main.serveDev"]); + +///////////////////// RUNNABLE TASKS ///////////////////// + +// Pre and postbuild +gulp.task("step.baseResources", cb => $.multiProcess(["sounds.fullbuild", "imgres.allOptimized"], cb, false)); +gulp.task("step.deleteEmpty", cb => { + deleteEmpty.sync(buildFolder); + cb(); +}); + +gulp.task("step.postbuild", $.sequence("imgres.cleanupUnusedCssInlineImages", "step.deleteEmpty")); + +// Builds everything (dev) +gulp.task("build.dev", cb => { + $.sequence( + "utils.cleanup", + "utils.copyAdditionalBuildFiles", + "imgres.atlas", + "sounds.dev", + "imgres.copyImageResources", + "imgres.copyNonImageResources", + "js.dev", + "css.dev", + "html.dev" + )(cb); +}); + +// Builds everything (standalone -dev) +gulp.task("build.standalone.dev", cb => { + $.sequence( + "utils.cleanup", + "imgres.atlas", + "sounds.dev", + "imgres.copyImageResources", + "imgres.copyNonImageResources", + "js.standalone-dev", + "css.dev", + "html.standalone-dev" + )(cb); +}); + +// Builds everything (staging) +gulp.task("step.staging.code", $.sequence("js.staging")); +gulp.task("step.staging.mainbuild", cb => + $.multiProcess(["utils.copyAdditionalBuildFiles", "step.baseResources", "step.staging.code"], cb, false) +); +gulp.task("step.staging.all", $.sequence("step.staging.mainbuild", "css.prod", "html.staging")); +gulp.task("build.staging", $.sequence("utils.cleanup", "step.staging.all", "step.postbuild")); + +// Builds everything (prod) +gulp.task("step.prod.code", $.sequence("js.prod")); +gulp.task("step.prod.mainbuild", cb => + $.multiProcess(["utils.copyAdditionalBuildFiles", "step.baseResources", "step.prod.code"], cb, false) +); +gulp.task("step.prod.all", $.sequence("step.prod.mainbuild", "css.prod", "html.prod")); +gulp.task("build.prod", $.sequence("utils.cleanup", "step.prod.all", "step.postbuild")); + +// Builds everything (standalone-beta) +gulp.task("step.standalone-beta.code", $.sequence("js.standalone-beta")); +gulp.task("step.standalone-beta.mainbuild", cb => + $.multiProcess( + ["utils.copyAdditionalBuildFiles", "step.baseResources", "step.standalone-beta.code"], + cb, + false + ) +); +gulp.task( + "step.standalone-beta.all", + $.sequence("step.standalone-beta.mainbuild", "css.prod-standalone", "html.standalone-beta") +); +gulp.task("build.standalone-beta", $.sequence("utils.cleanup", "step.standalone-beta.all", "step.postbuild")); + +// Builds everything (standalone-prod) +gulp.task("step.standalone-prod.code", $.sequence("js.standalone-prod")); +gulp.task("step.standalone-prod.mainbuild", cb => + $.multiProcess( + ["utils.copyAdditionalBuildFiles", "step.baseResources", "step.standalone-prod.code"], + cb, + false + ) +); +gulp.task( + "step.standalone-prod.all", + $.sequence("step.standalone-prod.mainbuild", "css.prod-standalone", "html.standalone-prod") +); +gulp.task("build.standalone-prod", $.sequence("utils.cleanup", "step.standalone-prod.all", "step.postbuild")); + +// Deploying! +gulp.task( + "main.deploy.staging", + $.sequence("utils.requireCleanWorkingTree", "build.staging", "ftp.upload.staging") +); +gulp.task("main.deploy.prod", $.sequence("utils.requireCleanWorkingTree", "build.prod", "ftp.upload.prod")); +gulp.task("main.deploy.all", $.sequence("main.deploy.staging", "main.deploy.prod")); + +// gulp.task("main.standalone.beta", $.sequence("build.standalone-beta", "standalone.package.beta")); +gulp.task("main.standalone", $.sequence("build.standalone-prod", "standalone.package.prod")); diff --git a/gulp/html.js b/gulp/html.js new file mode 100644 index 00000000..48c5547a --- /dev/null +++ b/gulp/html.js @@ -0,0 +1,360 @@ +const buildUtils = require("./buildutils"); +const fs = require("fs"); +const path = require("path"); +const crypto = require("crypto"); + +function computeIntegrityHash(fullPath, algorithm = "sha256") { + const file = fs.readFileSync(fullPath); + const hash = crypto.createHash(algorithm).update(file).digest("base64"); + return algorithm + "-" + hash; +} + +function gulptasksHTML($, gulp, buildFolder, browserSync) { + const commitHash = buildUtils.getRevision(); + async function buildHtml( + apiUrl, + { + analytics = false, + standalone = false, + app = false, + integrity = true, + enableCachebust = true, + gameAnalyticsKey = null, + gameAnalyticsSecret = null, + } + ) { + function cachebust(url) { + if (enableCachebust) { + return buildUtils.cachebust(url, commitHash); + } + return url; + } + + const hasLocalFiles = standalone || app; + + return gulp + .src("../src/html/" + (standalone ? "index.standalone.html" : "index.html")) + .pipe( + $.dom(function () { + // @ts-ignore + const document = /** @type {Document} */ (this); + + // Preconnect to api + const prefetchLink = document.createElement("link"); + prefetchLink.rel = "preconnect"; + prefetchLink.href = apiUrl; + prefetchLink.setAttribute("crossorigin", "anonymous"); + document.head.appendChild(prefetchLink); + + // // Append css preload + // const cssPreload = document.createElement("link"); + // cssPreload.rel = "preload"; + // cssPreload.href = cachebust("main.css"); + // cssPreload.setAttribute("as", "style"); + // document.head.appendChild(cssPreload); + // document.head.appendChild(prefetchLink); + + // // Append js preload + // const jsPreload = document.createElement("link"); + // jsPreload.rel = "preload"; + // jsPreload.href = cachebust("bundle.js"); + // jsPreload.setAttribute("as", "script"); + // document.head.appendChild(jsPreload); + + // Append css + const css = document.createElement("link"); + css.rel = "stylesheet"; + css.type = "text/css"; + css.media = "none"; + css.setAttribute("onload", "this.media='all'"); + css.href = cachebust("main.css"); + if (integrity) { + css.setAttribute( + "integrity", + computeIntegrityHash(path.join(buildFolder, "main.css")) + ); + } + document.head.appendChild(css); + + if (analytics) { + // Logrocket + // const logrocketScript = document.createElement("script"); + // logrocketScript.src = "https://cdn.lr-ingest.io/LogRocket.min.js"; + // logrocketScript.setAttribute("crossorigin", "anonymous"); + // document.head.appendChild(logrocketScript); + // const logrocketInit = document.createElement("script"); + // logrocketInit.textContent = "window.LogRocket && window.LogRocket.init('TODO: GET LOGROCKET ID');"; + // document.head.appendChild(logrocketInit); + } + + if (gameAnalyticsKey && gameAnalyticsSecret) { + const gaLoader = document.createElement("script"); + gaLoader.textContent = ` + window.GameAnalytics=window.GameAnalytics||function(){(GameAnalytics.q=GameAnalytics.q||[]).push(arguments)}; + window.ga_comKey = "${gameAnalyticsKey}"; + window.ga_comToken = "${gameAnalyticsSecret}"; + `; + document.head.appendChild(gaLoader); + + const gaScript = document.createElement("script"); + gaScript.src = "https://download.gameanalytics.com/js/GameAnalytics-4.0.10.min.js"; + gaScript.setAttribute("async", ""); + document.head.appendChild(gaScript); + } + + if (app) { + // Append cordova link + const cdv = document.createElement("script"); + cdv.src = "cordova.js"; + cdv.type = "text/javascript"; + document.head.appendChild(cdv); + } + + // Google analytics + if (analytics) { + const tagManagerScript = document.createElement("script"); + tagManagerScript.src = "https://www.googletagmanager.com/gtag/js?id=UA-165342524-1"; + tagManagerScript.setAttribute("async", ""); + document.head.appendChild(tagManagerScript); + + const initScript = document.createElement("script"); + initScript.textContent = ` + window.dataLayer = window.dataLayer || []; + function gtag(){dataLayer.push(arguments);} + gtag('js', new Date()); + gtag('config', 'UA-165342524-1', { anonymize_ip: true }); + `; + document.head.appendChild(initScript); + } + + // Do not need to preload in app or standalone + if (!hasLocalFiles) { + // Preload images + const images = buildUtils.getAllResourceImages(); + + // Preload essentials + const preloads = ["fonts/LouisGeorgeCafe.woff2"]; + + // for (let i = 0; i < images.length; ++i) { + // if (preloads.indexOf(images[i]) < 0) { + // preloads.push(images[i]); + // } + // } + + preloads.forEach(src => { + const preloadLink = document.createElement("link"); + preloadLink.rel = "preload"; + preloadLink.href = cachebust("res/" + src); + if (src.endsWith(".woff2")) { + preloadLink.setAttribute("crossorigin", "anonymous"); + preloadLink.setAttribute("as", "font"); + } else { + preloadLink.setAttribute("as", "image"); + } + document.head.appendChild(preloadLink); + }); + + // Sound preloads + // const sounds = buildUtils.getAllSounds(); + // sounds.forEach((src) => { + + // if (src.indexOf("sounds/music/") >= 0) { + // // skip music + // return; + // } + + // const preloadLink = document.createElement("link"); + // preloadLink.rel = "preload"; + // preloadLink.href = cachebust(src); + // // preloadLink.setAttribute("crossorigin", "anonymous"); + // preloadLink.setAttribute("as", "fetch"); + // document.head.appendChild(preloadLink); + // }); + } + + const loadingSvg = `background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46YXV0bztiYWNrZ3JvdW5kOjAgMCIgd2lkdGg9IjIwMCIgaGVpZ2h0PSIyMDAiIHZpZXdCb3g9IjAgMCAxMDAgMTAwIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCIgZGlzcGxheT0iYmxvY2siPjxjaXJjbGUgY3g9IjUwIiBjeT0iNTAiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzM5Mzc0NyIgc3Ryb2tlLXdpZHRoPSIzIiByPSI0MiIgc3Ryb2tlLWRhc2hhcnJheT0iMTk3LjkyMDMzNzE3NjE1Njk4IDY3Ljk3MzQ0NTcyNTM4NTY2IiB0cmFuc2Zvcm09InJvdGF0ZSg0OC4yNjUgNTAgNTApIj48YW5pbWF0ZVRyYW5zZm9ybSBhdHRyaWJ1dGVOYW1lPSJ0cmFuc2Zvcm0iIHR5cGU9InJvdGF0ZSIgcmVwZWF0Q291bnQ9ImluZGVmaW5pdGUiIGR1cj0iNS41NTU1NTU1NTU1NTU1NTVzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIi8+PC9jaXJjbGU+PC9zdmc+")`; + + const loadingCss = ` + @font-face { + font-family: 'GameFont'; + font-style: normal; + font-weight: normal; + font-display: swap; + src: url('${cachebust("res/fonts/LouisGeorgeCafe.woff2")}') format('woff2'); + } + + #ll_fp { + font-family: GameFont; + font-size: 14px; + position: fixed; + z-index: -1; + top: 0; + left: 0; + opacity: 0.05; + } + + #ll_p { + display: flex; + position: fixed; + z-index: 99999; + top: 0; + left: 0; + right: 0; + bottom: 0; + justify-content: + center; + align-items: center; + } + + #ll_p > div { + position: absolute; + text-align: center; + bottom: 40px; + left: 20px; + right: 20px; + color: #393747; + font-family: 'GameFont', sans-serif; + font-size: 20px; + } + + #ll_p > span { + width: 60px; + height: 60px; + display: inline-flex; + background: center center / contain no-repeat; + ${loadingSvg}; + } + `; + + const style = document.createElement("style"); + style.setAttribute("type", "text/css"); + style.textContent = loadingCss; + document.head.appendChild(style); + + // Append loader, but not in standalone (directly include bundle there) + if (standalone) { + const bundleScript = document.createElement("script"); + bundleScript.type = "text/javascript"; + bundleScript.src = "bundle.js"; + if (integrity) { + bundleScript.setAttribute( + "integrity", + computeIntegrityHash(path.join(buildFolder, "bundle.js")) + ); + } + document.head.appendChild(bundleScript); + } else { + const loadJs = document.createElement("script"); + loadJs.type = "text/javascript"; + let scriptContent = ""; + scriptContent += `var bundleSrc = '${cachebust("bundle.js")}';\n`; + scriptContent += `var bundleSrcTranspiled = '${cachebust( + "bundle-transpiled.js" + )}';\n`; + + if (integrity) { + scriptContent += + "var bundleIntegrity = '" + + computeIntegrityHash(path.join(buildFolder, "bundle.js")) + + "';\n"; + scriptContent += + "var bundleIntegrityTranspiled = '" + + computeIntegrityHash(path.join(buildFolder, "bundle-transpiled.js")) + + "';\n"; + } else { + scriptContent += "var bundleIntegrity = null;\n"; + scriptContent += "var bundleIntegrityTranspiled = null;\n"; + } + + scriptContent += fs.readFileSync("./bundle-loader.js").toString(); + loadJs.textContent = scriptContent; + document.head.appendChild(loadJs); + } + + const bodyContent = ` +
_
+
+ +
${hasLocalFiles ? "Loading" : "Downloading"} Game Files
+
+ `; + + document.body.innerHTML = bodyContent; + }) + ) + .pipe( + $.htmlmin({ + caseSensitive: true, + collapseBooleanAttributes: true, + collapseInlineTagWhitespace: true, + collapseWhitespace: true, + preserveLineBreaks: true, + minifyJS: true, + minifyCSS: true, + quoteCharacter: '"', + useShortDoctype: true, + }) + ) + .pipe($.htmlBeautify()) + .pipe($.rename("index.html")) + .pipe(gulp.dest(buildFolder)); + } + + gulp.task("html.dev", () => { + return buildHtml("http://localhost:5005", { + analytics: false, + integrity: false, + enableCachebust: false, + gameAnalyticsKey: "c8d77921633d5c32a7134e5d5cfcdf12", + // Not an actual "secret" since its built into the JS code + gameAnalyticsSecret: "6d23b40a70199bff0e7a7d8a073543772cf07097", + }); + }); + + gulp.task("html.staging", () => { + return buildHtml("https://api-staging.shapez.io", { + analytics: true, + gameAnalyticsKey: "903fa0dd2d2e23b07e66ea96ddc4c10c", + // Not an actual "secret" since its built into the JS code + gameAnalyticsSecret: "9417fc391d7142b9d73a3861ba6046cafa9df6cb", + }); + }); + + gulp.task("html.prod", () => { + return buildHtml("https://api.shapez.io", { + analytics: true, + gameAnalyticsKey: "16c7f9d352e40c92f6a750fc1a4f0443", + // Not an actual "secret" since its built into the JS code + gameAnalyticsSecret: "4202d7adf154c325ff91731e8be6912e6c0d10e5", + }); + }); + + gulp.task("html.standalone-dev", () => { + return buildHtml("https://localhost:5005", { + analytics: false, + standalone: true, + integrity: false, + enableCachebust: false, + }); + }); + + gulp.task("html.standalone-beta", () => { + return buildHtml("https://api-staging.shapez.io", { + analytics: true, + standalone: true, + enableCachebust: false, + }); + }); + + gulp.task("html.standalone-prod", () => { + return buildHtml("https://api.shapez.io", { + analytics: true, + standalone: true, + enableCachebust: false, + }); + }); +} + +module.exports = { + gulptasksHTML, +}; diff --git a/gulp/image-resources.js b/gulp/image-resources.js new file mode 100644 index 00000000..09511bc3 --- /dev/null +++ b/gulp/image-resources.js @@ -0,0 +1,138 @@ +// @ts-ignore +const path = require("path"); + +// Globs for non-ui resources +const nonImageResourcesGlobs = ["../res/**/*.woff2", "../res/*.ico"]; + +// Globs for ui resources +const imageResourcesGlobs = ["../res/**/*.png", "../res/**/*.svg", "../res/**/*.jpg"]; + +function gulptasksImageResources($, gulp, buildFolder) { + // Lossless options + const minifyImagesOptsLossless = () => [ + $.imagemin.jpegtran({ + progressive: true, + }), + $.imagemin.svgo({}), + $.imagemin.optipng({ + optimizationLevel: 3, + }), + ]; + + // Lossy options + const minifyImagesOpts = () => [ + $.imageminMozjpeg({ + quality: 80, + maxMemory: 1024 * 1024 * 8, + }), + $.imagemin.svgo({}), + $.imageminPngquant({ + speed: 1, + strip: true, + quality: [0.65, 0.9], + dithering: false, + verbose: false, + }), + $.imagemin.optipng({ + optimizationLevel: 3, + }), + ]; + + // Where the resources folder are + const resourcesDestFolder = path.join(buildFolder, "res"); + + /** + * Determines if an atlas must use lossless compression + * @param {string} fname + */ + function fileMustBeLossless(fname) { + return fname.indexOf("lossless") >= 0; + } + + /////////////// ATLAS ///////////////////// + + // Copies the atlas to the final destination + gulp.task("imgres.atlas", () => { + return gulp + .src(["../res_built/atlas/*.png"]) + .pipe($.cached("imgres.atlas")) + .pipe(gulp.dest(resourcesDestFolder)); + }); + + // Copies the atlas to the final destination after optimizing it (lossy compression) + gulp.task("imgres.atlasOptimized", () => { + return gulp + .src(["../res_built/atlas/*.png"]) + .pipe($.cached("imgres.atlasOptimized")) + .pipe( + $.if( + fname => fileMustBeLossless(fname.history[0]), + $.imagemin(minifyImagesOptsLossless()), + $.imagemin(minifyImagesOpts()) + ) + ) + .pipe(gulp.dest(resourcesDestFolder)); + }); + + //////////////////// RESOURCES ////////////////////// + + // Copies all resources which are no ui resources + gulp.task("imgres.copyNonImageResources", () => { + return gulp + .src(nonImageResourcesGlobs) + .pipe($.cached("imgres.copyNonImageResources")) + .pipe(gulp.dest(resourcesDestFolder)); + }); + + // Copies all ui resources + gulp.task("imgres.copyImageResources", () => { + return gulp + .src(imageResourcesGlobs) + .pipe($.cached("copyImageResources")) + .pipe(gulp.dest(path.join(resourcesDestFolder))); + }); + + // Copies all ui resources and optimizes them + gulp.task("imgres.copyImageResourcesOptimized", () => { + return gulp + .src(imageResourcesGlobs) + .pipe($.cached("imgres.copyImageResourcesOptimized")) + .pipe( + $.if( + fname => fileMustBeLossless(fname.history[0]), + $.imagemin(minifyImagesOptsLossless()), + $.imagemin(minifyImagesOpts()) + ) + ) + .pipe(gulp.dest(path.join(resourcesDestFolder))); + }); + + // Copies all resources and optimizes them + gulp.task("imgres.allOptimized", cb => + $.multiProcess( + ["imgres.atlasOptimized", "imgres.copyNonImageResources", "imgres.copyImageResourcesOptimized"], + cb, + false + ) + ); + + // Cleans up unused images which are instead inline into the css + gulp.task("imgres.cleanupUnusedCssInlineImages", () => { + return gulp + .src( + [ + path.join(buildFolder, "res", "ui", "**", "*.png"), + path.join(buildFolder, "res", "ui", "**", "*.jpg"), + path.join(buildFolder, "res", "ui", "**", "*.svg"), + ], + { read: false } + ) + .pipe($.if(fname => fname.history[0].indexOf("noinline") < 0, $.clean({ force: true }))); + }); +} + +module.exports = { + nonImageResourcesGlobs, + imageResourcesGlobs, + gulptasksImageResources, +}; diff --git a/gulp/js.js b/gulp/js.js new file mode 100644 index 00000000..a8f39c1e --- /dev/null +++ b/gulp/js.js @@ -0,0 +1,182 @@ +const path = require("path"); + +function requireUncached(module) { + delete require.cache[require.resolve(module)]; + return require(module); +} + +function gulptasksJS($, gulp, buildFolder, browserSync) { + gulp.task("js.prettify", () => { + return gulp + .src(path.join(buildFolder, "bundle.js")) + .pipe($.jsbeautifier(require("./jsbeautify.json"))) + .pipe(gulp.dest(buildFolder)); + }); + + //// DEV + + gulp.task("js.dev.watch", () => { + return gulp + .src("../src/js/main.js") + .pipe( + $.webpackStream( + requireUncached("./webpack.config.js")({ + watch: true, + }) + ) + ) + .pipe(gulp.dest(buildFolder)) + .pipe(browserSync.stream()); + }); + + gulp.task("js.dev", () => { + return gulp + .src("../src/js/main.js") + .pipe($.webpackStream(requireUncached("./webpack.config.js")({}))) + .pipe(gulp.dest(buildFolder)); + }); + + //// STAGING + + gulp.task("js.staging.transpiled", () => { + return gulp + .src("../src/js/main.js") + .pipe( + $.webpackStream( + requireUncached("./webpack.production.config.js")({ + enableAssert: true, + environment: "staging", + apiEndpoint: "https://api-staging.shapez.io/v1", + es6: false, + }) + ) + ) + .pipe($.rename("bundle-transpiled.js")) + .pipe(gulp.dest(buildFolder)); + }); + + gulp.task("js.staging.latest", () => { + return gulp + .src("../src/js/main.js") + .pipe( + $.webpackStream( + requireUncached("./webpack.production.config.js")({ + enableAssert: true, + environment: "staging", + apiEndpoint: "https://api-staging.shapez.io/v1", + es6: true, + }) + ) + ) + .pipe(gulp.dest(buildFolder)); + }); + gulp.task("js.staging", cb => $.multiProcess(["js.staging.transpiled", "js.staging.latest"], cb, false)); + + //// PROD + gulp.task("js.prod.transpiled", () => { + return gulp + .src("../src/js/main.js") + .pipe( + $.webpackStream( + requireUncached("./webpack.production.config.js")({ + enableAssert: false, + environment: "prod", + apiEndpoint: "https://api.shapez.io/v1", + es6: false, + }) + ) + ) + .pipe($.rename("bundle-transpiled.js")) + .pipe(gulp.dest(buildFolder)) + .pipe(browserSync.stream()); + }); + + gulp.task("js.prod.latest", () => { + return gulp + .src("../src/js/main.js") + .pipe( + $.webpackStream( + requireUncached("./webpack.production.config.js")({ + enableAssert: false, + environment: "prod", + es6: true, + apiEndpoint: "https://api.shapez.io/v1", + }) + ) + ) + .pipe(gulp.dest(buildFolder)) + .pipe(browserSync.stream()); + }); + + gulp.task("js.prod", cb => $.multiProcess(["js.prod.transpiled", "js.prod.latest"], cb, false)); + + //// STANDALONE + + gulp.task("js.standalone-dev.watch", () => { + return gulp + .src("../src/js/main.js") + .pipe( + $.webpackStream( + requireUncached("./webpack.config.js")({ + watch: true, + standalone: true, + }) + ) + ) + .pipe(gulp.dest(buildFolder)) + .pipe(browserSync.stream()); + }); + + gulp.task("js.standalone-dev", () => { + return gulp + .src("../src/js/main.js") + .pipe( + $.webpackStream( + requireUncached("./webpack.config.js")({ + standalone: true, + }) + ) + ) + .pipe(gulp.dest(buildFolder)); + }); + + gulp.task("js.standalone-beta", () => { + return gulp + .src("../src/js/main.js") + .pipe( + $.webpackStream( + requireUncached("./webpack.production.config.js")({ + enableAssert: true, + environment: "staging", + apiEndpoint: "https://api-staging.shapez.io/v1", + es6: true, + standalone: true, + }) + ) + ) + .pipe(gulp.dest(buildFolder)); + }); + + gulp.task("js.standalone-prod", () => { + return gulp + .src("../src/js/main.js") + .pipe( + $.webpackStream( + requireUncached("./webpack.production.config.js")({ + enableAssert: false, + environment: "prod", + apiEndpoint: "https://api.shapez.io/v1", + es6: true, + standalone: true, + }) + ) + ) + .pipe(gulp.dest(buildFolder)); + }); + + // TODO: Tasks for te app +} + +module.exports = { + gulptasksJS, +}; diff --git a/gulp/jsconfig.json b/gulp/jsconfig.json new file mode 100644 index 00000000..e28a1c04 --- /dev/null +++ b/gulp/jsconfig.json @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "target": "es6", + "checkJs": true + } +} diff --git a/gulp/loader.compressjson.js b/gulp/loader.compressjson.js new file mode 100644 index 00000000..9e80298f --- /dev/null +++ b/gulp/loader.compressjson.js @@ -0,0 +1,11 @@ +"use strict"; + +const lzString = require("lz-string"); + +module.exports = function (source) { + const compressed = lzString.compressToEncodedURIComponent(source); + const sourcecode = `module.exports = (function() { + return JSON.parse(require("global-compression").decompressX64("${compressed}")); + })()`; + return sourcecode; +}; diff --git a/gulp/loader.strip_block.js b/gulp/loader.strip_block.js new file mode 100644 index 00000000..31ae5432 --- /dev/null +++ b/gulp/loader.strip_block.js @@ -0,0 +1,21 @@ +/*jslint node:true */ +"use strict"; + +const startComment = "typehints:start"; +const endComment = "typehints:end"; +const regexPattern = new RegExp( + "[\\t ]*\\/\\* ?" + startComment + " ?\\*\\/[\\s\\S]*?\\/\\* ?" + endComment + " ?\\*\\/[\\t ]*\\n?", + "g" +); + +function StripBlockLoader(content) { + if (content.indexOf(startComment) >= 0) { + content = content.replace(regexPattern, ""); + } + if (this.cacheable) { + this.cacheable(true); + } + return content; +} + +module.exports = StripBlockLoader; diff --git a/gulp/package.json b/gulp/package.json new file mode 100644 index 00000000..3cb8ae15 --- /dev/null +++ b/gulp/package.json @@ -0,0 +1,115 @@ +{ + "name": "builder", + "version": "1.0.0", + "description": "builder", + "private": true, + "main": "main.js", + "scripts": { + "gulp": "gulp" + }, + "author": "tobspr", + "license": "private", + "dependencies": { + "@babel/core": "^7.9.0", + "@babel/plugin-transform-block-scoping": "^7.4.4", + "@babel/plugin-transform-classes": "^7.5.5", + "@babel/preset-env": "^7.5.4", + "@types/cordova": "^0.0.34", + "@types/filesystem": "^0.0.29", + "@types/node": "^12.7.5", + "ajv": "^6.10.2", + "babel-loader": "^8.1.0", + "browser-sync": "^2.24.6", + "circular-dependency-plugin": "^5.0.2", + "circular-json": "^0.5.9", + "colors": "^1.3.3", + "core-js": "3", + "crypto": "^1.0.1", + "cssnano-preset-advanced": "^4.0.7", + "delete-empty": "^3.0.0", + "email-validator": "^2.0.4", + "eslint": "^5.9.0", + "fastdom": "^1.0.9", + "flatted": "^2.0.1", + "fs-extra": "^8.1.0", + "howler": "^2.1.2", + "html-loader": "^0.5.5", + "ignore-loader": "^0.1.2", + "lz-string": "^1.4.4", + "markdown-loader": "^5.1.0", + "node-sri": "^1.1.1", + "obfuscator-loader": "^1.1.2", + "phonegap-plugin-mobile-accessibility": "^1.0.5", + "promise-polyfill": "^8.1.0", + "query-string": "^6.8.1", + "rusha": "^0.8.13", + "serialize-error": "^3.0.0", + "sloc": "^0.2.1", + "strictdom": "^1.0.1", + "string-replace-webpack-plugin": "^0.1.3", + "terser-webpack-plugin": "^1.1.0", + "uglify-template-string-loader": "^1.1.0", + "unused-files-webpack-plugin": "^3.4.0", + "webpack": "^4.31.0", + "webpack-bundle-analyzer": "^3.0.3", + "webpack-cli": "^3.1.0", + "webpack-deep-scope-plugin": "^1.6.0", + "webpack-plugin-replace": "^1.1.1", + "webpack-strip-block": "^0.2.0", + "whatwg-fetch": "^3.0.0", + "worker-loader": "^2.0.0" + }, + "devDependencies": { + "autoprefixer": "^9.4.3", + "babel-plugin-closure-elimination": "^1.3.0", + "babel-plugin-console-source": "^2.0.2", + "babel-plugin-danger-remove-unused-import": "^1.1.2", + "css-mqpacker": "^7.0.0", + "cssnano": "^4.1.10", + "electron-packager": "^14.0.6", + "faster.js": "^1.1.0", + "glob": "^7.1.3", + "gulp": "^3.9.1", + "gulp-cache": "^1.1.3", + "gulp-cached": "^1.1.1", + "gulp-clean": "^0.4.0", + "gulp-cssbeautify": "^1.0.1", + "gulp-csslint": "^1.0.1", + "gulp-dom": "^1.0.0", + "gulp-flatten": "^0.4.0", + "gulp-fluent-ffmpeg": "^1.0.2", + "gulp-html-beautify": "^1.0.1", + "gulp-htmlmin": "^5.0.1", + "gulp-if": "^2.0.2", + "gulp-imagemin": "^5.0.3", + "gulp-javascript-obfuscator": "^1.1.5", + "gulp-jsbeautifier": "^3.0.0", + "gulp-load-plugins": "^1.5.0", + "gulp-multi-process": "^1.3.1", + "gulp-phonegap-build": "^0.1.5", + "gulp-plumber": "^1.2.1", + "gulp-pngquant": "^1.0.12", + "gulp-postcss": "^8.0.0", + "gulp-rename": "^1.4.0", + "gulp-sass": "^4.0.1", + "gulp-sass-lint": "^1.4.0", + "gulp-sequence": "^1.0.0", + "gulp-sftp": "^0.1.5", + "gulp-terser": "^1.2.0", + "gulp-webserver": "^0.9.1", + "imagemin-mozjpeg": "^8.0.0", + "imagemin-pngquant": "^8.0.0", + "jimp": "^0.6.1", + "js-yaml": "^3.13.1", + "onesky-fetch": "^0.0.7", + "postcss-assets": "^5.0.0", + "postcss-preset-env": "^6.5.0", + "postcss-round-subpixels": "^1.2.0", + "postcss-unprefix": "^2.1.3", + "sass-unused": "^0.3.0", + "speed-measure-webpack-plugin": "^1.3.1", + "strip-json-comments": "^3.0.1", + "trim": "^0.0.1", + "webpack-stream": "^5.1.0" + } +} diff --git a/gulp/sounds.js b/gulp/sounds.js new file mode 100644 index 00000000..3233162b --- /dev/null +++ b/gulp/sounds.js @@ -0,0 +1,107 @@ +const path = require("path"); + +function gulptasksSounds($, gulp, buildFolder) { + // Gather some basic infos + const soundsDir = path.join("..", "res_raw", "sounds"); + const builtSoundsDir = path.join("..", "res_built", "sounds"); + + gulp.task("sounds.clear", () => { + return gulp.src(builtSoundsDir).pipe($.clean({ force: true })); + }); + + const filters = ["loudnorm", "volume=0.2"]; + + const fileCache = new $.cache.Cache({ + cacheDirName: "shapezio-precompiled-sounds", + }); + + // Encodes the game music + gulp.task("sounds.encodeMusic", () => { + return gulp + .src([path.join(soundsDir, "music", "**", "*.wav"), path.join(soundsDir, "music", "**", "*.mp3")]) + .pipe( + $.cache( + $.fluentFfmpeg("mp3", function (cmd) { + return cmd + .audioBitrate(48) + .audioChannels(1) + .audioFrequency(22050) + .audioCodec("libmp3lame"); + // .audioFilters(["volume=0.25"]) + }), + { + name: "music", + fileCache, + } + ) + ) + .pipe(gulp.dest(path.join(builtSoundsDir, "music"))); + }); + + // Encodes the ui sounds + gulp.task("sounds.encodeUi", () => { + return gulp + .src([path.join(soundsDir, "ui", "**", "*.wav"), path.join(soundsDir, "ui", "**", "*.mp3")]) + .pipe( + $.cache( + $.fluentFfmpeg("mp3", function (cmd) { + return cmd + .audioBitrate(128) + .audioChannels(1) + .audioFrequency(22050) + .audioCodec("libmp3lame") + .audioFilters(filters); + }) + ), + { + name: "uisounds", + fileCache, + } + ) + .pipe(gulp.dest(path.join(builtSoundsDir, "ui"))); + }); + + // Encodes the game sounds + gulp.task("sounds.encodeGame", () => { + return gulp + .src([path.join(soundsDir, "game", "**", "*.wav"), path.join(soundsDir, "game", "**", "*.mp3")]) + .pipe( + $.cache( + $.fluentFfmpeg("mp3", function (cmd) { + return cmd + .audioBitrate(128) + .audioChannels(1) + .audioFrequency(22050) + .audioCodec("libmp3lame") + .audioFilters(filters); + }), + { + nane: "gamesounds", + fileCache, + } + ) + ) + .pipe(gulp.dest(path.join(builtSoundsDir, "game"))); + }); + + gulp.task("sounds.copy", () => { + return gulp + .src(path.join(builtSoundsDir, "**", "*.mp3")) + .pipe($.cached("sounds.copy")) + .pipe(gulp.dest(path.join(buildFolder, "res", "sounds"))); + }); + + gulp.task("sounds.buildall", cb => + $.multiProcess(["sounds.encodeMusic", "sounds.encodeUi", "sounds.encodeGame"], cb, true) + ); + + gulp.task("sounds.fullbuild", cb => $.sequence("sounds.clear", "sounds.buildall", "sounds.copy")(cb)); + + gulp.task("sounds.dev", cb => { + return $.sequence("sounds.buildall", "sounds.copy")(cb); + }); +} + +module.exports = { + gulptasksSounds, +}; diff --git a/gulp/standalone.js b/gulp/standalone.js new file mode 100644 index 00000000..26bc0043 --- /dev/null +++ b/gulp/standalone.js @@ -0,0 +1,215 @@ +const packager = require("electron-packager"); +const path = require("path"); +const buildutils = require("./buildutils"); +const fs = require("fs"); +const fse = require("fs-extra"); +const execSync = require("child_process").execSync; + +function gulptasksStandalone($, gulp, buildFolder) { + const electronBaseDir = path.join("../electron"); + + const tempDestDir = path.join("..", "tmp_standalone_files"); + const tempDestBuildDir = path.join(tempDestDir, "built"); + + gulp.task("standalone.prepare.cleanup", () => { + return gulp.src(tempDestDir, { read: false }).pipe($.clean({ force: true })); + }); + + gulp.task("standalone.prepare.copyPrefab", () => { + // const requiredFiles = $.glob.sync("../electron/"); + const requiredFiles = [ + path.join(electronBaseDir, "lib", "**", "*.node"), + path.join(electronBaseDir, "node_modules", "**", "*.*"), + path.join(electronBaseDir, "node_modules", "**", ".*"), + path.join(electronBaseDir, "node_modules", "**", "*"), + path.join(electronBaseDir, "favicon*"), + ]; + return gulp.src(requiredFiles, { base: electronBaseDir }).pipe(gulp.dest(tempDestBuildDir)); + }); + + gulp.task("standalone.prepare.writePackageJson", () => { + fs.writeFileSync( + path.join(tempDestBuildDir, "package.json"), + JSON.stringify( + { + devDependencies: { + electron: "6.0.10", + }, + }, + null, + 4 + ) + ); + }); + + gulp.task("standalone.prepare.minifyCode", () => { + return gulp + .src(path.join(electronBaseDir, "*.js")) + .pipe( + $.terser({ + ecma: 6, + parse: {}, + module: false, + toplevel: true, + keep_classnames: false, + keep_fnames: false, + safari10: false, + compress: { + arguments: false, // breaks + drop_console: false, + // keep_fargs: false, + keep_infinity: true, + passes: 2, + module: false, + toplevel: true, + unsafe_math: true, + unsafe_arrows: false, + warnings: true, + }, + mangle: { + eval: true, + keep_classnames: false, + keep_fnames: false, + module: false, + toplevel: true, + safari10: false, + }, + output: { + comments: false, + ascii_only: true, + beautify: false, + braces: false, + ecma: 6, + }, + }) + ) + .pipe(gulp.dest(tempDestBuildDir)); + }); + + gulp.task("standalone.prepare.copyGamefiles", () => { + return gulp.src("../../www/**/*.*", { base: "../../www" }).pipe(gulp.dest(tempDestBuildDir)); + }); + + gulp.task("standalone.killRunningInstances", () => { + try { + execSync("taskkill /F /IM shapezio.exe"); + } catch (ex) { + console.warn("Failed to kill running instances, maybe none are up."); + } + }); + + gulp.task( + "standalone.prepare", + $.sequence( + "standalone.killRunningInstances", + "standalone.prepare.cleanup", + "standalone.prepare.copyPrefab", + "standalone.prepare.writePackageJson", + "standalone.prepare.minifyCode", + "standalone.prepare.copyGamefiles" + ) + ); + + /** + * + * @param {'win32'|'linux'|'darwin'} platform + * @param {'x64'|'ia32'} arch + * @param {function():void} cb + * @param {boolean=} isRelease + */ + function packageStandalone(platform, arch, cb, isRelease = false) { + const libDirName = (platform === "win32" ? "win" : platform) + (arch === "x64" ? "64" : "32"); + + const libDir = path.join(electronBaseDir, "lib", libDirName); + if (!fs.existsSync(libDir)) { + console.error("FATAL ERROR: LIB DIR does not exist:", libDir); + cb(); + return; + } + + packager({ + dir: tempDestBuildDir, + appCopyright: "Tobias Springer IT Solutions", + appVersion: buildutils.getVersion(), + buildVersion: "1.0.0", + arch, + platform, + asar: true, + executableName: "shapezio", + icon: path.join(electronBaseDir, "favicon"), + name: "Shapez.io Standalone", + out: tempDestDir, + overwrite: true, + appBundleId: "io.shapez.standalone", + appCategoryType: "public.app-category.games", + }).then( + appPaths => { + console.log("Packages created:", appPaths); + appPaths.forEach(appPath => { + if (!fs.existsSync(appPath)) { + console.error("Bad app path gotten:", appPath); + return; + } + + console.log("Copying lib files to", appPath); + const libFiles = $.glob.sync(path.join("**", "*.+(dylib|so|dll|lib)"), { cwd: libDir }); + libFiles.forEach(f => { + console.log(" -> Copying", f); + fs.copyFileSync(path.join(libDir, f), path.join(appPath, f)); + }); + + const playablePath = appPath + "_PLAYABLE"; + fse.copySync(appPath, playablePath); + fs.writeFileSync(path.join(playablePath, "steam_appid.txt"), "1134480"); + fs.writeFileSync( + path.join(playablePath, "play.bat"), + "start shapezio --dev --disable-direct-composition --in-process-gpu\r\n" + ); + fs.writeFileSync( + path.join(playablePath, "play_local.bat"), + "start shapezio --local --dev --disable-direct-composition --in-process-gpu\r\n" + ); + }); + + cb(); + }, + err => { + console.error("Packaging error:", err); + cb(); + } + ); + } + + // gulp.task("standalone.package.beta.win64", (cb) => packageStandalone("win32", "x64", cb)); + // gulp.task("standalone.package.beta.win32", (cb) => packageStandalone("win32", "ia32", cb)); + // gulp.task("standalone.package.beta.linux64", (cb) => packageStandalone("linux", "x64", cb)); + // gulp.task("standalone.package.beta.linux32", (cb) => packageStandalone("linux", "ia32", cb)); + // gulp.task("standalone.package.beta.darwin64", (cb) => packageStandalone("darwin", "x64", cb)); + + // gulp.task("standalone.package.beta", $.sequence("standalone.prepare", [ + // "standalone.package.beta.win64", + // "standalone.package.beta.win32", + // "standalone.package.beta.linux64", + // "standalone.package.beta.linux32", + // "standalone.package.beta.darwin64" + // ])); + + gulp.task("standalone.package.prod.win64", cb => packageStandalone("win32", "x64", cb, true)); + gulp.task("standalone.package.prod.win32", cb => packageStandalone("win32", "ia32", cb, true)); + gulp.task("standalone.package.prod.linux64", cb => packageStandalone("linux", "x64", cb, true)); + gulp.task("standalone.package.prod.linux32", cb => packageStandalone("linux", "ia32", cb, true)); + gulp.task("standalone.package.prod.darwin64", cb => packageStandalone("darwin", "x64", cb, true)); + + gulp.task( + "standalone.package.prod", + $.sequence("standalone.prepare", [ + "standalone.package.prod.win64", + // "standalone.package.prod.win32", + // "standalone.package.prod.linux64", + // "standalone.package.prod.linux32", + // "standalone.package.prod.darwin64" + ]) + ); +} + +module.exports = { gulptasksStandalone }; diff --git a/gulp/tsconfig.json b/gulp/tsconfig.json new file mode 100644 index 00000000..0de5c39f --- /dev/null +++ b/gulp/tsconfig.json @@ -0,0 +1,59 @@ +{ + "compilerOptions": { + /* Basic Options */ + "target": "es6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */, + "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */, + // "lib": [], /* Specify library files to be included in the compilation. */ + "allowJs": true /* Allow javascript files to be compiled. */, + "checkJs": true /* Report errors in .js files. */, + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./typedefs_gen", /* Concatenate and emit output to single file. */ + // "outDir": "./typedefs_gen", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "composite": true, /* Enable project compilation */ + // "incremental": true, /* Enable incremental compilation */ + // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ + // "removeComments": true, /* Do not emit comments to output. */ + "noEmit": true /* Do not emit outputs. */, + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + /* Strict Type-Checking Options */ + // "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + "strictFunctionTypes": true /* Enable strict checking of function types. */, + "strictBindCallApply": true /* Enable strict 'bind', 'call', and 'apply' methods on functions. */, + // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */, + "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */, + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */, + /* Module Resolution Options */ + "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */, + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, + // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + /* Source Map Options */ + // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + "resolveJsonModule": true + }, + "exclude": ["backend/shared/gameserver_base_impl"] +} diff --git a/gulp/webpack.config.js b/gulp/webpack.config.js new file mode 100644 index 00000000..31d2d7f5 --- /dev/null +++ b/gulp/webpack.config.js @@ -0,0 +1,116 @@ +const path = require("path"); +const webpack = require("webpack"); +const utils = require("./buildutils"); +const lzString = require("lz-string"); +// const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; +const CircularDependencyPlugin = require("circular-dependency-plugin"); + +module.exports = ({ watch = false, standalone = false }) => { + return { + mode: "development", + devtool: "cheap-source-map", + entry: { + "bundle.js": [path.resolve(__dirname, "../src/js/main.js")], + }, + watch, + node: { + fs: "empty", + }, + resolve: { + alias: { + "global-compression": path.resolve(__dirname, "..", "src", "js", "core", "lzstring.js"), + }, + }, + context: path.resolve(__dirname, ".."), + plugins: [ + new webpack.DefinePlugin({ + assert: "window.assert", + assertAlways: "window.assert", + abstract: + "window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));", + G_HAVE_ASSERT: "true", + G_APP_ENVIRONMENT: JSON.stringify("dev"), + G_API_ENDPOINT: JSON.stringify( + lzString.compressToEncodedURIComponent("http://localhost:5005/v1") + ), + G_TRACKING_ENDPOINT: JSON.stringify( + lzString.compressToEncodedURIComponent("http://localhost:10005/v1") + ), + G_IS_DEV: "true", + G_IS_PROD: "false", + G_IS_RELEASE: "false", + G_IS_MOBILE_APP: "false", + G_IS_BROWSER: "true", + G_IS_STANDALONE: standalone ? "true" : "false", + G_BUILD_TIME: "" + new Date().getTime(), + G_BUILD_COMMIT_HASH: JSON.stringify(utils.getRevision()), + G_BUILD_VERSION: JSON.stringify(utils.getVersion()), + G_ALL_UI_IMAGES: JSON.stringify(utils.getAllResourceImages()), + }), + + new CircularDependencyPlugin({ + // exclude detection of files based on a RegExp + exclude: /node_modules/, + + // add errors to webpack instead of warnings + failOnError: true, + + // allow import cycles that include an asyncronous import, + // e.g. via import(/* webpackMode: "weak" */ './file.js') + allowAsyncCycles: false, + + // set the current working directory for displaying module paths + cwd: path.join(__dirname, "..", "src", "js"), + }), + // new BundleAnalyzerPlugin() + ], + module: { + rules: [ + { + test: /\.json$/, + enforce: "pre", + use: ["./gulp/loader.compressjson"], + type: "javascript/auto", + }, + { test: /\.(png|jpe?g|svg)$/, loader: "ignore-loader" }, + { + test: /\.md$/, + use: [ + { + loader: "html-loader", + }, + "markdown-loader", + ], + }, + { + test: /\.js$/, + enforce: "pre", + exclude: /node_modules/, + use: [ + { + loader: "webpack-strip-block", + options: { + start: "typehints:start", + end: "typehints:end", + }, + }, + ], + }, + { + test: /\.worker\.js$/, + use: { + loader: "worker-loader", + options: { + fallback: false, + inline: true, + }, + }, + }, + ], + }, + output: { + filename: "bundle.js", + path: path.resolve(__dirname, "..", "build"), + }, + }; +}; diff --git a/gulp/webpack.production.config.js b/gulp/webpack.production.config.js new file mode 100644 index 00000000..a48f20e5 --- /dev/null +++ b/gulp/webpack.production.config.js @@ -0,0 +1,258 @@ +const path = require("path"); +const webpack = require("webpack"); +const utils = require("./buildutils"); +const lzString = require("lz-string"); + +const TerserPlugin = require("terser-webpack-plugin"); +const StringReplacePlugin = require("string-replace-webpack-plugin"); +// const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin; +const UnusedFilesPlugin = require("unused-files-webpack-plugin").UnusedFilesWebpackPlugin; +// const SpeedMeasurePlugin = require("speed-measure-webpack-plugin"); + +module.exports = ({ + enableAssert = false, + apiEndpoint, + environment, + es6 = false, + standalone = false, + isBrowser = true, + mobileApp = false, +}) => { + const globalDefs = { + assert: enableAssert ? "window.assert" : "false && window.assert", + assertAlways: "window.assert", + abstract: "window.assert(false, 'abstract method called');", + G_IS_DEV: "false", + G_IS_PROD: "true", + G_IS_RELEASE: environment === "prod" ? "true" : "false", + G_IS_STANDALONE: standalone ? "true" : "false", + G_IS_BROWSER: isBrowser ? "true" : "false", + G_IS_MOBILE_APP: mobileApp ? "true" : "false", + G_API_ENDPOINT: JSON.stringify(lzString.compressToEncodedURIComponent(apiEndpoint)), + G_TRACKING_ENDPOINT: JSON.stringify( + lzString.compressToEncodedURIComponent("https://tracking.shapez.io/v1") + ), + G_APP_ENVIRONMENT: JSON.stringify(environment), + G_HAVE_ASSERT: enableAssert ? "true" : "false", + G_BUILD_TIME: "" + new Date().getTime(), + G_BUILD_COMMIT_HASH: JSON.stringify(utils.getRevision()), + G_BUILD_VERSION: JSON.stringify(utils.getVersion()), + G_ALL_UI_IMAGES: JSON.stringify(utils.getAllResourceImages()), + }; + + return { + mode: "production", + devtool: false, + entry: { + "bundle.js": [path.resolve(__dirname, "..", "src", "js", "main.js")], + }, + node: { + fs: "empty", + }, + output: { + filename: "bundle.js", + path: path.resolve(__dirname, "..", "build"), + }, + context: path.resolve(__dirname, ".."), + stats: { + // Examine all modules + maxModules: Infinity, + // Display bailout reasons + optimizationBailout: true, + }, + resolve: { + alias: { + "global-compression": path.resolve(__dirname, "..", "src", "js", "core", "lzstring.js"), + }, + }, + optimization: { + minimize: true, + // namedModules: true, + + noEmitOnErrors: true, + removeAvailableModules: true, + removeEmptyChunks: true, + mergeDuplicateChunks: true, + flagIncludedChunks: true, + occurrenceOrder: true, + providedExports: true, + usedExports: true, + concatenateModules: true, + sideEffects: true, + + minimizer: [ + new TerserPlugin({ + parallel: true, + sourceMap: false, + cache: false, + terserOptions: { + ecma: es6 ? 6 : 5, + parse: {}, + module: true, + toplevel: true, + keep_classnames: false, + keep_fnames: false, + keep_fargs: false, + safari10: true, + compress: { + arguments: false, // breaks + drop_console: false, + global_defs: globalDefs, + keep_fargs: false, + keep_infinity: true, + passes: 2, + module: true, + pure_funcs: [ + "Math.round", + "Math.ceil", + "Math.floor", + "Math.sqrt", + "Math.hypot", + "Math.abs", + "Math.max", + "Math.min", + "Math.sin", + "Math.cos", + "Math.tan", + "Math.sign", + "Math.pow", + "Math.atan2", + + "Math_round", + "Math_ceil", + "Math_floor", + "Math_sqrt", + "Math_hypot", + "Math_abs", + "Math_max", + "Math_min", + "Math_sin", + "Math_cos", + "Math_tan", + "Math_sign", + "Math_pow", + "Math_atan2", + ], + toplevel: true, + unsafe_math: true, + unsafe_arrows: false, + warnings: true, + }, + mangle: { + eval: true, + keep_classnames: false, + keep_fnames: false, + module: true, + toplevel: true, + safari10: true, + }, + output: { + comments: false, + ascii_only: true, + beautify: false, + braces: false, + ecma: es6 ? 6 : 5, + preamble: + "/* Shapez.io Codebase - Copyright 2020 Tobias Springer - " + + utils.getVersion() + + " @ " + + utils.getRevision() + + " */", + }, + }, + }), + ], + }, + performance: { + maxEntrypointSize: 5120000, + maxAssetSize: 5120000, + }, + plugins: [ + new webpack.DefinePlugin(globalDefs), + + new UnusedFilesPlugin({ + failOnUnused: false, + cwd: path.join(__dirname, "..", "src", "js"), + patterns: ["../src/js/**/*.js"], + }), + + // new ReplaceCompressBlocks() + // new webpack.optimize.ModuleConcatenationPlugin() + // new WebpackDeepScopeAnalysisPlugin() + // new BundleAnalyzerPlugin() + ], + module: { + rules: [ + { + test: /\.json$/, + enforce: "pre", + use: ["./gulp/loader.compressjson"], + type: "javascript/auto", + }, + { test: /\.(png|jpe?g|svg)$/, loader: "ignore-loader" }, + { + test: /\.js$/, + enforce: "pre", + exclude: /node_modules/, + use: [ + { + loader: "webpack-strip-block", + options: { + start: "typehints:start", + end: "typehints:end", + }, + }, + { + loader: "webpack-strip-block", + options: { + start: "dev:start", + end: "dev:end", + }, + }, + ], + }, + { + test: /\.js$/, + use: [ + // "thread-loader", + { + loader: "babel-loader?cacheDirectory", + options: { + configFile: require.resolve( + es6 ? "./babel-es6.config.js" : "./babel.config.js" + ), + }, + }, + "uglify-template-string-loader", // Finally found this plugin + StringReplacePlugin.replace({ + replacements: [ + { pattern: /globalConfig\.tileSize/g, replacement: () => "32" }, + { pattern: /globalConfig\.halfTileSize/g, replacement: () => "16" }, + { + pattern: /globalConfig\.beltSpeedItemsPerSecond/g, + replacement: () => "1.0", + }, + { pattern: /globalConfig\.itemSpacingOnBelts/g, replacement: () => "0.8" }, + { pattern: /globalConfig\.debug/g, replacement: () => "''" }, + ], + }), + ], + }, + { + test: /\.worker\.js$/, + use: { + loader: "worker-loader", + options: { + fallback: false, + inline: true, + }, + }, + }, + { + test: /\.md$/, + use: ["html-loader", "markdown-loader"], + }, + ], + }, + }; +}; diff --git a/gulp/yarn.lock b/gulp/yarn.lock new file mode 100644 index 00000000..702d54b9 --- /dev/null +++ b/gulp/yarn.lock @@ -0,0 +1,14195 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.5.5.tgz#bc0782f6d69f7b7d49531219699b988f669a8f9d" + integrity sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw== + dependencies: + "@babel/highlight" "^7.0.0" + +"@babel/code-frame@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e" + integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g== + dependencies: + "@babel/highlight" "^7.8.3" + +"@babel/core@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.9.0.tgz#ac977b538b77e132ff706f3b8a4dbad09c03c56e" + integrity sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/generator" "^7.9.0" + "@babel/helper-module-transforms" "^7.9.0" + "@babel/helpers" "^7.9.0" + "@babel/parser" "^7.9.0" + "@babel/template" "^7.8.6" + "@babel/traverse" "^7.9.0" + "@babel/types" "^7.9.0" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.1" + json5 "^2.1.2" + lodash "^4.17.13" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" + +"@babel/generator@^7.6.0": + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.6.0.tgz#e2c21efbfd3293ad819a2359b448f002bfdfda56" + integrity sha512-Ms8Mo7YBdMMn1BYuNtKuP/z0TgEIhbcyB8HVR6PPNYp4P61lMsABiS4A3VG1qznjXVCf3r+fVHhm4efTYVsySA== + dependencies: + "@babel/types" "^7.6.0" + jsesc "^2.5.1" + lodash "^4.17.13" + source-map "^0.5.0" + trim-right "^1.0.1" + +"@babel/generator@^7.9.0", "@babel/generator@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.9.5.tgz#27f0917741acc41e6eaaced6d68f96c3fa9afaf9" + integrity sha512-GbNIxVB3ZJe3tLeDm1HSn2AhuD/mVcyLDpgtLXa5tplmWrJdF/elxB56XNqCuD6szyNkDi6wuoKXln3QeBmCHQ== + dependencies: + "@babel/types" "^7.9.5" + jsesc "^2.5.1" + lodash "^4.17.13" + source-map "^0.5.0" + +"@babel/helper-annotate-as-pure@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32" + integrity sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz#6b69628dfe4087798e0c4ed98e3d4a6b2fbd2f5f" + integrity sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w== + dependencies: + "@babel/helper-explode-assignable-expression" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-call-delegate@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.4.4.tgz#87c1f8ca19ad552a736a7a27b1c1fcf8b1ff1f43" + integrity sha512-l79boDFJ8S1c5hvQvG+rc+wHw6IuH7YldmRKsYtpbawsxURu/paVy57FZMomGK22/JckepaikOkY0MoAmdyOlQ== + dependencies: + "@babel/helper-hoist-variables" "^7.4.4" + "@babel/traverse" "^7.4.4" + "@babel/types" "^7.4.4" + +"@babel/helper-define-map@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.5.5.tgz#3dec32c2046f37e09b28c93eb0b103fd2a25d369" + integrity sha512-fTfxx7i0B5NJqvUOBBGREnrqbTxRh7zinBANpZXAVDlsZxYdclDp467G1sQ8VZYMnAURY3RpBUAgOYT9GfzHBg== + dependencies: + "@babel/helper-function-name" "^7.1.0" + "@babel/types" "^7.5.5" + lodash "^4.17.13" + +"@babel/helper-explode-assignable-expression@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz#537fa13f6f1674df745b0c00ec8fe4e99681c8f6" + integrity sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA== + dependencies: + "@babel/traverse" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-function-name@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz#a0ceb01685f73355d4360c1247f582bfafc8ff53" + integrity sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw== + dependencies: + "@babel/helper-get-function-arity" "^7.0.0" + "@babel/template" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-function-name@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz#2b53820d35275120e1874a82e5aabe1376920a5c" + integrity sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw== + dependencies: + "@babel/helper-get-function-arity" "^7.8.3" + "@babel/template" "^7.8.3" + "@babel/types" "^7.9.5" + +"@babel/helper-get-function-arity@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz#83572d4320e2a4657263734113c42868b64e49c3" + integrity sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-get-function-arity@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz#b894b947bd004381ce63ea1db9f08547e920abd5" + integrity sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-hoist-variables@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.4.tgz#0298b5f25c8c09c53102d52ac4a98f773eb2850a" + integrity sha512-VYk2/H/BnYbZDDg39hr3t2kKyifAm1W6zHRfhx8jGjIHpQEBv9dry7oQ2f3+J703TLu69nYdxsovl0XYfcnK4w== + dependencies: + "@babel/types" "^7.4.4" + +"@babel/helper-member-expression-to-functions@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.5.5.tgz#1fb5b8ec4453a93c439ee9fe3aeea4a84b76b590" + integrity sha512-5qZ3D1uMclSNqYcXqiHoA0meVdv+xUEex9em2fqMnrk/scphGlGgg66zjMrPJESPwrFJ6sbfFQYUSa0Mz7FabA== + dependencies: + "@babel/types" "^7.5.5" + +"@babel/helper-member-expression-to-functions@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz#659b710498ea6c1d9907e0c73f206eee7dadc24c" + integrity sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-module-imports@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz#96081b7111e486da4d2cd971ad1a4fe216cc2e3d" + integrity sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-module-imports@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz#7fe39589b39c016331b6b8c3f441e8f0b1419498" + integrity sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-module-transforms@^7.1.0", "@babel/helper-module-transforms@^7.4.4": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.5.5.tgz#f84ff8a09038dcbca1fd4355661a500937165b4a" + integrity sha512-jBeCvETKuJqeiaCdyaheF40aXnnU1+wkSiUs/IQg3tB85up1LyL8x77ClY8qJpuRJUcXQo+ZtdNESmZl4j56Pw== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/helper-simple-access" "^7.1.0" + "@babel/helper-split-export-declaration" "^7.4.4" + "@babel/template" "^7.4.4" + "@babel/types" "^7.5.5" + lodash "^4.17.13" + +"@babel/helper-module-transforms@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz#43b34dfe15961918707d247327431388e9fe96e5" + integrity sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA== + dependencies: + "@babel/helper-module-imports" "^7.8.3" + "@babel/helper-replace-supers" "^7.8.6" + "@babel/helper-simple-access" "^7.8.3" + "@babel/helper-split-export-declaration" "^7.8.3" + "@babel/template" "^7.8.6" + "@babel/types" "^7.9.0" + lodash "^4.17.13" + +"@babel/helper-optimise-call-expression@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz#a2920c5702b073c15de51106200aa8cad20497d5" + integrity sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-optimise-call-expression@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz#7ed071813d09c75298ef4f208956006b6111ecb9" + integrity sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-plugin-utils@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz#bbb3fbee98661c569034237cc03967ba99b4f250" + integrity sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA== + +"@babel/helper-regex@^7.0.0", "@babel/helper-regex@^7.4.4": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.5.5.tgz#0aa6824f7100a2e0e89c1527c23936c152cab351" + integrity sha512-CkCYQLkfkiugbRDO8eZn6lRuR8kzZoGXCg3149iTk5se7g6qykSpy3+hELSwquhu+TgHn8nkLiBwHvNX8Hofcw== + dependencies: + lodash "^4.17.13" + +"@babel/helper-remap-async-to-generator@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz#361d80821b6f38da75bd3f0785ece20a88c5fe7f" + integrity sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.0.0" + "@babel/helper-wrap-function" "^7.1.0" + "@babel/template" "^7.1.0" + "@babel/traverse" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-replace-supers@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.5.5.tgz#f84ce43df031222d2bad068d2626cb5799c34bc2" + integrity sha512-XvRFWrNnlsow2u7jXDuH4jDDctkxbS7gXssrP4q2nUD606ukXHRvydj346wmNg+zAgpFx4MWf4+usfC93bElJg== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.5.5" + "@babel/helper-optimise-call-expression" "^7.0.0" + "@babel/traverse" "^7.5.5" + "@babel/types" "^7.5.5" + +"@babel/helper-replace-supers@^7.8.6": + version "7.8.6" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.8.6.tgz#5ada744fd5ad73203bf1d67459a27dcba67effc8" + integrity sha512-PeMArdA4Sv/Wf4zXwBKPqVj7n9UF/xg6slNRtZW84FM7JpE1CbG8B612FyM4cxrf4fMAMGO0kR7voy1ForHHFA== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.8.3" + "@babel/helper-optimise-call-expression" "^7.8.3" + "@babel/traverse" "^7.8.6" + "@babel/types" "^7.8.6" + +"@babel/helper-simple-access@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz#65eeb954c8c245beaa4e859da6188f39d71e585c" + integrity sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w== + dependencies: + "@babel/template" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-simple-access@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz#7f8109928b4dab4654076986af575231deb639ae" + integrity sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw== + dependencies: + "@babel/template" "^7.8.3" + "@babel/types" "^7.8.3" + +"@babel/helper-split-export-declaration@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz#ff94894a340be78f53f06af038b205c49d993677" + integrity sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q== + dependencies: + "@babel/types" "^7.4.4" + +"@babel/helper-split-export-declaration@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz#31a9f30070f91368a7182cf05f831781065fc7a9" + integrity sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-validator-identifier@^7.9.0", "@babel/helper-validator-identifier@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz#90977a8e6fbf6b431a7dc31752eee233bf052d80" + integrity sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g== + +"@babel/helper-wrap-function@^7.1.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz#c4e0012445769e2815b55296ead43a958549f6fa" + integrity sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ== + dependencies: + "@babel/helper-function-name" "^7.1.0" + "@babel/template" "^7.1.0" + "@babel/traverse" "^7.1.0" + "@babel/types" "^7.2.0" + +"@babel/helpers@^7.9.0": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.9.2.tgz#b42a81a811f1e7313b88cba8adc66b3d9ae6c09f" + integrity sha512-JwLvzlXVPjO8eU9c/wF9/zOIN7X6h8DYf7mG4CiFRZRvZNKEF5dQ3H3V+ASkHoIB3mWhatgl5ONhyqHRI6MppA== + dependencies: + "@babel/template" "^7.8.3" + "@babel/traverse" "^7.9.0" + "@babel/types" "^7.9.0" + +"@babel/highlight@^7.0.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.5.0.tgz#56d11312bd9248fa619591d02472be6e8cb32540" + integrity sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ== + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^4.0.0" + +"@babel/highlight@^7.8.3": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.9.0.tgz#4e9b45ccb82b79607271b2979ad82c7b68163079" + integrity sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ== + dependencies: + "@babel/helper-validator-identifier" "^7.9.0" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.6.0": + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.6.0.tgz#3e05d0647432a8326cb28d0de03895ae5a57f39b" + integrity sha512-+o2q111WEx4srBs7L9eJmcwi655eD8sXniLqMB93TBK9GrNzGrxDWSjiqz2hLU0Ha8MTXFIP0yd9fNdP+m43ZQ== + +"@babel/parser@^7.8.6", "@babel/parser@^7.9.0": + version "7.9.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.9.4.tgz#68a35e6b0319bbc014465be43828300113f2f2e8" + integrity sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA== + +"@babel/plugin-proposal-async-generator-functions@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz#b289b306669dce4ad20b0252889a15768c9d417e" + integrity sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-remap-async-to-generator" "^7.1.0" + "@babel/plugin-syntax-async-generators" "^7.2.0" + +"@babel/plugin-proposal-dynamic-import@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.5.0.tgz#e532202db4838723691b10a67b8ce509e397c506" + integrity sha512-x/iMjggsKTFHYC6g11PL7Qy58IK8H5zqfm9e6hu4z1iH2IRyAp9u9dL80zA6R76yFovETFLKz2VJIC2iIPBuFw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-dynamic-import" "^7.2.0" + +"@babel/plugin-proposal-json-strings@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz#568ecc446c6148ae6b267f02551130891e29f317" + integrity sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-json-strings" "^7.2.0" + +"@babel/plugin-proposal-object-rest-spread@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.5.tgz#61939744f71ba76a3ae46b5eea18a54c16d22e58" + integrity sha512-F2DxJJSQ7f64FyTVl5cw/9MWn6naXGdk3Q3UhDbFEEHv+EilCPoeRD3Zh/Utx1CJz4uyKlQ4uH+bJPbEhMV7Zw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-object-rest-spread" "^7.2.0" + +"@babel/plugin-proposal-optional-catch-binding@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz#135d81edb68a081e55e56ec48541ece8065c38f5" + integrity sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" + +"@babel/plugin-proposal-unicode-property-regex@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.4.tgz#501ffd9826c0b91da22690720722ac7cb1ca9c78" + integrity sha512-j1NwnOqMG9mFUOH58JTFsA/+ZYzQLUZ/drqWUqxCYLGeu2JFZL8YrNC9hBxKmWtAuOCHPcRpgv7fhap09Fb4kA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.4.4" + regexpu-core "^4.5.4" + +"@babel/plugin-syntax-async-generators@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz#69e1f0db34c6f5a0cf7e2b3323bf159a76c8cb7f" + integrity sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-dynamic-import@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz#69c159ffaf4998122161ad8ebc5e6d1f55df8612" + integrity sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-json-strings@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz#72bd13f6ffe1d25938129d2a186b11fd62951470" + integrity sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-object-rest-spread@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz#3b7a3e733510c57e820b9142a6579ac8b0dfad2e" + integrity sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz#a94013d6eda8908dfe6a477e7f9eda85656ecf5c" + integrity sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-arrow-functions@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz#9aeafbe4d6ffc6563bf8f8372091628f00779550" + integrity sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-async-to-generator@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.5.0.tgz#89a3848a0166623b5bc481164b5936ab947e887e" + integrity sha512-mqvkzwIGkq0bEF1zLRRiTdjfomZJDV33AH3oQzHVGkI2VzEmXLpKKOBvEVaFZBJdN0XTyH38s9j/Kiqr68dggg== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-remap-async-to-generator" "^7.1.0" + +"@babel/plugin-transform-block-scoped-functions@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz#5d3cc11e8d5ddd752aa64c9148d0db6cb79fd190" + integrity sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-block-scoping@^7.4.4", "@babel/plugin-transform-block-scoping@^7.6.0": + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.0.tgz#c49e21228c4bbd4068a35667e6d951c75439b1dc" + integrity sha512-tIt4E23+kw6TgL/edACZwP1OUKrjOTyMrFMLoT5IOFrfMRabCgekjqFd5o6PaAMildBu46oFkekIdMuGkkPEpA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + lodash "^4.17.13" + +"@babel/plugin-transform-classes@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.5.5.tgz#d094299d9bd680a14a2a0edae38305ad60fb4de9" + integrity sha512-U2htCNK/6e9K7jGyJ++1p5XRU+LJjrwtoiVn9SzRlDT2KubcZ11OOwy3s24TjHxPgxNwonCYP7U2K51uVYCMDg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.0.0" + "@babel/helper-define-map" "^7.5.5" + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-optimise-call-expression" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-replace-supers" "^7.5.5" + "@babel/helper-split-export-declaration" "^7.4.4" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz#83a7df6a658865b1c8f641d510c6f3af220216da" + integrity sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-destructuring@^7.6.0": + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.6.0.tgz#44bbe08b57f4480094d57d9ffbcd96d309075ba6" + integrity sha512-2bGIS5P1v4+sWTCnKNDZDxbGvEqi0ijeqM/YqHtVGrvG2y0ySgnEEhXErvE9dA0bnIzY9bIzdFK0jFA46ASIIQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-dotall-regex@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.4.tgz#361a148bc951444312c69446d76ed1ea8e4450c3" + integrity sha512-P05YEhRc2h53lZDjRPk/OektxCVevFzZs2Gfjd545Wde3k+yFDbXORgl2e0xpbq8mLcKJ7Idss4fAg0zORN/zg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.4.4" + regexpu-core "^4.5.4" + +"@babel/plugin-transform-duplicate-keys@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.5.0.tgz#c5dbf5106bf84cdf691222c0974c12b1df931853" + integrity sha512-igcziksHizyQPlX9gfSjHkE2wmoCH3evvD2qR5w29/Dk0SMKE/eOI7f1HhBdNhR/zxJDqrgpoDTq5YSLH/XMsQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-exponentiation-operator@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz#a63868289e5b4007f7054d46491af51435766008" + integrity sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.1.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-for-of@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.4.tgz#0267fc735e24c808ba173866c6c4d1440fc3c556" + integrity sha512-9T/5Dlr14Z9TIEXLXkt8T1DU7F24cbhwhMNUziN3hB1AXoZcdzPcTiKGRn/6iOymDqtTKWnr/BtRKN9JwbKtdQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-function-name@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.4.tgz#e1436116abb0610c2259094848754ac5230922ad" + integrity sha512-iU9pv7U+2jC9ANQkKeNF6DrPy4GBa4NWQtl6dHB4Pb3izX2JOEvDTFarlNsBj/63ZEzNNIAMs3Qw4fNCcSOXJA== + dependencies: + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-literals@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz#690353e81f9267dad4fd8cfd77eafa86aba53ea1" + integrity sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-member-expression-literals@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.2.0.tgz#fa10aa5c58a2cb6afcf2c9ffa8cb4d8b3d489a2d" + integrity sha512-HiU3zKkSU6scTidmnFJ0bMX8hz5ixC93b4MHMiYebmk2lUVNGOboPsqQvx5LzooihijUoLR/v7Nc1rbBtnc7FA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-modules-amd@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.5.0.tgz#ef00435d46da0a5961aa728a1d2ecff063e4fb91" + integrity sha512-n20UsQMKnWrltocZZm24cRURxQnWIvsABPJlw/fvoy9c6AgHZzoelAIzajDHAQrDpuKFFPPcFGd7ChsYuIUMpg== + dependencies: + "@babel/helper-module-transforms" "^7.1.0" + "@babel/helper-plugin-utils" "^7.0.0" + babel-plugin-dynamic-import-node "^2.3.0" + +"@babel/plugin-transform-modules-commonjs@^7.6.0": + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.6.0.tgz#39dfe957de4420445f1fcf88b68a2e4aa4515486" + integrity sha512-Ma93Ix95PNSEngqomy5LSBMAQvYKVe3dy+JlVJSHEXZR5ASL9lQBedMiCyVtmTLraIDVRE3ZjTZvmXXD2Ozw3g== + dependencies: + "@babel/helper-module-transforms" "^7.4.4" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-simple-access" "^7.1.0" + babel-plugin-dynamic-import-node "^2.3.0" + +"@babel/plugin-transform-modules-systemjs@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.5.0.tgz#e75266a13ef94202db2a0620977756f51d52d249" + integrity sha512-Q2m56tyoQWmuNGxEtUyeEkm6qJYFqs4c+XyXH5RAuYxObRNz9Zgj/1g2GMnjYp2EUyEy7YTrxliGCXzecl/vJg== + dependencies: + "@babel/helper-hoist-variables" "^7.4.4" + "@babel/helper-plugin-utils" "^7.0.0" + babel-plugin-dynamic-import-node "^2.3.0" + +"@babel/plugin-transform-modules-umd@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz#7678ce75169f0877b8eb2235538c074268dd01ae" + integrity sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw== + dependencies: + "@babel/helper-module-transforms" "^7.1.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-named-capturing-groups-regex@^7.6.0": + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.6.0.tgz#1e6e663097813bb4f53d42df0750cf28ad3bb3f1" + integrity sha512-jem7uytlmrRl3iCAuQyw8BpB4c4LWvSpvIeXKpMb+7j84lkx4m4mYr5ErAcmN5KM7B6BqrAvRGjBIbbzqCczew== + dependencies: + regexp-tree "^0.1.13" + +"@babel/plugin-transform-new-target@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz#18d120438b0cc9ee95a47f2c72bc9768fbed60a5" + integrity sha512-r1z3T2DNGQwwe2vPGZMBNjioT2scgWzK9BCnDEh+46z8EEwXBq24uRzd65I7pjtugzPSj921aM15RpESgzsSuA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-object-super@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.5.5.tgz#c70021df834073c65eb613b8679cc4a381d1a9f9" + integrity sha512-un1zJQAhSosGFBduPgN/YFNvWVpRuHKU7IHBglLoLZsGmruJPOo6pbInneflUdmq7YvSVqhpPs5zdBvLnteltQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-replace-supers" "^7.5.5" + +"@babel/plugin-transform-parameters@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz#7556cf03f318bd2719fe4c922d2d808be5571e16" + integrity sha512-oMh5DUO1V63nZcu/ZVLQFqiihBGo4OpxJxR1otF50GMeCLiRx5nUdtokd+u9SuVJrvvuIh9OosRFPP4pIPnwmw== + dependencies: + "@babel/helper-call-delegate" "^7.4.4" + "@babel/helper-get-function-arity" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-property-literals@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.2.0.tgz#03e33f653f5b25c4eb572c98b9485055b389e905" + integrity sha512-9q7Dbk4RhgcLp8ebduOpCbtjh7C0itoLYHXd9ueASKAG/is5PQtMR5VJGka9NKqGhYEGn5ITahd4h9QeBMylWQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-regenerator@^7.4.5": + version "7.4.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.5.tgz#629dc82512c55cee01341fb27bdfcb210354680f" + integrity sha512-gBKRh5qAaCWntnd09S8QC7r3auLCqq5DI6O0DlfoyDjslSBVqBibrMdsqO+Uhmx3+BlOmE/Kw1HFxmGbv0N9dA== + dependencies: + regenerator-transform "^0.14.0" + +"@babel/plugin-transform-reserved-words@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.2.0.tgz#4792af87c998a49367597d07fedf02636d2e1634" + integrity sha512-fz43fqW8E1tAB3DKF19/vxbpib1fuyCwSPE418ge5ZxILnBhWyhtPgz8eh1RCGGJlwvksHkyxMxh0eenFi+kFw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-shorthand-properties@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz#6333aee2f8d6ee7e28615457298934a3b46198f0" + integrity sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-spread@^7.2.0": + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz#3103a9abe22f742b6d406ecd3cd49b774919b406" + integrity sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-sticky-regex@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz#a1e454b5995560a9c1e0d537dfc15061fd2687e1" + integrity sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.0.0" + +"@babel/plugin-transform-template-literals@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz#9d28fea7bbce637fb7612a0750989d8321d4bcb0" + integrity sha512-mQrEC4TWkhLN0z8ygIvEL9ZEToPhG5K7KDW3pzGqOfIGZ28Jb0POUkeWcoz8HnHvhFy6dwAT1j8OzqN8s804+g== + dependencies: + "@babel/helper-annotate-as-pure" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-typeof-symbol@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz#117d2bcec2fbf64b4b59d1f9819894682d29f2b2" + integrity sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-unicode-regex@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.4.tgz#ab4634bb4f14d36728bf5978322b35587787970f" + integrity sha512-il+/XdNw01i93+M9J9u4T7/e/Ue/vWfNZE4IRUQjplu2Mqb/AFTDimkw2tdEdSH50wuQXZAbXSql0UphQke+vA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.4.4" + regexpu-core "^4.5.4" + +"@babel/preset-env@^7.5.4": + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.6.0.tgz#aae4141c506100bb2bfaa4ac2a5c12b395619e50" + integrity sha512-1efzxFv/TcPsNXlRhMzRnkBFMeIqBBgzwmZwlFDw5Ubj0AGLeufxugirwZmkkX/ayi3owsSqoQ4fw8LkfK9SYg== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-proposal-async-generator-functions" "^7.2.0" + "@babel/plugin-proposal-dynamic-import" "^7.5.0" + "@babel/plugin-proposal-json-strings" "^7.2.0" + "@babel/plugin-proposal-object-rest-spread" "^7.5.5" + "@babel/plugin-proposal-optional-catch-binding" "^7.2.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" + "@babel/plugin-syntax-async-generators" "^7.2.0" + "@babel/plugin-syntax-dynamic-import" "^7.2.0" + "@babel/plugin-syntax-json-strings" "^7.2.0" + "@babel/plugin-syntax-object-rest-spread" "^7.2.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" + "@babel/plugin-transform-arrow-functions" "^7.2.0" + "@babel/plugin-transform-async-to-generator" "^7.5.0" + "@babel/plugin-transform-block-scoped-functions" "^7.2.0" + "@babel/plugin-transform-block-scoping" "^7.6.0" + "@babel/plugin-transform-classes" "^7.5.5" + "@babel/plugin-transform-computed-properties" "^7.2.0" + "@babel/plugin-transform-destructuring" "^7.6.0" + "@babel/plugin-transform-dotall-regex" "^7.4.4" + "@babel/plugin-transform-duplicate-keys" "^7.5.0" + "@babel/plugin-transform-exponentiation-operator" "^7.2.0" + "@babel/plugin-transform-for-of" "^7.4.4" + "@babel/plugin-transform-function-name" "^7.4.4" + "@babel/plugin-transform-literals" "^7.2.0" + "@babel/plugin-transform-member-expression-literals" "^7.2.0" + "@babel/plugin-transform-modules-amd" "^7.5.0" + "@babel/plugin-transform-modules-commonjs" "^7.6.0" + "@babel/plugin-transform-modules-systemjs" "^7.5.0" + "@babel/plugin-transform-modules-umd" "^7.2.0" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.6.0" + "@babel/plugin-transform-new-target" "^7.4.4" + "@babel/plugin-transform-object-super" "^7.5.5" + "@babel/plugin-transform-parameters" "^7.4.4" + "@babel/plugin-transform-property-literals" "^7.2.0" + "@babel/plugin-transform-regenerator" "^7.4.5" + "@babel/plugin-transform-reserved-words" "^7.2.0" + "@babel/plugin-transform-shorthand-properties" "^7.2.0" + "@babel/plugin-transform-spread" "^7.2.0" + "@babel/plugin-transform-sticky-regex" "^7.2.0" + "@babel/plugin-transform-template-literals" "^7.4.4" + "@babel/plugin-transform-typeof-symbol" "^7.2.0" + "@babel/plugin-transform-unicode-regex" "^7.4.4" + "@babel/types" "^7.6.0" + browserslist "^4.6.0" + core-js-compat "^3.1.1" + invariant "^2.2.2" + js-levenshtein "^1.1.3" + semver "^5.5.0" + +"@babel/runtime@7.0.0-beta.42": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.0.0-beta.42.tgz#352e40c92e0460d3e82f49bd7e79f6cda76f919f" + integrity sha512-iOGRzUoONLOtmCvjUsZv3mZzgCT6ljHQY5fr1qG1QIiJQwtM7zbPWGGpa3QWETq+UqwWyJnoi5XZDZRwZDFciQ== + dependencies: + core-js "^2.5.3" + regenerator-runtime "^0.11.1" + +"@babel/runtime@7.0.0-rc.1": + version "7.0.0-rc.1" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.0.0-rc.1.tgz#42f36fc5817911c89ea75da2b874054922967616" + integrity sha512-Nifv2kwP/nwR39cAOasNxzjYfpeuf/ZbZNtQz5eYxWTC9yHARU9wItFnAwz1GTZ62MU+AtSjzZPMbLK5Q9hmbg== + dependencies: + regenerator-runtime "^0.12.0" + +"@babel/runtime@^7.5.5": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.2.tgz#d90df0583a3a252f09aaa619665367bae518db06" + integrity sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/template@^7.1.0", "@babel/template@^7.4.4": + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.6.0.tgz#7f0159c7f5012230dad64cca42ec9bdb5c9536e6" + integrity sha512-5AEH2EXD8euCk446b7edmgFdub/qfH1SN6Nii3+fyXP807QRx9Q73A2N5hNwRRslC2H9sNzaFhsPubkS4L8oNQ== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.6.0" + "@babel/types" "^7.6.0" + +"@babel/template@^7.8.3", "@babel/template@^7.8.6": + version "7.8.6" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.6.tgz#86b22af15f828dfb086474f964dcc3e39c43ce2b" + integrity sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/parser" "^7.8.6" + "@babel/types" "^7.8.6" + +"@babel/traverse@^7.1.0", "@babel/traverse@^7.4.4", "@babel/traverse@^7.5.5": + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.6.0.tgz#389391d510f79be7ce2ddd6717be66d3fed4b516" + integrity sha512-93t52SaOBgml/xY74lsmt7xOR4ufYvhb5c5qiM6lu4J/dWGMAfAh6eKw4PjLes6DI6nQgearoxnFJk60YchpvQ== + dependencies: + "@babel/code-frame" "^7.5.5" + "@babel/generator" "^7.6.0" + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-split-export-declaration" "^7.4.4" + "@babel/parser" "^7.6.0" + "@babel/types" "^7.6.0" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.13" + +"@babel/traverse@^7.8.6", "@babel/traverse@^7.9.0": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.9.5.tgz#6e7c56b44e2ac7011a948c21e283ddd9d9db97a2" + integrity sha512-c4gH3jsvSuGUezlP6rzSJ6jf8fYjLj3hsMZRx/nX0h+fmHN0w+ekubRrHPqnMec0meycA2nwCsJ7dC8IPem2FQ== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/generator" "^7.9.5" + "@babel/helper-function-name" "^7.9.5" + "@babel/helper-split-export-declaration" "^7.8.3" + "@babel/parser" "^7.9.0" + "@babel/types" "^7.9.5" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.13" + +"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5", "@babel/types@^7.6.0": + version "7.6.1" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.6.1.tgz#53abf3308add3ac2a2884d539151c57c4b3ac648" + integrity sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g== + dependencies: + esutils "^2.0.2" + lodash "^4.17.13" + to-fast-properties "^2.0.0" + +"@babel/types@^7.8.3", "@babel/types@^7.8.6", "@babel/types@^7.9.0", "@babel/types@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.9.5.tgz#89231f82915a8a566a703b3b20133f73da6b9444" + integrity sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg== + dependencies: + "@babel/helper-validator-identifier" "^7.9.5" + lodash "^4.17.13" + to-fast-properties "^2.0.0" + +"@csstools/convert-colors@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-1.4.0.tgz#ad495dc41b12e75d588c6db8b9834f08fa131eb7" + integrity sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw== + +"@electron/get@^1.3.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@electron/get/-/get-1.5.0.tgz#6217d9d18fb71fbd8cd2445a31aa0edc723d19dd" + integrity sha512-tafxBz6n08G6SX961F/h8XFtpB/DdwRvJJoDeOH9x78jDSCMQ2G/rRWqSwLFp9oeMFBJf0Pf5Kkw6TKt5w9TWg== + dependencies: + debug "^4.1.1" + env-paths "^2.2.0" + fs-extra "^8.1.0" + got "^9.6.0" + sanitize-filename "^1.6.2" + sumchecker "^3.0.0" + +"@jimp/bmp@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/bmp/-/bmp-0.6.8.tgz#8abbfd9e26ba17a47fab311059ea9f7dd82005b6" + integrity sha512-uxVgSkI62uAzk5ZazYHEHBehow590WAkLKmDXLzkr/XP/Hv2Fx1T4DKwJ/15IY5ktq5VAhAUWGXTyd8KWFsx7w== + dependencies: + "@jimp/utils" "^0.6.8" + bmp-js "^0.1.0" + core-js "^2.5.7" + +"@jimp/core@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/core/-/core-0.6.8.tgz#6a41089792516f6e64a5302d12eb562aa7847c7b" + integrity sha512-JOFqBBcSNiDiMZJFr6OJqC6viXj5NVBQISua0eacoYvo4YJtTajOIxC4MqWyUmGrDpRMZBR8QhSsIOwsFrdROA== + dependencies: + "@jimp/utils" "^0.6.8" + any-base "^1.1.0" + buffer "^5.2.0" + core-js "^2.5.7" + exif-parser "^0.1.12" + file-type "^9.0.0" + load-bmfont "^1.3.1" + mkdirp "0.5.1" + phin "^2.9.1" + pixelmatch "^4.0.2" + tinycolor2 "^1.4.1" + +"@jimp/custom@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/custom/-/custom-0.6.8.tgz#0476d7b3f5da3121d98895a2e14f2899e602f2b6" + integrity sha512-FrYlzZRVXP2vuVwd7Nc2dlK+iZk4g6IaT1Ib8Z6vU5Kkwlt83FJIPJ2UUFABf3bF5big0wkk8ZUihWxE4Nzdng== + dependencies: + "@jimp/core" "^0.6.8" + core-js "^2.5.7" + +"@jimp/gif@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/gif/-/gif-0.6.8.tgz#848dd4e6e1a56ca2b3ce528969e44dfa99a53b14" + integrity sha512-yyOlujjQcgz9zkjM5ihZDEppn9d1brJ7jQHP5rAKmqep0G7FU1D0AKcV+Ql18RhuI/CgWs10wAVcrQpmLnu4Yw== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + omggif "^1.0.9" + +"@jimp/jpeg@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/jpeg/-/jpeg-0.6.8.tgz#4cad85a6d1e15759acb56bddef29aa3473859f2c" + integrity sha512-rGtXbYpFXAn471qLpTGvhbBMNHJo5KiufN+vC5AWyufntmkt5f0Ox2Cx4ijuBMDtirZchxbMLtrfGjznS4L/ew== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + jpeg-js "^0.3.4" + +"@jimp/plugin-blit@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-blit/-/plugin-blit-0.6.8.tgz#646ebb631f35afc28c1e8908524bc43d1e9afa3d" + integrity sha512-7Tl6YpKTSpvwQbnGNhsfX2zyl3jRVVopd276Y2hF2zpDz9Bycow7NdfNU/4Nx1jaf96X6uWOtSVINcQ7rGd47w== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + +"@jimp/plugin-blur@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-blur/-/plugin-blur-0.6.8.tgz#7b753ae94f6099103f57c268c3b2679047eefe95" + integrity sha512-NpZCMKxXHLDQsX9zPlWtpMA660DQStY6/z8ZetyxCDbqrLe9YCXpeR4MNhdJdABIiwTm1W5FyFF4kp81PHJx3Q== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + +"@jimp/plugin-color@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-color/-/plugin-color-0.6.8.tgz#4101cb1208879b331db6e43ea6b96eaf8dbaedbc" + integrity sha512-jjFyU0zNmGOH2rjzHuOMU4kaia0oo82s/7UYfn5h7OUkmUZTd6Do3ZSK1PiXA7KR+s4B76/Omm6Doh/0SGb7BQ== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + tinycolor2 "^1.4.1" + +"@jimp/plugin-contain@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-contain/-/plugin-contain-0.6.8.tgz#af95d33b63d0478943374ae15dd2607fc69cad14" + integrity sha512-p/P2wCXhAzbmEgXvGsvmxLmbz45feF6VpR4m9suPSOr8PC/i/XvTklTqYEUidYYAft4vHgsYJdS74HKSMnH8lw== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + +"@jimp/plugin-cover@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-cover/-/plugin-cover-0.6.8.tgz#490e3186627a34d93cc015c4169bac9070d6ad17" + integrity sha512-2PvWgk+PJfRsfWDI1G8Fpjrsu0ZlpNyZxO2+fqWlVo6y/y2gP4v08FqvbkcqSjNlOu2IDWIFXpgyU0sTINWZLg== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + +"@jimp/plugin-crop@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-crop/-/plugin-crop-0.6.8.tgz#ffec8951a2f3eccad1e3cff9afff5326bd980ce7" + integrity sha512-CbrcpWE2xxPK1n/JoTXzhRUhP4mO07mTWaSavenCg664oQl/9XCtL+A0FekuNHzIvn4myEqvkiTwN7FsbunS/Q== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + +"@jimp/plugin-displace@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-displace/-/plugin-displace-0.6.8.tgz#89df05ab7daaff6befc190bb8ac54ec8d57e533b" + integrity sha512-RmV2bPxoPE6mrPxtYSPtHxm2cGwBQr5a2p+9gH6SPy+eUMrbGjbvjwKNfXWUYD0leML+Pt5XOmAS9pIROmuruQ== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + +"@jimp/plugin-dither@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-dither/-/plugin-dither-0.6.8.tgz#17e5b9f56575a871e329fef8b388e614b92d84f8" + integrity sha512-x6V/qjxe+xypjpQm7GbiMNqci1EW5UizrcebOhHr8AHijOEqHd2hjXh5f6QIGfrkTFelc4/jzq1UyCsYntqz9Q== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + +"@jimp/plugin-flip@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-flip/-/plugin-flip-0.6.8.tgz#153df0c677f79d4078bb9e4c1f2ac392b96dc3a1" + integrity sha512-4il6Da6G39s9MyWBEee4jztEOUGJ40E6OlPjkMrdpDNvge6hYEAB31BczTYBP/CEY74j4LDSoY5LbcU4kv06yA== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + +"@jimp/plugin-gaussian@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-gaussian/-/plugin-gaussian-0.6.8.tgz#100abc7ae1f19fe9c09ed41625b475aae7c6093c" + integrity sha512-pVOblmjv7stZjsqloi4YzHVwAPXKGdNaHPhp4KP4vj41qtc6Hxd9z/+VWGYRTunMFac84gUToe0UKIXd6GhoKw== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + +"@jimp/plugin-invert@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-invert/-/plugin-invert-0.6.8.tgz#f40bfaa3b592d21ff14ede0e49aabec88048cad0" + integrity sha512-11zuLiXDHr6tFv4U8aieXqNXQEKbDbSBG/h+X62gGTNFpyn8EVPpncHhOqrAFtZUaPibBqMFlNJ15SzwC7ExsQ== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + +"@jimp/plugin-mask@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-mask/-/plugin-mask-0.6.8.tgz#e64405f7dacf0672bff74f3b95b724d9ac517f86" + integrity sha512-hZJ0OiKGJyv7hDSATwJDkunB1Ie80xJnONMgpUuUseteK45YeYNBOiZVUe8vum8QI1UwavgBzcvQ9u4fcgXc9g== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + +"@jimp/plugin-normalize@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-normalize/-/plugin-normalize-0.6.8.tgz#a0180f2b8835e3638cdc5e057b44ac63f60db6ba" + integrity sha512-Q4oYhU+sSyTJI7pMZlg9/mYh68ujLfOxXzQGEXuw0sHGoGQs3B0Jw7jmzGa6pIS06Hup5hD2Zuh1ppvMdjJBfQ== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + +"@jimp/plugin-print@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-print/-/plugin-print-0.6.8.tgz#66309549e01896473111e3a0ad2cee428638bd6e" + integrity sha512-2aokejGn4Drv1FesnZGqh5KEq0FQtR0drlmtyZrBH+r9cx7hh0Qgf4D1BOTDEgXkfSSngjGRjKKRW/fwOrVXYw== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + load-bmfont "^1.4.0" + +"@jimp/plugin-resize@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-resize/-/plugin-resize-0.6.8.tgz#c26d9a973f7eec51ad9018fcbbac1146f7a73aa0" + integrity sha512-27nPh8L1YWsxtfmV/+Ub5dOTpXyC0HMF2cu52RQSCYxr+Lm1+23dJF70AF1poUbUe+FWXphwuUxQzjBJza9UoA== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + +"@jimp/plugin-rotate@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-rotate/-/plugin-rotate-0.6.8.tgz#2afda247984eeebed95c1bb1b13ccd3be5973299" + integrity sha512-GbjETvL05BDoLdszNUV4Y0yLkHf177MnqGqilA113LIvx9aD0FtUopGXYfRGVvmtTOTouoaGJUc+K6qngvKxww== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + +"@jimp/plugin-scale@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-scale/-/plugin-scale-0.6.8.tgz#5de403345859bb0b30bf3e242dedd8ceb6ecb96c" + integrity sha512-GzIYWR/oCUK2jAwku23zt19V1ssaEU4pL0x2XsLNKuuJEU6DvEytJyTMXCE7OLG/MpDBQcQclJKHgiyQm5gIOQ== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + +"@jimp/plugins@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugins/-/plugins-0.6.8.tgz#5618170a986ced1ea795adcd9376122f2543b856" + integrity sha512-fMcTI72Vn/Lz6JftezTURmyP5ml/xGMe0Ljx2KRJ85IWyP33vDmGIUuutFiBEbh2+y7lRT+aTSmjs0QGa/xTmQ== + dependencies: + "@jimp/plugin-blit" "^0.6.8" + "@jimp/plugin-blur" "^0.6.8" + "@jimp/plugin-color" "^0.6.8" + "@jimp/plugin-contain" "^0.6.8" + "@jimp/plugin-cover" "^0.6.8" + "@jimp/plugin-crop" "^0.6.8" + "@jimp/plugin-displace" "^0.6.8" + "@jimp/plugin-dither" "^0.6.8" + "@jimp/plugin-flip" "^0.6.8" + "@jimp/plugin-gaussian" "^0.6.8" + "@jimp/plugin-invert" "^0.6.8" + "@jimp/plugin-mask" "^0.6.8" + "@jimp/plugin-normalize" "^0.6.8" + "@jimp/plugin-print" "^0.6.8" + "@jimp/plugin-resize" "^0.6.8" + "@jimp/plugin-rotate" "^0.6.8" + "@jimp/plugin-scale" "^0.6.8" + core-js "^2.5.7" + timm "^1.6.1" + +"@jimp/png@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/png/-/png-0.6.8.tgz#ee06cf078b381137ec7206c4bb1b4cfcbe15ca6f" + integrity sha512-JHHg/BZ7KDtHQrcG+a7fztw45rdf7okL/YwkN4qU5FH7Fcrp41nX5QnRviDtD9hN+GaNC7kvjvcqRAxW25qjew== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + pngjs "^3.3.3" + +"@jimp/tiff@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/tiff/-/tiff-0.6.8.tgz#79bd22ed435edbe29d02a2c8c9bf829f988ebacc" + integrity sha512-iWHbxd+0IKWdJyJ0HhoJCGYmtjPBOusz1z1HT/DnpePs/Lo3TO4d9ALXqYfUkyG74ZK5jULZ69KLtwuhuJz1bg== + dependencies: + core-js "^2.5.7" + utif "^2.0.1" + +"@jimp/types@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/types/-/types-0.6.8.tgz#4510eb635cd00b201745d70e38f791748baa7075" + integrity sha512-vCZ/Cp2osy69VP21XOBACfHI5HeR60Rfd4Jidj4W73UL+HrFWOtyQiJ7hlToyu1vI5mR/NsUQpzyQvz56ADm5A== + dependencies: + "@jimp/bmp" "^0.6.8" + "@jimp/gif" "^0.6.8" + "@jimp/jpeg" "^0.6.8" + "@jimp/png" "^0.6.8" + "@jimp/tiff" "^0.6.8" + core-js "^2.5.7" + timm "^1.6.1" + +"@jimp/utils@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/utils/-/utils-0.6.8.tgz#09f794945631173567aa50f72ac28170de58a63d" + integrity sha512-7RDfxQ2C/rarNG9iso5vmnKQbcvlQjBIlF/p7/uYj72WeZgVCB+5t1fFBKJSU4WhniHX4jUMijK+wYGE3Y3bGw== + dependencies: + core-js "^2.5.7" + +"@mrmlnc/readdir-enhanced@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" + integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== + dependencies: + call-me-maybe "^1.0.1" + glob-to-regexp "^0.3.0" + +"@nodelib/fs.stat@^1.1.2": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" + integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== + +"@sindresorhus/is@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" + integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== + +"@sindresorhus/is@^0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" + integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow== + +"@szmarczak/http-timer@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" + integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== + dependencies: + defer-to-connect "^1.0.1" + +"@types/cordova@^0.0.34": + version "0.0.34" + resolved "https://registry.yarnpkg.com/@types/cordova/-/cordova-0.0.34.tgz#ea7addf74ecec3d7629827a0c39e2c9addc73d04" + integrity sha1-6nrd907Ow9dimCegw54smt3HPQQ= + +"@types/filesystem@^0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/filesystem/-/filesystem-0.0.29.tgz#ee3748eb5be140dcf980c3bd35f11aec5f7a3748" + integrity sha512-85/1KfRedmfPGsbK8YzeaQUyV1FQAvMPMTuWFQ5EkLd2w7szhNO96bk3Rh/SKmOfd9co2rCLf0Voy4o7ECBOvw== + dependencies: + "@types/filewriter" "*" + +"@types/filewriter@*": + version "0.0.28" + resolved "https://registry.yarnpkg.com/@types/filewriter/-/filewriter-0.0.28.tgz#c054e8af4d9dd75db4e63abc76f885168714d4b3" + integrity sha1-wFTor02d11205jq8dviFFocU1LM= + +"@types/node@^12.7.5": + version "12.7.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.5.tgz#e19436e7f8e9b4601005d73673b6dc4784ffcc2f" + integrity sha512-9fq4jZVhPNW8r+UYKnxF1e2HkDWOWKM5bC2/7c9wPV835I0aOrVbS/Hw/pWPk2uKrNXQqg9Z959Kz+IYDd5p3w== + +"@types/q@^1.5.1": + version "1.5.2" + resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" + integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw== + +"@webassemblyjs/ast@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" + integrity sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ== + dependencies: + "@webassemblyjs/helper-module-context" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/wast-parser" "1.8.5" + +"@webassemblyjs/floating-point-hex-parser@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz#1ba926a2923613edce496fd5b02e8ce8a5f49721" + integrity sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ== + +"@webassemblyjs/helper-api-error@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz#c49dad22f645227c5edb610bdb9697f1aab721f7" + integrity sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA== + +"@webassemblyjs/helper-buffer@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz#fea93e429863dd5e4338555f42292385a653f204" + integrity sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q== + +"@webassemblyjs/helper-code-frame@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz#9a740ff48e3faa3022b1dff54423df9aa293c25e" + integrity sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ== + dependencies: + "@webassemblyjs/wast-printer" "1.8.5" + +"@webassemblyjs/helper-fsm@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz#ba0b7d3b3f7e4733da6059c9332275d860702452" + integrity sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow== + +"@webassemblyjs/helper-module-context@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz#def4b9927b0101dc8cbbd8d1edb5b7b9c82eb245" + integrity sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g== + dependencies: + "@webassemblyjs/ast" "1.8.5" + mamacro "^0.0.3" + +"@webassemblyjs/helper-wasm-bytecode@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz#537a750eddf5c1e932f3744206551c91c1b93e61" + integrity sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ== + +"@webassemblyjs/helper-wasm-section@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz#74ca6a6bcbe19e50a3b6b462847e69503e6bfcbf" + integrity sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-buffer" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/wasm-gen" "1.8.5" + +"@webassemblyjs/ieee754@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz#712329dbef240f36bf57bd2f7b8fb9bf4154421e" + integrity sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.8.5.tgz#044edeb34ea679f3e04cd4fd9824d5e35767ae10" + integrity sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.8.5.tgz#a8bf3b5d8ffe986c7c1e373ccbdc2a0915f0cedc" + integrity sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw== + +"@webassemblyjs/wasm-edit@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz#962da12aa5acc1c131c81c4232991c82ce56e01a" + integrity sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-buffer" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/helper-wasm-section" "1.8.5" + "@webassemblyjs/wasm-gen" "1.8.5" + "@webassemblyjs/wasm-opt" "1.8.5" + "@webassemblyjs/wasm-parser" "1.8.5" + "@webassemblyjs/wast-printer" "1.8.5" + +"@webassemblyjs/wasm-gen@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz#54840766c2c1002eb64ed1abe720aded714f98bc" + integrity sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/ieee754" "1.8.5" + "@webassemblyjs/leb128" "1.8.5" + "@webassemblyjs/utf8" "1.8.5" + +"@webassemblyjs/wasm-opt@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz#b24d9f6ba50394af1349f510afa8ffcb8a63d264" + integrity sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-buffer" "1.8.5" + "@webassemblyjs/wasm-gen" "1.8.5" + "@webassemblyjs/wasm-parser" "1.8.5" + +"@webassemblyjs/wasm-parser@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz#21576f0ec88b91427357b8536383668ef7c66b8d" + integrity sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-api-error" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/ieee754" "1.8.5" + "@webassemblyjs/leb128" "1.8.5" + "@webassemblyjs/utf8" "1.8.5" + +"@webassemblyjs/wast-parser@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz#e10eecd542d0e7bd394f6827c49f3df6d4eefb8c" + integrity sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/floating-point-hex-parser" "1.8.5" + "@webassemblyjs/helper-api-error" "1.8.5" + "@webassemblyjs/helper-code-frame" "1.8.5" + "@webassemblyjs/helper-fsm" "1.8.5" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/wast-printer@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz#114bbc481fd10ca0e23b3560fa812748b0bae5bc" + integrity sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/wast-parser" "1.8.5" + "@xtuc/long" "4.2.2" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +abab@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.1.tgz#3fa17797032b71410ec372e11668f4b4ffc86a82" + integrity sha512-1zSbbCuoIjafKZ3mblY5ikvAb0ODUbqBnFuUb7f6uLeQhhGJ0vEV4ntmtxKLT2WgXCO94E07BjunsIw1jOMPZw== + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +accepts@~1.3.4, accepts@~1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + dependencies: + mime-types "~2.1.24" + negotiator "0.6.2" + +acorn-globals@^4.3.0: + version "4.3.4" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7" + integrity sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A== + dependencies: + acorn "^6.0.1" + acorn-walk "^6.0.1" + +acorn-jsx@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" + integrity sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s= + dependencies: + acorn "^3.0.4" + +acorn-jsx@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-4.1.1.tgz#e8e41e48ea2fe0c896740610ab6a4ffd8add225e" + integrity sha512-JY+iV6r+cO21KtntVvFkD+iqjtdpRUpGqKWgfkCdZq1R+kbreEl8EcdcJR4SmiIgsIQT33s6QzheQ9a275Q8xw== + dependencies: + acorn "^5.0.3" + +acorn-jsx@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.2.tgz#84b68ea44b373c4f8686023a551f61a21b7c4a4f" + integrity sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw== + +acorn-walk@^6.0.1, acorn-walk@^6.1.1: + version "6.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" + integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA== + +acorn@^3.0.4: + version "3.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + integrity sha1-ReN/s56No/JbruP/U2niu18iAXo= + +acorn@^5.0.3, acorn@^5.5.0, acorn@^5.6.0: + version "5.7.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" + integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== + +acorn@^6.0.1, acorn@^6.0.2, acorn@^6.0.7, acorn@^6.2.1: + version "6.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.3.0.tgz#0087509119ffa4fc0a0041d1e93a417e68cb856e" + integrity sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA== + +after@0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" + integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= + +ajv-errors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" + integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== + +ajv-keywords@^1.0.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" + integrity sha1-MU3QpLM2j609/NxU7eYXG4htrzw= + +ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" + integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== + +ajv@^4.7.0: + version "4.11.8" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" + integrity sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY= + dependencies: + co "^4.6.0" + json-stable-stringify "^1.0.1" + +ajv@^6.1.0, ajv@^6.10.2, ajv@^6.5.5, ajv@^6.9.1: + version "6.10.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" + integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw== + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^6.12.0: + version "6.12.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.0.tgz#06d60b96d87b8454a5adaba86e7854da629db4b7" + integrity sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +alphanum-sort@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" + integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= + +ansi-colors@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-1.1.0.tgz#6374b4dd5d4718ff3ce27a671a3b1cad077132a9" + integrity sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA== + dependencies: + ansi-wrap "^0.1.0" + +ansi-colors@^4.1.0, ansi-colors@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + +ansi-cyan@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-cyan/-/ansi-cyan-0.1.1.tgz#538ae528af8982f28ae30d86f2f17456d2609873" + integrity sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM= + dependencies: + ansi-wrap "0.1.0" + +ansi-escapes@^1.1.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" + integrity sha1-06ioOzGapneTZisT52HHkRQiMG4= + +ansi-escapes@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" + integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== + +ansi-gray@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251" + integrity sha1-KWLPVOyXksSFEKPetSRDaGHvclE= + dependencies: + ansi-wrap "0.1.0" + +ansi-red@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-red/-/ansi-red-0.1.1.tgz#8c638f9d1080800a353c9c28c8a81ca4705d946c" + integrity sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw= + dependencies: + ansi-wrap "0.1.0" + +ansi-regex@^0.2.0, ansi-regex@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-0.2.1.tgz#0d8e946967a3d8143f93e24e298525fc1b2235f9" + integrity sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk= + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + +ansi-styles@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.1.0.tgz#eaecbf66cd706882760b2f4691582b8f55d7a7de" + integrity sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94= + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +ansi-styles@^3.2.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-wrap@0.1.0, ansi-wrap@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" + integrity sha1-qCJQ3bABXponyoLoLqYDu/pF768= + +any-base@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/any-base/-/any-base-1.1.0.tgz#ae101a62bc08a597b4c9ab5b7089d456630549fe" + integrity sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg== + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +aproba@^1.0.3, aproba@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +arch@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/arch/-/arch-2.1.1.tgz#8f5c2731aa35a30929221bb0640eed65175ec84e" + integrity sha512-BLM56aPo9vLLFVa8+/+pJLnrZ7QGGTVHWsCwieAWT9o9K8UeGaQbzZbGoabWLOo2ksBCztoXdqBZBplqLDDCSg== + +archive-type@^3.0.0, archive-type@^3.0.1: + version "3.2.0" + resolved "https://registry.yarnpkg.com/archive-type/-/archive-type-3.2.0.tgz#9cd9c006957ebe95fadad5bd6098942a813737f6" + integrity sha1-nNnABpV+vpX62tW9YJiUKoE3N/Y= + dependencies: + file-type "^3.1.0" + +archive-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/archive-type/-/archive-type-4.0.0.tgz#f92e72233056dfc6969472749c267bdb046b1d70" + integrity sha1-+S5yIzBW38aWlHJ0nCZ72wRrHXA= + dependencies: + file-type "^4.2.0" + +archiver@~0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/archiver/-/archiver-0.11.0.tgz#98177da7a6c0192b7f2798f30cd6eab8abd76690" + integrity sha1-mBd9p6bAGSt/J5jzDNbquKvXZpA= + dependencies: + async "~0.9.0" + buffer-crc32 "~0.2.1" + glob "~3.2.6" + lazystream "~0.1.0" + lodash "~2.4.1" + readable-stream "~1.0.26" + tar-stream "~0.4.0" + zip-stream "~0.4.0" + +archy@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" + integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA= + +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +arr-diff@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-1.1.0.tgz#687c32758163588fef7de7b36fabe495eb1a399a" + integrity sha1-aHwydYFjWI/vfeezb6vklesaOZo= + dependencies: + arr-flatten "^1.0.1" + array-slice "^0.2.3" + +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + integrity sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8= + dependencies: + arr-flatten "^1.0.1" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-flatten@^1.0.1, arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-2.1.0.tgz#20f9eab5ec70f5c7d215b1077b1c39161d292c7d" + integrity sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0= + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + +array-differ@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" + integrity sha1-7/UuN1gknTO+QCuLuOVkuytdQDE= + +array-each@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/array-each/-/array-each-1.0.1.tgz#a794af0c05ab1752846ee753a1f211a05ba0c44f" + integrity sha1-p5SvDAWrF1KEbudTofIRoFugxE8= + +array-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" + integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= + +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +array-slice@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5" + integrity sha1-3Tz7gO15c6dRF82sabC5nshhhvU= + +array-slice@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-1.1.0.tgz#e368ea15f89bc7069f7ffb89aec3a6c7d4ac22d4" + integrity sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w== + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.0, array-uniq@^1.0.1, array-uniq@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= + +array-uniq@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-2.1.0.tgz#46603d5e28e79bfd02b046fcc1d77c6820bd8e98" + integrity sha512-bdHxtev7FN6+MXI1YFW0Q8mQ8dTJc2S8AMfju+ZR77pbg2yAdVyDlwkaUI7Har0LyOMRFPHrJ9lYdyjZZswdlQ== + +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + +arraybuffer.slice@~0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675" + integrity sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog== + +arrify@^1.0.0, arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + +asar@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/asar/-/asar-2.0.1.tgz#8518a1c62c238109c15a5f742213e83a09b9fd38" + integrity sha512-Vo9yTuUtyFahkVMFaI6uMuX6N7k5DWa6a/8+7ov0/f8Lq9TVR0tUjzSzxQSxT1Y+RJIZgnP7BVb6Uhi+9cjxqA== + dependencies: + chromium-pickle-js "^0.2.0" + commander "^2.20.0" + cuint "^0.2.2" + glob "^7.1.3" + minimatch "^3.0.4" + mkdirp "^0.5.1" + tmp-promise "^1.0.5" + +asn1.js@^4.0.0: + version "4.10.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" + integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +asn1@0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.1.tgz#ecc73f75d31ea3c6ed9d47428db35fecc7b2c6dc" + integrity sha1-7Mc/ddMeo8btnUdCjbNf7Meyxtw= + +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + +assert@^1.1.1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" + integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== + dependencies: + object-assign "^4.1.1" + util "0.10.3" + +assets@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/assets/-/assets-3.0.1.tgz#7a69f4bcc3aca9702760e2a73a7e76ca93e9e3e0" + integrity sha512-fTyLNf/9V24y5zO83f4DAEuvaKj7MWBixbnqdZneAhsv1r21yQ/6ogZfvXHmphJAHsz4DhuOwHeJKVbGqqvk0Q== + dependencies: + async "^2.5.0" + bluebird "^3.4.6" + calipers "^2.0.0" + calipers-gif "^2.0.0" + calipers-jpeg "^2.0.0" + calipers-png "^2.0.0" + calipers-svg "^2.0.0" + calipers-webp "^2.0.0" + glob "^7.0.6" + lodash "^4.15.0" + mime "^2.4.0" + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +ast-types@0.9.6: + version "0.9.6" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.6.tgz#102c9e9e9005d3e7e3829bf0c4fa24ee862ee9b9" + integrity sha1-ECyenpAF0+fjgpvwxPok7oYu6bk= + +astral-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== + +async-each-series@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/async-each-series/-/async-each-series-0.1.1.tgz#7617c1917401fd8ca4a28aadce3dbae98afeb432" + integrity sha1-dhfBkXQB/Yykooqtzj266Yr+tDI= + +async-each-series@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/async-each-series/-/async-each-series-1.1.0.tgz#f42fd8155d38f21a5b8ea07c28e063ed1700b138" + integrity sha1-9C/YFV048hpbjqB8KOBj7RcAsTg= + +async-each@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== + +async-foreach@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/async-foreach/-/async-foreach-0.1.3.tgz#36121f845c0578172de419a97dbeb1d16ec34542" + integrity sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI= + +async-limiter@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== + +async.queue@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/async.queue/-/async.queue-0.5.2.tgz#8d5d90812e1481066bc0904e8cc1712b17c3bd7c" + integrity sha1-jV2QgS4UgQZrwJBOjMFxKxfDvXw= + dependencies: + async.util.queue "0.5.2" + +async.util.arrayeach@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/async.util.arrayeach/-/async.util.arrayeach-0.5.2.tgz#58c4e98028d55d69bfb05aeb3af44e0a555a829c" + integrity sha1-WMTpgCjVXWm/sFrrOvROClVagpw= + +async.util.isarray@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/async.util.isarray/-/async.util.isarray-0.5.2.tgz#e62dac8f2636f65875dcf7521c2d24d0dfb2bbdf" + integrity sha1-5i2sjyY29lh13PdSHC0k0N+yu98= + +async.util.map@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/async.util.map/-/async.util.map-0.5.2.tgz#e588ef86e0b3ab5f027d97af4d6835d055ca69d6" + integrity sha1-5YjvhuCzq18CfZevTWg10FXKadY= + +async.util.noop@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/async.util.noop/-/async.util.noop-0.5.2.tgz#bdd62b97cb0aa3f60b586ad148468698975e58b9" + integrity sha1-vdYrl8sKo/YLWGrRSEaGmJdeWLk= + +async.util.onlyonce@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/async.util.onlyonce/-/async.util.onlyonce-0.5.2.tgz#b8e6fc004adc923164d79e32f2813ee465c24ff2" + integrity sha1-uOb8AErckjFk154y8oE+5GXCT/I= + +async.util.queue@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/async.util.queue/-/async.util.queue-0.5.2.tgz#57f65abe1a3cdf273d31abd28ab95425f8222ee5" + integrity sha1-V/Zavho83yc9MavSirlUJfgiLuU= + dependencies: + async.util.arrayeach "0.5.2" + async.util.isarray "0.5.2" + async.util.map "0.5.2" + async.util.noop "0.5.2" + async.util.onlyonce "0.5.2" + async.util.setimmediate "0.5.2" + +async.util.setimmediate@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/async.util.setimmediate/-/async.util.setimmediate-0.5.2.tgz#2812ebabf2a58027758d4bc7793d1ccfaf10255f" + integrity sha1-KBLrq/KlgCd1jUvHeT0cz68QJV8= + +async@1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= + +async@>=0.2.9: + version "3.1.0" + resolved "https://registry.yarnpkg.com/async/-/async-3.1.0.tgz#42b3b12ae1b74927b5217d8c0016baaf62463772" + integrity sha512-4vx/aaY6j/j3Lw3fbCHNWP0pPaTCew3F6F3hYyl/tHs/ndmV1q7NW9T5yuJ2XAGwdQrP+6Wu20x06U4APo/iQQ== + +async@^2.5.0: + version "2.6.3" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== + dependencies: + lodash "^4.17.14" + +async@~0.2.10: + version "0.2.10" + resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" + integrity sha1-trvgsGdLnXGXCMo43owjfLUmw9E= + +async@~0.9.0: + version "0.9.2" + resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" + integrity sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0= + +async@~2.1.4: + version "2.1.5" + resolved "https://registry.yarnpkg.com/async/-/async-2.1.5.tgz#e587c68580994ac67fc56ff86d3ac56bdbe810bc" + integrity sha1-5YfGhYCZSsZ/xW/4bTrFa9voELw= + dependencies: + lodash "^4.14.0" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +atob@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +author-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/author-regex/-/author-regex-1.0.0.tgz#d08885be6b9bbf9439fe087c76287245f0a81450" + integrity sha1-0IiFvmubv5Q5/gh8dihyRfCoFFA= + +autoprefixer@^9.4.3, autoprefixer@^9.4.7, autoprefixer@^9.6.1: + version "9.6.1" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.6.1.tgz#51967a02d2d2300bb01866c1611ec8348d355a47" + integrity sha512-aVo5WxR3VyvyJxcJC3h4FKfwCQvQWb1tSI5VHNibddCVWrcD1NvlxEweg3TSgiPztMnWfjpy2FURKA2kvDE+Tw== + dependencies: + browserslist "^4.6.3" + caniuse-lite "^1.0.30000980" + chalk "^2.4.2" + normalize-range "^0.1.2" + num2fraction "^1.2.2" + postcss "^7.0.17" + postcss-value-parser "^4.0.0" + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" + integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== + +axios@0.19.0: + version "0.19.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.0.tgz#8e09bff3d9122e133f7b8101c8fbdd00ed3d2ab8" + integrity sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ== + dependencies: + follow-redirects "1.5.10" + is-buffer "^2.0.2" + +babel-loader@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.1.0.tgz#c611d5112bd5209abe8b9fa84c3e4da25275f1c3" + integrity sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw== + dependencies: + find-cache-dir "^2.1.0" + loader-utils "^1.4.0" + mkdirp "^0.5.3" + pify "^4.0.1" + schema-utils "^2.6.5" + +babel-plugin-closure-elimination@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/babel-plugin-closure-elimination/-/babel-plugin-closure-elimination-1.3.0.tgz#3217fbf6d416dfdf14ff41a8a34e4d0a6bfc22b2" + integrity sha512-ClKuSxKLLNhe69bvTMuONDI0dQDW49lXB2qtQyyKCzvwegRGel/q4/e+1EoDNDN97Hf1QkxGMbzpAGPmU4Tfjw== + +babel-plugin-console-source@^2.0.2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/babel-plugin-console-source/-/babel-plugin-console-source-2.0.4.tgz#263985b1d69b68e463358d087fa877dd967c5f41" + integrity sha512-OGhrdhuMjiEW0Ma0P9e2B4dFddCpJ/xN/RRaM/4wwDLl+6ZKf+Xd77FtVjpNeDzNRNk8wjRdStA4hpZizXzl1g== + +babel-plugin-danger-remove-unused-import@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/babel-plugin-danger-remove-unused-import/-/babel-plugin-danger-remove-unused-import-1.1.2.tgz#ac39c30edfe524ef8cfc411fec5edc479d19e132" + integrity sha512-3bNmVAaakP3b1aROj7O3bOWj2kBa85sZR5naZ3Rn8L9buiZaAyZLgjfrPDL3zhX4wySOA5jrTm/wSmJPsMm3cg== + +babel-plugin-dynamic-import-node@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz#f00f507bdaa3c3e3ff6e7e5e98d90a7acab96f7f" + integrity sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ== + dependencies: + object.assign "^4.1.0" + +babel-polyfill@6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.23.0.tgz#8364ca62df8eafb830499f699177466c3b03499d" + integrity sha1-g2TKYt+Or7gwSZ9pkXdGbDsDSZ0= + dependencies: + babel-runtime "^6.22.0" + core-js "^2.4.0" + regenerator-runtime "^0.10.0" + +babel-runtime@^6.22.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babel-runtime@^7.0.0-beta.3: + version "7.0.0-beta.3" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-7.0.0-beta.3.tgz#7c750de5514452c27612172506b49085a4a630f2" + integrity sha512-jlzZ8RACjt0QGxq+wqsw5bCQE9RcUyWpw987mDY3GYxTpOQT2xoyNoG++oVCHzr/nACLBIprfVBNvv/If1ZYcg== + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +backo2@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" + integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base64-arraybuffer@0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8" + integrity sha1-c5JncZI7Whl0etZmqlzUv5xunOg= + +base64-js@^1.0.2, base64-js@^1.2.3: + version "1.3.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" + integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== + +base64id@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/base64id/-/base64id-1.0.0.tgz#47688cb99bb6804f0e06d3e763b1c32e57d8e6b6" + integrity sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY= + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + +beeper@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/beeper/-/beeper-1.1.1.tgz#e6d5ea8c5dad001304a70b22638447f69cb2f809" + integrity sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak= + +better-assert@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/better-assert/-/better-assert-1.0.2.tgz#40866b9e1b9e0b55b481894311e68faffaebc522" + integrity sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI= + dependencies: + callsite "1.0.0" + +bfj@^6.1.1: + version "6.1.2" + resolved "https://registry.yarnpkg.com/bfj/-/bfj-6.1.2.tgz#325c861a822bcb358a41c78a33b8e6e2086dde7f" + integrity sha512-BmBJa4Lip6BPRINSZ0BPEIfB1wUY/9rwbwvIHQA1KjX9om29B6id0wnWXq7m3bn5JrUVjeOTnVuhPT1FiHwPGw== + dependencies: + bluebird "^3.5.5" + check-types "^8.0.3" + hoopy "^0.1.4" + tryer "^1.0.1" + +big.js@^3.1.3: + version "3.2.0" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" + integrity sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q== + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +bin-build@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/bin-build/-/bin-build-2.2.0.tgz#11f8dd61f70ffcfa2bdcaa5b46f5e8fedd4221cc" + integrity sha1-EfjdYfcP/Por3KpbRvXo/t1CIcw= + dependencies: + archive-type "^3.0.1" + decompress "^3.0.0" + download "^4.1.2" + exec-series "^1.0.0" + rimraf "^2.2.6" + tempfile "^1.0.0" + url-regex "^3.0.0" + +bin-build@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bin-build/-/bin-build-3.0.0.tgz#c5780a25a8a9f966d8244217e6c1f5082a143861" + integrity sha512-jcUOof71/TNAI2uM5uoUaDq2ePcVBQ3R/qhxAz1rX7UfvduAL/RXD3jXzvn8cVcDJdGVkiR1shal3OH0ImpuhA== + dependencies: + decompress "^4.0.0" + download "^6.2.2" + execa "^0.7.0" + p-map-series "^1.0.0" + tempfile "^2.0.0" + +bin-check@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/bin-check/-/bin-check-2.0.0.tgz#86f8e6f4253893df60dc316957f5af02acb05930" + integrity sha1-hvjm9CU4k99g3DFpV/WvAqywWTA= + dependencies: + executable "^1.0.0" + +bin-check@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bin-check/-/bin-check-4.1.0.tgz#fc495970bdc88bb1d5a35fc17e65c4a149fc4a49" + integrity sha512-b6weQyEUKsDGFlACWSIOfveEnImkJyK/FGW6FAG42loyoquvjdtOIqO6yBFzHyqyVVhNgNkQxxx09SFLK28YnA== + dependencies: + execa "^0.7.0" + executable "^4.1.0" + +bin-version-check@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/bin-version-check/-/bin-version-check-2.1.0.tgz#e4e5df290b9069f7d111324031efc13fdd11a5b0" + integrity sha1-5OXfKQuQaffRETJAMe/BP90RpbA= + dependencies: + bin-version "^1.0.0" + minimist "^1.1.0" + semver "^4.0.3" + semver-truncate "^1.0.0" + +bin-version-check@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/bin-version-check/-/bin-version-check-4.0.0.tgz#7d819c62496991f80d893e6e02a3032361608f71" + integrity sha512-sR631OrhC+1f8Cvs8WyVWOA33Y8tgwjETNPyyD/myRBXLkfS/vl74FmH/lFcRl9KY3zwGh7jFhvyk9vV3/3ilQ== + dependencies: + bin-version "^3.0.0" + semver "^5.6.0" + semver-truncate "^1.1.2" + +bin-version@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/bin-version/-/bin-version-1.0.4.tgz#9eb498ee6fd76f7ab9a7c160436f89579435d78e" + integrity sha1-nrSY7m/Xb3q5p8FgQ2+JV5Q1144= + dependencies: + find-versions "^1.0.0" + +bin-version@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bin-version/-/bin-version-3.1.0.tgz#5b09eb280752b1bd28f0c9db3f96f2f43b6c0839" + integrity sha512-Mkfm4iE1VFt4xd4vH+gx+0/71esbfus2LsnCGe8Pi4mndSPyT+NGES/Eg99jx8/lUGWfu3z2yuB/bt5UB+iVbQ== + dependencies: + execa "^1.0.0" + find-versions "^3.0.0" + +bin-wrapper@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/bin-wrapper/-/bin-wrapper-3.0.2.tgz#67d3306262e4b1a5f2f88ee23464f6a655677aeb" + integrity sha1-Z9MwYmLksaXy+I7iNGT2plVneus= + dependencies: + bin-check "^2.0.0" + bin-version-check "^2.1.0" + download "^4.0.0" + each-async "^1.1.1" + lazy-req "^1.0.0" + os-filter-obj "^1.0.0" + +bin-wrapper@^4.0.0, bin-wrapper@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bin-wrapper/-/bin-wrapper-4.1.0.tgz#99348f2cf85031e3ef7efce7e5300aeaae960605" + integrity sha512-hfRmo7hWIXPkbpi0ZltboCMVrU+0ClXR/JgbCKKjlDjQf6igXa7OwdqNcFWQZPZTgiY7ZpzE3+LjjkLiTN2T7Q== + dependencies: + bin-check "^4.1.0" + bin-version-check "^4.0.0" + download "^7.1.0" + import-lazy "^3.1.0" + os-filter-obj "^2.0.0" + pify "^4.0.1" + +binary-extensions@^1.0.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== + +bl@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/bl/-/bl-0.7.0.tgz#3fb0670602ac2878eb770dc2039f1836be62ae5b" + integrity sha1-P7BnBgKsKHjrdw3CA58YNr5irls= + dependencies: + readable-stream "~1.0.2" + +bl@^0.9.0: + version "0.9.5" + resolved "https://registry.yarnpkg.com/bl/-/bl-0.9.5.tgz#c06b797af085ea00bc527afc8efcf11de2232054" + integrity sha1-wGt5evCF6gC8Unr8jvzxHeIjIFQ= + dependencies: + readable-stream "~1.0.26" + +bl@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c" + integrity sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA== + dependencies: + readable-stream "^2.3.5" + safe-buffer "^5.1.1" + +blob@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.5.tgz#d680eeef25f8cd91ad533f5b01eed48e64caf683" + integrity sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig== + +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo= + dependencies: + inherits "~2.0.0" + +bluebird@3.x.x, bluebird@^3.1.1, bluebird@^3.4.6, bluebird@^3.5.0, bluebird@^3.5.5: + version "3.5.5" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.5.tgz#a8d0afd73251effbbd5fe384a77d73003c17a71f" + integrity sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w== + +bmp-js@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.1.0.tgz#e05a63f796a6c1ff25f4771ec7adadc148c07233" + integrity sha1-4Fpj95amwf8l9Hcex62twUjAcjM= + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: + version "4.11.8" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" + integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== + +body-parser@1.19.0: + version "1.19.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" + integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== + dependencies: + bytes "3.1.0" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "1.7.2" + iconv-lite "0.4.24" + on-finished "~2.3.0" + qs "6.7.0" + raw-body "2.4.0" + type-is "~1.6.17" + +body-parser@~1.8.0: + version "1.8.4" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.8.4.tgz#d497e04bc13b3f9a8bd8c70bb0cdc16f2e028898" + integrity sha1-1JfgS8E7P5qL2McLsM3Bby4CiJg= + dependencies: + bytes "1.0.0" + depd "0.4.5" + iconv-lite "0.4.4" + media-typer "0.3.0" + on-finished "2.1.0" + qs "2.2.4" + raw-body "1.3.0" + type-is "~1.5.1" + +boolbase@^1.0.0, boolbase@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= + +brace-expansion@^1.0.0, brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + integrity sha1-uneWLhLf+WnWt2cR6RS3N4V79qc= + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + +braces@^2.3.1, braces@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + +browser-process-hrtime@^0.1.2: + version "0.1.3" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz#616f00faef1df7ec1b5bf9cfe2bdc3170f26c7b4" + integrity sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw== + +browser-sync-client@^2.26.6: + version "2.26.6" + resolved "https://registry.yarnpkg.com/browser-sync-client/-/browser-sync-client-2.26.6.tgz#e5201d3ace8aee88af17656b7b0c0620b6f8e4ab" + integrity sha512-mGrkZdNzttKdf/16I+y+2dTQxoMCIpKbVIMJ/uP8ZpnKu9f9qa/2CYVtLtbjZG8nsM14EwiCrjuFTGBEnT3Gjw== + dependencies: + etag "1.8.1" + fresh "0.5.2" + mitt "^1.1.3" + rxjs "^5.5.6" + +browser-sync-ui@^2.26.4: + version "2.26.4" + resolved "https://registry.yarnpkg.com/browser-sync-ui/-/browser-sync-ui-2.26.4.tgz#3772f13c6b93f2d7d333f4be0ca1ec02aae97dba" + integrity sha512-u20P3EsZoM8Pt+puoi3BU3KlbQAH1lAcV+/O4saF26qokrBqIDotmGonfWwoRbUmdxZkM9MBmA0K39ZTG1h4sA== + dependencies: + async-each-series "0.1.1" + connect-history-api-fallback "^1" + immutable "^3" + server-destroy "1.0.1" + socket.io-client "^2.0.4" + stream-throttle "^0.1.3" + +browser-sync@^2.24.6: + version "2.26.7" + resolved "https://registry.yarnpkg.com/browser-sync/-/browser-sync-2.26.7.tgz#120287716eb405651a76cc74fe851c31350557f9" + integrity sha512-lY3emme0OyvA2ujEMpRmyRy9LY6gHLuTr2/ABxhIm3lADOiRXzP4dgekvnDrQqZ/Ec2Fz19lEjm6kglSG5766w== + dependencies: + browser-sync-client "^2.26.6" + browser-sync-ui "^2.26.4" + bs-recipes "1.3.4" + bs-snippet-injector "^2.0.1" + chokidar "^2.0.4" + connect "3.6.6" + connect-history-api-fallback "^1" + dev-ip "^1.0.1" + easy-extender "^2.3.4" + eazy-logger "^3" + etag "^1.8.1" + fresh "^0.5.2" + fs-extra "3.0.1" + http-proxy "1.15.2" + immutable "^3" + localtunnel "1.9.2" + micromatch "^3.1.10" + opn "5.3.0" + portscanner "2.1.1" + qs "6.2.3" + raw-body "^2.3.2" + resp-modifier "6.0.2" + rx "4.1.0" + send "0.16.2" + serve-index "1.9.1" + serve-static "1.13.2" + server-destroy "1.0.1" + socket.io "2.1.1" + ua-parser-js "0.7.17" + yargs "6.4.0" + +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" + integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= + dependencies: + bn.js "^4.1.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" + integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg= + dependencies: + bn.js "^4.1.1" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.2" + elliptic "^6.0.0" + inherits "^2.0.1" + parse-asn1 "^5.0.0" + +browserify-zlib@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== + dependencies: + pako "~1.0.5" + +browserslist@^4.0.0, browserslist@^4.6.0, browserslist@^4.6.3, browserslist@^4.6.4, browserslist@^4.6.6: + version "4.7.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.7.0.tgz#9ee89225ffc07db03409f2fee524dc8227458a17" + integrity sha512-9rGNDtnj+HaahxiVV38Gn8n8Lr8REKsel68v1sPFfIGEK6uSXTY3h9acgiT1dZVtOOUtifo/Dn8daDQ5dUgVsA== + dependencies: + caniuse-lite "^1.0.30000989" + electron-to-chromium "^1.3.247" + node-releases "^1.1.29" + +bs-recipes@1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/bs-recipes/-/bs-recipes-1.3.4.tgz#0d2d4d48a718c8c044769fdc4f89592dc8b69585" + integrity sha1-DS1NSKcYyMBEdp/cT4lZLci2lYU= + +bs-snippet-injector@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/bs-snippet-injector/-/bs-snippet-injector-2.0.1.tgz#61b5393f11f52559ed120693100343b6edb04dd5" + integrity sha1-YbU5PxH1JVntEgaTEANDtu2wTdU= + +buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== + +buffer-alloc@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + +buffer-crc32@~0.2.1, buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= + +buffer-equal@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-0.0.1.tgz#91bc74b11ea405bc916bc6aa908faafa5b4aac4b" + integrity sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs= + +buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +buffer-to-vinyl@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-to-vinyl/-/buffer-to-vinyl-1.1.0.tgz#00f15faee3ab7a1dda2cde6d9121bffdd07b2262" + integrity sha1-APFfruOreh3aLN5tkSG//dB7ImI= + dependencies: + file-type "^3.1.0" + readable-stream "^2.0.2" + uuid "^2.0.1" + vinyl "^1.0.0" + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= + +buffer@^4.3.0: + version "4.9.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" + integrity sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg= + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +buffer@^5.2.0, buffer@^5.2.1: + version "5.4.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.4.3.tgz#3fbc9c69eb713d323e3fc1a895eee0710c072115" + integrity sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= + +bytes@1, bytes@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-1.0.0.tgz#3569ede8ba34315fab99c3e92cb04c7220de1fa8" + integrity sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g= + +bytes@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" + integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== + +cacache@^12.0.2: + version "12.0.3" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.3.tgz#be99abba4e1bf5df461cd5a2c1071fc432573390" + integrity sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw== + dependencies: + bluebird "^3.5.5" + chownr "^1.1.1" + figgy-pudding "^3.5.1" + glob "^7.1.4" + graceful-fs "^4.1.15" + infer-owner "^1.0.3" + lru-cache "^5.1.1" + mississippi "^3.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.3" + ssri "^6.0.1" + unique-filename "^1.1.1" + y18n "^4.0.0" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +cache-swap@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/cache-swap/-/cache-swap-0.3.0.tgz#1c541aa108a50106f630bdd98fe1dec8ba133f51" + integrity sha1-HFQaoQilAQb2ML3Zj+HeyLoTP1E= + dependencies: + graceful-fs "^4.1.2" + mkdirp "^0.5.1" + object-assign "^4.0.1" + rimraf "^2.4.0" + +cacheable-request@^2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-2.1.4.tgz#0d808801b6342ad33c91df9d0b44dc09b91e5c3d" + integrity sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0= + dependencies: + clone-response "1.0.2" + get-stream "3.0.0" + http-cache-semantics "3.8.1" + keyv "3.0.0" + lowercase-keys "1.0.0" + normalize-url "2.0.1" + responselike "1.0.2" + +cacheable-request@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" + integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^3.0.0" + lowercase-keys "^2.0.0" + normalize-url "^4.1.0" + responselike "^1.0.2" + +calipers-gif@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/calipers-gif/-/calipers-gif-2.0.0.tgz#b5eefec3064a77c6dcdbd5bdc51735a01bafdc37" + integrity sha1-te7+wwZKd8bc29W9xRc1oBuv3Dc= + dependencies: + bluebird "3.x.x" + +calipers-jpeg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/calipers-jpeg/-/calipers-jpeg-2.0.0.tgz#06d56a53f62717dd809cb956cf64423ce693465b" + integrity sha1-BtVqU/YnF92AnLlWz2RCPOaTRls= + dependencies: + bluebird "3.x.x" + +calipers-png@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/calipers-png/-/calipers-png-2.0.0.tgz#1d0d20e5c1ae5f79b74d5286a2e97f59bb70b658" + integrity sha1-HQ0g5cGuX3m3TVKGoul/Wbtwtlg= + dependencies: + bluebird "3.x.x" + +calipers-svg@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/calipers-svg/-/calipers-svg-2.0.1.tgz#cd9eaa58ef7428c1a14f5da57e56715fb60f6541" + integrity sha512-3PROqHARmj8wWudUC7DzXm1+mSocqgY7jNuehFNHgrUVrKf8o7MqDjS92vJz5LvZsAofJsoAFMajkqwbxBROSQ== + dependencies: + bluebird "3.x.x" + +calipers-webp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/calipers-webp/-/calipers-webp-2.0.0.tgz#e126ece2f84cd71779612bfa2b2653cd95cea77a" + integrity sha1-4Sbs4vhM1xd5YSv6KyZTzZXOp3o= + dependencies: + bluebird "3.x.x" + +calipers@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/calipers/-/calipers-2.0.1.tgz#0d3f303ce75ec5f1eda7fecfc7dba6736e35c926" + integrity sha512-AP4Ui2Z8fZf69d8Dx4cfJgPjQHY3m+QXGFCaAGu8pfNQjyajkosS+Kkf1n6pQDMZcelN5h3MdcjweUqxcsS4pg== + dependencies: + bluebird "3.x.x" + +call-me-maybe@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" + integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= + +caller-callsite@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" + integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= + dependencies: + callsites "^2.0.0" + +caller-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" + integrity sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8= + dependencies: + callsites "^0.2.0" + +caller-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" + integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= + dependencies: + caller-callsite "^2.0.0" + +callsite@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" + integrity sha1-KAOY5dZkvXQDi28JBRU+borxvCA= + +callsites@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" + integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo= + +callsites@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" + integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camel-case@3.0.x: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" + integrity sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M= + dependencies: + no-case "^2.2.0" + upper-case "^1.1.1" + +camelcase-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc= + dependencies: + camelcase "^2.0.0" + map-obj "^1.0.0" + +camelcase@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= + +camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo= + +camelcase@^5.0.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +caniuse-api@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" + integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw== + dependencies: + browserslist "^4.0.0" + caniuse-lite "^1.0.0" + lodash.memoize "^4.1.2" + lodash.uniq "^4.5.0" + +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30000989: + version "1.0.30000989" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz#b9193e293ccf7e4426c5245134b8f2a56c0ac4b9" + integrity sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw== + +capture-stack-trace@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" + integrity sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw== + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + +caw@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/caw/-/caw-1.2.0.tgz#ffb226fe7efc547288dc62ee3e97073c212d1034" + integrity sha1-/7Im/n78VHKI3GLuPpcHPCEtEDQ= + dependencies: + get-proxy "^1.0.1" + is-obj "^1.0.0" + object-assign "^3.0.0" + tunnel-agent "^0.4.0" + +caw@^2.0.0, caw@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/caw/-/caw-2.0.1.tgz#6c3ca071fc194720883c2dc5da9b074bfc7e9e95" + integrity sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA== + dependencies: + get-proxy "^2.0.0" + isurl "^1.0.0-alpha5" + tunnel-agent "^0.6.0" + url-to-options "^1.0.1" + +chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.2.tgz#250dc96b07491bfd601e648d66ddf5f60c7a5c65" + integrity sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" + integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.5.1.tgz#663b3a648b68b55d04690d49167aa837858f2174" + integrity sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ= + dependencies: + ansi-styles "^1.1.0" + escape-string-regexp "^1.0.0" + has-ansi "^0.1.0" + strip-ansi "^0.3.0" + supports-color "^0.2.0" + +chance@1.0.13: + version "1.0.13" + resolved "https://registry.yarnpkg.com/chance/-/chance-1.0.13.tgz#666bec2db42b3084456a3e4f4c28a82db5ccb7e6" + integrity sha512-9cpcgmAIQiXC0eMgQuMZgXuHR2Y+gKUyGQnalqSAg5LlUJyJFsZeKyuHVSGhj+bx18ppH+Jo3VOayNeXR/7p9Q== + +chance@1.0.16: + version "1.0.16" + resolved "https://registry.yarnpkg.com/chance/-/chance-1.0.16.tgz#bd61912716b0010c3dca8e3948a960efcaa7bb1b" + integrity sha512-2bgDHH5bVfAXH05SPtjqrsASzZ7h90yCuYT2z4mkYpxxYvJXiIydBFzVieVHZx7wLH1Ag2Azaaej2/zA1XUrNQ== + +chardet@^0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" + integrity sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I= + +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + +charenc@~0.0.1: + version "0.0.2" + resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" + integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc= + +check-types@^8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/check-types/-/check-types-8.0.3.tgz#3356cca19c889544f2d7a95ed49ce508a0ecf552" + integrity sha512-YpeKZngUmG65rLudJ4taU7VLkOCTMhNl/u4ctNC56LQS/zJTyNH0Lrtwm1tfTsbLlwvlfsA2d1c8vCf/Kh2KwQ== + +chokidar@^2.0.2, chokidar@^2.0.4: + version "2.1.8" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.2.1" + upath "^1.1.1" + optionalDependencies: + fsevents "^1.2.7" + +chownr@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.2.tgz#a18f1e0b269c8a6a5d3c86eb298beb14c3dd7bf6" + integrity sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A== + +chrome-trace-event@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" + integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ== + dependencies: + tslib "^1.9.0" + +chromium-pickle-js@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz#04a106672c18b085ab774d983dfa3ea138f22205" + integrity sha1-BKEGZywYsIWrd02YPfo+oTjyIgU= + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +circular-dependency-plugin@^5.0.2: + version "5.2.0" + resolved "https://registry.yarnpkg.com/circular-dependency-plugin/-/circular-dependency-plugin-5.2.0.tgz#e09dbc2dd3e2928442403e2d45b41cea06bc0a93" + integrity sha512-7p4Kn/gffhQaavNfyDFg7LS5S/UT1JAjyGd4UqR2+jzoYF02eDkj0Ec3+48TsIa4zghjLY87nQHIh/ecK9qLdw== + +circular-json@^0.3.1: + version "0.3.3" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" + integrity sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A== + +circular-json@^0.5.9: + version "0.5.9" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.5.9.tgz#932763ae88f4f7dead7a0d09c8a51a4743a53b1d" + integrity sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ== + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +class-validator@0.8.5: + version "0.8.5" + resolved "https://registry.yarnpkg.com/class-validator/-/class-validator-0.8.5.tgz#484785acda98f68549c3a84dc1bb2f77b736dc58" + integrity sha512-84yezRo44aP4oGhvPmqj6obAFQF1NzUyfR0+f8jubzdAspO5pmjpHhBBlPf335epUskzXAFe5uo4Qf+c7SI+DA== + dependencies: + validator "9.2.0" + +class-validator@0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/class-validator/-/class-validator-0.9.1.tgz#d60e58c5d14abca0a41bce38cf792ad4c46d1531" + integrity sha512-3wApflrd3ywVZyx4jaasGoFt8pmo4aGLPPAEKCKCsTRWVGPilahD88q3jQjRQwja50rl9a7rsP5LAxJYwGK8/Q== + dependencies: + google-libphonenumber "^3.1.6" + validator "10.4.0" + +clean-css@4.2.x: + version "4.2.1" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.1.tgz#2d411ef76b8569b6d0c84068dabe85b0aa5e5c17" + integrity sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g== + dependencies: + source-map "~0.6.0" + +cli-cursor@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" + integrity sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc= + dependencies: + restore-cursor "^1.0.1" + +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= + dependencies: + restore-cursor "^2.0.0" + +cli-table@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.1.tgz#f53b05266a8b1a0b934b3d0821e6e2dc5914ae23" + integrity sha1-9TsFJmqLGguTSz0IIebi3FkUriM= + dependencies: + colors "1.0.3" + +cli-width@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= + +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + +cliui@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" + integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== + dependencies: + string-width "^3.1.0" + strip-ansi "^5.2.0" + wrap-ansi "^5.1.0" + +clone-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" + integrity sha1-4+JbIHrE5wGvch4staFnksrD3Fg= + +clone-response@1.0.2, clone-response@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" + integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= + dependencies: + mimic-response "^1.0.0" + +clone-stats@^0.0.1, clone-stats@~0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1" + integrity sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE= + +clone-stats@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" + integrity sha1-s3gt/4u1R04Yuba/D9/ngvh3doA= + +clone@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/clone/-/clone-0.2.0.tgz#c6126a90ad4f72dbf5acdb243cc37724fe93fc1f" + integrity sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8= + +clone@^1.0.0, clone@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= + +clone@^2.1.1, clone@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= + +cloneable-readable@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.1.3.tgz#120a00cb053bfb63a222e709f9683ea2e11d8cec" + integrity sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ== + dependencies: + inherits "^2.0.1" + process-nextick-args "^2.0.0" + readable-stream "^2.3.5" + +co@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/co/-/co-3.1.0.tgz#4ea54ea5a08938153185e15210c68d9092bc1b78" + integrity sha1-TqVOpaCJOBUxheFSEMaNkJK8G3g= + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + +coa@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3" + integrity sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA== + dependencies: + "@types/q" "^1.5.1" + chalk "^2.4.1" + q "^1.1.2" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0, color-convert@^1.9.1: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +color-string@^1.5.2: + version "1.5.3" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc" + integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw== + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + +color-support@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" + integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== + +color@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/color/-/color-3.1.2.tgz#68148e7f85d41ad7649c5fa8c8106f098d229e10" + integrity sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg== + dependencies: + color-convert "^1.9.1" + color-string "^1.5.2" + +colors@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" + integrity sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs= + +colors@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.3.tgz#39e005d546afe01e01f9c4ca8fa50f686a01205d" + integrity sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg== + +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@2.15.1: + version "2.15.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" + integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== + +commander@2.17.1, commander@2.17.x: + version "2.17.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" + integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== + +commander@^2.18.0, commander@^2.19.0, commander@^2.2.0, commander@^2.20.0, commander@^2.8.1: + version "2.20.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" + integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== + +commander@~2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" + integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== + +commander@~2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4" + integrity sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ= + dependencies: + graceful-readlink ">= 1.0.0" + +commander@~2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" + integrity sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q= + dependencies: + graceful-readlink ">= 1.0.0" + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + +compare-version@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/compare-version/-/compare-version-0.1.2.tgz#0162ec2d9351f5ddd59a9202cba935366a725080" + integrity sha1-AWLsLZNR9d3VmpICy6k1NmpyUIA= + +component-bind@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1" + integrity sha1-AMYIq33Nk4l8AAllGx06jh5zu9E= + +component-emitter@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= + +component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +component-inherit@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143" + integrity sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM= + +compress-commons@~0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-0.1.6.tgz#0c740870fde58cba516f0ac0c822e33a0b85dfa3" + integrity sha1-DHQIcP3ljLpRbwrAyCLjOguF36M= + dependencies: + buffer-crc32 "~0.2.1" + crc32-stream "~0.3.1" + readable-stream "~1.0.26" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +concat-stream@^1.4.6, concat-stream@^1.4.7, concat-stream@^1.4.8, concat-stream@^1.5.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +config-chain@^1.1.11, config-chain@^1.1.12: + version "1.1.12" + resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa" + integrity sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA== + dependencies: + ini "^1.3.4" + proto-list "~1.2.1" + +connect-history-api-fallback@^1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" + integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== + +connect-livereload@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/connect-livereload/-/connect-livereload-0.4.1.tgz#0f8a1a816bc9baffae4637ccea917462fe35917a" + integrity sha1-D4oagWvJuv+uRjfM6pF0Yv41kXo= + +connect@3.6.6: + version "3.6.6" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.6.6.tgz#09eff6c55af7236e137135a72574858b6786f524" + integrity sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ= + dependencies: + debug "2.6.9" + finalhandler "1.1.0" + parseurl "~1.3.2" + utils-merge "1.0.1" + +connect@^3.0.1: + version "3.7.0" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" + integrity sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ== + dependencies: + debug "2.6.9" + finalhandler "1.1.2" + parseurl "~1.3.3" + utils-merge "1.0.1" + +console-browserify@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" + integrity sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA= + dependencies: + date-now "^0.1.4" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + +console-stream@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/console-stream/-/console-stream-0.1.1.tgz#a095fe07b20465955f2fafd28b5d72bccd949d44" + integrity sha1-oJX+B7IEZZVfL6/Si11yvM2UnUQ= + +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= + +content-disposition@0.5.3, content-disposition@^0.5.2: + version "0.5.3" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" + integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== + dependencies: + safe-buffer "5.1.2" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +convert-source-map@^1.1.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" + integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== + dependencies: + safe-buffer "~5.1.1" + +convert-source-map@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" + integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== + dependencies: + safe-buffer "~5.1.1" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= + +cookie@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" + integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== + +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +core-js-compat@^3.1.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.2.1.tgz#0cbdbc2e386e8e00d3b85dc81c848effec5b8150" + integrity sha512-MwPZle5CF9dEaMYdDeWm73ao/IflDH+FjeJCWEADcEgFSE9TLimFKwJsfmkwzI8eC0Aj0mgvMDjeQjrElkz4/A== + dependencies: + browserslist "^4.6.6" + semver "^6.3.0" + +core-js@3: + version "3.2.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.2.1.tgz#cd41f38534da6cc59f7db050fe67307de9868b09" + integrity sha512-Qa5XSVefSVPRxy2XfUC13WbvqkxhkwB3ve+pgCQveNgYzbM/UxZeu1dcOX/xr4UmfUd+muuvsaxilQzCyUurMw== + +core-js@^2.4.0, core-js@^2.5.3, core-js@^2.5.7: + version "2.6.9" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2" + integrity sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A== + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +cosmiconfig@^5.0.0, cosmiconfig@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" + integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA== + dependencies: + import-fresh "^2.0.0" + is-directory "^0.3.1" + js-yaml "^3.13.1" + parse-json "^4.0.0" + +crc32-stream@~0.3.1: + version "0.3.4" + resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-0.3.4.tgz#73bc25b45fac1db6632231a7bfce8927e9f06552" + integrity sha1-c7wltF+sHbZjIjGnv86JJ+nwZVI= + dependencies: + buffer-crc32 "~0.2.1" + readable-stream "~1.0.24" + +create-ecdh@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" + integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== + dependencies: + bn.js "^4.1.0" + elliptic "^6.0.0" + +create-error-class@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" + integrity sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y= + dependencies: + capture-stack-trace "^1.0.0" + +create-hash@^1.1.0, create-hash@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-3.0.1.tgz#1256037ecb9f0c5f79e3d6ef135e30770184b982" + integrity sha1-ElYDfsufDF9549bvE14wdwGEuYI= + dependencies: + lru-cache "^4.0.1" + which "^1.2.9" + +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-zip@^2.1.5: + version "2.1.6" + resolved "https://registry.yarnpkg.com/cross-zip/-/cross-zip-2.1.6.tgz#344d3ba9488609942987d815bb84860cff3d9491" + integrity sha512-xLIETNkzRcU6jGRzenJyRFxahbtP4628xEKMTI/Ql0Vu8m4h8M7uRLVi7E5OYHuJ6VQPsG4icJumKAFUvfm0+A== + dependencies: + rimraf "^3.0.0" + +crypt@~0.0.1: + version "0.0.2" + resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" + integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs= + +crypto-browserify@^3.11.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +crypto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/crypto/-/crypto-1.0.1.tgz#2af1b7cad8175d24c8a1b0778255794a21803037" + integrity sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig== + +css-blank-pseudo@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz#dfdefd3254bf8a82027993674ccf35483bfcb3c5" + integrity sha512-LHz35Hr83dnFeipc7oqFDmsjHdljj3TQtxGGiNWSOsTLIAubSm4TEz8qCaKFpk7idaQ1GfWscF4E6mgpBysA1w== + dependencies: + postcss "^7.0.5" + +css-color-names@0.0.4, css-color-names@^0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" + integrity sha1-gIrcLnnPhHOAabZGyyDsJ762KeA= + +css-declaration-sorter@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz#c198940f63a76d7e36c1e71018b001721054cb22" + integrity sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA== + dependencies: + postcss "^7.0.1" + timsort "^0.3.0" + +css-has-pseudo@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/css-has-pseudo/-/css-has-pseudo-0.10.0.tgz#3c642ab34ca242c59c41a125df9105841f6966ee" + integrity sha512-Z8hnfsZu4o/kt+AuFzeGpLVhFOGO9mluyHBaA2bA8aCGTwah5sT3WV/fTHH8UNZUytOIImuGPrl/prlb4oX4qQ== + dependencies: + postcss "^7.0.6" + postcss-selector-parser "^5.0.0-rc.4" + +css-loader@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.9.1.tgz#2e1aa00ce7e30ef2c6a7a4b300a080a7c979e0dc" + integrity sha1-LhqgDOfjDvLGp6SzAKCAp8l54Nw= + dependencies: + csso "1.3.x" + loader-utils "~0.2.2" + source-map "~0.1.38" + +css-mqpacker@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/css-mqpacker/-/css-mqpacker-7.0.0.tgz#48f4a0ff45b81ec661c4a33ed80b9db8a026333b" + integrity sha512-temVrWS+sB4uocE2quhW8ru/KguDmGhCU7zN213KxtDvWOH3WS/ZUStfpF4fdCT7W8fPpFrQdWRFqtFtPPfBLA== + dependencies: + minimist "^1.2.0" + postcss "^7.0.0" + +css-prefers-color-scheme@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz#6f830a2714199d4f0d0d0bb8a27916ed65cff1f4" + integrity sha512-MTu6+tMs9S3EUqzmqLXEcgNRbNkkD/TGFvowpeoWJn5Vfq7FMgsmRQs9X5NXAURiOBmOxm/lLjsDNXDE6k9bhg== + dependencies: + postcss "^7.0.5" + +css-select-base-adapter@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7" + integrity sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w== + +css-select@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.0.2.tgz#ab4386cec9e1f668855564b17c3733b43b2a5ede" + integrity sha512-dSpYaDVoWaELjvZ3mS6IKZM/y2PMPa/XYoEfYNZePL4U/XgyxZNroHEHReDx/d+VgXh9VbCTtFqLkFbmeqeaRQ== + dependencies: + boolbase "^1.0.0" + css-what "^2.1.2" + domutils "^1.7.0" + nth-check "^1.0.2" + +css-tree@1.0.0-alpha.29: + version "1.0.0-alpha.29" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.29.tgz#3fa9d4ef3142cbd1c301e7664c1f352bd82f5a39" + integrity sha512-sRNb1XydwkW9IOci6iB2xmy8IGCj6r/fr+JWitvJ2JxQRPzN3T4AGGVWCMlVmVwM1gtgALJRmGIlWv5ppnGGkg== + dependencies: + mdn-data "~1.1.0" + source-map "^0.5.3" + +css-tree@1.0.0-alpha.33: + version "1.0.0-alpha.33" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.33.tgz#970e20e5a91f7a378ddd0fc58d0b6c8d4f3be93e" + integrity sha512-SPt57bh5nQnpsTBsx/IXbO14sRc9xXu5MtMAVuo0BaQQmyf0NupNPPSoMaqiAF5tDFafYsTkfeH4Q/HCKXkg4w== + dependencies: + mdn-data "2.0.4" + source-map "^0.5.3" + +css-unit-converter@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/css-unit-converter/-/css-unit-converter-1.1.1.tgz#d9b9281adcfd8ced935bdbaba83786897f64e996" + integrity sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY= + +css-what@^2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" + integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== + +cssbeautify@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cssbeautify/-/cssbeautify-0.3.1.tgz#12dd1f734035c2e6faca67dcbdcef74e42811397" + integrity sha1-Et0fc0A1wub6ymfcvc73TkKBE5c= + +cssdb@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-4.4.0.tgz#3bf2f2a68c10f5c6a08abd92378331ee803cddb0" + integrity sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ== + +cssesc@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-2.0.0.tgz#3b13bd1bb1cb36e1bcb5a4dcd27f54c5dcb35703" + integrity sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg== + +csslint@^1.0.2: + version "1.0.5" + resolved "https://registry.yarnpkg.com/csslint/-/csslint-1.0.5.tgz#19cc3eda322160fd3f7232af1cb2a360e898a2e9" + integrity sha1-Gcw+2jIhYP0/cjKvHLKjYOiYouk= + dependencies: + clone "~2.1.0" + parserlib "~1.1.1" + +cssnano-preset-advanced@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/cssnano-preset-advanced/-/cssnano-preset-advanced-4.0.7.tgz#d981527b77712e2f3f3f09c73313e9b71b278b88" + integrity sha512-j1O5/DQnaAqEyFFQfC+Z/vRlLXL3LxJHN+lvsfYqr7KgPH74t69+Rsy2yXkovWNaJjZYBpdz2Fj8ab2nH7pZXw== + dependencies: + autoprefixer "^9.4.7" + cssnano-preset-default "^4.0.7" + postcss-discard-unused "^4.0.1" + postcss-merge-idents "^4.0.1" + postcss-reduce-idents "^4.0.2" + postcss-zindex "^4.0.1" + +cssnano-preset-default@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz#51ec662ccfca0f88b396dcd9679cdb931be17f76" + integrity sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA== + dependencies: + css-declaration-sorter "^4.0.1" + cssnano-util-raw-cache "^4.0.1" + postcss "^7.0.0" + postcss-calc "^7.0.1" + postcss-colormin "^4.0.3" + postcss-convert-values "^4.0.1" + postcss-discard-comments "^4.0.2" + postcss-discard-duplicates "^4.0.2" + postcss-discard-empty "^4.0.1" + postcss-discard-overridden "^4.0.1" + postcss-merge-longhand "^4.0.11" + postcss-merge-rules "^4.0.3" + postcss-minify-font-values "^4.0.2" + postcss-minify-gradients "^4.0.2" + postcss-minify-params "^4.0.2" + postcss-minify-selectors "^4.0.2" + postcss-normalize-charset "^4.0.1" + postcss-normalize-display-values "^4.0.2" + postcss-normalize-positions "^4.0.2" + postcss-normalize-repeat-style "^4.0.2" + postcss-normalize-string "^4.0.2" + postcss-normalize-timing-functions "^4.0.2" + postcss-normalize-unicode "^4.0.1" + postcss-normalize-url "^4.0.1" + postcss-normalize-whitespace "^4.0.2" + postcss-ordered-values "^4.1.2" + postcss-reduce-initial "^4.0.3" + postcss-reduce-transforms "^4.0.2" + postcss-svgo "^4.0.2" + postcss-unique-selectors "^4.0.1" + +cssnano-util-get-arguments@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz#ed3a08299f21d75741b20f3b81f194ed49cc150f" + integrity sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8= + +cssnano-util-get-match@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz#c0e4ca07f5386bb17ec5e52250b4f5961365156d" + integrity sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0= + +cssnano-util-raw-cache@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz#b26d5fd5f72a11dfe7a7846fb4c67260f96bf282" + integrity sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA== + dependencies: + postcss "^7.0.0" + +cssnano-util-same-parent@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz#574082fb2859d2db433855835d9a8456ea18bbf3" + integrity sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q== + +cssnano@^4.1.10: + version "4.1.10" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-4.1.10.tgz#0ac41f0b13d13d465487e111b778d42da631b8b2" + integrity sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ== + dependencies: + cosmiconfig "^5.0.0" + cssnano-preset-default "^4.0.7" + is-resolvable "^1.0.0" + postcss "^7.0.0" + +csso@1.3.x: + version "1.3.12" + resolved "https://registry.yarnpkg.com/csso/-/csso-1.3.12.tgz#fc628694a2d38938aaac4996753218fd311cdb9e" + integrity sha1-/GKGlKLTiTiqrEmWdTIY/TEc254= + +csso@^3.5.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/csso/-/csso-3.5.1.tgz#7b9eb8be61628973c1b261e169d2f024008e758b" + integrity sha512-vrqULLffYU1Q2tLdJvaCYbONStnfkfimRxXNaGjxMldI0C7JPBC4rB1RyjhfdZ4m1frm8pM9uRPKH3d2knZ8gg== + dependencies: + css-tree "1.0.0-alpha.29" + +cssom@0.3.x, cssom@^0.3.4: + version "0.3.8" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" + integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== + +cssstyle@^1.1.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.4.0.tgz#9d31328229d3c565c61e586b02041a28fccdccf1" + integrity sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA== + dependencies: + cssom "0.3.x" + +cuint@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/cuint/-/cuint-0.2.2.tgz#408086d409550c2631155619e9fa7bcadc3b991b" + integrity sha1-QICG1AlVDCYxFVYZ6fp7ytw7mRs= + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= + dependencies: + array-find-index "^1.0.1" + +cyclist@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" + integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= + +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +data-urls@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe" + integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ== + dependencies: + abab "^2.0.0" + whatwg-mimetype "^2.2.0" + whatwg-url "^7.0.0" + +date-now@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" + integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= + +dateformat@^1.0.11, dateformat@^1.0.7-1.2.3: + version "1.0.12" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-1.0.12.tgz#9f124b67594c937ff706932e4a642cca8dbbfee9" + integrity sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk= + dependencies: + get-stdin "^4.0.1" + meow "^3.3.0" + +dateformat@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-2.2.0.tgz#4065e2013cf9fb916ddfd82efb506ad4c6769062" + integrity sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI= + +debug@2.6.9, debug@^2.1.1, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@4.1.1, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@~4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + +debug@=3.1.0, debug@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +debug@^3.1.0, debug@^3.2.6: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + +debug@~0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-0.8.1.tgz#20ff4d26f5e422cb68a1bacbbb61039ad8c1c130" + integrity sha1-IP9NJvXkIstoobrLu2EDmtjBwTA= + +decamelize@^1.1.1, decamelize@^1.1.2, decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +decompress-response@^3.2.0, decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= + dependencies: + mimic-response "^1.0.0" + +decompress-tar@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-3.1.0.tgz#217c789f9b94450efaadc5c5e537978fc333c466" + integrity sha1-IXx4n5uURQ76rcXF5TeXj8MzxGY= + dependencies: + is-tar "^1.0.0" + object-assign "^2.0.0" + strip-dirs "^1.0.0" + tar-stream "^1.1.1" + through2 "^0.6.1" + vinyl "^0.4.3" + +decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1" + integrity sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ== + dependencies: + file-type "^5.2.0" + is-stream "^1.1.0" + tar-stream "^1.5.2" + +decompress-tarbz2@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/decompress-tarbz2/-/decompress-tarbz2-3.1.0.tgz#8b23935681355f9f189d87256a0f8bdd96d9666d" + integrity sha1-iyOTVoE1X58YnYclag+L3ZbZZm0= + dependencies: + is-bzip2 "^1.0.0" + object-assign "^2.0.0" + seek-bzip "^1.0.3" + strip-dirs "^1.0.0" + tar-stream "^1.1.1" + through2 "^0.6.1" + vinyl "^0.4.3" + +decompress-tarbz2@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz#3082a5b880ea4043816349f378b56c516be1a39b" + integrity sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A== + dependencies: + decompress-tar "^4.1.0" + file-type "^6.1.0" + is-stream "^1.1.0" + seek-bzip "^1.0.5" + unbzip2-stream "^1.0.9" + +decompress-targz@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/decompress-targz/-/decompress-targz-3.1.0.tgz#b2c13df98166268991b715d6447f642e9696f5a0" + integrity sha1-ssE9+YFmJomRtxXWRH9kLpaW9aA= + dependencies: + is-gzip "^1.0.0" + object-assign "^2.0.0" + strip-dirs "^1.0.0" + tar-stream "^1.1.1" + through2 "^0.6.1" + vinyl "^0.4.3" + +decompress-targz@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-targz/-/decompress-targz-4.1.1.tgz#c09bc35c4d11f3de09f2d2da53e9de23e7ce1eee" + integrity sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w== + dependencies: + decompress-tar "^4.1.1" + file-type "^5.2.0" + is-stream "^1.1.0" + +decompress-unzip@^3.0.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/decompress-unzip/-/decompress-unzip-3.4.0.tgz#61475b4152066bbe3fee12f9d629d15fe6478eeb" + integrity sha1-YUdbQVIGa74/7hL51inRX+ZHjus= + dependencies: + is-zip "^1.0.0" + read-all-stream "^3.0.0" + stat-mode "^0.2.0" + strip-dirs "^1.0.0" + through2 "^2.0.0" + vinyl "^1.0.0" + yauzl "^2.2.1" + +decompress-unzip@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/decompress-unzip/-/decompress-unzip-4.0.1.tgz#deaaccdfd14aeaf85578f733ae8210f9b4848f69" + integrity sha1-3qrM39FK6vhVePczroIQ+bSEj2k= + dependencies: + file-type "^3.8.0" + get-stream "^2.2.0" + pify "^2.3.0" + yauzl "^2.4.2" + +decompress@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/decompress/-/decompress-3.0.0.tgz#af1dd50d06e3bfc432461d37de11b38c0d991bed" + integrity sha1-rx3VDQbjv8QyRh033hGzjA2ZG+0= + dependencies: + buffer-to-vinyl "^1.0.0" + concat-stream "^1.4.6" + decompress-tar "^3.0.0" + decompress-tarbz2 "^3.0.0" + decompress-targz "^3.0.0" + decompress-unzip "^3.0.0" + stream-combiner2 "^1.1.1" + vinyl-assign "^1.0.1" + vinyl-fs "^2.2.0" + +decompress@^4.0.0, decompress@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/decompress/-/decompress-4.2.0.tgz#7aedd85427e5a92dacfe55674a7c505e96d01f9d" + integrity sha1-eu3YVCflqS2s/lVnSnxQXpbQH50= + dependencies: + decompress-tar "^4.0.0" + decompress-tarbz2 "^4.0.0" + decompress-targz "^4.0.0" + decompress-unzip "^4.0.1" + graceful-fs "^4.1.10" + make-dir "^1.0.0" + pify "^2.3.0" + strip-dirs "^2.0.0" + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + +deep-scope-analyser@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/deep-scope-analyser/-/deep-scope-analyser-1.7.0.tgz#23015b3a1d23181b1d9cebd25b783a7378ead8da" + integrity sha512-rl5Dmt2IZkFpZo6XbEY1zG8st2Wpq8Pi/dV2gz8ZF6BDYt3fnor2JNxHwdO1WLo0k6JbmYp0x8MNy8kE4l1NtA== + dependencies: + esrecurse "^4.2.1" + estraverse "^4.2.0" + +defaults@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" + integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= + dependencies: + clone "^1.0.2" + +defer-to-connect@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.0.2.tgz#4bae758a314b034ae33902b5aac25a8dd6a8633e" + integrity sha512-k09hcQcTDY+cwgiwa6PYKLm3jlagNzQ+RSvhjzESOGOx+MNOuXkxTfEvPrO1IOQ81tArCFYQgi631clB70RpQw== + +define-properties@^1.1.2, define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + +delete-empty@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/delete-empty/-/delete-empty-3.0.0.tgz#f8040f2669f26fa7060bc2304e9859c593b685e8" + integrity sha512-ZUyiwo76W+DYnKsL3Kim6M/UOavPdBJgDYWOmuQhYaZvJH0AXAHbUNyEDtRbBra8wqqr686+63/0azfEk1ebUQ== + dependencies: + ansi-colors "^4.1.0" + minimist "^1.2.0" + path-starts-with "^2.0.0" + rimraf "^2.6.2" + +depd@0.4.5: + version "0.4.5" + resolved "https://registry.yarnpkg.com/depd/-/depd-0.4.5.tgz#1a664b53388b4a6573e8ae67b5f767c693ca97f1" + integrity sha1-GmZLUziLSmVz6K5ntfdnxpPKl/E= + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +deprecated@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/deprecated/-/deprecated-0.0.1.tgz#f9c9af5464afa1e7a971458a8bdef2aa94d5bb19" + integrity sha1-+cmvVGSvoeepcUWKi97yqpTVuxk= + +des.js@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" + integrity sha1-wHTS4qpqipoH29YfmhXCzYPsjsw= + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +detect-file@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" + integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= + +detect-libc@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= + +dev-ip@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/dev-ip/-/dev-ip-1.0.1.tgz#a76a3ed1855be7a012bb8ac16cb80f3c00dc28f0" + integrity sha1-p2o+0YVb56ASu4rBbLgPPADcKPA= + +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +dir-glob@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034" + integrity sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag== + dependencies: + arrify "^1.0.1" + path-type "^3.0.0" + +doctrine@^1.2.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +dom-serializer@0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.1.tgz#13650c850daffea35d8b626a4cfc4d3a17643fdb" + integrity sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q== + dependencies: + domelementtype "^2.0.1" + entities "^2.0.0" + +dom-walk@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" + integrity sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg= + +domain-browser@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== + +domelementtype@1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" + integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== + +domelementtype@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d" + integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ== + +domexception@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" + integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug== + dependencies: + webidl-conversions "^4.0.2" + +domutils@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" + integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== + dependencies: + dom-serializer "0" + domelementtype "1" + +dot-prop@^4.1.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" + integrity sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ== + dependencies: + is-obj "^1.0.0" + +download@^4.0.0, download@^4.1.2: + version "4.4.3" + resolved "https://registry.yarnpkg.com/download/-/download-4.4.3.tgz#aa55fdad392d95d4b68e8c2be03e0c2aa21ba9ac" + integrity sha1-qlX9rTktldS2jowr4D4MKqIbqaw= + dependencies: + caw "^1.0.1" + concat-stream "^1.4.7" + each-async "^1.0.0" + filenamify "^1.0.1" + got "^5.0.0" + gulp-decompress "^1.2.0" + gulp-rename "^1.2.0" + is-url "^1.2.0" + object-assign "^4.0.1" + read-all-stream "^3.0.0" + readable-stream "^2.0.2" + stream-combiner2 "^1.1.1" + vinyl "^1.0.0" + vinyl-fs "^2.2.0" + ware "^1.2.0" + +download@^6.2.2: + version "6.2.5" + resolved "https://registry.yarnpkg.com/download/-/download-6.2.5.tgz#acd6a542e4cd0bb42ca70cfc98c9e43b07039714" + integrity sha512-DpO9K1sXAST8Cpzb7kmEhogJxymyVUd5qz/vCOSyvwtp2Klj2XcDt5YUuasgxka44SxF0q5RriKIwJmQHG2AuA== + dependencies: + caw "^2.0.0" + content-disposition "^0.5.2" + decompress "^4.0.0" + ext-name "^5.0.0" + file-type "5.2.0" + filenamify "^2.0.0" + get-stream "^3.0.0" + got "^7.0.0" + make-dir "^1.0.0" + p-event "^1.0.0" + pify "^3.0.0" + +download@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/download/-/download-7.1.0.tgz#9059aa9d70b503ee76a132897be6dec8e5587233" + integrity sha512-xqnBTVd/E+GxJVrX5/eUJiLYjCGPwMpdL+jGhGU57BvtcA7wwhtHVbXBeUk51kOpW3S7Jn3BQbN9Q1R1Km2qDQ== + dependencies: + archive-type "^4.0.0" + caw "^2.0.1" + content-disposition "^0.5.2" + decompress "^4.2.0" + ext-name "^5.0.0" + file-type "^8.1.0" + filenamify "^2.0.0" + get-stream "^3.0.0" + got "^8.3.1" + make-dir "^1.2.0" + p-event "^2.1.0" + pify "^3.0.0" + +duplexer2@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db" + integrity sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds= + dependencies: + readable-stream "~1.1.9" + +duplexer2@^0.1.4, duplexer2@~0.1.0: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" + integrity sha1-ixLauHjA1p4+eJEFFmKjL8a93ME= + dependencies: + readable-stream "^2.0.2" + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= + +duplexer@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + integrity sha1-rOb/gIwc5mtX0ev5eXessCM0z8E= + +duplexify@^3.2.0, duplexify@^3.4.2, duplexify@^3.5.0, duplexify@^3.6.0: + version "3.7.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +each-async@^1.0.0, each-async@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/each-async/-/each-async-1.1.1.tgz#dee5229bdf0ab6ba2012a395e1b869abf8813473" + integrity sha1-3uUim98KtrogEqOV4bhpq/iBNHM= + dependencies: + onetime "^1.0.0" + set-immediate-shim "^1.0.0" + +easy-extender@^2.3.4: + version "2.3.4" + resolved "https://registry.yarnpkg.com/easy-extender/-/easy-extender-2.3.4.tgz#298789b64f9aaba62169c77a2b3b64b4c9589b8f" + integrity sha512-8cAwm6md1YTiPpOvDULYJL4ZS6WfM5/cTeVVh4JsvyYZAoqlRVUpHL9Gr5Fy7HA6xcSZicUia3DeAgO3Us8E+Q== + dependencies: + lodash "^4.17.10" + +eazy-logger@^3: + version "3.0.2" + resolved "https://registry.yarnpkg.com/eazy-logger/-/eazy-logger-3.0.2.tgz#a325aa5e53d13a2225889b2ac4113b2b9636f4fc" + integrity sha1-oyWqXlPROiIliJsqxBE7K5Y29Pw= + dependencies: + tfunk "^3.0.1" + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +editorconfig@^0.15.3: + version "0.15.3" + resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-0.15.3.tgz#bef84c4e75fb8dcb0ce5cee8efd51c15999befc5" + integrity sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g== + dependencies: + commander "^2.19.0" + lru-cache "^4.1.5" + semver "^5.6.0" + sigmund "^1.0.1" + +ee-first@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.0.5.tgz#8c9b212898d8cd9f1a9436650ce7be202c9e9ff0" + integrity sha1-jJshKJjYzZ8alDZlDOe+ICyen/A= + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +ejs@^2.6.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.1.tgz#5b5ab57f718b79d4aca9254457afecd36fa80228" + integrity sha512-kS/gEPzZs3Y1rRsbGX4UOSjtP/CeJP0CxSNZHYxGfVM/VgLcv0ZqM7C45YyTj2DI2g7+P9Dd24C+IMIg6D0nYQ== + +electron-notarize@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/electron-notarize/-/electron-notarize-0.1.1.tgz#c3563d70c5e7b3315f44e8495b30050a8c408b91" + integrity sha512-TpKfJcz4LXl5jiGvZTs5fbEx+wUFXV5u8voeG5WCHWfY/cdgdD8lDZIZRqLVOtR3VO+drgJ9aiSHIO9TYn/fKg== + dependencies: + debug "^4.1.1" + fs-extra "^8.0.1" + +electron-osx-sign@^0.4.11: + version "0.4.13" + resolved "https://registry.yarnpkg.com/electron-osx-sign/-/electron-osx-sign-0.4.13.tgz#4f77f0ff2f5cd71b91c1e6ce550c3a2937ebbef2" + integrity sha512-+44lasF26lSBLh9HDG6TGpPjuqqtWGD9Pcp+YglE8gyf1OGYdbW8UCIshKPh69O/AcdvDB0ohaTYQz3nbGPbtw== + dependencies: + bluebird "^3.5.0" + compare-version "^0.1.2" + debug "^2.6.8" + isbinaryfile "^3.0.2" + minimist "^1.2.0" + plist "^3.0.1" + +electron-packager@^14.0.6: + version "14.0.6" + resolved "https://registry.yarnpkg.com/electron-packager/-/electron-packager-14.0.6.tgz#e187f2ef83cc29a97a0f940b7c3bb5e4edc8a8e2" + integrity sha512-X+ikV+TnnNkIrK93vOjsjPeykCQBFxBS7LXKMTE1s62rXWirGMdjWL+edVkBOMRkH0ROJyFmWM28Dpj6sfEg+A== + dependencies: + "@electron/get" "^1.3.0" + asar "^2.0.1" + cross-zip "^2.1.5" + debug "^4.0.1" + electron-notarize "^0.1.1" + electron-osx-sign "^0.4.11" + fs-extra "^8.1.0" + galactus "^0.2.1" + get-package-info "^1.0.0" + junk "^3.1.0" + parse-author "^2.0.0" + plist "^3.0.0" + rcedit "^2.0.0" + resolve "^1.1.6" + sanitize-filename "^1.6.0" + semver "^6.0.0" + yargs-parser "^13.0.0" + +electron-to-chromium@^1.3.247: + version "1.3.264" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.264.tgz#ed837f44524d0601a7b2b7b6efd86e35753d0e27" + integrity sha512-z8E7WkrrquCuGYv+kKyybuZIbdms+4PeHp7Zm2uIgEhAigP0bOwqXILItwj0YO73o+QyHY/7XtEfP5DsHOWQgQ== + +elliptic@^6.0.0: + version "6.5.1" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.1.tgz#c380f5f909bf1b9b4428d028cd18d3b0efd6b52b" + integrity sha512-xvJINNLbTeWQjrl6X+7eQCrIy/YPv5XCpKW6kB5mKvtnGILoLDcySuwomfdzt0BMdLNVnuRNTuzKNHj0bva1Cg== + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + +email-validator@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/email-validator/-/email-validator-2.0.4.tgz#b8dfaa5d0dae28f1b03c95881d904d4e40bfe7ed" + integrity sha512-gYCwo7kh5S3IDyZPLZf6hSS0MnZT8QmJFqYvbqlDZSbwdZlY6QZWxJ4i/6UhITOJ4XzyI647Bm2MXKCLqnJ4nQ== + +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + +encodeurl@~1.0.1, encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +encoding@^0.1.11: + version "0.1.12" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" + integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s= + dependencies: + iconv-lite "~0.4.13" + +end-of-stream@^1.0.0, end-of-stream@^1.1.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" + integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== + dependencies: + once "^1.4.0" + +end-of-stream@~0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-0.1.5.tgz#8e177206c3c80837d85632e8b9359dfe8b2f6eaf" + integrity sha1-jhdyBsPICDfYVjLouTWd/osvbq8= + dependencies: + once "~1.3.0" + +engine.io-client@~3.2.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.2.1.tgz#6f54c0475de487158a1a7c77d10178708b6add36" + integrity sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw== + dependencies: + component-emitter "1.2.1" + component-inherit "0.0.3" + debug "~3.1.0" + engine.io-parser "~2.1.1" + has-cors "1.1.0" + indexof "0.0.1" + parseqs "0.0.5" + parseuri "0.0.5" + ws "~3.3.1" + xmlhttprequest-ssl "~1.5.4" + yeast "0.1.2" + +engine.io-client@~3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.4.0.tgz#82a642b42862a9b3f7a188f41776b2deab643700" + integrity sha512-a4J5QO2k99CM2a0b12IznnyQndoEvtA4UAldhGzKqnHf42I3Qs2W5SPnDvatZRcMaNZs4IevVicBPayxYt6FwA== + dependencies: + component-emitter "1.2.1" + component-inherit "0.0.3" + debug "~4.1.0" + engine.io-parser "~2.2.0" + has-cors "1.1.0" + indexof "0.0.1" + parseqs "0.0.5" + parseuri "0.0.5" + ws "~6.1.0" + xmlhttprequest-ssl "~1.5.4" + yeast "0.1.2" + +engine.io-parser@~2.1.0, engine.io-parser@~2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.1.3.tgz#757ab970fbf2dfb32c7b74b033216d5739ef79a6" + integrity sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA== + dependencies: + after "0.8.2" + arraybuffer.slice "~0.0.7" + base64-arraybuffer "0.1.5" + blob "0.0.5" + has-binary2 "~1.0.2" + +engine.io-parser@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.2.0.tgz#312c4894f57d52a02b420868da7b5c1c84af80ed" + integrity sha512-6I3qD9iUxotsC5HEMuuGsKA0cXerGz+4uGcXQEkfBidgKf0amsjrrtwcbwK/nzpZBxclXlV7gGl9dgWvu4LF6w== + dependencies: + after "0.8.2" + arraybuffer.slice "~0.0.7" + base64-arraybuffer "0.1.5" + blob "0.0.5" + has-binary2 "~1.0.2" + +engine.io@~3.2.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-3.2.1.tgz#b60281c35484a70ee0351ea0ebff83ec8c9522a2" + integrity sha512-+VlKzHzMhaU+GsCIg4AoXF1UdDFjHHwMmMKqMJNDNLlUlejz58FCy4LBqB2YVJskHGYl06BatYWKP2TVdVXE5w== + dependencies: + accepts "~1.3.4" + base64id "1.0.0" + cookie "0.3.1" + debug "~3.1.0" + engine.io-parser "~2.1.0" + ws "~3.3.1" + +enhanced-resolve@4.1.0, enhanced-resolve@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f" + integrity sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng== + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.4.0" + tapable "^1.0.0" + +entities@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4" + integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw== + +env-paths@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.0.tgz#cdca557dc009152917d6166e2febe1f039685e43" + integrity sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA== + +errno@^0.1.3, errno@~0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" + integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== + dependencies: + prr "~1.0.1" + +error-ex@^1.2.0, error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.12.0, es-abstract@^1.13.0, es-abstract@^1.5.1: + version "1.14.2" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.14.2.tgz#7ce108fad83068c8783c3cdf62e504e084d8c497" + integrity sha512-DgoQmbpFNOofkjJtKwr87Ma5EW4Dc8fWhD0R+ndq7Oc456ivUfGOOP6oAZTTKl5/CcNMP+EN+e3/iUzgE0veZg== + dependencies: + es-to-primitive "^1.2.0" + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.0" + is-callable "^1.1.4" + is-regex "^1.0.4" + object-inspect "^1.6.0" + object-keys "^1.1.1" + string.prototype.trimleft "^2.0.0" + string.prototype.trimright "^2.0.0" + +es-to-primitive@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" + integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.51, es5-ext@~0.10.14: + version "0.10.51" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.51.tgz#ed2d7d9d48a12df86e0299287e93a09ff478842f" + integrity sha512-oRpWzM2WcLHVKpnrcyB7OW8j/s67Ba04JCm0WnNv3RiABSvs7mrQlutB8DBv793gKcp0XENR8Il8WxGTlZ73gQ== + dependencies: + es6-iterator "~2.0.3" + es6-symbol "~3.1.1" + next-tick "^1.0.0" + +es6-iterator@^2.0.3, es6-iterator@~2.0.1, es6-iterator@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-map@^0.1.3: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" + integrity sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA= + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-set "~0.1.5" + es6-symbol "~3.1.1" + event-emitter "~0.3.5" + +es6-set@~0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" + integrity sha1-0rPsXU2ADO2BjbU40ol02wpzzLE= + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-symbol "3.1.1" + event-emitter "~0.3.5" + +es6-symbol@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" + integrity sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc= + dependencies: + d "1" + es5-ext "~0.10.14" + +es6-symbol@^3.1.1, es6-symbol@~3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.2.tgz#859fdd34f32e905ff06d752e7171ddd4444a7ed1" + integrity sha512-/ZypxQsArlv+KHpGvng52/Iz8by3EQPxhmbuz8yFG89N/caTFBSbcXONDw0aMjy827gQg26XAjP4uXFvnfINmQ== + dependencies: + d "^1.0.1" + es5-ext "^0.10.51" + +es6-templates@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/es6-templates/-/es6-templates-0.2.3.tgz#5cb9ac9fb1ded6eb1239342b81d792bbb4078ee4" + integrity sha1-XLmsn7He1usSOTQrgdeSu7QHjuQ= + dependencies: + recast "~0.11.12" + through "~2.3.6" + +es6-weak-map@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.3.tgz#b6da1f16cc2cc0d9be43e6bdbfc5e7dfcdf31d53" + integrity sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA== + dependencies: + d "1" + es5-ext "^0.10.46" + es6-iterator "^2.0.3" + es6-symbol "^3.1.1" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +escape-string-regexp@^1.0.0, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +escodegen-wallaby@1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/escodegen-wallaby/-/escodegen-wallaby-1.6.18.tgz#95a41e2fdc88687466e43550c7bf136386fd4363" + integrity sha512-3UvR14JRNh8VfKJixTDHWmhPNKAJiVZS807KUjECBk6f05WMe8ZeWL1gbrswNYhDiAUeDBQccyTWR91fayx3og== + dependencies: + esprima "^2.7.1" + estraverse "^1.9.1" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.2.0" + +escodegen-wallaby@1.6.19: + version "1.6.19" + resolved "https://registry.yarnpkg.com/escodegen-wallaby/-/escodegen-wallaby-1.6.19.tgz#acd6bbd73f9270763e18570cdc13c0d694759a23" + integrity sha512-q+JGvR5+NR+EJBLnGAevCk5PIiIhPkUFCvcm6w9MWYtm8sv4FdGUsgzWsY6At/YHkgMyA366sjphA/JTNC8CeQ== + dependencies: + esprima "^2.7.1" + estraverse "^1.9.1" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.2.0" + +escodegen@^1.11.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.12.0.tgz#f763daf840af172bb3a2b6dd7219c0e17f7ff541" + integrity sha512-TuA+EhsanGcme5T3R0L80u4t8CpbXQjegRmf7+FPTJrtCTErXFeelblRgHQa1FofEzqYYJmJ/OqjTwREp9qgmg== + dependencies: + esprima "^3.1.3" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +escope@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" + integrity sha1-4Bl16BJ4GhY6ba392AOY3GTIicM= + dependencies: + es6-map "^0.1.3" + es6-weak-map "^2.0.1" + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-scope@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" + integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-utils@^1.3.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.2.tgz#166a5180ef6ab7eb462f162fd0e6f2463d7309ab" + integrity sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q== + dependencies: + eslint-visitor-keys "^1.0.0" + +eslint-visitor-keys@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" + integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== + +eslint@^2.7.0: + version "2.13.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-2.13.1.tgz#e4cc8fa0f009fb829aaae23855a29360be1f6c11" + integrity sha1-5MyPoPAJ+4KaquI4VaKTYL4fbBE= + dependencies: + chalk "^1.1.3" + concat-stream "^1.4.6" + debug "^2.1.1" + doctrine "^1.2.2" + es6-map "^0.1.3" + escope "^3.6.0" + espree "^3.1.6" + estraverse "^4.2.0" + esutils "^2.0.2" + file-entry-cache "^1.1.1" + glob "^7.0.3" + globals "^9.2.0" + ignore "^3.1.2" + imurmurhash "^0.1.4" + inquirer "^0.12.0" + is-my-json-valid "^2.10.0" + is-resolvable "^1.0.0" + js-yaml "^3.5.1" + json-stable-stringify "^1.0.0" + levn "^0.3.0" + lodash "^4.0.0" + mkdirp "^0.5.0" + optionator "^0.8.1" + path-is-absolute "^1.0.0" + path-is-inside "^1.0.1" + pluralize "^1.2.1" + progress "^1.1.8" + require-uncached "^1.0.2" + shelljs "^0.6.0" + strip-json-comments "~1.0.1" + table "^3.7.8" + text-table "~0.2.0" + user-home "^2.0.0" + +eslint@^5.9.0: + version "5.16.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.16.0.tgz#a1e3ac1aae4a3fbd8296fcf8f7ab7314cbb6abea" + integrity sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg== + dependencies: + "@babel/code-frame" "^7.0.0" + ajv "^6.9.1" + chalk "^2.1.0" + cross-spawn "^6.0.5" + debug "^4.0.1" + doctrine "^3.0.0" + eslint-scope "^4.0.3" + eslint-utils "^1.3.1" + eslint-visitor-keys "^1.0.0" + espree "^5.0.1" + esquery "^1.0.1" + esutils "^2.0.2" + file-entry-cache "^5.0.1" + functional-red-black-tree "^1.0.1" + glob "^7.1.2" + globals "^11.7.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + inquirer "^6.2.2" + js-yaml "^3.13.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.11" + minimatch "^3.0.4" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.2" + progress "^2.0.0" + regexpp "^2.0.1" + semver "^5.5.1" + strip-ansi "^4.0.0" + strip-json-comments "^2.0.1" + table "^5.2.3" + text-table "^0.2.0" + +espree@3.5.4, espree@^3.1.6: + version "3.5.4" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7" + integrity sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A== + dependencies: + acorn "^5.5.0" + acorn-jsx "^3.0.0" + +espree@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-4.0.0.tgz#253998f20a0f82db5d866385799d912a83a36634" + integrity sha512-kapdTCt1bjmspxStVKX6huolXVV5ZfyZguY1lcfhVVZstce3bqxH9mcLzNn3/mlgW6wQ732+0fuG9v7h0ZQoKg== + dependencies: + acorn "^5.6.0" + acorn-jsx "^4.1.1" + +espree@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.1.tgz#5d6526fa4fc7f0788a5cf75b15f30323e2f81f7a" + integrity sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A== + dependencies: + acorn "^6.0.7" + acorn-jsx "^5.0.0" + eslint-visitor-keys "^1.0.0" + +esprima@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" + integrity sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE= + +esprima@^3.1.3, esprima@~3.1.0: + version "3.1.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" + integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM= + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esquery@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" + integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA== + dependencies: + estraverse "^4.0.0" + +esrecurse@^4.1.0, esrecurse@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== + dependencies: + estraverse "^4.1.0" + +estraverse@4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= + +estraverse@^1.9.1: + version "1.9.3" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" + integrity sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q= + +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +etag@1.8.1, etag@^1.8.1, etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +event-emitter@~0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + integrity sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk= + dependencies: + d "1" + es5-ext "~0.10.14" + +eventemitter3@1.x.x: + version "1.2.0" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-1.2.0.tgz#1c86991d816ad1e504750e73874224ecf3bec508" + integrity sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg= + +events@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88" + integrity sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA== + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +exec-buffer@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/exec-buffer/-/exec-buffer-3.2.0.tgz#b1686dbd904c7cf982e652c1f5a79b1e5573082b" + integrity sha512-wsiD+2Tp6BWHoVv3B+5Dcx6E7u5zky+hUwOHjuH2hKSLR3dvRmX8fk8UD8uqQixHs4Wk6eDmiegVrMPjKj7wpA== + dependencies: + execa "^0.7.0" + p-finally "^1.0.0" + pify "^3.0.0" + rimraf "^2.5.4" + tempfile "^2.0.0" + +exec-series@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/exec-series/-/exec-series-1.0.3.tgz#6d257a9beac482a872c7783bc8615839fc77143a" + integrity sha1-bSV6m+rEgqhyx3g7yGFYOfx3FDo= + dependencies: + async-each-series "^1.1.0" + object-assign "^4.1.0" + +execa@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.10.0.tgz#ff456a8f53f90f8eccc71a96d11bdfc7f082cb50" + integrity sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw== + dependencies: + cross-spawn "^6.0.0" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +executable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/executable/-/executable-1.1.0.tgz#877980e9112f3391066da37265de7ad8434ab4d9" + integrity sha1-h3mA6REvM5EGbaNyZd562ENKtNk= + dependencies: + meow "^3.1.0" + +executable@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/executable/-/executable-4.1.1.tgz#41532bff361d3e57af4d763b70582db18f5d133c" + integrity sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg== + dependencies: + pify "^2.2.0" + +exif-parser@^0.1.12: + version "0.1.12" + resolved "https://registry.yarnpkg.com/exif-parser/-/exif-parser-0.1.12.tgz#58a9d2d72c02c1f6f02a0ef4a9166272b7760922" + integrity sha1-WKnS1ywCwfbwKg70qRZicrd2CSI= + +exit-hook@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" + integrity sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g= + +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + integrity sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s= + dependencies: + is-posix-bracket "^0.1.0" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= + dependencies: + fill-range "^2.1.0" + +expand-tilde@^2.0.0, expand-tilde@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" + integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI= + dependencies: + homedir-polyfill "^1.0.1" + +express@^4.16.3: + version "4.17.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" + integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== + dependencies: + accepts "~1.3.7" + array-flatten "1.1.1" + body-parser "1.19.0" + content-disposition "0.5.3" + content-type "~1.0.4" + cookie "0.4.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "~1.1.2" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.5" + qs "6.7.0" + range-parser "~1.2.1" + safe-buffer "5.1.2" + send "0.17.1" + serve-static "1.14.1" + setprototypeof "1.1.1" + statuses "~1.5.0" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +ext-list@^2.0.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/ext-list/-/ext-list-2.2.2.tgz#0b98e64ed82f5acf0f2931babf69212ef52ddd37" + integrity sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA== + dependencies: + mime-db "^1.28.0" + +ext-name@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ext-name/-/ext-name-5.0.0.tgz#70781981d183ee15d13993c8822045c506c8f0a6" + integrity sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ== + dependencies: + ext-list "^2.0.0" + sort-keys-length "^1.0.0" + +extend-shallow@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-1.1.4.tgz#19d6bf94dfc09d76ba711f39b872d21ff4dd9071" + integrity sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE= + dependencies: + kind-of "^1.1.0" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@^3.0.0, extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +external-editor@^2.0.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" + integrity sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A== + dependencies: + chardet "^0.4.0" + iconv-lite "^0.4.17" + tmp "^0.0.33" + +external-editor@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" + integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + integrity sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE= + dependencies: + is-extglob "^1.0.0" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + +fancy-log@^1.1.0, fancy-log@^1.2.0, fancy-log@^1.3.2, fancy-log@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.3.tgz#dbc19154f558690150a23953a0adbd035be45fc7" + integrity sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw== + dependencies: + ansi-gray "^0.1.1" + color-support "^1.1.3" + parse-node-version "^1.0.0" + time-stamp "^1.0.0" + +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= + +fast-deep-equal@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" + integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== + +fast-glob@^2.0.2: + version "2.2.7" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d" + integrity sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw== + dependencies: + "@mrmlnc/readdir-enhanced" "^2.2.1" + "@nodelib/fs.stat" "^1.1.2" + glob-parent "^3.1.0" + is-glob "^4.0.0" + merge2 "^1.2.3" + micromatch "^3.1.10" + +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= + +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +fastdom@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/fastdom/-/fastdom-1.0.9.tgz#b395fab11a3701173c02a054fe769d8f596a0a26" + integrity sha512-SSp4fbVzu8JkkG01NUX+0iOwe9M5PN3MGIQ84txLf4TkkJG4q30khkzumKgi4hUqO1+jX6wLHfnCPoZ6eSZ6Tg== + dependencies: + strictdom "^1.0.1" + +faster.js@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/faster.js/-/faster.js-1.1.1.tgz#8bbd7eefdb8f03faac26ad5025b059f94c5cfb4d" + integrity sha512-vPThNSLL/E1f7cLHd9yuayxZR82o/Iic4S5ZY45iY5AgBLNIlr3b3c+VpDjoYqjY9a9C/FQVUQy9oTILVP7X0g== + +fastparse@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9" + integrity sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ== + +faye-websocket@~0.7.2: + version "0.7.3" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.7.3.tgz#cc4074c7f4a4dfd03af54dd65c354b135132ce11" + integrity sha1-zEB0x/Sk39A69U3WXDVLE1EyzhE= + dependencies: + websocket-driver ">=0.3.6" + +fd-slicer@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" + integrity sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4= + dependencies: + pend "~1.2.0" + +figgy-pudding@^3.5.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" + integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w== + +figures@^1.3.5: + version "1.7.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + integrity sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4= + dependencies: + escape-string-regexp "^1.0.5" + object-assign "^4.1.0" + +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^1.1.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-1.3.1.tgz#44c61ea607ae4be9c1402f41f44270cbfe334ff8" + integrity sha1-RMYepgeuS+nBQC9B9EJwy/4zT/g= + dependencies: + flat-cache "^1.2.1" + object-assign "^4.0.1" + +file-entry-cache@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" + integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== + dependencies: + flat-cache "^2.0.1" + +file-loader@^0.8.1: + version "0.8.5" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-0.8.5.tgz#9275d031fe780f27d47f5f4af02bd43713cc151b" + integrity sha1-knXQMf54DyfUf19K8CvUNxPMFRs= + dependencies: + loader-utils "~0.2.5" + +file-type@5.2.0, file-type@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-5.2.0.tgz#2ddbea7c73ffe36368dfae49dc338c058c2b8ad6" + integrity sha1-LdvqfHP/42No365J3DOMBYwritY= + +file-type@^10.4.0, file-type@^10.7.0: + version "10.11.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-10.11.0.tgz#2961d09e4675b9fb9a3ee6b69e9cd23f43fd1890" + integrity sha512-uzk64HRpUZyTGZtVuvrjP0FYxzQrBf4rojot6J65YMEbwBLB0CWm0CLojVpwpmFmxcE/lkvYICgfcGozbBq6rw== + +file-type@^3.1.0, file-type@^3.8.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" + integrity sha1-JXoHg4TR24CHvESdEH1SpSZyuek= + +file-type@^4.2.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-4.4.0.tgz#1b600e5fca1fbdc6e80c0a70c71c8dba5f7906c5" + integrity sha1-G2AOX8ofvcboDApwxxyNul95BsU= + +file-type@^6.1.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919" + integrity sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg== + +file-type@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-8.1.0.tgz#244f3b7ef641bbe0cca196c7276e4b332399f68c" + integrity sha512-qyQ0pzAy78gVoJsmYeNgl8uH8yKhr1lVhW7JbzJmnlRi0I4R2eEDEJZVKG8agpDnLpacwNbDhLNG/LMdxHD2YQ== + +file-type@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-9.0.0.tgz#a68d5ad07f486414dfb2c8866f73161946714a18" + integrity sha512-Qe/5NJrgIOlwijpq3B7BEpzPFcgzggOTagZmkXQY4LA6bsXKTUstK7Wp12lEJ/mLKTpvIZxmIuRcLYWT6ov9lw== + +filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY= + +filename-reserved-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-1.0.0.tgz#e61cf805f0de1c984567d0386dc5df50ee5af7e4" + integrity sha1-5hz4BfDeHJhFZ9A4bcXfUO5a9+Q= + +filename-reserved-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz#abf73dfab735d045440abfea2d91f389ebbfa229" + integrity sha1-q/c9+rc10EVECr/qLZHzieu/oik= + +filenamify@^1.0.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/filenamify/-/filenamify-1.2.1.tgz#a9f2ffd11c503bed300015029272378f1f1365a5" + integrity sha1-qfL/0RxQO+0wABUCknI3jx8TZaU= + dependencies: + filename-reserved-regex "^1.0.0" + strip-outer "^1.0.0" + trim-repeated "^1.0.0" + +filenamify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/filenamify/-/filenamify-2.1.0.tgz#88faf495fb1b47abfd612300002a16228c677ee9" + integrity sha512-ICw7NTT6RsDp2rnYKVd8Fu4cr6ITzGy3+u4vUujPkabyaz+03F24NWEX7fs5fp+kBonlaqPH8fAO2NM+SXt/JA== + dependencies: + filename-reserved-regex "^2.0.0" + strip-outer "^1.0.0" + trim-repeated "^1.0.0" + +filesize@^3.6.1: + version "3.6.1" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317" + integrity sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg== + +fill-range@^2.1.0: + version "2.2.4" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" + integrity sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q== + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^3.0.0" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +finalhandler@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.0.tgz#ce0b6855b45853e791b2fcc680046d88253dd7f5" + integrity sha1-zgtoVbRYU+eRsvzGgARtiCU91/U= + dependencies: + debug "2.6.9" + encodeurl "~1.0.1" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.2" + statuses "~1.3.1" + unpipe "~1.0.0" + +finalhandler@1.1.2, finalhandler@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + +find-cache-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" + integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== + dependencies: + commondir "^1.0.1" + make-dir "^2.0.0" + pkg-dir "^3.0.0" + +find-index@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/find-index/-/find-index-0.1.1.tgz#675d358b2ca3892d795a1ab47232f8b6e2e0dde4" + integrity sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ= + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +find-versions@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-1.2.1.tgz#cbde9f12e38575a0af1be1b9a2c5d5fd8f186b62" + integrity sha1-y96fEuOFdaCvG+G5osXV/Y8Ya2I= + dependencies: + array-uniq "^1.0.0" + get-stdin "^4.0.1" + meow "^3.5.0" + semver-regex "^1.0.0" + +find-versions@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-3.1.0.tgz#10161f29cf3eb4350dec10a29bdde75bff0df32d" + integrity sha512-NCTfNiVzeE/xL+roNDffGuRbrWI6atI18lTJ22vKp7rs2OhYzMK3W1dIdO2TUndH/QMcacM4d1uWwgcZcHK69Q== + dependencies: + array-uniq "^2.1.0" + semver-regex "^2.0.0" + +findup-sync@3.0.0, findup-sync@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1" + integrity sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg== + dependencies: + detect-file "^1.0.0" + is-glob "^4.0.0" + micromatch "^3.0.4" + resolve-dir "^1.0.1" + +findup-sync@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc" + integrity sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw= + dependencies: + detect-file "^1.0.0" + is-glob "^3.1.0" + micromatch "^3.0.4" + resolve-dir "^1.0.1" + +fined@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fined/-/fined-1.2.0.tgz#d00beccf1aa2b475d16d423b0238b713a2c4a37b" + integrity sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng== + dependencies: + expand-tilde "^2.0.2" + is-plain-object "^2.0.3" + object.defaults "^1.1.0" + object.pick "^1.2.0" + parse-filepath "^1.0.1" + +first-chunk-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz#59bfb50cd905f60d7c394cd3d9acaab4e6ad934e" + integrity sha1-Wb+1DNkF9g18OUzT2ayqtOatk04= + +flagged-respawn@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/flagged-respawn/-/flagged-respawn-1.0.1.tgz#e7de6f1279ddd9ca9aac8a5971d618606b3aab41" + integrity sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q== + +flat-cache@^1.2.1: + version "1.3.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.4.tgz#2c2ef77525cc2929007dfffa1dd314aa9c9dee6f" + integrity sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg== + dependencies: + circular-json "^0.3.1" + graceful-fs "^4.1.2" + rimraf "~2.6.2" + write "^0.2.1" + +flat-cache@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" + integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== + dependencies: + flatted "^2.0.0" + rimraf "2.6.3" + write "1.0.3" + +flatted@^2.0.0, flatted@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.1.tgz#69e57caa8f0eacbc281d2e2cb458d46fdb449e08" + integrity sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg== + +flatten@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" + integrity sha1-2uRqnXj74lKSJYzB54CkHZXAN4I= + +flora-colossus@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/flora-colossus/-/flora-colossus-1.0.1.tgz#aba198425a8185341e64f9d2a6a96fd9a3cbdb93" + integrity sha512-d+9na7t9FyH8gBJoNDSi28mE4NgQVGGvxQ4aHtFRetjyh5SXjuus+V5EZaxFmFdXVemSOrx0lsgEl/ZMjnOWJA== + dependencies: + debug "^4.1.1" + fs-extra "^7.0.0" + +fluent-ffmpeg@^2.0.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/fluent-ffmpeg/-/fluent-ffmpeg-2.1.2.tgz#c952de2240f812ebda0aa8006d7776ee2acf7d74" + integrity sha1-yVLeIkD4EuvaCqgAbXd27irPfXQ= + dependencies: + async ">=0.2.9" + which "^1.1.1" + +flush-write-stream@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" + integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== + dependencies: + inherits "^2.0.3" + readable-stream "^2.3.6" + +follow-redirects@1.5.10: + version "1.5.10" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" + integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== + dependencies: + debug "=3.1.0" + +for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + +for-in@^1.0.1, for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4= + dependencies: + for-in "^1.0.1" + +for-own@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-1.0.0.tgz#c63332f415cedc4b04dbfe70cf836494c53cb44b" + integrity sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs= + dependencies: + for-in "^1.0.1" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +fork-stream@^0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/fork-stream/-/fork-stream-0.0.4.tgz#db849fce77f6708a5f8f386ae533a0907b54ae70" + integrity sha1-24Sfznf2cIpfjzhq5TOgkHtUrnA= + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + dependencies: + map-cache "^0.2.2" + +fresh@0.5.2, fresh@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +from2@^2.1.0, from2@^2.1.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +front-matter@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/front-matter/-/front-matter-2.1.2.tgz#f75983b9f2f413be658c93dfd7bd8ce4078f5cdb" + integrity sha1-91mDufL0E75ljJPf172M5AePXNs= + dependencies: + js-yaml "^3.4.6" + +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + +fs-extra@3.0.1, fs-extra@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-3.0.1.tgz#3794f378c58b342ea7dbbb23095109c4b3b62291" + integrity sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE= + dependencies: + graceful-fs "^4.1.2" + jsonfile "^3.0.0" + universalify "^0.1.0" + +fs-extra@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" + integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" + integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^8.0.1, fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-minipass@^1.2.5: + version "1.2.7" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" + integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== + dependencies: + minipass "^2.6.0" + +fs-write-stream-atomic@^1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@^1.2.7: + version "1.2.9" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.9.tgz#3f5ed66583ccd6f400b5a00db6f7e861363e388f" + integrity sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw== + dependencies: + nan "^2.12.1" + node-pre-gyp "^0.12.0" + +fstream@^1.0.0, fstream@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" + integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg== + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +galactus@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/galactus/-/galactus-0.2.1.tgz#cbed2d20a40c1f5679a35908e2b9415733e78db9" + integrity sha1-y+0tIKQMH1Z5o1kI4rlBVzPnjbk= + dependencies: + debug "^3.1.0" + flora-colossus "^1.0.0" + fs-extra "^4.0.0" + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + 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" + +gaze@^0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/gaze/-/gaze-0.5.2.tgz#40b709537d24d1d45767db5a908689dfe69ac44f" + integrity sha1-QLcJU30k0dRXZ9takIaJ3+aaxE8= + dependencies: + globule "~0.1.0" + +gaze@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/gaze/-/gaze-1.1.3.tgz#c441733e13b927ac8c0ff0b4c3b033f28812924a" + integrity sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g== + dependencies: + globule "^1.0.0" + +generate-function@^2.0.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.3.1.tgz#f069617690c10c868e73b8465746764f97c3479f" + integrity sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ== + dependencies: + is-property "^1.0.2" + +generate-object-property@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" + integrity sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA= + dependencies: + is-property "^1.0.0" + +gensync@^1.0.0-beta.1: + version "1.0.0-beta.1" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" + integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg== + +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-package-info@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/get-package-info/-/get-package-info-1.0.0.tgz#6432796563e28113cd9474dbbd00052985a4999c" + integrity sha1-ZDJ5ZWPigRPNlHTbvQAFKYWkmZw= + dependencies: + bluebird "^3.1.1" + debug "^2.2.0" + lodash.get "^4.0.0" + read-pkg-up "^2.0.0" + +get-proxy@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/get-proxy/-/get-proxy-1.1.0.tgz#894854491bc591b0f147d7ae570f5c678b7256eb" + integrity sha1-iUhUSRvFkbDxR9euVw9cZ4tyVus= + dependencies: + rc "^1.1.2" + +get-proxy@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/get-proxy/-/get-proxy-2.1.0.tgz#349f2b4d91d44c4d4d4e9cba2ad90143fac5ef93" + integrity sha512-zmZIaQTWnNQb4R4fJUEp/FC51eZsc6EkErspy3xtIYStaq8EB/hDIWipxsal+E8rz0qD7f2sL/NA9Xee4RInJw== + dependencies: + npm-conf "^1.1.0" + +get-stdin@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" + integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= + +get-stream@3.0.0, get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= + +get-stream@^2.2.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" + integrity sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4= + dependencies: + object-assign "^4.0.1" + pinkie-promise "^2.0.0" + +get-stream@^4.0.0, get-stream@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-stream@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.1.0.tgz#01203cdc92597f9b909067c3e656cc1f4d3c4dc9" + integrity sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw== + dependencies: + pump "^3.0.0" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + +gifsicle@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/gifsicle/-/gifsicle-4.0.1.tgz#30e1e61e3ee4884ef702641b2e98a15c2127b2e2" + integrity sha512-A/kiCLfDdV+ERV/UB+2O41mifd+RxH8jlRG8DMxZO84Bma/Fw0htqZ+hY2iaalLRNyUu7tYZQslqUBJxBggxbg== + dependencies: + bin-build "^3.0.0" + bin-wrapper "^4.0.0" + execa "^1.0.0" + logalot "^2.0.0" + +glob-all@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-all/-/glob-all-3.1.0.tgz#8913ddfb5ee1ac7812656241b03d5217c64b02ab" + integrity sha1-iRPd+17hrHgSZWJBsD1SF8ZLAqs= + dependencies: + glob "^7.0.5" + yargs "~1.2.6" + +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q= + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg= + dependencies: + is-glob "^2.0.0" + +glob-parent@^3.0.0, glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-stream@^3.1.5: + version "3.1.18" + resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-3.1.18.tgz#9170a5f12b790306fdfe598f313f8f7954fd143b" + integrity sha1-kXCl8St5Awb9/lmPMT+PeVT9FDs= + dependencies: + glob "^4.3.1" + glob2base "^0.0.12" + minimatch "^2.0.1" + ordered-read-streams "^0.1.0" + through2 "^0.6.1" + unique-stream "^1.0.0" + +glob-stream@^5.3.2: + version "5.3.5" + resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-5.3.5.tgz#a55665a9a8ccdc41915a87c701e32d4e016fad22" + integrity sha1-pVZlqajM3EGRWofHAeMtTgFvrSI= + dependencies: + extend "^3.0.0" + glob "^5.0.3" + glob-parent "^3.0.0" + micromatch "^2.3.7" + ordered-read-streams "^0.3.0" + through2 "^0.6.0" + to-absolute-glob "^0.1.1" + unique-stream "^2.0.2" + +glob-to-regexp@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" + integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= + +glob-watcher@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/glob-watcher/-/glob-watcher-0.0.6.tgz#b95b4a8df74b39c83298b0c05c978b4d9a3b710b" + integrity sha1-uVtKjfdLOcgymLDAXJeLTZo7cQs= + dependencies: + gaze "^0.5.1" + +glob2base@^0.0.12: + version "0.0.12" + resolved "https://registry.yarnpkg.com/glob2base/-/glob2base-0.0.12.tgz#9d419b3e28f12e83a362164a277055922c9c0d56" + integrity sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY= + dependencies: + find-index "^0.1.1" + +glob@^4.3.1: + version "4.5.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-4.5.3.tgz#c6cb73d3226c1efef04de3c56d012f03377ee15f" + integrity sha1-xstz0yJsHv7wTePFbQEvAzd+4V8= + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "^2.0.1" + once "^1.3.0" + +glob@^5.0.3: + version "5.0.15" + resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" + integrity sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E= + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@~7.1.1: + version "7.1.4" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" + integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== + dependencies: + 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" + +glob@~3.1.21: + version "3.1.21" + resolved "https://registry.yarnpkg.com/glob/-/glob-3.1.21.tgz#d29e0a055dea5138f4d07ed40e8982e83c2066cd" + integrity sha1-0p4KBV3qUTj00H7UDomC6DwgZs0= + dependencies: + graceful-fs "~1.2.0" + inherits "1" + minimatch "~0.2.11" + +glob@~3.2.6: + version "3.2.11" + resolved "https://registry.yarnpkg.com/glob/-/glob-3.2.11.tgz#4a973f635b9190f715d10987d5c00fd2815ebe3d" + integrity sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0= + dependencies: + inherits "2" + minimatch "0.3" + +global-modules@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" + integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== + dependencies: + global-prefix "^3.0.0" + +global-modules@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" + integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg== + dependencies: + global-prefix "^1.0.1" + is-windows "^1.0.1" + resolve-dir "^1.0.0" + +global-prefix@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" + integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4= + dependencies: + expand-tilde "^2.0.2" + homedir-polyfill "^1.0.1" + ini "^1.3.4" + is-windows "^1.0.1" + which "^1.2.14" + +global-prefix@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97" + integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg== + dependencies: + ini "^1.3.5" + kind-of "^6.0.2" + which "^1.3.1" + +global@~4.3.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f" + integrity sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8= + dependencies: + min-document "^2.19.0" + process "~0.5.1" + +globals@^11.1.0, globals@^11.7.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globals@^9.2.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== + +globby@^8.0.1: + version "8.0.2" + resolved "https://registry.yarnpkg.com/globby/-/globby-8.0.2.tgz#5697619ccd95c5275dbb2d6faa42087c1a941d8d" + integrity sha512-yTzMmKygLp8RUpG1Ymu2VXPSJQZjNAZPD4ywgYEaG7e4tBJeUQBO8OpXrf1RCNcEs5alsoJYPAMiIHP0cmeC7w== + dependencies: + array-union "^1.0.1" + dir-glob "2.0.0" + fast-glob "^2.0.2" + glob "^7.1.2" + ignore "^3.3.5" + pify "^3.0.0" + slash "^1.0.0" + +globule@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.1.tgz#5dffb1b191f22d20797a9369b49eab4e9839696d" + integrity sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ== + dependencies: + glob "~7.1.1" + lodash "~4.17.10" + minimatch "~3.0.2" + +globule@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/globule/-/globule-0.1.0.tgz#d9c8edde1da79d125a151b79533b978676346ae5" + integrity sha1-2cjt3h2nnRJaFRt5UzuXhnY0auU= + dependencies: + glob "~3.1.21" + lodash "~1.0.1" + minimatch "~0.2.11" + +glogg@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.2.tgz#2d7dd702beda22eb3bffadf880696da6d846313f" + integrity sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA== + dependencies: + sparkles "^1.0.0" + +gonzales-pe-sl@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/gonzales-pe-sl/-/gonzales-pe-sl-4.2.3.tgz#6a868bc380645f141feeb042c6f97fcc71b59fe6" + integrity sha1-aoaLw4BkXxQf7rBCxvl/zHG1n+Y= + dependencies: + minimist "1.1.x" + +gonzales-pe@^4.2.3: + version "4.2.4" + resolved "https://registry.yarnpkg.com/gonzales-pe/-/gonzales-pe-4.2.4.tgz#356ae36a312c46fe0f1026dd6cb539039f8500d2" + integrity sha512-v0Ts/8IsSbh9n1OJRnSfa7Nlxi4AkXIsWB6vPept8FDbL4bXn3FNuxjYtO/nmBGu7GDkL9MFeGebeSu6l55EPQ== + dependencies: + minimist "1.1.x" + +google-libphonenumber@^3.1.6: + version "3.2.5" + resolved "https://registry.yarnpkg.com/google-libphonenumber/-/google-libphonenumber-3.2.5.tgz#2ebe6437fd3dbbffd65f4339ad1ba93b3dc56836" + integrity sha512-Y0r7MFCI11UDLn0KaMPBEInhROyIOkWkQIyvWMFVF2I+h+sHE3vbl5a7FVe39td6u/w+nlKDdUMP9dMOZyv+2Q== + +got@^5.0.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/got/-/got-5.7.1.tgz#5f81635a61e4a6589f180569ea4e381680a51f35" + integrity sha1-X4FjWmHkplifGAVp6k44FoClHzU= + dependencies: + create-error-class "^3.0.1" + duplexer2 "^0.1.4" + is-redirect "^1.0.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + lowercase-keys "^1.0.0" + node-status-codes "^1.0.0" + object-assign "^4.0.1" + parse-json "^2.1.0" + pinkie-promise "^2.0.0" + read-all-stream "^3.0.0" + readable-stream "^2.0.5" + timed-out "^3.0.0" + unzip-response "^1.0.2" + url-parse-lax "^1.0.0" + +got@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a" + integrity sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw== + dependencies: + decompress-response "^3.2.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + is-plain-obj "^1.1.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + isurl "^1.0.0-alpha5" + lowercase-keys "^1.0.0" + p-cancelable "^0.3.0" + p-timeout "^1.1.1" + safe-buffer "^5.0.1" + timed-out "^4.0.0" + url-parse-lax "^1.0.0" + url-to-options "^1.0.1" + +got@^8.3.1: + version "8.3.2" + resolved "https://registry.yarnpkg.com/got/-/got-8.3.2.tgz#1d23f64390e97f776cac52e5b936e5f514d2e937" + integrity sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw== + dependencies: + "@sindresorhus/is" "^0.7.0" + cacheable-request "^2.1.1" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + into-stream "^3.1.0" + is-retry-allowed "^1.1.0" + isurl "^1.0.0-alpha5" + lowercase-keys "^1.0.0" + mimic-response "^1.0.0" + p-cancelable "^0.4.0" + p-timeout "^2.0.1" + pify "^3.0.0" + safe-buffer "^5.1.1" + timed-out "^4.0.1" + url-parse-lax "^3.0.0" + url-to-options "^1.0.1" + +got@^9.6.0: + version "9.6.0" + resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" + integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== + dependencies: + "@sindresorhus/is" "^0.14.0" + "@szmarczak/http-timer" "^1.1.2" + cacheable-request "^6.0.0" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^4.1.0" + lowercase-keys "^1.0.1" + mimic-response "^1.0.1" + p-cancelable "^1.0.0" + to-readable-stream "^1.0.0" + url-parse-lax "^3.0.0" + +graceful-fs@^3.0.0: + version "3.0.12" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-3.0.12.tgz#0034947ce9ed695ec8ab0b854bc919e82b1ffaef" + integrity sha512-J55gaCS4iTTJfTXIxSVw3EMQckcqkpdRv3IR7gu6sq0+tbC363Zx6KH/SEwXASK9JRbhyZmVjJEVJIOxYsB3Qg== + dependencies: + natives "^1.1.3" + +graceful-fs@^4.0.0, graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0: + version "4.2.2" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.2.tgz#6f0952605d0140c1cfdb138ed005775b92d67b02" + integrity sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q== + +graceful-fs@~1.2.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-1.2.3.tgz#15a4806a57547cb2d2dbf27f42e89a8c3451b364" + integrity sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q= + +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= + +gulp-cache@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/gulp-cache/-/gulp-cache-1.1.3.tgz#7c427670aad4d25364c3cc9c53e492b348190d27" + integrity sha512-NE814LdX1NWQn2sMzn+Rf673o4mqlgg7OyLf92oQ4KEl6DdPfduEGLNH+HexLVcFZXH93DBuxFOvpv4/Js5VaA== + dependencies: + "@babel/runtime" "^7.5.5" + cache-swap "^0.3.0" + core-js "3" + object.pick "^1.3.0" + plugin-error "^1.0.1" + through2 "3.0.1" + vinyl "^2.2.0" + +gulp-cached@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/gulp-cached/-/gulp-cached-1.1.1.tgz#fe7cd4f87f37601e6073cfedee5c2bdaf8b6acce" + integrity sha1-/nzU+H83YB5gc8/t7lwr2vi2rM4= + dependencies: + lodash.defaults "^4.2.0" + through2 "^2.0.1" + +gulp-clean@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/gulp-clean/-/gulp-clean-0.4.0.tgz#3bc25e7084e641bbd7bde057cf90c01c50d95950" + integrity sha512-DARK8rNMo4lHOFLGTiHEJdf19GuoBDHqGUaypz+fOhrvOs3iFO7ntdYtdpNxv+AzSJBx/JfypF0yEj9ks1IStQ== + dependencies: + fancy-log "^1.3.2" + plugin-error "^0.1.2" + rimraf "^2.6.2" + through2 "^2.0.3" + vinyl "^2.1.0" + +gulp-cssbeautify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gulp-cssbeautify/-/gulp-cssbeautify-1.0.1.tgz#136903ab47e8d6c14ec1306acd1064433c5cc592" + integrity sha512-6eMR1sqbdm0O5WLdnM3nDxFJc4XkdOJcYDPv2XGnDeSF05ed3PpJlJNVTBW+l5Yl6m9tUn6L17x/vnjx9MALwA== + dependencies: + cssbeautify "^0.3.1" + plugin-error "^1.0.1" + through2 "^2.0.3" + +gulp-csslint@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gulp-csslint/-/gulp-csslint-1.0.1.tgz#112a908f7aef98efc27b7bd00801f13a77becb93" + integrity sha512-Rec56+RpCGg7feK3d/S45oqgxyLV3end0ed+UjWFv6YziQae2Bp4DNSDobwEvJdfCAsOhOSExEEB+jcfMx430w== + dependencies: + csslint "^1.0.2" + fancy-log "^1.3.2" + plugin-error "^1.0.1" + rcloader "^0.2.1" + through2 "^2.0.1" + vinyl "^2.1.0" + +gulp-decompress@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/gulp-decompress/-/gulp-decompress-1.2.0.tgz#8eeb65a5e015f8ed8532cafe28454960626f0dc7" + integrity sha1-jutlpeAV+O2FMsr+KEVJYGJvDcc= + dependencies: + archive-type "^3.0.0" + decompress "^3.0.0" + gulp-util "^3.0.1" + readable-stream "^2.0.2" + +gulp-dom@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gulp-dom/-/gulp-dom-1.0.0.tgz#f834d5299c09b85e11c32505044a2ebe86ae1375" + integrity sha512-hD2w2t3fsjPicX2mT6MFFb+eP3FyCVtEHdejGMMH4+w9EBFxA2xIZadqlzYdAEdE+39dP1aGatuhdHJteUvn1A== + dependencies: + jsdom "12.2.0" + plugin-error "1.0.1" + through2 "2.0.3" + +gulp-flatten@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/gulp-flatten/-/gulp-flatten-0.4.0.tgz#d9ac819416c30fd5dfb3dea9da79c83a1bcd61d1" + integrity sha512-eg4spVTAiv1xXmugyaCxWne1oPtNG0UHEtABx5W8ScLiqAYceyYm6GYA36x0Qh8KOIXmAZV97L2aYGnKREG3Sg== + dependencies: + plugin-error "^0.1.2" + through2 "^2.0.0" + +gulp-fluent-ffmpeg@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/gulp-fluent-ffmpeg/-/gulp-fluent-ffmpeg-1.0.2.tgz#1521b803254f17598274162cc536ae2a9b7cb8f7" + integrity sha1-FSG4AyVPF1mCdBYsxTauKpt8uPc= + dependencies: + concat-stream "^1.4.8" + fluent-ffmpeg "^2.0.1" + gulp-util "^3.0.4" + through2 "^0.6.5" + +gulp-html-beautify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gulp-html-beautify/-/gulp-html-beautify-1.0.1.tgz#2834c6f77669605726eee55e3205f63074b7a152" + integrity sha1-KDTG93ZpYFcm7uVeMgX2MHS3oVI= + dependencies: + js-beautify "^1.5.10" + rcloader "^0.1.4" + through2 "^2.0.0" + +gulp-htmlmin@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/gulp-htmlmin/-/gulp-htmlmin-5.0.1.tgz#90fc5e8ad0425a9e86d5d521427184e7276365e7" + integrity sha512-ASlyDPZOSKjHYUifYV0rf9JPDflN9IRIb8lw2vRqtYMC4ljU3zAmnnaVXwFQ3H+CfXxZSUesZ2x7jrnPJu93jA== + dependencies: + html-minifier "^3.5.20" + plugin-error "^1.0.1" + through2 "^2.0.3" + +gulp-if@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/gulp-if/-/gulp-if-2.0.2.tgz#a497b7e7573005041caa2bc8b7dda3c80444d629" + integrity sha1-pJe351cwBQQcqivIt92jyARE1ik= + dependencies: + gulp-match "^1.0.3" + ternary-stream "^2.0.1" + through2 "^2.0.1" + +gulp-imagemin@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/gulp-imagemin/-/gulp-imagemin-5.0.3.tgz#b8236aff523eebd2d4b552a814a35df07ee710bc" + integrity sha512-bKJMix4r6EQPVV2u8sUglw6Rn0PSp6i70pSK2ECN7j0dRy0w/Lz5SBbynY3MfGBZ0cTMZlaUq+6LyKlZgP74Ew== + dependencies: + chalk "^2.4.1" + fancy-log "^1.3.2" + imagemin "^6.0.0" + plugin-error "^1.0.1" + plur "^3.0.1" + pretty-bytes "^5.1.0" + through2-concurrent "^2.0.0" + optionalDependencies: + imagemin-gifsicle "^6.0.1" + imagemin-jpegtran "^6.0.0" + imagemin-optipng "^6.0.0" + imagemin-svgo "^7.0.0" + +gulp-javascript-obfuscator@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/gulp-javascript-obfuscator/-/gulp-javascript-obfuscator-1.1.6.tgz#4615ce5adb6a0f846246aacea8e1402d8fe04e06" + integrity sha512-oiROhi7Zlu/0fM2h20jBFPaDOZicilT6kN+97Si82yieeFqr6l70o2R3gZ2Ah0u8v5IqGa+Pt8c2q3UnkMuk2A== + dependencies: + javascript-obfuscator latest + plugin-error "^1.0.1" + through2 "^2.0.0" + vinyl "^2.2.0" + +gulp-jsbeautifier@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/gulp-jsbeautifier/-/gulp-jsbeautifier-3.0.1.tgz#4b26991e0adf063130452c5d74910239fadbf254" + integrity sha512-zSXsXQy0/s6qjhhtTun+/ZfC/q8cz/fZpZmxoGPKpmxjuP7/F+oGpV/LHqtOAaWNo+WjcxLVey0cFoNrPZiHWg== + dependencies: + ansi-colors "^4.1.1" + cosmiconfig "^5.2.1" + fancy-log "^1.3.3" + js-beautify "^1.10.1" + lodash.mergewith "^4.6.2" + plugin-error "^1.0.1" + through2 "^3.0.1" + +gulp-load-plugins@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/gulp-load-plugins/-/gulp-load-plugins-1.6.0.tgz#2d060c42faf481141ef638431572923d8701bd0d" + integrity sha512-HlCODki0WHJvQIgAsJYOTkyo0c7TsDCetvfhrdGz9JYPL6A4mFRMGmKfoi6JmXjA/vvzg+fkT91c9FBh7rnkyg== + dependencies: + array-unique "^0.2.1" + fancy-log "^1.2.0" + findup-sync "^3.0.0" + gulplog "^1.0.0" + has-gulplog "^0.1.0" + micromatch "^3.1.10" + resolve "^1.1.7" + +gulp-match@^1.0.3: + version "1.1.0" + resolved "https://registry.yarnpkg.com/gulp-match/-/gulp-match-1.1.0.tgz#552b7080fc006ee752c90563f9fec9d61aafdf4f" + integrity sha512-DlyVxa1Gj24DitY2OjEsS+X6tDpretuxD6wTfhXE/Rw2hweqc1f6D/XtsJmoiCwLWfXgR87W9ozEityPCVzGtQ== + dependencies: + minimatch "^3.0.3" + +gulp-multi-process@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/gulp-multi-process/-/gulp-multi-process-1.3.1.tgz#e12aa818e4c234357ad99d5caff8df8a18f46e9e" + integrity sha512-okxYy3mxUkekM0RNjkBg8OPuzpnD2yXMAdnGOaQPSJ2wzBdE9R9pkTV+tzPZ65ORK7b57YUc6s+gROA4+EIOLg== + dependencies: + async.queue "^0.5.2" + +gulp-phonegap-build@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/gulp-phonegap-build/-/gulp-phonegap-build-0.1.5.tgz#36c145e63cd204702be0f3b99be19e096712bcaf" + integrity sha1-NsFF5jzSBHAr4PO5m+GeCWcSvK8= + dependencies: + archiver "~0.11.0" + gulp "~3.8.7" + gulp-util "~3.0.0" + lodash "~2.4.1" + needle "" + read "~1.0.4" + through2 "~0.6.1" + vinyl-buffer "0.0.0" + vinyl-source-stream "^0.1.1" + +gulp-plumber@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/gulp-plumber/-/gulp-plumber-1.2.1.tgz#d38700755a300b9d372318e4ffb5ff7ced0b2c84" + integrity sha512-mctAi9msEAG7XzW5ytDVZ9PxWMzzi1pS2rBH7lA095DhMa6KEXjm+St0GOCc567pJKJ/oCvosVAZEpAey0q2eQ== + dependencies: + chalk "^1.1.3" + fancy-log "^1.3.2" + plugin-error "^0.1.2" + through2 "^2.0.3" + +gulp-pngquant@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/gulp-pngquant/-/gulp-pngquant-1.0.12.tgz#48db0a5a99d923d74d3f292b55ef38fba531eae1" + integrity sha512-fGdXZtxnH4gM+Pa0wt9EceGwHDYN6lANkY3ISufb5K5GHvKJ5JK07kARYqoulb5HzyeerJxHLTd1QyP7diQE7A== + dependencies: + chalk "1.1.3" + gulp-util "3.0.7" + pngquant-bin "3.1.1" + through2 "2.0.1" + +gulp-postcss@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/gulp-postcss/-/gulp-postcss-8.0.0.tgz#8d3772cd4d27bca55ec8cb4c8e576e3bde4dc550" + integrity sha512-Wtl6vH7a+8IS/fU5W9IbOpcaLqKxd5L1DUOzaPmlnCbX1CrG0aWdwVnC3Spn8th0m8D59YbysV5zPUe1n/GJYg== + dependencies: + fancy-log "^1.3.2" + plugin-error "^1.0.1" + postcss "^7.0.2" + postcss-load-config "^2.0.0" + vinyl-sourcemaps-apply "^0.2.1" + +gulp-rename@^1.2.0, gulp-rename@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/gulp-rename/-/gulp-rename-1.4.0.tgz#de1c718e7c4095ae861f7296ef4f3248648240bd" + integrity sha512-swzbIGb/arEoFK89tPY58vg3Ok1bw+d35PfUNwWqdo7KM4jkmuGA78JiDNqR+JeZFaeeHnRg9N7aihX3YPmsyg== + +gulp-sass-lint@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/gulp-sass-lint/-/gulp-sass-lint-1.4.0.tgz#6f7096c5abcbc0ce99ddf060c9e1a99067a47ebe" + integrity sha512-XerYvHx7rznInkedMw5Ayif+p8EhysOVHUBvlgUa0FSl88H2cjNjaRZ3NGn5Efmp+2HxpXp4NHqMIbOSdwef3A== + dependencies: + plugin-error "^0.1.2" + sass-lint "^1.12.0" + through2 "^2.0.2" + +gulp-sass@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/gulp-sass/-/gulp-sass-4.0.2.tgz#cfb1e3eff2bd9852431c7ce87f43880807d8d505" + integrity sha512-q8psj4+aDrblJMMtRxihNBdovfzGrXJp1l4JU0Sz4b/Mhsi2DPrKFYCGDwjIWRENs04ELVHxdOJQ7Vs98OFohg== + dependencies: + chalk "^2.3.0" + lodash.clonedeep "^4.3.2" + node-sass "^4.8.3" + plugin-error "^1.0.1" + replace-ext "^1.0.0" + strip-ansi "^4.0.0" + through2 "^2.0.0" + vinyl-sourcemaps-apply "^0.2.0" + +gulp-sequence@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gulp-sequence/-/gulp-sequence-1.0.0.tgz#862f93e6503e67c350a42948fa666953cf88ba67" + integrity sha512-c+p+EcyBl1UCpbfFA/vUD6MuC7uxoY6Y4g2lq9lLtzOHh9o1wijAQ4o0TIRQ14C7cG6zR6Zi+bpA0cW78CFt6g== + dependencies: + thunks "^4.9.0" + +gulp-sftp@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/gulp-sftp/-/gulp-sftp-0.1.5.tgz#57afec28b23823465d9ac44deba2f02de8dc5c70" + integrity sha1-V6/sKLI4I0ZdmsRN66LwLejcXHA= + dependencies: + async "~0.9.0" + gulp-util "~3.0.0" + object-assign "~0.3.1" + parents "~1.0.0" + ssh2 "~0.3.3" + through2 "~0.4.2" + +gulp-sourcemaps@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/gulp-sourcemaps/-/gulp-sourcemaps-1.6.0.tgz#b86ff349d801ceb56e1d9e7dc7bbcb4b7dee600c" + integrity sha1-uG/zSdgBzrVuHZ59x7vLS33uYAw= + dependencies: + convert-source-map "^1.1.1" + graceful-fs "^4.1.2" + strip-bom "^2.0.0" + through2 "^2.0.0" + vinyl "^1.0.0" + +gulp-terser@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/gulp-terser/-/gulp-terser-1.2.0.tgz#41df2a1d0257d011ba8b05efb2568432ecd0495b" + integrity sha512-lf+jE2DALg2w32p0HRiYMlFYRYelKZPNunHp2pZccCYrrdCLOs0ItbZcN63yr2pbz116IyhUG9mD/QbtRO1FKA== + dependencies: + plugin-error "^1.0.1" + terser "^4.0.0" + through2 "^3.0.1" + vinyl-sourcemaps-apply "^0.2.1" + +gulp-util@3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-3.0.7.tgz#78925c4b8f8b49005ac01a011c557e6218941cbb" + integrity sha1-eJJcS4+LSQBawBoBHFV+YhiUHLs= + dependencies: + array-differ "^1.0.0" + array-uniq "^1.0.2" + beeper "^1.0.0" + chalk "^1.0.0" + dateformat "^1.0.11" + fancy-log "^1.1.0" + gulplog "^1.0.0" + has-gulplog "^0.1.0" + lodash._reescape "^3.0.0" + lodash._reevaluate "^3.0.0" + lodash._reinterpolate "^3.0.0" + lodash.template "^3.0.0" + minimist "^1.1.0" + multipipe "^0.1.2" + object-assign "^3.0.0" + replace-ext "0.0.1" + through2 "^2.0.0" + vinyl "^0.5.0" + +gulp-util@^2.2.19: + version "2.2.20" + resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-2.2.20.tgz#d7146e5728910bd8f047a6b0b1e549bc22dbd64c" + integrity sha1-1xRuVyiRC9jwR6awseVJvCLb1kw= + dependencies: + chalk "^0.5.0" + dateformat "^1.0.7-1.2.3" + lodash._reinterpolate "^2.4.1" + lodash.template "^2.4.1" + minimist "^0.2.0" + multipipe "^0.1.0" + through2 "^0.5.0" + vinyl "^0.2.1" + +gulp-util@^3.0.0, gulp-util@^3.0.1, gulp-util@^3.0.4, gulp-util@~3.0.0: + version "3.0.8" + resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-3.0.8.tgz#0054e1e744502e27c04c187c3ecc505dd54bbb4f" + integrity sha1-AFTh50RQLifATBh8PsxQXdVLu08= + dependencies: + array-differ "^1.0.0" + array-uniq "^1.0.2" + beeper "^1.0.0" + chalk "^1.0.0" + dateformat "^2.0.0" + fancy-log "^1.1.0" + gulplog "^1.0.0" + has-gulplog "^0.1.0" + lodash._reescape "^3.0.0" + lodash._reevaluate "^3.0.0" + lodash._reinterpolate "^3.0.0" + lodash.template "^3.0.0" + minimist "^1.1.0" + multipipe "^0.1.2" + object-assign "^3.0.0" + replace-ext "0.0.1" + through2 "^2.0.0" + vinyl "^0.5.0" + +gulp-webserver@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/gulp-webserver/-/gulp-webserver-0.9.1.tgz#e09992165d97c5865616d642a1601529b0367064" + integrity sha1-4JmSFl2XxYZWFtZCoWAVKbA2cGQ= + dependencies: + connect "^3.0.1" + connect-livereload "^0.4.0" + gulp-util "^2.2.19" + isarray "0.0.1" + node.extend "^1.0.10" + open "^0.0.5" + proxy-middleware "^0.5.0" + serve-index "^1.1.4" + serve-static "^1.3.0" + through2 "^0.5.1" + tiny-lr "0.1.4" + watch "^0.11.0" + +gulp@^3.9.1: + version "3.9.1" + resolved "https://registry.yarnpkg.com/gulp/-/gulp-3.9.1.tgz#571ce45928dd40af6514fc4011866016c13845b4" + integrity sha1-VxzkWSjdQK9lFPxAEYZgFsE4RbQ= + dependencies: + archy "^1.0.0" + chalk "^1.0.0" + deprecated "^0.0.1" + gulp-util "^3.0.0" + interpret "^1.0.0" + liftoff "^2.1.0" + minimist "^1.1.0" + orchestrator "^0.3.0" + pretty-hrtime "^1.0.0" + semver "^4.1.0" + tildify "^1.0.0" + v8flags "^2.0.2" + vinyl-fs "^0.3.0" + +gulp@~3.8.7: + version "3.8.11" + resolved "https://registry.yarnpkg.com/gulp/-/gulp-3.8.11.tgz#d557e0a7283eb4136491969b0497767972f1d28a" + integrity sha1-1Vfgpyg+tBNkkZabBJd2eXLx0oo= + dependencies: + archy "^1.0.0" + chalk "^0.5.0" + deprecated "^0.0.1" + gulp-util "^3.0.0" + interpret "^0.3.2" + liftoff "^2.0.1" + minimist "^1.1.0" + orchestrator "^0.3.0" + pretty-hrtime "^0.2.0" + semver "^4.1.0" + tildify "^1.0.0" + v8flags "^2.0.2" + vinyl-fs "^0.3.0" + +gulplog@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gulplog/-/gulplog-1.0.0.tgz#e28c4d45d05ecbbed818363ce8f9c5926229ffe5" + integrity sha1-4oxNRdBey77YGDY86PnFkmIp/+U= + dependencies: + glogg "^1.0.0" + +gzip-size@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.1.1.tgz#cb9bee692f87c0612b232840a873904e4c135274" + integrity sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA== + dependencies: + duplexer "^0.1.1" + pify "^4.0.1" + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.0: + version "5.1.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" + integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== + dependencies: + ajv "^6.5.5" + har-schema "^2.0.0" + +has-ansi@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-0.1.0.tgz#84f265aae8c0e6a88a12d7022894b7568894c62e" + integrity sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4= + dependencies: + ansi-regex "^0.2.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + +has-binary2@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-binary2/-/has-binary2-1.0.3.tgz#7776ac627f3ea77250cfc332dab7ddf5e4f5d11d" + integrity sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw== + dependencies: + isarray "2.0.1" + +has-cors@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-cors/-/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39" + integrity sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk= + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-gulplog@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/has-gulplog/-/has-gulplog-0.1.0.tgz#6414c82913697da51590397dafb12f22967811ce" + integrity sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4= + dependencies: + sparkles "^1.0.0" + +has-symbol-support-x@^1.4.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" + integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw== + +has-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" + integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= + +has-to-string-tag-x@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" + integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw== + dependencies: + has-symbol-support-x "^1.4.1" + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has@^1.0.0, has@^1.0.1, has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hash-base@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" + integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +he@1.2.x: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +hex-color-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" + integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ== + +hmac-drbg@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +homedir-polyfill@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" + integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== + dependencies: + parse-passwd "^1.0.0" + +hoopy@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/hoopy/-/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d" + integrity sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ== + +hosted-git-info@^2.1.4: + version "2.8.4" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.4.tgz#44119abaf4bc64692a16ace34700fed9c03e2546" + integrity sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ== + +howler@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/howler/-/howler-2.1.2.tgz#8433a09d8fe84132a3e726e05cb2bd352ef8bd49" + integrity sha512-oKrTFaVXsDRoB/jik7cEpWKTj7VieoiuzMYJ7E/EU5ayvmpRhumCv3YQ3823zi9VTJkSWAhbryHnlZAionGAJg== + +hsl-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/hsl-regex/-/hsl-regex-1.0.0.tgz#d49330c789ed819e276a4c0d272dffa30b18fe6e" + integrity sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4= + +hsla-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/hsla-regex/-/hsla-regex-1.0.0.tgz#c1ce7a3168c8c6614033a4b5f7877f3b225f9c38" + integrity sha1-wc56MWjIxmFAM6S194d/OyJfnDg= + +html-comment-regex@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7" + integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ== + +html-encoding-sniffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" + integrity sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw== + dependencies: + whatwg-encoding "^1.0.1" + +html-loader@^0.5.5: + version "0.5.5" + resolved "https://registry.yarnpkg.com/html-loader/-/html-loader-0.5.5.tgz#6356dbeb0c49756d8ebd5ca327f16ff06ab5faea" + integrity sha512-7hIW7YinOYUpo//kSYcPB6dCKoceKLmOwjEMmhIobHuWGDVl0Nwe4l68mdG/Ru0wcUxQjVMEoZpkalZ/SE7zog== + dependencies: + es6-templates "^0.2.3" + fastparse "^1.1.1" + html-minifier "^3.5.8" + loader-utils "^1.1.0" + object-assign "^4.1.1" + +html-minifier@^3.5.20, html-minifier@^3.5.8: + version "3.5.21" + resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-3.5.21.tgz#d0040e054730e354db008463593194015212d20c" + integrity sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA== + dependencies: + camel-case "3.0.x" + clean-css "4.2.x" + commander "2.17.x" + he "1.2.x" + param-case "2.1.x" + relateurl "0.2.x" + uglify-js "3.4.x" + +http-cache-semantics@3.8.1: + version "3.8.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" + integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== + +http-cache-semantics@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.0.3.tgz#495704773277eeef6e43f9ab2c2c7d259dda25c5" + integrity sha512-TcIMG3qeVLgDr1TEd2XvHaTnMPwYQUQMIBLy+5pLSDKYFc7UIqj39w8EGzZkaxoLv/l2K8HaI0t5AVA+YYgUew== + +http-errors@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" + integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-errors@1.7.3, http-errors@~1.7.2: + version "1.7.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +"http-parser-js@>=0.4.0 <0.4.11": + version "0.4.10" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.10.tgz#92c9c1374c35085f75db359ec56cc257cbb93fa4" + integrity sha1-ksnBN0w1CF912zWexWzCV8u5P6Q= + +http-proxy@1.15.2: + version "1.15.2" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.15.2.tgz#642fdcaffe52d3448d2bda3b0079e9409064da31" + integrity sha1-ZC/cr/5S00SNK9o7AHnpQJBk2jE= + dependencies: + eventemitter3 "1.x.x" + requires-port "1.x.x" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= + +iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.4.tgz#e95f2e41db0735fc21652f7827a5ee32e63c83a8" + integrity sha1-6V8uQdsHNfwhZS94J6XuMuY8g6g= + +ieee754@^1.1.4: + version "1.1.13" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" + integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== + +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= + +ignore-loader@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ignore-loader/-/ignore-loader-0.1.2.tgz#d81f240376d0ba4f0d778972c3ad25874117a463" + integrity sha1-2B8kA3bQuk8Nd4lyw60lh0EXpGM= + +ignore-walk@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.2.tgz#99d83a246c196ea5c93ef9315ad7b0819c35069b" + integrity sha512-EXyErtpHbn75ZTsOADsfx6J/FPo6/5cjev46PXrcTpd8z3BoRkXgYu9/JVqrI7tusjmwCZutGeRJeU0Wo1e4Cw== + dependencies: + minimatch "^3.0.4" + +ignore@^3.1.2, ignore@^3.3.5: + version "3.3.10" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" + integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== + +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +imagemin-gifsicle@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/imagemin-gifsicle/-/imagemin-gifsicle-6.0.1.tgz#6abad4e95566d52e5a104aba1c24b4f3b48581b3" + integrity sha512-kuu47c6iKDQ6R9J10xCwL0lgs0+sMz3LRHqRcJ2CRBWdcNmo3T5hUaM8hSZfksptZXJLGKk8heSAvwtSdB1Fng== + dependencies: + exec-buffer "^3.0.0" + gifsicle "^4.0.0" + is-gif "^3.0.0" + +imagemin-jpegtran@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/imagemin-jpegtran/-/imagemin-jpegtran-6.0.0.tgz#c8d3bcfb6ec9c561c20a987142854be70d90b04f" + integrity sha512-Ih+NgThzqYfEWv9t58EItncaaXIHR0u9RuhKa8CtVBlMBvY0dCIxgQJQCfwImA4AV1PMfmUKlkyIHJjb7V4z1g== + dependencies: + exec-buffer "^3.0.0" + is-jpg "^2.0.0" + jpegtran-bin "^4.0.0" + +imagemin-mozjpeg@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/imagemin-mozjpeg/-/imagemin-mozjpeg-8.0.0.tgz#d2ca4e8c982c7c6eda55069af89dee4c1cebcdfd" + integrity sha512-+EciPiIjCb8JWjQNr1q8sYWYf7GDCNDxPYnkD11TNIjjWNzaV+oTg4DpOPQjl5ZX/KRCPMEgS79zLYAQzLitIA== + dependencies: + execa "^1.0.0" + is-jpg "^2.0.0" + mozjpeg "^6.0.0" + +imagemin-optipng@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/imagemin-optipng/-/imagemin-optipng-6.0.0.tgz#a6bfc7b542fc08fc687e83dfb131249179a51a68" + integrity sha512-FoD2sMXvmoNm/zKPOWdhKpWdFdF9qiJmKC17MxZJPH42VMAp17/QENI/lIuP7LCUnLVAloO3AUoTSNzfhpyd8A== + dependencies: + exec-buffer "^3.0.0" + is-png "^1.0.0" + optipng-bin "^5.0.0" + +imagemin-pngquant@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/imagemin-pngquant/-/imagemin-pngquant-8.0.0.tgz#bf7a41d850c6998f2475c54058ab1db9c516385d" + integrity sha512-PVq0diOxO+Zyq/zlMCz2Pfu6mVLHgiT1GpW702OwVlnej+NhS6ZQegYi3OFEDW8d7GxouyR5e8R+t53SMciOeg== + dependencies: + execa "^1.0.0" + is-png "^2.0.0" + is-stream "^2.0.0" + ow "^0.13.2" + pngquant-bin "^5.0.0" + +imagemin-svgo@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/imagemin-svgo/-/imagemin-svgo-7.0.0.tgz#a22d0a5917a0d0f37e436932c30f5e000fa91b1c" + integrity sha512-+iGJFaPIMx8TjFW6zN+EkOhlqcemdL7F3N3Y0wODvV2kCUBuUtZK7DRZc1+Zfu4U2W/lTMUyx2G8YMOrZntIWg== + dependencies: + is-svg "^3.0.0" + svgo "^1.0.5" + +imagemin@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/imagemin/-/imagemin-6.1.0.tgz#62508b465728fea36c03cdc07d915fe2d8cf9e13" + integrity sha512-8ryJBL1CN5uSHpiBMX0rJw79C9F9aJqMnjGnrd/1CafegpNuA81RBAAru/jQQEOWlOJJlpRnlcVFF6wq+Ist0A== + dependencies: + file-type "^10.7.0" + globby "^8.0.1" + make-dir "^1.0.0" + p-pipe "^1.1.0" + pify "^4.0.1" + replace-ext "^1.0.0" + +immutable@^3: + version "3.8.2" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.2.tgz#c2439951455bb39913daf281376f1530e104adf3" + integrity sha1-wkOZUUVbs5kT2vKBN28VMOEErfM= + +import-cwd@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9" + integrity sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk= + dependencies: + import-from "^2.1.0" + +import-fresh@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" + integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= + dependencies: + caller-path "^2.0.0" + resolve-from "^3.0.0" + +import-fresh@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.1.0.tgz#6d33fa1dcef6df930fae003446f33415af905118" + integrity sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +import-from@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-from/-/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1" + integrity sha1-M1238qev/VOqpHHUuAId7ja387E= + dependencies: + resolve-from "^3.0.0" + +import-lazy@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-3.1.0.tgz#891279202c8a2280fdbd6674dbd8da1a1dfc67cc" + integrity sha512-8/gvXvX2JMn0F+CDlSC4l6kOmVaLOO3XLkksI7CI3Ud95KDYJuYur2b9P/PUt/i/pDAMd/DulQsNbbbmRRsDIQ== + +import-local@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" + integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== + dependencies: + pkg-dir "^3.0.0" + resolve-cwd "^2.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +in-publish@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/in-publish/-/in-publish-2.0.0.tgz#e20ff5e3a2afc2690320b6dc552682a9c7fadf51" + integrity sha1-4g/146KvwmkDILbcVSaCqcf631E= + +indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA= + dependencies: + repeating "^2.0.0" + +indexes-of@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" + integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= + +indexof@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" + integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10= + +infer-owner@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-1.0.2.tgz#ca4309dadee6b54cc0b8d247e8d7c7a0975bdc9b" + integrity sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js= + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + +inquirer@3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.0.6.tgz#e04aaa9d05b7a3cb9b0f407d04375f0447190347" + integrity sha1-4EqqnQW3o8ubD0B9BDdfBEcZA0c= + dependencies: + ansi-escapes "^1.1.0" + chalk "^1.0.0" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^2.0.1" + figures "^2.0.0" + lodash "^4.3.0" + mute-stream "0.0.7" + run-async "^2.2.0" + rx "^4.1.0" + string-width "^2.0.0" + strip-ansi "^3.0.0" + through "^2.3.6" + +inquirer@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e" + integrity sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34= + dependencies: + ansi-escapes "^1.1.0" + ansi-regex "^2.0.0" + chalk "^1.0.0" + cli-cursor "^1.0.1" + cli-width "^2.0.0" + figures "^1.3.5" + lodash "^4.3.0" + readline2 "^1.0.1" + run-async "^0.1.0" + rx-lite "^3.1.2" + string-width "^1.0.1" + strip-ansi "^3.0.0" + through "^2.3.6" + +inquirer@^6.2.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" + integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ== + dependencies: + ansi-escapes "^3.2.0" + chalk "^2.4.2" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^3.0.3" + figures "^2.0.0" + lodash "^4.17.12" + mute-stream "0.0.7" + run-async "^2.2.0" + rxjs "^6.4.0" + string-width "^2.1.0" + strip-ansi "^5.1.0" + through "^2.3.6" + +interpret@1.2.0, interpret@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" + integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw== + +interpret@^0.3.2: + version "0.3.10" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-0.3.10.tgz#088c25de731c6c5b112a90f0071cfaf459e5a7bb" + integrity sha1-CIwl3nMcbFsRKpDwBxz69Fnlp7s= + +into-stream@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-3.1.0.tgz#96fb0a936c12babd6ff1752a17d05616abd094c6" + integrity sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY= + dependencies: + from2 "^2.1.1" + p-is-promise "^1.1.0" + +invariant@^2.2.2: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + +inversify@4.11.1: + version "4.11.1" + resolved "https://registry.yarnpkg.com/inversify/-/inversify-4.11.1.tgz#9a10635d1fd347da11da96475b3608babd5945a6" + integrity sha512-9bs/36crPdTSOCcoomHMb96s+B8W0+2c9dHFP/Srv9ZQaPnUvsMgzmMHfgVECqfHVUIW+M5S7SYOjoig8khWuQ== + +inversify@4.13.0: + version "4.13.0" + resolved "https://registry.yarnpkg.com/inversify/-/inversify-4.13.0.tgz#0ab40570bfa4474b04d5b919bbab3a4f682a72f5" + integrity sha512-O5d8y7gKtyRwrvTLZzYET3kdFjqUy58sGpBYMARF13mzqDobpfBXVOPLH7HmnD2VR6Q+1HzZtslGvsdQfeb0SA== + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= + +invert-kv@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" + integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== + +ip-regex@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-1.0.3.tgz#dc589076f659f419c222039a33316f1c7387effd" + integrity sha1-3FiQdvZZ9BnCIgOaMzFvHHOH7/0= + +ipaddr.js@1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.0.tgz#37df74e430a0e47550fe54a2defe30d8acd95f65" + integrity sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA== + +irregular-plurals@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/irregular-plurals/-/irregular-plurals-2.0.0.tgz#39d40f05b00f656d0b7fa471230dd3b714af2872" + integrity sha512-Y75zBYLkh0lJ9qxeHlMjQ7bSbyiSqNW/UOPWDmzC7cXskL1hekSITh1Oc6JV0XCWWZ9DE8VYSB71xocLk3gmGw== + +is-absolute-url@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" + integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY= + +is-absolute@^0.1.5: + version "0.1.7" + resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-0.1.7.tgz#847491119fccb5fb436217cc737f7faad50f603f" + integrity sha1-hHSREZ/MtftDYhfMc39/qtUPYD8= + dependencies: + is-relative "^0.1.0" + +is-absolute@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576" + integrity sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA== + dependencies: + is-relative "^1.0.0" + is-windows "^1.0.1" + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= + dependencies: + binary-extensions "^1.0.0" + +is-buffer@^1.1.5, is-buffer@~1.1.1: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-buffer@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.3.tgz#4ecf3fcf749cbd1e472689e109ac66261a25e725" + integrity sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw== + +is-bzip2@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-bzip2/-/is-bzip2-1.0.0.tgz#5ee58eaa5a2e9c80e21407bedf23ae5ac091b3fc" + integrity sha1-XuWOqlounIDiFAe+3yOuWsCRs/w= + +is-callable@^1.1.3, is-callable@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" + integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== + +is-color-stop@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-color-stop/-/is-color-stop-1.1.0.tgz#cfff471aee4dd5c9e158598fbe12967b5cdad345" + integrity sha1-z/9HGu5N1cnhWFmPvhKWe1za00U= + dependencies: + css-color-names "^0.0.4" + hex-color-regex "^1.1.0" + hsl-regex "^1.0.0" + hsla-regex "^1.0.0" + rgb-regex "^1.0.1" + rgba-regex "^1.0.0" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-date-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-directory@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= + +is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE= + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + integrity sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ= + dependencies: + is-primitive "^2.0.0" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-finite@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + integrity sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-function@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5" + integrity sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU= + +is-gif@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-gif/-/is-gif-3.0.0.tgz#c4be60b26a301d695bb833b20d9b5d66c6cf83b1" + integrity sha512-IqJ/jlbw5WJSNfwQ/lHEDXF8rxhRgF6ythk2oiEvhpG29F704eX9NO6TvPfMiq9DrbwgcEDnETYNcZDPewQoVw== + dependencies: + file-type "^10.4.0" + +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= + dependencies: + is-extglob "^1.0.0" + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-gzip@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-gzip/-/is-gzip-1.0.0.tgz#6ca8b07b99c77998025900e555ced8ed80879a83" + integrity sha1-bKiwe5nHeZgCWQDlVc7Y7YCHmoM= + +is-jpg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-jpg/-/is-jpg-2.0.0.tgz#2e1997fa6e9166eaac0242daae443403e4ef1d97" + integrity sha1-LhmX+m6RZuqsAkLarkQ0A+TvHZc= + +is-my-ip-valid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz#7b351b8e8edd4d3995d4d066680e664d94696824" + integrity sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ== + +is-my-json-valid@^2.10.0: + version "2.20.0" + resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.20.0.tgz#1345a6fca3e8daefc10d0fa77067f54cedafd59a" + integrity sha512-XTHBZSIIxNsIsZXg7XB5l8z/OBFosl1Wao4tXLpeC7eKU4Vm/kdop2azkPqULwnfGQjmeDIyey9g7afMMtdWAA== + dependencies: + generate-function "^2.0.0" + generate-object-property "^1.1.0" + is-my-ip-valid "^1.0.0" + jsonpointer "^4.0.0" + xtend "^4.0.0" + +is-natural-number@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-2.1.1.tgz#7d4c5728377ef386c3e194a9911bf57c6dc335e7" + integrity sha1-fUxXKDd+84bD4ZSpkRv1fG3DNec= + +is-natural-number@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8" + integrity sha1-q5124dtM7VHjXeDHLr7PCfc0zeg= + +is-number-like@^1.0.3: + version "1.0.8" + resolved "https://registry.yarnpkg.com/is-number-like/-/is-number-like-1.0.8.tgz#2e129620b50891042e44e9bbbb30593e75cfbbe3" + integrity sha512-6rZi3ezCyFcn5L71ywzz2bS5b2Igl1En3eTlZlvKjpz1n3IZLAYMbKYAIQgFmEu0GENg92ziU/faEOA/aixjbA== + dependencies: + lodash.isfinite "^3.3.2" + +is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8= + dependencies: + kind-of "^3.0.2" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-number@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== + +is-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= + +is-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" + integrity sha1-iVJojF7C/9awPsyF52ngKQMINHA= + +is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= + +is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-png@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-png/-/is-png-1.1.0.tgz#d574b12bf275c0350455570b0e5b57ab062077ce" + integrity sha1-1XSxK/J1wDUEVVcLDltXqwYgd84= + +is-png@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-png/-/is-png-2.0.0.tgz#ee8cbc9e9b050425cedeeb4a6fb74a649b0a4a8d" + integrity sha512-4KPGizaVGj2LK7xwJIz8o5B2ubu1D/vcQsgOGFEDlpcvgZHto4gBnyd0ig7Ws+67ixmwKoNmu0hYnpo6AaKb5g== + +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + integrity sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q= + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU= + +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= + +is-property@^1.0.0, is-property@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + integrity sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ= + +is-redirect@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" + integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ= + +is-regex@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= + dependencies: + has "^1.0.1" + +is-relative@^0.1.0: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-0.1.3.tgz#905fee8ae86f45b3ec614bc3c15c869df0876e82" + integrity sha1-kF/uiuhvRbPsYUvDwVyGnfCHboI= + +is-relative@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d" + integrity sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA== + dependencies: + is-unc-path "^1.0.0" + +is-resolvable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" + integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== + +is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" + integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== + +is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" + integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== + +is-svg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-3.0.0.tgz#9321dbd29c212e5ca99c4fa9794c714bcafa2f75" + integrity sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ== + dependencies: + html-comment-regex "^1.1.0" + +is-symbol@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" + integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw== + dependencies: + has-symbols "^1.0.0" + +is-tar@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-tar/-/is-tar-1.0.0.tgz#2f6b2e1792c1f5bb36519acaa9d65c0d26fe853d" + integrity sha1-L2suF5LB9bs2UZrKqdZcDSb+hT0= + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-unc-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-1.0.0.tgz#d731e8898ed090a12c352ad2eaed5095ad322c9d" + integrity sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ== + dependencies: + unc-path-regex "^0.1.2" + +is-url@^1.2.0: + version "1.2.4" + resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52" + integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww== + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= + +is-valid-glob@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/is-valid-glob/-/is-valid-glob-0.3.0.tgz#d4b55c69f51886f9b65c70d6c2622d37e29f48fe" + integrity sha1-1LVcafUYhvm2XHDWwmItN+KfSP4= + +is-windows@^1.0.1, is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +is-wsl@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= + +is-zip@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-zip/-/is-zip-1.0.0.tgz#47b0a8ff4d38a76431ccfd99a8e15a4c86ba2325" + integrity sha1-R7Co/004p2QxzP2ZqOFaTIa6IyU= + +is@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/is/-/is-3.3.0.tgz#61cff6dd3c4193db94a3d62582072b44e5645d79" + integrity sha512-nW24QBoPcFGGHJGUwnfpI7Yc5CdqWNdsyHQszVE/z2pKHXzh7FZ5GWhJqSyaQ9wMkQnsTx+kAI8bHlCX4tKdbg== + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isarray@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e" + integrity sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4= + +isbinaryfile@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.3.tgz#5d6def3edebf6e8ca8cae9c30183a804b5f8be80" + integrity sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw== + dependencies: + buffer-alloc "^1.2.0" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +isurl@^1.0.0-alpha5: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" + integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w== + dependencies: + has-to-string-tag-x "^1.2.0" + is-object "^1.0.1" + +javascript-obfuscator@^0.15.0: + version "0.15.0" + resolved "https://registry.yarnpkg.com/javascript-obfuscator/-/javascript-obfuscator-0.15.0.tgz#e2b348c3a6895ef9195e3088f05747cff7a914f1" + integrity sha512-d4mzMLkwZarZE9ZDFXQapNba4iHEj6ARveU4qCz7j/T/TlrHJVbyhVRcZigIuiQqgotTWGub5vMCa2/ep+hA+w== + dependencies: + "@babel/runtime" "7.0.0-beta.42" + chalk "2.3.2" + chance "1.0.13" + class-validator "0.8.5" + commander "2.15.1" + escodegen-wallaby "1.6.18" + espree "3.5.4" + estraverse "4.2.0" + inversify "4.11.1" + js-string-escape "1.0.1" + md5 "2.2.1" + mkdirp "0.5.1" + multimatch "2.1.0" + opencollective "1.0.3" + pjson "1.0.9" + reflect-metadata "0.1.12" + source-map-support "0.5.4" + string-template "1.0.0" + tslib "1.9.0" + +javascript-obfuscator@latest: + version "0.18.1" + resolved "https://registry.yarnpkg.com/javascript-obfuscator/-/javascript-obfuscator-0.18.1.tgz#ed536645bd64998c8d284c1ab87957d6d8d8294c" + integrity sha512-pQ2DyRV4j0neaWdII1S7iJftCyks9H7afVkQRSE4gslkqpeqyM1DE0eapsZKHR0BnYvw3tPU+Ky+j4yhzcxRZA== + dependencies: + "@babel/runtime" "7.0.0-rc.1" + chalk "2.4.1" + chance "1.0.16" + class-validator "0.9.1" + commander "2.17.1" + escodegen-wallaby "1.6.19" + espree "4.0.0" + estraverse "4.2.0" + inversify "4.13.0" + js-string-escape "1.0.1" + md5 "2.2.1" + mkdirp "0.5.1" + multimatch "2.1.0" + opencollective "1.0.3" + reflect-metadata "0.1.12" + source-map-support "0.5.8" + string-template "1.0.0" + tslib "1.9.3" + +jimp@^0.6.1: + version "0.6.8" + resolved "https://registry.yarnpkg.com/jimp/-/jimp-0.6.8.tgz#63074984337cc469cd4030946e503e7c02a18b5c" + integrity sha512-F7emeG7Hp61IM8VFbNvWENLTuHe0ghizWPuP4JS9ujx2r5mCVYEd/zdaz6M2M42ZdN41blxPajLWl9FXo7Mr2Q== + dependencies: + "@jimp/custom" "^0.6.8" + "@jimp/plugins" "^0.6.8" + "@jimp/types" "^0.6.8" + core-js "^2.5.7" + regenerator-runtime "^0.13.3" + +jpeg-js@^0.3.4: + version "0.3.6" + resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.3.6.tgz#c40382aac9506e7d1f2d856eb02f6c7b2a98b37c" + integrity sha512-MUj2XlMB8kpe+8DJUGH/3UJm4XpI8XEgZQ+CiHDeyrGoKPdW/8FJv6ku+3UiYm5Fz3CWaL+iXmD8Q4Ap6aC1Jw== + +jpegtran-bin@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jpegtran-bin/-/jpegtran-bin-4.0.0.tgz#d00aed809fba7aa6f30817e59eee4ddf198f8f10" + integrity sha512-2cRl1ism+wJUoYAYFt6O/rLBfpXNWG2dUWbgcEkTt5WGMnqI46eEro8T4C5zGROxKRqyKpCBSdHPvt5UYCtxaQ== + dependencies: + bin-build "^3.0.0" + bin-wrapper "^4.0.0" + logalot "^2.0.0" + +js-base64@^2.1.8, js-base64@^2.1.9: + version "2.5.1" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.1.tgz#1efa39ef2c5f7980bb1784ade4a8af2de3291121" + integrity sha512-M7kLczedRMYX4L8Mdh4MzyAMM9O5osx+4FcOQuTvr3A9F2D9S5JXheN0ewNbrvK2UatkTRhL5ejGmGSjNMiZuw== + +js-beautify@^1.10.1, js-beautify@^1.5.10: + version "1.10.2" + resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.10.2.tgz#88c9099cd6559402b124cfab18754936f8a7b178" + integrity sha512-ZtBYyNUYJIsBWERnQP0rPN9KjkrDfJcMjuVGcvXOUJrD1zmOGwhRwQ4msG+HJ+Ni/FA7+sRQEMYVzdTQDvnzvQ== + dependencies: + config-chain "^1.1.12" + editorconfig "^0.15.3" + glob "^7.1.3" + mkdirp "~0.5.1" + nopt "~4.0.1" + +js-levenshtein@^1.1.3: + version "1.1.6" + resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d" + integrity sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g== + +js-string-escape@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" + integrity sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8= + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.0, js-yaml@^3.13.1, js-yaml@^3.4.6, js-yaml@^3.5.1, js-yaml@^3.5.4: + version "3.13.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +jsdom@12.2.0: + version "12.2.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-12.2.0.tgz#7cf3f5b5eafd47f8f09ca52315d367ff6e95de23" + integrity sha512-QPOggIJ8fquWPLaYYMoh+zqUmdphDtu1ju0QGTitZT1Yd8I5qenPpXM1etzUegu3MjVp8XPzgZxdn8Yj7e40ig== + dependencies: + abab "^2.0.0" + acorn "^6.0.2" + acorn-globals "^4.3.0" + array-equal "^1.0.0" + cssom "^0.3.4" + cssstyle "^1.1.1" + data-urls "^1.0.1" + domexception "^1.0.1" + escodegen "^1.11.0" + html-encoding-sniffer "^1.0.2" + nwsapi "^2.0.9" + parse5 "5.1.0" + pn "^1.1.0" + request "^2.88.0" + request-promise-native "^1.0.5" + saxes "^3.1.3" + symbol-tree "^3.2.2" + tough-cookie "^2.4.3" + w3c-hr-time "^1.0.1" + webidl-conversions "^4.0.2" + whatwg-encoding "^1.0.5" + whatwg-mimetype "^2.2.0" + whatwg-url "^7.0.0" + ws "^6.1.0" + xml-name-validator "^3.0.0" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= + +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= + +json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= + dependencies: + jsonify "~0.0.0" + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +json5@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= + +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" + +json5@^2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" + integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== + dependencies: + minimist "^1.2.5" + +jsonfile@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-3.0.1.tgz#a5ecc6f65f53f662c4415c7675a0331d0992ec66" + integrity sha1-pezG9l9T9mLEQVx2daAzHQmS7GY= + optionalDependencies: + graceful-fs "^4.1.6" + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= + +jsonpointer@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" + integrity sha1-T9kss04OnbPInIYi7PUfm5eMbLk= + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +junk@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/junk/-/junk-3.1.0.tgz#31499098d902b7e98c5d9b9c80f43457a88abfa1" + integrity sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ== + +keyv@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.0.0.tgz#44923ba39e68b12a7cec7df6c3268c031f2ef373" + integrity sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA== + dependencies: + json-buffer "3.0.0" + +keyv@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" + integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== + dependencies: + json-buffer "3.0.0" + +kind-of@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-1.1.0.tgz#140a3d2d41a36d2efcfa9377b62c24f8495a5c44" + integrity sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ= + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" + integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== + +known-css-properties@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.11.0.tgz#0da784f115ea77c76b81536d7052e90ee6c86a8a" + integrity sha512-bEZlJzXo5V/ApNNa5z375mJC6Nrz4vG43UgcSCrg2OHC+yuB6j0iDSrY7RQ/+PRofFB03wNIIt9iXIVLr4wc7w== + +known-css-properties@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.3.0.tgz#a3d135bbfc60ee8c6eacf2f7e7e6f2d4755e49a4" + integrity sha512-QMQcnKAiQccfQTqtBh/qwquGZ2XK/DXND1jrcN9M8gMMy99Gwla7GQjndVUsEqIaRyP6bsFRuhwRj5poafBGJQ== + +lazy-req@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/lazy-req/-/lazy-req-1.1.0.tgz#bdaebead30f8d824039ce0ce149d4daa07ba1fac" + integrity sha1-va6+rTD42CQDnODOFJ1Nqge6H6w= + +lazystream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4" + integrity sha1-9plf4PggOS9hOWvolGJAe7dxaOQ= + dependencies: + readable-stream "^2.0.5" + +lazystream@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-0.1.0.tgz#1b25d63c772a4c20f0a5ed0a9d77f484b6e16920" + integrity sha1-GyXWPHcqTCDwpe0KnXf0hLbhaSA= + dependencies: + readable-stream "~1.0.2" + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= + dependencies: + invert-kv "^1.0.0" + +lcid@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" + integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== + dependencies: + invert-kv "^2.0.0" + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +liftoff@^2.0.1, liftoff@^2.1.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-2.5.0.tgz#2009291bb31cea861bbf10a7c15a28caf75c31ec" + integrity sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew= + dependencies: + extend "^3.0.0" + findup-sync "^2.0.0" + fined "^1.0.1" + flagged-respawn "^1.0.0" + is-plain-object "^2.0.4" + object.map "^1.0.0" + rechoir "^0.6.2" + resolve "^1.1.7" + +limiter@^1.0.5: + version "1.1.4" + resolved "https://registry.yarnpkg.com/limiter/-/limiter-1.1.4.tgz#87c9c3972d389fdb0ba67a45aadbc5d2f8413bc1" + integrity sha512-XCpr5bElgDI65vVgstP8TWjv6/QKWm9GU5UG0Pr5sLQ3QLo8NVKsioe+Jed5/3vFOe3IQuqE7DKwTvKQkjTHvg== + +load-bmfont@^1.3.1, load-bmfont@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/load-bmfont/-/load-bmfont-1.4.0.tgz#75f17070b14a8c785fe7f5bee2e6fd4f98093b6b" + integrity sha512-kT63aTAlNhZARowaNYcY29Fn/QYkc52M3l6V1ifRcPewg2lvUZDAj7R6dXjOL9D0sict76op3T5+odumDSF81g== + dependencies: + 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" + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +load-json-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + strip-bom "^3.0.0" + +loader-runner@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" + integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== + +loader-utils@1.2.3, loader-utils@^1.0.0, loader-utils@^1.1.0, loader-utils@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" + integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== + dependencies: + big.js "^5.2.2" + emojis-list "^2.0.0" + json5 "^1.0.1" + +loader-utils@^0.2.5, loader-utils@~0.2.2, loader-utils@~0.2.3, loader-utils@~0.2.5: + version "0.2.17" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" + integrity sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g= + dependencies: + big.js "^3.1.3" + emojis-list "^2.0.0" + json5 "^0.5.0" + object-assign "^4.0.1" + +loader-utils@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" + integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^1.0.1" + +localtunnel@1.9.2: + version "1.9.2" + resolved "https://registry.yarnpkg.com/localtunnel/-/localtunnel-1.9.2.tgz#0012fcabc29cf964c130a01858768aa2bb65b5af" + integrity sha512-NEKF7bDJE9U3xzJu3kbayF0WTvng6Pww7tzqNb/XtEARYwqw7CKEX7BvOMg98FtE9es2CRizl61gkV3hS8dqYg== + dependencies: + axios "0.19.0" + debug "4.1.1" + openurl "1.1.1" + yargs "6.6.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +lodash._basecopy@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" + integrity sha1-jaDmqHbPNEwK2KVIghEd08XHyjY= + +lodash._basetostring@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz#d1861d877f824a52f669832dcaf3ee15566a07d5" + integrity sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U= + +lodash._basevalues@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz#5b775762802bde3d3297503e26300820fdf661b7" + integrity sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc= + +lodash._escapehtmlchar@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._escapehtmlchar/-/lodash._escapehtmlchar-2.4.1.tgz#df67c3bb6b7e8e1e831ab48bfa0795b92afe899d" + integrity sha1-32fDu2t+jh6DGrSL+geVuSr+iZ0= + dependencies: + lodash._htmlescapes "~2.4.1" + +lodash._escapestringchar@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._escapestringchar/-/lodash._escapestringchar-2.4.1.tgz#ecfe22618a2ade50bfeea43937e51df66f0edb72" + integrity sha1-7P4iYYoq3lC/7qQ5N+Ud9m8O23I= + +lodash._getnative@^3.0.0: + version "3.9.1" + resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" + integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U= + +lodash._htmlescapes@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._htmlescapes/-/lodash._htmlescapes-2.4.1.tgz#32d14bf0844b6de6f8b62a051b4f67c228b624cb" + integrity sha1-MtFL8IRLbeb4tioFG09nwii2JMs= + +lodash._isiterateecall@^3.0.0: + version "3.0.9" + resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" + integrity sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw= + +lodash._isnative@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._isnative/-/lodash._isnative-2.4.1.tgz#3ea6404b784a7be836c7b57580e1cdf79b14832c" + integrity sha1-PqZAS3hKe+g2x7V1gOHN95sUgyw= + +lodash._objecttypes@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz#7c0b7f69d98a1f76529f890b0cdb1b4dfec11c11" + integrity sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE= + +lodash._reescape@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reescape/-/lodash._reescape-3.0.0.tgz#2b1d6f5dfe07c8a355753e5f27fac7f1cde1616a" + integrity sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo= + +lodash._reevaluate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz#58bc74c40664953ae0b124d806996daca431e2ed" + integrity sha1-WLx0xAZklTrgsSTYBpltrKQx4u0= + +lodash._reinterpolate@^2.4.1, lodash._reinterpolate@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-2.4.1.tgz#4f1227aa5a8711fc632f5b07a1f4607aab8b3222" + integrity sha1-TxInqlqHEfxjL1sHofRgequLMiI= + +lodash._reinterpolate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" + integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= + +lodash._reunescapedhtml@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._reunescapedhtml/-/lodash._reunescapedhtml-2.4.1.tgz#747c4fc40103eb3bb8a0976e571f7a2659e93ba7" + integrity sha1-dHxPxAED6zu4oJduVx96JlnpO6c= + dependencies: + lodash._htmlescapes "~2.4.1" + lodash.keys "~2.4.1" + +lodash._root@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" + integrity sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI= + +lodash._shimkeys@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._shimkeys/-/lodash._shimkeys-2.4.1.tgz#6e9cc9666ff081f0b5a6c978b83e242e6949d203" + integrity sha1-bpzJZm/wgfC1psl4uD4kLmlJ0gM= + dependencies: + lodash._objecttypes "~2.4.1" + +lodash.assign@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" + integrity sha1-DZnzzNem0mHRm9rrkkUAXShYCOc= + +lodash.capitalize@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz#f826c9b4e2a8511d84e3aca29db05e1a4f3b72a9" + integrity sha1-+CbJtOKoUR2E46yinbBeGk87cqk= + +lodash.clone@^4.3.2: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clone/-/lodash.clone-4.5.0.tgz#195870450f5a13192478df4bc3d23d2dea1907b6" + integrity sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y= + +lodash.clonedeep@^4.3.2: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= + +lodash.defaults@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" + integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw= + +lodash.defaults@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-2.4.1.tgz#a7e8885f05e68851144b6e12a8f3678026bc4c54" + integrity sha1-p+iIXwXmiFEUS24SqPNngCa8TFQ= + dependencies: + lodash._objecttypes "~2.4.1" + lodash.keys "~2.4.1" + +lodash.escape@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-3.2.0.tgz#995ee0dc18c1b48cc92effae71a10aab5b487698" + integrity sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg= + dependencies: + lodash._root "^3.0.0" + +lodash.escape@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-2.4.1.tgz#2ce12c5e084db0a57dda5e5d1eeeb9f5d175a3b4" + integrity sha1-LOEsXghNsKV92l5dHu659dF1o7Q= + dependencies: + lodash._escapehtmlchar "~2.4.1" + lodash._reunescapedhtml "~2.4.1" + lodash.keys "~2.4.1" + +lodash.get@^4.0.0: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" + integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= + +lodash.isarguments@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + integrity sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo= + +lodash.isarray@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" + integrity sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U= + +lodash.isequal@^4.0.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA= + +lodash.isfinite@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz#fb89b65a9a80281833f0b7478b3a5104f898ebb3" + integrity sha1-+4m2WpqAKBgz8LdHizpRBPiY67M= + +lodash.isobject@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/lodash.isobject/-/lodash.isobject-3.0.2.tgz#3c8fb8d5b5bf4bf90ae06e14f2a530a4ed935e1d" + integrity sha1-PI+41bW/S/kK4G4U8qUwpO2TXh0= + +lodash.isobject@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.isobject/-/lodash.isobject-2.4.1.tgz#5a2e47fe69953f1ee631a7eba1fe64d2d06558f5" + integrity sha1-Wi5H/mmVPx7mMafrof5k0tBlWPU= + dependencies: + lodash._objecttypes "~2.4.1" + +lodash.kebabcase@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36" + integrity sha1-hImxyw0p/4gZXM7KRI/21swpXDY= + +lodash.keys@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" + integrity sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo= + dependencies: + lodash._getnative "^3.0.0" + lodash.isarguments "^3.0.0" + lodash.isarray "^3.0.0" + +lodash.keys@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-2.4.1.tgz#48dea46df8ff7632b10d706b8acb26591e2b3727" + integrity sha1-SN6kbfj/djKxDXBrissmWR4rNyc= + dependencies: + lodash._isnative "~2.4.1" + lodash._shimkeys "~2.4.1" + lodash.isobject "~2.4.1" + +lodash.memoize@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= + +lodash.merge@^4.6.0: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lodash.mergewith@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55" + integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ== + +lodash.restparam@^3.0.0: + version "3.6.1" + resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" + integrity sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU= + +lodash.some@^4.2.2: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" + integrity sha1-G7nzFO9ri63tE7VJFpsqlF62jk0= + +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= + +lodash.template@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-2.4.1.tgz#9e611007edf629129a974ab3c48b817b3e1cf20d" + integrity sha1-nmEQB+32KRKal0qzxIuBez4c8g0= + dependencies: + lodash._escapestringchar "~2.4.1" + lodash._reinterpolate "~2.4.1" + lodash.defaults "~2.4.1" + lodash.escape "~2.4.1" + lodash.keys "~2.4.1" + lodash.templatesettings "~2.4.1" + lodash.values "~2.4.1" + +lodash.template@^3.0.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-3.6.2.tgz#f8cdecc6169a255be9098ae8b0c53d378931d14f" + integrity sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8= + dependencies: + lodash._basecopy "^3.0.0" + lodash._basetostring "^3.0.0" + lodash._basevalues "^3.0.0" + lodash._isiterateecall "^3.0.0" + lodash._reinterpolate "^3.0.0" + lodash.escape "^3.0.0" + lodash.keys "^3.0.0" + lodash.restparam "^3.0.0" + lodash.templatesettings "^3.0.0" + +lodash.template@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab" + integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A== + dependencies: + lodash._reinterpolate "^3.0.0" + lodash.templatesettings "^4.0.0" + +lodash.templatesettings@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz#fb307844753b66b9f1afa54e262c745307dba8e5" + integrity sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU= + dependencies: + lodash._reinterpolate "^3.0.0" + lodash.escape "^3.0.0" + +lodash.templatesettings@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz#e481310f049d3cf6d47e912ad09313b154f0fb33" + integrity sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ== + dependencies: + lodash._reinterpolate "^3.0.0" + +lodash.templatesettings@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-2.4.1.tgz#ea76c75d11eb86d4dbe89a83893bb861929ac699" + integrity sha1-6nbHXRHrhtTb6JqDiTu4YZKaxpk= + dependencies: + lodash._reinterpolate "~2.4.1" + lodash.escape "~2.4.1" + +lodash.uniq@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= + +lodash.values@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.values/-/lodash.values-2.4.1.tgz#abf514436b3cb705001627978cbcf30b1280eea4" + integrity sha1-q/UUQ2s8twUAFieXjLzzCxKA7qQ= + dependencies: + lodash.keys "~2.4.1" + +lodash@^3.0.1: + version "3.10.1" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" + integrity sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y= + +lodash@^4.0.0, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.3.0, lodash@~4.17.10: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" + integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== + +lodash@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-1.0.2.tgz#8f57560c83b59fc270bd3d561b690043430e2551" + integrity sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE= + +lodash@~2.4.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-2.4.2.tgz#fadd834b9683073da179b3eae6d9c0d15053f73e" + integrity sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4= + +logalot@^2.0.0, logalot@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/logalot/-/logalot-2.1.0.tgz#5f8e8c90d304edf12530951a5554abb8c5e3f552" + integrity sha1-X46MkNME7fElMJUaVVSruMXj9VI= + dependencies: + figures "^1.3.5" + squeak "^1.0.0" + +longest@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" + integrity sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc= + +loose-envify@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +loud-rejection@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lower-case@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" + integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw= + +lowercase-keys@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" + integrity sha1-TjNms55/VFfjXxMkvfb4jQv8cwY= + +lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== + +lpad-align@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/lpad-align/-/lpad-align-1.1.2.tgz#21f600ac1c3095c3c6e497ee67271ee08481fe9e" + integrity sha1-IfYArBwwlcPG5JfuZyce4ISB/p4= + dependencies: + get-stdin "^4.0.1" + indent-string "^2.1.0" + longest "^1.0.0" + meow "^3.3.0" + +lru-cache@2: + version "2.7.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" + integrity sha1-bUUk6LlV+V1PW1iFHOId1y+06VI= + +lru-cache@^4.0.1, lru-cache@^4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +lz-string@^1.4.4: + version "1.4.4" + resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26" + integrity sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY= + +make-dir@^1.0.0, make-dir@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== + dependencies: + pify "^3.0.0" + +make-dir@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + +make-iterator@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/make-iterator/-/make-iterator-1.0.1.tgz#29b33f312aa8f547c4a5e490f56afcec99133ad6" + integrity sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw== + dependencies: + kind-of "^6.0.2" + +mamacro@^0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" + integrity sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA== + +map-age-cleaner@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" + integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== + dependencies: + p-defer "^1.0.0" + +map-cache@^0.2.0, map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-obj@^1.0.0, map-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + +markdown-loader@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/markdown-loader/-/markdown-loader-5.1.0.tgz#4efd5006b1514ca966141c661a47e542a9836e6e" + integrity sha512-xtQNozLEL+55ZSPTNwro8epZqf1h7HjAZd/69zNe8lbckDiGVHeLQm849bXzocln2pwRK2A/GrW/7MAmwjcFog== + dependencies: + loader-utils "^1.2.3" + marked "^0.7.0" + +marked@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/marked/-/marked-0.7.0.tgz#b64201f051d271b1edc10a04d1ae9b74bb8e5c0e" + integrity sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg== + +math-random@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.4.tgz#5dd6943c938548267016d4e34f057583080c514c" + integrity sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A== + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +md5@2.2.1, md5@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9" + integrity sha1-U6s41f48iJG6RlMp6iP6wFQBJvk= + dependencies: + charenc "~0.0.1" + crypt "~0.0.1" + is-buffer "~1.1.1" + +mdn-data@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" + integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA== + +mdn-data@~1.1.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-1.1.4.tgz#50b5d4ffc4575276573c4eedb8780812a8419f01" + integrity sha512-FSYbp3lyKjyj3E7fMl6rYvUdX0FBXaluGqlFoYESWQlyUTq8R+wp0rkFxoYFqZlHCvsUXGjyJmLQSnXToYhOSA== + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +mem@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" + integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== + dependencies: + map-age-cleaner "^0.1.1" + mimic-fn "^2.0.0" + p-is-promise "^2.0.0" + +memory-fs@^0.4.0, memory-fs@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +meow@^3.1.0, meow@^3.3.0, meow@^3.5.0, meow@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs= + dependencies: + camelcase-keys "^2.0.0" + decamelize "^1.1.2" + loud-rejection "^1.0.0" + map-obj "^1.0.1" + minimist "^1.1.3" + normalize-package-data "^2.3.4" + object-assign "^4.0.1" + read-pkg-up "^1.0.1" + redent "^1.0.0" + trim-newlines "^1.0.0" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +merge-stream@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1" + integrity sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE= + dependencies: + readable-stream "^2.0.1" + +merge2@^1.2.3: + version "1.3.0" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.3.0.tgz#5b366ee83b2f1582c48f87e47cf1a9352103ca81" + integrity sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw== + +merge@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145" + integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +micromatch@^2.3.7: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU= + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + +micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +mime-db@1.40.0: + version "1.40.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32" + integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA== + +mime-db@^1.28.0: + version "1.41.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.41.0.tgz#9110408e1f6aa1b34aef51f2c9df3caddf46b6a0" + integrity sha512-B5gxBI+2K431XW8C2rcc/lhppbuji67nf9v39eH8pkWoZDxnAL0PxdpH32KYRScniF8qDHBDlI+ipgg5WrCUYw== + +mime-db@~1.12.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.12.0.tgz#3d0c63180f458eb10d325aaa37d7c58ae312e9d7" + integrity sha1-PQxjGA9FjrENMlqqN9fFiuMS6dc= + +mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24: + version "2.1.24" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81" + integrity sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ== + dependencies: + mime-db "1.40.0" + +mime-types@~2.0.9: + version "2.0.14" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.0.14.tgz#310e159db23e077f8bb22b748dabfa4957140aa6" + integrity sha1-MQ4VnbI+B3+Lsit0jav6SVcUCqY= + dependencies: + mime-db "~1.12.0" + +mime@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" + integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== + +mime@1.6.0, mime@^1.3.4: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mime@^2.4.0: + version "2.4.4" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.4.tgz#bd7b91135fc6b01cde3e9bae33d659b63d8857e5" + integrity sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA== + +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== + +mimic-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mimic-response@^1.0.0, mimic-response@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +min-document@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU= + dependencies: + dom-walk "^0.1.0" + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + +minimatch@0.3: + version "0.3.0" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.3.0.tgz#275d8edaac4f1bb3326472089e7949c8394699dd" + integrity sha1-J12O2qxPG7MyZHIInnlJyDlGmd0= + dependencies: + lru-cache "2" + sigmund "~1.0.0" + +"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@~3.0.2: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^2.0.1: + version "2.0.10" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-2.0.10.tgz#8d087c39c6b38c001b97fca7ce6d0e1e80afbac7" + integrity sha1-jQh8OcazjAAbl/ynzm0OHoCvusc= + dependencies: + brace-expansion "^1.0.0" + +minimatch@~0.2.11: + version "0.2.14" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.2.14.tgz#c74e780574f63c6f9a090e90efbe6ef53a6a756a" + integrity sha1-x054BXT2PG+aCQ6Q775u9TpqdWo= + dependencies: + lru-cache "2" + sigmund "~1.0.0" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= + +minimist@1.1.x: + version "1.1.3" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.1.3.tgz#3bedfd91a92d39016fcfaa1c681e8faa1a1efda8" + integrity sha1-O+39kaktOQFvz6ocaB6Pqhoe/ag= + +minimist@1.2.0, minimist@^1.1.0, minimist@^1.1.3, minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= + +minimist@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.1.0.tgz#99df657a52574c21c9057497df742790b2b4c0de" + integrity sha1-md9lelJXTCHJBXSX33QnkLK0wN4= + +minimist@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.2.0.tgz#4dffe525dae2b864c66c2e23c6271d7afdecefce" + integrity sha1-Tf/lJdriuGTGbC4jxicdev3s784= + +minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +minipass@^2.2.1, minipass@^2.6.0, minipass@^2.6.4: + version "2.7.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.7.0.tgz#c01093a82287c8331f08f1075499fef124888796" + integrity sha512-+CbZuJ4uEiuTL9s5Z/ULkuRg1O9AvVqVvceaBrhbYHIy1R3dPO7FMmG0nZLD0//ZzZq0MUOjwdBQvk+w1JHUqQ== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.2.tgz#6f0ccc82fa53e1bf2ff145f220d2da9fa6e3a166" + integrity sha512-hR3At21uSrsjjDTWrbu0IMLTpnkpv8IIMFDFaoz43Tmu4LkmAXfH44vNNzpTnf+OAQQCHrb91y/wc2J4x5XgSQ== + dependencies: + minipass "^2.2.1" + +mississippi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" + integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^3.0.0" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + +mitt@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/mitt/-/mitt-1.1.3.tgz#528c506238a05dce11cd914a741ea2cc332da9b8" + integrity sha512-mUDCnVNsAi+eD6qA0HkRkwYczbLHJ49z17BGe2PYRhZL4wpZUFZGJHU7/5tmvohoma+Hdn0Vh/oJTiPEmgSruA== + +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@0.5.1, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= + dependencies: + minimist "0.0.8" + +mkdirp@^0.5.3: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + +mozjpeg@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/mozjpeg/-/mozjpeg-6.0.1.tgz#56969dddb5741ef2bcb1af066cae21e61a91a27b" + integrity sha512-9Z59pJMi8ni+IUvSH5xQwK5tNLw7p3dwDNCZ3o1xE+of3G5Hc/yOz6Ue/YuLiBXU3ZB5oaHPURyPdqfBX/QYJA== + dependencies: + bin-build "^3.0.0" + bin-wrapper "^4.0.0" + logalot "^2.1.0" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +ms@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +multimatch@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" + integrity sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis= + dependencies: + array-differ "^1.0.0" + array-union "^1.0.1" + arrify "^1.0.0" + minimatch "^3.0.0" + +multipipe@^0.1.0, multipipe@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/multipipe/-/multipipe-0.1.2.tgz#2a8f2ddf70eed564dff2d57f1e1a137d9f05078b" + integrity sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s= + dependencies: + duplexer2 "0.0.2" + +mute-stream@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" + integrity sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA= + +mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= + +mute-stream@~0.0.4: + version "0.0.8" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" + integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== + +nan@^2.12.1, nan@^2.13.2: + version "2.14.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" + integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +natives@^1.1.3: + version "1.1.6" + resolved "https://registry.yarnpkg.com/natives/-/natives-1.1.6.tgz#a603b4a498ab77173612b9ea1acdec4d980f00bb" + integrity sha512-6+TDFewD4yxY14ptjKaS63GVdtKiES1pTPyxn9Jb0rBqPMZ7VcCiooEhPNsr+mqHtMGxa/5c/HhcC4uPEUw/nA== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +needle@, needle@^2.2.1: + version "2.4.0" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.0.tgz#6833e74975c444642590e15a750288c5f939b57c" + integrity sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg== + dependencies: + debug "^3.2.6" + iconv-lite "^0.4.4" + sax "^1.2.4" + +negotiator@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== + +neo-async@^2.5.0, neo-async@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" + integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== + +next-tick@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" + integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +no-case@^2.2.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" + integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ== + dependencies: + lower-case "^1.1.1" + +node-fetch@1.6.3: + version "1.6.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.6.3.tgz#dc234edd6489982d58e8f0db4f695029abcd8c04" + integrity sha1-3CNO3WSJmC1Y6PDbT2lQKavNjAQ= + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + +node-fetch@^1.6.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" + integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ== + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + +node-gyp@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.8.0.tgz#540304261c330e80d0d5edce253a68cb3964218c" + integrity sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA== + dependencies: + 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" + +node-libs-browser@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" + integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== + dependencies: + assert "^1.1.1" + browserify-zlib "^0.2.0" + buffer "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events "^3.0.0" + https-browserify "^1.0.0" + os-browserify "^0.3.0" + path-browserify "0.0.1" + process "^0.11.10" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.3.3" + stream-browserify "^2.0.1" + stream-http "^2.7.2" + string_decoder "^1.0.0" + timers-browserify "^2.0.4" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.11.0" + vm-browserify "^1.0.1" + +node-pre-gyp@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149" + integrity sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A== + dependencies: + 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" + +node-releases@^1.1.29: + version "1.1.32" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.32.tgz#485b35c1bf9b4d8baa105d782f8ca731e518276e" + integrity sha512-VhVknkitq8dqtWoluagsGPn3dxTvN9fwgR59fV3D7sLBHe0JfDramsMI8n8mY//ccq/Kkrf8ZRHRpsyVZ3qw1A== + dependencies: + semver "^5.3.0" + +node-sass@^4.8.3: + version "4.12.0" + resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.12.0.tgz#0914f531932380114a30cc5fa4fa63233a25f017" + integrity sha512-A1Iv4oN+Iel6EPv77/HddXErL2a+gZ4uBeZUy+a8O35CFYTXhgA8MgLCWBtwpGZdCvTvQ9d+bQxX/QC36GDPpQ== + dependencies: + 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.11" + 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.4" + stdout-stream "^1.4.0" + "true-case-path" "^1.0.2" + +node-sri@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/node-sri/-/node-sri-1.1.1.tgz#041096d2b11f232b65dedc4c3ae1cb62babb54b0" + integrity sha1-BBCW0rEfIytl3txMOuHLYrq7VLA= + +node-status-codes@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/node-status-codes/-/node-status-codes-1.0.0.tgz#5ae5541d024645d32a58fcddc9ceecea7ae3ac2f" + integrity sha1-WuVUHQJGRdMqWPzdyc7s6nrjrC8= + +node.extend@^1.0.10: + version "1.1.8" + resolved "https://registry.yarnpkg.com/node.extend/-/node.extend-1.1.8.tgz#0aab3e63789f4e6d68b42bc00073ad1881243cf0" + integrity sha512-L/dvEBwyg3UowwqOUTyDsGBU6kjBQOpOhshio9V3i3BMPv5YUb9+mWNN8MK0IbWqT0AqaTSONZf0aTuMMahWgA== + dependencies: + has "^1.0.3" + is "^3.2.1" + +"nopt@2 || 3": + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= + dependencies: + abbrev "1" + +nopt@^4.0.1, nopt@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= + dependencies: + abbrev "1" + osenv "^0.1.4" + +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.0.1, normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= + +normalize-url@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-2.0.1.tgz#835a9da1551fa26f70e92329069a23aa6574d7e6" + integrity sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw== + dependencies: + prepend-http "^2.0.0" + query-string "^5.0.1" + sort-keys "^2.0.0" + +normalize-url@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" + integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== + +normalize-url@^4.1.0: + version "4.4.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.4.1.tgz#81e9c153b0ad5743755696f2aa20488d48e962b6" + integrity sha512-rjH3yRt0Ssx19mUwS0hrDUOdG9VI+oRLpLHJ7tXRdjcuQ7v7wo6qPvOZppHRrqfslTKr0L2yBhjj4UXd7c3cQg== + +npm-bundled@^1.0.1: + version "1.0.6" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.6.tgz#e7ba9aadcef962bb61248f91721cd932b3fe6bdd" + integrity sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g== + +npm-conf@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/npm-conf/-/npm-conf-1.1.3.tgz#256cc47bd0e218c259c4e9550bf413bc2192aff9" + integrity sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw== + dependencies: + config-chain "^1.1.11" + pify "^3.0.0" + +npm-packlist@^1.1.6: + version "1.4.4" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.4.tgz#866224233850ac534b63d1a6e76050092b5d2f44" + integrity sha512-zTLo8UcVYtDU3gdeaFu2Xu0n0EvelfHDGuqtNIn5RO7yQj4H1TqNdBc/yZjxnWA0PVB8D3Woyp0i5B43JwQ6Vw== + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + dependencies: + path-key "^2.0.0" + +"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0, npmlog@^4.0.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +nth-check@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" + integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== + dependencies: + boolbase "~1.0.0" + +num2fraction@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" + integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +nwsapi@^2.0.9: + version "2.1.4" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.1.4.tgz#e006a878db23636f8e8a67d33ca0e4edf61a842f" + integrity sha512-iGfd9Y6SFdTNldEy2L0GUhcarIutFmk+MPWIn9dmj8NMIup03G08uUF2KGbbmv/Ux4RT0VZJoP/sVbWA6d/VIw== + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +obfuscator-loader@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/obfuscator-loader/-/obfuscator-loader-1.1.2.tgz#6e8460066296fc642a68c945e64906e3c964cb0f" + integrity sha512-5PKsa4Vzq8uLJG0GT9BvC9ZxCr44wyV0c9wi782RYWh44GdFMSqlnUldgqSV+HQkFH3MWNc34AlSVSEhg7I26w== + dependencies: + esprima "^4.0.0" + javascript-obfuscator "^0.15.0" + loader-utils "^1.1.0" + +object-assign@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-2.1.1.tgz#43c36e5d569ff8e4816c4efa8be02d26967c18aa" + integrity sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo= + +object-assign@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-3.0.0.tgz#9bedd5ca0897949bca47e7ff408062d549f587f2" + integrity sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I= + +object-assign@^4.0.0, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-assign@~0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-0.3.1.tgz#060e2a2a27d7c0d77ec77b78f11aa47fd88008d2" + integrity sha1-Bg4qKifXwNd+x3t48Rqkf9iACNI= + +object-component@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291" + integrity sha1-8MaapQ78lbhmwYb0AKM3acsvEpE= + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-inspect@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b" + integrity sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ== + +object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object-keys@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" + integrity sha1-KKaq50KN0sOpLz2V8hM13SBOAzY= + +object-path@^0.9.0: + version "0.9.2" + resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.9.2.tgz#0fd9a74fc5fad1ae3968b586bda5c632bd6c05a5" + integrity sha1-D9mnT8X60a45aLWGvaXGMr1sBaU= + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + +object.assign@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" + +object.defaults@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/object.defaults/-/object.defaults-1.1.0.tgz#3a7f868334b407dea06da16d88d5cd29e435fecf" + integrity sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8= + dependencies: + array-each "^1.0.1" + array-slice "^1.0.0" + for-own "^1.0.0" + isobject "^3.0.0" + +object.getownpropertydescriptors@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" + integrity sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY= + dependencies: + define-properties "^1.1.2" + es-abstract "^1.5.1" + +object.map@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object.map/-/object.map-1.0.1.tgz#cf83e59dc8fcc0ad5f4250e1f78b3b81bd801d37" + integrity sha1-z4Plncj8wK1fQlDh94s7gb2AHTc= + dependencies: + for-own "^1.0.0" + make-iterator "^1.0.0" + +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + integrity sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo= + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + +object.pick@^1.2.0, object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + +object.values@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.0.tgz#bf6810ef5da3e5325790eaaa2be213ea84624da9" + integrity sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.12.0" + function-bind "^1.1.1" + has "^1.0.3" + +omggif@^1.0.9: + version "1.0.10" + resolved "https://registry.yarnpkg.com/omggif/-/omggif-1.0.10.tgz#ddaaf90d4a42f532e9e7cb3a95ecdd47f17c7b19" + integrity sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw== + +on-finished@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.1.0.tgz#0c539f09291e8ffadde0c8a25850fb2cedc7022d" + integrity sha1-DFOfCSkej/rd4MiiWFD7LO3HAi0= + dependencies: + ee-first "1.0.5" + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +once@~1.3.0: + version "1.3.3" + resolved "https://registry.yarnpkg.com/once/-/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20" + integrity sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA= + dependencies: + wrappy "1" + +onesky-fetch@^0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/onesky-fetch/-/onesky-fetch-0.0.7.tgz#96fce1a258a80683d6a37840958bae2f6fdb2809" + integrity sha1-lvzholioBoPWo3hAlYuuL2/bKAk= + dependencies: + md5 "^2.2.1" + node-fetch "^1.6.3" + +onetime@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" + integrity sha1-ofeDj4MUxRbwXs78vEzP4EtO14k= + +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= + dependencies: + mimic-fn "^1.0.0" + +open@^0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/open/-/open-0.0.5.tgz#42c3e18ec95466b6bf0dc42f3a2945c3f0cad8fc" + integrity sha1-QsPhjslUZra/DcQvOilFw/DK2Pw= + +opencollective@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/opencollective/-/opencollective-1.0.3.tgz#aee6372bc28144583690c3ca8daecfc120dd0ef1" + integrity sha1-ruY3K8KBRFg2kMPKja7PwSDdDvE= + dependencies: + babel-polyfill "6.23.0" + chalk "1.1.3" + inquirer "3.0.6" + minimist "1.2.0" + node-fetch "1.6.3" + opn "4.0.2" + +opener@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed" + integrity sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA== + +openurl@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/openurl/-/openurl-1.1.1.tgz#3875b4b0ef7a52c156f0db41d4609dbb0f94b387" + integrity sha1-OHW0sO96UsFW8NtB1GCduw+Us4c= + +opn@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/opn/-/opn-4.0.2.tgz#7abc22e644dff63b0a96d5ab7f2790c0f01abc95" + integrity sha1-erwi5kTf9jsKltWrfyeQwPAavJU= + dependencies: + object-assign "^4.0.1" + pinkie-promise "^2.0.0" + +opn@5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/opn/-/opn-5.3.0.tgz#64871565c863875f052cfdf53d3e3cb5adb53b1c" + integrity sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g== + dependencies: + is-wsl "^1.1.0" + +optionator@^0.8.1, optionator@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q= + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + +optipng-bin@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/optipng-bin/-/optipng-bin-5.1.0.tgz#a7c7ab600a3ab5a177dae2f94c2d800aa386b5a9" + integrity sha512-9baoqZTNNmXQjq/PQTWEXbVV3AMO2sI/GaaqZJZ8SExfAzjijeAP7FEeT+TtyumSw7gr0PZtSUYB/Ke7iHQVKA== + dependencies: + bin-build "^3.0.0" + bin-wrapper "^4.0.0" + logalot "^2.0.0" + +orchestrator@^0.3.0: + version "0.3.8" + resolved "https://registry.yarnpkg.com/orchestrator/-/orchestrator-0.3.8.tgz#14e7e9e2764f7315fbac184e506c7aa6df94ad7e" + integrity sha1-FOfp4nZPcxX7rBhOUGx6pt+UrX4= + dependencies: + end-of-stream "~0.1.5" + sequencify "~0.0.7" + stream-consume "~0.1.0" + +ordered-read-streams@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz#fd565a9af8eb4473ba69b6ed8a34352cb552f126" + integrity sha1-/VZamvjrRHO6abbtijQ1LLVS8SY= + +ordered-read-streams@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz#7137e69b3298bb342247a1bbee3881c80e2fd78b" + integrity sha1-cTfmmzKYuzQiR6G77jiByA4v14s= + dependencies: + is-stream "^1.0.1" + readable-stream "^2.0.1" + +os-browserify@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= + +os-filter-obj@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/os-filter-obj/-/os-filter-obj-1.0.3.tgz#5915330d90eced557d2d938a31c6dd214d9c63ad" + integrity sha1-WRUzDZDs7VV9LZOKMcbdIU2cY60= + +os-filter-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/os-filter-obj/-/os-filter-obj-2.0.0.tgz#1c0b62d5f3a2442749a2d139e6dddee6e81d8d16" + integrity sha512-uksVLsqG3pVdzzPvmAHpBK0wKxYItuzZr7SziusRPoz67tGV8rL1szZ6IdeUrbqLjGDwApBtN29eEE3IqGHOjg== + dependencies: + arch "^2.1.0" + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + +os-locale@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + integrity sha1-IPnxeuKe00XoveWDsT0gCYA8FNk= + dependencies: + lcid "^1.0.0" + +os-locale@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" + integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== + dependencies: + execa "^1.0.0" + lcid "^2.0.0" + mem "^4.0.0" + +os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +osenv@0, osenv@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +ow@^0.13.2: + version "0.13.2" + resolved "https://registry.yarnpkg.com/ow/-/ow-0.13.2.tgz#375e76d3d3f928a8dfcf0cd0b9c921cb62e469a0" + integrity sha512-9wvr+q+ZTDRvXDjL6eDOdFe5WUl/wa5sntf9kAolxqSpkBqaIObwLgFCGXSJASFw+YciXnOVtDWpxXa9cqV94A== + dependencies: + type-fest "^0.5.1" + +p-cancelable@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa" + integrity sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw== + +p-cancelable@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.4.1.tgz#35f363d67d52081c8d9585e37bcceb7e0bbcb2a0" + integrity sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ== + +p-cancelable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" + integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== + +p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= + +p-event@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-event/-/p-event-1.3.0.tgz#8e6b4f4f65c72bc5b6fe28b75eda874f96a4a085" + integrity sha1-jmtPT2XHK8W2/ii3XtqHT5akoIU= + dependencies: + p-timeout "^1.1.1" + +p-event@^2.1.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/p-event/-/p-event-2.3.1.tgz#596279ef169ab2c3e0cae88c1cfbb08079993ef6" + integrity sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA== + dependencies: + p-timeout "^2.0.1" + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-is-promise@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" + integrity sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4= + +p-is-promise@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" + integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-limit@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537" + integrity sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg== + dependencies: + p-try "^2.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-map-series@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-map-series/-/p-map-series-1.0.0.tgz#bf98fe575705658a9e1351befb85ae4c1f07bdca" + integrity sha1-v5j+V1cFZYqeE1G++4WuTB8Hvco= + dependencies: + p-reduce "^1.0.0" + +p-pipe@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/p-pipe/-/p-pipe-1.2.0.tgz#4b1a11399a11520a67790ee5a0c1d5881d6befe9" + integrity sha1-SxoROZoRUgpneQ7loMHViB1r7+k= + +p-reduce@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" + integrity sha1-GMKw3ZNqRpClKfgjH1ig/bakffo= + +p-timeout@^1.1.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386" + integrity sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y= + dependencies: + p-finally "^1.0.0" + +p-timeout@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038" + integrity sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA== + dependencies: + p-finally "^1.0.0" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +pako@^1.0.5, pako@~1.0.5: + version "1.0.10" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.10.tgz#4328badb5086a426aa90f541977d4955da5c9732" + integrity sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw== + +parallel-transform@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" + integrity sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg== + dependencies: + cyclist "^1.0.1" + inherits "^2.0.3" + readable-stream "^2.1.5" + +param-case@2.1.x: + version "2.1.1" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247" + integrity sha1-35T9jPZTHs915r75oIWPvHK+Ikc= + dependencies: + no-case "^2.2.0" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parents@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parents/-/parents-1.0.1.tgz#fedd4d2bf193a77745fe71e371d73c3307d9c751" + integrity sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E= + dependencies: + path-platform "~0.11.15" + +parse-asn1@^5.0.0: + version "5.1.5" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.5.tgz#003271343da58dc94cace494faef3d2147ecea0e" + integrity sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ== + dependencies: + asn1.js "^4.0.0" + browserify-aes "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" + +parse-author@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/parse-author/-/parse-author-2.0.0.tgz#d3460bf1ddd0dfaeed42da754242e65fb684a81f" + integrity sha1-00YL8d3Q367tQtp1QkLmX7aEqB8= + dependencies: + author-regex "^1.0.0" + +parse-bmfont-ascii@^1.0.3: + version "1.0.6" + resolved "https://registry.yarnpkg.com/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz#11ac3c3ff58f7c2020ab22769079108d4dfa0285" + integrity sha1-Eaw8P/WPfCAgqyJ2kHkQjU36AoU= + +parse-bmfont-binary@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz#d038b476d3e9dd9db1e11a0b0e53a22792b69006" + integrity sha1-0Di0dtPp3Z2x4RoLDlOiJ5K2kAY= + +parse-bmfont-xml@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/parse-bmfont-xml/-/parse-bmfont-xml-1.1.4.tgz#015319797e3e12f9e739c4d513872cd2fa35f389" + integrity sha512-bjnliEOmGv3y1aMEfREMBJ9tfL3WR0i0CKPj61DnSLaoxWR3nLrsQrEbCId/8rF4NyRF0cCqisSVXyQYWM+mCQ== + dependencies: + xml-parse-from-string "^1.0.0" + xml2js "^0.4.5" + +parse-filepath@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891" + integrity sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE= + dependencies: + is-absolute "^1.0.0" + map-cache "^0.2.0" + path-root "^0.1.1" + +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + +parse-headers@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.2.tgz#9545e8a4c1ae5eaea7d24992bca890281ed26e34" + integrity sha512-/LypJhzFmyBIDYP9aDVgeyEb5sQfbfY5mnDq4hVhlQ69js87wXfmEI5V3xI6vvXasqebp0oCytYFLxsBVfCzSg== + dependencies: + for-each "^0.3.3" + string.prototype.trim "^1.1.2" + +parse-json@^2.1.0, parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= + dependencies: + error-ex "^1.2.0" + +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + +parse-node-version@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b" + integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA== + +parse-passwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" + integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= + +parse5@5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2" + integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ== + +parseqs@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d" + integrity sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0= + dependencies: + better-assert "~1.0.0" + +parserlib@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/parserlib/-/parserlib-1.1.1.tgz#a64cfa724062434fdfc351c9a4ec2d92b94c06f4" + integrity sha1-pkz6ckBiQ0/fw1HJpOwtkrlMBvQ= + +parseuri@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.5.tgz#80204a50d4dbb779bfdc6ebe2778d90e4bce320a" + integrity sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo= + dependencies: + better-assert "~1.0.0" + +parseurl@~1.3.0, parseurl@~1.3.2, parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + +path-browserify@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" + integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-is-inside@^1.0.1, path-is-inside@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= + +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + +path-platform@~0.11.15: + version "0.11.15" + resolved "https://registry.yarnpkg.com/path-platform/-/path-platform-0.11.15.tgz#e864217f74c36850f0852b78dc7bf7d4a5721bf2" + integrity sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I= + +path-root-regex@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" + integrity sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0= + +path-root@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7" + integrity sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc= + dependencies: + path-root-regex "^0.1.0" + +path-starts-with@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-starts-with/-/path-starts-with-2.0.0.tgz#ffd6d51926cd497022b44d392196033d5451892f" + integrity sha512-3UHTHbJz5+NLkPafFR+2ycJOjoc4WV2e9qCZCnm71zHiWaFrm1XniLVTkZXvaRgxr1xFh9JsTdicpH2yM03nLA== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +path-type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" + integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= + dependencies: + pify "^2.0.0" + +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== + dependencies: + pify "^3.0.0" + +pbkdf2@^3.0.3: + version "3.0.17" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" + integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +phin@^2.9.1: + version "2.9.3" + resolved "https://registry.yarnpkg.com/phin/-/phin-2.9.3.tgz#f9b6ac10a035636fb65dfc576aaaa17b8743125c" + integrity sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA== + +phonegap-plugin-mobile-accessibility@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/phonegap-plugin-mobile-accessibility/-/phonegap-plugin-mobile-accessibility-1.0.5.tgz#95a8754d127508bc6e1ae259a53ce765836eac03" + integrity sha1-lah1TRJ1CLxuGuJZpTznZYNurAM= + +pify@^2.0.0, pify@^2.2.0, pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + +pixelmatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/pixelmatch/-/pixelmatch-4.0.2.tgz#8f47dcec5011b477b67db03c243bc1f3085e8854" + integrity sha1-j0fc7FARtHe2fbA8JDvB8wheiFQ= + dependencies: + pngjs "^3.0.0" + +pjson@1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/pjson/-/pjson-1.0.9.tgz#8a9520ce76a4739f8fee91679dad6b065b1c7938" + integrity sha512-4hRJH3YzkUpOlShRzhyxAmThSNnAaIlWZCAb27hd0pVUAXNUAHAO7XZbsPPvsCYwBFEScTmCCL6DGE8NyZ8BdQ== + +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== + dependencies: + find-up "^3.0.0" + +plist@^3.0.0, plist@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/plist/-/plist-3.0.1.tgz#a9b931d17c304e8912ef0ba3bdd6182baf2e1f8c" + integrity sha512-GpgvHHocGRyQm74b6FWEZZVRroHKE1I0/BTjAmySaohK+cUn+hZpbqXkc3KWgW3gQYkqcQej35FohcT0FRlkRQ== + dependencies: + base64-js "^1.2.3" + xmlbuilder "^9.0.7" + xmldom "0.1.x" + +plugin-error@1.0.1, plugin-error@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-1.0.1.tgz#77016bd8919d0ac377fdcdd0322328953ca5781c" + integrity sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA== + dependencies: + ansi-colors "^1.0.1" + arr-diff "^4.0.0" + arr-union "^3.1.0" + extend-shallow "^3.0.2" + +plugin-error@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-0.1.2.tgz#3b9bb3335ccf00f425e07437e19276967da47ace" + integrity sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4= + dependencies: + ansi-cyan "^0.1.1" + ansi-red "^0.1.1" + arr-diff "^1.0.1" + arr-union "^2.0.1" + extend-shallow "^1.1.2" + +plur@^3.0.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/plur/-/plur-3.1.1.tgz#60267967866a8d811504fe58f2faaba237546a5b" + integrity sha512-t1Ax8KUvV3FFII8ltczPn2tJdjqbd1sIzu6t4JL7nQ3EyeL/lTrj5PWKb06ic5/6XYDr65rQ4uzQEGN70/6X5w== + dependencies: + irregular-plurals "^2.0.0" + +pluralize@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" + integrity sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU= + +pn@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" + integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA== + +pngjs@^3.0.0, pngjs@^3.3.3: + version "3.4.0" + resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f" + integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w== + +pngquant-bin@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/pngquant-bin/-/pngquant-bin-3.1.1.tgz#d124d98a75a9487f40c1640b4dbfcbb2bd5a1fd1" + integrity sha1-0STZinWpSH9AwWQLTb/Lsr1aH9E= + dependencies: + bin-build "^2.0.0" + bin-wrapper "^3.0.0" + logalot "^2.0.0" + +pngquant-bin@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/pngquant-bin/-/pngquant-bin-5.0.2.tgz#6f34f3e89c9722a72bbc509062b40f1b17cda460" + integrity sha512-OLdT+4JZx5BqE1CFJkrvomYV0aSsv6x2Bba+aWaVc0PMfWlE+ZByNKYAdKeIqsM4uvW1HOSEHnf8KcOnykPNxA== + dependencies: + bin-build "^3.0.0" + bin-wrapper "^4.0.1" + execa "^0.10.0" + logalot "^2.0.0" + +portscanner@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/portscanner/-/portscanner-2.1.1.tgz#eabb409e4de24950f5a2a516d35ae769343fbb96" + integrity sha1-6rtAnk3iSVD1oqUW01rnaTQ/u5Y= + dependencies: + async "1.5.2" + is-number-like "^1.0.3" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + +postcss-assets@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-assets/-/postcss-assets-5.0.0.tgz#f721d07d339605fb58414e9f69cf05401c54e709" + integrity sha1-9yHQfTOWBftYQU6fac8FQBxU5wk= + dependencies: + assets "^3.0.0" + bluebird "^3.5.0" + postcss "^6.0.10" + postcss-functions "^3.0.0" + +postcss-attribute-case-insensitive@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-4.0.1.tgz#b2a721a0d279c2f9103a36331c88981526428cc7" + integrity sha512-L2YKB3vF4PetdTIthQVeT+7YiSzMoNMLLYxPXXppOOP7NoazEAy45sh2LvJ8leCQjfBcfkYQs8TtCcQjeZTp8A== + dependencies: + postcss "^7.0.2" + postcss-selector-parser "^5.0.0" + +postcss-calc@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-7.0.1.tgz#36d77bab023b0ecbb9789d84dcb23c4941145436" + integrity sha512-oXqx0m6tb4N3JGdmeMSc/i91KppbYsFZKdH0xMOqK8V1rJlzrKlTdokz8ozUXLVejydRN6u2IddxpcijRj2FqQ== + dependencies: + css-unit-converter "^1.1.1" + postcss "^7.0.5" + postcss-selector-parser "^5.0.0-rc.4" + postcss-value-parser "^3.3.1" + +postcss-color-functional-notation@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/postcss-color-functional-notation/-/postcss-color-functional-notation-2.0.1.tgz#5efd37a88fbabeb00a2966d1e53d98ced93f74e0" + integrity sha512-ZBARCypjEDofW4P6IdPVTLhDNXPRn8T2s1zHbZidW6rPaaZvcnCS2soYFIQJrMZSxiePJ2XIYTlcb2ztr/eT2g== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-color-gray@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-color-gray/-/postcss-color-gray-5.0.0.tgz#532a31eb909f8da898ceffe296fdc1f864be8547" + integrity sha512-q6BuRnAGKM/ZRpfDascZlIZPjvwsRye7UDNalqVz3s7GDxMtqPY6+Q871liNxsonUw8oC61OG+PSaysYpl1bnw== + dependencies: + "@csstools/convert-colors" "^1.4.0" + postcss "^7.0.5" + postcss-values-parser "^2.0.0" + +postcss-color-hex-alpha@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/postcss-color-hex-alpha/-/postcss-color-hex-alpha-5.0.3.tgz#a8d9ca4c39d497c9661e374b9c51899ef0f87388" + integrity sha512-PF4GDel8q3kkreVXKLAGNpHKilXsZ6xuu+mOQMHWHLPNyjiUBOr75sp5ZKJfmv1MCus5/DWUGcK9hm6qHEnXYw== + dependencies: + postcss "^7.0.14" + postcss-values-parser "^2.0.1" + +postcss-color-mod-function@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/postcss-color-mod-function/-/postcss-color-mod-function-3.0.3.tgz#816ba145ac11cc3cb6baa905a75a49f903e4d31d" + integrity sha512-YP4VG+xufxaVtzV6ZmhEtc+/aTXH3d0JLpnYfxqTvwZPbJhWqp8bSY3nfNzNRFLgB4XSaBA82OE4VjOOKpCdVQ== + dependencies: + "@csstools/convert-colors" "^1.4.0" + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-color-rebeccapurple@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-4.0.1.tgz#c7a89be872bb74e45b1e3022bfe5748823e6de77" + integrity sha512-aAe3OhkS6qJXBbqzvZth2Au4V3KieR5sRQ4ptb2b2O8wgvB3SJBsdG+jsn2BZbbwekDG8nTfcCNKcSfe/lEy8g== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-colormin@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-4.0.3.tgz#ae060bce93ed794ac71264f08132d550956bd381" + integrity sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw== + dependencies: + browserslist "^4.0.0" + color "^3.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-convert-values@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz#ca3813ed4da0f812f9d43703584e449ebe189a7f" + integrity sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ== + dependencies: + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-custom-media@^7.0.8: + version "7.0.8" + resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-7.0.8.tgz#fffd13ffeffad73621be5f387076a28b00294e0c" + integrity sha512-c9s5iX0Ge15o00HKbuRuTqNndsJUbaXdiNsksnVH8H4gdc+zbLzr/UasOwNG6CTDpLFekVY4672eWdiiWu2GUg== + dependencies: + postcss "^7.0.14" + +postcss-custom-properties@^8.0.11: + version "8.0.11" + resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz#2d61772d6e92f22f5e0d52602df8fae46fa30d97" + integrity sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA== + dependencies: + postcss "^7.0.17" + postcss-values-parser "^2.0.1" + +postcss-custom-selectors@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/postcss-custom-selectors/-/postcss-custom-selectors-5.1.2.tgz#64858c6eb2ecff2fb41d0b28c9dd7b3db4de7fba" + integrity sha512-DSGDhqinCqXqlS4R7KGxL1OSycd1lydugJ1ky4iRXPHdBRiozyMHrdu0H3o7qNOCiZwySZTUI5MV0T8QhCLu+w== + dependencies: + postcss "^7.0.2" + postcss-selector-parser "^5.0.0-rc.3" + +postcss-dir-pseudo-class@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-5.0.0.tgz#6e3a4177d0edb3abcc85fdb6fbb1c26dabaeaba2" + integrity sha512-3pm4oq8HYWMZePJY+5ANriPs3P07q+LW6FAdTlkFH2XqDdP4HeeJYMOzn0HYLhRSjBO3fhiqSwwU9xEULSrPgw== + dependencies: + postcss "^7.0.2" + postcss-selector-parser "^5.0.0-rc.3" + +postcss-discard-comments@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz#1fbabd2c246bff6aaad7997b2b0918f4d7af4033" + integrity sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg== + dependencies: + postcss "^7.0.0" + +postcss-discard-duplicates@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz#3fe133cd3c82282e550fc9b239176a9207b784eb" + integrity sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ== + dependencies: + postcss "^7.0.0" + +postcss-discard-empty@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz#c8c951e9f73ed9428019458444a02ad90bb9f765" + integrity sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w== + dependencies: + postcss "^7.0.0" + +postcss-discard-overridden@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz#652aef8a96726f029f5e3e00146ee7a4e755ff57" + integrity sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg== + dependencies: + postcss "^7.0.0" + +postcss-discard-unused@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-unused/-/postcss-discard-unused-4.0.1.tgz#ee7cc66af8c7e8c19bd36f12d09c4bde4039abea" + integrity sha512-/3vq4LU0bLH2Lj4NYN7BTf2caly0flUB7Xtrk9a5K3yLuXMkHMqMO/x3sDq8W2b1eQFSCyY0IVz2L+0HP8kUUA== + dependencies: + postcss "^7.0.0" + postcss-selector-parser "^3.0.0" + uniqs "^2.0.0" + +postcss-double-position-gradients@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/postcss-double-position-gradients/-/postcss-double-position-gradients-1.0.0.tgz#fc927d52fddc896cb3a2812ebc5df147e110522e" + integrity sha512-G+nV8EnQq25fOI8CH/B6krEohGWnF5+3A6H/+JEpOncu5dCnkS1QQ6+ct3Jkaepw1NGVqqOZH6lqrm244mCftA== + dependencies: + postcss "^7.0.5" + postcss-values-parser "^2.0.0" + +postcss-env-function@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/postcss-env-function/-/postcss-env-function-2.0.2.tgz#0f3e3d3c57f094a92c2baf4b6241f0b0da5365d7" + integrity sha512-rwac4BuZlITeUbiBq60h/xbLzXY43qOsIErngWa4l7Mt+RaSkT7QBjXVGTcBHupykkblHMDrBFh30zchYPaOUw== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-focus-visible@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-focus-visible/-/postcss-focus-visible-4.0.0.tgz#477d107113ade6024b14128317ade2bd1e17046e" + integrity sha512-Z5CkWBw0+idJHSV6+Bgf2peDOFf/x4o+vX/pwcNYrWpXFrSfTkQ3JQ1ojrq9yS+upnAlNRHeg8uEwFTgorjI8g== + dependencies: + postcss "^7.0.2" + +postcss-focus-within@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-focus-within/-/postcss-focus-within-3.0.0.tgz#763b8788596cee9b874c999201cdde80659ef680" + integrity sha512-W0APui8jQeBKbCGZudW37EeMCjDeVxKgiYfIIEo8Bdh5SpB9sxds/Iq8SEuzS0Q4YFOlG7EPFulbbxujpkrV2w== + dependencies: + postcss "^7.0.2" + +postcss-font-variant@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-font-variant/-/postcss-font-variant-4.0.0.tgz#71dd3c6c10a0d846c5eda07803439617bbbabacc" + integrity sha512-M8BFYKOvCrI2aITzDad7kWuXXTm0YhGdP9Q8HanmN4EF1Hmcgs1KK5rSHylt/lUJe8yLxiSwWAHdScoEiIxztg== + dependencies: + postcss "^7.0.2" + +postcss-functions@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-functions/-/postcss-functions-3.0.0.tgz#0e94d01444700a481de20de4d55fb2640564250e" + integrity sha1-DpTQFERwCkgd4g3k1V+yZAVkJQ4= + dependencies: + glob "^7.1.2" + object-assign "^4.1.1" + postcss "^6.0.9" + postcss-value-parser "^3.3.0" + +postcss-gap-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-gap-properties/-/postcss-gap-properties-2.0.0.tgz#431c192ab3ed96a3c3d09f2ff615960f902c1715" + integrity sha512-QZSqDaMgXCHuHTEzMsS2KfVDOq7ZFiknSpkrPJY6jmxbugUPTuSzs/vuE5I3zv0WAS+3vhrlqhijiprnuQfzmg== + dependencies: + postcss "^7.0.2" + +postcss-image-set-function@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/postcss-image-set-function/-/postcss-image-set-function-3.0.1.tgz#28920a2f29945bed4c3198d7df6496d410d3f288" + integrity sha512-oPTcFFip5LZy8Y/whto91L9xdRHCWEMs3e1MdJxhgt4jy2WYXfhkng59fH5qLXSCPN8k4n94p1Czrfe5IOkKUw== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-initial@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-3.0.1.tgz#99d319669a13d6c06ef8e70d852f68cb1b399b61" + integrity sha512-I2Sz83ZSHybMNh02xQDK609lZ1/QOyYeuizCjzEhlMgeV/HcDJapQiH4yTqLjZss0X6/6VvKFXUeObaHpJoINw== + dependencies: + lodash.template "^4.5.0" + postcss "^7.0.2" + +postcss-lab-function@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-2.0.1.tgz#bb51a6856cd12289ab4ae20db1e3821ef13d7d2e" + integrity sha512-whLy1IeZKY+3fYdqQFuDBf8Auw+qFuVnChWjmxm/UhHWqNHZx+B99EwxTvGYmUBqe3Fjxs4L1BoZTJmPu6usVg== + dependencies: + "@csstools/convert-colors" "^1.4.0" + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-load-config@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-2.1.0.tgz#c84d692b7bb7b41ddced94ee62e8ab31b417b003" + integrity sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q== + dependencies: + cosmiconfig "^5.0.0" + import-cwd "^2.0.0" + +postcss-logical@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-logical/-/postcss-logical-3.0.0.tgz#2495d0f8b82e9f262725f75f9401b34e7b45d5b5" + integrity sha512-1SUKdJc2vuMOmeItqGuNaC+N8MzBWFWEkAnRnLpFYj1tGGa7NqyVBujfRtgNa2gXR+6RkGUiB2O5Vmh7E2RmiA== + dependencies: + postcss "^7.0.2" + +postcss-media-minmax@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-media-minmax/-/postcss-media-minmax-4.0.0.tgz#b75bb6cbc217c8ac49433e12f22048814a4f5ed5" + integrity sha512-fo9moya6qyxsjbFAYl97qKO9gyre3qvbMnkOZeZwlsW6XYFsvs2DMGDlchVLfAd8LHPZDxivu/+qW2SMQeTHBw== + dependencies: + postcss "^7.0.2" + +postcss-merge-idents@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-merge-idents/-/postcss-merge-idents-4.0.1.tgz#b7df282a92f052ea0a66c62d8f8812e6d2cbed23" + integrity sha512-43S/VNdF6II0NZ31YxcvNYq4gfURlPAAsJW/z84avBXQCaP4I4qRHUH18slW/SOlJbcxxCobflPNUApYDddS7A== + dependencies: + cssnano-util-same-parent "^4.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-merge-longhand@^4.0.11: + version "4.0.11" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz#62f49a13e4a0ee04e7b98f42bb16062ca2549e24" + integrity sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw== + dependencies: + css-color-names "0.0.4" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + stylehacks "^4.0.0" + +postcss-merge-rules@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz#362bea4ff5a1f98e4075a713c6cb25aefef9a650" + integrity sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ== + dependencies: + browserslist "^4.0.0" + caniuse-api "^3.0.0" + cssnano-util-same-parent "^4.0.0" + postcss "^7.0.0" + postcss-selector-parser "^3.0.0" + vendors "^1.0.0" + +postcss-minify-font-values@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz#cd4c344cce474343fac5d82206ab2cbcb8afd5a6" + integrity sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg== + dependencies: + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-minify-gradients@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz#93b29c2ff5099c535eecda56c4aa6e665a663471" + integrity sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q== + dependencies: + cssnano-util-get-arguments "^4.0.0" + is-color-stop "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-minify-params@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz#6b9cef030c11e35261f95f618c90036d680db874" + integrity sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg== + dependencies: + alphanum-sort "^1.0.0" + browserslist "^4.0.0" + cssnano-util-get-arguments "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + uniqs "^2.0.0" + +postcss-minify-selectors@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz#e2e5eb40bfee500d0cd9243500f5f8ea4262fbd8" + integrity sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g== + dependencies: + alphanum-sort "^1.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-selector-parser "^3.0.0" + +postcss-nesting@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-7.0.1.tgz#b50ad7b7f0173e5b5e3880c3501344703e04c052" + integrity sha512-FrorPb0H3nuVq0Sff7W2rnc3SmIcruVC6YwpcS+k687VxyxO33iE1amna7wHuRVzM8vfiYofXSBHNAZ3QhLvYg== + dependencies: + postcss "^7.0.2" + +postcss-normalize-charset@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz#8b35add3aee83a136b0471e0d59be58a50285dd4" + integrity sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g== + dependencies: + postcss "^7.0.0" + +postcss-normalize-display-values@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz#0dbe04a4ce9063d4667ed2be476bb830c825935a" + integrity sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ== + dependencies: + cssnano-util-get-match "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-positions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz#05f757f84f260437378368a91f8932d4b102917f" + integrity sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA== + dependencies: + cssnano-util-get-arguments "^4.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-repeat-style@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz#c4ebbc289f3991a028d44751cbdd11918b17910c" + integrity sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q== + dependencies: + cssnano-util-get-arguments "^4.0.0" + cssnano-util-get-match "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-string@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz#cd44c40ab07a0c7a36dc5e99aace1eca4ec2690c" + integrity sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA== + dependencies: + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-timing-functions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz#8e009ca2a3949cdaf8ad23e6b6ab99cb5e7d28d9" + integrity sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A== + dependencies: + cssnano-util-get-match "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-unicode@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz#841bd48fdcf3019ad4baa7493a3d363b52ae1cfb" + integrity sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg== + dependencies: + browserslist "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-url@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz#10e437f86bc7c7e58f7b9652ed878daaa95faae1" + integrity sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA== + dependencies: + is-absolute-url "^2.0.0" + normalize-url "^3.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-whitespace@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz#bf1d4070fe4fcea87d1348e825d8cc0c5faa7d82" + integrity sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA== + dependencies: + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-ordered-values@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz#0cf75c820ec7d5c4d280189559e0b571ebac0eee" + integrity sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw== + dependencies: + cssnano-util-get-arguments "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-overflow-shorthand@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-overflow-shorthand/-/postcss-overflow-shorthand-2.0.0.tgz#31ecf350e9c6f6ddc250a78f0c3e111f32dd4c30" + integrity sha512-aK0fHc9CBNx8jbzMYhshZcEv8LtYnBIRYQD5i7w/K/wS9c2+0NSR6B3OVMu5y0hBHYLcMGjfU+dmWYNKH0I85g== + dependencies: + postcss "^7.0.2" + +postcss-page-break@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-page-break/-/postcss-page-break-2.0.0.tgz#add52d0e0a528cabe6afee8b46e2abb277df46bf" + integrity sha512-tkpTSrLpfLfD9HvgOlJuigLuk39wVTbbd8RKcy8/ugV2bNBUW3xU+AIqyxhDrQr1VUj1RmyJrBn1YWrqUm9zAQ== + dependencies: + postcss "^7.0.2" + +postcss-place@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-place/-/postcss-place-4.0.1.tgz#e9f39d33d2dc584e46ee1db45adb77ca9d1dcc62" + integrity sha512-Zb6byCSLkgRKLODj/5mQugyuj9bvAAw9LqJJjgwz5cYryGeXfFZfSXoP1UfveccFmeq0b/2xxwcTEVScnqGxBg== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-preset-env@^6.5.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-6.7.0.tgz#c34ddacf8f902383b35ad1e030f178f4cdf118a5" + integrity sha512-eU4/K5xzSFwUFJ8hTdTQzo2RBLbDVt83QZrAvI07TULOkmyQlnYlpwep+2yIK+K+0KlZO4BvFcleOCCcUtwchg== + dependencies: + autoprefixer "^9.6.1" + browserslist "^4.6.4" + caniuse-lite "^1.0.30000981" + css-blank-pseudo "^0.1.4" + css-has-pseudo "^0.10.0" + css-prefers-color-scheme "^3.1.1" + cssdb "^4.4.0" + postcss "^7.0.17" + postcss-attribute-case-insensitive "^4.0.1" + postcss-color-functional-notation "^2.0.1" + postcss-color-gray "^5.0.0" + postcss-color-hex-alpha "^5.0.3" + postcss-color-mod-function "^3.0.3" + postcss-color-rebeccapurple "^4.0.1" + postcss-custom-media "^7.0.8" + postcss-custom-properties "^8.0.11" + postcss-custom-selectors "^5.1.2" + postcss-dir-pseudo-class "^5.0.0" + postcss-double-position-gradients "^1.0.0" + postcss-env-function "^2.0.2" + postcss-focus-visible "^4.0.0" + postcss-focus-within "^3.0.0" + postcss-font-variant "^4.0.0" + postcss-gap-properties "^2.0.0" + postcss-image-set-function "^3.0.1" + postcss-initial "^3.0.0" + postcss-lab-function "^2.0.1" + postcss-logical "^3.0.0" + postcss-media-minmax "^4.0.0" + postcss-nesting "^7.0.0" + postcss-overflow-shorthand "^2.0.0" + postcss-page-break "^2.0.0" + postcss-place "^4.0.1" + postcss-pseudo-class-any-link "^6.0.0" + postcss-replace-overflow-wrap "^3.0.0" + postcss-selector-matches "^4.0.0" + postcss-selector-not "^4.0.0" + +postcss-pseudo-class-any-link@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-6.0.0.tgz#2ed3eed393b3702879dec4a87032b210daeb04d1" + integrity sha512-lgXW9sYJdLqtmw23otOzrtbDXofUdfYzNm4PIpNE322/swES3VU9XlXHeJS46zT2onFO7V1QFdD4Q9LiZj8mew== + dependencies: + postcss "^7.0.2" + postcss-selector-parser "^5.0.0-rc.3" + +postcss-reduce-idents@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-reduce-idents/-/postcss-reduce-idents-4.0.2.tgz#30447a6ec20941e78e21bd4482a11f569c4f455b" + integrity sha512-Tz70Ri10TclPoCtFfftjFVddx3fZGUkr0dEDbIEfbYhFUOFQZZ77TEqRrU0e6TvAvF+Wa5VVzYTpFpq0uwFFzw== + dependencies: + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-reduce-initial@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz#7fd42ebea5e9c814609639e2c2e84ae270ba48df" + integrity sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA== + dependencies: + browserslist "^4.0.0" + caniuse-api "^3.0.0" + has "^1.0.0" + postcss "^7.0.0" + +postcss-reduce-transforms@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz#17efa405eacc6e07be3414a5ca2d1074681d4e29" + integrity sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg== + dependencies: + cssnano-util-get-match "^4.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-replace-overflow-wrap@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-3.0.0.tgz#61b360ffdaedca84c7c918d2b0f0d0ea559ab01c" + integrity sha512-2T5hcEHArDT6X9+9dVSPQdo7QHzG4XKclFT8rU5TzJPDN7RIRTbO9c4drUISOVemLj03aezStHCR2AIcr8XLpw== + dependencies: + postcss "^7.0.2" + +postcss-round-subpixels@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/postcss-round-subpixels/-/postcss-round-subpixels-1.2.0.tgz#e21d6ac5952e185f9bdc008b94f004fe509d0a11" + integrity sha1-4h1qxZUuGF+b3ACLlPAE/lCdChE= + dependencies: + postcss "^5.0.2" + postcss-value-parser "^3.1.2" + +postcss-selector-matches@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-selector-matches/-/postcss-selector-matches-4.0.0.tgz#71c8248f917ba2cc93037c9637ee09c64436fcff" + integrity sha512-LgsHwQR/EsRYSqlwdGzeaPKVT0Ml7LAT6E75T8W8xLJY62CE4S/l03BWIt3jT8Taq22kXP08s2SfTSzaraoPww== + dependencies: + balanced-match "^1.0.0" + postcss "^7.0.2" + +postcss-selector-not@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-4.0.0.tgz#c68ff7ba96527499e832724a2674d65603b645c0" + integrity sha512-W+bkBZRhqJaYN8XAnbbZPLWMvZD1wKTu0UxtFKdhtGjWYmxhkUneoeOhRJKdAE5V7ZTlnbHfCR+6bNwK9e1dTQ== + dependencies: + balanced-match "^1.0.0" + postcss "^7.0.2" + +postcss-selector-parser@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz#4f875f4afb0c96573d5cf4d74011aee250a7e865" + integrity sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU= + dependencies: + dot-prop "^4.1.1" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-selector-parser@^5.0.0, postcss-selector-parser@^5.0.0-rc.3, postcss-selector-parser@^5.0.0-rc.4: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz#249044356697b33b64f1a8f7c80922dddee7195c" + integrity sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ== + dependencies: + cssesc "^2.0.0" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-svgo@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-4.0.2.tgz#17b997bc711b333bab143aaed3b8d3d6e3d38258" + integrity sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw== + dependencies: + is-svg "^3.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + svgo "^1.0.0" + +postcss-unique-selectors@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz#9446911f3289bfd64c6d680f073c03b1f9ee4bac" + integrity sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg== + dependencies: + alphanum-sort "^1.0.0" + postcss "^7.0.0" + uniqs "^2.0.0" + +postcss-unprefix@^2.1.3: + version "2.1.4" + resolved "https://registry.yarnpkg.com/postcss-unprefix/-/postcss-unprefix-2.1.4.tgz#ab1c038ab77f068799ed36e1cbd997b51e7360a1" + integrity sha512-s+muBiGIMx3RvgPTtPBnSrfvIBHJ2Zx16QZf/VDB/sAxdYP6FIzci8d1gLh0+9psu5W6zVtCbU5micNt6Zh3cg== + dependencies: + autoprefixer "^9.4.3" + known-css-properties "^0.11.0" + normalize-range "^0.1.2" + postcss-selector-parser "^5.0.0" + postcss-value-parser "^3.3.1" + pseudo-classes "^1.0.0" + pseudo-elements "^1.1.0" + +postcss-value-parser@^3.0.0, postcss-value-parser@^3.1.2, postcss-value-parser@^3.3.0, postcss-value-parser@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" + integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== + +postcss-value-parser@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.2.tgz#482282c09a42706d1fc9a069b73f44ec08391dc9" + integrity sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ== + +postcss-values-parser@^2.0.0, postcss-values-parser@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz#da8b472d901da1e205b47bdc98637b9e9e550e5f" + integrity sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg== + dependencies: + flatten "^1.0.2" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-zindex@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-zindex/-/postcss-zindex-4.0.1.tgz#8db6a4cec3111e5d3fd99ea70abeda61873d10c1" + integrity sha512-d/8BlQcUdEugZNRM9AdCA2V4fqREUtn/wcixLN3L6ITgc2P/FMcVVYz8QZkhItWT9NB5qr8wuN2dJCE4/+dlrA== + dependencies: + has "^1.0.0" + postcss "^7.0.0" + uniqs "^2.0.0" + +postcss@^5.0.2: + version "5.2.18" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.18.tgz#badfa1497d46244f6390f58b319830d9107853c5" + integrity sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg== + dependencies: + chalk "^1.1.3" + js-base64 "^2.1.9" + source-map "^0.5.6" + supports-color "^3.2.3" + +postcss@^6.0.10, postcss@^6.0.9: + version "6.0.23" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" + integrity sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag== + dependencies: + chalk "^2.4.1" + source-map "^0.6.1" + supports-color "^5.4.0" + +postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.5, postcss@^7.0.6: + version "7.0.18" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.18.tgz#4b9cda95ae6c069c67a4d933029eddd4838ac233" + integrity sha512-/7g1QXXgegpF+9GJj4iN7ChGF40sYuGYJ8WZu8DZWnmhQ/G36hfdk3q9LBJmoK+lZ+yzZ5KYpOoxq7LF1BxE8g== + dependencies: + chalk "^2.4.2" + source-map "^0.6.1" + supports-color "^6.1.0" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +prepend-http@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= + +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= + +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= + +pretty-bytes@^5.1.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.3.0.tgz#f2849e27db79fb4d6cfe24764fc4134f165989f2" + integrity sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg== + +pretty-hrtime@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-0.2.2.tgz#d4fd88351e3a4741f8173af7d6a4b846f9895c00" + integrity sha1-1P2INR46R0H4Fzr31qS4RvmJXAA= + +pretty-hrtime@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" + integrity sha1-t+PqQkNaTJsnWdmeDyAesZWALuE= + +private@^0.1.6, private@~0.1.5: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== + +process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +process-nextick-args@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + integrity sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M= + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= + +process@~0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf" + integrity sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8= + +progress@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" + integrity sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74= + +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= + +promise-polyfill@^8.1.0: + version "8.1.3" + resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-8.1.3.tgz#8c99b3cf53f3a91c68226ffde7bde81d7f904116" + integrity sha512-MG5r82wBzh7pSKDRa9y+vllNHz3e3d4CNj1PQE4BQYxLme0gKYYBm9YENq+UkEikyZ0XbiGWxYlVw3Rl9O/U8g== + +proto-list@~1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" + integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= + +proxy-addr@~2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.5.tgz#34cbd64a2d81f4b1fd21e76f9f06c8a45299ee34" + integrity sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ== + dependencies: + forwarded "~0.1.2" + ipaddr.js "1.9.0" + +proxy-middleware@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/proxy-middleware/-/proxy-middleware-0.5.1.tgz#da24d5d58c1ddf13dad237c7eca503849eaea903" + integrity sha1-2iTV1Ywd3xPa0jfH7KUDhJ6uqQM= + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= + +pseudo-classes@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pseudo-classes/-/pseudo-classes-1.0.0.tgz#60a69b67395c36ff119c4d1c86e1981785206b96" + integrity sha1-YKabZzlcNv8RnE0chuGYF4Uga5Y= + +pseudo-elements@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pseudo-elements/-/pseudo-elements-1.1.0.tgz#9ba6dd8ac3ce1f3d7d36d4355aa3e28d08391f28" + integrity sha1-m6bdisPOHz19NtQ1WqPijQg5Hyg= + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= + +psl@^1.1.24, psl@^1.1.28: + version "1.4.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.4.0.tgz#5dd26156cdb69fa1fdb8ab1991667d3f80ced7c2" + integrity sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw== + +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + +pump@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.3: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + +punycode@^1.2.4, punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +q@^1.1.2: + version "1.5.1" + resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" + integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= + +qs@2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/qs/-/qs-2.2.4.tgz#2e9fbcd34b540e3421c924ecd01e90aa975319c8" + integrity sha1-Lp+800tUDjQhySTs0B6QqpdTGcg= + +qs@6.2.3: + version "6.2.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.2.3.tgz#1cfcb25c10a9b2b483053ff39f5dfc9233908cfe" + integrity sha1-HPyyXBCpsrSDBT/zn138kjOQjP4= + +qs@6.7.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" + integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== + +qs@~2.2.3: + version "2.2.5" + resolved "https://registry.yarnpkg.com/qs/-/qs-2.2.5.tgz#1088abaf9dcc0ae5ae45b709e6c6b5888b23923c" + integrity sha1-EIirr53MCuWuRbcJ5sa1iIsjkjw= + +qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + +query-string@^5.0.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" + integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== + dependencies: + decode-uri-component "^0.2.0" + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + +query-string@^6.8.1: + version "6.8.3" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.8.3.tgz#fd9fb7ffb068b79062b43383685611ee47777d4b" + integrity sha512-llcxWccnyaWlODe7A9hRjkvdCKamEKTh+wH8ITdTc3OhchaqUZteiSCX/2ablWHVrkVIe04dntnaZJ7BdyW0lQ== + dependencies: + decode-uri-component "^0.2.0" + split-on-first "^1.0.0" + strict-uri-encode "^2.0.0" + +querystring-es3@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + +randomatic@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed" + integrity sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw== + dependencies: + is-number "^4.0.0" + kind-of "^6.0.0" + math-random "^1.0.1" + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +range-parser@~1.2.0, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-1.3.0.tgz#978230a156a5548f42eef14de22d0f4f610083d1" + integrity sha1-l4IwoValVI9C7vFN4i0PT2EAg9E= + dependencies: + bytes "1" + iconv-lite "0.4.4" + +raw-body@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" + integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== + dependencies: + bytes "3.1.0" + http-errors "1.7.2" + iconv-lite "0.4.24" + unpipe "1.0.0" + +raw-body@^2.3.2: + version "2.4.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c" + integrity sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA== + dependencies: + bytes "3.1.0" + http-errors "1.7.3" + iconv-lite "0.4.24" + unpipe "1.0.0" + +rc@^1.1.2, rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +rcedit@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/rcedit/-/rcedit-2.0.0.tgz#dcc85d93aa91a41c1ebc5c6aa1dfc43ea28b7dad" + integrity sha512-XcFGyEBjhWSsud+R8elwQtGBbVkCf7tAiad+nXo5jc6l2rMf46NfGNwjnmBNneBIZDfq+Npf8lwP371JTONfrw== + +rcfinder@^0.1.6: + version "0.1.9" + resolved "https://registry.yarnpkg.com/rcfinder/-/rcfinder-0.1.9.tgz#f3e80f387ddf9ae80ae30a4100329642eae81115" + integrity sha1-8+gPOH3fmugK4wpBADKWQuroERU= + dependencies: + lodash.clonedeep "^4.3.2" + +rcloader@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/rcloader/-/rcloader-0.1.4.tgz#d0c902f0444983a2ee5a6907937c6a79ca704509" + integrity sha1-0MkC8ERJg6LuWmkHk3xqecpwRQk= + dependencies: + lodash "^3.0.1" + rcfinder "^0.1.6" + +rcloader@^0.2.1: + version "0.2.2" + resolved "https://registry.yarnpkg.com/rcloader/-/rcloader-0.2.2.tgz#58d2298b462d0b9bfd2133d2a1ec74fbd705c717" + integrity sha1-WNIpi0YtC5v9ITPSoex0+9cFxxc= + dependencies: + lodash.assign "^4.2.0" + lodash.isobject "^3.0.2" + lodash.merge "^4.6.0" + rcfinder "^0.1.6" + +read-all-stream@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/read-all-stream/-/read-all-stream-3.1.0.tgz#35c3e177f2078ef789ee4bfafa4373074eaef4fa" + integrity sha1-NcPhd/IHjveJ7kv6+kNzB06u9Po= + dependencies: + pinkie-promise "^2.0.0" + readable-stream "^2.0.0" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" + integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= + dependencies: + find-up "^2.0.0" + read-pkg "^2.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +read-pkg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= + dependencies: + load-json-file "^2.0.0" + normalize-package-data "^2.3.2" + path-type "^2.0.0" + +read@~1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" + integrity sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ= + dependencies: + mute-stream "~0.0.4" + +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== + dependencies: + 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" + +readable-stream@1.0.27-1: + version "1.0.27-1" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.27-1.tgz#6b67983c20357cefd07f0165001a16d710d91078" + integrity sha1-a2eYPCA1fO/QfwFlABoW1xDZEHg= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +"readable-stream@2 || 3": + version "3.4.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.4.0.tgz#a51c26754658e0a3c21dbf59163bd45ba6f447fc" + integrity sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +"readable-stream@>=1.0.33-1 <1.1.0-0", readable-stream@~1.0.17, readable-stream@~1.0.2, readable-stream@~1.0.24, readable-stream@~1.0.26: + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@^1.0.27-1, readable-stream@~1.1.9: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@~2.0.0: + version "2.0.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" + integrity sha1-j5A0HmilPMySh4jaz80Rs265t44= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~0.10.x" + util-deprecate "~1.0.1" + +readdirp@^2.1.0, readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +readline2@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" + integrity sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + mute-stream "0.0.5" + +recast@~0.11.12: + version "0.11.23" + resolved "https://registry.yarnpkg.com/recast/-/recast-0.11.23.tgz#451fd3004ab1e4df9b4e4b66376b2a21912462d3" + integrity sha1-RR/TAEqx5N+bTktmN2sqIZEkYtM= + dependencies: + ast-types "0.9.6" + esprima "~3.1.0" + private "~0.1.5" + source-map "~0.5.0" + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= + dependencies: + resolve "^1.1.6" + +redent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94= + dependencies: + indent-string "^2.1.0" + strip-indent "^1.0.1" + +reflect-metadata@0.1.12: + version "0.1.12" + resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.12.tgz#311bf0c6b63cd782f228a81abe146a2bfa9c56f2" + integrity sha512-n+IyV+nGz3+0q3/Yf1ra12KpCyi001bi4XFxSjbiWWjfqb52iTTtpGXmCCAOWWIAn9KEuFZKGqBERHmrtScZ3A== + +regenerate-unicode-properties@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz#ef51e0f0ea4ad424b77bf7cb41f3e015c70a3f0e" + integrity sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA== + dependencies: + regenerate "^1.4.0" + +regenerate@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" + integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== + +regenerator-runtime@^0.10.0: + version "0.10.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" + integrity sha1-M2w+/BIgrc7dosn6tntaeVWjNlg= + +regenerator-runtime@^0.11.0, regenerator-runtime@^0.11.1: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== + +regenerator-runtime@^0.12.0: + version "0.12.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de" + integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg== + +regenerator-runtime@^0.13.3: + version "0.13.3" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz#7cf6a77d8f5c6f60eb73c5fc1955b2ceb01e6bf5" + integrity sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw== + +regenerator-runtime@^0.13.4: + version "0.13.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697" + integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA== + +regenerator-transform@^0.14.0: + version "0.14.1" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.1.tgz#3b2fce4e1ab7732c08f665dfdb314749c7ddd2fb" + integrity sha512-flVuee02C3FKRISbxhXl9mGzdbWUVHubl1SMaknjxkFB1/iqpJhArQUvRxOOPEc/9tAiX0BaQ28FJH10E4isSQ== + dependencies: + private "^0.1.6" + +regex-cache@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" + integrity sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ== + dependencies: + is-equal-shallow "^0.1.3" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexp-tree@^0.1.13: + version "0.1.13" + resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.13.tgz#5b19ab9377edc68bc3679256840bb29afc158d7f" + integrity sha512-hwdV/GQY5F8ReLZWO+W1SRoN5YfpOKY6852+tBFcma72DKBIcHjPRIlIvQN35bCOljuAfP2G2iB0FC/w236mUw== + +regexpp@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" + integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== + +regexpu-core@^4.5.4: + version "4.6.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.6.0.tgz#2037c18b327cfce8a6fea2a4ec441f2432afb8b6" + integrity sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg== + dependencies: + regenerate "^1.4.0" + regenerate-unicode-properties "^8.1.0" + regjsgen "^0.5.0" + regjsparser "^0.6.0" + unicode-match-property-ecmascript "^1.0.4" + unicode-match-property-value-ecmascript "^1.1.0" + +regjsgen@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.0.tgz#a7634dc08f89209c2049adda3525711fb97265dd" + integrity sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA== + +regjsparser@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.0.tgz#f1e6ae8b7da2bae96c99399b868cd6c933a2ba9c" + integrity sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ== + dependencies: + jsesc "~0.5.0" + +relateurl@0.2.x: + version "0.2.7" + resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" + integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +repeat-element@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + +repeat-string@^1.5.2, repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= + dependencies: + is-finite "^1.0.0" + +replace-ext@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924" + integrity sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ= + +replace-ext@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" + integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs= + +request-promise-core@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.2.tgz#339f6aababcafdb31c799ff158700336301d3346" + integrity sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag== + dependencies: + lodash "^4.17.11" + +request-promise-native@^1.0.5: + version "1.0.7" + resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.7.tgz#a49868a624bdea5069f1251d0a836e0d89aa2c59" + integrity sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w== + dependencies: + request-promise-core "1.1.2" + stealthy-require "^1.1.1" + tough-cookie "^2.3.3" + +request@^2.87.0, request@^2.88.0: + version "2.88.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" + integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.0" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.4.3" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +require-uncached@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" + integrity sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM= + dependencies: + caller-path "^0.1.0" + resolve-from "^1.0.0" + +requires-port@1.x.x: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= + dependencies: + resolve-from "^3.0.0" + +resolve-dir@^1.0.0, resolve-dir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" + integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M= + dependencies: + expand-tilde "^2.0.0" + global-modules "^1.0.0" + +resolve-from@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" + integrity sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY= + +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + integrity sha1-six699nWiBvItuZTM17rywoYh0g= + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.3.2: + version "1.12.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.12.0.tgz#3fc644a35c84a48554609ff26ec52b66fa577df6" + integrity sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w== + dependencies: + path-parse "^1.0.6" + +resp-modifier@6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/resp-modifier/-/resp-modifier-6.0.2.tgz#b124de5c4fbafcba541f48ffa73970f4aa456b4f" + integrity sha1-sSTeXE+6/LpUH0j/pzlw9KpFa08= + dependencies: + debug "^2.2.0" + minimatch "^3.0.2" + +responselike@1.0.2, responselike@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= + dependencies: + lowercase-keys "^1.0.0" + +restore-cursor@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" + integrity sha1-NGYfRohjJ/7SmRR5FSJS35LapUE= + dependencies: + exit-hook "^1.0.0" + onetime "^1.0.0" + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +rgb-regex@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/rgb-regex/-/rgb-regex-1.0.1.tgz#c0e0d6882df0e23be254a475e8edd41915feaeb1" + integrity sha1-wODWiC3w4jviVKR16O3UGRX+rrE= + +rgba-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" + integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM= + +rimraf@2, rimraf@^2.2.6, rimraf@^2.4.0, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +rimraf@2.6.3, rimraf@~2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + +rimraf@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.0.tgz#614176d4b3010b75e5c390eb0ee96f6dc0cebb9b" + integrity sha512-NDGVxTsjqfunkds7CqsOiEnxln4Bo7Nddl3XhS4pXg5OzwkLqJ971ZVAAnB+DDLnF76N+VnDEiBHaVV8I06SUg== + dependencies: + glob "^7.1.3" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +run-async@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" + integrity sha1-yK1KXhEGYeQCp9IbUw4AnyX444k= + dependencies: + once "^1.3.0" + +run-async@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" + integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= + dependencies: + is-promise "^2.1.0" + +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= + dependencies: + aproba "^1.1.1" + +rusha@^0.8.13: + version "0.8.13" + resolved "https://registry.yarnpkg.com/rusha/-/rusha-0.8.13.tgz#9a084e7b860b17bff3015b92c67a6a336191513a" + integrity sha1-mghOe4YLF7/zAVuSxnpqM2GRUTo= + +rx-lite@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" + integrity sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI= + +rx@4.1.0, rx@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" + integrity sha1-pfE/957zt0D+MKqAP7CfmIBdR4I= + +rxjs@^5.5.6: + version "5.5.12" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.12.tgz#6fa61b8a77c3d793dbaf270bee2f43f652d741cc" + integrity sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw== + dependencies: + symbol-observable "1.0.1" + +rxjs@^6.4.0: + version "6.5.3" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.3.tgz#510e26317f4db91a7eb1de77d9dd9ba0a4899a3a" + integrity sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA== + dependencies: + tslib "^1.9.0" + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" + integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sanitize-filename@^1.6.0, sanitize-filename@^1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/sanitize-filename/-/sanitize-filename-1.6.3.tgz#755ebd752045931977e30b2025d340d7c9090378" + integrity sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg== + dependencies: + truncate-utf8-bytes "^1.0.0" + +sass-graph@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/sass-graph/-/sass-graph-2.2.4.tgz#13fbd63cd1caf0908b9fd93476ad43a51d1e0b49" + integrity sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k= + dependencies: + glob "^7.0.0" + lodash "^4.0.0" + scss-tokenizer "^0.2.3" + yargs "^7.0.0" + +sass-lint@^1.12.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/sass-lint/-/sass-lint-1.13.1.tgz#5fd2b2792e9215272335eb0f0dc607f61e8acc8f" + integrity sha512-DSyah8/MyjzW2BWYmQWekYEKir44BpLqrCFsgs9iaWiVTcwZfwXHF586hh3D1n+/9ihUNMfd8iHAyb9KkGgs7Q== + dependencies: + commander "^2.8.1" + eslint "^2.7.0" + front-matter "2.1.2" + fs-extra "^3.0.1" + glob "^7.0.0" + globule "^1.0.0" + gonzales-pe-sl "^4.2.3" + js-yaml "^3.5.4" + known-css-properties "^0.3.0" + lodash.capitalize "^4.1.0" + lodash.kebabcase "^4.0.0" + merge "^1.2.0" + path-is-absolute "^1.0.0" + util "^0.10.3" + +sass-unused@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/sass-unused/-/sass-unused-0.3.0.tgz#69924e4996d6c96840fb3a99e0a0290516811a9f" + integrity sha512-fGNcUpDeSFwnN+BTQ251iM77Py8awPXc96vSE3TpvMcgbC90IrohonRb4oxWX/KzHpezkmUddS8/t04R+yIB8w== + dependencies: + glob "^7.0.5" + gonzales-pe "^4.2.3" + +sax@>=0.6.0, sax@^1.2.4, sax@~1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +saxes@^3.1.3: + version "3.1.11" + resolved "https://registry.yarnpkg.com/saxes/-/saxes-3.1.11.tgz#d59d1fd332ec92ad98a2e0b2ee644702384b1c5b" + integrity sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g== + dependencies: + xmlchars "^2.1.1" + +schema-utils@^0.4.0: + version "0.4.7" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187" + integrity sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ== + dependencies: + ajv "^6.1.0" + ajv-keywords "^3.1.0" + +schema-utils@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" + integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== + dependencies: + ajv "^6.1.0" + ajv-errors "^1.0.0" + ajv-keywords "^3.1.0" + +schema-utils@^2.6.5: + version "2.6.5" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.6.5.tgz#c758f0a7e624263073d396e29cd40aa101152d8a" + integrity sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ== + dependencies: + ajv "^6.12.0" + ajv-keywords "^3.4.1" + +scss-tokenizer@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1" + integrity sha1-jrBtualyMzOCTT9VMGQRSYR85dE= + dependencies: + js-base64 "^2.1.8" + source-map "^0.4.2" + +seek-bzip@^1.0.3, seek-bzip@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/seek-bzip/-/seek-bzip-1.0.5.tgz#cfe917cb3d274bcffac792758af53173eb1fabdc" + integrity sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w= + dependencies: + commander "~2.8.1" + +semver-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-1.0.0.tgz#92a4969065f9c70c694753d55248fc68f8f652c9" + integrity sha1-kqSWkGX5xwxpR1PVUkj8aPj2Usk= + +semver-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-2.0.0.tgz#a93c2c5844539a770233379107b38c7b4ac9d338" + integrity sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw== + +semver-truncate@^1.0.0, semver-truncate@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/semver-truncate/-/semver-truncate-1.1.2.tgz#57f41de69707a62709a7e0104ba2117109ea47e8" + integrity sha1-V/Qd5pcHpicJp+AQS6IRcQnqR+g= + dependencies: + semver "^5.3.0" + +"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@^4.0.3, semver@^4.1.0: + version "4.3.6" + resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" + integrity sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto= + +semver@^6.0.0, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@~5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + integrity sha1-myzl094C0XxgEq0yaqa00M9U+U8= + +send@0.16.2: + version "0.16.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" + integrity sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.6.2" + mime "1.4.1" + ms "2.0.0" + on-finished "~2.3.0" + range-parser "~1.2.0" + statuses "~1.4.0" + +send@0.17.1: + version "0.17.1" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" + integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.7.2" + mime "1.6.0" + ms "2.1.1" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + +sequencify@~0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/sequencify/-/sequencify-0.0.7.tgz#90cff19d02e07027fd767f5ead3e7b95d1e7380c" + integrity sha1-kM/xnQLgcCf9dn9erT57ldHnOAw= + +serialize-error@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-3.0.0.tgz#80100282b09be33c611536f50033481cb9cc87cf" + integrity sha512-+y3nkkG/go1Vdw+2f/+XUXM1DXX1XcxTl99FfiD/OEPUNw4uo0i6FKABfTAN5ZcgGtjTRZcEbxcE/jtXbEY19A== + +serialize-javascript@^1.7.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.9.1.tgz#cfc200aef77b600c47da9bb8149c943e798c2fdb" + integrity sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A== + +serve-index@1.9.1, serve-index@^1.1.4: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.13.2: + version "1.13.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" + integrity sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.2" + send "0.16.2" + +serve-static@1.14.1, serve-static@^1.3.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" + integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.1" + +server-destroy@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/server-destroy/-/server-destroy-1.0.1.tgz#f13bf928e42b9c3e79383e61cc3998b5d14e6cdd" + integrity sha1-8Tv5KOQrnD55OD5hzDmYtdFObN0= + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +set-immediate-shim@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" + integrity sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E= + +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setimmediate@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +shelljs@^0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.6.1.tgz#ec6211bed1920442088fe0f70b2837232ed2c8a8" + integrity sha1-7GIRvtGSBEIIj+D3Cyg3Iy7SyKg= + +sigmund@^1.0.1, sigmund@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" + integrity sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA= + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= + +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= + dependencies: + is-arrayish "^0.3.1" + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= + +slice-ansi@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" + integrity sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU= + +slice-ansi@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" + integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== + dependencies: + ansi-styles "^3.2.0" + astral-regex "^1.0.0" + is-fullwidth-code-point "^2.0.0" + +sloc@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/sloc/-/sloc-0.2.1.tgz#42ad891e76838c1a22bbd8483468e9d74c7f531e" + integrity sha512-8XJnwCFR4DatLz1s0nGFe6IJPJ+5pjRFhoBuBKq8SLgFI40eD7ak6jOXpzeG0tmIpyOc1zCs9bjKAxMFm1451A== + dependencies: + async "~2.1.4" + cli-table "^0.3.1" + commander "~2.9.0" + readdirp "^2.1.0" + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +socket.io-adapter@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz#2a805e8a14d6372124dd9159ad4502f8cb07f06b" + integrity sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs= + +socket.io-client@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.1.1.tgz#dcb38103436ab4578ddb026638ae2f21b623671f" + integrity sha512-jxnFyhAuFxYfjqIgduQlhzqTcOEQSn+OHKVfAxWaNWa7ecP7xSNk2Dx/3UEsDcY7NcFafxvNvKPmmO7HTwTxGQ== + dependencies: + backo2 "1.0.2" + base64-arraybuffer "0.1.5" + component-bind "1.0.0" + component-emitter "1.2.1" + debug "~3.1.0" + engine.io-client "~3.2.0" + has-binary2 "~1.0.2" + has-cors "1.1.0" + indexof "0.0.1" + object-component "0.0.3" + parseqs "0.0.5" + parseuri "0.0.5" + socket.io-parser "~3.2.0" + to-array "0.1.4" + +socket.io-client@^2.0.4: + version "2.3.0" + resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.3.0.tgz#14d5ba2e00b9bcd145ae443ab96b3f86cbcc1bb4" + integrity sha512-cEQQf24gET3rfhxZ2jJ5xzAOo/xhZwK+mOqtGRg5IowZsMgwvHwnf/mCRapAAkadhM26y+iydgwsXGObBB5ZdA== + dependencies: + backo2 "1.0.2" + base64-arraybuffer "0.1.5" + component-bind "1.0.0" + component-emitter "1.2.1" + debug "~4.1.0" + engine.io-client "~3.4.0" + has-binary2 "~1.0.2" + has-cors "1.1.0" + indexof "0.0.1" + object-component "0.0.3" + parseqs "0.0.5" + parseuri "0.0.5" + socket.io-parser "~3.3.0" + to-array "0.1.4" + +socket.io-parser@~3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.2.0.tgz#e7c6228b6aa1f814e6148aea325b51aa9499e077" + integrity sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA== + dependencies: + component-emitter "1.2.1" + debug "~3.1.0" + isarray "2.0.1" + +socket.io-parser@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.3.0.tgz#2b52a96a509fdf31440ba40fed6094c7d4f1262f" + integrity sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng== + dependencies: + component-emitter "1.2.1" + debug "~3.1.0" + isarray "2.0.1" + +socket.io@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-2.1.1.tgz#a069c5feabee3e6b214a75b40ce0652e1cfb9980" + integrity sha512-rORqq9c+7W0DAK3cleWNSyfv/qKXV99hV4tZe+gGLfBECw3XEhBy7x85F3wypA9688LKjtwO9pX9L33/xQI8yA== + dependencies: + debug "~3.1.0" + engine.io "~3.2.0" + has-binary2 "~1.0.2" + socket.io-adapter "~1.1.0" + socket.io-client "2.1.1" + socket.io-parser "~3.2.0" + +sort-keys-length@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sort-keys-length/-/sort-keys-length-1.0.1.tgz#9cb6f4f4e9e48155a6aa0671edd336ff1479a188" + integrity sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg= + dependencies: + sort-keys "^1.0.0" + +sort-keys@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" + integrity sha1-RBttTTRnmPG05J6JIK37oOVD+a0= + dependencies: + is-plain-obj "^1.0.0" + +sort-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" + integrity sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg= + dependencies: + is-plain-obj "^1.0.0" + +source-list-map@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== + +source-map-resolve@^0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" + integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== + dependencies: + atob "^2.1.1" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.4.tgz#54456efa89caa9270af7cd624cc2f123e51fbae8" + integrity sha512-PETSPG6BjY1AHs2t64vS2aqAgu6dMIMXJULWFBGbh2Gr8nVLbCFDo6i/RMMvviIQ2h1Z8+5gQhVKSn2je9nmdg== + dependencies: + source-map "^0.6.0" + +source-map-support@0.5.8: + version "0.5.8" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.8.tgz#04f5581713a8a65612d0175fbf3a01f80a162613" + integrity sha512-WqAEWPdb78u25RfKzOF0swBpY0dKrNdjc4GvLwm7ScX/o9bj8Eh/YL8mcMhBHYDGl87UkkSXDOFnW4G7GhWhGg== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-support@~0.5.12: + version "0.5.13" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" + integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + +source-map@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" + integrity sha1-66T12pwNyZneaAMti092FzZSA2s= + dependencies: + amdefine ">=0.0.4" + +source-map@^0.5.0, source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.0: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@~0.1.38: + version "0.1.43" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" + integrity sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y= + dependencies: + amdefine ">=0.0.4" + +source-map@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" + integrity sha1-2rc/vPwrqBm03gO9b26qSBZLP50= + dependencies: + amdefine ">=0.0.4" + +sparkles@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.1.tgz#008db65edce6c50eec0c5e228e1945061dd0437c" + integrity sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw== + +spdx-correct@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" + integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" + integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== + +spdx-expression-parse@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" + integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.5" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654" + integrity sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q== + +speed-measure-webpack-plugin@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/speed-measure-webpack-plugin/-/speed-measure-webpack-plugin-1.3.1.tgz#69840a5cdc08b4638697dac7db037f595d7f36a0" + integrity sha512-qVIkJvbtS9j/UeZumbdfz0vg+QfG/zxonAjzefZrqzkr7xOncLVXkeGbTpzd1gjCBM4PmVNkWlkeTVhgskAGSQ== + dependencies: + chalk "^2.0.1" + +split-on-first@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" + integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw== + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +squeak@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/squeak/-/squeak-1.3.0.tgz#33045037b64388b567674b84322a6521073916c3" + integrity sha1-MwRQN7ZDiLVnZ0uEMiplIQc5FsM= + dependencies: + chalk "^1.0.0" + console-stream "^0.1.1" + lpad-align "^1.0.1" + +ssh2@~0.3.3: + version "0.3.6" + resolved "https://registry.yarnpkg.com/ssh2/-/ssh2-0.3.6.tgz#49034434aee3821ee5fc22b952081e7801ff92ed" + integrity sha1-SQNENK7jgh7l/CK5UggeeAH/ku0= + dependencies: + asn1 "0.2.1" + readable-stream "1.0.27-1" + streamsearch "0.1.2" + +sshpk@^1.7.0: + version "1.16.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" + integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +ssri@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" + integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== + dependencies: + figgy-pudding "^3.5.1" + +stable@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" + integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== + +stat-mode@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/stat-mode/-/stat-mode-0.2.2.tgz#e6c80b623123d7d80cf132ce538f346289072502" + integrity sha1-5sgLYjEj19gM8TLOU480YokHJQI= + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +statuses@~1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" + integrity sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4= + +statuses@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" + integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew== + +stdout-stream@^1.4.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/stdout-stream/-/stdout-stream-1.4.1.tgz#5ac174cdd5cd726104aa0c0b2bd83815d8d535de" + integrity sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA== + dependencies: + readable-stream "^2.0.1" + +stealthy-require@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= + +stream-browserify@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" + integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + +stream-combiner2@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stream-combiner2/-/stream-combiner2-1.1.1.tgz#fb4d8a1420ea362764e21ad4780397bebcb41cbe" + integrity sha1-+02KFCDqNidk4hrUeAOXvry0HL4= + dependencies: + duplexer2 "~0.1.0" + readable-stream "^2.0.2" + +stream-consume@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/stream-consume/-/stream-consume-0.1.1.tgz#d3bdb598c2bd0ae82b8cac7ac50b1107a7996c48" + integrity sha512-tNa3hzgkjEP7XbCkbRXe1jpg+ievoa0O4SCFlMOYEscGSS4JJsckGL8swUyAa/ApGU3Ae4t6Honor4HhL+tRyg== + +stream-each@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" + integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + +stream-http@^2.7.2: + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.3.6" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + +stream-shift@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" + integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI= + +stream-throttle@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/stream-throttle/-/stream-throttle-0.1.3.tgz#add57c8d7cc73a81630d31cd55d3961cfafba9c3" + integrity sha1-rdV8jXzHOoFjDTHNVdOWHPr7qcM= + dependencies: + commander "^2.2.0" + limiter "^1.0.5" + +streamsearch@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" + integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo= + +strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= + +strict-uri-encode@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" + integrity sha1-ucczDHBChi9rFC3CdLvMWGbONUY= + +strictdom@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strictdom/-/strictdom-1.0.1.tgz#189de91649f73d44d59b8432efa68ef9d2659460" + integrity sha1-GJ3pFkn3PUTVm4Qy76aO+dJllGA= + +string-replace-webpack-plugin@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/string-replace-webpack-plugin/-/string-replace-webpack-plugin-0.1.3.tgz#73c657e759d66cfe80ae1e0cf091aa256d0e715c" + integrity sha1-c8ZX51nWbP6Arh4M8JGqJW0OcVw= + dependencies: + async "~0.2.10" + loader-utils "~0.2.3" + optionalDependencies: + css-loader "^0.9.1" + file-loader "^0.8.1" + style-loader "^0.8.3" + +string-template@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/string-template/-/string-template-1.0.0.tgz#9e9f2233dc00f218718ec379a28a5673ecca8b96" + integrity sha1-np8iM9wA8hhxjsN5oopWc+zKi5Y= + +string-width@^1.0.1, string-width@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string-width@^3.0.0, string-width@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string.prototype.trim@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.0.tgz#75a729b10cfc1be439543dae442129459ce61e3d" + integrity sha512-9EIjYD/WdlvLpn987+ctkLf0FfvBefOCuiEr2henD8X+7jfwPnyvTdmW8OJhj5p+M0/96mBdynLWkxUr+rHlpg== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.13.0" + function-bind "^1.1.1" + +string.prototype.trimleft@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz#6cc47f0d7eb8d62b0f3701611715a3954591d634" + integrity sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw== + dependencies: + define-properties "^1.1.3" + function-bind "^1.1.1" + +string.prototype.trimright@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz#669d164be9df9b6f7559fa8e89945b168a5a6c58" + integrity sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg== + dependencies: + define-properties "^1.1.3" + function-bind "^1.1.1" + +string_decoder@^1.0.0, string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.3.0.tgz#25f48ea22ca79187f3174a4db8759347bb126220" + integrity sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA= + dependencies: + ansi-regex "^0.2.1" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +strip-bom-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz#e7144398577d51a6bed0fa1994fa05f43fd988ee" + integrity sha1-5xRDmFd9Uaa+0PoZlPoF9D/ZiO4= + dependencies: + first-chunk-stream "^1.0.0" + strip-bom "^2.0.0" + +strip-bom@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-1.0.0.tgz#85b8862f3844b5a6d5ec8467a93598173a36f794" + integrity sha1-hbiGLzhEtabV7IRnqTWYFzo295Q= + dependencies: + first-chunk-stream "^1.0.0" + is-utf8 "^0.2.0" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= + dependencies: + is-utf8 "^0.2.0" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + +strip-dirs@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/strip-dirs/-/strip-dirs-1.1.1.tgz#960bbd1287844f3975a4558aa103a8255e2456a0" + integrity sha1-lgu9EoeETzl1pFWKoQOoJV4kVqA= + dependencies: + chalk "^1.0.0" + get-stdin "^4.0.1" + is-absolute "^0.1.5" + is-natural-number "^2.0.0" + minimist "^1.1.0" + sum-up "^1.0.1" + +strip-dirs@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/strip-dirs/-/strip-dirs-2.1.0.tgz#4987736264fc344cf20f6c34aca9d13d1d4ed6c5" + integrity sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g== + dependencies: + is-natural-number "^4.0.1" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + +strip-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + integrity sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI= + dependencies: + get-stdin "^4.0.1" + +strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + +strip-json-comments@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7" + integrity sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw== + +strip-json-comments@~1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91" + integrity sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E= + +strip-outer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-outer/-/strip-outer-1.0.1.tgz#b2fd2abf6604b9d1e6013057195df836b8a9d631" + integrity sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg== + dependencies: + escape-string-regexp "^1.0.2" + +style-loader@^0.8.3: + version "0.8.3" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.8.3.tgz#f4f92eb7db63768748f15065cd6700f5a1c85357" + integrity sha1-9Pkut9tjdodI8VBlzWcA9aHIU1c= + dependencies: + loader-utils "^0.2.5" + +stylehacks@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-4.0.3.tgz#6718fcaf4d1e07d8a1318690881e8d96726a71d5" + integrity sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g== + dependencies: + browserslist "^4.0.0" + postcss "^7.0.0" + postcss-selector-parser "^3.0.0" + +sum-up@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sum-up/-/sum-up-1.0.3.tgz#1c661f667057f63bcb7875aa1438bc162525156e" + integrity sha1-HGYfZnBX9jvLeHWqFDi8FiUlFW4= + dependencies: + chalk "^1.0.0" + +sumchecker@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/sumchecker/-/sumchecker-3.0.0.tgz#da5457b4605184575c76540e5e99cc777cb8ce4c" + integrity sha512-yreseuC/z4iaodVoq07XULEOO9p4jnQazO7mbrnDSvWAU/y2cbyIKs+gWJptfcGu9R+1l27K8Rkj0bfvqnBpgQ== + dependencies: + debug "^4.1.0" + +supports-color@6.1.0, supports-color@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" + integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== + dependencies: + has-flag "^3.0.0" + +supports-color@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-0.2.0.tgz#d92de2694eb3f67323973d7ae3d8b55b4c22190a" + integrity sha1-2S3iaU6z9nMjlz1649i1W0wiGQo= + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + +supports-color@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= + dependencies: + has-flag "^1.0.0" + +supports-color@^5.3.0, supports-color@^5.4.0, supports-color@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +svgo@^1.0.0, svgo@^1.0.5: + version "1.3.0" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.0.tgz#bae51ba95ded9a33a36b7c46ce9c359ae9154313" + integrity sha512-MLfUA6O+qauLDbym+mMZgtXCGRfIxyQoeH6IKVcFslyODEe/ElJNwr0FohQ3xG4C6HK6bk3KYPPXwHVJk3V5NQ== + dependencies: + chalk "^2.4.1" + coa "^2.0.2" + css-select "^2.0.0" + css-select-base-adapter "^0.1.1" + css-tree "1.0.0-alpha.33" + csso "^3.5.1" + js-yaml "^3.13.1" + mkdirp "~0.5.1" + object.values "^1.1.0" + sax "~1.2.4" + stable "^0.1.8" + unquote "~1.1.1" + util.promisify "~1.0.0" + +symbol-observable@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4" + integrity sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ= + +symbol-tree@^3.2.2: + version "3.2.4" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" + integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== + +table@^3.7.8: + version "3.8.3" + resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f" + integrity sha1-K7xULw/amGGnVdOUf+/Ys/UThV8= + dependencies: + ajv "^4.7.0" + ajv-keywords "^1.0.0" + chalk "^1.1.1" + lodash "^4.0.0" + slice-ansi "0.0.4" + string-width "^2.0.0" + +table@^5.2.3: + version "5.4.6" + resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" + integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== + dependencies: + ajv "^6.10.2" + lodash "^4.17.14" + slice-ansi "^2.1.0" + string-width "^3.0.0" + +tapable@^1.0.0, tapable@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" + integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== + +tar-stream@^1.1.1, tar-stream@^1.5.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" + integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A== + dependencies: + bl "^1.0.0" + buffer-alloc "^1.2.0" + end-of-stream "^1.0.0" + fs-constants "^1.0.0" + readable-stream "^2.3.0" + to-buffer "^1.1.1" + xtend "^4.0.0" + +tar-stream@~0.4.0: + version "0.4.7" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-0.4.7.tgz#1f1d2ce9ebc7b42765243ca0e8f1b7bfda0aadcd" + integrity sha1-Hx0s6evHtCdlJDyg6PG3v9oKrc0= + dependencies: + bl "^0.9.0" + end-of-stream "^1.0.0" + readable-stream "^1.0.27-1" + xtend "^4.0.0" + +tar@^2.0.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.2.tgz#0ca8848562c7299b8b446ff6a4d60cdbb23edc40" + integrity sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA== + dependencies: + block-stream "*" + fstream "^1.0.12" + inherits "2" + +tar@^4: + version "4.4.11" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.11.tgz#7ac09801445a3cf74445ed27499136b5240ffb73" + integrity sha512-iI4zh3ktLJKaDNZKZc+fUONiQrSn9HkCFzamtb7k8FFmVilHVob7QsLX/VySAW8lAviMzMbFw4QtFb4errwgYA== + dependencies: + chownr "^1.1.1" + fs-minipass "^1.2.5" + minipass "^2.6.4" + minizlib "^1.2.1" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.3" + +temp-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" + integrity sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0= + +tempfile@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/tempfile/-/tempfile-1.1.1.tgz#5bcc4eaecc4ab2c707d8bc11d99ccc9a2cb287f2" + integrity sha1-W8xOrsxKsscH2LwR2ZzMmiyyh/I= + dependencies: + os-tmpdir "^1.0.0" + uuid "^2.0.1" + +tempfile@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/tempfile/-/tempfile-2.0.0.tgz#6b0446856a9b1114d1856ffcbe509cccb0977265" + integrity sha1-awRGhWqbERTRhW/8vlCczLCXcmU= + dependencies: + temp-dir "^1.0.0" + uuid "^3.0.1" + +ternary-stream@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ternary-stream/-/ternary-stream-2.1.1.tgz#4ad64b98668d796a085af2c493885a435a8a8bfc" + integrity sha512-j6ei9hxSoyGlqTmoMjOm+QNvUKDOIY6bNl4Uh1lhBvl6yjPW2iLqxDUYyfDPZknQ4KdRziFl+ec99iT4l7g0cw== + dependencies: + duplexify "^3.5.0" + fork-stream "^0.0.4" + merge-stream "^1.0.0" + through2 "^2.0.1" + +terser-webpack-plugin@^1.1.0, terser-webpack-plugin@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.1.tgz#61b18e40eaee5be97e771cdbb10ed1280888c2b4" + integrity sha512-ZXmmfiwtCLfz8WKZyYUuuHf3dMYEjg8NrjHMb0JqHVHVOSkzp3cW2/XG1fP3tRhqEqSzMwzzRQGtAPbs4Cncxg== + dependencies: + cacache "^12.0.2" + find-cache-dir "^2.1.0" + is-wsl "^1.1.0" + schema-utils "^1.0.0" + serialize-javascript "^1.7.0" + source-map "^0.6.1" + terser "^4.1.2" + webpack-sources "^1.4.0" + worker-farm "^1.7.0" + +terser@^4.0.0, terser@^4.1.2: + version "4.3.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.3.1.tgz#09820bcb3398299c4b48d9a86aefc65127d0ed65" + integrity sha512-pnzH6dnFEsR2aa2SJaKb1uSCl3QmIsJ8dEkj0Fky+2AwMMcC9doMqLOQIH6wVTEKaVfKVvLSk5qxPBEZT9mywg== + dependencies: + commander "^2.20.0" + source-map "~0.6.1" + source-map-support "~0.5.12" + +text-table@^0.2.0, text-table@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +tfunk@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/tfunk/-/tfunk-3.1.0.tgz#38e4414fc64977d87afdaa72facb6d29f82f7b5b" + integrity sha1-OORBT8ZJd9h6/apy+sttKfgve1s= + dependencies: + chalk "^1.1.1" + object-path "^0.9.0" + +through2-concurrent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/through2-concurrent/-/through2-concurrent-2.0.0.tgz#c9dd2c146504ec9962dbc86a5168b63d662669fa" + integrity sha512-R5/jLkfMvdmDD+seLwN7vB+mhbqzWop5fAjx5IX8/yQq7VhBhzDmhXgaHAOnhnWkCpRMM7gToYHycB0CS/pd+A== + dependencies: + through2 "^2.0.0" + +through2-filter@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/through2-filter/-/through2-filter-2.0.0.tgz#60bc55a0dacb76085db1f9dae99ab43f83d622ec" + integrity sha1-YLxVoNrLdghdsfna6Zq0P4PWIuw= + dependencies: + through2 "~2.0.0" + xtend "~4.0.0" + +through2-filter@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/through2-filter/-/through2-filter-3.0.0.tgz#700e786df2367c2c88cd8aa5be4cf9c1e7831254" + integrity sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA== + dependencies: + through2 "~2.0.0" + xtend "~4.0.0" + +through2@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.1.tgz#384e75314d49f32de12eebb8136b8eb6b5d59da9" + integrity sha1-OE51MU1J8y3hLuu4E2uOtrXVnak= + dependencies: + readable-stream "~2.0.0" + xtend "~4.0.0" + +through2@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" + integrity sha1-AARWmzfHx0ujnEPzzteNGtlBQL4= + dependencies: + readable-stream "^2.1.5" + xtend "~4.0.1" + +through2@3.0.1, through2@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/through2/-/through2-3.0.1.tgz#39276e713c3302edf9e388dd9c812dd3b825bd5a" + integrity sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww== + dependencies: + readable-stream "2 || 3" + +through2@^0.4.1, through2@~0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.4.2.tgz#dbf5866031151ec8352bb6c4db64a2292a840b9b" + integrity sha1-2/WGYDEVHsg1K7bE22SiKSqEC5s= + dependencies: + readable-stream "~1.0.17" + xtend "~2.1.1" + +through2@^0.5.0, through2@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.5.1.tgz#dfdd012eb9c700e2323fd334f38ac622ab372da7" + integrity sha1-390BLrnHAOIyP9M084rGIqs3Lac= + dependencies: + readable-stream "~1.0.17" + xtend "~3.0.0" + +through2@^0.6.0, through2@^0.6.1, through2@^0.6.5, through2@~0.6.1: + version "0.6.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48" + integrity sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg= + dependencies: + readable-stream ">=1.0.33-1 <1.1.0-0" + xtend ">=4.0.0 <4.1.0-0" + +through2@^2.0.0, through2@^2.0.1, through2@^2.0.2, through2@^2.0.3, through2@~2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +through2@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.3.0.tgz#2d1d28c8d1daf8d9c5cb78f0a69343c6b8642d97" + integrity sha1-LR0oyNHa+NnFy3jwppNDxrhkLZc= + dependencies: + readable-stream "~1.0.17" + xtend "~2.1.1" + +through@^2.3.6, through@^2.3.8, through@~2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +thunks@^4.9.0: + version "4.9.5" + resolved "https://registry.yarnpkg.com/thunks/-/thunks-4.9.5.tgz#fc764983de4de7230a2f300cfe2dc77092bc38f4" + integrity sha512-L0s0QzX1x0fcsP52TQs42t3CGX/z6lw0Ktz0ciex47OUhog5K3AsfH3mQ4JTLBYbnsNBhaIUcVMrY8sR+0Lo6w== + +tildify@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/tildify/-/tildify-1.2.0.tgz#dcec03f55dca9b7aa3e5b04f21817eb56e63588a" + integrity sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo= + dependencies: + os-homedir "^1.0.0" + +time-stamp@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" + integrity sha1-dkpaEa9QVhkhsTPztE5hhofg9cM= + +timed-out@^3.0.0: + version "3.1.3" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-3.1.3.tgz#95860bfcc5c76c277f8f8326fd0f5b2e20eba217" + integrity sha1-lYYL/MXHbCd/j4Mm/Q9bLiDrohc= + +timed-out@^4.0.0, timed-out@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= + +timers-browserify@^2.0.4: + version "2.0.11" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.11.tgz#800b1f3eee272e5bc53ee465a04d0e804c31211f" + integrity sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ== + dependencies: + setimmediate "^1.0.4" + +timm@^1.6.1: + version "1.6.2" + resolved "https://registry.yarnpkg.com/timm/-/timm-1.6.2.tgz#dfd8c6719f7ba1fcfc6295a32670a1c6d166c0bd" + integrity sha512-IH3DYDL1wMUwmIlVmMrmesw5lZD6N+ZOAFWEyLrtpoL9Bcrs9u7M/vyOnHzDD2SMs4irLkVjqxZbHrXStS/Nmw== + +timsort@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" + integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= + +tiny-lr@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/tiny-lr/-/tiny-lr-0.1.4.tgz#6e41d7e67dfd0878e5e0b37e37a06d67e309ff4d" + integrity sha1-bkHX5n39CHjl4LN+N6BtZ+MJ/00= + dependencies: + body-parser "~1.8.0" + debug "~0.8.1" + faye-websocket "~0.7.2" + parseurl "~1.3.0" + qs "~2.2.3" + +tinycolor2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.1.tgz#f4fad333447bc0b07d4dc8e9209d8f39a8ac77e8" + integrity sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g= + +tmp-promise@^1.0.5: + version "1.1.0" + resolved "https://registry.yarnpkg.com/tmp-promise/-/tmp-promise-1.1.0.tgz#bb924d239029157b9bc1d506a6aa341f8b13e64c" + integrity sha512-8+Ah9aB1IRXCnIOxXZ0uFozV1nMU5xiu7hhFVUSxZ3bYu+psD4TzagCzVbexUCgNNGJnsmNDQlS4nG3mTyoNkw== + dependencies: + bluebird "^3.5.0" + tmp "0.1.0" + +tmp@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.1.0.tgz#ee434a4e22543082e294ba6201dcc6eafefa2877" + integrity sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw== + dependencies: + rimraf "^2.6.3" + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +to-absolute-glob@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/to-absolute-glob/-/to-absolute-glob-0.1.1.tgz#1cdfa472a9ef50c239ee66999b662ca0eb39937f" + integrity sha1-HN+kcqnvUMI57maZm2YsoOs5k38= + dependencies: + extend-shallow "^2.0.1" + +to-array@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890" + integrity sha1-F+bBH3PdTz10zaek/zI46a2b+JA= + +to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= + +to-buffer@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" + integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg== + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + dependencies: + kind-of "^3.0.2" + +to-readable-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" + integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== + +tough-cookie@^2.3.3, tough-cookie@^2.4.3: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +tough-cookie@~2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" + integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ== + dependencies: + psl "^1.1.24" + punycode "^1.4.1" + +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= + dependencies: + punycode "^2.1.0" + +trim-newlines@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + integrity sha1-WIeWa7WCpFA6QetST301ARgVphM= + +trim-repeated@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-repeated/-/trim-repeated-1.0.0.tgz#e3646a2ea4e891312bf7eace6cfb05380bc01c21" + integrity sha1-42RqLqTokTEr9+rObPsFOAvAHCE= + dependencies: + escape-string-regexp "^1.0.2" + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= + +trim@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" + integrity sha1-WFhUf2spB1fulczMZm+1AITEYN0= + +"true-case-path@^1.0.2": + version "1.0.3" + resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-1.0.3.tgz#f813b5a8c86b40da59606722b144e3225799f47d" + integrity sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew== + dependencies: + glob "^7.1.2" + +truncate-utf8-bytes@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz#405923909592d56f78a5818434b0b78489ca5f2b" + integrity sha1-QFkjkJWS1W94pYGENLC3hInKXys= + dependencies: + utf8-byte-length "^1.0.1" + +tryer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" + integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA== + +tslib@1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.0.tgz#e37a86fda8cbbaf23a057f473c9f4dc64e5fc2e8" + integrity sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ== + +tslib@1.9.3: + version "1.9.3" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" + integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== + +tslib@^1.9.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" + integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== + +tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= + +tunnel-agent@^0.4.0: + version "0.4.3" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" + integrity sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us= + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +type-fest@^0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.5.2.tgz#d6ef42a0356c6cd45f49485c3b6281fc148e48a2" + integrity sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw== + +type-is@~1.5.1: + version "1.5.7" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.5.7.tgz#b9368a593cc6ef7d0645e78b2f4c64cbecd05e90" + integrity sha1-uTaKWTzG730GReeLL0xky+zQXpA= + dependencies: + media-typer "0.3.0" + mime-types "~2.0.9" + +type-is@~1.6.17, type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + +ua-parser-js@0.7.17: + version "0.7.17" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac" + integrity sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g== + +uglify-js@3.4.x: + version "3.4.10" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f" + integrity sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw== + dependencies: + commander "~2.19.0" + source-map "~0.6.1" + +uglify-template-string-loader@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/uglify-template-string-loader/-/uglify-template-string-loader-1.1.1.tgz#d091d15f66b65f1cae2f4222583009302c86339f" + integrity sha512-EHJx8m0aIHlwX5xlJd2xPYIFvLrPkVK5X8zpVxSNTmu7KoT2eSg1TNlwZS+JS65+dwJXC4rC5mc+F4UVe2rckw== + +ultron@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" + integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og== + +unbzip2-stream@^1.0.9: + version "1.3.3" + resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.3.3.tgz#d156d205e670d8d8c393e1c02ebd506422873f6a" + integrity sha512-fUlAF7U9Ah1Q6EieQ4x4zLNejrRvDWUYmxXUpN3uziFYCHapjWFaCAnreY9bGgxzaMCFAPPpYNng57CypwJVhg== + dependencies: + buffer "^5.2.1" + through "^2.3.8" + +unc-path-regex@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" + integrity sha1-5z3T17DXxe2G+6xrCufYxqadUPo= + +unicode-canonical-property-names-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" + integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== + +unicode-match-property-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" + integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg== + dependencies: + unicode-canonical-property-names-ecmascript "^1.0.4" + unicode-property-aliases-ecmascript "^1.0.4" + +unicode-match-property-value-ecmascript@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz#5b4b426e08d13a80365e0d657ac7a6c1ec46a277" + integrity sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g== + +unicode-property-aliases-ecmascript@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz#a9cc6cc7ce63a0a3023fc99e341b94431d405a57" + integrity sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw== + +union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + +uniq@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" + integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= + +uniqs@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" + integrity sha1-/+3ks2slKQaW5uFl1KWe25mOawI= + +unique-filename@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" + integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== + dependencies: + imurmurhash "^0.1.4" + +unique-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-1.0.0.tgz#d59a4a75427447d9aa6c91e70263f8d26a4b104b" + integrity sha1-1ZpKdUJ0R9mqbJHnAmP40mpLEEs= + +unique-stream@^2.0.2: + version "2.3.1" + resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-2.3.1.tgz#c65d110e9a4adf9a6c5948b28053d9a8d04cbeac" + integrity sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A== + dependencies: + json-stable-stringify-without-jsonify "^1.0.1" + through2-filter "^3.0.0" + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +unquote@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" + integrity sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ= + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +unused-files-webpack-plugin@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/unused-files-webpack-plugin/-/unused-files-webpack-plugin-3.4.0.tgz#adc67a3b5549d028818d3119cbf2b5c88aea8670" + integrity sha512-cmukKOBdIqaM1pqThY0+jp+mYgCVyzrD8uRbKEucQwIGZcLIRn+gSRiQ7uLjcDd3Zba9NUxVGyYa7lWM4UCGeg== + dependencies: + babel-runtime "^7.0.0-beta.3" + glob-all "^3.1.0" + semver "^5.5.0" + util.promisify "^1.0.0" + warning "^3.0.0" + +unzip-response@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-1.0.2.tgz#b984f0877fc0a89c2c773cc1ef7b5b232b5b06fe" + integrity sha1-uYTwh3/AqJwsdzzB73tbIytbBv4= + +upath@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== + +upper-case@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" + integrity sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg= + +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +url-parse-lax@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= + dependencies: + prepend-http "^1.0.1" + +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= + dependencies: + prepend-http "^2.0.0" + +url-regex@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/url-regex/-/url-regex-3.2.0.tgz#dbad1e0c9e29e105dd0b1f09f6862f7fdb482724" + integrity sha1-260eDJ4p4QXdCx8J9oYvf9tIJyQ= + dependencies: + ip-regex "^1.0.1" + +url-to-options@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" + integrity sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k= + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +user-home@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" + integrity sha1-K1viOjK2Onyd640PKNSFcko98ZA= + +user-home@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" + integrity sha1-nHC/2Babwdy/SGBODwS4tJzenp8= + dependencies: + os-homedir "^1.0.0" + +utf8-byte-length@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz#f45f150c4c66eee968186505ab93fcbb8ad6bf61" + integrity sha1-9F8VDExm7uloGGUFq5P8u4rWv2E= + +utif@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/utif/-/utif-2.0.1.tgz#9e1582d9bbd20011a6588548ed3266298e711759" + integrity sha512-Z/S1fNKCicQTf375lIP9G8Sa1H/phcysstNrrSdZKj1f9g58J4NMgb5IgiEZN9/nLMPDwF0W7hdOe9Qq2IYoLg== + dependencies: + pako "^1.0.5" + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +util.promisify@^1.0.0, util.promisify@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" + integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== + dependencies: + define-properties "^1.1.2" + object.getownpropertydescriptors "^2.0.3" + +util@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= + dependencies: + inherits "2.0.1" + +util@^0.10.3: + version "0.10.4" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901" + integrity sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A== + dependencies: + inherits "2.0.3" + +util@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" + integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== + dependencies: + inherits "2.0.3" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +uuid@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" + integrity sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho= + +uuid@^3.0.1, uuid@^3.3.2: + version "3.3.3" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.3.tgz#4568f0216e78760ee1dbf3a4d2cf53e224112866" + integrity sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ== + +v8-compile-cache@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe" + integrity sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w== + +v8flags@^2.0.2: + version "2.1.1" + resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.1.1.tgz#aab1a1fa30d45f88dd321148875ac02c0b55e5b4" + integrity sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ= + dependencies: + user-home "^1.1.1" + +vali-date@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/vali-date/-/vali-date-1.0.0.tgz#1b904a59609fb328ef078138420934f6b86709a6" + integrity sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY= + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +validator@10.4.0: + version "10.4.0" + resolved "https://registry.yarnpkg.com/validator/-/validator-10.4.0.tgz#ee99a44afb3bb5ed350a159f056ca72a204cfc3c" + integrity sha512-Q/wBy3LB1uOyssgNlXSRmaf22NxjvDNZM2MtIQ4jaEOAB61xsh1TQxsq1CgzUMBV1lDrVMogIh8GjG1DYW0zLg== + +validator@9.2.0: + version "9.2.0" + resolved "https://registry.yarnpkg.com/validator/-/validator-9.2.0.tgz#ad216eed5f37cac31a6fe00ceab1f6b88bded03e" + integrity sha512-6Ij4Eo0KM4LkR0d0IegOwluG5453uqT5QyF5SV5Ezvm8/zmkKI/L4eoraafZGlZPC9guLkwKzgypcw8VGWWnGA== + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +vendors@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.3.tgz#a6467781abd366217c050f8202e7e50cc9eef8c0" + integrity sha512-fOi47nsJP5Wqefa43kyWSg80qF+Q3XA6MUkgi7Hp1HQaKDQW4cQrK2D0P7mmbFtsV1N89am55Yru/nyEwRubcw== + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +vinyl-assign@^1.0.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/vinyl-assign/-/vinyl-assign-1.2.1.tgz#4d198891b5515911d771a8cd9c5480a46a074a45" + integrity sha1-TRmIkbVRWRHXcajNnFSApGoHSkU= + dependencies: + object-assign "^4.0.1" + readable-stream "^2.0.0" + +vinyl-buffer@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/vinyl-buffer/-/vinyl-buffer-0.0.0.tgz#d197a824badcb11cccf9643ac91be24d43eda8db" + integrity sha1-0ZeoJLrcsRzM+WQ6yRviTUPtqNs= + dependencies: + bl "^0.7.0" + through2 "^0.4.1" + +vinyl-fs@^0.3.0: + version "0.3.14" + resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-0.3.14.tgz#9a6851ce1cac1c1cea5fe86c0931d620c2cfa9e6" + integrity sha1-mmhRzhysHBzqX+hsCTHWIMLPqeY= + dependencies: + defaults "^1.0.0" + glob-stream "^3.1.5" + glob-watcher "^0.0.6" + graceful-fs "^3.0.0" + mkdirp "^0.5.0" + strip-bom "^1.0.0" + through2 "^0.6.1" + vinyl "^0.4.0" + +vinyl-fs@^2.2.0: + version "2.4.4" + resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-2.4.4.tgz#be6ff3270cb55dfd7d3063640de81f25d7532239" + integrity sha1-vm/zJwy1Xf19MGNkDegfJddTIjk= + dependencies: + duplexify "^3.2.0" + glob-stream "^5.3.2" + graceful-fs "^4.0.0" + gulp-sourcemaps "1.6.0" + is-valid-glob "^0.3.0" + lazystream "^1.0.0" + lodash.isequal "^4.0.0" + merge-stream "^1.0.0" + mkdirp "^0.5.0" + object-assign "^4.0.0" + readable-stream "^2.0.4" + strip-bom "^2.0.0" + strip-bom-stream "^1.0.0" + through2 "^2.0.0" + through2-filter "^2.0.0" + vali-date "^1.0.0" + vinyl "^1.0.0" + +vinyl-source-stream@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/vinyl-source-stream/-/vinyl-source-stream-0.1.1.tgz#a53a4f21a07a234695e04c2703f9f1b5b9084595" + integrity sha1-pTpPIaB6I0aV4EwnA/nxtbkIRZU= + dependencies: + through2 "~0.3.0" + vinyl "~0.2.2" + +vinyl-sourcemaps-apply@^0.2.0, vinyl-sourcemaps-apply@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz#ab6549d61d172c2b1b87be5c508d239c8ef87705" + integrity sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU= + dependencies: + source-map "^0.5.1" + +vinyl@^0.2.1, vinyl@~0.2.2: + version "0.2.3" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.2.3.tgz#bca938209582ec5a49ad538a00fa1f125e513252" + integrity sha1-vKk4IJWC7FpJrVOKAPofEl5RMlI= + dependencies: + clone-stats "~0.0.1" + +vinyl@^0.4.0, vinyl@^0.4.3: + version "0.4.6" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.4.6.tgz#2f356c87a550a255461f36bbeb2a5ba8bf784847" + integrity sha1-LzVsh6VQolVGHza76ypbqL94SEc= + dependencies: + clone "^0.2.0" + clone-stats "^0.0.1" + +vinyl@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.5.3.tgz#b0455b38fc5e0cf30d4325132e461970c2091cde" + integrity sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4= + dependencies: + clone "^1.0.0" + clone-stats "^0.0.1" + replace-ext "0.0.1" + +vinyl@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-1.2.0.tgz#5c88036cf565e5df05558bfc911f8656df218884" + integrity sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ= + dependencies: + clone "^1.0.0" + clone-stats "^0.0.1" + replace-ext "0.0.1" + +vinyl@^2.1.0, vinyl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.0.tgz#d85b07da96e458d25b2ffe19fece9f2caa13ed86" + integrity sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg== + dependencies: + clone "^2.1.1" + clone-buffer "^1.0.0" + clone-stats "^1.0.0" + cloneable-readable "^1.0.0" + remove-trailing-separator "^1.0.1" + replace-ext "^1.0.0" + +vm-browserify@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.0.tgz#bd76d6a23323e2ca8ffa12028dc04559c75f9019" + integrity sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw== + +w3c-hr-time@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045" + integrity sha1-gqwr/2PZUOqeMYmlimViX+3xkEU= + dependencies: + browser-process-hrtime "^0.1.2" + +ware@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/ware/-/ware-1.3.0.tgz#d1b14f39d2e2cb4ab8c4098f756fe4b164e473d4" + integrity sha1-0bFPOdLiy0q4xAmPdW/ksWTkc9Q= + dependencies: + wrap-fn "^0.1.0" + +warning@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/warning/-/warning-3.0.0.tgz#32e5377cb572de4ab04753bdf8821c01ed605b7c" + integrity sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w= + dependencies: + loose-envify "^1.0.0" + +watch@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/watch/-/watch-0.11.0.tgz#e8dba091b7456799a3af57978b986e77e1320406" + integrity sha1-6NugkbdFZ5mjr1eXi5hud+EyBAY= + +watchpack@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" + integrity sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA== + dependencies: + chokidar "^2.0.2" + graceful-fs "^4.1.2" + neo-async "^2.5.0" + +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== + +webpack-bundle-analyzer@^3.0.3: + version "3.5.1" + resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.5.1.tgz#84aabb1547178d842ebb4ccc7324084b6c3b0ea9" + integrity sha512-CDdaT3TTu4F9X3tcDq6PNJOiNGgREOM0WdN2vVAoUUn+M6NLB5kJ543HImCWbrDwOpbpGARSwU8r+u0Pl367kA== + dependencies: + acorn "^6.0.7" + acorn-walk "^6.1.1" + bfj "^6.1.1" + chalk "^2.4.1" + commander "^2.18.0" + ejs "^2.6.1" + express "^4.16.3" + filesize "^3.6.1" + gzip-size "^5.0.0" + lodash "^4.17.15" + mkdirp "^0.5.1" + opener "^1.5.1" + ws "^6.0.0" + +webpack-cli@^3.1.0: + version "3.3.9" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.3.9.tgz#79c27e71f94b7fe324d594ab64a8e396b9daa91a" + integrity sha512-xwnSxWl8nZtBl/AFJCOn9pG7s5CYUYdZxmmukv+fAHLcBIHM36dImfpQg3WfShZXeArkWlf6QRw24Klcsv8a5A== + dependencies: + chalk "2.4.2" + cross-spawn "6.0.5" + enhanced-resolve "4.1.0" + findup-sync "3.0.0" + global-modules "2.0.0" + import-local "2.0.0" + interpret "1.2.0" + loader-utils "1.2.3" + supports-color "6.1.0" + v8-compile-cache "2.0.3" + yargs "13.2.4" + +webpack-deep-scope-plugin@^1.6.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/webpack-deep-scope-plugin/-/webpack-deep-scope-plugin-1.6.2.tgz#131eac79739021e42ebc07066ea8869107f37b85" + integrity sha512-S5ZM1i7oTIVPIS1z/Fu41tqFzaXpy8vZnwEDC9I7NLj5XD8GGrDZbDXtG5FCGkHPGxtAzF4O21DKZZ76vpBGzw== + dependencies: + deep-scope-analyser "^1.7.0" + +webpack-plugin-replace@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/webpack-plugin-replace/-/webpack-plugin-replace-1.2.0.tgz#3f20db96237400433231e35ea76d9be3f7128916" + integrity sha512-1HA3etHpJW55qonJqv84o5w5GY7iqF8fqSHpTWdNwarj1llkkt4jT4QSvYs1hoaU8Lu5akDnq/spHHO5mXwo1w== + +webpack-sources@^1.4.0, webpack-sources@^1.4.1: + version "1.4.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" + integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack-stream@^5.1.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/webpack-stream/-/webpack-stream-5.2.1.tgz#35c992161399fe8cad9c10d4a5c258f022629b39" + integrity sha512-WvyVU0K1/VB1NZ7JfsaemVdG0PXAQUqbjUNW4A58th4pULvKMQxG+y33HXTL02JvD56ko2Cub+E2NyPwrLBT/A== + dependencies: + fancy-log "^1.3.3" + lodash.clone "^4.3.2" + lodash.some "^4.2.2" + memory-fs "^0.4.1" + plugin-error "^1.0.1" + supports-color "^5.5.0" + through "^2.3.8" + vinyl "^2.1.0" + webpack "^4.26.1" + +webpack-strip-block@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/webpack-strip-block/-/webpack-strip-block-0.2.0.tgz#c60d4a703e0eeee8895e7f1abe9b5fe914681470" + integrity sha1-xg1KcD4O7uiJXn8avptf6RRoFHA= + dependencies: + loader-utils "^1.1.0" + +webpack@^4.26.1, webpack@^4.31.0: + version "4.40.2" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.40.2.tgz#d21433d250f900bf0facbabe8f50d585b2dc30a7" + integrity sha512-5nIvteTDCUws2DVvP9Qe+JPla7kWPPIDFZv55To7IycHWZ+Z5qBdaBYPyuXWdhggTufZkQwfIK+5rKQTVovm2A== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-module-context" "1.8.5" + "@webassemblyjs/wasm-edit" "1.8.5" + "@webassemblyjs/wasm-parser" "1.8.5" + acorn "^6.2.1" + ajv "^6.10.2" + ajv-keywords "^3.4.1" + chrome-trace-event "^1.0.2" + enhanced-resolve "^4.1.0" + eslint-scope "^4.0.3" + json-parse-better-errors "^1.0.2" + loader-runner "^2.4.0" + loader-utils "^1.2.3" + memory-fs "^0.4.1" + micromatch "^3.1.10" + mkdirp "^0.5.1" + neo-async "^2.6.1" + node-libs-browser "^2.2.1" + schema-utils "^1.0.0" + tapable "^1.1.3" + terser-webpack-plugin "^1.4.1" + watchpack "^1.6.0" + webpack-sources "^1.4.1" + +websocket-driver@>=0.3.6: + version "0.7.3" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.3.tgz#a2d4e0d4f4f116f1e6297eba58b05d430100e9f9" + integrity sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg== + dependencies: + http-parser-js ">=0.4.0 <0.4.11" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29" + integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg== + +whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" + integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== + dependencies: + iconv-lite "0.4.24" + +whatwg-fetch@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb" + integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q== + +whatwg-mimetype@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" + integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== + +whatwg-url@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.0.0.tgz#fde926fa54a599f3adf82dff25a9f7be02dc6edd" + integrity sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +which-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + integrity sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8= + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which@1, which@^1.1.1, which@^1.2.14, which@^1.2.9, which@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + +window-size@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" + integrity sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU= + +wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= + +worker-farm@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" + integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== + dependencies: + errno "~0.1.7" + +worker-loader@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/worker-loader/-/worker-loader-2.0.0.tgz#45fda3ef76aca815771a89107399ee4119b430ac" + integrity sha512-tnvNp4K3KQOpfRnD20m8xltE3eWh89Ye+5oj7wXEEHKac1P4oZ6p9oTj8/8ExqoSBnk9nu5Pr4nKfQ1hn2APJw== + dependencies: + loader-utils "^1.0.0" + schema-utils "^0.4.0" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrap-ansi@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== + dependencies: + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" + +wrap-fn@^0.1.0: + version "0.1.5" + resolved "https://registry.yarnpkg.com/wrap-fn/-/wrap-fn-0.1.5.tgz#f21b6e41016ff4a7e31720dbc63a09016bdf9845" + integrity sha1-8htuQQFv9KfjFyDbxjoJAWvfmEU= + dependencies: + co "3.1.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +write@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" + integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== + dependencies: + mkdirp "^0.5.1" + +write@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" + integrity sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c= + dependencies: + mkdirp "^0.5.1" + +ws@^6.0.0, ws@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" + integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== + dependencies: + async-limiter "~1.0.0" + +ws@~3.3.1: + version "3.3.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" + integrity sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA== + dependencies: + async-limiter "~1.0.0" + safe-buffer "~5.1.0" + ultron "~1.1.0" + +ws@~6.1.0: + version "6.1.4" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.4.tgz#5b5c8800afab925e94ccb29d153c8d02c1776ef9" + integrity sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA== + dependencies: + async-limiter "~1.0.0" + +xhr@^2.0.1: + version "2.5.0" + resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.5.0.tgz#bed8d1676d5ca36108667692b74b316c496e49dd" + integrity sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ== + dependencies: + global "~4.3.0" + is-function "^1.0.1" + parse-headers "^2.0.0" + xtend "^4.0.0" + +xml-name-validator@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" + integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== + +xml-parse-from-string@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz#a9029e929d3dbcded169f3c6e28238d95a5d5a28" + integrity sha1-qQKekp09vN7RafPG4oI42VpdWig= + +xml2js@^0.4.5: + version "0.4.22" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.22.tgz#4fa2d846ec803237de86f30aa9b5f70b6600de02" + integrity sha512-MWTbxAQqclRSTnehWWe5nMKzI3VmJ8ltiJEco8akcC6j3miOhjjfzKum5sId+CWhfxdOs/1xauYr8/ZDBtQiRw== + dependencies: + sax ">=0.6.0" + util.promisify "~1.0.0" + xmlbuilder "~11.0.0" + +xmlbuilder@^9.0.7: + version "9.0.7" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" + integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= + +xmlbuilder@~11.0.0: + version "11.0.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" + integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== + +xmlchars@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" + integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== + +xmldom@0.1.x: + version "0.1.27" + resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9" + integrity sha1-1QH5ezvbQDr4757MIFcxh6rawOk= + +xmlhttprequest-ssl@~1.5.4: + version "1.5.5" + resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e" + integrity sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4= + +"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +xtend@~2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.1.2.tgz#6efecc2a4dad8e6962c4901b337ce7ba87b5d28b" + integrity sha1-bv7MKk2tjmlixJAbM3znuoe10os= + dependencies: + object-keys "~0.4.0" + +xtend@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-3.0.0.tgz#5cce7407baf642cba7becda568111c493f59665a" + integrity sha1-XM50B7r2Qsunvs2laBEcST9ZZlo= + +y18n@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= + +y18n@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= + +yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" + integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== + +yargs-parser@^13.0.0, yargs-parser@^13.1.0: + version "13.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" + integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-parser@^4.1.0, yargs-parser@^4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-4.2.1.tgz#29cceac0dc4f03c6c87b4a9f217dd18c9f74871c" + integrity sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw= + dependencies: + camelcase "^3.0.0" + +yargs-parser@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a" + integrity sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo= + dependencies: + camelcase "^3.0.0" + +yargs@13.2.4: + version "13.2.4" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.4.tgz#0b562b794016eb9651b98bd37acf364aa5d6dc83" + integrity sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg== + dependencies: + cliui "^5.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + os-locale "^3.1.0" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.1.0" + +yargs@6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-6.4.0.tgz#816e1a866d5598ccf34e5596ddce22d92da490d4" + integrity sha1-gW4ahm1VmMzzTlWW3c4i2S2kkNQ= + dependencies: + camelcase "^3.0.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.2" + which-module "^1.0.0" + window-size "^0.2.0" + y18n "^3.2.1" + yargs-parser "^4.1.0" + +yargs@6.6.0: + version "6.6.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-6.6.0.tgz#782ec21ef403345f830a808ca3d513af56065208" + integrity sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg= + dependencies: + camelcase "^3.0.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.2" + which-module "^1.0.0" + y18n "^3.2.1" + yargs-parser "^4.2.0" + +yargs@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" + integrity sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg= + dependencies: + camelcase "^3.0.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.2" + which-module "^1.0.0" + y18n "^3.2.1" + yargs-parser "^5.0.0" + +yargs@~1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-1.2.6.tgz#9c7b4a82fd5d595b2bf17ab6dcc43135432fe34b" + integrity sha1-nHtKgv1dWVsr8Xq23MQxNUMv40s= + dependencies: + minimist "^0.1.0" + +yauzl@^2.2.1, yauzl@^2.4.2: + version "2.10.0" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" + integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk= + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.1.0" + +yeast@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" + integrity sha1-AI4G2AlDIMNy28L47XagymyKxBk= + +zip-stream@~0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-0.4.1.tgz#4ea795a8ce19e9fab49a31d1d0877214159f03a3" + integrity sha1-TqeVqM4Z6fq0mjHR0IdyFBWfA6M= + dependencies: + compress-commons "~0.1.0" + lodash "~2.4.1" + readable-stream "~1.0.26" diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 00000000..6879acfe --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "target": "es6", + "checkJs": true, + + } +} \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 00000000..b978337a --- /dev/null +++ b/package.json @@ -0,0 +1,84 @@ +{ + "name": "shapez.io", + "version": "1.0.0", + "main": "index.js", + "repository": "https://github.com/tobspr/shapez.io", + "author": "Tobias Springer ", + "license": "MIT", + "private": true, + "scripts": { + "dev": "./gulp/gulp main.serveDev", + "prettier-all": "prettier --write src/**/*.* && prettier --write gulp/**/*.*" + }, + "dependencies": { + "@babel/core": "^7.5.4", + "@babel/plugin-transform-block-scoping": "^7.4.4", + "@babel/plugin-transform-classes": "^7.5.5", + "@babel/preset-env": "^7.5.4", + "@types/cordova": "^0.0.34", + "@types/filesystem": "^0.0.29", + "ajv": "^6.10.2", + "babel-loader": "^8.0.4", + "browser-sync": "^2.24.6", + "circular-dependency-plugin": "^5.0.2", + "circular-json": "^0.5.9", + "clipboard-copy": "^3.1.0", + "colors": "^1.3.3", + "core-js": "3", + "cssnano-preset-advanced": "^4.0.7", + "email-validator": "^2.0.4", + "eslint": "^5.9.0", + "fastdom": "^1.0.8", + "flatted": "^2.0.1", + "howler": "^2.1.2", + "html-loader": "^0.5.5", + "ignore-loader": "^0.1.2", + "lz-string": "^1.4.4", + "markdown-loader": "^4.0.0", + "obfuscator-loader": "^1.1.2", + "phonegap-plugin-mobile-accessibility": "^1.0.5", + "promise-polyfill": "^8.1.0", + "query-string": "^6.8.1", + "rusha": "^0.8.13", + "serialize-error": "^3.0.0", + "sloc": "^0.2.1", + "strictdom": "^1.0.1", + "string-replace-webpack-plugin": "^0.1.3", + "terser-webpack-plugin": "^1.1.0", + "uglify-template-string-loader": "^1.1.0", + "unused-files-webpack-plugin": "^3.4.0", + "webpack": "^4.31.0", + "webpack-bundle-analyzer": "^3.0.3", + "webpack-cli": "^3.1.0", + "webpack-deep-scope-plugin": "^1.6.0", + "webpack-plugin-replace": "^1.1.1", + "webpack-strip-block": "^0.2.0", + "whatwg-fetch": "^3.0.0", + "worker-loader": "^2.0.0" + }, + "devDependencies": { + "autoprefixer": "^9.4.3", + "babel-plugin-closure-elimination": "^1.3.0", + "babel-plugin-console-source": "^2.0.2", + "babel-plugin-danger-remove-unused-import": "^1.1.2", + "css-mqpacker": "^7.0.0", + "cssnano": "^4.1.10", + "faster.js": "^1.1.0", + "glob": "^7.1.3", + "imagemin-mozjpeg": "^8.0.0", + "imagemin-pngquant": "^8.0.0", + "jimp": "^0.6.1", + "js-yaml": "^3.13.1", + "onesky-fetch": "^0.0.7", + "postcss-assets": "^5.0.0", + "postcss-preset-env": "^6.5.0", + "postcss-round-subpixels": "^1.2.0", + "postcss-unprefix": "^2.1.3", + "prettier": "^2.0.4", + "sass-unused": "^0.3.0", + "speed-measure-webpack-plugin": "^1.3.1", + "strip-json-comments": "^3.0.1", + "trim": "^0.0.1", + "webpack-stream": "^5.1.0" + } +} diff --git a/res/fonts/LouisGeorgeCafe.woff2 b/res/fonts/LouisGeorgeCafe.woff2 new file mode 100644 index 00000000..7e4ebe03 Binary files /dev/null and b/res/fonts/LouisGeorgeCafe.woff2 differ diff --git a/res/logo.png b/res/logo.png new file mode 100644 index 00000000..4edea174 Binary files /dev/null and b/res/logo.png differ diff --git a/res/ui/building_tutorials/belt.png b/res/ui/building_tutorials/belt.png new file mode 100644 index 00000000..d36cc813 Binary files /dev/null and b/res/ui/building_tutorials/belt.png differ diff --git a/res/ui/building_tutorials/cutter.png b/res/ui/building_tutorials/cutter.png new file mode 100644 index 00000000..6b9daca8 Binary files /dev/null and b/res/ui/building_tutorials/cutter.png differ diff --git a/res/ui/building_tutorials/miner.png b/res/ui/building_tutorials/miner.png new file mode 100644 index 00000000..2bc95bc3 Binary files /dev/null and b/res/ui/building_tutorials/miner.png differ diff --git a/res/ui/building_tutorials/mixer.png b/res/ui/building_tutorials/mixer.png new file mode 100644 index 00000000..a04b09f4 Binary files /dev/null and b/res/ui/building_tutorials/mixer.png differ diff --git a/res/ui/building_tutorials/painter.png b/res/ui/building_tutorials/painter.png new file mode 100644 index 00000000..16fb4850 Binary files /dev/null and b/res/ui/building_tutorials/painter.png differ diff --git a/res/ui/building_tutorials/rotater.png b/res/ui/building_tutorials/rotater.png new file mode 100644 index 00000000..ed1ef55e Binary files /dev/null and b/res/ui/building_tutorials/rotater.png differ diff --git a/res/ui/building_tutorials/splitter.png b/res/ui/building_tutorials/splitter.png new file mode 100644 index 00000000..ece30fb5 Binary files /dev/null and b/res/ui/building_tutorials/splitter.png differ diff --git a/res/ui/building_tutorials/stacker.png b/res/ui/building_tutorials/stacker.png new file mode 100644 index 00000000..55232a2c Binary files /dev/null and b/res/ui/building_tutorials/stacker.png differ diff --git a/res/ui/building_tutorials/trash.png b/res/ui/building_tutorials/trash.png new file mode 100644 index 00000000..b33d1980 Binary files /dev/null and b/res/ui/building_tutorials/trash.png differ diff --git a/res/ui/building_tutorials/underground_belt.png b/res/ui/building_tutorials/underground_belt.png new file mode 100644 index 00000000..693882e4 Binary files /dev/null and b/res/ui/building_tutorials/underground_belt.png differ diff --git a/res/ui/dialog_bg_pattern.png b/res/ui/dialog_bg_pattern.png new file mode 100644 index 00000000..658e0607 Binary files /dev/null and b/res/ui/dialog_bg_pattern.png differ diff --git a/res/ui/icons/close.png b/res/ui/icons/close.png new file mode 100644 index 00000000..a03a2976 Binary files /dev/null and b/res/ui/icons/close.png differ diff --git a/res/ui/icons/mouse_left.png b/res/ui/icons/mouse_left.png new file mode 100644 index 00000000..89556415 Binary files /dev/null and b/res/ui/icons/mouse_left.png differ diff --git a/res/ui/icons/mouse_right.png b/res/ui/icons/mouse_right.png new file mode 100644 index 00000000..3bd1c8c8 Binary files /dev/null and b/res/ui/icons/mouse_right.png differ diff --git a/res/ui/icons/shop.png b/res/ui/icons/shop.png new file mode 100644 index 00000000..6e5d9c82 Binary files /dev/null and b/res/ui/icons/shop.png differ diff --git a/res/ui/icons/statistics.png b/res/ui/icons/statistics.png new file mode 100644 index 00000000..f9c548ea Binary files /dev/null and b/res/ui/icons/statistics.png differ diff --git a/res/ui/loading.svg b/res/ui/loading.svg new file mode 100644 index 00000000..e8f0d271 --- /dev/null +++ b/res/ui/loading.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/res/ui/locked_building.png b/res/ui/locked_building.png new file mode 100644 index 00000000..df72e773 Binary files /dev/null and b/res/ui/locked_building.png differ diff --git a/res/ui/menu_bg.noinline.jpg b/res/ui/menu_bg.noinline.jpg new file mode 100644 index 00000000..a9e5c689 Binary files /dev/null and b/res/ui/menu_bg.noinline.jpg differ diff --git a/res/ui/sad_ghost.png b/res/ui/sad_ghost.png new file mode 100644 index 00000000..19cd0cac Binary files /dev/null and b/res/ui/sad_ghost.png differ diff --git a/res/ui/upgrades/belt.png b/res/ui/upgrades/belt.png new file mode 100644 index 00000000..a1a9b716 Binary files /dev/null and b/res/ui/upgrades/belt.png differ diff --git a/res/ui/upgrades/miner.png b/res/ui/upgrades/miner.png new file mode 100644 index 00000000..535edc06 Binary files /dev/null and b/res/ui/upgrades/miner.png differ diff --git a/res/ui/upgrades/painting.png b/res/ui/upgrades/painting.png new file mode 100644 index 00000000..03749952 Binary files /dev/null and b/res/ui/upgrades/painting.png differ diff --git a/res/ui/upgrades/processors.png b/res/ui/upgrades/processors.png new file mode 100644 index 00000000..5d785baa Binary files /dev/null and b/res/ui/upgrades/processors.png differ diff --git a/res_raw/atlas.tps b/res_raw/atlas.tps new file mode 100644 index 00000000..211d1659 --- /dev/null +++ b/res_raw/atlas.tps @@ -0,0 +1,417 @@ + + + + fileFormatVersion + 4 + texturePackerVersion + 5.3.0 + autoSDSettings + + + scale + 1 + extension + _100 + spriteFilter + + acceptFractionalValues + + maxTextureSize + + width + -1 + height + -1 + + + + scale + 0.75 + extension + _75 + spriteFilter + + acceptFractionalValues + + maxTextureSize + + width + -1 + height + -1 + + + + scale + 0.5 + extension + _50 + spriteFilter + + acceptFractionalValues + + maxTextureSize + + width + -1 + height + -1 + + + + scale + 0.25 + extension + _25 + spriteFilter + + acceptFractionalValues + + maxTextureSize + + width + -1 + height + -1 + + + + scale + 0.1 + extension + _10 + spriteFilter + + acceptFractionalValues + + maxTextureSize + + width + -1 + height + -1 + + + + allowRotation + + shapeDebug + + dpi + 72 + dataFormat + json + textureFileName + + flipPVR + + pvrCompressionQuality + PVR_QUALITY_NORMAL + atfCompressData + + mipMapMinSize + 32768 + etc1CompressionQuality + ETC1_QUALITY_LOW_PERCEPTUAL + etc2CompressionQuality + ETC2_QUALITY_LOW_PERCEPTUAL + dxtCompressionMode + DXT_PERCEPTUAL + jxrColorFormat + JXR_YUV444 + jxrTrimFlexBits + 0 + jxrCompressionLevel + 0 + ditherType + NearestNeighbour + backgroundColor + 0 + libGdx + + filtering + + x + Linear + y + Linear + + + shapePadding + 0 + jpgQuality + 80 + pngOptimizationLevel + 0 + webpQualityLevel + 101 + textureSubPath + + atfFormats + + textureFormat + png + borderPadding + 1 + maxTextureSize + + width + 4096 + height + 4096 + + fixedTextureSize + + width + -1 + height + -1 + + algorithmSettings + + algorithm + MaxRects + freeSizeMode + Best + sizeConstraints + AnySize + forceSquared + + maxRects + + heuristic + Best + + basic + + sortBy + Best + order + Ascending + + polygon + + alignToGrid + 1 + + + dataFileNames + + data + + name + ../res_built/atlas/atlas{n}{v}.json + + + multiPack + + forceIdenticalLayout + + outputFormat + RGBA8888 + alphaHandling + ClearTransparentPixels + contentProtection + + key + + + autoAliasEnabled + + trimSpriteNames + + prependSmartFolderName + + autodetectAnimations + + globalSpriteSettings + + scale + 1 + scaleMode + Smooth + extrude + 2 + trimThreshold + 2 + trimMargin + 1 + trimMode + Trim + tracerTolerance + 200 + heuristicMask + + defaultPivotPoint + 0.5,0.5 + writePivotPoints + + + individualSpriteSettings + + sprites/belt/forward_0.png + sprites/belt/forward_1.png + sprites/belt/forward_2.png + sprites/buildings/miner.png + sprites/buildings/rotater.png + sprites/buildings/trash.png + + pivotPoint + 0.5,0.5 + spriteScale + 1 + scale9Enabled + + scale9Borders + 32,32,64,64 + scale9Paddings + 32,32,64,64 + scale9FromFile + + + sprites/belt/forward_3.png + sprites/belt/forward_4.png + sprites/belt/forward_5.png + sprites/belt/left_0.png + sprites/belt/left_1.png + sprites/belt/left_2.png + sprites/belt/left_3.png + sprites/belt/left_4.png + sprites/belt/left_5.png + sprites/belt/right_0.png + sprites/belt/right_1.png + sprites/belt/right_2.png + sprites/belt/right_3.png + sprites/belt/right_4.png + sprites/belt/right_5.png + sprites/buildings/belt_left.png + sprites/buildings/belt_right.png + sprites/buildings/belt_top.png + + pivotPoint + 0.5,0.5 + spriteScale + 1 + scale9Enabled + + scale9Borders + 32,32,63,63 + scale9Paddings + 32,32,63,63 + scale9FromFile + + + sprites/buildings/cutter.png + sprites/buildings/mixer.png + sprites/buildings/painter.png + sprites/buildings/splitter.png + sprites/buildings/stacker.png + + pivotPoint + 0.5,0.5 + spriteScale + 1 + scale9Enabled + + scale9Borders + 64,32,128,64 + scale9Paddings + 64,32,128,64 + scale9FromFile + + + sprites/buildings/hub.png + + pivotPoint + 0.5,0.5 + spriteScale + 1 + scale9Enabled + + scale9Borders + 192,192,384,384 + scale9Paddings + 192,192,384,384 + scale9FromFile + + + sprites/buildings/underground_belt_entry.png + sprites/buildings/underground_belt_exit.png + + pivotPoint + 0.5,0.5 + spriteScale + 1 + scale9Enabled + + scale9Borders + 48,48,96,96 + scale9Paddings + 48,48,96,96 + scale9FromFile + + + sprites/debug/acceptor_slot.png + sprites/debug/ejector_slot.png + sprites/map_overview/belt_forward.png + sprites/map_overview/belt_left.png + sprites/map_overview/belt_right.png + + pivotPoint + 0.5,0.5 + spriteScale + 1 + scale9Enabled + + scale9Borders + 8,8,16,16 + scale9Paddings + 8,8,16,16 + scale9FromFile + + + sprites/misc/slot_bad_arrow.png + sprites/misc/slot_good_arrow.png + + pivotPoint + 0.5,0.5 + spriteScale + 1 + scale9Enabled + + scale9Borders + 24,24,48,48 + scale9Paddings + 24,24,48,48 + scale9FromFile + + + + fileList + + sprites + + ignoreFileList + + replaceList + + ignoredWarnings + + commonDivisorX + 1 + commonDivisorY + 1 + packNormalMaps + + autodetectNormalMaps + + normalMapFilter + + normalMapSuffix + + normalMapSheetFileName + + exporterProperties + + + diff --git a/res_raw/sounds/music/main_menu.wav b/res_raw/sounds/music/main_menu.wav new file mode 100644 index 00000000..488479a8 --- /dev/null +++ b/res_raw/sounds/music/main_menu.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:811a57acb5a16af8079744e048c3809799211f1d7c6e79eaa5247ed852b5d4eb +size 23990546 diff --git a/res_raw/sounds/music/theme_full.wav b/res_raw/sounds/music/theme_full.wav new file mode 100644 index 00000000..68a7a043 --- /dev/null +++ b/res_raw/sounds/music/theme_full.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6b4cbf863591aba38d1729fb1cbaa792323f045722279f0deca2492acaaf19b5 +size 123844300 diff --git a/res_raw/sounds/ui/dialog_error.wav b/res_raw/sounds/ui/dialog_error.wav new file mode 100644 index 00000000..ef7eddfd --- /dev/null +++ b/res_raw/sounds/ui/dialog_error.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2b164ef5d1942b30480c202583266707cd52443cdd6fccc5304d941a4aa93c97 +size 17420 diff --git a/res_raw/sounds/ui/dialog_ok.wav b/res_raw/sounds/ui/dialog_ok.wav new file mode 100644 index 00000000..889d3426 --- /dev/null +++ b/res_raw/sounds/ui/dialog_ok.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:59eea912cf8d9c6668ec89b3fbfc3cb8c49221aad43449c62d9e30486550cb2f +size 169258 diff --git a/res_raw/sounds/ui/ui_click.wav b/res_raw/sounds/ui/ui_click.wav new file mode 100644 index 00000000..3118481d --- /dev/null +++ b/res_raw/sounds/ui/ui_click.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7f4c56728534d030fca2d75f297027a2774d6f765f5be84a27a3705569f878f2 +size 20158 diff --git a/res_raw/sounds/ui/ui_error.wav b/res_raw/sounds/ui/ui_error.wav new file mode 100644 index 00000000..283ea26c --- /dev/null +++ b/res_raw/sounds/ui/ui_error.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:88c66825955990b1b93197c2b943d010b3190b242991db7e4c10f6db8a688bb7 +size 59222 diff --git a/res_raw/sounds/ui/ui_swish_hide.wav b/res_raw/sounds/ui/ui_swish_hide.wav new file mode 100644 index 00000000..ad7bed1d --- /dev/null +++ b/res_raw/sounds/ui/ui_swish_hide.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:250247888bb15badf626dbcb6c76daddac5bb592075d4b6fcccc4930dc3a1465 +size 16924 diff --git a/res_raw/sounds/ui/ui_swish_show.wav b/res_raw/sounds/ui/ui_swish_show.wav new file mode 100644 index 00000000..63436899 --- /dev/null +++ b/res_raw/sounds/ui/ui_swish_show.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1c119251f4a7511f5d95c4b9eb208062ebb59eaafe535a8b352fcf7fbb5b409c +size 22178 diff --git a/res_raw/sprites/belt/forward_0.png b/res_raw/sprites/belt/forward_0.png new file mode 100644 index 00000000..def37d7d Binary files /dev/null and b/res_raw/sprites/belt/forward_0.png differ diff --git a/res_raw/sprites/belt/forward_1.png b/res_raw/sprites/belt/forward_1.png new file mode 100644 index 00000000..1ed11ef2 Binary files /dev/null and b/res_raw/sprites/belt/forward_1.png differ diff --git a/res_raw/sprites/belt/forward_2.png b/res_raw/sprites/belt/forward_2.png new file mode 100644 index 00000000..f8620703 Binary files /dev/null and b/res_raw/sprites/belt/forward_2.png differ diff --git a/res_raw/sprites/belt/forward_3.png b/res_raw/sprites/belt/forward_3.png new file mode 100644 index 00000000..0c0647fa Binary files /dev/null and b/res_raw/sprites/belt/forward_3.png differ diff --git a/res_raw/sprites/belt/forward_4.png b/res_raw/sprites/belt/forward_4.png new file mode 100644 index 00000000..5b6f59c0 Binary files /dev/null and b/res_raw/sprites/belt/forward_4.png differ diff --git a/res_raw/sprites/belt/forward_5.png b/res_raw/sprites/belt/forward_5.png new file mode 100644 index 00000000..850f14a8 Binary files /dev/null and b/res_raw/sprites/belt/forward_5.png differ diff --git a/res_raw/sprites/belt/left_0.png b/res_raw/sprites/belt/left_0.png new file mode 100644 index 00000000..822d922d Binary files /dev/null and b/res_raw/sprites/belt/left_0.png differ diff --git a/res_raw/sprites/belt/left_1.png b/res_raw/sprites/belt/left_1.png new file mode 100644 index 00000000..24f77c4a Binary files /dev/null and b/res_raw/sprites/belt/left_1.png differ diff --git a/res_raw/sprites/belt/left_2.png b/res_raw/sprites/belt/left_2.png new file mode 100644 index 00000000..e8473cc7 Binary files /dev/null and b/res_raw/sprites/belt/left_2.png differ diff --git a/res_raw/sprites/belt/left_3.png b/res_raw/sprites/belt/left_3.png new file mode 100644 index 00000000..d0984a31 Binary files /dev/null and b/res_raw/sprites/belt/left_3.png differ diff --git a/res_raw/sprites/belt/left_4.png b/res_raw/sprites/belt/left_4.png new file mode 100644 index 00000000..068c2c25 Binary files /dev/null and b/res_raw/sprites/belt/left_4.png differ diff --git a/res_raw/sprites/belt/left_5.png b/res_raw/sprites/belt/left_5.png new file mode 100644 index 00000000..52c53bcb Binary files /dev/null and b/res_raw/sprites/belt/left_5.png differ diff --git a/res_raw/sprites/belt/right_0.png b/res_raw/sprites/belt/right_0.png new file mode 100644 index 00000000..cdebc96f Binary files /dev/null and b/res_raw/sprites/belt/right_0.png differ diff --git a/res_raw/sprites/belt/right_1.png b/res_raw/sprites/belt/right_1.png new file mode 100644 index 00000000..4582b007 Binary files /dev/null and b/res_raw/sprites/belt/right_1.png differ diff --git a/res_raw/sprites/belt/right_2.png b/res_raw/sprites/belt/right_2.png new file mode 100644 index 00000000..79b30f46 Binary files /dev/null and b/res_raw/sprites/belt/right_2.png differ diff --git a/res_raw/sprites/belt/right_3.png b/res_raw/sprites/belt/right_3.png new file mode 100644 index 00000000..7e55e829 Binary files /dev/null and b/res_raw/sprites/belt/right_3.png differ diff --git a/res_raw/sprites/belt/right_4.png b/res_raw/sprites/belt/right_4.png new file mode 100644 index 00000000..9862d108 Binary files /dev/null and b/res_raw/sprites/belt/right_4.png differ diff --git a/res_raw/sprites/belt/right_5.png b/res_raw/sprites/belt/right_5.png new file mode 100644 index 00000000..f735403a Binary files /dev/null and b/res_raw/sprites/belt/right_5.png differ diff --git a/res_raw/sprites/buildings/belt_left.png b/res_raw/sprites/buildings/belt_left.png new file mode 100644 index 00000000..822d922d Binary files /dev/null and b/res_raw/sprites/buildings/belt_left.png differ diff --git a/res_raw/sprites/buildings/belt_right.png b/res_raw/sprites/buildings/belt_right.png new file mode 100644 index 00000000..cdebc96f Binary files /dev/null and b/res_raw/sprites/buildings/belt_right.png differ diff --git a/res_raw/sprites/buildings/belt_top.png b/res_raw/sprites/buildings/belt_top.png new file mode 100644 index 00000000..def37d7d Binary files /dev/null and b/res_raw/sprites/buildings/belt_top.png differ diff --git a/res_raw/sprites/buildings/cutter.png b/res_raw/sprites/buildings/cutter.png new file mode 100644 index 00000000..fcd2cd27 Binary files /dev/null and b/res_raw/sprites/buildings/cutter.png differ diff --git a/res_raw/sprites/buildings/hub.png b/res_raw/sprites/buildings/hub.png new file mode 100644 index 00000000..d7953ee2 Binary files /dev/null and b/res_raw/sprites/buildings/hub.png differ diff --git a/res_raw/sprites/buildings/miner.png b/res_raw/sprites/buildings/miner.png new file mode 100644 index 00000000..86f15008 Binary files /dev/null and b/res_raw/sprites/buildings/miner.png differ diff --git a/res_raw/sprites/buildings/mixer.png b/res_raw/sprites/buildings/mixer.png new file mode 100644 index 00000000..b68528b5 Binary files /dev/null and b/res_raw/sprites/buildings/mixer.png differ diff --git a/res_raw/sprites/buildings/painter.png b/res_raw/sprites/buildings/painter.png new file mode 100644 index 00000000..2eb883d3 Binary files /dev/null and b/res_raw/sprites/buildings/painter.png differ diff --git a/res_raw/sprites/buildings/rotater.png b/res_raw/sprites/buildings/rotater.png new file mode 100644 index 00000000..82d1a962 Binary files /dev/null and b/res_raw/sprites/buildings/rotater.png differ diff --git a/res_raw/sprites/buildings/splitter.png b/res_raw/sprites/buildings/splitter.png new file mode 100644 index 00000000..7cd9a2ef Binary files /dev/null and b/res_raw/sprites/buildings/splitter.png differ diff --git a/res_raw/sprites/buildings/stacker.png b/res_raw/sprites/buildings/stacker.png new file mode 100644 index 00000000..9524bbaf Binary files /dev/null and b/res_raw/sprites/buildings/stacker.png differ diff --git a/res_raw/sprites/buildings/trash.png b/res_raw/sprites/buildings/trash.png new file mode 100644 index 00000000..4452b7c3 Binary files /dev/null and b/res_raw/sprites/buildings/trash.png differ diff --git a/res_raw/sprites/buildings/underground_belt_entry.png b/res_raw/sprites/buildings/underground_belt_entry.png new file mode 100644 index 00000000..3b771f60 Binary files /dev/null and b/res_raw/sprites/buildings/underground_belt_entry.png differ diff --git a/res_raw/sprites/buildings/underground_belt_exit.png b/res_raw/sprites/buildings/underground_belt_exit.png new file mode 100644 index 00000000..c281ed0e Binary files /dev/null and b/res_raw/sprites/buildings/underground_belt_exit.png differ diff --git a/res_raw/sprites/debug/acceptor_slot.png b/res_raw/sprites/debug/acceptor_slot.png new file mode 100644 index 00000000..4ab91b5b Binary files /dev/null and b/res_raw/sprites/debug/acceptor_slot.png differ diff --git a/res_raw/sprites/debug/ejector_slot.png b/res_raw/sprites/debug/ejector_slot.png new file mode 100644 index 00000000..a1736a79 Binary files /dev/null and b/res_raw/sprites/debug/ejector_slot.png differ diff --git a/res_raw/sprites/map_overview/belt_forward.png b/res_raw/sprites/map_overview/belt_forward.png new file mode 100644 index 00000000..e7fb900c Binary files /dev/null and b/res_raw/sprites/map_overview/belt_forward.png differ diff --git a/res_raw/sprites/map_overview/belt_left.png b/res_raw/sprites/map_overview/belt_left.png new file mode 100644 index 00000000..9279c743 Binary files /dev/null and b/res_raw/sprites/map_overview/belt_left.png differ diff --git a/res_raw/sprites/map_overview/belt_right.png b/res_raw/sprites/map_overview/belt_right.png new file mode 100644 index 00000000..1f897cf5 Binary files /dev/null and b/res_raw/sprites/map_overview/belt_right.png differ diff --git a/res_raw/sprites/misc/slot_bad_arrow.png b/res_raw/sprites/misc/slot_bad_arrow.png new file mode 100644 index 00000000..27c938ac Binary files /dev/null and b/res_raw/sprites/misc/slot_bad_arrow.png differ diff --git a/res_raw/sprites/misc/slot_good_arrow.png b/res_raw/sprites/misc/slot_good_arrow.png new file mode 100644 index 00000000..760ab171 Binary files /dev/null and b/res_raw/sprites/misc/slot_good_arrow.png differ diff --git a/shapez.code-workspace b/shapez.code-workspace new file mode 100644 index 00000000..e0766264 --- /dev/null +++ b/shapez.code-workspace @@ -0,0 +1,18 @@ +{ + "folders": [ + { + "path": "." + } + ], + "settings": { + "files.exclude": { + "**/build": true, + "**/node_modules": true, + "**/typedefs_gen": true + }, + "vetur.format.defaultFormatter.js": "vscode-typescript", + "vetur.format.defaultFormatter.ts": "vscode-typescript", + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true + } +} \ No newline at end of file diff --git a/src/css/adinplay.scss b/src/css/adinplay.scss new file mode 100644 index 00000000..8b69bd84 --- /dev/null +++ b/src/css/adinplay.scss @@ -0,0 +1,107 @@ +#aip_gdpr { + &, + * { + text-shadow: none !important; + pointer-events: all; + color: #111 !important; + } + + #aip_gdpr_banner { + padding: 5px 0; + } + + #aip_gdpr_message { + padding: 0px 15px; + } +} + +#adinplayVideoContainer { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 20000; + background: rgba($mainBgColor, 0.9); + pointer-events: all; + cursor: default; + display: flex; + justify-content: center; + align-items: center; + + *, + & { + pointer-events: all; + } + + &:not(.visible) { + display: none; + } + + &.waitingForFinish { + .videoInner { + @include BorderRadius(4px); + overflow: hidden; + + &::after { + content: " "; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba($mainBgColor, 0.9) uiResource("loading.svg") center center / #{D(60px)} no-repeat; + @include InlineAnimation(0.2s ease-in-out) { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } + } + } + } + } + + @include InlineAnimation(1s ease-in-out) { + 0% { + background: rgba($mainBgColor, 0.1); + } + 100% { + background: rgba($mainBgColor, 0.9); + } + } + + .adInner { + @include BoxShadow3D(lighten($mainBgColor, 15)); + @include BorderRadius(4px); + @include S(padding, 15px); + // max-width: 960px; + display: block !important; + + .topbar { + display: grid; + grid-template-columns: 1fr auto; + @include S(margin-bottom, 15px); + @include S(grid-column-gap, 10px); + + .desc { + @include TextShadow3D(#fff); + @include PlainText; + } + + button.getOnSteam { + @include Text; + } + } + + .videoInner { + // width: 960px; + // height: 570px; + // min-width: 960px; + // min-height: 570px; + background: darken($mainBgColor, 1); + display: block !important; + } + } +} diff --git a/src/css/animations.scss b/src/css/animations.scss new file mode 100644 index 00000000..3e9b22f7 --- /dev/null +++ b/src/css/animations.scss @@ -0,0 +1,13 @@ +@include MakeAnimationWrappedEvenOdd(0.2s ease-in-out, "changeAnim") { + 0% { + transform: scale(1, 1); + } + + 50% { + transform: scale(1.03, 1.03); + } + + 100% { + transform: scale(1, 1); + } +} diff --git a/src/css/application_error.scss b/src/css/application_error.scss new file mode 100644 index 00000000..a53e4aa2 --- /dev/null +++ b/src/css/application_error.scss @@ -0,0 +1,67 @@ +#applicationError { + z-index: 9999; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: $mainBgColor; + color: #333; + display: flex; + flex-direction: column; + align-content: center; + align-items: center; + justify-content: center; + @include S(padding, 30px); + + @include Text; + text-align: center; + + h1 { + @include TextShadow3D(#ff0b40); + @include S(margin-top, 20px); + @include S(margin-bottom, 30px); + @include SuperHeading; + @include S(font-size, 35px); + } + + .desc { + // color: rgba(#fff, 0.6); + color: $themeColor; + text-align: left; + @include PlainText; + font-weight: bold; + + a { + cursor: pointer; + pointer-events: all; + font-weight: bold; + display: block; + @include TextShadow3D(#ff0b40); + @include S(margin-top, 10px); + } + + display: block; + @include S(max-width, 350px); + width: 100%; + } + + .details { + font-size: 11px; + line-height: 15px; + color: #888; + font-family: monospace; + text-align: left; + @include S(padding, 6px); + @include BorderRadius(2px); + @include BoxShadow3D(#eee); + position: absolute; + @include S(bottom, 25px); + left: 50%; + transform: translateX(-50%); + max-width: calc(100vw - 40px); + box-sizing: border-box; + @include BreakText; + min-width: 300px; + } +} diff --git a/src/css/common.scss b/src/css/common.scss new file mode 100644 index 00000000..7b8bafd2 --- /dev/null +++ b/src/css/common.scss @@ -0,0 +1,662 @@ +// Common classes and style + +* { + margin: 0; + padding: 0; + touch-action: pan-x pan-y !important; + pointer-events: none; + -webkit-tap-highlight-color: rgba(255, 255, 255, 0); +} + +html, +body { + overscroll-behavior: contain; + overflow: hidden; + font-family: $mainFont; + font-synthesis: none; + + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; +} + +html { + position: fixed; + // scroll-behavior: smooth; + background: $mainBgColor; + + // Disable zooming and thus + -ms-touch-action: pan-x, pan-y; + touch-action: pan-x, pan-y; + -ms-content-zooming: none; + + top: 0; + left: 0; + bottom: 0; + right: 0; + + background: #dee1ea; +} + +body { + color: #555; + user-select: none; + -moz-user-select: none; + -ms-user-select: none; + background: inherit !important; + + text-transform: none; + white-space: normal; + word-break: normal; + word-spacing: normal; + word-wrap: break-word; + font-style: normal; + line-break: auto; + font-stretch: 100%; + text-rendering: optimizeLegibility; + text-decoration: none; + text-size-adjust: 100%; + letter-spacing: normal; + scrollbar-width: 6px; + -webkit-font-smoothing: antialiased; + // -webkit-overflow-scrolling: touch; /* stop scrolling immediately */ + -webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */ + -webkit-text-size-adjust: none; /* prevent webkit from resizing text to fit */ + + // Internet explorer + scrollbar-face-color: #888; + scrollbar-track-color: rgba(255, 255, 255, 0.1); + + overflow: hidden; + @include Text; + + // For recording the bg video + + // filter: blur(5px); + // &::after { + // position: fixed; + // top: 0; + // left: 0; + // right: 0; + // bottom: 0; + // z-index: 9999; + // content: " "; + // background: rgba($ingameHudBg, 0.5); + // } +} + +// Dirty hack +* { + @include TextShadow3DImpl; +} + +img { + -webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */ +} + +i { + font-style: normal; +} +b, +strong { + font-weight: normal; +} +u, +a { + text-decoration: none; +} +input, +textarea, +select { + font-size: inherit; + font-weight: inherit; + font-family: inherit; + line-height: inherit; +} + +button { + background: transparent; + border: 0; + pointer-events: all; + cursor: pointer; + position: relative; + @include TextShadow3D; + + &.prefab_BuyButtonWithResources { + display: flex; + box-sizing: border-box; + @include S(padding, 6px, 4px); + // letter-spacing: 0; + background-color: color($cyan, 400); + flex-direction: row; + justify-content: center; + align-items: center; + @include S(width, 85px); + + &.tooExpensive { + color: $colorRedBright; + background-color: #555; + cursor: default; + } + + .cost_entry { + display: flex; + flex-grow: 1; + justify-content: center; + align-items: center; + } + + b { + display: flex; + flex-grow: 1; + justify-content: center; + align-items: center; + } + + &.tooExpensive { + cursor: default !important; + background-color: #565859 !important; + b { + color: $colorRedBright !important; + } + .cost_entry { + opacity: 0.6; + } + } + } +} + +.styledButton { + background: $themeColor; + text-transform: uppercase; + box-sizing: content-box; + @include S(padding, 3px, 10px); + @include IncreasedClickArea(10px); + @include BorderRadius(4px); + @include TextShadow3D(#fff, $borderColor: #28292a); + @include ButtonText; + @include Button3D($accentColorBright); + border: #{D(1px)} solid rgba(0, 10, 20, 0.2); + @include S(border-bottom-width, 2px); + color: $accentColorDark; + letter-spacing: 0.05em !important; + box-shadow: 0 #{D(1px)} #{D(2px)} 0 rgba(0, 10, 20, 0.2); + + .keybinding { + @include S(bottom, -2.5px); + @include S(right, -2px); + } +} + +::selection { + background: $colorGreenBright; /* WebKit/Blink Browsers */ +} +::-moz-selection { + background: $colorGreenBright; /* Gecko Browsers */ +} + +input[type="text"], +input[type="email"] { + @include S(padding, 11px, 12px); + @include S(margin, 10px, 0); + border: 0; + cursor: text; + display: block; + text-align: left; + box-sizing: border-box; + background: lighten($mainBgColor, 8); + color: #eee; + text-align: left; + + user-select: text !important; + pointer-events: all !important; + + @include Text; + @include IncreasedClickArea(15px); + @include BorderRadius(4px); + + &::placeholder { + color: #fff; + opacity: 0.4; + } + + transition: background-color 0.4s ease-in-out !important; + @include TextShadow3D(#fff); + @include BoxShadow3D(lighten($mainBgColor, 30)); + + &:focus { + @include BoxShadow3D(lighten($mainBgColor, 35)); + } + + &.errored { + @include BoxShadow3D(mix(lighten($mainBgColor, 30), #f77, 25%)); + + &:focus { + @include BoxShadow3D(mix(lighten($mainBgColor, 50), #f77, 25%)); + } + } + + &.input-token { + @include SuperHeading; + text-align: center; + @include S(letter-spacing, 30px); + @include S(padding-left, 30px); + } +} + +a { + color: $themeColor; +} + +button, +input, +select, +textarea, +a { + &:focus { + outline: none; + } + font-family: inherit; + font-weight: inherit; + pointer-events: all; +} + +a { + text-decoration: none; + cursor: pointer; + pointer-events: all; +} + +i { + font-style: normal; +} + +input { + user-select: text; + -moz-user-select: text; + pointer-events: all; + cursor: text; + border-radius: 0; +} + +canvas { + pointer-events: all; + image-rendering: auto; + // &.smoothed { + // } + // &.unsmoothed { + // } + letter-spacing: 0 !important; + + transform: translateZ(0); + backface-visibility: hidden; + -webkit-backface-visibility: hidden; +} + +.fontPreload { + position: absolute; + top: -100px; + left: -100px; +} + +// Scrollbar +::-webkit-scrollbar { + @include S(width, 6px); + @include S(height, 6px); +} + +::-webkit-scrollbar-track { + background: rgba(#000, 0.05); +} + +::-webkit-scrollbar-thumb { + border-radius: 4px; + background: #cdd0d4; +} + +::-webkit-scrollbar-thumb:hover { + background: #d8dce0; +} + +#uiTestPlaybackCursor { + position: fixed; + top: 100px; + left: 100px; + z-index: 9999; + border-radius: 50%; + background: rgba(255, 255, 0, 0.4); + width: 24px; + height: 24px; + border: 3px solid rgba(0, 0, 0, 0.5); + margin-top: -12px; + margin-left: -12px; + box-sizing: border-box; +} + +.pressed { + transform: scale(0.95) !important; + animation: none !important; +} + +.pressedSmallElement { + transform: scale(0.88) !important; + animation: none !important; +} + +.spritesheetImage { + display: block; + position: absolute; + background-repeat: no-repeat; + z-index: 1; +} + +.inlineTextIconSprite { + position: relative; + vertical-align: middle; + display: inline-block; +} + +.badged { + color: color($purple, 300); +} + +.prefab_LoadingTextWithAnim, +.prefab_LoadingTextWithAnimDelayed { + display: inline-flex; + align-items: center; + justify-content: center; + text-transform: uppercase; + + @include Text; + @include TextShadow3D; + opacity: 1; + z-index: 20; + color: #393747; + + &::after { + content: " "; + background: uiResource("loading.svg") center center / contain no-repeat; + @include S(width, 15px); + @include S(height, 15px); + @include S(margin-top, 1px); + @include S(margin-left, 5px); + display: inline-block; + vertical-align: middle; + } +} + +.prefab_LoadingTextWithAnimDelayed { + @include InlineAnimation(0.6s ease-in-out) { + 0% { + opacity: 0; + } + 50% { + opacity: 0; + } + 100% { + opacity: 1; + } + } +} + +.prefab_FeatureComingSoon { + position: relative; + + &::after { + @include S(top, -5px); + @include S(left, -5px); + @include S(right, -5px); + @include S(bottom, -5px); + content: "Coming soon!"; + z-index: 10000; + background: rgba(lighten($mainBgColor, 0), 0.4); + @include BorderRadius(4px); + position: absolute; + display: flex; + justify-content: center; + align-items: center; + pointer-events: all; + @include PlainText; + text-transform: uppercase; + } + + opacity: 0.6; + + > * { + opacity: 0.5 !important; + } +} + +.prefab_InfoIcon { + @include S(width, 25px); + @include S(height, 25px); + // background: uiResource("icons_small/info.png") center center / contain no-repeat; + z-index: 100; + opacity: 0.8; + cursor: pointer; + pointer-events: all; + display: inline-block; + position: relative; + @include IncreasedClickArea(10px); +} + +.gameState.prefab_LoadingState { + text-align: center; + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + + .loadingImage { + background: uiResource("loading.svg") center center / #{D(60px)} no-repeat; + width: 100%; + display: flex; + flex-grow: 1; + } + + .loadingStatus { + position: absolute; + @include S(left, 20px); + @include S(right, 20px); + @include S(bottom, 30px); + @include Text; + @include TextShadow3D(#aaa); + + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + + > .bar { + display: none; + @include S(margin-top, 15px); + width: 80vw; + @include BoxShadow3D(lighten($mainBgColor, 10), $size: 1px); + position: relative; + @include TextShadow3D(#fff); + height: 2px; + + .inner { + position: absolute !important; + top: 0; + left: 0; + bottom: 0; + z-index: 1; + @include BoxShadow3D($themeColor, $size: 1px); + @include BorderRadius(4px); + + transform-origin: 0% 50%; + + @include InlineAnimation(1.3s ease-in-out infinite) { + 0% { + background-color: darken($themeColor, 5); + transform: none; + } + 50% { + background-color: lighten($themeColor, 10); + transform: scale(1.01); + } + 100% { + background-color: darken($themeColor, 5); + transform: none; + } + } + } + + .status { + display: none; + position: relative; + z-index: 2; + display: inline-flex; + @include S(padding, 5px); + @include PlainText; + } + } + } +} + +.grow { + flex-grow: 1; +} + +.checkbox { + $bgColor: darken($mainBgColor, 0); + background-color: $bgColor; + @include S(width, 45px); + @include S(height, 20px); + display: flex; + @include S(padding, 3px); + box-sizing: content-box; + cursor: pointer; + pointer-events: all; + transition: opacity 0.2s ease-in-out, background-color 0.4s ease-in-out, box-shadow 0.4s ease-in-out !important; + position: relative; + @include BorderRadius(20px); + @include IncreasedClickArea(10px); + @include BoxShadow3D($bgColor, $size: 2px); + &.loading { + opacity: 0.2; + } + + .knob { + @include S(width, 20px); + @include S(height, 20px); + display: inline-block; + transition: margin-left 0.4s ease-in-out !important; + background: #fff; + position: relative; + @include BorderRadius(20px); + @include BoxShadow3D(#fff, $size: 1px); + } + + &.checked { + background-color: $themeColor; + @include BoxShadow3D($themeColor, $size: 2px); + .knob { + @include S(margin-left, 25px); + } + } +} + +.keybinding { + background: #fff; + text-transform: uppercase; + @include S(padding, 2px, 1px, 2px); + @include PlainText; + @include BorderRadius(2px); + &, + > span { + @include S(font-size, 9px); + @include S(line-height, 11px); + font-weight: bold !important; + text-shadow: none !important; + // font-family: Arial, sans-serif !important; + } + + font-weight: bold; + color: $accentColorDark; + text-align: center; + justify-content: center; + align-items: center; + @include S(min-width, 12px); + display: inline-flex; + position: absolute; + @include S(bottom, 0px); + @include S(right, 0px); + z-index: 999; + box-sizing: border-box; + @include S(height, 12px); + overflow: hidden; + border: #{D(1px)} solid $accentColorDark; + + .keybinding_space { + @include S(font-size, 17px); + @include S(line-height, 11px); + @include S(margin-top, -12px); + } +} + +.xpaystation-widget-lightbox { + z-index: 19999; + .xpaystation-widget-lightbox-overlay { + background: rgba($mainBgColor, 0.94); + } + + &, + iframe { + pointer-events: all; + user-select: all; + } +} + +iframe { + pointer-events: all; + user-select: all; +} + +// Steam overlay fiy +#steamOverlayCanvasFix { + position: fixed; + top: 0px; + left: 0; + right: 0; + bottom: 0; + width: 100%; + height: 100%; + opacity: 0.01; + pointer-events: none; + z-index: -1; +} + +.sentry-error-embed-wrapper { + z-index: 10000; + background: rgba(0, 0, 0, 0.9); + * { + text-shadow: none !important; + pointer-events: all; + } +} + +.cpmsrendertarget { + &, + * { + pointer-events: all; + } + + background: rgba($mainBgColor, 0.94) !important; + + .cpmsvideoclosebanner { + font-family: GameFont !important; + font-size: 16px !important; + border-radius: 2px !important; + background: $themeColor !important; + @include BoxShadow3D(darken($mainBgColor, 12)); + color: #eee !important; + &:active { + @include BoxShadow3D(darken($mainBgColor, 12), $size: 1px); + transform: translateY(2px); + } + } +} diff --git a/src/css/dynamic_ui.scss b/src/css/dynamic_ui.scss new file mode 100644 index 00000000..8b005eff --- /dev/null +++ b/src/css/dynamic_ui.scss @@ -0,0 +1,43 @@ +// Removes the unit (px, %, etc) from a value +@function strip-unit($number) { + @if type-of($number) == "number" and not unitless($number) { + @return $number / ($number * 0 + 1); + } + + @return $number; +} + +// Helper method to scale a value, for use in calc() etc +@function D($v) { + $baseValue: strip-unit($v) * 1px; + @return calc(#{$baseValue} * var(--ui-scale)); +} + +// Helper method to scale the font size +@mixin ScaleFont($fontSize, $lineHeight) { + font-size: D($fontSize * $mainFontScale); + line-height: D($lineHeight * $mainFontScale); +} + +// Helper method to scale a property value +@mixin S($propName, $v1, $v2: "", $v3: "", $v4: "", $important: false) { + $impSuffix: ""; + @if $important == true { + $impSuffix: "!important"; + } + + $v1: D($v1); + + @if $v2 != "" { + $v2: D($v2); + } + + @if $v3 != "" { + $v3: D($v3); + } + @if $v4 != "" { + $v4: D($v4); + } + + #{$propName}: #{$v1} #{$v2} #{$v3} #{$v4} #{$impSuffix}; +} diff --git a/src/css/game_state.scss b/src/css/game_state.scss new file mode 100644 index 00000000..60fab61d --- /dev/null +++ b/src/css/game_state.scss @@ -0,0 +1,31 @@ +$gameStateTransition: 0.2s ease-out; + +@mixin StateAnim($properties...) { + transition: all $gameStateTransition; + transition-property: $properties; +} + +.gameState { + display: block; + // background: $mainBgColor; + height: 100%; + width: 100%; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 0; + overflow: hidden !important; + @include Text; + + @include StateAnim(opacity, transform, filter); + opacity: 0; + // transform: scaleX(0.99) skewX(1deg) translate(1%, 0.5%); + + &.arrived { + opacity: 1; + filter: none !important; + transform: none; + } +} diff --git a/src/css/icons.scss b/src/css/icons.scss new file mode 100644 index 00000000..fa124f67 --- /dev/null +++ b/src/css/icons.scss @@ -0,0 +1,22 @@ +// $icons: ; + +// @each $icon in $icons { +// [data-icon="#{$icon}"] { +// background-image: uiResource("res/ui/#{$icon}"); +// } +// } + +$buildings: belt, cutter, miner, mixer, painter, rotater, splitter, stacker, trash, underground_belt; + +@each $building in $buildings { + [data-icon="building_tutorials/#{$building}.png"] { + background-image: uiResource("res/ui/building_tutorials/#{$building}.png") !important; + } +} + +$upgrades: belt, miner, painting, processors; +@each $upgrade in $upgrades { + [data-icon="upgrades/#{$upgrade}.png"] { + background-image: uiResource("res/ui/upgrades/#{$upgrade}.png") !important; + } +} diff --git a/src/css/ingame_hud/beta_overlay.scss b/src/css/ingame_hud/beta_overlay.scss new file mode 100644 index 00000000..816cddb2 --- /dev/null +++ b/src/css/ingame_hud/beta_overlay.scss @@ -0,0 +1,8 @@ +#ingame_HUD_BetaOverlay { + position: fixed; + @include S(top, 10px); + @include S(right, 15px); + color: $colorRedBright; + @include Heading; + text-transform: uppercase; +} diff --git a/src/css/ingame_hud/blur_overlay.scss b/src/css/ingame_hud/blur_overlay.scss new file mode 100644 index 00000000..d821b6b8 --- /dev/null +++ b/src/css/ingame_hud/blur_overlay.scss @@ -0,0 +1,8 @@ +body.ingameDialogOpen { + #ingame_Canvas, + #ingame_HUD_GameMenu, + #ingame_HUD_KeybindingOverlay, + #ingame_HUD_buildings_toolbar { + filter: blur(5px); + } +} diff --git a/src/css/ingame_hud/building_placer.scss b/src/css/ingame_hud/building_placer.scss new file mode 100644 index 00000000..f90f155f --- /dev/null +++ b/src/css/ingame_hud/building_placer.scss @@ -0,0 +1,35 @@ +#ingame_HUD_building_placer { + position: fixed; + @include S(bottom, 60px); + left: 50%; + transform: translateX(-50%); + + display: flex; + flex-direction: column; + + @include S(padding, 6px); + justify-content: center; + align-items: center; + background-color: $ingameHudBg; + @include S(border-radius, 4px); + background: #333; + @include S(width, 300px); + + .buildingLabel { + @include PlainText; + color: #fff; + text-transform: uppercase; + @include S(margin-bottom, 2px); + } + + .instructions, + .description { + text-align: center; + color: mix($accentColorDark, $accentColorBright, 50%); + @include SuperSmallText; + } + + @include StyleBelowWidth(700px) { + display: none !important; + } +} diff --git a/src/css/ingame_hud/buildings_toolbar.scss b/src/css/ingame_hud/buildings_toolbar.scss new file mode 100644 index 00000000..779333ba --- /dev/null +++ b/src/css/ingame_hud/buildings_toolbar.scss @@ -0,0 +1,181 @@ +#ingame_HUD_buildings_toolbar { + position: fixed; + @include S(bottom, 0px); + left: 50%; + transform: translateX(-50%); + + $toolbarBg: rgba($accentColorBright, 0.9); + display: flex; + flex-direction: column; + background-color: $toolbarBg; + // border: $ingameHudBorder; + border-bottom-width: 0; + + @include S(border-radius, 4px, 4px, 0, 0); + // box-shadow: 0 0 0 #{D(2px)} rgba(darken($toolbarBg, 20), 0.5); + transition: transform 0.12s ease-in-out; + + &:not(.visible) { + transform: translateX(-50%) translateY(#{D(100px)}); + } + + .buildings { + display: grid; + grid-auto-flow: column; + @include S(padding, 0, 5px); + + .building { + color: $accentColorDark; + display: flex; + flex-direction: column; + position: relative; + align-items: center; + justify-content: center; + @include S(padding, 5px); + @include S(padding-bottom, 7px); + $buildingIconSize: 32px; + + &:not(.unlocked) { + @include S(width, 30px); + .tooltip { + display: none !important; + } + .keybinding, + .iconWrap { + opacity: 0.01; + } + &::before { + opacity: 0.5; + content: " "; + background: uiResource("locked_building.png") center center / #{D(20px)} #{D(20px)} + no-repeat; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 4; + } + } + + // &:first-child .tooltip { + // display: flex; + // } + + pointer-events: all; + transition: background-color 0.1s ease-in-out; + &.unlocked:hover { + background: rgba($accentColorDark, 0.1); + cursor: pointer; + } + + .iconWrap { + position: relative; + @include S(width, $buildingIconSize); + @include S(height, $buildingIconSize); + @include S(margin-top, 3px); + @include S(margin-bottom, 6px); + } + + .label { + @include SuperSmallText; + display: none; + font-weight: bold; + text-transform: uppercase; + } + + .keybinding { + // position: relative; + right: 50%; + transform: translateX(50%); + background: transparent; + border: 0; + @include S(bottom, 2pxpx); + } + + &[data-tilewidth="2"] { + .iconWrap { + @include S(width, 2 * $buildingIconSize); + } + } + + &:last-child { + border: none; + } + + .tooltip { + position: absolute; + pointer-events: none; + background: #333; + @include S(padding, 7px); + bottom: calc(100% + #{D(10px)}); + left: 50%; + transform: translateX(-50%); + box-sizing: content-box; + @include SuperSmallText; + @include S(width, 200px); + @include S(border-radius, 4px); + + box-shadow: #{D(1px)} #{D(1px)} 0 0 rgba(0, 10, 25, 0.2); + + display: none; + z-index: 9999; + + flex-direction: column; + + .title { + color: #fff; + @include PlainText; + text-transform: uppercase; + margin-bottom: 5px; + } + + .desc { + color: #aaa; + @include SuperSmallText; + margin-bottom: 10px; + strong { + color: #fff; + } + } + + .tutorialImage { + display: inline-block; + @include S(width, 200px); + @include S(height, 200px); + @include S(border-radius, 4px); + background-size: contain; + background-repeat: no-repeat; + } + + &::after { + top: 100%; + left: 50%; + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; + pointer-events: none; + border-top-color: #333; + @include S(border-width, 5px); + transform: translateX(-50%); + } + } + + &:hover .tooltip { + display: flex; + + @include InlineAnimation(0.5s ease-in-out) { + 90% { + opacity: 0; + } + 0% { + transform: translate(-50%, 5%) scale(0.9); + opacity: 0; + } + } + } + } + } +} diff --git a/src/css/ingame_hud/dialogs.scss b/src/css/ingame_hud/dialogs.scss new file mode 100644 index 00000000..b7aca1e5 --- /dev/null +++ b/src/css/ingame_hud/dialogs.scss @@ -0,0 +1,63 @@ +.ingameDialog { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + pointer-events: all; + background: $modalDialogBg; + + display: flex; + align-items: center; + justify-content: center; + + &.visible { + .dialogInner { + opacity: 1; + } + } + + .dialogInner { + transition: opacity 0.2s ease-in-out; + opacity: 0; + } + + > .dialogInner { + background: #fff; + @include S(min-width, 500px); + max-width: calc(100vw - #{D(50px)}); + max-height: calc(100vh - #{D(50px)}); + @include S(border-radius, 4px); + display: flex; + flex-direction: column; + @include S(padding, 15px); + pointer-events: all; + + > .title { + @include Heading; + margin: 0; + text-transform: uppercase; + display: grid; + grid-template-columns: 1fr auto; + @include S(margin-bottom, 10px); + + > .closeButton { + opacity: 0.7; + @include S(width, 20px); + @include S(height, 20px); + background: uiResource("icons/close.png") center center / 60% no-repeat; + cursor: pointer; + pointer-events: all; + transition: opacity 0.2s ease-in-out; + &:hover { + opacity: 0.4; + } + } + } + + > .content { + overflow-y: auto; + pointer-events: all; + } + } +} diff --git a/src/css/ingame_hud/game_menu.scss b/src/css/ingame_hud/game_menu.scss new file mode 100644 index 00000000..16ac3129 --- /dev/null +++ b/src/css/ingame_hud/game_menu.scss @@ -0,0 +1,59 @@ +#ingame_HUD_GameMenu { + position: absolute; + top: 0; + left: 50%; + display: grid; + transform: translateX(-50%); + @include S(grid-gap, 3px); + grid-auto-flow: column; + + button { + background: $colorGreenBright; + @include PlainText; + color: #fff; + border-color: rgba(0, 0, 0, 0.1); + @include S(padding, 5px, 5px, 5px); + transition: all 0.12s ease-in-out; + transition-property: opacity, transform; + + &:hover { + opacity: 0.9; + transform: translateY(3px); + } + + @include IncreasedClickArea(10px); + @include ButtonText; + border: #{D(2px)} solid rgba(0, 10, 20, 0.2); + @include S(border-width, 2px); + border-radius: 0 0 #{D(4px)} #{D(4px)}; + @include S(border-top-width, 10px); + @include S(padding-left, 30px); + @include S(margin-top, -5px); + @include S(letter-spacing, 1px, $important: true); + background: center #{D(10px)} / #{D(20px)} no-repeat; + @include S(min-height, 47px); + + &[data-button-id="shop"] { + background-color: rgb(141, 70, 223); + background-image: uiResource("icons/shop.png"); + } + &[data-button-id="stats"] { + background-color: rgb(53, 235, 113); + background-image: uiResource("icons/statistics.png"); + } + + .keybinding { + border: 0; + color: #fff; + border-top-left-radius: 0; + border-top-right-radius: 0; + bottom: unset; + // background: rgba(0, 10, 20, 0.5); + background: transparent; + @include S(top, -5px); + right: unset; + left: 50%; + transform: translateX(-50%); + } + } +} diff --git a/src/css/ingame_hud/keybindings_overlay.scss b/src/css/ingame_hud/keybindings_overlay.scss new file mode 100644 index 00000000..db05aacf --- /dev/null +++ b/src/css/ingame_hud/keybindings_overlay.scss @@ -0,0 +1,78 @@ +#ingame_HUD_KeybindingOverlay { + position: absolute; + @include S(top, 10px); + @include S(left, 10px); + + display: flex; + flex-direction: column; + align-items: flex-start; + + > .binding { + display: inline-grid; + @include PlainText; + align-items: center; + @include S(margin-bottom, 3px); + grid-auto-flow: column; + @include S(grid-gap, 2px); + + i { + display: inline-block; + @include S(height, 10px); + width: 1px; + @include S(margin, 0, 3px); + background-color: #ccc; + transform: rotate(10deg); + // @include S(margin, 0, 3px); + } + + code { + position: relative; + top: unset; + left: unset; + margin: 0; + &.rightMouse { + background: #fff uiResource("icons/mouse_right.png") center center / 85% no-repeat; + } + + &.leftMouse { + background: #fff uiResource("icons/mouse_left.png") center center / 85% no-repeat; + } + } + label { + color: $accentColorDark; + @include SuperSmallText; + text-transform: uppercase; + @include S(margin-left, 5px); + } + } + + &:not(.placementActive) .binding.placementOnly { + display: none; + } + &.placementActive .binding.noPlacementOnly { + display: none; + } + + .binding.placementOnly, + &:not(.placementActive) .binding.noPlacementOnly { + transform-origin: 0% 50%; + @include InlineAnimation(0.3s ease-in-out) { + 0% { + color: $colorRedBright; + transform: scale(1.2); + } + } + } + + .shift .keybinding { + transition: all 0.1s ease-in-out; + transition-property: background-color, color, border-color; + background: $colorRedBright; + border-color: $colorRedBright; + color: #fff; + } + + &.shiftDown .shift .keybinding { + border-color: darken($colorRedBright, 40); + } +} diff --git a/src/css/ingame_hud/shop.scss b/src/css/ingame_hud/shop.scss new file mode 100644 index 00000000..c6ad0711 --- /dev/null +++ b/src/css/ingame_hud/shop.scss @@ -0,0 +1,180 @@ +#ingame_HUD_Shop { + .content { + @include S(padding-right, 10px); + display: flex; + flex-direction: column; + .upgrade { + display: grid; + grid-template-columns: auto 1fr auto; + background: #eee; + @include S(border-radius, 3px); + @include S(margin-bottom, 4px); + @include S(padding, 5px, 10px); + @include S(grid-row-gap, 5px); + @include S(height, 95px); + grid-template-rows: #{D(20px)} auto; + + &:last-child { + margin-bottom: 0; + } + + .title { + grid-column: 2 / 3; + grid-row: 1 / 2; + @include Heading; + display: flex; + align-items: center; + + .tier { + @include S(margin-left, 5px); + background: $colorGreenBright; + @include S(border-radius, 4px); + text-transform: uppercase; + @include PlainText; + color: #fff; + font-weight: bold; + @include S(margin-top, 1px); + + @include S(padding, 0px, 5px); + + &[data-tier="0"] { + background-color: rgb(73, 186, 190); + } + &[data-tier="1"] { + background-color: rgb(73, 94, 190); + } + &[data-tier="2"] { + background-color: rgb(186, 73, 190); + } + &[data-tier="3"] { + background-color: rgb(96, 190, 73); + } + &[data-tier="4"] { + background-color: rgb(190, 91, 73); + } + &[data-tier="5"] { + background-color: rgb(219, 184, 29); + } + &[data-tier="6"] { + background-color: rgb(190, 73, 73); + } + } + } + + .icon { + @include S(width, 40px); + @include S(height, 40px); + background: center center / contain no-repeat; + align-self: center; + justify-self: center; + grid-column: 1 / 2; + grid-row: 1 / 4; + @include S(margin-right, 20px); + opacity: 0.2; + } + + .description { + grid-column: 3 / 4; + grid-row: 1 / 2; + @include PlainText; + color: #aaa; + align-self: start; + justify-self: end; + } + + .requirements { + grid-column: 2 / 3; + grid-row: 3 / 4; + display: grid; + grid-auto-flow: column; + @include S(grid-gap, 15px); + justify-content: start; + + .requirement { + position: relative; + display: flex; + flex-direction: column; + align-items: center; + + canvas { + @include S(width, 40px); + @include S(height, 40px); + } + + .amount { + @include S(margin-top, 4px); + z-index: 10; + @include SuperSmallText; + letter-spacing: 0; + background: #e2e4e6; + + @include S(line-height, 13px); + @include S(border-radius, 2px); + @include S(padding, 0, 2px, 3px); + position: relative; + text-align: center; + @include S(min-width, 50px); + overflow: hidden; + + .progressBar { + bottom: 0; + left: 0; + right: 0; + top: 0; + @include S(border-radius, 2px); + position: absolute; + display: inline-block; + z-index: -1; + transition: all 0.2s ease-in-out; + transition-property: width, background-color; + background: #bdbfca; + + &.complete { + background-color: $colorGreenBright; + } + } + } + } + } + + button.buy { + grid-column: 3 / 4; + grid-row: 3 / 4; + align-self: end; + justify-self: end; + // @include S(padding, 4px, 5px); + // @include PlainText; + background-color: $colorGreenBright; + color: #fff; + + transition: all 0.2s ease-in-out; + transition-property: background-color, opacity; + + &:not(.buyable) { + background-color: #aaa; + cursor: default; + pointer-events: none; + opacity: 0.3; + } + } + + &.maxLevel { + button.buy { + opacity: 0 !important; + } + .requirements { + display: none; + } + .description { + // grid-column: 2 / 4; + // grid-row: 2 / 3; + align-self: end; + justify-self: center; + color: $colorGreenBright; + text-transform: uppercase; + @include S(margin-top, 20px); + } + } + } + } +} diff --git a/src/css/ingame_hud/unlock_notification.scss b/src/css/ingame_hud/unlock_notification.scss new file mode 100644 index 00000000..f81232d0 --- /dev/null +++ b/src/css/ingame_hud/unlock_notification.scss @@ -0,0 +1,134 @@ +#ingame_HUD_UnlockNotification { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(#333538, 0.95) uiResource("dialog_bg_pattern.png") top left / #{D(10px)} repeat; + display: flex; + justify-content: center; + align-items: flex-start; + pointer-events: all; + @include InlineAnimation(0.1s ease-in-out) { + 0% { + opacity: 0; + } + } + + .dialog { + background: rgba(#333539, 0.5); + @include S(padding, 30px); + + @include InlineAnimation(0.5s ease-in-out) { + 0% { + opacity: 0; + } + } + + color: #fff; + text-align: center; + .title, + .subTitle { + @include SuperHeading; + text-transform: uppercase; + @include S(font-size, 50px); + + @include InlineAnimation(0.5s ease-in-out) { + 0% { + transform: translateY(-50vh); + } + 50% { + transform: translateY(5vh); + } + 75% { + transform: translateY(-2vh); + } + } + } + + .subTitle { + @include Heading; + background: $colorGreenBright; + display: inline-block; + @include S(padding, 1px, 6px); + @include S(margin, 20px, 0, 20px); + + @include S(border-radius, 4px); + @include InlineAnimation(0.5s ease-in-out) { + 0% { + transform: translateY(-60vh); + } + 50% { + transform: translateY(6vh); + } + 75% { + transform: translateY(-3vh); + } + } + } + + .contents { + @include S(width, 400px); + @include InlineAnimation(0.5s ease-in-out) { + 0% { + transform: translateX(-100vw); + } + 50% { + transform: translateX(5vw); + } + + 75% { + transform: translateX(-2vw); + } + } + display: grid; + grid-template-columns: auto auto; + align-items: center; + justify-content: center; + @include S(grid-gap, 10px); + + .reward { + grid-column: 1 / 3; + @include InlineAnimation(0.5s ease-in-out) { + 0% { + transform: translateX(200vw); + } + 50% { + transform: translateX(-10vw); + } + + 75% { + transform: translateX(4vw); + } + } + } + + .buildingExplanation { + @include S(width, 200px); + @include S(height, 200px); + display: inline-block; + background-position: center center; + background-size: cover; + background-repeat: no-repeat; + @include S(border-radius, 4px); + box-shadow: #{D(2px)} #{D(3px)} 0 0 rgba(0, 0, 0, 0.15); + } + } + + button.close { + border: 0; + @include InlineAnimation(0.5s ease-in-out) { + 0% { + transform: translateY(50vh); + } + 50% { + transform: translateY(-5vh); + } + 75% { + transform: translateY(2vh); + } + } + @include S(margin-top, 30px); + } + } +} diff --git a/src/css/main.scss b/src/css/main.scss new file mode 100644 index 00000000..6d99f6a5 --- /dev/null +++ b/src/css/main.scss @@ -0,0 +1,50 @@ +// Control here whether to inline all resources or instead load them +@function uiResource($pth) { + @if (str-index($string: $pth, $substring: ".noinline")) { + @return resolve($pth); + } + @return inline($pth); +} + +@import "icons"; +@import "trigonometry"; +@import "material_colors"; +@import "dynamic_ui"; +@import "variables"; + +@import "mixins"; +@import "common"; +@import "animations"; +@import "game_state"; +@import "application_error"; +@import "textual_game_state"; +@import "adinplay"; + +@import "states/preload"; +@import "states/main_menu"; +@import "states/ingame"; + +@import "ingame_hud/buildings_toolbar"; +@import "ingame_hud/building_placer"; +@import "ingame_hud/beta_overlay"; +@import "ingame_hud/keybindings_overlay"; +@import "ingame_hud/unlock_notification"; +@import "ingame_hud/shop"; +@import "ingame_hud/game_menu"; +@import "ingame_hud/blur_overlay"; +@import "ingame_hud/dialogs"; + +// Z-Index +$elements: ingame_Canvas, ingame_HUD_building_placer_overlay, ingame_HUD_building_placer, + ingame_HUD_buildings_toolbar, ingame_HUD_GameMenu, ingame_HUD_KeybindingOverlay, ingame_HUD_Shop, + ingame_HUD_BetaOverlay, ingame_HUD_UnlockNotification; + +$zindex: 100; + +@each $elem in $elements { + ##{$elem} { + z-index: $zindex; + } + + $zindex: $zindex + 10; +} diff --git a/src/css/material_colors.scss b/src/css/material_colors.scss new file mode 100644 index 00000000..dd4bdd1d --- /dev/null +++ b/src/css/material_colors.scss @@ -0,0 +1,319 @@ +// +// color palette + +// sass-lint:disable hex-length + +@function color($color, $value: 500) { + @return map-get($color, $value); +} + +$red: ( + 50: #ffebee, + 100: #ffcdd2, + 200: #ef9a9a, + 300: #e57373, + 400: #ef5350, + 500: #f44336, + 600: #e53935, + 700: #d32f2f, + 800: #c62828, + 900: #b71c1c, + a100: #ff8a80, + a200: #ff5252, + a400: #ff1744, + a700: #d50000, +); + +$pink: ( + 50: #fce4ec, + 100: #f8bbd0, + 200: #f48fb1, + 300: #f06292, + 400: #ec407a, + 500: #e91e63, + 600: #d81b60, + 700: #c2185b, + 800: #ad1457, + 900: #880e4f, + a100: #ff80ab, + a200: #ff4081, + a400: #f50057, + a700: hsl(333, 84%, 42%), +); + +$purple: ( + 50: #f3e5f5, + 100: #e1bee7, + 200: #ce93d8, + 300: #ba68c8, + 400: #ab47bc, + 500: #9c27b0, + 600: #8e24aa, + 700: #7b1fa2, + 800: #6a1b9a, + 900: #4a148c, + a100: #ea80fc, + a200: #e040fb, + a400: #d500f9, + a700: #aa00ff, +); + +$deep-purple: ( + 50: #ede7f6, + 100: #d1c4e9, + 200: #b39ddb, + 300: #9575cd, + 400: #7e57c2, + 500: #673ab7, + 600: #5e35b1, + 700: #512da8, + 800: #4527a0, + 900: #311b92, + a100: #b388ff, + a200: #7c4dff, + a400: #651fff, + a700: #6200ea, +); + +$indigo: ( + 50: #e8eaf6, + 100: #c5cae9, + 200: #9fa8da, + 300: #7986cb, + 400: #5c6bc0, + 500: #3f51b5, + 600: #3949ab, + 700: #303f9f, + 800: #283593, + 900: #1a237e, + a100: #8c9eff, + a200: #536dfe, + a400: #3d5afe, + a700: #304ffe, +); + +$blue: ( + 50: #e3f2fd, + 100: #bbdefb, + 200: #90caf9, + 300: #64b5f6, + 400: #42a5f5, + 500: #2196f3, + 600: #1e88e5, + 700: #1976d2, + 800: #1565c0, + 900: #0d47a1, + a100: #82b1ff, + a200: #448aff, + a400: #2979ff, + a700: #2962ff, +); + +$light-blue: ( + 50: #e1f5fe, + 100: #b3e5fc, + 200: #81d4fa, + 300: #4fc3f7, + 400: #29b6f6, + 500: #03a9f4, + 600: #039be5, + 700: #0288d1, + 800: #0277bd, + 900: #01579b, + a100: #80d8ff, + a200: #40c4ff, + a400: #00b0ff, + a700: #0091ea, +); + +$cyan: ( + 50: #e0f7fa, + 100: #b2ebf2, + 200: #80deea, + 300: #4dd0e1, + 400: #26c6da, + 500: #00bcd4, + 600: #00acc1, + 700: #0097a7, + 800: #00838f, + 900: #006064, + a100: #84ffff, + a200: #18ffff, + a400: #00e5ff, + a700: #00b8d4, +); + +$teal: ( + 50: #e0f2f1, + 100: #b2dfdb, + 200: #80cbc4, + 300: #4db6ac, + 400: #26a69a, + 500: #009688, + 600: #00897b, + 700: #00796b, + 800: #00695c, + 900: #004d40, + a100: #a7ffeb, + a200: #64ffda, + a400: #1de9b6, + a700: #00bfa5, +); + +$green: ( + 50: #e8f5e9, + 100: #c8e6c9, + 200: #a5d6a7, + 300: #81c784, + 400: #66bb6a, + 500: #4caf50, + 600: #43a047, + 700: #388e3c, + 800: #2e7d32, + 900: #1b5e20, + a100: #b9f6ca, + a200: #69f0ae, + a400: #00e676, + a700: #00c853, +); + +$light-green: ( + 50: #f1f8e9, + 100: #dcedc8, + 200: #c5e1a5, + 300: #aed581, + 400: #9ccc65, + 500: #8bc34a, + 600: #7cb342, + 700: #689f38, + 800: #558b2f, + 900: #33691e, + a100: #ccff90, + a200: #b2ff59, + a400: #76ff03, + a700: #64dd17, +); + +$lime: ( + 50: #f9fbe7, + 100: #f0f4c3, + 200: #e6ee9c, + 300: #dce775, + 400: #d4e157, + 500: #cddc39, + 600: #c0ca33, + 700: #afb42b, + 800: #9e9d24, + 900: #827717, + a100: #f4ff81, + a200: #eeff41, + a400: #c6ff00, + a700: #aeea00, +); + +$yellow: ( + 50: #fffde7, + 100: #fff9c4, + 200: #fff59d, + 300: #fff176, + 400: #ffee58, + 500: #ffeb3b, + 600: #fdd835, + 700: #fbc02d, + 800: #f9a825, + 900: #f57f17, + a100: #ffff8d, + a200: #ffff00, + a400: #ffea00, + a700: #ffd600, +); + +$amber: ( + 50: #fff8e1, + 100: #ffecb3, + 200: #ffe082, + 300: #ffd54f, + 400: #ffca28, + 500: #ffc107, + 600: #ffb300, + 700: #ffa000, + 800: #ff8f00, + 900: #ff6f00, + a100: #ffe57f, + a200: #ffd740, + a400: #ffc400, + a700: #ffab00, +); + +$orange: ( + 50: #fff3e0, + 100: #ffe0b2, + 200: #ffcc80, + 300: #ffb74d, + 400: #ffa726, + 500: #ff9800, + 600: #fb8c00, + 700: #f57c00, + 800: #ef6c00, + 900: #e65100, + a100: #ffd180, + a200: #ffab40, + a400: #ff9100, + a700: #ff6d00, +); + +$deep-orange: ( + 50: #fbe9e7, + 100: #ffccbc, + 200: #ffab91, + 300: #ff8a65, + 400: #ff7043, + 500: #ff5722, + 600: #f4511e, + 700: #e64a19, + 800: #d84315, + 900: #bf360c, + a100: #ff9e80, + a200: #ff6e40, + a400: #ff3d00, + a700: #dd2c00, +); + +$brown: ( + 50: #efebe9, + 100: #d7ccc8, + 200: #bcaaa4, + 300: #a1887f, + 400: #8d6e63, + 500: #795548, + 600: #6d4c41, + 700: #5d4037, + 800: #4e342e, + 900: #3e2723, +); + +$grey: ( + 50: #fafafa, + 100: #f5f5f5, + 200: #eeeeee, + 300: #e0e0e0, + 400: #bdbdbd, + 500: #9e9e9e, + 600: #757575, + 700: #616161, + 800: #424242, + 900: #212121, +); + +$blue-grey: ( + 50: #eceff1, + 100: #cfd8dc, + 200: #b0bec5, + 300: #90a4ae, + 400: #78909c, + 500: #607d8b, + 600: #546e7a, + 700: #455a64, + 800: #37474f, + 900: #263238, +); diff --git a/src/css/mixins.scss b/src/css/mixins.scss new file mode 100644 index 00000000..9881ffea --- /dev/null +++ b/src/css/mixins.scss @@ -0,0 +1,379 @@ +// ---------------------------------------- +/* Forces an element to get rendered on its own layer, increasing +the performance when animated. Use only transform and opacity in animations! */ +@mixin FastAnimation { + // will-change: transform, opacity; + transform: translateZ(0); + backface-visibility: hidden; + -webkit-backface-visibility: hidden; +} + +// Helper which includes the translateZ webkit fix, use together with Fast animation +// $hardwareAcc: translateZ(0); +$hardwareAcc: null; + +// ---------------------------------------- +/** Increased click area for this element, helpful on mobile */ +@mixin IncreasedClickArea($size) { + &::after { + content: ""; + position: absolute; + top: #{D(-$size)}; + bottom: #{D(-$size)}; + left: #{D(-$size)}; + right: #{D(-$size)}; + // background: rgba(255, 0, 0, 0.3); + } +} +button, +.increasedClickArea { + position: relative; + @include IncreasedClickArea(15px); +} + +// ---------------------------------------- +/* Duplicates an animation and adds two classes .Even and .Odd which uses the + animation. This can be used to replay the animation by toggling between the classes, because + it is not possible to restart a css animation */ +@mixin MakeAnimationWrappedEvenOdd($duration, $classPrefix: "anim", $childSelector: "") { + $animName: autogen_anim_#{unique-id()}; + + @at-root { + @keyframes #{$animName}_even { + @content; + } + + @keyframes #{$animName}_odd { + @content; + } + } + + &.#{$classPrefix}Even #{$childSelector} { + animation: #{$animName}_even $duration; + } + + &.#{$classPrefix}Odd #{$childSelector} { + animation: #{$animName}_odd $duration; + } +} + +// ---------------------------------------- +/* Allows to use and define an animation without specifying its name */ +@mixin InlineAnimation($duration) { + $animName: autogen_anim_#{unique-id()}; + + @at-root { + @keyframes #{$animName} { + @content; + } + } + + animation: $animName $duration !important; +} + +// ---------------------------------------- +/* Animation prefab for a double bounce pop-in animation, useful for dialogs */ +@mixin DoubleBounceAnim($duration: 0.5s ease-in-out, $amount: 0.2, $initialOpacity: 0) { + @include InlineAnimation($duration) { + 0% { + opacity: $initialOpacity; + transform: scale(0) $hardwareAcc; + } + + 25% { + opacity: 0.5; + transform: scale(1 + $amount) $hardwareAcc; + } + + 50% { + opacity: 1; + transform: scale(1 - $amount * 0.5) $hardwareAcc; + } + + 75% { + transform: scale(1 + $amount * 0.25) $hardwareAcc; + } + + 100% { + transform: scale(1) $hardwareAcc; + } + } + + opacity: 1; +} + +// ---------------------------------------- +/* Define a style which is only applied in horizontal mode */ +@mixin HorizontalStyle { + @include AppendGlobal(".h") { + @content; + } +} + +// ---------------------------------------- +/* Define a style which is only applied in vertical mode */ +@mixin VerticalStyle { + @include AppendGlobal(".v") { + @content; + } +} + +// ---------------------------------------- +/* Define a style which is only while the hardware keyboard is open */ +@mixin AndroidHwKeyboardOpen { + @include AppendGlobal(".kb") { + @content; + } +} + +// ---------------------------------------- +/* Automatically transforms the game state if a hardware keyboard is open */ +@mixin TransformToMatchKeyboard { + transition: transform 0.2s ease-in-out; + @include AndroidHwKeyboardOpen { + @include VerticalStyle { + transform: translateY(#{D(-125px)}) $hardwareAcc; + } + @include HorizontalStyle { + transform: translateY(#{D(-100px)}) $hardwareAcc; + } + } +} + +// ---------------------------------------- +/* Define a style which is only applied when the viewport is at least X pixels wide */ +@mixin StyleAtWidth($minW) { + @media (min-width: #{$minW}) { + @content; + } +} + +// ---------------------------------------- +/* Define a style which is only applied when the viewport is at least X pixels height */ +@mixin StyleAtHeight($minH) { + @media (min-height: #{$minH}) { + @content; + } +} + +// ---------------------------------------- +/* Define a style which is only applied when the viewport has at least the given dimensions */ +@mixin StyleAtDims($minW, $minH) { + @media (min-height: #{$minH}) and (min-width: #{$minW}) { + @content; + } +} + +// ---------------------------------------- +/* Define a style which is only applied when the viewport has at maximum the given dimensions */ +@mixin StyleBelowDims($maxW, $maxH) { + @media (max-height: #{$maxH}) and (max-width: #{$maxW}) { + @content; + } +} + +// ---------------------------------------- +/* Define a style which is only applied when the viewport has at maximum the given height */ +@mixin StyleBelowHeight($maxH) { + @media (max-height: #{$maxH}) { + @content; + } +} +// ---------------------------------------- +/* Define a style which is only applied when the viewport has at maximum the given width */ +@mixin StyleBelowWidth($maxW) { + @media (max-width: #{$maxW}) { + @content; + } +} + +// ---------------------------------------- +// Dynamic graphics quality styles + +@mixin BoxShadow3D($bgColor, $size: 3px, $pressEffect: true) { + background-color: $bgColor; + + $borderSize: 1.5px; + $borderColor: rgb(18, 20, 24); + + // box-shadow: 0 0 0 D($borderSize) $borderColor, 0 D($size) 0 0px rgba(mix(darken($bgColor, 9), #b0e2ff, 95%), 1), + // 0 D($size) 0 D($borderSize) $borderColor; + + // box-shadow: 0 0 0 D($borderSize) $borderColor, 0 D($size) 0 D($borderSize) $borderColor, + // D(-$size * 1.5) D($size * 2) 0 D($borderSize) rgba(0, 0, 0, 0.1); + + // transition: box-shadow 0.1s ease-in-out; + + // @if $pressEffect { + // &.pressed { + // transform: none !important; + // $pSize: max(0, $size - 1.5px); + // transition: none !important; + // box-shadow: 0 0 0 D($borderSize) $borderColor, 0 D($pSize) 0 0px rgba(mix(darken($bgColor, 9), #b0e2ff, 95%), 1), + // 0 D($pSize) 0 D($borderSize) $borderColor; + // top: D($size - $pSize); + // } + // } +} + +@mixin BorderRadius($v1: 2px, $v2: "", $v3: "", $v4: "") { + @include S(border-radius, $v1, $v2, $v3, $v4); +} + +@mixin BoxShadow($x, $y, $blur, $offset, $color) { + box-shadow: D($x) D($y) D($blur) D($offset) $color; +} + +@mixin DropShadow($yOffset: 2px, $blur: 2px, $amount: 0.2) { + @include BoxShadow(0, $yOffset, $blur, 0, rgba(#000, $amount)); +} + +@mixin TextShadow($yOffset: 2px, $blur: 1px, $amount: 0.6) { + text-shadow: 0 D($yOffset) D($blur) rgba(#000, $amount); +} + +@mixin Button3D($bgColor, $pressEffect: true) { + @include BoxShadow3D($bgColor, 2px, $pressEffect); +} + +@mixin ButtonDisabled3D($bgColor) { + @include BoxShadow3D($bgColor, 0.5px, false); +} + +@mixin BoxShadowInset($bgColor, $size: 3px) { + background-color: $bgColor; + + $borderSize: 1px; + $borderColor: rgb(15, 19, 24); + box-shadow: 0 0 0 D($borderSize) $borderColor, 0 D($size) 0 rgba(#fff, 0.07); + border-top: D($size) solid rgba(#000, 0.1); + + //, 0 D($size) 0 0px rgba(mix(darken($bgColor, 9), #b0e2ff, 95%), 1), + // 0 D($size + $borderSize) 0 0 $borderColor; +} + +@mixin TextShadow3D($color: rgb(222, 234, 238), $borderColor: #000) { + // @if $borderColor != #000 { + // @include TextShadow3DImpl($color: $color, $borderColor: $borderColor); + // } + color: $color; +} + +@mixin TextShadow3DImpl( + $color: rgb(222, 234, 238), + $scale: 1, + $additionalShadowAlpha: 1, + $borderColor: #222428 +) { + // color: $text3dColor; + + $borderColor: rgba(15, 18, 23, 0.9); + + // $shadowColor: darken($color, 40%); + + $border: 0.07em; + $borderMid: $border * 1.14; + + $drop1: $borderMid + 0.02; + $drop2: $borderMid + 0.06em; + + // text-shadow: #{$border} #{$border} 0 $borderColor, #{-$border} #{$border} 0 $borderColor, #{$border} #{-$border} 0 $borderColor, + // #{-$border} #{-$border} 0 $borderColor, 0 #{$borderMid} 0 $borderColor, 0 #{-$borderMid} 0 $borderColor, + // #{$borderMid} 0 0 $borderColor, #{-$borderMid} 0 0 $borderColor, 0 #{$drop1} 0 $borderColor, #{$borderMid} #{$drop1} 0 $borderColor, + // #{-$borderMid} #{$drop1} 0 $borderColor, 0 #{$drop2} 0 $borderColor, #{$borderMid} #{$drop2} 0 $borderColor, + // #{-$borderMid} #{$drop2} 0 $borderColor, -0.2em 0.13em 0 rgba(#111, 0.25); // 0px 0.07em 0px $shadowColor, + // 0px 0.15em 0.09em rgba(#333539, $additionalShadowAlpha);; +} + +// ---------------------------------------- +/* Shine animation prefab, useful for buttons etc. Adds a bright shine which moves over + the button like a reflection. Performance heavy. */ +@mixin ShineAnimation($duration, $bgColor, $w: 200px, $shineAlpha: 0.25, $lightenAmount: 7, $bgAnim: true) { + $bgBase: darken($bgColor, 5); + background-color: $bgBase; + + @include HighQualityOrMore { + position: relative; + // overflow: hidden; + // overflow: visible; + + &:before { + content: " "; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: uiResource("misc/shine_bg.png") 0px center / 100% 100% no-repeat; + + @include InlineAnimation($duration ease-in-out infinite) { + 0% { + background-position-x: #{D(-$w)}; + } + 100% { + background-position-x: #{D($w)}; + } + } + } + + @if ($bgAnim) { + @include InlineAnimation($duration ease-in-out infinite) { + 0% { + background-color: $bgBase; + } + 50% { + background-color: lighten($bgBase, $lightenAmount); + } + 100% { + background-color: $bgBase; + } + } + } + } +} + +// ---------------------------------------- +/* String replacement */ +@function str-replace($string, $search, $replace: "") { + $index: str-index($string, $search); + + @if $index { + @return str-slice($string, 1, $index - 1) + $replace + + str-replace(str-slice($string, $index + str-length($search)), $search, $replace); + } + + @return $string; +} + +@mixin BounceInFromSide($mul, $duration: 0.18s ease-in-out) { + @include InlineAnimation($duration) { + 0% { + transform: translateY(#{D(-100px * $mul)}) scale(0.9); + opacity: 0; + } + + 100% { + opacity: 1; + transform: none; + } + } + opacity: 1; + transform: none; +} + +@mixin BreakText { + word-wrap: break-word; + word-break: break-all; + overflow-wrap: break-all; +} + +@mixin SupportsAndroidNotchQuery { + @supports (color: constant(--notch-inset-left)) { + @content; + } +} +@mixin SupportsiOsNotchQuery { + @supports (color: env(safe-area-inset-left, 0px)) { + @content; + } +} diff --git a/src/css/states/ingame.scss b/src/css/states/ingame.scss new file mode 100644 index 00000000..04e9383a --- /dev/null +++ b/src/css/states/ingame.scss @@ -0,0 +1,16 @@ +#state_InGameState { + .gameLoadingOverlay { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 9999; + align-items: center; + justify-content: center; + pointer-events: all; + display: flex; + background: $mainBgColor; + flex-direction: column; + } +} diff --git a/src/css/states/main_menu.scss b/src/css/states/main_menu.scss new file mode 100644 index 00000000..4e027a4d --- /dev/null +++ b/src/css/states/main_menu.scss @@ -0,0 +1,27 @@ +#state_MainMenuState { + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + + background: uiResource("menu_bg.noinline.jpg") center center / cover no-repeat !important; + + .logo { + img { + @include S(width, 350px); + } + } + + .mainContainer { + @include S(margin-top, 40px); + display: flex; + + .playButton { + @include SuperHeading; + @include S(width, 150px); + @include S(padding, 15px, 20px); + color: #fff; + background-color: $accentColorDark; + } + } +} diff --git a/src/css/states/preload.scss b/src/css/states/preload.scss new file mode 100644 index 00000000..25b13ead --- /dev/null +++ b/src/css/states/preload.scss @@ -0,0 +1,100 @@ +#state_PreloadState { + &.failure { + .loadingImage, + .loadingStatus { + display: none; + } + } + + .failureBox { + .logo { + img { + @include S(width, 240px); + } + + @include S(margin-bottom, 30px); + } + + @include InlineAnimation(0.3s ease-in-out) { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } + } + + .failureInner { + // background: darken($mainBgColor, 6); + @include S(max-width, 350px); + margin: 0 20px; + text-align: left; + + @include BoxShadow3D(#fff); + @include S(padding, 15px); + @include BorderRadius(4px); + @include DropShadow; + + .errorHeader { + color: #ef5072; + } + + .errorMessage { + @include PlainText; + display: block; + color: #666; + text-align: left; + @include BreakText; + hyphens: auto; + // border: dotted #666; + // @include S(border-width, 1px, 0); + @include S(padding, 10px, 0); + @include S(margin-top, 10px); + } + + .supportHelp { + @include S(margin-top, 10px); + @include PlainText; + + .email { + color: $themeColor; + cursor: pointer; + pointer-events: all; + } + } + + .lower { + display: flex; + align-items: center; + @include S(margin-top, 16px); + + i { + flex-grow: 1; + text-align: right; + color: #777; + @include PlainText; + } + + button.resetApp { + @include Button3D($colorRedBright); + @include PlainText; + @include S(padding, 5px, 8px, 4px); + } + } + } + } + + /* Animations */ + .status { + transform: scale(0.7) $hardwareAcc; + opacity: 0; + @include StateAnim(transform, opacity); + } + + &.arrived { + .status { + opacity: 1; + transform: none; + } + } +} diff --git a/src/css/textual_game_state.scss b/src/css/textual_game_state.scss new file mode 100644 index 00000000..27cd27ba --- /dev/null +++ b/src/css/textual_game_state.scss @@ -0,0 +1,267 @@ +.gameState.textualState { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + $padding: 15px; + + .bottomPoppingInNotification { + position: absolute; + left: 50%; + text-align: center; + @include BoxShadow3D(mix(lighten($mainBgColor, 12), $colorRedBright, 50%)); + @include S(padding, 10px); + max-width: #{D(280px)}; + @include S(bottom, 30px); + box-sizing: border-box; + width: 100%; + @include PlainText; + @include BorderRadius(4px); + + $baseTransform: translateX(-50%); + transform-origin: 0% 100%; + transform: translateY(500%); + opacity: 0; + + display: block; + @include InlineAnimation(5s ease-in-out) { + 0% { + opacity: 0; + transform: scale(0) skew(5deg, 5deg) translateY(100%) $baseTransform; + } + 8% { + transform: scale(1.05) translateY(-2%) $baseTransform; + } + 12% { + transform: scale(1) $baseTransform; + opacity: 1; + } + 97% { + transform: scale(1) $baseTransform; + opacity: 1; + } + 100% { + opacity: 0; + transform: scale(0) skew(5deg, 5deg) translateY(100%) $baseTransform; + } + } + } + + .widthKeeper { + width: 100%; + height: 100%; + + display: flex; + flex-direction: column; + overflow: hidden; + + box-sizing: content-box; + @include S(max-width, 1000px); + + @include StyleAtHeight(800px) { + @include S(padding-top, 30px); + } + + .headerBar { + display: flex; + + @include VerticalStyle { + // margin-top: 1px; + } + + // margin-bottom: 15px; + padding: $padding; + + $h: 25px; + @include S(min-height, $h); + @include S(max-height, $h); + + align-items: center; + justify-content: center; + position: relative; + z-index: 50; + background: transparent; + + @include S(padding-top, $padding); + @include S(padding-left, $padding); + @include S(padding-right, $padding); + background-size: calc(100% - #{D(6px)}) 100%; + $paddingBottom: 20px; + + @include S(padding-bottom, $paddingBottom); + @include S(margin-bottom, -$h - $padding - $paddingBottom); + + h1 { + // text-align: center; + cursor: pointer; + // transform-origin: 0px 50%; + pointer-events: all; + @include S(padding, 5px, 0px, 5px, 30px); + @include S(left, -2px); + @include S(min-width, 100px); + position: relative; + @include IncreasedClickArea(25px); + text-transform: uppercase; + // background: uiResource("back_arrow.png") center center no-repeat; + @include S(background-position-x, -3px); + @include S(background-size, 25px, 25px); + + // Due to back button + color: $text3dColor; + @include TextShadow3D($borderColor: #18151d); + @include SuperHeading; + @include StyleBelowWidth(380px) { + @include Heading; + } + } + + .grow { + flex-grow: 1; + } + } + + .container { + text-align: left; + flex-direction: column; + pointer-events: all; + box-sizing: border-box; + z-index: 25; + position: relative; + + @include S(padding-left, 0px); + @include S(padding-right, 0px); + + height: 100%; + @include SupportsAndroidNotchQuery { + height: calc( + 100% - constant(safe-area-inset-top) - constant(safe-area-inset-bottom) - + var(--notch-inset-top) - var(--notch-inset-bottom) + ); + } + @include SupportsiOsNotchQuery { + height: calc( + 100% - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px) - + var(--notch-inset-top) - var(--notch-inset-bottom) + ); + } + + .loadingIndicator { + display: none; + } + + .errorIndicator { + display: none; + flex-direction: column; + text-align: center; + + .errorInner { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + @include S(max-width, 350px); + + strong { + $col: #ff4564; + @include TextShadow3D($col); + @include Heading; + } + + i { + @include PlainText; + color: #888; + @include S(margin-top, 10px); + display: inline-block; + } + } + } + + .loadingIndicator, + .errorIndicator { + box-sizing: border-box; + justify-content: center; + align-items: center; + height: 100%; + @include S(padding, 30px); + } + + // Loading state + &.loading { + .mainContent { + animation: none; + display: none !important; + } + .loadingIndicator { + display: flex; + } + } + + // Error state + &.errored { + .mainContent { + animation: none; + display: none !important; + } + + .errorIndicator { + animation: none; + display: flex; + } + } + } + + .mainContent { + overflow-y: auto !important; + overflow-x: hidden; + @include S(padding, $padding); + height: 100%; + width: 100%; + box-sizing: border-box; + + @include InlineAnimation(0.4s ease-in-out) { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } + } + + .category_label { + display: block; + @include S(margin-top, 40px); + + text-transform: uppercase; + &:first-child { + margin-top: 0 !important; + } + + @include S(margin-bottom, 16px); + @include Heading; + + @include TextShadow3D(#68a1bb, $borderColor: #141718); + } + + .cardbox { + @include S(padding, 20px, 15px); + $cardBg: lighten($mainBgColor, 9); + background: $cardBg; + margin-bottom: 15px; + @include S(margin-bottom, 15px); + @include BorderRadius(4px); + @include S(padding-bottom, 14px); + @include BoxShadow3D($cardBg); + + &:last-child { + border-bottom: 0; + } + } + } + } + + &.hasTitle { + .mainContent { + @include S(padding-top, 70px, $important: true); + } + } +} diff --git a/src/css/trigonometry.scss b/src/css/trigonometry.scss new file mode 100644 index 00000000..97d2e730 --- /dev/null +++ b/src/css/trigonometry.scss @@ -0,0 +1,66 @@ +/////////////////////////////////////////////////////////// +// Plain SASS Trigonometry Algorithm in Taylor Expansion // +// // +// Based on // +// http://japborst.net/posts/sass-sines-and-cosines // +/////////////////////////////////////////////////////////// + +$pi: 3.14159265359; +$_precision: 10; + +@function pow($base, $exp) { + $value: $base; + @if $exp > 1 { + @for $i from 2 through $exp { + $value: $value * $base; + } + } + @if $exp < 1 { + @for $i from 0 through -$exp { + $value: $value / $base; + } + } + @return $value; +} + +@function fact($num) { + $fact: 1; + @if $num > 0 { + @for $i from 1 through $num { + $fact: $fact * $i; + } + } + @return $fact; +} + +@function _to_unitless_rad($angle) { + @if unit($angle) == "deg" { + $angle: $angle / 180deg * $pi; + } + @if unit($angle) == "rad" { + $angle: $angle / 1rad; + } + @return $angle; +} + +@function sin($angle) { + $a: _to_unitless_rad($angle); + $sin: $a; + @for $n from 1 through $_precision { + $sin: $sin + (pow(-1, $n) / fact(2 * $n + 1)) * pow($a, (2 * $n + 1)); + } + @return $sin; +} + +@function cos($angle) { + $a: _to_unitless_rad($angle); + $cos: 1; + @for $n from 1 through $_precision { + $cos: $cos + (pow(-1, $n) / fact(2 * $n)) * pow($a, 2 * $n); + } + @return $cos; +} + +@function tan($angle) { + @return sin($angle) / cos($angle); +} diff --git a/src/css/variables.scss b/src/css/variables.scss new file mode 100644 index 00000000..392393d6 --- /dev/null +++ b/src/css/variables.scss @@ -0,0 +1,195 @@ +// When to reduce control elements size for small devices +$layoutExpandMinWidth: 340px; + +// Font sizes and line heights +$superHeadingFontSize: 25px; +$superHeadingLineHeight: 24px; + +$breakTooltipShowStatsPx: 1023px; + +$headingFontSize: 19px; +$headingLineHeight: 21px; + +$textFontSize: 16px; +$textLineHeight: 21px; + +$plainTextFontSize: 13px; +$plainTextLineHeight: 17px; + +$supersmallTextFontSize: 10px; +$supersmallTextLineHeight: 13px; + +$buttonFontSize: 14px; +$buttonLineHeight: 18px; + +// Main background color +$mainBgColor: #dee1ea; + +// Accent colors + +$accentColorBright: #e1e4ed; +$accentColorDark: #7d808a; +$colorGreenBright: #66bb6a; +$colorRedBright: #ef5072; +$themeColor: #393747; +$ingameHudBg: rgba($accentColorBright, 0.9); +$ingameHudBorder: #{D(1.5px)} solid $accentColorDark; + +$text3dColor: #f4ffff; + +// Dialog properties +$modalDialogBg: rgba(#666a73, 0.8); +$dialogBgColor: lighten($mainBgColor, 10); + +$lightFontWeight: normal; +$boldFontWeight: 600; + +$iconSizeSmall: 30px; +$iconSizeMedium: 40px; +$iconSizeLarge: 60px; + +// Poppins 500 +// Rubik 400 +// Cairo 400 +// Viga 400 +// Sniglet 400 + +$mainFont: "GameFont", sans-serif; +// $mainFont: "DK Canoodle"; +// $mainFont: "MADE Florence Sans"; +$numberFont: $mainFont; +$textFont: $mainFont; + +$mainFontWeight: 400; +$mainFontSpacing: 0.04em; +$mainFontScale: 1; + +@mixin DebugText($color) { + // font-size: 3px; + // &, + // * { + // color: $color !important; + // } +} + +@mixin SuperSmallText { + @include ScaleFont($supersmallTextFontSize, $supersmallTextLineHeight); + font-weight: $mainFontWeight; + font-family: $mainFont; + letter-spacing: $mainFontSpacing; + @include DebugText(green); +} + +@mixin PlainText { + @include ScaleFont($plainTextFontSize, $plainTextLineHeight); + font-weight: $mainFontWeight; + font-family: $mainFont; + letter-spacing: $mainFontSpacing; + + @include DebugText(red); +} + +@mixin Text { + @include ScaleFont($textFontSize, $textLineHeight); + font-weight: $mainFontWeight; + font-family: $mainFont; + + letter-spacing: $mainFontSpacing; + + @include DebugText(blue); +} + +@mixin Heading { + @include ScaleFont($headingFontSize, $headingLineHeight); + font-weight: $mainFontWeight; + font-family: $mainFont; + letter-spacing: $mainFontSpacing; + + @include DebugText(yellow); +} + +@mixin SuperHeading { + @include ScaleFont($superHeadingFontSize, $superHeadingLineHeight); + font-weight: $mainFontWeight; + font-family: $mainFont; + letter-spacing: $mainFontSpacing; + + @include DebugText(orange); +} + +@mixin ButtonText { + @include ScaleFont($buttonFontSize, $buttonLineHeight); + font-weight: $mainFontWeight; + font-family: $mainFont; + letter-spacing: $mainFontSpacing; + @include DebugText(purple); +} + +@function str-split($string, $separator) { + // empty array/list + $split-arr: (); + // first index of separator in string + $index: str-index($string, $separator); + // loop through string + @while $index != null { + // get the substring from the first character to the separator + $item: str-slice($string, 1, $index - 1); + // push item to array + $split-arr: append($split-arr, $item); + // remove item and separator from string + $string: str-slice($string, $index + 1); + // find new index of separator + $index: str-index($string, $separator); + } + // add the remaining string to list (the last item) + $split-arr: append($split-arr, $string); + + @return $split-arr; +} + +@function _first-index($string, $direction: "left") { + @for $i from 1 through str-length($string) { + $index: if($direction == "left", $i, -$i); + + @if str-slice($string, $index, $index) != " " { + @return $index; + } + } + + @return 0; +} + +@function trim($string) { + @return str-slice($string, _first-index($string, "left"), _first-index($string, "right")); +} + +@mixin AppendGlobal($prefix) { + $strSelector: quote(&); + $selectors: str-split($strSelector, ","); + + $builtSelector: null; + + @if (& == null) { + $builtSelector: "html" + $prefix; + } @else { + $builtSelector: (); + // @debug ($strSelector, "->>>", $selectors); + @each $srcSelector in $selectors { + $srcSelector: trim($srcSelector); + // @debug ("___", $srcSelector); + $selector: "html" + $prefix + " " + $srcSelector; + @if str-index($srcSelector, "html.") { + $selector: "html" + + $prefix + + "." + + str-slice($srcSelector, str-index($srcSelector, "html.") + 5); + } + // @debug ("_______", $selector); + $builtSelector: append($builtSelector, $selector, comma); + } + } + + @at-root #{$builtSelector} { + @content; + } +} diff --git a/src/html/index.html b/src/html/index.html new file mode 100644 index 00000000..1d4553c0 --- /dev/null +++ b/src/html/index.html @@ -0,0 +1,43 @@ + + + + shapez.io + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/js/application.js b/src/js/application.js new file mode 100644 index 00000000..75d47ab0 --- /dev/null +++ b/src/js/application.js @@ -0,0 +1,362 @@ +import { AnimationFrame } from "./core/animation_frame"; +import { performanceNow } from "./core/builtins"; +import { GameState } from "./core/game_state"; +import { GLOBAL_APP, setGlobalApp } from "./core/globals"; +import { InputDistributor } from "./core/input_distributor"; +import { StateManager } from "./core/state_manager"; +import { getPlatformName, waitNextFrame } from "./core/utils"; +import { SavegameManager } from "./savegame/savegame_manager"; +import { AdProviderInterface } from "./platform/ad_provider"; +import { NoAdProvider } from "./platform/ad_providers/no_ad_provider"; +import { SoundImplBrowser } from "./platform/browser/sound"; +import { StorageImplBrowser } from "./platform/browser/storage"; +import { PlatformWrapperImplBrowser } from "./platform/browser/wrapper"; +import { SoundInterface } from "./platform/sound"; +import { StorageInterface } from "./platform/storage"; +import { PlatformWrapperInterface } from "./platform/wrapper"; +import { ApplicationSettings } from "./profile/application_settings"; +import { Vector } from "./core/vector"; +import { createLogger, logSection } from "./core/logging"; +import { TrackedState } from "./core/tracked_state"; +import { IS_MOBILE } from "./core/config"; +import { BackgroundResourcesLoader } from "./core/background_resources_loader"; +import { PreloadState } from "./states/preload"; +import { MainMenuState } from "./states/main_menu"; +import { InGameState } from "./states/ingame"; +import { AnalyticsInterface } from "./platform/analytics"; +import { GoogleAnalyticsImpl } from "./platform/browser/google_analytics"; +import { Loader } from "./core/loader"; +import { GameAnalyticsInterface } from "./platform/game_analytics"; +import { GameAnalyticsDotCom } from "./platform/browser/game_analytics"; + +const logger = createLogger("application"); + +// Set the name of the hidden property and the change event for visibility +let pageHiddenPropName, pageVisibilityEventName; +if (typeof document.hidden !== "undefined") { + // Opera 12.10 and Firefox 18 and later support + pageHiddenPropName = "hidden"; + pageVisibilityEventName = "visibilitychange"; + // @ts-ignore +} else if (typeof document.msHidden !== "undefined") { + pageHiddenPropName = "msHidden"; + pageVisibilityEventName = "msvisibilitychange"; + // @ts-ignore +} else if (typeof document.webkitHidden !== "undefined") { + pageHiddenPropName = "webkitHidden"; + pageVisibilityEventName = "webkitvisibilitychange"; +} + +export class Application { + constructor() { + assert(!GLOBAL_APP, "Tried to construct application twice"); + logger.log("Creating application, platform =", getPlatformName()); + setGlobalApp(this); + + this.unloaded = false; + + // Global stuff + this.settings = new ApplicationSettings(this); + this.ticker = new AnimationFrame(); + this.stateMgr = new StateManager(this); + this.savegameMgr = new SavegameManager(this); + this.inputMgr = new InputDistributor(this); + this.backgroundResourceLoader = new BackgroundResourcesLoader(this); + + // Platform dependent stuff + + /** @type {StorageInterface} */ + this.storage = null; + + /** @type {SoundInterface} */ + this.sound = null; + + /** @type {PlatformWrapperInterface} */ + this.platformWrapper = null; + + /** @type {AdProviderInterface} */ + this.adProvider = null; + + /** @type {AnalyticsInterface} */ + this.analytics = null; + + /** @type {GameAnalyticsInterface} */ + this.gameAnalytics = null; + + this.initPlatformDependentInstances(); + + // Track if the window is focused (only relevant for browser) + this.focused = true; + + // Track if the window is visible + this.pageVisible = true; + + // Track if the app is paused (cordova) + this.applicationPaused = false; + + /** @type {TypedTrackedState} */ + this.trackedIsRenderable = new TrackedState(this.onAppRenderableStateChanged, this); + + // Dimensions + this.screenWidth = 0; + this.screenHeight = 0; + + // Store the timestamp where we last checked for a screen resize, since orientationchange is unreliable with cordova + this.lastResizeCheck = null; + + // Store the mouse position, or null if not available + /** @type {Vector|null} */ + this.mousePosition = null; + } + + /** + * Initializes all platform instances + */ + initPlatformDependentInstances() { + logger.log("Creating platform dependent instances"); + + // Start with empty ad provider + this.adProvider = new NoAdProvider(this); + this.storage = new StorageImplBrowser(this); + this.sound = new SoundImplBrowser(this); + this.platformWrapper = new PlatformWrapperImplBrowser(this); + this.analytics = new GoogleAnalyticsImpl(this); + this.gameAnalytics = new GameAnalyticsDotCom(this); + } + + /** + * Registers all game states + */ + registerStates() { + /** @type {Array} */ + const states = [PreloadState, MainMenuState, InGameState]; + + for (let i = 0; i < states.length; ++i) { + this.stateMgr.register(states[i]); + } + } + + /** + * Registers all event listeners + */ + registerEventListeners() { + window.addEventListener("focus", this.onFocus.bind(this)); + window.addEventListener("blur", this.onBlur.bind(this)); + + window.addEventListener("resize", () => this.checkResize(), true); + window.addEventListener("orientationchange", () => this.checkResize(), true); + + if (!G_IS_MOBILE_APP && !IS_MOBILE) { + window.addEventListener("mousemove", this.handleMousemove.bind(this)); + } + + // Unload events + window.addEventListener("beforeunload", this.onBeforeUnload.bind(this), true); + window.addEventListener("unload", this.onUnload.bind(this), true); + + document.addEventListener(pageVisibilityEventName, this.handleVisibilityChange.bind(this), false); + + // Track touches so we can update the focus appropriately + document.addEventListener("touchstart", this.updateFocusAfterUserInteraction.bind(this), true); + document.addEventListener("touchend", this.updateFocusAfterUserInteraction.bind(this), true); + } + + /** + * Checks the focus after a touch + * @param {TouchEvent} event + */ + updateFocusAfterUserInteraction(event) { + const target = /** @type {HTMLElement} */ (event.target); + if (!target || !target.tagName) { + // Safety check + logger.warn("Invalid touchstart/touchend event:", event); + return; + } + + // When clicking an element which is not the currently focused one, defocus it + if (target !== document.activeElement) { + // @ts-ignore + if (document.activeElement.blur) { + // @ts-ignore + document.activeElement.blur(); + } + } + + // If we click an input field, focus it now + if (target.tagName.toLowerCase() === "input") { + // We *really* need the focus + waitNextFrame().then(() => target.focus()); + } + } + + /** + * Handles a page visibility change event + * @param {Event} event + */ + handleVisibilityChange(event) { + const pageVisible = !document[pageHiddenPropName]; + if (pageVisible !== this.pageVisible) { + this.pageVisible = pageVisible; + logger.log("Visibility changed:", this.pageVisible); + this.trackedIsRenderable.set(this.isRenderable()); + } + } + + /** + * Handles a mouse move event + * @param {MouseEvent} event + */ + handleMousemove(event) { + this.mousePosition = new Vector(event.clientX, event.clientY); + } + + /** + * Internal on focus handler + */ + onFocus() { + this.focused = true; + } + + /** + * Internal blur handler + */ + onBlur() { + this.focused = false; + } + + /** + * Returns if the app is currently visible + */ + isRenderable() { + return !this.applicationPaused && this.pageVisible; + } + + onAppRenderableStateChanged(renderable) { + logger.log("Application renderable:", renderable); + if (!renderable) { + this.stateMgr.getCurrentState().onAppPause(); + } else { + // Got resume + this.stateMgr.getCurrentState().onAppResume(); + this.checkResize(); + } + + this.sound.onPageRenderableStateChanged(renderable); + } + + /** + * Internal unload handler + */ + onUnload(event) { + if (!this.unloaded) { + logSection("UNLOAD HANDLER", "#f77"); + this.unloaded = true; + this.stateMgr.getCurrentState().onBeforeExit(); + this.deinitialize(); + } + } + + /** + * Internal before-unload handler + */ + onBeforeUnload(event) { + logSection("BEFORE UNLOAD HANDLER", "#f77"); + + if (!G_IS_DEV && this.stateMgr.getCurrentState().getHasUnloadConfirmation()) { + if (G_IS_STANDALONE) { + } else { + // Need to show a "Are you sure you want to exit" + event.preventDefault(); + event.returnValue = "Are you sure you want to exit?"; + } + } + } + + /** + * Boots the application + */ + boot() { + this.registerStates(); + this.registerEventListeners(); + + Loader.linkAppAfterBoot(this); + + this.stateMgr.moveToState("PreloadState"); + + // Starting rendering + this.ticker.frameEmitted.add(this.onFrameEmitted, this); + this.ticker.bgFrameEmitted.add(this.onBackgroundFrame, this); + this.ticker.start(); + } + + /** + * Deinitializes the application + */ + deinitialize() { + return this.sound.deinitialize(); + } + + /** + * Background frame update callback + * @param {number} dt + */ + onBackgroundFrame(dt) { + if (this.isRenderable()) { + return; + } + + this.stateMgr.getCurrentState().onBackgroundTick(dt); + } + + /** + * Frame update callback + * @param {number} dt + */ + onFrameEmitted(dt) { + if (!this.isRenderable()) { + return; + } + + const time = performanceNow(); + + // Periodically check for resizes, this is expensive (takes 2-3ms so only do it once in a while!) + if (!this.lastResizeCheck || time - this.lastResizeCheck > 1000) { + this.checkResize(); + this.lastResizeCheck = time; + } + + this.stateMgr.getCurrentState().onRender(dt); + } + + /** + * Checks if the app resized. Only does this once in a while + * @param {boolean} forceUpdate Forced update of the dimensions + */ + checkResize(forceUpdate = false) { + const w = window.innerWidth; + const h = window.innerHeight; + if (this.screenWidth !== w || this.screenHeight !== h || forceUpdate) { + this.screenWidth = w; + this.screenHeight = h; + this.stateMgr.getCurrentState().onResized(this.screenWidth, this.screenHeight); + + const scale = this.getEffectiveUiScale(); + waitNextFrame().then(() => document.documentElement.style.setProperty("--ui-scale", scale)); + window.focus(); + } + } + + /** + * Returns the effective ui sclae + */ + getEffectiveUiScale() { + return this.platformWrapper.getUiScale() * this.settings.getInterfaceScaleValue(); + } + + /** + * Callback after ui scale has changed + */ + updateAfterUiScaleChanged() { + this.checkResize(true); + } +} diff --git a/src/js/core/animation_frame.js b/src/js/core/animation_frame.js new file mode 100644 index 00000000..b7243af7 --- /dev/null +++ b/src/js/core/animation_frame.js @@ -0,0 +1,71 @@ +import { Signal } from "./signal"; + +// @ts-ignore +import BackgroundAnimationFrameEmitterWorker from "../webworkers/background_animation_frame_emittter.worker"; + +import { createLogger } from "./logging"; +import { performanceNow } from "./builtins"; + +const logger = createLogger("animation_frame"); + +const maxDtMs = 1000; +const resetDtMs = 16; + +export class AnimationFrame { + constructor() { + this.frameEmitted = new Signal(); + this.bgFrameEmitted = new Signal(); + + this.lastTime = null; + this.bgLastTime = null; + + this.boundMethod = this.handleAnimationFrame.bind(this); + + /** @type {Worker} */ + this.backgroundWorker = new BackgroundAnimationFrameEmitterWorker(); + this.backgroundWorker.addEventListener("error", err => { + logger.error("Error in background fps worker:", err); + }); + this.backgroundWorker.addEventListener("message", this.handleBackgroundTick.bind(this)); + } + + /** + * + * @param {MessageEvent} event + */ + handleBackgroundTick(event) { + const time = performanceNow(); + if (!this.bgLastTime) { + // First update, first delta is always 16ms + this.bgFrameEmitted.dispatch(1000 / 60); + } else { + let dt = time - this.bgLastTime; + if (dt > maxDtMs) { + dt = resetDtMs; + } + this.bgFrameEmitted.dispatch(dt); + } + this.bgLastTime = time; + } + + start() { + assertAlways(window.requestAnimationFrame, "requestAnimationFrame is not supported!"); + this.handleAnimationFrame(); + } + + handleAnimationFrame(time) { + if (!this.lastTime) { + // First update, first delta is always 16ms + this.frameEmitted.dispatch(1000 / 60); + } else { + let dt = time - this.lastTime; + if (dt > maxDtMs) { + // warn(this, "Clamping", dt, "to", resetDtMs); + dt = resetDtMs; + } + this.frameEmitted.dispatch(dt); + } + this.lastTime = time; + window.requestAnimationFrame(this.boundMethod); + } +} diff --git a/src/js/core/assert.js b/src/js/core/assert.js new file mode 100644 index 00000000..2d15660d --- /dev/null +++ b/src/js/core/assert.js @@ -0,0 +1,26 @@ +import { createLogger } from "./logging"; + +const logger = createLogger("assert"); + +let assertionErrorShown = false; + +function initAssert() { + /** + * Expects a given condition to be true + * @param {Boolean} condition + * @param {...String} failureMessage + */ + // @ts-ignore + window.assert = function (condition, ...failureMessage) { + if (!condition) { + logger.error("assertion failed:", ...failureMessage); + if (!assertionErrorShown) { + // alert("Assertion failed (the game will try to continue to run): \n\n" + failureMessage); + assertionErrorShown = true; + } + throw new Error("AssertionError: " + failureMessage.join(" ")); + } + }; +} + +initAssert(); diff --git a/src/js/core/async_compression.js b/src/js/core/async_compression.js new file mode 100644 index 00000000..479ee80b --- /dev/null +++ b/src/js/core/async_compression.js @@ -0,0 +1,143 @@ +// @ts-ignore +import CompressionWorker from "../webworkers/compression.worker"; +import { createLogger } from "./logging"; +import { compressX64 } from "./lzstring"; +import { performanceNow, JSON_stringify } from "./builtins"; + +const logger = createLogger("async_compression"); + +export let compressionPrefix = String.fromCodePoint(1); + +function checkCryptPrefix(prefix) { + try { + window.localStorage.setItem("prefix_test", prefix); + window.localStorage.removeItem("prefix_test"); + return true; + } catch (ex) { + logger.warn("Prefix '" + prefix + "' not available"); + return false; + } +} + +if (!checkCryptPrefix(compressionPrefix)) { + logger.warn("Switching to basic prefix"); + compressionPrefix = " "; + if (!checkCryptPrefix(compressionPrefix)) { + logger.warn("Prefix not available, ls seems to be unavailable"); + } +} + +/** + * @typedef {{ + * errorHandler: function(any) : void, + * resolver: function(any) : void, + * startTime: number + * }} JobEntry + */ + +class AsynCompression { + constructor() { + /** @type {Worker} */ + this.worker = new CompressionWorker(); + + this.currentJobId = 1000; + + /** @type {Object.} */ + this.currentJobs = {}; + + this.worker.addEventListener("message", event => { + const { jobId, result } = event.data; + const jobData = this.currentJobs[jobId]; + if (!jobData) { + logger.error("Failed to resolve job result, job id", jobId, "is not known"); + return; + } + + const duration = performanceNow() - jobData.startTime; + // log(this, "Got response from worker within", duration.toFixed(2), "ms"); + const resolver = jobData.resolver; + delete this.currentJobs[jobId]; + resolver(result); + }); + + this.worker.addEventListener("error", err => { + logger.error("Got error from webworker:", err, "aborting all jobs"); + const failureCalls = []; + for (const jobId in this.currentJobs) { + failureCalls.push(this.currentJobs[jobId].errorHandler); + } + this.currentJobs = {}; + for (let i = 0; i < failureCalls.length; ++i) { + failureCalls[i](err); + } + }); + } + + /** + * Compresses file + * @param {string} text + */ + compressFileAsync(text) { + return this.internalQueueJob("compressFile", { + text, + compressionPrefix, + }); + } + + /** + * Compresses regulary + * @param {string} text + */ + compressX64Async(text) { + if (text.length < 1024) { + // Ok so this is not worth it + return Promise.resolve(compressX64(text)); + } + return this.internalQueueJob("compressX64", text); + } + + /** + * Compresses with checksum + * @param {any} obj + */ + compressWithChecksum(obj) { + const stringified = JSON_stringify(obj); + return this.internalQueueJob("compressWithChecksum", stringified); + } + + /** + * Compresses with checksum + * @param {any} data The packets data + * @param {number} packetId The numeric packet id + */ + compressPacket(data, packetId) { + return this.internalQueueJob("compressPacket", { + data, + packetId, + }); + } + + /** + * Queues a new job + * @param {string} job + * @param {any} data + * @returns {Promise} + */ + internalQueueJob(job, data) { + const jobId = ++this.currentJobId; + return new Promise((resolve, reject) => { + const errorHandler = err => { + logger.error("Failed to compress job", jobId, ":", err); + reject(err); + }; + this.currentJobs[jobId] = { + errorHandler, + resolver: resolve, + startTime: performanceNow(), + }; + this.worker.postMessage({ jobId, job, data }); + }); + } +} + +export const asyncCompressor = new AsynCompression(); diff --git a/src/js/core/atlas_definitions.js b/src/js/core/atlas_definitions.js new file mode 100644 index 00000000..043b3996 --- /dev/null +++ b/src/js/core/atlas_definitions.js @@ -0,0 +1,38 @@ +/** + * @typedef {{ + * frame: { x: number, y: number, w: number, h: number }, + * rotated: false, + * spriteSourceSize: { x: number, y: number, w: number, h: number }, + * sourceSize: { w: number, h: number}, + * trimmed: true + * }} SpriteDefinition + */ + +export class AtlasDefinition { + constructor(sourceData) { + this.sourceFileName = sourceData.meta.image; + this.meta = sourceData.meta; + + /** @type {Object.} */ + this.sourceData = sourceData.frames; + } + + getFullSourcePath() { + return this.sourceFileName; + } +} + +// @ts-ignore +export const atlasFiles = require + .context("../../../res_built/atlas/", false, /.*\.json/i) + .keys() + .map(f => f.replace(/^\.\//gi, "")) + .map(f => require("../../../res_built/atlas/" + f)) + .map(data => new AtlasDefinition(data)); + +// export const atlasDefinitions = { +// qualityPreload: atlasFiles.filter((atlas) => atlas.meta.image.indexOf("_preload") >= 0), +// qualityLow: atlasFiles.filter((atlas) => atlas.meta.image.indexOf("_low") >= 0), +// qualityMedium: atlasFiles.filter((atlas) => atlas.meta.image.indexOf("_medium") >= 0), +// qualityHigh: atlasFiles.filter((atlas) => atlas.meta.image.indexOf("_high") >= 0), +// }; diff --git a/src/js/core/background_resources_loader.js b/src/js/core/background_resources_loader.js new file mode 100644 index 00000000..44bb598e --- /dev/null +++ b/src/js/core/background_resources_loader.js @@ -0,0 +1,216 @@ +/* typehints:start */ +import { Application } from "../application"; +/* typehints:end */ + +import { Loader } from "./loader"; +import { createLogger } from "./logging"; +import { Signal } from "./signal"; +import { SOUNDS, MUSIC } from "../platform/sound"; +import { AtlasDefinition, atlasFiles } from "./atlas_definitions"; + +const logger = createLogger("background_loader"); + +const essentialMainMenuSprites = ["logo.png", ...G_ALL_UI_IMAGES.filter(src => src.startsWith("ui/"))]; +const essentialMainMenuSounds = [ + SOUNDS.uiClick, + SOUNDS.uiError, + SOUNDS.dialogError, + SOUNDS.dialogOk, + SOUNDS.swishShow, + SOUNDS.swishHide, +]; + +const essentialBareGameAtlases = atlasFiles; +const essentialBareGameSprites = G_ALL_UI_IMAGES; +const essentialBareGameSounds = [MUSIC.gameBg]; + +const additionalGameSprites = []; +const additionalGameSounds = []; +for (const key in SOUNDS) { + additionalGameSounds.push(SOUNDS[key]); +} +for (const key in MUSIC) { + additionalGameSounds.push(MUSIC[key]); +} + +export class BackgroundResourcesLoader { + /** + * + * @param {Application} app + */ + constructor(app) { + this.app = app; + + this.registerReady = false; + this.mainMenuReady = false; + this.bareGameReady = false; + this.additionalReady = false; + + this.signalMainMenuLoaded = new Signal(); + this.signalBareGameLoaded = new Signal(); + this.signalAdditionalLoaded = new Signal(); + + this.numAssetsLoaded = 0; + this.numAssetsToLoadTotal = 0; + + // Avoid loading stuff twice + this.spritesLoaded = []; + this.soundsLoaded = []; + } + + getNumAssetsLoaded() { + return this.numAssetsLoaded; + } + + getNumAssetsTotal() { + return this.numAssetsToLoadTotal; + } + + getPromiseForMainMenu() { + if (this.mainMenuReady) { + return Promise.resolve(); + } + + return new Promise(resolve => { + this.signalMainMenuLoaded.add(resolve); + }); + } + + getPromiseForBareGame() { + if (this.bareGameReady) { + return Promise.resolve(); + } + + return new Promise(resolve => { + this.signalBareGameLoaded.add(resolve); + }); + } + + startLoading() { + this.internalStartLoadingEssentialsForMainMenu(); + } + + internalStartLoadingEssentialsForMainMenu() { + logger.log("⏰ Start load: main menu"); + this.internalLoadSpritesAndSounds(essentialMainMenuSprites, essentialMainMenuSounds) + .catch(err => { + logger.warn("⏰ Failed to load essentials for main menu:", err); + }) + .then(() => { + logger.log("⏰ Finish load: main menu"); + this.mainMenuReady = true; + this.signalMainMenuLoaded.dispatch(); + this.internalStartLoadingEssentialsForBareGame(); + }); + } + + internalStartLoadingEssentialsForBareGame() { + logger.log("⏰ Start load: bare game"); + this.internalLoadSpritesAndSounds( + essentialBareGameSprites, + essentialBareGameSounds, + essentialBareGameAtlases + ) + .catch(err => { + logger.warn("⏰ Failed to load essentials for bare game:", err); + }) + .then(() => { + logger.log("⏰ Finish load: bare game"); + Loader.createAtlasLinks(); + this.bareGameReady = true; + this.signalBareGameLoaded.dispatch(); + this.internalStartLoadingAdditionalGameAssets(); + }); + } + + internalStartLoadingAdditionalGameAssets() { + const additionalAtlases = []; + logger.log("⏰ Start load: additional assets (", additionalAtlases.length, "images)"); + this.internalLoadSpritesAndSounds(additionalGameSprites, additionalGameSounds, additionalAtlases) + .catch(err => { + logger.warn("⏰ Failed to load additional assets:", err); + }) + .then(() => { + logger.log("⏰ Finish load: additional assets"); + this.additionalReady = true; + this.signalAdditionalLoaded.dispatch(); + }); + } + + /** + * @param {Array} sprites + * @param {Array} sounds + * @param {Array} atlases + * @returns {Promise} + */ + internalLoadSpritesAndSounds(sprites, sounds, atlases = []) { + this.numAssetsToLoadTotal = sprites.length + sounds.length + atlases.length; + this.numAssetsLoaded = 0; + + let promises = []; + + for (let i = 0; i < sounds.length; ++i) { + if (this.soundsLoaded.indexOf(sounds[i]) >= 0) { + // Already loaded + continue; + } + + this.soundsLoaded.push(sounds[i]); + promises.push( + this.app.sound + .loadSound(sounds[i]) + .catch(err => { + logger.warn("Failed to load sound:", sounds[i]); + }) + .then(() => { + this.numAssetsLoaded++; + }) + ); + } + + for (let i = 0; i < sprites.length; ++i) { + if (this.spritesLoaded.indexOf(sprites[i]) >= 0) { + // Already loaded + continue; + } + this.spritesLoaded.push(sprites[i]); + promises.push( + Loader.preloadCSSSprite(sprites[i]) + .catch(err => { + logger.warn("Failed to load css sprite:", sprites[i]); + }) + .then(() => { + this.numAssetsLoaded++; + }) + ); + } + + for (let i = 0; i < atlases.length; ++i) { + const atlas = atlases[i]; + promises.push( + Loader.preloadAtlas(atlas) + .catch(err => { + logger.warn("Failed to load atlas:", atlas.sourceFileName); + }) + .then(() => { + this.numAssetsLoaded++; + }) + ); + } + + return ( + Promise.all(promises) + + // // Remove some pressure by waiting a bit + // .then(() => { + // return new Promise(resolve => { + // setTimeout(resolve, 200); + // }); + // }) + .then(() => { + this.numAssetsToLoadTotal = 0; + this.numAssetsLoaded = 0; + }) + ); + } +} diff --git a/src/js/core/buffer_maintainer.js b/src/js/core/buffer_maintainer.js new file mode 100644 index 00000000..3be1c08f --- /dev/null +++ b/src/js/core/buffer_maintainer.js @@ -0,0 +1,146 @@ +import { GameRoot } from "../game/root"; +import { + makeOffscreenBuffer, + freeCanvas, + getBufferVramUsageBytes, + getBufferStats, + clearBufferBacklog, +} from "./buffer_utils"; +import { createLogger } from "./logging"; +import { round2Digits, round1Digit } from "./utils"; + +/** + * @typedef {{ + * canvas: HTMLCanvasElement, + * context: CanvasRenderingContext2D, + * lastUse: number, + * }} CacheEntry + */ + +const logger = createLogger("buffers"); + +const bufferGcDurationSeconds = 3; + +export class BufferMaintainer { + /** + * @param {GameRoot} root + */ + constructor(root) { + this.root = root; + + /** @type {Map>} */ + this.cache = new Map(); + + this.iterationIndex = 1; + this.lastIteration = 0; + } + + /** + * Goes to the next buffer iteration, clearing all buffers which were not used + * for a few iterations + */ + garbargeCollect() { + let totalKeys = 0; + let deletedKeys = 0; + const minIteration = this.iterationIndex; + + this.cache.forEach((subCache, key) => { + let unusedSubKeys = []; + + // Filter sub cache + subCache.forEach((cacheEntry, subKey) => { + if (cacheEntry.lastUse < minIteration) { + unusedSubKeys.push(subKey); + freeCanvas(cacheEntry.canvas); + ++deletedKeys; + } else { + ++totalKeys; + } + }); + + // Delete unused sub keys + for (let i = 0; i < unusedSubKeys.length; ++i) { + subCache.delete(unusedSubKeys[i]); + } + }); + + // Make sure our backlog never gets too big + clearBufferBacklog(); + + const bufferStats = getBufferStats(); + const mbUsed = round1Digit(bufferStats.vramUsage / (1024 * 1024)); + logger.log( + "GC: Remove", + (deletedKeys + "").padStart(4), + ", Remain", + (totalKeys + "").padStart(4), + "(", + (bufferStats.bufferCount + "").padStart(4), + "total", + ")", + + "(", + (bufferStats.backlog + "").padStart(4), + "backlog", + ")", + + "VRAM:", + mbUsed, + "MB" + ); + + ++this.iterationIndex; + } + + update() { + const now = this.root.time.realtimeNow(); + if (now - this.lastIteration > bufferGcDurationSeconds) { + this.lastIteration = now; + this.garbargeCollect(); + } + } + + /** + * + * @param {string} key + * @param {string} subKey + * @param {function(HTMLCanvasElement, CanvasRenderingContext2D, number, number, number, object?) : void} redrawMethod + * @param {object=} additionalParams + * @returns {HTMLCanvasElement} + * + */ + getForKey(key, subKey, w, h, dpi, redrawMethod, additionalParams) { + // First, create parent key + let parent = this.cache.get(key); + if (!parent) { + parent = new Map(); + this.cache.set(key, parent); + } + + // Now search for sub key + const cacheHit = parent.get(subKey); + if (cacheHit) { + cacheHit.lastUse = this.iterationIndex; + return cacheHit.canvas; + } + + // Need to generate new buffer + const effectiveWidth = w * dpi; + const effectiveHeight = h * dpi; + + const [canvas, context] = makeOffscreenBuffer(effectiveWidth, effectiveHeight, { + reusable: true, + label: "buffer-" + key + "/" + subKey, + smooth: true, + }); + + redrawMethod(canvas, context, w, h, dpi, additionalParams); + + parent.set(subKey, { + canvas, + context, + lastUse: this.iterationIndex, + }); + return canvas; + } +} diff --git a/src/js/core/buffer_utils.js b/src/js/core/buffer_utils.js new file mode 100644 index 00000000..3c087d1b --- /dev/null +++ b/src/js/core/buffer_utils.js @@ -0,0 +1,201 @@ +import { globalConfig } from "./config"; +import { Math_max, Math_floor, Math_abs } from "./builtins"; +import { fastArrayDelete } from "./utils"; +import { createLogger } from "./logging"; + +const logger = createLogger("buffer_utils"); + +/** + * Enables images smoothing on a context + * @param {CanvasRenderingContext2D} context + */ +export function enableImageSmoothing(context) { + context.imageSmoothingEnabled = true; + context.webkitImageSmoothingEnabled = true; + + // @ts-ignore + context.imageSmoothingQuality = globalConfig.smoothing.quality; +} + +/** + * Disables image smoothing on a context + * @param {CanvasRenderingContext2D} context + */ +export function disableImageSmoothing(context) { + context.imageSmoothingEnabled = false; + context.webkitImageSmoothingEnabled = false; +} + +const registeredCanvas = []; +const freeCanvasList = []; + +let vramUsage = 0; +let bufferCount = 0; + +/** + * + * @param {HTMLCanvasElement} canvas + */ +export function getBufferVramUsageBytes(canvas) { + return canvas.width * canvas.height * 4; +} + +/** + * Returns stats on the allocated buffers + */ +export function getBufferStats() { + return { + vramUsage, + bufferCount, + backlog: freeCanvasList.length, + }; +} + +export function clearBufferBacklog() { + while (freeCanvasList.length > 50) { + freeCanvasList.pop(); + } +} + +/** + * Creates a new offscreen buffer + * @param {Number} w + * @param {Number} h + * @returns {[HTMLCanvasElement, CanvasRenderingContext2D]} + */ +export function makeOffscreenBuffer(w, h, { smooth = true, reusable = true, label = "buffer" }) { + assert(w > 0 && h > 0, "W or H < 0"); + if (w % 1 !== 0 || h % 1 !== 0) { + // console.warn("Subpixel offscreen buffer size:", w, h); + } + if (w < 1 || h < 1) { + logger.error("Offscreen buffer size < 0:", w, "x", h); + w = Math_max(1, w); + h = Math_max(1, h); + } + + const recommendedSize = 1024 * 1024; + if (w * h > recommendedSize) { + logger.warn("Creating huge buffer:", w, "x", h, "with label", label); + } + + w = Math_floor(w); + h = Math_floor(h); + + let canvas = null; + let context = null; + + let bestMatchingOne = null; + let bestMatchingPixelsDiff = 1e50; + + const currentPixels = w * h; + + // Ok, search in cache first + for (let i = 0; i < freeCanvasList.length; ++i) { + const { canvas: useableCanvas, context: useableContext } = freeCanvasList[i]; + if (useableCanvas.width === w && useableCanvas.height === h) { + // Ok we found one + canvas = useableCanvas; + context = useableContext; + + fastArrayDelete(freeCanvasList, i); + break; + } + + const otherPixels = useableCanvas.width * useableCanvas.height; + const diff = Math_abs(otherPixels - currentPixels); + if (diff < bestMatchingPixelsDiff) { + bestMatchingPixelsDiff = diff; + bestMatchingOne = { + canvas: useableCanvas, + context: useableContext, + index: i, + }; + } + } + + // Ok none matching, reuse one though + if (!canvas && bestMatchingOne) { + canvas = bestMatchingOne.canvas; + context = bestMatchingOne.context; + canvas.width = w; + canvas.height = h; + fastArrayDelete(freeCanvasList, bestMatchingOne.index); + } + + // Reset context + if (context) { + // Restore past state + context.restore(); + context.save(); + context.clearRect(0, 0, canvas.width, canvas.height); + + delete canvas.style.width; + delete canvas.style.height; + } + + // None found , create new one + if (!canvas) { + canvas = document.createElement("canvas"); + context = canvas.getContext("2d" /*, { alpha } */); + + canvas.width = w; + canvas.height = h; + + // Initial state + context.save(); + } + + canvas.label = label; + + if (smooth) { + enableImageSmoothing(context); + } else { + disableImageSmoothing(context); + } + + if (reusable) { + registerCanvas(canvas, context); + } + + return [canvas, context]; +} + +/** + * Frees a canvas + * @param {HTMLCanvasElement} canvas + */ +export function registerCanvas(canvas, context) { + registeredCanvas.push({ canvas, context }); + + bufferCount += 1; + vramUsage += getBufferVramUsageBytes(canvas); +} + +/** + * Frees a canvas + * @param {HTMLCanvasElement} canvas + */ +export function freeCanvas(canvas) { + assert(canvas, "Canvas is empty"); + + let index = -1; + let data = null; + for (let i = 0; i < registeredCanvas.length; ++i) { + if (registeredCanvas[i].canvas === canvas) { + index = i; + data = registeredCanvas[i]; + break; + } + } + + if (index < 0) { + logger.error("Tried to free unregistered canvas of size", canvas.width, canvas.height); + return; + } + fastArrayDelete(registeredCanvas, index); + freeCanvasList.push(data); + + bufferCount -= 1; + vramUsage -= getBufferVramUsageBytes(canvas); +} diff --git a/src/js/core/builtins.js b/src/js/core/builtins.js new file mode 100644 index 00000000..77f40b77 --- /dev/null +++ b/src/js/core/builtins.js @@ -0,0 +1,34 @@ +// Store the original version of all builtins to prevent modification + +export const JSON_stringify = JSON.stringify.bind(JSON); +export const JSON_parse = JSON.parse.bind(JSON); + +export function Math_radians(degrees) { + return (degrees * Math_PI) / 180.0; +} + +export function Math_degrees(radians) { + return (radians * 180.0) / Math_PI; +} + +export const performanceNow = performance.now.bind(performance); + +export const Math_abs = Math.abs.bind(Math); +export const Math_ceil = Math.ceil.bind(Math); +export const Math_floor = Math.floor.bind(Math); +export const Math_round = Math.round.bind(Math); +export const Math_sign = Math.sign.bind(Math); +export const Math_sqrt = Math.sqrt.bind(Math); +export const Math_min = Math.min.bind(Math); +export const Math_max = Math.max.bind(Math); +export const Math_sin = Math.sin.bind(Math); +export const Math_cos = Math.cos.bind(Math); +export const Math_tan = Math.tan.bind(Math); +export const Math_hypot = Math.hypot.bind(Math); +export const Math_atan2 = Math.atan2.bind(Math); +export const Math_pow = Math.pow.bind(Math); +export const Math_random = Math.random.bind(Math); +export const Math_exp = Math.exp.bind(Math); +export const Math_log10 = Math.log10.bind(Math); + +export const Math_PI = 3.1415926; diff --git a/src/js/core/cachebust.js b/src/js/core/cachebust.js new file mode 100644 index 00000000..26be0449 --- /dev/null +++ b/src/js/core/cachebust.js @@ -0,0 +1,10 @@ +/** + * Generates a cachebuster string. This only modifies the path in the browser version + * @param {string} path + */ +export function cachebust(path) { + if (G_IS_BROWSER && !G_IS_STANDALONE && !G_IS_DEV) { + return "/v/" + G_BUILD_COMMIT_HASH + "/" + path; + } + return path; +} diff --git a/src/js/core/click_detector.js b/src/js/core/click_detector.js new file mode 100644 index 00000000..abe666da --- /dev/null +++ b/src/js/core/click_detector.js @@ -0,0 +1,431 @@ +import { performanceNow } from "../core/builtins"; +import { createLogger } from "../core/logging"; +import { Signal } from "../core/signal"; +import { fastArrayDelete, fastArrayDeleteValueIfContained } from "./utils"; +import { Vector } from "./vector"; +import { IS_MOBILE } from "./config"; + +const logger = createLogger("click_detector"); + +export const MAX_MOVE_DISTANCE_PX = IS_MOBILE ? 20 : 40; + +// For debugging +const registerClickDetectors = G_IS_DEV && true; +if (registerClickDetectors) { + /** @type {Array} */ + window.activeClickDetectors = []; +} + +// Store active click detectors so we can cancel them +/** @type {Array} */ +const ongoingClickDetectors = []; + +// Store when the last touch event was registered, to avoid accepting a touch *and* a click event + +export let clickDetectorGlobals = { + lastTouchTime: -1000, +}; + +/** + * Click detector creation payload typehints + * @typedef {{ + * consumeEvents?: boolean, + * preventDefault?: boolean, + * applyCssClass?: string, + * captureTouchmove?: boolean, + * targetOnly?: boolean, + * maxDistance?: number, + * clickSound?: string, + * }} ClickDetectorConstructorArgs + */ + +// Detects clicks +export class ClickDetector { + /** + * + * @param {Element} element + * @param {object} param1 + * @param {boolean=} param1.consumeEvents Whether to call stopPropagation + * (Useful for nested elements where the parent has a click handler as wel) + * @param {boolean=} param1.preventDefault Whether to call preventDefault (Usually makes the handler faster) + * @param {string=} param1.applyCssClass The css class to add while the element is pressed + * @param {boolean=} param1.captureTouchmove Whether to capture touchmove events as well + * @param {boolean=} param1.targetOnly Whether to also accept clicks on child elements (e.target !== element) + * @param {number=} param1.maxDistance The maximum distance in pixels to accept clicks + * @param {string=} param1.clickSound Sound key to play on touchdown + */ + constructor( + element, + { + consumeEvents = false, + preventDefault = true, + applyCssClass = "pressed", + captureTouchmove = false, + targetOnly = false, + maxDistance = MAX_MOVE_DISTANCE_PX, + clickSound = null, + } + ) { + assert(element, "No element given!"); + this.clickDownPosition = null; + + this.consumeEvents = consumeEvents; + this.preventDefault = preventDefault; + this.applyCssClass = applyCssClass; + this.captureTouchmove = captureTouchmove; + this.targetOnly = targetOnly; + this.clickSound = clickSound; + this.maxDistance = maxDistance; + + // Signals + this.click = new Signal(); + this.rightClick = new Signal(); + this.touchstart = new Signal(); + this.touchmove = new Signal(); + this.touchend = new Signal(); + this.touchcancel = new Signal(); + + // Simple signals which just receive the touch position + this.touchstartSimple = new Signal(); + this.touchmoveSimple = new Signal(); + this.touchendSimple = new Signal(); + + // Store time of touch start + this.clickStartTime = null; + + // A click can be cancelled if another detector registers a click + this.cancelled = false; + + this.internalBindTo(/** @type {HTMLElement} */ (element)); + } + + /** + * Cleans up all event listeners of this detector + */ + cleanup() { + if (this.element) { + if (registerClickDetectors) { + const index = window.activeClickDetectors.indexOf(this); + if (index < 0) { + logger.error("Click detector cleanup but is not active"); + } else { + window.activeClickDetectors.splice(index, 1); + } + } + const options = this.internalGetEventListenerOptions(); + this.element.removeEventListener("touchstart", this.handlerTouchStart, options); + this.element.removeEventListener("touchend", this.handlerTouchEnd, options); + this.element.removeEventListener("touchcancel", this.handlerTouchCancel, options); + + this.element.removeEventListener("mouseup", this.handlerTouchStart, options); + this.element.removeEventListener("mousedown", this.handlerTouchEnd, options); + this.element.removeEventListener("mouseout", this.handlerTouchCancel, options); + + if (this.captureTouchmove) { + this.element.removeEventListener("touchmove", this.handlerTouchMove, options); + this.element.removeEventListener("mousemove", this.handlerTouchMove, options); + } + + this.click.removeAll(); + this.touchstart.removeAll(); + this.touchmove.removeAll(); + this.touchend.removeAll(); + this.touchcancel.removeAll(); + + // TODO: Remove pointer captures + + this.element = null; + } + } + + // INTERNAL METHODS + + /** + * Internal method to get the options to pass to an event listener + */ + internalGetEventListenerOptions() { + return { + capture: this.consumeEvents, + passive: !this.preventDefault, + }; + } + + /** + * Binds the click detector to an element + * @param {HTMLElement} element + */ + internalBindTo(element) { + const options = this.internalGetEventListenerOptions(); + + this.handlerTouchStart = this.internalOnPointerDown.bind(this); + this.handlerTouchEnd = this.internalOnPointerEnd.bind(this); + this.handlerTouchMove = this.internalOnPointerMove.bind(this); + this.handlerTouchCancel = this.internalOnTouchCancel.bind(this); + + element.addEventListener("touchstart", this.handlerTouchStart, options); + element.addEventListener("touchend", this.handlerTouchEnd, options); + element.addEventListener("touchcancel", this.handlerTouchCancel, options); + + element.addEventListener("mousedown", this.handlerTouchStart, options); + element.addEventListener("mouseup", this.handlerTouchEnd, options); + element.addEventListener("mouseout", this.handlerTouchCancel, options); + + if (this.captureTouchmove) { + element.addEventListener("touchmove", this.handlerTouchMove, options); + element.addEventListener("mousemove", this.handlerTouchMove, options); + } + + if (registerClickDetectors) { + window.activeClickDetectors.push(this); + } + this.element = element; + } + + /** + * Returns if the bound element is currently in the DOM. + */ + internalIsDomElementAttached() { + return this.element && document.documentElement.contains(this.element); + } + + /** + * Checks if the given event is relevant for this detector + * @param {TouchEvent|MouseEvent} event + */ + internalEventPreHandler(event, expectedRemainingTouches = 1) { + if (!this.element) { + // Already cleaned up + return false; + } + + if (this.targetOnly && event.target !== this.element) { + // Clicked a child element + return false; + } + + // Stop any propagation and defaults if configured + if (this.consumeEvents && event.cancelable) { + event.stopPropagation(); + } + + if (this.preventDefault && event.cancelable) { + event.preventDefault(); + } + + if (window.TouchEvent && event instanceof TouchEvent) { + clickDetectorGlobals.lastTouchTime = performanceNow(); + + // console.log("Got touches", event.targetTouches.length, "vs", expectedRemainingTouches); + if (event.targetTouches.length !== expectedRemainingTouches) { + return false; + } + } + + if (event instanceof MouseEvent) { + if (performanceNow() - clickDetectorGlobals.lastTouchTime < 1000.0) { + return false; + } + } + + return true; + } + + /** + * Extracts the mous position from an event + * @param {TouchEvent|MouseEvent} event + * @returns {Vector} The client space position + */ + static extractPointerPosition(event) { + if (window.TouchEvent && event instanceof TouchEvent) { + if (event.changedTouches.length !== 1) { + logger.warn( + "Got unexpected target touches:", + event.targetTouches.length, + "->", + event.targetTouches + ); + return new Vector(0, 0); + } + + const touch = event.changedTouches[0]; + return new Vector(touch.clientX, touch.clientY); + } + + if (event instanceof MouseEvent) { + return new Vector(event.clientX, event.clientY); + } + + assertAlways(false, "Got unknown event: " + event); + + return new Vector(0, 0); + } + + /** + * Cacnels all ongoing events on this detector + */ + cancelOngoingEvents() { + if (this.applyCssClass && this.element) { + this.element.classList.remove(this.applyCssClass); + } + this.clickDownPosition = null; + this.clickStartTime = null; + this.cancelled = true; + fastArrayDeleteValueIfContained(ongoingClickDetectors, this); + } + + /** + * Internal pointer down handler + * @param {TouchEvent|MouseEvent} event + */ + internalOnPointerDown(event) { + if (!this.internalEventPreHandler(event, 1)) { + return false; + } + + const position = /** @type {typeof ClickDetector} */ (this.constructor).extractPointerPosition(event); + + if (event instanceof MouseEvent) { + const isRightClick = event.which == 3; + if (isRightClick) { + // Ignore right clicks + this.rightClick.dispatch(position, event); + this.cancelled = true; + return; + } + } + + if (this.clickDownPosition) { + logger.warn("Ignoring double click"); + return false; + } + + this.cancelled = false; + this.touchstart.dispatch(event); + + // Store where the touch started + this.clickDownPosition = position; + this.clickStartTime = performanceNow(); + this.touchstartSimple.dispatch(this.clickDownPosition.x, this.clickDownPosition.y); + + // If we are not currently within a click, register it + if (ongoingClickDetectors.indexOf(this) < 0) { + ongoingClickDetectors.push(this); + } else { + logger.warn("Click detector got pointer down of active pointer twice"); + } + + // If we should apply any classes, do this now + if (this.applyCssClass) { + this.element.classList.add(this.applyCssClass); + } + + // If we should play any sound, do this + if (this.clickSound) { + throw new Error("TODO: Play sounds on click"); + // GLOBAL_APP.sound.playUiSound(this.clickSound); + } + + return false; + } + + /** + * Internal pointer move handler + * @param {TouchEvent|MouseEvent} event + */ + internalOnPointerMove(event) { + if (!this.internalEventPreHandler(event, 1)) { + return false; + } + this.touchmove.dispatch(event); + const pos = /** @type {typeof ClickDetector} */ (this.constructor).extractPointerPosition(event); + this.touchmoveSimple.dispatch(pos.x, pos.y); + return false; + } + + /** + * Internal pointer end handler + * @param {TouchEvent|MouseEvent} event + */ + internalOnPointerEnd(event) { + if (!this.internalEventPreHandler(event, 0)) { + return false; + } + + if (this.cancelled) { + // warn(this, "Not dispatching touchend on cancelled listener"); + return false; + } + + if (event instanceof MouseEvent) { + const isRightClick = event.which == 3; + if (isRightClick) { + return; + } + } + + const index = ongoingClickDetectors.indexOf(this); + if (index < 0) { + logger.warn("Got pointer end but click detector is not in pressed state"); + } else { + fastArrayDelete(ongoingClickDetectors, index); + } + + let dispatchClick = false; + let dispatchClickPos = null; + + // Check for correct down position, otherwise must have pinched or so + if (this.clickDownPosition) { + const pos = /** @type {typeof ClickDetector} */ (this.constructor).extractPointerPosition(event); + const distance = pos.distance(this.clickDownPosition); + if (distance <= this.maxDistance) { + dispatchClick = true; + dispatchClickPos = pos; + } else { + // console.warn("[ClickDetector] Touch does not count as click: ms=", timeSinceStart, "-> tolerance:", tolerance, "(was", distance, ")"); + } + } + + this.clickDownPosition = null; + this.clickStartTime = null; + + if (this.applyCssClass) { + this.element.classList.remove(this.applyCssClass); + } + + // Dispatch in the end to avoid the element getting invalidated + // Also make sure that the element is still in the dom + if (this.internalIsDomElementAttached()) { + this.touchend.dispatch(event); + this.touchendSimple.dispatch(); + + if (dispatchClick) { + const detectors = ongoingClickDetectors.slice(); + for (let i = 0; i < detectors.length; ++i) { + detectors[i].cancelOngoingEvents(); + } + this.click.dispatch(dispatchClickPos, event); + } + } + return false; + } + + /** + * Internal touch cancel handler + * @param {TouchEvent|MouseEvent} event + */ + internalOnTouchCancel(event) { + if (!this.internalEventPreHandler(event, 0)) { + return false; + } + + if (this.cancelled) { + // warn(this, "Not dispatching touchcancel on cancelled listener"); + return false; + } + + this.cancelOngoingEvents(); + this.touchcancel.dispatch(event); + this.touchendSimple.dispatch(event); + return false; + } +} diff --git a/src/js/core/config.js b/src/js/core/config.js new file mode 100644 index 00000000..b9153cfa --- /dev/null +++ b/src/js/core/config.js @@ -0,0 +1,104 @@ +export const IS_DEBUG = + G_IS_DEV && + typeof window !== "undefined" && + window.location.port === "3005" && + (window.location.host.indexOf("localhost:") >= 0 || window.location.host.indexOf("192.168.0.") >= 0) && + window.location.search.indexOf("nodebug") < 0; + +const smoothCanvas = true; + +export const globalConfig = { + // Size of a single tile in Pixels. + // NOTICE: Update webpack.production.config too! + tileSize: 32, + halfTileSize: 16, + + // Which dpi the assets have + assetsDpi: 192 / 32, + assetsSharpness: 1.2, + shapesSharpness: 1.4, + + // [Calculated] physics step size + physicsDeltaMs: 0, + physicsDeltaSeconds: 0, + + // Update physics at N fps, independent of rendering + physicsUpdateRate: 60, + + // Map + mapChunkSize: 32, + mapChunkPrerenderMinZoom: 0.7, + mapChunkOverviewMinZoom: 0.7, + + // Belt speeds + // NOTICE: Update webpack.production.config too! + beltSpeedItemsPerSecond: 1, + itemSpacingOnBelts: 0.63, + minerSpeedItemsPerSecond: 0, // COMPUTED + + undergroundBeltMaxTiles: 5, + + buildingSpeeds: { + cutter: 1 / 6, + rotater: 1 / 2, + painter: 1 / 3, + mixer: 1 / 2, + stacker: 1 / 5, + }, + + // Zooming + initialZoom: 1.9, + minZoomLevel: 0.1, + maxZoomLevel: 3, + + // Global game speed + gameSpeed: 1, + + warmupTimeSecondsFast: 0.1, + warmupTimeSecondsRegular: 1, + + smoothing: { + smoothMainCanvas: smoothCanvas && true, + quality: "low", // Low is CRUCIAL for mobile performance! + }, + + rendering: {}, + + debug: { + /* dev:start */ + fastGameEnter: true, + noArtificialDelays: true, + disableSavegameWrite: false, + showEntityBounds: false, + showAcceptorEjectors: false, + usePlainShapeIds: true, + disableMusic: true, + doNotRenderStatics: false, + disableZoomLimits: false, + showChunkBorders: false, + rewardsInstant: false, + allBuildingsUnlocked: true, + upgradesNoCost: true, + disableUnlockDialog: true, + /* dev:end */ + }, + + // Secret vars + info: { + // Binary file salt + file: "Ec'])@^+*9zMevK3uMV4432x9%iK'=", + + // Savegame salt + sgSalt: "}95Q3%8/.837Lqym_BJx%q7)pAHJbF", + }, +}; + +export const IS_MOBILE = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent); + +// Automatic calculations + +globalConfig.physicsDeltaMs = 1000.0 / globalConfig.physicsUpdateRate; +globalConfig.physicsDeltaSeconds = 1.0 / globalConfig.physicsUpdateRate; + +globalConfig.minerSpeedItemsPerSecond = + globalConfig.beltSpeedItemsPerSecond / globalConfig.itemSpacingOnBelts / 6; diff --git a/src/js/core/dpi_manager.js b/src/js/core/dpi_manager.js new file mode 100644 index 00000000..2045a5e0 --- /dev/null +++ b/src/js/core/dpi_manager.js @@ -0,0 +1,117 @@ +import { globalConfig } from "../core/config"; +import { Math_ceil, Math_floor, Math_round } from "./builtins"; +import { round1Digit, round2Digits } from "./utils"; + +/** + * Returns the current dpi + * @returns {number} + */ +export function getDeviceDPI() { + return window.devicePixelRatio || 1; +} + +/** + * + * @param {number} dpi + * @returns {number} Smoothed dpi + */ +export function smoothenDpi(dpi) { + if (dpi < 0.05) { + return 0.05; + } else if (dpi < 0.1) { + return round2Digits(dpi); + } else if (dpi < 1) { + return round1Digit(dpi); + } else { + return round1Digit(Math_round(dpi / 0.5) * 0.5); + } +} + +// Initial dpi +// setDPIMultiplicator(1); + +/** + * Prepares a context for hihg dpi rendering + * @param {CanvasRenderingContext2D} context + */ +export function prepareHighDPIContext(context, smooth = true) { + const dpi = getDeviceDPI(); + context.scale(dpi, dpi); + + if (smooth) { + context.imageSmoothingEnabled = true; + context.webkitImageSmoothingEnabled = true; + + // @ts-ignore + context.imageSmoothingQuality = globalConfig.smoothing.quality; + } else { + context.imageSmoothingEnabled = false; + context.webkitImageSmoothingEnabled = false; + } +} + +/** + * Resizes a high dpi canvas + * @param {HTMLCanvasElement} canvas + * @param {number} w + * @param {number} h + */ +export function resizeHighDPICanvas(canvas, w, h, smooth = true) { + const dpi = getDeviceDPI(); + + const wNumber = Math_floor(w); + const hNumber = Math_floor(h); + + const targetW = Math_floor(wNumber * dpi); + const targetH = Math_floor(hNumber * dpi); + + if (targetW !== canvas.width || targetH !== canvas.height) { + // console.log("Resize Canvas from", canvas.width, canvas.height, "to", targetW, targetH) + canvas.width = targetW; + canvas.height = targetH; + canvas.style.width = wNumber + "px"; + canvas.style.height = hNumber + "px"; + prepareHighDPIContext(canvas.getContext("2d"), smooth); + } +} + +/** + * Resizes a canvas + * @param {HTMLCanvasElement} canvas + * @param {number} w + * @param {number} h + */ +export function resizeCanvas(canvas, w, h, setStyle = true) { + const actualW = Math_ceil(w); + const actualH = Math_ceil(h); + if (actualW !== canvas.width || actualH !== canvas.height) { + canvas.width = actualW; + canvas.height = actualH; + if (setStyle) { + canvas.style.width = actualW + "px"; + canvas.style.height = actualH + "px"; + } + // console.log("Resizing canvas to", actualW, "x", actualH); + } +} + +/** + * Resizes a canvas and makes sure its cleared + * @param {HTMLCanvasElement} canvas + * @param {CanvasRenderingContext2D} context + * @param {number} w + * @param {number} h + */ +export function resizeCanvasAndClear(canvas, context, w, h) { + const actualW = Math_ceil(w); + const actualH = Math_ceil(h); + if (actualW !== canvas.width || actualH !== canvas.height) { + canvas.width = actualW; + canvas.height = actualH; + canvas.style.width = actualW + "px"; + canvas.style.height = actualH + "px"; + // console.log("Resizing canvas to", actualW, "x", actualH); + } else { + context.clearRect(0, 0, actualW, actualH); + } +} diff --git a/src/js/core/draw_parameters.js b/src/js/core/draw_parameters.js new file mode 100644 index 00000000..5e06c59f --- /dev/null +++ b/src/js/core/draw_parameters.js @@ -0,0 +1,25 @@ +import { Rectangle } from "./rectangle"; + +/* typehints:start */ +import { GameRoot } from "../game/root"; +/* typehints:end */ + +export class DrawParameters { + constructor({ context, visibleRect, desiredAtlasScale, zoomLevel, root }) { + /** @type {CanvasRenderingContext2D} */ + this.context = context; + + /** @type {Rectangle} */ + this.visibleRect = visibleRect; + + /** @type {number} */ + this.desiredAtlasScale = desiredAtlasScale; + + /** @type {number} */ + this.zoomLevel = zoomLevel; + + // FIXME: Not really nice + /** @type {GameRoot} */ + this.root = root; + } +} diff --git a/src/js/core/draw_utils.js b/src/js/core/draw_utils.js new file mode 100644 index 00000000..8057a211 --- /dev/null +++ b/src/js/core/draw_utils.js @@ -0,0 +1,321 @@ +/* typehints:start */ +import { AtlasSprite } from "./sprites"; +import { DrawParameters } from "./draw_parameters"; +/* typehints:end */ + +import { Math_PI, Math_round, Math_atan2, Math_hypot, Math_floor } from "./builtins"; +import { Vector } from "./vector"; +import { Rectangle } from "./rectangle"; +import { createLogger } from "./logging"; + +const logger = createLogger("draw_utils"); + +export function initDrawUtils() { + CanvasRenderingContext2D.prototype.beginRoundedRect = function (x, y, w, h, r) { + if (r < 0.05) { + this.beginPath(); + this.rect(x, y, w, h); + return; + } + + if (w < 2 * r) { + r = w / 2; + } + if (h < 2 * r) { + r = h / 2; + } + this.beginPath(); + this.moveTo(x + r, y); + this.arcTo(x + w, y, x + w, y + h, r); + this.arcTo(x + w, y + h, x, y + h, r); + this.arcTo(x, y + h, x, y, r); + this.arcTo(x, y, x + w, y, r); + // this.closePath(); + }; + + CanvasRenderingContext2D.prototype.beginCircle = function (x, y, r) { + if (r < 0.05) { + this.beginPath(); + this.rect(x, y, 1, 1); + return; + } + this.beginPath(); + this.arc(x, y, r, 0, 2.0 * Math_PI); + }; +} + +/** + * + * @param {object} param0 + * @param {DrawParameters} param0.parameters + * @param {AtlasSprite} param0.sprite + * @param {number} param0.x + * @param {number} param0.y + * @param {number} param0.angle + * @param {number} param0.size + * @param {number=} param0.offsetX + * @param {number=} param0.offsetY + */ +export function drawRotatedSprite({ parameters, sprite, x, y, angle, size, offsetX = 0, offsetY = 0 }) { + parameters.context.translate(x, y); + parameters.context.rotate(angle); + sprite.drawCachedCentered(parameters, offsetX, offsetY, size, false); + parameters.context.rotate(-angle); + parameters.context.translate(-x, -y); +} + +export function drawLineFast(context, { x1, x2, y1, y2, color = null, lineSize = 1 }) { + const dX = x2 - x1; + const dY = y2 - y1; + + const angle = Math_atan2(dY, dX) + 0.0 * Math_PI; + const len = Math_hypot(dX, dY); + + context.translate(x1, y1); + context.rotate(angle); + + if (color) { + context.fillStyle = color; + } + + context.fillRect(0, -lineSize / 2, len, lineSize); + + context.rotate(-angle); + context.translate(-x1, -y1); +} + +const INSIDE = 0; +const LEFT = 1; +const RIGHT = 2; +const BOTTOM = 4; +const TOP = 8; + +// https://en.wikipedia.org/wiki/Cohen%E2%80%93Sutherland_algorithm + +function computeOutCode(x, y, xmin, xmax, ymin, ymax) { + let code = INSIDE; + + if (x < xmin) + // to the left of clip window + code |= LEFT; + else if (x > xmax) + // to the right of clip window + code |= RIGHT; + if (y < ymin) + // below the clip window + code |= BOTTOM; + else if (y > ymax) + // above the clip window + code |= TOP; + + return code; +} + +// Cohen–Sutherland clipping algorithm clips a line from +// P0 = (x0, y0) to P1 = (x1, y1) against a rectangle with +// diagonal from (xmin, ymin) to (xmax, ymax). +/** + * + * @param {CanvasRenderingContext2D} context + */ +export function drawLineFastClipped(context, rect, { x0, y0, x1, y1, color = null, lineSize = 1 }) { + const xmin = rect.x; + const ymin = rect.y; + const xmax = rect.right(); + const ymax = rect.bottom(); + + // compute outcodes for P0, P1, and whatever point lies outside the clip rectangle + let outcode0 = computeOutCode(x0, y0, xmin, xmax, ymin, ymax); + let outcode1 = computeOutCode(x1, y1, xmin, xmax, ymin, ymax); + let accept = false; + + // eslint-disable-next-line no-constant-condition + while (true) { + if (!(outcode0 | outcode1)) { + // bitwise OR is 0: both points inside window; trivially accept and exit loop + accept = true; + break; + } else if (outcode0 & outcode1) { + // bitwise AND is not 0: both points share an outside zone (LEFT, RIGHT, TOP, + // or BOTTOM), so both must be outside window; exit loop (accept is false) + break; + } else { + // failed both tests, so calculate the line segment to clip + // from an outside point to an intersection with clip edge + let x, y; + + // At least one endpoint is outside the clip rectangle; pick it. + let outcodeOut = outcode0 ? outcode0 : outcode1; + + // Now find the intersection point; + // use formulas: + // slope = (y1 - y0) / (x1 - x0) + // x = x0 + (1 / slope) * (ym - y0), where ym is ymin or ymax + // y = y0 + slope * (xm - x0), where xm is xmin or xmax + // No need to worry about divide-by-zero because, in each case, the + // outcode bit being tested guarantees the denominator is non-zero + if (outcodeOut & TOP) { + // point is above the clip window + x = x0 + ((x1 - x0) * (ymax - y0)) / (y1 - y0); + y = ymax; + } else if (outcodeOut & BOTTOM) { + // point is below the clip window + x = x0 + ((x1 - x0) * (ymin - y0)) / (y1 - y0); + y = ymin; + } else if (outcodeOut & RIGHT) { + // point is to the right of clip window + y = y0 + ((y1 - y0) * (xmax - x0)) / (x1 - x0); + x = xmax; + } else if (outcodeOut & LEFT) { + // point is to the left of clip window + y = y0 + ((y1 - y0) * (xmin - x0)) / (x1 - x0); + x = xmin; + } + + // Now we move outside point to intersection point to clip + // and get ready for next pass. + if (outcodeOut == outcode0) { + x0 = x; + y0 = y; + outcode0 = computeOutCode(x0, y0, xmin, xmax, ymin, ymax); + } else { + x1 = x; + y1 = y; + outcode1 = computeOutCode(x1, y1, xmin, xmax, ymin, ymax); + } + } + } + if (accept) { + // Following functions are left for implementation by user based on + // their platform (OpenGL/graphics.h etc.) + // DrawRectangle(xmin, ymin, xmax, ymax); + // LineSegment(x0, y0, x1, y1); + drawLineFast(context, { + x1: x0, + y1: y0, + x2: x1, + y2: y1, + color, + lineSize, + }); + } +} + +/** + * Converts an HSL color value to RGB. Conversion formula + * adapted from http://en.wikipedia.org/wiki/HSL_color_space. + * Assumes h, s, and l are contained in the set [0, 1] and + * returns r, g, and b in the set [0, 255]. + * + * @param {number} h The hue + * @param {number} s The saturation + * @param {number} l The lightness + * @return {Array} The RGB representation + */ +export function hslToRgb(h, s, l) { + let r; + let g; + let b; + + if (s === 0) { + r = g = b = l; // achromatic + } else { + // tslint:disable-next-line:no-shadowed-variable + const hue2rgb = function (p, q, t) { + if (t < 0) { + t += 1; + } + if (t > 1) { + t -= 1; + } + if (t < 1 / 6) { + return p + (q - p) * 6 * t; + } + if (t < 1 / 2) { + return q; + } + if (t < 2 / 3) { + return p + (q - p) * (2 / 3 - t) * 6; + } + return p; + }; + + let q = l < 0.5 ? l * (1 + s) : l + s - l * s; + let p = 2 * l - q; + r = hue2rgb(p, q, h + 1 / 3); + g = hue2rgb(p, q, h); + b = hue2rgb(p, q, h - 1 / 3); + } + + return [Math_round(r * 255), Math_round(g * 255), Math_round(b * 255)]; +} + +export function wrapText(context, text, x, y, maxWidth, lineHeight, stroke = false) { + var words = text.split(" "); + var line = ""; + + for (var n = 0; n < words.length; n++) { + var testLine = line + words[n] + " "; + var metrics = context.measureText(testLine); + var testWidth = metrics.width; + if (testWidth > maxWidth && n > 0) { + if (stroke) { + context.strokeText(line, x, y); + } else { + context.fillText(line, x, y); + } + line = words[n] + " "; + y += lineHeight; + } else { + line = testLine; + } + } + + if (stroke) { + context.strokeText(line, x, y); + } else { + context.fillText(line, x, y); + } +} + +/** + * Returns a rotated trapez, used for spotlight culling + * @param {number} x + * @param {number} y + * @param {number} w + * @param {number} h + * @param {number} leftHeight + * @param {number} angle + */ +export function rotateTrapezRightFaced(x, y, w, h, leftHeight, angle) { + const halfY = y + h / 2; + const points = [ + new Vector(x, halfY - leftHeight / 2), + new Vector(x + w, y), + new Vector(x, halfY + leftHeight / 2), + new Vector(x + w, y + h), + ]; + + return Rectangle.getAroundPointsRotated(points, angle); +} + +/** + * Converts values from 0 .. 255 to values like 07, 7f, 5d etc + * @param {number} value + * @returns {string} + */ +export function mapClampedColorValueToHex(value) { + const hex = "0123456789abcdef"; + return hex[Math_floor(value / 16)] + hex[value % 16]; +} + +/** + * Converts rgb to a hex string + * @param {number} r + * @param {number} g + * @param {number} b + * @returns {string} + */ +export function rgbToHex(r, g, b) { + return mapClampedColorValueToHex(r) + mapClampedColorValueToHex(g) + mapClampedColorValueToHex(b); +} diff --git a/src/js/core/error_handler.js b/src/js/core/error_handler.js new file mode 100644 index 00000000..bcb6fcf4 --- /dev/null +++ b/src/js/core/error_handler.js @@ -0,0 +1,126 @@ +import { logSection } from "./logging"; +import { stringifyObjectContainingErrors } from "./logging"; +import { removeAllChildren } from "./utils"; + +export let APPLICATION_ERROR_OCCURED = false; + +/** + * + * @param {Event|string} message + * @param {string} source + * @param {number} lineno + * @param {number} colno + * @param {Error} source + */ +function catchErrors(message, source, lineno, colno, error) { + let fullPayload = JSON.parse( + stringifyObjectContainingErrors({ + message, + source, + lineno, + colno, + error, + }) + ); + + if (("" + message).indexOf("Script error.") >= 0) { + console.warn("Thirdparty script error:", message); + return; + } + + if (("" + message).indexOf("NS_ERROR_FAILURE") >= 0) { + console.warn("Firefox NS_ERROR_FAILURE error:", message); + return; + } + + if (("" + message).indexOf("Cannot read property 'postMessage' of null") >= 0) { + console.warn("Safari can not read post message error:", message); + return; + } + + if (!G_IS_DEV && G_IS_BROWSER && ("" + source).indexOf("shapez.io") < 0) { + console.warn("Thirdparty error:", message); + return; + } + + console.log("\n\n\n⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️\n\n\n"); + console.log(" APPLICATION CRASHED "); + console.log("\n\n⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️\n\n\n"); + + logSection("APPLICATION CRASH", "#e53935"); + console.log("Error:", message, "->", error); + console.log("Payload:", fullPayload); + + if (window.Sentry && !window.anyModLoaded) { + window.Sentry.withScope(scope => { + window.Sentry.setTag("message", message); + window.Sentry.setTag("source", source); + + window.Sentry.setExtra("message", message); + window.Sentry.setExtra("source", source); + window.Sentry.setExtra("lineno", lineno); + window.Sentry.setExtra("colno", colno); + window.Sentry.setExtra("error", error); + window.Sentry.setExtra("fullPayload", fullPayload); + + try { + const userName = window.localStorage.getItem("tracking_context") || null; + window.Sentry.setTag("username", userName); + } catch (ex) { + // ignore + } + + window.Sentry.captureException(error || source); + }); + } + + if (APPLICATION_ERROR_OCCURED) { + console.warn("ERROR: Only showing and submitting first error"); + return; + } + + APPLICATION_ERROR_OCCURED = true; + const element = document.createElement("div"); + element.id = "applicationError"; + + const title = document.createElement("h1"); + title.innerText = "Whoops!"; + element.appendChild(title); + + const desc = document.createElement("div"); + desc.classList.add("desc"); + desc.innerHTML = ` + It seems the application crashed - I am sorry for that!

+ An anonymized crash report has been sent, and I will have a look as soon as possible.

+ If you have additional information how I can reproduce this error, please E-Mail me:  + bugs@shapez.io`; + element.appendChild(desc); + + const details = document.createElement("pre"); + details.classList.add("details"); + details.innerText = (error && error.stack) || message; + element.appendChild(details); + + const inject = function () { + if (!G_IS_DEV) { + removeAllChildren(document.body); + } + if (document.body.parentElement) { + document.body.parentElement.appendChild(element); + } else { + document.body.appendChild(element); + } + }; + + if (document.body) { + inject(); + } else { + setTimeout(() => { + inject(); + }, 200); + } + + return true; +} + +window.onerror = catchErrors; diff --git a/src/js/core/explained_result.js b/src/js/core/explained_result.js new file mode 100644 index 00000000..11371129 --- /dev/null +++ b/src/js/core/explained_result.js @@ -0,0 +1,40 @@ +export class ExplainedResult { + constructor(result = true, reason = null, additionalProps = {}) { + /** @type {boolean} */ + this.result = result; + + /** @type {string} */ + this.reason = reason; + + // Copy additional props + for (const key in additionalProps) { + this[key] = additionalProps[key]; + } + } + + isGood() { + return !!this.result; + } + + isBad() { + return !this.result; + } + + static good() { + return new ExplainedResult(true); + } + + static bad(reason, additionalProps) { + return new ExplainedResult(false, reason, additionalProps); + } + + static requireAll(...args) { + for (let i = 0; i < args.length; ++i) { + const subResult = args[i].call(); + if (!subResult.isGood()) { + return subResult; + } + } + return this.good(); + } +} diff --git a/src/js/core/factory.js b/src/js/core/factory.js new file mode 100644 index 00000000..f2587f69 --- /dev/null +++ b/src/js/core/factory.js @@ -0,0 +1,81 @@ +import { createLogger } from "./logging"; + +const logger = createLogger("factory"); + +// simple factory pattern +export class Factory { + constructor(id) { + this.id = id; + + // Store array as well as dictionary, to speed up lookups + this.entries = []; + this.entryIds = []; + this.idToEntry = {}; + } + + getId() { + return this.id; + } + + register(entry) { + // Extract id + const id = entry.getId(); + assert(id, "Factory: Invalid id for class: " + entry); + + // Check duplicates + assert(!this.idToEntry[id], "Duplicate factory entry for " + id); + + // Insert + this.entries.push(entry); + this.entryIds.push(id); + this.idToEntry[id] = entry; + } + + /** + * Checks if a given id is registered + * @param {string} id + * @returns {boolean} + */ + hasId(id) { + return !!this.idToEntry[id]; + } + + /** + * Finds an instance by a given id + * @param {string} id + * @returns {object} + */ + findById(id) { + const entry = this.idToEntry[id]; + if (!entry) { + logger.error("Object with id", id, "is not registered on factory", this.id, "!"); + assert(false, "Factory: Object with id '" + id + "' is not registered!"); + return null; + } + return entry; + } + + /** + * Returns all entries + * @returns {Array} + */ + getEntries() { + return this.entries; + } + + /** + * Returns all registered ids + * @returns {Array} + */ + getAllIds() { + return this.entryIds; + } + + /** + * Returns amount of stored entries + * @returns {number} + */ + getNumEntries() { + return this.entries.length; + } +} diff --git a/src/js/core/game_state.js b/src/js/core/game_state.js new file mode 100644 index 00000000..81744089 --- /dev/null +++ b/src/js/core/game_state.js @@ -0,0 +1,365 @@ +/* typehints:start */ +import { Application } from "../application"; +import { StateManager } from "./state_manager"; +/* typehints:end */ + +import { globalConfig } from "./config"; +import { ClickDetector } from "./click_detector"; +import { logSection, createLogger } from "./logging"; +import { InputReceiver } from "./input_receiver"; +import { waitNextFrame } from "./utils"; +import { RequestChannel } from "./request_channel"; +import { MUSIC } from "../platform/sound"; + +const logger = createLogger("game_state"); + +/** + * Basic state of the game state machine. This is the base of the whole game + */ +export class GameState { + /** + * Constructs a new state with the given id + * @param {string} key The id of the state. We use ids to refer to states because otherwise we get + * circular references + */ + constructor(key) { + this.key = key; + + /** @type {StateManager} */ + this.stateManager = null; + + /** @type {Application} */ + this.app = null; + + // Store if we are currently fading out + this.fadingOut = false; + + /** @type {Array} */ + this.clickDetectors = []; + + // Every state captures keyboard events by default + this.inputReciever = new InputReceiver("state-" + key); + this.inputReciever.backButton.add(this.onBackButton, this); + + // A channel we can use to perform async ops + this.asyncChannel = new RequestChannel(); + } + + //// GETTERS / HELPER METHODS //// + + /** + * Returns the states key + * @returns {string} + */ + getKey() { + return this.key; + } + + /** + * Returns the html element of the state + * @returns {HTMLElement} + */ + getDivElement() { + return document.getElementById("state_" + this.key); + } + + /** + * Transfers to a new state + * @param {string} stateKey The id of the new state + */ + moveToState(stateKey, payload = {}, skipFadeOut = false) { + if (this.fadingOut) { + logger.warn("Skipping move to '" + stateKey + "' since already fading out"); + return; + } + + // Clean up event listeners + this.internalCleanUpClickDetectors(); + + // Fading + const fadeTime = this.internalGetFadeInOutTime(); + const doFade = !skipFadeOut && this.getHasFadeOut() && fadeTime !== 0; + logger.log("Moving to", stateKey, "(fading=", doFade, ")"); + if (doFade) { + this.htmlElement.classList.remove("arrived"); + this.fadingOut = true; + setTimeout(() => { + this.stateManager.moveToState(stateKey, payload); + }, fadeTime); + } else { + this.stateManager.moveToState(stateKey, payload); + } + } + + /** + * + * @param {string} nextStateId + * @param {object=} nextStatePayload + */ + watchAdAndMoveToState(nextStateId, nextStatePayload = {}) { + if (this.app.adProvider.getCanShowVideoAd() && this.app.isRenderable()) { + this.moveToState( + "WatchAdState", + { + nextStateId, + nextStatePayload, + }, + true + ); + } else { + this.moveToState(nextStateId, nextStatePayload); + } + } + + /** + * Tracks clicks on a given element and calls the given callback *on this state*. + * If you want to call another function wrap it inside a lambda. + * @param {Element} element The element to track clicks on + * @param {function():void} handler The handler to call + * @param {import("./click_detector").ClickDetectorConstructorArgs=} args Click detector arguments + */ + trackClicks(element, handler, args = {}) { + const detector = new ClickDetector(element, args); + detector.click.add(handler, this); + if (G_IS_DEV) { + // Append a source so we can check where the click detector is from + // @ts-ignore + detector._src = "state-" + this.key; + } + this.clickDetectors.push(detector); + } + + /** + * Cancels all promises on the api as well as our async channel + */ + cancelAllAsyncOperations() { + this.asyncChannel.cancelAll(); + // TODO + // this.app.api.cancelRequests(); + } + + //// CALLBACKS //// + + /** + * Callback when entering the state, to be overriddemn + * @param {any} payload Arbitrary data passed from the state which we are transferring from + */ + onEnter(payload) {} + + /** + * Callback when leaving the state + */ + onLeave() {} + + /** + * Callback before leaving the game state or when the page is unloaded + */ + onBeforeExit() {} + + /** + * Callback when the app got paused (on android, this means in background) + */ + onAppPause() {} + + /** + * Callback when the app got resumed (on android, this means in foreground again) + */ + onAppResume() {} + + /** + * Render callback + * @param {number} dt Delta time in ms since last render + */ + onRender(dt) {} + + /** + * Background tick callback, called while the game is inactiev + * @param {number} dt Delta time in ms since last tick + */ + onBackgroundTick(dt) {} + + /** + * Called when the screen resized + * @param {number} w window/screen width + * @param {number} h window/screen height + */ + onResized(w, h) {} + + /** + * Internal backbutton handler, called when the hardware back button is pressed or + * the escape key is pressed + */ + onBackButton() {} + + //// INTERFACE //// + + /** + * Should return how many mulliseconds to fade in / out the state. Not recommended to override! + * @returns {number} Time in milliseconds to fade out + */ + getInOutFadeTime() { + if (globalConfig.debug.noArtificialDelays) { + return 0; + } + return 200; + } + + /** + * Should return whether to fade in the game state. This will then apply the right css classes + * for the fadein. + * @returns {boolean} + */ + getHasFadeIn() { + return true; + } + + /** + * Should return whether to fade out the game state. This will then apply the right css classes + * for the fadeout and wait the delay before moving states + * @returns {boolean} + */ + getHasFadeOut() { + return true; + } + + /** + * Returns if this state should get paused if it does not have focus + * @returns {boolean} true to pause the updating of the game + */ + getPauseOnFocusLost() { + return true; + } + + /** + * Should return the html code of the state. + * @returns {string} + */ + getInnerHTML() { + abstract; + return ""; + } + + /** + * Returns if the state has an unload confirmation, this is the + * "Are you sure you want to leave the page" message. + */ + getHasUnloadConfirmation() { + return false; + } + + /** + * Should return the theme music for this state + * @returns {string|null} + */ + getThemeMusic() { + return MUSIC.mainMenu; + } + + //////////////////// + + //// INTERNAL //// + + /** + * Internal callback from the manager. Do not override! + * @param {StateManager} stateManager + */ + internalRegisterCallback(stateManager, app) { + assert(stateManager, "No state manager"); + assert(app, "No app"); + this.stateManager = stateManager; + this.app = app; + } + + /** + * Internal callback when entering the state. Do not override! + * @param {any} payload Arbitrary data passed from the state which we are transferring from + * @param {boolean} callCallback Whether to call the onEnter callback + */ + internalEnterCallback(payload, callCallback = true) { + logSection(this.key, "#26a69a"); + this.app.inputMgr.pushReciever(this.inputReciever); + + this.htmlElement = this.getDivElement(); + this.htmlElement.classList.add("active"); + + // Apply classes in the next frame so the css transition keeps up + waitNextFrame().then(() => { + if (this.htmlElement) { + this.htmlElement.classList.remove("fadingOut"); + this.htmlElement.classList.remove("fadingIn"); + } + }); + + // Call handler + if (callCallback) { + this.onEnter(payload); + } + } + + /** + * Internal callback when the state is left. Do not override! + */ + internalLeaveCallback() { + this.onLeave(); + + this.htmlElement.classList.remove("active"); + this.app.inputMgr.popReciever(this.inputReciever); + this.internalCleanUpClickDetectors(); + this.asyncChannel.cancelAll(); + } + + /** + * Internal callback *before* the state is left. Also is called on page unload + */ + internalOnBeforeExitCallback() { + this.onBeforeExit(); + } + + /** + * Internal app pause callback + */ + internalOnAppPauseCallback() { + this.onAppPause(); + } + + /** + * Internal app resume callback + */ + internalOnAppResumeCallback() { + this.onAppResume(); + } + + /** + * Cleans up all click detectors + */ + internalCleanUpClickDetectors() { + if (this.clickDetectors) { + for (let i = 0; i < this.clickDetectors.length; ++i) { + this.clickDetectors[i].cleanup(); + } + this.clickDetectors = []; + } + } + + /** + * Internal method to get the HTML of the game state. + * @returns {string} + */ + internalGetFullHtml() { + return this.getInnerHTML(); + } + + /** + * Internal method to compute the time to fade in / out + * @returns {number} time to fade in / out in ms + */ + internalGetFadeInOutTime() { + if (G_IS_DEV && globalConfig.debug.fastGameEnter) { + return 1; + } + if (G_IS_DEV && globalConfig.debug.noArtificialDelays) { + return 1; + } + return this.getInOutFadeTime(); + } +} diff --git a/src/js/core/global_registries.js b/src/js/core/global_registries.js new file mode 100644 index 00000000..321732e0 --- /dev/null +++ b/src/js/core/global_registries.js @@ -0,0 +1,35 @@ +import { SingletonFactory } from "./singleton_factory"; +import { Factory } from "./factory"; + +/* typehints:start */ +import { BaseGameSpeed } from "../game/time/base_game_speed"; +import { Component } from "../game/component"; +import { BaseItem } from "../game/base_item"; +import { MetaBuilding } from "../game/meta_building"; +/* typehints:end */ + +// These factories are here to remove circular dependencies + +/** @type {SingletonFactoryTemplate} */ +export let gMetaBuildingRegistry = new SingletonFactory(); + +/** @type {Object.>} */ +export let gBuildingsByCategory = null; + +/** @type {FactoryTemplate} */ +export let gComponentRegistry = new Factory("component"); + +/** @type {FactoryTemplate} */ +export let gGameSpeedRegistry = new Factory("gamespeed"); + +/** @type {FactoryTemplate} */ +export let gItemRegistry = new Factory("item"); + +// Helpers + +/** + * @param {Object.>} buildings + */ +export function initBuildingsByCategory(buildings) { + gBuildingsByCategory = buildings; +} diff --git a/src/js/core/globals.js b/src/js/core/globals.js new file mode 100644 index 00000000..15197880 --- /dev/null +++ b/src/js/core/globals.js @@ -0,0 +1,17 @@ +/* typehints:start */ +import { Application } from "../application"; +/* typehints:end */ + +/** + * Used for the bug reporter, and the click detector which both have no handles to this. + * It would be nicer to have no globals, but this is the only one. I promise! + * @type {Application} */ +export let GLOBAL_APP = null; + +/** + * @param {Application} app + */ +export function setGlobalApp(app) { + assert(!GLOBAL_APP, "Create application twice!"); + GLOBAL_APP = app; +} diff --git a/src/js/core/input_distributor.js b/src/js/core/input_distributor.js new file mode 100644 index 00000000..668cdcec --- /dev/null +++ b/src/js/core/input_distributor.js @@ -0,0 +1,235 @@ +/* typehints:start */ +import { Application } from "../application"; +import { InputReceiver } from "./input_receiver"; +/* typehints:end */ + +import { Signal, STOP_PROPAGATION } from "./signal"; +import { createLogger } from "./logging"; +import { arrayDeleteValue, fastArrayDeleteValue } from "./utils"; + +const logger = createLogger("input_distributor"); + +export class InputDistributor { + /** + * + * @param {Application} app + */ + constructor(app) { + this.app = app; + + /** @type {Array} */ + this.recieverStack = []; + + /** @type {Array} */ + this.filters = []; + + this.shiftIsDown = false; + this.altIsDown = false; + + this.bindToEvents(); + } + + /** + * Attaches a new filter which can filter and reject events + * @param {function(any): boolean} filter + */ + installFilter(filter) { + this.filters.push(filter); + } + + /** + * Removes an attached filter + * @param {function(any) : boolean} filter + */ + dismountFilter(filter) { + fastArrayDeleteValue(this.filters, filter); + } + + /** + * @param {InputReceiver} reciever + */ + pushReciever(reciever) { + if (this.isRecieverAttached(reciever)) { + assert(false, "Can not add reciever " + reciever.context + " twice"); + logger.error("Can not add reciever", reciever.context, "twice"); + return; + } + this.recieverStack.push(reciever); + + if (this.recieverStack.length > 10) { + logger.error( + "Reciever stack is huge, probably some dead receivers arround:", + this.recieverStack.map(x => x.context) + ); + } + } + + /** + * @param {InputReceiver} reciever + */ + popReciever(reciever) { + if (this.recieverStack.indexOf(reciever) < 0) { + assert(false, "Can not pop reciever " + reciever.context + " since its not contained"); + logger.error("Can not pop reciever", reciever.context, "since its not contained"); + return; + } + if (this.recieverStack[this.recieverStack.length - 1] !== reciever) { + logger.warn( + "Popping reciever", + reciever.context, + "which is not on top of the stack. Stack is: ", + this.recieverStack.map(x => x.context) + ); + } + arrayDeleteValue(this.recieverStack, reciever); + } + + /** + * @param {InputReceiver} reciever + */ + isRecieverAttached(reciever) { + return this.recieverStack.indexOf(reciever) >= 0; + } + + /** + * @param {InputReceiver} reciever + */ + isRecieverOnTop(reciever) { + return ( + this.isRecieverAttached(reciever) && + this.recieverStack[this.recieverStack.length - 1] === reciever + ); + } + + /** + * @param {InputReceiver} reciever + */ + makeSureAttachedAndOnTop(reciever) { + this.makeSureDetached(reciever); + this.pushReciever(reciever); + } + + /** + * @param {InputReceiver} reciever + */ + makeSureDetached(reciever) { + if (this.isRecieverAttached(reciever)) { + arrayDeleteValue(this.recieverStack, reciever); + } + } + + /** + * + * @param {InputReceiver} reciever + */ + destroyReceiver(reciever) { + this.makeSureDetached(reciever); + reciever.cleanup(); + } + + // Internal + + getTopReciever() { + if (this.recieverStack.length > 0) { + return this.recieverStack[this.recieverStack.length - 1]; + } + return null; + } + + bindToEvents() { + window.addEventListener("popstate", this.handleBackButton.bind(this), false); + document.addEventListener("backbutton", this.handleBackButton.bind(this), false); + window.addEventListener("keydown", this.handleKeydown.bind(this)); + window.addEventListener("keyup", this.handleKeyup.bind(this)); + window.addEventListener("blur", this.handleBlur.bind(this)); + } + + forwardToReceiver(eventId, payload = null) { + // Check filters + for (let i = 0; i < this.filters.length; ++i) { + if (!this.filters[i](eventId)) { + return STOP_PROPAGATION; + } + } + + const reciever = this.getTopReciever(); + if (!reciever) { + logger.warn("Dismissing event because not reciever was found:", eventId); + return; + } + const signal = reciever[eventId]; + assert(signal instanceof Signal, "Not a valid event id"); + return signal.dispatch(payload); + } + + /** + * @param {Event} event + */ + handleBackButton(event) { + event.preventDefault(); + event.stopPropagation(); + this.forwardToReceiver("backButton"); + } + + /** + * Handles when the page got blurred + */ + handleBlur() { + this.shiftIsDown = false; + this.forwardToReceiver("pageBlur", {}); + this.forwardToReceiver("shiftUp", {}); + } + + /** + * @param {KeyboardEvent} event + */ + handleKeydown(event) { + if (event.keyCode === 16) { + this.shiftIsDown = true; + } + + if ( + // TAB + event.keyCode === 9 || + // F1 - F10 + (event.keyCode >= 112 && event.keyCode < 122 && !G_IS_DEV) + ) { + event.preventDefault(); + } + + if ( + this.forwardToReceiver("keydown", { + keyCode: event.keyCode, + shift: event.shiftKey, + alt: event.altKey, + event, + }) === STOP_PROPAGATION + ) { + return; + } + + const code = event.keyCode; + if (code === 27) { + // Escape key + event.preventDefault(); + event.stopPropagation(); + return this.forwardToReceiver("backButton"); + } + } + + /** + * @param {KeyboardEvent} event + */ + handleKeyup(event) { + if (event.keyCode === 16) { + this.shiftIsDown = false; + this.forwardToReceiver("shiftUp", {}); + } + + this.forwardToReceiver("keyup", { + keyCode: event.keyCode, + shift: event.shiftKey, + alt: event.altKey, + }); + } +} diff --git a/src/js/core/input_receiver.js b/src/js/core/input_receiver.js new file mode 100644 index 00000000..f2fdf32f --- /dev/null +++ b/src/js/core/input_receiver.js @@ -0,0 +1,25 @@ +import { Signal } from "./signal"; + +export class InputReceiver { + constructor(context = "unknown") { + this.context = context; + + this.backButton = new Signal(); + + this.keydown = new Signal(); + this.keyup = new Signal(); + this.pageBlur = new Signal(); + this.shiftUp = new Signal(); + + // Dispatched on destroy + this.destroyed = new Signal(); + } + + cleanup() { + this.backButton.removeAll(); + this.keydown.removeAll(); + this.keyup.removeAll(); + + this.destroyed.dispatch(); + } +} diff --git a/src/js/core/loader.js b/src/js/core/loader.js new file mode 100644 index 00000000..5c8e17ec --- /dev/null +++ b/src/js/core/loader.js @@ -0,0 +1,243 @@ +/* typehints:start */ +import { Application } from "../application"; +/* typehints:end */ + +import { AtlasDefinition } from "./atlas_definitions"; +import { makeOffscreenBuffer } from "./buffer_utils"; +import { AtlasSprite, BaseSprite, RegularSprite, SpriteAtlasLink } from "./sprites"; +import { cachebust } from "./cachebust"; +import { createLogger } from "./logging"; + +const logger = createLogger("loader"); + +const missingSpriteIds = {}; + +class LoaderImpl { + constructor() { + /** @type {Application} */ + this.app = null; + + /** @type {Map} */ + this.sprites = new Map(); + + this.rawImages = []; + } + + linkAppAfterBoot(app) { + this.app = app; + this.makeSpriteNotFoundCanvas(); + } + + /** + * Fetches a given sprite from the cache + * @param {string} key + * @returns {BaseSprite} + */ + getSpriteInternal(key) { + const sprite = this.sprites.get(key); + if (!sprite) { + if (!missingSpriteIds[key]) { + // Only show error once + missingSpriteIds[key] = true; + logger.error("Sprite '" + key + "' not found!"); + } + return this.spriteNotFoundSprite; + } + return sprite; + } + + /** + * Returns an atlas sprite from the cache + * @param {string} key + * @returns {AtlasSprite} + */ + getSprite(key) { + const sprite = this.getSpriteInternal(key); + assert(sprite instanceof AtlasSprite || sprite === this.spriteNotFoundSprite, "Not an atlas sprite"); + return /** @type {AtlasSprite} */ (sprite); + } + + /** + * Retursn a regular sprite from the cache + * @param {string} key + * @returns {RegularSprite} + */ + getRegularSprite(key) { + const sprite = this.getSpriteInternal(key); + assert( + sprite instanceof RegularSprite || sprite === this.spriteNotFoundSprite, + "Not a regular sprite" + ); + return /** @type {RegularSprite} */ (sprite); + } + + /** + * + * @param {string} key + * @returns {Promise} + */ + internalPreloadImage(key) { + const url = cachebust("res/" + key); + const image = new Image(); + + let triesSoFar = 0; + + return Promise.race([ + new Promise((resolve, reject) => { + setTimeout(reject, G_IS_DEV ? 3000 : 60000); + }), + + new Promise(resolve => { + image.onload = () => { + image.onerror = null; + image.onload = null; + + if (typeof image.decode === "function") { + // SAFARI: Image.decode() fails on safari with svgs -> we dont want to fail + // on that + // FIREFOX: Decode never returns if the image is in cache, so call it in background + image.decode().then( + () => null, + () => null + ); + } + resolve(image); + }; + + image.onerror = reason => { + logger.warn("Failed to load '" + url + "':", reason); + if (++triesSoFar < 4) { + logger.log("Retrying to load image from", url); + image.src = url + "?try=" + triesSoFar; + } else { + logger.warn("Failed to load", url, "after", triesSoFar, "tries with reason", reason); + image.onerror = null; + image.onload = null; + resolve(null); + } + }; + + image.src = url; + }), + ]); + } + + /** + * Preloads a sprite + * @param {string} key + * @returns {Promise} + */ + preloadCSSSprite(key) { + return this.internalPreloadImage(key).then(image => { + if (key.indexOf("game_misc") >= 0) { + // Allow access to regular sprites + this.sprites.set(key, new RegularSprite(image, image.width, image.height)); + } + this.rawImages.push(image); + }); + } + + /** + * Preloads an atlas + * @param {AtlasDefinition} atlas + * @returns {Promise} + */ + preloadAtlas(atlas) { + return this.internalPreloadImage(atlas.getFullSourcePath()).then(image => { + // @ts-ignore + image.label = atlas.sourceFileName; + return this.internalParseAtlas(atlas, image); + }); + } + + /** + * + * @param {AtlasDefinition} atlas + * @param {HTMLImageElement} loadedImage + */ + internalParseAtlas(atlas, loadedImage) { + this.rawImages.push(loadedImage); + + for (const spriteKey in atlas.sourceData) { + const spriteData = atlas.sourceData[spriteKey]; + + let sprite = /** @type {AtlasSprite} */ (this.sprites.get(spriteKey)); + + if (!sprite) { + sprite = new AtlasSprite({ + spriteName: spriteKey, + }); + this.sprites.set(spriteKey, sprite); + } + + const link = new SpriteAtlasLink({ + packedX: spriteData.frame.x, + packedY: spriteData.frame.y, + packedW: spriteData.frame.w, + packedH: spriteData.frame.h, + packOffsetX: spriteData.spriteSourceSize.x, + packOffsetY: spriteData.spriteSourceSize.y, + atlas: loadedImage, + w: spriteData.sourceSize.w, + h: spriteData.sourceSize.h, + }); + sprite.linksByResolution[atlas.meta.scale] = link; + } + } + + /** + * Creates the links for the sprites after the atlas has been loaded. Used so we + * don't have to store duplicate sprites. + */ + createAtlasLinks() { + // NOT USED + } + + /** + * Makes the canvas which shows the question mark, shown when a sprite was not found + */ + makeSpriteNotFoundCanvas() { + const dims = 128; + + const [canvas, context] = makeOffscreenBuffer(dims, dims, { + smooth: false, + label: "not-found-sprite", + }); + context.fillStyle = "#f77"; + context.fillRect(0, 0, dims, dims); + + context.textAlign = "center"; + context.textBaseline = "middle"; + context.fillStyle = "#eee"; + context.font = "25px Arial"; + context.fillText("???", dims / 2, dims / 2); + + // TODO: Not sure why this is set here + // @ts-ignore + canvas.src = "not-found"; + + const resolutions = ["0.1", "0.25", "0.5", "0.75", "1"]; + const sprite = new AtlasSprite({ + spriteName: "not-found", + }); + + for (let i = 0; i < resolutions.length; ++i) { + const res = resolutions[i]; + const link = new SpriteAtlasLink({ + packedX: 0, + packedY: 0, + w: dims, + h: dims, + packOffsetX: 0, + packOffsetY: 0, + packedW: dims, + packedH: dims, + atlas: canvas, + }); + sprite.linksByResolution[res] = link; + } + this.spriteNotFoundSprite = sprite; + } +} + +export const Loader = new LoaderImpl(); diff --git a/src/js/core/logging.js b/src/js/core/logging.js new file mode 100644 index 00000000..e84d4159 --- /dev/null +++ b/src/js/core/logging.js @@ -0,0 +1,249 @@ +import { globalConfig } from "../core/config"; +import { Math_floor, performanceNow } from "./builtins"; + +const circularJson = require("circular-json"); + +/* +Logging functions +- To be extended +*/ + +/** + * Base logger class + */ +class Logger { + constructor(context) { + this.context = context; + } + + debug(...args) { + globalDebug(this.context, ...args); + } + + log(...args) { + globalLog(this.context, ...args); + } + + warn(...args) { + globalWarn(this.context, ...args); + } + + error(...args) { + globalError(this.context, ...args); + } +} + +export function createLogger(context) { + return new Logger(context); +} + +function prepareObjectForLogging(obj, maxDepth = 1) { + if (!window.Sentry) { + // Not required without sentry + return obj; + } + + if (typeof obj !== "object" && !Array.isArray(obj)) { + return obj; + } + const result = {}; + for (const key in obj) { + const val = obj[key]; + + if (typeof val === "object") { + if (maxDepth > 0) { + result[key] = prepareObjectForLogging(val, maxDepth - 1); + } else { + result[key] = "[object]"; + } + } else { + result[key] = val; + } + } + return result; +} + +/** + * Serializes an error + * @param {Error|ErrorEvent} err + */ +export function serializeError(err) { + if (!err) { + return null; + } + const result = { + type: err.constructor.name, + }; + + if (err instanceof Error) { + result.message = err.message; + result.name = err.name; + result.stack = err.stack; + result.type = "{type.Error}"; + } else if (err instanceof ErrorEvent) { + result.filename = err.filename; + result.message = err.message; + result.lineno = err.lineno; + result.colno = err.colno; + result.type = "{type.ErrorEvent}"; + + if (err.error) { + result.error = serializeError(err.error); + } else { + result.error = "{not-provided}"; + } + } else { + result.type = "{unkown-type:" + typeof err + "}"; + } + + return result; +} + +/** + * Serializes an event + * @param {Event} event + */ +function serializeEvent(event) { + let result = { + type: "{type.Event:" + typeof event + "}", + }; + result.eventType = event.type; + return result; +} + +/** + * Prepares a json payload + * @param {string} key + * @param {any} value + */ +function preparePayload(key, value) { + if (value instanceof Error || value instanceof ErrorEvent) { + return serializeError(value); + } + if (value instanceof Event) { + return serializeEvent(value); + } + if (typeof value === "undefined") { + return null; + } + return value; +} + +/** + * Stringifies an object containing circular references and errors + * @param {any} payload + */ +export function stringifyObjectContainingErrors(payload) { + return circularJson.stringify(payload, preparePayload); +} + +export function globalDebug(context, ...args) { + if (G_IS_DEV) { + logInternal(context, console.log, prepareArgsForLogging(args)); + } +} + +export function globalLog(context, ...args) { + // eslint-disable-next-line no-console + logInternal(context, console.log, prepareArgsForLogging(args)); +} + +export function globalWarn(context, ...args) { + // eslint-disable-next-line no-console + logInternal(context, console.warn, prepareArgsForLogging(args)); +} + +export function globalError(context, ...args) { + args = prepareArgsForLogging(args); + // eslint-disable-next-line no-console + logInternal(context, console.error, args); + + if (window.Sentry) { + window.Sentry.withScope(scope => { + scope.setExtra("args", args); + window.Sentry.captureMessage(internalBuildStringFromArgs(args), "error"); + }); + } +} + +function prepareArgsForLogging(args) { + let result = []; + for (let i = 0; i < args.length; ++i) { + result.push(prepareObjectForLogging(args[i])); + } + return result; +} + +/** + * @param {Array} args + */ +function internalBuildStringFromArgs(args) { + let result = []; + + for (let i = 0; i < args.length; ++i) { + let arg = args[i]; + if ( + typeof arg === "string" || + typeof arg === "number" || + typeof arg === "boolean" || + arg === null || + arg === undefined + ) { + result.push("" + arg); + } else if (arg instanceof Error) { + result.push(arg.message); + } else { + result.push("[object]"); + } + } + return result.join(" "); +} + +export function logSection(name, color) { + while (name.length <= 14) { + name = " " + name + " "; + } + name = name.padEnd(19, " "); + + const lineCss = + "letter-spacing: -3px; color: " + color + "; font-size: 6px; background: #eee; color: #eee;"; + const line = "%c----------------------------"; + console.log("\n" + line + " %c" + name + " " + line + "\n", lineCss, "color: " + color, lineCss); +} + +function extractHandleContext(handle) { + let context = handle || "unknown"; + if (handle && handle.constructor && handle.constructor.name) { + context = handle.constructor.name; + if (context === "String") { + context = handle; + } + } + + if (handle && handle.name) { + context = handle.name; + } + return context + ""; +} + +function logInternal(handle, consoleMethod, args) { + const context = extractHandleContext(handle).padEnd(20, " "); + const labelColor = handle && handle.LOG_LABEL_COLOR ? handle.LOG_LABEL_COLOR : "#aaa"; + + if (G_IS_DEV && globalConfig.debug.logTimestamps) { + const timestamp = "⏱ %c" + (Math_floor(performanceNow()) + "").padEnd(6, " ") + ""; + consoleMethod.call( + console, + timestamp + " %c" + context, + "color: #7f7;", + "color: " + labelColor + ";", + ...args + ); + } else { + if (G_IS_DEV && !globalConfig.debug.disableLoggingLogSources) { + consoleMethod.call(console, "%c" + context, "color: " + labelColor, ...args); + } else { + consoleMethod.call(console, ...args); + } + } +} diff --git a/src/js/core/lzstring.js b/src/js/core/lzstring.js new file mode 100644 index 00000000..79d0523c --- /dev/null +++ b/src/js/core/lzstring.js @@ -0,0 +1,493 @@ +// Copyright (c) 2013 Pieroxy +// This work is free. You can redistribute it and/or modify it +// under the terms of the WTFPL, Version 2 +// For more information see LICENSE.txt or http://www.wtfpl.net/ +// +// For more information, the home page: +// http://pieroxy.net/blog/pages/lz-string/testing.html +// +// LZ-based compression algorithm, version 1.4.4 + +const fromCharCode = String.fromCharCode; +const hasOwnProperty = Object.prototype.hasOwnProperty; + +const keyStrUriSafe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$"; +const baseReverseDic = {}; + +function getBaseValue(alphabet, character) { + if (!baseReverseDic[alphabet]) { + baseReverseDic[alphabet] = {}; + for (let i = 0; i < alphabet.length; i++) { + baseReverseDic[alphabet][alphabet.charAt(i)] = i; + } + } + return baseReverseDic[alphabet][character]; +} + +//compress into uint8array (UCS-2 big endian format) +export function compressU8(uncompressed) { + let compressed = compress(uncompressed); + let buf = new Uint8Array(compressed.length * 2); // 2 bytes per character + + for (let i = 0, TotalLen = compressed.length; i < TotalLen; i++) { + let current_value = compressed.charCodeAt(i); + buf[i * 2] = current_value >>> 8; + buf[i * 2 + 1] = current_value % 256; + } + return buf; +} + +// Compreses with header +/** + * @param {string} uncompressed + * @param {number} header + */ +export function compressU8WHeader(uncompressed, header) { + let compressed = compress(uncompressed); + let buf = new Uint8Array(2 + compressed.length * 2); // 2 bytes per character + + buf[0] = header >>> 8; + buf[1] = header % 256; + for (let i = 0, TotalLen = compressed.length; i < TotalLen; i++) { + let current_value = compressed.charCodeAt(i); + buf[2 + i * 2] = current_value >>> 8; + buf[2 + i * 2 + 1] = current_value % 256; + } + return buf; +} + +//decompress from uint8array (UCS-2 big endian format) +/** + * + * @param {Uint8Array} compressed + */ +export function decompressU8WHeader(compressed) { + // let buf = new Array(compressed.length / 2); // 2 bytes per character + // for (let i = 0, TotalLen = buf.length; i < TotalLen; i++) { + // buf[i] = compressed[i * 2] * 256 + compressed[i * 2 + 1]; + // } + + // let result = []; + // buf.forEach(function (c) { + // result.push(fromCharCode(c)); + // }); + let result = []; + for (let i = 2, n = compressed.length; i < n; i += 2) { + const code = compressed[i] * 256 + compressed[i + 1]; + result.push(fromCharCode(code)); + } + return decompress(result.join("")); +} + +//compress into a string that is already URI encoded +export function compressX64(input) { + if (input == null) return ""; + return _compress(input, 6, function (a) { + return keyStrUriSafe.charAt(a); + }); +} + +//decompress from an output of compressToEncodedURIComponent +export function decompressX64(input) { + if (input == null) return ""; + if (input == "") return null; + input = input.replace(/ /g, "+"); + return _decompress(input.length, 32, function (index) { + return getBaseValue(keyStrUriSafe, input.charAt(index)); + }); +} + +function compress(uncompressed) { + return _compress(uncompressed, 16, function (a) { + return fromCharCode(a); + }); +} + +function _compress(uncompressed, bitsPerChar, getCharFromInt) { + if (uncompressed == null) return ""; + let i, + value, + context_dictionary = {}, + context_dictionaryToCreate = {}, + context_c = "", + context_wc = "", + context_w = "", + context_enlargeIn = 2, // Compensate for the first entry which should not count + context_dictSize = 3, + context_numBits = 2, + context_data = [], + context_data_val = 0, + context_data_position = 0, + ii; + + for (ii = 0; ii < uncompressed.length; ii += 1) { + context_c = uncompressed.charAt(ii); + if (!hasOwnProperty.call(context_dictionary, context_c)) { + context_dictionary[context_c] = context_dictSize++; + context_dictionaryToCreate[context_c] = true; + } + + context_wc = context_w + context_c; + if (hasOwnProperty.call(context_dictionary, context_wc)) { + context_w = context_wc; + } else { + if (hasOwnProperty.call(context_dictionaryToCreate, context_w)) { + if (context_w.charCodeAt(0) < 256) { + for (i = 0; i < context_numBits; i++) { + context_data_val = context_data_val << 1; + if (context_data_position == bitsPerChar - 1) { + context_data_position = 0; + context_data.push(getCharFromInt(context_data_val)); + context_data_val = 0; + } else { + context_data_position++; + } + } + value = context_w.charCodeAt(0); + for (i = 0; i < 8; i++) { + context_data_val = (context_data_val << 1) | (value & 1); + if (context_data_position == bitsPerChar - 1) { + context_data_position = 0; + context_data.push(getCharFromInt(context_data_val)); + context_data_val = 0; + } else { + context_data_position++; + } + value = value >> 1; + } + } else { + value = 1; + for (i = 0; i < context_numBits; i++) { + context_data_val = (context_data_val << 1) | value; + if (context_data_position == bitsPerChar - 1) { + context_data_position = 0; + context_data.push(getCharFromInt(context_data_val)); + context_data_val = 0; + } else { + context_data_position++; + } + value = 0; + } + value = context_w.charCodeAt(0); + for (i = 0; i < 16; i++) { + context_data_val = (context_data_val << 1) | (value & 1); + if (context_data_position == bitsPerChar - 1) { + context_data_position = 0; + context_data.push(getCharFromInt(context_data_val)); + context_data_val = 0; + } else { + context_data_position++; + } + value = value >> 1; + } + } + context_enlargeIn--; + if (context_enlargeIn == 0) { + context_enlargeIn = Math.pow(2, context_numBits); + context_numBits++; + } + delete context_dictionaryToCreate[context_w]; + } else { + value = context_dictionary[context_w]; + for (i = 0; i < context_numBits; i++) { + context_data_val = (context_data_val << 1) | (value & 1); + if (context_data_position == bitsPerChar - 1) { + context_data_position = 0; + context_data.push(getCharFromInt(context_data_val)); + context_data_val = 0; + } else { + context_data_position++; + } + value = value >> 1; + } + } + context_enlargeIn--; + if (context_enlargeIn == 0) { + context_enlargeIn = Math.pow(2, context_numBits); + context_numBits++; + } + // Add wc to the dictionary. + context_dictionary[context_wc] = context_dictSize++; + context_w = String(context_c); + } + } + + // Output the code for w. + if (context_w !== "") { + if (hasOwnProperty.call(context_dictionaryToCreate, context_w)) { + if (context_w.charCodeAt(0) < 256) { + for (i = 0; i < context_numBits; i++) { + context_data_val = context_data_val << 1; + if (context_data_position == bitsPerChar - 1) { + context_data_position = 0; + context_data.push(getCharFromInt(context_data_val)); + context_data_val = 0; + } else { + context_data_position++; + } + } + value = context_w.charCodeAt(0); + for (i = 0; i < 8; i++) { + context_data_val = (context_data_val << 1) | (value & 1); + if (context_data_position == bitsPerChar - 1) { + context_data_position = 0; + context_data.push(getCharFromInt(context_data_val)); + context_data_val = 0; + } else { + context_data_position++; + } + value = value >> 1; + } + } else { + value = 1; + for (i = 0; i < context_numBits; i++) { + context_data_val = (context_data_val << 1) | value; + if (context_data_position == bitsPerChar - 1) { + context_data_position = 0; + context_data.push(getCharFromInt(context_data_val)); + context_data_val = 0; + } else { + context_data_position++; + } + value = 0; + } + value = context_w.charCodeAt(0); + for (i = 0; i < 16; i++) { + context_data_val = (context_data_val << 1) | (value & 1); + if (context_data_position == bitsPerChar - 1) { + context_data_position = 0; + context_data.push(getCharFromInt(context_data_val)); + context_data_val = 0; + } else { + context_data_position++; + } + value = value >> 1; + } + } + context_enlargeIn--; + if (context_enlargeIn == 0) { + context_enlargeIn = Math.pow(2, context_numBits); + context_numBits++; + } + delete context_dictionaryToCreate[context_w]; + } else { + value = context_dictionary[context_w]; + for (i = 0; i < context_numBits; i++) { + context_data_val = (context_data_val << 1) | (value & 1); + if (context_data_position == bitsPerChar - 1) { + context_data_position = 0; + context_data.push(getCharFromInt(context_data_val)); + context_data_val = 0; + } else { + context_data_position++; + } + value = value >> 1; + } + } + context_enlargeIn--; + if (context_enlargeIn == 0) { + context_enlargeIn = Math.pow(2, context_numBits); + context_numBits++; + } + } + + // Mark the end of the stream + value = 2; + for (i = 0; i < context_numBits; i++) { + context_data_val = (context_data_val << 1) | (value & 1); + if (context_data_position == bitsPerChar - 1) { + context_data_position = 0; + context_data.push(getCharFromInt(context_data_val)); + context_data_val = 0; + } else { + context_data_position++; + } + value = value >> 1; + } + + // Flush the last char + // eslint-disable-next-line no-constant-condition + while (true) { + context_data_val = context_data_val << 1; + if (context_data_position == bitsPerChar - 1) { + context_data.push(getCharFromInt(context_data_val)); + break; + } else context_data_position++; + } + return context_data.join(""); +} + +function decompress(compressed) { + if (compressed == null) return ""; + if (compressed == "") return null; + return _decompress(compressed.length, 32768, function (index) { + return compressed.charCodeAt(index); + }); +} + +function _decompress(length, resetValue, getNextValue) { + let dictionary = [], + next, + enlargeIn = 4, + dictSize = 4, + numBits = 3, + entry = "", + result = [], + i, + w, + bits, + resb, + maxpower, + power, + c, + data = { val: getNextValue(0), position: resetValue, index: 1 }; + + for (i = 0; i < 3; i += 1) { + dictionary[i] = i; + } + + bits = 0; + maxpower = Math.pow(2, 2); + power = 1; + while (power != maxpower) { + resb = data.val & data.position; + data.position >>= 1; + if (data.position == 0) { + data.position = resetValue; + data.val = getNextValue(data.index++); + } + bits |= (resb > 0 ? 1 : 0) * power; + power <<= 1; + } + + switch ((next = bits)) { + case 0: + bits = 0; + maxpower = Math.pow(2, 8); + power = 1; + while (power != maxpower) { + resb = data.val & data.position; + data.position >>= 1; + if (data.position == 0) { + data.position = resetValue; + data.val = getNextValue(data.index++); + } + bits |= (resb > 0 ? 1 : 0) * power; + power <<= 1; + } + c = fromCharCode(bits); + break; + case 1: + bits = 0; + maxpower = Math.pow(2, 16); + power = 1; + while (power != maxpower) { + resb = data.val & data.position; + data.position >>= 1; + if (data.position == 0) { + data.position = resetValue; + data.val = getNextValue(data.index++); + } + bits |= (resb > 0 ? 1 : 0) * power; + power <<= 1; + } + c = fromCharCode(bits); + break; + case 2: + return ""; + } + dictionary[3] = c; + w = c; + result.push(c); + + // eslint-disable-next-line no-constant-condition + while (true) { + if (data.index > length) { + return ""; + } + + bits = 0; + maxpower = Math.pow(2, numBits); + power = 1; + while (power != maxpower) { + resb = data.val & data.position; + data.position >>= 1; + if (data.position == 0) { + data.position = resetValue; + data.val = getNextValue(data.index++); + } + bits |= (resb > 0 ? 1 : 0) * power; + power <<= 1; + } + + switch ((c = bits)) { + case 0: + bits = 0; + maxpower = Math.pow(2, 8); + power = 1; + while (power != maxpower) { + resb = data.val & data.position; + data.position >>= 1; + if (data.position == 0) { + data.position = resetValue; + data.val = getNextValue(data.index++); + } + bits |= (resb > 0 ? 1 : 0) * power; + power <<= 1; + } + + dictionary[dictSize++] = fromCharCode(bits); + c = dictSize - 1; + enlargeIn--; + break; + case 1: + bits = 0; + maxpower = Math.pow(2, 16); + power = 1; + while (power != maxpower) { + resb = data.val & data.position; + data.position >>= 1; + if (data.position == 0) { + data.position = resetValue; + data.val = getNextValue(data.index++); + } + bits |= (resb > 0 ? 1 : 0) * power; + power <<= 1; + } + dictionary[dictSize++] = fromCharCode(bits); + c = dictSize - 1; + enlargeIn--; + break; + case 2: + return result.join(""); + } + + if (enlargeIn == 0) { + enlargeIn = Math.pow(2, numBits); + numBits++; + } + + if (dictionary[c]) { + // @ts-ignore + entry = dictionary[c]; + } else { + if (c === dictSize) { + entry = w + w.charAt(0); + } else { + return null; + } + } + result.push(entry); + + // Add w+entry[0] to the dictionary. + dictionary[dictSize++] = w + entry.charAt(0); + enlargeIn--; + + w = entry; + + if (enlargeIn == 0) { + enlargeIn = Math.pow(2, numBits); + numBits++; + } + } +} diff --git a/src/js/core/perlin_noise.js b/src/js/core/perlin_noise.js new file mode 100644 index 00000000..0cce61ed --- /dev/null +++ b/src/js/core/perlin_noise.js @@ -0,0 +1,175 @@ +import { perlinNoiseData } from "./perlin_noise_data"; +import { Math_sqrt } from "./builtins"; + +class Grad { + constructor(x, y, z) { + this.x = x; + this.y = y; + this.z = z; + } + + dot2(x, y) { + return this.x * x + this.y * y; + } + + dot3(x, y, z) { + return this.x * x + this.y * y + this.z * z; + } +} + +function fade(t) { + return t * t * t * (t * (t * 6 - 15) + 10); +} + +function lerp(a, b, t) { + return (1 - t) * a + t * b; +} + +const F2 = 0.5 * (Math_sqrt(3) - 1); +const G2 = (3 - Math_sqrt(3)) / 6; + +const F3 = 1 / 3; +const G3 = 1 / 6; + +export class PerlinNoise { + constructor(seed) { + this.perm = new Array(512); + this.gradP = new Array(512); + this.grad3 = [ + new Grad(1, 1, 0), + new Grad(-1, 1, 0), + new Grad(1, -1, 0), + new Grad(-1, -1, 0), + new Grad(1, 0, 1), + new Grad(-1, 0, 1), + new Grad(1, 0, -1), + new Grad(-1, 0, -1), + new Grad(0, 1, 1), + new Grad(0, -1, 1), + new Grad(0, 1, -1), + new Grad(0, -1, -1), + ]; + + this.seed = seed; + this.initializeFromSeed(seed); + } + + initializeFromSeed(seed) { + const P = perlinNoiseData; + + if (seed > 0 && seed < 1) { + // Scale the seed out + seed *= 65536; + } + + seed = Math.floor(seed); + if (seed < 256) { + seed |= seed << 8; + } + + for (let i = 0; i < 256; i++) { + let v; + if (i & 1) { + v = P[i] ^ (seed & 255); + } else { + v = P[i] ^ ((seed >> 8) & 255); + } + + this.perm[i] = this.perm[i + 256] = v; + this.gradP[i] = this.gradP[i + 256] = this.grad3[v % 12]; + } + } + + /** + * 2d Perlin Noise + * @param {number} x + * @param {number} y + * @returns {number} + */ + computePerlin2(x, y) { + // Find unit grid cell containing point + let X = Math.floor(x), + Y = Math.floor(y); + + // Get relative xy coordinates of point within that cell + x = x - X; + y = y - Y; + + // Wrap the integer cells at 255 (smaller integer period can be introduced here) + X = X & 255; + Y = Y & 255; + + // Calculate noise contributions from each of the four corners + let n00 = this.gradP[X + this.perm[Y]].dot2(x, y); + let n01 = this.gradP[X + this.perm[Y + 1]].dot2(x, y - 1); + let n10 = this.gradP[X + 1 + this.perm[Y]].dot2(x - 1, y); + let n11 = this.gradP[X + 1 + this.perm[Y + 1]].dot2(x - 1, y - 1); + + // Compute the fade curve value for x + let u = fade(x); + + // Interpolate the four results + return lerp(lerp(n00, n10, u), lerp(n01, n11, u), fade(y)); + } + + computeSimplex2(xin, yin) { + var n0, n1, n2; // Noise contributions from the three corners + // Skew the input space to determine which simplex cell we're in + var s = (xin + yin) * F2; // Hairy factor for 2D + var i = Math.floor(xin + s); + var j = Math.floor(yin + s); + var t = (i + j) * G2; + var x0 = xin - i + t; // The x,y distances from the cell origin, unskewed. + var y0 = yin - j + t; + // For the 2D case, the simplex shape is an equilateral triangle. + // Determine which simplex we are in. + var i1, j1; // Offsets for second (middle) corner of simplex in (i,j) coords + if (x0 > y0) { + // lower triangle, XY order: (0,0)->(1,0)->(1,1) + i1 = 1; + j1 = 0; + } else { + // upper triangle, YX order: (0,0)->(0,1)->(1,1) + i1 = 0; + j1 = 1; + } + // A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and + // a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where + // c = (3-sqrt(3))/6 + var x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords + var y1 = y0 - j1 + G2; + var x2 = x0 - 1 + 2 * G2; // Offsets for last corner in (x,y) unskewed coords + var y2 = y0 - 1 + 2 * G2; + // Work out the hashed gradient indices of the three simplex corners + i &= 255; + j &= 255; + var gi0 = this.gradP[i + this.perm[j]]; + var gi1 = this.gradP[i + i1 + this.perm[j + j1]]; + var gi2 = this.gradP[i + 1 + this.perm[j + 1]]; + // Calculate the contribution from the three corners + var t0 = 0.5 - x0 * x0 - y0 * y0; + if (t0 < 0) { + n0 = 0; + } else { + t0 *= t0; + n0 = t0 * t0 * gi0.dot2(x0, y0); // (x,y) of grad3 used for 2D gradient + } + var t1 = 0.5 - x1 * x1 - y1 * y1; + if (t1 < 0) { + n1 = 0; + } else { + t1 *= t1; + n1 = t1 * t1 * gi1.dot2(x1, y1); + } + var t2 = 0.5 - x2 * x2 - y2 * y2; + if (t2 < 0) { + n2 = 0; + } else { + t2 *= t2; + n2 = t2 * t2 * gi2.dot2(x2, y2); + } + // Add contributions from each corner to get the final noise value. + // The result is scaled to return values in the interval [-1,1]. + return 70 * (n0 + n1 + n2); + } +} diff --git a/src/js/core/perlin_noise_data.js b/src/js/core/perlin_noise_data.js new file mode 100644 index 00000000..14a25ba0 --- /dev/null +++ b/src/js/core/perlin_noise_data.js @@ -0,0 +1,258 @@ +export const perlinNoiseData = [ + 151, + 160, + 137, + 91, + 90, + 15, + 131, + 13, + 201, + 95, + 96, + 53, + 194, + 233, + 7, + 225, + 140, + 36, + 103, + 30, + 69, + 142, + 8, + 99, + 37, + 240, + 21, + 10, + 23, + 190, + 6, + 148, + 247, + 120, + 234, + 75, + 0, + 26, + 197, + 62, + 94, + 252, + 219, + 203, + 117, + 35, + 11, + 32, + 57, + 177, + 33, + 88, + 237, + 149, + 56, + 87, + 174, + 20, + 125, + 136, + 171, + 168, + 68, + 175, + 74, + 165, + 71, + 134, + 139, + 48, + 27, + 166, + 77, + 146, + 158, + 231, + 83, + 111, + 229, + 122, + 60, + 211, + 133, + 230, + 220, + 105, + 92, + 41, + 55, + 46, + 245, + 40, + 244, + 102, + 143, + 54, + 65, + 25, + 63, + 161, + 1, + 216, + 80, + 73, + 209, + 76, + 132, + 187, + 208, + 89, + 18, + 169, + 200, + 196, + 135, + 130, + 116, + 188, + 159, + 86, + 164, + 100, + 109, + 198, + 173, + 186, + 3, + 64, + 52, + 217, + 226, + 250, + 124, + 123, + 5, + 202, + 38, + 147, + 118, + 126, + 255, + 82, + 85, + 212, + 207, + 206, + 59, + 227, + 47, + 16, + 58, + 17, + 182, + 189, + 28, + 42, + 223, + 183, + 170, + 213, + 119, + 248, + 152, + 2, + 44, + 154, + 163, + 70, + 221, + 153, + 101, + 155, + 167, + 43, + 172, + 9, + 129, + 22, + 39, + 253, + 19, + 98, + 108, + 110, + 79, + 113, + 224, + 232, + 178, + 185, + 112, + 104, + 218, + 246, + 97, + 228, + 251, + 34, + 242, + 193, + 238, + 210, + 144, + 12, + 191, + 179, + 162, + 241, + 81, + 51, + 145, + 235, + 249, + 14, + 239, + 107, + 49, + 192, + 214, + 31, + 181, + 199, + 106, + 157, + 184, + 84, + 204, + 176, + 115, + 121, + 50, + 45, + 127, + 4, + 150, + 254, + 138, + 236, + 205, + 93, + 222, + 114, + 67, + 29, + 24, + 72, + 243, + 141, + 128, + 195, + 78, + 66, + 215, + 61, + 156, + 180, +]; diff --git a/src/js/core/polyfills.js b/src/js/core/polyfills.js new file mode 100644 index 00000000..22688836 --- /dev/null +++ b/src/js/core/polyfills.js @@ -0,0 +1,69 @@ +function mathPolyfills() { + // Converts from degrees to radians. + Math.radians = function (degrees) { + return (degrees * Math_PI) / 180.0; + }; + + // Converts from radians to degrees. + Math.degrees = function (radians) { + return (radians * 180.0) / Math_PI; + }; +} + +function stringPolyfills() { + // https://github.com/uxitten/polyfill/blob/master/string.polyfill.js + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart + if (!String.prototype.padStart) { + String.prototype.padStart = function padStart(targetLength, padString) { + targetLength = targetLength >> 0; //truncate if number, or convert non-number to 0; + padString = String(typeof padString !== "undefined" ? padString : " "); + if (this.length >= targetLength) { + return String(this); + } else { + targetLength = targetLength - this.length; + if (targetLength > padString.length) { + padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed + } + return padString.slice(0, targetLength) + String(this); + } + }; + } + + // https://github.com/uxitten/polyfill/blob/master/string.polyfill.js + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd + if (!String.prototype.padEnd) { + String.prototype.padEnd = function padEnd(targetLength, padString) { + targetLength = targetLength >> 0; //floor if number or convert non-number to 0; + padString = String(typeof padString !== "undefined" ? padString : " "); + if (this.length > targetLength) { + return String(this); + } else { + targetLength = targetLength - this.length; + if (targetLength > padString.length) { + padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed + } + return String(this) + padString.slice(0, targetLength); + } + }; + } +} + +function initPolyfills() { + mathPolyfills(); + stringPolyfills(); +} + +function initExtensions() { + String.prototype.replaceAll = function (search, replacement) { + var target = this; + return target.split(search).join(replacement); + }; +} + +// Fetch polyfill +import "whatwg-fetch"; +import { Math_PI } from "./builtins"; + +// Other polyfills +initPolyfills(); +initExtensions(); diff --git a/src/js/core/query_parameters.js b/src/js/core/query_parameters.js new file mode 100644 index 00000000..b3dab1b3 --- /dev/null +++ b/src/js/core/query_parameters.js @@ -0,0 +1,10 @@ +const queryString = require("query-string"); +const options = queryString.parse(location.search); + +export let queryParamOptions = { + embedProvider: null, +}; + +if (options.embed) { + queryParamOptions.embedProvider = options.embed; +} diff --git a/src/js/core/read_write_proxy.js b/src/js/core/read_write_proxy.js new file mode 100644 index 00000000..07bf5667 --- /dev/null +++ b/src/js/core/read_write_proxy.js @@ -0,0 +1,300 @@ +/* typehints:start */ +import { Application } from "../application"; +/* typehints:end */ + +import { sha1 } from "./sensitive_utils.encrypt"; +import { createLogger } from "./logging"; +import { FILE_NOT_FOUND } from "../platform/storage"; +import { accessNestedPropertyReverse } from "./utils"; +import { IS_DEBUG, globalConfig } from "./config"; +import { JSON_stringify, JSON_parse } from "./builtins"; +import { ExplainedResult } from "./explained_result"; +import { decompressX64, compressX64 } from ".//lzstring"; +import { asyncCompressor, compressionPrefix } from "./async_compression"; + +const logger = createLogger("read_write_proxy"); + +const salt = accessNestedPropertyReverse(globalConfig, ["file", "info"]); + +// Helper which only writes / reads if verify() works. Also performs migration +export class ReadWriteProxy { + constructor(app, filename) { + /** @type {Application} */ + this.app = app; + + this.filename = filename; + + /** @type {object} */ + this.currentData = null; + + // TODO: EXTREMELY HACKY! To verify we need to do this a step later + if (G_IS_DEV && IS_DEBUG) { + setTimeout(() => { + assert( + this.verify(this.getDefaultData()).result, + "Verify() failed for default data: " + this.verify(this.getDefaultData()).reason + ); + }); + } + } + + // -- Methods to override + + /** @returns {ExplainedResult} */ + verify(data) { + abstract; + return ExplainedResult.bad(); + } + + // Should return the default data + getDefaultData() { + abstract; + return {}; + } + + // Should return the current version as an integer + getCurrentVersion() { + abstract; + return 0; + } + + // Should migrate the data (Modify in place) + /** @returns {ExplainedResult} */ + migrate(data) { + abstract; + return ExplainedResult.bad(); + } + + // -- / Methods + + // Resets whole data, returns promise + resetEverythingAsync() { + logger.warn("Reset data to default"); + this.currentData = this.getDefaultData(); + return this.writeAsync(); + } + + getCurrentData() { + return this.currentData; + } + + /** + * Writes the data asychronously, fails if verify() fails + * @returns {Promise} + */ + writeAsync() { + const verifyResult = this.internalVerifyEntry(this.currentData); + + if (!verifyResult.result) { + logger.error("Tried to write invalid data to", this.filename, "reason:", verifyResult.reason); + return Promise.reject(verifyResult.reason); + } + const jsonString = JSON_stringify(this.currentData); + + if (!this.app.pageVisible || this.app.unloaded) { + logger.log("Saving file sync because in unload handler"); + const checksum = sha1(jsonString + salt); + let compressed = compressionPrefix + compressX64(checksum + jsonString); + if (G_IS_DEV && IS_DEBUG) { + compressed = jsonString; + } + + if (!this.app.storage.writeFileSyncIfSupported(this.filename, compressed)) { + return Promise.reject("Failed to write " + this.filename + " sync!"); + } else { + logger.log("📄 Wrote (sync!)", this.filename); + return Promise.resolve(compressed); + } + } + + return asyncCompressor + .compressFileAsync(jsonString) + .then(compressed => { + if (G_IS_DEV && IS_DEBUG) { + compressed = jsonString; + } + return this.app.storage.writeFileAsync(this.filename, compressed); + }) + .then(() => { + logger.log("📄 Wrote", this.filename); + return jsonString; + }) + .catch(err => { + logger.error("Failed to write", this.filename, ":", err); + throw err; + }); + } + + // Reads the data asynchronously, fails if verify() fails + readAsync() { + // Start read request + return ( + this.app.storage + .readFileAsync(this.filename) + + // Check for errors during read + .catch(err => { + if (err === FILE_NOT_FOUND) { + logger.log("File not found, using default data"); + + // File not found or unreadable, assume default file + return Promise.resolve(null); + } + + return Promise.reject("file-error: " + err); + }) + + // Decrypt data (if its encrypted) + // @ts-ignore + .then(rawData => { + if (rawData == null) { + // So, the file has not been found, use default data + return JSON_stringify(this.getDefaultData()); + } + + if (rawData.startsWith(compressionPrefix)) { + const decompressed = decompressX64(rawData.substr(compressionPrefix.length)); + if (!decompressed) { + // LZ string decompression failure + return Promise.reject("bad-content / decompression-failed"); + } + if (decompressed.length < 40) { + // String too short + return Promise.reject("bad-content / payload-too-small"); + } + + // Compare stored checksum with actual checksum + const checksum = decompressed.substring(0, 40); + const jsonString = decompressed.substr(40); + const desiredChecksum = sha1(jsonString + salt); + if (desiredChecksum !== checksum) { + // Checksum mismatch + return Promise.reject("bad-content / checksum-mismatch"); + } + return jsonString; + } else { + if (!G_IS_DEV) { + return Promise.reject("bad-content / missing-compression"); + } + } + return rawData; + }) + + // Parse JSON, this could throw but thats fine + .then(res => { + try { + return JSON_parse(res); + } catch (ex) { + logger.error( + "Failed to parse file content of", + this.filename, + ":", + ex, + "(content was:", + res, + ")" + ); + throw new Error("invalid-serialized-data"); + } + }) + + // Verify basic structure + .then(contents => { + const result = this.internalVerifyBasicStructure(contents); + if (!result.isGood()) { + return Promise.reject("verify-failed: " + result.reason); + } + return contents; + }) + + // Check version and migrate if required + .then(contents => { + if (contents.version > this.getCurrentVersion()) { + return Promise.reject("stored-data-is-newer"); + } + + if (contents.version < this.getCurrentVersion()) { + logger.log( + "Trying to migrate data object from version", + contents.version, + "to", + this.getCurrentVersion() + ); + const migrationResult = this.migrate(contents); // modify in place + if (migrationResult.isBad()) { + return Promise.reject("migration-failed: " + migrationResult.reason); + } + } + return contents; + }) + + // Verify + .then(contents => { + const verifyResult = this.internalVerifyEntry(contents); + if (!verifyResult.result) { + logger.error( + "Read invalid data from", + this.filename, + "reason:", + verifyResult.reason, + "contents:", + contents + ); + return Promise.reject("invalid-data: " + verifyResult.reason); + } + return contents; + }) + + // Store + .then(contents => { + this.currentData = contents; + logger.log("📄 Read data with version", this.currentData.version, "from", this.filename); + return contents; + }) + + // Catchall + .catch(err => { + return Promise.reject("Failed to read " + this.filename + ": " + err); + }) + ); + } + + /** + * Deletes the file + * @returns {Promise} + */ + deleteAsync() { + return this.app.storage.deleteFileAsync(this.filename); + } + + // Internal + + /** @returns {ExplainedResult} */ + internalVerifyBasicStructure(data) { + if (!data) { + return ExplainedResult.bad("Data is empty"); + } + if (!Number.isInteger(data.version) || data.version < 0) { + return ExplainedResult.bad( + `Data has invalid version: ${data.version} (expected ${this.getCurrentVersion()})` + ); + } + + return ExplainedResult.good(); + } + + /** @returns {ExplainedResult} */ + internalVerifyEntry(data) { + if (data.version !== this.getCurrentVersion()) { + return ExplainedResult.bad( + "Version mismatch, got " + data.version + " and expected " + this.getCurrentVersion() + ); + } + + const verifyStructureError = this.internalVerifyBasicStructure(data); + if (!verifyStructureError.isGood()) { + return verifyStructureError; + } + return this.verify(data); + } +} diff --git a/src/js/core/rectangle.js b/src/js/core/rectangle.js new file mode 100644 index 00000000..e736f9bd --- /dev/null +++ b/src/js/core/rectangle.js @@ -0,0 +1,287 @@ +import { globalConfig } from "./config"; +import { Math_ceil, Math_floor, Math_max, Math_min } from "./builtins"; +import { clamp, epsilonCompare, round2Digits } from "./utils"; +import { Vector } from "./vector"; + +export class Rectangle { + constructor(x = 0, y = 0, w = 0, h = 0) { + this.x = x; + this.y = y; + this.w = w; + this.h = h; + } + + /** + * Creates a rectangle from top right bottom and left offsets + * @param {number} top + * @param {number} right + * @param {number} bottom + * @param {number} left + */ + static fromTRBL(top, right, bottom, left) { + return new Rectangle(left, top, right - left, bottom - top); + } + + /** + * Constructs a new square rectangle + * @param {number} x + * @param {number} y + * @param {number} size + */ + static fromSquare(x, y, size) { + return new Rectangle(x, y, size, size); + } + + /** + * + * @param {Vector} p1 + * @param {Vector} p2 + */ + static fromTwoPoints(p1, p2) { + const left = Math_min(p1.x, p2.x); + const top = Math_min(p1.y, p2.y); + const right = Math_max(p1.x, p2.x); + const bottom = Math_max(p1.y, p2.y); + return new Rectangle(left, top, right - left, bottom - top); + } + + /** + * @param {Rectangle} a + * @param {Rectangle} b + */ + static intersects(a, b) { + return a.left <= b.right && b.left <= a.right && a.top <= b.bottom && b.top <= a.bottom; + } + + /** + * Returns a rectangle arround a rotated point + * @param {Array} points + * @param {number} angle + * @returns {Rectangle} + */ + static getAroundPointsRotated(points, angle) { + let minX = 1e10; + let minY = 1e10; + let maxX = -1e10; + let maxY = -1e10; + for (let i = 0; i < points.length; ++i) { + const rotated = points[i].rotated(angle); + minX = Math_min(minX, rotated.x); + minY = Math_min(minY, rotated.y); + maxX = Math_max(maxX, rotated.x); + maxY = Math_max(maxY, rotated.y); + } + return new Rectangle(minX, minY, maxX - minX, maxY - minY); + } + + // Ensures the rectangle contains the given square + extendBySquare(centerX, centerY, halfWidth, halfHeight) { + if (this.isEmpty()) { + // Just assign values since this rectangle is empty + this.x = centerX - halfWidth; + this.y = centerY - halfHeight; + this.w = halfWidth * 2; + this.h = halfHeight * 2; + // console.log("Assigned", this.x, this.y, this.w, this.h); + } else { + // console.log("before", this.x, this.y, this.w, this.h); + this.setLeft(Math_min(this.x, centerX - halfWidth)); + this.setRight(Math_max(this.right(), centerX + halfWidth)); + this.setTop(Math_min(this.y, centerY - halfHeight)); + this.setBottom(Math_max(this.bottom(), centerY + halfHeight)); + // console.log("Extended", this.x, this.y, this.w, this.h); + } + } + + isEmpty() { + return epsilonCompare(this.w * this.h, 0); + } + + equalsEpsilon(other, epsilon) { + return ( + epsilonCompare(this.x, other.x, epsilon) && + epsilonCompare(this.y, other.y, epsilon) && + epsilonCompare(this.w, other.w, epsilon) && + epsilonCompare(this.h, other.h, epsilon) + ); + } + + left() { + return this.x; + } + + right() { + return this.x + this.w; + } + + top() { + return this.y; + } + + bottom() { + return this.y + this.h; + } + + trbl() { + return [this.y, this.right(), this.bottom(), this.x]; + } + + getCenter() { + return new Vector(this.x + this.w / 2, this.y + this.h / 2); + } + + setRight(right) { + this.w = right - this.x; + } + + setBottom(bottom) { + this.h = bottom - this.y; + } + + // Sets top while keeping bottom + setTop(top) { + const bottom = this.bottom(); + this.y = top; + this.setBottom(bottom); + } + + // Sets left while keeping right + setLeft(left) { + const right = this.right(); + this.x = left; + this.setRight(right); + } + + topLeft() { + return new Vector(this.x, this.y); + } + + bottomRight() { + return new Vector(this.right(), this.bottom()); + } + + moveBy(x, y) { + this.x += x; + this.y += y; + } + + moveByVector(vec) { + this.x += vec.x; + this.y += vec.y; + } + + // Returns a scaled version which also scales the position of the rectangle + allScaled(factor) { + return new Rectangle(this.x * factor, this.y * factor, this.w * factor, this.h * factor); + } + + // Increases the rectangle in all directions + expandInAllDirections(amount) { + this.x -= amount; + this.y -= amount; + this.w += 2 * amount; + this.h += 2 * amount; + return this; + } + + // Culling helpers + getMinStartTile() { + return new Vector(this.x, this.y).snapWorldToTile(); + } + + /** + * Returns if the given rectangle is contained + * @param {Rectangle} rect + * @returns {boolean} + */ + containsRect(rect) { + return ( + this.x <= rect.right() && + rect.x <= this.right() && + this.y <= rect.bottom() && + rect.y <= this.bottom() + ); + } + + containsRect4Params(x, y, w, h) { + return this.x <= x + w && x <= this.right() && this.y <= y + h && y <= this.bottom(); + } + + /** + * Returns if the rectangle contains the given circle at (x, y) with the radius (radius) + * @param {number} x + * @param {number} y + * @param {number} radius + */ + containsCircle(x, y, radius) { + return ( + this.x <= x + radius && + x - radius <= this.right() && + this.y <= y + radius && + y - radius <= this.bottom() + ); + } + + /** + * Returns if hte rectangle contains the given point + * @param {number} x + * @param {number} y + */ + containsPoint(x, y) { + return x >= this.x && x < this.right() && y >= this.y && y < this.bottom(); + } + + /** + * Returns the shared area with another rectangle, or null if there is no intersection + * @param {Rectangle} rect + * @returns {Rectangle|null} + */ + getUnion(rect) { + const left = Math_max(this.x, rect.x); + const top = Math_max(this.y, rect.y); + + const right = Math_min(this.x + this.w, rect.x + rect.w); + const bottom = Math_min(this.y + this.h, rect.y + rect.h); + + if (right <= left || bottom <= top) { + return null; + } + return Rectangle.fromTRBL(top, right, bottom, left); + } + + /** + * Good for caching stuff + */ + toCompareableString() { + return ( + round2Digits(this.x) + + "/" + + round2Digits(this.y) + + "/" + + round2Digits(this.w) + + "/" + + round2Digits(this.h) + ); + } + + /** + * Returns a new recangle in tile space which includes all tiles which are visible in this rect + * @param {boolean=} includeHalfTiles + * @returns {Rectangle} + */ + toTileCullRectangle(includeHalfTiles = true) { + let scaled = this.allScaled(1.0 / globalConfig.tileSize); + + if (includeHalfTiles) { + // Increase rectangle size + scaled = Rectangle.fromTRBL( + Math_floor(scaled.y), + Math_ceil(scaled.right()), + Math_ceil(scaled.bottom()), + Math_floor(scaled.x) + ); + } + + return scaled; + } +} diff --git a/src/js/core/request_channel.js b/src/js/core/request_channel.js new file mode 100644 index 00000000..b5b8c81f --- /dev/null +++ b/src/js/core/request_channel.js @@ -0,0 +1,72 @@ +import { createLogger } from "../core/logging"; +import { fastArrayDeleteValueIfContained } from "../core/utils"; + +const logger = createLogger("request_channel"); + +// Thrown when a request is aborted +export const PROMISE_ABORTED = "promise-aborted"; + +export class RequestChannel { + constructor() { + /** @type {Array} */ + this.pendingPromises = []; + } + + /** + * + * @param {Promise} promise + * @returns {Promise} + */ + watch(promise) { + // log(this, "Added new promise:", promise, "(pending =", this.pendingPromises.length, ")"); + let cancelled = false; + const wrappedPromise = new Promise((resolve, reject) => { + promise.then( + result => { + // Remove from pending promises + fastArrayDeleteValueIfContained(this.pendingPromises, wrappedPromise); + + // If not cancelled, resolve promise with same payload + if (!cancelled) { + resolve.call(this, result); + } else { + logger.warn("Not resolving because promise got cancelled"); + // reject.call(this, PROMISE_ABORTED); + } + }, + err => { + // Remove from pending promises + fastArrayDeleteValueIfContained(this.pendingPromises, wrappedPromise); + + // If not cancelled, reject promise with same payload + if (!cancelled) { + reject.call(this, err); + } else { + logger.warn("Not rejecting because promise got cancelled"); + // reject.call(this, PROMISE_ABORTED); + } + } + ); + }); + + // Add cancel handler + // @ts-ignore + wrappedPromise.cancel = function () { + cancelled = true; + }; + + this.pendingPromises.push(wrappedPromise); + return wrappedPromise; + } + + cancelAll() { + if (this.pendingPromises.length > 0) { + logger.log("Cancel all pending promises (", this.pendingPromises.length, ")"); + } + for (let i = 0; i < this.pendingPromises.length; ++i) { + // @ts-ignore + this.pendingPromises[i].cancel(); + } + this.pendingPromises = []; + } +} diff --git a/src/js/core/rng.js b/src/js/core/rng.js new file mode 100644 index 00000000..0653b95c --- /dev/null +++ b/src/js/core/rng.js @@ -0,0 +1,133 @@ +import { Math_random } from "./builtins"; + +// ALEA RNG + +function Mash() { + var n = 0xefc8249d; + return function (data) { + data = data.toString(); + for (var i = 0; i < data.length; i++) { + n += data.charCodeAt(i); + var h = 0.02519603282416938 * n; + n = h >>> 0; + h -= n; + h *= n; + n = h >>> 0; + h -= n; + n += h * 0x100000000; // 2^32 + } + return (n >>> 0) * 2.3283064365386963e-10; // 2^-32 + }; +} + +/** + * @param {number|string} seed + */ +function makeNewRng(seed) { + // Johannes Baagøe , 2010 + var c = 1; + var mash = Mash(); + let s0 = mash(" "); + let s1 = mash(" "); + let s2 = mash(" "); + + s0 -= mash(seed); + if (s0 < 0) { + s0 += 1; + } + s1 -= mash(seed); + if (s1 < 0) { + s1 += 1; + } + s2 -= mash(seed); + if (s2 < 0) { + s2 += 1; + } + mash = null; + + var random = function () { + var t = 2091639 * s0 + c * 2.3283064365386963e-10; // 2^-32 + s0 = s1; + s1 = s2; + return (s2 = t - (c = t | 0)); + }; + + random.exportState = function () { + return [s0, s1, s2, c]; + }; + + random.importState = function (i) { + s0 = +i[0] || 0; + s1 = +i[1] || 0; + s2 = +i[2] || 0; + c = +i[3] || 0; + }; + + return random; +} + +export class RandomNumberGenerator { + /** + * + * @param {number|string=} seed + */ + constructor(seed) { + this.internalRng = makeNewRng(seed || Math_random()); + } + + /** + * Re-seeds the generator + * @param {number|string} seed + */ + reseed(seed) { + this.internalRng = makeNewRng(seed || Math_random()); + } + + /** + * @returns {number} between 0 and 1 + */ + next() { + return this.internalRng(); + } + + /** + * @param {number} min + * @param {number} max + * @returns {number} Integer in range [min, max[ + */ + nextIntRange(min, max) { + assert(Number.isFinite(min), "Minimum is no integer"); + assert(Number.isFinite(max), "Maximum is no integer"); + assert(max > min, "rng: max <= min"); + return Math.floor(this.next() * (max - min) + min); + } + /** + * @param {number} min + * @param {number} max + * @returns {number} Integer in range [min, max] + */ + nextIntRangeInclusive(min, max) { + assert(Number.isFinite(min), "Minimum is no integer"); + assert(Number.isFinite(max), "Maximum is no integer"); + assert(max > min, "rng: max <= min"); + return Math.round(this.next() * (max - min) + min); + } + + /** + * @param {number} min + * @param {number} max + * @returns {number} Number in range [min, max[ + */ + nextRange(min, max) { + assert(max > min, "rng: max <= min"); + return this.next() * (max - min) + min; + } + + /** + * Updates the seed + * @param {number} seed + */ + setSeed(seed) { + this.internalRng = makeNewRng(seed); + } +} diff --git a/src/js/core/sensitive_utils.encrypt.js b/src/js/core/sensitive_utils.encrypt.js new file mode 100644 index 00000000..7434164e --- /dev/null +++ b/src/js/core/sensitive_utils.encrypt.js @@ -0,0 +1,62 @@ +import { globalConfig } from "./config"; +import { decompressX64, compressX64 } from "./lzstring"; + +const Rusha = require("rusha"); + +const encryptKey = globalConfig.info.sgSalt; + +export function decodeHashedString(s) { + return decompressX64(s); +} + +export function sha1(str) { + return Rusha.createHash().update(str).digest("hex"); +} + +// Window.location.host +export function getNameOfProvider() { + return window[decodeHashedString("DYewxghgLgliB2Q")][decodeHashedString("BYewzgLgdghgtgUyA")]; +} + +export function compressWithChecksum(object) { + const stringified = JSON.stringify(object); + const checksum = Rusha.createHash() + .update(stringified + encryptKey) + .digest("hex"); + return compressX64(checksum + stringified); +} + +export function decompressWithChecksum(binary) { + let decompressed = null; + try { + decompressed = decompressX64(binary); + } catch (err) { + throw new Error("failed-to-decompress"); + } + + // Split into checksum and content + if (!decompressed || decompressed.length < 41) { + throw new Error("checksum-missing"); + } + + const checksum = decompressed.substr(0, 40); + const rawData = decompressed.substr(40); + + // Validate checksum + const computedChecksum = Rusha.createHash() + .update(rawData + encryptKey) + .digest("hex"); + if (computedChecksum !== checksum) { + throw new Error("checksum-mismatch"); + } + + // Try parsing the JSON + let data = null; + try { + data = JSON.parse(rawData); + } catch (err) { + throw new Error("failed-to-parse"); + } + + return data; +} diff --git a/src/js/core/signal.js b/src/js/core/signal.js new file mode 100644 index 00000000..57fe1fca --- /dev/null +++ b/src/js/core/signal.js @@ -0,0 +1,66 @@ +export const STOP_PROPAGATION = "stop_propagation"; + +export class Signal { + constructor() { + this.receivers = []; + this.modifyCount = 0; + } + + /** + * Adds a new signal listener + * @param {object} receiver + * @param {object} scope + */ + add(receiver, scope = null) { + assert(receiver, "receiver is null"); + this.receivers.push({ receiver, scope }); + ++this.modifyCount; + } + + /** + * Dispatches the signal + * @param {...any} payload + */ + dispatch() { + const modifyState = this.modifyCount; + + const n = this.receivers.length; + for (let i = 0; i < n; ++i) { + const { receiver, scope } = this.receivers[i]; + if (receiver.apply(scope, arguments) === STOP_PROPAGATION) { + return STOP_PROPAGATION; + } + + if (modifyState !== this.modifyCount) { + // Signal got modified during iteration + return STOP_PROPAGATION; + } + } + } + + /** + * Removes a receiver + * @param {object} receiver + */ + remove(receiver) { + let index = null; + const n = this.receivers.length; + for (let i = 0; i < n; ++i) { + if (this.receivers[i].receiver === receiver) { + index = i; + break; + } + } + assert(index !== null, "Receiver not found in list"); + this.receivers.splice(index, 1); + ++this.modifyCount; + } + + /** + * Removes all receivers + */ + removeAll() { + this.receivers = []; + ++this.modifyCount; + } +} diff --git a/src/js/core/singleton_factory.js b/src/js/core/singleton_factory.js new file mode 100644 index 00000000..27d192c5 --- /dev/null +++ b/src/js/core/singleton_factory.js @@ -0,0 +1,78 @@ +// simple factory pattern +export class SingletonFactory { + constructor() { + // Store array as well as dictionary, to speed up lookups + this.entries = []; + this.idToEntry = {}; + } + + register(classHandle) { + // First, construct instance + const instance = new classHandle(); + + // Extract id + const id = instance.getId(); + assert(id, "Factory: Invalid id for class " + classHandle.name + ": " + id); + + // Check duplicates + assert(!this.idToEntry[id], "Duplicate factory entry for " + id); + + // Insert + this.entries.push(instance); + this.idToEntry[id] = instance; + } + + /** + * Checks if a given id is registered + * @param {string} id + * @returns {boolean} + */ + hasId(id) { + return !!this.idToEntry[id]; + } + + /** + * Finds an instance by a given id + * @param {string} id + * @returns {object} + */ + findById(id) { + const entry = this.idToEntry[id]; + if (!entry) { + assert(false, "Factory: Object with id '" + id + "' is not registered!"); + return null; + } + return entry; + } + + /** + * Finds an instance by its constructor (The class handle) + * @param {object} classHandle + * @returns {object} + */ + findByClass(classHandle) { + for (let i = 0; i < this.entries.length; ++i) { + if (this.entries[i] instanceof classHandle) { + return this.entries[i]; + } + } + assert(false, "Factory: Object not found by classHandle (classid: " + classHandle.name + ")"); + return null; + } + + /** + * Returns all entries + * @returns {Array} + */ + getEntries() { + return this.entries; + } + + /** + * Returns amount of stored entries + * @returns {number} + */ + getNumEntries() { + return this.entries.length; + } +} diff --git a/src/js/core/sprites.js b/src/js/core/sprites.js new file mode 100644 index 00000000..90efaae0 --- /dev/null +++ b/src/js/core/sprites.js @@ -0,0 +1,351 @@ +import { DrawParameters } from "./draw_parameters"; +import { Math_floor } from "./builtins"; +import { Rectangle } from "./rectangle"; +import { epsilonCompare, round3Digits } from "./utils"; + +const floorSpriteCoordinates = false; + +const ORIGINAL_SCALE = "1"; + +export class BaseSprite { + /** + * Returns the raw handle + * @returns {HTMLImageElement|HTMLCanvasElement} + */ + getRawTexture() { + abstract; + return null; + } + + /** + * Draws the sprite + * @param {CanvasRenderingContext2D} context + * @param {number} x + * @param {number} y + * @param {number} w + * @param {number} h + */ + draw(context, x, y, w, h) { + // eslint-disable-line no-unused-vars + abstract; + } +} + +/** + * Position of a sprite within an atlas + */ +export class SpriteAtlasLink { + /** + * + * @param {object} param0 + * @param {number} param0.packedX + * @param {number} param0.packedY + * @param {number} param0.packOffsetX + * @param {number} param0.packOffsetY + * @param {number} param0.packedW + * @param {number} param0.packedH + * @param {number} param0.w + * @param {number} param0.h + * @param {HTMLImageElement|HTMLCanvasElement} param0.atlas + */ + constructor({ w, h, packedX, packedY, packOffsetX, packOffsetY, packedW, packedH, atlas }) { + this.packedX = packedX; + this.packedY = packedY; + this.packedW = packedW; + this.packedH = packedH; + this.packOffsetX = packOffsetX; + this.packOffsetY = packOffsetY; + this.atlas = atlas; + this.w = w; + this.h = h; + } +} + +export class AtlasSprite extends BaseSprite { + /** + * + * @param {object} param0 + * @param {string} param0.spriteName + */ + constructor({ spriteName = "sprite" }) { + super(); + /** @type {Object.} */ + this.linksByResolution = {}; + this.spriteName = spriteName; + } + + getRawTexture() { + return this.linksByResolution[ORIGINAL_SCALE].atlas; + } + + /** + * Draws the sprite onto a regular context using no contexts + * @see {BaseSprite.draw} + */ + draw(context, x, y, w, h) { + if (G_IS_DEV) { + assert(context instanceof CanvasRenderingContext2D, "Not a valid context"); + } + console.warn("drawing sprite regulary"); + + const link = this.linksByResolution[ORIGINAL_SCALE]; + + const width = w || link.w; + const height = h || link.h; + + const scaleW = width / link.w; + const scaleH = height / link.h; + + context.drawImage( + link.atlas, + + link.packedX, + link.packedY, + link.packedW, + link.packedH, + + x + link.packOffsetX * scaleW, + y + link.packOffsetY * scaleH, + link.packedW * scaleW, + link.packedH * scaleH + ); + } + + /** + * + * @param {DrawParameters} parameters + * @param {number} x + * @param {number} y + * @param {number} size + * @param {boolean=} clipping + */ + drawCachedCentered(parameters, x, y, size, clipping = true) { + this.drawCached(parameters, x - size / 2, y - size / 2, size, size, clipping); + } + + /** + * + * @param {CanvasRenderingContext2D} context + * @param {number} x + * @param {number} y + * @param {number} size + */ + drawCentered(context, x, y, size) { + this.draw(context, x - size / 2, y - size / 2, size, size); + } + + /** + * Draws the sprite + * @param {DrawParameters} parameters + * @param {number} x + * @param {number} y + * @param {number} w + * @param {number} h + * @param {boolean=} clipping Whether to perform culling + */ + drawCached(parameters, x, y, w = null, h = null, clipping = true) { + if (G_IS_DEV) { + assertAlways(parameters instanceof DrawParameters, "Not a valid context"); + assertAlways(!!w && w > 0, "Not a valid width:" + w); + assertAlways(!!h && h > 0, "Not a valid height:" + h); + } + + const visibleRect = parameters.visibleRect; + + const scale = parameters.desiredAtlasScale; + const link = this.linksByResolution[scale]; + const scaleW = w / link.w; + const scaleH = h / link.h; + + let destX = x + link.packOffsetX * scaleW; + let destY = y + link.packOffsetY * scaleH; + let destW = link.packedW * scaleW; + let destH = link.packedH * scaleH; + + let srcX = link.packedX; + let srcY = link.packedY; + let srcW = link.packedW; + let srcH = link.packedH; + + let intersection = null; + + if (clipping) { + const rect = new Rectangle(destX, destY, destW, destH); + intersection = rect.getUnion(visibleRect); + if (!intersection) { + return; + } + + srcX += (intersection.x - destX) / scaleW; + srcY += (intersection.y - destY) / scaleH; + + srcW *= intersection.w / destW; + srcH *= intersection.h / destH; + + destX = intersection.x; + destY = intersection.y; + + destW = intersection.w; + destH = intersection.h; + } + + // assert(epsilonCompare(scaleW, scaleH), "Sprite should be square for cached rendering"); + + if (floorSpriteCoordinates) { + parameters.context.drawImage( + link.atlas, + + // atlas src pos + Math_floor(srcX), + Math_floor(srcY), + + // atlas src size + Math_floor(srcW), + Math_floor(srcH), + + // dest pos + Math_floor(destX), + Math_floor(destY), + + // dest size + Math_floor(destW), + Math_floor(destH) + ); + } else { + parameters.context.drawImage( + link.atlas, + + // atlas src pos + srcX, + srcY, + + // atlas src siize + srcW, + srcH, + + // dest pos and size + destX, + destY, + destW, + destH + ); + } + } + + /** + * Renders into an html element + * @param {HTMLElement} element + * @param {number} w + * @param {number} h + */ + renderToHTMLElement(element, w = 1, h = 1) { + element.style.position = "relative"; + element.innerHTML = this.getAsHTML(w, h); + } + + /** + * Returns the html to render as icon + * @param {number} w + * @param {number} h + */ + getAsHTML(w, h) { + const link = this.linksByResolution["0.5"]; + + // Find out how much we have to scale it so that it fits + const scaleX = w / link.w; + const scaleY = h / link.h; + + // Find out how big the scaled atlas is + const atlasW = link.atlas.width * scaleX; + const atlasH = link.atlas.height * scaleY; + + // @ts-ignore + const srcSafe = link.atlas.src.replaceAll("\\", "/"); + + // Find out how big we render the sprite + const widthAbsolute = scaleX * link.packedW; + const heightAbsolute = scaleY * link.packedH; + + // Compute the position in the relative container + const leftRelative = (link.packOffsetX * scaleX) / w; + const topRelative = (link.packOffsetY * scaleY) / h; + const widthRelative = widthAbsolute / w; + const heightRelative = heightAbsolute / h; + + // Scale the atlas relative to the width and height of the element + const bgW = atlasW / widthAbsolute; + const bgH = atlasH / heightAbsolute; + + // Figure out what the position of the atlas is + const bgX = link.packedX * scaleX; + const bgY = link.packedY * scaleY; + + // Fuck you, whoever thought its a good idea to make background-position work like it does now + const bgXRelative = -bgX / (widthAbsolute - atlasW); + const bgYRelative = -bgY / (heightAbsolute - atlasH); + + return ` + + `; + } +} + +export class RegularSprite extends BaseSprite { + constructor(sprite, w, h) { + super(); + this.w = w; + this.h = h; + this.sprite = sprite; + } + + getRawTexture() { + return this.sprite; + } + + /** + * Draws the sprite, do *not* use this for sprites which are rendered! Only for drawing + * images into buffers + * @param {CanvasRenderingContext2D} context + * @param {number} x + * @param {number} y + * @param {number} w + * @param {number} h + */ + draw(context, x, y, w, h) { + assert(context, "No context given"); + assert(x !== undefined, "No x given"); + assert(y !== undefined, "No y given"); + assert(w !== undefined, "No width given"); + assert(h !== undefined, "No height given"); + context.drawImage(this.sprite, x, y, w, h); + } + + /** + * Draws the sprite, do *not* use this for sprites which are rendered! Only for drawing + * images into buffers + * @param {CanvasRenderingContext2D} context + * @param {number} x + * @param {number} y + * @param {number} w + * @param {number} h + */ + drawCentered(context, x, y, w, h) { + assert(context, "No context given"); + assert(x !== undefined, "No x given"); + assert(y !== undefined, "No y given"); + assert(w !== undefined, "No width given"); + assert(h !== undefined, "No height given"); + context.drawImage(this.sprite, x - w / 2, y - h / 2, w, h); + } +} diff --git a/src/js/core/state_manager.js b/src/js/core/state_manager.js new file mode 100644 index 00000000..3c49ada9 --- /dev/null +++ b/src/js/core/state_manager.js @@ -0,0 +1,121 @@ +/* typehints:start*/ +import { Application } from "../application"; +/* typehints:end*/ + +import { GameState } from "./game_state"; +import { createLogger } from "./logging"; +import { APPLICATION_ERROR_OCCURED } from "./error_handler"; +import { waitNextFrame, removeAllChildren } from "./utils"; + +const logger = createLogger("state_manager"); + +/** + * This is the main state machine which drives the game states. + */ +export class StateManager { + /** + * @param {Application} app + */ + constructor(app) { + this.app = app; + + /** @type {GameState} */ + this.currentState = null; + + /** @type {Object. GameState>} */ + this.stateClasses = {}; + } + + /** + * Registers a new state class, should be a GameState derived class + * @param {object} stateClass + */ + register(stateClass) { + // Create a dummy to retrieve the key + const dummy = new stateClass(); + assert(dummy instanceof GameState, "Not a state!"); + const key = dummy.getKey(); + assert(!this.stateClasses[key], `State '${key}' is already registered!`); + this.stateClasses[key] = stateClass; + } + + /** + * Constructs a new state or returns the instance from the cache + * @param {string} key + */ + constructState(key) { + if (this.stateClasses[key]) { + return new this.stateClasses[key](); + } + assert(false, `State '${key}' is not known!`); + } + + /** + * Moves to a given state + * @param {string} key State Key + */ + moveToState(key, payload = {}) { + if (APPLICATION_ERROR_OCCURED) { + console.warn("Skipping state transition because of application crash"); + return; + } + + if (this.currentState) { + if (key === this.currentState.getKey()) { + logger.error(`State '${key}' is already active!`); + return false; + } + this.currentState.internalLeaveCallback(); + + // Remove all references + for (const stateKey in this.currentState) { + if (this.currentState.hasOwnProperty(stateKey)) { + delete this.currentState[stateKey]; + } + } + this.currentState = null; + } + + this.currentState = this.constructState(key); + this.currentState.internalRegisterCallback(this, this.app); + + // Clean up old elements + removeAllChildren(document.body); + + document.body.className = "gameState " + (this.currentState.getHasFadeIn() ? "" : "arrived"); + document.body.id = "state_" + key; + document.body.innerHTML = this.currentState.internalGetFullHtml(); + + const dialogParent = document.createElement("div"); + dialogParent.classList.add("modalDialogParent"); + document.body.appendChild(dialogParent); + + this.app.sound.playThemeMusic(this.currentState.getThemeMusic()); + + this.currentState.internalEnterCallback(payload); + this.currentState.onResized(this.app.screenWidth, this.app.screenHeight); + + this.app.analytics.trackStateEnter(key); + + window.history.pushState( + { + key, + }, + key + ); + + waitNextFrame().then(() => { + document.body.classList.add("arrived"); + }); + + return true; + } + + /** + * Returns the current state + * @returns {GameState} + */ + getCurrentState() { + return this.currentState; + } +} diff --git a/src/js/core/tracked_state.js b/src/js/core/tracked_state.js new file mode 100644 index 00000000..1a538bc6 --- /dev/null +++ b/src/js/core/tracked_state.js @@ -0,0 +1,39 @@ +export class TrackedState { + constructor(callbackMethod = null, callbackScope = null) { + this.lastSeenValue = null; + + if (callbackMethod) { + this.callback = callbackMethod; + if (callbackScope) { + this.callback = this.callback.bind(callbackScope); + } + } + } + + set(value, changeHandler = null, changeScope = null) { + if (value !== this.lastSeenValue) { + // Copy value since the changeHandler call could actually modify our lastSeenValue + const valueCopy = value; + this.lastSeenValue = value; + if (changeHandler) { + if (changeScope) { + changeHandler.call(changeScope, valueCopy); + } else { + changeHandler(valueCopy); + } + } else if (this.callback) { + this.callback(value); + } else { + assert(false, "No callback specified"); + } + } + } + + setSilent(value) { + this.lastSeenValue = value; + } + + get() { + return this.lastSeenValue; + } +} diff --git a/src/js/core/utils.js b/src/js/core/utils.js new file mode 100644 index 00000000..2b7eca48 --- /dev/null +++ b/src/js/core/utils.js @@ -0,0 +1,889 @@ +import { globalConfig, IS_DEBUG } from "./config"; +import { + Math_abs, + Math_atan2, + Math_ceil, + Math_floor, + Math_log10, + Math_max, + Math_min, + Math_PI, + Math_pow, + Math_random, + Math_round, + Math_sin, + performanceNow, +} from "./builtins"; +import { Vector } from "./vector"; + +// Constants +export const TOP = new Vector(0, -1); +export const RIGHT = new Vector(1, 0); +export const BOTTOM = new Vector(0, 1); +export const LEFT = new Vector(-1, 0); +export const ALL_DIRECTIONS = [TOP, RIGHT, BOTTOM, LEFT]; + +export const thousand = 1000; +export const million = 1000 * 1000; +export const billion = 1000 * 1000 * 1000; + +/** + * Returns the build id + * @returns {string} + */ +export function getBuildId() { + if (G_IS_DEV && IS_DEBUG) { + return "local-dev"; + } else if (G_IS_DEV) { + return "dev-" + getPlatformName() + "-" + G_BUILD_COMMIT_HASH; + } else { + return "prod-" + getPlatformName() + "-" + G_BUILD_COMMIT_HASH; + } +} + +/** + * Returns the environment id (dev, prod, etc) + * @returns {string} + */ +export function getEnvironmentId() { + if (G_IS_DEV && IS_DEBUG) { + return "local-dev"; + } else if (G_IS_DEV) { + return "dev-" + getPlatformName(); + } else if (G_IS_RELEASE) { + return "release-" + getPlatformName(); + } else { + return "staging-" + getPlatformName(); + } +} + +/** + * Returns if this platform is android + * @returns {boolean} + */ +export function isAndroid() { + if (!G_IS_MOBILE_APP) { + return false; + } + const platform = window.device.platform; + return platform === "Android" || platform === "amazon-fireos"; +} + +/** + * Returns if this platform is iOs + * @returns {boolean} + */ +export function isIos() { + if (!G_IS_MOBILE_APP) { + return false; + } + return window.device.platform === "iOS"; +} + +/** + * Returns a platform name + * @returns {string} + */ +export function getPlatformName() { + if (G_IS_STANDALONE) { + return "standalone"; + } else if (G_IS_BROWSER) { + return "browser"; + } else if (G_IS_MOBILE_APP && isAndroid()) { + return "android"; + } else if (G_IS_MOBILE_APP && isIos()) { + return "ios"; + } + return "unknown"; +} + +/** + * Returns the IPC renderer, or null if not within the standalone + * @returns {object|null} + */ +let ipcRenderer = null; +export function getIPCRenderer() { + if (!G_IS_STANDALONE) { + return null; + } + if (!ipcRenderer) { + ipcRenderer = eval("require")("electron").ipcRenderer; + } + return ipcRenderer; +} + +/** + * Formats a sensitive token by only displaying the first digits of it. Use for + * stuff like savegame keys etc which should not appear in the log. + * @param {string} key + */ +export function formatSensitive(key) { + if (!key) { + return ""; + } + key = key || ""; + return "[" + key.substr(0, 8) + "...]"; +} + +/** + * Creates a new 2D array with the given fill method + * @param {number} w Width + * @param {number} h Height + * @param {(function(number, number) : any) | number | boolean | string | null | undefined} filler Either Fill method, which should return the content for each cell, or static content + * @param {string=} context Optional context for memory tracking + * @returns {Array>} + */ +export function make2DArray(w, h, filler, context = null) { + if (typeof filler === "function") { + const tiles = new Array(w); + for (let x = 0; x < w; ++x) { + const row = new Array(h); + for (let y = 0; y < h; ++y) { + row[y] = filler(x, y); + } + tiles[x] = row; + } + return tiles; + } else { + const tiles = new Array(w); + const row = new Array(h); + for (let y = 0; y < h; ++y) { + row[y] = filler; + } + + for (let x = 0; x < w; ++x) { + tiles[x] = row.slice(); + } + return tiles; + } +} + +/** + * Makes a new 2D array with undefined contents + * @param {number} w + * @param {number} h + * @param {string=} context + * @returns {Array>} + */ +export function make2DUndefinedArray(w, h, context = null) { + const result = new Array(w); + for (let x = 0; x < w; ++x) { + result[x] = new Array(h); + } + return result; +} + +/** + * Clears a given 2D array with the given fill method + * @param {Array>} array + * @param {number} w Width + * @param {number} h Height + * @param {(function(number, number) : any) | number | boolean | string | null | undefined} filler Either Fill method, which should return the content for each cell, or static content + */ +export function clear2DArray(array, w, h, filler) { + assert(array.length === w, "Array dims mismatch w"); + assert(array[0].length === h, "Array dims mismatch h"); + if (typeof filler === "function") { + for (let x = 0; x < w; ++x) { + const row = array[x]; + for (let y = 0; y < h; ++y) { + row[y] = filler(x, y); + } + } + } else { + for (let x = 0; x < w; ++x) { + const row = array[x]; + for (let y = 0; y < h; ++y) { + row[y] = filler; + } + } + } +} + +/** + * Creates a new map (an empty object without any props) + */ +export function newEmptyMap() { + return Object.create(null); +} + +/** + * Returns a random integer in the range [start,end] + * @param {number} start + * @param {number} end + */ +export function randomInt(start, end) { + return start + Math_round(Math_random() * (end - start)); +} + +/** + * Access an object in a very annoying way, used for obsfuscation. + * @param {any} obj + * @param {Array} keys + */ +export function accessNestedPropertyReverse(obj, keys) { + let result = obj; + for (let i = keys.length - 1; i >= 0; --i) { + result = result[keys[i]]; + } + return result; +} + +/** + * Chooses a random entry of an array + * @param {Array | string} arr + */ +export function randomChoice(arr) { + return arr[Math_floor(Math_random() * arr.length)]; +} + +/** + * Deletes from an array by swapping with the last element + * @param {Array} array + * @param {number} index + */ +export function fastArrayDelete(array, index) { + if (index < 0 || index >= array.length) { + throw new Error("Out of bounds"); + } + // When the element is not the last element + if (index !== array.length - 1) { + // Get the last element, and swap it with the one we want to delete + const last = array[array.length - 1]; + array[index] = last; + } + + // Finally remove the last element + array.length -= 1; +} + +/** + * Deletes from an array by swapping with the last element. Searches + * for the value in the array first + * @param {Array} array + * @param {any} value + */ +export function fastArrayDeleteValue(array, value) { + if (array == null) { + throw new Error("Tried to delete from non array!"); + } + const index = array.indexOf(value); + if (index < 0) { + console.error("Value", value, "not contained in array:", array, "!"); + return value; + } + return fastArrayDelete(array, index); +} + +/** + * @see fastArrayDeleteValue + * @param {Array} array + * @param {any} value + */ +export function fastArrayDeleteValueIfContained(array, value) { + if (array == null) { + throw new Error("Tried to delete from non array!"); + } + const index = array.indexOf(value); + if (index < 0) { + return value; + } + return fastArrayDelete(array, index); +} + +/** + * Deletes from an array at the given index + * @param {Array} array + * @param {number} index + */ +export function arrayDelete(array, index) { + if (index < 0 || index >= array.length) { + throw new Error("Out of bounds"); + } + array.splice(index, 1); +} + +/** + * Deletes the given value from an array + * @param {Array} array + * @param {any} value + */ +export function arrayDeleteValue(array, value) { + if (array == null) { + throw new Error("Tried to delete from non array!"); + } + const index = array.indexOf(value); + if (index < 0) { + console.error("Value", value, "not contained in array:", array, "!"); + return value; + } + return arrayDelete(array, index); +} + +// Converts a direction into a 0 .. 7 index +/** + * Converts a direction into a index from 0 .. 7, used for miners, zombies etc which have 8 sprites + * @param {Vector} offset direction + * @param {boolean} inverse if inverse, the direction is reversed + * @returns {number} in range [0, 7] + */ +export function angleToSpriteIndex(offset, inverse = false) { + const twoPi = 2.0 * Math_PI; + const factor = inverse ? -1 : 1; + const offs = inverse ? 2.5 : 3.5; + const angle = (factor * Math_atan2(offset.y, offset.x) + offs * Math_PI) % twoPi; + + const index = Math_round((angle / twoPi) * 8) % 8; + return index; +} + +/** + * Compare two floats for epsilon equality + * @param {number} a + * @param {number} b + * @returns {boolean} + */ +export function epsilonCompare(a, b, epsilon = 1e-5) { + return Math_abs(a - b) < epsilon; +} + +/** + * Compare a float for epsilon equal to 0 + * @param {number} a + * @returns {boolean} + */ +export function epsilonIsZero(a) { + return epsilonCompare(a, 0); +} + +/** + * Interpolates two numbers + * @param {number} a + * @param {number} b + * @param {number} x Mix factor, 0 means 100% a, 1 means 100%b, rest is interpolated + */ +export function lerp(a, b, x) { + return a * (1 - x) + b * x; +} + +/** + * Finds a value which is nice to display, e.g. 15669 -> 15000. Also handles fractional stuff + * @param {number} num + */ +export function findNiceValue(num) { + if (num > 1e8) { + return num; + } + if (num < 0.00001) { + return 0; + } + + const roundAmount = 0.5 * Math_pow(10, Math_floor(Math_log10(num) - 1)); + const niceValue = Math_floor(num / roundAmount) * roundAmount; + if (num >= 10) { + return Math_round(niceValue); + } + if (num >= 1) { + return Math_round(niceValue * 10) / 10; + } + + return Math_round(niceValue * 100) / 100; +} + +/** + * Finds a nice integer value + * @see findNiceValue + * @param {number} num + */ +export function findNiceIntegerValue(num) { + return Math_ceil(findNiceValue(num)); +} + +/** + * Smart rounding + fractional handling + * @param {number} n + */ +function roundSmart(n) { + if (n < 100) { + return n.toFixed(1); + } + return Math_round(n); +} + +/** + * Formats a big number + * @param {number} num + * @param {string=} divider THe divider for numbers like 50,000 (divider=',') + * @returns {string} + */ +export function formatBigNumber(num, divider = ".") { + const sign = num < 0 ? "-" : ""; + num = Math_abs(num); + + if (num > 1e54) { + return sign + "inf"; + } + + if (num < 10 && !Number.isInteger(num)) { + return sign + num.toFixed(2); + } + if (num < 50 && !Number.isInteger(num)) { + return sign + num.toFixed(1); + } + num = Math_floor(num); + + if (num < 1000) { + return sign + "" + num; + } + + // if (num > 1e51) return sign + T.common.number_format.sedecillion.replace("%amount%", "" + roundSmart(num / 1e51)); + // if (num > 1e48) + // return sign + T.common.number_format.quinquadecillion.replace("%amount%", "" + roundSmart(num / 1e48)); + // if (num > 1e45) + // return sign + T.common.number_format.quattuordecillion.replace("%amount%", "" + roundSmart(num / 1e45)); + // if (num > 1e42) return sign + T.common.number_format.tredecillion.replace("%amount%", "" + roundSmart(num / 1e42)); + // if (num > 1e39) return sign + T.common.number_format.duodecillions.replace("%amount%", "" + roundSmart(num / 1e39)); + // if (num > 1e36) return sign + T.common.number_format.undecillions.replace("%amount%", "" + roundSmart(num / 1e36)); + // if (num > 1e33) return sign + T.common.number_format.decillions.replace("%amount%", "" + roundSmart(num / 1e33)); + // if (num > 1e30) return sign + T.common.number_format.nonillions.replace("%amount%", "" + roundSmart(num / 1e30)); + // if (num > 1e27) return sign + T.common.number_format.octillions.replace("%amount%", "" + roundSmart(num / 1e27)); + // if (num >= 1e24) return sign + T.common.number_format.septillions.replace("%amount%", "" + roundSmart(num / 1e24)); + // if (num >= 1e21) return sign + T.common.number_format.sextillions.replace("%amount%", "" + roundSmart(num / 1e21)); + // if (num >= 1e18) return sign + T.common.number_format.quintillions.replace("%amount%", "" + roundSmart(num / 1e18)); + // if (num >= 1e15) return sign + T.common.number_format.quantillions.replace("%amount%", "" + roundSmart(num / 1e15)); + // if (num >= 1e12) return sign + T.common.number_format.trillions.replace("%amount%", "" + roundSmart(num / 1e12)); + // if (num >= 1e9) return sign + T.common.number_format.billions.replace("%amount%", "" + roundSmart(num / 1e9)); + // if (num >= 1e6) return sign + T.common.number_format.millions.replace("%amount%", "" + roundSmart(num / 1e6)); + // if (num > 99999) return sign + T.common.number_format.thousands.replace("%amount%", "" + roundSmart(num / 1e3)); + + let rest = num; + let out = ""; + + while (rest >= 1000) { + out = (rest % 1000).toString().padStart(3, "0") + (out !== "" ? divider : "") + out; + rest = Math_floor(rest / 1000); + } + + out = rest + divider + out; + return sign + out; +} + +/** + * Formats a big number, but does not add any suffix and instead uses its full representation + * @param {number} num + * @param {string=} divider THe divider for numbers like 50,000 (divider=',') + * @returns {string} + */ +export function formatBigNumberFull(num, divider = T.common.number_format.divider_thousands || " ") { + if (num < 1000) { + return num + ""; + } + if (num > 1e54) { + return "infinite"; + } + let rest = num; + let out = ""; + while (rest >= 1000) { + out = (rest % 1000).toString().padStart(3, "0") + divider + out; + rest = Math_floor(rest / 1000); + } + out = rest + divider + out; + + return out.substring(0, out.length - 1); +} + +/** + * Formats an amount of seconds into something like "5s ago" + * @param {number} secs Seconds + * @returns {string} + */ +export function formatSecondsToTimeAgo(secs) { + const seconds = Math_floor(secs); + const minutes = Math_floor(seconds / 60); + const hours = Math_floor(minutes / 60); + const days = Math_floor(hours / 24); + + const trans = T.common.time; + + if (seconds <= 60) { + if (seconds <= 1) { + return trans.one_second_before; + } + return trans.seconds_before.replace("%amount%", "" + seconds); + } else if (minutes <= 60) { + if (minutes <= 1) { + return trans.one_minute_before; + } + return trans.minutes_before.replace("%amount%", "" + minutes); + } else if (hours <= 60) { + if (hours <= 1) { + return trans.one_hour_before; + } + return trans.hours_before.replace("%amount%", "" + hours); + } else { + if (days <= 1) { + return trans.one_day_before; + } + return trans.days_before.replace("%amount%", "" + days); + } +} + +/** + * Formats seconds into a readable string like "5h 23m" + * @param {number} secs Seconds + * @returns {string} + */ +export function formatSeconds(secs) { + const trans = T.common.time; + secs = Math_ceil(secs); + if (secs < 60) { + return trans.seconds_short.replace("%seconds%", "" + secs); + } else if (secs < 60 * 60) { + const minutes = Math_floor(secs / 60); + const seconds = secs % 60; + return trans.minutes_seconds_short + .replace("%seconds%", "" + seconds) + .replace("%minutes%", "" + minutes); + } else { + const hours = Math_floor(secs / 3600); + const minutes = Math_floor(secs / 60) % 60; + return trans.hours_minutes_short.replace("%minutes%", "" + minutes).replace("%hours%", "" + hours); + } +} + +/** + * Delayes a promise so that it will resolve after a *minimum* amount of time only + * @param {Promise} promise The promise to delay + * @param {number} minTimeMs The time to make it run at least + * @returns {Promise} The delayed promise + */ +export function artificialDelayedPromise(promise, minTimeMs = 500) { + if (G_IS_DEV && globalConfig.debug.noArtificialDelays) { + return promise; + } + + const startTime = performanceNow(); + return promise.then( + result => { + const timeTaken = performanceNow() - startTime; + const waitTime = Math_floor(minTimeMs - timeTaken); + if (waitTime > 0) { + return new Promise(resolve => { + setTimeout(() => { + resolve(result); + }, waitTime); + }); + } else { + return result; + } + }, + error => { + const timeTaken = performanceNow() - startTime; + const waitTime = Math_floor(minTimeMs - timeTaken); + if (waitTime > 0) { + // @ts-ignore + return new Promise((resolve, reject) => { + setTimeout(() => { + reject(error); + }, waitTime); + }); + } else { + throw error; + } + } + ); +} + +/** + * Computes a sine-based animation which pulsates from 0 .. 1 .. 0 + * @param {number} time Current time in seconds + * @param {number} duration Duration of the full pulse in seconds + * @param {number} seed Seed to offset the animation + */ +export function pulseAnimation(time, duration = 1.0, seed = 0.0) { + return Math_sin((time * Math_PI * 2.0) / duration + seed * 5642.86729349) * 0.5 + 0.5; +} + +/** + * Returns the smallest angle between two angles + * @param {number} a + * @param {number} b + * @returns {number} 0 .. 2 PI + */ +export function smallestAngle(a, b) { + return safeMod(a - b + Math_PI, 2.0 * Math_PI) - Math_PI; +} + +/** + * Modulo which works for negative numbers + * @param {number} n + * @param {number} m + */ +export function safeMod(n, m) { + return ((n % m) + m) % m; +} + +/** + * Wraps an angle between 0 and 2 pi + * @param {number} angle + */ +export function wrapAngle(angle) { + return safeMod(angle, 2.0 * Math_PI); +} + +/** + * Waits two frames so the ui is updated + * @returns {Promise} + */ +export function waitNextFrame() { + return new Promise(function (resolve, reject) { + window.requestAnimationFrame(function () { + window.requestAnimationFrame(function () { + resolve(); + }); + }); + }); +} + +/** + * Rounds 1 digit + * @param {number} n + * @returns {number} + */ +export function round1Digit(n) { + return Math_floor(n * 10.0) / 10.0; +} + +/** + * Rounds 2 digits + * @param {number} n + * @returns {number} + */ +export function round2Digits(n) { + return Math_floor(n * 100.0) / 100.0; +} + +/** + * Rounds 3 digits + * @param {number} n + * @returns {number} + */ +export function round3Digits(n) { + return Math_floor(n * 1000.0) / 1000.0; +} + +/** + * Rounds 4 digits + * @param {number} n + * @returns {number} + */ +export function round4Digits(n) { + return Math_floor(n * 10000.0) / 10000.0; +} + +/** + * Clamps a value between [min, max] + * @param {number} v + * @param {number=} minimum Default 0 + * @param {number=} maximum Default 1 + */ +export function clamp(v, minimum = 0, maximum = 1) { + return Math_max(minimum, Math_min(maximum, v)); +} + +/** + * Measures how long a function took + * @param {string} name + * @param {function():void} target + */ +export function measure(name, target) { + const now = performanceNow(); + for (let i = 0; i < 25; ++i) { + target(); + } + const dur = (performanceNow() - now) / 25.0; + console.warn("->", name, "took", dur.toFixed(2), "ms"); +} + +/** + * Helper method to create a new div + * @param {Element} parent + * @param {string=} id + * @param {Array=} classes + * @param {string=} innerHTML + */ +export function makeDiv(parent, id = null, classes = [], innerHTML = "") { + const div = document.createElement("div"); + if (id) { + div.id = id; + } + for (let i = 0; i < classes.length; ++i) { + div.classList.add(classes[i]); + } + div.innerHTML = innerHTML; + parent.appendChild(div); + return div; +} + +/** + * Removes all children of the given element + * @param {Element} elem + */ +export function removeAllChildren(elem) { + var range = document.createRange(); + range.selectNodeContents(elem); + range.deleteContents(); +} + +export function smartFadeNumber(current, newOne, minFade = 0.01, maxFade = 0.9) { + const tolerance = Math.min(current, newOne) * 0.5 + 10; + let fade = minFade; + if (Math.abs(current - newOne) < tolerance) { + fade = maxFade; + } + + return current * fade + newOne * (1 - fade); +} + +/** + * Fixes lockstep simulation by converting times like 34.0000000003 to 34.00. + * We use 3 digits of precision, this allows to store sufficient precision of 1 ms without + * the risk to simulation errors due to resync issues + * @param {number} value + */ +export function quantizeFloat(value) { + return Math.round(value * 1000.0) / 1000.0; +} + +/** + * Safe check to check if a timer is expired. quantizes numbers + * @param {number} now Current time + * @param {number} lastTick Last tick of the timer + * @param {number} tickRate Interval of the timer + */ +export function checkTimerExpired(now, lastTick, tickRate) { + if (!G_IS_PROD) { + if (quantizeFloat(now) !== now) { + console.error("Got non-quantizied time:" + now + " vs " + quantizeFloat(now)); + now = quantizeFloat(now); + } + if (quantizeFloat(lastTick) !== lastTick) { + // FIXME: REENABLE + // console.error("Got non-quantizied timer:" + lastTick + " vs " + quantizeFloat(lastTick)); + lastTick = quantizeFloat(lastTick); + } + } else { + // just to be safe + now = quantizeFloat(now); + lastTick = quantizeFloat(lastTick); + } + /* + Ok, so heres the issue (Died a bit while debugging it): + + In multiplayer lockstep simulation, client A will simulate everything at T, but client B + will simulate it at T + 3. So we are running into the following precision issue: + Lets say on client A the time is T = 30. Then on clientB the time is T = 33. + Now, our timer takes 0.1 seconds and ticked at 29.90 - What does happen now? + Client A computes the timer and checks T > lastTick + interval. He computes + + 30 >= 29.90 + 0.1 <=> 30 >= 30.0000 <=> True <=> Tick performed + + However, this is what it looks on client B: + + 33 >= 32.90 + 0.1 <=> 33 >= 32.999999999999998 <=> False <=> No tick performed! + + This means that Client B will only tick at the *next* frame, which means it from now is out + of sync by one tick, which means the game will resync further or later and be not able to recover, + since it will run into the same issue over and over. + */ + + // The next tick, in our example it would be 30.0000 / 32.99999999998. In order to fix it, we quantize + // it, so its now 30.0000 / 33.0000 + const nextTick = quantizeFloat(lastTick + tickRate); + + // This check is safe, but its the only check where you may compare times. You always need to use + // this method! + return now >= nextTick; +} + +/** + * Returns if the game supports this browser + */ +export function isSupportedBrowser() { + if (navigator.userAgent.toLowerCase().indexOf("firefox") >= 0) { + return true; + } + + return isSupportedBrowserForMultiplayer(); +} + +// https://stackoverflow.com/questions/4565112/javascript-how-to-find-out-if-the-user-browser-is-chrome/13348618#13348618 +export function isSupportedBrowserForMultiplayer() { + // please note, + // that IE11 now returns undefined again for window.chrome + // and new Opera 30 outputs true for window.chrome + // but needs to check if window.opr is not undefined + // and new IE Edge outputs to true now for window.chrome + // and if not iOS Chrome check + // so use the below updated condition + + if (G_IS_MOBILE_APP || G_IS_STANDALONE) { + return true; + } + + // @ts-ignore + var isChromium = window.chrome; + var winNav = window.navigator; + var vendorName = winNav.vendor; + // @ts-ignore + var isOpera = typeof window.opr !== "undefined"; + var isIEedge = winNav.userAgent.indexOf("Edge") > -1; + var isIOSChrome = winNav.userAgent.match("CriOS"); + + if (isIOSChrome) { + // is Google Chrome on IOS + return false; + } else if ( + isChromium !== null && + typeof isChromium !== "undefined" && + vendorName === "Google Inc." && + isIEedge === false + ) { + // is Google Chrome + return true; + } else { + // not Google Chrome + return false; + } +} + +/** + * Helper function to create a json schema object + * @param {any} properties + */ +export function schemaObject(properties) { + return { + type: "object", + required: Object.keys(properties).slice(), + additionalProperties: false, + properties, + }; +} + +/** + * Quickly + * @param {number} x + * @param {number} y + * @param {number} deg + * @returns {Vector} + */ +export function fastRotateMultipleOf90(x, y, deg) { + switch (deg) { + case 0: { + return new Vector(x, y); + } + case 90: { + return new Vector(x, y); + } + } +} diff --git a/src/js/core/vector.js b/src/js/core/vector.js new file mode 100644 index 00000000..2bd6cfe9 --- /dev/null +++ b/src/js/core/vector.js @@ -0,0 +1,665 @@ +import { globalConfig } from "./config"; +import { + Math_abs, + Math_floor, + Math_PI, + Math_max, + Math_min, + Math_round, + Math_hypot, + Math_atan2, + Math_sin, + Math_cos, +} from "./builtins"; + +const tileSize = globalConfig.tileSize; +const halfTileSize = globalConfig.halfTileSize; + +/** + * @enum {string} + */ +export const enumDirection = { + top: "top", + right: "right", + bottom: "bottom", + left: "left", +}; + +/** + * @enum {string} + */ +export const enumInvertedDirections = { + [enumDirection.top]: enumDirection.bottom, + [enumDirection.right]: enumDirection.left, + [enumDirection.bottom]: enumDirection.top, + [enumDirection.left]: enumDirection.right, +}; + +/** + * @enum {number} + */ +export const enumDirectionToAngle = { + [enumDirection.top]: 0, + [enumDirection.right]: 90, + [enumDirection.bottom]: 180, + [enumDirection.left]: 270, +}; + +/** + * @enum {enumDirection} + */ +export const enumAngleToDirection = { + 0: enumDirection.top, + 90: enumDirection.right, + 180: enumDirection.bottom, + 270: enumDirection.left, +}; + +export class Vector { + /** + * + * @param {number=} x + * @param {number=} y + */ + constructor(x, y) { + this.x = x || 0; + this.y = y || 0; + } + + /** + * return a copy of the vector + * @returns {Vector} + */ + copy() { + return new Vector(this.x, this.y); + } + + /** + * Adds a vector and return a new vector + * @param {Vector} other + * @returns {Vector} + */ + add(other) { + return new Vector(this.x + other.x, this.y + other.y); + } + + /** + * Adds a vector + * @param {Vector} other + * @returns {Vector} + */ + addInplace(other) { + this.x += other.x; + this.y += other.y; + return this; + } + + /** + * Substracts a vector and return a new vector + * @param {Vector} other + * @returns {Vector} + */ + sub(other) { + return new Vector(this.x - other.x, this.y - other.y); + } + + /** + * Multiplies with a vector and return a new vector + * @param {Vector} other + * @returns {Vector} + */ + mul(other) { + return new Vector(this.x * other.x, this.y * other.y); + } + + /** + * Adds two scalars and return a new vector + * @param {number} x + * @param {number} y + * @returns {Vector} + */ + addScalars(x, y) { + return new Vector(this.x + x, this.y + y); + } + + /** + * Substracts a scalar and return a new vector + * @param {number} f + * @returns {Vector} + */ + subScalar(f) { + return new Vector(this.x - f, this.y - f); + } + + /** + * Substracts two scalars and return a new vector + * @param {number} x + * @param {number} y + * @returns {Vector} + */ + subScalars(x, y) { + return new Vector(this.x - x, this.y - y); + } + + /** + * Returns the euclidian length + * @returns {number} + */ + length() { + return Math_hypot(this.x, this.y); + } + + /** + * Returns the square length + * @returns {number} + */ + lengthSquare() { + return this.x * this.x + this.y * this.y; + } + + /** + * Divides both components by a scalar and return a new vector + * @param {number} f + * @returns {Vector} + */ + divideScalar(f) { + return new Vector(this.x / f, this.y / f); + } + + /** + * Divides both components by the given scalars and return a new vector + * @param {number} a + * @param {number} b + * @returns {Vector} + */ + divideScalars(a, b) { + return new Vector(this.x / a, this.y / b); + } + + /** + * Divides both components by a scalar + * @param {number} f + * @returns {Vector} + */ + divideScalarInplace(f) { + this.x /= f; + this.y /= f; + return this; + } + + /** + * Multiplies both components with a scalar and return a new vector + * @param {number} f + * @returns {Vector} + */ + multiplyScalar(f) { + return new Vector(this.x * f, this.y * f); + } + + /** + * Multiplies both components with two scalars and returns a new vector + * @param {number} a + * @param {number} b + * @returns {Vector} + */ + multiplyScalars(a, b) { + return new Vector(this.x * a, this.y * b); + } + + /** + * For both components, compute the maximum of each component and the given scalar, and return a new vector. + * For example: + * - new Vector(-1, 5).maxScalar(0) -> Vector(0, 5) + * @param {number} f + * @returns {Vector} + */ + maxScalar(f) { + return new Vector(Math_max(f, this.x), Math_max(f, this.y)); + } + + /** + * Adds a scalar to both components and return a new vector + * @param {number} f + * @returns {Vector} + */ + addScalar(f) { + return new Vector(this.x + f, this.y + f); + } + + /** + * Computes the component wise minimum and return a new vector + * @param {Vector} v + * @returns {Vector} + */ + min(v) { + return new Vector(Math_min(v.x, this.x), Math_min(v.y, this.y)); + } + + /** + * Computes the component wise maximum and return a new vector + * @param {Vector} v + * @returns {Vector} + */ + max(v) { + return new Vector(Math_max(v.x, this.x), Math_max(v.y, this.y)); + } + /** + * Computes the component wise absolute + * @returns {Vector} + */ + abs() { + return new Vector(Math_abs(this.x), Math_abs(this.y)); + } + + /** + * Computes the scalar product + * @param {Vector} v + * @returns {number} + */ + dot(v) { + return this.x * v.x + this.y * v.y; + } + + /** + * Computes the distance to a given vector + * @param {Vector} v + * @returns {number} + */ + distance(v) { + return Math_hypot(this.x - v.x, this.y - v.y); + } + + /** + * Computes the square distance to a given vectort + * @param {Vector} v + * @returns {number} + */ + distanceSquare(v) { + const dx = this.x - v.x; + const dy = this.y - v.y; + return dx * dx + dy * dy; + } + + /** + * Computes and returns the center between both points + * @param {Vector} v + * @returns {Vector} + */ + centerPoint(v) { + const cx = this.x + v.x; + const cy = this.y + v.y; + return new Vector(cx / 2, cy / 2); + } + + /** + * Computes componentwise floor and return a new vector + * @returns {Vector} + */ + floor() { + return new Vector(Math_floor(this.x), Math_floor(this.y)); + } + + /** + * Computes componentwise round and return a new vector + * @returns {Vector} + */ + round() { + return new Vector(Math_round(this.x), Math_round(this.y)); + } + + /** + * Converts this vector from world to tile space and return a new vector + * @returns {Vector} + */ + toTileSpace() { + return new Vector(Math_floor(this.x / tileSize), Math_floor(this.y / tileSize)); + } + + /** + * Converts this vector from world to street space and return a new vector + * @returns {Vector} + */ + toStreetSpace() { + return new Vector(Math_floor(this.x / halfTileSize + 0.25), Math_floor(this.y / halfTileSize + 0.25)); + } + + /** + * Converts this vector to world space and return a new vector + * @returns {Vector} + */ + toWorldSpace() { + return new Vector(this.x * tileSize, this.y * tileSize); + } + + /** + * Converts this vector to world space and return a new vector + * @returns {Vector} + */ + toWorldSpaceCenterOfTile() { + return new Vector(this.x * tileSize + halfTileSize, this.y * tileSize + halfTileSize); + } + + /** + * Converts the top left tile position of this vector + * @returns {Vector} + */ + snapWorldToTile() { + return new Vector(Math_floor(this.x / tileSize) * tileSize, Math_floor(this.y / tileSize) * tileSize); + } + + /** + * Normalizes the vector, dividing by the length(), and return a new vector + * @returns {Vector} + */ + normalize() { + const len = Math_max(1e-5, Math_hypot(this.x, this.y)); + return new Vector(this.x / len, this.y / len); + } + + /** + * Normalizes the vector, dividing by the length(), and return a new vector + * @returns {Vector} + */ + normalizeIfGreaterOne() { + const len = Math_max(1, Math_hypot(this.x, this.y)); + return new Vector(this.x / len, this.y / len); + } + + /** + * Returns the normalized vector to the other point + * @param {Vector} v + * @returns {Vector} + */ + normalizedDirection(v) { + const dx = v.x - this.x; + const dy = v.y - this.y; + const len = Math_max(1e-5, Math_hypot(dx, dy)); + return new Vector(dx / len, dy / len); + } + + /** + * Returns a perpendicular vector + * @returns {Vector} + */ + findPerpendicular() { + return new Vector(-this.y, this.x); + } + + /** + * Returns the unnormalized direction to the other point + * @param {Vector} v + * @returns {Vector} + */ + direction(v) { + return new Vector(v.x - this.x, v.y - this.y); + } + + /** + * Returns a string representation of the vector + * @returns {string} + */ + toString() { + return this.x + "," + this.y; + } + + /** + * Compares both vectors for exact equality. Does not do an epsilon compare + * @param {Vector} v + * @returns {Boolean} + */ + equals(v) { + return this.x === v.x && this.y === v.y; + } + + /** + * Rotates this vector + * @param {number} angle + * @returns {Vector} new vector + */ + rotated(angle) { + const sin = Math_sin(angle); + const cos = Math_cos(angle); + return new Vector(this.x * cos - this.y * sin, this.x * sin + this.y * cos); + } + + /** + * Rotates this vector + * @param {number} angle + * @returns {Vector} this vector + */ + rotateInplaceFastMultipleOf90(angle) { + // const sin = Math_sin(angle); + // const cos = Math_cos(angle); + // let sin = 0, cos = 1; + assert(angle >= 0 && angle <= 360, "Invalid angle, please clamp first: " + angle); + + switch (angle) { + case 0: + case 360: { + return this; + } + case 90: { + // sin = 1; + // cos = 0; + + const x = this.x; + this.x = -this.y; + this.y = x; + return this; + } + case 180: { + // sin = 0 + // cos = -1 + this.x = -this.x; + this.y = -this.y; + return this; + } + case 270: { + // sin = -1 + // cos = 0 + const x = this.x; + this.x = this.y; + this.y = -x; + return this; + } + default: { + assertAlways(false, "Invalid fast inplace rotation: " + angle); + return this; + } + } + // return new Vector(this.x * cos - this.y * sin, this.x * sin + this.y * cos); + } + + /** + * Rotates this vector + * @param {number} angle + * @returns {Vector} new vector + */ + rotateFastMultipleOf90(angle) { + assert(angle >= 0 && angle <= 360, "Invalid angle, please clamp first: " + angle); + + switch (angle) { + case 360: + case 0: { + return new Vector(this.x, this.y); + } + case 90: { + return new Vector(-this.y, this.x); + } + case 180: { + return new Vector(-this.x, -this.y); + } + case 270: { + return new Vector(this.y, -this.x); + } + default: { + assertAlways(false, "Invalid fast inplace rotation: " + angle); + return new Vector(); + } + } + } + + /** + * Helper method to rotate a direction + * @param {enumDirection} direction + * @param {number} angle + * @returns {enumDirection} + */ + static transformDirectionFromMultipleOf90(direction, angle) { + if (angle === 0 || angle === 360) { + return direction; + } + assert(angle >= 0 && angle <= 360, "Invalid angle: " + angle); + switch (direction) { + case enumDirection.top: { + switch (angle) { + case 90: + return enumDirection.right; + case 180: + return enumDirection.bottom; + case 270: + return enumDirection.left; + default: + assertAlways(false, "Invalid angle: " + angle); + return; + } + } + + case enumDirection.right: { + switch (angle) { + case 90: + return enumDirection.bottom; + case 180: + return enumDirection.left; + case 270: + return enumDirection.top; + default: + assertAlways(false, "Invalid angle: " + angle); + return; + } + } + + case enumDirection.bottom: { + switch (angle) { + case 90: + return enumDirection.left; + case 180: + return enumDirection.top; + case 270: + return enumDirection.right; + default: + assertAlways(false, "Invalid angle: " + angle); + return; + } + } + + case enumDirection.left: { + switch (angle) { + case 90: + return enumDirection.top; + case 180: + return enumDirection.right; + case 270: + return enumDirection.bottom; + default: + assertAlways(false, "Invalid angle: " + angle); + return; + } + } + default: + assertAlways(false, "Invalid angle: " + angle); + return; + } + } + + /** + * Compares both vectors for epsilon equality + * @param {Vector} v + * @returns {Boolean} + */ + equalsEpsilon(v, epsilon = 1e-5) { + return Math_abs(this.x - v.x) < 1e-5 && Math_abs(this.y - v.y) < epsilon; + } + + /** + * Returns the angle + * @returns {number} 0 .. 2 PI + */ + angle() { + return Math_atan2(this.y, this.x) + Math_PI / 2; + } + + /** + * Serializes the vector to a string + * @returns {string} + */ + serializeTile() { + return String.fromCharCode(33 + this.x) + String.fromCharCode(33 + this.y); + } + + /** + * Creates a simple representation of the vector + */ + serializeSimple() { + return { x: this.x, y: this.y }; + } + + /** + * @returns {number} + */ + serializeTileToInt() { + return this.x + this.y * 256; + } + + /** + * + * @param {number} i + * @returns {Vector} + */ + static deserializeTileFromInt(i) { + const x = i % 256; + const y = Math_floor(i / 256); + return new Vector(x, y); + } + + /** + * Deserializes a vector from a string + * @param {string} s + * @returns {Vector} + */ + static deserializeTile(s) { + return new Vector(s.charCodeAt(0) - 33, s.charCodeAt(1) - 33); + } + + /** + * Deserializes a vector from a serialized json object + * @param {object} obj + * @returns {Vector} + */ + static fromSerializedObject(obj) { + if (obj) { + return new Vector(obj.x || 0, obj.y || 0); + } + } +} + +/** + * Interpolates two vectors, for a = 0, returns v1 and for a = 1 return v2, otherwise interpolate + * @param {Vector} v1 + * @param {Vector} v2 + * @param {number} a + */ +export function mixVector(v1, v2, a) { + return new Vector(v1.x * (1 - a) + v2.x * a, v1.y * (1 - a) + v2.y * a); +} + +/** + * Mapping from string direction to actual vector + * @enum {Vector} + */ +export const enumDirectionToVector = { + top: new Vector(0, -1), + right: new Vector(1, 0), + bottom: new Vector(0, 1), + left: new Vector(-1, 0), +}; diff --git a/src/js/game/automatic_save.js b/src/js/game/automatic_save.js new file mode 100644 index 00000000..03686603 --- /dev/null +++ b/src/js/game/automatic_save.js @@ -0,0 +1,80 @@ +import { GameRoot } from "./root"; +import { globalConfig, IS_DEBUG } from "../core/config"; +import { Math_max } from "../core/builtins"; + +// How important it is that a savegame is created +/** + * @enum {number} + */ +export const enumSavePriority = { + regular: 2, + asap: 100, +}; + +// Internals +let MIN_INTERVAL_SECS = 15; + +if (G_IS_DEV && IS_DEBUG) { + // // Testing + // MIN_INTERVAL_SECS = 1; + // MAX_INTERVAL_SECS = 1; + MIN_INTERVAL_SECS = 9999999; +} + +export class AutomaticSave { + constructor(root) { + /** @type {GameRoot} */ + this.root = root; + + // Store the current maximum save importance + this.saveImportance = enumSavePriority.regular; + + this.lastSaveAttempt = -1000; + } + + setSaveImportance(importance) { + this.saveImportance = Math_max(this.saveImportance, importance); + } + + doSave() { + if (G_IS_DEV && globalConfig.debug.disableSavegameWrite) { + return; + } + + this.root.gameState.doSave(); + this.saveImportance = enumSavePriority.regular; + } + + update() { + if (!this.root.gameInitialized) { + // Bad idea + return; + } + // Check when the last save was, but make sure that if it fails, we don't spam + const lastSaveTime = Math_max(this.lastSaveAttempt, this.root.savegame.getRealLastUpdate()); + + let secondsSinceLastSave = (Date.now() - lastSaveTime) / 1000.0; + let shouldSave = false; + + switch (this.saveImportance) { + case enumSavePriority.asap: + // High always should save + shouldSave = true; + break; + + case enumSavePriority.regular: + // Could determine if there is a good / bad point here + shouldSave = secondsSinceLastSave > MIN_INTERVAL_SECS; + break; + + default: + assert(false, "Unknown save prio: " + this.saveImportance); + break; + } + if (shouldSave) { + // log(this, "Saving automatically"); + this.lastSaveAttempt = Date.now(); + this.doSave(); + } + } +} diff --git a/src/js/game/base_item.js b/src/js/game/base_item.js new file mode 100644 index 00000000..a4bd5e68 --- /dev/null +++ b/src/js/game/base_item.js @@ -0,0 +1,33 @@ +import { DrawParameters } from "../core/draw_parameters"; +import { BasicSerializableObject, types } from "../savegame/serialization"; + +/** + * Class for items on belts etc. Not an entity for performance reasons + */ +export class BaseItem extends BasicSerializableObject { + constructor() { + super(); + } + + static getId() { + return "base_item"; + } + + /** @returns {object} */ + static getSchema() { + return {}; + } + + /** + * Draws the item at the given position + * @param {number} x + * @param {number} y + * @param {DrawParameters} parameters + * @param {number=} size + */ + draw(x, y, parameters, size) {} + + getBackgroundColorAsResource() { + return "#eaebec"; + } +} diff --git a/src/js/game/buildings/belt_base.js b/src/js/game/buildings/belt_base.js new file mode 100644 index 00000000..f021f74e --- /dev/null +++ b/src/js/game/buildings/belt_base.js @@ -0,0 +1,204 @@ +import { Loader } from "../../core/loader"; +import { enumAngleToDirection, enumDirection, Vector } from "../../core/vector"; +import { BeltComponent } from "../components/belt"; +import { ItemAcceptorComponent } from "../components/item_acceptor"; +import { ItemEjectorComponent } from "../components/item_ejector"; +import { ReplaceableMapEntityComponent } from "../components/replaceable_map_entity"; +import { Entity } from "../entity"; +import { MetaBuilding } from "../meta_building"; +import { GameRoot } from "../root"; + +export const arrayBeltVariantToRotation = [enumDirection.top, enumDirection.left, enumDirection.right]; + +export class MetaBeltBaseBuilding extends MetaBuilding { + constructor() { + super("belt"); + } + + getSilhouetteColor() { + return "#777"; + } + + /** + * Creates the entity at the given location + * @param {Entity} entity + */ + setupEntityComponents(entity) { + entity.addComponent( + new BeltComponent({ + direction: enumDirection.top, // updated later + }) + ); + + entity.addComponent( + new ItemAcceptorComponent({ + slots: [ + { + pos: new Vector(0, 0), + directions: [enumDirection.bottom], + }, + ], + }) + ); + + entity.addComponent( + new ItemEjectorComponent({ + slots: [ + { + pos: new Vector(0, 0), + direction: enumDirection.top, // updated later + }, + ], + instantEject: true, + }) + ); + // Make this entity replaceabel + entity.addComponent(new ReplaceableMapEntityComponent()); + } + + /** + * + * @param {Entity} entity + * @param {number} rotationVariant + */ + updateRotationVariant(entity, rotationVariant) { + entity.components.Belt.direction = arrayBeltVariantToRotation[rotationVariant]; + entity.components.ItemEjector.slots[0].direction = arrayBeltVariantToRotation[rotationVariant]; + + entity.components.StaticMapEntity.spriteKey = null; + } + + /** + * Computes optimal belt rotation variant + * @param {GameRoot} root + * @param {Vector} tile + * @param {number} rotation + * @return {{ rotation: number, rotationVariant: number }} + */ + computeOptimalDirectionAndRotationVariantAtTile(root, tile, rotation) { + const topDirection = enumAngleToDirection[rotation]; + const rightDirection = enumAngleToDirection[(rotation + 90) % 360]; + const bottomDirection = enumAngleToDirection[(rotation + 180) % 360]; + const leftDirection = enumAngleToDirection[(rotation + 270) % 360]; + + const { ejectors, acceptors } = root.logic.getEjectorsAndAcceptorsAtTile(tile); + + let hasBottomEjector = false; + let hasLeftEjector = false; + let hasRightEjector = false; + + let hasTopAcceptor = false; + let hasLeftAcceptor = false; + let hasRightAcceptor = false; + + // Check all ejectors + for (let i = 0; i < ejectors.length; ++i) { + const ejector = ejectors[i]; + + if (ejector.toDirection === topDirection) { + hasBottomEjector = true; + } else if (ejector.toDirection === leftDirection) { + hasLeftEjector = true; + } else if (ejector.toDirection === rightDirection) { + hasRightEjector = true; + } + } + + // Check all acceptors + for (let i = 0; i < acceptors.length; ++i) { + const acceptor = acceptors[i]; + if (acceptor.fromDirection === bottomDirection) { + hasTopAcceptor = true; + } else if (acceptor.fromDirection === rightDirection) { + hasLeftAcceptor = true; + } else if (acceptor.fromDirection === leftDirection) { + hasRightAcceptor = true; + } + } + + // Soo .. if there is any ejector below us we always prioritize + // this ejector + if (!hasBottomEjector) { + // When something ejects to us from the left and nothing from the right, + // do a curve from the left to the top + if (hasLeftEjector && !hasRightEjector) { + return { + rotation: (rotation + 270) % 360, + rotationVariant: 2, + }; + } + + // When something ejects to us from the right and nothing from the left, + // do a curve from the right to the top + if (hasRightEjector && !hasLeftEjector) { + return { + rotation: (rotation + 90) % 360, + rotationVariant: 1, + }; + } + } + + // When there is a top acceptor, ignore sides + // NOTICE: This makes the belt prefer side turns *way* too much! + // if (!hasTopAcceptor) { + // // When there is an acceptor to the right but no acceptor to the left, + // // do a turn to the right + // if (hasRightAcceptor && !hasLeftAcceptor) { + // return { + // rotation, + // rotationVariant: 2, + // }; + // } + + // // When there is an acceptor to the left but no acceptor to the right, + // // do a turn to the left + // if (hasLeftAcceptor && !hasRightAcceptor) { + // return { + // rotation, + // rotationVariant: 1, + // }; + // } + // } + + return { + rotation, + rotationVariant: 0, + }; + } + + getName() { + return "Belt"; + } + + getDescription() { + return "Transports items, hold and drag to place multiple, press 'R' to rotate."; + } + + getPreviewSprite(rotationVariant) { + switch (arrayBeltVariantToRotation[rotationVariant]) { + case enumDirection.top: { + return Loader.getSprite("sprites/belt/forward_0.png"); + } + case enumDirection.left: { + return Loader.getSprite("sprites/belt/left_0.png"); + } + case enumDirection.right: { + return Loader.getSprite("sprites/belt/right_0.png"); + } + default: { + assertAlways(false, "Invalid belt rotation variant"); + } + } + } + + getStayInPlacementMode() { + return true; + } + + /** + * Can be overridden + */ + internalGetBeltDirection(rotationVariant) { + return enumDirection.top; + } +} diff --git a/src/js/game/buildings/cutter.js b/src/js/game/buildings/cutter.js new file mode 100644 index 00000000..07a574f7 --- /dev/null +++ b/src/js/game/buildings/cutter.js @@ -0,0 +1,71 @@ +import { globalConfig } from "../../core/config"; +import { enumDirection, Vector } from "../../core/vector"; +import { enumItemAcceptorItemFilter, ItemAcceptorComponent } from "../components/item_acceptor"; +import { ItemEjectorComponent } from "../components/item_ejector"; +import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor"; +import { Entity } from "../entity"; +import { MetaBuilding } from "../meta_building"; +import { GameRoot } from "../root"; +import { enumHubGoalRewards } from "../tutorial_goals"; + +export class MetaCutterBuilding extends MetaBuilding { + constructor() { + super("cutter"); + } + + getSilhouetteColor() { + return "#7dcda2"; + } + + getDimensions() { + return new Vector(2, 1); + } + + getName() { + return "Cut Half"; + } + + getDescription() { + return "Cuts shapes from top to bottom and outputs both halfs. If you use only one part, be sure to destroy the other part or it will stall!"; + } + + /** + * @param {GameRoot} root + */ + getIsUnlocked(root) { + return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_cutter_and_trash); + } + + /** + * Creates the entity at the given location + * @param {Entity} entity + */ + setupEntityComponents(entity) { + entity.addComponent( + new ItemProcessorComponent({ + inputsPerCharge: 1, + processorType: enumItemProcessorTypes.cutter, + }) + ); + + entity.addComponent( + new ItemEjectorComponent({ + slots: [ + { pos: new Vector(0, 0), direction: enumDirection.top }, + { pos: new Vector(1, 0), direction: enumDirection.top }, + ], + }) + ); + entity.addComponent( + new ItemAcceptorComponent({ + slots: [ + { + pos: new Vector(0, 0), + directions: [enumDirection.bottom], + filter: enumItemAcceptorItemFilter.shape, + }, + ], + }) + ); + } +} diff --git a/src/js/game/buildings/hub.js b/src/js/game/buildings/hub.js new file mode 100644 index 00000000..6186597e --- /dev/null +++ b/src/js/game/buildings/hub.js @@ -0,0 +1,125 @@ +import { enumDirection, Vector } from "../../core/vector"; +import { enumItemAcceptorItemFilter, ItemAcceptorComponent } from "../components/item_acceptor"; +import { Entity } from "../entity"; +import { MetaBuilding } from "../meta_building"; +import { ItemProcessorComponent, enumItemProcessorTypes } from "../components/item_processor"; +import { globalConfig } from "../../core/config"; +import { UnremovableComponent } from "../components/unremovable"; +import { HubComponent } from "../components/hub"; + +export class MetaHubBuilding extends MetaBuilding { + constructor() { + super("hub"); + } + + getDimensions() { + return new Vector(4, 4); + } + + getSilhouetteColor() { + return "#eb5555"; + } + + getName() { + return "Hub"; + } + + getDescription() { + return "Your central hub, deliver shapes to it to unlock new buildings."; + } + + isRotateable() { + return false; + } + + /** + * Creates the entity at the given location + * @param {Entity} entity + */ + setupEntityComponents(entity) { + entity.addComponent(new HubComponent()); + entity.addComponent( + new ItemProcessorComponent({ + inputsPerCharge: 1, + processorType: enumItemProcessorTypes.hub, + }) + ); + entity.addComponent(new UnremovableComponent()); + entity.addComponent( + new ItemAcceptorComponent({ + slots: [ + { + pos: new Vector(0, 0), + directions: [enumDirection.top, enumDirection.left], + filter: enumItemAcceptorItemFilter.shape, + }, + { + pos: new Vector(1, 0), + directions: [enumDirection.top], + filter: enumItemAcceptorItemFilter.shape, + }, + { + pos: new Vector(2, 0), + directions: [enumDirection.top], + filter: enumItemAcceptorItemFilter.shape, + }, + { + pos: new Vector(3, 0), + directions: [enumDirection.top, enumDirection.right], + filter: enumItemAcceptorItemFilter.shape, + }, + { + pos: new Vector(0, 3), + directions: [enumDirection.bottom, enumDirection.left], + filter: enumItemAcceptorItemFilter.shape, + }, + { + pos: new Vector(1, 3), + directions: [enumDirection.bottom], + filter: enumItemAcceptorItemFilter.shape, + }, + { + pos: new Vector(2, 3), + directions: [enumDirection.bottom], + filter: enumItemAcceptorItemFilter.shape, + }, + { + pos: new Vector(3, 3), + directions: [enumDirection.bottom, enumDirection.right], + filter: enumItemAcceptorItemFilter.shape, + }, + { + pos: new Vector(0, 1), + directions: [enumDirection.left], + filter: enumItemAcceptorItemFilter.shape, + }, + { + pos: new Vector(0, 2), + directions: [enumDirection.left], + filter: enumItemAcceptorItemFilter.shape, + }, + { + pos: new Vector(0, 3), + directions: [enumDirection.left], + filter: enumItemAcceptorItemFilter.shape, + }, + { + pos: new Vector(3, 1), + directions: [enumDirection.right], + filter: enumItemAcceptorItemFilter.shape, + }, + { + pos: new Vector(3, 2), + directions: [enumDirection.right], + filter: enumItemAcceptorItemFilter.shape, + }, + { + pos: new Vector(3, 3), + directions: [enumDirection.right], + filter: enumItemAcceptorItemFilter.shape, + }, + ], + }) + ); + } +} diff --git a/src/js/game/buildings/miner.js b/src/js/game/buildings/miner.js new file mode 100644 index 00000000..83791504 --- /dev/null +++ b/src/js/game/buildings/miner.js @@ -0,0 +1,36 @@ +import { enumDirection, Vector } from "../../core/vector"; +import { ItemEjectorComponent } from "../components/item_ejector"; +import { MinerComponent } from "../components/miner"; +import { Entity } from "../entity"; +import { MetaBuilding } from "../meta_building"; + +export class MetaMinerBuilding extends MetaBuilding { + constructor() { + super("miner"); + } + + getName() { + return "Extract"; + } + + getSilhouetteColor() { + return "#b37dcd"; + } + + getDescription() { + return "Place over a shape or color to extract it. Six extractors fill exactly one belt."; + } + + /** + * Creates the entity at the given location + * @param {Entity} entity + */ + setupEntityComponents(entity) { + entity.addComponent(new MinerComponent({})); + entity.addComponent( + new ItemEjectorComponent({ + slots: [{ pos: new Vector(0, 0), direction: enumDirection.top }], + }) + ); + } +} diff --git a/src/js/game/buildings/mixer.js b/src/js/game/buildings/mixer.js new file mode 100644 index 00000000..15c7d699 --- /dev/null +++ b/src/js/game/buildings/mixer.js @@ -0,0 +1,73 @@ +import { globalConfig } from "../../core/config"; +import { enumDirection, Vector } from "../../core/vector"; +import { ItemAcceptorComponent, enumItemAcceptorItemFilter } from "../components/item_acceptor"; +import { ItemEjectorComponent } from "../components/item_ejector"; +import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor"; +import { Entity } from "../entity"; +import { MetaBuilding } from "../meta_building"; +import { GameRoot } from "../root"; +import { enumHubGoalRewards } from "../tutorial_goals"; + +export class MetaMixerBuilding extends MetaBuilding { + constructor() { + super("mixer"); + } + + getDimensions() { + return new Vector(2, 1); + } + + getName() { + return "Mix Colors"; + } + + getDescription() { + return "Mixes two colors using additive blending."; + } + + getSilhouetteColor() { + return "#cdbb7d"; + } + + /** + * @param {GameRoot} root + */ + getIsUnlocked(root) { + return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_mixer); + } + + /** + * Creates the entity at the given location + * @param {Entity} entity + */ + setupEntityComponents(entity) { + entity.addComponent( + new ItemProcessorComponent({ + inputsPerCharge: 2, + processorType: enumItemProcessorTypes.mixer, + }) + ); + + entity.addComponent( + new ItemEjectorComponent({ + slots: [{ pos: new Vector(0, 0), direction: enumDirection.top }], + }) + ); + entity.addComponent( + new ItemAcceptorComponent({ + slots: [ + { + pos: new Vector(0, 0), + directions: [enumDirection.bottom], + filter: enumItemAcceptorItemFilter.color, + }, + { + pos: new Vector(1, 0), + directions: [enumDirection.bottom], + filter: enumItemAcceptorItemFilter.color, + }, + ], + }) + ); + } +} diff --git a/src/js/game/buildings/painter.js b/src/js/game/buildings/painter.js new file mode 100644 index 00000000..746f9070 --- /dev/null +++ b/src/js/game/buildings/painter.js @@ -0,0 +1,73 @@ +import { globalConfig } from "../../core/config"; +import { enumDirection, Vector } from "../../core/vector"; +import { enumItemAcceptorItemFilter, ItemAcceptorComponent } from "../components/item_acceptor"; +import { ItemEjectorComponent } from "../components/item_ejector"; +import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor"; +import { Entity } from "../entity"; +import { MetaBuilding } from "../meta_building"; +import { enumHubGoalRewards } from "../tutorial_goals"; +import { GameRoot } from "../root"; + +export class MetaPainterBuilding extends MetaBuilding { + constructor() { + super("painter"); + } + + getDimensions() { + return new Vector(2, 1); + } + + getName() { + return "Dye"; + } + + getDescription() { + return "Colors the whole shape on the left input with the color from the right input."; + } + + getSilhouetteColor() { + return "#cd9b7d"; + } + + /** + * @param {GameRoot} root + */ + getIsUnlocked(root) { + return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_painter); + } + + /** + * Creates the entity at the given location + * @param {Entity} entity + */ + setupEntityComponents(entity) { + entity.addComponent( + new ItemProcessorComponent({ + inputsPerCharge: 2, + processorType: enumItemProcessorTypes.painter, + }) + ); + + entity.addComponent( + new ItemEjectorComponent({ + slots: [{ pos: new Vector(0, 0), direction: enumDirection.top }], + }) + ); + entity.addComponent( + new ItemAcceptorComponent({ + slots: [ + { + pos: new Vector(0, 0), + directions: [enumDirection.bottom], + filter: enumItemAcceptorItemFilter.shape, + }, + { + pos: new Vector(1, 0), + directions: [enumDirection.bottom], + filter: enumItemAcceptorItemFilter.color, + }, + ], + }) + ); + } +} diff --git a/src/js/game/buildings/rotater.js b/src/js/game/buildings/rotater.js new file mode 100644 index 00000000..6c129115 --- /dev/null +++ b/src/js/game/buildings/rotater.js @@ -0,0 +1,64 @@ +import { globalConfig } from "../../core/config"; +import { enumDirection, Vector } from "../../core/vector"; +import { ItemAcceptorComponent, enumItemAcceptorItemFilter } from "../components/item_acceptor"; +import { ItemEjectorComponent } from "../components/item_ejector"; +import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor"; +import { Entity } from "../entity"; +import { MetaBuilding } from "../meta_building"; +import { enumHubGoalRewards } from "../tutorial_goals"; +import { GameRoot } from "../root"; + +export class MetaRotaterBuilding extends MetaBuilding { + constructor() { + super("rotater"); + } + + getName() { + return "Rotate"; + } + + getDescription() { + return "Rotates shapes clockwise by 90 degrees."; + } + + getSilhouetteColor() { + return "#7dc6cd"; + } + + /** + * @param {GameRoot} root + */ + getIsUnlocked(root) { + return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_rotater); + } + + /** + * Creates the entity at the given location + * @param {Entity} entity + */ + setupEntityComponents(entity) { + entity.addComponent( + new ItemProcessorComponent({ + inputsPerCharge: 1, + processorType: enumItemProcessorTypes.rotater, + }) + ); + + entity.addComponent( + new ItemEjectorComponent({ + slots: [{ pos: new Vector(0, 0), direction: enumDirection.top }], + }) + ); + entity.addComponent( + new ItemAcceptorComponent({ + slots: [ + { + pos: new Vector(0, 0), + directions: [enumDirection.bottom], + filter: enumItemAcceptorItemFilter.shape, + }, + ], + }) + ); + } +} diff --git a/src/js/game/buildings/splitter.js b/src/js/game/buildings/splitter.js new file mode 100644 index 00000000..4e6370e6 --- /dev/null +++ b/src/js/game/buildings/splitter.js @@ -0,0 +1,80 @@ +import { globalConfig } from "../../core/config"; +import { enumDirection, Vector } from "../../core/vector"; +import { ItemAcceptorComponent } from "../components/item_acceptor"; +import { ItemEjectorComponent } from "../components/item_ejector"; +import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor"; +import { Entity } from "../entity"; +import { MetaBuilding } from "../meta_building"; +import { GameRoot } from "../root"; +import { enumHubGoalRewards } from "../tutorial_goals"; + +export class MetaSplitterBuilding extends MetaBuilding { + constructor() { + super("splitter"); + } + + getDimensions() { + return new Vector(2, 1); + } + + getName() { + return "Distribute"; + } + + getSilhouetteColor() { + return "#444"; + } + + getDescription() { + return "Accepts up to two inputs and evenly distributes them on the outputs. Can also be used to merge two inputs into one output."; + } + + /** + * @param {GameRoot} root + */ + getIsUnlocked(root) { + return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_splitter); + } + + /** + * Creates the entity at the given location + * @param {Entity} entity + */ + setupEntityComponents(entity) { + entity.addComponent( + new ItemAcceptorComponent({ + slots: [ + { + pos: new Vector(0, 0), + directions: [enumDirection.bottom], + }, + { + pos: new Vector(1, 0), + directions: [enumDirection.bottom], + }, + ], + }) + ); + + entity.addComponent( + new ItemProcessorComponent({ + inputsPerCharge: 1, + processorType: enumItemProcessorTypes.splitter, + + beltUnderlays: [ + { pos: new Vector(0, 0), direction: enumDirection.top }, + { pos: new Vector(1, 0), direction: enumDirection.top }, + ], + }) + ); + + entity.addComponent( + new ItemEjectorComponent({ + slots: [ + { pos: new Vector(0, 0), direction: enumDirection.top }, + { pos: new Vector(1, 0), direction: enumDirection.top }, + ], + }) + ); + } +} diff --git a/src/js/game/buildings/stacker.js b/src/js/game/buildings/stacker.js new file mode 100644 index 00000000..5edfb050 --- /dev/null +++ b/src/js/game/buildings/stacker.js @@ -0,0 +1,73 @@ +import { globalConfig } from "../../core/config"; +import { enumDirection, Vector } from "../../core/vector"; +import { ItemAcceptorComponent, enumItemAcceptorItemFilter } from "../components/item_acceptor"; +import { ItemEjectorComponent } from "../components/item_ejector"; +import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor"; +import { Entity } from "../entity"; +import { MetaBuilding } from "../meta_building"; +import { GameRoot } from "../root"; +import { enumHubGoalRewards } from "../tutorial_goals"; + +export class MetaStackerBuilding extends MetaBuilding { + constructor() { + super("stacker"); + } + + getName() { + return "Combine"; + } + + getSilhouetteColor() { + return "#9fcd7d"; + } + + getDescription() { + return "Combines both items. If they can not be merged, the right item is placed above the left item."; + } + + getDimensions() { + return new Vector(2, 1); + } + + /** + * @param {GameRoot} root + */ + getIsUnlocked(root) { + return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_stacker); + } + + /** + * Creates the entity at the given location + * @param {Entity} entity + */ + setupEntityComponents(entity) { + entity.addComponent( + new ItemProcessorComponent({ + inputsPerCharge: 2, + processorType: enumItemProcessorTypes.stacker, + }) + ); + + entity.addComponent( + new ItemEjectorComponent({ + slots: [{ pos: new Vector(0, 0), direction: enumDirection.top }], + }) + ); + entity.addComponent( + new ItemAcceptorComponent({ + slots: [ + { + pos: new Vector(0, 0), + directions: [enumDirection.bottom], + filter: enumItemAcceptorItemFilter.shape, + }, + { + pos: new Vector(1, 0), + directions: [enumDirection.bottom], + filter: enumItemAcceptorItemFilter.shape, + }, + ], + }) + ); + } +} diff --git a/src/js/game/buildings/trash.js b/src/js/game/buildings/trash.js new file mode 100644 index 00000000..e630255c --- /dev/null +++ b/src/js/game/buildings/trash.js @@ -0,0 +1,73 @@ +import { enumDirection, Vector } from "../../core/vector"; +import { ItemAcceptorComponent } from "../components/item_acceptor"; +import { ItemEjectorComponent } from "../components/item_ejector"; +import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor"; +import { Entity } from "../entity"; +import { MetaBuilding } from "../meta_building"; +import { enumHubGoalRewards } from "../tutorial_goals"; +import { GameRoot } from "../root"; + +export class MetaTrashBuilding extends MetaBuilding { + constructor() { + super("trash"); + } + + getName() { + return "Destroyer"; + } + + getDescription() { + return "Accepts inputs from all sides and destroys them. Forever."; + } + + isRotateable() { + return false; + } + + getSilhouetteColor() { + return "#cd7d86"; + } + + /** + * @param {GameRoot} root + */ + getIsUnlocked(root) { + return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_cutter_and_trash); + } + + /** + * Creates the entity at the given location + * @param {Entity} entity + */ + setupEntityComponents(entity) { + entity.addComponent( + new ItemProcessorComponent({ + inputsPerCharge: 1, + processorType: enumItemProcessorTypes.trash, + }) + ); + + // Required, since the item processor needs this. + entity.addComponent( + new ItemEjectorComponent({ + slots: [], + }) + ); + + entity.addComponent( + new ItemAcceptorComponent({ + slots: [ + { + pos: new Vector(0, 0), + directions: [ + enumDirection.top, + enumDirection.right, + enumDirection.bottom, + enumDirection.left, + ], + }, + ], + }) + ); + } +} diff --git a/src/js/game/buildings/underground_belt.js b/src/js/game/buildings/underground_belt.js new file mode 100644 index 00000000..31021c6e --- /dev/null +++ b/src/js/game/buildings/underground_belt.js @@ -0,0 +1,158 @@ +import { Loader } from "../../core/loader"; +import { enumDirection, Vector, enumAngleToDirection, enumDirectionToVector } from "../../core/vector"; +import { ItemAcceptorComponent } from "../components/item_acceptor"; +import { ItemEjectorComponent } from "../components/item_ejector"; +import { enumUndergroundBeltMode, UndergroundBeltComponent } from "../components/underground_belt"; +import { Entity } from "../entity"; +import { MetaBuilding } from "../meta_building"; +import { GameRoot } from "../root"; +import { globalConfig } from "../../core/config"; +import { enumHubGoalRewards } from "../tutorial_goals"; + +/** @enum {string} */ +export const arrayUndergroundRotationVariantToMode = [ + enumUndergroundBeltMode.sender, + enumUndergroundBeltMode.receiver, +]; + +export class MetaUndergroundBeltBuilding extends MetaBuilding { + constructor() { + super("underground_belt"); + } + + getName() { + return "Tunnel"; + } + + getSilhouetteColor() { + return "#555"; + } + + getDescription() { + return "Allows to tunnel resources under buildings and belts."; + } + + getFlipOrientationAfterPlacement() { + return true; + } + + getStayInPlacementMode() { + return true; + } + + getPreviewSprite(rotationVariant) { + switch (arrayUndergroundRotationVariantToMode[rotationVariant]) { + case enumUndergroundBeltMode.sender: + return Loader.getSprite("sprites/buildings/underground_belt_entry.png"); + case enumUndergroundBeltMode.receiver: + return Loader.getSprite("sprites/buildings/underground_belt_exit.png"); + default: + assertAlways(false, "Invalid rotation variant"); + } + } + + /** + * @param {GameRoot} root + */ + getIsUnlocked(root) { + return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_tunnel); + } + + /** + * Creates the entity at the given location + * @param {Entity} entity + */ + setupEntityComponents(entity) { + // Required, since the item processor needs this. + entity.addComponent( + new ItemEjectorComponent({ + slots: [], + }) + ); + + entity.addComponent(new UndergroundBeltComponent({})); + entity.addComponent( + new ItemAcceptorComponent({ + slots: [], + }) + ); + } + + /** + * @param {GameRoot} root + * @param {Vector} tile + * @param {number} rotation + * @return {{ rotation: number, rotationVariant: number, connectedEntities?: Array }} + */ + computeOptimalDirectionAndRotationVariantAtTile(root, tile, rotation) { + const searchDirection = enumAngleToDirection[rotation]; + const searchVector = enumDirectionToVector[searchDirection]; + + const targetRotation = (rotation + 180) % 360; + + for (let searchOffset = 1; searchOffset <= globalConfig.undergroundBeltMaxTiles; ++searchOffset) { + tile = tile.addScalars(searchVector.x, searchVector.y); + + const contents = root.map.getTileContent(tile); + if (contents) { + const undergroundComp = contents.components.UndergroundBelt; + if (undergroundComp) { + const staticComp = contents.components.StaticMapEntity; + if (staticComp.rotationDegrees === targetRotation) { + if (undergroundComp.mode !== enumUndergroundBeltMode.sender) { + // If we encounter an underground receiver on our way which is also faced in our direction, we don't accept that + break; + } + // console.log("GOT IT! rotation is", rotation, "and target is", staticComp.rotationDegrees); + + return { + rotation: targetRotation, + rotationVariant: 1, + connectedEntities: [contents], + }; + } + } + } + } + + return { + rotation, + rotationVariant: 0, + }; + } + + /** + * @param {Entity} entity + * @param {number} rotationVariant + */ + updateRotationVariant(entity, rotationVariant) { + entity.components.StaticMapEntity.spriteKey = this.getPreviewSprite(rotationVariant).spriteName; + + switch (arrayUndergroundRotationVariantToMode[rotationVariant]) { + case enumUndergroundBeltMode.sender: { + entity.components.UndergroundBelt.mode = enumUndergroundBeltMode.sender; + entity.components.ItemEjector.setSlots([]); + entity.components.ItemAcceptor.setSlots([ + { + pos: new Vector(0, 0), + directions: [enumDirection.bottom], + }, + ]); + return; + } + case enumUndergroundBeltMode.receiver: { + entity.components.UndergroundBelt.mode = enumUndergroundBeltMode.receiver; + entity.components.ItemAcceptor.setSlots([]); + entity.components.ItemEjector.setSlots([ + { + pos: new Vector(0, 0), + direction: enumDirection.top, + }, + ]); + return; + } + default: + assertAlways(false, "Invalid rotation variant"); + } + } +} diff --git a/src/js/game/camera.js b/src/js/game/camera.js new file mode 100644 index 00000000..f302f543 --- /dev/null +++ b/src/js/game/camera.js @@ -0,0 +1,870 @@ +import { + Math_abs, + Math_ceil, + Math_floor, + Math_min, + Math_random, + performanceNow, + Math_max, +} from "../core/builtins"; +import { Rectangle } from "../core/rectangle"; +import { Signal, STOP_PROPAGATION } from "../core/signal"; +import { clamp, lerp } from "../core/utils"; +import { mixVector, Vector } from "../core/vector"; +import { globalConfig } from "../core/config"; +import { GameRoot } from "./root"; +import { BasicSerializableObject, types } from "../savegame/serialization"; +import { clickDetectorGlobals } from "../core/click_detector"; +import { createLogger } from "../core/logging"; + +const logger = createLogger("camera"); + +export const USER_INTERACT_MOVE = "move"; +export const USER_INTERACT_ZOOM = "zoom"; +export const USER_INTERACT_TOUCHEND = "touchend"; + +const velocitySmoothing = 0.5; +const velocityFade = 0.98; +const velocityStrength = 0.4; +const velocityMax = 20; + +export class Camera extends BasicSerializableObject { + constructor(root) { + super(); + + /** @type {GameRoot} */ + this.root = root; + + // Zoom level, 2 means double size + + // Find optimal initial zoom + + this.zoomLevel = this.findInitialZoom(); + this.clampZoomLevel(); + + /** @type {Vector} */ + this.center = new Vector(0, 0); + + // Input handling + this.currentlyMoving = false; + this.lastMovingPosition = null; + this.cameraUpdateTimeBucket = 0.0; + this.didMoveSinceTouchStart = false; + this.currentlyPinching = false; + this.lastPinchPositions = null; + + this.keyboardForce = new Vector(); + + // Signal which gets emitted once the user changed something + this.userInteraction = new Signal(); + + /** @type {Vector} */ + this.currentShake = new Vector(0, 0); + + /** @type {Vector} */ + this.currentPan = new Vector(0, 0); + + // Set desired pan (camera movement) + /** @type {Vector} */ + this.desiredPan = new Vector(0, 0); + + // Set desired camera center + /** @type {Vector} */ + this.desiredCenter = null; + + // Set desired camera zoom + /** @type {number} */ + this.desiredZoom = null; + + /** @type {Vector} */ + this.touchPostMoveVelocity = new Vector(0, 0); + + // Handlers + this.downPreHandler = new Signal(/* pos */); + this.movePreHandler = new Signal(/* pos */); + this.pinchPreHandler = new Signal(/* pos */); + this.upPostHandler = new Signal(/* pos */); + + this.internalInitEvents(); + this.clampZoomLevel(); + this.bindKeys(); + } + + // Serialization + static getId() { + return "Camera"; + } + + static getSchema() { + return { + zoomLevel: types.float, + center: types.vector, + }; + } + + deserialize(data) { + const errorCode = super.deserialize(data); + if (errorCode) { + return errorCode; + } + + // Safety + this.clampZoomLevel(); + } + + // Simple geters & setters + + addScreenShake(amount) { + const currentShakeAmount = this.currentShake.length(); + const scale = 1 / (1 + 3 * currentShakeAmount); + this.currentShake.x = this.currentShake.x + 2 * (Math_random() - 0.5) * scale * amount; + this.currentShake.y = this.currentShake.y + 2 * (Math_random() - 0.5) * scale * amount; + } + + /** + * Sets a point in world space to focus on + * @param {Vector} center + */ + setDesiredCenter(center) { + this.desiredCenter = center.copy(); + this.currentlyMoving = false; + } + + /** + * Returns if this camera is currently moving by a non-user interaction + */ + isCurrentlyMovingToDesiredCenter() { + return this.desiredCenter !== null; + } + + /** + * Sets the camera pan, every frame the camera will move by this amount + * @param {Vector} pan + */ + setPan(pan) { + this.desiredPan = pan.copy(); + } + + /** + * Finds a good initial zoom level + */ + findInitialZoom() { + return 3; + const desiredWorldSpaceWidth = 20 * globalConfig.tileSize; + const zoomLevelX = this.root.gameWidth / desiredWorldSpaceWidth; + const zoomLevelY = this.root.gameHeight / desiredWorldSpaceWidth; + + const finalLevel = Math_min(zoomLevelX, zoomLevelY); + assert( + Number.isFinite(finalLevel) && finalLevel > 0, + "Invalid zoom level computed for initial zoom: " + finalLevel + ); + return finalLevel; + } + + /** + * Clears all animations + */ + clearAnimations() { + this.touchPostMoveVelocity.x = 0; + this.touchPostMoveVelocity.y = 0; + this.desiredCenter = null; + this.desiredPan.x = 0; + this.desiredPan.y = 0; + this.currentPan.x = 0; + this.currentPan.y = 0; + this.currentlyPinching = false; + this.currentlyMoving = false; + this.lastMovingPosition = null; + this.didMoveSinceTouchStart = false; + this.desiredZoom = null; + } + + /** + * Returns if the user is currently interacting with the camera + * @returns {boolean} true if the user interacts + */ + isCurrentlyInteracting() { + if (this.currentlyPinching) { + return true; + } + if (this.currentlyMoving) { + // Only interacting if moved at least once + return this.didMoveSinceTouchStart; + } + if (this.touchPostMoveVelocity.lengthSquare() > 1) { + return true; + } + return false; + } + + /** + * Returns if in the next frame the viewport will change + * @returns {boolean} true if it willchange + */ + viewportWillChange() { + return this.desiredCenter !== null || this.desiredZoom !== null || this.isCurrentlyInteracting(); + } + + /** + * Cancels all interactions, that is user interaction and non user interaction + */ + cancelAllInteractions() { + this.touchPostMoveVelocity = new Vector(0, 0); + this.desiredCenter = null; + this.currentlyMoving = false; + this.currentlyPinching = false; + this.desiredZoom = null; + } + + /** + * Returns effective viewport width + */ + getViewportWidth() { + return this.root.gameWidth / this.zoomLevel; + } + + /** + * Returns effective viewport height + */ + getViewportHeight() { + return this.root.gameHeight / this.zoomLevel; + } + + /** + * Returns effective world space viewport left + */ + getViewportLeft() { + return this.center.x - this.getViewportWidth() / 2 + (this.currentShake.x * 10) / this.zoomLevel; + } + + /** + * Returns effective world space viewport right + */ + getViewportRight() { + return this.center.x + this.getViewportWidth() / 2 + (this.currentShake.x * 10) / this.zoomLevel; + } + + /** + * Returns effective world space viewport top + */ + getViewportTop() { + return this.center.y - this.getViewportHeight() / 2 + (this.currentShake.x * 10) / this.zoomLevel; + } + + /** + * Returns effective world space viewport bottom + */ + getViewportBottom() { + return this.center.y + this.getViewportHeight() / 2 + (this.currentShake.x * 10) / this.zoomLevel; + } + + /** + * Returns the visible world space rect + * @returns {Rectangle} + */ + getVisibleRect() { + return Rectangle.fromTRBL( + Math_floor(this.getViewportTop()), + Math_ceil(this.getViewportRight()), + Math_ceil(this.getViewportBottom()), + Math_floor(this.getViewportLeft()) + ); + } + + getIsMapOverlayActive() { + return this.zoomLevel < globalConfig.mapChunkOverviewMinZoom; + } + + /** + * Attaches all event listeners + */ + internalInitEvents() { + this.eventListenerTouchStart = this.onTouchStart.bind(this); + this.eventListenerTouchEnd = this.onTouchEnd.bind(this); + this.eventListenerTouchMove = this.onTouchMove.bind(this); + this.eventListenerMousewheel = this.onMouseWheel.bind(this); + this.eventListenerMouseDown = this.onMouseDown.bind(this); + this.eventListenerMouseMove = this.onMouseMove.bind(this); + this.eventListenerMouseUp = this.onMouseUp.bind(this); + + this.root.canvas.addEventListener("touchstart", this.eventListenerTouchStart); + this.root.canvas.addEventListener("touchend", this.eventListenerTouchEnd); + this.root.canvas.addEventListener("touchcancel", this.eventListenerTouchEnd); + this.root.canvas.addEventListener("touchmove", this.eventListenerTouchMove); + + this.root.canvas.addEventListener("wheel", this.eventListenerMousewheel); + this.root.canvas.addEventListener("mousedown", this.eventListenerMouseDown); + this.root.canvas.addEventListener("mousemove", this.eventListenerMouseMove); + this.root.canvas.addEventListener("mouseup", this.eventListenerMouseUp); + this.root.canvas.addEventListener("mouseout", this.eventListenerMouseUp); + } + + /** + * Cleans up all event listeners + */ + cleanup() { + this.root.canvas.removeEventListener("touchstart", this.eventListenerTouchStart); + this.root.canvas.removeEventListener("touchend", this.eventListenerTouchEnd); + this.root.canvas.removeEventListener("touchcancel", this.eventListenerTouchEnd); + this.root.canvas.removeEventListener("touchmove", this.eventListenerTouchMove); + + this.root.canvas.removeEventListener("wheel", this.eventListenerMousewheel); + this.root.canvas.removeEventListener("mousedown", this.eventListenerMouseDown); + this.root.canvas.removeEventListener("mousemove", this.eventListenerMouseMove); + this.root.canvas.removeEventListener("mouseup", this.eventListenerMouseUp); + this.root.canvas.removeEventListener("mouseout", this.eventListenerMouseUp); + } + + /** + * Binds the arrow keys + */ + bindKeys() { + const mapper = this.root.gameState.keyActionMapper; + mapper.getBinding("map_move_up").add(() => (this.keyboardForce.y = -1)); + mapper.getBinding("map_move_down").add(() => (this.keyboardForce.y = 1)); + mapper.getBinding("map_move_right").add(() => (this.keyboardForce.x = 1)); + mapper.getBinding("map_move_left").add(() => (this.keyboardForce.x = -1)); + + mapper.getBinding("center_map").add(() => (this.desiredCenter = new Vector(0, 0))); + } + + /** + * Converts from screen to world space + * @param {Vector} screen + * @returns {Vector} world space + */ + screenToWorld(screen) { + const centerSpace = screen.subScalars(this.root.gameWidth / 2, this.root.gameHeight / 2); + return centerSpace.divideScalar(this.zoomLevel).add(this.center); + } + + /** + * Converts from world to screen space + * @param {Vector} world + * @returns {Vector} screen space + */ + worldToScreen(world) { + const screenSpace = world.sub(this.center).multiplyScalar(this.zoomLevel); + return screenSpace.addScalars(this.root.gameWidth / 2, this.root.gameHeight / 2); + } + + /** + * Returns if a point is on screen + * @param {Vector} point + * @returns {boolean} true if its on screen + */ + isWorldPointOnScreen(point) { + const rect = this.getVisibleRect(); + return rect.containsPoint(point.x, point.y); + } + + /** + * Returns if we can further zoom in + * @returns {boolean} + */ + canZoomIn() { + const maxLevel = this.root.app.platformWrapper.getMaximumZoom(); + return this.zoomLevel <= maxLevel - 0.01; + } + + /** + * Returns if we can further zoom out + * @returns {boolean} + */ + canZoomOut() { + const minLevel = this.root.app.platformWrapper.getMinimumZoom(); + return this.zoomLevel >= minLevel + 0.01; + } + + // EVENTS + + /** + * Checks if the mouse event is too close after a touch event and thus + * should get ignored + */ + checkPreventDoubleMouse() { + if (performanceNow() - clickDetectorGlobals.lastTouchTime < 1000.0) { + return false; + } + return true; + } + + /** + * Mousedown handler + * @param {MouseEvent} event + */ + onMouseDown(event) { + if (event.cancelable) { + event.preventDefault(); + // event.stopPropagation(); + } + + if (!this.checkPreventDoubleMouse()) { + return; + } + + this.touchPostMoveVelocity = new Vector(0, 0); + if (event.which === 1) { + this.combinedSingleTouchStartHandler(event.clientX, event.clientY); + } + return false; + } + + /** + * Mousemove handler + * @param {MouseEvent} event + */ + onMouseMove(event) { + if (event.cancelable) { + event.preventDefault(); + // event.stopPropagation(); + } + + if (!this.checkPreventDoubleMouse()) { + return; + } + + if (event.which === 1) { + this.combinedSingleTouchMoveHandler(event.clientX, event.clientY); + } + + // Clamp everything afterwards + this.clampZoomLevel(); + return false; + } + + /** + * Mouseup handler + * @param {MouseEvent=} event + */ + onMouseUp(event) { + if (event) { + if (event.cancelable) { + event.preventDefault(); + // event.stopPropagation(); + } + } + + if (!this.checkPreventDoubleMouse()) { + return; + } + + this.combinedSingleTouchStopHandler(event.clientX, event.clientY); + return false; + } + + /** + * Mousewheel event + * @param {WheelEvent} event + */ + onMouseWheel(event) { + if (event.cancelable) { + event.preventDefault(); + // event.stopPropagation(); + } + + const delta = Math.sign(event.deltaY) * -0.15; + assert(Number.isFinite(delta), "Got invalid delta in mouse wheel event: " + event.deltaY); + assert(Number.isFinite(this.zoomLevel), "Got invalid zoom level *before* wheel: " + this.zoomLevel); + this.zoomLevel *= 1 + delta; + assert(Number.isFinite(this.zoomLevel), "Got invalid zoom level *after* wheel: " + this.zoomLevel); + + this.clampZoomLevel(); + this.desiredZoom = null; + return false; + } + + /** + * Touch start handler + * @param {TouchEvent} event + */ + onTouchStart(event) { + if (event.cancelable) { + event.preventDefault(); + // event.stopPropagation(); + } + + clickDetectorGlobals.lastTouchTime = performanceNow(); + this.touchPostMoveVelocity = new Vector(0, 0); + + if (event.touches.length === 1) { + const touch = event.touches[0]; + this.combinedSingleTouchStartHandler(touch.clientX, touch.clientY); + } else if (event.touches.length === 2) { + if (this.pinchPreHandler.dispatch() === STOP_PROPAGATION) { + // Something prevented pinching + return false; + } + + const touch1 = event.touches[0]; + const touch2 = event.touches[1]; + this.currentlyMoving = false; + this.currentlyPinching = true; + this.lastPinchPositions = [ + new Vector(touch1.clientX, touch1.clientY), + new Vector(touch2.clientX, touch2.clientY), + ]; + } + return false; + } + + /** + * Touch move handler + * @param {TouchEvent} event + */ + onTouchMove(event) { + if (event.cancelable) { + event.preventDefault(); + // event.stopPropagation(); + } + + clickDetectorGlobals.lastTouchTime = performanceNow(); + + if (event.touches.length === 1) { + const touch = event.touches[0]; + this.combinedSingleTouchMoveHandler(touch.clientX, touch.clientY); + } else if (event.touches.length === 2) { + if (this.currentlyPinching) { + const touch1 = event.touches[0]; + const touch2 = event.touches[1]; + + const newPinchPositions = [ + new Vector(touch1.clientX, touch1.clientY), + new Vector(touch2.clientX, touch2.clientY), + ]; + + // Get distance of taps last time and now + const lastDistance = this.lastPinchPositions[0].distance(this.lastPinchPositions[1]); + const thisDistance = newPinchPositions[0].distance(newPinchPositions[1]); + + // IMPORTANT to do math max here to avoid NaN and causing an invalid zoom level + const difference = thisDistance / Math_max(0.001, lastDistance); + + // Find old center of zoom + let oldCenter = this.lastPinchPositions[0].centerPoint(this.lastPinchPositions[1]); + + // Find new center of zoom + let center = newPinchPositions[0].centerPoint(newPinchPositions[1]); + + // Compute movement + let movement = oldCenter.sub(center); + this.center.x += movement.x / this.zoomLevel; + this.center.y += movement.y / this.zoomLevel; + + // Compute zoom + center = center.sub(new Vector(this.root.gameWidth / 2, this.root.gameHeight / 2)); + + // Apply zoom + assert( + Number.isFinite(difference), + "Invalid pinch difference: " + + difference + + "(last=" + + lastDistance + + ", new = " + + thisDistance + + ")" + ); + this.zoomLevel *= difference; + + // Stick to pivot point + const correcture = center.multiplyScalar(difference - 1).divideScalar(this.zoomLevel); + + this.center = this.center.add(correcture); + this.lastPinchPositions = newPinchPositions; + this.userInteraction.dispatch(USER_INTERACT_MOVE); + + // Since we zoomed, abort any programmed zooming + if (this.desiredZoom) { + this.desiredZoom = null; + } + } + } + + // Clamp everything afterwards + this.clampZoomLevel(); + return false; + } + + /** + * Touch end and cancel handler + * @param {TouchEvent=} event + */ + onTouchEnd(event) { + if (event) { + if (event.cancelable) { + event.preventDefault(); + // event.stopPropagation(); + } + } + + clickDetectorGlobals.lastTouchTime = performanceNow(); + if (event.changedTouches.length === 0) { + logger.warn("Touch end without changed touches"); + } + + const touch = event.changedTouches[0]; + this.combinedSingleTouchStopHandler(touch.clientX, touch.clientY); + return false; + } + + /** + * Internal touch start handler + * @param {number} x + * @param {number} y + */ + combinedSingleTouchStartHandler(x, y) { + const pos = new Vector(x, y); + if (this.downPreHandler.dispatch(pos) === STOP_PROPAGATION) { + // Somebody else captured it + return; + } + + this.touchPostMoveVelocity = new Vector(0, 0); + this.currentlyMoving = true; + this.lastMovingPosition = pos; + this.didMoveSinceTouchStart = false; + } + + /** + * Internal touch move handler + * @param {number} x + * @param {number} y + */ + combinedSingleTouchMoveHandler(x, y) { + const pos = new Vector(x, y); + if (this.movePreHandler.dispatch(pos) === STOP_PROPAGATION) { + // Somebody else captured it + return; + } + + if (!this.currentlyMoving) { + return false; + } + + let delta = this.lastMovingPosition.sub(pos).divideScalar(this.zoomLevel); + if (G_IS_DEV && globalConfig.debug.testCulling) { + // When testing culling, we see everything from the same distance + delta = delta.multiplyScalar(this.zoomLevel * -2); + } + + this.didMoveSinceTouchStart = this.didMoveSinceTouchStart || delta.length() > 0; + this.center = this.center.add(delta); + + this.touchPostMoveVelocity = this.touchPostMoveVelocity + .multiplyScalar(velocitySmoothing) + .add(delta.multiplyScalar(1 - velocitySmoothing)); + + this.lastMovingPosition = pos; + this.userInteraction.dispatch(USER_INTERACT_MOVE); + + // Since we moved, abort any programmed moving + if (this.desiredCenter) { + this.desiredCenter = null; + } + } + + /** + * Internal touch stop handler + */ + combinedSingleTouchStopHandler(x, y) { + if (this.currentlyMoving || this.currentlyPinching) { + this.currentlyMoving = false; + this.currentlyPinching = false; + this.lastMovingPosition = null; + this.lastPinchPositions = null; + this.userInteraction.dispatch(USER_INTERACT_TOUCHEND); + this.didMoveSinceTouchStart = false; + } + this.upPostHandler.dispatch(new Vector(x, y)); + } + + /** + * Clamps the camera zoom level within the allowed range + */ + clampZoomLevel() { + if (G_IS_DEV && globalConfig.debug.disableZoomLimits) { + return; + } + + const wrapper = this.root.app.platformWrapper; + + assert(Number.isFinite(this.zoomLevel), "Invalid zoom level *before* clamp: " + this.zoomLevel); + this.zoomLevel = clamp(this.zoomLevel, wrapper.getMinimumZoom(), wrapper.getMaximumZoom()); + assert(Number.isFinite(this.zoomLevel), "Invalid zoom level *after* clamp: " + this.zoomLevel); + + if (this.desiredZoom) { + this.desiredZoom = clamp(this.desiredZoom, wrapper.getMinimumZoom(), wrapper.getMaximumZoom()); + } + } + + /** + * Updates the camera + * @param {number} dt Delta time in milliseconds + */ + update(dt) { + dt = Math_min(dt, 33); + this.cameraUpdateTimeBucket += dt; + + // Simulate movement of N FPS + const updatesPerFrame = 4; + const physicsStepSizeMs = 1000.0 / (60.0 * updatesPerFrame); + + let now = this.root.time.systemNow() - 3 * physicsStepSizeMs; + + while (this.cameraUpdateTimeBucket > physicsStepSizeMs) { + now += physicsStepSizeMs; + this.cameraUpdateTimeBucket -= physicsStepSizeMs; + + this.internalUpdatePanning(now, physicsStepSizeMs); + this.internalUpdateZooming(now, physicsStepSizeMs); + this.internalUpdateCentering(now, physicsStepSizeMs); + this.internalUpdateShake(now, physicsStepSizeMs); + this.internalUpdateKeyboardForce(now, physicsStepSizeMs); + } + this.clampZoomLevel(); + } + + /** + * Prepares a context to transform it + * @param {CanvasRenderingContext2D} context + */ + transform(context) { + if (G_IS_DEV && globalConfig.debug.testCulling) { + context.transform(1, 0, 0, 1, 100, 100); + return; + } + + this.clampZoomLevel(); + const zoom = this.zoomLevel; + + context.transform( + // Scale, skew, rotate + zoom, + 0, + 0, + zoom, + + // Translate + -zoom * this.getViewportLeft(), + -zoom * this.getViewportTop() + ); + } + + /** + * Internal shake handler + * @param {number} now Time now in seconds + * @param {number} dt Delta time + */ + internalUpdateShake(now, dt) { + this.currentShake = this.currentShake.multiplyScalar(0.92); + } + + /** + * Internal pan handler + * @param {number} now Time now in seconds + * @param {number} dt Delta time + */ + internalUpdatePanning(now, dt) { + const baseStrength = velocityStrength * this.root.app.platformWrapper.getTouchPanStrength(); + + this.touchPostMoveVelocity = this.touchPostMoveVelocity.multiplyScalar(velocityFade); + + // Check influence of past points + if (!this.currentlyMoving && !this.currentlyPinching) { + const len = this.touchPostMoveVelocity.length(); + if (len >= velocityMax) { + this.touchPostMoveVelocity.x = (this.touchPostMoveVelocity.x * velocityMax) / len; + this.touchPostMoveVelocity.y = (this.touchPostMoveVelocity.y * velocityMax) / len; + } + + this.center = this.center.add(this.touchPostMoveVelocity.multiplyScalar(baseStrength)); + + // Panning + this.currentPan = mixVector(this.currentPan, this.desiredPan, 0.06); + this.center = this.center.add(this.currentPan.multiplyScalar((0.5 * dt) / this.zoomLevel)); + } + } + + /** + * Updates the non user interaction zooming + * @param {number} now Time now in seconds + * @param {number} dt Delta time + */ + internalUpdateZooming(now, dt) { + if (!this.currentlyPinching && this.desiredZoom !== null) { + const diff = this.zoomLevel - this.desiredZoom; + if (Math_abs(diff) > 0.05) { + let fade = 0.94; + if (diff > 0) { + // Zoom out faster than in + fade = 0.9; + } + + assert(Number.isFinite(this.desiredZoom), "Desired zoom is NaN: " + this.desiredZoom); + assert(Number.isFinite(fade), "Zoom fade is NaN: " + fade); + this.zoomLevel = this.zoomLevel * fade + this.desiredZoom * (1 - fade); + assert(Number.isFinite(this.zoomLevel), "Zoom level is NaN after fade: " + this.zoomLevel); + } else { + this.desiredZoom = null; + } + } + } + + /** + * Updates the non user interaction centering + * @param {number} now Time now in seconds + * @param {number} dt Delta time + */ + internalUpdateCentering(now, dt) { + if (!this.currentlyMoving && this.desiredCenter !== null) { + const diff = this.center.direction(this.desiredCenter); + const length = diff.length(); + const tolerance = 1 / this.zoomLevel; + if (length > tolerance) { + const movement = diff.multiplyScalar(Math_min(1, dt * 0.008)); + this.center.x += movement.x; + this.center.y += movement.y; + } else { + this.desiredCenter = null; + } + } + } + + /** + * Updates the keyboard forces + * @param {number} now + * @param {number} dt Delta time + */ + internalUpdateKeyboardForce(now, dt) { + if (!this.currentlyMoving && this.desiredCenter == null) { + const limitingDimension = Math_min(this.root.gameWidth, this.root.gameHeight); + + const moveAmount = ((limitingDimension / 2048) * dt) / this.zoomLevel; + + let forceX = 0; + let forceY = 0; + + const actionMapper = this.root.gameState.keyActionMapper; + if (actionMapper.getBinding("map_move_up").currentlyDown) { + forceY -= 1; + } + + if (actionMapper.getBinding("map_move_down").currentlyDown) { + forceY += 1; + } + + if (actionMapper.getBinding("map_move_left").currentlyDown) { + forceX -= 1; + } + + if (actionMapper.getBinding("map_move_right").currentlyDown) { + forceX += 1; + } + + this.center.x += moveAmount * forceX; + this.center.y += moveAmount * forceY; + } + } +} diff --git a/src/js/game/canvas_click_interceptor.js b/src/js/game/canvas_click_interceptor.js new file mode 100644 index 00000000..675c1387 --- /dev/null +++ b/src/js/game/canvas_click_interceptor.js @@ -0,0 +1,70 @@ +import { STOP_PROPAGATION } from "../core/signal"; +import { GameRoot } from "./root"; +import { ClickDetector } from "../core/click_detector"; +import { createLogger } from "../core/logging"; + +const logger = createLogger("canvas_click_interceptor"); + +export class CanvasClickInterceptor { + /** + * @param {GameRoot} root + */ + constructor(root) { + this.root = root; + + this.root.signals.postLoadHook.add(this.initialize, this); + this.root.signals.aboutToDestruct.add(this.cleanup, this); + + /** @type {Array} */ + this.interceptors = []; + } + + initialize() { + this.clickDetector = new ClickDetector(this.root.canvas, { + applyCssClass: null, + captureTouchmove: false, + targetOnly: true, + preventDefault: true, + maxDistance: 13, + clickSound: null, + }); + this.clickDetector.click.add(this.onCanvasClick, this); + this.clickDetector.rightClick.add(this.onCanvasRightClick, this); + + if (this.root.hud.parts.buildingPlacer) { + this.interceptors.push(this.root.hud.parts.buildingPlacer); + } + + logger.log("Registered", this.interceptors.length, "interceptors"); + } + + cleanup() { + if (this.clickDetector) { + this.clickDetector.cleanup(); + } + this.interceptors = []; + } + + onCanvasClick(position, event, cancelAction = false) { + if (!this.root.gameInitialized) { + logger.warn("Skipping click outside of game initiaization!"); + return; + } + + if (this.root.hud.hasBlockingOverlayOpen()) { + return; + } + + for (let i = 0; i < this.interceptors.length; ++i) { + const interceptor = this.interceptors[i]; + if (interceptor.onCanvasClick(position, cancelAction) === STOP_PROPAGATION) { + // log(this, "Interceptor", interceptor.constructor.name, "catched click"); + break; + } + } + } + + onCanvasRightClick(position, event) { + this.onCanvasClick(position, event, true); + } +} diff --git a/src/js/game/colors.js b/src/js/game/colors.js new file mode 100644 index 00000000..8926dd23 --- /dev/null +++ b/src/js/game/colors.js @@ -0,0 +1,167 @@ +/** @enum {string} */ +export const enumColors = { + red: "red", + green: "green", + blue: "blue", + + yellow: "yellow", + purple: "purple", + cyan: "cyan", + + white: "white", + uncolored: "uncolored", +}; + +/** @enum {string} */ +export const enumColorToShortcode = { + [enumColors.red]: "r", + [enumColors.green]: "g", + [enumColors.blue]: "b", + + [enumColors.yellow]: "y", + [enumColors.purple]: "p", + [enumColors.cyan]: "c", + + [enumColors.white]: "w", + [enumColors.uncolored]: "u", +}; + +/** @enum {enumColors} */ +export const enumShortcodeToColor = {}; +for (const key in enumColorToShortcode) { + enumShortcodeToColor[enumColorToShortcode[key]] = key; +} + +/** @enum {string} */ +export const enumColorsToHexCode = { + [enumColors.red]: "#ff666a", + [enumColors.green]: "#78ff66", + [enumColors.blue]: "#66a7ff", + + // red + green + [enumColors.yellow]: "#fcf52a", + + // red + blue + [enumColors.purple]: "#dd66ff", + + // blue + green + [enumColors.cyan]: "#87fff5", + + // blue + green + red + [enumColors.white]: "#ffffff", + + [enumColors.uncolored]: "#aaaaaa", +}; + +const c = enumColors; +/** @enum {Object.} */ +export const enumColorMixingResults = { + // 255, 0, 0 + [c.red]: { + [c.green]: c.yellow, + [c.blue]: c.purple, + + [c.yellow]: c.yellow, + [c.purple]: c.purple, + [c.cyan]: c.white, + + [c.white]: c.white, + }, + + // 0, 255, 0 + [c.green]: { + [c.blue]: c.cyan, + + [c.yellow]: c.yellow, + [c.purple]: c.white, + [c.cyan]: c.cyan, + + [c.white]: c.white, + }, + + // 0, 255, 0 + [c.blue]: { + [c.yellow]: c.white, + [c.purple]: c.purple, + [c.cyan]: c.cyan, + + [c.white]: c.white, + }, + + // 255, 255, 0 + [c.yellow]: { + [c.purple]: c.white, + [c.cyan]: c.white, + }, + + // 255, 0, 255 + [c.purple]: { + [c.cyan]: c.white, + }, + + // 0, 255, 255 + [c.cyan]: {}, + + //// SPECIAL COLORS + + // 255, 255, 255 + [c.white]: { + // auto + }, + + // X, X, X + [c.uncolored]: { + // auto + }, +}; + +// Create same color lookups +for (const color in enumColors) { + enumColorMixingResults[color][color] = color; + + // Anything with white is white again + enumColorMixingResults[color][c.white] = c.white; + + // Anything with uncolored is the same color + enumColorMixingResults[color][c.uncolored] = color; +} + +// Create reverse lookup and check color mixing lookups +for (const colorA in enumColorMixingResults) { + for (const colorB in enumColorMixingResults[colorA]) { + const resultColor = enumColorMixingResults[colorA][colorB]; + if (!enumColorMixingResults[colorB]) { + enumColorMixingResults[colorB] = { + [colorA]: resultColor, + }; + } else { + const existingResult = enumColorMixingResults[colorB][colorA]; + if (existingResult && existingResult !== resultColor) { + assertAlways( + false, + "invalid color mixing configuration, " + + colorA + + " + " + + colorB + + " is " + + resultColor + + " but " + + colorB + + " + " + + colorA + + " is " + + existingResult + ); + } + enumColorMixingResults[colorB][colorA] = resultColor; + } + } +} + +for (const colorA in enumColorMixingResults) { + for (const colorB in enumColorMixingResults) { + if (!enumColorMixingResults[colorA][colorB]) { + assertAlways(false, "Color mixing of", colorA, "with", colorB, "is not defined"); + } + } +} diff --git a/src/js/game/component.js b/src/js/game/component.js new file mode 100644 index 00000000..8c492351 --- /dev/null +++ b/src/js/game/component.js @@ -0,0 +1,38 @@ +import { BasicSerializableObject } from "../savegame/serialization"; + +export class Component extends BasicSerializableObject { + /** + * Returns the components unique id + * @returns {string} + */ + static getId() { + abstract; + return "unknown-component"; + } + + /** + * Should return the schema used for serialization + */ + static getSchema() { + return {}; + } + + /* dev:start */ + + /** + * Fixes typeof DerivedComponent is not assignable to typeof Component, compiled out + * in non-dev builds + */ + constructor(...args) { + super(); + } + + /** + * Returns a string representing the components data, only in dev builds + * @returns {string} + */ + getDebugString() { + return null; + } + /* dev:end */ +} diff --git a/src/js/game/component_registry.js b/src/js/game/component_registry.js new file mode 100644 index 00000000..16ae01d8 --- /dev/null +++ b/src/js/game/component_registry.js @@ -0,0 +1,38 @@ +import { gComponentRegistry } from "../core/global_registries"; +import { StaticMapEntityComponent } from "./components/static_map_entity"; +import { BeltComponent } from "./components/belt"; +import { ItemEjectorComponent } from "./components/item_ejector"; +import { ItemAcceptorComponent } from "./components/item_acceptor"; +import { MinerComponent } from "./components/miner"; +import { ItemProcessorComponent } from "./components/item_processor"; +import { ReplaceableMapEntityComponent } from "./components/replaceable_map_entity"; +import { UndergroundBeltComponent } from "./components/underground_belt"; +import { UnremovableComponent } from "./components/unremovable"; +import { HubComponent } from "./components/hub"; + +export function initComponentRegistry() { + gComponentRegistry.register(StaticMapEntityComponent); + gComponentRegistry.register(BeltComponent); + gComponentRegistry.register(ItemEjectorComponent); + gComponentRegistry.register(ItemAcceptorComponent); + gComponentRegistry.register(MinerComponent); + gComponentRegistry.register(ItemProcessorComponent); + gComponentRegistry.register(ReplaceableMapEntityComponent); + gComponentRegistry.register(UndergroundBeltComponent); + gComponentRegistry.register(UnremovableComponent); + gComponentRegistry.register(HubComponent); + + // IMPORTANT ^^^^^ REGENERATE SAVEGAME SCHEMA AFTERWARDS + // IMPORTANT ^^^^^ ALSO UPDATE ENTITY COMPONENT STORAG + + // Sanity check - If this is thrown, you (=me, lol) forgot to add a new component here + + assert( + // @ts-ignore + require.context("./components", false, /.*\.js/i).keys().length === + gComponentRegistry.getNumEntries(), + "Not all components are registered" + ); + + console.log("📦 There are", gComponentRegistry.getNumEntries(), "components"); +} diff --git a/src/js/game/components/belt.js b/src/js/game/components/belt.js new file mode 100644 index 00000000..6e9569ee --- /dev/null +++ b/src/js/game/components/belt.js @@ -0,0 +1,92 @@ +import { Component } from "../component"; +import { types } from "../../savegame/serialization"; +import { gItemRegistry } from "../../core/global_registries"; +import { BaseItem } from "../base_item"; +import { Vector, enumDirection } from "../../core/vector"; +import { Math_PI, Math_sin, Math_cos } from "../../core/builtins"; +import { globalConfig } from "../../core/config"; + +export class BeltComponent extends Component { + static getId() { + return "Belt"; + } + + static getSchema() { + return { + direction: types.string, + sortedItems: types.array(types.pair(types.ufloat, types.obj(gItemRegistry))), + }; + } + + /** + * + * @param {object} param0 + * @param {enumDirection=} param0.direction The direction of the belt + */ + constructor({ direction = enumDirection.top }) { + super(); + + this.direction = direction; + + /** @type {Array<[number, BaseItem]>} */ + this.sortedItems = []; + } + + /** + * Converts from belt space (0 = start of belt ... 1 = end of belt) to the local + * belt coordinates (-0.5|-0.5 to 0.5|0.5) + * @param {number} progress + * @returns {Vector} + */ + transformBeltToLocalSpace(progress) { + switch (this.direction) { + case enumDirection.top: + return new Vector(0, 0.5 - progress); + + case enumDirection.right: { + const arcProgress = progress * 0.5 * Math_PI; + return new Vector(0.5 - 0.5 * Math_cos(arcProgress), 0.5 - 0.5 * Math_sin(arcProgress)); + } + case enumDirection.left: { + const arcProgress = progress * 0.5 * Math_PI; + return new Vector(-0.5 + 0.5 * Math_cos(arcProgress), 0.5 - 0.5 * Math_sin(arcProgress)); + } + default: + assertAlways(false, "Invalid belt direction: " + this.direction); + return new Vector(0, 0); + } + } + + /** + * Returns if the belt can currently accept an item from the given direction + * @param {enumDirection} direction + */ + canAcceptNewItem(direction) { + const firstItem = this.sortedItems[0]; + if (!firstItem) { + return true; + } + + return firstItem[0] > globalConfig.itemSpacingOnBelts; + } + + /** + * Pushes a new item to the belt + * @param {BaseItem} item + * @param {enumDirection} direction + */ + takeNewItem(item, direction) { + this.sortedItems.unshift([0, item]); + } + + /** + * Returns how much space there is to the first item + */ + getDistanceToFirstItemCenter() { + const firstItem = this.sortedItems[0]; + if (!firstItem) { + return 1; + } + return firstItem[0]; + } +} diff --git a/src/js/game/components/hub.js b/src/js/game/components/hub.js new file mode 100644 index 00000000..6df1bcf5 --- /dev/null +++ b/src/js/game/components/hub.js @@ -0,0 +1,25 @@ +import { Component } from "../component"; +import { ShapeDefinition } from "../shape_definition"; + +export class HubComponent extends Component { + static getId() { + return "Hub"; + } + + constructor() { + super(); + + /** + * Shape definitions in queue to be analyzed and counted towards the goal + * @type {Array} + */ + this.definitionsToAnalyze = []; + } + + /** + * @param {ShapeDefinition} definition + */ + queueShapeDefinition(definition) { + this.definitionsToAnalyze.push(definition); + } +} diff --git a/src/js/game/components/item_acceptor.js b/src/js/game/components/item_acceptor.js new file mode 100644 index 00000000..bc02330c --- /dev/null +++ b/src/js/game/components/item_acceptor.js @@ -0,0 +1,129 @@ +import { Component } from "../component"; +import { Vector, enumDirection, enumDirectionToAngle, enumInvertedDirections } from "../../core/vector"; +import { BaseItem } from "../base_item"; +import { ShapeItem } from "../items/shape_item"; +import { ColorItem } from "../items/color_item"; + +/** + * @enum {string?} + */ +export const enumItemAcceptorItemFilter = { + shape: "shape", + color: "color", + none: null, +}; + +/** @typedef {{ + * pos: Vector, + * directions: enumDirection[], + * filter?: enumItemAcceptorItemFilter + * }} ItemAcceptorSlot */ + +export class ItemAcceptorComponent extends Component { + static getId() { + return "ItemAcceptor"; + } + + static getSchema() { + return { + // slots: "TODO", + }; + } + + /** + * + * @param {object} param0 + * @param {Array<{pos: Vector, directions: enumDirection[], filter?: enumItemAcceptorItemFilter}>} param0.slots The slots from which we accept items + */ + constructor({ slots }) { + super(); + + this.setSlots(slots); + } + + /** + * + * @param {Array<{pos: Vector, directions: enumDirection[], filter?: enumItemAcceptorItemFilter}>} slots + */ + setSlots(slots) { + /** @type {Array<{pos: Vector, directions: enumDirection[], filter?: enumItemAcceptorItemFilter}>} */ + this.slots = []; + for (let i = 0; i < slots.length; ++i) { + const slot = slots[i]; + this.slots.push({ + pos: slot.pos, + directions: slot.directions, + + // Which type of item to accept (shape | color | all) @see enumItemAcceptorItemFilter + filter: slot.filter, + }); + } + } + + /** + * Returns if this acceptor can accept a new item at slot N + * @param {number} slotIndex + * @param {BaseItem=} item + */ + canAcceptItem(slotIndex, item) { + const slot = this.slots[slotIndex]; + switch (slot.filter) { + case enumItemAcceptorItemFilter.shape: { + return item instanceof ShapeItem; + } + case enumItemAcceptorItemFilter.color: { + return item instanceof ColorItem; + } + default: + return true; + } + } + + /** + * Tries to find a slot which accepts the current item + * @param {Vector} targetLocalTile + * @param {enumDirection} fromLocalDirection + * @returns {{ + * slot: ItemAcceptorSlot, + * index: number, + * acceptedDirection: enumDirection + * }|null} + */ + findMatchingSlot(targetLocalTile, fromLocalDirection) { + // We need to invert our direction since the acceptor specifies *from* which direction + // it accepts items, but the ejector specifies *into* which direction it ejects items. + // E.g.: Ejector ejects into "right" direction but acceptor accepts from "left" direction. + const desiredDirection = enumInvertedDirections[fromLocalDirection]; + + // Go over all slots and try to find a target slot + for (let slotIndex = 0; slotIndex < this.slots.length; ++slotIndex) { + const slot = this.slots[slotIndex]; + + // const acceptorLocalPosition = targetStaticComp.applyRotationToVector( + // slot.pos + // ); + + // const acceptorGlobalPosition = acceptorLocalPosition.add(targetStaticComp.origin); + + // Make sure the acceptor slot is on the right position + if (!slot.pos.equals(targetLocalTile)) { + continue; + } + + // Check if the acceptor slot accepts items from our direction + for (let i = 0; i < slot.directions.length; ++i) { + // const localDirection = targetStaticComp.localDirectionToWorld(slot.directions[l]); + if (desiredDirection === slot.directions[i]) { + return { + slot, + index: slotIndex, + acceptedDirection: desiredDirection, + }; + } + } + } + + // && this.canAcceptItem(slotIndex, ejectingItem) + return null; + } +} diff --git a/src/js/game/components/item_ejector.js b/src/js/game/components/item_ejector.js new file mode 100644 index 00000000..786213ce --- /dev/null +++ b/src/js/game/components/item_ejector.js @@ -0,0 +1,162 @@ +import { globalConfig } from "../../core/config"; +import { Vector, enumDirection, enumDirectionToVector } from "../../core/vector"; +import { BaseItem } from "../base_item"; +import { Component } from "../component"; + +/** + * @typedef {{ + * pos: Vector, + * direction: enumDirection, + * item: BaseItem, + * progress: number? + * }} ItemEjectorSlot + */ + +export class ItemEjectorComponent extends Component { + static getId() { + return "ItemEjector"; + } + + static getSchema() { + return { + // slots: "TODO" + }; + } + + /** + * + * @param {object} param0 + * @param {Array<{pos: Vector, direction: enumDirection}>} param0.slots The slots to eject on + * @param {boolean=} param0.instantEject If the ejection is instant + */ + constructor({ slots, instantEject = false }) { + super(); + + // How long items take to eject + this.instantEject = instantEject; + + this.setSlots(slots); + } + + /** + * @param {Array<{pos: Vector, direction: enumDirection}>} slots The slots to eject on + */ + setSlots(slots) { + /** @type {Array} */ + this.slots = []; + for (let i = 0; i < slots.length; ++i) { + const slot = slots[i]; + this.slots.push({ + pos: slot.pos, + direction: slot.direction, + item: null, + progress: 0, + }); + } + } + + /** + * Returns the amount of slots + */ + getNumSlots() { + return this.slots.length; + } + + /** + * Returns where this slot ejects to + * @param {number} index + * @returns {Vector} + */ + getSlotTargetLocalTile(index) { + const slot = this.slots[index]; + const directionVector = enumDirectionToVector[slot.direction]; + return slot.pos.add(directionVector); + } + + /** + * Returns whether any slot ejects to the given local tile + * @param {Vector} tile + */ + anySlotEjectsToLocalTile(tile) { + for (let i = 0; i < this.slots.length; ++i) { + if (this.getSlotTargetLocalTile(i).equals(tile)) { + return true; + } + } + return false; + } + + /** + * Returns if slot # is currently ejecting + * @param {number} slotIndex + * @returns {boolean} + */ + isSlotEjecting(slotIndex) { + assert(slotIndex >= 0 && slotIndex < this.slots.length, "Invalid ejector slot: " + slotIndex); + return !!this.slots[slotIndex].item; + } + + /** + * Returns if we can eject on a given slot + * @param {number} slotIndex + * @returns {boolean} + */ + canEjectOnSlot(slotIndex) { + assert(slotIndex >= 0 && slotIndex < this.slots.length, "Invalid ejector slot: " + slotIndex); + return !this.slots[slotIndex].item; + } + + /** + * Returns the first free slot on this ejector or null if there is none + * @returns {number?} + */ + getFirstFreeSlot() { + for (let i = 0; i < this.slots.length; ++i) { + if (this.canEjectOnSlot(i)) { + return i; + } + } + return null; + } + + /** + * Returns if any slot is ejecting + * @returns {boolean} + */ + isAnySlotEjecting() { + for (let i = 0; i < this.slots.length; ++i) { + if (this.slots[i].item) { + return true; + } + } + return false; + } + + /** + * Returns if any slot is free + * @returns {boolean} + */ + hasAnySlotFree() { + for (let i = 0; i < this.slots.length; ++i) { + if (this.canEjectOnSlot(i)) { + return true; + } + } + return false; + } + + /** + * Tries to eject a given item + * @param {number} slotIndex + * @param {BaseItem} item + * @returns {boolean} + */ + tryEject(slotIndex, item) { + if (!this.canEjectOnSlot(slotIndex)) { + return false; + } + this.slots[slotIndex].item = item; + this.slots[slotIndex].progress = this.instantEject ? 1 : 0; + return true; + } +} diff --git a/src/js/game/components/item_processor.js b/src/js/game/components/item_processor.js new file mode 100644 index 00000000..f5257bcb --- /dev/null +++ b/src/js/game/components/item_processor.js @@ -0,0 +1,106 @@ +import { BaseItem } from "../base_item"; +import { Component } from "../component"; +import { enumDirection, Vector } from "../../core/vector"; + +/** @enum {string} */ +export const enumItemProcessorTypes = { + splitter: "splitter", + cutter: "cutter", + rotater: "rotater", + stacker: "stacker", + trash: "trash", + mixer: "mixer", + painter: "painter", + hub: "hub", +}; + +export class ItemProcessorComponent extends Component { + static getId() { + return "ItemProcessor"; + } + + static getSchema() { + return { + // TODO + }; + } + + /** + * + * @param {object} param0 + * @param {enumItemProcessorTypes} param0.processorType Which type of processor this is + * @param {number} param0.inputsPerCharge How many items this machine needs until it can start working + * @param {Array<{pos: Vector, direction: enumDirection}>=} param0.beltUnderlays Where to render belt underlays + * + */ + constructor({ processorType = enumItemProcessorTypes.splitter, inputsPerCharge, beltUnderlays = [] }) { + super(); + + // Which slot to emit next, this is only a preference and if it can't emit + // it will take the other one. Some machines ignore this (e.g. the splitter) to make + // sure the outputs always match + this.nextOutputSlot = 0; + + // Type of the processor + this.type = processorType; + + // How many inputs we need for one charge + this.inputsPerCharge = inputsPerCharge; + + // Which belt underlays to render + this.beltUnderlays = beltUnderlays; + + /** + * Our current inputs + * @type {Array<{ item: BaseItem, sourceSlot: number }>} + */ + this.inputSlots = []; + + /** + * What we are currently processing, empty if we don't produce anything rn + * requiredSlot: Item *must* be ejected on this slot + * preferredSlot: Item *can* be ejected on this slot, but others are fine too if the one is not usable + * @type {Array<{item: BaseItem, requiredSlot?: number, preferredSlot?: number}>} + */ + this.itemsToEject = []; + + /** + * How long it takes until we are done with the current items + */ + this.secondsUntilEject = 0; + + /** + * Fixes belt animations + * @type {Array<{ item: BaseItem, slotIndex: number, animProgress: number, direction: enumDirection}>} + */ + this.itemConsumptionAnimations = []; + } + + /** + * Tries to take the item + * @param {BaseItem} item + */ + tryTakeItem(item, sourceSlot, sourceDirection) { + if (this.inputSlots.length >= this.inputsPerCharge) { + // Already full + return false; + } + + // Check that we only take one item per slot + for (let i = 0; i < this.inputSlots.length; ++i) { + const slot = this.inputSlots[i]; + if (slot.sourceSlot === sourceSlot) { + return false; + } + } + + this.inputSlots.push({ item, sourceSlot }); + this.itemConsumptionAnimations.push({ + item, + slotIndex: sourceSlot, + direction: sourceDirection, + animProgress: 0.0, + }); + return true; + } +} diff --git a/src/js/game/components/miner.js b/src/js/game/components/miner.js new file mode 100644 index 00000000..09c4f437 --- /dev/null +++ b/src/js/game/components/miner.js @@ -0,0 +1,23 @@ +import { globalConfig } from "../../core/config"; +import { types } from "../../savegame/serialization"; +import { Component } from "../component"; + +export class MinerComponent extends Component { + static getId() { + return "Miner"; + } + + static getSchema() { + return { + lastMiningTime: types.ufloat, + }; + } + + /** + * @param {object} param0 + */ + constructor({}) { + super(); + this.lastMiningTime = 0; + } +} diff --git a/src/js/game/components/replaceable_map_entity.js b/src/js/game/components/replaceable_map_entity.js new file mode 100644 index 00000000..e6fd95d5 --- /dev/null +++ b/src/js/game/components/replaceable_map_entity.js @@ -0,0 +1,11 @@ +import { Component } from "../component"; + +/** + * Marks an entity as replaceable, so that when other buildings are placed above him it + * simply gets deleted + */ +export class ReplaceableMapEntityComponent extends Component { + static getId() { + return "ReplaceableMapEntity"; + } +} diff --git a/src/js/game/components/static_map_entity.js b/src/js/game/components/static_map_entity.js new file mode 100644 index 00000000..dc1cf0d5 --- /dev/null +++ b/src/js/game/components/static_map_entity.js @@ -0,0 +1,184 @@ +import { Math_radians } from "../../core/builtins"; +import { globalConfig } from "../../core/config"; +import { DrawParameters } from "../../core/draw_parameters"; +import { Rectangle } from "../../core/rectangle"; +import { AtlasSprite } from "../../core/sprites"; +import { enumDirection, Vector } from "../../core/vector"; +import { types } from "../../savegame/serialization"; +import { Component } from "../component"; + +export class StaticMapEntityComponent extends Component { + static getId() { + return "StaticMapEntity"; + } + + static getSchema() { + return { + origin: types.tileVector, + tileSize: types.tileVector, + rotationDegrees: types.uint, + spriteKey: types.string, + }; + } + + /** + * + * @param {object} param0 + * @param {Vector=} param0.origin Origin (Top Left corner) of the entity + * @param {Vector=} param0.tileSize Size of the entity in tiles + * @param {number=} param0.rotationDegrees Rotation in degrees. Must be multiple of 90 + * @param {string=} param0.spriteKey Optional sprite + * @param {string=} param0.silhouetteColor Optional silhouette color override + */ + constructor({ + origin = new Vector(), + tileSize = new Vector(1, 1), + rotationDegrees = 0, + spriteKey = null, + silhouetteColor = null, + }) { + super(); + assert( + rotationDegrees % 90 === 0, + "Rotation of static map entity must be multiple of 90 (was " + rotationDegrees + ")" + ); + + this.origin = origin; + this.tileSize = tileSize; + this.spriteKey = spriteKey; + this.rotationDegrees = rotationDegrees; + this.silhouetteColor = silhouetteColor; + } + + /** + * Returns the effective rectangle of this entity in tile space + * @returns {Rectangle} + */ + getTileSpaceBounds() { + switch (this.rotationDegrees) { + case 0: + return new Rectangle(this.origin.x, this.origin.y, this.tileSize.x, this.tileSize.y); + case 90: + return new Rectangle( + this.origin.x - this.tileSize.y + 1, + this.origin.y, + this.tileSize.y, + this.tileSize.x + ); + case 180: + return new Rectangle( + this.origin.x - this.tileSize.x + 1, + this.origin.y - this.tileSize.y + 1, + this.tileSize.x, + this.tileSize.y + ); + case 270: + return new Rectangle( + this.origin.x, + this.origin.y - this.tileSize.x + 1, + this.tileSize.y, + this.tileSize.x + ); + default: + assert(false, "Invalid rotation"); + } + } + + /** + * Transforms the given vector/rotation from local space to world space + * @param {Vector} vector + * @returns {Vector} + */ + applyRotationToVector(vector) { + return vector.rotateFastMultipleOf90(this.rotationDegrees); + } + + /** + * Transforms the given vector/rotation from world space to local space + * @param {Vector} vector + * @returns {Vector} + */ + unapplyRotationToVector(vector) { + return vector.rotateFastMultipleOf90(360 - this.rotationDegrees); + } + + /** + * Transforms the given direction from local space + * @param {enumDirection} direction + * @returns {enumDirection} + */ + localDirectionToWorld(direction) { + return Vector.transformDirectionFromMultipleOf90(direction, this.rotationDegrees); + } + + /** + * Transforms the given direction from world to local space + * @param {enumDirection} direction + * @returns {enumDirection} + */ + worldDirectionToLocal(direction) { + return Vector.transformDirectionFromMultipleOf90(direction, 360 - this.rotationDegrees); + } + + /** + * Transforms from local tile space to global tile space + * @param {Vector} localTile + * @returns {Vector} + */ + localTileToWorld(localTile) { + const result = this.applyRotationToVector(localTile); + result.addInplace(this.origin); + return result; + } + + /** + * Transforms from world space to local space + * @param {Vector} worldTile + */ + worldToLocalTile(worldTile) { + const localUnrotated = worldTile.sub(this.origin); + return this.unapplyRotationToVector(localUnrotated); + } + + /** + * Draws a sprite over the whole space of the entity + * @param {DrawParameters} parameters + * @param {AtlasSprite} sprite + * @param {number=} extrudePixels How many pixels to extrude the sprite + * @param {boolean=} clipping Whether to clip + */ + drawSpriteOnFullEntityBounds(parameters, sprite, extrudePixels = 0, clipping = true) { + const worldX = this.origin.x * globalConfig.tileSize; + const worldY = this.origin.y * globalConfig.tileSize; + + if (this.rotationDegrees === 0) { + // Early out, is faster + sprite.drawCached( + parameters, + worldX - extrudePixels * this.tileSize.x, + worldY - extrudePixels * this.tileSize.y, + globalConfig.tileSize * this.tileSize.x + 2 * extrudePixels * this.tileSize.x, + globalConfig.tileSize * this.tileSize.y + 2 * extrudePixels * this.tileSize.y, + clipping + ); + } else { + const rotationCenterX = worldX + globalConfig.halfTileSize; + const rotationCenterY = worldY + globalConfig.halfTileSize; + + parameters.context.translate(rotationCenterX, rotationCenterY); + parameters.context.rotate(Math_radians(this.rotationDegrees)); + + sprite.drawCached( + parameters, + -globalConfig.halfTileSize - extrudePixels * this.tileSize.x, + -globalConfig.halfTileSize - extrudePixels * this.tileSize.y, + globalConfig.tileSize * this.tileSize.x + 2 * extrudePixels * this.tileSize.x, + globalConfig.tileSize * this.tileSize.y + 2 * extrudePixels * this.tileSize.y, + false + ); + + parameters.context.rotate(-Math_radians(this.rotationDegrees)); + parameters.context.translate(-rotationCenterX, -rotationCenterY); + } + } +} diff --git a/src/js/game/components/underground_belt.js b/src/js/game/components/underground_belt.js new file mode 100644 index 00000000..707cd131 --- /dev/null +++ b/src/js/game/components/underground_belt.js @@ -0,0 +1,88 @@ +import { BaseItem } from "../base_item"; +import { Component } from "../component"; +import { globalConfig } from "../../core/config"; + +/** @enum {string} */ +export const enumUndergroundBeltMode = { + sender: "sender", + receiver: "receiver", +}; + +export class UndergroundBeltComponent extends Component { + static getId() { + return "UndergroundBelt"; + } + + /** + * + * @param {object} param0 + * @param {enumUndergroundBeltMode=} param0.mode As which type of belt the entity acts + */ + constructor({ mode = enumUndergroundBeltMode.sender }) { + super(); + + this.mode = mode; + + /** + * Used on both receiver and sender. + * Reciever: Used to store the next item to transfer, and to block input while doing this + * Sender: Used to store which items are currently "travelling" + * @type {Array<[BaseItem, number]>} Format is [Item, remaining seconds until transfer/ejection] + */ + this.pendingItems = []; + } + + /** + * Tries to accept an item from an external source like a regular belt or building + * @param {BaseItem} item + * @param {number} beltSpeed How fast this item travels + */ + tryAcceptExternalItem(item, beltSpeed) { + if (this.mode !== enumUndergroundBeltMode.sender) { + // Only senders accept external items + return false; + } + + if (this.pendingItems.length > 0) { + // We currently have a pending item + return false; + } + + console.log("Takes", 1 / beltSpeed); + this.pendingItems.push([item, 1 / beltSpeed]); + return true; + } + + /** + * Tries to accept a tunneled item + * @param {BaseItem} item + * @param {number} travelDistance How many tiles this item has to travel + * @param {number} beltSpeed How fast this item travels + */ + tryAcceptTunneledItem(item, travelDistance, beltSpeed) { + if (this.mode !== enumUndergroundBeltMode.receiver) { + // Only receivers can accept tunneled items + return false; + } + + // Notice: We assume that for all items the travel distance is the same + const maxItemsInTunnel = (1 + travelDistance) / globalConfig.itemSpacingOnBelts; + if (this.pendingItems.length >= maxItemsInTunnel) { + // Simulate a real belt which gets full at some point + return false; + } + + // NOTICE: + // This corresponds to the item ejector - it needs 0.5 additional tiles to eject the item. + // So instead of adding 1 we add 0.5 only. + const travelDuration = (travelDistance + 0.5) / beltSpeed; + console.log(travelDistance, "->", travelDuration); + + this.pendingItems.push([item, travelDuration]); + + // Sort so we can only look at the first ones + this.pendingItems.sort((a, b) => a[1] - b[1]); + + return true; + } +} diff --git a/src/js/game/components/unremovable.js b/src/js/game/components/unremovable.js new file mode 100644 index 00000000..4f6dd33a --- /dev/null +++ b/src/js/game/components/unremovable.js @@ -0,0 +1,7 @@ +import { Component } from "../component"; + +export class UnremovableComponent extends Component { + static getId() { + return "Unremovable"; + } +} diff --git a/src/js/game/core.js b/src/js/game/core.js new file mode 100644 index 00000000..8a9c4857 --- /dev/null +++ b/src/js/game/core.js @@ -0,0 +1,434 @@ +/* typehints:start */ +import { InGameState } from "../states/ingame"; +import { Application } from "../application"; +/* typehints:end */ + +import { BufferMaintainer } from "../core/buffer_maintainer"; +import { disableImageSmoothing, enableImageSmoothing, registerCanvas } from "../core/buffer_utils"; +import { Math_random } from "../core/builtins"; +import { globalConfig } from "../core/config"; +import { getDeviceDPI, resizeHighDPICanvas } from "../core/dpi_manager"; +import { DrawParameters } from "../core/draw_parameters"; +import { gMetaBuildingRegistry } from "../core/global_registries"; +import { createLogger } from "../core/logging"; +import { PerlinNoise } from "../core/perlin_noise"; +import { Vector } from "../core/vector"; +import { Savegame } from "../savegame/savegame"; +import { SavegameSerializer } from "../savegame/savegame_serializer"; +import { AutomaticSave } from "./automatic_save"; +import { MetaHubBuilding } from "./buildings/hub"; +import { Camera } from "./camera"; +import { CanvasClickInterceptor } from "./canvas_click_interceptor"; +import { EntityManager } from "./entity_manager"; +import { GameSystemManager } from "./game_system_manager"; +import { HubGoals } from "./hub_goals"; +import { GameHUD } from "./hud/hud"; +import { KeyActionMapper } from "./key_action_mapper"; +import { GameLogic } from "./logic"; +import { MapView } from "./map_view"; +import { GameRoot } from "./root"; +import { ShapeDefinitionManager } from "./shape_definition_manager"; +import { SoundProxy } from "./sound_proxy"; +import { GameTime } from "./time/game_time"; + +const logger = createLogger("ingame/core"); + +// Store the canvas so we can reuse it later +/** @type {HTMLCanvasElement} */ +let lastCanvas = null; +/** @type {CanvasRenderingContext2D} */ +let lastContext = null; + +/** + * The core manages the root and represents the whole game. It wraps the root, since + * the root class is just a data holder. + */ +export class GameCore { + /** @param {Application} app */ + constructor(app) { + this.app = app; + + /** @type {GameRoot} */ + this.root = null; + + /** + * Time budget (seconds) for logic updates + */ + this.logicTimeBudget = 0; + + /** + * Time budget (seconds) for user interface updates + */ + this.uiTimeBudget = 0; + + /** + * Set to true at the beginning of a logic update and cleared when its finished. + * This is to prevent doing a recursive logic update which can lead to unexpected + * behaviour. + */ + this.duringLogicUpdate = false; + + // Cached + this.boundInternalTick = this.updateLogic.bind(this); + } + + /** + * Initializes the root object which stores all game related data. The state + * is required as a back reference (used sometimes) + * @param {InGameState} parentState + * @param {Savegame} savegame + */ + initializeRoot(parentState, savegame) { + // Construct the root element, this is the data representation of the game + this.root = new GameRoot(this.app); + this.root.gameState = parentState; + this.root.savegame = savegame; + this.root.gameWidth = this.app.screenWidth; + this.root.gameHeight = this.app.screenHeight; + + // Initialize canvas element & context + this.internalInitCanvas(); + + // Members + const root = this.root; + + // This isn't nice, but we need it right here + root.gameState.keyActionMapper = new KeyActionMapper(root, this.root.gameState.inputReciever); + + // Init classes + root.camera = new Camera(root); + root.map = new MapView(root); + root.logic = new GameLogic(root); + root.hud = new GameHUD(root); + root.time = new GameTime(root); + root.canvasClickInterceptor = new CanvasClickInterceptor(root); + root.automaticSave = new AutomaticSave(root); + root.soundProxy = new SoundProxy(root); + + // Init managers + root.entityMgr = new EntityManager(root); + root.systemMgr = new GameSystemManager(root); + root.shapeDefinitionMgr = new ShapeDefinitionManager(root); + root.mapNoiseGenerator = new PerlinNoise(Math.random()); // TODO: Save seed + root.hubGoals = new HubGoals(root); + root.buffers = new BufferMaintainer(root); + + // root.particleMgr = new ParticleManager(root); + // root.uiParticleMgr = new ParticleManager(root); + + // Initialize the hud once everything is loaded + this.root.hud.initialize(); + + // Initial resize event, it might be possible that the screen + // resized later during init tho, which is why will emit it later + // again anyways + this.resize(this.app.screenWidth, this.app.screenHeight); + + if (G_IS_DEV) { + // @ts-ignore + window.globalRoot = root; + } + } + + /** + * Initializes a new game, this means creating a new map and centering on the + * plaerbase + * */ + initNewGame() { + logger.log("Initializing new game"); + this.root.gameIsFresh = true; + + gMetaBuildingRegistry + .findByClass(MetaHubBuilding) + .createAndPlaceEntity(this.root, new Vector(-2, -2), 0); + } + + /** + * Inits an existing game by loading the raw savegame data and deserializing it. + * Also runs basic validity checks. + */ + initExistingGame() { + logger.log("Initializing existing game"); + const serializer = new SavegameSerializer(); + + try { + const status = serializer.deserialize(this.root.savegame.getCurrentDump(), this.root); + if (!status.isGood()) { + logger.error("savegame-deserialize-failed:" + status.reason); + return false; + } + } catch (ex) { + logger.error("Exception during deserialization:", ex); + return false; + } + this.root.gameIsFresh = false; + return true; + } + + /** + * Initializes the render canvas + */ + internalInitCanvas() { + let canvas, context; + if (!lastCanvas) { + logger.log("Creating new canvas"); + canvas = document.createElement("canvas"); + canvas.id = "ingame_Canvas"; + canvas.setAttribute("opaque", "true"); + canvas.setAttribute("webkitOpaque", "true"); + canvas.setAttribute("mozOpaque", "true"); + this.root.gameState.getDivElement().appendChild(canvas); + context = canvas.getContext("2d", { alpha: false }); + + lastCanvas = canvas; + lastContext = context; + } else { + logger.log("Reusing canvas"); + if (lastCanvas.parentElement) { + lastCanvas.parentElement.removeChild(lastCanvas); + } + this.root.gameState.getDivElement().appendChild(lastCanvas); + + canvas = lastCanvas; + context = lastContext; + + lastContext.clearRect(0, 0, lastCanvas.width, lastCanvas.height); + } + + // globalConfig.smoothing.smoothMainCanvas = getDeviceDPI() < 1.5; + // globalConfig.smoothing.smoothMainCanvas = true; + + canvas.classList.toggle("smoothed", globalConfig.smoothing.smoothMainCanvas); + + // Oof, use :not() instead + canvas.classList.toggle("unsmoothed", !globalConfig.smoothing.smoothMainCanvas); + + if (globalConfig.smoothing.smoothMainCanvas) { + enableImageSmoothing(context); + } else { + disableImageSmoothing(context); + } + + this.root.canvas = canvas; + this.root.context = context; + + registerCanvas(canvas, context); + } + + /** + * Destructs the root, freeing all resources + */ + destruct() { + if (lastCanvas && lastCanvas.parentElement) { + lastCanvas.parentElement.removeChild(lastCanvas); + } + + this.root.destruct(); + delete this.root; + this.root = null; + this.app = null; + } + + tick(deltaMs) { + const root = this.root; + + if (root.hud.parts.processingOverlay.hasTasks() || root.hud.parts.processingOverlay.isRunning()) { + return true; + } + + // Extract current real time + root.time.updateRealtimeNow(); + + // Camera is always updated, no matter what + root.camera.update(deltaMs); + + // Perform logic ticks + this.root.time.performTicks(deltaMs, this.boundInternalTick); + + // Update UI particles + this.uiTimeBudget += deltaMs; + const maxUiSteps = 3; + if (this.uiTimeBudget > globalConfig.physicsDeltaMs * maxUiSteps) { + this.uiTimeBudget = globalConfig.physicsDeltaMs; + } + while (this.uiTimeBudget >= globalConfig.physicsDeltaMs) { + this.uiTimeBudget -= globalConfig.physicsDeltaMs; + // root.uiParticleMgr.update(); + } + + // Update automatic save after everything finished + root.automaticSave.update(); + + return true; + } + + shouldRender() { + if (this.root.queue.requireRedraw) { + return true; + } + if (this.root.hud.shouldPauseRendering()) { + return false; + } + + // Do not render + if (!this.app.isRenderable()) { + return false; + } + + return true; + } + + updateLogic() { + const root = this.root; + this.duringLogicUpdate = true; + + // Update entities, this removes destroyed entities + root.entityMgr.update(); + + // IMPORTANT: At this point, the game might be game over. Stop if this is the case + if (!this.root) { + logger.log("Root destructed, returning false"); + return false; + } + + root.systemMgr.update(); + // root.particleMgr.update(); + + this.duringLogicUpdate = false; + + return true; + } + + resize(w, h) { + this.root.gameWidth = w; + this.root.gameHeight = h; + resizeHighDPICanvas(this.root.canvas, w, h, globalConfig.smoothing.smoothMainCanvas); + this.root.signals.resized.dispatch(w, h); + this.root.queue.requireRedraw = true; + } + + postLoadHook() { + logger.log("Dispatching post load hook"); + this.root.signals.postLoadHook.dispatch(); + + if (!this.root.gameIsFresh) { + // Also dispatch game restored hook on restored savegames + this.root.signals.gameRestored.dispatch(); + } + + this.root.gameInitialized = true; + } + + draw() { + const root = this.root; + const systems = root.systemMgr.systems; + + const taskRunner = root.hud.parts.processingOverlay; + if (taskRunner.hasTasks()) { + if (!taskRunner.isRunning()) { + taskRunner.process(); + } + return; + } + + if (!this.shouldRender()) { + // Always update hud tho + root.hud.update(); + return; + } + + // Update buffers as the very first + root.buffers.update(); + + root.queue.requireRedraw = false; + + // Gather context and save all state + const context = root.context; + context.save(); + + // Compute optimal zoom level and atlas scale + const zoomLevel = root.camera.zoomLevel; + const effectiveZoomLevel = + (zoomLevel / globalConfig.assetsDpi) * getDeviceDPI() * globalConfig.assetsSharpness; + + let desiredAtlasScale = "0.1"; + if (effectiveZoomLevel > 0.75) { + desiredAtlasScale = "1"; + } else if (effectiveZoomLevel > 0.5) { + desiredAtlasScale = "0.75"; + } else if (effectiveZoomLevel > 0.25) { + desiredAtlasScale = "0.5"; + } else if (effectiveZoomLevel > 0.1) { + desiredAtlasScale = "0.25"; + } + + // Construct parameters required for drawing + const params = new DrawParameters({ + context: context, + visibleRect: root.camera.getVisibleRect(), + desiredAtlasScale, + zoomLevel, + root: root, + }); + + if (G_IS_DEV && (globalConfig.debug.testCulling || globalConfig.debug.hideFog)) { + context.clearRect(0, 0, root.gameWidth, root.gameHeight); + } + + // Transform to world space + root.camera.transform(context); + + assert(context.globalAlpha === 1.0, "Global alpha not 1 on frame start"); + + // Update hud + root.hud.update(); + + // Main rendering order + // ----- + + root.map.drawBackground(params); + // systems.mapResources.draw(params); + + if (!this.root.camera.getIsMapOverlayActive()) { + systems.itemProcessor.drawUnderlays(params); + systems.belt.draw(params); + systems.itemEjector.draw(params); + systems.itemProcessor.draw(params); + } + + root.map.drawForeground(params); + if (!this.root.camera.getIsMapOverlayActive()) { + systems.hub.draw(params); + } + + if (G_IS_DEV) { + root.map.drawStaticEntities(params); + } + + // END OF GAME CONTENT + // ----- + + // Finally, draw the hud. Nothing should come after that + root.hud.draw(params); + + assert(context.globalAlpha === 1.0, "Global alpha not 1 on frame end before restore"); + + // Restore to screen space + context.restore(); + + // Draw overlays, those are screen space + root.hud.drawOverlays(params); + + assert(context.globalAlpha === 1.0, "context.globalAlpha not 1 on frame end"); + + if (G_IS_DEV && globalConfig.debug.simulateSlowRendering) { + let sum = 0; + for (let i = 0; i < 1e8; ++i) { + sum += i; + } + if (Math_random() > 0.95) { + console.log(sum); + } + } + } +} diff --git a/src/js/game/entity.js b/src/js/game/entity.js new file mode 100644 index 00000000..4161f2a7 --- /dev/null +++ b/src/js/game/entity.js @@ -0,0 +1,222 @@ +/* typehints:start */ +import { GameRoot } from "./root"; +import { DrawParameters } from "../core/draw_parameters"; +import { Component } from "./component"; +/* typehints:end */ + +import { globalConfig } from "../core/config"; +import { Vector, enumDirectionToVector, enumDirectionToAngle } from "../core/vector"; +import { BasicSerializableObject, types } from "../savegame/serialization"; +import { EntityComponentStorage } from "./entity_components"; +import { Loader } from "../core/loader"; +import { drawRotatedSprite } from "../core/draw_utils"; +import { Math_radians } from "../core/builtins"; +// import { gFactionRegistry, gComponentRegistry } from "../core/global_registries"; +// import { EntityComponentStorage } from "./entity_components"; + +export class Entity extends BasicSerializableObject { + /** + * @param {GameRoot} root + */ + constructor(root) { + super(); + + /** + * Handle to the global game root + */ + this.root = root; + + /** + * The metaclass of the entity, should be set by subclasses + */ + this.meta = null; + + /** + * The components of the entity + */ + this.components = new EntityComponentStorage(); + + /** + * Whether this entity was registered on the @see EntityManager so far + */ + this.registered = false; + + /** + * Internal entity unique id, set by the @see EntityManager + */ + this.uid = 0; + + /* typehints:start */ + + /** + * Stores if this entity is destroyed, set by the @see EntityManager + * @type {boolean} */ + this.destroyed; + + /** + * Stores if this entity is queued to get destroyed in the next tick + * of the @see EntityManager + * @type {boolean} */ + this.queuedForDestroy; + + /** + * Stores the reason why this entity was destroyed + * @type {string} */ + this.destroyReason; + + /* typehints:end */ + } + + static getId() { + return "Entity"; + } + + /** + * @see BasicSerializableObject.getSchema + * @returns {import("../savegame/serialization").Schema} + */ + static getSchema() { + return { + uid: types.uint, + // components: types.keyValueMap(types.objData(gComponentRegistry), false) + }; + } + + /** + * Returns whether the entity is still alive + * @returns {boolean} + */ + isAlive() { + return !this.destroyed && !this.queuedForDestroy; + } + + /** + * Returns the meta class of the entity. + * @returns {object} + */ + getMetaclass() { + assert(this.meta, "Entity has no metaclass"); + return this.meta; + } + + /** + * Internal destroy callback + */ + internalDestroyCallback() { + assert(!this.destroyed, "Can not destroy entity twice"); + this.destroyed = true; + } + + /** + * Adds a new component, only possible until the entity is registered on the entity manager, + * after that use @see EntityManager.addDynamicComponent + * @param {Component} componentInstance + * @param {boolean} force Used by the entity manager. Internal parameter, do not change + */ + addComponent(componentInstance, force = false) { + assert(force || !this.registered, "Entity already registered, use EntityManager.addDynamicComponent"); + const id = /** @type {typeof Component} */ (componentInstance.constructor).getId(); + assert(!this.components[id], "Component already present"); + this.components[id] = componentInstance; + } + + /** + * Removes a given component, only possible until the entity is registered on the entity manager, + * after that use @see EntityManager.removeDynamicComponent + * @param {typeof Component} componentClass + */ + removeComponent(componentClass) { + assert(!this.registered, "Entity already registered, use EntityManager.removeDynamicComponent"); + const id = componentClass.getId(); + assert(this.components[id], "Component does not exist on entity"); + delete this.components[id]; + } + + /** + * Draws the entity, to override use @see Entity.drawImpl + * @param {DrawParameters} parameters + */ + draw(parameters) { + const context = parameters.context; + const staticComp = this.components.StaticMapEntity; + + if (G_IS_DEV && staticComp && globalConfig.debug.showEntityBounds) { + if (staticComp) { + const transformed = staticComp.getTileSpaceBounds(); + context.strokeStyle = "rgba(255, 0, 0, 0.5)"; + context.lineWidth = 2; + // const boundsSize = 20; + context.beginPath(); + context.rect( + transformed.x * globalConfig.tileSize, + transformed.y * globalConfig.tileSize, + transformed.w * globalConfig.tileSize, + transformed.h * globalConfig.tileSize + ); + context.stroke(); + } + } + if (G_IS_DEV && staticComp && globalConfig.debug.showAcceptorEjectors) { + const ejectorComp = this.components.ItemEjector; + + if (ejectorComp) { + const ejectorSprite = Loader.getSprite("sprites/debug/ejector_slot.png"); + for (let i = 0; i < ejectorComp.slots.length; ++i) { + const slot = ejectorComp.slots[i]; + const slotTile = staticComp.localTileToWorld(slot.pos); + const direction = staticComp.localDirectionToWorld(slot.direction); + const directionVector = enumDirectionToVector[direction]; + const angle = Math_radians(enumDirectionToAngle[direction]); + + context.globalAlpha = slot.item ? 1 : 0.2; + drawRotatedSprite({ + parameters, + sprite: ejectorSprite, + x: (slotTile.x + 0.5 + directionVector.x * 0.37) * globalConfig.tileSize, + y: (slotTile.y + 0.5 + directionVector.y * 0.37) * globalConfig.tileSize, + angle, + size: globalConfig.tileSize * 0.25, + }); + } + } + const acceptorComp = this.components.ItemAcceptor; + + if (acceptorComp) { + const acceptorSprite = Loader.getSprite("sprites/debug/acceptor_slot.png"); + for (let i = 0; i < acceptorComp.slots.length; ++i) { + const slot = acceptorComp.slots[i]; + const slotTile = staticComp.localTileToWorld(slot.pos); + for (let k = 0; k < slot.directions.length; ++k) { + const direction = staticComp.localDirectionToWorld(slot.directions[k]); + const directionVector = enumDirectionToVector[direction]; + const angle = Math_radians(enumDirectionToAngle[direction] + 180); + context.globalAlpha = 0.4; + drawRotatedSprite({ + parameters, + sprite: acceptorSprite, + x: (slotTile.x + 0.5 + directionVector.x * 0.37) * globalConfig.tileSize, + y: (slotTile.y + 0.5 + directionVector.y * 0.37) * globalConfig.tileSize, + angle, + size: globalConfig.tileSize * 0.25, + }); + } + } + } + + context.globalAlpha = 1; + } + // this.drawImpl(parameters); + } + + ///// Helper interfaces + + ///// Interface to override by subclasses + + /** + * override, should draw the entity + * @param {DrawParameters} parameters + */ + drawImpl(parameters) { + abstract; + } +} diff --git a/src/js/game/entity_components.js b/src/js/game/entity_components.js new file mode 100644 index 00000000..5b58264b --- /dev/null +++ b/src/js/game/entity_components.js @@ -0,0 +1,57 @@ +/* typehints:start */ +import { StaticMapEntityComponent } from "./components/static_map_entity"; +import { BeltComponent } from "./components/belt"; +import { ItemEjectorComponent } from "./components/item_ejector"; +import { ItemAcceptorComponent } from "./components/item_acceptor"; +import { MinerComponent } from "./components/miner"; +import { ItemProcessorComponent } from "./components/item_processor"; +import { ReplaceableMapEntityComponent } from "./components/replaceable_map_entity"; +import { UndergroundBeltComponent } from "./components/underground_belt"; +import { UnremovableComponent } from "./components/unremovable"; +import { HubComponent } from "./components/hub"; +/* typehints:end */ + +/** + * Typedefs for all entity components. These are not actually present on the entity, + * thus they are undefined by default + */ +export class EntityComponentStorage { + constructor() { + // TODO: Figure out if its faster to declare all components here and not + // compile them out (In theory, should make it a fast object in V8 engine) + + /* typehints:start */ + + /** @type {StaticMapEntityComponent} */ + this.StaticMapEntity; + + /** @type {BeltComponent} */ + this.Belt; + + /** @type {ItemEjectorComponent} */ + this.ItemEjector; + + /** @type {ItemAcceptorComponent} */ + this.ItemAcceptor; + + /** @type {MinerComponent} */ + this.Miner; + + /** @type {ItemProcessorComponent} */ + this.ItemProcessor; + + /** @type {ReplaceableMapEntityComponent} */ + this.ReplaceableMapEntity; + + /** @type {UndergroundBeltComponent} */ + this.UndergroundBelt; + + /** @type {UnremovableComponent} */ + this.Unremovable; + + /** @type {HubComponent} */ + this.Hub; + + /* typehints:end */ + } +} diff --git a/src/js/game/entity_manager.js b/src/js/game/entity_manager.js new file mode 100644 index 00000000..84a92768 --- /dev/null +++ b/src/js/game/entity_manager.js @@ -0,0 +1,239 @@ +import { arrayDeleteValue, newEmptyMap } from "../core/utils"; +import { Component } from "./component"; +import { GameRoot } from "./root"; +import { Entity } from "./entity"; +import { BasicSerializableObject, types } from "../savegame/serialization"; +import { createLogger } from "../core/logging"; + +const logger = createLogger("entity_manager"); + +// Manages all entities + +// TODO & NOTICE: We use arrayDeleteValue instead of fastArrayDeleteValue since that does not preserve the order +// This is slower but we need it for the street path generation + +export class EntityManager extends BasicSerializableObject { + constructor(root) { + super(); + + /** @type {GameRoot} */ + this.root = root; + + /** @type {Array} */ + this.entities = []; + + // We store a seperate list with entities to destroy, since we don't destroy + // them instantly + /** @type {Array} */ + this.destroyList = []; + + // Store a map from componentid to entities - This is used by the game system + // for faster processing + /** @type {Object.>} */ + this.componentToEntity = newEmptyMap(); + + // Store the next uid to use + this.nextUid = 10000; + } + + static getId() { + return "EntityManager"; + } + + static getSchema() { + return { + nextUid: types.uint, + }; + } + + getStatsText() { + return this.entities.length + " entities [" + this.destroyList.length + " to kill]"; + } + + // Main update + update() { + this.processDestroyList(); + } + + /** + * Registers a new entity + * @param {Entity} entity + * @param {number=} uid Optional predefined uid + */ + registerEntity(entity, uid = null) { + assert(this.entities.indexOf(entity) < 0, `RegisterEntity() called twice for entity ${entity}`); + assert(!entity.destroyed, `Attempting to register destroyed entity ${entity}`); + + if (G_IS_DEV && uid !== null) { + assert(!this.findByUid(uid, false), "Entity uid already taken: " + uid); + } + + if (uid !== null) { + assert(uid >= 0 && uid < Number.MAX_SAFE_INTEGER, "Invalid uid passed: " + uid); + } + + this.entities.push(entity); + + // Register into the componentToEntity map + for (const componentId in entity.components) { + if (entity.components[componentId]) { + if (this.componentToEntity[componentId]) { + this.componentToEntity[componentId].push(entity); + } else { + this.componentToEntity[componentId] = [entity]; + } + } + } + + // Give each entity a unique id + entity.uid = uid ? uid : this.generateUid(); + entity.registered = true; + + this.root.signals.entityAdded.dispatch(entity); + } + + /** + * Sorts all entitiy lists after a resync + */ + sortEntityLists() { + this.entities.sort((a, b) => a.uid - b.uid); + this.destroyList.sort((a, b) => a.uid - b.uid); + + for (const key in this.componentToEntity) { + this.componentToEntity[key].sort((a, b) => a.uid - b.uid); + } + } + + /** + * Generates a new uid + * @returns {number} + */ + generateUid() { + return this.nextUid++; + } + + /** + * Call to attach a new component after the creation of the entity + * @param {Entity} entity + * @param {Component} component + */ + attachDynamicComponent(entity, component) { + entity.addComponent(component, true); + const componentId = /** @type {typeof Component} */ (component.constructor).getId(); + if (this.componentToEntity[componentId]) { + this.componentToEntity[componentId].push(entity); + } else { + this.componentToEntity[componentId] = [entity]; + } + this.root.signals.entityGotNewComponent.dispatch(entity); + } + + /** + * Finds an entity buy its uid, kinda slow since it loops over all entities + * @param {number} uid + * @param {boolean=} errorWhenNotFound + * @returns {Entity} + */ + findByUid(uid, errorWhenNotFound = true) { + const arr = this.entities; + for (let i = 0, len = arr.length; i < len; ++i) { + const entity = arr[i]; + if (entity.uid === uid) { + if (entity.queuedForDestroy || entity.destroyed) { + if (errorWhenNotFound) { + logger.warn("Entity with UID", uid, "not found (destroyed)"); + } + return null; + } + return entity; + } + } + if (errorWhenNotFound) { + logger.warn("Entity with UID", uid, "not found"); + } + return null; + } + + /** + * Returns all entities having the given component + * @param {typeof Component} componentHandle + * @returns {Array} entities + */ + getAllWithComponent(componentHandle) { + return this.componentToEntity[componentHandle.getId()] || []; + } + + /** + * Return all of a given class. This is SLOW! + * @param {object} entityClass + * @returns {Array} entities + */ + getAllOfClass(entityClass) { + // FIXME: Slow + const result = []; + for (let i = 0; i < this.entities.length; ++i) { + const entity = this.entities[i]; + if (entity instanceof entityClass) { + result.push(entity); + } + } + return result; + } + + /** + * Unregisters all components of an entity from the component to entity mapping + * @param {Entity} entity + */ + unregisterEntityComponents(entity) { + for (const componentId in entity.components) { + if (entity.components[componentId]) { + arrayDeleteValue(this.componentToEntity[componentId], entity); + } + } + } + + // Processes the entities to destroy and actually destroys them + /* eslint-disable max-statements */ + processDestroyList() { + for (let i = 0; i < this.destroyList.length; ++i) { + const entity = this.destroyList[i]; + + // Remove from entities list + arrayDeleteValue(this.entities, entity); + + // Remove from componentToEntity list + this.unregisterEntityComponents(entity); + + entity.registered = false; + entity.internalDestroyCallback(); + + this.root.signals.entityDestroyed.dispatch(entity); + } + + this.destroyList = []; + } + + /** + * Queues an entity for destruction + * @param {Entity} entity + */ + destroyEntity(entity) { + if (entity.destroyed) { + logger.error("Tried to destroy already destroyed entity:", entity.uid); + return; + } + + if (entity.queuedForDestroy) { + logger.error("Trying to destroy entity which is already queued for destroy!", entity.uid); + return; + } + + if (this.destroyList.indexOf(entity) < 0) { + this.destroyList.push(entity); + entity.queuedForDestroy = true; + this.root.signals.entityQueuedForDestroy.dispatch(entity); + } else { + assert(false, "Trying to destroy entity twice"); + } + } +} diff --git a/src/js/game/game_loading_overlay.js b/src/js/game/game_loading_overlay.js new file mode 100644 index 00000000..63aadb02 --- /dev/null +++ b/src/js/game/game_loading_overlay.js @@ -0,0 +1,57 @@ +/* typehints:start */ +import { Application } from "../application"; +/* typehints:end */ + +export class GameLoadingOverlay { + /** + * + * @param {Application} app + * @param {HTMLElement} parent + */ + constructor(app, parent) { + this.app = app; + this.parent = parent; + + /** @type {HTMLElement} */ + this.element = null; + } + + /** + * Removes the overlay if its currently visible + */ + removeIfAttached() { + if (this.element) { + this.element.remove(); + this.element = null; + } + } + + /** + * Returns if the loading overlay is attached + */ + isAttached() { + return this.element; + } + + /** + * Shows a super basic overlay + */ + showBasic() { + assert(!this.element, "Loading overlay already visible, cant show again"); + this.element = document.createElement("div"); + this.element.classList.add("gameLoadingOverlay"); + this.parent.appendChild(this.element); + this.internalAddSpinnerAndText(this.element); + } + + /** + * Adds a text with 'loading' and a spinner + * @param {HTMLElement} element + */ + internalAddSpinnerAndText(element) { + const inner = document.createElement("span"); + inner.classList.add("prefab_LoadingTextWithAnim"); + inner.innerText = "Loading"; + element.appendChild(inner); + } +} diff --git a/src/js/game/game_system.js b/src/js/game/game_system.js new file mode 100644 index 00000000..defae1bf --- /dev/null +++ b/src/js/game/game_system.js @@ -0,0 +1,43 @@ +/* typehints:start */ +import { GameRoot } from "./root"; +import { DrawParameters } from "../core/draw_parameters"; +/* typehints:end */ + +/** + * A game system processes all entities which match a given schema, usually a list of + * required components. This is the core of the game logic. + */ +export class GameSystem { + /** + * @param {GameRoot} root + */ + constructor(root) { + this.root = root; + } + + ///// PUBLIC API ///// + + /** + * Updates the game system, override to perform logic + */ + update() {} + + /** + * Override, do not call this directly, use startDraw() + * @param {DrawParameters} parameters + */ + draw(parameters) {} + + /** + * Should refresh all caches + */ + refreshCaches() {} + + /** + * @see GameSystem.draw Wrapper arround the draw method + * @param {DrawParameters} parameters + */ + startDraw(parameters) { + this.draw(parameters); + } +} diff --git a/src/js/game/game_system_manager.js b/src/js/game/game_system_manager.js new file mode 100644 index 00000000..810ddec0 --- /dev/null +++ b/src/js/game/game_system_manager.js @@ -0,0 +1,104 @@ +/* typehints:start */ +import { GameRoot } from "./root"; +/* typehints:end */ + +import { createLogger } from "../core/logging"; +import { BeltSystem } from "./systems/belt"; +import { ItemEjectorSystem } from "./systems/item_ejector"; +import { MapResourcesSystem } from "./systems/map_resources"; +import { MinerSystem } from "./systems/miner"; +import { ItemProcessorSystem } from "./systems/item_processor"; +import { UndergroundBeltSystem } from "./systems/underground_belt"; +import { HubSystem } from "./systems/hub"; +import { StaticMapEntitySystem } from "./systems/static_map_entity"; + +const logger = createLogger("game_system_manager"); + +export class GameSystemManager { + /** + * + * @param {GameRoot} root + */ + constructor(root) { + this.root = root; + + this.systems = { + /* typehints:start */ + /** @type {BeltSystem} */ + belt: null, + + /** @type {ItemEjectorSystem} */ + itemEjector: null, + + /** @type {MapResourcesSystem} */ + mapResources: null, + + /** @type {MinerSystem} */ + miner: null, + + /** @type {ItemProcessorSystem} */ + itemProcessor: null, + + /** @type {UndergroundBeltSystem} */ + undergroundBelt: null, + + /** @type {HubSystem} */ + hub: null, + + /** @type {StaticMapEntitySystem} */ + staticMapEntities: null, + + /* typehints:end */ + }; + this.systemUpdateOrder = []; + + this.internalInitSystems(); + } + + /** + * Initializes all systems + */ + internalInitSystems() { + const add = (id, systemClass) => { + this.systems[id] = new systemClass(this.root); + this.systemUpdateOrder.push(id); + }; + + // Order is important! + + add("belt", BeltSystem); + + add("itemEjector", ItemEjectorSystem); + + add("miner", MinerSystem); + + add("mapResources", MapResourcesSystem); + + add("itemProcessor", ItemProcessorSystem); + + add("undergroundBelt", UndergroundBeltSystem); + + add("hub", HubSystem); + + add("staticMapEntities", StaticMapEntitySystem); + + logger.log("📦 There are", this.systemUpdateOrder.length, "game systems"); + } + + /** + * Updates all systems + */ + update() { + for (let i = 0; i < this.systemUpdateOrder.length; ++i) { + const system = this.systems[this.systemUpdateOrder[i]]; + system.update(); + } + } + + refreshCaches() { + for (let i = 0; i < this.systemUpdateOrder.length; ++i) { + const system = this.systems[this.systemUpdateOrder[i]]; + system.refreshCaches(); + } + } +} diff --git a/src/js/game/game_system_with_filter.js b/src/js/game/game_system_with_filter.js new file mode 100644 index 00000000..3585c24e --- /dev/null +++ b/src/js/game/game_system_with_filter.js @@ -0,0 +1,175 @@ +/* typehints:start */ +import { Component } from "./component"; +import { GameRoot } from "./root"; +import { Entity } from "./entity"; +/* typehints:end */ + +import { GameSystem } from "./game_system"; +import { arrayDelete } from "../core/utils"; +import { DrawParameters } from "../core/draw_parameters"; +import { globalConfig } from "../core/config"; +import { Math_floor, Math_ceil } from "../core/builtins"; + +export class GameSystemWithFilter extends GameSystem { + /** + * Constructs a new game system with the given component filter. It will process + * all entities which have *all* of the passed components + * @param {GameRoot} root + * @param {Array} requiredComponents + */ + constructor(root, requiredComponents) { + super(root); + this.requiredComponents = requiredComponents; + this.requiredComponentIds = requiredComponents.map(component => component.getId()); + + /** + * All entities which match the current components + * @type {Array} + */ + this.allEntities = []; + + this.root.signals.entityAdded.add(this.internalPushEntityIfMatching, this); + this.root.signals.entityGotNewComponent.add(this.internalReconsiderEntityToAdd, this); + this.root.signals.entityQueuedForDestroy.add(this.internalPopEntityIfMatching, this); + + this.root.signals.postLoadHook.add(this.internalPostLoadHook, this); + } + + /** + * Calls a function for each matching entity on the screen, useful for drawing them + * @param {DrawParameters} parameters + * @param {function} callback + */ + forEachMatchingEntityOnScreen(parameters, callback) { + const cullRange = parameters.visibleRect.toTileCullRectangle(); + if (this.allEntities.length < 100) { + // So, its much quicker to simply perform per-entity checking + + for (let i = 0; i < this.allEntities.length; ++i) { + const entity = this.allEntities[i]; + if (cullRange.containsRect(entity.components.StaticMapEntity.getTileSpaceBounds())) { + callback(parameters, entity); + } + } + return; + } + + const top = cullRange.top(); + const right = cullRange.right(); + const bottom = cullRange.bottom(); + const left = cullRange.left(); + + const border = 1; + const minY = top - border; + const maxY = bottom + border; + const minX = left - border; + const maxX = right + border - 1; + + const map = this.root.map; + + let seenUids = new Set(); + + const chunkStartX = Math_floor(minX / globalConfig.mapChunkSize); + const chunkStartY = Math_floor(minY / globalConfig.mapChunkSize); + + const chunkEndX = Math_ceil(maxX / globalConfig.mapChunkSize); + const chunkEndY = Math_ceil(maxY / globalConfig.mapChunkSize); + + const requiredComponents = this.requiredComponentIds; + + // Render y from top down for proper blending + for (let chunkX = chunkStartX; chunkX <= chunkEndX; ++chunkX) { + for (let chunkY = chunkStartY; chunkY <= chunkEndY; ++chunkY) { + const chunk = map.getChunk(chunkX, chunkY, false); + if (!chunk) { + continue; + } + + // BIG TODO: CULLING ON AN ENTITY BASIS + + const entities = chunk.containedEntities; + entityLoop: for (let i = 0; i < entities.length; ++i) { + const entity = entities[i]; + + // Avoid drawing twice + if (seenUids.has(entity.uid)) { + continue; + } + seenUids.add(entity.uid); + + for (let i = 0; i < requiredComponents.length; ++i) { + if (!entity.components[requiredComponents[i]]) { + continue entityLoop; + } + } + callback(parameters, entity); + } + } + } + } + + /** + * @param {Entity} entity + */ + internalPushEntityIfMatching(entity) { + for (let i = 0; i < this.requiredComponentIds.length; ++i) { + if (!entity.components[this.requiredComponentIds[i]]) { + return; + } + } + + assert(this.allEntities.indexOf(entity) < 0, "entity already in list: " + entity); + this.internalRegisterEntity(entity); + } + + /** + * + * @param {Entity} entity + */ + internalReconsiderEntityToAdd(entity) { + for (let i = 0; i < this.requiredComponentIds.length; ++i) { + if (!entity.components[this.requiredComponentIds[i]]) { + return; + } + } + if (this.allEntities.indexOf(entity) >= 0) { + return; + } + this.internalRegisterEntity(entity); + } + + refreshCaches() { + this.allEntities.sort((a, b) => a.uid - b.uid); + } + + /** + * Recomputes all target entities after the game has loaded + */ + internalPostLoadHook() { + this.refreshCaches(); + } + + /** + * + * @param {Entity} entity + */ + internalRegisterEntity(entity) { + this.allEntities.push(entity); + + if (this.root.gameInitialized) { + // Sort entities by uid so behaviour is predictable + this.allEntities.sort((a, b) => a.uid - b.uid); + } + } + + /** + * + * @param {Entity} entity + */ + internalPopEntityIfMatching(entity) { + const index = this.allEntities.indexOf(entity); + if (index >= 0) { + arrayDelete(this.allEntities, index); + } + } +} diff --git a/src/js/game/hub_goals.js b/src/js/game/hub_goals.js new file mode 100644 index 00000000..a14239ac --- /dev/null +++ b/src/js/game/hub_goals.js @@ -0,0 +1,330 @@ +import { BasicSerializableObject } from "../savegame/serialization"; +import { GameRoot } from "./root"; +import { ShapeDefinition, enumSubShape } from "./shape_definition"; +import { enumColors } from "./colors"; +import { randomChoice, clamp, randomInt, findNiceIntegerValue } from "../core/utils"; +import { tutorialGoals, enumHubGoalRewards } from "./tutorial_goals"; +import { createLogger } from "../core/logging"; +import { globalConfig } from "../core/config"; +import { Math_random } from "../core/builtins"; +import { UPGRADES } from "./upgrades"; +import { enumItemProcessorTypes } from "./components/item_processor"; + +const logger = createLogger("hub_goals"); + +export class HubGoals extends BasicSerializableObject { + static getId() { + return "HubGoals"; + } + + /** + * @param {GameRoot} root + */ + constructor(root) { + super(); + + this.root = root; + + this.level = 1; + + /** + * Which story rewards we already gained + */ + this.gainedRewards = {}; + + /** + * Mapping from shape hash -> amount + * @type {Object} + */ + this.storedShapes = {}; + + /** + * Stores the levels for all upgrades + * @type {Object} + */ + this.upgradeLevels = {}; + + /** + * Stores the improvements for all upgrades + * @type {Object} + */ + this.upgradeImprovements = {}; + for (const key in UPGRADES) { + this.upgradeImprovements[key] = UPGRADES[key].baseValue || 1; + } + + this.createNextGoal(); + + // Allow quickly switching goals in dev mode with key "C" + if (G_IS_DEV) { + this.root.gameState.inputReciever.keydown.add(key => { + if (key.keyCode === 67) { + // Key: c + this.onGoalCompleted(); + } + }); + } + } + + /** + * Returns how much of the current shape is stored + * @param {ShapeDefinition} definition + * @returns {number} + */ + getShapesStored(definition) { + return this.storedShapes[definition.getHash()] || 0; + } + + /** + * Returns how much of the current goal was already delivered + */ + getCurrentGoalDelivered() { + return this.getShapesStored(this.currentGoal.definition); + } + + /** + * Returns the current level of a given upgrade + * @param {string} upgradeId + */ + getUpgradeLevel(upgradeId) { + return this.upgradeLevels[upgradeId] || 0; + } + + /** + * Returns whether the given reward is already unlocked + * @param {enumHubGoalRewards} reward + */ + isRewardUnlocked(reward) { + if (G_IS_DEV && globalConfig.debug.allBuildingsUnlocked) { + return true; + } + return !!this.gainedRewards[reward]; + } + + /** + * Handles the given definition, by either accounting it towards the + * goal or otherwise granting some points + * @param {ShapeDefinition} definition + */ + handleDefinitionDelivered(definition) { + const hash = definition.getHash(); + this.storedShapes[hash] = (this.storedShapes[hash] || 0) + 1; + + // Check if we have enough for the next level + const targetHash = this.currentGoal.definition.getHash(); + if ( + this.storedShapes[targetHash] >= this.currentGoal.required || + (G_IS_DEV && globalConfig.debug.rewardsInstant) + ) { + this.onGoalCompleted(); + } + } + + /** + * Creates the next goal + */ + createNextGoal() { + const storyIndex = this.level - 1; + if (storyIndex < tutorialGoals.length) { + const { shape, required, reward } = tutorialGoals[storyIndex]; + this.currentGoal = { + /** @type {ShapeDefinition} */ + definition: this.root.shapeDefinitionMgr.registerOrReturnHandle( + ShapeDefinition.fromShortKey(shape) + ), + required, + reward, + }; + return; + } + + const reward = enumHubGoalRewards.no_reward; + + this.currentGoal = { + /** @type {ShapeDefinition} */ + definition: this.createRandomShape(), + required: 1000 + findNiceIntegerValue(this.level * 47.5), + reward, + }; + } + + /** + * Called when the level was completed + */ + onGoalCompleted() { + const reward = this.currentGoal.reward; + this.gainedRewards[reward] = (this.gainedRewards[reward] || 0) + 1; + this.root.signals.storyGoalCompleted.dispatch(this.level, reward); + + this.root.app.gameAnalytics.handleLevelCompleted(this.level); + ++this.level; + this.createNextGoal(); + } + + /** + * Returns whether a given upgrade can be unlocked + * @param {string} upgradeId + */ + canUnlockUpgrade(upgradeId) { + const handle = UPGRADES[upgradeId]; + const currentLevel = this.getUpgradeLevel(upgradeId); + + if (currentLevel >= handle.tiers.length) { + // Max level + return false; + } + + if (G_IS_DEV && globalConfig.debug.upgradesNoCost) { + return true; + } + + const tierData = handle.tiers[currentLevel]; + + for (let i = 0; i < tierData.required.length; ++i) { + const requirement = tierData.required[i]; + if ((this.storedShapes[requirement.shape] || 0) < requirement.amount) { + return false; + } + } + return true; + } + + /** + * Tries to unlock the given upgrade + * @param {string} upgradeId + * @returns {boolean} + */ + tryUnlockUgprade(upgradeId) { + if (!this.canUnlockUpgrade(upgradeId)) { + return false; + } + + const handle = UPGRADES[upgradeId]; + const currentLevel = this.getUpgradeLevel(upgradeId); + + const tierData = handle.tiers[currentLevel]; + if (!tierData) { + return false; + } + + if (G_IS_DEV && globalConfig.debug.upgradesNoCost) { + // Dont take resources + } else { + for (let i = 0; i < tierData.required.length; ++i) { + const requirement = tierData.required[i]; + + // Notice: Don't have to check for hash here + this.storedShapes[requirement.shape] -= requirement.amount; + } + } + + this.upgradeLevels[upgradeId] = (this.upgradeLevels[upgradeId] || 0) + 1; + this.upgradeImprovements[upgradeId] += tierData.improvement; + + this.root.signals.upgradePurchased.dispatch(upgradeId); + + this.root.app.gameAnalytics.handleUpgradeUnlocked(upgradeId, currentLevel); + + return true; + } + + /** + * @returns {ShapeDefinition} + */ + createRandomShape() { + const layerCount = clamp(this.level / 50, 2, 4); + /** @type {Array} */ + let layers = []; + + // @ts-ignore + const randomColor = () => randomChoice(Object.values(enumColors)); + // @ts-ignore + const randomShape = () => randomChoice(Object.values(enumSubShape)); + + let anyIsMissingTwo = false; + + for (let i = 0; i < layerCount; ++i) { + /** @type {import("./shape_definition").ShapeLayer} */ + const layer = [null, null, null, null]; + + for (let quad = 0; quad < 4; ++quad) { + layer[quad] = { + subShape: randomShape(), + color: randomColor(), + }; + } + + // Sometimes shapes are missing + if (Math_random() > 0.85) { + layer[randomInt(0, 3)] = null; + } + + // Sometimes they actually are missing *two* ones! + // Make sure at max only one layer is missing it though, otherwise we could + // create an uncreateable shape + if (Math_random() > 0.95 && !anyIsMissingTwo) { + layer[randomInt(0, 3)] = null; + anyIsMissingTwo = true; + } + + layers.push(layer); + } + + const definition = new ShapeDefinition({ layers }); + return this.root.shapeDefinitionMgr.registerOrReturnHandle(definition); + } + + ////////////// HELPERS + + /** + * Belt speed + * @returns {number} items / sec + */ + getBeltBaseSpeed() { + return globalConfig.beltSpeedItemsPerSecond * this.upgradeImprovements.belt; + } + + /** + * Underground belt speed + * @returns {number} items / sec + */ + getUndergroundBeltBaseSpeed() { + return globalConfig.beltSpeedItemsPerSecond * this.upgradeImprovements.belt; + } + + /** + * Miner speed + * @returns {number} items / sec + */ + getMinerBaseSpeed() { + return globalConfig.minerSpeedItemsPerSecond * this.upgradeImprovements.miner; + } + + /** + * Processor speed + * @param {enumItemProcessorTypes} processorType + * @returns {number} items / sec + */ + getProcessorBaseSpeed(processorType) { + switch (processorType) { + case enumItemProcessorTypes.trash: + return 1e30; + case enumItemProcessorTypes.splitter: + return (2 / globalConfig.beltSpeedItemsPerSecond) * this.upgradeImprovements.splitter; + case enumItemProcessorTypes.cutter: + case enumItemProcessorTypes.rotater: + case enumItemProcessorTypes.stacker: + case enumItemProcessorTypes.mixer: + case enumItemProcessorTypes.painter: + return ( + (1 / globalConfig.beltSpeedItemsPerSecond) * + this.upgradeImprovements.processor * + globalConfig.buildingSpeeds[processorType] + ); + default: + assertAlways(false, "invalid processor type"); + } + + return 1 / globalConfig.beltSpeedItemsPerSecond; + } +} diff --git a/src/js/game/hud/base_hud_part.js b/src/js/game/hud/base_hud_part.js new file mode 100644 index 00000000..cec7e525 --- /dev/null +++ b/src/js/game/hud/base_hud_part.js @@ -0,0 +1,175 @@ +/* typehints:start */ +import { GameRoot } from "../root"; +import { DrawParameters } from "../../core/draw_parameters"; +/* typehints:end */ + +import { ClickDetector } from "../../core/click_detector"; +import { KeyActionMapper } from "../key_action_mapper"; + +export class BaseHUDPart { + /** + * @param {GameRoot} root + */ + constructor(root) { + this.root = root; + + /** @type {Array} */ + this.clickDetectors = []; + } + + /** + * Should create all require elements + * @param {HTMLElement} parent + */ + createElements(parent) {} + + /** + * Should initialize the element, called *after* the elements have been created + */ + initialize() { + abstract; + } + + /** + * Should update any required logic + */ + update() {} + + /** + * Should draw the hud + * @param {DrawParameters} parameters + */ + draw(parameters) {} + + /** + * Should draw any overlays (screen space) + * @param {DrawParameters} parameters + */ + drawOverlays(parameters) {} + + /** + * Should return true if the widget has a modal dialog opened and thus + * the game does not need to update / redraw + * @returns {boolean} + */ + shouldPauseRendering() { + return false; + } + + /** + * Should return false if the game should be paused + * @returns {boolean} + */ + shouldPauseGame() { + return false; + } + + /** + * Should return true if this overlay is open and currently blocking any user interaction + */ + isBlockingOverlay() { + return false; + } + + /** + * Cleans up the hud element, if overridden make sure to call super.cleanups + */ + cleanup() { + if (this.clickDetectors) { + for (let i = 0; i < this.clickDetectors.length; ++i) { + this.clickDetectors[i].cleanup(); + } + this.clickDetectors = []; + } + } + + /** + * Should close the element, in case its supported + */ + close() {} + + // Helpers + + /** + * Calls closeMethod if an overlay is opened + * @param {function=} closeMethod + */ + closeOnOverlayOpen(closeMethod = null) { + this.root.hud.signals.overlayOpened.add(overlay => { + if (overlay !== this) { + (closeMethod || this.close).call(this); + } + }, this); + } + + /** + * Helper method to construct a new click detector + * @param {Element} element The element to listen on + * @param {function} handler The handler to call on this object + * @param {import("../../core/click_detector").ClickDetectorConstructorArgs=} args Click detector arguments + * + */ + trackClicks(element, handler, args = {}) { + const detector = new ClickDetector(element, args); + detector.click.add(handler, this); + this.registerClickDetector(detector); + } + + /** + * Registers a new click detector + * @param {ClickDetector} detector + */ + registerClickDetector(detector) { + this.clickDetectors.push(detector); + if (G_IS_DEV) { + // @ts-ignore + detector._src = "hud-" + this.constructor.name; + } + } + + /** + * Closes this element when its background is clicked + * @param {HTMLElement} element + * @param {function} closeMethod + */ + closeOnBackgroundClick(element, closeMethod = null) { + const bgClickDetector = new ClickDetector(element, { + preventDefault: true, + targetOnly: true, + applyCssClass: null, + consumeEvents: true, + clickSound: null, + }); + + // If the state defines a close method, use that as fallback + // @ts-ignore + bgClickDetector.touchend.add(closeMethod || this.close, this); + this.registerClickDetector(bgClickDetector); + } + + /** + * Forwards the game speed keybindings so you can toggle pause / Fastforward + * in the building tooltip and such + * @param {KeyActionMapper} sourceMapper + */ + forwardGameSpeedKeybindings(sourceMapper) { + sourceMapper.forward(this.root.gameState.keyActionMapper, [ + "gamespeed_pause", + "gamespeed_fastforward", + ]); + } + + /** + * Forwards the map movement keybindings so you can move the map with the + * arrow keys + * @param {KeyActionMapper} sourceMapper + */ + forwardMapMovementKeybindings(sourceMapper) { + sourceMapper.forward(this.root.gameState.keyActionMapper, [ + "map_move_up", + "map_move_right", + "map_move_down", + "map_move_left", + ]); + } +} diff --git a/src/js/game/hud/dynamic_dom_attach.js b/src/js/game/hud/dynamic_dom_attach.js new file mode 100644 index 00000000..68f09052 --- /dev/null +++ b/src/js/game/hud/dynamic_dom_attach.js @@ -0,0 +1,79 @@ +import { GameRoot } from "../root"; + +// Automatically attaches and detaches elements from the dom +// Also supports detaching elements after a given time, useful if there is a +// hide animation like for the tooltips + +// Also attaches a class name if desired + +export class DynamicDomAttach { + constructor(root, element, { timeToKeepSeconds = 0, attachClass = null } = {}) { + /** @type {GameRoot} */ + this.root = root; + + /** @type {HTMLElement} */ + this.element = element; + this.parent = this.element.parentElement; + + this.attachClass = attachClass; + + this.timeToKeepSeconds = timeToKeepSeconds; + this.lastVisibleTime = 0; + + // We start attached, so detach the node first + this.attached = true; + this.internalDetach(); + + this.internalIsClassAttached = false; + this.classAttachTimeout = null; + } + + internalAttach() { + if (!this.attached) { + this.parent.appendChild(this.element); + assert(this.element.parentElement === this.parent, "Invalid parent #1"); + this.attached = true; + } + } + + internalDetach() { + if (this.attached) { + assert(this.element.parentElement === this.parent, "Invalid parent #2"); + this.element.parentElement.removeChild(this.element); + this.attached = false; + } + } + + isAttached() { + return this.attached; + } + + update(isVisible) { + if (isVisible) { + this.lastVisibleTime = this.root ? this.root.time.realtimeNow() : 0; + this.internalAttach(); + } else { + if (!this.root || this.root.time.realtimeNow() - this.lastVisibleTime >= this.timeToKeepSeconds) { + this.internalDetach(); + } + } + + if (this.attachClass && isVisible !== this.internalIsClassAttached) { + // State changed + this.internalIsClassAttached = isVisible; + + if (this.classAttachTimeout) { + clearTimeout(this.classAttachTimeout); + this.classAttachTimeout = null; + } + + if (isVisible) { + this.classAttachTimeout = setTimeout(() => { + this.element.classList.add(this.attachClass); + }, 15); + } else { + this.element.classList.remove(this.attachClass); + } + } + } +} diff --git a/src/js/game/hud/hud.js b/src/js/game/hud/hud.js new file mode 100644 index 00000000..deae4591 --- /dev/null +++ b/src/js/game/hud/hud.js @@ -0,0 +1,187 @@ +/* typehints:start */ +import { GameRoot } from "../root"; +/* typehints:end */ + +import { Signal } from "../../core/signal"; +import { DrawParameters } from "../../core/draw_parameters"; +import { HUDProcessingOverlay } from "./parts/processing_overlay"; +import { HUDBuildingsToolbar } from "./parts/buildings_toolbar"; +import { HUDBuildingPlacer } from "./parts/building_placer"; +import { HUDBetaOverlay } from "./parts/beta_overlay"; +import { HUDKeybindingOverlay } from "./parts/keybinding_overlay"; +import { HUDUnlockNotification } from "./parts/unlock_notification"; +import { HUDGameMenu } from "./parts/game_menu"; +import { HUDShop } from "./parts/shop"; +import { IS_MOBILE } from "../../core/config"; + +export class GameHUD { + /** + * @param {GameRoot} root + */ + constructor(root) { + this.root = root; + } + + /** + * Initializes the hud parts + */ + initialize() { + this.signals = { + overlayOpened: new Signal(/* overlay */), + }; + + this.parts = { + processingOverlay: new HUDProcessingOverlay(this.root), + + buildingsToolbar: new HUDBuildingsToolbar(this.root), + buildingPlacer: new HUDBuildingPlacer(this.root), + + unlockNotification: new HUDUnlockNotification(this.root), + + gameMenu: new HUDGameMenu(this.root), + + shop: new HUDShop(this.root), + + // betaOverlay: new HUDBetaOverlay(this.root), + }; + + this.signals = { + selectedPlacementBuildingChanged: new Signal(/* metaBuilding|null */), + }; + + if (!IS_MOBILE) { + this.parts.keybindingOverlay = new HUDKeybindingOverlay(this.root); + } + + const frag = document.createDocumentFragment(); + for (const key in this.parts) { + this.parts[key].createElements(frag); + } + + document.body.appendChild(frag); + + for (const key in this.parts) { + this.parts[key].initialize(); + } + this.internalInitSignalConnections(); + + this.root.gameState.keyActionMapper.getBinding("toggle_hud").add(this.toggleUi, this); + } + + /** + * Attempts to close all overlays + */ + closeAllOverlays() { + for (const key in this.parts) { + this.parts[key].close(); + } + } + + /** + * Returns true if the game logic should be paused + */ + shouldPauseGame() { + for (const key in this.parts) { + if (this.parts[key].shouldPauseGame()) { + return true; + } + } + return false; + } + + /** + * Returns true if the rendering can be paused + */ + shouldPauseRendering() { + for (const key in this.parts) { + if (this.parts[key].shouldPauseRendering()) { + return true; + } + } + return false; + } + + /** + * Returns true if the rendering can be paused + */ + hasBlockingOverlayOpen() { + if (this.root.camera.getIsMapOverlayActive()) { + return true; + } + for (const key in this.parts) { + if (this.parts[key].isBlockingOverlay()) { + return true; + } + } + return false; + } + + /** + * Toggles the ui + */ + toggleUi() { + document.body.classList.toggle("uiHidden"); + } + + /** + * Initializes connections between parts + */ + internalInitSignalConnections() { + const p = this.parts; + p.buildingsToolbar.sigBuildingSelected.add(p.buildingPlacer.startSelection, p.buildingPlacer); + } + + /** + * Updates all parts + */ + update() { + if (!this.root.gameInitialized) { + return; + } + + for (const key in this.parts) { + this.parts[key].update(); + } + } + + /** + * Draws all parts + * @param {DrawParameters} parameters + */ + draw(parameters) { + const partsOrder = ["buildingPlacer"]; + + for (let i = 0; i < partsOrder.length; ++i) { + if (this.parts[partsOrder[i]]) { + this.parts[partsOrder[i]].draw(parameters); + } + } + } + + /** + * Draws all part overlays + * @param {DrawParameters} parameters + */ + drawOverlays(parameters) { + const partsOrder = []; + + for (let i = 0; i < partsOrder.length; ++i) { + if (this.parts[partsOrder[i]]) { + this.parts[partsOrder[i]].drawOverlays(parameters); + } + } + } + + /** + * Cleans up everything + */ + cleanup() { + for (const key in this.parts) { + this.parts[key].cleanup(); + } + + for (const key in this.signals) { + this.signals[key].removeAll(); + } + } +} diff --git a/src/js/game/hud/parts/beta_overlay.js b/src/js/game/hud/parts/beta_overlay.js new file mode 100644 index 00000000..517a15b7 --- /dev/null +++ b/src/js/game/hud/parts/beta_overlay.js @@ -0,0 +1,10 @@ +import { BaseHUDPart } from "../base_hud_part"; +import { makeDiv } from "../../../core/utils"; + +export class HUDBetaOverlay extends BaseHUDPart { + createElements(parent) { + this.element = makeDiv(parent, "ingame_HUD_BetaOverlay", [], "CLOSED BETA"); + } + + initialize() {} +} diff --git a/src/js/game/hud/parts/building_placer.js b/src/js/game/hud/parts/building_placer.js new file mode 100644 index 00000000..bb256dc6 --- /dev/null +++ b/src/js/game/hud/parts/building_placer.js @@ -0,0 +1,492 @@ +import { BaseHUDPart } from "../base_hud_part"; +import { MetaBuilding } from "../../meta_building"; +import { DrawParameters } from "../../../core/draw_parameters"; +import { globalConfig } from "../../../core/config"; +import { StaticMapEntityComponent } from "../../components/static_map_entity"; +import { STOP_PROPAGATION, Signal } from "../../../core/signal"; +import { + Vector, + enumDirectionToAngle, + enumInvertedDirections, + enumDirectionToVector, +} from "../../../core/vector"; +import { pulseAnimation, makeDiv } from "../../../core/utils"; +import { DynamicDomAttach } from "../dynamic_dom_attach"; +import { TrackedState } from "../../../core/tracked_state"; +import { Math_abs, Math_radians } from "../../../core/builtins"; +import { Loader } from "../../../core/loader"; +import { drawRotatedSprite } from "../../../core/draw_utils"; +import { Entity } from "../../entity"; + +export class HUDBuildingPlacer extends BaseHUDPart { + initialize() { + /** @type {TypedTrackedState} */ + this.currentMetaBuilding = new TrackedState(this.onSelectedMetaBuildingChanged, this); + this.currentBaseRotation = 0; + + /** @type {Entity} */ + this.fakeEntity = null; + + const keyActionMapper = this.root.gameState.keyActionMapper; + keyActionMapper.getBinding("building_abort_placement").add(() => this.currentMetaBuilding.set(null)); + keyActionMapper.getBinding("back").add(() => this.currentMetaBuilding.set(null)); + + keyActionMapper.getBinding("rotate_while_placing").add(this.tryRotate, this); + + this.domAttach = new DynamicDomAttach(this.root, this.element, {}); + + this.root.camera.downPreHandler.add(this.onMouseDown, this); + this.root.camera.movePreHandler.add(this.onMouseMove, this); + this.root.camera.upPostHandler.add(this.abortDragging, this); + + this.currentlyDragging = false; + + /** + * The tile we last dragged onto + * @type {Vector} + * */ + this.lastDragTile = null; + + /** + * The tile we initially dragged from + * @type {Vector} + */ + this.initialDragTile = null; + } + + createElements(parent) { + this.element = makeDiv(parent, "ingame_HUD_building_placer", [], ``); + + this.buildingLabel = makeDiv(this.element, null, ["buildingLabel"], "Extract"); + this.buildingDescription = makeDiv(this.element, null, ["description"], ""); + } + + /** + * mouse down pre handler + * @param {Vector} pos + */ + onMouseDown(pos) { + if (this.root.camera.getIsMapOverlayActive()) { + return; + } + + if (this.currentMetaBuilding.get()) { + this.currentlyDragging = true; + this.lastDragTile = this.root.camera.screenToWorld(pos).toTileSpace(); + + // Place initial building + this.tryPlaceCurrentBuildingAt(this.lastDragTile); + + return STOP_PROPAGATION; + } + } + + /** + * mouse move pre handler + * @param {Vector} pos + */ + onMouseMove(pos) { + if (this.root.camera.getIsMapOverlayActive()) { + return; + } + + if (this.currentMetaBuilding.get() && this.lastDragTile) { + const oldPos = this.lastDragTile; + const newPos = this.root.camera.screenToWorld(pos).toTileSpace(); + + if (!oldPos.equals(newPos)) { + const delta = newPos.sub(oldPos); + // - Using bresenhams algorithmus + + let x0 = oldPos.x; + let y0 = oldPos.y; + let x1 = newPos.x; + let y1 = newPos.y; + + var dx = Math_abs(x1 - x0); + var dy = Math_abs(y1 - y0); + var sx = x0 < x1 ? 1 : -1; + var sy = y0 < y1 ? 1 : -1; + var err = dx - dy; + + while (true) { + this.tryPlaceCurrentBuildingAt(new Vector(x0, y0)); + if (x0 === x1 && y0 === y1) break; + var e2 = 2 * err; + if (e2 > -dy) { + err -= dy; + x0 += sx; + } + if (e2 < dx) { + err += dx; + y0 += sy; + } + } + } + + this.lastDragTile = newPos; + + return STOP_PROPAGATION; + } + } + + update() { + // ALways update since the camera might have moved + const mousePos = this.root.app.mousePosition; + if (mousePos) { + this.onMouseMove(mousePos); + } + } + + /** + * aborts any dragging op + */ + abortDragging() { + this.currentlyDragging = true; + this.lastDragTile = null; + } + + /** + * + * @param {MetaBuilding} metaBuilding + */ + startSelection(metaBuilding) { + this.currentMetaBuilding.set(metaBuilding); + } + + /** + * + * @param {MetaBuilding} metaBuilding + */ + onSelectedMetaBuildingChanged(metaBuilding) { + this.root.hud.signals.selectedPlacementBuildingChanged.dispatch(metaBuilding); + if (metaBuilding) { + this.buildingLabel.innerHTML = metaBuilding.getName(); + this.buildingDescription.innerHTML = metaBuilding.getDescription(); + + this.fakeEntity = new Entity(null); + metaBuilding.setupEntityComponents(this.fakeEntity, null); + this.fakeEntity.addComponent( + new StaticMapEntityComponent({ + origin: new Vector(0, 0), + rotationDegrees: 0, + tileSize: metaBuilding.getDimensions().copy(), + }) + ); + } else { + this.currentlyDragging = false; + this.fakeEntity = null; + } + } + + /** + * Tries to rotate + */ + tryRotate() { + const selectedBuilding = this.currentMetaBuilding.get(); + if (selectedBuilding) { + this.currentBaseRotation = (this.currentBaseRotation + 90) % 360; + const staticComp = this.fakeEntity.components.StaticMapEntity; + staticComp.rotationDegrees = this.currentBaseRotation; + } + } + + /** + * Tries to delete the building under the mouse + */ + deleteBelowCursor() { + const mousePosition = this.root.app.mousePosition; + if (!mousePosition) { + // Not on screen + return; + } + + const worldPos = this.root.camera.screenToWorld(mousePosition); + const tile = worldPos.toTileSpace(); + const contents = this.root.map.getTileContent(tile); + if (contents) { + this.root.logic.tryDeleteBuilding(contents); + } + } + + /** + * Canvas click handler + * @param {Vector} mousePos + * @param {boolean} cancelAction + */ + onCanvasClick(mousePos, cancelAction = false) { + if (cancelAction) { + if (this.currentMetaBuilding.get()) { + this.currentMetaBuilding.set(null); + } else { + this.deleteBelowCursor(); + } + return STOP_PROPAGATION; + } + + if (!this.currentMetaBuilding.get()) { + return; + } + + return STOP_PROPAGATION; + } + + /** + * Tries to place the current building at the given tile + * @param {Vector} tile + */ + tryPlaceCurrentBuildingAt(tile) { + if (this.root.camera.zoomLevel < globalConfig.mapChunkOverviewMinZoom) { + // Dont allow placing in overview mode + return; + } + // Transform to world space + + const metaBuilding = this.currentMetaBuilding.get(); + + const { rotation, rotationVariant } = metaBuilding.computeOptimalDirectionAndRotationVariantAtTile( + this.root, + tile, + this.currentBaseRotation + ); + + if ( + this.root.logic.tryPlaceBuilding({ + origin: tile, + rotation, + rotationVariant, + building: this.currentMetaBuilding.get(), + }) + ) { + // Succesfully placed + + if (metaBuilding.getFlipOrientationAfterPlacement()) { + this.currentBaseRotation = (180 + this.currentBaseRotation) % 360; + } + + if (!metaBuilding.getStayInPlacementMode() && !this.root.app.inputMgr.shiftIsDown) { + // Stop placement + this.currentMetaBuilding.set(null); + } + + return true; + } else { + return false; + } + } + + /** + * + * @param {DrawParameters} parameters + */ + draw(parameters) { + if (this.root.camera.zoomLevel < globalConfig.mapChunkOverviewMinZoom) { + // Dont allow placing in overview mode + this.domAttach.update(false); + return; + } + + this.domAttach.update(this.currentMetaBuilding.get()); + const metaBuilding = this.currentMetaBuilding.get(); + + if (!metaBuilding) { + return; + } + + const mousePosition = this.root.app.mousePosition; + if (!mousePosition) { + // Not on screen + return; + } + + const worldPos = this.root.camera.screenToWorld(mousePosition); + const tile = worldPos.toTileSpace(); + + // Compute best rotation variant + const { + rotation, + rotationVariant, + connectedEntities, + } = metaBuilding.computeOptimalDirectionAndRotationVariantAtTile( + this.root, + tile, + this.currentBaseRotation + ); + + // Check if there are connected entities + if (connectedEntities) { + for (let i = 0; i < connectedEntities.length; ++i) { + const connectedEntity = connectedEntities[i]; + const connectedWsPoint = connectedEntity.components.StaticMapEntity.getTileSpaceBounds() + .getCenter() + .toWorldSpace(); + + const startWsPoint = tile.toWorldSpaceCenterOfTile(); + + const startOffset = connectedWsPoint + .sub(startWsPoint) + .normalize() + .multiplyScalar(globalConfig.tileSize * 0.3); + const effectiveStartPoint = startWsPoint.add(startOffset); + const effectiveEndPoint = connectedWsPoint.sub(startOffset); + + parameters.context.globalAlpha = 0.6; + + // parameters.context.lineCap = "round"; + parameters.context.strokeStyle = "#7f7"; + parameters.context.lineWidth = 10; + parameters.context.beginPath(); + parameters.context.moveTo(effectiveStartPoint.x, effectiveStartPoint.y); + parameters.context.lineTo(effectiveEndPoint.x, effectiveEndPoint.y); + parameters.context.stroke(); + parameters.context.globalAlpha = 1; + // parameters.context.lineCap = "square"; + } + } + + // Synchronize rotation and origin + const staticComp = this.fakeEntity.components.StaticMapEntity; + staticComp.origin = tile; + staticComp.rotationDegrees = rotation; + metaBuilding.updateRotationVariant(this.fakeEntity, rotationVariant); + + // Check if we could place the buildnig + const canBuild = this.root.logic.checkCanPlaceBuilding(tile, rotation, metaBuilding); + + // Determine the bounds and visualize them + const entityBounds = staticComp.getTileSpaceBounds(); + const drawBorder = 2; + parameters.context.globalAlpha = 0.5; + if (canBuild) { + parameters.context.fillStyle = "rgba(0, 255, 0, 0.2)"; + } else { + parameters.context.fillStyle = "rgba(255, 0, 0, 0.2)"; + } + parameters.context.fillRect( + entityBounds.x * globalConfig.tileSize - drawBorder, + entityBounds.y * globalConfig.tileSize - drawBorder, + entityBounds.w * globalConfig.tileSize + 2 * drawBorder, + entityBounds.h * globalConfig.tileSize + 2 * drawBorder + ); + + // Draw ejectors + if (canBuild) { + this.drawMatchingAcceptorsAndEjectors(parameters); + } + + // HACK to draw the entity sprite + const previewSprite = metaBuilding.getPreviewSprite(rotationVariant); + parameters.context.globalAlpha = 0.8 + pulseAnimation(this.root.time.realtimeNow(), 1) * 0.1; + staticComp.origin = worldPos.divideScalar(globalConfig.tileSize).subScalars(0.5, 0.5); + staticComp.drawSpriteOnFullEntityBounds(parameters, previewSprite); + staticComp.origin = tile; + parameters.context.globalAlpha = 1; + } + + /** + * + * @param {DrawParameters} parameters + */ + drawMatchingAcceptorsAndEjectors(parameters) { + const acceptorComp = this.fakeEntity.components.ItemAcceptor; + const ejectorComp = this.fakeEntity.components.ItemEjector; + const staticComp = this.fakeEntity.components.StaticMapEntity; + + const goodArrowSprite = Loader.getSprite("sprites/misc/slot_good_arrow.png"); + const badArrowSprite = Loader.getSprite("sprites/misc/slot_bad_arrow.png"); + + // Just ignore this code ... + + if (acceptorComp) { + const slots = acceptorComp.slots; + for (let acceptorSlotIndex = 0; acceptorSlotIndex < slots.length; ++acceptorSlotIndex) { + const slot = slots[acceptorSlotIndex]; + const acceptorSlotWsTile = staticComp.localTileToWorld(slot.pos); + const acceptorSlotWsPos = acceptorSlotWsTile.toWorldSpaceCenterOfTile(); + + for ( + let acceptorDirectionIndex = 0; + acceptorDirectionIndex < slot.directions.length; + ++acceptorDirectionIndex + ) { + const direction = slot.directions[acceptorDirectionIndex]; + const worldDirection = staticComp.localDirectionToWorld(direction); + + const sourceTile = acceptorSlotWsTile.add(enumDirectionToVector[worldDirection]); + const sourceEntity = this.root.map.getTileContent(sourceTile); + + let sprite = goodArrowSprite; + let alpha = 0.5; + + if (sourceEntity) { + sprite = badArrowSprite; + const sourceEjector = sourceEntity.components.ItemEjector; + const sourceStaticComp = sourceEntity.components.StaticMapEntity; + const ejectorAcceptLocalTile = sourceStaticComp.worldToLocalTile(acceptorSlotWsTile); + if (sourceEjector && sourceEjector.anySlotEjectsToLocalTile(ejectorAcceptLocalTile)) { + sprite = goodArrowSprite; + } + alpha = 1.0; + } + + parameters.context.globalAlpha = alpha; + drawRotatedSprite({ + parameters, + sprite, + x: acceptorSlotWsPos.x, + y: acceptorSlotWsPos.y, + angle: Math_radians(enumDirectionToAngle[enumInvertedDirections[worldDirection]]), + size: 13, + offsetY: 15, + }); + parameters.context.globalAlpha = 1; + } + } + } + + if (ejectorComp) { + const slots = ejectorComp.slots; + for (let ejectorSlotIndex = 0; ejectorSlotIndex < slots.length; ++ejectorSlotIndex) { + const slot = ejectorComp.slots[ejectorSlotIndex]; + + const ejectorSlotWsTile = staticComp.localTileToWorld( + ejectorComp.getSlotTargetLocalTile(ejectorSlotIndex) + ); + const ejectorSLotWsPos = ejectorSlotWsTile.toWorldSpaceCenterOfTile(); + const ejectorSlotWsDirection = staticComp.localDirectionToWorld(slot.direction); + + const destEntity = this.root.map.getTileContent(ejectorSlotWsTile); + + let sprite = goodArrowSprite; + let alpha = 0.5; + if (destEntity) { + alpha = 1; + const destAcceptor = destEntity.components.ItemAcceptor; + const destStaticComp = destEntity.components.StaticMapEntity; + + if (destAcceptor) { + const destLocalTile = destStaticComp.worldToLocalTile(ejectorSlotWsTile); + const destLocalDir = destStaticComp.worldDirectionToLocal(ejectorSlotWsDirection); + if (destAcceptor.findMatchingSlot(destLocalTile, destLocalDir)) { + sprite = goodArrowSprite; + } else { + sprite = badArrowSprite; + } + } + } + + parameters.context.globalAlpha = alpha; + drawRotatedSprite({ + parameters, + sprite, + x: ejectorSLotWsPos.x, + y: ejectorSLotWsPos.y, + angle: Math_radians(enumDirectionToAngle[ejectorSlotWsDirection]), + size: 13, + offsetY: 15, + }); + parameters.context.globalAlpha = 1; + } + } + } +} diff --git a/src/js/game/hud/parts/buildings_toolbar.js b/src/js/game/hud/parts/buildings_toolbar.js new file mode 100644 index 00000000..4d621a2d --- /dev/null +++ b/src/js/game/hud/parts/buildings_toolbar.js @@ -0,0 +1,128 @@ +import { BaseHUDPart } from "../base_hud_part"; +import { makeDiv } from "../../../core/utils"; +import { gMetaBuildingRegistry } from "../../../core/global_registries"; +import { MetaBuilding } from "../../meta_building"; +import { Signal } from "../../../core/signal"; +import { MetaSplitterBuilding } from "../../buildings/splitter"; +import { MetaMinerBuilding } from "../../buildings/miner"; +import { MetaCutterBuilding } from "../../buildings/cutter"; +import { MetaRotaterBuilding } from "../../buildings/rotater"; +import { MetaStackerBuilding } from "../../buildings/stacker"; +import { MetaMixerBuilding } from "../../buildings/mixer"; +import { MetaPainterBuilding } from "../../buildings/painter"; +import { MetaTrashBuilding } from "../../buildings/trash"; +import { MetaBeltBaseBuilding } from "../../buildings/belt_base"; +import { MetaUndergroundBeltBuilding } from "../../buildings/underground_belt"; +import { globalConfig } from "../../../core/config"; +import { TrackedState } from "../../../core/tracked_state"; + +const toolbarBuildings = [ + MetaBeltBaseBuilding, + MetaMinerBuilding, + MetaUndergroundBeltBuilding, + MetaSplitterBuilding, + MetaCutterBuilding, + MetaRotaterBuilding, + MetaStackerBuilding, + MetaMixerBuilding, + MetaPainterBuilding, + MetaTrashBuilding, +]; + +export class HUDBuildingsToolbar extends BaseHUDPart { + constructor(root) { + super(root); + + /** @type {Object.} */ + this.buildingUnlockStates = {}; + + this.sigBuildingSelected = new Signal(); + + this.trackedIsVisisible = new TrackedState(this.onVisibilityChanged, this); + } + + onVisibilityChanged(visible) { + this.element.classList.toggle("visible", visible); + } + + /** + * Should create all require elements + * @param {HTMLElement} parent + */ + createElements(parent) { + this.element = makeDiv(parent, "ingame_HUD_buildings_toolbar", [], ""); + } + + initialize() { + const actionMapper = this.root.gameState.keyActionMapper; + + const items = makeDiv(this.element, null, ["buildings"]); + const iconSize = 32; + + for (let i = 0; i < toolbarBuildings.length; ++i) { + const metaBuilding = gMetaBuildingRegistry.findByClass(toolbarBuildings[i]); + const binding = actionMapper.getBinding("building_" + metaBuilding.getId()); + + const dimensions = metaBuilding.getDimensions(); + const itemContainer = makeDiv(items, null, ["building"]); + itemContainer.setAttribute("data-tilewidth", dimensions.x); + itemContainer.setAttribute("data-tileheight", dimensions.y); + + const label = makeDiv(itemContainer, null, ["label"]); + label.innerText = metaBuilding.getName(); + + const tooltip = makeDiv( + itemContainer, + null, + ["tooltip"], + ` + ${metaBuilding.getName()} + ${metaBuilding.getDescription()} + + ` + ); + + const sprite = metaBuilding.getPreviewSprite(0); + + const spriteWrapper = makeDiv(itemContainer, null, ["iconWrap"]); + spriteWrapper.innerHTML = sprite.getAsHTML(iconSize * dimensions.x, iconSize * dimensions.y); + + binding.appendLabelToElement(itemContainer); + binding.add(() => this.selectBuildingForPlacement(metaBuilding)); + + this.trackClicks(itemContainer, () => this.selectBuildingForPlacement(metaBuilding), {}); + + this.buildingUnlockStates[metaBuilding.id] = { + metaBuilding, + element: itemContainer, + status: false, + }; + } + } + + update() { + this.trackedIsVisisible.set(!this.root.camera.getIsMapOverlayActive()); + + for (const buildingId in this.buildingUnlockStates) { + const handle = this.buildingUnlockStates[buildingId]; + const newStatus = handle.metaBuilding.getIsUnlocked(this.root); + if (handle.status !== newStatus) { + handle.status = newStatus; + handle.element.classList.toggle("unlocked", newStatus); + } + } + } + + /** + * + * @param {MetaBuilding} metaBuilding + */ + selectBuildingForPlacement(metaBuilding) { + if (!metaBuilding.getIsUnlocked(this.root)) { + this.root.soundProxy.playUiError(); + return; + } + + this.sigBuildingSelected.dispatch(metaBuilding); + } +} diff --git a/src/js/game/hud/parts/game_menu.js b/src/js/game/hud/parts/game_menu.js new file mode 100644 index 00000000..105b0970 --- /dev/null +++ b/src/js/game/hud/parts/game_menu.js @@ -0,0 +1,37 @@ +import { BaseHUDPart } from "../base_hud_part"; +import { makeDiv } from "../../../core/utils"; + +export class HUDGameMenu extends BaseHUDPart { + initialize() {} + createElements(parent) { + this.element = makeDiv(parent, "ingame_HUD_GameMenu"); + + const buttons = [ + { + id: "shop", + label: "Upgrades", + handler: () => this.root.hud.parts.shop.show(), + keybinding: "menu_open_shop", + }, + { + id: "stats", + label: "Stats", + handler: () => null, + keybinding: "menu_open_stats", + }, + ]; + + buttons.forEach(({ id, label, handler, keybinding }) => { + const button = document.createElement("button"); + button.setAttribute("data-button-id", id); + this.element.appendChild(button); + this.trackClicks(button, handler); + + if (keybinding) { + const binding = this.root.gameState.keyActionMapper.getBinding(keybinding); + binding.add(handler); + binding.appendLabelToElement(button); + } + }); + } +} diff --git a/src/js/game/hud/parts/keybinding_overlay.js b/src/js/game/hud/parts/keybinding_overlay.js new file mode 100644 index 00000000..96be31e3 --- /dev/null +++ b/src/js/game/hud/parts/keybinding_overlay.js @@ -0,0 +1,73 @@ +import { BaseHUDPart } from "../base_hud_part"; +import { makeDiv } from "../../../core/utils"; +import { getStringForKeyCode } from "../../key_action_mapper"; +import { TrackedState } from "../../../core/tracked_state"; + +export class HUDKeybindingOverlay extends BaseHUDPart { + initialize() { + this.shiftDownTracker = new TrackedState(this.onShiftStateChanged, this); + } + + onShiftStateChanged(shiftDown) { + this.element.classList.toggle("shiftDown", shiftDown); + } + + createElements(parent) { + const mapper = this.root.gameState.keyActionMapper; + + const getKeycode = id => { + return getStringForKeyCode(mapper.getBinding(id).keyCode); + }; + + this.element = makeDiv( + parent, + "ingame_HUD_KeybindingOverlay", + [], + ` +
+ ${getKeycode("center_map")} + +
+ +
+ + ${getKeycode("map_move_up")} + ${getKeycode("map_move_left")} + ${getKeycode("map_move_down")} + ${getKeycode("map_move_right")} + +
+ +
+ + +
+ + +
+ + ${getKeycode("building_abort_placement")} + +
+ +
+ ${getKeycode("rotate_while_placing")} + +
+ +
+ SHIFT + +
+ ` + ); + } + + onSelectedBuildingForPlacementChanged(selectedMetaBuilding) { + this.element.classList.toggle("placementActive", !!selectedMetaBuilding); + } + + update() { + this.shiftDownTracker.set(this.root.app.inputMgr.shiftIsDown); + } +} diff --git a/src/js/game/hud/parts/processing_overlay.js b/src/js/game/hud/parts/processing_overlay.js new file mode 100644 index 00000000..a8debea9 --- /dev/null +++ b/src/js/game/hud/parts/processing_overlay.js @@ -0,0 +1,117 @@ +import { DynamicDomAttach } from "../dynamic_dom_attach"; +import { BaseHUDPart } from "../base_hud_part"; +import { performanceNow } from "../../../core/builtins"; +import { makeDiv } from "../../../core/utils"; +import { Signal } from "../../../core/signal"; +import { InputReceiver } from "../../../core/input_receiver"; +import { createLogger } from "../../../core/logging"; + +const logger = createLogger("hud/processing_overlay"); + +export class HUDProcessingOverlay extends BaseHUDPart { + constructor(root) { + super(root); + this.tasks = []; + this.computeTimeout = null; + + this.root.signals.performAsync.add(this.queueTask, this); + + this.allTasksFinished = new Signal(); + this.inputReceiver = new InputReceiver("processing-overlay"); + + this.root.signals.aboutToDestruct.add(() => + this.root.app.inputMgr.destroyReceiver(this.inputReceiver) + ); + } + + createElements(parent) { + this.element = makeDiv( + parent, + "rg_HUD_ProcessingOverlay", + ["hudElement"], + ` + + Computing + + ` + ); + } + + initialize() { + this.domWatcher = new DynamicDomAttach(this.root, this.element, { + timeToKeepSeconds: 0, + }); + } + + queueTask(task, name) { + if (!this.root.gameInitialized) { + // Tasks before the game started can be done directlry + task(); + return; + } + // if (name) { + // console.warn("QUEUE", name); + // } + + task.__name = name; + this.tasks.push(task); + } + + hasTasks() { + return this.tasks.length > 0; + } + + isRunning() { + return this.computeTimeout !== null; + } + + processSync() { + const now = performanceNow(); + while (this.tasks.length > 0) { + const workload = this.tasks[0]; + workload.call(); + this.tasks.shift(); + } + const duration = performanceNow() - now; + if (duration > 100) { + logger.log("Tasks done slow (SYNC!) within", (performanceNow() - now).toFixed(2), "ms"); + } + } + + process() { + this.root.app.inputMgr.makeSureAttachedAndOnTop(this.inputReceiver); + + this.domWatcher.update(true); + if (this.tasks.length === 0) { + logger.warn("No tasks but still called process"); + return; + } + + if (this.computeTimeout) { + assert(false, "Double compute queued"); + clearTimeout(this.computeTimeout); + } + + this.computeTimeout = setTimeout(() => { + const now = performanceNow(); + while (this.tasks.length > 0) { + const workload = this.tasks[0]; + workload.call(); + this.tasks.shift(); + } + const duration = performanceNow() - now; + if (duration > 100) { + logger.log("Tasks done slow within", (performanceNow() - now).toFixed(2), "ms"); + } + + this.domWatcher.update(false); + + this.root.app.inputMgr.makeSureDetached(this.inputReceiver); + + clearTimeout(this.computeTimeout); + this.computeTimeout = null; + + this.allTasksFinished.dispatch(); + }); + } +} diff --git a/src/js/game/hud/parts/shop.js b/src/js/game/hud/parts/shop.js new file mode 100644 index 00000000..db92ded3 --- /dev/null +++ b/src/js/game/hud/parts/shop.js @@ -0,0 +1,181 @@ +import { BaseHUDPart } from "../base_hud_part"; +import { makeDiv, removeAllChildren, formatBigNumber } from "../../../core/utils"; +import { UPGRADES, TIER_LABELS } from "../../upgrades"; +import { ShapeDefinition } from "../../shape_definition"; +import { DynamicDomAttach } from "../dynamic_dom_attach"; +import { InputReceiver } from "../../../core/input_receiver"; +import { KeyActionMapper } from "../../key_action_mapper"; +import { Math_min } from "../../../core/builtins"; + +export class HUDShop extends BaseHUDPart { + createElements(parent) { + this.background = makeDiv(parent, "ingame_HUD_Shop", ["ingameDialog"]); + + // DIALOG Inner / Wrapper + this.dialogInner = makeDiv(this.background, null, ["dialogInner"]); + this.title = makeDiv(this.dialogInner, null, ["title"], `Upgrades`); + this.closeButton = makeDiv(this.title, null, ["closeButton"]); + this.trackClicks(this.closeButton, this.close); + this.contentDiv = makeDiv(this.dialogInner, null, ["content"]); + + this.upgradeToElements = {}; + + // Upgrades + for (const upgradeId in UPGRADES) { + const { label } = UPGRADES[upgradeId]; + const handle = {}; + handle.requireIndexToElement = []; + + // Wrapper + handle.elem = makeDiv(this.contentDiv, null, ["upgrade"]); + handle.elem.setAttribute("data-upgrade-id", upgradeId); + + // Title + const title = makeDiv(handle.elem, null, ["title"], label); + + // Title > Tier + handle.elemTierLabel = makeDiv(title, null, ["tier"], "Tier ?"); + + // Icon + handle.icon = makeDiv(handle.elem, null, ["icon"]); + handle.icon.setAttribute("data-icon", "upgrades/" + upgradeId + ".png"); + + // Description + handle.elemDescription = makeDiv(handle.elem, null, ["description"], "??"); + handle.elemRequirements = makeDiv(handle.elem, null, ["requirements"]); + + // Buy button + handle.buyButton = document.createElement("button"); + handle.buyButton.classList.add("buy", "styledButton"); + handle.buyButton.innerText = "Upgrade"; + handle.elem.appendChild(handle.buyButton); + + this.trackClicks(handle.buyButton, () => this.tryUnlockNextTier(upgradeId)); + + // Assign handle + this.upgradeToElements[upgradeId] = handle; + } + } + + rerenderFull() { + for (const upgradeId in this.upgradeToElements) { + const handle = this.upgradeToElements[upgradeId]; + const { description, tiers } = UPGRADES[upgradeId]; + // removeAllChildren(handle.elem); + + const currentTier = this.root.hubGoals.getUpgradeLevel(upgradeId); + const tierHandle = tiers[currentTier]; + + // Set tier + handle.elemTierLabel.innerText = "Tier " + TIER_LABELS[currentTier]; + handle.elemTierLabel.setAttribute("data-tier", currentTier); + + // Cleanup + handle.requireIndexToElement = []; + removeAllChildren(handle.elemRequirements); + + handle.elem.classList.toggle("maxLevel", !tierHandle); + + if (!tierHandle) { + // Max level + handle.elemDescription.innerText = "Maximum level"; + continue; + } + + // Set description + handle.elemDescription.innerText = description(tierHandle.improvement); + + tierHandle.required.forEach(({ shape, amount }) => { + const requireDiv = makeDiv(handle.elemRequirements, null, ["requirement"]); + + const shapeDef = this.root.shapeDefinitionMgr.registerOrReturnHandle( + ShapeDefinition.fromShortKey(shape) + ); + const shapeCanvas = shapeDef.generateAsCanvas(120); + shapeCanvas.classList.add(); + requireDiv.appendChild(shapeCanvas); + + const progressContainer = makeDiv(requireDiv, null, ["amount"]); + const progressBar = document.createElement("label"); + progressBar.classList.add("progressBar"); + progressContainer.appendChild(progressBar); + + const progressLabel = document.createElement("label"); + progressContainer.appendChild(progressLabel); + + handle.requireIndexToElement.push({ + progressLabel, + progressBar, + definition: shapeDef, + required: amount, + }); + }); + } + } + + renderCountsAndStatus() { + for (const upgradeId in this.upgradeToElements) { + const handle = this.upgradeToElements[upgradeId]; + for (let i = 0; i < handle.requireIndexToElement.length; ++i) { + const { progressLabel, progressBar, definition, required } = handle.requireIndexToElement[i]; + + const haveAmount = this.root.hubGoals.getShapesStored(definition); + const progress = Math_min(haveAmount / required, 1.0); + + progressLabel.innerText = formatBigNumber(haveAmount) + " / " + formatBigNumber(required); + progressBar.style.width = progress * 100.0 + "%"; + progressBar.classList.toggle("complete", progress >= 1.0); + } + + handle.buyButton.classList.toggle("buyable", this.root.hubGoals.canUnlockUpgrade(upgradeId)); + } + } + + initialize() { + this.domAttach = new DynamicDomAttach(this.root, this.background, { + attachClass: "visible", + }); + + this.inputReciever = new InputReceiver("shop"); + this.keyActionMapper = new KeyActionMapper(this.root, this.inputReciever); + + this.keyActionMapper.getBinding("back").add(this.close, this); + this.keyActionMapper.getBinding("menu_open_shop").add(this.close, this); + + this.close(); + + this.rerenderFull(); + this.root.signals.upgradePurchased.add(this.rerenderFull, this); + } + + cleanup() { + document.body.classList.remove("ingameDialogOpen"); + } + + show() { + this.visible = true; + document.body.classList.add("ingameDialogOpen"); + // this.background.classList.add("visible"); + this.root.app.inputMgr.makeSureAttachedAndOnTop(this.inputReciever); + this.update(); + } + + close() { + this.visible = false; + document.body.classList.remove("ingameDialogOpen"); + this.root.app.inputMgr.makeSureDetached(this.inputReciever); + this.update(); + } + + update() { + this.domAttach.update(this.visible); + if (this.visible) { + this.renderCountsAndStatus(); + } + } + + tryUnlockNextTier(upgradeId) { + // Nothing + this.root.hubGoals.tryUnlockUgprade(upgradeId); + } +} diff --git a/src/js/game/hud/parts/unlock_notification.js b/src/js/game/hud/parts/unlock_notification.js new file mode 100644 index 00000000..62e103b7 --- /dev/null +++ b/src/js/game/hud/parts/unlock_notification.js @@ -0,0 +1,122 @@ +import { BaseHUDPart } from "../base_hud_part"; +import { makeDiv } from "../../../core/utils"; +import { DynamicDomAttach } from "../dynamic_dom_attach"; +import { gMetaBuildingRegistry } from "../../../core/global_registries"; +import { MetaBuilding } from "../../meta_building"; +import { MetaSplitterBuilding } from "../../buildings/splitter"; +import { MetaCutterBuilding } from "../../buildings/cutter"; +import { enumHubGoalRewards } from "../../tutorial_goals"; +import { MetaTrashBuilding } from "../../buildings/trash"; +import { MetaMinerBuilding } from "../../buildings/miner"; +import { MetaPainterBuilding } from "../../buildings/painter"; +import { MetaMixerBuilding } from "../../buildings/mixer"; +import { MetaRotaterBuilding } from "../../buildings/rotater"; +import { MetaStackerBuilding } from "../../buildings/stacker"; +import { MetaUndergroundBeltBuilding } from "../../buildings/underground_belt"; +import { globalConfig } from "../../../core/config"; + +export class HUDUnlockNotification extends BaseHUDPart { + initialize() { + this.visible = false; + + this.domAttach = new DynamicDomAttach(this.root, this.element, { + timeToKeepSeconds: 0, + }); + + if (!(G_IS_DEV && globalConfig.debug.disableUnlockDialog)) { + this.root.signals.storyGoalCompleted.add(this.showForLevel, this); + } + } + + shouldPauseGame() { + return this.visible; + } + + createElements(parent) { + this.element = makeDiv(parent, "ingame_HUD_UnlockNotification", []); + + const dialog = makeDiv(this.element, null, ["dialog"]); + + this.elemTitle = makeDiv(dialog, null, ["title"], ``); + this.elemSubTitle = makeDiv(dialog, null, ["subTitle"], `Completed`); + + this.elemContents = makeDiv( + dialog, + null, + ["contents"], + ` + Ready for the next one? + ` + ); + + this.btnClose = document.createElement("button"); + this.btnClose.classList.add("close", "styledButton"); + this.btnClose.innerText = "Next level"; + dialog.appendChild(this.btnClose); + + this.trackClicks(this.btnClose, this.close); + } + + showForLevel(level, reward) { + this.elemTitle.innerText = "Level " + ("" + level).padStart(2, "0"); + + let html = `Unlocked ${reward}!`; + + const addBuildingExplanation = metaBuildingClass => { + const metaBuilding = gMetaBuildingRegistry.findByClass(metaBuildingClass); + html += `
`; + }; + + switch (reward) { + case enumHubGoalRewards.reward_cutter_and_trash: { + addBuildingExplanation(MetaCutterBuilding); + addBuildingExplanation(MetaTrashBuilding); + break; + } + case enumHubGoalRewards.reward_mixer: { + addBuildingExplanation(MetaMixerBuilding); + break; + } + + case enumHubGoalRewards.reward_painter: { + addBuildingExplanation(MetaPainterBuilding); + break; + } + + case enumHubGoalRewards.reward_rotater: { + addBuildingExplanation(MetaRotaterBuilding); + break; + } + + case enumHubGoalRewards.reward_splitter: { + addBuildingExplanation(MetaSplitterBuilding); + break; + } + + case enumHubGoalRewards.reward_stacker: { + addBuildingExplanation(MetaStackerBuilding); + break; + } + + case enumHubGoalRewards.reward_tunnel: { + addBuildingExplanation(MetaUndergroundBeltBuilding); + break; + } + } + + // addBuildingExplanation(MetaSplitterBuilding); + // addBuildingExplanation(MetaCutterBuilding); + + this.elemContents.innerHTML = html; + + this.visible = true; + } + + close() { + this.visible = false; + } + + update() { + this.domAttach.update(this.visible); + } +} diff --git a/src/js/game/item_registry.js b/src/js/game/item_registry.js new file mode 100644 index 00000000..2ecb89c5 --- /dev/null +++ b/src/js/game/item_registry.js @@ -0,0 +1,6 @@ +import { gItemRegistry } from "../core/global_registries"; +import { ShapeItem } from "./items/shape_item"; + +export function initItemRegistry() { + gItemRegistry.register(ShapeItem); +} diff --git a/src/js/game/items/color_item.js b/src/js/game/items/color_item.js new file mode 100644 index 00000000..cc618228 --- /dev/null +++ b/src/js/game/items/color_item.js @@ -0,0 +1,90 @@ +import { DrawParameters } from "../../core/draw_parameters"; +import { createLogger } from "../../core/logging"; +import { extendSchema } from "../../savegame/serialization"; +import { BaseItem } from "../base_item"; +import { enumColorsToHexCode, enumColors } from "../colors"; +import { makeOffscreenBuffer } from "../../core/buffer_utils"; +import { globalConfig } from "../../core/config"; +import { round1Digit } from "../../core/utils"; +import { Math_max, Math_round } from "../../core/builtins"; +import { smoothenDpi } from "../../core/dpi_manager"; + +/** @enum {string} */ +const enumColorToMapBackground = { + [enumColors.red]: "#ffbfc1", + [enumColors.green]: "#cbffc4", + [enumColors.blue]: "#bfdaff", +}; + +export class ColorItem extends BaseItem { + static getId() { + return "color"; + } + + static getSchema() { + return extendSchema(BaseItem.getCachedSchema(), { + // TODO + }); + } + + /** + * @param {string} color + */ + constructor(color) { + super(); + this.color = color; + + this.bufferGenerator = this.internalGenerateColorBuffer.bind(this); + } + + getBackgroundColorAsResource() { + return enumColorToMapBackground[this.color]; + } + + /** + * @param {number} x + * @param {number} y + * @param {number} size + * @param {DrawParameters} parameters + */ + draw(x, y, parameters, size = 12) { + const dpi = smoothenDpi(globalConfig.shapesSharpness * parameters.zoomLevel); + + const key = size + "/" + dpi; + const canvas = parameters.root.buffers.getForKey( + key, + this.color, + size, + size, + dpi, + this.bufferGenerator + ); + parameters.context.drawImage(canvas, x - size / 2, y - size / 2, size, size); + } + /** + * + * @param {HTMLCanvasElement} canvas + * @param {CanvasRenderingContext2D} context + * @param {number} w + * @param {number} h + * @param {number} dpi + */ + internalGenerateColorBuffer(canvas, context, w, h, dpi) { + context.translate((w * dpi) / 2, (h * dpi) / 2); + context.scale((dpi * w) / 12, (dpi * h) / 12); + + context.fillStyle = enumColorsToHexCode[this.color]; + context.strokeStyle = "rgba(100,102, 110, 1)"; + context.lineWidth = 2; + context.beginCircle(2, -1, 3); + context.stroke(); + context.fill(); + context.beginCircle(-2, -1, 3); + context.stroke(); + context.fill(); + context.beginCircle(0, 2, 3); + context.closePath(); + context.stroke(); + context.fill(); + } +} diff --git a/src/js/game/items/shape_item.js b/src/js/game/items/shape_item.js new file mode 100644 index 00000000..9aa1b78d --- /dev/null +++ b/src/js/game/items/shape_item.js @@ -0,0 +1,42 @@ +import { BaseItem } from "../base_item"; +import { DrawParameters } from "../../core/draw_parameters"; +import { extendSchema } from "../../savegame/serialization"; +import { ShapeDefinition } from "../shape_definition"; +import { createLogger } from "../../core/logging"; + +const logger = createLogger("shape_item"); + +export class ShapeItem extends BaseItem { + static getId() { + return "shape"; + } + + static getSchema() { + return extendSchema(BaseItem.getCachedSchema(), { + // TODO + }); + } + + /** + * @param {ShapeDefinition} definition + */ + constructor(definition) { + super(); + // logger.log("New shape item for shape definition", definition.generateId(), "created"); + + /** + * This property must not be modified on runtime, you have to clone the class in order to change the definition + */ + this.definition = definition; + } + + /** + * @param {number} x + * @param {number} y + * @param {DrawParameters} parameters + * @param {number=} size + */ + draw(x, y, parameters, size) { + this.definition.draw(x, y, parameters, size); + } +} diff --git a/src/js/game/key_action_mapper.js b/src/js/game/key_action_mapper.js new file mode 100644 index 00000000..dae0c57e --- /dev/null +++ b/src/js/game/key_action_mapper.js @@ -0,0 +1,383 @@ +/* typehints:start */ +import { GameRoot } from "./root"; +import { InputReceiver } from "../core/input_receiver"; +import { Application } from "../application"; +/* typehints:end */ + +import { Signal, STOP_PROPAGATION } from "../core/signal"; +import { IS_MOBILE } from "../core/config"; + +function key(str) { + return str.toUpperCase().charCodeAt(0); +} + +// TODO: Configurable +export const defaultKeybindings = { + general: { + confirm: { keyCode: 13 }, // enter + back: { keyCode: 27, builtin: true }, // escape + }, + + ingame: { + map_move_up: { keyCode: key("W") }, + map_move_right: { keyCode: key("D") }, + map_move_down: { keyCode: key("S") }, + map_move_left: { keyCode: key("A") }, + toggle_hud: { keyCode: 113 }, + + center_map: { keyCode: 32 }, + + menu_open_shop: { keyCode: key("F") }, + menu_open_stats: { keyCode: key("G") }, + }, + + toolbar: { + building_belt: { keyCode: key("1") }, + building_miner: { keyCode: key("2") }, + building_underground_belt: { keyCode: key("3") }, + building_splitter: { keyCode: key("4") }, + building_cutter: { keyCode: key("5") }, + building_rotater: { keyCode: key("6") }, + building_stacker: { keyCode: key("7") }, + building_mixer: { keyCode: key("8") }, + building_painter: { keyCode: key("9") }, + building_trash: { keyCode: key("0") }, + + building_abort_placement: { keyCode: key("Q") }, + + rotate_while_placing: { keyCode: key("R") }, + }, +}; + +/** + * Returns a keycode -> string + * @param {number} code + * @returns {string} + */ +export function getStringForKeyCode(code) { + switch (code) { + case 8: + return "⌫"; + case 9: + return "TAB"; + case 13: + return "⏎"; + case 16: + return "⇪"; + case 17: + return "CTRL"; + case 18: + return "ALT"; + case 19: + return "PAUSE"; + case 20: + return "CAPS"; + case 27: + return "ESC"; + case 32: + return "SPACE"; + case 33: + return "PGUP"; + case 34: + return "PGDOWN"; + case 35: + return "END"; + case 36: + return "HOME"; + case 37: + return "⬅"; + case 38: + return "⬆"; + case 39: + return "➡"; + case 40: + return "⬇"; + case 44: + return "PRNT"; + case 45: + return "INS"; + case 46: + return "DEL"; + case 93: + return "SEL"; + case 96: + return "NUM 0"; + case 97: + return "NUM 1"; + case 98: + return "NUM 2"; + case 99: + return "NUM 3"; + case 100: + return "NUM 4"; + case 101: + return "NUM 5"; + case 102: + return "NUM 6"; + case 103: + return "NUM 7"; + case 104: + return "NUM 8"; + case 105: + return "NUM 9"; + case 106: + return "*"; + case 107: + return "+"; + case 109: + return "-"; + case 110: + return "."; + case 111: + return "/"; + case 112: + return "F1"; + case 113: + return "F2"; + case 114: + return "F3"; + case 115: + return "F4"; + case 116: + return "F4"; + case 117: + return "F5"; + case 118: + return "F6"; + case 119: + return "F7"; + case 120: + return "F8"; + case 121: + return "F9"; + case 122: + return "F10"; + case 123: + return "F11"; + case 124: + return "F12"; + + case 144: + return "NUMLOCK"; + case 145: + return "SCRLOCK"; + case 182: + return "COMP"; + case 183: + return "CALC"; + case 186: + return ";"; + case 187: + return "="; + case 188: + return ","; + case 189: + return "-"; + case 189: + return "."; + case 191: + return "/"; + case 219: + return "["; + case 220: + return "\\"; + case 221: + return "]"; + case 222: + return "'"; + } + + // TODO + return String.fromCharCode(code); +} + +export class Keybinding { + /** + * + * @param {Application} app + * @param {object} param0 + * @param {number} param0.keyCode + * @param {boolean=} param0.builtin + */ + constructor(app, { keyCode, builtin = false }) { + assert(keyCode && Number.isInteger(keyCode), "Invalid key code: " + keyCode); + this.app = app; + this.keyCode = keyCode; + this.builtin = builtin; + + this.currentlyDown = false; + + this.signal = new Signal(); + this.toggled = new Signal(); + } + + /** + * Adds an event listener + * @param {function() : void} receiver + * @param {object=} scope + */ + add(receiver, scope = null) { + this.signal.add(receiver, scope); + } + + /** + * @param {Element} elem + * @returns {HTMLElement} the created element, or null if the keybindings are not shown + * */ + appendLabelToElement(elem) { + if (IS_MOBILE) { + return null; + } + const spacer = document.createElement("code"); + spacer.classList.add("keybinding"); + spacer.innerHTML = getStringForKeyCode(this.keyCode); + elem.appendChild(spacer); + return spacer; + } + + /** + * Returns the key code as a nice string + */ + getKeyCodeString() { + return getStringForKeyCode(this.keyCode); + } + + /** + * Remvoes all signal receivers + */ + clearSignalReceivers() { + this.signal.removeAll(); + } +} + +export class KeyActionMapper { + /** + * + * @param {GameRoot} root + * @param {InputReceiver} inputReciever + */ + constructor(root, inputReciever) { + this.root = root; + inputReciever.keydown.add(this.handleKeydown, this); + inputReciever.keyup.add(this.handleKeyup, this); + + /** @type {Object.} */ + this.keybindings = {}; + + // const overrides = root.app.settings.getKeybindingOverrides(); + + for (const category in defaultKeybindings) { + for (const key in defaultKeybindings[category]) { + let payload = Object.assign({}, defaultKeybindings[category][key]); + // if (overrides[key]) { + // payload.keyCode = overrides[key]; + // } + + this.keybindings[key] = new Keybinding(this.root.app, payload); + } + } + + inputReciever.pageBlur.add(this.onPageBlur, this); + inputReciever.destroyed.add(this.cleanup, this); + } + + /** + * Returns all keybindings starting with the given id + * @param {string} pattern + * @returns {Array} + */ + getKeybindingsStartingWith(pattern) { + let result = []; + for (const key in this.keybindings) { + if (key.startsWith(pattern)) { + result.push(this.keybindings[key]); + } + } + return result; + } + + /** + * Forwards the given events to the other mapper (used in tooltips) + * @param {KeyActionMapper} receiver + * @param {Array} bindings + */ + forward(receiver, bindings) { + for (let i = 0; i < bindings.length; ++i) { + const key = bindings[i]; + this.keybindings[key].signal.add((...args) => receiver.keybindings[key].signal.dispatch(...args)); + } + } + + cleanup() { + for (const key in this.keybindings) { + this.keybindings[key].signal.removeAll(); + } + } + + onPageBlur() { + // Reset all down states + // Find mapping + for (const key in this.keybindings) { + /** @type {Keybinding} */ + const binding = this.keybindings[key]; + binding.currentlyDown = false; + } + } + + /** + * Internal keydown handler + * @param {object} param0 + * @param {number} param0.keyCode + * @param {boolean} param0.shift + * @param {boolean} param0.alt + */ + handleKeydown({ keyCode, shift, alt }) { + let stop = false; + + // Find mapping + for (const key in this.keybindings) { + /** @type {Keybinding} */ + const binding = this.keybindings[key]; + if (binding.keyCode === keyCode /* && binding.shift === shift && binding.alt === alt */) { + binding.currentlyDown = true; + + /** @type {Signal} */ + const signal = this.keybindings[key].signal; + if (signal.dispatch() === STOP_PROPAGATION) { + return; + } + } + } + + if (stop) { + return STOP_PROPAGATION; + } + } + + /** + * Internal keyup handler + * @param {object} param0 + * @param {number} param0.keyCode + * @param {boolean} param0.shift + * @param {boolean} param0.alt + */ + handleKeyup({ keyCode, shift, alt }) { + for (const key in this.keybindings) { + /** @type {Keybinding} */ + const binding = this.keybindings[key]; + if (binding.keyCode === keyCode) { + binding.currentlyDown = false; + } + } + } + + /** + * Returns a given keybinding + * @param {string} id + * @returns {Keybinding} + */ + getBinding(id) { + assert(this.keybindings[id], "Keybinding " + id + " not known!"); + return this.keybindings[id]; + } +} diff --git a/src/js/game/logic.js b/src/js/game/logic.js new file mode 100644 index 00000000..fe58ee4e --- /dev/null +++ b/src/js/game/logic.js @@ -0,0 +1,209 @@ +import { GameRoot } from "./root"; +import { Entity } from "./entity"; +import { Vector, enumDirectionToVector, enumDirection } from "../core/vector"; +import { MetaBuilding } from "./meta_building"; +import { StaticMapEntityComponent } from "./components/static_map_entity"; +import { Math_abs } from "../core/builtins"; +import { Rectangle } from "../core/rectangle"; +import { createLogger } from "../core/logging"; + +const logger = createLogger("ingame/logic"); + +/** + * Typing helper + * @typedef {Array<{ + * entity: Entity, + * slot: import("./components/item_ejector").ItemEjectorSlot, + * fromTile: Vector, + * toDirection: enumDirection + * }>} EjectorsAffectingTile + */ + +/** + * Typing helper + * @typedef {Array<{ + * entity: Entity, + * slot: import("./components/item_acceptor").ItemAcceptorSlot, + * toTile: Vector, + * fromDirection: enumDirection + * }>} AcceptorsAffectingTile + */ + +/** + * @typedef {{ + * acceptors: AcceptorsAffectingTile, + * ejectors: EjectorsAffectingTile + * }} AcceptorsAndEjectorsAffectingTile + */ + +export class GameLogic { + /** + * + * @param {GameRoot} root + */ + constructor(root) { + this.root = root; + } + + /** + * + * @param {Vector} origin + * @param {number} rotation + * @param {MetaBuilding} building + */ + isAreaFreeToBuild(origin, rotation, building) { + const checker = new StaticMapEntityComponent({ + origin, + tileSize: building.getDimensions(), + rotationDegrees: rotation, + }); + + const rect = checker.getTileSpaceBounds(); + + for (let x = rect.x; x < rect.x + rect.w; ++x) { + for (let y = rect.y; y < rect.y + rect.h; ++y) { + const contents = this.root.map.getTileContentXY(x, y); + if (contents && !contents.components.ReplaceableMapEntity) { + return false; + } + } + } + return true; + } + + /** + * + * @param {Vector} origin + * @param {number} rotation + * @param {MetaBuilding} building + */ + checkCanPlaceBuilding(origin, rotation, building) { + if (!building.getIsUnlocked(this.root)) { + return false; + } + return this.isAreaFreeToBuild(origin, rotation, building); + } + + /** + * + * @param {object} param0 + * @param {Vector} param0.origin + * @param {number} param0.rotation + * @param {number} param0.rotationVariant + * @param {MetaBuilding} param0.building + */ + tryPlaceBuilding({ origin, rotation, rotationVariant, building }) { + if (this.checkCanPlaceBuilding(origin, rotation, building)) { + // Remove any removeable entities below + const checker = new StaticMapEntityComponent({ + origin, + tileSize: building.getDimensions(), + rotationDegrees: rotation, + }); + + const rect = checker.getTileSpaceBounds(); + + for (let x = rect.x; x < rect.x + rect.w; ++x) { + for (let y = rect.y; y < rect.y + rect.h; ++y) { + const contents = this.root.map.getTileContentXY(x, y); + if (contents && contents.components.ReplaceableMapEntity) { + if (!this.tryDeleteBuilding(contents)) { + logger.error("Building has replaceable component but is also unremovable"); + return false; + } + } + } + } + + building.createAndPlaceEntity(this.root, origin, rotation, rotationVariant); + return true; + } + return false; + } + + /** + * Returns whether the given building can get removed + * @param {Entity} building + */ + canDeleteBuilding(building) { + return building.components.StaticMapEntity && !building.components.Unremovable; + } + + /** + * Tries to delete the given building + * @param {Entity} building + */ + tryDeleteBuilding(building) { + if (!this.canDeleteBuilding(building)) { + return false; + } + this.root.map.removeStaticEntity(building); + this.root.entityMgr.destroyEntity(building); + return true; + } + + /** + * Returns the acceptors and ejectors which affect the current tile + * @param {Vector} tile + * @returns {AcceptorsAndEjectorsAffectingTile} + */ + getEjectorsAndAcceptorsAtTile(tile) { + /** @type {EjectorsAffectingTile} */ + let ejectors = []; + /** @type {AcceptorsAffectingTile} */ + let acceptors = []; + + for (let dx = -1; dx <= 1; ++dx) { + for (let dy = -1; dy <= 1; ++dy) { + if (Math_abs(dx) + Math_abs(dy) !== 1) { + continue; + } + + const entity = this.root.map.getTileContentXY(tile.x + dx, tile.y + dy); + if (entity) { + const staticComp = entity.components.StaticMapEntity; + const itemEjector = entity.components.ItemEjector; + if (itemEjector) { + for (let ejectorSlot = 0; ejectorSlot < itemEjector.slots.length; ++ejectorSlot) { + const slot = itemEjector.slots[ejectorSlot]; + const wsTile = staticComp.localTileToWorld(slot.pos); + const wsDirection = staticComp.localDirectionToWorld(slot.direction); + const targetTile = wsTile.add(enumDirectionToVector[wsDirection]); + if (targetTile.equals(tile)) { + ejectors.push({ + entity, + slot, + fromTile: wsTile, + toDirection: wsDirection, + }); + } + } + } + + const itemAcceptor = entity.components.ItemAcceptor; + if (itemAcceptor) { + for (let acceptorSlot = 0; acceptorSlot < itemAcceptor.slots.length; ++acceptorSlot) { + const slot = itemAcceptor.slots[acceptorSlot]; + const wsTile = staticComp.localTileToWorld(slot.pos); + for (let k = 0; k < slot.directions.length; ++k) { + const direction = slot.directions[k]; + const wsDirection = staticComp.localDirectionToWorld(direction); + + const sourceTile = wsTile.add(enumDirectionToVector[wsDirection]); + if (sourceTile.equals(tile)) { + acceptors.push({ + entity, + slot, + toTile: wsTile, + fromDirection: wsDirection, + }); + } + } + } + } + } + } + } + return { ejectors, acceptors }; + } +} diff --git a/src/js/game/map.js b/src/js/game/map.js new file mode 100644 index 00000000..97f6d3e6 --- /dev/null +++ b/src/js/game/map.js @@ -0,0 +1,207 @@ +/* typehints:start */ +import { GameRoot } from "./root"; +/* typehints:end */ + +import { globalConfig } from "../core/config"; +import { Vector } from "../core/vector"; +import { Entity } from "./entity"; +import { Math_floor } from "../core/builtins"; +import { createLogger } from "../core/logging"; +import { BaseItem } from "./base_item"; +import { MapChunkView } from "./map_chunk_view"; + +const logger = createLogger("map"); + +export class BaseMap { + /** + * + * @param {GameRoot} root + */ + constructor(root) { + this.root = root; + + /** + * Mapping of 'X|Y' to chunk + * @type {Map} */ + this.chunksById = new Map(); + } + + /** + * Returns the given chunk by index + * @param {number} chunkX + * @param {number} chunkY + */ + getChunk(chunkX, chunkY, createIfNotExistent = false) { + // TODO: Better generation + const chunkIdentifier = chunkX + "|" + chunkY; + let storedChunk; + + if ((storedChunk = this.chunksById.get(chunkIdentifier))) { + return storedChunk; + } + + if (createIfNotExistent) { + const instance = new MapChunkView(this.root, chunkX, chunkY); + this.chunksById.set(chunkIdentifier, instance); + return instance; + } + + return null; + } + + /** + * Gets or creates a new chunk if not existent for the given tile + * @param {number} tileX + * @param {number} tileY + * @returns {MapChunkView} + */ + getOrCreateChunkAtTile(tileX, tileY) { + const chunkX = Math_floor(tileX / globalConfig.mapChunkSize); + const chunkY = Math_floor(tileY / globalConfig.mapChunkSize); + return this.getChunk(chunkX, chunkY, true); + } + + /** + * Gets a chunk if not existent for the given tile + * @param {number} tileX + * @param {number} tileY + * @returns {MapChunkView?} + */ + getChunkAtTileOrNull(tileX, tileY) { + const chunkX = Math_floor(tileX / globalConfig.mapChunkSize); + const chunkY = Math_floor(tileY / globalConfig.mapChunkSize); + return this.getChunk(chunkX, chunkY, false); + } + + /** + * Checks if a given tile is within the map bounds + * @param {Vector} tile + * @returns {boolean} + */ + isValidTile(tile) { + if (G_IS_DEV) { + assert(tile instanceof Vector, "tile is not a vector"); + } + return Number.isInteger(tile.x) && Number.isInteger(tile.y); + } + + /** + * Returns the tile content of a given tile + * @param {Vector} tile + * @returns {Entity} Entity or null + */ + getTileContent(tile) { + if (G_IS_DEV) { + this.internalCheckTile(tile); + } + const chunk = this.getChunkAtTileOrNull(tile.x, tile.y); + return chunk && chunk.getTileContentFromWorldCoords(tile.x, tile.y); + } + + /** + * Returns the lower layers content of the given tile + * @param {number} x + * @param {number} y + * @returns {BaseItem=} + */ + getLowerLayerContentXY(x, y) { + return this.getOrCreateChunkAtTile(x, y).getLowerLayerFromWorldCoords(x, y); + } + + /** + * Returns the tile content of a given tile + * @param {number} x + * @param {number} y + * @returns {Entity} Entity or null + */ + getTileContentXY(x, y) { + const chunk = this.getChunkAtTileOrNull(x, y); + return chunk && chunk.getTileContentFromWorldCoords(x, y); + } + + /** + * Checks if the tile is used + * @param {Vector} tile + * @returns {boolean} + */ + isTileUsed(tile) { + if (G_IS_DEV) { + this.internalCheckTile(tile); + } + const chunk = this.getChunkAtTileOrNull(tile.x, tile.y); + return chunk && chunk.getTileContentFromWorldCoords(tile.x, tile.y) != null; + } + + /** + * Sets the tiles content + * @param {Vector} tile + * @param {Entity} entity + */ + setTileContent(tile, entity) { + if (G_IS_DEV) { + this.internalCheckTile(tile); + } + + this.getOrCreateChunkAtTile(tile.x, tile.y).setTileContentFromWorldCords(tile.x, tile.y, entity); + + const staticComponent = entity.components.StaticMapEntity; + assert(staticComponent, "Can only place static map entities in tiles"); + } + + /** + * Places an entity with the StaticMapEntity component + * @param {Entity} entity + */ + placeStaticEntity(entity) { + assert(entity.components.StaticMapEntity, "Entity is not static"); + const staticComp = entity.components.StaticMapEntity; + const rect = staticComp.getTileSpaceBounds(); + for (let dx = 0; dx < rect.w; ++dx) { + for (let dy = 0; dy < rect.h; ++dy) { + const x = rect.x + dx; + const y = rect.y + dy; + this.getOrCreateChunkAtTile(x, y).setTileContentFromWorldCords(x, y, entity); + } + } + } + + /** + * Removes an entity with the StaticMapEntity component + * @param {Entity} entity + */ + removeStaticEntity(entity) { + assert(entity.components.StaticMapEntity, "Entity is not static"); + const staticComp = entity.components.StaticMapEntity; + const rect = staticComp.getTileSpaceBounds(); + for (let dx = 0; dx < rect.w; ++dx) { + for (let dy = 0; dy < rect.h; ++dy) { + const x = rect.x + dx; + const y = rect.y + dy; + this.getOrCreateChunkAtTile(x, y).setTileContentFromWorldCords(x, y, null); + } + } + } + + /** + * Resets the tiles content + * @param {Vector} tile + */ + clearTile(tile) { + if (G_IS_DEV) { + this.internalCheckTile(tile); + } + this.getOrCreateChunkAtTile(tile.x, tile.y).setTileContentFromWorldCords(tile.x, tile.y, null); + } + + // Internal + + /** + * Checks a given tile for validty + * @param {Vector} tile + */ + internalCheckTile(tile) { + assert(tile instanceof Vector, "tile is not a vector: " + tile); + assert(tile.x % 1 === 0, "Tile X is not a valid integer: " + tile.x); + assert(tile.y % 1 === 0, "Tile Y is not a valid integer: " + tile.y); + } +} diff --git a/src/js/game/map_chunk.js b/src/js/game/map_chunk.js new file mode 100644 index 00000000..8cb6758b --- /dev/null +++ b/src/js/game/map_chunk.js @@ -0,0 +1,359 @@ +/* typehints:start */ +import { GameRoot } from "./root"; +/* typehints:end */ + +import { Math_ceil, Math_max, Math_min, Math_random, Math_round } from "../core/builtins"; +import { globalConfig } from "../core/config"; +import { createLogger } from "../core/logging"; +import { + clamp, + fastArrayDeleteValueIfContained, + make2DUndefinedArray, + randomChoice, + randomInt, +} from "../core/utils"; +import { Vector } from "../core/vector"; +import { BaseItem } from "./base_item"; +import { enumColors } from "./colors"; +import { Entity } from "./entity"; +import { ColorItem } from "./items/color_item"; +import { ShapeItem } from "./items/shape_item"; +import { enumSubShape } from "./shape_definition"; + +const logger = createLogger("map_chunk"); + +export class MapChunk { + /** + * + * @param {GameRoot} root + * @param {number} x + * @param {number} y + */ + constructor(root, x, y) { + this.root = root; + this.x = x; + this.y = y; + this.tileX = x * globalConfig.mapChunkSize; + this.tileY = y * globalConfig.mapChunkSize; + + /** @type {Array>} */ + this.contents = make2DUndefinedArray( + globalConfig.mapChunkSize, + globalConfig.mapChunkSize, + "map-chunk@" + this.x + "|" + this.y + ); + + /** @type {Array>} */ + this.lowerLayer = make2DUndefinedArray( + globalConfig.mapChunkSize, + globalConfig.mapChunkSize, + "map-chunk-lower@" + this.x + "|" + this.y + ); + + /** @type {Array} */ + this.containedEntities = []; + + /** + * Store which patches we have so we can render them in the overview + * @type {Array<{pos: Vector, item: BaseItem, size: number }>} + */ + this.patches = []; + + this.generateLowerLayer(); + } + + /** + * Generates a patch filled with the given item + * @param {number} patchSize + * @param {BaseItem} item + * @param {number=} overrideX Override the X position of the patch + * @param {number=} overrideY Override the Y position of the patch + */ + internalGeneratePatch(patchSize, item, overrideX = null, overrideY = null) { + const border = Math_ceil(patchSize / 2 + 3); + + // Find a position within the chunk which is not blocked + let patchX = randomInt(border, globalConfig.mapChunkSize - border - 1); + let patchY = randomInt(border, globalConfig.mapChunkSize - border - 1); + + if (overrideX !== null) { + patchX = overrideX; + } + + if (overrideY !== null) { + patchY = overrideY; + } + + const avgPos = new Vector(0, 0); + let patchesDrawn = 0; + + // Each patch consists of multiple circles + const numCircles = patchSize; + // const numCircles = 1; + + for (let i = 0; i <= numCircles; ++i) { + // Determine circle parameters + const circleRadius = Math_min(1 + i, patchSize); + const circleRadiusSquare = circleRadius * circleRadius; + const circleOffsetRadius = (numCircles - i) / 2 + 2; + + // We draw an elipsis actually + const circleScaleY = 1 + (Math_random() * 2 - 1) * 0.1; + const circleScaleX = 1 + (Math_random() * 2 - 1) * 0.1; + + const circleX = patchX + randomInt(-circleOffsetRadius, circleOffsetRadius); + const circleY = patchY + randomInt(-circleOffsetRadius, circleOffsetRadius); + + for (let dx = -circleRadius * circleScaleX - 2; dx <= circleRadius * circleScaleX + 2; ++dx) { + for (let dy = -circleRadius * circleScaleY - 2; dy <= circleRadius * circleScaleY + 2; ++dy) { + const x = Math_round(circleX + dx); + const y = Math_round(circleY + dy); + if (x >= 0 && x < globalConfig.mapChunkSize && y >= 0 && y <= globalConfig.mapChunkSize) { + const originalDx = dx / circleScaleX; + const originalDy = dy / circleScaleY; + if (originalDx * originalDx + originalDy * originalDy <= circleRadiusSquare) { + if (!this.lowerLayer[x][y]) { + this.lowerLayer[x][y] = item; + ++patchesDrawn; + avgPos.x += x; + avgPos.y += y; + } + } + } else { + // logger.warn("Tried to spawn resource out of chunk"); + } + } + } + } + + this.patches.push({ + pos: avgPos.divideScalar(patchesDrawn), + item, + size: patchSize, + }); + } + + /** + * Generates a color patch + * @param {number} colorPatchSize + * @param {number} distanceToOriginInChunks + */ + internalGenerateColorPatch(colorPatchSize, distanceToOriginInChunks) { + // First, determine available colors + let availableColors = [enumColors.red, enumColors.green]; + if (distanceToOriginInChunks > 2) { + availableColors.push(enumColors.blue); + } + this.internalGeneratePatch(colorPatchSize, new ColorItem(randomChoice(availableColors))); + } + + /** + * Generates a shape patch + * @param {number} shapePatchSize + * @param {number} distanceToOriginInChunks + */ + internalGenerateShapePatch(shapePatchSize, distanceToOriginInChunks) { + /** @type {[enumSubShape, enumSubShape, enumSubShape, enumSubShape]} */ + let subShapes = null; + + let weights = {}; + + if (distanceToOriginInChunks < 3) { + // In the beginning, there are just circles + weights = { + [enumSubShape.circle]: 100, + }; + } else if (distanceToOriginInChunks < 6) { + // Later there come rectangles + if (Math_random() > 0.4) { + weights = { + [enumSubShape.circle]: 100, + }; + } else { + weights = { + [enumSubShape.rect]: 100, + }; + } + } else { + // Finally there is a mix of everything + weights = { + [enumSubShape.rect]: 100, + [enumSubShape.circle]: Math_round(50 + clamp(distanceToOriginInChunks * 2, 0, 50)), + [enumSubShape.star]: Math_round(20 + clamp(distanceToOriginInChunks * 2, 0, 30)), + [enumSubShape.windmill]: Math_round(5 + clamp(distanceToOriginInChunks * 2, 0, 20)), + }; + } + subShapes = [ + this.internalGenerateRandomSubShape(weights), + this.internalGenerateRandomSubShape(weights), + this.internalGenerateRandomSubShape(weights), + this.internalGenerateRandomSubShape(weights), + ]; + + const definition = this.root.shapeDefinitionMgr.getDefinitionFromSimpleShapes(subShapes); + this.internalGeneratePatch(shapePatchSize, new ShapeItem(definition)); + } + + /** + * Chooses a random shape with the given weights + * @param {Object.} weights + * @returns {enumSubShape} + */ + internalGenerateRandomSubShape(weights) { + // @ts-ignore + const sum = Object.values(weights).reduce((a, b) => a + b, 0); + + const chosenNumber = randomInt(0, sum - 1); + let accumulated = 0; + for (const key in weights) { + const weight = weights[key]; + if (accumulated + weight > chosenNumber) { + return key; + } + accumulated += weight; + } + + logger.error("Failed to find matching shape in chunk generation"); + return enumSubShape.circle; + } + + /** + * Generates the lower layer "terrain" + */ + generateLowerLayer() { + if (this.generatePredefined()) { + return; + } + + const chunkCenter = new Vector(this.x, this.y).addScalar(0.5); + const distanceToOriginInChunks = Math_round(chunkCenter.length()); + + // Determine how likely it is that there is a color patch + const colorPatchChance = 0.9 - clamp(distanceToOriginInChunks / 25, 0, 1) * 0.5; + if (Math_random() < colorPatchChance) { + const colorPatchSize = Math_max(2, Math_round(1 + clamp(distanceToOriginInChunks / 8, 0, 4))); + this.internalGenerateColorPatch(colorPatchSize, distanceToOriginInChunks); + } + + // Determine how likely it is that there is a shape patch + const shapePatchChance = 0.9 - clamp(distanceToOriginInChunks / 25, 0, 1) * 0.5; + if (Math_random() < shapePatchChance) { + const shapePatchSize = Math_max(2, Math_round(1 + clamp(distanceToOriginInChunks / 8, 0, 4))); + this.internalGenerateShapePatch(shapePatchSize, distanceToOriginInChunks); + } + } + + /** + * Checks if this chunk has predefined contents, and if so returns true and generates the + * predefined contents + * @returns {boolean} + */ + generatePredefined() { + if (this.x === 0 && this.y === 0) { + this.internalGeneratePatch(2, new ColorItem(enumColors.red), 7, 7); + return true; + } + if (this.x === -1 && this.y === 0) { + const definition = this.root.shapeDefinitionMgr.getDefinitionFromSimpleShapes([ + enumSubShape.circle, + enumSubShape.circle, + enumSubShape.circle, + enumSubShape.circle, + ]); + this.internalGeneratePatch(2, new ShapeItem(definition), globalConfig.mapChunkSize - 9, 7); + return true; + } + if (this.x === 0 && this.y === -1) { + const definition = this.root.shapeDefinitionMgr.getDefinitionFromSimpleShapes([ + enumSubShape.rect, + enumSubShape.rect, + enumSubShape.rect, + enumSubShape.rect, + ]); + this.internalGeneratePatch(2, new ShapeItem(definition), 5, globalConfig.mapChunkSize - 7); + return true; + } + + if (this.x === -1 && this.y === -1) { + this.internalGeneratePatch(2, new ColorItem(enumColors.green)); + return true; + } + + return false; + } + + /** + * + * @param {number} worldX + * @param {number} worldY + * @returns {BaseItem=} + */ + getLowerLayerFromWorldCoords(worldX, worldY) { + const localX = worldX - this.tileX; + const localY = worldY - this.tileY; + assert(localX >= 0, "Local X is < 0"); + assert(localY >= 0, "Local Y is < 0"); + assert(localX < globalConfig.mapChunkSize, "Local X is >= chunk size"); + assert(localY < globalConfig.mapChunkSize, "Local Y is >= chunk size"); + return this.lowerLayer[localX][localY] || null; + } + + /** + * Returns the contents of this chunk from the given world space coordinates + * @param {number} worldX + * @param {number} worldY + * @returns {Entity=} + */ + getTileContentFromWorldCoords(worldX, worldY) { + const localX = worldX - this.tileX; + const localY = worldY - this.tileY; + assert(localX >= 0, "Local X is < 0"); + assert(localY >= 0, "Local Y is < 0"); + assert(localX < globalConfig.mapChunkSize, "Local X is >= chunk size"); + assert(localY < globalConfig.mapChunkSize, "Local Y is >= chunk size"); + return this.contents[localX][localY] || null; + } + + /** + * Returns the chunks contents from the given local coordinates + * @param {number} localX + * @param {number} localY + * @returns {Entity=} + */ + getTileContentFromLocalCoords(localX, localY) { + assert(localX >= 0, "Local X is < 0"); + assert(localY >= 0, "Local Y is < 0"); + assert(localX < globalConfig.mapChunkSize, "Local X is >= chunk size"); + assert(localY < globalConfig.mapChunkSize, "Local Y is >= chunk size"); + + return this.contents[localX][localY] || null; + } + + /** + * Sets the chunks contents + * @param {number} tileX + * @param {number} tileY + * @param {Entity=} contents + */ + setTileContentFromWorldCords(tileX, tileY, contents) { + const localX = tileX - this.tileX; + const localY = tileY - this.tileY; + assert(localX >= 0, "Local X is < 0"); + assert(localY >= 0, "Local Y is < 0"); + assert(localX < globalConfig.mapChunkSize, "Local X is >= chunk size"); + assert(localY < globalConfig.mapChunkSize, "Local Y is >= chunk size"); + const oldContents = this.contents[localX][localY]; + assert(contents === null || !oldContents, "Tile already used: " + tileX + " / " + tileY); + + if (oldContents) { + // Remove from list + fastArrayDeleteValueIfContained(this.containedEntities, oldContents); + } + this.contents[localX][localY] = contents; + if (contents) { + if (this.containedEntities.indexOf(contents) < 0) { + this.containedEntities.push(contents); + } + } + } +} diff --git a/src/js/game/map_chunk_view.js b/src/js/game/map_chunk_view.js new file mode 100644 index 00000000..7634db64 --- /dev/null +++ b/src/js/game/map_chunk_view.js @@ -0,0 +1,226 @@ +import { MapChunk } from "./map_chunk"; +import { GameRoot } from "./root"; +import { globalConfig } from "../core/config"; +import { DrawParameters } from "../core/draw_parameters"; +import { round1Digit } from "../core/utils"; +import { Math_max, Math_round } from "../core/builtins"; +import { Rectangle } from "../core/rectangle"; +import { createLogger } from "../core/logging"; +import { smoothenDpi } from "../core/dpi_manager"; + +const logger = createLogger("chunk"); +const chunkSizePixels = globalConfig.mapChunkSize * globalConfig.tileSize; + +export class MapChunkView extends MapChunk { + /** + * + * @param {GameRoot} root + * @param {number} x + * @param {number} y + */ + constructor(root, x, y) { + super(root, x, y); + + this.boundInternalDrawBackgroundToContext = this.internalDrawBackgroundToContext.bind(this); + this.boundInternalDrawForegroundToContext = this.internalDrawForegroundToContext.bind(this); + + /** + * Whenever something changes, we increase this number - so we know we need to redraw + */ + this.renderIteration = 0; + + this.markDirty(); + } + + /** + * Marks this chunk as dirty, rerendering all caches + */ + markDirty() { + ++this.renderIteration; + this.renderKey = this.x + "/" + this.y + "@" + this.renderIteration; + } + + /** + * Draws the background layer + * @param {DrawParameters} parameters + */ + drawBackgroundLayer(parameters) { + if (parameters.zoomLevel > globalConfig.mapChunkPrerenderMinZoom) { + this.internalDrawBackgroundSystems(parameters); + return; + } + + const dpi = smoothenDpi(parameters.zoomLevel); + const buffer = this.root.buffers.getForKey( + "" + dpi, + this.renderKey + "@bg", + chunkSizePixels, + chunkSizePixels, + dpi, + this.boundInternalDrawBackgroundToContext, + { zoomLevel: parameters.zoomLevel } + ); + + parameters.context.drawImage( + buffer, + this.tileX * globalConfig.tileSize, + this.tileY * globalConfig.tileSize, + chunkSizePixels, + chunkSizePixels + ); + } + + /** + * Draws the foreground layer + * @param {DrawParameters} parameters + */ + drawForegroundLayer(parameters) { + if (parameters.zoomLevel > globalConfig.mapChunkPrerenderMinZoom) { + this.internalDrawForegroundSystems(parameters); + return; + } + + const dpi = smoothenDpi(parameters.zoomLevel); + const buffer = this.root.buffers.getForKey( + "" + dpi, + this.renderKey + "@fg", + chunkSizePixels, + chunkSizePixels, + dpi, + this.boundInternalDrawForegroundToContext, + { zoomLevel: parameters.zoomLevel } + ); + parameters.context.drawImage( + buffer, + this.tileX * globalConfig.tileSize, + this.tileY * globalConfig.tileSize, + chunkSizePixels, + chunkSizePixels + ); + } + + /** + * + * @param {HTMLCanvasElement} canvas + * @param {CanvasRenderingContext2D} context + * @param {number} w + * @param {number} h + * @param {number} dpi + */ + internalDrawBackgroundToContext(canvas, context, w, h, dpi, { zoomLevel }) { + const pattern = context.createPattern(this.root.map.cachedBackgroundCanvas, "repeat"); + context.scale(dpi, dpi); + + if (zoomLevel >= globalConfig.mapChunkOverviewMinZoom) { + const bgDpi = this.root.map.backgroundCacheDPI; + context.scale(1 / bgDpi, 1 / bgDpi); + context.fillStyle = pattern; + context.fillRect(0, 0, chunkSizePixels * bgDpi, chunkSizePixels * bgDpi); + context.scale(bgDpi, bgDpi); + } else { + if (this.containedEntities.length > 0) { + context.fillStyle = "#c5ccd6"; + } else { + context.fillStyle = "#a6afbb"; + } + context.fillRect(0, 0, 10000, 10000); + } + + if (G_IS_DEV && globalConfig.debug.showChunkBorders) { + context.fillStyle = "rgba(0, 0, 255, 0.1)"; + context.fillRect(0, 0, 10000, 10000); + } + + const parameters = new DrawParameters({ + context, + visibleRect: new Rectangle( + this.tileX * globalConfig.tileSize, + this.tileY * globalConfig.tileSize, + chunkSizePixels, + chunkSizePixels + ), + desiredAtlasScale: "1", + zoomLevel, + root: this.root, + }); + + parameters.context.translate( + -this.tileX * globalConfig.tileSize, + -this.tileY * globalConfig.tileSize + ); + // parameters.context.save(); + // parameters.context.transform( + // 1, + // 0, + // 0, + // zoomLevel, + // this.tileX * globalConfig.tileSize, + // this.tileY * globalConfig.tileSize + // ); + + this.internalDrawBackgroundSystems(parameters); + + // parameters.context.restore(); + } + + /** + * + * @param {HTMLCanvasElement} canvas + * @param {CanvasRenderingContext2D} context + * @param {number} w + * @param {number} h + * @param {number} dpi + */ + internalDrawForegroundToContext(canvas, context, w, h, dpi, { zoomLevel }) { + context.scale(dpi, dpi); + + const parameters = new DrawParameters({ + context, + visibleRect: new Rectangle( + this.tileX * globalConfig.tileSize, + this.tileY * globalConfig.tileSize, + chunkSizePixels, + chunkSizePixels + ), + desiredAtlasScale: "1", + zoomLevel, + root: this.root, + }); + // parameters.context.save(); + // parameters.context.save(); + // parameters.context.transform( + // zoomLevel, + // 0, + // 0, + // zoomLevel, + // this.tileX * globalConfig.tileSize, + // this.tileY * globalConfig.tileSize + // ); + + parameters.context.translate( + -this.tileX * globalConfig.tileSize, + -this.tileY * globalConfig.tileSize + ); + this.internalDrawForegroundSystems(parameters); + + // parameters.context.restore(); + } + + /** + * @param {DrawParameters} parameters + */ + internalDrawBackgroundSystems(parameters) { + const systems = this.root.systemMgr.systems; + systems.mapResources.drawChunk(parameters, this); + systems.belt.drawChunk(parameters, this); + } + + /** + * @param {DrawParameters} parameters + */ + internalDrawForegroundSystems(parameters) { + const systems = this.root.systemMgr.systems; + systems.miner.drawChunk(parameters, this); + systems.staticMapEntities.drawChunk(parameters, this); + } +} diff --git a/src/js/game/map_view.js b/src/js/game/map_view.js new file mode 100644 index 00000000..6c42b266 --- /dev/null +++ b/src/js/game/map_view.js @@ -0,0 +1,249 @@ +import { Math_max, Math_min, Math_floor, Math_ceil } from "../core/builtins"; +import { globalConfig } from "../core/config"; +import { DrawParameters } from "../core/draw_parameters"; +import { BaseMap } from "./map"; +import { freeCanvas, makeOffscreenBuffer } from "../core/buffer_utils"; +import { Entity } from "./entity"; + +/** + * This is the view of the map, it extends the map which is the raw model and allows + * to draw it + */ +export class MapView extends BaseMap { + constructor(root) { + super(root); + + /** + * DPI of the background cache images, required in some places + */ + this.backgroundCacheDPI = 4; + + /** + * The cached background sprite, containing the flat background + * @type {HTMLCanvasElement} */ + this.cachedBackgroundCanvas = null; + + /** @type {CanvasRenderingContext2D} */ + this.cachedBackgroundContext = null; + /** + * Cached pattern of the stripes background + * @type {CanvasPattern} */ + this.cachedBackgroundPattern = null; + + this.internalInitializeCachedBackgroundCanvases(); + this.root.signals.aboutToDestruct.add(this.cleanup, this); + + this.root.signals.entityAdded.add(this.onEntityChanged, this); + this.root.signals.entityDestroyed.add(this.onEntityChanged, this); + } + + cleanup() { + freeCanvas(this.cachedBackgroundCanvas); + this.cachedBackgroundCanvas = null; + this.cachedBackgroundPattern = null; + } + + /** + * Called when an entity was added or removed + * @param {Entity} entity + */ + onEntityChanged(entity) { + const staticComp = entity.components.StaticMapEntity; + if (staticComp) { + const rect = staticComp.getTileSpaceBounds(); + for (let x = rect.x; x <= rect.right(); ++x) { + for (let y = rect.y; y <= rect.bottom(); ++y) { + this.root.map.getOrCreateChunkAtTile(x, y).markDirty(); + } + } + } + } + + /** + * Draws all static entities like buildings etc. + * @param {DrawParameters} drawParameters + */ + drawStaticEntities(drawParameters) { + const cullRange = drawParameters.visibleRect.toTileCullRectangle(); + const top = cullRange.top(); + const right = cullRange.right(); + const bottom = cullRange.bottom(); + const left = cullRange.left(); + + const border = 1; + + const minY = top - border; + const maxY = bottom + border; + const minX = left - border; + const maxX = right + border - 1; + + // Render y from top down for proper blending + for (let y = minY; y <= maxY; ++y) { + for (let x = minX; x <= maxX; ++x) { + // const content = this.tiles[x][y]; + const chunk = this.getChunkAtTileOrNull(x, y); + if (!chunk) { + continue; + } + const content = chunk.getTileContentFromWorldCoords(x, y); + if (content) { + let isBorder = x <= left - 1 || x >= right + 1 || y <= top - 1 || y >= bottom + 1; + if (!isBorder) { + content.draw(drawParameters); + } + } + } + } + } + + /** + * Initializes all canvases used for background rendering + */ + internalInitializeCachedBackgroundCanvases() { + // Background canvas + const dims = globalConfig.tileSize; + const dpi = this.backgroundCacheDPI; + const [canvas, context] = makeOffscreenBuffer(dims * dpi, dims * dpi, { + smooth: false, + label: "map-cached-bg", + }); + context.scale(dpi, dpi); + + context.fillStyle = "#fff"; + context.fillRect(0, 0, dims, dims); + + context.fillStyle = "#fafafa"; + context.fillRect(0, 0, dims, 1); + context.fillRect(0, 0, 1, dims); + context.fillRect(dims - 1, 0, 1, dims); + context.fillRect(0, dims - 1, dims, 1); + + this.cachedBackgroundCanvas = canvas; + this.cachedBackgroundContext = context; + } + + /** + * Draws the maps foreground + * @param {DrawParameters} parameters + */ + drawForeground(parameters) { + const cullRange = parameters.visibleRect.toTileCullRectangle(); + const top = cullRange.top(); + const right = cullRange.right(); + const bottom = cullRange.bottom(); + const left = cullRange.left(); + + const border = 1; + const minY = top - border; + const maxY = bottom + border; + const minX = left - border; + const maxX = right + border - 1; + + const chunkStartX = Math_floor(minX / globalConfig.mapChunkSize); + const chunkStartY = Math_floor(minY / globalConfig.mapChunkSize); + + const chunkEndX = Math_ceil(maxX / globalConfig.mapChunkSize); + const chunkEndY = Math_ceil(maxY / globalConfig.mapChunkSize); + + // Render y from top down for proper blending + for (let chunkX = chunkStartX; chunkX <= chunkEndX; ++chunkX) { + for (let chunkY = chunkStartY; chunkY <= chunkEndY; ++chunkY) { + const chunk = this.root.map.getChunk(chunkX, chunkY, true); + chunk.drawForegroundLayer(parameters); + } + } + } + + /** + * Draws the map background + * @param {DrawParameters} parameters + */ + drawBackground(parameters) { + // If not using prerendered, draw background + if (parameters.zoomLevel > globalConfig.mapChunkPrerenderMinZoom) { + if (!this.cachedBackgroundPattern) { + this.cachedBackgroundPattern = parameters.context.createPattern( + this.cachedBackgroundCanvas, + "repeat" + ); + } + + const dpi = this.backgroundCacheDPI; + parameters.context.scale(1 / dpi, 1 / dpi); + + parameters.context.fillStyle = this.cachedBackgroundPattern; + parameters.context.fillRect( + parameters.visibleRect.x * dpi, + parameters.visibleRect.y * dpi, + parameters.visibleRect.w * dpi, + parameters.visibleRect.h * dpi + ); + parameters.context.scale(dpi, dpi); + } + + const cullRange = parameters.visibleRect.toTileCullRectangle(); + const top = cullRange.top(); + const right = cullRange.right(); + const bottom = cullRange.bottom(); + const left = cullRange.left(); + + const border = 1; + const minY = top - border; + const maxY = bottom + border; + const minX = left - border; + const maxX = right + border - 1; + + const chunkStartX = Math_floor(minX / globalConfig.mapChunkSize); + const chunkStartY = Math_floor(minY / globalConfig.mapChunkSize); + + const chunkEndX = Math_ceil(maxX / globalConfig.mapChunkSize); + const chunkEndY = Math_ceil(maxY / globalConfig.mapChunkSize); + + // Render y from top down for proper blending + for (let chunkX = chunkStartX; chunkX <= chunkEndX; ++chunkX) { + for (let chunkY = chunkStartY; chunkY <= chunkEndY; ++chunkY) { + const chunk = this.root.map.getChunk(chunkX, chunkY, true); + chunk.drawBackgroundLayer(parameters); + } + } + + if (G_IS_DEV && globalConfig.debug.showChunkBorders) { + const cullRange = parameters.visibleRect.toTileCullRectangle(); + const top = cullRange.top(); + const right = cullRange.right(); + const bottom = cullRange.bottom(); + const left = cullRange.left(); + + const border = 1; + const minY = top - border; + const maxY = bottom + border; + const minX = left - border; + const maxX = right + border - 1; + + const chunkStartX = Math_floor(minX / globalConfig.mapChunkSize); + const chunkStartY = Math_floor(minY / globalConfig.mapChunkSize); + + const chunkEndX = Math_ceil(maxX / globalConfig.mapChunkSize); + const chunkEndY = Math_ceil(maxY / globalConfig.mapChunkSize); + + // Render y from top down for proper blending + for (let chunkX = chunkStartX; chunkX <= chunkEndX; ++chunkX) { + for (let chunkY = chunkStartY; chunkY <= chunkEndY; ++chunkY) { + parameters.context.fillStyle = "#ffaaaa"; + parameters.context.fillRect( + chunkX * globalConfig.mapChunkSize * globalConfig.tileSize, + chunkY * globalConfig.mapChunkSize * globalConfig.tileSize, + globalConfig.mapChunkSize * globalConfig.tileSize, + 3 + ); + parameters.context.fillRect( + chunkX * globalConfig.mapChunkSize * globalConfig.tileSize, + chunkY * globalConfig.mapChunkSize * globalConfig.tileSize, + 3, + globalConfig.mapChunkSize * globalConfig.tileSize + ); + } + } + } + } +} diff --git a/src/js/game/meta_building.js b/src/js/game/meta_building.js new file mode 100644 index 00000000..a5fc8c25 --- /dev/null +++ b/src/js/game/meta_building.js @@ -0,0 +1,155 @@ +import { Vector, enumDirection, enumAngleToDirection } from "../core/vector"; +import { Loader } from "../core/loader"; +import { GameRoot } from "./root"; +import { AtlasSprite } from "../core/sprites"; +import { Entity } from "./entity"; +import { StaticMapEntityComponent } from "./components/static_map_entity"; + +export class MetaBuilding { + /** + * + * @param {string} id Building id + */ + constructor(id) { + this.id = id; + } + + /** + * Returns the id of this building + */ + getId() { + return this.id; + } + + /** + * Should return the dimensions of the building + */ + getDimensions() { + return new Vector(1, 1); + } + + /** + * Should return the name of this building + */ + getName() { + return this.id; + } + + /** + * Should return the description of this building + */ + getDescription() { + return "No Description"; + } + + /** + * Whether to stay in placement mode after having placed a building + */ + getStayInPlacementMode() { + return false; + } + + /** + * Whether to flip the orientation after a building has been placed - useful + * for tunnels. + */ + getFlipOrientationAfterPlacement() { + return false; + } + + /** + * Returns a preview sprite + * @returns {AtlasSprite} + */ + getPreviewSprite(rotationVariant = 0) { + return Loader.getSprite("sprites/buildings/" + this.id + ".png"); + } + + /** + * Returns whether this building is rotateable + * @returns {boolean} + */ + isRotateable() { + return true; + } + + /** + * Returns whether this building is unlocked for the given game + * @param {GameRoot} root + */ + getIsUnlocked(root) { + return true; + } + + /** + * Should return a silhouette color for the map overview or null if not set + */ + getSilhouetteColor() { + return null; + } + + /** + * Creates the entity at the given location + * @param {GameRoot} root + * @param {Vector} origin Origin tile + * @param {number=} rotation Rotation + * @param {number=} rotationVariant Rotation variant + */ + createAndPlaceEntity(root, origin, rotation = 0, rotationVariant = 0) { + const entity = new Entity(root); + entity.addComponent( + new StaticMapEntityComponent({ + spriteKey: "sprites/buildings/" + this.id + ".png", + origin: new Vector(origin.x, origin.y), + rotationDegrees: rotation, + tileSize: this.getDimensions().copy(), + silhouetteColor: this.getSilhouetteColor(), + }) + ); + + this.setupEntityComponents(entity, root); + this.updateRotationVariant(entity, rotationVariant); + + root.entityMgr.registerEntity(entity); + root.map.placeStaticEntity(entity); + return entity; + } + + /** + * Should compute the optimal rotation variant on the given tile + * @param {GameRoot} root + * @param {Vector} tile + * @param {number} rotation + * @return {{ rotation: number, rotationVariant: number, connectedEntities?: Array }} + */ + computeOptimalDirectionAndRotationVariantAtTile(root, tile, rotation) { + if (!this.isRotateable()) { + return { + rotation: 0, + rotationVariant: 0, + }; + } + return { + rotation, + rotationVariant: 0, + }; + } + + /** + * Should update the entity to match the given rotation variant + * @param {Entity} entity + * @param {number} rotationVariant + */ + updateRotationVariant(entity, rotationVariant) {} + + // PRIVATE INTERFACE + + /** + * Should setup the entity components + * @param {Entity} entity + * @param {GameRoot} root + */ + setupEntityComponents(entity, root) { + abstract; + } +} diff --git a/src/js/game/meta_building_registry.js b/src/js/game/meta_building_registry.js new file mode 100644 index 00000000..450a9743 --- /dev/null +++ b/src/js/game/meta_building_registry.js @@ -0,0 +1,26 @@ +import { gMetaBuildingRegistry } from "../core/global_registries"; +import { MetaBeltBaseBuilding } from "./buildings/belt_base"; +import { MetaCutterBuilding } from "./buildings/cutter"; +import { MetaMinerBuilding } from "./buildings/miner"; +import { MetaMixerBuilding } from "./buildings/mixer"; +import { MetaPainterBuilding } from "./buildings/painter"; +import { MetaRotaterBuilding } from "./buildings/rotater"; +import { MetaSplitterBuilding } from "./buildings/splitter"; +import { MetaStackerBuilding } from "./buildings/stacker"; +import { MetaTrashBuilding } from "./buildings/trash"; +import { MetaUndergroundBeltBuilding } from "./buildings/underground_belt"; +import { MetaHubBuilding } from "./buildings/hub"; + +export function initMetaBuildingRegistry() { + gMetaBuildingRegistry.register(MetaSplitterBuilding); + gMetaBuildingRegistry.register(MetaMinerBuilding); + gMetaBuildingRegistry.register(MetaCutterBuilding); + gMetaBuildingRegistry.register(MetaRotaterBuilding); + gMetaBuildingRegistry.register(MetaStackerBuilding); + gMetaBuildingRegistry.register(MetaMixerBuilding); + gMetaBuildingRegistry.register(MetaPainterBuilding); + gMetaBuildingRegistry.register(MetaTrashBuilding); + gMetaBuildingRegistry.register(MetaBeltBaseBuilding); + gMetaBuildingRegistry.register(MetaUndergroundBeltBuilding); + gMetaBuildingRegistry.register(MetaHubBuilding); +} diff --git a/src/js/game/root.js b/src/js/game/root.js new file mode 100644 index 00000000..7a6910f3 --- /dev/null +++ b/src/js/game/root.js @@ -0,0 +1,214 @@ +/* eslint-disable no-unused-vars */ + +import { Signal } from "../core/signal"; +import { RandomNumberGenerator } from "../core/rng"; +// import { gFactionRegistry } from "./global_registries"; +import { createLogger } from "../core/logging"; + +// Type hints +/* typehints:start */ +import { GameTime } from "./time/game_time"; +import { EntityManager } from "./entity_manager"; +import { GameSystemManager } from "./game_system_manager"; +import { GameHUD } from "./hud/hud"; +// import { GameLogic } from "./game_logic"; +import { MapView } from "./map_view"; +import { Camera } from "./camera"; +// import { ParticleManager } from "../particles/particle_manager"; +import { InGameState } from "../states/ingame"; +// import { CanvasClickInterceptor } from "/canvas_click_interceptor"; +import { AutomaticSave } from "./automatic_save"; +import { Application } from "../application"; +import { SoundProxy } from "./sound_proxy"; +import { Savegame } from "../savegame/savegame"; +import { GameLogic } from "./logic"; +import { ShapeDefinitionManager } from "./shape_definition_manager"; +import { CanvasClickInterceptor } from "./canvas_click_interceptor"; +import { PerlinNoise } from "../core/perlin_noise"; +import { HubGoals } from "./hub_goals"; +import { BufferMaintainer } from "../core/buffer_maintainer"; +/* typehints:end */ + +const logger = createLogger("game/root"); + +/** + * The game root is basically the whole game state at a given point, + * combining all important classes. We don't have globals, but this + * class is passed to almost all game classes. + */ +export class GameRoot { + /** + * Constructs a new game root + * @param {Application} app + */ + constructor(app) { + this.app = app; + + /** @type {Savegame} */ + this.savegame = null; + + /** @type {InGameState} */ + this.gameState = null; + + // Store game dimensions + this.gameWidth = 500; + this.gameHeight = 500; + + // Stores whether the current session is a fresh game (true), or was continued (false) + /** @type {boolean} */ + this.gameIsFresh = true; + + // Stores whether the logic is already initialized + /** @type {boolean} */ + this.logicInitialized = false; + + // Stores whether the game is already initialized, that is, all systems etc have been created + /** @type {boolean} */ + this.gameInitialized = false; + + //////// Other properties /////// + + /** @type {Camera} */ + this.camera = null; + + /** @type {HTMLCanvasElement} */ + this.canvas = null; + + /** @type {CanvasRenderingContext2D} */ + this.context = null; + + /** @type {MapView} */ + this.map = null; + + /** @type {GameLogic} */ + this.logic = null; + + /** @type {EntityManager} */ + this.entityMgr = null; + + /** @type {GameHUD} */ + this.hud = null; + + /** @type {GameSystemManager} */ + this.systemMgr = null; + + /** @type {GameTime} */ + this.time = null; + + /** @type {PerlinNoise} */ + this.mapNoiseGenerator = null; + + /** @type {HubGoals} */ + this.hubGoals = null; + + /** @type {BufferMaintainer} */ + this.buffers = null; + + // /** @type {ParticleManager} */ + // this.particleMgr = null; + + // /** @type {ParticleManager} */ + // this.uiParticleMgr = null; + + /** @type {CanvasClickInterceptor} */ + this.canvasClickInterceptor = null; + + /** @type {AutomaticSave} */ + this.automaticSave = null; + + /** @type {SoundProxy} */ + this.soundProxy = null; + + // /** @type {MinimapRenderer} */ + // this.minimapRenderer = null; + + /** @type {ShapeDefinitionManager} */ + this.shapeDefinitionMgr = null; + + this.signals = { + // Entities + entityAdded: new Signal(/* entity */), + entityGotNewComponent: new Signal(/* entity */), + entityQueuedForDestroy: new Signal(/* entity */), + entityDestroyed: new Signal(/* entity */), + + // Global + resized: new Signal(/* w, h */), // Game got resized, + readyToRender: new Signal(), + aboutToDestruct: new Signal(), + + // Game Hooks + gameSaved: new Signal(), // Game got saved + gameRestored: new Signal(), // Game got restored + gameOver: new Signal(), // Game over + + storyGoalCompleted: new Signal(/* level, reward */), + upgradePurchased: new Signal(), + + // Called right after game is initialized + postLoadHook: new Signal(), + + // Can be used to trigger an async task + performAsync: new Signal(), + }; + + // RNG's + /** @type {Object.>} */ + this.rngs = {}; + + // Work queue + this.queue = { + requireRedraw: false, + }; + } + + /** + * Destructs the game root + */ + destruct() { + logger.log("destructing root"); + this.signals.aboutToDestruct.dispatch(); + + this.reset(); + } + + /** + * Prepares the root for game over, this sets the right flags and + * detaches all signals so no bad stuff happens + */ + prepareGameOver() { + this.gameInitialized = false; + this.logicInitialized = false; + // for (const key in this.signals) { + // if (key !== "aboutToDestruct") { + // this.signals[key].removeAll(); + // } + // } + } + + /** + * Resets the whole root and removes all properties + */ + reset() { + if (this.signals) { + // Destruct all signals + for (let i = 0; i < this.signals.length; ++i) { + this.signals[i].removeAll(); + } + } + + if (this.hud) { + this.hud.cleanup(); + } + if (this.camera) { + this.camera.cleanup(); + } + + // Finally free all properties + for (let prop in this) { + if (this.hasOwnProperty(prop)) { + delete this[prop]; + } + } + } +} diff --git a/src/js/game/shape_definition.js b/src/js/game/shape_definition.js new file mode 100644 index 00000000..a3f91224 --- /dev/null +++ b/src/js/game/shape_definition.js @@ -0,0 +1,447 @@ +import { makeOffscreenBuffer } from "../core/buffer_utils"; +import { JSON_parse, JSON_stringify, Math_max, Math_PI, Math_radians } from "../core/builtins"; +import { globalConfig } from "../core/config"; +import { smoothenDpi } from "../core/dpi_manager"; +import { DrawParameters } from "../core/draw_parameters"; +import { createLogger } from "../core/logging"; +import { Vector } from "../core/vector"; +import { BasicSerializableObject } from "../savegame/serialization"; +import { enumColors, enumColorsToHexCode, enumColorToShortcode, enumShortcodeToColor } from "./colors"; + +const rusha = require("rusha"); + +const logger = createLogger("shape_definition"); + +/** + * @typedef {{ + * subShape: enumSubShape, + * color: enumColors, + * }} ShapeLayerItem + */ + +/** + * Order is Q1 (tr), Q2(br), Q3(bl), Q4(tl) + * @typedef {[ShapeLayerItem?, ShapeLayerItem?, ShapeLayerItem?, ShapeLayerItem?]} ShapeLayer + */ + +const arrayQuadrantIndexToOffset = [ + new Vector(1, -1), // tr + new Vector(1, 1), // br + new Vector(-1, 1), // bl + new Vector(-1, -1), // tl +]; + +/** @enum {string} */ +export const enumSubShape = { + rect: "rect", + circle: "circle", + star: "star", + windmill: "windmill", +}; + +/** @enum {string} */ +export const enumSubShapeToShortcode = { + [enumSubShape.rect]: "R", + [enumSubShape.circle]: "C", + [enumSubShape.star]: "S", + [enumSubShape.windmill]: "W", +}; + +/** @enum {enumSubShape} */ +export const enumShortcodeToSubShape = {}; +for (const key in enumSubShapeToShortcode) { + enumShortcodeToSubShape[enumSubShapeToShortcode[key]] = key; +} + +/** + * Converts the given parameters to a valid shape definition + * @param {*} layers + * @returns {Array} + */ +export function createSimpleShape(layers) { + layers.forEach(layer => { + layer.forEach(item => { + if (item) { + item.color = item.color || enumColors.uncolored; + } + }); + }); + return layers; +} + +export class ShapeDefinition extends BasicSerializableObject { + static getId() { + return "ShapeDefinition"; + } + + /** + * + * @param {object} param0 + * @param {Array=} param0.layers + */ + constructor({ layers = [] }) { + super(); + + /** + * The layers from bottom to top + * @type {Array} */ + this.layers = layers; + + /** @type {string} */ + this.cachedHash = null; + + // Set on demand + this.bufferGenerator = null; + } + + /** + * Generates the definition from the given short key + */ + static fromShortKey(key) { + const sourceLayers = key.split(":"); + let layers = []; + for (let i = 0; i < sourceLayers.length; ++i) { + const text = sourceLayers[i]; + assert(text.length === 8, "Invalid shape short key: " + key); + + /** @type {ShapeLayer} */ + const quads = [null, null, null, null]; + for (let quad = 0; quad < 4; ++quad) { + const shapeText = text[quad * 2 + 0]; + const subShape = enumShortcodeToSubShape[shapeText]; + const color = enumShortcodeToColor[text[quad * 2 + 1]]; + if (subShape) { + assert(color, "Invalid shape short key:", key); + quads[quad] = { + subShape, + color, + }; + } else if (shapeText !== "-") { + assert(false, "Invalid shape key: " + shapeText); + } + } + layers.push(quads); + } + + return new ShapeDefinition({ layers }); + } + + /** + * Internal method to clone the shape definition + * @returns {Array} + */ + internalCloneLayers() { + return JSON_parse(JSON_stringify(this.layers)); + } + + /** + * Returns if the definition is entirely empty^ + * @returns {boolean} + */ + isEntirelyEmpty() { + return this.layers.length === 0; + } + + /** + * Returns a unique id for this shape + * @returns {string} + */ + getHash() { + if (this.cachedHash) { + return this.cachedHash; + } + + let id = ""; + for (let layerIndex = 0; layerIndex < this.layers.length; ++layerIndex) { + const layer = this.layers[layerIndex]; + + for (let quadrant = 0; quadrant < layer.length; ++quadrant) { + const item = layer[quadrant]; + if (item) { + id += enumSubShapeToShortcode[item.subShape] + enumColorToShortcode[item.color]; + } else { + id += "--"; + } + } + } + this.cachedHash = id; + return id; + } + + /** + * Draws the shape definition + * @param {number} x + * @param {number} y + * @param {DrawParameters} parameters + */ + draw(x, y, parameters, size = 20) { + const dpi = smoothenDpi(globalConfig.shapesSharpness * parameters.zoomLevel); + + if (!this.bufferGenerator) { + this.bufferGenerator = this.internalGenerateShapeBuffer.bind(this); + } + + const key = size + "/" + dpi; + const canvas = parameters.root.buffers.getForKey( + key, + this.cachedHash, + size, + size, + dpi, + this.bufferGenerator + ); + parameters.context.drawImage(canvas, x - size / 2, y - size / 2, size, size); + } + + /** + * Generates this shape as a canvas + * @param {number} size + */ + generateAsCanvas(size = 20) { + const [canvas, context] = makeOffscreenBuffer(size, size, { + smooth: true, + label: "definition-canvas-cache-" + this.getHash(), + reusable: false, + }); + + this.internalGenerateShapeBuffer(canvas, context, size, size, 1); + return canvas; + } + + /** + * + * @param {HTMLCanvasElement} canvas + * @param {CanvasRenderingContext2D} context + * @param {number} w + * @param {number} h + * @param {number} dpi + */ + internalGenerateShapeBuffer(canvas, context, w, h, dpi) { + context.translate((w * dpi) / 2, (h * dpi) / 2); + context.scale((dpi * w) / 23, (dpi * h) / 23); + + context.fillStyle = "#e9ecf7"; + + const quadrantSize = 10; + const quadrantHalfSize = quadrantSize / 2; + + context.fillStyle = "rgba(40, 50, 65, 0.1)"; + context.beginCircle(0, 0, quadrantSize * 1.15); + context.fill(); + + for (let layerIndex = 0; layerIndex < this.layers.length; ++layerIndex) { + const quadrants = this.layers[layerIndex]; + + const layerScale = Math_max(0.1, 0.9 - layerIndex * 0.22); + + for (let quadrantIndex = 0; quadrantIndex < 4; ++quadrantIndex) { + if (!quadrants[quadrantIndex]) { + continue; + } + const { subShape, color } = quadrants[quadrantIndex]; + + const quadrantPos = arrayQuadrantIndexToOffset[quadrantIndex]; + const centerQuadrantX = quadrantPos.x * quadrantHalfSize; + const centerQuadrantY = quadrantPos.y * quadrantHalfSize; + + const rotation = Math_radians(quadrantIndex * 90); + + context.translate(centerQuadrantX, centerQuadrantY); + context.rotate(rotation); + + context.fillStyle = enumColorsToHexCode[color]; + context.strokeStyle = "#555"; + context.lineWidth = 1; + + const insetPadding = 0.0; + + switch (subShape) { + case enumSubShape.rect: { + context.beginPath(); + const dims = quadrantSize * layerScale; + context.rect( + insetPadding + -quadrantHalfSize, + -insetPadding + quadrantHalfSize - dims, + dims, + dims + ); + + break; + } + case enumSubShape.star: { + context.beginPath(); + const dims = quadrantSize * layerScale; + + let originX = insetPadding - quadrantHalfSize; + let originY = -insetPadding + quadrantHalfSize - dims; + + const moveInwards = dims * 0.4; + context.moveTo(originX, originY + moveInwards); + context.lineTo(originX + dims, originY); + context.lineTo(originX + dims - moveInwards, originY + dims); + context.lineTo(originX, originY + dims); + context.closePath(); + break; + } + + case enumSubShape.windmill: { + context.beginPath(); + const dims = quadrantSize * layerScale; + + let originX = insetPadding - quadrantHalfSize; + let originY = -insetPadding + quadrantHalfSize - dims; + const moveInwards = dims * 0.4; + context.moveTo(originX, originY + moveInwards); + context.lineTo(originX + dims, originY); + context.lineTo(originX + dims, originY + dims); + context.lineTo(originX, originY + dims); + context.closePath(); + break; + } + + case enumSubShape.circle: { + context.beginPath(); + context.moveTo(insetPadding + -quadrantHalfSize, -insetPadding + quadrantHalfSize); + context.arc( + insetPadding + -quadrantHalfSize, + -insetPadding + quadrantHalfSize, + quadrantSize * layerScale, + -Math_PI * 0.5, + 0 + ); + context.closePath(); + break; + } + + default: { + assertAlways(false, "Unkown sub shape: " + subShape); + } + } + + context.fill(); + context.stroke(); + + context.rotate(-rotation); + context.translate(-centerQuadrantX, -centerQuadrantY); + } + } + } + + /** + * Returns a definition with only the given quadrants + * @param {Array} includeQuadrants + * @returns {ShapeDefinition} + */ + cloneFilteredByQuadrants(includeQuadrants) { + const newLayers = this.internalCloneLayers(); + for (let layerIndex = 0; layerIndex < newLayers.length; ++layerIndex) { + const quadrants = newLayers[layerIndex]; + let anyContents = false; + for (let quadrantIndex = 0; quadrantIndex < 4; ++quadrantIndex) { + if (includeQuadrants.indexOf(quadrantIndex) < 0) { + quadrants[quadrantIndex] = null; + } else if (quadrants[quadrantIndex]) { + anyContents = true; + } + } + + // Check if the layer is entirely empty + if (!anyContents) { + newLayers.splice(layerIndex, 1); + layerIndex -= 1; + } + } + return new ShapeDefinition({ layers: newLayers }); + } + + /** + * Returns a definition which was rotated clockwise + * @returns {ShapeDefinition} + */ + cloneRotateCW() { + const newLayers = this.internalCloneLayers(); + for (let layerIndex = 0; layerIndex < newLayers.length; ++layerIndex) { + const quadrants = newLayers[layerIndex]; + quadrants.unshift(quadrants[3]); + quadrants.pop(); + } + return new ShapeDefinition({ layers: newLayers }); + } + + /** + * Stacks the given shape definition on top. + * @param {ShapeDefinition} definition + */ + cloneAndStackWith(definition) { + const newLayers = this.internalCloneLayers(); + + if (this.isEntirelyEmpty() || definition.isEntirelyEmpty()) { + assert(false, "Can not stack entirely empty definition"); + } + + // Put layer for layer on top + for (let i = 0; i < definition.layers.length; ++i) { + const layerToAdd = definition.layers[i]; + + // On which layer we can merge this upper layer + let mergeOnLayerIndex = null; + + // Go from top to bottom and check if there is anything intercepting it + for (let k = newLayers.length - 1; k >= 0; --k) { + const lowerLayer = newLayers[k]; + + let canMerge = true; + for (let quadrantIndex = 0; quadrantIndex < 4; ++quadrantIndex) { + const upperItem = layerToAdd[quadrantIndex]; + const lowerItem = lowerLayer[quadrantIndex]; + + if (upperItem && lowerItem) { + // so, we can't merge it because two items conflict + canMerge = false; + break; + } + } + + // If we can merge it, store it - since we go from top to bottom + // we can simply override it + if (canMerge) { + mergeOnLayerIndex = k; + } + } + + if (mergeOnLayerIndex !== null) { + // Simply merge using an OR mask + for (let quadrantIndex = 0; quadrantIndex < 4; ++quadrantIndex) { + newLayers[mergeOnLayerIndex][quadrantIndex] = + newLayers[mergeOnLayerIndex][quadrantIndex] || layerToAdd[quadrantIndex]; + } + } else { + // Add new layer + newLayers.push(layerToAdd); + } + } + + newLayers.splice(4); + + return new ShapeDefinition({ layers: newLayers }); + } + + /** + * Clones the shape and colors everything in the given color + * @param {enumColors} color + */ + cloneAndPaintWith(color) { + const newLayers = this.internalCloneLayers(); + + for (let layerIndex = 0; layerIndex < newLayers.length; ++layerIndex) { + const quadrants = newLayers[layerIndex]; + for (let quadrantIndex = 0; quadrantIndex < 4; ++quadrantIndex) { + const item = quadrants[quadrantIndex]; + if (item) { + item.color = color; + } + } + } + return new ShapeDefinition({ layers: newLayers }); + } +} diff --git a/src/js/game/shape_definition_manager.js b/src/js/game/shape_definition_manager.js new file mode 100644 index 00000000..25f456cd --- /dev/null +++ b/src/js/game/shape_definition_manager.js @@ -0,0 +1,142 @@ +import { BasicSerializableObject } from "../savegame/serialization"; +import { GameRoot } from "./root"; +import { ShapeDefinition, enumSubShape } from "./shape_definition"; +import { createLogger } from "../core/logging"; +import { enumColors } from "./colors"; + +const logger = createLogger("shape_definition_manager"); + +export class ShapeDefinitionManager extends BasicSerializableObject { + static getId() { + return "ShapeDefinitionManager"; + } + + /** + * + * @param {GameRoot} root + */ + constructor(root) { + super(); + this.root = root; + + this.shapeKeyToDefinition = {}; + + // Caches operations in the form of 'operation:def1[:def2]' + /** @type {Object.|ShapeDefinition>} */ + this.operationCache = {}; + } + + /** + * Registers a new shape definition + * @param {ShapeDefinition} definition + */ + registerShapeDefinition(definition) { + const id = definition.getHash(); + assert(!this.shapeKeyToDefinition[id], "Shape Definition " + id + " already exists"); + this.shapeKeyToDefinition[id] = definition; + // logger.log("Registered shape with key", id); + } + + /** + * Generates a definition for splitting a shape definition in two halfs + * @param {ShapeDefinition} definition + * @returns {[ShapeDefinition, ShapeDefinition]} + */ + shapeActionCutHalf(definition) { + const key = "cut:" + definition.getHash(); + if (this.operationCache[key]) { + return /** @type {[ShapeDefinition, ShapeDefinition]} */ (this.operationCache[key]); + } + const rightSide = definition.cloneFilteredByQuadrants([0, 1]); + const leftSide = definition.cloneFilteredByQuadrants([2, 3]); + + return /** @type {[ShapeDefinition, ShapeDefinition]} */ (this.operationCache[key] = [ + this.registerOrReturnHandle(rightSide), + this.registerOrReturnHandle(leftSide), + ]); + } + + /** + * Generates a definition for rotating a shape clockwise + * @param {ShapeDefinition} definition + * @returns {ShapeDefinition} + */ + shapeActionRotateCW(definition) { + const key = "rotate:" + definition.getHash(); + if (this.operationCache[key]) { + return /** @type {ShapeDefinition} */ (this.operationCache[key]); + } + + const rotated = definition.cloneRotateCW(); + + return /** @type {ShapeDefinition} */ (this.operationCache[key] = this.registerOrReturnHandle( + rotated + )); + } + + /** + * Generates a definition for stacking the upper definition onto the lower one + * @param {ShapeDefinition} lowerDefinition + * @param {ShapeDefinition} upperDefinition + * @returns {ShapeDefinition} + */ + shapeActionStack(lowerDefinition, upperDefinition) { + const key = "stack:" + lowerDefinition.getHash() + ":" + upperDefinition.getHash(); + if (this.operationCache[key]) { + return /** @type {ShapeDefinition} */ (this.operationCache[key]); + } + const stacked = lowerDefinition.cloneAndStackWith(upperDefinition); + return /** @type {ShapeDefinition} */ (this.operationCache[key] = this.registerOrReturnHandle( + stacked + )); + } + + /** + * Generates a definition for painting it with the given color + * @param {ShapeDefinition} definition + * @param {string} color + * @returns {ShapeDefinition} + */ + shapeActionPaintWith(definition, color) { + const key = "paint:" + definition.getHash() + ":" + color; + if (this.operationCache[key]) { + return /** @type {ShapeDefinition} */ (this.operationCache[key]); + } + const colorized = definition.cloneAndPaintWith(color); + return /** @type {ShapeDefinition} */ (this.operationCache[key] = this.registerOrReturnHandle( + colorized + )); + } + + /** + * Checks if we already have cached this definition, and if so throws it away and returns the already + * cached variant + * @param {ShapeDefinition} definition + */ + registerOrReturnHandle(definition) { + const id = definition.getHash(); + if (this.shapeKeyToDefinition[id]) { + return this.shapeKeyToDefinition[id]; + } + this.shapeKeyToDefinition[id] = definition; + // logger.log("Registered shape with key (2)", id); + return definition; + } + + /** + * + * @param {[enumSubShape, enumSubShape, enumSubShape, enumSubShape]} subShapes + * @returns {ShapeDefinition} + */ + getDefinitionFromSimpleShapes(subShapes, color = enumColors.uncolored) { + const shapeLayer = /** @type {import("./shape_definition").ShapeLayer} */ (subShapes.map( + subShape => ({ + subShape, + rotation: 0, + color, + }) + )); + + return this.registerOrReturnHandle(new ShapeDefinition({ layers: [shapeLayer] })); + } +} diff --git a/src/js/game/sound_proxy.js b/src/js/game/sound_proxy.js new file mode 100644 index 00000000..120136d4 --- /dev/null +++ b/src/js/game/sound_proxy.js @@ -0,0 +1,83 @@ +/* typehints:start */ +import { GameRoot } from "./root"; +/* typehints:end */ + +import { Vector } from "../core/vector"; +import { SOUNDS } from "../platform/sound"; + +const avgSoundDurationSeconds = 0.25; +const maxOngoingSounds = 10; + +// Proxy to the application sound instance +export class SoundProxy { + /** + * @param {GameRoot} root + */ + constructor(root) { + this.root = root; + + // Store a list of sounds and when we started them + this.playingSounds = []; + } + + /** + * Plays a new ui sound + * @param {string} id Sound ID + */ + playUi(id) { + assert(typeof id === "string", "Not a valid sound id: " + id); + this.root.app.sound.playUiSound(id); + } + + /** + * Plays the ui click sound + */ + playUiClick() { + this.playUi(SOUNDS.uiClick); + } + + /** + * Plays the ui error sound + */ + playUiError() { + this.playUi(SOUNDS.uiError); + } + + /** + * Plays a 3D sound whose volume is scaled based on where it was emitted + * @param {string} id Sound ID + * @param {Vector} pos World space position + */ + play3D(id, pos) { + assert(typeof id === "string", "Not a valid sound id: " + id); + assert(pos instanceof Vector, "Invalid sound position"); + this.internalUpdateOngoingSounds(); + + if (this.playingSounds.length > maxOngoingSounds) { + // Too many ongoing sounds + // console.warn( + // "Not playing", + // id, + // "because there are too many sounds playing" + // ); + return false; + } + + this.root.app.sound.play3DSound(id, pos, this.root); + this.playingSounds.push(this.root.time.realtimeNow()); + return true; + } + + /** + * Updates the list of ongoing sounds + */ + internalUpdateOngoingSounds() { + const now = this.root.time.realtimeNow(); + for (let i = 0; i < this.playingSounds.length; ++i) { + if (now - this.playingSounds[i] > avgSoundDurationSeconds) { + this.playingSounds.splice(i, 1); + i -= 1; + } + } + } +} diff --git a/src/js/game/systems/belt.js b/src/js/game/systems/belt.js new file mode 100644 index 00000000..a2853998 --- /dev/null +++ b/src/js/game/systems/belt.js @@ -0,0 +1,201 @@ +import { Math_radians, Math_min } from "../../core/builtins"; +import { globalConfig } from "../../core/config"; +import { DrawParameters } from "../../core/draw_parameters"; +import { Loader } from "../../core/loader"; +import { AtlasSprite } from "../../core/sprites"; +import { BeltComponent } from "../components/belt"; +import { Entity } from "../entity"; +import { GameSystemWithFilter } from "../game_system_with_filter"; +import { enumDirection, enumDirectionToVector, Vector } from "../../core/vector"; +import { MapChunkView } from "../map_chunk_view"; + +const BELT_ANIM_COUNT = 6; + +export class BeltSystem extends GameSystemWithFilter { + constructor(root) { + super(root, [BeltComponent]); + /** + * @type {Object.>} + */ + this.beltSprites = { + [enumDirection.top]: Loader.getSprite("sprites/belt/forward_0.png"), + [enumDirection.left]: Loader.getSprite("sprites/belt/left_0.png"), + [enumDirection.right]: Loader.getSprite("sprites/belt/right_0.png"), + }; + /** + * @type {Object.>} + */ + this.beltAnimations = { + [enumDirection.top]: [ + Loader.getSprite("sprites/belt/forward_0.png"), + Loader.getSprite("sprites/belt/forward_1.png"), + Loader.getSprite("sprites/belt/forward_2.png"), + Loader.getSprite("sprites/belt/forward_3.png"), + Loader.getSprite("sprites/belt/forward_4.png"), + Loader.getSprite("sprites/belt/forward_5.png"), + ], + [enumDirection.left]: [ + Loader.getSprite("sprites/belt/left_0.png"), + Loader.getSprite("sprites/belt/left_1.png"), + Loader.getSprite("sprites/belt/left_2.png"), + Loader.getSprite("sprites/belt/left_3.png"), + Loader.getSprite("sprites/belt/left_4.png"), + Loader.getSprite("sprites/belt/left_5.png"), + ], + [enumDirection.right]: [ + Loader.getSprite("sprites/belt/right_0.png"), + Loader.getSprite("sprites/belt/right_1.png"), + Loader.getSprite("sprites/belt/right_2.png"), + Loader.getSprite("sprites/belt/right_3.png"), + Loader.getSprite("sprites/belt/right_4.png"), + Loader.getSprite("sprites/belt/right_5.png"), + ], + }; + } + + draw(parameters) { + this.forEachMatchingEntityOnScreen(parameters, this.drawEntityItems.bind(this)); + } + + update() { + const beltSpeed = this.root.hubGoals.getBeltBaseSpeed() * globalConfig.physicsDeltaSeconds; + + for (let i = 0; i < this.allEntities.length; ++i) { + const entity = this.allEntities[i]; + const beltComp = entity.components.Belt; + const staticComp = entity.components.StaticMapEntity; + const items = beltComp.sortedItems; + if (items.length === 0) { + // Fast out for performance + continue; + } + + const ejectorComp = entity.components.ItemEjector; + let maxProgress = 1; + + // When ejecting, we can not go further than the item spacing since it + // will be on the corner + if (ejectorComp.isAnySlotEjecting()) { + maxProgress = 1 - globalConfig.itemSpacingOnBelts; + } else { + // Find follow up belt to make sure we don't clash items + const followUpDirection = staticComp.localDirectionToWorld(beltComp.direction); + const followUpVector = enumDirectionToVector[followUpDirection]; + + const followUpTile = staticComp.origin.add(followUpVector); + const followUpEntity = this.root.map.getTileContent(followUpTile); + + if (followUpEntity) { + const followUpBeltComp = followUpEntity.components.Belt; + if (followUpBeltComp) { + const spacingOnBelt = followUpBeltComp.getDistanceToFirstItemCenter(); + maxProgress = Math_min(1, 1 - globalConfig.itemSpacingOnBelts + spacingOnBelt); + } + } + } + + let speedMultiplier = 1; + if (beltComp.direction !== enumDirection.top) { + // Shaped belts are longer, thus being quicker + speedMultiplier = 1.41; + } + + for (let itemIndex = items.length - 1; itemIndex >= 0; --itemIndex) { + const itemAndProgress = items[itemIndex]; + + const newProgress = itemAndProgress[0] + speedMultiplier * beltSpeed; + if (newProgress >= 1.0) { + // Try to give this item to a new belt + const freeSlot = ejectorComp.getFirstFreeSlot(); + + if (freeSlot === null) { + // So, we don't have a free slot - damned! + itemAndProgress[0] = 1.0; + maxProgress = 1 - globalConfig.itemSpacingOnBelts; + } else { + // We got a free slot, remove this item and keep it on the ejector slot + if (!ejectorComp.tryEject(freeSlot, itemAndProgress[1])) { + assert(false, "Ejection failed"); + } + items.splice(itemIndex, 1); + maxProgress = 1; + } + } else { + itemAndProgress[0] = Math_min(newProgress, maxProgress); + maxProgress = itemAndProgress[0] - globalConfig.itemSpacingOnBelts; + } + } + } + } + + /** + * + * @param {DrawParameters} parameters + * @param {MapChunkView} chunk + */ + drawChunk(parameters, chunk) { + if (parameters.zoomLevel < globalConfig.mapChunkOverviewMinZoom) { + return; + 1; + } + + const speedMultiplier = this.root.hubGoals.getBeltBaseSpeed(); + + // SYNC with systems/item_processor.js:drawEntityUnderlays! + // 126 / 42 is the exact animation speed of the png animation + const animationIndex = Math.floor( + (this.root.time.now() * speedMultiplier * BELT_ANIM_COUNT * 126) / 42 + ); + const contents = chunk.contents; + for (let y = 0; y < globalConfig.mapChunkSize; ++y) { + for (let x = 0; x < globalConfig.mapChunkSize; ++x) { + const entity = contents[x][y]; + + if (entity && entity.components.Belt) { + const direction = entity.components.Belt.direction; + const sprite = this.beltAnimations[direction][animationIndex % BELT_ANIM_COUNT]; + + entity.components.StaticMapEntity.drawSpriteOnFullEntityBounds( + parameters, + sprite, + 0, + false + ); + } + } + } + 1; + } + + /** + * @param {DrawParameters} parameters + * @param {Entity} entity + */ + drawEntityItems(parameters, entity) { + const beltComp = entity.components.Belt; + const staticComp = entity.components.StaticMapEntity; + + const items = beltComp.sortedItems; + + if (items.length === 0) { + // Fast out for performance + return; + } + + for (let i = 0; i < items.length; ++i) { + const itemAndProgress = items[i]; + + // Nice would be const [pos, item] = itemAndPos; but that gets polyfilled and is super slow then + const progress = itemAndProgress[0]; + const item = itemAndProgress[1]; + + const position = staticComp.applyRotationToVector(beltComp.transformBeltToLocalSpace(progress)); + + item.draw( + (staticComp.origin.x + position.x + 0.5) * globalConfig.tileSize, + (staticComp.origin.y + position.y + 0.5) * globalConfig.tileSize, + parameters + ); + } + } +} diff --git a/src/js/game/systems/hub.js b/src/js/game/systems/hub.js new file mode 100644 index 00000000..9a768c81 --- /dev/null +++ b/src/js/game/systems/hub.js @@ -0,0 +1,83 @@ +import { GameSystemWithFilter } from "../game_system_with_filter"; +import { HubComponent } from "../components/hub"; +import { DrawParameters } from "../../core/draw_parameters"; +import { Entity } from "../entity"; +import { formatBigNumber } from "../../core/utils"; + +export class HubSystem extends GameSystemWithFilter { + constructor(root) { + super(root, [HubComponent]); + } + + draw(parameters) { + this.forEachMatchingEntityOnScreen(parameters, this.drawEntity.bind(this)); + } + + update() { + for (let i = 0; i < this.allEntities.length; ++i) { + const entity = this.allEntities[i]; + + const hubComponent = entity.components.Hub; + + const queue = hubComponent.definitionsToAnalyze; + for (let k = 0; k < queue.length; ++k) { + const definition = queue[k]; + this.root.hubGoals.handleDefinitionDelivered(definition); + } + + hubComponent.definitionsToAnalyze = []; + } + } + + /** + * @param {DrawParameters} parameters + * @param {Entity} entity + */ + drawEntity(parameters, entity) { + const context = parameters.context; + const staticComp = entity.components.StaticMapEntity; + + const pos = staticComp.getTileSpaceBounds().getCenter().toWorldSpace(); + + const definition = this.root.hubGoals.currentGoal.definition; + + definition.draw(pos.x - 25, pos.y - 10, parameters, 40); + + const goals = this.root.hubGoals.currentGoal; + + const textOffsetX = 2; + const textOffsetY = -6; + + // Deliver count + context.font = "bold 25px GameFont"; + context.fillStyle = "#64666e"; + context.textAlign = "left"; + context.fillText( + "" + formatBigNumber(this.root.hubGoals.getCurrentGoalDelivered()), + pos.x + textOffsetX, + pos.y + textOffsetY + ); + + // Required + context.font = "13px GameFont"; + context.fillStyle = "#a4a6b0"; + context.fillText( + "/ " + formatBigNumber(goals.required), + pos.x + textOffsetX, + pos.y + textOffsetY + 13 + ); + + // Reward + context.font = "bold 11px GameFont"; + context.fillStyle = "#fd0752"; + context.textAlign = "center"; + context.fillText(goals.reward.toUpperCase(), pos.x, pos.y + 46); + + // Level + context.font = "bold 11px GameFont"; + context.fillStyle = "#fff"; + context.fillText("" + this.root.hubGoals.level, pos.x - 42, pos.y - 36); + + context.textAlign = "left"; + } +} diff --git a/src/js/game/systems/item_ejector.js b/src/js/game/systems/item_ejector.js new file mode 100644 index 00000000..ee448dd9 --- /dev/null +++ b/src/js/game/systems/item_ejector.js @@ -0,0 +1,173 @@ +import { globalConfig } from "../../core/config"; +import { DrawParameters } from "../../core/draw_parameters"; +import { enumDirectionToVector, Vector } from "../../core/vector"; +import { BaseItem } from "../base_item"; +import { ItemEjectorComponent } from "../components/item_ejector"; +import { Entity } from "../entity"; +import { GameSystemWithFilter } from "../game_system_with_filter"; +import { Math_min } from "../../core/builtins"; + +export class ItemEjectorSystem extends GameSystemWithFilter { + constructor(root) { + super(root, [ItemEjectorComponent]); + } + + update() { + const effectiveBeltSpeed = this.root.hubGoals.getBeltBaseSpeed(); + const progressGrowth = (effectiveBeltSpeed / 0.5) * globalConfig.physicsDeltaSeconds; + + // Try to find acceptors for every ejector + for (let i = 0; i < this.allEntities.length; ++i) { + const entity = this.allEntities[i]; + const ejectorComp = entity.components.ItemEjector; + const staticComp = entity.components.StaticMapEntity; + + // For every ejector slot, try to find an acceptor + for (let ejectorSlotIndex = 0; ejectorSlotIndex < ejectorComp.slots.length; ++ejectorSlotIndex) { + const ejectorSlot = ejectorComp.slots[ejectorSlotIndex]; + const ejectingItem = ejectorSlot.item; + if (!ejectingItem) { + // No item ejected + continue; + } + + ejectorSlot.progress = Math_min(1, ejectorSlot.progress + progressGrowth); + if (ejectorSlot.progress < 1.0) { + // Still ejecting + continue; + } + + // Figure out where and into which direction we eject items + const ejectSlotWsTile = staticComp.localTileToWorld(ejectorSlot.pos); + const ejectSlotWsDirection = staticComp.localDirectionToWorld(ejectorSlot.direction); + const ejectSlotWsDirectionVector = enumDirectionToVector[ejectSlotWsDirection]; + const ejectSlotTargetWsTile = ejectSlotWsTile.add(ejectSlotWsDirectionVector); + + // Try to find the given acceptor component to take the item + const targetEntity = this.root.map.getTileContent(ejectSlotTargetWsTile); + if (!targetEntity) { + // No consumer for item + continue; + } + + const targetAcceptorComp = targetEntity.components.ItemAcceptor; + const targetStaticComp = targetEntity.components.StaticMapEntity; + if (!targetAcceptorComp) { + // Entity doesn't accept items + continue; + } + + const matchingSlot = targetAcceptorComp.findMatchingSlot( + targetStaticComp.worldToLocalTile(ejectSlotTargetWsTile), + targetStaticComp.worldDirectionToLocal(ejectSlotWsDirection) + ); + + if (!matchingSlot) { + // No matching slot found + continue; + } + + if (!targetAcceptorComp.canAcceptItem(matchingSlot.index, ejectingItem)) { + // Can not accept item + continue; + } + + if ( + this.tryPassOverItem( + ejectingItem, + targetEntity, + matchingSlot.index, + matchingSlot.acceptedDirection + ) + ) { + ejectorSlot.item = null; + continue; + } + } + } + } + + /** + * + * @param {BaseItem} item + * @param {Entity} receiver + * @param {number} slotIndex + * @param {string} localDirection + */ + tryPassOverItem(item, receiver, slotIndex, localDirection) { + // Try figuring out how what to do with the item + // TODO: Kinda hacky. How to solve this properly? Don't want to go through inheritance hell. + // Also its just a few cases (hope it stays like this .. :x). + + const beltComp = receiver.components.Belt; + if (beltComp) { + // Ayy, its a belt! + if (beltComp.canAcceptNewItem(localDirection)) { + beltComp.takeNewItem(item, localDirection); + return true; + } + } + + const itemProcessorComp = receiver.components.ItemProcessor; + if (itemProcessorComp) { + // Its an item processor .. + if (itemProcessorComp.tryTakeItem(item, slotIndex, localDirection)) { + return true; + } + } + + const undergroundBeltCmop = receiver.components.UndergroundBelt; + if (undergroundBeltCmop) { + // Its an underground belt. yay. + if ( + undergroundBeltCmop.tryAcceptExternalItem( + item, + this.root.hubGoals.getUndergroundBeltBaseSpeed() + ) + ) { + return true; + } + } + + return false; + } + + draw(parameters) { + this.forEachMatchingEntityOnScreen(parameters, this.drawSingleEntity.bind(this)); + } + + /** + * @param {DrawParameters} parameters + * @param {Entity} entity + */ + drawSingleEntity(parameters, entity) { + const ejectorComp = entity.components.ItemEjector; + const staticComp = entity.components.StaticMapEntity; + + for (let i = 0; i < ejectorComp.slots.length; ++i) { + const slot = ejectorComp.slots[i]; + const ejectedItem = slot.item; + if (!ejectedItem) { + // No item + continue; + } + + const realPosition = slot.pos.rotateFastMultipleOf90(staticComp.rotationDegrees); + const realDirection = Vector.transformDirectionFromMultipleOf90( + slot.direction, + staticComp.rotationDegrees + ); + const realDirectionVector = enumDirectionToVector[realDirection]; + + const tileX = + staticComp.origin.x + realPosition.x + 0.5 + realDirectionVector.x * 0.5 * slot.progress; + const tileY = + staticComp.origin.y + realPosition.y + 0.5 + realDirectionVector.y * 0.5 * slot.progress; + + const worldX = tileX * globalConfig.tileSize; + const worldY = tileY * globalConfig.tileSize; + + ejectedItem.draw(worldX, worldY, parameters); + } + } +} diff --git a/src/js/game/systems/item_processor.js b/src/js/game/systems/item_processor.js new file mode 100644 index 00000000..63e921a8 --- /dev/null +++ b/src/js/game/systems/item_processor.js @@ -0,0 +1,341 @@ +import { globalConfig } from "../../core/config"; +import { DrawParameters } from "../../core/draw_parameters"; +import { Loader } from "../../core/loader"; +import { Entity } from "../entity"; +import { GameSystemWithFilter } from "../game_system_with_filter"; +import { ItemProcessorComponent, enumItemProcessorTypes } from "../components/item_processor"; +import { Math_max, Math_radians } from "../../core/builtins"; +import { BaseItem } from "../base_item"; +import { ShapeItem } from "../items/shape_item"; +import { enumDirectionToVector, enumDirection, enumDirectionToAngle } from "../../core/vector"; +import { ColorItem } from "../items/color_item"; +import { enumColorMixingResults } from "../colors"; +import { drawRotatedSprite } from "../../core/draw_utils"; + +export class ItemProcessorSystem extends GameSystemWithFilter { + constructor(root) { + super(root, [ItemProcessorComponent]); + + this.sprites = {}; + for (const key in enumItemProcessorTypes) { + this.sprites[key] = Loader.getSprite("sprites/buildings/" + key + ".png"); + } + + this.underlayBeltSprites = [ + Loader.getSprite("sprites/belt/forward_0.png"), + Loader.getSprite("sprites/belt/forward_1.png"), + Loader.getSprite("sprites/belt/forward_2.png"), + Loader.getSprite("sprites/belt/forward_3.png"), + Loader.getSprite("sprites/belt/forward_4.png"), + Loader.getSprite("sprites/belt/forward_5.png"), + ]; + } + + draw(parameters) { + this.forEachMatchingEntityOnScreen(parameters, this.drawEntity.bind(this)); + } + + drawUnderlays(parameters) { + this.forEachMatchingEntityOnScreen(parameters, this.drawEntityUnderlays.bind(this)); + } + + update() { + for (let i = 0; i < this.allEntities.length; ++i) { + const entity = this.allEntities[i]; + + const processorComp = entity.components.ItemProcessor; + const ejectorComp = entity.components.ItemEjector; + + // First of all, process the current recipe + processorComp.secondsUntilEject = Math_max( + 0, + processorComp.secondsUntilEject - globalConfig.physicsDeltaSeconds + ); + + // Also, process item consumption animations to avoid items popping from the belts + for (let animIndex = 0; animIndex < processorComp.itemConsumptionAnimations.length; ++animIndex) { + const anim = processorComp.itemConsumptionAnimations[animIndex]; + anim.animProgress += + globalConfig.physicsDeltaSeconds * this.root.hubGoals.getBeltBaseSpeed() * 2; + if (anim.animProgress > 1) { + processorComp.itemConsumptionAnimations.splice(animIndex, 1); + animIndex -= 1; + } + } + + // Check if we have any finished items we can eject + if ( + processorComp.secondsUntilEject === 0 && // it was processed in time + processorComp.itemsToEject.length > 0 // we have some items left to eject + ) { + for (let itemIndex = 0; itemIndex < processorComp.itemsToEject.length; ++itemIndex) { + const { item, requiredSlot, preferredSlot } = processorComp.itemsToEject[itemIndex]; + + let slot = null; + if (requiredSlot !== null && requiredSlot !== undefined) { + // We have a slot override, check if that is free + if (ejectorComp.canEjectOnSlot(requiredSlot)) { + slot = requiredSlot; + } + } else if (preferredSlot !== null && preferredSlot !== undefined) { + // We have a slot preference, try using it but otherwise use a free slot + if (ejectorComp.canEjectOnSlot(preferredSlot)) { + slot = preferredSlot; + } else { + slot = ejectorComp.getFirstFreeSlot(); + } + } else { + // We can eject on any slot + slot = ejectorComp.getFirstFreeSlot(); + } + + if (slot !== null) { + // Alright, we can actually eject + if (!ejectorComp.tryEject(slot, item)) { + assert(false, "Failed to eject"); + } else { + processorComp.itemsToEject.splice(itemIndex, 1); + itemIndex -= 1; + } + } + } + } + + // Check if we have an empty queue and can start a new charge + if (processorComp.itemsToEject.length === 0) { + if (processorComp.inputSlots.length === processorComp.inputsPerCharge) { + this.startNewCharge(entity); + } + } + } + } + + /** + * Starts a new charge for the entity + * @param {Entity} entity + */ + startNewCharge(entity) { + const processorComp = entity.components.ItemProcessor; + + // First, take items + const items = processorComp.inputSlots; + processorComp.inputSlots = []; + + const baseSpeed = this.root.hubGoals.getProcessorBaseSpeed(processorComp.type); + processorComp.secondsUntilEject = 1 / baseSpeed; + + /** @type {Array<{item: BaseItem, requiredSlot?: number, preferredSlot?: number}>} */ + const outItems = []; + + // DO SOME MAGIC + + switch (processorComp.type) { + // SPLITTER + case enumItemProcessorTypes.splitter: { + let nextSlot = processorComp.nextOutputSlot++ % 2; + for (let i = 0; i < items.length; ++i) { + outItems.push({ + item: items[i].item, + preferredSlot: (nextSlot + i) % 2, + }); + } + break; + } + + // CUTTER + case enumItemProcessorTypes.cutter: { + const inputItem = /** @type {ShapeItem} */ (items[0].item); + assert(inputItem instanceof ShapeItem, "Input for cut is not a shape"); + const inputDefinition = inputItem.definition; + + const [cutDefinition1, cutDefinition2] = this.root.shapeDefinitionMgr.shapeActionCutHalf( + inputDefinition + ); + + if (!cutDefinition1.isEntirelyEmpty()) { + outItems.push({ + item: new ShapeItem(cutDefinition1), + requiredSlot: 0, + }); + } + + if (!cutDefinition2.isEntirelyEmpty()) { + outItems.push({ + item: new ShapeItem(cutDefinition2), + requiredSlot: 1, + }); + } + + break; + } + + // ROTATER + case enumItemProcessorTypes.rotater: { + const inputItem = /** @type {ShapeItem} */ (items[0].item); + assert(inputItem instanceof ShapeItem, "Input for cut is not a shape"); + const inputDefinition = inputItem.definition; + + const rotatedDefinition = this.root.shapeDefinitionMgr.shapeActionRotateCW(inputDefinition); + outItems.push({ + item: new ShapeItem(rotatedDefinition), + }); + break; + } + + // STACKER + + case enumItemProcessorTypes.stacker: { + const item1 = items[0]; + const item2 = items[1]; + + const lowerItem = /** @type {ShapeItem} */ (item1.sourceSlot === 0 ? item1.item : item2.item); + const upperItem = /** @type {ShapeItem} */ (item1.sourceSlot === 1 ? item1.item : item2.item); + assert(lowerItem instanceof ShapeItem, "Input for lower stack is not a shape"); + assert(upperItem instanceof ShapeItem, "Input for upper stack is not a shape"); + + const stackedDefinition = this.root.shapeDefinitionMgr.shapeActionStack( + lowerItem.definition, + upperItem.definition + ); + outItems.push({ + item: new ShapeItem(stackedDefinition), + }); + break; + } + + // TRASH + + case enumItemProcessorTypes.trash: { + // Well this one is easy .. simply do nothing with the item + break; + } + + // MIXER + + case enumItemProcessorTypes.mixer: { + // Find both colors and combine them + const item1 = /** @type {ColorItem} */ (items[0].item); + const item2 = /** @type {ColorItem} */ (items[1].item); + assert(item1 instanceof ColorItem, "Input for color mixer is not a color"); + assert(item2 instanceof ColorItem, "Input for color mixer is not a color"); + + const color1 = item1.color; + const color2 = item2.color; + + // Try finding mixer color, and if we can't mix it we simply return the same color + const mixedColor = enumColorMixingResults[color1][color2]; + let resultColor = color1; + if (mixedColor) { + resultColor = mixedColor; + } + outItems.push({ + item: new ColorItem(resultColor), + }); + + break; + } + + // PAINTER + + case enumItemProcessorTypes.painter: { + const item1 = items[0]; + const item2 = items[1]; + + const shapeItem = /** @type {ShapeItem} */ (item1.sourceSlot === 0 ? item1.item : item2.item); + const colorItem = /** @type {ColorItem} */ (item1.sourceSlot === 1 ? item1.item : item2.item); + + const colorizedDefinition = this.root.shapeDefinitionMgr.shapeActionPaintWith( + shapeItem.definition, + colorItem.color + ); + + outItems.push({ + item: new ShapeItem(colorizedDefinition), + }); + + break; + } + + // HUB + + case enumItemProcessorTypes.hub: { + const shapeItem = /** @type {ShapeItem} */ (items[0].item); + + const hubComponent = entity.components.Hub; + assert(hubComponent, "Hub item processor has no hub component"); + + hubComponent.queueShapeDefinition(shapeItem.definition); + break; + } + + default: + assertAlways(false, "Unkown item processor type: " + processorComp.type); + } + + processorComp.itemsToEject = outItems; + } + + /** + * @param {DrawParameters} parameters + * @param {Entity} entity + */ + drawEntity(parameters, entity) { + const staticComp = entity.components.StaticMapEntity; + const processorComp = entity.components.ItemProcessor; + const acceptorComp = entity.components.ItemAcceptor; + + for (let animIndex = 0; animIndex < processorComp.itemConsumptionAnimations.length; ++animIndex) { + const { item, slotIndex, animProgress, direction } = processorComp.itemConsumptionAnimations[ + animIndex + ]; + + const slotData = acceptorComp.slots[slotIndex]; + const slotWorldPos = staticComp.applyRotationToVector(slotData.pos).add(staticComp.origin); + + const fadeOutDirection = enumDirectionToVector[staticComp.localDirectionToWorld(direction)]; + const finalTile = slotWorldPos.subScalars( + fadeOutDirection.x * (animProgress / 2 - 0.5), + fadeOutDirection.y * (animProgress / 2 - 0.5) + ); + item.draw( + (finalTile.x + 0.5) * globalConfig.tileSize, + (finalTile.y + 0.5) * globalConfig.tileSize, + parameters + ); + } + } + /** + * @param {DrawParameters} parameters + * @param {Entity} entity + */ + drawEntityUnderlays(parameters, entity) { + const staticComp = entity.components.StaticMapEntity; + const processorComp = entity.components.ItemProcessor; + + const underlays = processorComp.beltUnderlays; + for (let i = 0; i < underlays.length; ++i) { + const { pos, direction } = underlays[i]; + + const transformedPos = staticComp.localTileToWorld(pos); + const angle = enumDirectionToAngle[staticComp.localDirectionToWorld(direction)]; + + // SYNC with systems/belt.js:drawSingleEntity! + const animationIndex = Math.floor( + (this.root.time.now() * + this.root.hubGoals.getBeltBaseSpeed() * + this.underlayBeltSprites.length * + 126) / + 42 + ); + + drawRotatedSprite({ + parameters, + sprite: this.underlayBeltSprites[animationIndex % this.underlayBeltSprites.length], + x: (transformedPos.x + 0.5) * globalConfig.tileSize, + y: (transformedPos.y + 0.5) * globalConfig.tileSize, + angle: Math_radians(angle), + size: globalConfig.tileSize, + }); + } + } +} diff --git a/src/js/game/systems/map_resources.js b/src/js/game/systems/map_resources.js new file mode 100644 index 00000000..7edb827c --- /dev/null +++ b/src/js/game/systems/map_resources.js @@ -0,0 +1,56 @@ +import { GameSystem } from "../game_system"; +import { DrawParameters } from "../../core/draw_parameters"; +import { globalConfig } from "../../core/config"; +import { MapChunkView } from "../map_chunk_view"; + +export class MapResourcesSystem extends GameSystem { + /** + * Draws the map resources + * @param {DrawParameters} parameters + * @param {MapChunkView} chunk + */ + drawChunk(parameters, chunk) { + const renderItems = parameters.zoomLevel >= globalConfig.mapChunkOverviewMinZoom; + + parameters.context.globalAlpha = 0.5; + const layer = chunk.lowerLayer; + for (let x = 0; x < globalConfig.mapChunkSize; ++x) { + const row = layer[x]; + for (let y = 0; y < globalConfig.mapChunkSize; ++y) { + const lowerItem = row[y]; + if (lowerItem) { + parameters.context.fillStyle = lowerItem.getBackgroundColorAsResource(); + parameters.context.fillRect( + (chunk.tileX + x) * globalConfig.tileSize, + (chunk.tileY + y) * globalConfig.tileSize, + globalConfig.tileSize, + globalConfig.tileSize + ); + if (renderItems) { + lowerItem.draw( + (chunk.tileX + x + 0.5) * globalConfig.tileSize, + (chunk.tileY + y + 0.5) * globalConfig.tileSize, + parameters + ); + } + } + } + } + parameters.context.globalAlpha = 1; + + if (!renderItems) { + // Render patches instead + const patches = chunk.patches; + for (let i = 0; i < patches.length; ++i) { + const { pos, item, size } = patches[i]; + + item.draw( + (chunk.tileX + pos.x + 0.5) * globalConfig.tileSize, + (chunk.tileY + pos.y + 0.5) * globalConfig.tileSize, + parameters, + 80 + ); + } + } + } +} diff --git a/src/js/game/systems/miner.js b/src/js/game/systems/miner.js new file mode 100644 index 00000000..4c9d5cca --- /dev/null +++ b/src/js/game/systems/miner.js @@ -0,0 +1,87 @@ +import { globalConfig } from "../../core/config"; +import { DrawParameters } from "../../core/draw_parameters"; +import { MinerComponent } from "../components/miner"; +import { GameSystemWithFilter } from "../game_system_with_filter"; +import { MapChunkView } from "../map_chunk_view"; + +export class MinerSystem extends GameSystemWithFilter { + constructor(root) { + super(root, [MinerComponent]); + } + + update() { + const miningSpeed = this.root.hubGoals.getMinerBaseSpeed(); + for (let i = 0; i < this.allEntities.length; ++i) { + const entity = this.allEntities[i]; + + const minerComp = entity.components.Miner; + const staticComp = entity.components.StaticMapEntity; + const ejectComp = entity.components.ItemEjector; + + if (this.root.time.isIngameTimerExpired(minerComp.lastMiningTime, 1 / miningSpeed)) { + if (!ejectComp.canEjectOnSlot(0)) { + // We can't eject further + continue; + } + + // Actually mine + minerComp.lastMiningTime = this.root.time.now(); + + const lowerLayerItem = this.root.map.getLowerLayerContentXY( + staticComp.origin.x, + staticComp.origin.y + ); + if (!lowerLayerItem) { + // Nothing below; + continue; + } + + // Try actually ejecting + if (!ejectComp.tryEject(0, lowerLayerItem)) { + assert(false, "Failed to eject"); + } + } + } + } + + /** + * + * @param {DrawParameters} parameters + * @param {MapChunkView} chunk + */ + drawChunk(parameters, chunk) { + const contents = chunk.contents; + for (let y = 0; y < globalConfig.mapChunkSize; ++y) { + for (let x = 0; x < globalConfig.mapChunkSize; ++x) { + const entity = contents[x][y]; + + if (entity && entity.components.Miner) { + const staticComp = entity.components.StaticMapEntity; + const lowerLayerItem = this.root.map.getLowerLayerContentXY( + staticComp.origin.x, + staticComp.origin.y + ); + + if (lowerLayerItem) { + const padding = 3; + parameters.context.fillStyle = lowerLayerItem.getBackgroundColorAsResource(); + parameters.context.fillRect( + staticComp.origin.x * globalConfig.tileSize + padding, + staticComp.origin.y * globalConfig.tileSize + padding, + globalConfig.tileSize - 2 * padding, + globalConfig.tileSize - 2 * padding + ); + } + + if (lowerLayerItem) { + lowerLayerItem.draw( + (0.5 + staticComp.origin.x) * globalConfig.tileSize, + (0.5 + staticComp.origin.y) * globalConfig.tileSize, + parameters + ); + } + } + } + } + } +} diff --git a/src/js/game/systems/static_map_entity.js b/src/js/game/systems/static_map_entity.js new file mode 100644 index 00000000..5c57b492 --- /dev/null +++ b/src/js/game/systems/static_map_entity.js @@ -0,0 +1,72 @@ +import { GameSystem } from "../game_system"; +import { DrawParameters } from "../../core/draw_parameters"; +import { globalConfig } from "../../core/config"; +import { MapChunkView } from "../map_chunk_view"; +import { Loader } from "../../core/loader"; +import { enumDirection } from "../../core/vector"; + +export class StaticMapEntitySystem extends GameSystem { + constructor(root) { + super(root); + + this.beltOverviewSprites = { + [enumDirection.top]: Loader.getSprite("sprites/map_overview/belt_forward.png"), + [enumDirection.right]: Loader.getSprite("sprites/map_overview/belt_right.png"), + [enumDirection.left]: Loader.getSprite("sprites/map_overview/belt_left.png"), + }; + } + + /** + * Draws the static entities + * @param {DrawParameters} parameters + * @param {MapChunkView} chunk + */ + drawChunk(parameters, chunk) { + if (G_IS_DEV && globalConfig.debug.doNotRenderStatics) { + return; + } + + const drawOutlinesOnly = parameters.zoomLevel < globalConfig.mapChunkOverviewMinZoom; + + const contents = chunk.contents; + for (let y = 0; y < globalConfig.mapChunkSize; ++y) { + for (let x = 0; x < globalConfig.mapChunkSize; ++x) { + const entity = contents[x][y]; + + if (entity) { + const staticComp = entity.components.StaticMapEntity; + if (drawOutlinesOnly) { + const rect = staticComp.getTileSpaceBounds(); + parameters.context.fillStyle = staticComp.silhouetteColor || "#aaa"; + const beltComp = entity.components.Belt; + if (beltComp) { + const sprite = this.beltOverviewSprites[beltComp.direction]; + staticComp.drawSpriteOnFullEntityBounds(parameters, sprite, 0, false); + } else { + parameters.context.fillRect( + rect.x * globalConfig.tileSize, + rect.y * globalConfig.tileSize, + rect.w * globalConfig.tileSize, + rect.h * globalConfig.tileSize + ); + } + } else { + const spriteKey = staticComp.spriteKey; + if (spriteKey) { + // Check if origin is contained to avoid drawing entities multiple times + if ( + staticComp.origin.x >= chunk.tileX && + staticComp.origin.x < chunk.tileX + globalConfig.mapChunkSize && + staticComp.origin.y >= chunk.tileY && + staticComp.origin.y < chunk.tileY + globalConfig.mapChunkSize + ) { + const sprite = Loader.getSprite(spriteKey); + staticComp.drawSpriteOnFullEntityBounds(parameters, sprite, 2, false); + } + } + } + } + } + } + } +} diff --git a/src/js/game/systems/underground_belt.js b/src/js/game/systems/underground_belt.js new file mode 100644 index 00000000..c8baec5b --- /dev/null +++ b/src/js/game/systems/underground_belt.js @@ -0,0 +1,129 @@ +import { GameSystemWithFilter } from "../game_system_with_filter"; +import { UndergroundBeltComponent, enumUndergroundBeltMode } from "../components/underground_belt"; +import { Entity } from "../entity"; +import { Loader } from "../../core/loader"; +import { Math_max } from "../../core/builtins"; +import { globalConfig } from "../../core/config"; +import { enumDirection, enumDirectionToVector, enumDirectionToAngle } from "../../core/vector"; +import { MapChunkView } from "../map_chunk_view"; +import { DrawParameters } from "../../core/draw_parameters"; + +export class UndergroundBeltSystem extends GameSystemWithFilter { + constructor(root) { + super(root, [UndergroundBeltComponent]); + + this.beltSprites = { + [enumUndergroundBeltMode.sender]: Loader.getSprite( + "sprites/buildings/underground_belt_entry.png" + ), + [enumUndergroundBeltMode.receiver]: Loader.getSprite( + "sprites/buildings/underground_belt_exit.png" + ), + }; + } + + update() { + for (let i = 0; i < this.allEntities.length; ++i) { + const entity = this.allEntities[i]; + + const undergroundComp = entity.components.UndergroundBelt; + + // Decrease remaining time of all items in belt + for (let k = 0; k < undergroundComp.pendingItems.length; ++k) { + const item = undergroundComp.pendingItems[k]; + item[1] = Math_max(0, item[1] - globalConfig.physicsDeltaSeconds); + } + + if (undergroundComp.mode === enumUndergroundBeltMode.sender) { + this.handleSender(entity); + } else { + this.handleReceiver(entity); + } + } + } + + /** + * + * @param {Entity} entity + */ + handleSender(entity) { + const staticComp = entity.components.StaticMapEntity; + const undergroundComp = entity.components.UndergroundBelt; + + // Check if we have any item + + if (undergroundComp.pendingItems.length > 0) { + const nextItemAndDuration = undergroundComp.pendingItems[0]; + const remainingTime = nextItemAndDuration[1]; + const nextItem = nextItemAndDuration[0]; + + if (remainingTime === 0) { + // Try to find a receiver + const searchDirection = staticComp.localDirectionToWorld(enumDirection.top); + const searchVector = enumDirectionToVector[searchDirection]; + const targetRotation = enumDirectionToAngle[searchDirection]; + + let currentTile = staticComp.origin; + + for ( + let searchOffset = 0; + searchOffset < globalConfig.undergroundBeltMaxTiles; + ++searchOffset + ) { + currentTile = currentTile.add(searchVector); + + const contents = this.root.map.getTileContent(currentTile); + if (contents) { + const receiverUndergroundComp = contents.components.UndergroundBelt; + if (receiverUndergroundComp) { + const receiverStaticComp = contents.components.StaticMapEntity; + if (receiverStaticComp.rotationDegrees === targetRotation) { + if (receiverUndergroundComp.mode === enumUndergroundBeltMode.receiver) { + // Try to pass over the item to the receiver + if ( + receiverUndergroundComp.tryAcceptTunneledItem( + nextItem, + searchOffset, + this.root.hubGoals.getUndergroundBeltBaseSpeed() + ) + ) { + undergroundComp.pendingItems = []; + } + } + + // When we hit some underground belt, always stop, no matter what + break; + } + } + } + } + } + } + } + + /** + * + * @param {Entity} entity + */ + handleReceiver(entity) { + const undergroundComp = entity.components.UndergroundBelt; + + // Try to eject items, we only check the first one cuz its sorted by remaining time + const items = undergroundComp.pendingItems; + if (items.length > 0) { + const nextItemAndDuration = undergroundComp.pendingItems[0]; + const remainingTime = nextItemAndDuration[1]; + const nextItem = nextItemAndDuration[0]; + + if (remainingTime <= 0) { + const ejectorComp = entity.components.ItemEjector; + const nextSlotIndex = ejectorComp.getFirstFreeSlot(); + if (nextSlotIndex !== null) { + if (ejectorComp.tryEject(nextSlotIndex, nextItem)) { + items.shift(); + } + } + } + } + } +} diff --git a/src/js/game/time/base_game_speed.js b/src/js/game/time/base_game_speed.js new file mode 100644 index 00000000..8898b6cf --- /dev/null +++ b/src/js/game/time/base_game_speed.js @@ -0,0 +1,55 @@ +/* typehints:start */ +import { GameRoot } from "../root"; +/* typehints:end */ + +import { BasicSerializableObject } from "../../savegame/serialization"; + +export class BaseGameSpeed extends BasicSerializableObject { + /** + * @param {GameRoot} root + */ + constructor(root) { + super(); + this.root = root; + this.initializeAfterDeserialize(root); + } + + /** @returns {string} */ + static getId() { + abstract; + return "unknown-speed"; + } + + getId() { + // @ts-ignore + return this.constructor.getId(); + } + + static getSchema() { + return {}; + } + + initializeAfterDeserialize(root) { + this.root = root; + } + + /** + * Returns the time multiplier + */ + getTimeMultiplier() { + return 1; + } + + /** + * Returns how many logic steps there may be queued + */ + getMaxLogicStepsInQueue() { + return 3; + } + + // Internals + /** @returns {BaseGameSpeed} */ + newSpeed(instance) { + return new instance(this.root); + } +} diff --git a/src/js/game/time/fast_forward_game_speed.js b/src/js/game/time/fast_forward_game_speed.js new file mode 100644 index 00000000..f2c23bec --- /dev/null +++ b/src/js/game/time/fast_forward_game_speed.js @@ -0,0 +1,16 @@ +import { BaseGameSpeed } from "./base_game_speed"; +import { globalConfig } from "../../core/config"; + +export class FastForwardGameSpeed extends BaseGameSpeed { + static getId() { + return "fast-forward"; + } + + getTimeMultiplier() { + return globalConfig.fastForwardSpeed; + } + + getMaxLogicStepsInQueue() { + return 3 * globalConfig.fastForwardSpeed; + } +} diff --git a/src/js/game/time/game_time.js b/src/js/game/time/game_time.js new file mode 100644 index 00000000..3fe48453 --- /dev/null +++ b/src/js/game/time/game_time.js @@ -0,0 +1,233 @@ +/* typehints:start */ +import { GameRoot } from "../root"; +/* typehints:end */ + +import { types, BasicSerializableObject } from "../../savegame/serialization"; +import { RegularGameSpeed } from "./regular_game_speed"; +import { BaseGameSpeed } from "./base_game_speed"; +import { PausedGameSpeed } from "./paused_game_speed"; +import { performanceNow } from "../../core/builtins"; +import { FastForwardGameSpeed } from "./fast_forward_game_speed"; +import { gGameSpeedRegistry } from "../../core/global_registries"; +import { globalConfig } from "../../core/config"; +import { checkTimerExpired, quantizeFloat } from "../../core/utils"; +import { createLogger } from "../../core/logging"; + +const logger = createLogger("game_time"); + +export class GameTime extends BasicSerializableObject { + /** + * @param {GameRoot} root + */ + constructor(root) { + super(); + this.root = root; + + // Current ingame time seconds, not incremented while paused + this.timeSeconds = 0; + + // Current "realtime", a timer which always is incremented no matter whether the game is paused or no + this.realtimeSeconds = 0; + + // The adjustment, used when loading savegames so we can continue where we were + this.realtimeAdjust = 0; + + /** @type {BaseGameSpeed} */ + this.speed = new RegularGameSpeed(this.root); + + // Store how much time we have in bucket + this.logicTimeBudget = 0; + + if (G_IS_DEV) { + window.addEventListener("keydown", ev => { + if (ev.key === "p") { + this.requestSpeedToggle(); + } + }); + } + } + + static getId() { + return "GameTime"; + } + + static getSchema() { + return { + timeSeconds: types.float, + speed: types.obj(gGameSpeedRegistry), + realtimeSeconds: types.float, + }; + } + + /** + * Fetches the new "real" time, called from the core once per frame, since performance now() is kinda slow + */ + updateRealtimeNow() { + this.realtimeSeconds = performanceNow() / 1000.0 + this.realtimeAdjust; + } + + /** + * Returns the ingame time in milliseconds + */ + getTimeMs() { + return this.timeSeconds * 1000.0; + } + + /** + * Safe check to check if a timer is expired. quantizes numbers + * @param {number} lastTick Last tick of the timer + * @param {number} tickRateSeconds Interval of the timer in seconds + */ + isIngameTimerExpired(lastTick, tickRateSeconds) { + return checkTimerExpired(this.timeSeconds, lastTick, tickRateSeconds); + } + + /** + * Returns how many seconds we are in the grace period + * @returns {number} + */ + getRemainingGracePeriodSeconds() { + return 0; + } + + /** + * Returns if we are currently in the grace period + * @returns {boolean} + */ + getIsWithinGracePeriod() { + return this.getRemainingGracePeriodSeconds() > 0; + } + + /** + * Internal method to generate new logic time budget + * @param {number} deltaMs + */ + înternalAddDeltaToBudget(deltaMs) { + // Only update if game is supposed to update + if (this.root.hud.shouldPauseGame()) { + this.logicTimeBudget = 0; + } else { + const multiplier = this.getSpeed().getTimeMultiplier(); + this.logicTimeBudget += deltaMs * multiplier; + } + + // Check for too big pile of updates -> reduce it to 1 + const maxLogicSteps = this.speed.getMaxLogicStepsInQueue(); + if (this.logicTimeBudget > globalConfig.physicsDeltaMs * maxLogicSteps) { + this.logicTimeBudget = globalConfig.physicsDeltaMs * maxLogicSteps; + } + } + + /** + * Performs update ticks based on the queued logic budget + * @param {number} deltaMs + * @param {function():boolean} updateMethod + */ + performTicks(deltaMs, updateMethod) { + this.înternalAddDeltaToBudget(deltaMs); + + const speedAtStart = this.root.time.getSpeed(); + + // Update physics & logic + while (this.logicTimeBudget >= globalConfig.physicsDeltaMs) { + this.logicTimeBudget -= globalConfig.physicsDeltaMs; + + if (!updateMethod()) { + // Gameover happened or so, do not update anymore + return; + } + + // Step game time + this.timeSeconds = quantizeFloat(this.timeSeconds + globalConfig.physicsDeltaSeconds); + + // Game time speed changed, need to abort since our logic steps are no longer valid + if (speedAtStart.getId() !== this.speed.getId()) { + logger.warn( + "Skipping update because speed changed from", + speedAtStart.getId(), + "to", + this.speed.getId() + ); + break; + } + + // If we queued async tasks, perform them next frame and do not update anymore + if (this.root.hud.parts.processingOverlay.hasTasks()) { + break; + } + } + } + + /** + * Returns ingame time in seconds + * @returns {number} seconds + */ + now() { + return this.timeSeconds; + } + + /** + * Returns "real" time in seconds + * @returns {number} seconds + */ + realtimeNow() { + return this.realtimeSeconds; + } + + /** + * Returns "real" time in seconds + * @returns {number} seconds + */ + systemNow() { + return (this.realtimeSeconds - this.realtimeAdjust) * 1000.0; + } + + getIsPaused() { + return this.speed.getId() === PausedGameSpeed.getId(); + } + + requestSpeedToggle() { + logger.warn("Request speed toggle"); + switch (this.speed.getId()) { + case PausedGameSpeed.getId(): + this.setSpeed(new RegularGameSpeed(this.root)); + break; + + case RegularGameSpeed.getId(): + this.setSpeed(new PausedGameSpeed(this.root)); + break; + + case FastForwardGameSpeed.getId(): + this.setSpeed(new RegularGameSpeed(this.root)); + break; + } + } + + getSpeed() { + return this.speed; + } + + setSpeed(speed) { + assert(speed instanceof BaseGameSpeed, "Not a valid game speed"); + if (this.speed.getId() === speed.getId()) { + logger.warn("Same speed set than current one:", speed.constructor.getId()); + } + this.speed = speed; + } + + deserialize(data) { + const errorCode = super.deserialize(data); + if (errorCode) { + return errorCode; + } + + // Adjust realtime now difference so they match + this.realtimeAdjust = this.realtimeSeconds - performanceNow() / 1000.0; + this.updateRealtimeNow(); + + // Make sure we have a quantizied time + this.timeSeconds = quantizeFloat(this.timeSeconds); + + this.speed.initializeAfterDeserialize(this.root); + } +} diff --git a/src/js/game/time/paused_game_speed.js b/src/js/game/time/paused_game_speed.js new file mode 100644 index 00000000..6d841b92 --- /dev/null +++ b/src/js/game/time/paused_game_speed.js @@ -0,0 +1,15 @@ +import { BaseGameSpeed } from "./base_game_speed"; + +export class PausedGameSpeed extends BaseGameSpeed { + static getId() { + return "paused"; + } + + getTimeMultiplier() { + return 0; + } + + getMaxLogicStepsInQueue() { + return 0; + } +} diff --git a/src/js/game/time/regular_game_speed.js b/src/js/game/time/regular_game_speed.js new file mode 100644 index 00000000..ffee6998 --- /dev/null +++ b/src/js/game/time/regular_game_speed.js @@ -0,0 +1,11 @@ +import { BaseGameSpeed } from "./base_game_speed"; + +export class RegularGameSpeed extends BaseGameSpeed { + static getId() { + return "regular"; + } + + getTimeMultiplier() { + return 1; + } +} diff --git a/src/js/game/tutorial_goals.js b/src/js/game/tutorial_goals.js new file mode 100644 index 00000000..7532e090 --- /dev/null +++ b/src/js/game/tutorial_goals.js @@ -0,0 +1,163 @@ +import { enumSubShape, ShapeDefinition, createSimpleShape } from "./shape_definition"; +import { enumColors } from "./colors"; + +/** + * @enum {string} + */ +export const enumHubGoalRewards = { + reward_cutter_and_trash: "Cutting Shapes", + reward_rotater: "Rotating", + reward_painter: "Painting", + reward_mixer: "Color Mixing", + reward_stacker: "Combiner", + reward_splitter: "Splitter/Merger", + reward_tunnel: "Tunnel", + + no_reward: "Next level", +}; + +export const tutorialGoals = [ + // Circle + { + shape: "CuCuCuCu", + required: 40, + reward: enumHubGoalRewards.reward_cutter_and_trash, + }, + + // Cutter + { + shape: "CuCu----", + required: 150, + reward: enumHubGoalRewards.no_reward, + }, + + { + shape: "----CuCu", + required: 200, + reward: enumHubGoalRewards.reward_splitter, + }, + + // Rectangle + { + shape: "RuRuRuRu", + required: 80, + reward: enumHubGoalRewards.no_reward, + }, + + { + shape: "RuRu----", + required: 250, + reward: enumHubGoalRewards.reward_rotater, + }, + + // Rotater + { + shape: "--CuCu--", + required: 300, + reward: enumHubGoalRewards.no_reward, + }, + + { + shape: "Ru----Ru", + required: 400, + reward: enumHubGoalRewards.reward_tunnel, + }, + + { + shape: "Cu------", + required: 800, + reward: enumHubGoalRewards.no_reward, + }, + + { + shape: "------Ru", + required: 1000, + reward: enumHubGoalRewards.reward_painter, + }, + + // Painter + { + shape: "CrCrCrCr", + required: 1500, + reward: enumHubGoalRewards.no_reward, + }, + + { + shape: "RbRb----", + required: 2500, + reward: enumHubGoalRewards.reward_mixer, + }, + + // Mixing (purple) + { + shape: "CpCpCpCp", + required: 4000, + reward: enumHubGoalRewards.no_reward, + }, + + // Star shape + cyan + { + shape: "ScScScSc", + required: 500, + reward: enumHubGoalRewards.reward_stacker, + }, + + // Stacker + { + shape: "CcCcRgRg", + required: 3000, + reward: enumHubGoalRewards.no_reward, + }, + + { + shape: "RgRgRgRg:CcCcCcCc", + required: 4000, + reward: enumHubGoalRewards.no_reward, + }, + + { + shape: "CgCgRgRg", + required: 6000, + reward: enumHubGoalRewards.no_reward, + }, + + { + shape: "CwSwCwSw", + required: 6000, + reward: enumHubGoalRewards.no_reward, + }, + + { + shape: "WyWyWyWy", + required: 2000, + reward: enumHubGoalRewards.no_reward, + }, + + { + shape: "WyWgWyWg:CbCpCbCp", + required: 4000, + reward: enumHubGoalRewards.no_reward, + }, + + { + shape: "WyRgWyCg:CbCpCbCp:CwCwCwCw", + required: 9000, + reward: enumHubGoalRewards.no_reward, + }, + + { + shape: "CwRrWbSp:WcWrCpCw", + required: 15000, + reward: enumHubGoalRewards.no_reward, + }, +]; + +if (G_IS_DEV) { + tutorialGoals.forEach(({ shape, required, reward }) => { + try { + ShapeDefinition.fromShortKey(shape); + } catch (ex) { + throw new Error("Invalid tutorial goal: '" + ex + "' for shape" + shape); + } + }); +} diff --git a/src/js/game/upgrades.js b/src/js/game/upgrades.js new file mode 100644 index 00000000..7dd9e8df --- /dev/null +++ b/src/js/game/upgrades.js @@ -0,0 +1,326 @@ +import { createSimpleShape, enumSubShape, ShapeDefinition } from "./shape_definition"; +import { enumColors } from "./colors"; +import { findNiceIntegerValue } from "../core/utils"; +import { globalConfig } from "../core/config"; + +export const TIER_LABELS = [ + "I", + "II", + "III", + "IV", + "V", + "VI", + "VII", + "VIII", + "IX", + "X", + "XI", + "XII", + "XIII", + "XIV", + "XV", + "XVI", + "XVII", + "XVIII", + "XIX", + "XX", +]; + +export const UPGRADES = { + belt: { + label: "Belts, Distributer & Tunnels", + description: improvement => "Speed +" + Math.floor(improvement * 100.0) + "%", + tiers: [ + { + required: [{ shape: "CuCuCuCu", amount: 80 }], + improvement: 1, + }, + { + required: [{ shape: "Ru----Ru", amount: 4000 }], + improvement: 2, + }, + { + required: [{ shape: "CwSwCwSw", amount: 30000 }], + improvement: 4, + }, + { + required: [{ shape: "RgRgSpSp:CwSwCwSw:Cr--Sw--", amount: 80000 }], + improvement: 8, + }, + ], + }, + + miner: { + label: "Extraction", + description: improvement => "Speed +" + Math.floor(improvement * 100.0) + "%", + tiers: [ + { + required: [{ shape: "RuRuRuRu", amount: 200 }], + improvement: 1, + }, + { + required: [{ shape: "Cu------", amount: 4000 }], + improvement: 2, + }, + { + required: [{ shape: "WyWgWyWg:CbCpCbCp", amount: 30000 }], + improvement: 4, + }, + { + required: [{ shape: "WyWgWyWg:CbCpCbCp:Rp----Rp", amount: 90000 }], + improvement: 8, + }, + ], + }, + + processors: { + label: "Shape Processing", + description: improvement => "Speed +" + Math.floor(improvement * 100.0) + "%", + tiers: [ + { + required: [{ shape: "RuRuRuRu", amount: 200 }], + improvement: 1, + }, + { + required: [{ shape: "Cu------", amount: 4000 }], + improvement: 2, + }, + { + required: [{ shape: "WyWgWyWg:CbCpCbCp", amount: 30000 }], + improvement: 4, + }, + { + required: [{ shape: "WyWgWyWg:CbCpCbCp:Rp----Rp", amount: 90000 }], + improvement: 8, + }, + ], + }, + + painting: { + label: "Mixing & Painting", + description: improvement => "Speed +" + Math.floor(improvement * 100.0) + "%", + tiers: [ + { + required: [{ shape: "RuRuRuRu", amount: 200 }], + improvement: 1, + }, + { + required: [{ shape: "Cu------", amount: 4000 }], + improvement: 2, + }, + { + required: [{ shape: "WyWgWyWg:CbCpCbCp", amount: 30000 }], + improvement: 4, + }, + { + required: [{ shape: "WyWgWyWg:CbCpCbCp:Rp----Rp", amount: 90000 }], + improvement: 8, + }, + ], + }, + + // cutter: { + // label: "Cut Half", + // description: improvement => "Speed +" + Math.floor(improvement * 100.0) + "%", + // tiers: [ + // { + // required: [{ shape: "----CuCu", amount: 450 }], + // improvement: 1, + // }, + // { + // required: [{ shape: "CpCpCpCp", amount: 12000 }], + // improvement: 2, + // }, + // { + // required: [{ shape: "CwRrWbSp:WcWrCpCw", amount: 45000 }], + // improvement: 4, + // }, + // { + // required: [{ shape: "CwRrWbSp:WcWrCpCw:WpWpWb--", amount: 100000 }], + // improvement: 8, + // }, + // ], + // }, + // splitter: { + // label: "Distribute", + // description: improvement => "Speed +" + Math.floor(improvement * 100.0) + "%", + // tiers: [ + // { + // required: [{ shape: "CuCu----", amount: 350 }], + // improvement: 1, + // }, + // { + // required: [{ shape: "CrCrCrCr", amount: 7000 }], + // improvement: 2, + // }, + // { + // required: [{ shape: "WyWyWyWy", amount: 30000 }], + // improvement: 4, + // }, + // { + // required: [{ shape: "WyWyWyWy:CwSpRgRc", amount: 100000 }], + // improvement: 8, + // }, + // ], + // }, + + // rotater: { + // label: "Rotate", + // description: improvement => "Speed +" + Math.floor(improvement * 100.0) + "%", + // tiers: [ + // { + // required: [{ shape: "RuRu----", amount: 750 }], + // improvement: 1, + // }, + // { + // required: [{ shape: "ScScScSc", amount: 3000 }], + // improvement: 2, + // }, + // { + // required: [{ shape: "ScSpRwRw:Cw----Cw", amount: 15000 }], + // improvement: 4, + // }, + // { + // required: [{ shape: "ScSpRwRw:Cw----Cw:CpCpCpCp", amount: 80000 }], + // improvement: 8, + // }, + // ], + // }, + + // underground_belt: { + // label: "Tunnel", + // description: improvement => "Speed +" + Math.floor(improvement * 100.0) + "%", + // tiers: [ + // { + // required: [{ shape: "--CuCu--", amount: 1000 }], + // improvement: 1, + // }, + // { + // required: [{ shape: "RbRb----", amount: 9000 }], + // improvement: 2, + // }, + // { + // required: [{ shape: "RbRb----:WpWpWpWp", amount: 25000 }], + // improvement: 4, + // }, + // { + // required: [{ shape: "RbRb----:WpWpWpWp:RwRwRpRp", amount: 100000 }], + // improvement: 8, + // }, + // ], + // }, + + // painter: { + // label: "Dye", + // description: improvement => "Speed +" + Math.floor(improvement * 100.0) + "%", + // tiers: [ + // { + // required: [{ shape: "------Ru", amount: 4000 }], + // improvement: 1, + // }, + // { + // required: [{ shape: "CcCcRgRg", amount: 15000 }], + // improvement: 2, + // }, + // { + // required: [{ shape: "CcCcRgRg:WgWgWgWg", amount: 35000 }], + // improvement: 4, + // }, + // { + // required: [{ shape: "CcCcRgRg:WgWgWgWg:CpRpCpRp", amount: 100000 }], + // improvement: 8, + // }, + // ], + // }, + + // mixer: { + // label: "Mix Colors", + // description: improvement => "Speed +" + Math.floor(improvement * 100.0) + "%", + // tiers: [ + // { + // required: [{ shape: "RgRgRgRg:CcCcCcCc", amount: 11000 }], + // improvement: 1, + // }, + // { + // required: [{ shape: "WyWgWyWg:CbCpCbCp", amount: 15000 }], + // improvement: 2, + // }, + // { + // required: [{ shape: "CcCcRgRg:WgWgWgWg:CpRpCpRp", amount: 45000 }], + // improvement: 4, + // }, + // { + // required: [{ shape: "CcCcRgRg:WgWgWgWg:CpRpCpRp:CpCpCpCp", amount: 100000 }], + // improvement: 8, + // }, + // ], + // }, + // stacker: { + // label: "Combine", + // description: improvement => "Speed +" + Math.floor(improvement * 100.0) + "%", + // tiers: [ + // { + // required: [{ shape: "CgCgRgRg", amount: 20000 }], + // improvement: 1, + // }, + // { + // required: [{ shape: "CgCgRgRg:WpRpWpRp", amount: 50000 }], + // improvement: 2, + // }, + // { + // required: [{ shape: "CgCgRgRg:WpRpWpRp:SpSwSpSw", amount: 70000 }], + // improvement: 4, + // }, + // { + // required: [{ shape: "CgCgRgRg:WpRpWpRp:SpSwSpSw:CwCwCwCw", amount: 100000 }], + // improvement: 8, + // }, + // ], + // }, +}; + +// Tiers need % of the previous tier as requirement too +const tierGrowth = 2; + +// Automatically generate tier levels +for (const upgradeId in UPGRADES) { + const upgrade = UPGRADES[upgradeId]; + + let currentTierRequirements = []; + for (let i = 0; i < upgrade.tiers.length; ++i) { + const tierHandle = upgrade.tiers[i]; + const originalRequired = tierHandle.required.slice(); + + for (let k = currentTierRequirements.length - 1; k >= 0; --k) { + const oldTierRequirement = currentTierRequirements[k]; + tierHandle.required.unshift({ + shape: oldTierRequirement.shape, + amount: oldTierRequirement.amount, + }); + } + currentTierRequirements.push( + ...originalRequired.map(req => ({ + amount: req.amount, + shape: req.shape, + })) + ); + currentTierRequirements.forEach(tier => { + tier.amount = findNiceIntegerValue(tier.amount * tierGrowth); + }); + } +} + +if (G_IS_DEV) { + for (const upgradeId in UPGRADES) { + const upgrade = UPGRADES[upgradeId]; + upgrade.tiers.forEach(tier => { + tier.required.forEach(({ shape }) => { + try { + ShapeDefinition.fromShortKey(shape); + } catch (ex) { + throw new Error("Invalid upgrade goal: '" + ex + "' for shape" + shape); + } + }); + }); + } +} diff --git a/src/js/game_analytics.d.ts b/src/js/game_analytics.d.ts new file mode 100644 index 00000000..3324213e --- /dev/null +++ b/src/js/game_analytics.d.ts @@ -0,0 +1,737 @@ +declare module gameanalytics { + enum EGAErrorSeverity { + Undefined = 0, + Debug = 1, + Info = 2, + Warning = 3, + Error = 4, + Critical = 5, + } + enum EGAProgressionStatus { + Undefined = 0, + Start = 1, + Complete = 2, + Fail = 3, + } + enum EGAResourceFlowType { + Undefined = 0, + Source = 1, + Sink = 2, + } + module http { + enum EGAHTTPApiResponse { + NoResponse = 0, + BadResponse = 1, + RequestTimeout = 2, + JsonEncodeFailed = 3, + JsonDecodeFailed = 4, + InternalServerError = 5, + BadRequest = 6, + Unauthorized = 7, + UnknownResponseCode = 8, + Ok = 9, + Created = 10, + } + } + module events { + enum EGASdkErrorCategory { + Undefined = 0, + EventValidation = 1, + Database = 2, + Init = 3, + Http = 4, + Json = 5, + } + enum EGASdkErrorArea { + Undefined = 0, + BusinessEvent = 1, + ResourceEvent = 2, + ProgressionEvent = 3, + DesignEvent = 4, + ErrorEvent = 5, + InitHttp = 9, + EventsHttp = 10, + ProcessEvents = 11, + AddEventsToStore = 12, + } + enum EGASdkErrorAction { + Undefined = 0, + InvalidCurrency = 1, + InvalidShortString = 2, + InvalidEventPartLength = 3, + InvalidEventPartCharacters = 4, + InvalidStore = 5, + InvalidFlowType = 6, + StringEmptyOrNull = 7, + NotFoundInAvailableCurrencies = 8, + InvalidAmount = 9, + NotFoundInAvailableItemTypes = 10, + WrongProgressionOrder = 11, + InvalidEventIdLength = 12, + InvalidEventIdCharacters = 13, + InvalidProgressionStatus = 15, + InvalidSeverity = 16, + InvalidLongString = 17, + DatabaseTooLarge = 18, + DatabaseOpenOrCreate = 19, + JsonError = 25, + FailHttpJsonDecode = 29, + FailHttpJsonEncode = 30, + } + enum EGASdkErrorParameter { + Undefined = 0, + Currency = 1, + CartType = 2, + ItemType = 3, + ItemId = 4, + Store = 5, + FlowType = 6, + Amount = 7, + Progression01 = 8, + Progression02 = 9, + Progression03 = 10, + EventId = 11, + ProgressionStatus = 12, + Severity = 13, + Message = 14, + } + } +} +export declare var EGAErrorSeverity: typeof gameanalytics.EGAErrorSeverity; +export declare var EGAProgressionStatus: typeof gameanalytics.EGAProgressionStatus; +export declare var EGAResourceFlowType: typeof gameanalytics.EGAResourceFlowType; +declare module gameanalytics { + module logging { + class GALogger { + private static readonly instance; + private infoLogEnabled; + private infoLogVerboseEnabled; + private static debugEnabled; + private static readonly Tag; + private constructor(); + static setInfoLog(value: boolean): void; + static setVerboseLog(value: boolean): void; + static i(format: string): void; + static w(format: string): void; + static e(format: string): void; + static ii(format: string): void; + static d(format: string): void; + private sendNotificationMessage; + } + } +} +declare module gameanalytics { + module utilities { + class GAUtilities { + static getHmac(key: string, data: string): string; + static stringMatch(s: string, pattern: RegExp): boolean; + static joinStringArray(v: Array, delimiter: string): string; + static stringArrayContainsString(array: Array, search: string): boolean; + private static readonly keyStr; + static encode64(input: string): string; + static decode64(input: string): string; + static timeIntervalSince1970(): number; + static createGuid(): string; + private static s4; + } + } +} +declare module gameanalytics { + module validators { + import EGASdkErrorCategory = gameanalytics.events.EGASdkErrorCategory; + import EGASdkErrorArea = gameanalytics.events.EGASdkErrorArea; + import EGASdkErrorAction = gameanalytics.events.EGASdkErrorAction; + import EGASdkErrorParameter = gameanalytics.events.EGASdkErrorParameter; + class ValidationResult { + category: EGASdkErrorCategory; + area: EGASdkErrorArea; + action: EGASdkErrorAction; + parameter: EGASdkErrorParameter; + reason: string; + constructor( + category: EGASdkErrorCategory, + area: EGASdkErrorArea, + action: EGASdkErrorAction, + parameter: EGASdkErrorParameter, + reason: string + ); + } + class GAValidator { + static validateBusinessEvent( + currency: string, + amount: number, + cartType: string, + itemType: string, + itemId: string + ): ValidationResult; + static validateResourceEvent( + flowType: EGAResourceFlowType, + currency: string, + amount: number, + itemType: string, + itemId: string, + availableCurrencies: Array, + availableItemTypes: Array + ): ValidationResult; + static validateProgressionEvent( + progressionStatus: EGAProgressionStatus, + progression01: string, + progression02: string, + progression03: string + ): ValidationResult; + static validateDesignEvent(eventId: string): ValidationResult; + static validateErrorEvent(severity: EGAErrorSeverity, message: string): ValidationResult; + static validateSdkErrorEvent( + gameKey: string, + gameSecret: string, + category: EGASdkErrorCategory, + area: EGASdkErrorArea, + action: EGASdkErrorAction + ): boolean; + static validateKeys(gameKey: string, gameSecret: string): boolean; + static validateCurrency(currency: string): boolean; + static validateEventPartLength(eventPart: string, allowNull: boolean): boolean; + static validateEventPartCharacters(eventPart: string): boolean; + static validateEventIdLength(eventId: string): boolean; + static validateEventIdCharacters(eventId: string): boolean; + static validateAndCleanInitRequestResponse( + initResponse: { + [key: string]: any; + }, + configsCreated: boolean + ): { + [key: string]: any; + }; + static validateBuild(build: string): boolean; + static validateSdkWrapperVersion(wrapperVersion: string): boolean; + static validateEngineVersion(engineVersion: string): boolean; + static validateUserId(uId: string): boolean; + static validateShortString(shortString: string, canBeEmpty: boolean): boolean; + static validateString(s: string, canBeEmpty: boolean): boolean; + static validateLongString(longString: string, canBeEmpty: boolean): boolean; + static validateConnectionType(connectionType: string): boolean; + static validateCustomDimensions(customDimensions: Array): boolean; + static validateResourceCurrencies(resourceCurrencies: Array): boolean; + static validateResourceItemTypes(resourceItemTypes: Array): boolean; + static validateDimension01(dimension01: string, availableDimensions: Array): boolean; + static validateDimension02(dimension02: string, availableDimensions: Array): boolean; + static validateDimension03(dimension03: string, availableDimensions: Array): boolean; + static validateArrayOfStrings( + maxCount: number, + maxStringLength: number, + allowNoValues: boolean, + logTag: string, + arrayOfStrings: Array + ): boolean; + static validateClientTs(clientTs: number): boolean; + } + } +} +declare module gameanalytics { + module device { + class NameValueVersion { + name: string; + value: string; + version: string; + constructor(name: string, value: string, version: string); + } + class NameVersion { + name: string; + version: string; + constructor(name: string, version: string); + } + class GADevice { + private static readonly sdkWrapperVersion; + private static readonly osVersionPair; + static readonly buildPlatform: string; + static readonly deviceModel: string; + static readonly deviceManufacturer: string; + static readonly osVersion: string; + static readonly browserVersion: string; + static sdkGameEngineVersion: string; + static gameEngineVersion: string; + private static connectionType; + static touch(): void; + static getRelevantSdkVersion(): string; + static getConnectionType(): string; + static updateConnectionType(): void; + private static getOSVersionString; + private static runtimePlatformToString; + private static getBrowserVersionString; + private static getDeviceModel; + private static getDeviceManufacturer; + private static matchItem; + } + } +} +declare module gameanalytics { + module threading { + class TimedBlock { + readonly deadline: Date; + block: () => void; + readonly id: number; + ignore: boolean; + async: boolean; + running: boolean; + private static idCounter; + constructor(deadline: Date); + } + } +} +declare module gameanalytics { + module threading { + interface IComparer { + compare(x: T, y: T): number; + } + class PriorityQueue { + _subQueues: { + [key: number]: Array; + }; + _sortedKeys: Array; + private comparer; + constructor(priorityComparer: IComparer); + enqueue(priority: number, item: TItem): void; + private addQueueOfPriority; + peek(): TItem; + hasItems(): boolean; + dequeue(): TItem; + private dequeueFromHighPriorityQueue; + } + } +} +declare module gameanalytics { + module store { + enum EGAStoreArgsOperator { + Equal = 0, + LessOrEqual = 1, + NotEqual = 2, + } + enum EGAStore { + Events = 0, + Sessions = 1, + Progression = 2, + } + class GAStore { + private static readonly instance; + private static storageAvailable; + private static readonly MaxNumberOfEntries; + private eventsStore; + private sessionsStore; + private progressionStore; + private storeItems; + private static readonly StringFormat; + private static readonly KeyFormat; + private static readonly EventsStoreKey; + private static readonly SessionsStoreKey; + private static readonly ProgressionStoreKey; + private static readonly ItemsStoreKey; + private constructor(); + static isStorageAvailable(): boolean; + static isStoreTooLargeForEvents(): boolean; + static select( + store: EGAStore, + args?: Array<[string, EGAStoreArgsOperator, any]>, + sort?: boolean, + maxCount?: number + ): Array<{ + [key: string]: any; + }>; + static update( + store: EGAStore, + setArgs: Array<[string, any]>, + whereArgs?: Array<[string, EGAStoreArgsOperator, any]> + ): boolean; + static delete(store: EGAStore, args: Array<[string, EGAStoreArgsOperator, any]>): void; + static insert( + store: EGAStore, + newEntry: { + [key: string]: any; + }, + replace?: boolean, + replaceKey?: string + ): void; + static save(gameKey: string): void; + static load(gameKey: string): void; + static setItem(gameKey: string, key: string, value: string): void; + static getItem(gameKey: string, key: string): string; + private static getStore; + } + } +} +declare module gameanalytics { + module state { + class GAState { + private static readonly CategorySdkError; + private static readonly MAX_CUSTOM_FIELDS_COUNT; + private static readonly MAX_CUSTOM_FIELDS_KEY_LENGTH; + private static readonly MAX_CUSTOM_FIELDS_VALUE_STRING_LENGTH; + static readonly instance: GAState; + private constructor(); + private userId; + static setUserId(userId: string): void; + private identifier; + static getIdentifier(): string; + private initialized; + static isInitialized(): boolean; + static setInitialized(value: boolean): void; + sessionStart: number; + static getSessionStart(): number; + private sessionNum; + static getSessionNum(): number; + private transactionNum; + static getTransactionNum(): number; + sessionId: string; + static getSessionId(): string; + private currentCustomDimension01; + static getCurrentCustomDimension01(): string; + private currentCustomDimension02; + static getCurrentCustomDimension02(): string; + private currentCustomDimension03; + static getCurrentCustomDimension03(): string; + private gameKey; + static getGameKey(): string; + private gameSecret; + static getGameSecret(): string; + private availableCustomDimensions01; + static getAvailableCustomDimensions01(): Array; + static setAvailableCustomDimensions01(value: Array): void; + private availableCustomDimensions02; + static getAvailableCustomDimensions02(): Array; + static setAvailableCustomDimensions02(value: Array): void; + private availableCustomDimensions03; + static getAvailableCustomDimensions03(): Array; + static setAvailableCustomDimensions03(value: Array): void; + private availableResourceCurrencies; + static getAvailableResourceCurrencies(): Array; + static setAvailableResourceCurrencies(value: Array): void; + private availableResourceItemTypes; + static getAvailableResourceItemTypes(): Array; + static setAvailableResourceItemTypes(value: Array): void; + private build; + static getBuild(): string; + static setBuild(value: string): void; + private useManualSessionHandling; + static getUseManualSessionHandling(): boolean; + private _isEventSubmissionEnabled; + static isEventSubmissionEnabled(): boolean; + sdkConfigCached: { + [key: string]: any; + }; + private configurations; + private remoteConfigsIsReady; + private remoteConfigsListeners; + initAuthorized: boolean; + clientServerTimeOffset: number; + configsHash: string; + abId: string; + static getABTestingId(): string; + abVariantId: string; + static getABTestingVariantId(): string; + private defaultUserId; + private setDefaultId; + static getDefaultId(): string; + sdkConfigDefault: { + [key: string]: string; + }; + sdkConfig: { + [key: string]: any; + }; + static getSdkConfig(): { + [key: string]: any; + }; + private progressionTries; + static readonly DefaultUserIdKey: string; + static readonly SessionNumKey: string; + static readonly TransactionNumKey: string; + private static readonly Dimension01Key; + private static readonly Dimension02Key; + private static readonly Dimension03Key; + static readonly SdkConfigCachedKey: string; + static isEnabled(): boolean; + static setCustomDimension01(dimension: string): void; + static setCustomDimension02(dimension: string): void; + static setCustomDimension03(dimension: string): void; + static incrementSessionNum(): void; + static incrementTransactionNum(): void; + static incrementProgressionTries(progression: string): void; + static getProgressionTries(progression: string): number; + static clearProgressionTries(progression: string): void; + static setKeys(gameKey: string, gameSecret: string): void; + static setManualSessionHandling(flag: boolean): void; + static setEnabledEventSubmission(flag: boolean): void; + static getEventAnnotations(): { + [key: string]: any; + }; + static getSdkErrorEventAnnotations(): { + [key: string]: any; + }; + static getInitAnnotations(): { + [key: string]: any; + }; + static getClientTsAdjusted(): number; + static sessionIsStarted(): boolean; + private static cacheIdentifier; + static ensurePersistedStates(): void; + static calculateServerTimeOffset(serverTs: number): number; + static validateAndCleanCustomFields(fields: { + [id: string]: any; + }): { + [id: string]: any; + }; + static validateAndFixCurrentDimensions(): void; + static getConfigurationStringValue(key: string, defaultValue: string): string; + static isRemoteConfigsReady(): boolean; + static addRemoteConfigsListener(listener: { onRemoteConfigsUpdated: () => void }): void; + static removeRemoteConfigsListener(listener: { onRemoteConfigsUpdated: () => void }): void; + static getRemoteConfigsContentAsString(): string; + static populateConfigurations(sdkConfig: { [key: string]: any }): void; + } + } +} +declare module gameanalytics { + module tasks { + class SdkErrorTask { + private static readonly MaxCount; + private static readonly countMap; + private static readonly timestampMap; + static execute(url: string, type: string, payloadData: string, secretKey: string): void; + } + } +} +declare module gameanalytics { + module http { + import EGASdkErrorCategory = gameanalytics.events.EGASdkErrorCategory; + import EGASdkErrorArea = gameanalytics.events.EGASdkErrorArea; + import EGASdkErrorAction = gameanalytics.events.EGASdkErrorAction; + import EGASdkErrorParameter = gameanalytics.events.EGASdkErrorParameter; + class GAHTTPApi { + static readonly instance: GAHTTPApi; + private protocol; + private hostName; + private version; + private remoteConfigsVersion; + private baseUrl; + private remoteConfigsBaseUrl; + private initializeUrlPath; + private eventsUrlPath; + private useGzip; + private static readonly MAX_ERROR_MESSAGE_LENGTH; + private constructor(); + requestInit( + configsHash: string, + callback: ( + response: EGAHTTPApiResponse, + json: { + [key: string]: any; + } + ) => void + ): void; + sendEventsInArray( + eventArray: Array<{ + [key: string]: any; + }>, + requestId: string, + callback: ( + response: EGAHTTPApiResponse, + json: { + [key: string]: any; + }, + requestId: string, + eventCount: number + ) => void + ): void; + sendSdkErrorEvent( + category: EGASdkErrorCategory, + area: EGASdkErrorArea, + action: EGASdkErrorAction, + parameter: EGASdkErrorParameter, + reason: string, + gameKey: string, + secretKey: string + ): void; + private static sendEventInArrayRequestCallback; + private static sendRequest; + private static initRequestCallback; + private createPayloadData; + private processRequestResponse; + private static sdkErrorCategoryString; + private static sdkErrorAreaString; + private static sdkErrorActionString; + private static sdkErrorParameterString; + } + } +} +declare module gameanalytics { + module events { + class GAEvents { + private static readonly CategorySessionStart; + private static readonly CategorySessionEnd; + private static readonly CategoryDesign; + private static readonly CategoryBusiness; + private static readonly CategoryProgression; + private static readonly CategoryResource; + private static readonly CategoryError; + private static readonly MaxEventCount; + private constructor(); + static addSessionStartEvent(): void; + static addSessionEndEvent(): void; + static addBusinessEvent( + currency: string, + amount: number, + itemType: string, + itemId: string, + cartType: string, + fields: { + [id: string]: any; + } + ): void; + static addResourceEvent( + flowType: EGAResourceFlowType, + currency: string, + amount: number, + itemType: string, + itemId: string, + fields: { + [id: string]: any; + } + ): void; + static addProgressionEvent( + progressionStatus: EGAProgressionStatus, + progression01: string, + progression02: string, + progression03: string, + score: number, + sendScore: boolean, + fields: { + [id: string]: any; + } + ): void; + static addDesignEvent( + eventId: string, + value: number, + sendValue: boolean, + fields: { + [id: string]: any; + } + ): void; + static addErrorEvent( + severity: EGAErrorSeverity, + message: string, + fields: { + [id: string]: any; + } + ): void; + static processEvents(category: string, performCleanUp: boolean): void; + private static processEventsCallback; + private static cleanupEvents; + private static fixMissingSessionEndEvents; + private static addEventToStore; + private static updateSessionStore; + private static addDimensionsToEvent; + private static addFieldsToEvent; + private static resourceFlowTypeToString; + private static progressionStatusToString; + private static errorSeverityToString; + } + } +} +declare module gameanalytics { + module threading { + class GAThreading { + private static readonly instance; + readonly blocks: PriorityQueue; + private readonly id2TimedBlockMap; + private static runTimeoutId; + private static readonly ThreadWaitTimeInMs; + private static ProcessEventsIntervalInSeconds; + private keepRunning; + private isRunning; + private constructor(); + static createTimedBlock(delayInSeconds?: number): TimedBlock; + static performTaskOnGAThread(taskBlock: () => void, delayInSeconds?: number): void; + static performTimedBlockOnGAThread(timedBlock: TimedBlock): void; + static scheduleTimer(interval: number, callback: () => void): number; + static getTimedBlockById(blockIdentifier: number): TimedBlock; + static ensureEventQueueIsRunning(): void; + static endSessionAndStopQueue(): void; + static stopEventQueue(): void; + static ignoreTimer(blockIdentifier: number): void; + static setEventProcessInterval(interval: number): void; + private addTimedBlock; + private static run; + private static startThread; + private static getNextBlock; + private static processEventQueue; + } + } +} +declare module gameanalytics { + class GameAnalytics { + private static initTimedBlockId; + static methodMap: { + [id: string]: (...args: any[]) => void; + }; + static init(): void; + static gaCommand(...args: any[]): void; + static configureAvailableCustomDimensions01(customDimensions?: Array): void; + static configureAvailableCustomDimensions02(customDimensions?: Array): void; + static configureAvailableCustomDimensions03(customDimensions?: Array): void; + static configureAvailableResourceCurrencies(resourceCurrencies?: Array): void; + static configureAvailableResourceItemTypes(resourceItemTypes?: Array): void; + static configureBuild(build?: string): void; + static configureSdkGameEngineVersion(sdkGameEngineVersion?: string): void; + static configureGameEngineVersion(gameEngineVersion?: string): void; + static configureUserId(uId?: string): void; + static initialize(gameKey?: string, gameSecret?: string): void; + static addBusinessEvent( + currency?: string, + amount?: number, + itemType?: string, + itemId?: string, + cartType?: string + ): void; + static addResourceEvent( + flowType?: EGAResourceFlowType, + currency?: string, + amount?: number, + itemType?: string, + itemId?: string + ): void; + static addProgressionEvent( + progressionStatus?: EGAProgressionStatus, + progression01?: string, + progression02?: string, + progression03?: string, + score?: any + ): void; + static addDesignEvent(eventId: string, value?: any): void; + static addErrorEvent(severity?: EGAErrorSeverity, message?: string): void; + static setEnabledInfoLog(flag?: boolean): void; + static setEnabledVerboseLog(flag?: boolean): void; + static setEnabledManualSessionHandling(flag?: boolean): void; + static setEnabledEventSubmission(flag?: boolean): void; + static setCustomDimension01(dimension?: string): void; + static setCustomDimension02(dimension?: string): void; + static setCustomDimension03(dimension?: string): void; + static setEventProcessInterval(intervalInSeconds: number): void; + static startSession(): void; + static endSession(): void; + static onStop(): void; + static onResume(): void; + static getRemoteConfigsValueAsString(key: string, defaultValue?: string): string; + static isRemoteConfigsReady(): boolean; + static addRemoteConfigsListener(listener: { onRemoteConfigsUpdated: () => void }): void; + static removeRemoteConfigsListener(listener: { onRemoteConfigsUpdated: () => void }): void; + static getRemoteConfigsContentAsString(): string; + static getABTestingId(): string; + static getABTestingVariantId(): string; + private static internalInitialize; + private static newSession; + private static startNewSessionCallback; + private static resumeSessionAndStartQueue; + private static isSdkReady; + } +} +declare var GameAnalyticsCommand: typeof gameanalytics.GameAnalytics.gaCommand; +export declare var GameAnalytics: typeof gameanalytics.GameAnalytics; +export default GameAnalytics; diff --git a/src/js/globals.d.ts b/src/js/globals.d.ts new file mode 100644 index 00000000..5a17daa8 --- /dev/null +++ b/src/js/globals.d.ts @@ -0,0 +1,191 @@ +// Globals defined by webpack + +declare const G_IS_DEV: boolean; +declare const G_IS_PROD: boolean; +declare function assert(condition: boolean | object | string, ...errorMessage: string[]): void; +declare function assertAlways(condition: boolean | object | string, ...errorMessage: string[]): void; + +declare const abstract: void; + +declare const G_API_ENDPOINT: string; +declare const G_APP_ENVIRONMENT: string; +declare const G_HAVE_ASSERT: boolean; +declare const G_BUILD_TIME: number; +declare const G_IS_STANDALONE: boolean; +declare const G_IS_BROWSER: boolean; +declare const G_IS_MOBILE_APP: boolean; + +declare const G_BUILD_COMMIT_HASH: string; +declare const G_TRACKING_ENDPOINT: string; +declare const G_BUILD_VERSION: string; +declare const G_ALL_UI_IMAGES: Array; +declare const G_IS_RELEASE: boolean; + +// Node require +declare function require(...args): any; + +// Polyfills +declare interface String { + replaceAll(search: string, replacement: string): string; +} + +declare interface CanvasRenderingContext2D { + beginRoundedRect(x: number, y: number, w: number, h: number, r: number): void; + beginCircle(x: number, y: number, r: number): void; + + msImageSmoothingEnabled: boolean; + mozImageSmoothingEnabled: boolean; + webkitImageSmoothingEnabled: boolean; +} + +declare interface HTMLCanvasElement { + opaque: boolean; + webkitOpaque: boolean; +} + +// Just for compatibility with the shared code +declare interface Logger { + log(...args); + warn(...args); + info(...args); + error(...args); +} + +// Cordova +declare interface Device { + uuid: string; + platform: string; + available: boolean; + version: string; + cordova: string; + model: string; + manufacturer: string; + isVirtual: boolean; + serial: string; +} + +declare interface MobileAccessibility { + usePreferredTextZoom(boolean); +} + +declare interface Window { + // Cordova + device: Device; + StatusBar: any; + AndroidFullScreen: any; + AndroidNotch: any; + plugins: any; + + // Adinplay + aiptag: any; + adPlayer: any; + aipPlayer: any; + MobileAccessibility: MobileAccessibility; + LocalFileSystem: any; + + // Debugging + activeClickDetectors: Array; + + // Experimental/Newer apis + FontFace: any; + TouchEvent: undefined | TouchEvent; + + // Thirdparty + XPayStationWidget: any; + Sentry: any; + LogRocket: any; + grecaptcha: any; + gtag: any; + cpmstarAPI: any; + + // Mods + registerMod: any; + anyModLoaded: any; + + webkitRequestAnimationFrame(); + + assert(condition: boolean, failureMessage: string); + + coreThreadLoadedCb(); + + gameanalytics: typeof import("./game_analytics"); +} + +declare interface Navigator { + app: any; + device: any; + splashscreen: any; +} + +// FontFace +declare interface Document { + fonts: any; +} + +// Webpack +declare interface WebpackContext { + keys(): Array; +} + +declare interface NodeRequire { + context(src: string, flag: boolean, regexp: RegExp): WebpackContext; +} + +// HTML Element +declare interface Element { + style: any; + innerText: string; + innerHTML: string; +} + +declare interface Math { + radians(number): number; + degrees(number): number; +} + +declare interface String { + padStart(size: number, fill: string): string; + padEnd(size: number, fill: string): string; +} + +declare interface FactoryTemplate { + entries: Array T>; + entryIds: Array; + idToEntry: any; + + getId(): string; + getAllIds(): Array; + register(entry: new (...args: any[]) => T): void; + hasId(id: string): boolean; + findById(id: string): new (...args: any[]) => T; + getEntries(): Array T>; + getNumEntries(): number; +} + +declare interface SingletonFactoryTemplate { + entries: Array; + idToEntry: any; + + register(classHandle: new (...args: any[]) => T): void; + hasId(id: string): boolean; + findById(id: string): T; + findByClass(classHandle: new (...args: any[]) => T): T; + getEntries(): Array; + getNumEntries(): number; +} + +declare interface SignalTemplate0 { + add(receiver: () => string | void, scope: null | any); + dispatch(): string | void; + remove(receiver: () => string | void); + removeAll(); +} + +declare class TypedTrackedState { + constructor(callbackMethod?: (value: T) => void, callbackScope?: any); + + set(value: T, changeHandler?: (value: T) => void, changeScope?: any): void; + + setSilent(value: any): void; + get(): T; +} diff --git a/src/js/main.js b/src/js/main.js new file mode 100644 index 00000000..5eef3a3f --- /dev/null +++ b/src/js/main.js @@ -0,0 +1,61 @@ +import "./core/polyfills"; +import "./core/assert"; +import "./core/error_handler"; + +import { createLogger, logSection } from "./core/logging"; +import { Application } from "./application"; +import { IS_DEBUG } from "./core/config"; +import { initComponentRegistry } from "./game/component_registry"; +import { initDrawUtils } from "./core/draw_utils"; +import { initItemRegistry } from "./game/item_registry"; +import { initMetaBuildingRegistry } from "./game/meta_building_registry"; + +const logger = createLogger("main"); + +if (window.coreThreadLoadedCb) { + logger.log("Javascript parsed, calling html thread"); + window.coreThreadLoadedCb(); +} + +console.log( + `%cshapez.io ️%c\n© 2019 Tobias Springer IT Solutions\nCommit %c${G_BUILD_COMMIT_HASH}%c on %c${new Date( + G_BUILD_TIME + ).toLocaleString()}\n`, + "font-size: 35px; font-family: Arial;font-weight: bold; padding: 10px 0;", + "color: #aaa", + "color: #7f7", + "color: #aaa", + "color: #7f7" +); + +console.log("Environment: %c" + G_APP_ENVIRONMENT, "color: #fff"); + +if (G_IS_DEV && IS_DEBUG) { + console.log("\n%c🛑 DEBUG ENVIRONMENT 🛑\n", "color: #f77"); +} + +/* typehints:start */ +// @ts-ignore +assert(false, "typehints built in, this should never be the case!"); +/* typehints:end */ + +/* dev:start */ +console.log("%cDEVCODE BUILT IN", "color: #f77"); +/* dev:end */ + +logSection("Boot Process", "#f9a825"); + +initDrawUtils(); +initComponentRegistry(); +initItemRegistry(); +initMetaBuildingRegistry(); + +let app = null; + +function bootApp() { + logger.log("Page Loaded"); + app = new Application(); + app.boot(); +} + +window.addEventListener("load", bootApp); diff --git a/src/js/platform/ad_provider.js b/src/js/platform/ad_provider.js new file mode 100644 index 00000000..a614a793 --- /dev/null +++ b/src/js/platform/ad_provider.js @@ -0,0 +1,45 @@ +/* typehints:start */ +import { Application } from "../application"; +/* typehints:end */ + +export class AdProviderInterface { + /** @param {Application} app */ + constructor(app) { + this.app = app; + } + + /** + * Initializes the storage + * @returns {Promise} + */ + initialize() { + return Promise.resolve(); + } + + /** + * Returns if this provider serves ads at all + * @returns {boolean} + */ + getHasAds() { + abstract; + return false; + } + + /** + * Returns if it would be possible to show a video ad *now*. This can be false if for + * example the last video ad is + * @returns {boolean} + */ + getCanShowVideoAd() { + abstract; + return false; + } + + /** + * Shows an video ad + * @returns {Promise} + */ + showVideoAd() { + return Promise.resolve(); + } +} diff --git a/src/js/platform/ad_providers/adinplay.js b/src/js/platform/ad_providers/adinplay.js new file mode 100644 index 00000000..a5731dfa --- /dev/null +++ b/src/js/platform/ad_providers/adinplay.js @@ -0,0 +1,188 @@ +/* typehints:start */ +import { Application } from "../../application"; +/* typehints:end */ + +import { AdProviderInterface } from "../ad_provider"; +import { createLogger } from "../../core/logging"; +import { ClickDetector } from "../../core/click_detector"; +import { performanceNow } from "../../core/builtins"; +import { clamp } from "../../core/utils"; + +const logger = createLogger("adprovider/adinplay"); + +const minimumTimeBetweenVideoAdsMs = G_IS_DEV ? 1 : 15 * 60 * 1000; + +export class AdinplayAdProvider extends AdProviderInterface { + /** + * + * @param {Application} app + */ + constructor(app) { + super(app); + + /** @type {ClickDetector} */ + this.getOnSteamClickDetector = null; + + /** @type {Element} */ + this.adContainerMainElement = null; + + /** + * The resolve function to finish the current video ad. Null if none is currently running + * @type {Function} + */ + this.videoAdResolveFunction = null; + + /** + * The current timer which will timeout the resolve + */ + this.videoAdResolveTimer = null; + + /** + * When we showed the last video ad + */ + this.lastVideoAdShowTime = -1e20; + } + + getHasAds() { + return true; + } + + getCanShowVideoAd() { + return ( + this.getHasAds() && + !this.videoAdResolveFunction && + performanceNow() - this.lastVideoAdShowTime > minimumTimeBetweenVideoAdsMs + ); + } + + initialize() { + // No point to initialize everything if ads are not supported + if (!this.getHasAds()) { + return Promise.resolve(); + } + + logger.log("🎬 Initializing Adinplay"); + + // Add the preroll element + this.adContainerMainElement = document.createElement("div"); + this.adContainerMainElement.id = "adinplayVideoContainer"; + this.adContainerMainElement.innerHTML = ` +
+
+ +
+
+ `; + + // Add the setup script + const setupScript = document.createElement("script"); + setupScript.textContent = ` + var aiptag = aiptag || {}; + aiptag.cmd = aiptag.cmd || []; + aiptag.cmd.display = aiptag.cmd.display || []; + aiptag.cmd.player = aiptag.cmd.player || []; + `; + document.head.appendChild(setupScript); + + window.aiptag.gdprShowConsentTool = 0; + window.aiptag.gdprAlternativeConsentTool = 1; + window.aiptag.gdprConsent = 1; + + const scale = this.app.getEffectiveUiScale(); + const targetW = 960; + const targetH = 540; + + const maxScaleX = (window.innerWidth - 100 * scale) / targetW; + const maxScaleY = (window.innerHeight - 150 * scale) / targetH; + + const scaleFactor = clamp(Math.min(maxScaleX, maxScaleY), 0.25, 2); + + const w = Math.round(targetW * scaleFactor); + const h = Math.round(targetH * scaleFactor); + + // Add the player + const videoElement = this.adContainerMainElement.querySelector(".videoInner"); + this.adContainerMainElement.querySelector(".adInner").style.maxWidth = w + "px"; + + const self = this; + window.aiptag.cmd.player.push(function () { + window.adPlayer = new window.aipPlayer({ + AD_WIDTH: w, + AD_HEIGHT: h, + AD_FULLSCREEN: false, + AD_CENTERPLAYER: false, + LOADING_TEXT: "Loading", + PREROLL_ELEM: function () { + return videoElement; + }, + AIP_COMPLETE: function () { + logger.log("🎬 ADINPLAY AD: completed"); + self.adContainerMainElement.classList.add("waitingForFinish"); + }, + AIP_REMOVE: function () { + logger.log("🎬 ADINPLAY AD: remove"); + if (self.videoAdResolveFunction) { + self.videoAdResolveFunction(); + } + }, + }); + }); + + // Load the ads + const aipScript = document.createElement("script"); + aipScript.src = "https://api.adinplay.com/libs/aiptag/pub/YRG/shapez.io/tag.min.js"; + aipScript.setAttribute("async", ""); + document.head.appendChild(aipScript); + + return Promise.resolve(); + } + + showVideoAd() { + assert(this.getHasAds(), "Called showVideoAd but ads are not supported!"); + assert(!this.videoAdResolveFunction, "Video ad still running, can not show again!"); + this.lastVideoAdShowTime = performanceNow(); + document.body.appendChild(this.adContainerMainElement); + this.adContainerMainElement.classList.add("visible"); + this.adContainerMainElement.classList.remove("waitingForFinish"); + + try { + // @ts-ignore + window.aiptag.cmd.player.push(function () { + console.log("🎬 ADINPLAY AD: Start pre roll"); + window.adPlayer.startPreRoll(); + }); + } catch (ex) { + logger.warn("🎬 Failed to play video ad:", ex); + document.body.removeChild(this.adContainerMainElement); + this.adContainerMainElement.classList.remove("visible"); + return Promise.resolve(); + } + + return new Promise(resolve => { + // So, wait for the remove call but also remove after N seconds + this.videoAdResolveFunction = () => { + this.videoAdResolveFunction = null; + clearTimeout(this.videoAdResolveTimer); + this.videoAdResolveTimer = null; + + // When the ad closed, also set the time + this.lastVideoAdShowTime = performanceNow(); + resolve(); + }; + + this.videoAdResolveTimer = setTimeout(() => { + logger.warn(this, "Automatically closing ad after not receiving callback"); + if (this.videoAdResolveFunction) { + this.videoAdResolveFunction(); + } + }, 120 * 1000); + }) + .catch(err => { + logger.error("Error while resolving video ad:", err); + }) + .then(() => { + document.body.removeChild(this.adContainerMainElement); + this.adContainerMainElement.classList.remove("visible"); + }); + } +} diff --git a/src/js/platform/ad_providers/no_ad_provider.js b/src/js/platform/ad_providers/no_ad_provider.js new file mode 100644 index 00000000..ca7d5db1 --- /dev/null +++ b/src/js/platform/ad_providers/no_ad_provider.js @@ -0,0 +1,11 @@ +import { AdProviderInterface } from "../ad_provider"; + +export class NoAdProvider extends AdProviderInterface { + getHasAds() { + return false; + } + + getCanShowVideoAd() { + return false; + } +} diff --git a/src/js/platform/analytics.js b/src/js/platform/analytics.js new file mode 100644 index 00000000..7bd7ae50 --- /dev/null +++ b/src/js/platform/analytics.js @@ -0,0 +1,43 @@ +/* typehints:start */ +import { Application } from "../application"; +/* typehints:end */ + +export class AnalyticsInterface { + constructor(app) { + /** @type {Application} */ + this.app = app; + } + + /** + * Initializes the analytics + * @returns {Promise} + */ + initialize() { + abstract; + return Promise.reject(); + } + + /** + * Sets the player name for analytics + * @param {string} userName + */ + setUserContext(userName) {} + + /** + * Tracks a click no an ui element + * @param {string} elementName + */ + trackUiClick(elementName) {} + + /** + * Tracks when a new state is entered + * @param {string} stateId + */ + trackStateEnter(stateId) {} + + /** + * Tracks a new user decision + * @param {string} name + */ + trackDecision(name) {} +} diff --git a/src/js/platform/browser/embed_provider.js b/src/js/platform/browser/embed_provider.js new file mode 100644 index 00000000..8703ec27 --- /dev/null +++ b/src/js/platform/browser/embed_provider.js @@ -0,0 +1,47 @@ +import { AdProviderInterface } from "../ad_provider"; + +/** + * Stores information about where we are iframed + */ +export class EmbedProvider { + /** + * @returns {string} + */ + getId() { + abstract; + return ""; + } + + /** + * Whether this provider supports ads + * @returns {boolean} + */ + getSupportsAds() { + return false; + } + + /** + * Returns the ad provider + * @returns {typeof AdProviderInterface} + */ + getAdProvider() { + abstract; + return null; + } + + /** + * Whetherexternal links are supported + * @returns {boolean} + */ + getSupportsExternalLinks() { + return true; + } + + /** + * Returns whether this provider is iframed + * @returns {boolean} + */ + getIsIframed() { + return true; + } +} diff --git a/src/js/platform/browser/embed_providers/armorgames.js b/src/js/platform/browser/embed_providers/armorgames.js new file mode 100644 index 00000000..867e0a71 --- /dev/null +++ b/src/js/platform/browser/embed_providers/armorgames.js @@ -0,0 +1,16 @@ +import { AdinplayAdProvider } from "../../ad_providers/adinplay"; +import { ShapezioWebsiteEmbedProvider } from "./shapezio_website"; + +export class ArmorgamesEmbedProvider extends ShapezioWebsiteEmbedProvider { + getId() { + return "armorgames"; + } + + getAdProvider() { + return AdinplayAdProvider; + } + + getIsIframed() { + return true; + } +} diff --git a/src/js/platform/browser/embed_providers/crazygames.js b/src/js/platform/browser/embed_providers/crazygames.js new file mode 100644 index 00000000..dc0b09dc --- /dev/null +++ b/src/js/platform/browser/embed_providers/crazygames.js @@ -0,0 +1,11 @@ +import { ShapezioWebsiteEmbedProvider } from "./shapezio_website"; + +export class CrazygamesEmbedProvider extends ShapezioWebsiteEmbedProvider { + getId() { + return "crazygames"; + } + + getIsIframed() { + return true; + } +} diff --git a/src/js/platform/browser/embed_providers/gamedistribution.js b/src/js/platform/browser/embed_providers/gamedistribution.js new file mode 100644 index 00000000..49dda339 --- /dev/null +++ b/src/js/platform/browser/embed_providers/gamedistribution.js @@ -0,0 +1,20 @@ +import { AdinplayAdProvider } from "../../ad_providers/adinplay"; +import { ShapezioWebsiteEmbedProvider } from "./shapezio_website"; + +export class GamedistributionEmbedProvider extends ShapezioWebsiteEmbedProvider { + getId() { + return "gamedistribution"; + } + + getAdProvider() { + return AdinplayAdProvider; + } + + getSupportsExternalLinks() { + return false; + } + + getIsIframed() { + return true; + } +} diff --git a/src/js/platform/browser/embed_providers/iogames_space.js b/src/js/platform/browser/embed_providers/iogames_space.js new file mode 100644 index 00000000..5f7d317d --- /dev/null +++ b/src/js/platform/browser/embed_providers/iogames_space.js @@ -0,0 +1,15 @@ +import { ShapezioWebsiteEmbedProvider } from "./shapezio_website"; + +export class IogamesSpaceEmbedProvider extends ShapezioWebsiteEmbedProvider { + getId() { + return "iogames.space"; + } + + getShowUpvoteHints() { + return true; + } + + getIsIframed() { + return true; + } +} diff --git a/src/js/platform/browser/embed_providers/kongregate.js b/src/js/platform/browser/embed_providers/kongregate.js new file mode 100644 index 00000000..b0ed4d8b --- /dev/null +++ b/src/js/platform/browser/embed_providers/kongregate.js @@ -0,0 +1,24 @@ +import { NoAdProvider } from "../../ad_providers/no_ad_provider"; +import { EmbedProvider } from "../embed_provider"; + +export class KongregateEmbedProvider extends EmbedProvider { + getId() { + return "kongregate"; + } + + getSupportsAds() { + return false; + } + + getAdProvider() { + return NoAdProvider; + } + + getSupportsExternalLinks() { + return true; + } + + getIsIframed() { + return true; + } +} diff --git a/src/js/platform/browser/embed_providers/miniclip.js b/src/js/platform/browser/embed_providers/miniclip.js new file mode 100644 index 00000000..e0612978 --- /dev/null +++ b/src/js/platform/browser/embed_providers/miniclip.js @@ -0,0 +1,11 @@ +import { ShapezioWebsiteEmbedProvider } from "./shapezio_website"; + +export class MiniclipEmbedProvider extends ShapezioWebsiteEmbedProvider { + getId() { + return "miniclip"; + } + + getIsIframed() { + return true; + } +} diff --git a/src/js/platform/browser/embed_providers/shapezio_website.js b/src/js/platform/browser/embed_providers/shapezio_website.js new file mode 100644 index 00000000..2a5359ed --- /dev/null +++ b/src/js/platform/browser/embed_providers/shapezio_website.js @@ -0,0 +1,24 @@ +import { EmbedProvider } from "../embed_provider"; +import { AdinplayAdProvider } from "../../ad_providers/adinplay"; + +export class ShapezioWebsiteEmbedProvider extends EmbedProvider { + getId() { + return "shapezio"; + } + + getSupportsAds() { + return true; + } + + getAdProvider() { + return AdinplayAdProvider; + } + + getIsIframed() { + return false; + } + + getSupportsExternalLinks() { + return true; + } +} diff --git a/src/js/platform/browser/game_analytics.js b/src/js/platform/browser/game_analytics.js new file mode 100644 index 00000000..1c06a602 --- /dev/null +++ b/src/js/platform/browser/game_analytics.js @@ -0,0 +1,69 @@ +import { GameAnalyticsInterface } from "../game_analytics"; +import { createLogger } from "../../core/logging"; +import { ShapeDefinition } from "../../game/shape_definition"; +import { gameCreationAction } from "../../states/ingame"; + +const logger = createLogger("ga_com"); + +export class GameAnalyticsDotCom extends GameAnalyticsInterface { + /** + * @returns {Promise} + */ + initialize() { + try { + const ga = window.gameanalytics.GameAnalytics; + ga.configureBuild(G_APP_ENVIRONMENT + "@" + G_BUILD_VERSION + "@" + G_BUILD_COMMIT_HASH); + + ga.setEnabledInfoLog(G_IS_DEV); + ga.setEnabledVerboseLog(G_IS_DEV); + + // @ts-ignore + ga.initialize(window.ga_comKey, window.ga_comToken); + + // start new session + ga.startSession(); + } catch (ex) { + logger.warn("ga_com init error:", ex); + } + return Promise.resolve(); + } + + /** + * @param {ShapeDefinition} definition + */ + handleShapeDelivered(definition) { + const hash = definition.getHash(); + logger.log("Deliver:", hash); + } + + /** + * Handles the given level completed + * @param {number} level + */ + handleLevelCompleted(level) { + logger.log("Complete level", level); + try { + const gaD = window.gameanalytics; + const ga = gaD.GameAnalytics; + ga.addProgressionEvent(gaD.EGAProgressionStatus.Complete, "story", "" + level); + } catch (ex) { + logger.error("ga_com lvl complete error:", ex); + } + } + + /** + * Handles the given upgrade completed + * @param {string} id + * @param {number} level + */ + handleUpgradeUnlocked(id, level) { + logger.log("Unlock upgrade", id, level); + try { + const gaD = window.gameanalytics; + const ga = gaD.GameAnalytics; + ga.addProgressionEvent(gaD.EGAProgressionStatus.Complete, "upgrade", id, "" + level); + } catch (ex) { + logger.error("ga_com upgrade unlock error:", ex); + } + } +} diff --git a/src/js/platform/browser/google_analytics.js b/src/js/platform/browser/google_analytics.js new file mode 100644 index 00000000..55de95cc --- /dev/null +++ b/src/js/platform/browser/google_analytics.js @@ -0,0 +1,101 @@ +import { AnalyticsInterface } from "../analytics"; +import { Math_random, performanceNow } from "../../core/builtins"; +import { createLogger } from "../../core/logging"; + +const logger = createLogger("ga"); + +export class GoogleAnalyticsImpl extends AnalyticsInterface { + initialize() { + this.lastUiClickTracked = -1000; + + setInterval(() => this.internalTrackAfkEvent(), 120 * 1000); + + // Analytics is already loaded in the html + return Promise.resolve(); + } + + setUserContext(userName) { + try { + if (window.gtag) { + logger.log("📊 Setting user context:", userName); + window.gtag("set", { + player: userName, + }); + } + } catch (ex) { + logger.warn("📊 Failed to set user context:", ex); + } + } + + trackStateEnter(stateId) { + const nonInteractionStates = [ + "LoginState", + "MainMenuState", + "PreloadState", + "RegisterState", + "WatchAdState", + ]; + + try { + if (window.gtag) { + logger.log("📊 Tracking state enter:", stateId); + window.gtag("event", "enter_state", { + event_category: "ui", + event_label: stateId, + non_interaction: nonInteractionStates.indexOf(stateId) >= 0, + }); + } + } catch (ex) { + logger.warn("📊 Failed to track state analytcis:", ex); + } + } + + trackDecision(decisionName) { + try { + if (window.gtag) { + logger.log("📊 Tracking decision:", decisionName); + window.gtag("event", "decision", { + event_category: "ui", + event_label: decisionName, + non_interaction: true, + }); + } + } catch (ex) { + logger.warn("📊 Failed to track state analytcis:", ex); + } + } + + trackUiClick(elementName) { + // Only track a fraction of clicks to not annoy google analytics + if (Math_random() < 0.9) { + return; + } + + const stateKey = this.app.stateMgr.getCurrentState().key; + const fullSelector = stateKey + ">" + elementName; + + try { + if (window.gtag) { + logger.log("📊 Tracking click on:", fullSelector); + window.gtag("event", "click", { + event_category: "ui", + event_label: fullSelector, + }); + } + } catch (ex) { + logger.warn("📊 Failed to track ui click:", ex); + } + } + + /** + * Tracks an event so GA keeps track of the user + */ + internalTrackAfkEvent() { + if (window.gtag) { + window.gtag("event", "afk", { + event_category: "ping", + event_label: "timed", + }); + } + } +} diff --git a/src/js/platform/browser/sound.js b/src/js/platform/browser/sound.js new file mode 100644 index 00000000..6776a6d1 --- /dev/null +++ b/src/js/platform/browser/sound.js @@ -0,0 +1,146 @@ +import { MusicInstanceInterface, SoundInstanceInterface, SoundInterface } from "../sound"; +import { cachebust } from "../../core/cachebust"; +import { createLogger } from "../../core/logging"; + +const { Howl, Howler } = require("howler"); + +const logger = createLogger("sound/browser"); + +class SoundInstance extends SoundInstanceInterface { + constructor(key, url) { + super(key, url); + this.howl = null; + this.instance = null; + } + + load() { + return Promise.race([ + new Promise((resolve, reject) => { + setTimeout(reject, G_IS_DEV ? 5000 : 60000); + }), + new Promise(resolve => { + this.howl = new Howl({ + src: cachebust("res/sounds/" + this.url), + autoplay: false, + loop: false, + volume: 0, + preload: true, + onload: () => { + resolve(); + }, + onloaderror: (id, err) => { + logger.warn("Sound", this.url, "failed to load:", id, err); + this.howl = null; + resolve(); + }, + onplayerror: (id, err) => { + logger.warn("Sound", this.url, "failed to play:", id, err); + }, + }); + }), + ]); + } + + play(volume) { + if (this.howl) { + if (!this.instance) { + this.instance = this.howl.play(); + } else { + this.howl.play(this.instance); + this.howl.seek(0, this.instance); + } + this.howl.volume(volume, this.instance); + } + } + + deinitialize() { + if (this.howl) { + this.howl.unload(); + this.howl = null; + this.instance = null; + } + } +} + +class MusicInstance extends MusicInstanceInterface { + constructor(key, url) { + super(key, url); + this.howl = null; + this.instance = null; + this.playing = false; + } + load() { + return Promise.race([ + new Promise((resolve, reject) => { + setTimeout(reject, G_IS_DEV ? 5000 : 60000); + }), + new Promise((resolve, reject) => { + this.howl = new Howl({ + src: cachebust("res/sounds/music/" + this.url), + autoplay: false, + loop: true, + html5: true, + volume: 1, + preload: true, + pool: 2, + + onload: () => { + resolve(); + }, + onloaderror: (id, err) => { + logger.warn(this, "Music", this.url, "failed to load:", id, err); + this.howl = null; + resolve(); + }, + onplayerror: (id, err) => { + logger.warn(this, "Music", this.url, "failed to play:", id, err); + }, + }); + }), + ]); + } + + stop() { + if (this.howl && this.instance) { + this.playing = false; + this.howl.pause(this.instance); + } + } + + isPlaying() { + return this.playing; + } + + play() { + if (this.howl) { + this.playing = true; + if (this.instance) { + this.howl.play(this.instance); + } else { + this.instance = this.howl.play(); + } + } + } + + deinitialize() { + if (this.howl) { + this.howl.unload(); + this.howl = null; + this.instance = null; + } + } +} + +export class SoundImplBrowser extends SoundInterface { + constructor(app) { + super(app, SoundInstance, MusicInstance); + } + + initialize() { + return super.initialize(); + } + + deinitialize() { + return super.deinitialize().then(() => Howler.unload()); + } +} diff --git a/src/js/platform/browser/storage.js b/src/js/platform/browser/storage.js new file mode 100644 index 00000000..23cbe700 --- /dev/null +++ b/src/js/platform/browser/storage.js @@ -0,0 +1,97 @@ +import { FILE_NOT_FOUND, StorageInterface } from "../storage"; +import { createLogger } from "../../core/logging"; + +const logger = createLogger("storage/browser"); + +const LOCAL_STORAGE_UNAVAILABLE = "local-storage-unavailable"; +const LOCAL_STORAGE_NO_WRITE_PERMISSION = "local-storage-no-write-permission"; + +let randomDelay = () => 0; + +if (G_IS_DEV) { + // Random delay for testing + // randomDelay = () => 500; +} + +export class StorageImplBrowser extends StorageInterface { + constructor(app) { + super(app); + this.currentBusyFilename = false; + } + + initialize() { + return new Promise((resolve, reject) => { + // Check for local storage availability in general + if (!window.localStorage) { + alert("Local storage is not available! Please upgrade to a newer browser!"); + reject(LOCAL_STORAGE_UNAVAILABLE); + } + + // Check if we can set and remove items + try { + window.localStorage.setItem("storage_availability_test", "1"); + window.localStorage.removeItem("storage_availability_test"); + } catch (e) { + alert( + "It seems we don't have permission to write to local storage! Please update your browsers settings or use a different browser!" + ); + reject(LOCAL_STORAGE_NO_WRITE_PERMISSION); + return; + } + setTimeout(resolve, 0); + }); + } + + writeFileAsync(filename, contents) { + if (this.currentBusyFilename === filename) { + logger.warn("Attempt to write", filename, "while write process is not finished!"); + } + + this.currentBusyFilename = filename; + window.localStorage.setItem(filename, contents); + return new Promise((resolve, reject) => { + setTimeout(() => { + this.currentBusyFilename = false; + resolve(); + }, 0); + }); + } + + writeFileSyncIfSupported(filename, contents) { + window.localStorage.setItem(filename, contents); + return true; + } + + readFileAsync(filename) { + if (this.currentBusyFilename === filename) { + logger.warn("Attempt to read", filename, "while write progress on it is ongoing!"); + } + + return new Promise((resolve, reject) => { + const contents = window.localStorage.getItem(filename); + if (!contents) { + // File not found + setTimeout(() => reject(FILE_NOT_FOUND), randomDelay()); + return; + } + + // File read, simulate delay + setTimeout(() => resolve(contents), 0); + }); + } + + deleteFileAsync(filename) { + if (this.currentBusyFilename === filename) { + logger.warn("Attempt to delete", filename, "while write progres on it is ongoing!"); + } + + this.currentBusyFilename = filename; + return new Promise((resolve, reject) => { + window.localStorage.removeItem(filename); + setTimeout(() => { + this.currentBusyFilename = false; + resolve(); + }, 0); + }); + } +} diff --git a/src/js/platform/browser/wrapper.js b/src/js/platform/browser/wrapper.js new file mode 100644 index 00000000..93565342 --- /dev/null +++ b/src/js/platform/browser/wrapper.js @@ -0,0 +1,242 @@ +import { Math_min } from "../../core/builtins"; +import { createLogger } from "../../core/logging"; +import { queryParamOptions } from "../../core/query_parameters"; +import { clamp } from "../../core/utils"; +import { globalConfig, IS_MOBILE } from "../../core/config"; +import { NoAdProvider } from "../ad_providers/no_ad_provider"; +import { PlatformWrapperInterface } from "../wrapper"; +import { ShapezioWebsiteEmbedProvider } from "./embed_providers/shapezio_website"; +import { ArmorgamesEmbedProvider } from "./embed_providers/armorgames"; +import { IogamesSpaceEmbedProvider } from "./embed_providers/iogames_space"; +import { MiniclipEmbedProvider } from "./embed_providers/miniclip"; +import { GamedistributionEmbedProvider } from "./embed_providers/gamedistribution"; +import { KongregateEmbedProvider } from "./embed_providers/kongregate"; +import { CrazygamesEmbedProvider } from "./embed_providers/crazygames"; +import { EmbedProvider } from "./embed_provider"; + +const logger = createLogger("platform/browser"); + +export class PlatformWrapperImplBrowser extends PlatformWrapperInterface { + initialize() { + this.recaptchaTokenCallback = null; + + this.embedProvider = new ShapezioWebsiteEmbedProvider(); + + if (!G_IS_STANDALONE && queryParamOptions.embedProvider) { + const providerId = queryParamOptions.embedProvider; + + switch (providerId) { + case "armorgames": { + this.embedProvider = new ArmorgamesEmbedProvider(); + break; + } + + case "iogames.space": { + this.embedProvider = new IogamesSpaceEmbedProvider(); + break; + } + + case "miniclip": { + this.embedProvider = new MiniclipEmbedProvider(); + break; + } + + case "gamedistribution": { + this.embedProvider = new GamedistributionEmbedProvider(); + break; + } + + case "kongregate": { + this.embedProvider = new KongregateEmbedProvider(); + break; + } + + case "crazygames": { + this.embedProvider = new CrazygamesEmbedProvider(); + break; + } + + default: { + logger.error("Got unsupported embed provider:", providerId); + } + } + } + + logger.log("Embed provider:", this.embedProvider.getId()); + + return super.initialize().then(() => { + // SENTRY + if (!G_IS_DEV && false) { + logger.log(this, "Loading sentry"); + const sentryTag = document.createElement("script"); + sentryTag.src = "https://browser.sentry-cdn.com/5.7.1/bundle.min.js"; + sentryTag.setAttribute("integrity", "TODO_SENTRY"); + sentryTag.setAttribute("crossorigin", "anonymous"); + sentryTag.addEventListener("load", this.onSentryLoaded.bind(this)); + document.head.appendChild(sentryTag); + } + }); + } + + /** + * @returns {EmbedProvider} + */ + getEmbedProvider() { + return this.embedProvider; + } + + onSentryLoaded() { + logger.log("Initializing sentry"); + window.Sentry.init({ + dsn: "TODO SENTRY DSN", + release: G_APP_ENVIRONMENT + "-" + G_BUILD_VERSION + "@" + G_BUILD_COMMIT_HASH, + // Will cause a deprecation warning, but the demise of `ignoreErrors` is still under discussion. + // See: https://github.com/getsentry/raven-js/issues/73 + ignoreErrors: [ + // Random plugins/extensions + "top.GLOBALS", + // See: http://blog.errorception.com/2012/03/tale-of-unfindable-js-error.html + "originalCreateNotification", + "canvas.contentDocument", + "MyApp_RemoveAllHighlights", + "http://tt.epicplay.com", + "Can't find variable: ZiteReader", + "jigsaw is not defined", + "ComboSearch is not defined", + "http://loading.retry.widdit.com/", + "atomicFindClose", + // Facebook borked + "fb_xd_fragment", + // ISP "optimizing" proxy - `Cache-Control: no-transform` seems to reduce this. (thanks @acdha) + // See http://stackoverflow.com/questions/4113268/how-to-stop-javascript-injection-from-vodafone-proxy + "bmi_SafeAddOnload", + "EBCallBackMessageReceived", + // See http://toolbar.conduit.com/Developer/HtmlAndGadget/Methods/JSInjection.aspx + "conduitPage", + // Generic error code from errors outside the security sandbox + // You can delete this if using raven.js > 1.0, which ignores these automatically. + "Script error.", + + // Errors from ads + "Cannot read property 'postMessage' of null", + + // Firefox only + "AbortError: The operation was aborted.", + + "", + ], + ignoreUrls: [ + // Facebook flakiness + /graph\.facebook\.com/i, + // Facebook blocked + /connect\.facebook\.net\/en_US\/all\.js/i, + // Woopra flakiness + /eatdifferent\.com\.woopra-ns\.com/i, + /static\.woopra\.com\/js\/woopra\.js/i, + // Chrome extensions + /extensions\//i, + /^chrome:\/\//i, + // Other plugins + /127\.0\.0\.1:4001\/isrunning/i, // Cacaoweb + /webappstoolbarba\.texthelp\.com\//i, + /metrics\.itunes\.apple\.com\.edgesuite\.net\//i, + ], + beforeSend(event, hint) { + if (window.anyModLoaded) { + return null; + } + return event; + }, + }); + } + + getId() { + return "browser@" + this.embedProvider.getId(); + } + + getUiScale() { + if (IS_MOBILE) { + return 1; + } + + const avgDims = Math_min(this.app.screenWidth, this.app.screenHeight); + return clamp((avgDims / 1000.0) * 1.9, 0.1, 10); + } + + getSupportsRestart() { + return true; + } + + getTouchPanStrength() { + return IS_MOBILE ? 1 : 0.5; + } + + openExternalLink(url, force = false) { + logger.log("Opening external:", url); + // if (force || this.embedProvider.getSupportsExternalLinks()) { + window.open(url); + // } else { + // // Do nothing + // alert("This platform does not allow opening external links. You can play on the website directly to open them."); + // } + } + + getSupportsAds() { + return this.embedProvider.getSupportsAds(); + } + + performRestart() { + logger.log("Performing restart"); + window.location.reload(true); + } + + /** + * Detects if there is an adblocker installed + * @returns {Promise} + */ + detectAdblock() { + return Promise.race([ + new Promise(resolve => { + // If the request wasn't blocked within a very short period of time, this means + // the adblocker is not active and the request was actually made -> ignore it then + setTimeout(() => resolve(false), 30); + }), + new Promise(resolve => { + fetch("https://googleads.g.doubleclick.net/pagead/id", { + method: "HEAD", + mode: "no-cors", + }) + .then(res => { + resolve(false); + }) + .catch(err => { + resolve(true); + }); + }), + ]); + } + + initializeAdProvider() { + if (G_IS_DEV && !globalConfig.debug.testAds) { + return Promise.resolve(); + } + + // First, detect adblocker + return this.detectAdblock().then(hasAdblocker => { + if (hasAdblocker) { + return; + } + + const adProvider = this.embedProvider.getAdProvider(); + this.app.adProvider = new adProvider(this.app); + return this.app.adProvider.initialize().catch(err => { + logger.error("Failed to initialize ad provider, disabling ads:", err); + this.app.adProvider = new NoAdProvider(this.app); + }); + }); + } + + exitApp() { + // Can not exit app + } +} diff --git a/src/js/platform/game_analytics.js b/src/js/platform/game_analytics.js new file mode 100644 index 00000000..5b70e565 --- /dev/null +++ b/src/js/platform/game_analytics.js @@ -0,0 +1,38 @@ +/* typehints:start */ +import { Application } from "../application"; +import { ShapeDefinition } from "../game/shape_definition"; +/* typehints:end */ + +export class GameAnalyticsInterface { + constructor(app) { + /** @type {Application} */ + this.app = app; + } + + /** + * Initializes the analytics + * @returns {Promise} + */ + initialize() { + abstract; + return Promise.reject(); + } + + /** + * @param {ShapeDefinition} definition + */ + handleShapeDelivered(definition) {} + + /** + * Handles the given level completed + * @param {number} level + */ + handleLevelCompleted(level) {} + + /** + * Handles the given upgrade completed + * @param {string} id + * @param {number} level + */ + handleUpgradeUnlocked(id, level) {} +} diff --git a/src/js/platform/sound.js b/src/js/platform/sound.js new file mode 100644 index 00000000..c62db515 --- /dev/null +++ b/src/js/platform/sound.js @@ -0,0 +1,277 @@ +/* typehints:start */ +import { Application } from "../application"; +import { Vector } from "../core/vector"; +import { GameRoot } from "../game/root"; +/* typehints:end */ + +import { newEmptyMap, clamp } from "../core/utils"; +import { createLogger } from "../core/logging"; +import { globalConfig } from "../core/config"; + +const logger = createLogger("sound"); + +export const SOUNDS = { + // Menu and such + uiClick: "ui/ui_click.mp3", + uiError: "ui/ui_error.mp3", + dialogError: "ui/dialog_error.mp3", + dialogOk: "ui/dialog_ok.mp3", + swishHide: "ui/ui_swish_hide.mp3", + swishShow: "ui/ui_swish_show.mp3", +}; + +export const MUSIC = { + mainMenu: "main_menu.mp3", + gameBg: "theme_full.mp3", +}; + +export class SoundInstanceInterface { + constructor(key, url) { + this.key = key; + this.url = url; + } + + /** @returns {Promise} */ + load() { + abstract; + return Promise.resolve(); + } + + play(volume) { + abstract; + } + + deinitialize() {} +} + +export class MusicInstanceInterface { + constructor(key, url) { + this.key = key; + this.url = url; + } + + stop() { + abstract; + } + + play() { + abstract; + } + + /** @returns {Promise} */ + load() { + abstract; + return Promise.resolve(); + } + + /** @returns {boolean} */ + isPlaying() { + abstract; + return false; + } + + deinitialize() {} +} + +export class SoundInterface { + constructor(app, soundClass, musicClass) { + /** @type {Application} */ + this.app = app; + + this.soundClass = soundClass; + this.musicClass = musicClass; + + /** @type {Object} */ + this.sounds = newEmptyMap(); + + /** @type {Object} */ + this.music = newEmptyMap(); + + /** @type {MusicInstanceInterface} */ + this.currentMusic = null; + + this.pageIsVisible = true; + + this.musicMuted = false; + this.soundsMuted = false; + } + + /** + * Initializes the sound + * @returns {Promise} + */ + initialize() { + for (const soundKey in SOUNDS) { + const soundPath = SOUNDS[soundKey]; + const sound = new this.soundClass(soundKey, soundPath); + this.sounds[soundPath] = sound; + } + + for (const musicKey in MUSIC) { + const musicPath = MUSIC[musicKey]; + const music = new this.musicClass(musicKey, musicPath); + this.music[musicPath] = music; + } + + // this.musicMuted = this.app.userProfile.getMusicMuted(); + // this.soundsMuted = this.app.userProfile.getSoundsMuted(); + + this.musicMuted = false; + this.soundsMuted = false; + + if (G_IS_DEV && globalConfig.debug.disableMusic) { + this.musicMuted = true; + } + + return Promise.resolve(); + } + + /** + * Pre-Loads the given sounds + * @param {string} key + * @returns {Promise} + */ + loadSound(key) { + if (this.sounds[key]) { + return this.sounds[key].load(); + } else if (this.music[key]) { + return this.music[key].load(); + } else { + logger.error("Sound/Music by key not found:", key); + return Promise.resolve(); + } + } + + /** Deinits the sound */ + deinitialize() { + const promises = []; + for (const key in this.sounds) { + promises.push(this.sounds[key].deinitialize()); + } + for (const key in this.music) { + promises.push(this.music[key].deinitialize()); + } + return Promise.all(promises); + } + + /** + * Returns if the music is muted + * @returns {boolean} + */ + getMusicMuted() { + return this.musicMuted; + } + + /** + * Returns if sounds are muted + * @returns {boolean} + */ + getSoundsMuted() { + return this.soundsMuted; + } + + /** + * Sets if the music is muted + * @param {boolean} muted + */ + setMusicMuted(muted) { + this.musicMuted = muted; + if (this.musicMuted) { + if (this.currentMusic) { + this.currentMusic.stop(); + } + } else { + if (this.currentMusic) { + this.currentMusic.play(); + } + } + } + + /** + * Sets if the sounds are muted + * @param {boolean} muted + */ + setSoundsMuted(muted) { + this.soundsMuted = muted; + } + + /** + * Focus change handler, called by the pap + * @param {boolean} pageIsVisible + */ + onPageRenderableStateChanged(pageIsVisible) { + this.pageIsVisible = pageIsVisible; + if (this.currentMusic) { + if (pageIsVisible) { + if (!this.currentMusic.isPlaying() && !this.musicMuted) { + this.currentMusic.play(); + } + } else { + this.currentMusic.stop(); + } + } + } + + /** + * @param {string} key + */ + playUiSound(key) { + if (this.soundsMuted) { + return; + } + if (!this.sounds[key]) { + logger.warn("Sound", key, "not found, probably not loaded yet"); + return; + } + this.sounds[key].play(1.0); + } + + /** + * + * @param {string} key + * @param {Vector} worldPosition + * @param {GameRoot} root + */ + play3DSound(key, worldPosition, root) { + if (!this.sounds[key]) { + logger.warn("Music", key, "not found, probably not loaded yet"); + return; + } + if (!this.pageIsVisible || this.soundsMuted) { + return; + } + + // hack, but works + if (root.time.getIsPaused()) { + return; + } + + let volume = 1.0; + if (!root.camera.isWorldPointOnScreen(worldPosition)) { + volume = 0.2; + } + volume *= clamp(root.camera.zoomLevel / 3); + this.sounds[key].play(clamp(volume)); + } + + /** + * @param {string} key + */ + playThemeMusic(key) { + const music = this.music[key]; + if (key !== null && !music) { + logger.warn("Music", key, "not found"); + } + if (this.currentMusic !== music) { + if (this.currentMusic) { + logger.log("Stopping", this.currentMusic.key); + this.currentMusic.stop(); + } + this.currentMusic = music; + if (music && this.pageIsVisible && !this.musicMuted) { + logger.log("Starting", this.currentMusic.key); + music.play(); + } + } + } +} diff --git a/src/js/platform/storage.js b/src/js/platform/storage.js new file mode 100644 index 00000000..1c7fc54b --- /dev/null +++ b/src/js/platform/storage.js @@ -0,0 +1,62 @@ +/* typehints:start */ +import { Application } from "../application"; +/* typehints:end */ + +export const FILE_NOT_FOUND = "file_not_found"; + +export class StorageInterface { + constructor(app) { + /** @type {Application} */ + this.app = app; + } + + /** + * Initializes the storage + * @returns {Promise} + */ + initialize() { + abstract; + return Promise.reject(); + } + + /** + * Writes a string to a file asynchronously + * @param {string} filename + * @param {string} contents + * @returns {Promise} + */ + writeFileAsync(filename, contents) { + abstract; + return Promise.reject(); + } + + /** + * Tries to write a file synchronously, used in unload handler + * @param {string} filename + * @param {string} contents + */ + writeFileSyncIfSupported(filename, contents) { + abstract; + return false; + } + + /** + * Reads a string asynchronously. Returns Promise if file was not found. + * @param {string} filename + * @returns {Promise} + */ + readFileAsync(filename) { + abstract; + return Promise.reject(); + } + + /** + * Tries to delete a file + * @param {string} filename + * @returns {Promise} + */ + deleteFileAsync(filename) { + // Default implementation does not allow deleting files + return Promise.reject(); + } +} diff --git a/src/js/platform/wrapper.js b/src/js/platform/wrapper.js new file mode 100644 index 00000000..bda56fc2 --- /dev/null +++ b/src/js/platform/wrapper.js @@ -0,0 +1,131 @@ +/* typehints:start */ +import { Application } from "../application"; +/* typehints:end */ + +import { IS_MOBILE } from "../core/config"; + +export class PlatformWrapperInterface { + constructor(app) { + /** @type {Application} */ + this.app = app; + } + + /** @returns {string} */ + getId() { + abstract; + return "unknown-platform"; + } + + /** + * Returns the UI scale, called on every resize + * @returns {number} */ + getUiScale() { + return 1; + } + + /** @returns {boolean} */ + getSupportsRestart() { + abstract; + return false; + } + + /** + * Returns the strength of touch pans with the mouse + */ + getTouchPanStrength() { + return 1; + } + + /** @returns {Promise} */ + initialize() { + document.documentElement.classList.add("p-" + this.getId()); + return Promise.resolve(); + } + + /** + * Should initialize the apps ad provider in case supported + * @returns {Promise} + */ + initializeAdProvider() { + return Promise.resolve(); + } + + /** + * Should return the minimum supported zoom level + * @returns {number} + */ + getMinimumZoom() { + return 0.2 * this.getScreenScale(); + } + + /** + * Should return the maximum supported zoom level + * @returns {number} + */ + getMaximumZoom() { + return 4 * this.getScreenScale(); + } + + getScreenScale() { + return Math.min(window.innerWidth, window.innerHeight) / 1024.0; + } + + /** + * Should return if this platform supports ads at all + */ + getSupportsAds() { + return false; + } + + /** + * Attempt to open an external url + * @param {string} url + * @param {boolean=} force Whether to always open the url even if not allowed + */ + openExternalLink(url, force = false) { + abstract; + } + + /** + * Attempt to restart the app + */ + performRestart() { + abstract; + } + + /** + * Returns whether this platform supports a toggleable fullscreen + */ + getSupportsFullscreen() { + return false; + } + + /** + * Should set the apps fullscreen state to the desired state + * @param {boolean} flag + */ + setFullscreen(flag) { + abstract; + } + + /** + * Returns whether this platform supports quitting the app + */ + getSupportsAppExit() { + return false; + } + + /** + * Attempts to quit the app + */ + exitApp() { + abstract; + } + + /** + * Whether this platform supports a keyboard + */ + getSupportsKeyboard() { + return !IS_MOBILE; + } +} diff --git a/src/js/profile/application_settings.js b/src/js/profile/application_settings.js new file mode 100644 index 00000000..6d09c148 --- /dev/null +++ b/src/js/profile/application_settings.js @@ -0,0 +1,191 @@ +/* typehints:start */ +import { Application } from "../application"; +/* typehints:end */ + +import { ReadWriteProxy } from "../core/read_write_proxy"; +import { BoolSetting, EnumSetting, BaseSetting } from "./setting_types"; +import { createLogger } from "../core/logging"; +import { ExplainedResult } from "../core/explained_result"; + +const logger = createLogger("application_settings"); + +const categoryGame = "game"; +const categoryApp = "app"; + +export const uiScales = [ + { + id: "super_small", + size: 0.6, + label: "Super small", + }, + { + id: "small", + size: 0.8, + label: "Small", + }, + { + id: "regular", + size: 1, + label: "Regular", + }, + { + id: "large", + size: 1.2, + label: "Large", + }, + { + id: "huge", + size: 1.4, + label: "Huge", + }, +]; + +/** @type {Array} */ +export const allApplicationSettings = [ + new EnumSetting("uiScale", { + options: uiScales.sort((a, b) => a.size - b.size), + valueGetter: scale => scale.id, + textGetter: scale => scale.label, + category: categoryApp, + restartRequired: false, + changeCb: + /** + * @param {Application} app + */ + (app, id) => app.updateAfterUiScaleChanged(), + }), + new BoolSetting( + "fullscreen", + categoryApp, + /** + * @param {Application} app + */ + (app, value) => { + if (app.platformWrapper.getSupportsFullscreen()) { + app.platformWrapper.setFullscreen(value); + } + }, + G_IS_STANDALONE + ), + + // GAME +]; + +export function getApplicationSettingById(id) { + return allApplicationSettings.find(setting => setting.id === id); +} + +class SettingsStorage { + constructor() { + this.uiScale = "regular"; + this.fullscreen = G_IS_STANDALONE; + } +} + +export class ApplicationSettings extends ReadWriteProxy { + constructor(app) { + super(app, "app_settings.bin"); + } + + initialize() { + // Read and directly write latest data back + return this.readAsync().then(() => this.writeAsync()); + } + + save() { + return this.writeAsync(); + } + + // Getters + + /** + * @returns {SettingsStorage} + */ + getAllSettings() { + return this.getCurrentData().settings; + } + + /** + * @param {string} key + */ + getSetting(key) { + assert(this.getAllSettings().hasOwnProperty(key), "Setting not known: " + key); + return this.getAllSettings()[key]; + } + + getInterfaceScaleId() { + if (!this.currentData) { + // Not initialized yet + return "regular"; + } + return this.getAllSettings().uiScale; + } + + getInterfaceScaleValue() { + const id = this.getInterfaceScaleId(); + for (let i = 0; i < uiScales.length; ++i) { + if (uiScales[i].id === id) { + return uiScales[i].size; + } + } + logger.error("Unknown ui scale id:", id); + return 1; + } + + getIsFullScreen() { + return this.getAllSettings().fullscreen; + } + + // Setters + + /** + * @param {string} key + * @param {string|boolean} value + */ + updateSetting(key, value) { + assert(this.getAllSettings().hasOwnProperty(key), "Setting not known: " + key); + this.getAllSettings()[key] = value; + return this.writeAsync(); + } + + // RW Proxy impl + verify(data) { + if (!data.settings) { + return ExplainedResult.bad("missing key 'settings'"); + } + if (typeof data.settings !== "object") { + return ExplainedResult.bad("Bad settings object"); + } + + const settings = data.settings; + for (let i = 0; i < allApplicationSettings.length; ++i) { + const setting = allApplicationSettings[i]; + const storedValue = settings[setting.id]; + if (!setting.validate(storedValue)) { + return ExplainedResult.bad("Bad setting value for " + setting.id + ": " + storedValue); + } + } + return ExplainedResult.good(); + } + + getDefaultData() { + return { + version: this.getCurrentVersion(), + settings: new SettingsStorage(), + }; + } + + getCurrentVersion() { + return 1; + } + + migrate(data) { + // Simply reset + if (data.version < 1) { + data.settings = new SettingsStorage(); + data.version = 1; + } + + return ExplainedResult.good(); + } +} diff --git a/src/js/profile/setting_types.js b/src/js/profile/setting_types.js new file mode 100644 index 00000000..f35d17a6 --- /dev/null +++ b/src/js/profile/setting_types.js @@ -0,0 +1,208 @@ +/* typehints:start */ +import { Application } from "../application"; +/* typehints:end */ + +import { createLogger } from "../core/logging"; + +const logger = createLogger("setting_types"); + +export class BaseSetting { + /** + * + * @param {string} id + * @param {string} categoryId + * @param {function(Application, any):void} changeCb + * @param {boolean} enabled + */ + constructor(id, categoryId, changeCb, enabled) { + this.id = id; + this.categoryId = categoryId; + this.changeCb = changeCb; + this.enabled = enabled; + + /** @type {Application} */ + this.app = null; + + this.element = null; + this.dialogs = null; + } + + /** + * @param {Application} app + * @param {Element} element + * @param {HUDModalDialogs} dialogs + */ + bind(app, element, dialogs) { + this.app = app; + this.element = element; + this.dialogs = dialogs; + } + + getHtml() { + abstract; + return ""; + } + + syncValueToElement() { + abstract; + } + + modify() { + abstract; + } + + showRestartRequiredDialog() { + const { restart } = this.dialogs.showInfo( + "Restart required", + "You need to restart the game to apply the settings.", + this.app.platformWrapper.getSupportsRestart() ? ["later:grey", "restart:misc"] : ["ok:good"] + ); + if (restart) { + restart.add(() => this.app.platformWrapper.performRestart()); + } + } + + /** + * @param {any} value + * @returns {boolean} + */ + validate(value) { + abstract; + return false; + } +} + +export class EnumSetting extends BaseSetting { + constructor( + id, + { + options, + valueGetter, + textGetter, + descGetter = null, + category, + restartRequired = true, + iconPrefix = null, + changeCb = null, + magicValue = null, + enabled = true, + } + ) { + super(id, category, changeCb, enabled); + + this.options = options; + this.valueGetter = valueGetter; + this.textGetter = textGetter; + this.descGetter = descGetter || (() => null); + this.restartRequired = restartRequired; + this.iconPrefix = iconPrefix; + this.magicValue = magicValue; + } + + getHtml() { + return ` +
+
+ +
+
+
+ TODO: SETTING DESC +
+
`; + } + + validate(value) { + if (value === this.magicValue) { + return true; + } + + const availableValues = this.options.map(option => this.valueGetter(option)); + if (availableValues.indexOf(value) < 0) { + logger.error( + "Value '" + value + "' is not contained in available values:", + availableValues, + "of", + this.id + ); + return false; + } + return true; + } + + syncValueToElement() { + const value = this.app.settings.getSetting(this.id); + let displayText = "???"; + const matchedInstance = this.options.find(data => this.valueGetter(data) === value); + if (matchedInstance) { + displayText = this.textGetter(matchedInstance); + } else { + logger.warn("Setting value", value, "not found for", this.id, "!"); + } + this.element.innerText = displayText; + } + + modify() { + const { optionSelected } = this.dialogs.showOptionChooser("TODO: SETTING TITLE", { + active: this.app.settings.getSetting(this.id), + options: this.options.map(option => ({ + value: this.valueGetter(option), + text: this.textGetter(option), + desc: this.descGetter(option), + iconPrefix: this.iconPrefix, + })), + }); + optionSelected.add(value => { + this.app.settings.updateSetting(this.id, value); + this.syncValueToElement(); + + if (this.restartRequired) { + this.showRestartRequiredDialog(); + } + + if (this.changeCb) { + this.changeCb(this.app, value); + } + }, this); + } +} + +export class BoolSetting extends BaseSetting { + constructor(id, category, changeCb = null, enabled = true) { + super(id, category, changeCb, enabled); + } + + getHtml() { + return ` +
+
+ +
+ +
+
+
+ TODO: SETTING DESC +
+
`; + } + + syncValueToElement() { + const value = this.app.settings.getSetting(this.id); + this.element.classList.toggle("checked", value); + } + + modify() { + const newValue = !this.app.settings.getSetting(this.id); + this.app.settings.updateSetting(this.id, newValue); + this.syncValueToElement(); + + if (this.changeCb) { + this.changeCb(this.app, newValue); + } + } + + validate(value) { + return typeof value === "boolean"; + } +} diff --git a/src/js/savegame/savegame.js b/src/js/savegame/savegame.js new file mode 100644 index 00000000..f752c836 --- /dev/null +++ b/src/js/savegame/savegame.js @@ -0,0 +1,237 @@ +/* typehints:start */ +import { Application } from "../application"; +import { GameRoot } from "../game/root"; +/* typehints:end */ + +import { ReadWriteProxy } from "../core/read_write_proxy"; +import { ExplainedResult } from "../core/explained_result"; +import { SavegameSerializer } from "./savegame_serializer"; +import { BaseSavegameInterface } from "./savegame_interface"; +import { createLogger } from "../core/logging"; +import { globalConfig } from "../core/config"; +import { SavegameInterface_V1000 } from "./schemas/1000"; +import { getSavegameInterface } from "./savegame_interface_registry"; + +const logger = createLogger("savegame"); + +export class Savegame extends ReadWriteProxy { + /** + * + * @param {Application} app + * @param {object} param0 + * @param {string} param0.internalId + * @param {import("./savegame_manager").SavegameMetadata} param0.metaDataRef Handle to the meta data + */ + constructor(app, { internalId, metaDataRef }) { + super(app, "savegame-" + internalId + ".bin"); + this.internalId = internalId; + this.metaDataRef = metaDataRef; + + /** @type {SavegameData} */ + this.currentData = this.getDefaultData(); + } + + //////// RW Proxy Impl ////////// + + /** + * @returns {number} + */ + static getCurrentVersion() { + return 1015; + } + + /** + * @returns {typeof BaseSavegameInterface} + */ + static getReaderClass() { + return SavegameInterface_V1000; + } + + /** + * @returns {number} + */ + getCurrentVersion() { + return /** @type {typeof Savegame} */ (this.constructor).getCurrentVersion(); + } + + /** + * Returns the savegames default data + * @returns {SavegameData} + */ + getDefaultData() { + return { + version: this.getCurrentVersion(), + dump: null, + stats: { + buildingsPlaced: 0, + }, + lastUpdate: Date.now(), + }; + } + + /** + * Migrates the savegames data + * @param {SavegameData} data + */ + migrate(data) { + // if (data.version === 1014) { + // if (data.dump) { + // const reader = new SavegameInterface_V1015(fakeLogger, data); + // reader.migrateFrom1014(); + // } + // data.version = 1015; + // } + return ExplainedResult.good(); + } + + /** + * Verifies the savegames data + * @param {SavegameData} data + */ + verify(data) { + if (!data.dump) { + // Well, guess that works + return ExplainedResult.good(); + } + + if (!this.getDumpReaderForExternalData(data).validate()) { + return ExplainedResult.bad("dump-reader-failed-validation"); + } + return ExplainedResult.good(); + } + + //////// Subclasses interface //////// + + /** + * Returns if this game can be saved on disc + * @returns {boolean} + */ + isSaveable() { + return true; + } + /** + * Returns the statistics of the savegame + * @returns {SavegameStats} + */ + getStatistics() { + return this.currentData.stats; + } + + /** + * Returns the *real* last update of the savegame, not the one of the metadata + * which could also be the servers one + */ + getRealLastUpdate() { + return this.currentData.lastUpdate; + } + + /** + * Returns if this game has a serialized game dump + */ + hasGameDump() { + return !!this.currentData.dump; + } + + /** + * Returns the current game dump + * @returns {SerializedGame} + */ + getCurrentDump() { + return this.currentData.dump; + } + + /** + * Returns a reader to access the data + * @returns {BaseSavegameInterface} + */ + getDumpReader() { + if (!this.currentData.dump) { + logger.warn("Getting reader on null-savegame dump"); + } + + const cls = /** @type {typeof Savegame} */ (this.constructor).getReaderClass(); + return new cls(this.currentData); + } + + /** + * Returns a reader to access external data + * @returns {BaseSavegameInterface} + */ + getDumpReaderForExternalData(data) { + assert(data.version, "External data contains no version"); + return getSavegameInterface(data); + } + + ///////// Public Interface /////////// + + /** + * Updates the last update field so we can send the savegame to the server, + * WITHOUT Saving! + */ + setLastUpdate(time) { + this.currentData.lastUpdate = time; + } + + /** + * + * @param {GameRoot} root + */ + updateData(root) { + // Construct a new serializer + const serializer = new SavegameSerializer(); + + // let timer = performanceNow(); + const dump = serializer.generateDumpFromGameRoot(root); + if (!dump) { + return false; + } + // let duration = performanceNow() - timer; + // console.log("TOOK", duration, "ms to generate dump:", dump); + + const shadowData = Object.assign({}, this.currentData); + shadowData.dump = dump; + shadowData.lastUpdate = new Date().getTime(); + shadowData.version = this.getCurrentVersion(); + + const reader = this.getDumpReaderForExternalData(shadowData); + + // Validate (not in prod though) + if (!G_IS_RELEASE) { + const validationResult = reader.validate(); + if (!validationResult) { + return false; + } + } + + // Save data + this.currentData = shadowData; + } + + /** + * Writes the savegame as well as its metadata + */ + writeSavegameAndMetadata() { + return this.writeAsync().then(() => this.saveMetadata()); + } + + /** + * Updates the savegames metadata + */ + saveMetadata() { + const reader = this.getDumpReader(); + this.metaDataRef.lastUpdate = new Date().getTime(); + this.metaDataRef.version = this.getCurrentVersion(); + return this.app.savegameMgr.writeAsync(); + } + + /** + * @see ReadWriteProxy.writeAsync + * @returns {Promise} + */ + writeAsync() { + if (G_IS_DEV && globalConfig.debug.disableSavegameWrite) { + return Promise.resolve(); + } + return super.writeAsync(); + } +} diff --git a/src/js/savegame/savegame_interface.js b/src/js/savegame/savegame_interface.js new file mode 100644 index 00000000..66cada22 --- /dev/null +++ b/src/js/savegame/savegame_interface.js @@ -0,0 +1,108 @@ +import { createLogger } from "../core/logging"; + +const Ajv = require("ajv"); +const ajv = new Ajv({ + allErrors: false, + uniqueItems: false, + unicode: false, + nullable: false, +}); + +const validators = {}; + +const logger = createLogger("savegame_interface"); + +export class BaseSavegameInterface { + /** + * Returns the interfaces version + */ + getVersion() { + throw new Error("Implement get version"); + } + + /** + * Returns the uncached json schema + * @returns {object} + */ + getSchemaUncached() { + throw new Error("Implement get schema"); + return {}; + } + + getValidator() { + const version = this.getVersion(); + if (validators[version]) { + return validators[version]; + } + logger.log("Compiling schema for savegame version", version); + const schema = this.getSchemaUncached(); + try { + validators[version] = ajv.compile(schema); + } catch (ex) { + logger.error("SCHEMA FOR", this.getVersion(), "IS INVALID!"); + logger.error(ex); + throw new Error("Invalid schema for version " + version); + } + return validators[version]; + } + + /** + * Constructs an new interface for the given savegame + * @param {any} data + */ + constructor(data) { + this.data = data; + } + + /** + * Validates the data + * @returns {boolean} + */ + validate() { + const validator = this.getValidator(); + + if (!validator(this.data)) { + logger.error( + "Savegame failed validation! ErrorText:", + ajv.errorsText(validator.errors), + "RawErrors:", + validator.errors + ); + return false; + } + + return true; + } + + ///// INTERFACE (Override when the schema changes) ///// + + /** + * Returns the time of last update + * @returns {number} + */ + readLastUpdate() { + return this.data.lastUpdate; + } + + /** + * Returns the ingame time in seconds + * @returns {number} + */ + readIngameTimeSeconds() { + return this.data.dump.time.timeSeconds; + } + + /** + + + //////// ANTICHEAT /////// + + /** + * Detects cheats in the savegmae - returns false if the game looks cheated + */ + performAnticheatCheck() { + // TODO + + return true; + } +} diff --git a/src/js/savegame/savegame_interface_registry.js b/src/js/savegame/savegame_interface_registry.js new file mode 100644 index 00000000..6ad22a42 --- /dev/null +++ b/src/js/savegame/savegame_interface_registry.js @@ -0,0 +1,35 @@ +import { BaseSavegameInterface } from "./savegame_interface"; +import { SavegameInterface_V1000 } from "./schemas/1000"; +import { createLogger } from "../core/logging"; + +/** @type {Object.} */ +const interfaces = { + 1000: SavegameInterface_V1000, +}; + +const logger = createLogger("savegame_interface_registry"); + +/** + * Returns if the given savegame has any supported interface + * @param {any} savegame + * @returns {BaseSavegameInterface|null} + */ +export function getSavegameInterface(savegame) { + if (!savegame || !savegame.version) { + logger.warn("Savegame does not contain a valid version (undefined)"); + return null; + } + const version = savegame.version; + if (!Number.isInteger(version)) { + logger.warn("Savegame does not contain a valid version (non-integer):", version); + return null; + } + + const interfaceClass = interfaces[version]; + if (!interfaceClass) { + logger.warn("Version", version, "has no implemented interface!"); + return null; + } + + return new interfaceClass(savegame); +} diff --git a/src/js/savegame/savegame_manager.js b/src/js/savegame/savegame_manager.js new file mode 100644 index 00000000..69a275bb --- /dev/null +++ b/src/js/savegame/savegame_manager.js @@ -0,0 +1,211 @@ +import { ExplainedResult } from "../core/explained_result"; +import { createLogger } from "../core/logging"; +import { ReadWriteProxy } from "../core/read_write_proxy"; +import { globalConfig } from "../core/config"; +import { Savegame } from "./savegame"; +import { Math_floor } from "../core/builtins"; + +const logger = createLogger("savegame_manager"); + +const Rusha = require("rusha"); + +/** @enum {string} */ +export const enumLocalSavegameStatus = { + offline: "offline", + synced: "synced", +}; + +/** + * @typedef {{ + * lastUpdate: number, + * version: number, + * internalId: string + * }} SavegameMetadata + * + * @typedef {{ + * version: number, + * savegames: Array + * }} SavegamesData + */ + +export class SavegameManager extends ReadWriteProxy { + constructor(app) { + super(app, "savegames.bin"); + + /** @type {SavegamesData} */ + this.currentData = this.getDefaultData(); + } + + // RW Proxy Impl + /** + * @returns {SavegamesData} + */ + getDefaultData() { + return { + version: this.getCurrentVersion(), + savegames: [], + }; + } + + getCurrentVersion() { + return 1000; + } + + /** + * @returns {SavegamesData} + */ + getCurrentData() { + return super.getCurrentData(); + } + + verify(data) { + // TODO / FIXME!!!! + return ExplainedResult.good(); + } + + /** + * + * @param {SavegamesData} data + */ + migrate(data) { + return ExplainedResult.good(); + } + + // End rw proxy + + /** + * @returns {Array} + */ + getSavegamesMetaData() { + return this.currentData.savegames; + } + + /** + * + * @param {string} internalId + * @returns {Savegame} + */ + getSavegameById(internalId) { + const metadata = this.getGameMetaDataByInternalId(internalId); + if (!metadata) { + return null; + } + return new Savegame(this.app, { internalId, metaDataRef: metadata }); + } + + /** + * Deletes a savegame + * @param {SavegameMetadata} game + */ + deleteSavegame(game) { + const handle = new Savegame(this.app, { + internalId: game.internalId, + metaDataRef: game, + }); + + return handle.deleteAsync().then(() => { + for (let i = 0; i < this.currentData.savegames.length; ++i) { + const potentialGame = this.currentData.savegames[i]; + if (potentialGame.internalId === handle.internalId) { + this.currentData.savegames.splice(i, 1); + break; + } + } + + return this.writeAsync(); + }); + } + + /** + * Returns a given games metadata by id + * @param {string} id + * @returns {SavegameMetadata} + */ + getGameMetaDataByInternalId(id) { + for (let i = 0; i < this.currentData.savegames.length; ++i) { + const data = this.currentData.savegames[i]; + if (data.internalId === id) { + return data; + } + } + logger.error("Savegame internal id not found:", id); + return null; + } + + /** + * Creates a new savegame + * @returns {Savegame} + */ + createNewSavegame() { + const id = this.generateInternalId(); + + const metaData = /** @type {SavegameMetadata} */ ({ + lastUpdate: Date.now(), + version: Savegame.getCurrentVersion(), + internalId: id, + }); + + this.currentData.savegames.push(metaData); + this.sortSavegames(); + + return new Savegame(this.app, { + internalId: id, + metaDataRef: metaData, + }); + } + + /** + * Sorts all savegames by their creation time descending + * @returns {Promise} + */ + sortSavegames() { + this.currentData.savegames.sort((a, b) => b.lastUpdate - a.lastUpdate); + let promiseChain = Promise.resolve(); + while (this.currentData.savegames.length > 100) { + const toRemove = this.currentData.savegames.pop(); + + // Try to remove the savegame since its no longer available + const game = new Savegame(this.app, { + internalId: toRemove.internalId, + metaDataRef: toRemove, + }); + promiseChain = promiseChain + .then(() => game.deleteAsync()) + .then( + () => {}, + err => { + logger.error(this, "Failed to remove old savegame:", toRemove, ":", err); + } + ); + } + + return promiseChain; + } + + /** + * Helper method to generate a new internal savegame id + */ + generateInternalId() { + const timestamp = ("" + Math_floor(Date.now() / 1000.0 - 1565641619)).padStart(10, "0"); + return ( + timestamp + + "." + + Rusha.createHash() + .update(Date.now() + "/" + Math.random()) + .digest("hex") + ); + } + + // End + + initialize() { + // First read, then directly write to ensure we have the latest data + // @ts-ignore + return this.readAsync().then(() => { + if (G_IS_DEV && globalConfig.debug.disableSavegameWrite) { + return Promise.resolve(); + } + return this.writeAsync(); + }); + } +} diff --git a/src/js/savegame/savegame_serializer.js b/src/js/savegame/savegame_serializer.js new file mode 100644 index 00000000..0c02e550 --- /dev/null +++ b/src/js/savegame/savegame_serializer.js @@ -0,0 +1,216 @@ +/* typehints:start */ +import { Component } from "../game/component"; +import { GameRoot } from "../game/root"; +/* typehints:end */ + +import { JSON_stringify } from "../core/builtins"; +import { ExplainedResult } from "../core/explained_result"; +import { createLogger } from "../core/logging"; +// import { BuildingComponent } from "../components/impl/building"; +import { gComponentRegistry } from "../core/global_registries"; +import { SerializerInternal } from "./serializer_internal"; + +const logger = createLogger("savegame_serializer"); + +/** + * Allows to serialize a savegame + */ +export class SavegameSerializer { + constructor() { + this.internal = new SerializerInternal(); + } + + /** + * Serializes the game root into a dump + * @param {GameRoot} root + * @param {boolean=} sanityChecks Whether to check for validity + * @returns {SerializedGame} + */ + generateDumpFromGameRoot(root, sanityChecks = true) { + // Finalize particles before saving (Like granting destroy indicator rewards) + // root.particleMgr.finalizeBeforeSave(); + // root.uiParticleMgr.finalizeBeforeSave(); + + // Now store generic savegame payload + const data = /** @type {SerializedGame} */ ({ + camera: root.camera.serialize(), + time: root.time.serialize(), + entityMgr: root.entityMgr.serialize(), + entities: {}, + }); + + // Serialize all types of entities + const serializeEntities = component => + this.internal.serializeEntityArray(root.entityMgr.getAllWithComponent(component)); + const serializeEntitiesFixed = component => + this.internal.serializeEntityArrayFixedType(root.entityMgr.getAllWithComponent(component)); + + // data.entities.resources = serializeEntitiesFixed(RawMaterialComponent); + // data.entities.buildings = serializeEntities(BuildingComponent); + + if (!G_IS_RELEASE) { + if (sanityChecks) { + // Sanity check + const sanity = this.verifyLogicalErrors(data); + if (!sanity.result) { + logger.error("Created invalid savegame:", sanity.reason, "savegame:", data); + return null; + } + } + } + + return data; + } + + /** + * Verifies if there are logical errors in the savegame + * @param {SerializedGame} savegame + * @returns {ExplainedResult} + */ + verifyLogicalErrors(savegame) { + if (!savegame.entities) { + return ExplainedResult.bad("Savegame has no entities"); + } + + const seenUids = []; + + // Check for duplicate UIDS + for (const entityListId in savegame.entities) { + for (let i = 0; i < savegame.entities[entityListId].length; ++i) { + const list = savegame.entities[entityListId][i]; + for (let k = 0; k < list.length; ++k) { + const entity = list[k]; + const uid = entity.uid; + if (!Number.isInteger(uid)) { + return ExplainedResult.bad("Entity has invalid uid: " + uid); + } + if (seenUids.indexOf(uid) >= 0) { + return ExplainedResult.bad("Duplicate uid " + uid); + } + seenUids.push(uid); + + // Verify components + if (!entity.components) { + return ExplainedResult.bad( + "Entity is missing key 'components': " + JSON_stringify(entity) + ); + } + const components = entity.components; + for (const componentId in components) { + // Verify component data + const componentData = components[componentId]; + const componentClass = gComponentRegistry.findById(componentId); + + // Check component id is known + if (!componentClass) { + return ExplainedResult.bad("Unknown component id: " + componentId); + } + + // Check component data is ok + const componentVerifyError = /** @type {typeof Component} */ (componentClass).verify( + componentData + ); + if (componentVerifyError) { + return ExplainedResult.bad( + "Component " + componentId + " has invalid data: " + componentVerifyError + ); + } + } + } + } + } + + return ExplainedResult.good(); + } + + /** + * Tries to load the savegame from a given dump + * @param {SerializedGame} savegame + * @param {GameRoot} root + * @returns {ExplainedResult} + */ + deserialize(savegame, root) { + // Sanity + const verifyResult = this.verifyLogicalErrors(savegame); + if (!verifyResult.result) { + return ExplainedResult.bad(verifyResult.reason); + } + + let errorReason = null; + + // entities + errorReason = errorReason || root.entityMgr.deserialize(savegame.entityMgr); + + // resources + errorReason = + errorReason || + this.internal.deserializeEntityArrayFixedType( + root, + savegame.entities.resources, + this.internal.deserializeResource + ); + + // buildings + errorReason = + errorReason || + this.internal.deserializeEntityArray( + root, + savegame.entities.buildings, + this.internal.deserializeBuilding + ); + + // other stuff + errorReason = errorReason || root.time.deserialize(savegame.time); + errorReason = errorReason || root.camera.deserialize(savegame.camera); + + // Check for errors + if (errorReason) { + return ExplainedResult.bad(errorReason); + } + + return ExplainedResult.good(); + } + + /////////// MIGRATION HELPERS /////////// + + /** + * Performs a function on each component (useful to add / remove / alter properties for migration) + * @param {SerializedGame} savegame + * @param {typeof Component} componentHandle + * @param {function} modifier + */ + migration_migrateComponent(savegame, componentHandle, modifier) { + const targetId = componentHandle.getId(); + for (const entityListId in savegame.entities) { + for (let i = 0; i < savegame.entities[entityListId].length; ++i) { + const list = savegame.entities[entityListId][i]; + for (let k = 0; k < list.length; ++k) { + const entity = list[k]; + const components = entity.components; + if (components[targetId]) { + modifier(components[targetId]); + } + } + } + } + } + + /** + * Performs an operation on each object which is a PooledObject (usually Projectiles). Useful to + * perform migrations + * @param {Array} pools + * @param {string} targetClassKey + * @param {function} modifier + */ + migration_migrateGenericObjectPool(pools, targetClassKey, modifier) { + for (let i = 0; i < pools.length; ++i) { + const pool = pools[i]; + if (pool.key === targetClassKey) { + const entries = pool.data.entries; + for (const uid in entries) { + modifier(entries[uid]); + } + } + } + } +} diff --git a/src/js/savegame/savegame_typedefs.js b/src/js/savegame/savegame_typedefs.js new file mode 100644 index 00000000..3ab73761 --- /dev/null +++ b/src/js/savegame/savegame_typedefs.js @@ -0,0 +1,35 @@ +/** + * @typedef {{ + * buildingsPlaced: number + * }} SavegameStats + */ + +/** + * @typedef {{ + * x: number, + * y: number, + * uid: number, + * key: string + * }} SerializedMapResource + */ + +/** + * @typedef {{ + * camera: any, + * time: any, + * entityMgr: any, + * entities: { + * resources: Array, + * buildings: Array + * } + * }} SerializedGame + */ + +/** + * @typedef {{ + * version: number, + * dump: SerializedGame, + * stats: SavegameStats, + * lastUpdate: number + * }} SavegameData + */ diff --git a/src/js/savegame/schemas/1000.js b/src/js/savegame/schemas/1000.js new file mode 100644 index 00000000..29cd0b1a --- /dev/null +++ b/src/js/savegame/schemas/1000.js @@ -0,0 +1,13 @@ +import { BaseSavegameInterface } from "../savegame_interface.js"; + +const schema = require("./1000.json"); + +export class SavegameInterface_V1000 extends BaseSavegameInterface { + getVersion() { + return 1000; + } + + getSchemaUncached() { + return schema; + } +} diff --git a/src/js/savegame/schemas/1000.json b/src/js/savegame/schemas/1000.json new file mode 100644 index 00000000..6682f615 --- /dev/null +++ b/src/js/savegame/schemas/1000.json @@ -0,0 +1,5 @@ +{ + "type": "object", + "required": [], + "additionalProperties": true +} diff --git a/src/js/savegame/serialization.js b/src/js/savegame/serialization.js new file mode 100644 index 00000000..a6c8f4c0 --- /dev/null +++ b/src/js/savegame/serialization.js @@ -0,0 +1,330 @@ +import { JSON_stringify } from "../core/builtins"; +import { + BaseDataType, + TypeArray, + TypeBoolean, + TypeClass, + TypeClassId, + TypeEntity, + TypeEntityWeakref, + TypeEnum, + TypeFixedClass, + TypeInteger, + TypeKeyValueMap, + TypeMetaClass, + TypeNullable, + TypeNumber, + TypePair, + TypePositiveInteger, + TypePositiveNumber, + TypeString, + TypeVector, + TypeClassFromMetaclass, + TypeClassData, +} from "./serialization_data_types"; +import { createLogger } from "../core/logging"; + +const logger = createLogger("serialization"); + +// Schema declarations +export const types = { + int: new TypeInteger(), + uint: new TypePositiveInteger(), + float: new TypeNumber(), + ufloat: new TypePositiveNumber(), + string: new TypeString(), + entity: new TypeEntity(), + weakEntityRef: new TypeEntityWeakref(), + vector: new TypeVector(), + tileVector: new TypeVector(), + bool: new TypeBoolean(), + + /** + * @param {BaseDataType} wrapped + */ + nullable(wrapped) { + return new TypeNullable(wrapped); + }, + + /** + * @param {FactoryTemplate<*>|SingletonFactoryTemplate<*>} registry + */ + classId(registry) { + return new TypeClassId(registry); + }, + /** + * @param {BaseDataType} valueType + * @param {boolean=} includeEmptyValues + */ + keyValueMap(valueType, includeEmptyValues = true) { + return new TypeKeyValueMap(valueType, includeEmptyValues); + }, + + /** + * @param {Array} values + */ + enum(values) { + return new TypeEnum(values); + }, + + /** + * @param {FactoryTemplate<*>} registry + */ + obj(registry) { + return new TypeClass(registry); + }, + + /** + * @param {FactoryTemplate<*>} registry + */ + objData(registry) { + return new TypeClassData(registry); + }, + + /** + * @param {typeof BasicSerializableObject} cls + */ + knownType(cls) { + return new TypeFixedClass(cls); + }, + + /** + * @param {BaseDataType} innerType + */ + array(innerType) { + return new TypeArray(innerType); + }, + + /** + * @param {SingletonFactoryTemplate<*>} innerType + */ + classRef(registry) { + return new TypeMetaClass(registry); + }, + + /** + * @param {BaseDataType} a + * @param {BaseDataType} b + */ + pair(a, b) { + return new TypePair(a, b); + }, + + /** + * @param {typeof BasicSerializableObject} classHandle + * @param {SingletonFactoryTemplate<*>} registry + */ + classWithMetaclass(classHandle, registry) { + return new TypeClassFromMetaclass(classHandle, registry); + }, +}; + +/** + * A full schema declaration + * @typedef {Object.} Schema + */ + +const globalSchemaCache = {}; + +/* dev:start */ +const classnamesCache = {}; +/* dev:end*/ + +export class BasicSerializableObject { + /* dev:start */ + /** + * Fixes typeof DerivedComponent is not assignable to typeof Component, compiled out + * in non-dev builds + */ + constructor(...args) {} + + /* dev:end */ + + static getId() { + abstract; + } + + /** + * Should return the serialization schema + * @returns {Schema} + */ + static getSchema() { + return {}; + } + + // Implementation + /** @returns {Schema} */ + static getCachedSchema() { + const id = this.getId(); + + /* dev:start */ + assert( + classnamesCache[id] === this || classnamesCache[id] === undefined, + "Class name taken twice: " + id + " (from " + this.name + ")" + ); + classnamesCache[id] = this; + /* dev:end */ + + const entry = globalSchemaCache[id]; + if (entry) { + return entry; + } + + const schema = this.getSchema(); + globalSchemaCache[id] = schema; + return schema; + } + + /** @returns {object} */ + serialize() { + return serializeSchema( + this, + /** @type {typeof BasicSerializableObject} */ (this.constructor).getCachedSchema() + ); + } + + /** @returns {string|void} */ + deserialize(data) { + return deserializeSchema( + this, + /** @type {typeof BasicSerializableObject} */ (this.constructor).getCachedSchema(), + data + ); + } + + /** @returns {string|void} */ + static verify(data) { + return verifySchema(this.getCachedSchema(), data); + } +} + +/** + * Serializes an object using the given schema, mergin with the given properties + * @param {object} obj The object to serialize + * @param {Schema} schema The schema to use + * @param {object=} mergeWith Any additional properties to merge with the schema, useful for super calls + * @returns {object} Serialized data object + */ +export function serializeSchema(obj, schema, mergeWith = {}) { + for (const key in schema) { + if (!obj.hasOwnProperty(key)) { + logger.error("Invalid schema, property", key, "does not exist on", obj, "(schema=", schema, ")"); + assert( + obj.hasOwnProperty(key), + "serialization: invalid schema, property does not exist on object: " + key + ); + } + if (!schema[key]) { + assert(false, "Invalid schema: " + JSON_stringify(schema) + " / " + key); + } + + if (G_IS_DEV) { + try { + mergeWith[key] = schema[key].serialize(obj[key]); + } catch (ex) { + logger.error( + "Serialization of", + obj, + "failed on key '" + key + "' ->", + ex, + "(schema was", + schema, + ")" + ); + throw ex; + } + } else { + mergeWith[key] = schema[key].serialize(obj[key]); + } + } + return mergeWith; +} + +/** + * Deserializes data into an object + * @param {object} obj The object to store the deserialized data into + * @param {Schema} schema The schema to use + * @param {object} data The serialized data + * @param {string|void|null=} baseclassErrorResult Convenience, if this is a string error code, do nothing and return it + * @returns {string|void} String error code or nothing on success + */ +export function deserializeSchema(obj, schema, data, baseclassErrorResult = null) { + if (baseclassErrorResult) { + return baseclassErrorResult; + } + + if (!data) { + logger.error("Got 'NULL' data for", obj, "and schema", schema, "!"); + return "Got null data"; + } + + for (const key in schema) { + if (!data.hasOwnProperty(key)) { + logger.error("Data", data, "does not contain", key, "(schema:", schema, ")"); + return "Missing key in schema: " + key + " of class " + obj.constructor.name; + } + if (!schema[key].allowNull() && (data[key] === null || data[key] === undefined)) { + logger.error("Data", data, "has null value for", key, "(schema:", schema, ")"); + return "Non-nullable entry is null: " + key + " of class " + obj.constructor.name; + } + + const errorStatus = schema[key].deserializeWithVerify(data[key], obj, key, obj.root); + if (errorStatus) { + error( + "serialization", + "Deserialization failed with error '" + errorStatus + "' on object", + obj, + "and key", + key, + "(root? =", + obj.root ? "y" : "n", + ")" + ); + return errorStatus; + } + } +} + +/** + * Verifies stored data using the given schema + * @param {Schema} schema The schema to use + * @param {object} data The data to verify + * @returns {string|void} String error code or nothing on success + */ +export function verifySchema(schema, data) { + for (const key in schema) { + if (!data.hasOwnProperty(key)) { + error("verify", "Data", data, "does not contain", key, "(schema:", schema, ")"); + return "verify: missing key required by schema in stored data: " + key; + } + if (!schema[key].allowNull() && (data[key] === null || data[key] === undefined)) { + error("verify", "Data", data, "has null value for", key, "(schema:", schema, ")"); + return "verify: non-nullable entry is null: " + key; + } + + const errorStatus = schema[key].verifySerializedValue(data[key]); + if (errorStatus) { + error("verify", errorStatus); + return "verify: " + errorStatus; + } + } +} + +/** + * Extends a schema by adding the properties from the new schema to the existing base schema + * @param {Schema} base + * @param {Schema} newOne + * @returns {Schema} + */ +export function extendSchema(base, newOne) { + /** @type {Schema} */ + const result = Object.assign({}, base); + for (const key in newOne) { + if (result.hasOwnProperty(key)) { + logger.error("Extend schema got duplicate key:", key); + continue; + } + result[key] = newOne[key]; + } + return result; +} diff --git a/src/js/savegame/serialization_data_types.js b/src/js/savegame/serialization_data_types.js new file mode 100644 index 00000000..240e2313 --- /dev/null +++ b/src/js/savegame/serialization_data_types.js @@ -0,0 +1,1204 @@ +/* typehints:start */ +import { GameRoot } from "../game/root"; +import { BasicSerializableObject } from "./serialization"; +/* typehints:end */ + +import { Vector } from "../core/vector"; +import { round4Digits, schemaObject } from "../core/utils"; +import { JSON_stringify } from "../core/builtins"; + +export const globalJsonSchemaDefs = {}; + +/** + * + * @param {import("./serialization").Schema} schema + */ +export function schemaToJsonSchema(schema) { + const jsonSchema = { + type: "object", + additionalProperties: false, + required: [], + properties: {}, + }; + + for (const key in schema) { + const subSchema = schema[key].getAsJsonSchema(); + jsonSchema.required.push(key); + jsonSchema.properties[key] = subSchema; + } + + return jsonSchema; +} + +/** + * Base serialization data type + */ +export class BaseDataType { + /** + * Serializes a given raw value + * @param {any} value + */ + serialize(value) { + abstract; + return {}; + } + + /** + * Verifies a given serialized value + * @param {any} value + * @returns {string|void} String error code or null on success + */ + verifySerializedValue(value) {} + + /** + * Deserializes a serialized value into the target object under the given key + * @param {any} value + * @param {GameRoot} root + * @param {object} targetObject + * @param {string|number} targetKey + * @returns {string|void} String error code or null on success + */ + deserialize(value, targetObject, targetKey, root) { + abstract; + } + + /** + * Returns the json schema + */ + getAsJsonSchema() { + const key = this.getCacheKey(); + const schema = this.getAsJsonSchemaUncached(); + + if (!globalJsonSchemaDefs[key]) { + // schema.$id = key; + globalJsonSchemaDefs[key] = schema; + } + + return { + $ref: "#/definitions/" + key, + }; + + // return this.getAsJsonSchemaUncached(); + // if (!globalJsonSchemaDefs[key]) { + // // schema.$id = key; + // globalJsonSchemaDefs[key] = { + // $id: key, + // definitions: { + // ["d-" + key]: schema + // } + // }; + // } + + // return { + // $ref: key + "#/definitions/d-" + key + // } + + // // return this.getAsJsonSchemaUncached(); + } + + /** + * INTERNAL Should return the json schema representation + */ + getAsJsonSchemaUncached() { + abstract; + } + + /** + * Returns whether null values are okay + * @returns {boolean} + */ + allowNull() { + return false; + } + + // Helper methods + + /** + * Deserializes a serialized value, but performs integrity checks before + * @param {any} value + * @param {GameRoot} root + * @param {object} targetObject + * @param {string|number} targetKey + * @returns {string|void} String error code or null on success + */ + deserializeWithVerify(value, targetObject, targetKey, root) { + const errorCode = this.verifySerializedValue(value); + if (errorCode) { + return ( + "serialization verify failed: " + + errorCode + + " [value " + + JSON_stringify(value).substr(0, 100) + + "]" + ); + } + return this.deserialize(value, targetObject, targetKey, root); + } + + /** + * Should return a cacheable key + */ + getCacheKey() { + abstract; + return ""; + } +} + +export class TypeInteger extends BaseDataType { + serialize(value) { + assert(Number.isInteger(value), "Type integer got non integer for serialize: " + value); + return value; + } + + /** + * @see BaseDataType.deserialize + * @param {any} value + * @param {GameRoot} root + * @param {object} targetObject + * @param {string|number} targetKey + * @returns {string|void} String error code or null on success + */ + deserialize(value, targetObject, targetKey, root) { + targetObject[targetKey] = value; + } + + getAsJsonSchemaUncached() { + return { + type: "integer", + }; + } + + verifySerializedValue(value) { + if (!Number.isInteger(value)) { + return "Not a valid number"; + } + } + + getCacheKey() { + return "int"; + } +} + +export class TypePositiveInteger extends BaseDataType { + serialize(value) { + assert(Number.isInteger(value), "Type integer got non integer for serialize: " + value); + assert(value >= 0, "value < 0: " + value); + return value; + } + + /** + * @see BaseDataType.deserialize + * @param {any} value + * @param {GameRoot} root + * @param {object} targetObject + * @param {string|number} targetKey + * @returns {string|void} String error code or null on success + */ + deserialize(value, targetObject, targetKey, root) { + targetObject[targetKey] = value; + } + + getAsJsonSchemaUncached() { + return { + type: "integer", + minimum: 0, + }; + } + + verifySerializedValue(value) { + if (!Number.isInteger(value)) { + return "Not a valid number"; + } + if (value < 0) { + return "Negative value for positive integer"; + } + } + + getCacheKey() { + return "uint"; + } +} + +export class TypeBoolean extends BaseDataType { + serialize(value) { + assert(value === true || value === false, "Type bool got non bool for serialize: " + value); + return value; + } + + /** + * @see BaseDataType.deserialize + * @param {any} value + * @param {GameRoot} root + * @param {object} targetObject + * @param {string|number} targetKey + * @returns {string|void} String error code or null on success + */ + deserialize(value, targetObject, targetKey, root) { + targetObject[targetKey] = value; + } + + getAsJsonSchemaUncached() { + return { + type: "boolean", + }; + } + + verifySerializedValue(value) { + if (value !== true && value !== false) { + return "Not a boolean"; + } + } + + getCacheKey() { + return "bool"; + } +} + +export class TypeString extends BaseDataType { + serialize(value) { + assert(typeof value === "string", "Type string got non string for serialize: " + value); + return value; + } + + /** + * @see BaseDataType.deserialize + * @param {any} value + * @param {GameRoot} root + * @param {object} targetObject + * @param {string|number} targetKey + * @returns {string|void} String error code or null on success + */ + deserialize(value, targetObject, targetKey, root) { + targetObject[targetKey] = value; + } + getAsJsonSchemaUncached() { + return { + type: "string", + }; + } + + verifySerializedValue(value) { + if (typeof value !== "string") { + return "Not a valid string"; + } + } + + getCacheKey() { + return "string"; + } +} + +export class TypeVector extends BaseDataType { + serialize(value) { + assert(value instanceof Vector, "Type vector got non vector for serialize: " + value); + return { + x: round4Digits(value.x), + y: round4Digits(value.y), + }; + } + + getAsJsonSchemaUncached() { + return schemaObject({ + x: { + type: "number", + }, + y: { + type: "number", + }, + }); + } + + /** + * @see BaseDataType.deserialize + * @param {any} value + * @param {GameRoot} root + * @param {object} targetObject + * @param {string|number} targetKey + * @returns {string|void} String error code or null on success + */ + deserialize(value, targetObject, targetKey, root) { + targetObject[targetKey] = new Vector(value.x, value.y); + } + + verifySerializedValue(value) { + if (!Number.isFinite(value.x) || !Number.isFinite(value.y)) { + return "Not a valid vector, missing x/y or bad data type"; + } + } + + getCacheKey() { + return "vector"; + } +} + +export class TypeTileVector extends BaseDataType { + serialize(value) { + assert(value instanceof Vector, "Type vector got non vector for serialize: " + value); + assert(Number.isInteger(value.x) && value.x > 0, "Invalid tile x:" + value.x); + assert(Number.isInteger(value.y) && value.y > 0, "Invalid tile x:" + value.y); + return { x: value.x, y: value.y }; + } + + getAsJsonSchemaUncached() { + return schemaObject({ + x: { + type: "integer", + minimum: 0, + maximum: 256, + }, + y: { + type: "integer", + minimum: 0, + maximum: 256, + }, + }); + } + + /** + * @see BaseDataType.deserialize + * @param {any} value + * @param {GameRoot} root + * @param {object} targetObject + * @param {string|number} targetKey + * @returns {string|void} String error code or null on success + */ + deserialize(value, targetObject, targetKey, root) { + targetObject[targetKey] = new Vector(value.x, value.y); + } + + verifySerializedValue(value) { + if (!Number.isInteger(value.x) || !Number.isInteger(value.y)) { + return "Not a valid tile vector, missing x/y or bad data type"; + } + if (value.x < 0 || value.y < 0) { + return "Invalid tile vector, x or y < 0"; + } + } + + getCacheKey() { + return "tilevector"; + } +} + +export class TypeNumber extends BaseDataType { + serialize(value) { + assert(Number.isFinite(value), "Type number got non number for serialize: " + value); + assert(!Number.isNaN(value), "Value is nan: " + value); + return round4Digits(value); + } + + getAsJsonSchemaUncached() { + return { + type: "number", + }; + } + + /** + * @see BaseDataType.deserialize + * @param {any} value + * @param {GameRoot} root + * @param {object} targetObject + * @param {string|number} targetKey + * @returns {string|void} String error code or null on success + */ + deserialize(value, targetObject, targetKey, root) { + targetObject[targetKey] = value; + } + + verifySerializedValue(value) { + if (!Number.isFinite(value)) { + return "Not a valid number: " + value; + } + } + + getCacheKey() { + return "float"; + } +} + +export class TypePositiveNumber extends BaseDataType { + serialize(value) { + assert(Number.isFinite(value), "Type number got non number for serialize: " + value); + assert(value >= 0, "Postitive number got negative value: " + value); + return round4Digits(value); + } + + /** + * @see BaseDataType.deserialize + * @param {any} value + * @param {GameRoot} root + * @param {object} targetObject + * @param {string|number} targetKey + * @returns {string|void} String error code or null on success + */ + deserialize(value, targetObject, targetKey, root) { + targetObject[targetKey] = value; + } + + getAsJsonSchemaUncached() { + return { + type: "number", + minimum: 0, + }; + } + + verifySerializedValue(value) { + if (!Number.isFinite(value)) { + return "Not a valid number: " + value; + } + if (value < 0) { + return "Positive number got negative value: " + value; + } + } + + getCacheKey() { + return "ufloat"; + } +} + +export class TypeEnum extends BaseDataType { + /** + * @param {Array} availableValues + */ + constructor(availableValues = []) { + super(); + this.availableValues = availableValues; + } + + serialize(value) { + assert(this.availableValues.indexOf(value) >= 0, "Unknown value: " + value); + return value; + } + + /** + * @see BaseDataType.deserialize + * @param {any} value + * @param {GameRoot} root + * @param {object} targetObject + * @param {string|number} targetKey + * @returns {string|void} String error code or null on success + */ + deserialize(value, targetObject, targetKey, root) { + targetObject[targetKey] = value; + } + + getAsJsonSchemaUncached() { + return { + type: "string", + enum: this.availableValues, + }; + } + + verifySerializedValue(value) { + if (this.availableValues.indexOf(value) < 0) { + return "Unknown enum value: " + value; + } + } + + getCacheKey() { + return "enum." + this.availableValues.join(","); + } +} + +export class TypeEntity extends BaseDataType { + serialize(value) { + // assert(value instanceof Entity, "Not a valid entity ref: " + value); + assert(value.uid, "Entity has no uid yet"); + assert(!value.destroyed, "Entity already destroyed"); + assert(!value.queuedForDestroy, "Entity queued for destroy"); + + return value.uid; + } + + getAsJsonSchemaUncached() { + return { + type: "integer", + minimum: 0, + }; + } + + /** + * @see BaseDataType.deserialize + * @param {any} value + * @param {GameRoot} root + * @param {object} targetObject + * @param {string|number} targetKey + * @returns {string|void} String error code or null on success + */ + deserialize(value, targetObject, targetKey, root) { + const entity = root.entityMgr.findByUid(value); + if (!entity) { + return "Entity not found by uid: " + value; + } + targetObject[targetKey] = entity; + } + + verifySerializedValue(value) { + if (!Number.isFinite(value)) { + return "Not a valid uuid: " + value; + } + } + + getCacheKey() { + return "entity"; + } +} + +export class TypeEntityWeakref extends BaseDataType { + serialize(value) { + if (value === null) { + return null; + } + + // assert(value instanceof Entity, "Not a valid entity ref (weak): " + value); + assert(value.uid, "Entity has no uid yet"); + if (value.destroyed || value.queuedForDestroy) { + return null; + } + return value.uid; + } + + /** + * @see BaseDataType.deserialize + * @param {any} value + * @param {GameRoot} root + * @param {object} targetObject + * @param {string|number} targetKey + * @returns {string|void} String error code or null on success + */ + deserialize(value, targetObject, targetKey, root) { + if (value === null) { + targetObject[targetKey] = null; + return; + } + const entity = root.entityMgr.findByUid(value, false); + targetObject[targetKey] = entity; + } + + getAsJsonSchemaUncached() { + return { + type: ["null", "integer"], + minimum: 0, + }; + } + + allowNull() { + return true; + } + + verifySerializedValue(value) { + if (value !== null && !Number.isFinite(value)) { + return "Not a valid uuid: " + value; + } + } + + getCacheKey() { + return "entity-weakref"; + } +} + +export class TypeClass extends BaseDataType { + /** + * + * @param {FactoryTemplate<*>} registry + */ + constructor(registry) { + super(); + this.registry = registry; + } + + serialize(value) { + assert(typeof value === "object", "Not a class instance: " + value); + return { + $: value.constructor.getId(), + data: value.serialize(), + }; + } + + getAsJsonSchemaUncached() { + const options = []; + const entries = this.registry.getEntries(); + for (let i = 0; i < entries.length; ++i) { + const entry = entries[i]; + + options.push( + schemaObject({ + $: { + type: "string", + // @ts-ignore + enum: [entry.getId()], + }, + // @ts-ignore + data: schemaToJsonSchema(entry.getCachedSchema()), + }) + ); + } + + return { oneOf: options }; + } + + /** + * @see BaseDataType.deserialize + * @param {any} value + * @param {GameRoot} root + * @param {object} targetObject + * @param {string|number} targetKey + * @returns {string|void} String error code or null on success + */ + deserialize(value, targetObject, targetKey, root) { + const instanceClass = this.registry.findById(value.$); + if (!instanceClass || !instanceClass.prototype) { + return "Invalid class id (runtime-err): " + value.$ + "->" + instanceClass; + } + const instance = Object.create(instanceClass.prototype); + const errorState = instance.deserialize(value.data); + if (errorState) { + return errorState; + } + targetObject[targetKey] = instance; + } + + verifySerializedValue(value) { + if (!value) { + return "Got null data"; + } + + if (!this.registry.hasId(value.$)) { + return "Invalid class id: " + value.$; + } + } + + getCacheKey() { + return "class." + this.registry.getId(); + } +} + +export class TypeClassData extends BaseDataType { + /** + * + * @param {FactoryTemplate<*>} registry + */ + constructor(registry) { + super(); + this.registry = registry; + } + + serialize(value) { + assert(typeof value === "object", "Not a class instance: " + value); + return value.serialize(); + } + + getAsJsonSchemaUncached() { + const options = []; + const entries = this.registry.getEntries(); + for (let i = 0; i < entries.length; ++i) { + const entry = entries[i]; + options.push( + schemaToJsonSchema(/** @type {typeof BasicSerializableObject} */ (entry).getCachedSchema()) + ); + } + return { oneOf: options }; + } + + /** + * @see BaseDataType.deserialize + * @param {any} value + * @param {GameRoot} root + * @param {object} targetObject + * @param {string|number} targetKey + * @returns {string|void} String error code or null on success + */ + deserialize(value, targetObject, targetKey, root) { + assert(false, "can not deserialize class data"); + } + + verifySerializedValue(value) { + if (!value) { + return "Got null data"; + } + } + + getCacheKey() { + return "class." + this.registry.getId(); + } +} + +export class TypeClassFromMetaclass extends BaseDataType { + /** + * + * @param {typeof BasicSerializableObject} classHandle + * @param {SingletonFactoryTemplate<*>} registry + */ + constructor(classHandle, registry) { + super(); + this.registry = registry; + this.classHandle = classHandle; + } + + serialize(value) { + assert(typeof value === "object", "Not a class instance: " + value); + return { + $: value.getMetaclass().getId(), + data: value.serialize(), + }; + } + + getAsJsonSchemaUncached() { + // const options = []; + const ids = this.registry.getAllIds(); + + return { + $: { + type: "string", + enum: ids, + }, + data: schemaToJsonSchema(this.classHandle.getCachedSchema()), + }; + } + + /** + * @see BaseDataType.deserialize + * @param {any} value + * @param {GameRoot} root + * @param {object} targetObject + * @param {string|number} targetKey + * @returns {string|void} String error code or null on success + */ + deserialize(value, targetObject, targetKey, root) { + const metaClassInstance = this.registry.findById(value.$); + if (!metaClassInstance || !metaClassInstance.prototype) { + return "Invalid meta class id (runtime-err): " + value.$ + "->" + metaClassInstance; + } + + const instanceClass = metaClassInstance.getInstanceClass(); + const instance = Object.create(instanceClass.prototype); + const errorState = instance.deserialize(value.data); + if (errorState) { + return errorState; + } + targetObject[targetKey] = instance; + } + + verifySerializedValue(value) { + if (!value) { + return "Got null data"; + } + + if (!this.registry.hasId(value.$)) { + return "Invalid class id: " + value.$; + } + } + + getCacheKey() { + return "classofmetaclass." + this.registry.getId(); + } +} + +export class TypeMetaClass extends BaseDataType { + /** + * + * @param {SingletonFactoryTemplate<*>} registry + */ + constructor(registry) { + super(); + this.registry = registry; + } + + serialize(value) { + return value.getId(); + } + + /** + * @see BaseDataType.deserialize + * @param {any} value + * @param {GameRoot} root + * @param {object} targetObject + * @param {string|number} targetKey + * @returns {string|void} String error code or null on success + */ + deserialize(value, targetObject, targetKey, root) { + const instanceClass = this.registry.findById(value); + if (!instanceClass) { + return "Invalid class id (runtime-err): " + value; + } + targetObject[targetKey] = instanceClass; + } + + getAsJsonSchemaUncached() { + return { + type: "string", + enum: this.registry.getAllIds(), + }; + } + + verifySerializedValue(value) { + if (!value) { + return "Got null data"; + } + + if (typeof value !== "string") { + return "Got non string data"; + } + + if (!this.registry.hasId(value)) { + return "Invalid class id: " + value; + } + } + + getCacheKey() { + return "metaclass." + this.registry.getId(); + } +} + +export class TypeArray extends BaseDataType { + /** + * @param {BaseDataType} innerType + */ + constructor(innerType) { + super(); + this.innerType = innerType; + } + + serialize(value) { + assert(Array.isArray(value), "Not an array"); + const result = new Array(value.length); + for (let i = 0; i < value.length; ++i) { + result[i] = this.innerType.serialize(value[i]); + } + return result; + } + + /** + * @see BaseDataType.deserialize + * @param {any} value + * @param {GameRoot} root + * @param {object} targetObject + * @param {string|number} targetKey + * @returns {string|void} String error code or null on success + */ + deserialize(value, targetObject, targetKey, root) { + const result = new Array(value.length); + for (let i = 0; i < value.length; ++i) { + const errorStatus = this.innerType.deserializeWithVerify(value[i], result, i, root); + if (errorStatus) { + return errorStatus; + } + } + targetObject[targetKey] = result; + } + + getAsJsonSchemaUncached() { + return { + type: "array", + items: this.innerType.getAsJsonSchema(), + }; + } + + verifySerializedValue(value) { + if (!Array.isArray(value)) { + return "Not an array: " + value; + } + } + + getCacheKey() { + return "array." + this.innerType.getCacheKey(); + } +} + +export class TypeFixedClass extends BaseDataType { + /** + * + * @param {typeof BasicSerializableObject} baseclass + */ + constructor(baseclass) { + super(); + this.baseclass = baseclass; + } + + serialize(value) { + assert(value instanceof this.baseclass, "Not a valid class instance"); + return value.serialize(); + } + + /** + * @see BaseDataType.deserialize + * @param {any} value + * @param {GameRoot} root + * @param {object} targetObject + * @param {string|number} targetKey + * @returns {string|void} String error code or null on success + */ + deserialize(value, targetObject, targetKey, root) { + const instance = Object.create(this.baseclass.prototype); + const errorState = instance.deserialize(value); + if (errorState) { + return "Failed to deserialize class: " + errorState; + } + targetObject[targetKey] = instance; + } + + getAsJsonSchemaUncached() { + this.baseclass.getSchema(); + this.baseclass.getCachedSchema(); + return schemaToJsonSchema(this.baseclass.getCachedSchema()); + } + + verifySerializedValue(value) { + if (!value) { + return "Got null data"; + } + } + + getCacheKey() { + return "fixedclass." + this.baseclass.getId(); + } +} + +export class TypeKeyValueMap extends BaseDataType { + /** + * @param {BaseDataType} valueType + * @param {boolean=} includeEmptyValues + */ + constructor(valueType, includeEmptyValues = true) { + super(); + this.valueType = valueType; + this.includeEmptyValues = includeEmptyValues; + } + + serialize(value) { + assert(typeof value === "object", "not an object"); + let result = {}; + for (const key in value) { + const serialized = this.valueType.serialize(value[key]); + if (!this.includeEmptyValues && typeof serialized === "object") { + if ( + serialized.$ && + typeof serialized.data === "object" && + Object.keys(serialized.data).length === 0 + ) { + continue; + } else if (Object.keys(serialized).length === 0) { + continue; + } + } + + result[key] = serialized; + } + return result; + } + + /** + * @see BaseDataType.deserialize + * @param {any} value + * @param {GameRoot} root + * @param {object} targetObject + * @param {string|number} targetKey + * @returns {string|void} String error code or null on success + */ + deserialize(value, targetObject, targetKey, root) { + let result = {}; + for (const key in value) { + const errorCode = this.valueType.deserializeWithVerify(value[key], result, key, root); + if (errorCode) { + return errorCode; + } + } + targetObject[targetKey] = result; + } + + getAsJsonSchemaUncached() { + return { + type: "object", + additionalProperties: this.valueType.getAsJsonSchema(), + }; + } + + verifySerializedValue(value) { + if (typeof value !== "object") { + return "KV map is not an object"; + } + } + + getCacheKey() { + return "kvmap." + this.valueType.getCacheKey(); + } +} + +export class TypeClassId extends BaseDataType { + /** + * @param {FactoryTemplate<*>|SingletonFactoryTemplate<*>} registry + */ + constructor(registry) { + super(); + this.registry = registry; + } + + serialize(value) { + assert(typeof value === "string", "Not a valid string"); + assert(this.registry.hasId(value), "Id " + value + " not found in registry"); + return value; + } + + /** + * @see BaseDataType.deserialize + * @param {any} value + * @param {GameRoot} root + * @param {object} targetObject + * @param {string|number} targetKey + * @returns {string|void} String error code or null on success + */ + deserialize(value, targetObject, targetKey, root) { + targetObject[targetKey] = value; + } + + getAsJsonSchemaUncached() { + return { + type: "string", + enum: this.registry.getAllIds(), + }; + } + + verifySerializedValue(value) { + if (typeof value !== "string") { + return "Not a valid registry id key: " + value; + } + if (!this.registry.hasId(value)) { + return "Id " + value + " not known to registry"; + } + } + + getCacheKey() { + return "classid." + this.registry.getId(); + } +} + +export class TypePair extends BaseDataType { + /** + * @param {BaseDataType} type1 + * @param {BaseDataType} type2 + */ + constructor(type1, type2) { + super(); + this.type1 = type1; + this.type2 = type2; + } + + serialize(value) { + assert(Array.isArray(value), "pair: not an array"); + assert(value.length === 2, "pair: length != 2"); + return [this.type1.serialize(value[0]), this.type2.serialize(value[1])]; + } + + /** + * @see BaseDataType.deserialize + * @param {any} value + * @param {GameRoot} root + * @param {object} targetObject + * @param {string|number} targetKey + * @returns {string|void} String error code or null on success + */ + deserialize(value, targetObject, targetKey, root) { + const result = [undefined, undefined]; + + let errorCode = this.type1.deserialize(value, result, 0, root); + if (errorCode) { + return errorCode; + } + + errorCode = this.type2.deserialize(value, result, 1, root); + if (errorCode) { + return errorCode; + } + + targetObject[targetKey] = result; + } + + getAsJsonSchemaUncached() { + return { + type: "array", + minLength: 2, + maxLength: 2, + items: [this.type1.getAsJsonSchema(), this.type2.getAsJsonSchema()], + }; + } + + verifySerializedValue(value) { + if (!Array.isArray(value)) { + return "Pair is not an array"; + } + if (value.length !== 2) { + return "Pair length != 2"; + } + let errorCode = this.type1.verifySerializedValue(value[0]); + if (errorCode) { + return errorCode; + } + errorCode = this.type2.verifySerializedValue(value[1]); + if (errorCode) { + return errorCode; + } + } + + getCacheKey() { + return "pair.(" + this.type1.getCacheKey() + "," + this.type2.getCacheKey + ")"; + } +} + +export class TypeNullable extends BaseDataType { + /** + * @param {BaseDataType} wrapped + */ + constructor(wrapped) { + super(); + this.wrapped = wrapped; + } + + serialize(value) { + if (value === null || value === undefined) { + return null; + } + return this.wrapped.serialize(value); + } + + /** + * @see BaseDataType.deserialize + * @param {any} value + * @param {GameRoot} root + * @param {object} targetObject + * @param {string|number} targetKey + * @returns {string|void} String error code or null on success + */ + deserialize(value, targetObject, targetKey, root) { + if (value === null || value === undefined) { + targetObject[targetKey] = null; + return; + } + return this.wrapped.deserialize(value, targetObject, targetKey, root); + } + + verifySerializedValue(value) { + if (value === null) { + return; + } + return this.wrapped.verifySerializedValue(value); + } + + getAsJsonSchemaUncached() { + return { + oneOf: [ + { + type: "null", + }, + this.wrapped.getAsJsonSchema(), + ], + }; + } + + allowNull() { + return true; + } + + getCacheKey() { + return "nullable." + this.wrapped.getCacheKey(); + } +} diff --git a/src/js/savegame/serializer_internal.js b/src/js/savegame/serializer_internal.js new file mode 100644 index 00000000..298871e5 --- /dev/null +++ b/src/js/savegame/serializer_internal.js @@ -0,0 +1,180 @@ +/* typehints:start */ +import { GameRoot } from "../game/root"; +/* typehints:end */ + +import { Vector } from "../core/vector"; +import { createLogger } from "../core/logging"; +import { gMetaBuildingRegistry } from "../core/global_registries"; +import { Entity } from "../game/entity"; + +const logger = createLogger("serializer_internal"); + +// Internal serializer methods +export class SerializerInternal { + constructor() {} + + /** + * Serializes an array of entities + * @param {Array} array + */ + serializeEntityArray(array) { + const serialized = []; + for (let i = 0; i < array.length; ++i) { + const entity = array[i]; + if (!entity.queuedForDestroy && !entity.destroyed) { + serialized.push({ + $: entity.getMetaclass().getId(), + data: entity.serialize(), + }); + } + } + return serialized; + } + + /** + * Serializes an array of entities where we know the type of + * @param {Array} array + */ + serializeEntityArrayFixedType(array) { + const serialized = []; + for (let i = 0; i < array.length; ++i) { + const entity = array[i]; + if (!entity.queuedForDestroy && !entity.destroyed) { + serialized.push(entity.serialize()); + } + } + return serialized; + } + + /** + * + * @param {GameRoot} root + * @param {Array} array + * @param {function(GameRoot, { $: string, data: object }):string|void} deserializerMethod + * @returns {string|void} + */ + deserializeEntityArray(root, array, deserializerMethod) { + for (let i = 0; i < array.length; ++i) { + const errorState = deserializerMethod.call(this, root, array[i]); + if (errorState) { + return errorState; + } + } + return null; + } + + /** + * + * @param {GameRoot} root + * @param {Array} array + * @param {function(GameRoot, object):string|void} deserializerMethod + * @returns {string|void} + */ + deserializeEntityArrayFixedType(root, array, deserializerMethod) { + for (let i = 0; i < array.length; ++i) { + const errorState = deserializerMethod.call(this, root, array[i]); + if (errorState) { + return errorState; + } + } + return null; + } + + /** + * Deserializes a building + * @param {GameRoot} root + * @param {{ $: string, data: any }} payload + */ + deserializeBuilding(root, payload) { + const data = payload.data; + const id = payload.$; + if (!gMetaBuildingRegistry.hasId(id)) { + return "Metaclass not found for building: '" + id + "'"; + } + const meta = gMetaBuildingRegistry.findById(id); + if (!meta) { + return "Metaclass not found for building: '" + id + "'"; + } + + const tile = new Vector(data.x, data.y).toTileSpace(); + const instance = root.logic.internalPlaceBuildingLocalClientOnly({ + tile: tile, + metaBuilding: meta, + uid: data.uid, + }); + + // Apply component specific properties + const errorStatus = this.deserializeComponents(instance, data.components); + if (errorStatus) { + return errorStatus; + } + + // Apply enhancements + instance.updateEnhancements(); + } + + /** + * Deserializes a blueprint + * @param {GameRoot} root + * @param {any} data + * @returns {string|void} + */ + deserializeBlueprint(root, data) { + const id = data.meta; + const metaClass = gMetaBuildingRegistry.findById(id); + if (!metaClass) { + return "Metaclass not found for blueprint: '" + id + "'"; + } + + const tile = new Vector(data.x, data.y).toTileSpace(); + const instance = root.logic.internalPlaceBlueprintLocalClientOnly({ + tile: tile, + metaBuilding: metaClass, + uid: data.uid, + }); + return this.deserializeComponents(instance, data.components); + } + + /////// COMPONENTS //// + + /** + * Deserializes components of an entity + * @param {Entity} entity + * @param {Object.} data + * @returns {string|void} + */ + deserializeComponents(entity, data) { + for (const componentId in data) { + const componentHandle = entity.components[componentId]; + if (!componentHandle) { + logger.warn( + "Loading outdated savegame, where entity had component", + componentId, + "but now no longer has" + ); + continue; + } + const componentData = data[componentId]; + const errorStatus = componentHandle.deserialize(componentData); + if (errorStatus) { + return errorStatus; + } + } + } + + /** + * Deserializes a resource + * @param {GameRoot} root + * @param {object} data + * @returns {string|void} + */ + deserializeResource(root, data) { + const id = data.key; + const instance = new MapResource(root, this.neutralFaction, id); + root.logic.internalPlaceMapEntityLocalClientOnly( + new Vector(data.x, data.y).toTileSpace(), + instance, + data.uid + ); + } +} diff --git a/src/js/states/ingame.js b/src/js/states/ingame.js new file mode 100644 index 00000000..6a400a14 --- /dev/null +++ b/src/js/states/ingame.js @@ -0,0 +1,443 @@ +import { APPLICATION_ERROR_OCCURED } from "../core/error_handler"; +import { GameState } from "../core/game_state"; +import { logSection, createLogger } from "../core/logging"; +import { waitNextFrame } from "../core/utils"; +import { globalConfig } from "../core/config"; +import { GameLoadingOverlay } from "../game/game_loading_overlay"; +import { KeyActionMapper } from "../game/key_action_mapper"; +import { Savegame } from "../savegame/savegame"; +import { GameCore } from "../game/core"; +import { MUSIC } from "../platform/sound"; + +const logger = createLogger("state/ingame"); + +// Different sub-states +const stages = { + s3_createCore: "🌈 3: Create core", + s4_A_initEmptyGame: "🌈 4/A: Init empty game", + s4_B_resumeGame: "🌈 4/B: Resume game", + + s5_firstUpdate: "🌈 5: First game update", + s6_postLoadHook: "🌈 6: Post load hook", + s7_warmup: "🌈 7: Warmup", + + s10_gameRunning: "🌈 10: Game finally running", + + leaving: "🌈 Saving, then leaving the game", + destroyed: "🌈 DESTROYED: Core is empty and waits for state leave", + initFailed: "🌈 ERROR: Initialization failed!", +}; + +export const gameCreationAction = { + new: "new-game", + resume: "resume-game", +}; + +// Typehints +export class GameCreationPayload { + constructor() { + /** @type {boolean|undefined} */ + this.fastEnter; + + /** @type {Savegame} */ + this.savegame; + } +} + +export class InGameState extends GameState { + constructor() { + super("InGameState"); + + /** @type {GameCreationPayload} */ + this.creationPayload = null; + + // Stores current stage + this.stage = ""; + + /** @type {GameCore} */ + this.core = null; + + /** @type {KeyActionMapper} */ + this.keyActionMapper = null; + + /** @type {GameLoadingOverlay} */ + this.loadingOverlay = null; + + /** @type {Savegame} */ + this.savegame; + + this.boundInputFilter = this.filterInput.bind(this); + } + + /** + * Switches the game into another sub-state + * @param {string} stage + */ + switchStage(stage) { + assert(stage, "Got empty stage"); + if (stage !== this.stage) { + this.stage = stage; + logger.log(this.stage); + return true; + } else { + // log(this, "Re entering", stage); + return false; + } + } + + // GameState implementation + getInnerHTML() { + return ""; + } + + getThemeMusic() { + // set later + return MUSIC.gameBg; + } + + onBeforeExit() { + logger.log("Saving before quitting"); + return this.doSave(true, true).then(() => { + logger.log(this, "Successfully saved"); + // this.stageDestroyed(); + }); + } + + onAppPause() { + if (this.stage === stages.s10_gameRunning) { + logger.log("Saving because app got paused"); + this.doSave(true, true); + } + } + + getHasFadeIn() { + return false; + } + + getPauseOnFocusLost() { + return !this.isMultiplayer(); + } + + getHasUnloadConfirmation() { + return true; + } + + onLeave() { + if (this.core) { + this.stageDestroyed(); + } + this.app.inputMgr.dismountFilter(this.boundInputFilter); + } + + onResized(w, h) { + super.onResized(w, h); + if (this.stage === stages.s10_gameRunning) { + this.core.resize(w, h); + } + } + + // ---- End of GameState implementation + + /** + * Goes back to the menu state + */ + goBackToMenu() { + this.saveThenGoToState("MainMenuState"); + } + + /** + * Moves to a state outside of the game + * @param {string} stateId + * @param {any=} payload + */ + saveThenGoToState(stateId, payload) { + if (this.stage === stages.leaving || this.stage === stages.destroyed) { + logger.warn( + "Tried to leave game twice or during destroy:", + this.stage, + "(attempted to move to", + stateId, + ")" + ); + return; + } + this.stageLeavingGame(); + this.doSave(false, true).then(() => { + this.stageDestroyed(); + this.moveToState(stateId, payload); + }); + } + + onBackButton() { + // do nothing + } + + /** + * Called when the game somehow failed to initialize. Resets everything to basic state and + * then goes to the main menu, showing the error + * @param {string} err + */ + onInitializationFailure(err) { + if (this.switchStage(stages.initFailed)) { + logger.error("Init failure:", err); + this.stageDestroyed(); + this.moveToState("MainMenuState", { loadError: err }); + } + } + + // STAGES + + /** + * Creates the game core instance, and thus the root + */ + stage3CreateCore() { + if (this.switchStage(stages.s3_createCore)) { + logger.log("Creating new game core"); + this.core = new GameCore(this.app); + + this.core.initializeRoot(this, this.savegame); + + if (this.savegame.hasGameDump()) { + this.stage4bResumeGame(); + } else { + this.stage4aInitEmptyGame(); + } + } + } + + /** + * Initializes a new empty game + */ + stage4aInitEmptyGame() { + if (this.switchStage(stages.s4_A_initEmptyGame)) { + this.core.initNewGame(); + this.stage5FirstUpdate(); + } + } + + /** + * Resumes an existing game + */ + stage4bResumeGame() { + if (this.switchStage(stages.s4_B_resumeGame)) { + if (!this.core.initExistingGame()) { + this.onInitializationFailure("Savegame is corrupt and can not be restored."); + return; + } + this.stage5FirstUpdate(); + } + } + + /** + * Performs the first game update on the game which initializes most caches + */ + stage5FirstUpdate() { + if (this.switchStage(stages.s5_firstUpdate)) { + this.core.root.logicInitialized = true; + this.core.updateLogic(); + this.stage6PostLoadHook(); + } + } + + /** + * Call the post load hook, this means that we have loaded the game, and all systems + * can operate and start to work now. + */ + stage6PostLoadHook() { + if (this.switchStage(stages.s6_postLoadHook)) { + logger.log("Post load hook"); + this.core.postLoadHook(); + this.stage7Warmup(); + } + } + + /** + * This makes the game idle and draw for a while, because we run most code this way + * the V8 engine can already start to optimize it. Also this makes sure the resources + * are in the VRAM and we have a smooth experience once we start. + */ + stage7Warmup() { + if (this.switchStage(stages.s7_warmup)) { + if (G_IS_DEV && globalConfig.debug.noArtificialDelays) { + this.warmupTimeSeconds = 0.05; + } else { + if (this.creationPayload.fastEnter) { + this.warmupTimeSeconds = globalConfig.warmupTimeSecondsFast; + } else { + this.warmupTimeSeconds = globalConfig.warmupTimeSecondsRegular; + } + } + } + } + + /** + * The final stage where this game is running and updating regulary. + */ + stage10GameRunning() { + if (this.switchStage(stages.s10_gameRunning)) { + this.core.root.signals.readyToRender.dispatch(); + + logSection("GAME STARTED", "#26a69a"); + + // Initial resize, might have changed during loading (this is possible) + this.core.resize(this.app.screenWidth, this.app.screenHeight); + } + } + + /** + * This stage destroys the whole game, used to cleanup + */ + stageDestroyed() { + if (this.switchStage(stages.destroyed)) { + // Cleanup all api calls + this.cancelAllAsyncOperations(); + + if (this.syncer) { + this.syncer.cancelSync(); + this.syncer = null; + } + + // Cleanup core + if (this.core) { + this.core.destruct(); + this.core = null; + } + } + } + + /** + * When leaving the game + */ + stageLeavingGame() { + if (this.switchStage(stages.leaving)) { + // ... + } + } + + // END STAGES + + /** + * Filters the input (keybindings) + */ + filterInput() { + return this.stage === stages.s10_gameRunning; + } + + /** + * @param {GameCreationPayload} payload + */ + onEnter(payload) { + this.app.inputMgr.installFilter(this.boundInputFilter); + + this.creationPayload = payload; + this.savegame = payload.savegame; + + this.loadingOverlay = new GameLoadingOverlay(this.app, this.getDivElement()); + this.loadingOverlay.showBasic(); + + // Remove unneded default element + document.body.querySelector(".modalDialogParent").remove(); + + this.asyncChannel.watch(waitNextFrame()).then(() => this.stage3CreateCore()); + } + + /** + * Render callback + * @param {number} dt + */ + onRender(dt) { + if (APPLICATION_ERROR_OCCURED) { + // Application somehow crashed, do not do anything + return; + } + + if (this.stage === stages.s7_warmup) { + this.core.draw(); + this.warmupTimeSeconds -= dt / 1000.0; + if (this.warmupTimeSeconds < 0) { + logger.log("Warmup completed"); + this.stage10GameRunning(); + } + } + + // // Check if we can show an ad + // // DISABLED + // if (this.stage === stages.s10_gameRunning && !this.core.root.hud.parts.processingOverlay.hasTasks()) { + // if (this.app.isRenderable() && this.app.adProvider.getCanShowVideoAd()) { + // this.saveThenGoToState("WatchAdState", { + // nextStateId: "RunningGameState", + // nextStatePayload: this.creationPayload, + // }); + // } + // } + + if (this.stage === stages.s10_gameRunning) { + this.core.tick(dt); + } + + // If the stage is still active (This might not be the case if tick() moved us to game over) + if (this.stage === stages.s10_gameRunning) { + // Only draw if page visible + if (this.app.pageVisible) { + this.core.draw(); + } + + this.loadingOverlay.removeIfAttached(); + } else { + if (!this.loadingOverlay.isAttached()) { + this.loadingOverlay.showBasic(); + } + } + } + + onBackgroundTick(dt) { + this.onRender(dt); + } + + /** + * Saves the game + * @param {boolean=} syncWithServer + * @param {boolean} force + */ + + doSave(syncWithServer = true, force = false) { + // TODO + return; + + if (!this.savegame || !this.savegame.isSaveable()) { + // Can not save in multiplayer + return Promise.resolve(); + } + + if (APPLICATION_ERROR_OCCURED) { + logger.warn("skipping save because application crashed"); + return Promise.resolve(); + } + + if ( + this.stage !== stages.s10_gameRunning && + this.stage !== stages.s7_warmup && + this.stage !== stages.leaving + ) { + logger.warn("Skipping save because game is not ready"); + return Promise.resolve(); + } + + // First update the game data + + logger.log("Starting to save game ..."); + this.savegame.updateData(this.core.root); + + let savePromise = this.savegame.writeSavegameAndMetadata(); + + if (syncWithServer) { + // Sync in parallel + // @ts-ignore + savePromise = savePromise.then(() => this.syncer.sync(this.core, this.savegame, force)); + } + + return savePromise.catch(err => { + logger.warn("Failed to save:", err); + }); + } +} diff --git a/src/js/states/main_menu.js b/src/js/states/main_menu.js new file mode 100644 index 00000000..b5ea8c63 --- /dev/null +++ b/src/js/states/main_menu.js @@ -0,0 +1,52 @@ +import { GameState } from "../core/game_state"; +import { cachebust } from "../core/cachebust"; +import { globalConfig } from "../core/config"; + +export class MainMenuState extends GameState { + constructor() { + super("MainMenuState"); + } + + getInnerHTML() { + return ` + + + +
+ +
+ `; + } + + onBackButton() { + this.app.platformWrapper.exitApp(); + } + + onEnter(payload) { + if (payload.loadError) { + alert("Error while loading game: " + payload.loadError); + } + + const qs = this.htmlElement.querySelector.bind(this.htmlElement); + this.trackClicks(qs(".mainContainer .playButton"), this.onPlayButtonClicked); + + if (G_IS_DEV && globalConfig.debug.fastGameEnter) { + this.onPlayButtonClicked(); + } + } + + onPlayButtonClicked() { + const savegame = this.app.savegameMgr.createNewSavegame(); + + this.app.analytics.trackUiClick("startgame"); + this.moveToState("InGameState", { + savegame, + }); + } + + onLeave() { + // this.dialogs.cleanup(); + } +} diff --git a/src/js/states/preload.js b/src/js/states/preload.js new file mode 100644 index 00000000..ba3b515f --- /dev/null +++ b/src/js/states/preload.js @@ -0,0 +1,238 @@ +import { GameState } from "../core/game_state"; +import { createLogger } from "../core/logging"; +import { findNiceValue, waitNextFrame } from "../core/utils"; +import { cachebust } from "../core/cachebust"; +import { PlatformWrapperImplBrowser } from "../platform/browser/wrapper"; + +const logger = createLogger("state/preload"); + +export class PreloadState extends GameState { + constructor() { + super("PreloadState"); + } + + getInnerHTML() { + return ` +
+
+ Booting + + + 0% + +
+ + `; + } + + getThemeMusic() { + return null; + } + + getHasFadeIn() { + return false; + } + + onEnter(payload) { + this.htmlElement.classList.add("prefab_LoadingState"); + + const elementsToRemove = ["#loadingPreload", "#fontPreload"]; + for (let i = 0; i < elementsToRemove.length; ++i) { + const elem = document.querySelector(elementsToRemove[i]); + if (elem) { + elem.remove(); + } + } + + // this.dialogs = new HUDModalDialogs(null, this.app); + // const dialogsElement = document.body.querySelector(".modalDialogParent"); + // this.dialogs.initializeToElement(dialogsElement); + + this.statusText = this.htmlElement.querySelector(".loadingStatus > .desc"); + this.statusBar = this.htmlElement.querySelector(".loadingStatus > .bar > .inner"); + this.statusBarText = this.htmlElement.querySelector(".loadingStatus > .bar > .status"); + this.currentStatus = "booting"; + this.currentIndex = 0; + + this.startLoading(); + } + + onLeave() { + // this.dialogs.cleanup(); + } + + startLoading() { + this.setStatus("Booting") + + .then(() => this.setStatus("Creating platform wrapper")) + .then(() => this.app.platformWrapper.initialize()) + + .then(() => this.setStatus("Initializing libraries")) + .then(() => this.app.analytics.initialize()) + .then(() => this.app.gameAnalytics.initialize()) + + .then(() => this.setStatus("Initializing local storage")) + .then(() => { + const wrapper = this.app.platformWrapper; + if (wrapper instanceof PlatformWrapperImplBrowser) { + try { + window.localStorage.setItem("local_storage_test", "1"); + window.localStorage.removeItem("local_storage_test"); + } catch (ex) { + logger.error("Failed to read/write local storage:", ex); + return new Promise(() => { + alert(`Your brower does not support thirdparty cookies or you have disabled it in your security settings.\n\n + In Chrome this setting is called "Block third-party cookies and site data".\n\n + Please allow third party cookies and then reload the page.`); + // Never return + }); + } + } + }) + + .then(() => this.setStatus("Creating storage")) + .then(() => { + return this.app.storage.initialize(); + }) + + .then(() => this.setStatus("Initializing settings")) + .then(() => { + return this.app.settings.initialize(); + }) + .then(() => { + // Make sure the app pickups the right size + this.app.updateAfterUiScaleChanged(); + }) + + .then(() => { + // Initialize fullscreen + if (this.app.platformWrapper.getSupportsFullscreen()) { + this.app.platformWrapper.setFullscreen(this.app.settings.getIsFullScreen()); + } + }) + + .then(() => this.setStatus("Initializing sounds")) + .then(() => { + // Notice: We don't await the sounds loading itself + return this.app.sound.initialize(); + }) + + .then(() => { + this.app.backgroundResourceLoader.startLoading(); + }) + + .then(() => this.setStatus("Initializing savegame")) + .then(() => { + return this.app.savegameMgr.initialize().catch(err => { + logger.error("Failed to initialize savegames:", err); + return new Promise(resolve => { + // const { ok } = this.dialogs.showWarning( + // T.preload.savegame_corrupt_dialog.title, + // T.preload.savegame_corrupt_dialog.content, + // ["ok:good"] + // ); + // ok.add(resolve); + alert("Your savegames failed to load. They might not show up. Sorry!"); + }); + }); + }) + + .then(() => this.setStatus("Downloading resources")) + .then(() => { + return this.app.backgroundResourceLoader.getPromiseForBareGame(); + }) + + .then(() => this.setStatus("Launching")) + .then( + () => { + this.moveToState("MainMenuState"); + }, + err => { + this.showFailMessage(err); + } + ); + } + + setStatus(text) { + logger.log("✅ " + text); + this.currentIndex += 1; + this.currentStatus = text; + this.statusText.innerText = text; + + const numSteps = 10; // FIXME + + const percentage = (this.currentIndex / numSteps) * 100.0; + this.statusBar.style.width = percentage + "%"; + this.statusBarText.innerText = findNiceValue(percentage) + "%"; + + if (G_IS_DEV) { + return Promise.resolve(); + } + return waitNextFrame(); + } + + showFailMessage(text) { + logger.error("App init failed:", text); + + const email = "bugs@shapez.io"; + + const subElement = document.createElement("div"); + subElement.classList.add("failureBox"); + + subElement.innerHTML = ` + +
+
+ Failed to initialize application! +
+
+ ${this.currentStatus} failed:
+ ${text} +
+ +
+ Please send me an email with steps to reproduce and what you did before this happened: +
+
+ +
+ + Build ${G_BUILD_VERSION} @ ${G_BUILD_COMMIT_HASH} +
+
+ `; + + this.htmlElement.classList.add("failure"); + this.htmlElement.appendChild(subElement); + + const resetBtn = subElement.querySelector("button.resetApp"); + this.trackClicks(resetBtn, this.showResetConfirm); + } + + showResetConfirm() { + if (confirm("Are you sure you want to reset the app? This will delete all your savegames")) { + this.resetApp(); + } + // const signals = this.dialogs.showWarning(T.preload.reset_app_warning.title, T.preload.reset_app_warning.desc, [ + // "delete:bad:timeout", + // "cancel:good", + // ]); + // signals.delete.add(this.resetApp, this); + } + + resetApp() { + this.app.settings + .resetEverythingAsync() + .then(() => { + this.app.savegameMgr.resetEverythingAsync(); + }) + .then(() => { + this.app.settings.resetEverythingAsync(); + }) + .then(() => { + window.location.reload(); + }); + } +} diff --git a/src/js/webworkers/background_animation_frame_emittter.worker.js b/src/js/webworkers/background_animation_frame_emittter.worker.js new file mode 100644 index 00000000..5a3fe5c9 --- /dev/null +++ b/src/js/webworkers/background_animation_frame_emittter.worker.js @@ -0,0 +1,16 @@ +// We clamp high deltas so 30 fps is fairly ok +const bgFps = 30; +const desiredMsDelay = 1000 / bgFps; + +let lastTick = 0; + +function tick() { + const now = performance.now(); + const delta = now - lastTick; + lastTick = now; + + // @ts-ignore + postMessage({ delta }); +} + +setInterval(tick, desiredMsDelay); diff --git a/src/js/webworkers/compression.worker.js b/src/js/webworkers/compression.worker.js new file mode 100644 index 00000000..69e7a817 --- /dev/null +++ b/src/js/webworkers/compression.worker.js @@ -0,0 +1,48 @@ +import { compressX64 } from "../core/lzstring"; +import { globalConfig } from "../core/config"; +import { sha1 } from "../core/sensitive_utils.encrypt"; + +function accessNestedPropertyReverse(obj, keys) { + let result = obj; + for (let i = keys.length - 1; i >= 0; --i) { + result = result[keys[i]]; + } + return result; +} + +const rusha = require("rusha"); + +const salt = accessNestedPropertyReverse(globalConfig, ["file", "info"]); +const encryptKey = globalConfig.info.sgSalt; + +onmessage = function (event) { + const { jobId, job, data } = event.data; + const result = performJob(job, data); + + // @ts-ignore + postMessage({ + jobId, + result, + }); +}; + +function performJob(job, data) { + switch (job) { + case "compressX64": { + return compressX64(data); + } + case "compressWithChecksum": { + const checksum = rusha + .createHash() + .update(data + encryptKey) + .digest("hex"); + return compressX64(checksum + data); + } + case "compressFile": { + const checksum = sha1(data.text + salt); + return data.compressionPrefix + compressX64(checksum + data.text); + } + default: + throw new Error("Webworker: Unknown job: " + job); + } +} diff --git a/tools/shape_generator/index.html b/tools/shape_generator/index.html new file mode 100644 index 00000000..22a388d6 --- /dev/null +++ b/tools/shape_generator/index.html @@ -0,0 +1,72 @@ + + + + + shapez.io shape generator + + + + + + + +
Error
+
+ + + diff --git a/tools/shape_generator/index.js b/tools/shape_generator/index.js new file mode 100644 index 00000000..d248e678 --- /dev/null +++ b/tools/shape_generator/index.js @@ -0,0 +1,125 @@ +// From shape_definition.js + +/** @enum {string} */ +const enumSubShape = { + rect: "rect", + circle: "circle", + star: "star", + windmill: "windmill", +}; + +/** @enum {string} */ +const enumSubShapeToShortcode = { + [enumSubShape.rect]: "R", + [enumSubShape.circle]: "C", + [enumSubShape.star]: "S", + [enumSubShape.windmill]: "W", +}; + +/** @enum {enumSubShape} */ +const enumShortcodeToSubShape = {}; +for (const key in enumSubShapeToShortcode) { + enumShortcodeToSubShape[enumSubShapeToShortcode[key]] = key; +} + +// From colors.js +/** @enum {string} */ +const enumColors = { + red: "red", + green: "green", + blue: "blue", + + yellow: "yellow", + purple: "purple", + cyan: "cyan", + + white: "white", + uncolored: "uncolored", +}; + +/** @enum {string} */ +const enumColorToShortcode = { + [enumColors.red]: "r", + [enumColors.green]: "g", + [enumColors.blue]: "b", + + [enumColors.yellow]: "y", + [enumColors.purple]: "p", + [enumColors.cyan]: "c", + + [enumColors.white]: "w", + [enumColors.uncolored]: "u", +}; + +/** @enum {enumColors} */ +const enumShortcodeToColor = {}; +for (const key in enumColorToShortcode) { + enumShortcodeToColor[enumColorToShortcode[key]] = key; +} + +///////////////////////////////////////////////////// + +/** + * Generates the definition from the given short key + */ +function fromShortKey(key) { + const sourceLayers = key.split(":"); + let layers = []; + for (let i = 0; i < sourceLayers.length; ++i) { + const text = sourceLayers[i]; + if (text.length !== 8) { + throw new Error("Invalid layer: '" + text + "' -> must be 8 characters"); + } + + const quads = [null, null, null, null]; + for (let quad = 0; quad < 4; ++quad) { + const shapeText = text[quad * 2 + 0]; + const subShape = enumShortcodeToSubShape[shapeText]; + const color = enumShortcodeToColor[text[quad * 2 + 1]]; + if (subShape) { + if (!color) { + throw new Error("Invalid shape color key: " + key); + } + quads[quad] = { + subShape, + color, + }; + } else if (shapeText !== "-") { + throw new Error("Invalid shape key: " + shapeText); + } + } + layers.push(quads); + } + + return layers; +} + +///////////////////////////////////////////////////// + +function showError(msg) { + const errorDiv = document.getElementById("error"); + errorDiv.classList.toggle("hasError", !!msg); + if (msg) { + errorDiv.innerText = msg; + } else { + errorDiv.innerText = "Shape generated"; + } +} + +window.generate = () => { + showError(null); + const code = document.getElementById("code").value.trim(); + + let parsed = null; + try { + parsed = fromShortKey(code); + } catch (ex) { + showError(ex); + } +}; + +window.debounce = fn => { + setTimeout(fn, 0); +}; + +window.addEventListener("load", generate); diff --git a/tools/shape_generator/package.json b/tools/shape_generator/package.json new file mode 100644 index 00000000..0715ac87 --- /dev/null +++ b/tools/shape_generator/package.json @@ -0,0 +1,13 @@ +{ + "name": "shape_generator", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "private": true, + "devDependencies": { + "http-server": "^0.12.3" + }, + "scripts": { + "serve": "http-server . -p 9000 -g --cors -o -c-1" + } +} diff --git a/tools/shape_generator/yarn.lock b/tools/shape_generator/yarn.lock new file mode 100644 index 00000000..013aab17 --- /dev/null +++ b/tools/shape_generator/yarn.lock @@ -0,0 +1,152 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +async@^2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== + dependencies: + lodash "^4.17.14" + +basic-auth@^1.0.3: + version "1.1.0" + resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-1.1.0.tgz#45221ee429f7ee1e5035be3f51533f1cdfd29884" + integrity sha1-RSIe5Cn37h5QNb4/UVM/HN/SmIQ= + +colors@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + +corser@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/corser/-/corser-2.0.1.tgz#8eda252ecaab5840dcd975ceb90d9370c819ff87" + integrity sha1-jtolLsqrWEDc2XXOuQ2TcMgZ/4c= + +debug@^3.0.0, debug@^3.1.1: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + +ecstatic@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/ecstatic/-/ecstatic-3.3.2.tgz#6d1dd49814d00594682c652adb66076a69d46c48" + integrity sha512-fLf9l1hnwrHI2xn9mEDT7KIi22UDqA2jaCwyCbSUJh9a1V+LEUSL/JO/6TIz/QyuBURWUHrFL5Kg2TtO1bkkog== + dependencies: + he "^1.1.1" + mime "^1.6.0" + minimist "^1.1.0" + url-join "^2.0.5" + +eventemitter3@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.0.tgz#d65176163887ee59f386d64c82610b696a4a74eb" + integrity sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg== + +follow-redirects@^1.0.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.11.0.tgz#afa14f08ba12a52963140fe43212658897bc0ecb" + integrity sha512-KZm0V+ll8PfBrKwMzdo5D13b1bur9Iq9Zd/RMmAoQQcl2PxxFml8cxXPaaPYVbV0RjNjq1CU7zIzAOqtUPudmA== + dependencies: + debug "^3.0.0" + +he@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +http-proxy@^1.18.0: + version "1.18.0" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.0.tgz#dbe55f63e75a347db7f3d99974f2692a314a6a3a" + integrity sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +http-server@^0.12.3: + version "0.12.3" + resolved "https://registry.yarnpkg.com/http-server/-/http-server-0.12.3.tgz#ba0471d0ecc425886616cb35c4faf279140a0d37" + integrity sha512-be0dKG6pni92bRjq0kvExtj/NrrAd28/8fCXkaI/4piTwQMSDSLMhWyW0NI1V+DBI3aa1HMlQu46/HjVLfmugA== + dependencies: + basic-auth "^1.0.3" + colors "^1.4.0" + corser "^2.0.1" + ecstatic "^3.3.2" + http-proxy "^1.18.0" + minimist "^1.2.5" + opener "^1.5.1" + portfinder "^1.0.25" + secure-compare "3.0.1" + union "~0.5.0" + +lodash@^4.17.14: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" + integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== + +mime@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +minimist@^1.1.0, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +mkdirp@^0.5.1: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +ms@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +opener@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed" + integrity sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA== + +portfinder@^1.0.25: + version "1.0.26" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.26.tgz#475658d56ca30bed72ac7f1378ed350bd1b64e70" + integrity sha512-Xi7mKxJHHMI3rIUrnm/jjUgwhbYMkp/XKEcZX3aG4BrumLpq3nmoQMX+ClYnDZnZ/New7IatC1no5RX0zo1vXQ== + dependencies: + async "^2.6.2" + debug "^3.1.1" + mkdirp "^0.5.1" + +qs@^6.4.0: + version "6.9.4" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.4.tgz#9090b290d1f91728d3c22e54843ca44aea5ab687" + integrity sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +secure-compare@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/secure-compare/-/secure-compare-3.0.1.tgz#f1a0329b308b221fae37b9974f3d578d0ca999e3" + integrity sha1-8aAymzCLIh+uN7mXTz1XjQypmeM= + +union@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/union/-/union-0.5.0.tgz#b2c11be84f60538537b846edb9ba266ba0090075" + integrity sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA== + dependencies: + qs "^6.4.0" + +url-join@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/url-join/-/url-join-2.0.5.tgz#5af22f18c052a000a48d7b82c5e9c2e2feeda728" + integrity sha1-WvIvGMBSoACkjXuCxenC4v7tpyg= diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..17d22902 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,62 @@ +{ + "compilerOptions": { + /* Basic Options */ + "target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ + // "lib": [], /* Specify library files to be included in the compilation. */ + "allowJs": true, /* Allow javascript files to be compiled. */ + "checkJs": true, /* Report errors in .js files. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./typedefs_gen", /* Concatenate and emit output to single file. */ + // "outDir": "./typedefs_gen", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "composite": true, /* Enable project compilation */ + // "incremental": true, /* Enable incremental compilation */ + // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ + // "removeComments": true, /* Do not emit comments to output. */ + "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + /* Strict Type-Checking Options */ + // "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + "strictFunctionTypes": true, /* Enable strict checking of function types. */ + "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ + // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + /* Module Resolution Options */ + "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ + // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + /* Source Map Options */ + // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + "resolveJsonModule": true + }, + "exclude": [ + "backend/shared/gameserver_base_impl", + "backend/shared/sentry_logger.js" + ] +} \ No newline at end of file diff --git a/tslint.json b/tslint.json new file mode 100644 index 00000000..01942cdc --- /dev/null +++ b/tslint.json @@ -0,0 +1,23 @@ +{ + "defaultSeverity": "error", + "extends": [ + "tslint:recommended" + ], + "jsRules": { + "trailing-comma": false, + "comma-dangle": [ + "error", + "never" + ], + "object-literal-sort-keys": false, + "member-ordering": false, + "max-line-length": false, + "no-console": false, + "forin": false, + "no-empty": false, + "space-before-function-paren": [ + "always" + ] + }, + "rulesDirectory": [] +} \ No newline at end of file diff --git a/version b/version new file mode 100644 index 00000000..8a9ecc2e --- /dev/null +++ b/version @@ -0,0 +1 @@ +0.0.1 \ No newline at end of file diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 00000000..7fbd075b --- /dev/null +++ b/yarn.lock @@ -0,0 +1,9580 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e" + integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g== + dependencies: + "@babel/highlight" "^7.8.3" + +"@babel/compat-data@^7.8.6", "@babel/compat-data@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.9.0.tgz#04815556fc90b0c174abd2c0c1bb966faa036a6c" + integrity sha512-zeFQrr+284Ekvd9e7KAX954LkapWiOmQtsfHirhxqfdlX6MEC32iRE+pqUGlYIBchdevaCwvzxWGSy/YBNI85g== + dependencies: + browserslist "^4.9.1" + invariant "^2.2.4" + semver "^5.5.0" + +"@babel/core@^7.5.4": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.9.0.tgz#ac977b538b77e132ff706f3b8a4dbad09c03c56e" + integrity sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/generator" "^7.9.0" + "@babel/helper-module-transforms" "^7.9.0" + "@babel/helpers" "^7.9.0" + "@babel/parser" "^7.9.0" + "@babel/template" "^7.8.6" + "@babel/traverse" "^7.9.0" + "@babel/types" "^7.9.0" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.1" + json5 "^2.1.2" + lodash "^4.17.13" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" + +"@babel/generator@^7.9.0", "@babel/generator@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.9.5.tgz#27f0917741acc41e6eaaced6d68f96c3fa9afaf9" + integrity sha512-GbNIxVB3ZJe3tLeDm1HSn2AhuD/mVcyLDpgtLXa5tplmWrJdF/elxB56XNqCuD6szyNkDi6wuoKXln3QeBmCHQ== + dependencies: + "@babel/types" "^7.9.5" + jsesc "^2.5.1" + lodash "^4.17.13" + source-map "^0.5.0" + +"@babel/helper-annotate-as-pure@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.8.3.tgz#60bc0bc657f63a0924ff9a4b4a0b24a13cf4deee" + integrity sha512-6o+mJrZBxOoEX77Ezv9zwW7WV8DdluouRKNY/IR5u/YTMuKHgugHOzYWlYvYLpLA9nPsQCAAASpCIbjI9Mv+Uw== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.8.3.tgz#c84097a427a061ac56a1c30ebf54b7b22d241503" + integrity sha512-5eFOm2SyFPK4Rh3XMMRDjN7lBH0orh3ss0g3rTYZnBQ+r6YPj7lgDyCvPphynHvUrobJmeMignBr6Acw9mAPlw== + dependencies: + "@babel/helper-explode-assignable-expression" "^7.8.3" + "@babel/types" "^7.8.3" + +"@babel/helper-compilation-targets@^7.8.7": + version "7.8.7" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.8.7.tgz#dac1eea159c0e4bd46e309b5a1b04a66b53c1dde" + integrity sha512-4mWm8DCK2LugIS+p1yArqvG1Pf162upsIsjE7cNBjez+NjliQpVhj20obE520nao0o14DaTnFJv+Fw5a0JpoUw== + dependencies: + "@babel/compat-data" "^7.8.6" + browserslist "^4.9.1" + invariant "^2.2.4" + levenary "^1.1.1" + semver "^5.5.0" + +"@babel/helper-create-regexp-features-plugin@^7.8.3", "@babel/helper-create-regexp-features-plugin@^7.8.8": + version "7.8.8" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.8.tgz#5d84180b588f560b7864efaeea89243e58312087" + integrity sha512-LYVPdwkrQEiX9+1R29Ld/wTrmQu1SSKYnuOk3g0CkcZMA1p0gsNxJFj/3gBdaJ7Cg0Fnek5z0DsMULePP7Lrqg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.8.3" + "@babel/helper-regex" "^7.8.3" + regexpu-core "^4.7.0" + +"@babel/helper-define-map@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.8.3.tgz#a0655cad5451c3760b726eba875f1cd8faa02c15" + integrity sha512-PoeBYtxoZGtct3md6xZOCWPcKuMuk3IHhgxsRRNtnNShebf4C8YonTSblsK4tvDbm+eJAw2HAPOfCr+Q/YRG/g== + dependencies: + "@babel/helper-function-name" "^7.8.3" + "@babel/types" "^7.8.3" + lodash "^4.17.13" + +"@babel/helper-explode-assignable-expression@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.8.3.tgz#a728dc5b4e89e30fc2dfc7d04fa28a930653f982" + integrity sha512-N+8eW86/Kj147bO9G2uclsg5pwfs/fqqY5rwgIL7eTBklgXjcOJ3btzS5iM6AitJcftnY7pm2lGsrJVYLGjzIw== + dependencies: + "@babel/traverse" "^7.8.3" + "@babel/types" "^7.8.3" + +"@babel/helper-function-name@^7.8.3", "@babel/helper-function-name@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz#2b53820d35275120e1874a82e5aabe1376920a5c" + integrity sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw== + dependencies: + "@babel/helper-get-function-arity" "^7.8.3" + "@babel/template" "^7.8.3" + "@babel/types" "^7.9.5" + +"@babel/helper-get-function-arity@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz#b894b947bd004381ce63ea1db9f08547e920abd5" + integrity sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-hoist-variables@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.8.3.tgz#1dbe9b6b55d78c9b4183fc8cdc6e30ceb83b7134" + integrity sha512-ky1JLOjcDUtSc+xkt0xhYff7Z6ILTAHKmZLHPxAhOP0Nd77O+3nCsd6uSVYur6nJnCI029CrNbYlc0LoPfAPQg== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-member-expression-to-functions@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz#659b710498ea6c1d9907e0c73f206eee7dadc24c" + integrity sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-module-imports@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz#7fe39589b39c016331b6b8c3f441e8f0b1419498" + integrity sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-module-transforms@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz#43b34dfe15961918707d247327431388e9fe96e5" + integrity sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA== + dependencies: + "@babel/helper-module-imports" "^7.8.3" + "@babel/helper-replace-supers" "^7.8.6" + "@babel/helper-simple-access" "^7.8.3" + "@babel/helper-split-export-declaration" "^7.8.3" + "@babel/template" "^7.8.6" + "@babel/types" "^7.9.0" + lodash "^4.17.13" + +"@babel/helper-optimise-call-expression@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz#7ed071813d09c75298ef4f208956006b6111ecb9" + integrity sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz#9ea293be19babc0f52ff8ca88b34c3611b208670" + integrity sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ== + +"@babel/helper-regex@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.8.3.tgz#139772607d51b93f23effe72105b319d2a4c6965" + integrity sha512-BWt0QtYv/cg/NecOAZMdcn/waj/5P26DR4mVLXfFtDokSR6fyuG0Pj+e2FqtSME+MqED1khnSMulkmGl8qWiUQ== + dependencies: + lodash "^4.17.13" + +"@babel/helper-remap-async-to-generator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.8.3.tgz#273c600d8b9bf5006142c1e35887d555c12edd86" + integrity sha512-kgwDmw4fCg7AVgS4DukQR/roGp+jP+XluJE5hsRZwxCYGg+Rv9wSGErDWhlI90FODdYfd4xG4AQRiMDjjN0GzA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.8.3" + "@babel/helper-wrap-function" "^7.8.3" + "@babel/template" "^7.8.3" + "@babel/traverse" "^7.8.3" + "@babel/types" "^7.8.3" + +"@babel/helper-replace-supers@^7.8.3", "@babel/helper-replace-supers@^7.8.6": + version "7.8.6" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.8.6.tgz#5ada744fd5ad73203bf1d67459a27dcba67effc8" + integrity sha512-PeMArdA4Sv/Wf4zXwBKPqVj7n9UF/xg6slNRtZW84FM7JpE1CbG8B612FyM4cxrf4fMAMGO0kR7voy1ForHHFA== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.8.3" + "@babel/helper-optimise-call-expression" "^7.8.3" + "@babel/traverse" "^7.8.6" + "@babel/types" "^7.8.6" + +"@babel/helper-simple-access@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz#7f8109928b4dab4654076986af575231deb639ae" + integrity sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw== + dependencies: + "@babel/template" "^7.8.3" + "@babel/types" "^7.8.3" + +"@babel/helper-split-export-declaration@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz#31a9f30070f91368a7182cf05f831781065fc7a9" + integrity sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-validator-identifier@^7.9.0", "@babel/helper-validator-identifier@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz#90977a8e6fbf6b431a7dc31752eee233bf052d80" + integrity sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g== + +"@babel/helper-wrap-function@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.8.3.tgz#9dbdb2bb55ef14aaa01fe8c99b629bd5352d8610" + integrity sha512-LACJrbUET9cQDzb6kG7EeD7+7doC3JNvUgTEQOx2qaO1fKlzE/Bf05qs9w1oXQMmXlPO65lC3Tq9S6gZpTErEQ== + dependencies: + "@babel/helper-function-name" "^7.8.3" + "@babel/template" "^7.8.3" + "@babel/traverse" "^7.8.3" + "@babel/types" "^7.8.3" + +"@babel/helpers@^7.9.0": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.9.2.tgz#b42a81a811f1e7313b88cba8adc66b3d9ae6c09f" + integrity sha512-JwLvzlXVPjO8eU9c/wF9/zOIN7X6h8DYf7mG4CiFRZRvZNKEF5dQ3H3V+ASkHoIB3mWhatgl5ONhyqHRI6MppA== + dependencies: + "@babel/template" "^7.8.3" + "@babel/traverse" "^7.9.0" + "@babel/types" "^7.9.0" + +"@babel/highlight@^7.8.3": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.9.0.tgz#4e9b45ccb82b79607271b2979ad82c7b68163079" + integrity sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ== + dependencies: + "@babel/helper-validator-identifier" "^7.9.0" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.8.6", "@babel/parser@^7.9.0": + version "7.9.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.9.4.tgz#68a35e6b0319bbc014465be43828300113f2f2e8" + integrity sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA== + +"@babel/plugin-proposal-async-generator-functions@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.8.3.tgz#bad329c670b382589721b27540c7d288601c6e6f" + integrity sha512-NZ9zLv848JsV3hs8ryEh7Uaz/0KsmPLqv0+PdkDJL1cJy0K4kOCFa8zc1E3mp+RHPQcpdfb/6GovEsW4VDrOMw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-remap-async-to-generator" "^7.8.3" + "@babel/plugin-syntax-async-generators" "^7.8.0" + +"@babel/plugin-proposal-dynamic-import@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.8.3.tgz#38c4fe555744826e97e2ae930b0fb4cc07e66054" + integrity sha512-NyaBbyLFXFLT9FP+zk0kYlUlA8XtCUbehs67F0nnEg7KICgMc2mNkIeu9TYhKzyXMkrapZFwAhXLdnt4IYHy1w== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-dynamic-import" "^7.8.0" + +"@babel/plugin-proposal-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.8.3.tgz#da5216b238a98b58a1e05d6852104b10f9a70d6b" + integrity sha512-KGhQNZ3TVCQG/MjRbAUwuH+14y9q0tpxs1nWWs3pbSleRdDro9SAMMDyye8HhY1gqZ7/NqIc8SKhya0wRDgP1Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.0" + +"@babel/plugin-proposal-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.8.3.tgz#e4572253fdeed65cddeecfdab3f928afeb2fd5d2" + integrity sha512-TS9MlfzXpXKt6YYomudb/KU7nQI6/xnapG6in1uZxoxDghuSMZsPb6D2fyUwNYSAp4l1iR7QtFOjkqcRYcUsfw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + +"@babel/plugin-proposal-numeric-separator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.8.3.tgz#5d6769409699ec9b3b68684cd8116cedff93bad8" + integrity sha512-jWioO1s6R/R+wEHizfaScNsAx+xKgwTLNXSh7tTC4Usj3ItsPEhYkEpU4h+lpnBwq7NBVOJXfO6cRFYcX69JUQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.8.3" + +"@babel/plugin-proposal-object-rest-spread@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.5.tgz#3fd65911306d8746014ec0d0cf78f0e39a149116" + integrity sha512-VP2oXvAf7KCYTthbUHwBlewbl1Iq059f6seJGsxMizaCdgHIeczOr7FBqELhSqfkIl04Fi8okzWzl63UKbQmmg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + "@babel/plugin-transform-parameters" "^7.9.5" + +"@babel/plugin-proposal-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.8.3.tgz#9dee96ab1650eed88646ae9734ca167ac4a9c5c9" + integrity sha512-0gkX7J7E+AtAw9fcwlVQj8peP61qhdg/89D5swOkjYbkboA2CVckn3kiyum1DE0wskGb7KJJxBdyEBApDLLVdw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" + +"@babel/plugin-proposal-optional-chaining@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.9.0.tgz#31db16b154c39d6b8a645292472b98394c292a58" + integrity sha512-NDn5tu3tcv4W30jNhmc2hyD5c56G6cXx4TesJubhxrJeCvuuMpttxr0OnNCqbZGhFjLrg+NIhxxC+BK5F6yS3w== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.0" + +"@babel/plugin-proposal-unicode-property-regex@^7.4.4", "@babel/plugin-proposal-unicode-property-regex@^7.8.3": + version "7.8.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.8.8.tgz#ee3a95e90cdc04fe8cd92ec3279fa017d68a0d1d" + integrity sha512-EVhjVsMpbhLw9ZfHWSx2iy13Q8Z/eg8e8ccVWt23sWQK5l1UdkoLJPN5w69UA4uITGBnEZD2JOe4QOHycYKv8A== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.8.8" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-async-generators@^7.8.0": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-dynamic-import@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" + integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-json-strings@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.8.0", "@babel/plugin-syntax-numeric-separator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.8.3.tgz#0e3fb63e09bea1b11e96467271c8308007e7c41f" + integrity sha512-H7dCMAdN83PcCmqmkHB5dtp+Xa9a6LKSvA2hiFBC/5alSHxM5VgWZXFqDi0YFe8XNGT6iCa+z4V4zSt/PdZ7Dw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-object-rest-spread@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-top-level-await@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.8.3.tgz#3acdece695e6b13aaf57fc291d1a800950c71391" + integrity sha512-kwj1j9lL/6Wd0hROD3b/OZZ7MSrZLqqn9RAZ5+cYYsflQ9HZBIKCUkr3+uL1MEJ1NePiUbf98jjiMQSv0NMR9g== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-arrow-functions@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.8.3.tgz#82776c2ed0cd9e1a49956daeb896024c9473b8b6" + integrity sha512-0MRF+KC8EqH4dbuITCWwPSzsyO3HIWWlm30v8BbbpOrS1B++isGxPnnuq/IZvOX5J2D/p7DQalQm+/2PnlKGxg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-async-to-generator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.8.3.tgz#4308fad0d9409d71eafb9b1a6ee35f9d64b64086" + integrity sha512-imt9tFLD9ogt56Dd5CI/6XgpukMwd/fLGSrix2httihVe7LOGVPhyhMh1BU5kDM7iHD08i8uUtmV2sWaBFlHVQ== + dependencies: + "@babel/helper-module-imports" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-remap-async-to-generator" "^7.8.3" + +"@babel/plugin-transform-block-scoped-functions@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.8.3.tgz#437eec5b799b5852072084b3ae5ef66e8349e8a3" + integrity sha512-vo4F2OewqjbB1+yaJ7k2EJFHlTP3jR634Z9Cj9itpqNjuLXvhlVxgnjsHsdRgASR8xYDrx6onw4vW5H6We0Jmg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-block-scoping@^7.4.4", "@babel/plugin-transform-block-scoping@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.8.3.tgz#97d35dab66857a437c166358b91d09050c868f3a" + integrity sha512-pGnYfm7RNRgYRi7bids5bHluENHqJhrV4bCZRwc5GamaWIIs07N4rZECcmJL6ZClwjDz1GbdMZFtPs27hTB06w== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + lodash "^4.17.13" + +"@babel/plugin-transform-classes@^7.5.5", "@babel/plugin-transform-classes@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.9.5.tgz#800597ddb8aefc2c293ed27459c1fcc935a26c2c" + integrity sha512-x2kZoIuLC//O5iA7PEvecB105o7TLzZo8ofBVhP79N+DO3jaX+KYfww9TQcfBEZD0nikNyYcGB1IKtRq36rdmg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.8.3" + "@babel/helper-define-map" "^7.8.3" + "@babel/helper-function-name" "^7.9.5" + "@babel/helper-optimise-call-expression" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-replace-supers" "^7.8.6" + "@babel/helper-split-export-declaration" "^7.8.3" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.8.3.tgz#96d0d28b7f7ce4eb5b120bb2e0e943343c86f81b" + integrity sha512-O5hiIpSyOGdrQZRQ2ccwtTVkgUDBBiCuK//4RJ6UfePllUTCENOzKxfh6ulckXKc0DixTFLCfb2HVkNA7aDpzA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-destructuring@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.9.5.tgz#72c97cf5f38604aea3abf3b935b0e17b1db76a50" + integrity sha512-j3OEsGel8nHL/iusv/mRd5fYZ3DrOxWC82x0ogmdN/vHfAP4MYw+AFKYanzWlktNwikKvlzUV//afBW5FTp17Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-dotall-regex@^7.4.4", "@babel/plugin-transform-dotall-regex@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.8.3.tgz#c3c6ec5ee6125c6993c5cbca20dc8621a9ea7a6e" + integrity sha512-kLs1j9Nn4MQoBYdRXH6AeaXMbEJFaFu/v1nQkvib6QzTj8MZI5OQzqmD83/2jEM1z0DLilra5aWO5YpyC0ALIw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-duplicate-keys@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.8.3.tgz#8d12df309aa537f272899c565ea1768e286e21f1" + integrity sha512-s8dHiBUbcbSgipS4SMFuWGqCvyge5V2ZeAWzR6INTVC3Ltjig/Vw1G2Gztv0vU/hRG9X8IvKvYdoksnUfgXOEQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-exponentiation-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.8.3.tgz#581a6d7f56970e06bf51560cd64f5e947b70d7b7" + integrity sha512-zwIpuIymb3ACcInbksHaNcR12S++0MDLKkiqXHl3AzpgdKlFNhog+z/K0+TGW+b0w5pgTq4H6IwV/WhxbGYSjQ== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-for-of@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.9.0.tgz#0f260e27d3e29cd1bb3128da5e76c761aa6c108e" + integrity sha512-lTAnWOpMwOXpyDx06N+ywmF3jNbafZEqZ96CGYabxHrxNX8l5ny7dt4bK/rGwAh9utyP2b2Hv7PlZh1AAS54FQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-function-name@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.8.3.tgz#279373cb27322aaad67c2683e776dfc47196ed8b" + integrity sha512-rO/OnDS78Eifbjn5Py9v8y0aR+aSYhDhqAwVfsTl0ERuMZyr05L1aFSCJnbv2mmsLkit/4ReeQ9N2BgLnOcPCQ== + dependencies: + "@babel/helper-function-name" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-literals@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.8.3.tgz#aef239823d91994ec7b68e55193525d76dbd5dc1" + integrity sha512-3Tqf8JJ/qB7TeldGl+TT55+uQei9JfYaregDcEAyBZ7akutriFrt6C/wLYIer6OYhleVQvH/ntEhjE/xMmy10A== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-member-expression-literals@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.8.3.tgz#963fed4b620ac7cbf6029c755424029fa3a40410" + integrity sha512-3Wk2EXhnw+rP+IDkK6BdtPKsUE5IeZ6QOGrPYvw52NwBStw9V1ZVzxgK6fSKSxqUvH9eQPR3tm3cOq79HlsKYA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-modules-amd@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.9.0.tgz#19755ee721912cf5bb04c07d50280af3484efef4" + integrity sha512-vZgDDF003B14O8zJy0XXLnPH4sg+9X5hFBBGN1V+B2rgrB+J2xIypSN6Rk9imB2hSTHQi5OHLrFWsZab1GMk+Q== + dependencies: + "@babel/helper-module-transforms" "^7.9.0" + "@babel/helper-plugin-utils" "^7.8.3" + babel-plugin-dynamic-import-node "^2.3.0" + +"@babel/plugin-transform-modules-commonjs@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.9.0.tgz#e3e72f4cbc9b4a260e30be0ea59bdf5a39748940" + integrity sha512-qzlCrLnKqio4SlgJ6FMMLBe4bySNis8DFn1VkGmOcxG9gqEyPIOzeQrA//u0HAKrWpJlpZbZMPB1n/OPa4+n8g== + dependencies: + "@babel/helper-module-transforms" "^7.9.0" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-simple-access" "^7.8.3" + babel-plugin-dynamic-import-node "^2.3.0" + +"@babel/plugin-transform-modules-systemjs@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.9.0.tgz#e9fd46a296fc91e009b64e07ddaa86d6f0edeb90" + integrity sha512-FsiAv/nao/ud2ZWy4wFacoLOm5uxl0ExSQ7ErvP7jpoihLR6Cq90ilOFyX9UXct3rbtKsAiZ9kFt5XGfPe/5SQ== + dependencies: + "@babel/helper-hoist-variables" "^7.8.3" + "@babel/helper-module-transforms" "^7.9.0" + "@babel/helper-plugin-utils" "^7.8.3" + babel-plugin-dynamic-import-node "^2.3.0" + +"@babel/plugin-transform-modules-umd@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.9.0.tgz#e909acae276fec280f9b821a5f38e1f08b480697" + integrity sha512-uTWkXkIVtg/JGRSIABdBoMsoIeoHQHPTL0Y2E7xf5Oj7sLqwVsNXOkNk0VJc7vF0IMBsPeikHxFjGe+qmwPtTQ== + dependencies: + "@babel/helper-module-transforms" "^7.9.0" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-named-capturing-groups-regex@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.8.3.tgz#a2a72bffa202ac0e2d0506afd0939c5ecbc48c6c" + integrity sha512-f+tF/8UVPU86TrCb06JoPWIdDpTNSGGcAtaD9mLP0aYGA0OS0j7j7DHJR0GTFrUZPUU6loZhbsVZgTh0N+Qdnw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.8.3" + +"@babel/plugin-transform-new-target@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.8.3.tgz#60cc2ae66d85c95ab540eb34babb6434d4c70c43" + integrity sha512-QuSGysibQpyxexRyui2vca+Cmbljo8bcRckgzYV4kRIsHpVeyeC3JDO63pY+xFZ6bWOBn7pfKZTqV4o/ix9sFw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-object-super@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.8.3.tgz#ebb6a1e7a86ffa96858bd6ac0102d65944261725" + integrity sha512-57FXk+gItG/GejofIyLIgBKTas4+pEU47IXKDBWFTxdPd7F80H8zybyAY7UoblVfBhBGs2EKM+bJUu2+iUYPDQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-replace-supers" "^7.8.3" + +"@babel/plugin-transform-parameters@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.9.5.tgz#173b265746f5e15b2afe527eeda65b73623a0795" + integrity sha512-0+1FhHnMfj6lIIhVvS4KGQJeuhe1GI//h5uptK4PvLt+BGBxsoUJbd3/IW002yk//6sZPlFgsG1hY6OHLcy6kA== + dependencies: + "@babel/helper-get-function-arity" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-property-literals@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.8.3.tgz#33194300d8539c1ed28c62ad5087ba3807b98263" + integrity sha512-uGiiXAZMqEoQhRWMK17VospMZh5sXWg+dlh2soffpkAl96KAm+WZuJfa6lcELotSRmooLqg0MWdH6UUq85nmmg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-regenerator@^7.8.7": + version "7.8.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.7.tgz#5e46a0dca2bee1ad8285eb0527e6abc9c37672f8" + integrity sha512-TIg+gAl4Z0a3WmD3mbYSk+J9ZUH6n/Yc57rtKRnlA/7rcCvpekHXe0CMZHP1gYp7/KLe9GHTuIba0vXmls6drA== + dependencies: + regenerator-transform "^0.14.2" + +"@babel/plugin-transform-reserved-words@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.8.3.tgz#9a0635ac4e665d29b162837dd3cc50745dfdf1f5" + integrity sha512-mwMxcycN3omKFDjDQUl+8zyMsBfjRFr0Zn/64I41pmjv4NJuqcYlEtezwYtw9TFd9WR1vN5kiM+O0gMZzO6L0A== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-shorthand-properties@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.8.3.tgz#28545216e023a832d4d3a1185ed492bcfeac08c8" + integrity sha512-I9DI6Odg0JJwxCHzbzW08ggMdCezoWcuQRz3ptdudgwaHxTjxw5HgdFJmZIkIMlRymL6YiZcped4TTCB0JcC8w== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.8.3.tgz#9c8ffe8170fdfb88b114ecb920b82fb6e95fe5e8" + integrity sha512-CkuTU9mbmAoFOI1tklFWYYbzX5qCIZVXPVy0jpXgGwkplCndQAa58s2jr66fTeQnA64bDox0HL4U56CFYoyC7g== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-sticky-regex@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.8.3.tgz#be7a1290f81dae767475452199e1f76d6175b100" + integrity sha512-9Spq0vGCD5Bb4Z/ZXXSK5wbbLFMG085qd2vhL1JYu1WcQ5bXqZBAYRzU1d+p79GcHs2szYv5pVQCX13QgldaWw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-regex" "^7.8.3" + +"@babel/plugin-transform-template-literals@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.8.3.tgz#7bfa4732b455ea6a43130adc0ba767ec0e402a80" + integrity sha512-820QBtykIQOLFT8NZOcTRJ1UNuztIELe4p9DCgvj4NK+PwluSJ49we7s9FB1HIGNIYT7wFUJ0ar2QpCDj0escQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-typeof-symbol@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.8.4.tgz#ede4062315ce0aaf8a657a920858f1a2f35fc412" + integrity sha512-2QKyfjGdvuNfHsb7qnBBlKclbD4CfshH2KvDabiijLMGXPHJXGxtDzwIF7bQP+T0ysw8fYTtxPafgfs/c1Lrqg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-unicode-regex@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.8.3.tgz#0cef36e3ba73e5c57273effb182f46b91a1ecaad" + integrity sha512-+ufgJjYdmWfSQ+6NS9VGUR2ns8cjJjYbrbi11mZBTaWm+Fui/ncTLFF28Ei1okavY+xkojGr1eJxNsWYeA5aZw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/preset-env@^7.5.4": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.9.5.tgz#8ddc76039bc45b774b19e2fc548f6807d8a8919f" + integrity sha512-eWGYeADTlPJH+wq1F0wNfPbVS1w1wtmMJiYk55Td5Yu28AsdR9AsC97sZ0Qq8fHqQuslVSIYSGJMcblr345GfQ== + dependencies: + "@babel/compat-data" "^7.9.0" + "@babel/helper-compilation-targets" "^7.8.7" + "@babel/helper-module-imports" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-proposal-async-generator-functions" "^7.8.3" + "@babel/plugin-proposal-dynamic-import" "^7.8.3" + "@babel/plugin-proposal-json-strings" "^7.8.3" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-proposal-numeric-separator" "^7.8.3" + "@babel/plugin-proposal-object-rest-spread" "^7.9.5" + "@babel/plugin-proposal-optional-catch-binding" "^7.8.3" + "@babel/plugin-proposal-optional-chaining" "^7.9.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.8.3" + "@babel/plugin-syntax-async-generators" "^7.8.0" + "@babel/plugin-syntax-dynamic-import" "^7.8.0" + "@babel/plugin-syntax-json-strings" "^7.8.0" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + "@babel/plugin-syntax-numeric-separator" "^7.8.0" + "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" + "@babel/plugin-syntax-optional-chaining" "^7.8.0" + "@babel/plugin-syntax-top-level-await" "^7.8.3" + "@babel/plugin-transform-arrow-functions" "^7.8.3" + "@babel/plugin-transform-async-to-generator" "^7.8.3" + "@babel/plugin-transform-block-scoped-functions" "^7.8.3" + "@babel/plugin-transform-block-scoping" "^7.8.3" + "@babel/plugin-transform-classes" "^7.9.5" + "@babel/plugin-transform-computed-properties" "^7.8.3" + "@babel/plugin-transform-destructuring" "^7.9.5" + "@babel/plugin-transform-dotall-regex" "^7.8.3" + "@babel/plugin-transform-duplicate-keys" "^7.8.3" + "@babel/plugin-transform-exponentiation-operator" "^7.8.3" + "@babel/plugin-transform-for-of" "^7.9.0" + "@babel/plugin-transform-function-name" "^7.8.3" + "@babel/plugin-transform-literals" "^7.8.3" + "@babel/plugin-transform-member-expression-literals" "^7.8.3" + "@babel/plugin-transform-modules-amd" "^7.9.0" + "@babel/plugin-transform-modules-commonjs" "^7.9.0" + "@babel/plugin-transform-modules-systemjs" "^7.9.0" + "@babel/plugin-transform-modules-umd" "^7.9.0" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.8.3" + "@babel/plugin-transform-new-target" "^7.8.3" + "@babel/plugin-transform-object-super" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.9.5" + "@babel/plugin-transform-property-literals" "^7.8.3" + "@babel/plugin-transform-regenerator" "^7.8.7" + "@babel/plugin-transform-reserved-words" "^7.8.3" + "@babel/plugin-transform-shorthand-properties" "^7.8.3" + "@babel/plugin-transform-spread" "^7.8.3" + "@babel/plugin-transform-sticky-regex" "^7.8.3" + "@babel/plugin-transform-template-literals" "^7.8.3" + "@babel/plugin-transform-typeof-symbol" "^7.8.4" + "@babel/plugin-transform-unicode-regex" "^7.8.3" + "@babel/preset-modules" "^0.1.3" + "@babel/types" "^7.9.5" + browserslist "^4.9.1" + core-js-compat "^3.6.2" + invariant "^2.2.2" + levenary "^1.1.1" + semver "^5.5.0" + +"@babel/preset-modules@^0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.3.tgz#13242b53b5ef8c883c3cf7dddd55b36ce80fbc72" + integrity sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" + "@babel/plugin-transform-dotall-regex" "^7.4.4" + "@babel/types" "^7.4.4" + esutils "^2.0.2" + +"@babel/runtime@7.0.0-beta.42": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.0.0-beta.42.tgz#352e40c92e0460d3e82f49bd7e79f6cda76f919f" + integrity sha512-iOGRzUoONLOtmCvjUsZv3mZzgCT6ljHQY5fr1qG1QIiJQwtM7zbPWGGpa3QWETq+UqwWyJnoi5XZDZRwZDFciQ== + dependencies: + core-js "^2.5.3" + regenerator-runtime "^0.11.1" + +"@babel/runtime@^7.8.4": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.2.tgz#d90df0583a3a252f09aaa619665367bae518db06" + integrity sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/template@^7.8.3", "@babel/template@^7.8.6": + version "7.8.6" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.6.tgz#86b22af15f828dfb086474f964dcc3e39c43ce2b" + integrity sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/parser" "^7.8.6" + "@babel/types" "^7.8.6" + +"@babel/traverse@^7.8.3", "@babel/traverse@^7.8.6", "@babel/traverse@^7.9.0": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.9.5.tgz#6e7c56b44e2ac7011a948c21e283ddd9d9db97a2" + integrity sha512-c4gH3jsvSuGUezlP6rzSJ6jf8fYjLj3hsMZRx/nX0h+fmHN0w+ekubRrHPqnMec0meycA2nwCsJ7dC8IPem2FQ== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/generator" "^7.9.5" + "@babel/helper-function-name" "^7.9.5" + "@babel/helper-split-export-declaration" "^7.8.3" + "@babel/parser" "^7.9.0" + "@babel/types" "^7.9.5" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.13" + +"@babel/types@^7.4.4", "@babel/types@^7.8.3", "@babel/types@^7.8.6", "@babel/types@^7.9.0", "@babel/types@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.9.5.tgz#89231f82915a8a566a703b3b20133f73da6b9444" + integrity sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg== + dependencies: + "@babel/helper-validator-identifier" "^7.9.5" + lodash "^4.17.13" + to-fast-properties "^2.0.0" + +"@csstools/convert-colors@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-1.4.0.tgz#ad495dc41b12e75d588c6db8b9834f08fa131eb7" + integrity sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw== + +"@jimp/bmp@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/bmp/-/bmp-0.6.8.tgz#8abbfd9e26ba17a47fab311059ea9f7dd82005b6" + integrity sha512-uxVgSkI62uAzk5ZazYHEHBehow590WAkLKmDXLzkr/XP/Hv2Fx1T4DKwJ/15IY5ktq5VAhAUWGXTyd8KWFsx7w== + dependencies: + "@jimp/utils" "^0.6.8" + bmp-js "^0.1.0" + core-js "^2.5.7" + +"@jimp/core@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/core/-/core-0.6.8.tgz#6a41089792516f6e64a5302d12eb562aa7847c7b" + integrity sha512-JOFqBBcSNiDiMZJFr6OJqC6viXj5NVBQISua0eacoYvo4YJtTajOIxC4MqWyUmGrDpRMZBR8QhSsIOwsFrdROA== + dependencies: + "@jimp/utils" "^0.6.8" + any-base "^1.1.0" + buffer "^5.2.0" + core-js "^2.5.7" + exif-parser "^0.1.12" + file-type "^9.0.0" + load-bmfont "^1.3.1" + mkdirp "0.5.1" + phin "^2.9.1" + pixelmatch "^4.0.2" + tinycolor2 "^1.4.1" + +"@jimp/custom@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/custom/-/custom-0.6.8.tgz#0476d7b3f5da3121d98895a2e14f2899e602f2b6" + integrity sha512-FrYlzZRVXP2vuVwd7Nc2dlK+iZk4g6IaT1Ib8Z6vU5Kkwlt83FJIPJ2UUFABf3bF5big0wkk8ZUihWxE4Nzdng== + dependencies: + "@jimp/core" "^0.6.8" + core-js "^2.5.7" + +"@jimp/gif@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/gif/-/gif-0.6.8.tgz#848dd4e6e1a56ca2b3ce528969e44dfa99a53b14" + integrity sha512-yyOlujjQcgz9zkjM5ihZDEppn9d1brJ7jQHP5rAKmqep0G7FU1D0AKcV+Ql18RhuI/CgWs10wAVcrQpmLnu4Yw== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + omggif "^1.0.9" + +"@jimp/jpeg@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/jpeg/-/jpeg-0.6.8.tgz#4cad85a6d1e15759acb56bddef29aa3473859f2c" + integrity sha512-rGtXbYpFXAn471qLpTGvhbBMNHJo5KiufN+vC5AWyufntmkt5f0Ox2Cx4ijuBMDtirZchxbMLtrfGjznS4L/ew== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + jpeg-js "^0.3.4" + +"@jimp/plugin-blit@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-blit/-/plugin-blit-0.6.8.tgz#646ebb631f35afc28c1e8908524bc43d1e9afa3d" + integrity sha512-7Tl6YpKTSpvwQbnGNhsfX2zyl3jRVVopd276Y2hF2zpDz9Bycow7NdfNU/4Nx1jaf96X6uWOtSVINcQ7rGd47w== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + +"@jimp/plugin-blur@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-blur/-/plugin-blur-0.6.8.tgz#7b753ae94f6099103f57c268c3b2679047eefe95" + integrity sha512-NpZCMKxXHLDQsX9zPlWtpMA660DQStY6/z8ZetyxCDbqrLe9YCXpeR4MNhdJdABIiwTm1W5FyFF4kp81PHJx3Q== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + +"@jimp/plugin-color@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-color/-/plugin-color-0.6.8.tgz#4101cb1208879b331db6e43ea6b96eaf8dbaedbc" + integrity sha512-jjFyU0zNmGOH2rjzHuOMU4kaia0oo82s/7UYfn5h7OUkmUZTd6Do3ZSK1PiXA7KR+s4B76/Omm6Doh/0SGb7BQ== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + tinycolor2 "^1.4.1" + +"@jimp/plugin-contain@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-contain/-/plugin-contain-0.6.8.tgz#af95d33b63d0478943374ae15dd2607fc69cad14" + integrity sha512-p/P2wCXhAzbmEgXvGsvmxLmbz45feF6VpR4m9suPSOr8PC/i/XvTklTqYEUidYYAft4vHgsYJdS74HKSMnH8lw== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + +"@jimp/plugin-cover@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-cover/-/plugin-cover-0.6.8.tgz#490e3186627a34d93cc015c4169bac9070d6ad17" + integrity sha512-2PvWgk+PJfRsfWDI1G8Fpjrsu0ZlpNyZxO2+fqWlVo6y/y2gP4v08FqvbkcqSjNlOu2IDWIFXpgyU0sTINWZLg== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + +"@jimp/plugin-crop@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-crop/-/plugin-crop-0.6.8.tgz#ffec8951a2f3eccad1e3cff9afff5326bd980ce7" + integrity sha512-CbrcpWE2xxPK1n/JoTXzhRUhP4mO07mTWaSavenCg664oQl/9XCtL+A0FekuNHzIvn4myEqvkiTwN7FsbunS/Q== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + +"@jimp/plugin-displace@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-displace/-/plugin-displace-0.6.8.tgz#89df05ab7daaff6befc190bb8ac54ec8d57e533b" + integrity sha512-RmV2bPxoPE6mrPxtYSPtHxm2cGwBQr5a2p+9gH6SPy+eUMrbGjbvjwKNfXWUYD0leML+Pt5XOmAS9pIROmuruQ== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + +"@jimp/plugin-dither@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-dither/-/plugin-dither-0.6.8.tgz#17e5b9f56575a871e329fef8b388e614b92d84f8" + integrity sha512-x6V/qjxe+xypjpQm7GbiMNqci1EW5UizrcebOhHr8AHijOEqHd2hjXh5f6QIGfrkTFelc4/jzq1UyCsYntqz9Q== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + +"@jimp/plugin-flip@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-flip/-/plugin-flip-0.6.8.tgz#153df0c677f79d4078bb9e4c1f2ac392b96dc3a1" + integrity sha512-4il6Da6G39s9MyWBEee4jztEOUGJ40E6OlPjkMrdpDNvge6hYEAB31BczTYBP/CEY74j4LDSoY5LbcU4kv06yA== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + +"@jimp/plugin-gaussian@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-gaussian/-/plugin-gaussian-0.6.8.tgz#100abc7ae1f19fe9c09ed41625b475aae7c6093c" + integrity sha512-pVOblmjv7stZjsqloi4YzHVwAPXKGdNaHPhp4KP4vj41qtc6Hxd9z/+VWGYRTunMFac84gUToe0UKIXd6GhoKw== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + +"@jimp/plugin-invert@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-invert/-/plugin-invert-0.6.8.tgz#f40bfaa3b592d21ff14ede0e49aabec88048cad0" + integrity sha512-11zuLiXDHr6tFv4U8aieXqNXQEKbDbSBG/h+X62gGTNFpyn8EVPpncHhOqrAFtZUaPibBqMFlNJ15SzwC7ExsQ== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + +"@jimp/plugin-mask@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-mask/-/plugin-mask-0.6.8.tgz#e64405f7dacf0672bff74f3b95b724d9ac517f86" + integrity sha512-hZJ0OiKGJyv7hDSATwJDkunB1Ie80xJnONMgpUuUseteK45YeYNBOiZVUe8vum8QI1UwavgBzcvQ9u4fcgXc9g== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + +"@jimp/plugin-normalize@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-normalize/-/plugin-normalize-0.6.8.tgz#a0180f2b8835e3638cdc5e057b44ac63f60db6ba" + integrity sha512-Q4oYhU+sSyTJI7pMZlg9/mYh68ujLfOxXzQGEXuw0sHGoGQs3B0Jw7jmzGa6pIS06Hup5hD2Zuh1ppvMdjJBfQ== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + +"@jimp/plugin-print@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-print/-/plugin-print-0.6.8.tgz#66309549e01896473111e3a0ad2cee428638bd6e" + integrity sha512-2aokejGn4Drv1FesnZGqh5KEq0FQtR0drlmtyZrBH+r9cx7hh0Qgf4D1BOTDEgXkfSSngjGRjKKRW/fwOrVXYw== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + load-bmfont "^1.4.0" + +"@jimp/plugin-resize@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-resize/-/plugin-resize-0.6.8.tgz#c26d9a973f7eec51ad9018fcbbac1146f7a73aa0" + integrity sha512-27nPh8L1YWsxtfmV/+Ub5dOTpXyC0HMF2cu52RQSCYxr+Lm1+23dJF70AF1poUbUe+FWXphwuUxQzjBJza9UoA== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + +"@jimp/plugin-rotate@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-rotate/-/plugin-rotate-0.6.8.tgz#2afda247984eeebed95c1bb1b13ccd3be5973299" + integrity sha512-GbjETvL05BDoLdszNUV4Y0yLkHf177MnqGqilA113LIvx9aD0FtUopGXYfRGVvmtTOTouoaGJUc+K6qngvKxww== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + +"@jimp/plugin-scale@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-scale/-/plugin-scale-0.6.8.tgz#5de403345859bb0b30bf3e242dedd8ceb6ecb96c" + integrity sha512-GzIYWR/oCUK2jAwku23zt19V1ssaEU4pL0x2XsLNKuuJEU6DvEytJyTMXCE7OLG/MpDBQcQclJKHgiyQm5gIOQ== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + +"@jimp/plugins@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/plugins/-/plugins-0.6.8.tgz#5618170a986ced1ea795adcd9376122f2543b856" + integrity sha512-fMcTI72Vn/Lz6JftezTURmyP5ml/xGMe0Ljx2KRJ85IWyP33vDmGIUuutFiBEbh2+y7lRT+aTSmjs0QGa/xTmQ== + dependencies: + "@jimp/plugin-blit" "^0.6.8" + "@jimp/plugin-blur" "^0.6.8" + "@jimp/plugin-color" "^0.6.8" + "@jimp/plugin-contain" "^0.6.8" + "@jimp/plugin-cover" "^0.6.8" + "@jimp/plugin-crop" "^0.6.8" + "@jimp/plugin-displace" "^0.6.8" + "@jimp/plugin-dither" "^0.6.8" + "@jimp/plugin-flip" "^0.6.8" + "@jimp/plugin-gaussian" "^0.6.8" + "@jimp/plugin-invert" "^0.6.8" + "@jimp/plugin-mask" "^0.6.8" + "@jimp/plugin-normalize" "^0.6.8" + "@jimp/plugin-print" "^0.6.8" + "@jimp/plugin-resize" "^0.6.8" + "@jimp/plugin-rotate" "^0.6.8" + "@jimp/plugin-scale" "^0.6.8" + core-js "^2.5.7" + timm "^1.6.1" + +"@jimp/png@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/png/-/png-0.6.8.tgz#ee06cf078b381137ec7206c4bb1b4cfcbe15ca6f" + integrity sha512-JHHg/BZ7KDtHQrcG+a7fztw45rdf7okL/YwkN4qU5FH7Fcrp41nX5QnRviDtD9hN+GaNC7kvjvcqRAxW25qjew== + dependencies: + "@jimp/utils" "^0.6.8" + core-js "^2.5.7" + pngjs "^3.3.3" + +"@jimp/tiff@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/tiff/-/tiff-0.6.8.tgz#79bd22ed435edbe29d02a2c8c9bf829f988ebacc" + integrity sha512-iWHbxd+0IKWdJyJ0HhoJCGYmtjPBOusz1z1HT/DnpePs/Lo3TO4d9ALXqYfUkyG74ZK5jULZ69KLtwuhuJz1bg== + dependencies: + core-js "^2.5.7" + utif "^2.0.1" + +"@jimp/types@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/types/-/types-0.6.8.tgz#4510eb635cd00b201745d70e38f791748baa7075" + integrity sha512-vCZ/Cp2osy69VP21XOBACfHI5HeR60Rfd4Jidj4W73UL+HrFWOtyQiJ7hlToyu1vI5mR/NsUQpzyQvz56ADm5A== + dependencies: + "@jimp/bmp" "^0.6.8" + "@jimp/gif" "^0.6.8" + "@jimp/jpeg" "^0.6.8" + "@jimp/png" "^0.6.8" + "@jimp/tiff" "^0.6.8" + core-js "^2.5.7" + timm "^1.6.1" + +"@jimp/utils@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@jimp/utils/-/utils-0.6.8.tgz#09f794945631173567aa50f72ac28170de58a63d" + integrity sha512-7RDfxQ2C/rarNG9iso5vmnKQbcvlQjBIlF/p7/uYj72WeZgVCB+5t1fFBKJSU4WhniHX4jUMijK+wYGE3Y3bGw== + dependencies: + core-js "^2.5.7" + +"@sindresorhus/is@^0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" + integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow== + +"@types/color-name@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" + integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== + +"@types/cordova@^0.0.34": + version "0.0.34" + resolved "https://registry.yarnpkg.com/@types/cordova/-/cordova-0.0.34.tgz#ea7addf74ecec3d7629827a0c39e2c9addc73d04" + integrity sha1-6nrd907Ow9dimCegw54smt3HPQQ= + +"@types/filesystem@^0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/filesystem/-/filesystem-0.0.29.tgz#ee3748eb5be140dcf980c3bd35f11aec5f7a3748" + integrity sha512-85/1KfRedmfPGsbK8YzeaQUyV1FQAvMPMTuWFQ5EkLd2w7szhNO96bk3Rh/SKmOfd9co2rCLf0Voy4o7ECBOvw== + dependencies: + "@types/filewriter" "*" + +"@types/filewriter@*": + version "0.0.28" + resolved "https://registry.yarnpkg.com/@types/filewriter/-/filewriter-0.0.28.tgz#c054e8af4d9dd75db4e63abc76f885168714d4b3" + integrity sha1-wFTor02d11205jq8dviFFocU1LM= + +"@types/q@^1.5.1": + version "1.5.2" + resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" + integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw== + +"@webassemblyjs/ast@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" + integrity sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA== + dependencies: + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" + +"@webassemblyjs/floating-point-hex-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz#3c3d3b271bddfc84deb00f71344438311d52ffb4" + integrity sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA== + +"@webassemblyjs/helper-api-error@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz#203f676e333b96c9da2eeab3ccef33c45928b6a2" + integrity sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw== + +"@webassemblyjs/helper-buffer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz#a1442d269c5feb23fcbc9ef759dac3547f29de00" + integrity sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA== + +"@webassemblyjs/helper-code-frame@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz#647f8892cd2043a82ac0c8c5e75c36f1d9159f27" + integrity sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA== + dependencies: + "@webassemblyjs/wast-printer" "1.9.0" + +"@webassemblyjs/helper-fsm@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz#c05256b71244214671f4b08ec108ad63b70eddb8" + integrity sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw== + +"@webassemblyjs/helper-module-context@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz#25d8884b76839871a08a6c6f806c3979ef712f07" + integrity sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g== + dependencies: + "@webassemblyjs/ast" "1.9.0" + +"@webassemblyjs/helper-wasm-bytecode@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz#4fed8beac9b8c14f8c58b70d124d549dd1fe5790" + integrity sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw== + +"@webassemblyjs/helper-wasm-section@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz#5a4138d5a6292ba18b04c5ae49717e4167965346" + integrity sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + +"@webassemblyjs/ieee754@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz#15c7a0fbaae83fb26143bbacf6d6df1702ad39e4" + integrity sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.9.0.tgz#f19ca0b76a6dc55623a09cffa769e838fa1e1c95" + integrity sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.9.0.tgz#04d33b636f78e6a6813227e82402f7637b6229ab" + integrity sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w== + +"@webassemblyjs/wasm-edit@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz#3fe6d79d3f0f922183aa86002c42dd256cfee9cf" + integrity sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/helper-wasm-section" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-opt" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + "@webassemblyjs/wast-printer" "1.9.0" + +"@webassemblyjs/wasm-gen@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz#50bc70ec68ded8e2763b01a1418bf43491a7a49c" + integrity sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + +"@webassemblyjs/wasm-opt@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz#2211181e5b31326443cc8112eb9f0b9028721a61" + integrity sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + +"@webassemblyjs/wasm-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz#9d48e44826df4a6598294aa6c87469d642fff65e" + integrity sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + +"@webassemblyjs/wast-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz#3031115d79ac5bd261556cecc3fa90a3ef451914" + integrity sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/floating-point-hex-parser" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-code-frame" "1.9.0" + "@webassemblyjs/helper-fsm" "1.9.0" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/wast-printer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz#4935d54c85fef637b00ce9f52377451d00d47899" + integrity sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" + "@xtuc/long" "4.2.2" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +accepts@~1.3.4, accepts@~1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + dependencies: + mime-types "~2.1.24" + negotiator "0.6.2" + +acorn-jsx@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" + integrity sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s= + dependencies: + acorn "^3.0.4" + +acorn-jsx@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.2.0.tgz#4c66069173d6fdd68ed85239fc256226182b2ebe" + integrity sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ== + +acorn-walk@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.1.1.tgz#345f0dffad5c735e7373d2fec9a1023e6a44b83e" + integrity sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ== + +acorn@^3.0.4: + version "3.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + integrity sha1-ReN/s56No/JbruP/U2niu18iAXo= + +acorn@^5.5.0: + version "5.7.4" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e" + integrity sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg== + +acorn@^6.0.7, acorn@^6.2.1: + version "6.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" + integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA== + +acorn@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.1.tgz#e35668de0b402f359de515c5482a1ab9f89a69bf" + integrity sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg== + +after@0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" + integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= + +ajv-errors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" + integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== + +ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" + integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== + +ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.9.1: + version "6.12.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.0.tgz#06d60b96d87b8454a5adaba86e7854da629db4b7" + integrity sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +alphanum-sort@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" + integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= + +ansi-colors@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-1.1.0.tgz#6374b4dd5d4718ff3ce27a671a3b1cad077132a9" + integrity sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA== + dependencies: + ansi-wrap "^0.1.0" + +ansi-escapes@^1.1.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" + integrity sha1-06ioOzGapneTZisT52HHkRQiMG4= + +ansi-escapes@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" + integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== + +ansi-gray@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251" + integrity sha1-KWLPVOyXksSFEKPetSRDaGHvclE= + dependencies: + ansi-wrap "0.1.0" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + +ansi-regex@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" + integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +ansi-styles@^3.2.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" + integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== + dependencies: + "@types/color-name" "^1.1.1" + color-convert "^2.0.1" + +ansi-wrap@0.1.0, ansi-wrap@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" + integrity sha1-qCJQ3bABXponyoLoLqYDu/pF768= + +any-base@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/any-base/-/any-base-1.1.0.tgz#ae101a62bc08a597b4c9ab5b7089d456630549fe" + integrity sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg== + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +aproba@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +arch@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/arch/-/arch-2.1.1.tgz#8f5c2731aa35a30929221bb0640eed65175ec84e" + integrity sha512-BLM56aPo9vLLFVa8+/+pJLnrZ7QGGTVHWsCwieAWT9o9K8UeGaQbzZbGoabWLOo2ksBCztoXdqBZBplqLDDCSg== + +archive-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/archive-type/-/archive-type-4.0.0.tgz#f92e72233056dfc6969472749c267bdb046b1d70" + integrity sha1-+S5yIzBW38aWlHJ0nCZ72wRrHXA= + dependencies: + file-type "^4.2.0" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + +array-differ@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" + integrity sha1-7/UuN1gknTO+QCuLuOVkuytdQDE= + +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + +arraybuffer.slice@~0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675" + integrity sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog== + +arrify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + +asn1.js@^4.0.0: + version "4.10.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" + integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +assert@^1.1.1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" + integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== + dependencies: + object-assign "^4.1.1" + util "0.10.3" + +assets@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/assets/-/assets-3.0.1.tgz#7a69f4bcc3aca9702760e2a73a7e76ca93e9e3e0" + integrity sha512-fTyLNf/9V24y5zO83f4DAEuvaKj7MWBixbnqdZneAhsv1r21yQ/6ogZfvXHmphJAHsz4DhuOwHeJKVbGqqvk0Q== + dependencies: + async "^2.5.0" + bluebird "^3.4.6" + calipers "^2.0.0" + calipers-gif "^2.0.0" + calipers-jpeg "^2.0.0" + calipers-png "^2.0.0" + calipers-svg "^2.0.0" + calipers-webp "^2.0.0" + glob "^7.0.6" + lodash "^4.15.0" + mime "^2.4.0" + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +ast-types@0.9.6: + version "0.9.6" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.6.tgz#102c9e9e9005d3e7e3829bf0c4fa24ee862ee9b9" + integrity sha1-ECyenpAF0+fjgpvwxPok7oYu6bk= + +astral-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== + +async-each-series@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/async-each-series/-/async-each-series-0.1.1.tgz#7617c1917401fd8ca4a28aadce3dbae98afeb432" + integrity sha1-dhfBkXQB/Yykooqtzj266Yr+tDI= + +async-each@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== + +async-limiter@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== + +async@1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= + +async@^2.5.0: + version "2.6.3" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== + dependencies: + lodash "^4.17.14" + +async@~0.2.10: + version "0.2.10" + resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" + integrity sha1-trvgsGdLnXGXCMo43owjfLUmw9E= + +async@~2.1.4: + version "2.1.5" + resolved "https://registry.yarnpkg.com/async/-/async-2.1.5.tgz#e587c68580994ac67fc56ff86d3ac56bdbe810bc" + integrity sha1-5YfGhYCZSsZ/xW/4bTrFa9voELw= + dependencies: + lodash "^4.14.0" + +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +autoprefixer@^9.4.3, autoprefixer@^9.4.7, autoprefixer@^9.6.1: + version "9.7.6" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.7.6.tgz#63ac5bbc0ce7934e6997207d5bb00d68fa8293a4" + integrity sha512-F7cYpbN7uVVhACZTeeIeealwdGM6wMtfWARVLTy5xmKtgVdBNJvbDRoCK3YO1orcs7gv/KwYlb3iXwu9Ug9BkQ== + dependencies: + browserslist "^4.11.1" + caniuse-lite "^1.0.30001039" + chalk "^2.4.2" + normalize-range "^0.1.2" + num2fraction "^1.2.2" + postcss "^7.0.27" + postcss-value-parser "^4.0.3" + +axios@0.19.0: + version "0.19.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.0.tgz#8e09bff3d9122e133f7b8101c8fbdd00ed3d2ab8" + integrity sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ== + dependencies: + follow-redirects "1.5.10" + is-buffer "^2.0.2" + +babel-loader@^8.0.4: + version "8.1.0" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.1.0.tgz#c611d5112bd5209abe8b9fa84c3e4da25275f1c3" + integrity sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw== + dependencies: + find-cache-dir "^2.1.0" + loader-utils "^1.4.0" + mkdirp "^0.5.3" + pify "^4.0.1" + schema-utils "^2.6.5" + +babel-plugin-closure-elimination@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/babel-plugin-closure-elimination/-/babel-plugin-closure-elimination-1.3.0.tgz#3217fbf6d416dfdf14ff41a8a34e4d0a6bfc22b2" + integrity sha512-ClKuSxKLLNhe69bvTMuONDI0dQDW49lXB2qtQyyKCzvwegRGel/q4/e+1EoDNDN97Hf1QkxGMbzpAGPmU4Tfjw== + +babel-plugin-console-source@^2.0.2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/babel-plugin-console-source/-/babel-plugin-console-source-2.0.4.tgz#263985b1d69b68e463358d087fa877dd967c5f41" + integrity sha512-OGhrdhuMjiEW0Ma0P9e2B4dFddCpJ/xN/RRaM/4wwDLl+6ZKf+Xd77FtVjpNeDzNRNk8wjRdStA4hpZizXzl1g== + +babel-plugin-danger-remove-unused-import@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/babel-plugin-danger-remove-unused-import/-/babel-plugin-danger-remove-unused-import-1.1.2.tgz#ac39c30edfe524ef8cfc411fec5edc479d19e132" + integrity sha512-3bNmVAaakP3b1aROj7O3bOWj2kBa85sZR5naZ3Rn8L9buiZaAyZLgjfrPDL3zhX4wySOA5jrTm/wSmJPsMm3cg== + +babel-plugin-dynamic-import-node@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz#f00f507bdaa3c3e3ff6e7e5e98d90a7acab96f7f" + integrity sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ== + dependencies: + object.assign "^4.1.0" + +babel-polyfill@6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.23.0.tgz#8364ca62df8eafb830499f699177466c3b03499d" + integrity sha1-g2TKYt+Or7gwSZ9pkXdGbDsDSZ0= + dependencies: + babel-runtime "^6.22.0" + core-js "^2.4.0" + regenerator-runtime "^0.10.0" + +babel-runtime@^6.22.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babel-runtime@^7.0.0-beta.3: + version "7.0.0-beta.3" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-7.0.0-beta.3.tgz#7c750de5514452c27612172506b49085a4a630f2" + integrity sha512-jlzZ8RACjt0QGxq+wqsw5bCQE9RcUyWpw987mDY3GYxTpOQT2xoyNoG++oVCHzr/nACLBIprfVBNvv/If1ZYcg== + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +backo2@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" + integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base64-arraybuffer@0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8" + integrity sha1-c5JncZI7Whl0etZmqlzUv5xunOg= + +base64-js@^1.0.2: + version "1.3.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" + integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== + +base64id@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/base64id/-/base64id-1.0.0.tgz#47688cb99bb6804f0e06d3e763b1c32e57d8e6b6" + integrity sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY= + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= + +better-assert@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/better-assert/-/better-assert-1.0.2.tgz#40866b9e1b9e0b55b481894311e68faffaebc522" + integrity sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI= + dependencies: + callsite "1.0.0" + +bfj@^6.1.1: + version "6.1.2" + resolved "https://registry.yarnpkg.com/bfj/-/bfj-6.1.2.tgz#325c861a822bcb358a41c78a33b8e6e2086dde7f" + integrity sha512-BmBJa4Lip6BPRINSZ0BPEIfB1wUY/9rwbwvIHQA1KjX9om29B6id0wnWXq7m3bn5JrUVjeOTnVuhPT1FiHwPGw== + dependencies: + bluebird "^3.5.5" + check-types "^8.0.3" + hoopy "^0.1.4" + tryer "^1.0.1" + +big.js@^3.1.3: + version "3.2.0" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" + integrity sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q== + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +bin-build@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bin-build/-/bin-build-3.0.0.tgz#c5780a25a8a9f966d8244217e6c1f5082a143861" + integrity sha512-jcUOof71/TNAI2uM5uoUaDq2ePcVBQ3R/qhxAz1rX7UfvduAL/RXD3jXzvn8cVcDJdGVkiR1shal3OH0ImpuhA== + dependencies: + decompress "^4.0.0" + download "^6.2.2" + execa "^0.7.0" + p-map-series "^1.0.0" + tempfile "^2.0.0" + +bin-check@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bin-check/-/bin-check-4.1.0.tgz#fc495970bdc88bb1d5a35fc17e65c4a149fc4a49" + integrity sha512-b6weQyEUKsDGFlACWSIOfveEnImkJyK/FGW6FAG42loyoquvjdtOIqO6yBFzHyqyVVhNgNkQxxx09SFLK28YnA== + dependencies: + execa "^0.7.0" + executable "^4.1.0" + +bin-version-check@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/bin-version-check/-/bin-version-check-4.0.0.tgz#7d819c62496991f80d893e6e02a3032361608f71" + integrity sha512-sR631OrhC+1f8Cvs8WyVWOA33Y8tgwjETNPyyD/myRBXLkfS/vl74FmH/lFcRl9KY3zwGh7jFhvyk9vV3/3ilQ== + dependencies: + bin-version "^3.0.0" + semver "^5.6.0" + semver-truncate "^1.1.2" + +bin-version@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bin-version/-/bin-version-3.1.0.tgz#5b09eb280752b1bd28f0c9db3f96f2f43b6c0839" + integrity sha512-Mkfm4iE1VFt4xd4vH+gx+0/71esbfus2LsnCGe8Pi4mndSPyT+NGES/Eg99jx8/lUGWfu3z2yuB/bt5UB+iVbQ== + dependencies: + execa "^1.0.0" + find-versions "^3.0.0" + +bin-wrapper@^4.0.0, bin-wrapper@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bin-wrapper/-/bin-wrapper-4.1.0.tgz#99348f2cf85031e3ef7efce7e5300aeaae960605" + integrity sha512-hfRmo7hWIXPkbpi0ZltboCMVrU+0ClXR/JgbCKKjlDjQf6igXa7OwdqNcFWQZPZTgiY7ZpzE3+LjjkLiTN2T7Q== + dependencies: + bin-check "^4.1.0" + bin-version-check "^4.0.0" + download "^7.1.0" + import-lazy "^3.1.0" + os-filter-obj "^2.0.0" + pify "^4.0.1" + +binary-extensions@^1.0.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== + +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +bl@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c" + integrity sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA== + dependencies: + readable-stream "^2.3.5" + safe-buffer "^5.1.1" + +blob@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.5.tgz#d680eeef25f8cd91ad533f5b01eed48e64caf683" + integrity sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig== + +bluebird@3.x.x, bluebird@^3.4.6, bluebird@^3.5.0, bluebird@^3.5.5: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +bmp-js@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.1.0.tgz#e05a63f796a6c1ff25f4771ec7adadc148c07233" + integrity sha1-4Fpj95amwf8l9Hcex62twUjAcjM= + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: + version "4.11.8" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" + integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== + +body-parser@1.19.0: + version "1.19.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" + integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== + dependencies: + bytes "3.1.0" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "1.7.2" + iconv-lite "0.4.24" + on-finished "~2.3.0" + qs "6.7.0" + raw-body "2.4.0" + type-is "~1.6.17" + +boolbase@^1.0.0, boolbase@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^2.3.1, braces@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + +browser-sync-client@^2.26.6: + version "2.26.6" + resolved "https://registry.yarnpkg.com/browser-sync-client/-/browser-sync-client-2.26.6.tgz#e5201d3ace8aee88af17656b7b0c0620b6f8e4ab" + integrity sha512-mGrkZdNzttKdf/16I+y+2dTQxoMCIpKbVIMJ/uP8ZpnKu9f9qa/2CYVtLtbjZG8nsM14EwiCrjuFTGBEnT3Gjw== + dependencies: + etag "1.8.1" + fresh "0.5.2" + mitt "^1.1.3" + rxjs "^5.5.6" + +browser-sync-ui@^2.26.4: + version "2.26.4" + resolved "https://registry.yarnpkg.com/browser-sync-ui/-/browser-sync-ui-2.26.4.tgz#3772f13c6b93f2d7d333f4be0ca1ec02aae97dba" + integrity sha512-u20P3EsZoM8Pt+puoi3BU3KlbQAH1lAcV+/O4saF26qokrBqIDotmGonfWwoRbUmdxZkM9MBmA0K39ZTG1h4sA== + dependencies: + async-each-series "0.1.1" + connect-history-api-fallback "^1" + immutable "^3" + server-destroy "1.0.1" + socket.io-client "^2.0.4" + stream-throttle "^0.1.3" + +browser-sync@^2.24.6: + version "2.26.7" + resolved "https://registry.yarnpkg.com/browser-sync/-/browser-sync-2.26.7.tgz#120287716eb405651a76cc74fe851c31350557f9" + integrity sha512-lY3emme0OyvA2ujEMpRmyRy9LY6gHLuTr2/ABxhIm3lADOiRXzP4dgekvnDrQqZ/Ec2Fz19lEjm6kglSG5766w== + dependencies: + browser-sync-client "^2.26.6" + browser-sync-ui "^2.26.4" + bs-recipes "1.3.4" + bs-snippet-injector "^2.0.1" + chokidar "^2.0.4" + connect "3.6.6" + connect-history-api-fallback "^1" + dev-ip "^1.0.1" + easy-extender "^2.3.4" + eazy-logger "^3" + etag "^1.8.1" + fresh "^0.5.2" + fs-extra "3.0.1" + http-proxy "1.15.2" + immutable "^3" + localtunnel "1.9.2" + micromatch "^3.1.10" + opn "5.3.0" + portscanner "2.1.1" + qs "6.2.3" + raw-body "^2.3.2" + resp-modifier "6.0.2" + rx "4.1.0" + send "0.16.2" + serve-index "1.9.1" + serve-static "1.13.2" + server-destroy "1.0.1" + socket.io "2.1.1" + ua-parser-js "0.7.17" + yargs "6.4.0" + +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" + integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= + dependencies: + bn.js "^4.1.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" + integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg= + dependencies: + bn.js "^4.1.1" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.2" + elliptic "^6.0.0" + inherits "^2.0.1" + parse-asn1 "^5.0.0" + +browserify-zlib@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== + dependencies: + pako "~1.0.5" + +browserslist@^4.0.0, browserslist@^4.11.1, browserslist@^4.6.4, browserslist@^4.8.5, browserslist@^4.9.1: + version "4.11.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.11.1.tgz#92f855ee88d6e050e7e7311d987992014f1a1f1b" + integrity sha512-DCTr3kDrKEYNw6Jb9HFxVLQNaue8z+0ZfRBRjmCunKDEXEBajKDj2Y+Uelg+Pi29OnvaSGwjOsnRyNEkXzHg5g== + dependencies: + caniuse-lite "^1.0.30001038" + electron-to-chromium "^1.3.390" + node-releases "^1.1.53" + pkg-up "^2.0.0" + +bs-recipes@1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/bs-recipes/-/bs-recipes-1.3.4.tgz#0d2d4d48a718c8c044769fdc4f89592dc8b69585" + integrity sha1-DS1NSKcYyMBEdp/cT4lZLci2lYU= + +bs-snippet-injector@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/bs-snippet-injector/-/bs-snippet-injector-2.0.1.tgz#61b5393f11f52559ed120693100343b6edb04dd5" + integrity sha1-YbU5PxH1JVntEgaTEANDtu2wTdU= + +buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== + +buffer-alloc@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= + +buffer-equal@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-0.0.1.tgz#91bc74b11ea405bc916bc6aa908faafa5b4aac4b" + integrity sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs= + +buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= + +buffer@^4.3.0: + version "4.9.2" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" + integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +buffer@^5.2.0, buffer@^5.2.1: + version "5.5.0" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.5.0.tgz#9c3caa3d623c33dd1c7ef584b89b88bf9c9bc1ce" + integrity sha512-9FTEDjLjwoAkEwyMGDjYJQN2gfRgOKBKRfiglhvibGbpeeU/pQn1bJxQqm32OD/AIeEuHxU9roxXxg34Byp/Ww== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= + +bytes@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" + integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== + +cacache@^12.0.2: + version "12.0.4" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" + integrity sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ== + dependencies: + bluebird "^3.5.5" + chownr "^1.1.1" + figgy-pudding "^3.5.1" + glob "^7.1.4" + graceful-fs "^4.1.15" + infer-owner "^1.0.3" + lru-cache "^5.1.1" + mississippi "^3.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.3" + ssri "^6.0.1" + unique-filename "^1.1.1" + y18n "^4.0.0" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +cacheable-request@^2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-2.1.4.tgz#0d808801b6342ad33c91df9d0b44dc09b91e5c3d" + integrity sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0= + dependencies: + clone-response "1.0.2" + get-stream "3.0.0" + http-cache-semantics "3.8.1" + keyv "3.0.0" + lowercase-keys "1.0.0" + normalize-url "2.0.1" + responselike "1.0.2" + +calipers-gif@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/calipers-gif/-/calipers-gif-2.0.0.tgz#b5eefec3064a77c6dcdbd5bdc51735a01bafdc37" + integrity sha1-te7+wwZKd8bc29W9xRc1oBuv3Dc= + dependencies: + bluebird "3.x.x" + +calipers-jpeg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/calipers-jpeg/-/calipers-jpeg-2.0.0.tgz#06d56a53f62717dd809cb956cf64423ce693465b" + integrity sha1-BtVqU/YnF92AnLlWz2RCPOaTRls= + dependencies: + bluebird "3.x.x" + +calipers-png@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/calipers-png/-/calipers-png-2.0.0.tgz#1d0d20e5c1ae5f79b74d5286a2e97f59bb70b658" + integrity sha1-HQ0g5cGuX3m3TVKGoul/Wbtwtlg= + dependencies: + bluebird "3.x.x" + +calipers-svg@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/calipers-svg/-/calipers-svg-2.0.1.tgz#cd9eaa58ef7428c1a14f5da57e56715fb60f6541" + integrity sha512-3PROqHARmj8wWudUC7DzXm1+mSocqgY7jNuehFNHgrUVrKf8o7MqDjS92vJz5LvZsAofJsoAFMajkqwbxBROSQ== + dependencies: + bluebird "3.x.x" + +calipers-webp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/calipers-webp/-/calipers-webp-2.0.0.tgz#e126ece2f84cd71779612bfa2b2653cd95cea77a" + integrity sha1-4Sbs4vhM1xd5YSv6KyZTzZXOp3o= + dependencies: + bluebird "3.x.x" + +calipers@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/calipers/-/calipers-2.0.1.tgz#0d3f303ce75ec5f1eda7fecfc7dba6736e35c926" + integrity sha512-AP4Ui2Z8fZf69d8Dx4cfJgPjQHY3m+QXGFCaAGu8pfNQjyajkosS+Kkf1n6pQDMZcelN5h3MdcjweUqxcsS4pg== + dependencies: + bluebird "3.x.x" + +caller-callsite@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" + integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= + dependencies: + callsites "^2.0.0" + +caller-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" + integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= + dependencies: + caller-callsite "^2.0.0" + +callsite@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" + integrity sha1-KAOY5dZkvXQDi28JBRU+borxvCA= + +callsites@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" + integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camel-case@3.0.x: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" + integrity sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M= + dependencies: + no-case "^2.2.0" + upper-case "^1.1.1" + +camelcase-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc= + dependencies: + camelcase "^2.0.0" + map-obj "^1.0.0" + +camelcase@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= + +camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo= + +camelcase@^5.0.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +caniuse-api@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" + integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw== + dependencies: + browserslist "^4.0.0" + caniuse-lite "^1.0.0" + lodash.memoize "^4.1.2" + lodash.uniq "^4.5.0" + +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001038, caniuse-lite@^1.0.30001039: + version "1.0.30001041" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001041.tgz#c2ea138dafc6fe03877921ddcddd4a02a14daf76" + integrity sha512-fqDtRCApddNrQuBxBS7kEiSGdBsgO4wiVw4G/IClfqzfhW45MbTumfN4cuUJGTM0YGFNn97DCXPJ683PS6zwvA== + +caw@^2.0.0, caw@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/caw/-/caw-2.0.1.tgz#6c3ca071fc194720883c2dc5da9b074bfc7e9e95" + integrity sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA== + dependencies: + get-proxy "^2.0.0" + isurl "^1.0.0-alpha5" + tunnel-agent "^0.6.0" + url-to-options "^1.0.1" + +chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.2.tgz#250dc96b07491bfd601e648d66ddf5f60c7a5c65" + integrity sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chance@1.0.13: + version "1.0.13" + resolved "https://registry.yarnpkg.com/chance/-/chance-1.0.13.tgz#666bec2db42b3084456a3e4f4c28a82db5ccb7e6" + integrity sha512-9cpcgmAIQiXC0eMgQuMZgXuHR2Y+gKUyGQnalqSAg5LlUJyJFsZeKyuHVSGhj+bx18ppH+Jo3VOayNeXR/7p9Q== + +chardet@^0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" + integrity sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I= + +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + +charenc@~0.0.1: + version "0.0.2" + resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" + integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc= + +check-types@^8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/check-types/-/check-types-8.0.3.tgz#3356cca19c889544f2d7a95ed49ce508a0ecf552" + integrity sha512-YpeKZngUmG65rLudJ4taU7VLkOCTMhNl/u4ctNC56LQS/zJTyNH0Lrtwm1tfTsbLlwvlfsA2d1c8vCf/Kh2KwQ== + +chokidar@^2.0.4, chokidar@^2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.2.1" + upath "^1.1.1" + optionalDependencies: + fsevents "^1.2.7" + +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + +chrome-trace-event@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" + integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ== + dependencies: + tslib "^1.9.0" + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +circular-dependency-plugin@^5.0.2: + version "5.2.0" + resolved "https://registry.yarnpkg.com/circular-dependency-plugin/-/circular-dependency-plugin-5.2.0.tgz#e09dbc2dd3e2928442403e2d45b41cea06bc0a93" + integrity sha512-7p4Kn/gffhQaavNfyDFg7LS5S/UT1JAjyGd4UqR2+jzoYF02eDkj0Ec3+48TsIa4zghjLY87nQHIh/ecK9qLdw== + +circular-json@^0.5.9: + version "0.5.9" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.5.9.tgz#932763ae88f4f7dead7a0d09c8a51a4743a53b1d" + integrity sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ== + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +class-validator@0.8.5: + version "0.8.5" + resolved "https://registry.yarnpkg.com/class-validator/-/class-validator-0.8.5.tgz#484785acda98f68549c3a84dc1bb2f77b736dc58" + integrity sha512-84yezRo44aP4oGhvPmqj6obAFQF1NzUyfR0+f8jubzdAspO5pmjpHhBBlPf335epUskzXAFe5uo4Qf+c7SI+DA== + dependencies: + validator "9.2.0" + +clean-css@4.2.x: + version "4.2.3" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78" + integrity sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA== + dependencies: + source-map "~0.6.0" + +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= + dependencies: + restore-cursor "^2.0.0" + +cli-table@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.1.tgz#f53b05266a8b1a0b934b3d0821e6e2dc5914ae23" + integrity sha1-9TsFJmqLGguTSz0IIebi3FkUriM= + dependencies: + colors "1.0.3" + +cli-width@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= + +clipboard-copy@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/clipboard-copy/-/clipboard-copy-3.1.0.tgz#4c59030a43d4988990564a664baeafba99f78ca4" + integrity sha512-Xsu1NddBXB89IUauda5BIq3Zq73UWkjkaQlPQbLNvNsd5WBMnTWPNKYR6HGaySOxGYZ+BKxP2E9X4ElnI3yiPA== + +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + +cliui@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" + integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== + dependencies: + string-width "^3.1.0" + strip-ansi "^5.2.0" + wrap-ansi "^5.1.0" + +cliui@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" + integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^6.2.0" + +clone-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" + integrity sha1-4+JbIHrE5wGvch4staFnksrD3Fg= + +clone-response@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" + integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= + dependencies: + mimic-response "^1.0.0" + +clone-stats@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" + integrity sha1-s3gt/4u1R04Yuba/D9/ngvh3doA= + +clone@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= + +cloneable-readable@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.1.3.tgz#120a00cb053bfb63a222e709f9683ea2e11d8cec" + integrity sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ== + dependencies: + inherits "^2.0.1" + process-nextick-args "^2.0.0" + readable-stream "^2.3.5" + +coa@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3" + integrity sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA== + dependencies: + "@types/q" "^1.5.1" + chalk "^2.4.1" + q "^1.1.2" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0, color-convert@^1.9.1: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@^1.0.0, color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +color-string@^1.5.2: + version "1.5.3" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc" + integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw== + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + +color-support@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" + integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== + +color@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/color/-/color-3.1.2.tgz#68148e7f85d41ad7649c5fa8c8106f098d229e10" + integrity sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg== + dependencies: + color-convert "^1.9.1" + color-string "^1.5.2" + +colors@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" + integrity sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs= + +colors@^1.3.3: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + +commander@2.15.1: + version "2.15.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" + integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== + +commander@2.17.x: + version "2.17.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" + integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== + +commander@^2.18.0, commander@^2.2.0, commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@~2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" + integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== + +commander@~2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4" + integrity sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ= + dependencies: + graceful-readlink ">= 1.0.0" + +commander@~2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" + integrity sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q= + dependencies: + graceful-readlink ">= 1.0.0" + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + +component-bind@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1" + integrity sha1-AMYIq33Nk4l8AAllGx06jh5zu9E= + +component-emitter@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= + +component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +component-inherit@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143" + integrity sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM= + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +concat-stream@^1.5.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +config-chain@^1.1.11: + version "1.1.12" + resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa" + integrity sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA== + dependencies: + ini "^1.3.4" + proto-list "~1.2.1" + +connect-history-api-fallback@^1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" + integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== + +connect@3.6.6: + version "3.6.6" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.6.6.tgz#09eff6c55af7236e137135a72574858b6786f524" + integrity sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ= + dependencies: + debug "2.6.9" + finalhandler "1.1.0" + parseurl "~1.3.2" + utils-merge "1.0.1" + +console-browserify@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" + integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== + +console-stream@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/console-stream/-/console-stream-0.1.1.tgz#a095fe07b20465955f2fafd28b5d72bccd949d44" + integrity sha1-oJX+B7IEZZVfL6/Si11yvM2UnUQ= + +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= + +content-disposition@0.5.3, content-disposition@^0.5.2: + version "0.5.3" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" + integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== + dependencies: + safe-buffer "5.1.2" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +convert-source-map@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" + integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== + dependencies: + safe-buffer "~5.1.1" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= + +cookie@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" + integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== + +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +core-js-compat@^3.6.2: + version "3.6.5" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.6.5.tgz#2a51d9a4e25dfd6e690251aa81f99e3c05481f1c" + integrity sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng== + dependencies: + browserslist "^4.8.5" + semver "7.0.0" + +core-js@3: + version "3.6.5" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.5.tgz#7395dc273af37fb2e50e9bd3d9fe841285231d1a" + integrity sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA== + +core-js@^2.4.0, core-js@^2.5.3, core-js@^2.5.7: + version "2.6.11" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c" + integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg== + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +cosmiconfig@^5.0.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" + integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA== + dependencies: + import-fresh "^2.0.0" + is-directory "^0.3.1" + js-yaml "^3.13.1" + parse-json "^4.0.0" + +create-ecdh@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" + integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== + dependencies: + bn.js "^4.1.0" + elliptic "^6.0.0" + +create-hash@^1.1.0, create-hash@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +crypt@~0.0.1: + version "0.0.2" + resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" + integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs= + +crypto-browserify@^3.11.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +css-blank-pseudo@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz#dfdefd3254bf8a82027993674ccf35483bfcb3c5" + integrity sha512-LHz35Hr83dnFeipc7oqFDmsjHdljj3TQtxGGiNWSOsTLIAubSm4TEz8qCaKFpk7idaQ1GfWscF4E6mgpBysA1w== + dependencies: + postcss "^7.0.5" + +css-color-names@0.0.4, css-color-names@^0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" + integrity sha1-gIrcLnnPhHOAabZGyyDsJ762KeA= + +css-declaration-sorter@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz#c198940f63a76d7e36c1e71018b001721054cb22" + integrity sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA== + dependencies: + postcss "^7.0.1" + timsort "^0.3.0" + +css-has-pseudo@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/css-has-pseudo/-/css-has-pseudo-0.10.0.tgz#3c642ab34ca242c59c41a125df9105841f6966ee" + integrity sha512-Z8hnfsZu4o/kt+AuFzeGpLVhFOGO9mluyHBaA2bA8aCGTwah5sT3WV/fTHH8UNZUytOIImuGPrl/prlb4oX4qQ== + dependencies: + postcss "^7.0.6" + postcss-selector-parser "^5.0.0-rc.4" + +css-loader@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.9.1.tgz#2e1aa00ce7e30ef2c6a7a4b300a080a7c979e0dc" + integrity sha1-LhqgDOfjDvLGp6SzAKCAp8l54Nw= + dependencies: + csso "1.3.x" + loader-utils "~0.2.2" + source-map "~0.1.38" + +css-mqpacker@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/css-mqpacker/-/css-mqpacker-7.0.0.tgz#48f4a0ff45b81ec661c4a33ed80b9db8a026333b" + integrity sha512-temVrWS+sB4uocE2quhW8ru/KguDmGhCU7zN213KxtDvWOH3WS/ZUStfpF4fdCT7W8fPpFrQdWRFqtFtPPfBLA== + dependencies: + minimist "^1.2.0" + postcss "^7.0.0" + +css-prefers-color-scheme@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz#6f830a2714199d4f0d0d0bb8a27916ed65cff1f4" + integrity sha512-MTu6+tMs9S3EUqzmqLXEcgNRbNkkD/TGFvowpeoWJn5Vfq7FMgsmRQs9X5NXAURiOBmOxm/lLjsDNXDE6k9bhg== + dependencies: + postcss "^7.0.5" + +css-select-base-adapter@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7" + integrity sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w== + +css-select@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.1.0.tgz#6a34653356635934a81baca68d0255432105dbef" + integrity sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ== + dependencies: + boolbase "^1.0.0" + css-what "^3.2.1" + domutils "^1.7.0" + nth-check "^1.0.2" + +css-tree@1.0.0-alpha.37: + version "1.0.0-alpha.37" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.37.tgz#98bebd62c4c1d9f960ec340cf9f7522e30709a22" + integrity sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg== + dependencies: + mdn-data "2.0.4" + source-map "^0.6.1" + +css-tree@1.0.0-alpha.39: + version "1.0.0-alpha.39" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.39.tgz#2bff3ffe1bb3f776cf7eefd91ee5cba77a149eeb" + integrity sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA== + dependencies: + mdn-data "2.0.6" + source-map "^0.6.1" + +css-what@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.2.1.tgz#f4a8f12421064621b456755e34a03a2c22df5da1" + integrity sha512-WwOrosiQTvyms+Ti5ZC5vGEK0Vod3FTt1ca+payZqvKuGJF+dq7bG63DstxtN0dpm6FxY27a/zS3Wten+gEtGw== + +cssdb@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-4.4.0.tgz#3bf2f2a68c10f5c6a08abd92378331ee803cddb0" + integrity sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ== + +cssesc@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-2.0.0.tgz#3b13bd1bb1cb36e1bcb5a4dcd27f54c5dcb35703" + integrity sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg== + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +cssnano-preset-advanced@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/cssnano-preset-advanced/-/cssnano-preset-advanced-4.0.7.tgz#d981527b77712e2f3f3f09c73313e9b71b278b88" + integrity sha512-j1O5/DQnaAqEyFFQfC+Z/vRlLXL3LxJHN+lvsfYqr7KgPH74t69+Rsy2yXkovWNaJjZYBpdz2Fj8ab2nH7pZXw== + dependencies: + autoprefixer "^9.4.7" + cssnano-preset-default "^4.0.7" + postcss-discard-unused "^4.0.1" + postcss-merge-idents "^4.0.1" + postcss-reduce-idents "^4.0.2" + postcss-zindex "^4.0.1" + +cssnano-preset-default@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz#51ec662ccfca0f88b396dcd9679cdb931be17f76" + integrity sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA== + dependencies: + css-declaration-sorter "^4.0.1" + cssnano-util-raw-cache "^4.0.1" + postcss "^7.0.0" + postcss-calc "^7.0.1" + postcss-colormin "^4.0.3" + postcss-convert-values "^4.0.1" + postcss-discard-comments "^4.0.2" + postcss-discard-duplicates "^4.0.2" + postcss-discard-empty "^4.0.1" + postcss-discard-overridden "^4.0.1" + postcss-merge-longhand "^4.0.11" + postcss-merge-rules "^4.0.3" + postcss-minify-font-values "^4.0.2" + postcss-minify-gradients "^4.0.2" + postcss-minify-params "^4.0.2" + postcss-minify-selectors "^4.0.2" + postcss-normalize-charset "^4.0.1" + postcss-normalize-display-values "^4.0.2" + postcss-normalize-positions "^4.0.2" + postcss-normalize-repeat-style "^4.0.2" + postcss-normalize-string "^4.0.2" + postcss-normalize-timing-functions "^4.0.2" + postcss-normalize-unicode "^4.0.1" + postcss-normalize-url "^4.0.1" + postcss-normalize-whitespace "^4.0.2" + postcss-ordered-values "^4.1.2" + postcss-reduce-initial "^4.0.3" + postcss-reduce-transforms "^4.0.2" + postcss-svgo "^4.0.2" + postcss-unique-selectors "^4.0.1" + +cssnano-util-get-arguments@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz#ed3a08299f21d75741b20f3b81f194ed49cc150f" + integrity sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8= + +cssnano-util-get-match@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz#c0e4ca07f5386bb17ec5e52250b4f5961365156d" + integrity sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0= + +cssnano-util-raw-cache@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz#b26d5fd5f72a11dfe7a7846fb4c67260f96bf282" + integrity sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA== + dependencies: + postcss "^7.0.0" + +cssnano-util-same-parent@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz#574082fb2859d2db433855835d9a8456ea18bbf3" + integrity sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q== + +cssnano@^4.1.10: + version "4.1.10" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-4.1.10.tgz#0ac41f0b13d13d465487e111b778d42da631b8b2" + integrity sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ== + dependencies: + cosmiconfig "^5.0.0" + cssnano-preset-default "^4.0.7" + is-resolvable "^1.0.0" + postcss "^7.0.0" + +csso@1.3.x: + version "1.3.12" + resolved "https://registry.yarnpkg.com/csso/-/csso-1.3.12.tgz#fc628694a2d38938aaac4996753218fd311cdb9e" + integrity sha1-/GKGlKLTiTiqrEmWdTIY/TEc254= + +csso@^4.0.2: + version "4.0.3" + resolved "https://registry.yarnpkg.com/csso/-/csso-4.0.3.tgz#0d9985dc852c7cc2b2cacfbbe1079014d1a8e903" + integrity sha512-NL3spysxUkcrOgnpsT4Xdl2aiEiBG6bXswAABQVHcMrfjjBisFOKwLDOmf4wf32aPdcJws1zds2B0Rg+jqMyHQ== + dependencies: + css-tree "1.0.0-alpha.39" + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= + dependencies: + array-find-index "^1.0.1" + +cyclist@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" + integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= + +debug@2.6.9, debug@^2.2.0, debug@^2.3.3: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@4.1.1, debug@^4.0.1, debug@^4.1.0, debug@~4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + +debug@=3.1.0, debug@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +decamelize@^1.1.1, decamelize@^1.1.2, decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +decompress-response@^3.2.0, decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= + dependencies: + mimic-response "^1.0.0" + +decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1" + integrity sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ== + dependencies: + file-type "^5.2.0" + is-stream "^1.1.0" + tar-stream "^1.5.2" + +decompress-tarbz2@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz#3082a5b880ea4043816349f378b56c516be1a39b" + integrity sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A== + dependencies: + decompress-tar "^4.1.0" + file-type "^6.1.0" + is-stream "^1.1.0" + seek-bzip "^1.0.5" + unbzip2-stream "^1.0.9" + +decompress-targz@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-targz/-/decompress-targz-4.1.1.tgz#c09bc35c4d11f3de09f2d2da53e9de23e7ce1eee" + integrity sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w== + dependencies: + decompress-tar "^4.1.1" + file-type "^5.2.0" + is-stream "^1.1.0" + +decompress-unzip@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/decompress-unzip/-/decompress-unzip-4.0.1.tgz#deaaccdfd14aeaf85578f733ae8210f9b4848f69" + integrity sha1-3qrM39FK6vhVePczroIQ+bSEj2k= + dependencies: + file-type "^3.8.0" + get-stream "^2.2.0" + pify "^2.3.0" + yauzl "^2.4.2" + +decompress@^4.0.0, decompress@^4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/decompress/-/decompress-4.2.1.tgz#007f55cc6a62c055afa37c07eb6a4ee1b773f118" + integrity sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ== + dependencies: + decompress-tar "^4.0.0" + decompress-tarbz2 "^4.0.0" + decompress-targz "^4.0.0" + decompress-unzip "^4.0.1" + graceful-fs "^4.1.10" + make-dir "^1.0.0" + pify "^2.3.0" + strip-dirs "^2.0.0" + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + +deep-scope-analyser@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/deep-scope-analyser/-/deep-scope-analyser-1.7.0.tgz#23015b3a1d23181b1d9cebd25b783a7378ead8da" + integrity sha512-rl5Dmt2IZkFpZo6XbEY1zG8st2Wpq8Pi/dV2gz8ZF6BDYt3fnor2JNxHwdO1WLo0k6JbmYp0x8MNy8kE4l1NtA== + dependencies: + esrecurse "^4.2.1" + estraverse "^4.2.0" + +define-properties@^1.1.2, define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +des.js@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" + integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +detect-file@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" + integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= + +dev-ip@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/dev-ip/-/dev-ip-1.0.1.tgz#a76a3ed1855be7a012bb8ac16cb80f3c00dc28f0" + integrity sha1-p2o+0YVb56ASu4rBbLgPPADcKPA= + +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +dom-serializer@0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" + integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== + dependencies: + domelementtype "^2.0.1" + entities "^2.0.0" + +dom-walk@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" + integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== + +domain-browser@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== + +domelementtype@1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" + integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== + +domelementtype@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d" + integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ== + +domutils@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" + integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== + dependencies: + dom-serializer "0" + domelementtype "1" + +dot-prop@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.2.0.tgz#c34ecc29556dc45f1f4c22697b6f4904e0cc4fcb" + integrity sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A== + dependencies: + is-obj "^2.0.0" + +download@^6.2.2: + version "6.2.5" + resolved "https://registry.yarnpkg.com/download/-/download-6.2.5.tgz#acd6a542e4cd0bb42ca70cfc98c9e43b07039714" + integrity sha512-DpO9K1sXAST8Cpzb7kmEhogJxymyVUd5qz/vCOSyvwtp2Klj2XcDt5YUuasgxka44SxF0q5RriKIwJmQHG2AuA== + dependencies: + caw "^2.0.0" + content-disposition "^0.5.2" + decompress "^4.0.0" + ext-name "^5.0.0" + file-type "5.2.0" + filenamify "^2.0.0" + get-stream "^3.0.0" + got "^7.0.0" + make-dir "^1.0.0" + p-event "^1.0.0" + pify "^3.0.0" + +download@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/download/-/download-7.1.0.tgz#9059aa9d70b503ee76a132897be6dec8e5587233" + integrity sha512-xqnBTVd/E+GxJVrX5/eUJiLYjCGPwMpdL+jGhGU57BvtcA7wwhtHVbXBeUk51kOpW3S7Jn3BQbN9Q1R1Km2qDQ== + dependencies: + archive-type "^4.0.0" + caw "^2.0.1" + content-disposition "^0.5.2" + decompress "^4.2.0" + ext-name "^5.0.0" + file-type "^8.1.0" + filenamify "^2.0.0" + get-stream "^3.0.0" + got "^8.3.1" + make-dir "^1.2.0" + p-event "^2.1.0" + pify "^3.0.0" + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= + +duplexer@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + integrity sha1-rOb/gIwc5mtX0ev5eXessCM0z8E= + +duplexify@^3.4.2, duplexify@^3.6.0: + version "3.7.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +easy-extender@^2.3.4: + version "2.3.4" + resolved "https://registry.yarnpkg.com/easy-extender/-/easy-extender-2.3.4.tgz#298789b64f9aaba62169c77a2b3b64b4c9589b8f" + integrity sha512-8cAwm6md1YTiPpOvDULYJL4ZS6WfM5/cTeVVh4JsvyYZAoqlRVUpHL9Gr5Fy7HA6xcSZicUia3DeAgO3Us8E+Q== + dependencies: + lodash "^4.17.10" + +eazy-logger@^3: + version "3.0.2" + resolved "https://registry.yarnpkg.com/eazy-logger/-/eazy-logger-3.0.2.tgz#a325aa5e53d13a2225889b2ac4113b2b9636f4fc" + integrity sha1-oyWqXlPROiIliJsqxBE7K5Y29Pw= + dependencies: + tfunk "^3.0.1" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +ejs@^2.6.1: + version "2.7.4" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.4.tgz#48661287573dcc53e366c7a1ae52c3a120eec9ba" + integrity sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA== + +electron-to-chromium@^1.3.390: + version "1.3.403" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.403.tgz#c8bab4e2e72bf78bc28bad1cc355c061f9cc1918" + integrity sha512-JaoxV4RzdBAZOnsF4dAlZ2ijJW72MbqO5lNfOBHUWiBQl3Rwe+mk2RCUMrRI3rSClLJ8HSNQNqcry12H+0ZjFw== + +elliptic@^6.0.0: + version "6.5.2" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" + integrity sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw== + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + +email-validator@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/email-validator/-/email-validator-2.0.4.tgz#b8dfaa5d0dae28f1b03c95881d904d4e40bfe7ed" + integrity sha512-gYCwo7kh5S3IDyZPLZf6hSS0MnZT8QmJFqYvbqlDZSbwdZlY6QZWxJ4i/6UhITOJ4XzyI647Bm2MXKCLqnJ4nQ== + +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + +encodeurl@~1.0.1, encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +encoding@^0.1.11: + version "0.1.12" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" + integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s= + dependencies: + iconv-lite "~0.4.13" + +end-of-stream@^1.0.0, end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +engine.io-client@~3.2.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.2.1.tgz#6f54c0475de487158a1a7c77d10178708b6add36" + integrity sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw== + dependencies: + component-emitter "1.2.1" + component-inherit "0.0.3" + debug "~3.1.0" + engine.io-parser "~2.1.1" + has-cors "1.1.0" + indexof "0.0.1" + parseqs "0.0.5" + parseuri "0.0.5" + ws "~3.3.1" + xmlhttprequest-ssl "~1.5.4" + yeast "0.1.2" + +engine.io-client@~3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.4.0.tgz#82a642b42862a9b3f7a188f41776b2deab643700" + integrity sha512-a4J5QO2k99CM2a0b12IznnyQndoEvtA4UAldhGzKqnHf42I3Qs2W5SPnDvatZRcMaNZs4IevVicBPayxYt6FwA== + dependencies: + component-emitter "1.2.1" + component-inherit "0.0.3" + debug "~4.1.0" + engine.io-parser "~2.2.0" + has-cors "1.1.0" + indexof "0.0.1" + parseqs "0.0.5" + parseuri "0.0.5" + ws "~6.1.0" + xmlhttprequest-ssl "~1.5.4" + yeast "0.1.2" + +engine.io-parser@~2.1.0, engine.io-parser@~2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.1.3.tgz#757ab970fbf2dfb32c7b74b033216d5739ef79a6" + integrity sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA== + dependencies: + after "0.8.2" + arraybuffer.slice "~0.0.7" + base64-arraybuffer "0.1.5" + blob "0.0.5" + has-binary2 "~1.0.2" + +engine.io-parser@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.2.0.tgz#312c4894f57d52a02b420868da7b5c1c84af80ed" + integrity sha512-6I3qD9iUxotsC5HEMuuGsKA0cXerGz+4uGcXQEkfBidgKf0amsjrrtwcbwK/nzpZBxclXlV7gGl9dgWvu4LF6w== + dependencies: + after "0.8.2" + arraybuffer.slice "~0.0.7" + base64-arraybuffer "0.1.5" + blob "0.0.5" + has-binary2 "~1.0.2" + +engine.io@~3.2.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-3.2.1.tgz#b60281c35484a70ee0351ea0ebff83ec8c9522a2" + integrity sha512-+VlKzHzMhaU+GsCIg4AoXF1UdDFjHHwMmMKqMJNDNLlUlejz58FCy4LBqB2YVJskHGYl06BatYWKP2TVdVXE5w== + dependencies: + accepts "~1.3.4" + base64id "1.0.0" + cookie "0.3.1" + debug "~3.1.0" + engine.io-parser "~2.1.0" + ws "~3.3.1" + +enhanced-resolve@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f" + integrity sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng== + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.4.0" + tapable "^1.0.0" + +enhanced-resolve@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz#2937e2b8066cd0fe7ce0990a98f0d71a35189f66" + integrity sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA== + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.5.0" + tapable "^1.0.0" + +entities@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4" + integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw== + +errno@^0.1.3, errno@~0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" + integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== + dependencies: + prr "~1.0.1" + +error-ex@^1.2.0, error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.5: + version "1.17.5" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.5.tgz#d8c9d1d66c8981fb9200e2251d799eee92774ae9" + integrity sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg== + dependencies: + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + is-callable "^1.1.5" + is-regex "^1.0.5" + object-inspect "^1.7.0" + object-keys "^1.1.1" + object.assign "^4.1.0" + string.prototype.trimleft "^2.1.1" + string.prototype.trimright "^2.1.1" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +es6-templates@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/es6-templates/-/es6-templates-0.2.3.tgz#5cb9ac9fb1ded6eb1239342b81d792bbb4078ee4" + integrity sha1-XLmsn7He1usSOTQrgdeSu7QHjuQ= + dependencies: + recast "~0.11.12" + through "~2.3.6" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +escodegen-wallaby@1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/escodegen-wallaby/-/escodegen-wallaby-1.6.18.tgz#95a41e2fdc88687466e43550c7bf136386fd4363" + integrity sha512-3UvR14JRNh8VfKJixTDHWmhPNKAJiVZS807KUjECBk6f05WMe8ZeWL1gbrswNYhDiAUeDBQccyTWR91fayx3og== + dependencies: + esprima "^2.7.1" + estraverse "^1.9.1" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.2.0" + +eslint-scope@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" + integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-utils@^1.3.1: + version "1.4.3" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" + integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== + dependencies: + eslint-visitor-keys "^1.1.0" + +eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" + integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== + +eslint@^5.9.0: + version "5.16.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.16.0.tgz#a1e3ac1aae4a3fbd8296fcf8f7ab7314cbb6abea" + integrity sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg== + dependencies: + "@babel/code-frame" "^7.0.0" + ajv "^6.9.1" + chalk "^2.1.0" + cross-spawn "^6.0.5" + debug "^4.0.1" + doctrine "^3.0.0" + eslint-scope "^4.0.3" + eslint-utils "^1.3.1" + eslint-visitor-keys "^1.0.0" + espree "^5.0.1" + esquery "^1.0.1" + esutils "^2.0.2" + file-entry-cache "^5.0.1" + functional-red-black-tree "^1.0.1" + glob "^7.1.2" + globals "^11.7.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + inquirer "^6.2.2" + js-yaml "^3.13.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.11" + minimatch "^3.0.4" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.2" + progress "^2.0.0" + regexpp "^2.0.1" + semver "^5.5.1" + strip-ansi "^4.0.0" + strip-json-comments "^2.0.1" + table "^5.2.3" + text-table "^0.2.0" + +espree@3.5.4: + version "3.5.4" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7" + integrity sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A== + dependencies: + acorn "^5.5.0" + acorn-jsx "^3.0.0" + +espree@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.1.tgz#5d6526fa4fc7f0788a5cf75b15f30323e2f81f7a" + integrity sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A== + dependencies: + acorn "^6.0.7" + acorn-jsx "^5.0.0" + eslint-visitor-keys "^1.0.0" + +esprima@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" + integrity sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE= + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esprima@~3.1.0: + version "3.1.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" + integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM= + +esquery@^1.0.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.2.1.tgz#105239e215c5aa480369c7794d74b8b5914c19d4" + integrity sha512-/IcAXa9GWOX9BUIb/Tz2QrrAWFWzWGrFIeLeMRwtiuwg9qTFhSYemsi9DixwrFFqVbhBZ47vGcxEnu5mbPqbig== + dependencies: + estraverse "^5.0.0" + +esrecurse@^4.1.0, esrecurse@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== + dependencies: + estraverse "^4.1.0" + +estraverse@4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= + +estraverse@^1.9.1: + version "1.9.3" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" + integrity sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q= + +estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.0.0.tgz#ac81750b482c11cca26e4b07e83ed8f75fbcdc22" + integrity sha512-j3acdrMzqrxmJTNj5dbr1YbjacrYgAxVMeF0gK16E3j494mOe7xygM/ZLIguEQ0ETwAg2hlJCtHRGav+y0Ny5A== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +etag@1.8.1, etag@^1.8.1, etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +eventemitter3@1.x.x: + version "1.2.0" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-1.2.0.tgz#1c86991d816ad1e504750e73874224ecf3bec508" + integrity sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg= + +events@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.1.0.tgz#84279af1b34cb75aa88bf5ff291f6d0bd9b31a59" + integrity sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg== + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +execa@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.10.0.tgz#ff456a8f53f90f8eccc71a96d11bdfc7f082cb50" + integrity sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw== + dependencies: + cross-spawn "^6.0.0" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +executable@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/executable/-/executable-4.1.1.tgz#41532bff361d3e57af4d763b70582db18f5d133c" + integrity sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg== + dependencies: + pify "^2.2.0" + +exif-parser@^0.1.12: + version "0.1.12" + resolved "https://registry.yarnpkg.com/exif-parser/-/exif-parser-0.1.12.tgz#58a9d2d72c02c1f6f02a0ef4a9166272b7760922" + integrity sha1-WKnS1ywCwfbwKg70qRZicrd2CSI= + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expand-tilde@^2.0.0, expand-tilde@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" + integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI= + dependencies: + homedir-polyfill "^1.0.1" + +express@^4.16.3: + version "4.17.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" + integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== + dependencies: + accepts "~1.3.7" + array-flatten "1.1.1" + body-parser "1.19.0" + content-disposition "0.5.3" + content-type "~1.0.4" + cookie "0.4.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "~1.1.2" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.5" + qs "6.7.0" + range-parser "~1.2.1" + safe-buffer "5.1.2" + send "0.17.1" + serve-static "1.14.1" + setprototypeof "1.1.1" + statuses "~1.5.0" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +ext-list@^2.0.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/ext-list/-/ext-list-2.2.2.tgz#0b98e64ed82f5acf0f2931babf69212ef52ddd37" + integrity sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA== + dependencies: + mime-db "^1.28.0" + +ext-name@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ext-name/-/ext-name-5.0.0.tgz#70781981d183ee15d13993c8822045c506c8f0a6" + integrity sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ== + dependencies: + ext-list "^2.0.0" + sort-keys-length "^1.0.0" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +external-editor@^2.0.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" + integrity sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A== + dependencies: + chardet "^0.4.0" + iconv-lite "^0.4.17" + tmp "^0.0.33" + +external-editor@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" + integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +fancy-log@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.3.tgz#dbc19154f558690150a23953a0adbd035be45fc7" + integrity sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw== + dependencies: + ansi-gray "^0.1.1" + color-support "^1.1.3" + parse-node-version "^1.0.0" + time-stamp "^1.0.0" + +fast-deep-equal@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" + integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +fastdom@^1.0.8: + version "1.0.9" + resolved "https://registry.yarnpkg.com/fastdom/-/fastdom-1.0.9.tgz#b395fab11a3701173c02a054fe769d8f596a0a26" + integrity sha512-SSp4fbVzu8JkkG01NUX+0iOwe9M5PN3MGIQ84txLf4TkkJG4q30khkzumKgi4hUqO1+jX6wLHfnCPoZ6eSZ6Tg== + dependencies: + strictdom "^1.0.1" + +faster.js@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/faster.js/-/faster.js-1.1.1.tgz#8bbd7eefdb8f03faac26ad5025b059f94c5cfb4d" + integrity sha512-vPThNSLL/E1f7cLHd9yuayxZR82o/Iic4S5ZY45iY5AgBLNIlr3b3c+VpDjoYqjY9a9C/FQVUQy9oTILVP7X0g== + +fastparse@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9" + integrity sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ== + +fd-slicer@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" + integrity sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4= + dependencies: + pend "~1.2.0" + +figgy-pudding@^3.5.1: + version "3.5.2" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" + integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== + +figures@^1.3.5: + version "1.7.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + integrity sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4= + dependencies: + escape-string-regexp "^1.0.5" + object-assign "^4.1.0" + +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" + integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== + dependencies: + flat-cache "^2.0.1" + +file-loader@^0.8.1: + version "0.8.5" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-0.8.5.tgz#9275d031fe780f27d47f5f4af02bd43713cc151b" + integrity sha1-knXQMf54DyfUf19K8CvUNxPMFRs= + dependencies: + loader-utils "~0.2.5" + +file-type@5.2.0, file-type@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-5.2.0.tgz#2ddbea7c73ffe36368dfae49dc338c058c2b8ad6" + integrity sha1-LdvqfHP/42No365J3DOMBYwritY= + +file-type@^3.8.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" + integrity sha1-JXoHg4TR24CHvESdEH1SpSZyuek= + +file-type@^4.2.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-4.4.0.tgz#1b600e5fca1fbdc6e80c0a70c71c8dba5f7906c5" + integrity sha1-G2AOX8ofvcboDApwxxyNul95BsU= + +file-type@^6.1.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919" + integrity sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg== + +file-type@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-8.1.0.tgz#244f3b7ef641bbe0cca196c7276e4b332399f68c" + integrity sha512-qyQ0pzAy78gVoJsmYeNgl8uH8yKhr1lVhW7JbzJmnlRi0I4R2eEDEJZVKG8agpDnLpacwNbDhLNG/LMdxHD2YQ== + +file-type@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-9.0.0.tgz#a68d5ad07f486414dfb2c8866f73161946714a18" + integrity sha512-Qe/5NJrgIOlwijpq3B7BEpzPFcgzggOTagZmkXQY4LA6bsXKTUstK7Wp12lEJ/mLKTpvIZxmIuRcLYWT6ov9lw== + +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + +filename-reserved-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz#abf73dfab735d045440abfea2d91f389ebbfa229" + integrity sha1-q/c9+rc10EVECr/qLZHzieu/oik= + +filenamify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/filenamify/-/filenamify-2.1.0.tgz#88faf495fb1b47abfd612300002a16228c677ee9" + integrity sha512-ICw7NTT6RsDp2rnYKVd8Fu4cr6ITzGy3+u4vUujPkabyaz+03F24NWEX7fs5fp+kBonlaqPH8fAO2NM+SXt/JA== + dependencies: + filename-reserved-regex "^2.0.0" + strip-outer "^1.0.0" + trim-repeated "^1.0.0" + +filesize@^3.6.1: + version "3.6.1" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317" + integrity sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg== + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +finalhandler@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.0.tgz#ce0b6855b45853e791b2fcc680046d88253dd7f5" + integrity sha1-zgtoVbRYU+eRsvzGgARtiCU91/U= + dependencies: + debug "2.6.9" + encodeurl "~1.0.1" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.2" + statuses "~1.3.1" + unpipe "~1.0.0" + +finalhandler@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + +find-cache-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" + integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== + dependencies: + commondir "^1.0.1" + make-dir "^2.0.0" + pkg-dir "^3.0.0" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +find-versions@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-3.2.0.tgz#10297f98030a786829681690545ef659ed1d254e" + integrity sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww== + dependencies: + semver-regex "^2.0.0" + +findup-sync@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1" + integrity sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg== + dependencies: + detect-file "^1.0.0" + is-glob "^4.0.0" + micromatch "^3.0.4" + resolve-dir "^1.0.1" + +flat-cache@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" + integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== + dependencies: + flatted "^2.0.0" + rimraf "2.6.3" + write "1.0.3" + +flatted@^2.0.0, flatted@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" + integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== + +flatten@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b" + integrity sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg== + +flush-write-stream@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" + integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== + dependencies: + inherits "^2.0.3" + readable-stream "^2.3.6" + +follow-redirects@1.5.10: + version "1.5.10" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" + integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== + dependencies: + debug "=3.1.0" + +for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + dependencies: + map-cache "^0.2.2" + +fresh@0.5.2, fresh@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +from2@^2.1.0, from2@^2.1.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + +fs-extra@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-3.0.1.tgz#3794f378c58b342ea7dbbb23095109c4b3b62291" + integrity sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE= + dependencies: + graceful-fs "^4.1.2" + jsonfile "^3.0.0" + universalify "^0.1.0" + +fs-write-stream-atomic@^1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@^1.2.7: + version "1.2.12" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.12.tgz#db7e0d8ec3b0b45724fd4d83d43554a8f1f0de5c" + integrity sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q== + dependencies: + bindings "^1.5.0" + nan "^2.12.1" + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +gensync@^1.0.0-beta.1: + version "1.0.0-beta.1" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" + integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg== + +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-proxy@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/get-proxy/-/get-proxy-2.1.0.tgz#349f2b4d91d44c4d4d4e9cba2ad90143fac5ef93" + integrity sha512-zmZIaQTWnNQb4R4fJUEp/FC51eZsc6EkErspy3xtIYStaq8EB/hDIWipxsal+E8rz0qD7f2sL/NA9Xee4RInJw== + dependencies: + npm-conf "^1.1.0" + +get-stdin@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" + integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= + +get-stream@3.0.0, get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= + +get-stream@^2.2.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" + integrity sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4= + dependencies: + object-assign "^4.0.1" + pinkie-promise "^2.0.0" + +get-stream@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + +glob-all@^3.1.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/glob-all/-/glob-all-3.2.1.tgz#082ca81afd2247cbd3ed2149bb2630f4dc877d95" + integrity sha512-x877rVkzB3ipid577QOp+eQCR6M5ZyiwrtaYgrX/z3EThaSPFtLDwBXFHc3sH1cG0R0vFYI5SRYeWMMSEyXkUw== + dependencies: + glob "^7.1.2" + yargs "^15.3.1" + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob@^7.0.5, glob@^7.0.6, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + 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" + +global-modules@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" + integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== + dependencies: + global-prefix "^3.0.0" + +global-modules@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" + integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg== + dependencies: + global-prefix "^1.0.1" + is-windows "^1.0.1" + resolve-dir "^1.0.0" + +global-prefix@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" + integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4= + dependencies: + expand-tilde "^2.0.2" + homedir-polyfill "^1.0.1" + ini "^1.3.4" + is-windows "^1.0.1" + which "^1.2.14" + +global-prefix@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97" + integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg== + dependencies: + ini "^1.3.5" + kind-of "^6.0.2" + which "^1.3.1" + +global@~4.3.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f" + integrity sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8= + dependencies: + min-document "^2.19.0" + process "~0.5.1" + +globals@^11.1.0, globals@^11.7.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +gonzales-pe@^4.2.3: + version "4.3.0" + resolved "https://registry.yarnpkg.com/gonzales-pe/-/gonzales-pe-4.3.0.tgz#fe9dec5f3c557eead09ff868c65826be54d067b3" + integrity sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ== + dependencies: + minimist "^1.2.5" + +got@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a" + integrity sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw== + dependencies: + decompress-response "^3.2.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + is-plain-obj "^1.1.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + isurl "^1.0.0-alpha5" + lowercase-keys "^1.0.0" + p-cancelable "^0.3.0" + p-timeout "^1.1.1" + safe-buffer "^5.0.1" + timed-out "^4.0.0" + url-parse-lax "^1.0.0" + url-to-options "^1.0.1" + +got@^8.3.1: + version "8.3.2" + resolved "https://registry.yarnpkg.com/got/-/got-8.3.2.tgz#1d23f64390e97f776cac52e5b936e5f514d2e937" + integrity sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw== + dependencies: + "@sindresorhus/is" "^0.7.0" + cacheable-request "^2.1.1" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + into-stream "^3.1.0" + is-retry-allowed "^1.1.0" + isurl "^1.0.0-alpha5" + lowercase-keys "^1.0.0" + mimic-response "^1.0.0" + p-cancelable "^0.4.0" + p-timeout "^2.0.1" + pify "^3.0.0" + safe-buffer "^5.1.1" + timed-out "^4.0.1" + url-parse-lax "^3.0.0" + url-to-options "^1.0.1" + +graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6: + version "4.2.3" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" + integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== + +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= + +gzip-size@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.1.1.tgz#cb9bee692f87c0612b232840a873904e4c135274" + integrity sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA== + dependencies: + duplexer "^0.1.1" + pify "^4.0.1" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + +has-binary2@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-binary2/-/has-binary2-1.0.3.tgz#7776ac627f3ea77250cfc332dab7ddf5e4f5d11d" + integrity sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw== + dependencies: + isarray "2.0.1" + +has-cors@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-cors/-/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39" + integrity sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk= + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-symbol-support-x@^1.4.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" + integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw== + +has-symbols@^1.0.0, has-symbols@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" + integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== + +has-to-string-tag-x@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" + integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw== + dependencies: + has-symbol-support-x "^1.4.1" + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has@^1.0.0, has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hash-base@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" + integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +he@1.2.x: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +hex-color-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" + integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ== + +hmac-drbg@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +homedir-polyfill@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" + integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== + dependencies: + parse-passwd "^1.0.0" + +hoopy@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/hoopy/-/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d" + integrity sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ== + +hosted-git-info@^2.1.4: + version "2.8.8" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" + integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== + +howler@^2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/howler/-/howler-2.1.3.tgz#07c88618f8767e879407a4d647fe2d6d5f15f121" + integrity sha512-PSGbOi1EYgw80C5UQbxtJM7TmzD+giJunIMBYyH3RVzHZx2fZLYBoes0SpVVHi/SFa1GoNtgXj/j6I7NOKYBxQ== + +hsl-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/hsl-regex/-/hsl-regex-1.0.0.tgz#d49330c789ed819e276a4c0d272dffa30b18fe6e" + integrity sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4= + +hsla-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/hsla-regex/-/hsla-regex-1.0.0.tgz#c1ce7a3168c8c6614033a4b5f7877f3b225f9c38" + integrity sha1-wc56MWjIxmFAM6S194d/OyJfnDg= + +html-comment-regex@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7" + integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ== + +html-loader@^0.5.5: + version "0.5.5" + resolved "https://registry.yarnpkg.com/html-loader/-/html-loader-0.5.5.tgz#6356dbeb0c49756d8ebd5ca327f16ff06ab5faea" + integrity sha512-7hIW7YinOYUpo//kSYcPB6dCKoceKLmOwjEMmhIobHuWGDVl0Nwe4l68mdG/Ru0wcUxQjVMEoZpkalZ/SE7zog== + dependencies: + es6-templates "^0.2.3" + fastparse "^1.1.1" + html-minifier "^3.5.8" + loader-utils "^1.1.0" + object-assign "^4.1.1" + +html-minifier@^3.5.8: + version "3.5.21" + resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-3.5.21.tgz#d0040e054730e354db008463593194015212d20c" + integrity sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA== + dependencies: + camel-case "3.0.x" + clean-css "4.2.x" + commander "2.17.x" + he "1.2.x" + param-case "2.1.x" + relateurl "0.2.x" + uglify-js "3.4.x" + +http-cache-semantics@3.8.1: + version "3.8.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" + integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== + +http-errors@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" + integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-errors@1.7.3, http-errors@~1.7.2: + version "1.7.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-proxy@1.15.2: + version "1.15.2" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.15.2.tgz#642fdcaffe52d3448d2bda3b0079e9409064da31" + integrity sha1-ZC/cr/5S00SNK9o7AHnpQJBk2jE= + dependencies: + eventemitter3 "1.x.x" + requires-port "1.x.x" + +https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= + +iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.24, iconv-lite@~0.4.13: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ieee754@^1.1.4: + version "1.1.13" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" + integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== + +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= + +ignore-loader@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ignore-loader/-/ignore-loader-0.1.2.tgz#d81f240376d0ba4f0d778972c3ad25874117a463" + integrity sha1-2B8kA3bQuk8Nd4lyw60lh0EXpGM= + +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +imagemin-mozjpeg@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/imagemin-mozjpeg/-/imagemin-mozjpeg-8.0.0.tgz#d2ca4e8c982c7c6eda55069af89dee4c1cebcdfd" + integrity sha512-+EciPiIjCb8JWjQNr1q8sYWYf7GDCNDxPYnkD11TNIjjWNzaV+oTg4DpOPQjl5ZX/KRCPMEgS79zLYAQzLitIA== + dependencies: + execa "^1.0.0" + is-jpg "^2.0.0" + mozjpeg "^6.0.0" + +imagemin-pngquant@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/imagemin-pngquant/-/imagemin-pngquant-8.0.0.tgz#bf7a41d850c6998f2475c54058ab1db9c516385d" + integrity sha512-PVq0diOxO+Zyq/zlMCz2Pfu6mVLHgiT1GpW702OwVlnej+NhS6ZQegYi3OFEDW8d7GxouyR5e8R+t53SMciOeg== + dependencies: + execa "^1.0.0" + is-png "^2.0.0" + is-stream "^2.0.0" + ow "^0.13.2" + pngquant-bin "^5.0.0" + +immutable@^3: + version "3.8.2" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.2.tgz#c2439951455bb39913daf281376f1530e104adf3" + integrity sha1-wkOZUUVbs5kT2vKBN28VMOEErfM= + +import-fresh@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" + integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= + dependencies: + caller-path "^2.0.0" + resolve-from "^3.0.0" + +import-fresh@^3.0.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" + integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +import-lazy@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-3.1.0.tgz#891279202c8a2280fdbd6674dbd8da1a1dfc67cc" + integrity sha512-8/gvXvX2JMn0F+CDlSC4l6kOmVaLOO3XLkksI7CI3Ud95KDYJuYur2b9P/PUt/i/pDAMd/DulQsNbbbmRRsDIQ== + +import-local@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" + integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== + dependencies: + pkg-dir "^3.0.0" + resolve-cwd "^2.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA= + dependencies: + repeating "^2.0.0" + +indexes-of@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" + integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= + +indexof@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" + integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10= + +infer-owner@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +ini@^1.3.4, ini@^1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + +inquirer@3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.0.6.tgz#e04aaa9d05b7a3cb9b0f407d04375f0447190347" + integrity sha1-4EqqnQW3o8ubD0B9BDdfBEcZA0c= + dependencies: + ansi-escapes "^1.1.0" + chalk "^1.0.0" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^2.0.1" + figures "^2.0.0" + lodash "^4.3.0" + mute-stream "0.0.7" + run-async "^2.2.0" + rx "^4.1.0" + string-width "^2.0.0" + strip-ansi "^3.0.0" + through "^2.3.6" + +inquirer@^6.2.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" + integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ== + dependencies: + ansi-escapes "^3.2.0" + chalk "^2.4.2" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^3.0.3" + figures "^2.0.0" + lodash "^4.17.12" + mute-stream "0.0.7" + run-async "^2.2.0" + rxjs "^6.4.0" + string-width "^2.1.0" + strip-ansi "^5.1.0" + through "^2.3.6" + +interpret@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" + integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw== + +into-stream@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-3.1.0.tgz#96fb0a936c12babd6ff1752a17d05616abd094c6" + integrity sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY= + dependencies: + from2 "^2.1.1" + p-is-promise "^1.1.0" + +invariant@^2.2.2, invariant@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + +inversify@4.11.1: + version "4.11.1" + resolved "https://registry.yarnpkg.com/inversify/-/inversify-4.11.1.tgz#9a10635d1fd347da11da96475b3608babd5945a6" + integrity sha512-9bs/36crPdTSOCcoomHMb96s+B8W0+2c9dHFP/Srv9ZQaPnUvsMgzmMHfgVECqfHVUIW+M5S7SYOjoig8khWuQ== + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= + +invert-kv@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" + integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-absolute-url@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" + integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY= + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= + dependencies: + binary-extensions "^1.0.0" + +is-buffer@^1.1.5, is-buffer@~1.1.1: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-buffer@^2.0.2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" + integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A== + +is-callable@^1.1.4, is-callable@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" + integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q== + +is-color-stop@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-color-stop/-/is-color-stop-1.1.0.tgz#cfff471aee4dd5c9e158598fbe12967b5cdad345" + integrity sha1-z/9HGu5N1cnhWFmPvhKWe1za00U= + dependencies: + css-color-names "^0.0.4" + hex-color-regex "^1.1.0" + hsl-regex "^1.0.0" + hsla-regex "^1.0.0" + rgb-regex "^1.0.1" + rgba-regex "^1.0.0" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-date-object@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" + integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-directory@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-finite@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" + integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-function@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5" + integrity sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU= + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-jpg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-jpg/-/is-jpg-2.0.0.tgz#2e1997fa6e9166eaac0242daae443403e4ef1d97" + integrity sha1-LhmX+m6RZuqsAkLarkQ0A+TvHZc= + +is-natural-number@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8" + integrity sha1-q5124dtM7VHjXeDHLr7PCfc0zeg= + +is-number-like@^1.0.3: + version "1.0.8" + resolved "https://registry.yarnpkg.com/is-number-like/-/is-number-like-1.0.8.tgz#2e129620b50891042e44e9bbbb30593e75cfbbe3" + integrity sha512-6rZi3ezCyFcn5L71ywzz2bS5b2Igl1En3eTlZlvKjpz1n3IZLAYMbKYAIQgFmEu0GENg92ziU/faEOA/aixjbA== + dependencies: + lodash.isfinite "^3.3.2" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" + integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== + +is-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" + integrity sha1-iVJojF7C/9awPsyF52ngKQMINHA= + +is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= + +is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-png@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-png/-/is-png-2.0.0.tgz#ee8cbc9e9b050425cedeeb4a6fb74a649b0a4a8d" + integrity sha512-4KPGizaVGj2LK7xwJIz8o5B2ubu1D/vcQsgOGFEDlpcvgZHto4gBnyd0ig7Ws+67ixmwKoNmu0hYnpo6AaKb5g== + +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= + +is-regex@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" + integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== + dependencies: + has "^1.0.3" + +is-resolvable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" + integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== + +is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" + integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== + +is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" + integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== + +is-svg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-3.0.0.tgz#9321dbd29c212e5ca99c4fa9794c714bcafa2f75" + integrity sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ== + dependencies: + html-comment-regex "^1.1.0" + +is-symbol@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" + integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== + dependencies: + has-symbols "^1.0.1" + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= + +is-windows@^1.0.1, is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +is-wsl@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isarray@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e" + integrity sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4= + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +isurl@^1.0.0-alpha5: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" + integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w== + dependencies: + has-to-string-tag-x "^1.2.0" + is-object "^1.0.1" + +javascript-obfuscator@^0.15.0: + version "0.15.0" + resolved "https://registry.yarnpkg.com/javascript-obfuscator/-/javascript-obfuscator-0.15.0.tgz#e2b348c3a6895ef9195e3088f05747cff7a914f1" + integrity sha512-d4mzMLkwZarZE9ZDFXQapNba4iHEj6ARveU4qCz7j/T/TlrHJVbyhVRcZigIuiQqgotTWGub5vMCa2/ep+hA+w== + dependencies: + "@babel/runtime" "7.0.0-beta.42" + chalk "2.3.2" + chance "1.0.13" + class-validator "0.8.5" + commander "2.15.1" + escodegen-wallaby "1.6.18" + espree "3.5.4" + estraverse "4.2.0" + inversify "4.11.1" + js-string-escape "1.0.1" + md5 "2.2.1" + mkdirp "0.5.1" + multimatch "2.1.0" + opencollective "1.0.3" + pjson "1.0.9" + reflect-metadata "0.1.12" + source-map-support "0.5.4" + string-template "1.0.0" + tslib "1.9.0" + +jimp@^0.6.1: + version "0.6.8" + resolved "https://registry.yarnpkg.com/jimp/-/jimp-0.6.8.tgz#63074984337cc469cd4030946e503e7c02a18b5c" + integrity sha512-F7emeG7Hp61IM8VFbNvWENLTuHe0ghizWPuP4JS9ujx2r5mCVYEd/zdaz6M2M42ZdN41blxPajLWl9FXo7Mr2Q== + dependencies: + "@jimp/custom" "^0.6.8" + "@jimp/plugins" "^0.6.8" + "@jimp/types" "^0.6.8" + core-js "^2.5.7" + regenerator-runtime "^0.13.3" + +jpeg-js@^0.3.4: + version "0.3.7" + resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.3.7.tgz#471a89d06011640592d314158608690172b1028d" + integrity sha512-9IXdWudL61npZjvLuVe/ktHiA41iE8qFyLB+4VDTblEsWBzeg8WQTlktdUK4CdncUqtUgUg0bbOmTE2bKBKaBQ== + +js-base64@^2.1.9: + version "2.5.2" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.2.tgz#313b6274dda718f714d00b3330bbae6e38e90209" + integrity sha512-Vg8czh0Q7sFBSUMWWArX/miJeBWYBPpdU/3M/DKSaekLMqrqVPaedp+5mZhie/r0lgrcaYBfwXatEew6gwgiQQ== + +js-string-escape@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" + integrity sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8= + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.0, js-yaml@^3.13.1: + version "3.13.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= + +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= + +json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +json5@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= + +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" + +json5@^2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" + integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== + dependencies: + minimist "^1.2.5" + +jsonfile@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-3.0.1.tgz#a5ecc6f65f53f662c4415c7675a0331d0992ec66" + integrity sha1-pezG9l9T9mLEQVx2daAzHQmS7GY= + optionalDependencies: + graceful-fs "^4.1.6" + +keyv@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.0.0.tgz#44923ba39e68b12a7cec7df6c3268c031f2ef373" + integrity sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA== + dependencies: + json-buffer "3.0.0" + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +known-css-properties@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.11.0.tgz#0da784f115ea77c76b81536d7052e90ee6c86a8a" + integrity sha512-bEZlJzXo5V/ApNNa5z375mJC6Nrz4vG43UgcSCrg2OHC+yuB6j0iDSrY7RQ/+PRofFB03wNIIt9iXIVLr4wc7w== + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= + dependencies: + invert-kv "^1.0.0" + +lcid@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" + integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== + dependencies: + invert-kv "^2.0.0" + +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + +levenary@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/levenary/-/levenary-1.1.1.tgz#842a9ee98d2075aa7faeedbe32679e9205f46f77" + integrity sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ== + dependencies: + leven "^3.1.0" + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +limiter@^1.0.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/limiter/-/limiter-1.1.5.tgz#8f92a25b3b16c6131293a0cc834b4a838a2aa7c2" + integrity sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA== + +load-bmfont@^1.3.1, load-bmfont@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/load-bmfont/-/load-bmfont-1.4.0.tgz#75f17070b14a8c785fe7f5bee2e6fd4f98093b6b" + integrity sha512-kT63aTAlNhZARowaNYcY29Fn/QYkc52M3l6V1ifRcPewg2lvUZDAj7R6dXjOL9D0sict76op3T5+odumDSF81g== + dependencies: + 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" + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +loader-runner@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" + integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== + +loader-utils@1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" + integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== + dependencies: + big.js "^5.2.2" + emojis-list "^2.0.0" + json5 "^1.0.1" + +loader-utils@^0.2.5, loader-utils@~0.2.2, loader-utils@~0.2.3, loader-utils@~0.2.5: + version "0.2.17" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" + integrity sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g= + dependencies: + big.js "^3.1.3" + emojis-list "^2.0.0" + json5 "^0.5.0" + object-assign "^4.0.1" + +loader-utils@^1.0.0, loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" + integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^1.0.1" + +localtunnel@1.9.2: + version "1.9.2" + resolved "https://registry.yarnpkg.com/localtunnel/-/localtunnel-1.9.2.tgz#0012fcabc29cf964c130a01858768aa2bb65b5af" + integrity sha512-NEKF7bDJE9U3xzJu3kbayF0WTvng6Pww7tzqNb/XtEARYwqw7CKEX7BvOMg98FtE9es2CRizl61gkV3hS8dqYg== + dependencies: + axios "0.19.0" + debug "4.1.1" + openurl "1.1.1" + yargs "6.6.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash._reinterpolate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" + integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= + +lodash.clone@^4.3.2: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clone/-/lodash.clone-4.5.0.tgz#195870450f5a13192478df4bc3d23d2dea1907b6" + integrity sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y= + +lodash.isfinite@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz#fb89b65a9a80281833f0b7478b3a5104f898ebb3" + integrity sha1-+4m2WpqAKBgz8LdHizpRBPiY67M= + +lodash.memoize@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= + +lodash.some@^4.2.2: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" + integrity sha1-G7nzFO9ri63tE7VJFpsqlF62jk0= + +lodash.template@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab" + integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A== + dependencies: + lodash._reinterpolate "^3.0.0" + lodash.templatesettings "^4.0.0" + +lodash.templatesettings@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz#e481310f049d3cf6d47e912ad09313b154f0fb33" + integrity sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ== + dependencies: + lodash._reinterpolate "^3.0.0" + +lodash.uniq@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= + +lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.3.0: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" + integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== + +logalot@^2.0.0, logalot@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/logalot/-/logalot-2.1.0.tgz#5f8e8c90d304edf12530951a5554abb8c5e3f552" + integrity sha1-X46MkNME7fElMJUaVVSruMXj9VI= + dependencies: + figures "^1.3.5" + squeak "^1.0.0" + +longest@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" + integrity sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc= + +loose-envify@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +loud-rejection@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lower-case@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" + integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw= + +lowercase-keys@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" + integrity sha1-TjNms55/VFfjXxMkvfb4jQv8cwY= + +lowercase-keys@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + +lpad-align@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/lpad-align/-/lpad-align-1.1.2.tgz#21f600ac1c3095c3c6e497ee67271ee08481fe9e" + integrity sha1-IfYArBwwlcPG5JfuZyce4ISB/p4= + dependencies: + get-stdin "^4.0.1" + indent-string "^2.1.0" + longest "^1.0.0" + meow "^3.3.0" + +lru-cache@^4.0.1: + version "4.1.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +lz-string@^1.4.4: + version "1.4.4" + resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26" + integrity sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY= + +make-dir@^1.0.0, make-dir@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== + dependencies: + pify "^3.0.0" + +make-dir@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + +map-age-cleaner@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" + integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== + dependencies: + p-defer "^1.0.0" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-obj@^1.0.0, map-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + +markdown-loader@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/markdown-loader/-/markdown-loader-4.0.0.tgz#502eb94f5db1673beb1721bed82dac9e1d333b9a" + integrity sha512-9BCm8iyLF4AVYtjtybOTg8cTcpWYKsDGWWhsc7XaJlXQiddo3ztbZxLPJ28pmCxFI1BlMkT1wDVav1chPjTpdA== + dependencies: + loader-utils "^1.1.0" + marked "^0.5.0" + +marked@^0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/marked/-/marked-0.5.2.tgz#3efdb27b1fd0ecec4f5aba362bddcd18120e5ba9" + integrity sha512-fdZvBa7/vSQIZCi4uuwo2N3q+7jJURpMVCcbaX0S1Mg65WZ5ilXvC67MviJAsdjqqgD+CEq4RKo5AYGgINkVAA== + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +md5@2.2.1, md5@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9" + integrity sha1-U6s41f48iJG6RlMp6iP6wFQBJvk= + dependencies: + charenc "~0.0.1" + crypt "~0.0.1" + is-buffer "~1.1.1" + +mdn-data@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" + integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA== + +mdn-data@2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.6.tgz#852dc60fcaa5daa2e8cf6c9189c440ed3e042978" + integrity sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA== + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +mem@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" + integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== + dependencies: + map-age-cleaner "^0.1.1" + mimic-fn "^2.0.0" + p-is-promise "^2.0.0" + +memory-fs@^0.4.0, memory-fs@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +memory-fs@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" + integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA== + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +meow@^3.3.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs= + dependencies: + camelcase-keys "^2.0.0" + decamelize "^1.1.2" + loud-rejection "^1.0.0" + map-obj "^1.0.1" + minimist "^1.1.3" + normalize-package-data "^2.3.4" + object-assign "^4.0.1" + read-pkg-up "^1.0.1" + redent "^1.0.0" + trim-newlines "^1.0.0" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +mime-db@1.43.0, mime-db@^1.28.0: + version "1.43.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58" + integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ== + +mime-types@~2.1.17, mime-types@~2.1.24: + version "2.1.26" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06" + integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ== + dependencies: + mime-db "1.43.0" + +mime@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" + integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== + +mime@1.6.0, mime@^1.3.4: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mime@^2.4.0: + version "2.4.4" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.4.tgz#bd7b91135fc6b01cde3e9bae33d659b63d8857e5" + integrity sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA== + +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== + +mimic-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mimic-response@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +min-document@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU= + dependencies: + dom-walk "^0.1.0" + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + +minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= + +minimist@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= + +minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +mississippi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" + integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^3.0.0" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + +mitt@^1.1.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mitt/-/mitt-1.2.0.tgz#cb24e6569c806e31bd4e3995787fe38a04fdf90d" + integrity sha512-r6lj77KlwqLhIUku9UWYes7KJtsczvolZkzp8hbaDPPaE24OmWl5s539Mytlj22siEQKosZ26qCBgda2PKwoJw== + +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= + dependencies: + minimist "0.0.8" + +mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@~0.5.1: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + +mozjpeg@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/mozjpeg/-/mozjpeg-6.0.1.tgz#56969dddb5741ef2bcb1af066cae21e61a91a27b" + integrity sha512-9Z59pJMi8ni+IUvSH5xQwK5tNLw7p3dwDNCZ3o1xE+of3G5Hc/yOz6Ue/YuLiBXU3ZB5oaHPURyPdqfBX/QYJA== + dependencies: + bin-build "^3.0.0" + bin-wrapper "^4.0.0" + logalot "^2.1.0" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +ms@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +multimatch@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" + integrity sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis= + dependencies: + array-differ "^1.0.0" + array-union "^1.0.1" + arrify "^1.0.0" + minimatch "^3.0.0" + +mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= + +nan@^2.12.1: + version "2.14.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" + integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +negotiator@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== + +neo-async@^2.5.0, neo-async@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" + integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +no-case@^2.2.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" + integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ== + dependencies: + lower-case "^1.1.1" + +node-fetch@1.6.3: + version "1.6.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.6.3.tgz#dc234edd6489982d58e8f0db4f695029abcd8c04" + integrity sha1-3CNO3WSJmC1Y6PDbT2lQKavNjAQ= + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + +node-fetch@^1.6.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" + integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ== + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + +node-libs-browser@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" + integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== + dependencies: + assert "^1.1.1" + browserify-zlib "^0.2.0" + buffer "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events "^3.0.0" + https-browserify "^1.0.0" + os-browserify "^0.3.0" + path-browserify "0.0.1" + process "^0.11.10" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.3.3" + stream-browserify "^2.0.1" + stream-http "^2.7.2" + string_decoder "^1.0.0" + timers-browserify "^2.0.4" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.11.0" + vm-browserify "^1.0.1" + +node-releases@^1.1.53: + version "1.1.53" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.53.tgz#2d821bfa499ed7c5dffc5e2f28c88e78a08ee3f4" + integrity sha512-wp8zyQVwef2hpZ/dJH7SfSrIPD6YoJz6BDQDpGEkcA0s3LpAQoxBIYmfIq6QAhC1DhwsyCgTaTTcONwX8qzCuQ== + +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= + +normalize-url@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-2.0.1.tgz#835a9da1551fa26f70e92329069a23aa6574d7e6" + integrity sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw== + dependencies: + prepend-http "^2.0.0" + query-string "^5.0.1" + sort-keys "^2.0.0" + +normalize-url@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" + integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== + +npm-conf@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/npm-conf/-/npm-conf-1.1.3.tgz#256cc47bd0e218c259c4e9550bf413bc2192aff9" + integrity sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw== + dependencies: + config-chain "^1.1.11" + pify "^3.0.0" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + dependencies: + path-key "^2.0.0" + +nth-check@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" + integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== + dependencies: + boolbase "~1.0.0" + +num2fraction@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" + integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +obfuscator-loader@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/obfuscator-loader/-/obfuscator-loader-1.1.2.tgz#6e8460066296fc642a68c945e64906e3c964cb0f" + integrity sha512-5PKsa4Vzq8uLJG0GT9BvC9ZxCr44wyV0c9wi782RYWh44GdFMSqlnUldgqSV+HQkFH3MWNc34AlSVSEhg7I26w== + dependencies: + esprima "^4.0.0" + javascript-obfuscator "^0.15.0" + loader-utils "^1.1.0" + +object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-component@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291" + integrity sha1-8MaapQ78lbhmwYb0AKM3acsvEpE= + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-inspect@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" + integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== + +object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object-path@^0.9.0: + version "0.9.2" + resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.9.2.tgz#0fd9a74fc5fad1ae3968b586bda5c632bd6c05a5" + integrity sha1-D9mnT8X60a45aLWGvaXGMr1sBaU= + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + +object.assign@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" + +object.getownpropertydescriptors@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649" + integrity sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + +object.values@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.1.tgz#68a99ecde356b7e9295a3c5e0ce31dc8c953de5e" + integrity sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + function-bind "^1.1.1" + has "^1.0.3" + +omggif@^1.0.9: + version "1.0.10" + resolved "https://registry.yarnpkg.com/omggif/-/omggif-1.0.10.tgz#ddaaf90d4a42f532e9e7cb3a95ecdd47f17c7b19" + integrity sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw== + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onesky-fetch@^0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/onesky-fetch/-/onesky-fetch-0.0.7.tgz#96fce1a258a80683d6a37840958bae2f6fdb2809" + integrity sha1-lvzholioBoPWo3hAlYuuL2/bKAk= + dependencies: + md5 "^2.2.1" + node-fetch "^1.6.3" + +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= + dependencies: + mimic-fn "^1.0.0" + +opencollective@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/opencollective/-/opencollective-1.0.3.tgz#aee6372bc28144583690c3ca8daecfc120dd0ef1" + integrity sha1-ruY3K8KBRFg2kMPKja7PwSDdDvE= + dependencies: + babel-polyfill "6.23.0" + chalk "1.1.3" + inquirer "3.0.6" + minimist "1.2.0" + node-fetch "1.6.3" + opn "4.0.2" + +opener@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed" + integrity sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA== + +openurl@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/openurl/-/openurl-1.1.1.tgz#3875b4b0ef7a52c156f0db41d4609dbb0f94b387" + integrity sha1-OHW0sO96UsFW8NtB1GCduw+Us4c= + +opn@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/opn/-/opn-4.0.2.tgz#7abc22e644dff63b0a96d5ab7f2790c0f01abc95" + integrity sha1-erwi5kTf9jsKltWrfyeQwPAavJU= + dependencies: + object-assign "^4.0.1" + pinkie-promise "^2.0.0" + +opn@5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/opn/-/opn-5.3.0.tgz#64871565c863875f052cfdf53d3e3cb5adb53b1c" + integrity sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g== + dependencies: + is-wsl "^1.1.0" + +optionator@^0.8.1, optionator@^0.8.2: + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.3" + +os-browserify@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= + +os-filter-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/os-filter-obj/-/os-filter-obj-2.0.0.tgz#1c0b62d5f3a2442749a2d139e6dddee6e81d8d16" + integrity sha512-uksVLsqG3pVdzzPvmAHpBK0wKxYItuzZr7SziusRPoz67tGV8rL1szZ6IdeUrbqLjGDwApBtN29eEE3IqGHOjg== + dependencies: + arch "^2.1.0" + +os-locale@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + integrity sha1-IPnxeuKe00XoveWDsT0gCYA8FNk= + dependencies: + lcid "^1.0.0" + +os-locale@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" + integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== + dependencies: + execa "^1.0.0" + lcid "^2.0.0" + mem "^4.0.0" + +os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +ow@^0.13.2: + version "0.13.2" + resolved "https://registry.yarnpkg.com/ow/-/ow-0.13.2.tgz#375e76d3d3f928a8dfcf0cd0b9c921cb62e469a0" + integrity sha512-9wvr+q+ZTDRvXDjL6eDOdFe5WUl/wa5sntf9kAolxqSpkBqaIObwLgFCGXSJASFw+YciXnOVtDWpxXa9cqV94A== + dependencies: + type-fest "^0.5.1" + +p-cancelable@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa" + integrity sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw== + +p-cancelable@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.4.1.tgz#35f363d67d52081c8d9585e37bcceb7e0bbcb2a0" + integrity sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ== + +p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= + +p-event@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-event/-/p-event-1.3.0.tgz#8e6b4f4f65c72bc5b6fe28b75eda874f96a4a085" + integrity sha1-jmtPT2XHK8W2/ii3XtqHT5akoIU= + dependencies: + p-timeout "^1.1.1" + +p-event@^2.1.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/p-event/-/p-event-2.3.1.tgz#596279ef169ab2c3e0cae88c1cfbb08079993ef6" + integrity sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA== + dependencies: + p-timeout "^2.0.1" + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-is-promise@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" + integrity sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4= + +p-is-promise@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" + integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-limit@^2.0.0, p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-map-series@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-map-series/-/p-map-series-1.0.0.tgz#bf98fe575705658a9e1351befb85ae4c1f07bdca" + integrity sha1-v5j+V1cFZYqeE1G++4WuTB8Hvco= + dependencies: + p-reduce "^1.0.0" + +p-reduce@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" + integrity sha1-GMKw3ZNqRpClKfgjH1ig/bakffo= + +p-timeout@^1.1.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386" + integrity sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y= + dependencies: + p-finally "^1.0.0" + +p-timeout@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038" + integrity sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA== + dependencies: + p-finally "^1.0.0" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +pako@^1.0.5, pako@~1.0.5: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + +parallel-transform@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" + integrity sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg== + dependencies: + cyclist "^1.0.1" + inherits "^2.0.3" + readable-stream "^2.1.5" + +param-case@2.1.x: + version "2.1.1" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247" + integrity sha1-35T9jPZTHs915r75oIWPvHK+Ikc= + dependencies: + no-case "^2.2.0" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-asn1@^5.0.0: + version "5.1.5" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.5.tgz#003271343da58dc94cace494faef3d2147ecea0e" + integrity sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ== + dependencies: + asn1.js "^4.0.0" + browserify-aes "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" + +parse-bmfont-ascii@^1.0.3: + version "1.0.6" + resolved "https://registry.yarnpkg.com/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz#11ac3c3ff58f7c2020ab22769079108d4dfa0285" + integrity sha1-Eaw8P/WPfCAgqyJ2kHkQjU36AoU= + +parse-bmfont-binary@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz#d038b476d3e9dd9db1e11a0b0e53a22792b69006" + integrity sha1-0Di0dtPp3Z2x4RoLDlOiJ5K2kAY= + +parse-bmfont-xml@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/parse-bmfont-xml/-/parse-bmfont-xml-1.1.4.tgz#015319797e3e12f9e739c4d513872cd2fa35f389" + integrity sha512-bjnliEOmGv3y1aMEfREMBJ9tfL3WR0i0CKPj61DnSLaoxWR3nLrsQrEbCId/8rF4NyRF0cCqisSVXyQYWM+mCQ== + dependencies: + xml-parse-from-string "^1.0.0" + xml2js "^0.4.5" + +parse-headers@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.3.tgz#5e8e7512383d140ba02f0c7aa9f49b4399c92515" + integrity sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA== + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= + dependencies: + error-ex "^1.2.0" + +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + +parse-node-version@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b" + integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA== + +parse-passwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" + integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= + +parseqs@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d" + integrity sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0= + dependencies: + better-assert "~1.0.0" + +parseuri@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.5.tgz#80204a50d4dbb779bfdc6ebe2778d90e4bce320a" + integrity sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo= + dependencies: + better-assert "~1.0.0" + +parseurl@~1.3.2, parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + +path-browserify@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" + integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-is-inside@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= + +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +pbkdf2@^3.0.3: + version "3.0.17" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" + integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= + +phin@^2.9.1: + version "2.9.3" + resolved "https://registry.yarnpkg.com/phin/-/phin-2.9.3.tgz#f9b6ac10a035636fb65dfc576aaaa17b8743125c" + integrity sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA== + +phonegap-plugin-mobile-accessibility@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/phonegap-plugin-mobile-accessibility/-/phonegap-plugin-mobile-accessibility-1.0.5.tgz#95a8754d127508bc6e1ae259a53ce765836eac03" + integrity sha1-lah1TRJ1CLxuGuJZpTznZYNurAM= + +pify@^2.0.0, pify@^2.2.0, pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + +pixelmatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/pixelmatch/-/pixelmatch-4.0.2.tgz#8f47dcec5011b477b67db03c243bc1f3085e8854" + integrity sha1-j0fc7FARtHe2fbA8JDvB8wheiFQ= + dependencies: + pngjs "^3.0.0" + +pjson@1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/pjson/-/pjson-1.0.9.tgz#8a9520ce76a4739f8fee91679dad6b065b1c7938" + integrity sha512-4hRJH3YzkUpOlShRzhyxAmThSNnAaIlWZCAb27hd0pVUAXNUAHAO7XZbsPPvsCYwBFEScTmCCL6DGE8NyZ8BdQ== + +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== + dependencies: + find-up "^3.0.0" + +pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" + integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= + dependencies: + find-up "^2.1.0" + +plugin-error@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-1.0.1.tgz#77016bd8919d0ac377fdcdd0322328953ca5781c" + integrity sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA== + dependencies: + ansi-colors "^1.0.1" + arr-diff "^4.0.0" + arr-union "^3.1.0" + extend-shallow "^3.0.2" + +pngjs@^3.0.0, pngjs@^3.3.3: + version "3.4.0" + resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f" + integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w== + +pngquant-bin@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/pngquant-bin/-/pngquant-bin-5.0.2.tgz#6f34f3e89c9722a72bbc509062b40f1b17cda460" + integrity sha512-OLdT+4JZx5BqE1CFJkrvomYV0aSsv6x2Bba+aWaVc0PMfWlE+ZByNKYAdKeIqsM4uvW1HOSEHnf8KcOnykPNxA== + dependencies: + bin-build "^3.0.0" + bin-wrapper "^4.0.1" + execa "^0.10.0" + logalot "^2.0.0" + +portscanner@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/portscanner/-/portscanner-2.1.1.tgz#eabb409e4de24950f5a2a516d35ae769343fbb96" + integrity sha1-6rtAnk3iSVD1oqUW01rnaTQ/u5Y= + dependencies: + async "1.5.2" + is-number-like "^1.0.3" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + +postcss-assets@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-assets/-/postcss-assets-5.0.0.tgz#f721d07d339605fb58414e9f69cf05401c54e709" + integrity sha1-9yHQfTOWBftYQU6fac8FQBxU5wk= + dependencies: + assets "^3.0.0" + bluebird "^3.5.0" + postcss "^6.0.10" + postcss-functions "^3.0.0" + +postcss-attribute-case-insensitive@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-4.0.2.tgz#d93e46b504589e94ac7277b0463226c68041a880" + integrity sha512-clkFxk/9pcdb4Vkn0hAHq3YnxBQ2p0CGD1dy24jN+reBck+EWxMbxSUqN4Yj7t0w8csl87K6p0gxBe1utkJsYA== + dependencies: + postcss "^7.0.2" + postcss-selector-parser "^6.0.2" + +postcss-calc@^7.0.1: + version "7.0.2" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-7.0.2.tgz#504efcd008ca0273120568b0792b16cdcde8aac1" + integrity sha512-rofZFHUg6ZIrvRwPeFktv06GdbDYLcGqh9EwiMutZg+a0oePCCw1zHOEiji6LCpyRcjTREtPASuUqeAvYlEVvQ== + dependencies: + postcss "^7.0.27" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.0.2" + +postcss-color-functional-notation@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/postcss-color-functional-notation/-/postcss-color-functional-notation-2.0.1.tgz#5efd37a88fbabeb00a2966d1e53d98ced93f74e0" + integrity sha512-ZBARCypjEDofW4P6IdPVTLhDNXPRn8T2s1zHbZidW6rPaaZvcnCS2soYFIQJrMZSxiePJ2XIYTlcb2ztr/eT2g== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-color-gray@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-color-gray/-/postcss-color-gray-5.0.0.tgz#532a31eb909f8da898ceffe296fdc1f864be8547" + integrity sha512-q6BuRnAGKM/ZRpfDascZlIZPjvwsRye7UDNalqVz3s7GDxMtqPY6+Q871liNxsonUw8oC61OG+PSaysYpl1bnw== + dependencies: + "@csstools/convert-colors" "^1.4.0" + postcss "^7.0.5" + postcss-values-parser "^2.0.0" + +postcss-color-hex-alpha@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/postcss-color-hex-alpha/-/postcss-color-hex-alpha-5.0.3.tgz#a8d9ca4c39d497c9661e374b9c51899ef0f87388" + integrity sha512-PF4GDel8q3kkreVXKLAGNpHKilXsZ6xuu+mOQMHWHLPNyjiUBOr75sp5ZKJfmv1MCus5/DWUGcK9hm6qHEnXYw== + dependencies: + postcss "^7.0.14" + postcss-values-parser "^2.0.1" + +postcss-color-mod-function@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/postcss-color-mod-function/-/postcss-color-mod-function-3.0.3.tgz#816ba145ac11cc3cb6baa905a75a49f903e4d31d" + integrity sha512-YP4VG+xufxaVtzV6ZmhEtc+/aTXH3d0JLpnYfxqTvwZPbJhWqp8bSY3nfNzNRFLgB4XSaBA82OE4VjOOKpCdVQ== + dependencies: + "@csstools/convert-colors" "^1.4.0" + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-color-rebeccapurple@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-4.0.1.tgz#c7a89be872bb74e45b1e3022bfe5748823e6de77" + integrity sha512-aAe3OhkS6qJXBbqzvZth2Au4V3KieR5sRQ4ptb2b2O8wgvB3SJBsdG+jsn2BZbbwekDG8nTfcCNKcSfe/lEy8g== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-colormin@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-4.0.3.tgz#ae060bce93ed794ac71264f08132d550956bd381" + integrity sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw== + dependencies: + browserslist "^4.0.0" + color "^3.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-convert-values@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz#ca3813ed4da0f812f9d43703584e449ebe189a7f" + integrity sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ== + dependencies: + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-custom-media@^7.0.8: + version "7.0.8" + resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-7.0.8.tgz#fffd13ffeffad73621be5f387076a28b00294e0c" + integrity sha512-c9s5iX0Ge15o00HKbuRuTqNndsJUbaXdiNsksnVH8H4gdc+zbLzr/UasOwNG6CTDpLFekVY4672eWdiiWu2GUg== + dependencies: + postcss "^7.0.14" + +postcss-custom-properties@^8.0.11: + version "8.0.11" + resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz#2d61772d6e92f22f5e0d52602df8fae46fa30d97" + integrity sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA== + dependencies: + postcss "^7.0.17" + postcss-values-parser "^2.0.1" + +postcss-custom-selectors@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/postcss-custom-selectors/-/postcss-custom-selectors-5.1.2.tgz#64858c6eb2ecff2fb41d0b28c9dd7b3db4de7fba" + integrity sha512-DSGDhqinCqXqlS4R7KGxL1OSycd1lydugJ1ky4iRXPHdBRiozyMHrdu0H3o7qNOCiZwySZTUI5MV0T8QhCLu+w== + dependencies: + postcss "^7.0.2" + postcss-selector-parser "^5.0.0-rc.3" + +postcss-dir-pseudo-class@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-5.0.0.tgz#6e3a4177d0edb3abcc85fdb6fbb1c26dabaeaba2" + integrity sha512-3pm4oq8HYWMZePJY+5ANriPs3P07q+LW6FAdTlkFH2XqDdP4HeeJYMOzn0HYLhRSjBO3fhiqSwwU9xEULSrPgw== + dependencies: + postcss "^7.0.2" + postcss-selector-parser "^5.0.0-rc.3" + +postcss-discard-comments@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz#1fbabd2c246bff6aaad7997b2b0918f4d7af4033" + integrity sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg== + dependencies: + postcss "^7.0.0" + +postcss-discard-duplicates@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz#3fe133cd3c82282e550fc9b239176a9207b784eb" + integrity sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ== + dependencies: + postcss "^7.0.0" + +postcss-discard-empty@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz#c8c951e9f73ed9428019458444a02ad90bb9f765" + integrity sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w== + dependencies: + postcss "^7.0.0" + +postcss-discard-overridden@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz#652aef8a96726f029f5e3e00146ee7a4e755ff57" + integrity sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg== + dependencies: + postcss "^7.0.0" + +postcss-discard-unused@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-unused/-/postcss-discard-unused-4.0.1.tgz#ee7cc66af8c7e8c19bd36f12d09c4bde4039abea" + integrity sha512-/3vq4LU0bLH2Lj4NYN7BTf2caly0flUB7Xtrk9a5K3yLuXMkHMqMO/x3sDq8W2b1eQFSCyY0IVz2L+0HP8kUUA== + dependencies: + postcss "^7.0.0" + postcss-selector-parser "^3.0.0" + uniqs "^2.0.0" + +postcss-double-position-gradients@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/postcss-double-position-gradients/-/postcss-double-position-gradients-1.0.0.tgz#fc927d52fddc896cb3a2812ebc5df147e110522e" + integrity sha512-G+nV8EnQq25fOI8CH/B6krEohGWnF5+3A6H/+JEpOncu5dCnkS1QQ6+ct3Jkaepw1NGVqqOZH6lqrm244mCftA== + dependencies: + postcss "^7.0.5" + postcss-values-parser "^2.0.0" + +postcss-env-function@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/postcss-env-function/-/postcss-env-function-2.0.2.tgz#0f3e3d3c57f094a92c2baf4b6241f0b0da5365d7" + integrity sha512-rwac4BuZlITeUbiBq60h/xbLzXY43qOsIErngWa4l7Mt+RaSkT7QBjXVGTcBHupykkblHMDrBFh30zchYPaOUw== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-focus-visible@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-focus-visible/-/postcss-focus-visible-4.0.0.tgz#477d107113ade6024b14128317ade2bd1e17046e" + integrity sha512-Z5CkWBw0+idJHSV6+Bgf2peDOFf/x4o+vX/pwcNYrWpXFrSfTkQ3JQ1ojrq9yS+upnAlNRHeg8uEwFTgorjI8g== + dependencies: + postcss "^7.0.2" + +postcss-focus-within@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-focus-within/-/postcss-focus-within-3.0.0.tgz#763b8788596cee9b874c999201cdde80659ef680" + integrity sha512-W0APui8jQeBKbCGZudW37EeMCjDeVxKgiYfIIEo8Bdh5SpB9sxds/Iq8SEuzS0Q4YFOlG7EPFulbbxujpkrV2w== + dependencies: + postcss "^7.0.2" + +postcss-font-variant@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-font-variant/-/postcss-font-variant-4.0.0.tgz#71dd3c6c10a0d846c5eda07803439617bbbabacc" + integrity sha512-M8BFYKOvCrI2aITzDad7kWuXXTm0YhGdP9Q8HanmN4EF1Hmcgs1KK5rSHylt/lUJe8yLxiSwWAHdScoEiIxztg== + dependencies: + postcss "^7.0.2" + +postcss-functions@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-functions/-/postcss-functions-3.0.0.tgz#0e94d01444700a481de20de4d55fb2640564250e" + integrity sha1-DpTQFERwCkgd4g3k1V+yZAVkJQ4= + dependencies: + glob "^7.1.2" + object-assign "^4.1.1" + postcss "^6.0.9" + postcss-value-parser "^3.3.0" + +postcss-gap-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-gap-properties/-/postcss-gap-properties-2.0.0.tgz#431c192ab3ed96a3c3d09f2ff615960f902c1715" + integrity sha512-QZSqDaMgXCHuHTEzMsS2KfVDOq7ZFiknSpkrPJY6jmxbugUPTuSzs/vuE5I3zv0WAS+3vhrlqhijiprnuQfzmg== + dependencies: + postcss "^7.0.2" + +postcss-image-set-function@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/postcss-image-set-function/-/postcss-image-set-function-3.0.1.tgz#28920a2f29945bed4c3198d7df6496d410d3f288" + integrity sha512-oPTcFFip5LZy8Y/whto91L9xdRHCWEMs3e1MdJxhgt4jy2WYXfhkng59fH5qLXSCPN8k4n94p1Czrfe5IOkKUw== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-initial@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-3.0.2.tgz#f018563694b3c16ae8eaabe3c585ac6319637b2d" + integrity sha512-ugA2wKonC0xeNHgirR4D3VWHs2JcU08WAi1KFLVcnb7IN89phID6Qtg2RIctWbnvp1TM2BOmDtX8GGLCKdR8YA== + dependencies: + lodash.template "^4.5.0" + postcss "^7.0.2" + +postcss-lab-function@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-2.0.1.tgz#bb51a6856cd12289ab4ae20db1e3821ef13d7d2e" + integrity sha512-whLy1IeZKY+3fYdqQFuDBf8Auw+qFuVnChWjmxm/UhHWqNHZx+B99EwxTvGYmUBqe3Fjxs4L1BoZTJmPu6usVg== + dependencies: + "@csstools/convert-colors" "^1.4.0" + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-logical@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-logical/-/postcss-logical-3.0.0.tgz#2495d0f8b82e9f262725f75f9401b34e7b45d5b5" + integrity sha512-1SUKdJc2vuMOmeItqGuNaC+N8MzBWFWEkAnRnLpFYj1tGGa7NqyVBujfRtgNa2gXR+6RkGUiB2O5Vmh7E2RmiA== + dependencies: + postcss "^7.0.2" + +postcss-media-minmax@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-media-minmax/-/postcss-media-minmax-4.0.0.tgz#b75bb6cbc217c8ac49433e12f22048814a4f5ed5" + integrity sha512-fo9moya6qyxsjbFAYl97qKO9gyre3qvbMnkOZeZwlsW6XYFsvs2DMGDlchVLfAd8LHPZDxivu/+qW2SMQeTHBw== + dependencies: + postcss "^7.0.2" + +postcss-merge-idents@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-merge-idents/-/postcss-merge-idents-4.0.1.tgz#b7df282a92f052ea0a66c62d8f8812e6d2cbed23" + integrity sha512-43S/VNdF6II0NZ31YxcvNYq4gfURlPAAsJW/z84avBXQCaP4I4qRHUH18slW/SOlJbcxxCobflPNUApYDddS7A== + dependencies: + cssnano-util-same-parent "^4.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-merge-longhand@^4.0.11: + version "4.0.11" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz#62f49a13e4a0ee04e7b98f42bb16062ca2549e24" + integrity sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw== + dependencies: + css-color-names "0.0.4" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + stylehacks "^4.0.0" + +postcss-merge-rules@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz#362bea4ff5a1f98e4075a713c6cb25aefef9a650" + integrity sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ== + dependencies: + browserslist "^4.0.0" + caniuse-api "^3.0.0" + cssnano-util-same-parent "^4.0.0" + postcss "^7.0.0" + postcss-selector-parser "^3.0.0" + vendors "^1.0.0" + +postcss-minify-font-values@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz#cd4c344cce474343fac5d82206ab2cbcb8afd5a6" + integrity sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg== + dependencies: + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-minify-gradients@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz#93b29c2ff5099c535eecda56c4aa6e665a663471" + integrity sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q== + dependencies: + cssnano-util-get-arguments "^4.0.0" + is-color-stop "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-minify-params@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz#6b9cef030c11e35261f95f618c90036d680db874" + integrity sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg== + dependencies: + alphanum-sort "^1.0.0" + browserslist "^4.0.0" + cssnano-util-get-arguments "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + uniqs "^2.0.0" + +postcss-minify-selectors@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz#e2e5eb40bfee500d0cd9243500f5f8ea4262fbd8" + integrity sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g== + dependencies: + alphanum-sort "^1.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-selector-parser "^3.0.0" + +postcss-nesting@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-7.0.1.tgz#b50ad7b7f0173e5b5e3880c3501344703e04c052" + integrity sha512-FrorPb0H3nuVq0Sff7W2rnc3SmIcruVC6YwpcS+k687VxyxO33iE1amna7wHuRVzM8vfiYofXSBHNAZ3QhLvYg== + dependencies: + postcss "^7.0.2" + +postcss-normalize-charset@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz#8b35add3aee83a136b0471e0d59be58a50285dd4" + integrity sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g== + dependencies: + postcss "^7.0.0" + +postcss-normalize-display-values@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz#0dbe04a4ce9063d4667ed2be476bb830c825935a" + integrity sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ== + dependencies: + cssnano-util-get-match "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-positions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz#05f757f84f260437378368a91f8932d4b102917f" + integrity sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA== + dependencies: + cssnano-util-get-arguments "^4.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-repeat-style@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz#c4ebbc289f3991a028d44751cbdd11918b17910c" + integrity sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q== + dependencies: + cssnano-util-get-arguments "^4.0.0" + cssnano-util-get-match "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-string@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz#cd44c40ab07a0c7a36dc5e99aace1eca4ec2690c" + integrity sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA== + dependencies: + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-timing-functions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz#8e009ca2a3949cdaf8ad23e6b6ab99cb5e7d28d9" + integrity sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A== + dependencies: + cssnano-util-get-match "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-unicode@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz#841bd48fdcf3019ad4baa7493a3d363b52ae1cfb" + integrity sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg== + dependencies: + browserslist "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-url@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz#10e437f86bc7c7e58f7b9652ed878daaa95faae1" + integrity sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA== + dependencies: + is-absolute-url "^2.0.0" + normalize-url "^3.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-whitespace@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz#bf1d4070fe4fcea87d1348e825d8cc0c5faa7d82" + integrity sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA== + dependencies: + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-ordered-values@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz#0cf75c820ec7d5c4d280189559e0b571ebac0eee" + integrity sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw== + dependencies: + cssnano-util-get-arguments "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-overflow-shorthand@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-overflow-shorthand/-/postcss-overflow-shorthand-2.0.0.tgz#31ecf350e9c6f6ddc250a78f0c3e111f32dd4c30" + integrity sha512-aK0fHc9CBNx8jbzMYhshZcEv8LtYnBIRYQD5i7w/K/wS9c2+0NSR6B3OVMu5y0hBHYLcMGjfU+dmWYNKH0I85g== + dependencies: + postcss "^7.0.2" + +postcss-page-break@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-page-break/-/postcss-page-break-2.0.0.tgz#add52d0e0a528cabe6afee8b46e2abb277df46bf" + integrity sha512-tkpTSrLpfLfD9HvgOlJuigLuk39wVTbbd8RKcy8/ugV2bNBUW3xU+AIqyxhDrQr1VUj1RmyJrBn1YWrqUm9zAQ== + dependencies: + postcss "^7.0.2" + +postcss-place@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-place/-/postcss-place-4.0.1.tgz#e9f39d33d2dc584e46ee1db45adb77ca9d1dcc62" + integrity sha512-Zb6byCSLkgRKLODj/5mQugyuj9bvAAw9LqJJjgwz5cYryGeXfFZfSXoP1UfveccFmeq0b/2xxwcTEVScnqGxBg== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-preset-env@^6.5.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-6.7.0.tgz#c34ddacf8f902383b35ad1e030f178f4cdf118a5" + integrity sha512-eU4/K5xzSFwUFJ8hTdTQzo2RBLbDVt83QZrAvI07TULOkmyQlnYlpwep+2yIK+K+0KlZO4BvFcleOCCcUtwchg== + dependencies: + autoprefixer "^9.6.1" + browserslist "^4.6.4" + caniuse-lite "^1.0.30000981" + css-blank-pseudo "^0.1.4" + css-has-pseudo "^0.10.0" + css-prefers-color-scheme "^3.1.1" + cssdb "^4.4.0" + postcss "^7.0.17" + postcss-attribute-case-insensitive "^4.0.1" + postcss-color-functional-notation "^2.0.1" + postcss-color-gray "^5.0.0" + postcss-color-hex-alpha "^5.0.3" + postcss-color-mod-function "^3.0.3" + postcss-color-rebeccapurple "^4.0.1" + postcss-custom-media "^7.0.8" + postcss-custom-properties "^8.0.11" + postcss-custom-selectors "^5.1.2" + postcss-dir-pseudo-class "^5.0.0" + postcss-double-position-gradients "^1.0.0" + postcss-env-function "^2.0.2" + postcss-focus-visible "^4.0.0" + postcss-focus-within "^3.0.0" + postcss-font-variant "^4.0.0" + postcss-gap-properties "^2.0.0" + postcss-image-set-function "^3.0.1" + postcss-initial "^3.0.0" + postcss-lab-function "^2.0.1" + postcss-logical "^3.0.0" + postcss-media-minmax "^4.0.0" + postcss-nesting "^7.0.0" + postcss-overflow-shorthand "^2.0.0" + postcss-page-break "^2.0.0" + postcss-place "^4.0.1" + postcss-pseudo-class-any-link "^6.0.0" + postcss-replace-overflow-wrap "^3.0.0" + postcss-selector-matches "^4.0.0" + postcss-selector-not "^4.0.0" + +postcss-pseudo-class-any-link@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-6.0.0.tgz#2ed3eed393b3702879dec4a87032b210daeb04d1" + integrity sha512-lgXW9sYJdLqtmw23otOzrtbDXofUdfYzNm4PIpNE322/swES3VU9XlXHeJS46zT2onFO7V1QFdD4Q9LiZj8mew== + dependencies: + postcss "^7.0.2" + postcss-selector-parser "^5.0.0-rc.3" + +postcss-reduce-idents@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-reduce-idents/-/postcss-reduce-idents-4.0.2.tgz#30447a6ec20941e78e21bd4482a11f569c4f455b" + integrity sha512-Tz70Ri10TclPoCtFfftjFVddx3fZGUkr0dEDbIEfbYhFUOFQZZ77TEqRrU0e6TvAvF+Wa5VVzYTpFpq0uwFFzw== + dependencies: + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-reduce-initial@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz#7fd42ebea5e9c814609639e2c2e84ae270ba48df" + integrity sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA== + dependencies: + browserslist "^4.0.0" + caniuse-api "^3.0.0" + has "^1.0.0" + postcss "^7.0.0" + +postcss-reduce-transforms@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz#17efa405eacc6e07be3414a5ca2d1074681d4e29" + integrity sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg== + dependencies: + cssnano-util-get-match "^4.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-replace-overflow-wrap@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-3.0.0.tgz#61b360ffdaedca84c7c918d2b0f0d0ea559ab01c" + integrity sha512-2T5hcEHArDT6X9+9dVSPQdo7QHzG4XKclFT8rU5TzJPDN7RIRTbO9c4drUISOVemLj03aezStHCR2AIcr8XLpw== + dependencies: + postcss "^7.0.2" + +postcss-round-subpixels@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/postcss-round-subpixels/-/postcss-round-subpixels-1.2.0.tgz#e21d6ac5952e185f9bdc008b94f004fe509d0a11" + integrity sha1-4h1qxZUuGF+b3ACLlPAE/lCdChE= + dependencies: + postcss "^5.0.2" + postcss-value-parser "^3.1.2" + +postcss-selector-matches@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-selector-matches/-/postcss-selector-matches-4.0.0.tgz#71c8248f917ba2cc93037c9637ee09c64436fcff" + integrity sha512-LgsHwQR/EsRYSqlwdGzeaPKVT0Ml7LAT6E75T8W8xLJY62CE4S/l03BWIt3jT8Taq22kXP08s2SfTSzaraoPww== + dependencies: + balanced-match "^1.0.0" + postcss "^7.0.2" + +postcss-selector-not@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-4.0.0.tgz#c68ff7ba96527499e832724a2674d65603b645c0" + integrity sha512-W+bkBZRhqJaYN8XAnbbZPLWMvZD1wKTu0UxtFKdhtGjWYmxhkUneoeOhRJKdAE5V7ZTlnbHfCR+6bNwK9e1dTQ== + dependencies: + balanced-match "^1.0.0" + postcss "^7.0.2" + +postcss-selector-parser@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz#b310f5c4c0fdaf76f94902bbaa30db6aa84f5270" + integrity sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA== + dependencies: + dot-prop "^5.2.0" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-selector-parser@^5.0.0, postcss-selector-parser@^5.0.0-rc.3, postcss-selector-parser@^5.0.0-rc.4: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz#249044356697b33b64f1a8f7c80922dddee7195c" + integrity sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ== + dependencies: + cssesc "^2.0.0" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-selector-parser@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz#934cf799d016c83411859e09dcecade01286ec5c" + integrity sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg== + dependencies: + cssesc "^3.0.0" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-svgo@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-4.0.2.tgz#17b997bc711b333bab143aaed3b8d3d6e3d38258" + integrity sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw== + dependencies: + is-svg "^3.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + svgo "^1.0.0" + +postcss-unique-selectors@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz#9446911f3289bfd64c6d680f073c03b1f9ee4bac" + integrity sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg== + dependencies: + alphanum-sort "^1.0.0" + postcss "^7.0.0" + uniqs "^2.0.0" + +postcss-unprefix@^2.1.3: + version "2.1.4" + resolved "https://registry.yarnpkg.com/postcss-unprefix/-/postcss-unprefix-2.1.4.tgz#ab1c038ab77f068799ed36e1cbd997b51e7360a1" + integrity sha512-s+muBiGIMx3RvgPTtPBnSrfvIBHJ2Zx16QZf/VDB/sAxdYP6FIzci8d1gLh0+9psu5W6zVtCbU5micNt6Zh3cg== + dependencies: + autoprefixer "^9.4.3" + known-css-properties "^0.11.0" + normalize-range "^0.1.2" + postcss-selector-parser "^5.0.0" + postcss-value-parser "^3.3.1" + pseudo-classes "^1.0.0" + pseudo-elements "^1.1.0" + +postcss-value-parser@^3.0.0, postcss-value-parser@^3.1.2, postcss-value-parser@^3.3.0, postcss-value-parser@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" + integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== + +postcss-value-parser@^4.0.2, postcss-value-parser@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz#651ff4593aa9eda8d5d0d66593a2417aeaeb325d" + integrity sha512-N7h4pG+Nnu5BEIzyeaaIYWs0LI5XC40OrRh5L60z0QjFsqGWcHcbkBvpe1WYpcIS9yQ8sOi/vIPt1ejQCrMVrg== + +postcss-values-parser@^2.0.0, postcss-values-parser@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz#da8b472d901da1e205b47bdc98637b9e9e550e5f" + integrity sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg== + dependencies: + flatten "^1.0.2" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-zindex@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-zindex/-/postcss-zindex-4.0.1.tgz#8db6a4cec3111e5d3fd99ea70abeda61873d10c1" + integrity sha512-d/8BlQcUdEugZNRM9AdCA2V4fqREUtn/wcixLN3L6ITgc2P/FMcVVYz8QZkhItWT9NB5qr8wuN2dJCE4/+dlrA== + dependencies: + has "^1.0.0" + postcss "^7.0.0" + uniqs "^2.0.0" + +postcss@^5.0.2: + version "5.2.18" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.18.tgz#badfa1497d46244f6390f58b319830d9107853c5" + integrity sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg== + dependencies: + chalk "^1.1.3" + js-base64 "^2.1.9" + source-map "^0.5.6" + supports-color "^3.2.3" + +postcss@^6.0.10, postcss@^6.0.9: + version "6.0.23" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" + integrity sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag== + dependencies: + chalk "^2.4.1" + source-map "^0.6.1" + supports-color "^5.4.0" + +postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.27, postcss@^7.0.5, postcss@^7.0.6: + version "7.0.27" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.27.tgz#cc67cdc6b0daa375105b7c424a85567345fc54d9" + integrity sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ== + dependencies: + chalk "^2.4.2" + source-map "^0.6.1" + supports-color "^6.1.0" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +prepend-http@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= + +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= + +prettier@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.4.tgz#2d1bae173e355996ee355ec9830a7a1ee05457ef" + integrity sha512-SVJIQ51spzFDvh4fIbCLvciiDMCrRhlN3mbZvv/+ycjvmF5E73bKdGfU8QDLNmjYJf+lsGnDBC4UUnvTe5OO0w== + +private@^0.1.8, private@~0.1.5: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== + +process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= + +process@~0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf" + integrity sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8= + +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= + +promise-polyfill@^8.1.0: + version "8.1.3" + resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-8.1.3.tgz#8c99b3cf53f3a91c68226ffde7bde81d7f904116" + integrity sha512-MG5r82wBzh7pSKDRa9y+vllNHz3e3d4CNj1PQE4BQYxLme0gKYYBm9YENq+UkEikyZ0XbiGWxYlVw3Rl9O/U8g== + +proto-list@~1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" + integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= + +proxy-addr@~2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" + integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== + dependencies: + forwarded "~0.1.2" + ipaddr.js "1.9.1" + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= + +pseudo-classes@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pseudo-classes/-/pseudo-classes-1.0.0.tgz#60a69b67395c36ff119c4d1c86e1981785206b96" + integrity sha1-YKabZzlcNv8RnE0chuGYF4Uga5Y= + +pseudo-elements@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pseudo-elements/-/pseudo-elements-1.1.0.tgz#9ba6dd8ac3ce1f3d7d36d4355aa3e28d08391f28" + integrity sha1-m6bdisPOHz19NtQ1WqPijQg5Hyg= + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= + +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + +pump@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.3: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + +punycode@^1.2.4: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +q@^1.1.2: + version "1.5.1" + resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" + integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= + +qs@6.2.3: + version "6.2.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.2.3.tgz#1cfcb25c10a9b2b483053ff39f5dfc9233908cfe" + integrity sha1-HPyyXBCpsrSDBT/zn138kjOQjP4= + +qs@6.7.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" + integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== + +query-string@^5.0.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" + integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== + dependencies: + decode-uri-component "^0.2.0" + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + +query-string@^6.8.1: + version "6.12.1" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.12.1.tgz#2ae4d272db4fba267141665374e49a1de09e8a7c" + integrity sha512-OHj+zzfRMyj3rmo/6G8a5Ifvw3AleL/EbcHMD27YA31Q+cO5lfmQxECkImuNVjcskLcvBRVHNAB3w6udMs1eAA== + dependencies: + decode-uri-component "^0.2.0" + split-on-first "^1.0.0" + strict-uri-encode "^2.0.0" + +querystring-es3@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +range-parser@~1.2.0, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" + integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== + dependencies: + bytes "3.1.0" + http-errors "1.7.2" + iconv-lite "0.4.24" + unpipe "1.0.0" + +raw-body@^2.3.2: + version "2.4.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c" + integrity sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA== + dependencies: + bytes "3.1.0" + http-errors "1.7.3" + iconv-lite "0.4.24" + unpipe "1.0.0" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + 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" + +readdirp@^2.1.0, readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +recast@~0.11.12: + version "0.11.23" + resolved "https://registry.yarnpkg.com/recast/-/recast-0.11.23.tgz#451fd3004ab1e4df9b4e4b66376b2a21912462d3" + integrity sha1-RR/TAEqx5N+bTktmN2sqIZEkYtM= + dependencies: + ast-types "0.9.6" + esprima "~3.1.0" + private "~0.1.5" + source-map "~0.5.0" + +redent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94= + dependencies: + indent-string "^2.1.0" + strip-indent "^1.0.1" + +reflect-metadata@0.1.12: + version "0.1.12" + resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.12.tgz#311bf0c6b63cd782f228a81abe146a2bfa9c56f2" + integrity sha512-n+IyV+nGz3+0q3/Yf1ra12KpCyi001bi4XFxSjbiWWjfqb52iTTtpGXmCCAOWWIAn9KEuFZKGqBERHmrtScZ3A== + +regenerate-unicode-properties@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" + integrity sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA== + dependencies: + regenerate "^1.4.0" + +regenerate@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" + integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== + +regenerator-runtime@^0.10.0: + version "0.10.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" + integrity sha1-M2w+/BIgrc7dosn6tntaeVWjNlg= + +regenerator-runtime@^0.11.0, regenerator-runtime@^0.11.1: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== + +regenerator-runtime@^0.13.3, regenerator-runtime@^0.13.4: + version "0.13.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697" + integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA== + +regenerator-transform@^0.14.2: + version "0.14.4" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.4.tgz#5266857896518d1616a78a0479337a30ea974cc7" + integrity sha512-EaJaKPBI9GvKpvUz2mz4fhx7WPgvwRLY9v3hlNHWmAuJHI13T4nwKnNvm5RWJzEdnI5g5UwtOww+S8IdoUC2bw== + dependencies: + "@babel/runtime" "^7.8.4" + private "^0.1.8" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexpp@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" + integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== + +regexpu-core@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.0.tgz#fcbf458c50431b0bb7b45d6967b8192d91f3d938" + integrity sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ== + dependencies: + regenerate "^1.4.0" + regenerate-unicode-properties "^8.2.0" + regjsgen "^0.5.1" + regjsparser "^0.6.4" + unicode-match-property-ecmascript "^1.0.4" + unicode-match-property-value-ecmascript "^1.2.0" + +regjsgen@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.1.tgz#48f0bf1a5ea205196929c0d9798b42d1ed98443c" + integrity sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg== + +regjsparser@^0.6.4: + version "0.6.4" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.4.tgz#a769f8684308401a66e9b529d2436ff4d0666272" + integrity sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw== + dependencies: + jsesc "~0.5.0" + +relateurl@0.2.x: + version "0.2.7" + resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" + integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +repeat-element@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= + dependencies: + is-finite "^1.0.0" + +replace-ext@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" + integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs= + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +requires-port@1.x.x: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= + dependencies: + resolve-from "^3.0.0" + +resolve-dir@^1.0.0, resolve-dir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" + integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M= + dependencies: + expand-tilde "^2.0.0" + global-modules "^1.0.0" + +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + integrity sha1-six699nWiBvItuZTM17rywoYh0g= + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +resolve@^1.10.0, resolve@^1.3.2: + version "1.15.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8" + integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w== + dependencies: + path-parse "^1.0.6" + +resp-modifier@6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/resp-modifier/-/resp-modifier-6.0.2.tgz#b124de5c4fbafcba541f48ffa73970f4aa456b4f" + integrity sha1-sSTeXE+6/LpUH0j/pzlw9KpFa08= + dependencies: + debug "^2.2.0" + minimatch "^3.0.2" + +responselike@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= + dependencies: + lowercase-keys "^1.0.0" + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +rgb-regex@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/rgb-regex/-/rgb-regex-1.0.1.tgz#c0e0d6882df0e23be254a475e8edd41915feaeb1" + integrity sha1-wODWiC3w4jviVKR16O3UGRX+rrE= + +rgba-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" + integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM= + +rimraf@2.6.3: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + +rimraf@^2.5.4, rimraf@^2.6.3: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +run-async@^2.2.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.0.tgz#e59054a5b86876cfae07f431d18cbaddc594f1e8" + integrity sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg== + dependencies: + is-promise "^2.1.0" + +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= + dependencies: + aproba "^1.1.1" + +rusha@^0.8.13: + version "0.8.13" + resolved "https://registry.yarnpkg.com/rusha/-/rusha-0.8.13.tgz#9a084e7b860b17bff3015b92c67a6a336191513a" + integrity sha1-mghOe4YLF7/zAVuSxnpqM2GRUTo= + +rx@4.1.0, rx@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" + integrity sha1-pfE/957zt0D+MKqAP7CfmIBdR4I= + +rxjs@^5.5.6: + version "5.5.12" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.12.tgz#6fa61b8a77c3d793dbaf270bee2f43f652d741cc" + integrity sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw== + dependencies: + symbol-observable "1.0.1" + +rxjs@^6.4.0: + version "6.5.5" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.5.tgz#c5c884e3094c8cfee31bf27eb87e54ccfc87f9ec" + integrity sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ== + dependencies: + tslib "^1.9.0" + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" + integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sass-unused@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/sass-unused/-/sass-unused-0.3.0.tgz#69924e4996d6c96840fb3a99e0a0290516811a9f" + integrity sha512-fGNcUpDeSFwnN+BTQ251iM77Py8awPXc96vSE3TpvMcgbC90IrohonRb4oxWX/KzHpezkmUddS8/t04R+yIB8w== + dependencies: + glob "^7.0.5" + gonzales-pe "^4.2.3" + +sax@>=0.6.0, sax@~1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +schema-utils@^0.4.0: + version "0.4.7" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187" + integrity sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ== + dependencies: + ajv "^6.1.0" + ajv-keywords "^3.1.0" + +schema-utils@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" + integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== + dependencies: + ajv "^6.1.0" + ajv-errors "^1.0.0" + ajv-keywords "^3.1.0" + +schema-utils@^2.6.5: + version "2.6.5" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.6.5.tgz#c758f0a7e624263073d396e29cd40aa101152d8a" + integrity sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ== + dependencies: + ajv "^6.12.0" + ajv-keywords "^3.4.1" + +seek-bzip@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/seek-bzip/-/seek-bzip-1.0.5.tgz#cfe917cb3d274bcffac792758af53173eb1fabdc" + integrity sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w= + dependencies: + commander "~2.8.1" + +semver-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-2.0.0.tgz#a93c2c5844539a770233379107b38c7b4ac9d338" + integrity sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw== + +semver-truncate@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/semver-truncate/-/semver-truncate-1.1.2.tgz#57f41de69707a62709a7e0104ba2117109ea47e8" + integrity sha1-V/Qd5pcHpicJp+AQS6IRcQnqR+g= + dependencies: + semver "^5.3.0" + +"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" + integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== + +send@0.16.2: + version "0.16.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" + integrity sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.6.2" + mime "1.4.1" + ms "2.0.0" + on-finished "~2.3.0" + range-parser "~1.2.0" + statuses "~1.4.0" + +send@0.17.1: + version "0.17.1" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" + integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.7.2" + mime "1.6.0" + ms "2.1.1" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + +serialize-error@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-3.0.0.tgz#80100282b09be33c611536f50033481cb9cc87cf" + integrity sha512-+y3nkkG/go1Vdw+2f/+XUXM1DXX1XcxTl99FfiD/OEPUNw4uo0i6FKABfTAN5ZcgGtjTRZcEbxcE/jtXbEY19A== + +serialize-javascript@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61" + integrity sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ== + +serve-index@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.13.2: + version "1.13.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" + integrity sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.2" + send "0.16.2" + +serve-static@1.14.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" + integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.1" + +server-destroy@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/server-destroy/-/server-destroy-1.0.1.tgz#f13bf928e42b9c3e79383e61cc3998b5d14e6cdd" + integrity sha1-8Tv5KOQrnD55OD5hzDmYtdFObN0= + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setimmediate@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" + integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== + +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= + dependencies: + is-arrayish "^0.3.1" + +slice-ansi@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" + integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== + dependencies: + ansi-styles "^3.2.0" + astral-regex "^1.0.0" + is-fullwidth-code-point "^2.0.0" + +sloc@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/sloc/-/sloc-0.2.1.tgz#42ad891e76838c1a22bbd8483468e9d74c7f531e" + integrity sha512-8XJnwCFR4DatLz1s0nGFe6IJPJ+5pjRFhoBuBKq8SLgFI40eD7ak6jOXpzeG0tmIpyOc1zCs9bjKAxMFm1451A== + dependencies: + async "~2.1.4" + cli-table "^0.3.1" + commander "~2.9.0" + readdirp "^2.1.0" + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +socket.io-adapter@~1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz#ab3f0d6f66b8fc7fca3959ab5991f82221789be9" + integrity sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g== + +socket.io-client@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.1.1.tgz#dcb38103436ab4578ddb026638ae2f21b623671f" + integrity sha512-jxnFyhAuFxYfjqIgduQlhzqTcOEQSn+OHKVfAxWaNWa7ecP7xSNk2Dx/3UEsDcY7NcFafxvNvKPmmO7HTwTxGQ== + dependencies: + backo2 "1.0.2" + base64-arraybuffer "0.1.5" + component-bind "1.0.0" + component-emitter "1.2.1" + debug "~3.1.0" + engine.io-client "~3.2.0" + has-binary2 "~1.0.2" + has-cors "1.1.0" + indexof "0.0.1" + object-component "0.0.3" + parseqs "0.0.5" + parseuri "0.0.5" + socket.io-parser "~3.2.0" + to-array "0.1.4" + +socket.io-client@^2.0.4: + version "2.3.0" + resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.3.0.tgz#14d5ba2e00b9bcd145ae443ab96b3f86cbcc1bb4" + integrity sha512-cEQQf24gET3rfhxZ2jJ5xzAOo/xhZwK+mOqtGRg5IowZsMgwvHwnf/mCRapAAkadhM26y+iydgwsXGObBB5ZdA== + dependencies: + backo2 "1.0.2" + base64-arraybuffer "0.1.5" + component-bind "1.0.0" + component-emitter "1.2.1" + debug "~4.1.0" + engine.io-client "~3.4.0" + has-binary2 "~1.0.2" + has-cors "1.1.0" + indexof "0.0.1" + object-component "0.0.3" + parseqs "0.0.5" + parseuri "0.0.5" + socket.io-parser "~3.3.0" + to-array "0.1.4" + +socket.io-parser@~3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.2.0.tgz#e7c6228b6aa1f814e6148aea325b51aa9499e077" + integrity sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA== + dependencies: + component-emitter "1.2.1" + debug "~3.1.0" + isarray "2.0.1" + +socket.io-parser@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.3.0.tgz#2b52a96a509fdf31440ba40fed6094c7d4f1262f" + integrity sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng== + dependencies: + component-emitter "1.2.1" + debug "~3.1.0" + isarray "2.0.1" + +socket.io@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-2.1.1.tgz#a069c5feabee3e6b214a75b40ce0652e1cfb9980" + integrity sha512-rORqq9c+7W0DAK3cleWNSyfv/qKXV99hV4tZe+gGLfBECw3XEhBy7x85F3wypA9688LKjtwO9pX9L33/xQI8yA== + dependencies: + debug "~3.1.0" + engine.io "~3.2.0" + has-binary2 "~1.0.2" + socket.io-adapter "~1.1.0" + socket.io-client "2.1.1" + socket.io-parser "~3.2.0" + +sort-keys-length@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sort-keys-length/-/sort-keys-length-1.0.1.tgz#9cb6f4f4e9e48155a6aa0671edd336ff1479a188" + integrity sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg= + dependencies: + sort-keys "^1.0.0" + +sort-keys@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" + integrity sha1-RBttTTRnmPG05J6JIK37oOVD+a0= + dependencies: + is-plain-obj "^1.0.0" + +sort-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" + integrity sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg= + dependencies: + is-plain-obj "^1.0.0" + +source-list-map@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== + +source-map-resolve@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.4.tgz#54456efa89caa9270af7cd624cc2f123e51fbae8" + integrity sha512-PETSPG6BjY1AHs2t64vS2aqAgu6dMIMXJULWFBGbh2Gr8nVLbCFDo6i/RMMvviIQ2h1Z8+5gQhVKSn2je9nmdg== + dependencies: + source-map "^0.6.0" + +source-map-support@~0.5.12: + version "0.5.16" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042" + integrity sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + +source-map@^0.5.0, source-map@^0.5.6, source-map@~0.5.0: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@~0.1.38: + version "0.1.43" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" + integrity sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y= + dependencies: + amdefine ">=0.0.4" + +source-map@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" + integrity sha1-2rc/vPwrqBm03gO9b26qSBZLP50= + dependencies: + amdefine ">=0.0.4" + +spdx-correct@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" + integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" + integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== + +spdx-expression-parse@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" + integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.5" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654" + integrity sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q== + +speed-measure-webpack-plugin@^1.3.1: + version "1.3.3" + resolved "https://registry.yarnpkg.com/speed-measure-webpack-plugin/-/speed-measure-webpack-plugin-1.3.3.tgz#6ff894fc83e8a6310dde3af863a0329cd79da4f5" + integrity sha512-2ljD4Ch/rz2zG3HsLsnPfp23osuPBS0qPuz9sGpkNXTN1Ic4M+W9xB8l8rS8ob2cO4b1L+WTJw/0AJwWYVgcxQ== + dependencies: + chalk "^2.0.1" + +split-on-first@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" + integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw== + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +squeak@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/squeak/-/squeak-1.3.0.tgz#33045037b64388b567674b84322a6521073916c3" + integrity sha1-MwRQN7ZDiLVnZ0uEMiplIQc5FsM= + dependencies: + chalk "^1.0.0" + console-stream "^0.1.1" + lpad-align "^1.0.1" + +ssri@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" + integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== + dependencies: + figgy-pudding "^3.5.1" + +stable@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" + integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +statuses@~1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" + integrity sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4= + +statuses@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" + integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew== + +stream-browserify@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" + integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + +stream-each@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" + integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + +stream-http@^2.7.2: + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.3.6" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + +stream-shift@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" + integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== + +stream-throttle@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/stream-throttle/-/stream-throttle-0.1.3.tgz#add57c8d7cc73a81630d31cd55d3961cfafba9c3" + integrity sha1-rdV8jXzHOoFjDTHNVdOWHPr7qcM= + dependencies: + commander "^2.2.0" + limiter "^1.0.5" + +strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= + +strict-uri-encode@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" + integrity sha1-ucczDHBChi9rFC3CdLvMWGbONUY= + +strictdom@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strictdom/-/strictdom-1.0.1.tgz#189de91649f73d44d59b8432efa68ef9d2659460" + integrity sha1-GJ3pFkn3PUTVm4Qy76aO+dJllGA= + +string-replace-webpack-plugin@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/string-replace-webpack-plugin/-/string-replace-webpack-plugin-0.1.3.tgz#73c657e759d66cfe80ae1e0cf091aa256d0e715c" + integrity sha1-c8ZX51nWbP6Arh4M8JGqJW0OcVw= + dependencies: + async "~0.2.10" + loader-utils "~0.2.3" + optionalDependencies: + css-loader "^0.9.1" + file-loader "^0.8.1" + style-loader "^0.8.3" + +string-template@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/string-template/-/string-template-1.0.0.tgz#9e9f2233dc00f218718ec379a28a5673ecca8b96" + integrity sha1-np8iM9wA8hhxjsN5oopWc+zKi5Y= + +string-width@^1.0.1, string-width@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +string-width@^2.0.0, string-width@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string-width@^3.0.0, string-width@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" + integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.0" + +string.prototype.trimend@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" + integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + +string.prototype.trimleft@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz#4408aa2e5d6ddd0c9a80739b087fbc067c03b3cc" + integrity sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + string.prototype.trimstart "^1.0.0" + +string.prototype.trimright@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz#c76f1cef30f21bbad8afeb8db1511496cfb0f2a3" + integrity sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + string.prototype.trimend "^1.0.0" + +string.prototype.trimstart@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" + integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + +string_decoder@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +strip-ansi@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" + integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== + dependencies: + ansi-regex "^5.0.0" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= + dependencies: + is-utf8 "^0.2.0" + +strip-dirs@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/strip-dirs/-/strip-dirs-2.1.0.tgz#4987736264fc344cf20f6c34aca9d13d1d4ed6c5" + integrity sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g== + dependencies: + is-natural-number "^4.0.1" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + +strip-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + integrity sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI= + dependencies: + get-stdin "^4.0.1" + +strip-json-comments@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + +strip-json-comments@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.0.tgz#7638d31422129ecf4457440009fba03f9f9ac180" + integrity sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w== + +strip-outer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-outer/-/strip-outer-1.0.1.tgz#b2fd2abf6604b9d1e6013057195df836b8a9d631" + integrity sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg== + dependencies: + escape-string-regexp "^1.0.2" + +style-loader@^0.8.3: + version "0.8.3" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.8.3.tgz#f4f92eb7db63768748f15065cd6700f5a1c85357" + integrity sha1-9Pkut9tjdodI8VBlzWcA9aHIU1c= + dependencies: + loader-utils "^0.2.5" + +stylehacks@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-4.0.3.tgz#6718fcaf4d1e07d8a1318690881e8d96726a71d5" + integrity sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g== + dependencies: + browserslist "^4.0.0" + postcss "^7.0.0" + postcss-selector-parser "^3.0.0" + +supports-color@6.1.0, supports-color@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" + integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== + dependencies: + has-flag "^3.0.0" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + +supports-color@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= + dependencies: + has-flag "^1.0.0" + +supports-color@^5.3.0, supports-color@^5.4.0, supports-color@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +svgo@^1.0.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.2.tgz#b6dc511c063346c9e415b81e43401145b96d4167" + integrity sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw== + dependencies: + chalk "^2.4.1" + coa "^2.0.2" + css-select "^2.0.0" + css-select-base-adapter "^0.1.1" + css-tree "1.0.0-alpha.37" + csso "^4.0.2" + js-yaml "^3.13.1" + mkdirp "~0.5.1" + object.values "^1.1.0" + sax "~1.2.4" + stable "^0.1.8" + unquote "~1.1.1" + util.promisify "~1.0.0" + +symbol-observable@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4" + integrity sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ= + +table@^5.2.3: + version "5.4.6" + resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" + integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== + dependencies: + ajv "^6.10.2" + lodash "^4.17.14" + slice-ansi "^2.1.0" + string-width "^3.0.0" + +tapable@^1.0.0, tapable@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" + integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== + +tar-stream@^1.5.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" + integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A== + dependencies: + bl "^1.0.0" + buffer-alloc "^1.2.0" + end-of-stream "^1.0.0" + fs-constants "^1.0.0" + readable-stream "^2.3.0" + to-buffer "^1.1.1" + xtend "^4.0.0" + +temp-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" + integrity sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0= + +tempfile@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/tempfile/-/tempfile-2.0.0.tgz#6b0446856a9b1114d1856ffcbe509cccb0977265" + integrity sha1-awRGhWqbERTRhW/8vlCczLCXcmU= + dependencies: + temp-dir "^1.0.0" + uuid "^3.0.1" + +terser-webpack-plugin@^1.1.0, terser-webpack-plugin@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz#5ecaf2dbdc5fb99745fd06791f46fc9ddb1c9a7c" + integrity sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA== + dependencies: + cacache "^12.0.2" + find-cache-dir "^2.1.0" + is-wsl "^1.1.0" + schema-utils "^1.0.0" + serialize-javascript "^2.1.2" + source-map "^0.6.1" + terser "^4.1.2" + webpack-sources "^1.4.0" + worker-farm "^1.7.0" + +terser@^4.1.2: + version "4.6.11" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.6.11.tgz#12ff99fdd62a26de2a82f508515407eb6ccd8a9f" + integrity sha512-76Ynm7OXUG5xhOpblhytE7X58oeNSmC8xnNhjWVo8CksHit0U0kO4hfNbPrrYwowLWFgM2n9L176VNx2QaHmtA== + dependencies: + commander "^2.20.0" + source-map "~0.6.1" + source-map-support "~0.5.12" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +tfunk@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/tfunk/-/tfunk-3.1.0.tgz#38e4414fc64977d87afdaa72facb6d29f82f7b5b" + integrity sha1-OORBT8ZJd9h6/apy+sttKfgve1s= + dependencies: + chalk "^1.1.1" + object-path "^0.9.0" + +through2@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +through@^2.3.6, through@^2.3.8, through@~2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +time-stamp@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" + integrity sha1-dkpaEa9QVhkhsTPztE5hhofg9cM= + +timed-out@^4.0.0, timed-out@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= + +timers-browserify@^2.0.4: + version "2.0.11" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.11.tgz#800b1f3eee272e5bc53ee465a04d0e804c31211f" + integrity sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ== + dependencies: + setimmediate "^1.0.4" + +timm@^1.6.1: + version "1.6.2" + resolved "https://registry.yarnpkg.com/timm/-/timm-1.6.2.tgz#dfd8c6719f7ba1fcfc6295a32670a1c6d166c0bd" + integrity sha512-IH3DYDL1wMUwmIlVmMrmesw5lZD6N+ZOAFWEyLrtpoL9Bcrs9u7M/vyOnHzDD2SMs4irLkVjqxZbHrXStS/Nmw== + +timsort@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" + integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= + +tinycolor2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.1.tgz#f4fad333447bc0b07d4dc8e9209d8f39a8ac77e8" + integrity sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g= + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +to-array@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890" + integrity sha1-F+bBH3PdTz10zaek/zI46a2b+JA= + +to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= + +to-buffer@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" + integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg== + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== + +trim-newlines@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + integrity sha1-WIeWa7WCpFA6QetST301ARgVphM= + +trim-repeated@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-repeated/-/trim-repeated-1.0.0.tgz#e3646a2ea4e891312bf7eace6cfb05380bc01c21" + integrity sha1-42RqLqTokTEr9+rObPsFOAvAHCE= + dependencies: + escape-string-regexp "^1.0.2" + +trim@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" + integrity sha1-WFhUf2spB1fulczMZm+1AITEYN0= + +tryer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" + integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA== + +tslib@1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.0.tgz#e37a86fda8cbbaf23a057f473c9f4dc64e5fc2e8" + integrity sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ== + +tslib@^1.9.0: + version "1.11.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35" + integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA== + +tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +type-fest@^0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.5.2.tgz#d6ef42a0356c6cd45f49485c3b6281fc148e48a2" + integrity sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw== + +type-is@~1.6.17, type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + +ua-parser-js@0.7.17: + version "0.7.17" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac" + integrity sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g== + +uglify-js@3.4.x: + version "3.4.10" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f" + integrity sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw== + dependencies: + commander "~2.19.0" + source-map "~0.6.1" + +uglify-template-string-loader@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/uglify-template-string-loader/-/uglify-template-string-loader-1.1.1.tgz#d091d15f66b65f1cae2f4222583009302c86339f" + integrity sha512-EHJx8m0aIHlwX5xlJd2xPYIFvLrPkVK5X8zpVxSNTmu7KoT2eSg1TNlwZS+JS65+dwJXC4rC5mc+F4UVe2rckw== + +ultron@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" + integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og== + +unbzip2-stream@^1.0.9: + version "1.4.1" + resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.1.tgz#151b104af853df3efdaa135d8b1eca850a44b426" + integrity sha512-sgDYfSDPMsA4Hr2/w7vOlrJBlwzmyakk1+hW8ObLvxSp0LA36LcL2XItGvOT3OSblohSdevMuT8FQjLsqyy4sA== + dependencies: + buffer "^5.2.1" + through "^2.3.8" + +unicode-canonical-property-names-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" + integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== + +unicode-match-property-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" + integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg== + dependencies: + unicode-canonical-property-names-ecmascript "^1.0.4" + unicode-property-aliases-ecmascript "^1.0.4" + +unicode-match-property-value-ecmascript@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz#0d91f600eeeb3096aa962b1d6fc88876e64ea531" + integrity sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ== + +unicode-property-aliases-ecmascript@^1.0.4: + version "1.1.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz#dd57a99f6207bedff4628abefb94c50db941c8f4" + integrity sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg== + +union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + +uniq@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" + integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= + +uniqs@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" + integrity sha1-/+3ks2slKQaW5uFl1KWe25mOawI= + +unique-filename@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" + integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== + dependencies: + imurmurhash "^0.1.4" + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +unquote@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" + integrity sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ= + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +unused-files-webpack-plugin@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/unused-files-webpack-plugin/-/unused-files-webpack-plugin-3.4.0.tgz#adc67a3b5549d028818d3119cbf2b5c88aea8670" + integrity sha512-cmukKOBdIqaM1pqThY0+jp+mYgCVyzrD8uRbKEucQwIGZcLIRn+gSRiQ7uLjcDd3Zba9NUxVGyYa7lWM4UCGeg== + dependencies: + babel-runtime "^7.0.0-beta.3" + glob-all "^3.1.0" + semver "^5.5.0" + util.promisify "^1.0.0" + warning "^3.0.0" + +upath@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== + +upper-case@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" + integrity sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg= + +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +url-parse-lax@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= + dependencies: + prepend-http "^1.0.1" + +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= + dependencies: + prepend-http "^2.0.0" + +url-to-options@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" + integrity sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k= + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +utif@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/utif/-/utif-2.0.1.tgz#9e1582d9bbd20011a6588548ed3266298e711759" + integrity sha512-Z/S1fNKCicQTf375lIP9G8Sa1H/phcysstNrrSdZKj1f9g58J4NMgb5IgiEZN9/nLMPDwF0W7hdOe9Qq2IYoLg== + dependencies: + pako "^1.0.5" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +util.promisify@^1.0.0, util.promisify@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" + integrity sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.2" + has-symbols "^1.0.1" + object.getownpropertydescriptors "^2.1.0" + +util@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= + dependencies: + inherits "2.0.1" + +util@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" + integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== + dependencies: + inherits "2.0.3" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +uuid@^3.0.1: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +v8-compile-cache@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe" + integrity sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w== + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +validator@9.2.0: + version "9.2.0" + resolved "https://registry.yarnpkg.com/validator/-/validator-9.2.0.tgz#ad216eed5f37cac31a6fe00ceab1f6b88bded03e" + integrity sha512-6Ij4Eo0KM4LkR0d0IegOwluG5453uqT5QyF5SV5Ezvm8/zmkKI/L4eoraafZGlZPC9guLkwKzgypcw8VGWWnGA== + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +vendors@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.4.tgz#e2b800a53e7a29b93506c3cf41100d16c4c4ad8e" + integrity sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w== + +vinyl@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.0.tgz#d85b07da96e458d25b2ffe19fece9f2caa13ed86" + integrity sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg== + dependencies: + clone "^2.1.1" + clone-buffer "^1.0.0" + clone-stats "^1.0.0" + cloneable-readable "^1.0.0" + remove-trailing-separator "^1.0.1" + replace-ext "^1.0.0" + +vm-browserify@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" + integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== + +warning@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/warning/-/warning-3.0.0.tgz#32e5377cb572de4ab04753bdf8821c01ed605b7c" + integrity sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w= + dependencies: + loose-envify "^1.0.0" + +watchpack@^1.6.0: + version "1.6.1" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.1.tgz#280da0a8718592174010c078c7585a74cd8cd0e2" + integrity sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA== + dependencies: + chokidar "^2.1.8" + graceful-fs "^4.1.2" + neo-async "^2.5.0" + +webpack-bundle-analyzer@^3.0.3: + version "3.7.0" + resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.7.0.tgz#84da434e89442899b884d9ad38e466d0db02a56f" + integrity sha512-mETdjZ30a3Yf+NTB/wqTgACK7rAYQl5uxKK0WVTNmF0sM3Uv8s3R58YZMW7Rhu0Lk2Rmuhdj5dcH5Q76zCDVdA== + dependencies: + acorn "^7.1.1" + acorn-walk "^7.1.1" + bfj "^6.1.1" + chalk "^2.4.1" + commander "^2.18.0" + ejs "^2.6.1" + express "^4.16.3" + filesize "^3.6.1" + gzip-size "^5.0.0" + lodash "^4.17.15" + mkdirp "^0.5.1" + opener "^1.5.1" + ws "^6.0.0" + +webpack-cli@^3.1.0: + version "3.3.11" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.3.11.tgz#3bf21889bf597b5d82c38f215135a411edfdc631" + integrity sha512-dXlfuml7xvAFwYUPsrtQAA9e4DOe58gnzSxhgrO/ZM/gyXTBowrsYeubyN4mqGhYdpXMFNyQ6emjJS9M7OBd4g== + dependencies: + chalk "2.4.2" + cross-spawn "6.0.5" + enhanced-resolve "4.1.0" + findup-sync "3.0.0" + global-modules "2.0.0" + import-local "2.0.0" + interpret "1.2.0" + loader-utils "1.2.3" + supports-color "6.1.0" + v8-compile-cache "2.0.3" + yargs "13.2.4" + +webpack-deep-scope-plugin@^1.6.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/webpack-deep-scope-plugin/-/webpack-deep-scope-plugin-1.6.2.tgz#131eac79739021e42ebc07066ea8869107f37b85" + integrity sha512-S5ZM1i7oTIVPIS1z/Fu41tqFzaXpy8vZnwEDC9I7NLj5XD8GGrDZbDXtG5FCGkHPGxtAzF4O21DKZZ76vpBGzw== + dependencies: + deep-scope-analyser "^1.7.0" + +webpack-plugin-replace@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/webpack-plugin-replace/-/webpack-plugin-replace-1.2.0.tgz#3f20db96237400433231e35ea76d9be3f7128916" + integrity sha512-1HA3etHpJW55qonJqv84o5w5GY7iqF8fqSHpTWdNwarj1llkkt4jT4QSvYs1hoaU8Lu5akDnq/spHHO5mXwo1w== + +webpack-sources@^1.4.0, webpack-sources@^1.4.1: + version "1.4.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" + integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack-stream@^5.1.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/webpack-stream/-/webpack-stream-5.2.1.tgz#35c992161399fe8cad9c10d4a5c258f022629b39" + integrity sha512-WvyVU0K1/VB1NZ7JfsaemVdG0PXAQUqbjUNW4A58th4pULvKMQxG+y33HXTL02JvD56ko2Cub+E2NyPwrLBT/A== + dependencies: + fancy-log "^1.3.3" + lodash.clone "^4.3.2" + lodash.some "^4.2.2" + memory-fs "^0.4.1" + plugin-error "^1.0.1" + supports-color "^5.5.0" + through "^2.3.8" + vinyl "^2.1.0" + webpack "^4.26.1" + +webpack-strip-block@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/webpack-strip-block/-/webpack-strip-block-0.2.0.tgz#c60d4a703e0eeee8895e7f1abe9b5fe914681470" + integrity sha1-xg1KcD4O7uiJXn8avptf6RRoFHA= + dependencies: + loader-utils "^1.1.0" + +webpack@^4.26.1, webpack@^4.31.0: + version "4.42.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.42.1.tgz#ae707baf091f5ca3ef9c38b884287cfe8f1983ef" + integrity sha512-SGfYMigqEfdGchGhFFJ9KyRpQKnipvEvjc1TwrXEPCM6H5Wywu10ka8o3KGrMzSMxMQKt8aCHUFh5DaQ9UmyRg== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/wasm-edit" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + acorn "^6.2.1" + ajv "^6.10.2" + ajv-keywords "^3.4.1" + chrome-trace-event "^1.0.2" + enhanced-resolve "^4.1.0" + eslint-scope "^4.0.3" + json-parse-better-errors "^1.0.2" + loader-runner "^2.4.0" + loader-utils "^1.2.3" + memory-fs "^0.4.1" + micromatch "^3.1.10" + mkdirp "^0.5.3" + neo-async "^2.6.1" + node-libs-browser "^2.2.1" + schema-utils "^1.0.0" + tapable "^1.1.3" + terser-webpack-plugin "^1.4.3" + watchpack "^1.6.0" + webpack-sources "^1.4.1" + +whatwg-fetch@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb" + integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q== + +which-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + integrity sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8= + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which@^1.2.14, which@^1.2.9, which@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +window-size@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" + integrity sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU= + +word-wrap@~1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +worker-farm@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" + integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== + dependencies: + errno "~0.1.7" + +worker-loader@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/worker-loader/-/worker-loader-2.0.0.tgz#45fda3ef76aca815771a89107399ee4119b430ac" + integrity sha512-tnvNp4K3KQOpfRnD20m8xltE3eWh89Ye+5oj7wXEEHKac1P4oZ6p9oTj8/8ExqoSBnk9nu5Pr4nKfQ1hn2APJw== + dependencies: + loader-utils "^1.0.0" + schema-utils "^0.4.0" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrap-ansi@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== + dependencies: + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" + +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +write@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" + integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== + dependencies: + mkdirp "^0.5.1" + +ws@^6.0.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" + integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== + dependencies: + async-limiter "~1.0.0" + +ws@~3.3.1: + version "3.3.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" + integrity sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA== + dependencies: + async-limiter "~1.0.0" + safe-buffer "~5.1.0" + ultron "~1.1.0" + +ws@~6.1.0: + version "6.1.4" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.4.tgz#5b5c8800afab925e94ccb29d153c8d02c1776ef9" + integrity sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA== + dependencies: + async-limiter "~1.0.0" + +xhr@^2.0.1: + version "2.5.0" + resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.5.0.tgz#bed8d1676d5ca36108667692b74b316c496e49dd" + integrity sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ== + dependencies: + global "~4.3.0" + is-function "^1.0.1" + parse-headers "^2.0.0" + xtend "^4.0.0" + +xml-parse-from-string@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz#a9029e929d3dbcded169f3c6e28238d95a5d5a28" + integrity sha1-qQKekp09vN7RafPG4oI42VpdWig= + +xml2js@^0.4.5: + version "0.4.23" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" + integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== + dependencies: + sax ">=0.6.0" + xmlbuilder "~11.0.0" + +xmlbuilder@~11.0.0: + version "11.0.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" + integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== + +xmlhttprequest-ssl@~1.5.4: + version "1.5.5" + resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e" + integrity sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4= + +xtend@^4.0.0, xtend@~4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +y18n@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= + +y18n@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yargs-parser@^13.1.0: + version "13.1.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" + integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-parser@^18.1.1: + version "18.1.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.2.tgz#2f482bea2136dbde0861683abea7756d30b504f1" + integrity sha512-hlIPNR3IzC1YuL1c2UwwDKpXlNFBqD1Fswwh1khz5+d8Cq/8yc/Mn0i+rQXduu8hcrFKvO7Eryk+09NecTQAAQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-parser@^4.1.0, yargs-parser@^4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-4.2.1.tgz#29cceac0dc4f03c6c87b4a9f217dd18c9f74871c" + integrity sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw= + dependencies: + camelcase "^3.0.0" + +yargs@13.2.4: + version "13.2.4" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.4.tgz#0b562b794016eb9651b98bd37acf364aa5d6dc83" + integrity sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg== + dependencies: + cliui "^5.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + os-locale "^3.1.0" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.1.0" + +yargs@6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-6.4.0.tgz#816e1a866d5598ccf34e5596ddce22d92da490d4" + integrity sha1-gW4ahm1VmMzzTlWW3c4i2S2kkNQ= + dependencies: + camelcase "^3.0.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.2" + which-module "^1.0.0" + window-size "^0.2.0" + y18n "^3.2.1" + yargs-parser "^4.1.0" + +yargs@6.6.0: + version "6.6.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-6.6.0.tgz#782ec21ef403345f830a808ca3d513af56065208" + integrity sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg= + dependencies: + camelcase "^3.0.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.2" + which-module "^1.0.0" + y18n "^3.2.1" + yargs-parser "^4.2.0" + +yargs@^15.3.1: + version "15.3.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.3.1.tgz#9505b472763963e54afe60148ad27a330818e98b" + integrity sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA== + dependencies: + cliui "^6.0.0" + decamelize "^1.2.0" + find-up "^4.1.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^4.2.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^18.1.1" + +yauzl@^2.4.2: + version "2.10.0" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" + integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk= + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.1.0" + +yeast@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" + integrity sha1-AI4G2AlDIMNy28L47XagymyKxBk=