From 7352c6c6122a79a6e3ff78cc2ed5766535d2a82e Mon Sep 17 00:00:00 2001 From: Zef Hemel Date: Sun, 20 Mar 2022 09:56:28 +0100 Subject: [PATCH] Moving everything into a single repo and build --- .parcelrc | 6 + Makefile | 9 + bin/plugbox-bundle.mjs | 77 + jest.config.js | 12 + package.json | 94 + plugbox/iframe_sandbox.html | 8 + plugbox/iframe_sandbox.ts | 43 + plugbox/node_sandbox.ts | 45 + plugbox/node_worker.ts | 97 + plugbox/runtime.test.ts | 79 + plugbox/runtime.ts | 193 + plugbox/sandbox_worker.ts | 111 + plugbox/types.ts | 44 + plugbox/util.ts | 6 + plugbox/webworker_sandbox.ts | 34 + server/api.test.ts | 96 + server/api_server.ts | 121 + server/disk_storage.ts | 91 + server/index_api.ts | 90 + server/page_api.ts | 306 ++ server/server.ts | 46 + server/syscalls/page_index.ts | 83 + server/types.ts | 62 + server/util.ts | 5 + webapp/app_event.ts | 22 + webapp/boot.ts | 21 + webapp/collab.ts | 252 + webapp/commands.ts | 60 + webapp/components/command_palette.tsx | 39 + webapp/components/filter.tsx | 167 + webapp/components/page_navigator.tsx | 44 + webapp/components/status_bar.tsx | 17 + webapp/components/top_bar.tsx | 39 + webapp/constant.ts | 1 + webapp/cursorEffect.ts | 12 + webapp/customtags.ts | 12 + webapp/editor.tsx | 497 ++ webapp/event.ts | 20 + webapp/images/logo.png | Bin 0 -> 67362 bytes webapp/index.html | 15 + webapp/line_wrapper.ts | 83 + webapp/manifest.json | 17 + webapp/markdown/commands.ts | 371 ++ webapp/markdown/index.ts | 56 + webapp/markdown/markdown.ts | 84 + webapp/navigator.ts | 73 + webapp/parser.ts | 157 + webapp/reducer.ts | 63 + webapp/service_worker.ts | 17 + webapp/smart_quotes.ts | 35 + webapp/space.ts | 191 + webapp/style.ts | 38 + webapp/styles/editor.scss | 215 + webapp/styles/filter_box.scss | 88 + webapp/styles/main.scss | 88 + webapp/syscalls/db.localstorage.ts | 8 + webapp/syscalls/editor.browser.ts | 133 + webapp/syscalls/indexer.native.ts | 22 + webapp/syscalls/space.native.ts | 28 + webapp/syscalls/ui.browser.ts | 20 + webapp/types.ts | 70 + webapp/util.ts | 31 + webapp/watcher.ts | 2 + yarn.lock | 6597 +++++++++++++++++++++++++ 64 files changed, 11463 insertions(+) create mode 100644 .parcelrc create mode 100644 Makefile create mode 100755 bin/plugbox-bundle.mjs create mode 100644 jest.config.js create mode 100644 package.json create mode 100644 plugbox/iframe_sandbox.html create mode 100644 plugbox/iframe_sandbox.ts create mode 100644 plugbox/node_sandbox.ts create mode 100644 plugbox/node_worker.ts create mode 100644 plugbox/runtime.test.ts create mode 100644 plugbox/runtime.ts create mode 100644 plugbox/sandbox_worker.ts create mode 100644 plugbox/types.ts create mode 100644 plugbox/util.ts create mode 100644 plugbox/webworker_sandbox.ts create mode 100644 server/api.test.ts create mode 100644 server/api_server.ts create mode 100644 server/disk_storage.ts create mode 100644 server/index_api.ts create mode 100644 server/page_api.ts create mode 100644 server/server.ts create mode 100644 server/syscalls/page_index.ts create mode 100644 server/types.ts create mode 100644 server/util.ts create mode 100644 webapp/app_event.ts create mode 100644 webapp/boot.ts create mode 100644 webapp/collab.ts create mode 100644 webapp/commands.ts create mode 100644 webapp/components/command_palette.tsx create mode 100644 webapp/components/filter.tsx create mode 100644 webapp/components/page_navigator.tsx create mode 100644 webapp/components/status_bar.tsx create mode 100644 webapp/components/top_bar.tsx create mode 100644 webapp/constant.ts create mode 100644 webapp/cursorEffect.ts create mode 100644 webapp/customtags.ts create mode 100644 webapp/editor.tsx create mode 100644 webapp/event.ts create mode 100644 webapp/images/logo.png create mode 100644 webapp/index.html create mode 100644 webapp/line_wrapper.ts create mode 100644 webapp/manifest.json create mode 100644 webapp/markdown/commands.ts create mode 100644 webapp/markdown/index.ts create mode 100644 webapp/markdown/markdown.ts create mode 100644 webapp/navigator.ts create mode 100644 webapp/parser.ts create mode 100644 webapp/reducer.ts create mode 100644 webapp/service_worker.ts create mode 100644 webapp/smart_quotes.ts create mode 100644 webapp/space.ts create mode 100644 webapp/style.ts create mode 100644 webapp/styles/editor.scss create mode 100644 webapp/styles/filter_box.scss create mode 100644 webapp/styles/main.scss create mode 100644 webapp/syscalls/db.localstorage.ts create mode 100644 webapp/syscalls/editor.browser.ts create mode 100644 webapp/syscalls/indexer.native.ts create mode 100644 webapp/syscalls/space.native.ts create mode 100644 webapp/syscalls/ui.browser.ts create mode 100644 webapp/types.ts create mode 100644 webapp/util.ts create mode 100644 webapp/watcher.ts create mode 100644 yarn.lock diff --git a/.parcelrc b/.parcelrc new file mode 100644 index 0000000..c6b287a --- /dev/null +++ b/.parcelrc @@ -0,0 +1,6 @@ +{ + "extends": "@parcel/config-default", + "validators": { + "*.{ts,tsx}": ["@parcel/validator-typescript"] + } +} \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..fc54984 --- /dev/null +++ b/Makefile @@ -0,0 +1,9 @@ +.PHONY: core + +BUILD=../plugbox/bin/plugbox-bundle.mjs + +core: core/* + ${BUILD} --debug core/core.plug.json ../webapp/src/generated/core.plug.json + +watch: * + ls -d core/* | entr make diff --git a/bin/plugbox-bundle.mjs b/bin/plugbox-bundle.mjs new file mode 100755 index 0000000..6b6ddec --- /dev/null +++ b/bin/plugbox-bundle.mjs @@ -0,0 +1,77 @@ +#!/usr/bin/env node + +import esbuild from "esbuild"; +import { readFile, unlink, writeFile } from "fs/promises"; +import path from "path"; + +import yargs from "yargs"; +import { hideBin } from "yargs/helpers"; + +async function compile(filePath, functionName, debug) { + let outFile = "out.js"; + + let inFile = filePath; + + if (functionName) { + // Generate a new file importing just this one function and exporting it + inFile = "in.js"; + await writeFile( + inFile, + `import {${functionName}} from "./${filePath}"; +export default ${functionName};` + ); + } + + // TODO: Figure out how to make source maps work correctly with eval() code + let js = await esbuild.build({ + entryPoints: [inFile], + bundle: true, + format: "iife", + globalName: "mod", + platform: "neutral", + sourcemap: false, //sourceMap ? "inline" : false, + minify: !debug, + outfile: outFile, + }); + + let jsCode = (await readFile(outFile)).toString(); + jsCode = jsCode.replace(/^var mod ?= ?/, ""); + await unlink(outFile); + if (inFile !== filePath) { + await unlink(inFile); + } + // Strip final ';' + return jsCode.substring(0, jsCode.length - 2); +} + +async function bundle(manifestPath, sourceMaps) { + const rootPath = path.dirname(manifestPath); + const manifest = JSON.parse((await readFile(manifestPath)).toString()); + + for (let [name, def] of Object.entries(manifest.functions)) { + let jsFunctionName = def.functionName, + filePath = path.join(rootPath, def.path); + if (filePath.indexOf(":") !== -1) { + [filePath, jsFunctionName] = filePath.split(":"); + } + + def.code = await compile(filePath, jsFunctionName, sourceMaps); + delete def.path; + } + return manifest; +} +async function run() { + let args = await yargs(hideBin(process.argv)) + .option("debug", { + type: "boolean", + }) + .parse(); + + let generatedManifest = await bundle(args._[0], !!args.debug); + await writeFile(args._[1], JSON.stringify(generatedManifest, null, 2)); +} + +run().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..796ee81 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,12 @@ +export default { + extensionsToTreatAsEsm: [".ts"], + preset: "ts-jest/presets/default-esm", // or other ESM presets + globals: { + "ts-jest": { + useESM: true, + }, + }, + moduleNameMapper: { + "^(\\.{1,2}/.*)\\.js$": "$1", + }, +}; diff --git a/package.json b/package.json new file mode 100644 index 0000000..4458708 --- /dev/null +++ b/package.json @@ -0,0 +1,94 @@ +{ + "name": "silverbullet", + "version": "0.0.1", + "license": "MIT", + "resolutions": { + "@lezer/common": "https://github.com/zefhemel/common.git#046c880d1fcab713cadad327a5b7d8bb5de6522c" + }, + "scripts": { + "watch": "parcel watch", + "build": "parcel build", + "clean": "rm -rf dist", + "server": "nodemon dist/server/server.js pages" + }, + "targets": { + "webapp": { + "source": [ + "webapp/index.html" + ], + "context": "browser" + }, + "server": { + "source": [ + "server/server.ts" + ], + "outputFormat": "commonjs", + "isLibrary": true, + "context": "node" + } + }, + "dependencies": { + "@codemirror/basic-setup": "^0.19.1", + "@codemirror/collab": "^0.19.0", + "@codemirror/commands": "^0.19.8", + "@codemirror/lang-markdown": "^0.19.6", + "@codemirror/state": "^0.19.7", + "@codemirror/view": "^0.19.42", + "@fortawesome/fontawesome-svg-core": "1.3.0", + "@fortawesome/free-solid-svg-icons": "6.0.0", + "@fortawesome/react-fontawesome": "0.1.17", + "@parcel/optimizer-data-url": "2.3.2", + "@parcel/service-worker": "^2.3.2", + "@parcel/transformer-inline-string": "2.3.2", + "@types/cors": "^2.8.12", + "@types/express": "^4.17.13", + "dexie": "^3.2.1", + "idb": "^7.0.0", + "jest": "^27.5.1", + "lodash": "^4.17.21", + "nodemon": "^2.0.15", + "parcel": "^2.3.2", + "socket.io-client": "^4.4.1", + "ts-jest": "^27.1.3", + "express": "^4.17.3", + "vm2": "^3.9.9", + "yargs": "^17.3.1", + "better-sqlite3": "^7.5.0", + "body-parser": "^1.19.2", + "browserify-zlib": "^0.2.0", + "react": "^17.0.2", + "react-dom": "^17.0.2", + "buffer": "^6.0.3", + "knex": "^1.0.4", + "cors": "^2.8.5", + "socket.io": "^4.4.1", + "socket.io-client": "^4.4.1" + }, + "devDependencies": { + "@parcel/packager-raw-url": "2.3.2", + "@parcel/service-worker": "^2.3.2", + "@parcel/transformer-inline-string": "2.3.2", + "@parcel/transformer-sass": "2.3.2", + "@parcel/transformer-webmanifest": "2.3.2", + "@parcel/validator-typescript": "^2.3.2", + "@types/events": "^3.0.0", + "@types/jest": "^27.4.1", + "@types/node": "^17.0.21", + "@types/react": "^17.0.39", + "@types/react-dom": "^17.0.11", + "@vscode/sqlite3": "^5.0.7", + "assert": "^2.0.0", + "events": "^3.3.0", + "parcel": "^2.3.2", + "prettier": "^2.5.1", + "querystring-es3": "^0.2.1", + "stream-browserify": "^3.0.0", + "stream-http": "^3.2.0", + "timers-browserify": "^2.0.12", + "tty-browserify": "^0.0.1", + "typescript": "^4.6.2", + "uglify-js": "^3.15.1", + "url": "^0.11.0", + "util": "^0.12.4" + } +} diff --git a/plugbox/iframe_sandbox.html b/plugbox/iframe_sandbox.html new file mode 100644 index 0000000..ca0b2fc --- /dev/null +++ b/plugbox/iframe_sandbox.html @@ -0,0 +1,8 @@ + + + + + diff --git a/plugbox/iframe_sandbox.ts b/plugbox/iframe_sandbox.ts new file mode 100644 index 0000000..ddaadaf --- /dev/null +++ b/plugbox/iframe_sandbox.ts @@ -0,0 +1,43 @@ +import { ControllerMessage, WorkerLike, WorkerMessage } from "./types"; +import { Sandbox, System } from "./runtime"; +import { safeRun } from "./util"; + +// @ts-ignore +import sandboxHtml from "bundle-text:./iframe_sandbox.html"; + +class IFrameWrapper implements WorkerLike { + private iframe: HTMLIFrameElement; + onMessage?: (message: any) => Promise; + + constructor() { + const iframe = document.createElement("iframe", {}); + this.iframe = iframe; + iframe.style.display = "none"; + // Let's lock this down significantly + iframe.setAttribute("sandbox", "allow-scripts"); + iframe.srcdoc = sandboxHtml; + window.addEventListener("message", (evt: any) => { + if (evt.source !== iframe.contentWindow) { + return; + } + let data = evt.data; + if (!data) return; + safeRun(async () => { + await this.onMessage!(data); + }); + }); + document.body.appendChild(iframe); + } + + postMessage(message: any): void { + this.iframe.contentWindow!.postMessage(message, "*"); + } + + terminate() { + return this.iframe.remove(); + } +} + +export function createSandbox(system: System) { + return new Sandbox(system, new IFrameWrapper()); +} diff --git a/plugbox/node_sandbox.ts b/plugbox/node_sandbox.ts new file mode 100644 index 0000000..129a169 --- /dev/null +++ b/plugbox/node_sandbox.ts @@ -0,0 +1,45 @@ +import { ControllerMessage, WorkerLike, WorkerMessage } from "./types"; +import { System, Sandbox } from "./runtime"; + +import { Worker } from "worker_threads"; +import * as fs from "fs"; +import { safeRun } from "./util"; + +// @ts-ignore +import workerCode from "bundle-text:./node_worker.ts" + +// ParcelJS will simply inline this into the bundle. +// const workerCode = fs.readFileSync(__dirname + "/node_worker.ts", "utf-8"); + +class NodeWorkerWrapper implements WorkerLike { + onMessage?: (message: any) => Promise; + private worker: Worker; + + constructor(worker: Worker) { + this.worker = worker; + worker.on("message", (message: any) => { + safeRun(async () => { + await this.onMessage!(message); + }); + }); + } + + postMessage(message: any): void { + this.worker.postMessage(message); + } + + terminate(): void { + this.worker.terminate(); + } +} + +export function createSandbox(system: System) { + return new Sandbox( + system, + new NodeWorkerWrapper( + new Worker(workerCode, { + eval: true, + }) + ) + ); +} diff --git a/plugbox/node_worker.ts b/plugbox/node_worker.ts new file mode 100644 index 0000000..f960751 --- /dev/null +++ b/plugbox/node_worker.ts @@ -0,0 +1,97 @@ +const { VM, VMScript } = require("vm2"); +const { parentPort } = require("worker_threads"); + +let loadedFunctions = new Map(); +let pendingRequests = new Map< + number, + { + resolve: (result: unknown) => void; + reject: (e: any) => void; + } + >(); + +let vm = new VM({ + sandbox: { + console: console, + self: { + syscall: (reqId : number, name : string, args: any[]) => { + return new Promise((resolve, reject) => { + pendingRequests.set(reqId, { resolve, reject }); + parentPort.postMessage({ + type: "syscall", + id: reqId, + name, + // TODO: Figure out why this is necessary (to avoide a CloneError) + args: JSON.parse(JSON.stringify(args)), + }); + }); + }, + }, + }, +}); + +function wrapScript(code : string) { + return `(${code})["default"]`; +} + +function safeRun(fn : any) { + fn().catch((e : any) => { + console.error(e); + }); +} + +parentPort.on("message", (data : any) => { + safeRun(async () => { + switch (data.type) { + case "load": + console.log("Booting", data.name); + loadedFunctions.set(data.name, new VMScript(wrapScript(data.code))); + parentPort.postMessage({ + type: "inited", + name: data.name, + }); + break; + case "invoke": + let fn = loadedFunctions.get(data.name); + if (!fn) { + throw new Error(`Function not loaded: ${data.name}`); + } + try { + let r = vm.run(fn); + let result = await Promise.resolve(r(...data.args)); + parentPort.postMessage({ + type: "result", + id: data.id, + result: result, + }); + } catch (e : any) { + console.log("ERROR", e); + parentPort.postMessage({ + type: "result", + id: data.id, + error: e.message, + }); + } + break; + case "syscall-response": + let syscallId = data.id; + const lookup = pendingRequests.get(syscallId); + if (!lookup) { + console.log( + "Current outstanding requests", + pendingRequests, + "looking up", + syscallId + ); + throw Error("Invalid request id"); + } + pendingRequests.delete(syscallId); + if (data.error) { + lookup.reject(new Error(data.error)); + } else { + lookup.resolve(data.result); + } + break; + } + }); +}); diff --git a/plugbox/runtime.test.ts b/plugbox/runtime.test.ts new file mode 100644 index 0000000..2b00d35 --- /dev/null +++ b/plugbox/runtime.test.ts @@ -0,0 +1,79 @@ +import { createSandbox } from "./node_sandbox"; +import { System } from "./runtime"; +import { test, expect } from "@jest/globals"; + +test("Run a Node sandbox", async () => { + let system = new System(); + system.registerSyscalls({ + addNumbers: (a, b) => { + return a + b; + }, + failingSyscall: () => { + throw new Error("#fail"); + }, + }); + let plug = await system.load( + "test", + { + functions: { + addTen: { + code: `(() => { + return { + default: (n) => { + return n + 10; + } + }; + })()`, + }, + addNumbersSyscall: { + code: `(() => { + return { + default: async (a, b) => { + return await self.syscall(1, "addNumbers", [a, b]); + } + }; + })()`, + }, + errorOut: { + code: `(() => { + return { + default: () => { + throw Error("BOOM"); + } + }; + })()`, + }, + errorOutSys: { + code: `(() => { + return { + default: async () => { + await self.syscall(2, "failingSyscall", []); + } + }; + })()`, + }, + }, + hooks: { + events: {}, + }, + }, + createSandbox(system) + ); + expect(await plug.invoke("addTen", [10])).toBe(20); + for (let i = 0; i < 100; i++) { + expect(await plug.invoke("addNumbersSyscall", [10, i])).toBe(10 + i); + } + try { + await plug.invoke("errorOut", []); + expect(true).toBe(false); + } catch (e: any) { + expect(e.message).toBe("BOOM"); + } + try { + await plug.invoke("errorOutSys", []); + expect(true).toBe(false); + } catch (e: any) { + expect(e.message).toBe("#fail"); + } + await system.stop(); +}); diff --git a/plugbox/runtime.ts b/plugbox/runtime.ts new file mode 100644 index 0000000..bf01e9c --- /dev/null +++ b/plugbox/runtime.ts @@ -0,0 +1,193 @@ +import { + ControllerMessage, + Manifest, + WorkerLike, + WorkerMessage, +} from "./types"; + +interface SysCallMapping { + [key: string]: (...args: any) => Promise | any; +} + +export class Sandbox { + protected worker: WorkerLike; + protected reqId = 0; + protected outstandingInits = new Map void>(); + protected outstandingInvocations = new Map< + number, + { resolve: (result: any) => void; reject: (e: any) => void } + >(); + protected loadedFunctions = new Set(); + protected system: System; + + constructor(system: System, worker: WorkerLike) { + worker.onMessage = this.onMessage.bind(this); + this.worker = worker; + this.system = system; + } + + isLoaded(name: string) { + return this.loadedFunctions.has(name); + } + + async load(name: string, code: string): Promise { + this.worker.postMessage({ + type: "load", + name: name, + code: code, + } as WorkerMessage); + return new Promise((resolve) => { + this.loadedFunctions.add(name); + this.outstandingInits.set(name, resolve); + }); + } + + async onMessage(data: ControllerMessage) { + switch (data.type) { + case "inited": + let initCb = this.outstandingInits.get(data.name!); + initCb && initCb(); + this.outstandingInits.delete(data.name!); + break; + case "syscall": + try { + let result = await this.system.syscall(data.name!, data.args!); + + this.worker.postMessage({ + type: "syscall-response", + id: data.id, + result: result, + } as WorkerMessage); + } catch (e: any) { + this.worker.postMessage({ + type: "syscall-response", + id: data.id, + error: e.message, + } as WorkerMessage); + } + break; + case "result": + let resultCbs = this.outstandingInvocations.get(data.id!); + this.outstandingInvocations.delete(data.id!); + if (data.error) { + resultCbs && resultCbs.reject(new Error(data.error)); + } else { + resultCbs && resultCbs.resolve(data.result); + } + break; + default: + console.error("Unknown message type", data); + } + } + + async invoke(name: string, args: any[]): Promise { + this.reqId++; + this.worker.postMessage({ + type: "invoke", + id: this.reqId, + name, + args, + }); + return new Promise((resolve, reject) => { + this.outstandingInvocations.set(this.reqId, { resolve, reject }); + }); + } + + stop() { + this.worker.terminate(); + } +} + +export class Plug { + system: System; + sandbox: Sandbox; + public manifest?: Manifest; + + constructor(system: System, name: string, sandbox: Sandbox) { + this.system = system; + this.sandbox = sandbox; + } + + async load(manifest: Manifest) { + this.manifest = manifest; + await this.dispatchEvent("load"); + } + + async invoke(name: string, args: Array): Promise { + if (!this.sandbox.isLoaded(name)) { + const funDef = this.manifest!.functions[name]; + if (!funDef) { + throw new Error(`Function ${name} not found in manifest`); + } + await this.sandbox.load(name, this.manifest!.functions[name].code!); + } + return await this.sandbox.invoke(name, args); + } + + async dispatchEvent(name: string, data?: any): Promise { + let functionsToSpawn = this.manifest!.hooks.events[name]; + if (functionsToSpawn) { + return await Promise.all( + functionsToSpawn.map( + async (functionToSpawn: string) => + await this.invoke(functionToSpawn, [data]) + ) + ); + } else { + return []; + } + } + + async stop() { + this.sandbox.stop(); + } +} + +export class System { + protected plugs = new Map>(); + registeredSyscalls: SysCallMapping = {}; + + registerSyscalls(...registrationObjects: SysCallMapping[]) { + for (const registrationObject of registrationObjects) { + for (let p in registrationObject) { + this.registeredSyscalls[p] = registrationObject[p]; + } + } + } + + async syscall(name: string, args: Array): Promise { + const callback = this.registeredSyscalls[name]; + if (!name) { + throw Error(`Unregistered syscall ${name}`); + } + if (!callback) { + throw Error(`Registered but not implemented syscall ${name}`); + } + return Promise.resolve(callback(...args)); + } + + async load( + name: string, + manifest: Manifest, + sandbox: Sandbox + ): Promise> { + const plug = new Plug(this, name, sandbox); + await plug.load(manifest); + this.plugs.set(name, plug); + return plug; + } + + async dispatchEvent(name: string, data?: any): Promise { + let promises = []; + for (let plug of this.plugs.values()) { + promises.push(plug.dispatchEvent(name, data)); + } + return await Promise.all(promises); + } + + async stop(): Promise { + return Promise.all( + Array.from(this.plugs.values()).map((plug) => plug.stop()) + ); + } +} diff --git a/plugbox/sandbox_worker.ts b/plugbox/sandbox_worker.ts new file mode 100644 index 0000000..2415726 --- /dev/null +++ b/plugbox/sandbox_worker.ts @@ -0,0 +1,111 @@ +import { ControllerMessage, WorkerMessage, WorkerMessageType } from "./types"; +import { safeRun } from "./util"; + +let loadedFunctions = new Map(); +let pendingRequests = new Map< + number, + { + resolve: (result: unknown) => void; + reject: (e: any) => void; + } +>(); + +declare global { + function syscall(id: number, name: string, args: any[]): Promise; +} + +let postMessage = self.postMessage.bind(self); + +if (window.parent !== window) { + console.log("running in an iframe"); + postMessage = window.parent.postMessage.bind(window.parent); + // postMessage({ type: "test" }, "*"); +} + +self.syscall = async (id: number, name: string, args: any[]) => { + return await new Promise((resolve, reject) => { + pendingRequests.set(id, { resolve, reject }); + postMessage( + { + type: "syscall", + id, + name, + args, + }, + "*" + ); + }); +}; + +function wrapScript(code: string): string { + return `const fn = ${code}; +return fn["default"].apply(null, arguments);`; +} + +self.addEventListener("message", (event: { data: WorkerMessage }) => { + // console.log("Got a message", event.data); + safeRun(async () => { + let messageEvent = event; + let data = messageEvent.data; + switch (data.type) { + case "load": + console.log("Booting", data.name); + loadedFunctions.set(data.name!, new Function(wrapScript(data.code!))); + postMessage( + { + type: "inited", + name: data.name, + } as ControllerMessage, + "*" + ); + break; + case "invoke": + let fn = loadedFunctions.get(data.name!); + if (!fn) { + throw new Error(`Function not loaded: ${data.name}`); + } + try { + let result = await Promise.resolve(fn(...(data.args || []))); + postMessage( + { + type: "result", + id: data.id, + result: result, + } as ControllerMessage, + "*" + ); + } catch (e: any) { + postMessage( + { + type: "result", + id: data.id, + error: e.message, + } as ControllerMessage, + "*" + ); + throw e; + } + + break; + case "syscall-response": + let syscallId = data.id!; + const lookup = pendingRequests.get(syscallId); + if (!lookup) { + console.log( + "Current outstanding requests", + pendingRequests, + "looking up", + syscallId + ); + throw Error("Invalid request id"); + } + pendingRequests.delete(syscallId); + if (data.error) { + lookup.reject(new Error(data.error)); + } else { + lookup.resolve(data.result); + } + break; + } + }); +}); diff --git a/plugbox/types.ts b/plugbox/types.ts new file mode 100644 index 0000000..f50b3ec --- /dev/null +++ b/plugbox/types.ts @@ -0,0 +1,44 @@ +export type EventHook = { + events: { [key: string]: string[] }; +}; + +export type WorkerMessageType = "load" | "invoke" | "syscall-response"; + +export type WorkerMessage = { + type: WorkerMessageType; + id?: number; + name?: string; + code?: string; + args?: any[]; + result?: any; + error?: any; +}; + +export type ControllerMessageType = "inited" | "result" | "syscall"; + +export type ControllerMessage = { + type: ControllerMessageType; + id?: number; + name?: string; + args?: any[]; + error?: string; + result?: any; +}; + +export interface Manifest { + hooks: HookT & EventHook; + functions: { + [key: string]: FunctionDef; + }; +} + +export interface FunctionDef { + path?: string; + code?: string; +} + +export interface WorkerLike { + onMessage?: (message: any) => Promise; + postMessage(message: any): void; + terminate(): void; +} diff --git a/plugbox/util.ts b/plugbox/util.ts new file mode 100644 index 0000000..345961a --- /dev/null +++ b/plugbox/util.ts @@ -0,0 +1,6 @@ +export function safeRun(fn: () => Promise) { + fn().catch((e) => { + // console.error(e); + throw e; + }); +} diff --git a/plugbox/webworker_sandbox.ts b/plugbox/webworker_sandbox.ts new file mode 100644 index 0000000..72ae57a --- /dev/null +++ b/plugbox/webworker_sandbox.ts @@ -0,0 +1,34 @@ +import { ControllerMessage, WorkerLike, WorkerMessage } from "./types"; +import { Sandbox, System } from "./runtime"; +import { safeRun } from "./util"; + +class WebWorkerWrapper implements WorkerLike { + private worker: Worker; + onMessage?: (message: any) => Promise; + + constructor(worker: Worker) { + this.worker = worker; + this.worker.addEventListener("message", (evt: any) => { + let data = evt.data; + if (!data) return; + safeRun(async () => { + await this.onMessage!(data); + }); + }); + } + postMessage(message: any): void { + this.worker.postMessage(message); + } + + terminate() { + return this.worker.terminate(); + } +} + +export function createSandbox(system: System) { + // ParcelJS will build this file into a worker. + let worker = new Worker(new URL("sandbox_worker.ts", import.meta.url), { + type: "module", + }); + return new Sandbox(system, new WebWorkerWrapper(worker)); +} diff --git a/server/api.test.ts b/server/api.test.ts new file mode 100644 index 0000000..39dbe29 --- /dev/null +++ b/server/api.test.ts @@ -0,0 +1,96 @@ +import { test, expect, beforeAll, afterAll, describe } from "@jest/globals"; + +import { createServer } from "http"; +import { io as Client } from "socket.io-client"; +import { Server } from "socket.io"; +import { SocketServer } from "./api_server"; +import * as path from "path"; +import * as fs from "fs"; + +describe("Server test", () => { + let io: Server, + socketServer: SocketServer, + clientSocket: any, + reqId = 0; + const tmpDir = path.join(__dirname, "test"); + + function wsCall(eventName: string, ...args: any[]): Promise { + return new Promise((resolve, reject) => { + reqId++; + clientSocket.once(`${eventName}Resp${reqId}`, (err: any, result: any) => { + if (err) { + reject(err); + } else { + resolve(result); + } + }); + clientSocket.emit(eventName, reqId, ...args); + }); + } + + beforeAll((done) => { + const httpServer = createServer(); + io = new Server(httpServer); + fs.mkdirSync(tmpDir, { recursive: true }); + fs.writeFileSync(`${tmpDir}/test.md`, "This is a simple test"); + httpServer.listen(async () => { + // @ts-ignore + const port = httpServer.address().port; + // @ts-ignore + clientSocket = new Client(`http://localhost:${port}`); + socketServer = new SocketServer(tmpDir, io); + clientSocket.on("connect", done); + await socketServer.init(); + }); + }); + + afterAll(() => { + io.close(); + clientSocket.close(); + socketServer.close(); + fs.rmSync(tmpDir, { recursive: true, force: true }); + }); + + test("List pages", async () => { + let pages = await wsCall("page.listPages"); + expect(pages.length).toBe(1); + await wsCall("page.writePage", "test2.md", "This is another test"); + let pages2 = await wsCall("page.listPages"); + expect(pages2.length).toBe(2); + await wsCall("page.deletePage", "test2.md"); + let pages3 = await wsCall("page.listPages"); + expect(pages3.length).toBe(1); + }); + + test("Index operations", async () => { + await wsCall("index.clearPageIndexForPage", "test"); + await wsCall("index.set", "test", "testkey", "value"); + expect(await wsCall("index.get", "test", "testkey")).toBe("value"); + await wsCall("index.delete", "test", "testkey"); + expect(await wsCall("index.get", "test", "testkey")).toBe(null); + await wsCall("index.set", "test", "unrelated", 10); + await wsCall("index.set", "test", "unrelated", 12); + await wsCall("index.set", "test2", "complicated", { + name: "Bla", + age: 123123, + }); + await wsCall("index.set", "test", "complicated", { name: "Bla", age: 100 }); + await wsCall("index.set", "test", "complicated2", { + name: "Bla", + age: 101, + }); + expect(await wsCall("index.get", "test", "complicated")).toStrictEqual({ + name: "Bla", + age: 100, + }); + let result = await wsCall("index.scanPrefixForPage", "test", "compli"); + expect(result.length).toBe(2); + let result2 = await wsCall("index.scanPrefixGlobal", "compli"); + expect(result2.length).toBe(3); + await wsCall("index.deletePrefixForPage", "test", "compli"); + let result3 = await wsCall("index.scanPrefixForPage", "test", "compli"); + expect(result3.length).toBe(0); + let result4 = await wsCall("index.scanPrefixGlobal", "compli"); + expect(result4.length).toBe(1); + }); +}); diff --git a/server/api_server.ts b/server/api_server.ts new file mode 100644 index 0000000..968413c --- /dev/null +++ b/server/api_server.ts @@ -0,0 +1,121 @@ +import { Server, Socket } from "socket.io"; +import { Page } from "./types"; +import * as path from "path"; +import { IndexApi } from "./index_api"; +import { PageApi } from "./page_api"; +import { System } from "../plugbox/runtime"; +import { createSandbox } from "../plugbox/node_sandbox"; +import { NuggetHook } from "../webapp/types"; +import corePlug from "../webapp/generated/core.plug.json"; +import pageIndexSyscalls from "./syscalls/page_index"; + +export class ClientConnection { + openPages = new Set(); + constructor(readonly sock: Socket) {} +} + +export interface ApiProvider { + init(): Promise; + api(): Object; +} + +export class SocketServer { + private openPages = new Map(); + private connectedSockets = new Set(); + private apis = new Map(); + readonly rootPath: string; + private serverSocket: Server; + system: System; + + constructor(rootPath: string, serverSocket: Server) { + this.rootPath = path.resolve(rootPath); + this.serverSocket = serverSocket; + this.system = new System(); + } + + async registerApi(name: string, apiProvider: ApiProvider) { + await apiProvider.init(); + this.apis.set(name, apiProvider); + } + + public async init() { + const indexApi = new IndexApi(this.rootPath); + await this.registerApi("index", indexApi); + this.system.registerSyscalls(pageIndexSyscalls(indexApi.db)); + await this.registerApi( + "page", + new PageApi( + this.rootPath, + this.connectedSockets, + this.openPages, + this.system + ) + ); + + let plug = await this.system.load( + "core", + corePlug, + createSandbox(this.system) + ); + + this.serverSocket.on("connection", (socket) => { + const clientConn = new ClientConnection(socket); + + console.log("Connected", socket.id); + this.connectedSockets.add(socket); + + socket.on("disconnect", () => { + console.log("Disconnected", socket.id); + clientConn.openPages.forEach(disconnectPageSocket); + this.connectedSockets.delete(socket); + }); + + socket.on("page.closePage", (pageName: string) => { + console.log("Client closed page", pageName); + disconnectPageSocket(pageName); + clientConn.openPages.delete(pageName); + }); + + const onCall = ( + eventName: string, + cb: (...args: any[]) => Promise + ) => { + socket.on(eventName, (reqId: number, ...args) => { + cb(...args) + .then((result) => { + socket.emit(`${eventName}Resp${reqId}`, null, result); + }) + .catch((err) => { + socket.emit(`${eventName}Resp${reqId}`, err.message); + }); + }); + }; + + const disconnectPageSocket = (pageName: string) => { + let page = this.openPages.get(pageName); + if (page) { + for (let client of page.clientStates) { + if (client.socket === socket) { + (this.apis.get("page")! as PageApi).disconnectClient( + client, + page + ); + } + } + } + }; + for (let [apiName, apiProvider] of this.apis) { + Object.entries(apiProvider.api()).forEach(([eventName, cb]) => { + onCall(`${apiName}.${eventName}`, (...args: any[]): any => { + // @ts-ignore + return cb(clientConn, ...args); + }); + }); + } + }); + } + + close() { + (this.apis.get("index")! as IndexApi).db.destroy(); + } +} diff --git a/server/disk_storage.ts b/server/disk_storage.ts new file mode 100644 index 0000000..6014ecc --- /dev/null +++ b/server/disk_storage.ts @@ -0,0 +1,91 @@ +import { readdir, readFile, stat, unlink, writeFile } from "fs/promises"; +import * as path from "path"; +import { PageMeta } from "./types"; + +export class DiskStorage { + rootPath: string; + + constructor(rootPath: string) { + this.rootPath = rootPath; + } + + async listPages(): Promise { + let fileNames: PageMeta[] = []; + + const walkPath = async (dir: string) => { + let files = await readdir(dir); + for (let file of files) { + const fullPath = path.join(dir, file); + let s = await stat(fullPath); + if (s.isDirectory()) { + await walkPath(fullPath); + } else { + if (path.extname(file) === ".md") { + fileNames.push({ + name: fullPath.substring( + this.rootPath.length + 1, + fullPath.length - 3 + ), + lastModified: s.mtime.getTime(), + }); + } + } + } + }; + await walkPath(this.rootPath); + return fileNames; + } + + async readPage(pageName: string): Promise<{ text: string; meta: PageMeta }> { + const localPath = path.join(this.rootPath, pageName + ".md"); + try { + const s = await stat(localPath); + return { + text: await readFile(localPath, "utf8"), + meta: { + name: pageName, + lastModified: s.mtime.getTime(), + }, + }; + } catch (e) { + // console.error("Error while writing page", pageName, e); + throw Error(`Could not read page ${pageName}`); + } + } + + async writePage(pageName: string, text: string): Promise { + let localPath = path.join(this.rootPath, pageName + ".md"); + try { + await writeFile(localPath, text); + + // console.log(`Wrote to ${localPath}`); + const s = await stat(localPath); + return { + name: pageName, + lastModified: s.mtime.getTime(), + }; + } catch (e) { + console.error("Error while writing page", pageName, e); + throw Error(`Could not write ${pageName}`); + } + } + + async getPageMeta(pageName: string): Promise { + let localPath = path.join(this.rootPath, pageName + ".md"); + try { + const s = await stat(localPath); + return { + name: pageName, + lastModified: s.mtime.getTime(), + }; + } catch (e) { + console.error("Error while getting page meta", pageName, e); + throw Error(`Could not get meta for ${pageName}`); + } + } + + async deletePage(pageName: string) { + let localPath = path.join(this.rootPath, pageName + ".md"); + await unlink(localPath); + } +} diff --git a/server/index_api.ts b/server/index_api.ts new file mode 100644 index 0000000..d54a819 --- /dev/null +++ b/server/index_api.ts @@ -0,0 +1,90 @@ +import { ApiProvider, ClientConnection } from "./api_server"; +import knex, { Knex } from "knex"; +import path from "path"; +import pageIndexSyscalls from "./syscalls/page_index"; + +type IndexItem = { + page: string; + key: string; + value: any; +}; + +export class IndexApi implements ApiProvider { + db: Knex; + + constructor(rootPath: string) { + this.db = knex({ + client: "better-sqlite3", + connection: { + filename: path.join(rootPath, "data.db"), + }, + useNullAsDefault: true, + }); + } + + async init() { + if (!(await this.db.schema.hasTable("page_index"))) { + await this.db.schema.createTable("page_index", (table) => { + table.string("page"); + table.string("key"); + table.text("value"); + table.primary(["page", "key"]); + }); + console.log("Created table page_index"); + } + } + + api() { + const syscalls = pageIndexSyscalls(this.db); + return { + clearPageIndexForPage: async ( + clientConn: ClientConnection, + page: string + ) => { + return syscalls["indexer.clearPageIndexForPage"](page); + }, + set: async ( + clientConn: ClientConnection, + page: string, + key: string, + value: any + ) => { + return syscalls["indexer.set"](page, key, value); + }, + get: async (clientConn: ClientConnection, page: string, key: string) => { + return syscalls["indexer.get"](page, key); + }, + delete: async ( + clientConn: ClientConnection, + page: string, + key: string + ) => { + return syscalls["indexer.delete"](page, key); + }, + scanPrefixForPage: async ( + clientConn: ClientConnection, + page: string, + prefix: string + ) => { + return syscalls["indexer.scanPrefixForPage"](page, prefix); + }, + scanPrefixGlobal: async ( + clientConn: ClientConnection, + prefix: string + ) => { + return syscalls["indexer.scanPrefixGlobal"](prefix); + }, + deletePrefixForPage: async ( + clientConn: ClientConnection, + page: string, + prefix: string + ) => { + return syscalls["indexer.deletePrefixForPage"](page, prefix); + }, + + clearPageIndex: async (clientConn: ClientConnection) => { + return syscalls["indexer.clearPageIndex"](); + }, + }; + } +} diff --git a/server/page_api.ts b/server/page_api.ts new file mode 100644 index 0000000..02d3d5e --- /dev/null +++ b/server/page_api.ts @@ -0,0 +1,306 @@ +import { ClientPageState, Page, PageMeta } from "./types"; +import { ChangeSet } from "@codemirror/state"; +import { Update } from "@codemirror/collab"; +import { ApiProvider, ClientConnection } from "./api_server"; +import { Socket } from "socket.io"; +import { DiskStorage } from "./disk_storage"; +import { safeRun } from "./util"; +import fs from "fs"; +import path from "path"; +import { stat } from "fs/promises"; +import { Cursor, cursorEffect } from "../webapp/cursorEffect"; +import { System } from "../plugbox/runtime"; +import { NuggetHook } from "../webapp/types"; + +export class PageApi implements ApiProvider { + openPages: Map; + pageStore: DiskStorage; + rootPath: string; + connectedSockets: Set; + private system: System; + + constructor( + rootPath: string, + connectedSockets: Set, + openPages: Map, + system: System + ) { + this.pageStore = new DiskStorage(rootPath); + this.rootPath = rootPath; + this.openPages = openPages; + this.connectedSockets = connectedSockets; + this.system = system; + } + + async init(): Promise { + this.fileWatcher(); + } + + broadcastCursors(page: Page) { + page.clientStates.forEach((client) => { + client.socket.emit( + "cursorSnapshot", + page.name, + Object.fromEntries(page.cursors.entries()) + ); + }); + } + + flushPageToDisk(name: string, page: Page) { + safeRun(async () => { + let meta = await this.pageStore.writePage(name, page.text.sliceString(0)); + console.log(`Wrote page ${name} to disk`); + page.meta = meta; + }); + } + + disconnectClient(client: ClientPageState, page: Page) { + console.log("Disconnecting client"); + page.clientStates.delete(client); + if (page.clientStates.size === 0) { + console.log("No more clients for", page.name, "flushing"); + this.flushPageToDisk(page.name, page); + this.openPages.delete(page.name); + } else { + page.cursors.delete(client.socket.id); + this.broadcastCursors(page); + } + } + + fileWatcher() { + fs.watch( + this.rootPath, + { + recursive: true, + persistent: false, + }, + (eventType, filename) => { + safeRun(async () => { + if (!filename.endsWith(".md")) { + return; + } + let localPath = path.join(this.rootPath, filename); + let pageName = filename.substring(0, filename.length - 3); + // console.log("Edit in", pageName, eventType); + let modifiedTime = 0; + try { + let s = await stat(localPath); + modifiedTime = s.mtime.getTime(); + } catch (e) { + // File was deleted + console.log("Deleted", pageName); + for (let socket of this.connectedSockets) { + socket.emit("pageDeleted", pageName); + } + return; + } + const openPage = this.openPages.get(pageName); + if (openPage) { + if (openPage.meta.lastModified < modifiedTime) { + console.log("Page changed on disk outside of editor, reloading"); + this.openPages.delete(pageName); + const meta = { + name: pageName, + lastModified: modifiedTime, + } as PageMeta; + for (let client of openPage.clientStates) { + client.socket.emit("pageChanged", meta); + } + } + } + if (eventType === "rename") { + // This most likely means a new file was created, let's push new file listings to all connected sockets + console.log( + "New file created, broadcasting to all connected sockets", + pageName + ); + for (let socket of this.connectedSockets) { + socket.emit("pageCreated", { + name: pageName, + lastModified: modifiedTime, + } as PageMeta); + } + } + }); + } + ); + } + + api() { + return { + openPage: async (clientConn: ClientConnection, pageName: string) => { + let page = this.openPages.get(pageName); + if (!page) { + try { + let { text, meta } = await this.pageStore.readPage(pageName); + page = new Page(pageName, text, meta); + } catch (e) { + console.log("Creating new page", pageName); + page = new Page(pageName, "", { name: pageName, lastModified: 0 }); + } + this.openPages.set(pageName, page); + } + page.clientStates.add( + new ClientPageState(clientConn.sock, page.version) + ); + clientConn.openPages.add(pageName); + console.log("Opened page", pageName); + this.broadcastCursors(page); + return page.toJSON(); + }, + pushUpdates: async ( + clientConn: ClientConnection, + pageName: string, + version: number, + updates: any[] + ): Promise => { + let page = this.openPages.get(pageName); + + if (!page) { + console.error( + "Received updates for not open page", + pageName, + this.openPages.keys() + ); + return false; + } + if (version !== page.version) { + console.error("Invalid version", version, page.version); + return false; + } else { + console.log("Applying", updates.length, "updates to", pageName); + let transformedUpdates = []; + let textChanged = false; + for (let update of updates) { + let changes = ChangeSet.fromJSON(update.changes); + let transformedUpdate = { + changes, + clientID: update.clientID, + effects: update.cursors?.map((c: Cursor) => { + page!.cursors.set(c.userId, c); + return cursorEffect.of(c); + }), + }; + page.updates.push(transformedUpdate); + transformedUpdates.push(transformedUpdate); + let oldText = page.text; + page.text = changes.apply(page.text); + if (oldText !== page.text) { + textChanged = true; + } + } + console.log( + "New version", + page.version, + "Updates buffered:", + page.updates.length + ); + + if (textChanged) { + // Throttle + if (!page.saveTimer) { + page.saveTimer = setTimeout(() => { + if (page) { + console.log("Indexing", pageName); + + this.system.dispatchEvent("page:index", { + name: pageName, + text: page.text.sliceString(0), + }); + this.flushPageToDisk(pageName, page); + page.saveTimer = undefined; + } + }, 1000); + } + } + while (page.pending.length) { + page.pending.pop()!(transformedUpdates); + } + return true; + } + }, + + pullUpdates: async ( + clientConn: ClientConnection, + pageName: string, + version: number + ): Promise => { + let page = this.openPages.get(pageName); + // console.log("Pulling updates for", pageName); + if (!page) { + console.error("Fetching updates for not open page"); + return []; + } + // TODO: Optimize this + let oldestVersion = Infinity; + page.clientStates.forEach((client) => { + oldestVersion = Math.min(client.version, oldestVersion); + if (client.socket === clientConn.sock) { + client.version = version; + } + }); + page.flushUpdates(oldestVersion); + if (version < page.version) { + return page.updatesSince(version); + } else { + return new Promise((resolve) => { + page!.pending.push(resolve); + }); + } + }, + + readPage: async ( + clientConn: ClientConnection, + pageName: string + ): Promise<{ text: string; meta: PageMeta }> => { + let page = this.openPages.get(pageName); + if (page) { + console.log("Serving page from memory", pageName); + return { + text: page.text.sliceString(0), + meta: page.meta, + }; + } else { + return this.pageStore.readPage(pageName); + } + }, + + writePage: async ( + clientConn: ClientConnection, + pageName: string, + text: string + ) => { + let page = this.openPages.get(pageName); + if (page) { + for (let client of page.clientStates) { + client.socket.emit("reloadPage", pageName); + } + this.openPages.delete(pageName); + } + return this.pageStore.writePage(pageName, text); + }, + + deletePage: async (clientConn: ClientConnection, pageName: string) => { + this.openPages.delete(pageName); + clientConn.openPages.delete(pageName); + // Cascading of this to all connected clients will be handled by file watcher + return this.pageStore.deletePage(pageName); + }, + + listPages: async (clientConn: ClientConnection): Promise => { + return this.pageStore.listPages(); + }, + + getPageMeta: async ( + clientConn: ClientConnection, + pageName: string + ): Promise => { + let page = this.openPages.get(pageName); + if (page) { + return page.meta; + } + return this.pageStore.getPageMeta(pageName); + }, + }; + } +} diff --git a/server/server.ts b/server/server.ts new file mode 100644 index 0000000..63903d7 --- /dev/null +++ b/server/server.ts @@ -0,0 +1,46 @@ +import express from "express"; +import { readFile } from "fs/promises"; +import http from "http"; +import { Server } from "socket.io"; +import { SocketServer } from "./api_server"; +import yargs from "yargs"; +import { hideBin } from "yargs/helpers"; + +let args = yargs(hideBin(process.argv)) + .option("debug", { + type: "boolean", + }) + .option("port", { + type: "number", + default: 3000, + }) + .parse(); + +const app = express(); +const server = http.createServer(app); +const io = new Server(server, { + cors: { + methods: "GET,HEAD,PUT,OPTIONS,POST,DELETE", + preflightContinue: true, + }, +}); + +const port = args.port; +const distDir = `${__dirname}/../webapp`; + +app.use("/", express.static(distDir)); +let socketServer = new SocketServer(args._[0] as string, io); +socketServer.init(); + +// Fallback, serve index.html +let cachedIndex: string | undefined = undefined; +app.get("/*", async (req, res) => { + if (!cachedIndex) { + cachedIndex = await readFile(`${distDir}/index.html`, "utf8"); + } + res.status(200).header("Content-Type", "text/html").send(cachedIndex); +}); + +server.listen(port, () => { + console.log(`Server listening on port ${port}`); +}); diff --git a/server/syscalls/page_index.ts b/server/syscalls/page_index.ts new file mode 100644 index 0000000..3056fb4 --- /dev/null +++ b/server/syscalls/page_index.ts @@ -0,0 +1,83 @@ +import { Knex } from "knex"; + +type IndexItem = { + page: string; + key: string; + value: any; +}; + +export type KV = { + key: string; + value: any; +}; + +export default function (db: Knex) { + const apiObj = { + "indexer.clearPageIndexForPage": async (page: string) => { + await db("page_index").where({ page }).del(); + }, + "indexer.set": async (page: string, key: string, value: any) => { + let changed = await db("page_index") + .where({ page, key }) + .update("value", JSON.stringify(value)); + if (changed === 0) { + await db("page_index").insert({ + page, + key, + value: JSON.stringify(value), + }); + } + }, + "indexer.batchSet": async (page: string, kvs: KV[]) => { + for (let { key, value } of kvs) { + await apiObj["indexer.set"](page, key, value); + } + }, + "indexer.get": async (page: string, key: string) => { + let result = await db("page_index") + .where({ page, key }) + .select("value"); + if (result.length) { + return JSON.parse(result[0].value); + } else { + return null; + } + }, + "indexer.delete": async (page: string, key: string) => { + await db("page_index").where({ page, key }).del(); + }, + "indexer.scanPrefixForPage": async (page: string, prefix: string) => { + return ( + await db("page_index") + .where({ page }) + .andWhereLike("key", `${prefix}%`) + .select("page", "key", "value") + ).map(({ page, key, value }) => ({ + page, + key, + value: JSON.parse(value), + })); + }, + "indexer.scanPrefixGlobal": async (prefix: string) => { + return ( + await db("page_index") + .andWhereLike("key", `${prefix}%`) + .select("page", "key", "value") + ).map(({ page, key, value }) => ({ + page, + key, + value: JSON.parse(value), + })); + }, + "indexer.deletePrefixForPage": async (page: string, prefix: string) => { + return db("page_index") + .where({ page }) + .andWhereLike("key", `${prefix}%`) + .del(); + }, + "indexer.clearPageIndex": async () => { + return db("page_index").del(); + }, + }; + return apiObj; +} diff --git a/server/types.ts b/server/types.ts new file mode 100644 index 0000000..019fad9 --- /dev/null +++ b/server/types.ts @@ -0,0 +1,62 @@ +import { Update } from "@codemirror/collab"; +import { Text } from "@codemirror/state"; +import { Socket } from "socket.io"; +import { Cursor } from "../webapp/cursorEffect"; +export class ClientPageState { + constructor(public socket: Socket, public version: number) {} +} + +export type PageMeta = { + name: string; + lastModified: number; + version?: number; +}; + +export class Page { + versionOffset = 0; + updates: Update[] = []; + cursors = new Map(); + clientStates = new Set(); + + pending: ((value: any) => void)[] = []; + + text: Text; + meta: PageMeta; + + saveTimer: NodeJS.Timeout | undefined; + name: string; + + constructor(name: string, text: string, meta: PageMeta) { + this.name = name; + this.text = Text.of(text.split("\n")); + this.meta = meta; + } + + updatesSince(version: number): Update[] { + return this.updates.slice(version - this.versionOffset); + } + + get version(): number { + return this.updates.length + this.versionOffset; + } + + flushUpdates(version: number) { + if (this.versionOffset > version) { + throw Error("This should never happen"); + } + if (this.versionOffset === version) { + return; + } + this.updates = this.updates.slice(version - this.versionOffset); + this.versionOffset = version; + // console.log("Flushed updates, now got", this.updates.length, "updates"); + } + + toJSON() { + return { + text: this.text, + version: this.version, + cursors: Object.fromEntries(this.cursors.entries()), + }; + } +} diff --git a/server/util.ts b/server/util.ts new file mode 100644 index 0000000..55b0a08 --- /dev/null +++ b/server/util.ts @@ -0,0 +1,5 @@ +export function safeRun(fn: () => Promise) { + fn().catch((e) => { + console.error(e); + }); +} diff --git a/webapp/app_event.ts b/webapp/app_event.ts new file mode 100644 index 0000000..2ca8c13 --- /dev/null +++ b/webapp/app_event.ts @@ -0,0 +1,22 @@ +export type AppEvent = + | "app:ready" + | "page:save" + | "page:click" + | "page:index" + | "editor:complete"; + +export type ClickEvent = { + pos: number; + metaKey: boolean; + ctrlKey: boolean; + altKey: boolean; +}; + +export type IndexEvent = { + name: string; + text: string; +}; + +export interface AppEventDispatcher { + dispatchAppEvent(name: AppEvent, data?: any): Promise; +} diff --git a/webapp/boot.ts b/webapp/boot.ts new file mode 100644 index 0000000..02e02c9 --- /dev/null +++ b/webapp/boot.ts @@ -0,0 +1,21 @@ +import { Editor } from "./editor"; +import { Space } from "./space"; +import { safeRun } from "./util"; +import { io } from "socket.io-client"; + +let socket = io(`http://${location.hostname}:3000`); + +let editor = new Editor(new Space(socket), document.getElementById("root")!); + +safeRun(async () => { + await editor.init(); +}); + +// @ts-ignore +window.editor = editor; + +navigator.serviceWorker + .register(new URL("service_worker.ts", import.meta.url), { type: "module" }) + .then((r) => { + console.log("Service worker registered", r); + }); diff --git a/webapp/collab.ts b/webapp/collab.ts new file mode 100644 index 0000000..0962bb4 --- /dev/null +++ b/webapp/collab.ts @@ -0,0 +1,252 @@ +import { + collab, + getSyncedVersion, + receiveUpdates, + sendableUpdates, + Update, +} from "@codemirror/collab"; +import { RangeSetBuilder } from "@codemirror/rangeset"; +import { Text, Transaction } from "@codemirror/state"; +import { + Decoration, + DecorationSet, + EditorView, + ViewPlugin, + ViewUpdate, + WidgetType, +} from "@codemirror/view"; +import { throttle } from "./util"; +import { Cursor, cursorEffect } from "./cursorEffect"; +import { EventEmitter } from "./event"; + +const throttleInterval = 250; + +export class CollabDocument { + text: Text; + version: number; + cursors: Map; + + constructor(text: Text, version: number, cursors: Map) { + this.text = text; + this.version = version; + this.cursors = cursors; + } +} + +class CursorWidget extends WidgetType { + userId: string; + color: string; + + constructor(userId: string, color: string) { + super(); + this.userId = userId; + this.color = color; + } + + eq(other: CursorWidget) { + return other.userId == this.userId; + } + + toDOM() { + let el = document.createElement("span"); + el.className = "other-cursor"; + el.style.backgroundColor = this.color; + // let nameSpanContainer = document.createElement("span"); + // nameSpanContainer.className = "cursor-label-container"; + // let nameSpanLabel = document.createElement("label"); + // nameSpanLabel.className = "cursor-label"; + // nameSpanLabel.textContent = this.userId; + // nameSpanContainer.appendChild(nameSpanLabel); + // el.appendChild(nameSpanContainer); + return el; + } +} + +export type CollabEvents = { + cursorSnapshot: (pageName: string, cursors: Map) => void; +}; + +export function collabExtension( + pageName: string, + clientID: string, + doc: CollabDocument, + collabEmitter: EventEmitter, + callbacks: { + pushUpdates: ( + pageName: string, + version: number, + updates: readonly (Update & { origin: Transaction })[] + ) => Promise; + pullUpdates: ( + pageName: string, + version: number + ) => Promise; + reload: () => void; + } +) { + let plugin = ViewPlugin.fromClass( + class { + private pushing = false; + private done = false; + private failedPushes = 0; + private cursorPositions: Map = doc.cursors; + decorations: DecorationSet; + + throttledPush = throttle(() => this.push(), throttleInterval); + + eventHandlers: Partial = { + cursorSnapshot: (pageName, cursors) => { + console.log("Received new cursor snapshot", cursors); + this.cursorPositions = new Map(Object.entries(cursors)); + }, + }; + + buildDecorations(view: EditorView) { + let builder = new RangeSetBuilder(); + + let list = []; + for (let [userId, def] of this.cursorPositions) { + if (userId == clientID) { + continue; + } + list.push({ + pos: def.pos, + widget: Decoration.widget({ + widget: new CursorWidget(userId, def.color), + side: 1, + }), + }); + } + + list + .sort((a, b) => a.pos - b.pos) + .forEach((r) => { + builder.add(r.pos, r.pos, r.widget); + }); + + return builder.finish(); + } + + constructor(private view: EditorView) { + if (pageName) { + this.pull(); + } + this.decorations = this.buildDecorations(view); + collabEmitter.on(this.eventHandlers); + } + + update(update: ViewUpdate) { + if (update.selectionSet) { + let pos = update.state.selection.main.head; + // if (pos === 0) { + // console.error("Warning: position reset? at 0"); + // console.trace(); + // } + setTimeout(() => { + update.view.dispatch({ + effects: [ + cursorEffect.of({ pos: pos, userId: clientID, color: "red" }), + ], + }); + }); + } + let foundCursorMoves = new Set(); + for (let tx of update.transactions) { + let cursorMove = tx.effects.find((e) => e.is(cursorEffect)); + if (cursorMove) { + foundCursorMoves.add(cursorMove.value.userId); + } + } + // Update cursors + for (let cursor of this.cursorPositions.values()) { + if (foundCursorMoves.has(cursor.userId)) { + // Already got a cursor update for this one, no need to manually map + continue; + } + update.transactions.forEach((tx) => { + cursor.pos = tx.changes.mapPos(cursor.pos); + }); + } + this.decorations = this.buildDecorations(update.view); + if (update.docChanged || foundCursorMoves.size > 0) { + this.throttledPush(); + } + } + + async push() { + let updates = sendableUpdates(this.view.state); + // TODO: compose multiple updates into one + if (this.pushing || !updates.length) return; + this.pushing = true; + let version = getSyncedVersion(this.view.state); + console.log("Updates", updates, "to apply to version", version); + let success = await callbacks.pushUpdates(pageName, version, updates); + this.pushing = false; + + if (!success && !this.done) { + this.failedPushes++; + if (this.failedPushes > 10) { + // Not sure if 10 is a good number, but YOLO + console.log("10 pushes failed, reloading"); + callbacks.reload(); + return this.destroy(); + } + console.log( + `Push for page ${pageName} failed temporarily, but will try again` + ); + } else { + this.failedPushes = 0; + } + + // Regardless of whether the push failed or new updates came in + // while it was running, try again if there's updates remaining + if (!this.done && sendableUpdates(this.view.state).length) { + // setTimeout(() => this.push(), 100); + this.throttledPush(); + } + } + + async pull() { + while (!this.done) { + let version = getSyncedVersion(this.view.state); + let updates = await callbacks.pullUpdates(pageName, version); + let d = receiveUpdates(this.view.state, updates); + // Pull out cursor updates and update local state + for (let update of updates) { + if (update.effects) { + for (let effect of update.effects) { + if (effect.is(cursorEffect)) { + this.cursorPositions.set(effect.value.userId, { + userId: effect.value.userId, + pos: effect.value.pos, + color: effect.value.color, + }); + } + } + } + } + this.view.dispatch(d); + } + } + + destroy() { + this.done = true; + collabEmitter.off(this.eventHandlers); + } + }, + { + decorations: (v) => v.decorations, + } + ); + + return [ + collab({ + startVersion: doc.version, + clientID, + sharedEffects: (tr) => { + return tr.effects.filter((e) => e.is(cursorEffect)); + }, + }), + plugin, + ]; +} diff --git a/webapp/commands.ts b/webapp/commands.ts new file mode 100644 index 0000000..08c1736 --- /dev/null +++ b/webapp/commands.ts @@ -0,0 +1,60 @@ +import { EditorSelection, StateCommand, Transaction } from "@codemirror/state"; +import { Text } from "@codemirror/text"; + +export function insertMarker(marker: string): StateCommand { + return ({ state, dispatch }) => { + const changes = state.changeByRange((range) => { + const isBoldBefore = + state.sliceDoc(range.from - marker.length, range.from) === marker; + const isBoldAfter = + state.sliceDoc(range.to, range.to + marker.length) === marker; + const changes = []; + + changes.push( + isBoldBefore + ? { + from: range.from - marker.length, + to: range.from, + insert: Text.of([""]), + } + : { + from: range.from, + insert: Text.of([marker]), + } + ); + + changes.push( + isBoldAfter + ? { + from: range.to, + to: range.to + marker.length, + insert: Text.of([""]), + } + : { + from: range.to, + insert: Text.of([marker]), + } + ); + + const extendBefore = isBoldBefore ? -marker.length : marker.length; + const extendAfter = isBoldAfter ? -marker.length : marker.length; + + return { + changes, + range: EditorSelection.range( + range.from + extendBefore, + range.to + extendAfter + ), + }; + }); + + dispatch( + state.update(changes, { + scrollIntoView: true, + annotations: Transaction.userEvent.of("input"), + }) + ); + + return true; + }; +} diff --git a/webapp/components/command_palette.tsx b/webapp/components/command_palette.tsx new file mode 100644 index 0000000..aca4172 --- /dev/null +++ b/webapp/components/command_palette.tsx @@ -0,0 +1,39 @@ +import { AppCommand } from "../types"; +import { isMacLike } from "../util"; +import { FilterList, Option } from "./filter"; +import { faPersonRunning } from "@fortawesome/free-solid-svg-icons"; + +export function CommandPalette({ + commands, + onTrigger, +}: { + commands: Map; + onTrigger: (command: AppCommand | undefined) => void; +}) { + let options: Option[] = []; + const isMac = isMacLike(); + for (let [name, def] of commands.entries()) { + options.push({ + name: name, + hint: isMac && def.command.mac ? def.command.mac : def.command.key, + }); + } + console.log("Commands", options); + return ( + { + if (opt) { + onTrigger(commands.get(opt.name)); + } else { + onTrigger(undefined); + } + }} + /> + ); +} diff --git a/webapp/components/filter.tsx b/webapp/components/filter.tsx new file mode 100644 index 0000000..4cfc211 --- /dev/null +++ b/webapp/components/filter.tsx @@ -0,0 +1,167 @@ +import React, { useEffect, useRef, useState } from "react"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { IconDefinition } from "@fortawesome/free-solid-svg-icons"; + +export interface Option { + name: string; + orderId?: number; + hint?: string; +} + +function magicSorter(a: Option, b: Option): number { + if (a.orderId && b.orderId) { + return a.orderId < b.orderId ? -1 : 1; + } + return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1; +} + +export function FilterList({ + placeholder, + options, + label, + onSelect, + onKeyPress, + allowNew = false, + helpText = "", + icon, + newHint, +}: { + placeholder: string; + options: Option[]; + label: string; + onKeyPress?: (key: string, currentText: string) => void; + onSelect: (option: Option | undefined) => void; + allowNew?: boolean; + helpText: string; + newHint?: string; + icon?: IconDefinition; +}) { + const searchBoxRef = useRef(null); + const [text, setText] = useState(""); + const [matchingOptions, setMatchingOptions] = useState( + options.sort(magicSorter) + ); + const [selectedOption, setSelectionOption] = useState(0); + + let selectedElementRef = useRef(null); + + const filter = (e: React.ChangeEvent) => { + const originalPhrase = e.target.value; + const searchPhrase = originalPhrase.toLowerCase(); + + if (searchPhrase) { + let foundExactMatch = false; + let results = options.filter((option) => { + if (option.name.toLowerCase() === searchPhrase) { + foundExactMatch = true; + } + return option.name.toLowerCase().indexOf(searchPhrase) !== -1; + }); + results = results.sort(magicSorter); + if (allowNew && !foundExactMatch) { + results.push({ + name: originalPhrase, + hint: newHint, + }); + } + setMatchingOptions(results); + } else { + let results = options.sort(magicSorter); + setMatchingOptions(results); + } + + setText(originalPhrase); + setSelectionOption(0); + }; + + useEffect(() => { + searchBoxRef.current!.focus(); + }, []); + + useEffect(() => { + function closer() { + onSelect(undefined); + } + document.addEventListener("click", closer); + + return () => { + document.removeEventListener("click", closer); + }; + }, []); + + const returnEl = ( +
+
+ + { + // console.log("Key up", e.key); + if (onKeyPress) { + onKeyPress(e.key, text); + } + switch (e.key) { + case "ArrowUp": + setSelectionOption(Math.max(0, selectedOption - 1)); + break; + case "ArrowDown": + setSelectionOption( + Math.min(matchingOptions.length - 1, selectedOption + 1) + ); + break; + case "Enter": + onSelect(matchingOptions[selectedOption]); + e.preventDefault(); + break; + case "Escape": + onSelect(undefined); + break; + } + }} + /> +
+
+
+ {matchingOptions && matchingOptions.length > 0 + ? matchingOptions.map((option, idx) => ( +
{ + setSelectionOption(idx); + }} + onClick={(e) => { + e.preventDefault(); + onSelect(option); + }} + > + + {icon && } + + {option.name} + {option.hint && {option.hint}} +
+ )) + : null} +
+
+ ); + + useEffect(() => { + selectedElementRef.current?.scrollIntoView({ + block: "nearest", + }); + }); + + return returnEl; +} diff --git a/webapp/components/page_navigator.tsx b/webapp/components/page_navigator.tsx new file mode 100644 index 0000000..8b3ae3e --- /dev/null +++ b/webapp/components/page_navigator.tsx @@ -0,0 +1,44 @@ +import { PageMeta } from "../types"; +import { FilterList, Option } from "./filter"; +import { faFileLines } from "@fortawesome/free-solid-svg-icons"; + +export function PageNavigator({ + allPages, + onNavigate, + currentPage, +}: { + allPages: Set; + onNavigate: (page: string | undefined) => void; + currentPage?: string; +}) { + let options: Option[] = []; + for (let pageMeta of allPages) { + if (currentPage && currentPage === pageMeta.name) { + continue; + } + // Order by last modified date in descending order + let orderId = -pageMeta.lastModified; + // Unless it was opened and is still in memory + if (pageMeta.lastOpened) { + orderId = -pageMeta.lastOpened; + } + options.push({ + ...pageMeta, + orderId: orderId, + }); + } + return ( + { + onNavigate(opt?.name); + }} + /> + ); +} diff --git a/webapp/components/status_bar.tsx b/webapp/components/status_bar.tsx new file mode 100644 index 0000000..463eb8f --- /dev/null +++ b/webapp/components/status_bar.tsx @@ -0,0 +1,17 @@ +import { EditorView } from "@codemirror/view"; +import * as util from "../util"; + +export function StatusBar({ editorView }: { editorView?: EditorView }) { + let wordCount = 0, + readingTime = 0; + if (editorView) { + let text = editorView.state.sliceDoc(); + wordCount = util.countWords(text); + readingTime = util.readingTime(wordCount); + } + return ( +
+ {wordCount} words | {readingTime} min +
+ ); +} diff --git a/webapp/components/top_bar.tsx b/webapp/components/top_bar.tsx new file mode 100644 index 0000000..ef8cf9d --- /dev/null +++ b/webapp/components/top_bar.tsx @@ -0,0 +1,39 @@ +import { AppViewState, PageMeta } from "../types"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faFileLines } from "@fortawesome/free-solid-svg-icons"; +import { Notification } from "../types"; + +function prettyName(s: string | undefined): string { + if (!s) { + return ""; + } + return s.replaceAll("/", " / "); +} + +export function TopBar({ + pageName, + status, + notifications, + onClick, +}: { + pageName?: string; + status?: string; + notifications: Notification[]; + onClick: () => void; +}) { + return ( +
+
+ + + + {prettyName(pageName)} +
+ {notifications.map((notification) => ( +
{notification.message}
+ ))} +
+
+
+ ); +} diff --git a/webapp/constant.ts b/webapp/constant.ts new file mode 100644 index 0000000..47d2e66 --- /dev/null +++ b/webapp/constant.ts @@ -0,0 +1 @@ +export const pageLinkRegex = /\[\[([\w\s\/\:,\.\-]+)\]\]/; diff --git a/webapp/cursorEffect.ts b/webapp/cursorEffect.ts new file mode 100644 index 0000000..3e05bfd --- /dev/null +++ b/webapp/cursorEffect.ts @@ -0,0 +1,12 @@ +import { StateEffect } from "@codemirror/state"; +export type Cursor = { + pos: number; + userId: string; + color: string; +}; + +export const cursorEffect = StateEffect.define({ + map({ pos, userId, color }, changes) { + return { pos: changes.mapPos(pos), userId, color }; + }, +}); diff --git a/webapp/customtags.ts b/webapp/customtags.ts new file mode 100644 index 0000000..bbe9a02 --- /dev/null +++ b/webapp/customtags.ts @@ -0,0 +1,12 @@ +import { Tag } from "@codemirror/highlight"; + +export const WikiLinkTag = Tag.define(); +export const WikiLinkPageTag = Tag.define(); +export const TagTag = Tag.define(); +export const MentionTag = Tag.define(); +export const TaskTag = Tag.define(); +export const TaskMarkerTag = Tag.define(); +export const CommentTag = Tag.define(); +export const CommentMarkerTag = Tag.define(); +export const BulletList = Tag.define(); +export const OrderedList = Tag.define(); diff --git a/webapp/editor.tsx b/webapp/editor.tsx new file mode 100644 index 0000000..f34b328 --- /dev/null +++ b/webapp/editor.tsx @@ -0,0 +1,497 @@ +import { + autocompletion, + Completion, + CompletionContext, + completionKeymap, + CompletionResult, +} from "@codemirror/autocomplete"; +import { closeBrackets, closeBracketsKeymap } from "@codemirror/closebrackets"; +import { indentWithTab, standardKeymap } from "@codemirror/commands"; +import { history, historyKeymap } from "@codemirror/history"; +import { bracketMatching } from "@codemirror/matchbrackets"; +import { searchKeymap } from "@codemirror/search"; +import { EditorSelection, EditorState, Text } from "@codemirror/state"; +import { + drawSelection, + dropCursor, + EditorView, + highlightSpecialChars, + KeyBinding, + keymap, +} from "@codemirror/view"; +// import { debounce } from "lodash"; +import React, { useEffect, useReducer } from "react"; +import ReactDOM from "react-dom"; +import { Plug, System } from "../plugbox/runtime"; +import { createSandbox as createIFrameSandbox } from "../plugbox/iframe_sandbox"; +import { AppEvent, AppEventDispatcher, ClickEvent } from "./app_event"; +import { CollabDocument, collabExtension } from "./collab"; +import * as commands from "./commands"; +import { CommandPalette } from "./components/command_palette"; +import { PageNavigator } from "./components/page_navigator"; +import { TopBar } from "./components/top_bar"; +import { Cursor } from "./cursorEffect"; +import coreManifest from "./generated/core.plug.json"; +import { lineWrapper } from "./line_wrapper"; +import { markdown } from "./markdown"; +import { IPageNavigator, PathPageNavigator } from "./navigator"; +import customMarkDown from "./parser"; +import reducer from "./reducer"; +import { smartQuoteKeymap } from "./smart_quotes"; +import { Space } from "./space"; +import customMarkdownStyle from "./style"; +import dbSyscalls from "./syscalls/db.localstorage"; +import editorSyscalls from "./syscalls/editor.browser"; +import indexerSyscalls from "./syscalls/indexer.native"; +import spaceSyscalls from "./syscalls/space.native"; +import { + Action, + AppCommand, + AppViewState, + initialViewState, + NuggetHook, + slashCommandRegexp, +} from "./types"; +import { safeRun } from "./util"; + +class PageState { + scrollTop: number; + selection: EditorSelection; + + constructor(scrollTop: number, selection: EditorSelection) { + this.scrollTop = scrollTop; + this.selection = selection; + } +} + +export class Editor implements AppEventDispatcher { + editorView?: EditorView; + viewState: AppViewState; + viewDispatch: React.Dispatch; + openPages: Map; + space: Space; + editorCommands: Map; + plugs: Plug[]; + navigationResolve?: (val: undefined) => void; + pageNavigator: IPageNavigator; + + constructor(space: Space, parent: Element) { + this.editorCommands = new Map(); + this.openPages = new Map(); + this.plugs = []; + this.space = space; + this.viewState = initialViewState; + this.viewDispatch = () => {}; + this.render(parent); + this.editorView = new EditorView({ + state: this.createEditorState( + "", + new CollabDocument(Text.of([""]), 0, new Map()) + ), + parent: document.getElementById("editor")!, + }); + this.pageNavigator = new PathPageNavigator(); + } + + async init() { + await this.loadPlugs(); + this.focus(); + + this.pageNavigator.subscribe(async (pageName) => { + console.log("Now navigating to", pageName); + + if (!this.editorView) { + return; + } + + await this.loadPage(pageName); + }); + + this.space.on({ + connect: () => { + if (this.currentPage) { + console.log("Connected to socket, fetch fresh?"); + this.flashNotification("Reconnected, reloading page"); + this.reloadPage(); + } + }, + pageChanged: (meta) => { + if (this.currentPage === meta.name) { + console.log("Page changed on disk, reloading"); + this.flashNotification("Page changed on disk, reloading"); + this.reloadPage(); + } + }, + pageListUpdated: (pages) => { + this.viewDispatch({ + type: "pages-listed", + pages: pages, + }); + }, + }); + + if (this.pageNavigator.getCurrentPage() === "") { + this.pageNavigator.navigate("start"); + } + } + + flashNotification(message: string) { + let id = Math.floor(Math.random() * 1000000); + this.viewDispatch({ + type: "show-notification", + notification: { + id: id, + message: message, + date: new Date(), + }, + }); + setTimeout(() => { + this.viewDispatch({ + type: "dismiss-notification", + id: id, + }); + }, 2000); + } + + async loadPlugs() { + const system = new System(); + system.registerSyscalls( + dbSyscalls, + editorSyscalls(this), + spaceSyscalls(this), + indexerSyscalls(this.space) + ); + + console.log("Now loading core plug"); + let mainPlug = await system.load( + "core", + coreManifest, + createIFrameSandbox(system) + ); + this.plugs.push(mainPlug); + this.editorCommands = new Map(); + for (let plug of this.plugs) { + this.buildCommands(plug); + } + this.viewDispatch({ + type: "update-commands", + commands: this.editorCommands, + }); + } + + private buildCommands(plug: Plug) { + const cmds = plug.manifest!.hooks.commands; + for (let name in cmds) { + let cmd = cmds[name]; + this.editorCommands.set(name, { + command: cmd, + run: async (arg): Promise => { + return await plug.invoke(cmd.invoke, [arg]); + }, + }); + } + } + + // TODO: Parallelize? + async dispatchAppEvent(name: AppEvent, data?: any): Promise { + let results: any[] = []; + for (let plug of this.plugs) { + let plugResults = await plug.dispatchEvent(name, data); + if (plugResults) { + for (let result of plugResults) { + results.push(result); + } + } + } + return results; + } + + get currentPage(): string | undefined { + return this.viewState.currentPage; + } + + createEditorState(pageName: string, doc: CollabDocument): EditorState { + let commandKeyBindings: KeyBinding[] = []; + for (let def of this.editorCommands.values()) { + if (def.command.key) { + commandKeyBindings.push({ + key: def.command.key, + mac: def.command.mac, + run: (): boolean => { + Promise.resolve() + .then(async () => { + await def.run(null); + }) + .catch((e) => console.error(e)); + return true; + }, + }); + } + } + return EditorState.create({ + doc: doc.text, + extensions: [ + highlightSpecialChars(), + history(), + drawSelection(), + dropCursor(), + customMarkdownStyle, + bracketMatching(), + closeBrackets(), + collabExtension(pageName, this.space.socket.id, doc, this.space, { + pushUpdates: this.space.pushUpdates.bind(this.space), + pullUpdates: this.space.pullUpdates.bind(this.space), + reload: this.reloadPage.bind(this), + }), + autocompletion({ + override: [ + this.plugCompleter.bind(this), + this.commandCompleter.bind(this), + ], + }), + EditorView.lineWrapping, + lineWrapper([ + { selector: "ATXHeading1", class: "line-h1" }, + { selector: "ATXHeading2", class: "line-h2" }, + { selector: "ATXHeading3", class: "line-h3" }, + { selector: "ListItem", class: "line-li", nesting: true }, + { selector: "Blockquote", class: "line-blockquote" }, + { selector: "Task", class: "line-task" }, + { selector: "CodeBlock", class: "line-code" }, + { selector: "FencedCode", class: "line-fenced-code" }, + { selector: "Comment", class: "line-comment" }, + { selector: "BulletList", class: "line-ul" }, + { selector: "OrderedList", class: "line-ol" }, + ]), + keymap.of([ + ...smartQuoteKeymap, + ...closeBracketsKeymap, + ...standardKeymap, + ...searchKeymap, + ...historyKeymap, + ...completionKeymap, + indentWithTab, + ...commandKeyBindings, + { + key: "Ctrl-b", + mac: "Cmd-b", + run: commands.insertMarker("**"), + }, + { + key: "Ctrl-i", + mac: "Cmd-i", + run: commands.insertMarker("_"), + }, + { + key: "Ctrl-p", + mac: "Cmd-p", + run: (): boolean => { + window.open(location.href, "_blank")!.focus(); + return true; + }, + }, + { + key: "Ctrl-k", + mac: "Cmd-k", + run: (): boolean => { + this.viewDispatch({ type: "start-navigate" }); + return true; + }, + }, + { + key: "Ctrl-.", + mac: "Cmd-.", + run: (): boolean => { + this.viewDispatch({ + type: "show-palette", + }); + return true; + }, + }, + ]), + EditorView.domEventHandlers({ + click: (event: MouseEvent, view: EditorView) => { + safeRun(async () => { + let clickEvent: ClickEvent = { + ctrlKey: event.ctrlKey, + metaKey: event.metaKey, + altKey: event.altKey, + pos: view.posAtCoords(event)!, + }; + await this.dispatchAppEvent("page:click", clickEvent); + }); + }, + }), + markdown({ + base: customMarkDown, + }), + ], + }); + } + + reloadPage() { + console.log("Reloading page"); + safeRun(async () => { + await this.loadPage(this.currentPage!); + }); + } + + async plugCompleter(): Promise { + let allCompletionResults = await this.dispatchAppEvent("editor:complete"); + if (allCompletionResults.length === 1) { + return allCompletionResults[0]; + } else if (allCompletionResults.length > 1) { + console.error( + "Got completion results from multiple sources, cannot deal with that", + allCompletionResults + ); + } + return null; + } + + commandCompleter(ctx: CompletionContext): CompletionResult | null { + let prefix = ctx.matchBefore(slashCommandRegexp); + if (!prefix) { + return null; + } + let options: Completion[] = []; + for (let [name, def] of this.viewState.commands) { + if (!def.command.slashCommand) { + continue; + } + options.push({ + label: def.command.slashCommand, + detail: name, + apply: () => { + this.editorView?.dispatch({ + changes: { + from: prefix!.from, + to: ctx.pos, + insert: "", + }, + }); + safeRun(async () => { + await def.run(null); + }); + }, + }); + } + return { + from: prefix.from + 1, + options: options, + }; + } + + focus() { + this.editorView!.focus(); + } + + navigate(name: string) { + this.pageNavigator.navigate(name); + } + + async loadPage(pageName: string) { + const editorView = this.editorView; + if (!editorView) { + return; + } + + // Persist current page state and nicely close page + if (this.currentPage) { + let pageState = this.openPages.get(this.currentPage)!; + if (pageState) { + pageState.selection = this.editorView!.state.selection; + pageState.scrollTop = this.editorView!.scrollDOM.scrollTop; + } + + await this.space.closePage(this.currentPage); + } + + // Fetch next page to open + let doc = await this.space.openPage(pageName); + let editorState = this.createEditorState(pageName, doc); + let pageState = this.openPages.get(pageName); + editorView.setState(editorState); + if (!pageState) { + pageState = new PageState(0, editorState.selection); + this.openPages.set(pageName, pageState!); + editorView.dispatch({ + selection: { anchor: 0 }, + }); + } else { + // Restore state + console.log("Restoring selection state", pageState.selection); + editorView.dispatch({ + selection: pageState.selection, + }); + editorView.scrollDOM.scrollTop = pageState!.scrollTop; + } + + this.viewDispatch({ + type: "page-loaded", + name: pageName, + }); + } + + ViewComponent(): React.ReactElement { + const [viewState, dispatch] = useReducer(reducer, initialViewState); + this.viewState = viewState; + this.viewDispatch = dispatch; + + let editor = this; + + useEffect(() => { + if (viewState.currentPage) { + document.title = viewState.currentPage; + } + }, [viewState.currentPage]); + + return ( + <> + {viewState.showPageNavigator && ( + { + dispatch({ type: "stop-navigate" }); + editor.focus(); + if (page) { + safeRun(async () => { + editor.navigate(page); + }); + } + }} + /> + )} + {viewState.showCommandPalette && ( + { + dispatch({ type: "hide-palette" }); + editor!.focus(); + if (cmd) { + safeRun(async () => { + let result = await cmd.run(null); + console.log("Result of command", result); + }); + } + }} + commands={viewState.commands} + /> + )} + { + dispatch({ type: "start-navigate" }); + }} + /> +
+ + ); + } + + render(container: ReactDOM.Container) { + const ViewComponent = this.ViewComponent.bind(this); + ReactDOM.render(, container); + } +} diff --git a/webapp/event.ts b/webapp/event.ts new file mode 100644 index 0000000..3eb9ca7 --- /dev/null +++ b/webapp/event.ts @@ -0,0 +1,20 @@ +export abstract class EventEmitter { + private handlers: Partial[] = []; + + on(handlers: Partial) { + this.handlers.push(handlers); + } + + off(handlers: Partial) { + this.handlers = this.handlers.filter((h) => h !== handlers); + } + + emit(eventName: keyof HandlerT, ...args: any[]) { + for (let handler of this.handlers) { + let fn: any = handler[eventName]; + if (fn) { + fn(...args); + } + } + } +} diff --git a/webapp/images/logo.png b/webapp/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..49a5bce5beecbe5f379b12d21af73bfcca21f954 GIT binary patch literal 67362 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 + + + + Silver Bullet + + + + + + + +
+ + diff --git a/webapp/line_wrapper.ts b/webapp/line_wrapper.ts new file mode 100644 index 0000000..2d155bd --- /dev/null +++ b/webapp/line_wrapper.ts @@ -0,0 +1,83 @@ +import { syntaxTree } from "@codemirror/language"; +import { + Decoration, + DecorationSet, + EditorView, + ViewPlugin, + ViewUpdate, +} from "@codemirror/view"; + +import { Range } from "@codemirror/rangeset"; + +interface WrapElement { + selector: string; + class: string; + nesting?: boolean; +} + +function wrapLines(view: EditorView, wrapElements: WrapElement[]) { + let widgets: Range[] = []; + let elementStack: string[] = []; + for (let { from, to } of view.visibleRanges) { + const doc = view.state.doc; + syntaxTree(view.state).iterate({ + from, + to, + enter: (type, from, to) => { + const bodyText = doc.sliceString(from, to); + for (let wrapElement of wrapElements) { + if (type.name == wrapElement.selector) { + if (wrapElement.nesting) { + elementStack.push(type.name); + } + const bodyText = doc.sliceString(from, to); + let idx = from; + for (let line of bodyText.split("\n")) { + let cls = wrapElement.class; + if (wrapElement.nesting) { + cls = `${cls} ${cls}-${elementStack.length}`; + } + widgets.push( + Decoration.line({ + class: cls, + }).range(doc.lineAt(idx).from) + ); + idx += line.length + 1; + } + } + } + }, + leave(type, from: number, to: number) { + for (let wrapElement of wrapElements) { + if (type.name == wrapElement.selector && wrapElement.nesting) { + elementStack.pop(); + } + } + }, + }); + } + // Widgets have to be sorted by `from` in ascending order + widgets = widgets.sort((a, b) => { + return a.from < b.from ? -1 : 1; + }); + return Decoration.set(widgets); +} +export const lineWrapper = (wrapElements: WrapElement[]) => + ViewPlugin.fromClass( + class { + decorations: DecorationSet; + + constructor(view: EditorView) { + this.decorations = wrapLines(view, wrapElements); + } + + update(update: ViewUpdate) { + if (update.docChanged || update.viewportChanged) { + this.decorations = wrapLines(update.view, wrapElements); + } + } + }, + { + decorations: (v) => v.decorations, + } + ); diff --git a/webapp/manifest.json b/webapp/manifest.json new file mode 100644 index 0000000..4f2dd24 --- /dev/null +++ b/webapp/manifest.json @@ -0,0 +1,17 @@ +{ + "short_name": "Silver Bullet", + "name": "Silver Bullet", + "icons": [ + { + "src": "./images/logo.png", + "type": "image/png", + "sizes": "1024x1024" + } + ], + "capture_links": "new-client", + "start_url": "/", + "display": "standalone", + "scope": "/", + "theme_color": "#000", + "description": "Note taking for winners" +} diff --git a/webapp/markdown/commands.ts b/webapp/markdown/commands.ts new file mode 100644 index 0000000..22e95a3 --- /dev/null +++ b/webapp/markdown/commands.ts @@ -0,0 +1,371 @@ +import { + StateCommand, + Text, + EditorSelection, + ChangeSpec, +} from "@codemirror/state"; +import { syntaxTree } from "@codemirror/language"; +import { SyntaxNode, Tree } from "@lezer/common"; +import { markdownLanguage } from "./markdown"; + +function nodeStart(node: SyntaxNode, doc: Text) { + return doc.sliceString(node.from, node.from + 50); +} + +class Context { + constructor( + readonly node: SyntaxNode, + readonly from: number, + readonly to: number, + readonly spaceBefore: string, + readonly spaceAfter: string, + readonly type: string, + readonly item: SyntaxNode | null + ) {} + + blank(trailing: boolean = true) { + let result = this.spaceBefore; + if (this.node.name == "Blockquote") { + result += ">"; + } else if (this.node.name == "Comment") { + result += "%%"; + } else + for ( + let i = this.to - this.from - result.length - this.spaceAfter.length; + i > 0; + i-- + ) + result += " "; + return result + (trailing ? this.spaceAfter : ""); + } + + marker(doc: Text, add: number) { + let number = + this.node.name == "OrderedList" + ? String(+itemNumber(this.item!, doc)[2] + add) + : ""; + return this.spaceBefore + number + this.type + this.spaceAfter; + } +} + +function getContext(node: SyntaxNode, line: string, doc: Text) { + let nodes = []; + for ( + let cur: SyntaxNode | null = node; + cur && cur.name != "Document"; + cur = cur.parent + ) { + if ( + cur.name == "ListItem" || + cur.name == "Blockquote" || + cur.name == "Comment" + ) + nodes.push(cur); + } + let context = [], + pos = 0; + for (let i = nodes.length - 1; i >= 0; i--) { + let node = nodes[i], + match, + start = pos; + if ( + node.name == "Blockquote" && + (match = /^[ \t]*>( ?)/.exec(line.slice(pos))) + ) { + pos += match[0].length; + context.push(new Context(node, start, pos, "", match[1], ">", null)); + } else if ( + node.name == "Comment" && + (match = /^[ \t]*%%( ?)/.exec(line.slice(pos))) + ) { + pos += match[0].length; + context.push(new Context(node, start, pos, "", match[1], "%%", null)); + } else if ( + node.name == "ListItem" && + node.parent!.name == "OrderedList" && + (match = /^([ \t]*)\d+([.)])([ \t]*)/.exec(nodeStart(node, doc))) + ) { + let after = match[3], + len = match[0].length; + if (after.length >= 4) { + after = after.slice(0, after.length - 4); + len -= 4; + } + pos += len; + context.push( + new Context(node.parent!, start, pos, match[1], after, match[2], node) + ); + } else if ( + node.name == "ListItem" && + node.parent!.name == "BulletList" && + (match = /^([ \t]*)([-+*])([ \t]+)/.exec(nodeStart(node, doc))) + ) { + let after = match[3], + len = match[0].length; + if (after.length > 4) { + after = after.slice(0, after.length - 4); + len -= 4; + } + pos += len; + context.push( + new Context(node.parent!, start, pos, match[1], after, match[2], node) + ); + } + } + return context; +} + +function itemNumber(item: SyntaxNode, doc: Text) { + return /^(\s*)(\d+)(?=[.)])/.exec( + doc.sliceString(item.from, item.from + 10) + )!; +} + +function renumberList( + after: SyntaxNode, + doc: Text, + changes: ChangeSpec[], + offset = 0 +) { + for (let prev = -1, node = after; ; ) { + if (node.name == "ListItem") { + let m = itemNumber(node, doc); + let number = +m[2]; + if (prev >= 0) { + if (number != prev + 1) return; + changes.push({ + from: node.from + m[1].length, + to: node.from + m[0].length, + insert: String(prev + 2 + offset), + }); + } + prev = number; + } + let next = node.nextSibling; + if (!next) break; + node = next; + } +} + +/// This command, when invoked in Markdown context with cursor +/// selection(s), will create a new line with the markup for +/// blockquotes and lists that were active on the old line. If the +/// cursor was directly after the end of the markup for the old line, +/// trailing whitespace and list markers are removed from that line. +/// +/// The command does nothing in non-Markdown context, so it should +/// not be used as the only binding for Enter (even in a Markdown +/// document, HTML and code regions might use a different language). +export const insertNewlineContinueMarkup: StateCommand = ({ + state, + dispatch, +}) => { + let tree = syntaxTree(state), + { doc } = state; + let dont = null, + changes = state.changeByRange((range) => { + if (!range.empty || !markdownLanguage.isActiveAt(state, range.from)) + return (dont = { range }); + let pos = range.from, + line = doc.lineAt(pos); + let context = getContext(tree.resolveInner(pos, -1), line.text, doc); + while ( + context.length && + context[context.length - 1].from > pos - line.from + ) + context.pop(); + if (!context.length) return (dont = { range }); + let inner = context[context.length - 1]; + if (inner.to - inner.spaceAfter.length > pos - line.from) + return (dont = { range }); + + let emptyLine = + pos >= inner.to - inner.spaceAfter.length && + !/\S/.test(line.text.slice(inner.to)); + // Empty line in list + if (inner.item && emptyLine) { + // First list item or blank line before: delete a level of markup + if ( + inner.node.firstChild!.to >= pos || + (line.from > 0 && !/[^\s>]/.test(doc.lineAt(line.from - 1).text)) + ) { + let next = context.length > 1 ? context[context.length - 2] : null; + let delTo, + insert = ""; + if (next && next.item) { + // Re-add marker for the list at the next level + delTo = line.from + next.from; + insert = next.marker(doc, 1); + } else { + delTo = line.from + (next ? next.to : 0); + } + let changes: ChangeSpec[] = [{ from: delTo, to: pos, insert }]; + if (inner.node.name == "OrderedList") + renumberList(inner.item!, doc, changes, -2); + if (next && next.node.name == "OrderedList") + renumberList(next.item!, doc, changes); + return { + range: EditorSelection.cursor(delTo + insert.length), + changes, + }; + } else { + // Move this line down + let insert = ""; + for (let i = 0, e = context.length - 2; i <= e; i++) + insert += context[i].blank(i < e); + insert += state.lineBreak; + return { + range: EditorSelection.cursor(pos + insert.length), + changes: { from: line.from, insert }, + }; + } + } + + if (inner.node.name == "Blockquote" && emptyLine && line.from) { + let prevLine = doc.lineAt(line.from - 1), + quoted = />\s*$/.exec(prevLine.text); + // Two aligned empty quoted lines in a row + if (quoted && quoted.index == inner.from) { + let changes = state.changes([ + { from: prevLine.from + quoted.index, to: prevLine.to }, + { from: line.from + inner.from, to: line.to }, + ]); + return { range: range.map(changes), changes }; + } + } + + if (inner.node.name == "Comment" && emptyLine && line.from) { + let prevLine = doc.lineAt(line.from - 1), + commented = /%%\s*$/.exec(prevLine.text); + // Two aligned empty quoted lines in a row + if (commented && commented.index == inner.from) { + let changes = state.changes([ + { from: prevLine.from + commented.index, to: prevLine.to }, + { from: line.from + inner.from, to: line.to }, + ]); + return { range: range.map(changes), changes }; + } + } + + let changes: ChangeSpec[] = []; + if (inner.node.name == "OrderedList") + renumberList(inner.item!, doc, changes); + let insert = state.lineBreak; + let continued = inner.item && inner.item.from < line.from; + // If not dedented + if ( + !continued || + /^[\s\d.)\-+*>]*/.exec(line.text)![0].length >= inner.to + ) { + for (let i = 0, e = context.length - 1; i <= e; i++) + insert += + i == e && !continued + ? context[i].marker(doc, 1) + : context[i].blank(); + } + let from = pos; + while ( + from > line.from && + /\s/.test(line.text.charAt(from - line.from - 1)) + ) + from--; + changes.push({ from, to: pos, insert }); + return { range: EditorSelection.cursor(from + insert.length), changes }; + }); + if (dont) return false; + dispatch(state.update(changes, { scrollIntoView: true, userEvent: "input" })); + return true; +}; + +function isMark(node: SyntaxNode) { + return node.name == "QuoteMark" || node.name == "ListMark"; +} + +function contextNodeForDelete(tree: Tree, pos: number) { + let node = tree.resolveInner(pos, -1), + scan = pos; + if (isMark(node)) { + scan = node.from; + node = node.parent!; + } + for (let prev; (prev = node.childBefore(scan)); ) { + if (isMark(prev)) { + scan = prev.from; + } else if (prev.name == "OrderedList" || prev.name == "BulletList") { + node = prev.lastChild!; + scan = node.to; + } else { + break; + } + } + return node; +} + +/// This command will, when invoked in a Markdown context with the +/// cursor directly after list or blockquote markup, delete one level +/// of markup. When the markup is for a list, it will be replaced by +/// spaces on the first invocation (a further invocation will delete +/// the spaces), to make it easy to continue a list. +/// +/// When not after Markdown block markup, this command will return +/// false, so it is intended to be bound alongside other deletion +/// commands, with a higher precedence than the more generic commands. +export const deleteMarkupBackward: StateCommand = ({ state, dispatch }) => { + let tree = syntaxTree(state); + let dont = null, + changes = state.changeByRange((range) => { + let pos = range.from, + { doc } = state; + if (range.empty && markdownLanguage.isActiveAt(state, range.from)) { + let line = doc.lineAt(pos); + let context = getContext( + contextNodeForDelete(tree, pos), + line.text, + doc + ); + if (context.length) { + let inner = context[context.length - 1]; + let spaceEnd = + inner.to - inner.spaceAfter.length + (inner.spaceAfter ? 1 : 0); + // Delete extra trailing space after markup + if ( + pos - line.from > spaceEnd && + !/\S/.test(line.text.slice(spaceEnd, pos - line.from)) + ) + return { + range: EditorSelection.cursor(line.from + spaceEnd), + changes: { from: line.from + spaceEnd, to: pos }, + }; + if (pos - line.from == spaceEnd) { + let start = line.from + inner.from; + // Replace a list item marker with blank space + if ( + inner.item && + inner.node.from < inner.item.from && + /\S/.test(line.text.slice(inner.from, inner.to)) + ) + return { + range, + changes: { + from: start, + to: line.from + inner.to, + insert: inner.blank(), + }, + }; + // Delete one level of indentation + if (start < pos) + return { + range: EditorSelection.cursor(start), + changes: { from: start, to: pos }, + }; + } + } + } + return (dont = { range }); + }); + if (dont) return false; + dispatch( + state.update(changes, { scrollIntoView: true, userEvent: "delete" }) + ); + return true; +}; diff --git a/webapp/markdown/index.ts b/webapp/markdown/index.ts new file mode 100644 index 0000000..b14b909 --- /dev/null +++ b/webapp/markdown/index.ts @@ -0,0 +1,56 @@ +import {Prec} from "@codemirror/state" +import {KeyBinding, keymap} from "@codemirror/view" +import {Language, LanguageSupport, LanguageDescription} from "@codemirror/language" +import {MarkdownExtension, MarkdownParser, parseCode} from "@lezer/markdown" +import {html} from "@codemirror/lang-html" +import {commonmarkLanguage, markdownLanguage, mkLang, getCodeParser} from "./markdown" +import {insertNewlineContinueMarkup, deleteMarkupBackward} from "./commands" +export {commonmarkLanguage, markdownLanguage, insertNewlineContinueMarkup, deleteMarkupBackward} + +/// A small keymap with Markdown-specific bindings. Binds Enter to +/// [`insertNewlineContinueMarkup`](#lang-markdown.insertNewlineContinueMarkup) +/// and Backspace to +/// [`deleteMarkupBackward`](#lang-markdown.deleteMarkupBackward). +export const markdownKeymap: readonly KeyBinding[] = [ + {key: "Enter", run: insertNewlineContinueMarkup}, + {key: "Backspace", run: deleteMarkupBackward} +] + +const htmlNoMatch = html({matchClosingTags: false}) + +/// Markdown language support. +export function markdown(config: { + /// When given, this language will be used by default to parse code + /// blocks. + defaultCodeLanguage?: Language | LanguageSupport, + /// A collection of language descriptions to search through for a + /// matching language (with + /// [`LanguageDescription.matchLanguageName`](#language.LanguageDescription^matchLanguageName)) + /// when a fenced code block has an info string. + codeLanguages?: readonly LanguageDescription[], + /// Set this to false to disable installation of the Markdown + /// [keymap](#lang-markdown.markdownKeymap). + addKeymap?: boolean, + /// Markdown parser + /// [extensions](https://github.com/lezer-parser/markdown#user-content-markdownextension) + /// to add to the parser. + extensions?: MarkdownExtension, + /// The base language to use. Defaults to + /// [`commonmarkLanguage`](#lang-markdown.commonmarkLanguage). + base?: Language +} = {}) { + let {codeLanguages, defaultCodeLanguage, addKeymap = true, base: {parser} = commonmarkLanguage} = config + if (!(parser instanceof MarkdownParser)) throw new RangeError("Base parser provided to `markdown` should be a Markdown parser") + let extensions = config.extensions ? [config.extensions] : [] + let support = [htmlNoMatch.support], defaultCode + if (defaultCodeLanguage instanceof LanguageSupport) { + support.push(defaultCodeLanguage.support) + defaultCode = defaultCodeLanguage.language + } else if (defaultCodeLanguage) { + defaultCode = defaultCodeLanguage + } + let codeParser = codeLanguages || defaultCode ? getCodeParser(codeLanguages || [], defaultCode) : undefined + extensions.push(parseCode({codeParser, htmlParser: htmlNoMatch.language.parser})) + if (addKeymap) support.push(Prec.high(keymap.of(markdownKeymap))) + return new LanguageSupport(mkLang(parser.configure(extensions)), support) +} diff --git a/webapp/markdown/markdown.ts b/webapp/markdown/markdown.ts new file mode 100644 index 0000000..230f485 --- /dev/null +++ b/webapp/markdown/markdown.ts @@ -0,0 +1,84 @@ +import { + Language, defineLanguageFacet, languageDataProp, foldNodeProp, indentNodeProp, + LanguageDescription, ParseContext +} from "@codemirror/language" +import {styleTags, tags as t} from "@codemirror/highlight" +import {parser as baseParser, MarkdownParser, GFM, Subscript, Superscript, Emoji, MarkdownConfig} from "@lezer/markdown" + +const data = defineLanguageFacet({block: {open: ""}}) + +export const commonmark = baseParser.configure({ + props: [ + styleTags({ + "Blockquote/...": t.quote, + HorizontalRule: t.contentSeparator, + "ATXHeading1/... SetextHeading1/...": t.heading1, + "ATXHeading2/... SetextHeading2/...": t.heading2, + "ATXHeading3/...": t.heading3, + "ATXHeading4/...": t.heading4, + "ATXHeading5/...": t.heading5, + "ATXHeading6/...": t.heading6, + "Comment CommentBlock": t.comment, + Escape: t.escape, + Entity: t.character, + "Emphasis/...": t.emphasis, + "StrongEmphasis/...": t.strong, + "Link/... Image/...": t.link, + "OrderedList/... BulletList/...": t.list, + + // "CodeBlock/... FencedCode/...": t.blockComment, + "InlineCode CodeText": t.monospace, + URL: t.url, + "HeaderMark HardBreak QuoteMark ListMark LinkMark EmphasisMark CodeMark": t.processingInstruction, + "CodeInfo LinkLabel": t.labelName, + LinkTitle: t.string, + Paragraph: t.content + }), + foldNodeProp.add(type => { + if (!type.is("Block") || type.is("Document")) return undefined + return (tree, state) => ({from: state.doc.lineAt(tree.from).to, to: tree.to}) + }), + indentNodeProp.add({ + Document: () => null + }), + languageDataProp.add({ + Document: data + }) + ] +}) + +export function mkLang(parser: MarkdownParser) { + return new Language(data, parser, parser.nodeSet.types.find(t => t.name == "Document")!) +} + +/// Language support for strict CommonMark. +export const commonmarkLanguage = mkLang(commonmark) + +const extended = commonmark.configure([GFM, Subscript, Superscript, Emoji, { + props: [ + styleTags({ + "TableDelimiter SubscriptMark SuperscriptMark StrikethroughMark": t.processingInstruction, + "TableHeader/...": t.heading, + "Strikethrough/...": t.strikethrough, + TaskMarker: t.atom, + Task: t.list, + Emoji: t.character, + "Subscript Superscript": t.special(t.content), + TableCell: t.content + }) + ] +}]) + +/// Language support for [GFM](https://github.github.com/gfm/) plus +/// subscript, superscript, and emoji syntax. +export const markdownLanguage = mkLang(extended) + +export function getCodeParser(languages: readonly LanguageDescription[], + defaultLanguage?: Language) { + return (info: string) => { + let found = info && LanguageDescription.matchLanguageName(languages, info, true) + if (!found) return defaultLanguage ? defaultLanguage.parser : null + if (found.support) return found.support.language.parser + return ParseContext.getSkippingParser(found.load()) + } +} diff --git a/webapp/navigator.ts b/webapp/navigator.ts new file mode 100644 index 0000000..8e68067 --- /dev/null +++ b/webapp/navigator.ts @@ -0,0 +1,73 @@ +import { safeRun } from "./util"; + +export interface IPageNavigator { + subscribe(pageLoadCallback: (pageName: string) => Promise): void; + navigate(page: string): void; + getCurrentPage(): string; +} + +function encodePageUrl(name: string): string { + return name.replaceAll(" ", "_"); +} + +function decodePageUrl(url: string): string { + return url.replaceAll("_", " "); +} + +export class PathPageNavigator implements IPageNavigator { + navigationResolve?: (value: undefined) => void; + async navigate(page: string) { + window.history.pushState({ page: page }, page, `/${encodePageUrl(page)}`); + window.dispatchEvent(new PopStateEvent("popstate")); + await new Promise((resolve) => { + this.navigationResolve = resolve; + }); + this.navigationResolve = undefined; + } + subscribe(pageLoadCallback: (pageName: string) => Promise): void { + const cb = () => { + const gotoPage = this.getCurrentPage(); + if (!gotoPage) { + return; + } + safeRun(async () => { + await pageLoadCallback(this.getCurrentPage()); + if (this.navigationResolve) { + this.navigationResolve(undefined); + } + }); + }; + window.addEventListener("popstate", cb); + cb(); + } + + getCurrentPage(): string { + return decodePageUrl(location.pathname.substring(1)); + } +} + +export class HashPageNavigator implements IPageNavigator { + navigationResolve?: (value: undefined) => void; + async navigate(page: string) { + location.hash = encodePageUrl(page); + await new Promise((resolve) => { + this.navigationResolve = resolve; + }); + this.navigationResolve = undefined; + } + subscribe(pageLoadCallback: (pageName: string) => Promise): void { + const cb = () => { + safeRun(async () => { + await pageLoadCallback(this.getCurrentPage()); + if (this.navigationResolve) { + this.navigationResolve(undefined); + } + }); + }; + window.addEventListener("hashchange", cb); + cb(); + } + getCurrentPage(): string { + return decodePageUrl(location.hash.substring(1)); + } +} diff --git a/webapp/parser.ts b/webapp/parser.ts new file mode 100644 index 0000000..ec30d9a --- /dev/null +++ b/webapp/parser.ts @@ -0,0 +1,157 @@ +import { styleTags, tags as t } from "@codemirror/highlight"; +import { + MarkdownConfig, + TaskList, + BlockContext, + LeafBlock, + LeafBlockParser, +} from "@lezer/markdown"; +import { commonmark, mkLang } from "./markdown/markdown"; +import * as ct from "./customtags"; +import { pageLinkRegex } from "./constant"; + +const pageLinkRegexPrefix = new RegExp( + "^" + pageLinkRegex.toString().slice(1, -1) +); + +const WikiLink: MarkdownConfig = { + defineNodes: ["WikiLink", "WikiLinkPage"], + parseInline: [ + { + name: "WikiLink", + parse(cx, next, pos) { + let match: RegExpMatchArray | null; + if ( + next != 91 /* '[' */ || + !(match = pageLinkRegexPrefix.exec(cx.slice(pos, cx.end))) + ) { + return -1; + } + return cx.addElement( + cx.elt("WikiLink", pos, pos + match[0].length + 1, [ + cx.elt("WikiLinkPage", pos + 2, pos + match[0].length - 2), + ]) + ); + }, + after: "Emphasis", + }, + ], +}; + +const AtMention: MarkdownConfig = { + defineNodes: ["AtMention"], + parseInline: [ + { + name: "AtMention", + parse(cx, next, pos) { + let match: RegExpMatchArray | null; + if ( + next != 64 /* '@' */ || + !(match = /^[A-Za-z\.]+/.exec(cx.slice(pos + 1, cx.end))) + ) { + return -1; + } + return cx.addElement( + cx.elt("AtMention", pos, pos + 1 + match[0].length) + ); + }, + after: "Emphasis", + }, + ], +}; + +const urlRegexp = + /^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/; + +const UnmarkedUrl: MarkdownConfig = { + defineNodes: ["URL"], + parseInline: [ + { + name: "URL", + parse(cx, next, pos) { + let match: RegExpMatchArray | null; + if ( + next != 104 /* 'h' */ || + !(match = urlRegexp.exec(cx.slice(pos, cx.end))) + ) { + return -1; + } + return cx.addElement(cx.elt("URL", pos, pos + match[0].length)); + }, + after: "Emphasis", + }, + ], +}; + +class CommentParser implements LeafBlockParser { + nextLine() { + return false; + } + + finish(cx: BlockContext, leaf: LeafBlock) { + cx.addLeafElement( + leaf, + cx.elt("Comment", leaf.start, leaf.start + leaf.content.length, [ + // cx.elt("CommentMarker", leaf.start, leaf.start + 3), + ...cx.parser.parseInline(leaf.content.slice(3), leaf.start + 3), + ]) + ); + return true; + } +} +export const Comment: MarkdownConfig = { + defineNodes: [{ name: "Comment", block: true }], + parseBlock: [ + { + name: "Comment", + leaf(cx, leaf) { + return /^%%\s/.test(leaf.content) ? new CommentParser() : null; + }, + after: "SetextHeading", + }, + ], +}; + +const TagLink: MarkdownConfig = { + defineNodes: ["TagLink"], + parseInline: [ + { + name: "TagLink", + parse(cx, next, pos) { + let match: RegExpMatchArray | null; + if ( + next != 35 /* '#' */ || + !(match = /^[A-Za-z\.]+/.exec(cx.slice(pos + 1, cx.end))) + ) { + return -1; + } + return cx.addElement(cx.elt("TagLink", pos, pos + 1 + match[0].length)); + }, + after: "Emphasis", + }, + ], +}; +const WikiMarkdown = commonmark.configure([ + WikiLink, + AtMention, + // TagLink, + TaskList, + UnmarkedUrl, + Comment, + { + props: [ + styleTags({ + WikiLink: ct.WikiLinkTag, + WikiLinkPage: ct.WikiLinkPageTag, + AtMention: ct.MentionTag, + TagLink: ct.TagTag, + Task: ct.TaskTag, + TaskMarker: ct.TaskMarkerTag, + Url: t.url, + Comment: ct.CommentTag, + }), + ], + }, +]); + +export default mkLang(WikiMarkdown); diff --git a/webapp/reducer.ts b/webapp/reducer.ts new file mode 100644 index 0000000..12fa899 --- /dev/null +++ b/webapp/reducer.ts @@ -0,0 +1,63 @@ +import { Action, AppViewState } from "./types"; + +export default function reducer( + state: AppViewState, + action: Action +): AppViewState { + // console.log("Got action", action); + switch (action.type) { + case "page-loaded": + return { + ...state, + allPages: new Set( + [...state.allPages].map((pageMeta) => + pageMeta.name === action.name + ? { ...pageMeta, lastOpened: Date.now() } + : pageMeta + ) + ), + currentPage: action.name, + }; + case "start-navigate": + return { + ...state, + showPageNavigator: true, + }; + case "stop-navigate": + return { + ...state, + showPageNavigator: false, + }; + case "pages-listed": + return { + ...state, + allPages: action.pages, + }; + case "show-palette": + return { + ...state, + showCommandPalette: true, + }; + case "hide-palette": + return { + ...state, + showCommandPalette: false, + }; + case "update-commands": + return { + ...state, + commands: action.commands, + }; + case "show-notification": + return { + ...state, + notifications: [action.notification, ...state.notifications], + }; + case "dismiss-notification": + return { + ...state, + notifications: state.notifications.filter((n) => n.id !== action.id), + }; + } + return state; +} diff --git a/webapp/service_worker.ts b/webapp/service_worker.ts new file mode 100644 index 0000000..2c45a9d --- /dev/null +++ b/webapp/service_worker.ts @@ -0,0 +1,17 @@ +import { manifest, version } from "@parcel/service-worker"; + +async function install() { + const cache = await caches.open(version); + await cache.addAll(manifest); +} +//@ts-ignore +self.addEventListener("install", (e) => e.waitUntil(install())); + +async function activate() { + const keys = await caches.keys(); + await Promise.all(keys.map((key) => key !== version && caches.delete(key))); +} +//@ts-ignore +self.addEventListener("activate", (e) => e.waitUntil(activate())); + +self.addEventListener("fetch", function (event) {}); diff --git a/webapp/smart_quotes.ts b/webapp/smart_quotes.ts new file mode 100644 index 0000000..8bc9e15 --- /dev/null +++ b/webapp/smart_quotes.ts @@ -0,0 +1,35 @@ +import { KeyBinding } from "@codemirror/view"; + +// TODO: Add support for selection (put quotes around or create blockquote block?) +function keyBindingForQuote( + quote: string, + left: string, + right: string +): KeyBinding { + return { + key: quote, + run: (target): boolean => { + let cursorPos = target.state.selection.main.from; + let chBefore = target.state.sliceDoc(cursorPos - 1, cursorPos); + let quote = right; + if (/\W/.exec(chBefore) && !/[!\?,\.\-=“]/.exec(chBefore)) { + quote = left; + } + target.dispatch({ + changes: { + insert: quote, + from: cursorPos, + }, + selection: { + anchor: cursorPos + 1, + }, + }); + return true; + }, + }; +} + +export const smartQuoteKeymap: KeyBinding[] = [ + keyBindingForQuote('"', "“", "”"), + keyBindingForQuote("'", "‘", "’"), +]; diff --git a/webapp/space.ts b/webapp/space.ts new file mode 100644 index 0000000..b3e79d4 --- /dev/null +++ b/webapp/space.ts @@ -0,0 +1,191 @@ +import { PageMeta } from "./types"; +import { Socket } from "socket.io-client"; +import { Update } from "@codemirror/collab"; +import { ChangeSet, Text, Transaction } from "@codemirror/state"; + +import { CollabDocument, CollabEvents } from "./collab"; +import { cursorEffect } from "./cursorEffect"; +import { EventEmitter } from "./event"; + +export type SpaceEvents = { + connect: () => void; + pageCreated: (meta: PageMeta) => void; + pageChanged: (meta: PageMeta) => void; + pageDeleted: (name: string) => void; + pageListUpdated: (pages: Set) => void; +} & CollabEvents; + +export type KV = { + key: string; + value: any; +}; + +export class Space extends EventEmitter { + socket: Socket; + reqId = 0; + allPages = new Set(); + + constructor(socket: Socket) { + super(); + this.socket = socket; + + [ + "connect", + "cursorSnapshot", + "pageCreated", + "pageChanged", + "pageDeleted", + ].forEach((eventName) => { + socket.on(eventName, (...args) => { + this.emit(eventName as keyof SpaceEvents, ...args); + }); + }); + this.wsCall("page.listPages").then((pages) => { + this.allPages = new Set(pages); + this.emit("pageListUpdated", this.allPages); + }); + this.on({ + pageCreated: (meta) => { + // Cannot reply on equivalence in set, need to iterate over all pages + let found = false; + for (const page of this.allPages) { + if (page.name === meta.name) { + found = true; + break; + } + } + if(!found) { + this.allPages.add(meta); + console.log("New page created", meta); + this.emit("pageListUpdated", this.allPages); + } + }, + pageDeleted: (name) => { + console.log("Page delete", name); + this.allPages.forEach((meta) => { + if (name === meta.name) { + this.allPages.delete(meta); + } + }); + this.emit("pageListUpdated", this.allPages); + }, + }); + } + + private wsCall(eventName: string, ...args: any[]): Promise { + return new Promise((resolve, reject) => { + this.reqId++; + this.socket!.once(`${eventName}Resp${this.reqId}`, (err, result) => { + if (err) { + reject(err); + } else { + resolve(result); + } + }); + this.socket!.emit(eventName, this.reqId, ...args); + }); + } + + async pushUpdates( + pageName: string, + version: number, + fullUpdates: readonly (Update & { origin: Transaction })[] + ): Promise { + if (this.socket) { + let updates = fullUpdates.map((u) => ({ + clientID: u.clientID, + changes: u.changes.toJSON(), + cursors: u.effects?.map((e) => e.value), + })); + return this.wsCall("page.pushUpdates", pageName, version, updates); + } + return false; + } + + async pullUpdates( + pageName: string, + version: number + ): Promise { + let updates: Update[] = await this.wsCall( + "page.pullUpdates", + pageName, + version + ); + return updates.map((u) => ({ + changes: ChangeSet.fromJSON(u.changes), + effects: u.effects?.map((e) => cursorEffect.of(e.value)), + clientID: u.clientID, + })); + } + + async listPages(): Promise { + return Array.from(this.allPages); + } + + async openPage(name: string): Promise { + this.reqId++; + let pageJSON = await this.wsCall("page.openPage", name); + + return new CollabDocument( + Text.of(pageJSON.text), + pageJSON.version, + new Map(Object.entries(pageJSON.cursors)) + ); + } + + async closePage(name: string): Promise { + this.socket.emit("page.closePage", name); + } + + async readPage(name: string): Promise<{ text: string; meta: PageMeta }> { + return this.wsCall("page.readPage", name); + } + + async writePage(name: string, text: string): Promise { + return this.wsCall("page.writePage", name, text); + } + + async deletePage(name: string): Promise { + return this.wsCall("page.deletePage", name); + } + + async getPageMeta(name: string): Promise { + return this.wsCall("page.getPageMeta", name); + } + + async indexSet(pageName: string, key: string, value: any) { + await this.wsCall("index.set", pageName, key, value); + } + + async indexBatchSet(pageName: string, kvs: KV[]) { + // TODO: Optimize with batch call + for (let { key, value } of kvs) { + await this.indexSet(pageName, key, value); + } + } + + async indexGet(pageName: string, key: string): Promise { + return await this.wsCall("index.get", pageName, key); + } + + async indexScanPrefixForPage( + pageName: string, + keyPrefix: string + ): Promise<{ key: string; value: any }[]> { + return await this.wsCall("index.scanPrefixForPage", pageName, keyPrefix); + } + + async indexScanPrefixGlobal( + keyPrefix: string + ): Promise<{ key: string; value: any }[]> { + return await this.wsCall("index.scanPrefixGlobal", keyPrefix); + } + + async indexDeletePrefixForPage(pageName: string, keyPrefix: string) { + await this.wsCall("index.deletePrefixForPage", keyPrefix); + } + + async indexDelete(pageName: string, key: string) { + await this.wsCall("index.delete", pageName, key); + } +} diff --git a/webapp/style.ts b/webapp/style.ts new file mode 100644 index 0000000..f1a86ce --- /dev/null +++ b/webapp/style.ts @@ -0,0 +1,38 @@ +import { HighlightStyle, tags as t } from "@codemirror/highlight"; +import * as ct from "./customtags"; + +export default HighlightStyle.define([ + { tag: t.heading1, class: "h1" }, + { tag: t.heading2, class: "h2" }, + { tag: t.heading3, class: "h3" }, + { tag: t.link, class: "link" }, + { tag: t.meta, class: "meta" }, + { tag: t.quote, class: "quote" }, + { tag: t.monospace, class: "code" }, + { tag: t.url, class: "url" }, + { tag: ct.WikiLinkTag, class: "wiki-link" }, + { tag: ct.WikiLinkPageTag, class: "wiki-link-page" }, + { tag: ct.TagTag, class: "tag" }, + { tag: ct.MentionTag, class: "mention" }, + { tag: ct.TaskTag, class: "task" }, + { tag: ct.TaskMarkerTag, class: "task-marker" }, + { tag: ct.CommentTag, class: "comment" }, + { tag: ct.CommentMarkerTag, class: "comment-marker" }, + { tag: t.emphasis, class: "emphasis" }, + { tag: t.strong, class: "strong" }, + { tag: t.atom, class: "atom" }, + { tag: t.bool, class: "bool" }, + { tag: t.url, class: "url" }, + { tag: t.inserted, class: "inserted" }, + { tag: t.deleted, class: "deleted" }, + { tag: t.literal, class: "literal" }, + { tag: t.list, class: "list" }, + { tag: t.definition, class: "li" }, + { tag: t.string, class: "string" }, + { tag: t.number, class: "number" }, + { tag: [t.regexp, t.escape, t.special(t.string)], class: "string2" }, + { tag: t.variableName, class: "variableName" }, + { tag: t.comment, class: "comment" }, + { tag: t.invalid, class: "invalid" }, + { tag: t.punctuation, class: "punctuation" }, +]); diff --git a/webapp/styles/editor.scss b/webapp/styles/editor.scss new file mode 100644 index 0000000..e45cd1d --- /dev/null +++ b/webapp/styles/editor.scss @@ -0,0 +1,215 @@ +.cm-editor { + width: 100%; + height: 100%; + font-size: var(--ident); + + .cm-content { + font-family: var(--editor-font); + margin: auto; + max-width: 800px; + } + + .other-cursor { + display: inline-block; + width: 2px; + margin-right: -2px; + height: 1em; + } + + .cursor-label-container { + // display: none; + position: relative; + top: 2ch; + float: left; + width: 120px; + height: 2.2ch; + margin: 0; + padding: 0; + overflow: hidden; + font-family: Arial, Helvetica, sans-serif; + color: #fff; + border: gray 1px solid; + background-color: purple; + // font-size: 0.5em; + } + + .cursor-label-container label { + margin: 0; + padding: 0; + font-size: 0.7em; + } + + .cm-selectionBackground { + background-color: #d7e1f6 !important; + } + + .line-h1, + .line-h2, + .line-h3 { + background-color: rgba(0, 15, 52, 0.6); + color: #fff; + font-weight: bold; + padding: 2px 2px; + + .meta { + color: orange; + } + } + + .line-h1 { + font-size: 1.5em; + } + + .line-h2 { + font-size: 1.2em; + } + + .line-h3 { + font-size: 1.1em; + } + + /* Color list item this way */ + .line-li .meta { + color: rgb(0, 123, 19); + } + /* Then undo other meta */ + .line-li .meta ~ .meta { + color: #650007; + } + + .line-code { + background-color: #efefef; + margin-left: 30px; + } + + .line-fenced-code { + background-color: #efefef; + } + + .meta { + color: #650007; + } + + .line-blockquote { + background-color: rgba(220, 220, 220, 0.5); + color: #676767; + text-indent: -2ch; + padding-left: 2ch; + } + + .emphasis { + font-style: italic; + } + + .strong { + font-weight: 900; + } + + .link:not(.meta, .url) { + color: #0330cb; + text-decoration: underline; + } + + .link.url { + color: #7e7d7d; + } + + .url:not(.link) { + color: #0330cb; + text-decoration: underline; + } + + .wiki-link-page { + color: #0330cb; + text-decoration: underline; + } + .wiki-link { + color: #808080; + } + + .mention { + color: #0330cb; + text-decoration: underline; + } + + .tag { + color: #8d8d8d; + } + + .code { + background-color: #efefef; + } + + // Indentation of follow-up lines + @mixin lineOverflow($baseIndent) { + text-indent: -1 * ($baseIndent + 2ch); + padding-left: $baseIndent + 2ch; + + &.line-task { + text-indent: -1 * ($baseIndent + 6ch); + padding-left: $baseIndent + 6ch; + } + + &.line-blockquote { + text-indent: -1 * ($baseIndent + 4ch); + padding-left: $baseIndent + 4ch; + } + } + + .line-ul { + &.line-li-1 { + @include lineOverflow(0); + } + + &.line-li-1.line-li-2 { + @include lineOverflow(2); + } + + &.line-li-1.line-li-2.line-li-3 { + @include lineOverflow(4); + } + + &.line-li-1.line-li-2.line-li-3.line-li-4 { + @include lineOverflow(6); + } + + &.line-li-1.line-li-2.line-li-3.line-li-4.line-li-5 { + @include lineOverflow(8); + } + } + + .line-ol { + &.line-li-1 { + @include lineOverflow(1); + } + + &.line-li-1.line-li-2 { + @include lineOverflow(2); + } + + &.line-li-1.line-li-2.line-li-3 { + @include lineOverflow(4); + } + + &.line-li-1.line-li-2.line-li-3.line-li-4 { + @include lineOverflow(6); + } + + &.line-li-1.line-li-2.line-li-3.line-li-4.line-li-5 { + @include lineOverflow(8); + } + } + + .line-comment { + text-indent: -1 * 3ch; + padding-left: 3ch; + } + + .task-marker { + background-color: #ddd; + } + + .line-comment { + background-color: rgba(255, 255, 0, 0.5); + } +} diff --git a/webapp/styles/filter_box.scss b/webapp/styles/filter_box.scss new file mode 100644 index 0000000..8958884 --- /dev/null +++ b/webapp/styles/filter_box.scss @@ -0,0 +1,88 @@ +.filter-box { + position: absolute; + font-family: var(--ui-font); + margin: auto; + max-width: 500px; + height: 600px; + background-color: #fff; + left: 0; + right: 0; + top: 0; + bottom: 0; + max-height: 290px; + overflow: auto; + z-index: 100; + border: rgb(103, 103, 103) 1px solid; + border-radius: 8px; + box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px; + + .header { + border-bottom: 1px rgb(108, 108, 108) solid; + padding: 13px 10px 10px 10px; + display: flex; + label { + color: var(--highlight-color); + margin: 3px; + } + + input { + font-family: "Arial"; + background: transparent; + color: #000; + border: 0; + padding: 3px; + outline: 0; + font-size: 1em; + flex-grow: 100; + } + input::placeholder { + color: rgb(199, 199, 199); + font-weight: normal; + } + } + + .help-text { + background-color: #eee; + border-bottom: 1px rgb(108, 108, 108) solid; + padding: 5px; + color: #555; + } + + .result-list { + max-height: 200px; + overflow-y: scroll; + background-color: white; + + .icon { + padding: 0 8px 0 5px; + } + .name { + padding-top: -3px; + } + } + + .option, + .selected-option { + padding: 8px; + cursor: pointer; + } + + .selected-option { + background-color: var(--highlight-color); + color: #eee; + } + + .option .hint, + .selected-option .hint { + float: right; + margin-right: 0; + margin-top: -4px; + padding-left: 5px; + padding-right: 5px; + padding-top: 3px; + padding-bottom: 3px; + color: #eee; + background-color: #212476; + border-radius: 5px; + } +} diff --git a/webapp/styles/main.scss b/webapp/styles/main.scss new file mode 100644 index 0000000..08da7de --- /dev/null +++ b/webapp/styles/main.scss @@ -0,0 +1,88 @@ +@use "editor.scss"; +@use "filter_box.scss"; + +:root { + --ident: 18px; + /* --editor-font: "Avenir"; */ + --editor-font: "Menlo"; + --ui-font: "Arial"; + --top-bar-bg: rgb(41, 41, 41); + --highlight-color: #464cfc; +} + +html, +body { + height: 100%; + margin: 0; + padding: 0; +} + +#top { + height: 55px; + position: fixed; + top: 0; + left: 0; + right: 0; + background-color: rgb(213, 213, 213); + border-bottom: rgb(193, 193, 193) 1px solid; + color: rgb(55, 55, 55); + + .inner { + padding-top: 12px; + max-width: 800px; + font-size: 28px; + margin: auto; + + .status { + float: right; + border: rgb(41, 41, 41) 1px solid; + border-radius: 5px; + padding: 3px; + font-size: 14px; + } + .current-page { + font-family: var(--ui-font); + font-weight: bold; + } + + .icon { + padding-left: 5px; + padding-right: 10px; + } + } +} + +// #bottom { +// position: fixed; +// bottom: 0; +// left: 0; +// right: 0; +// height: 20px; +// background-color: rgb(232, 232, 232); +// color: rgb(79, 78, 78); +// border-top: rgb(186, 186, 186) 1px solid; +// margin: 0; +// padding: 5px 10px; +// font-family: var(--ui-font); +// font-size: 0.9em; +// text-align: right; +// } + +// body.keyboard #bottom { +// bottom: 250px; +// } + +#editor { + position: absolute; + top: 55px; + bottom: 0; + left: 0; + right: 0; + overflow-y: hidden; +} + +@media only screen and (max-width: 800px) { + .cm-editor .cm-content { + margin: 0 10px !important; + } +} diff --git a/webapp/syscalls/db.localstorage.ts b/webapp/syscalls/db.localstorage.ts new file mode 100644 index 0000000..b666f95 --- /dev/null +++ b/webapp/syscalls/db.localstorage.ts @@ -0,0 +1,8 @@ +export default { + "db.put": (key: string, value: any) => { + localStorage.setItem(key, value); + }, + "db.get": (key: string) => { + return localStorage.getItem(key); + }, +}; diff --git a/webapp/syscalls/editor.browser.ts b/webapp/syscalls/editor.browser.ts new file mode 100644 index 0000000..8e83e5a --- /dev/null +++ b/webapp/syscalls/editor.browser.ts @@ -0,0 +1,133 @@ +import { Editor } from "../editor"; +import { syntaxTree } from "@codemirror/language"; +import { Transaction } from "@codemirror/state"; +import { PageMeta } from "../types"; + +type SyntaxNode = { + name: string; + text: string; + from: number; + to: number; +}; + +function ensureAnchor(expr: any, start: boolean) { + var _a; + let { source } = expr; + let addStart = start && source[0] != "^", + addEnd = source[source.length - 1] != "$"; + if (!addStart && !addEnd) return expr; + return new RegExp( + `${addStart ? "^" : ""}(?:${source})${addEnd ? "$" : ""}`, + (_a = expr.flags) !== null && _a !== void 0 + ? _a + : expr.ignoreCase + ? "i" + : "" + ); +} + +export default (editor: Editor) => ({ + "editor.getCurrentPage": (): string => { + return editor.currentPage!; + }, + "editor.getText": () => { + return editor.editorView?.state.sliceDoc(); + }, + "editor.getCursor": (): number => { + return editor.editorView!.state.selection.main.from; + }, + "editor.navigate": async (name: string) => { + await editor.navigate(name); + }, + "editor.openUrl": async (url: string) => { + window.open(url, "_blank")!.focus(); + }, + "editor.insertAtPos": (text: string, pos: number) => { + editor.editorView!.dispatch({ + changes: { + insert: text, + from: pos, + }, + }); + }, + "editor.replaceRange": (from: number, to: number, text: string) => { + editor.editorView!.dispatch({ + changes: { + insert: text, + from: from, + to: to, + }, + }); + }, + "editor.moveCursor": (pos: number) => { + editor.editorView!.dispatch({ + selection: { + anchor: pos, + }, + }); + }, + "editor.insertAtCursor": (text: string) => { + let editorView = editor.editorView!; + let from = editorView.state.selection.main.from; + editorView.dispatch({ + changes: { + insert: text, + from: from, + }, + selection: { + anchor: from + text.length, + }, + }); + }, + "editor.getSyntaxNodeUnderCursor": (): SyntaxNode | undefined => { + const editorState = editor.editorView!.state; + let selection = editorState.selection.main; + if (selection.empty) { + let node = syntaxTree(editorState).resolveInner(selection.from); + if (node) { + return { + name: node.name, + text: editorState.sliceDoc(node.from, node.to), + from: node.from, + to: node.to, + }; + } + } + }, + "editor.matchBefore": ( + regexp: string + ): { from: number; to: number; text: string } | null => { + const editorState = editor.editorView!.state; + let selection = editorState.selection.main; + let from = selection.from; + if (selection.empty) { + let line = editorState.doc.lineAt(from); + let start = Math.max(line.from, from - 250); + let str = line.text.slice(start - line.from, from - line.from); + let found = str.search(ensureAnchor(new RegExp(regexp), false)); + // console.log("Line", line, start, str, new RegExp(regexp), found); + return found < 0 + ? null + : { from: start + found, to: from, text: str.slice(found) }; + } + return null; + }, + "editor.getSyntaxNodeAtPos": (pos: number): SyntaxNode | undefined => { + const editorState = editor.editorView!.state; + let node = syntaxTree(editorState).resolveInner(pos); + if (node) { + return { + name: node.name, + text: editorState.sliceDoc(node.from, node.to), + from: node.from, + to: node.to, + }; + } + }, + "editor.dispatch": (change: Transaction) => { + editor.editorView!.dispatch(change); + }, + "editor.prompt": (message: string, defaultValue = ""): string | null => { + return prompt(message, defaultValue); + }, +}); diff --git a/webapp/syscalls/indexer.native.ts b/webapp/syscalls/indexer.native.ts new file mode 100644 index 0000000..fbb97ba --- /dev/null +++ b/webapp/syscalls/indexer.native.ts @@ -0,0 +1,22 @@ +import { Space, KV } from "../space"; + +export default (space: Space) => ({ + "indexer.scanPrefixForPage": async (pageName: string, keyPrefix: string) => { + return await space.indexScanPrefixForPage(pageName, keyPrefix); + }, + "indexer.scanPrefixGlobal": async (keyPrefix: string) => { + return await space.indexScanPrefixGlobal(keyPrefix); + }, + "indexer.get": async (pageName: string, key: string): Promise => { + return await space.indexGet(pageName, key); + }, + "indexer.set": async (pageName: string, key: string, value: any) => { + await space.indexSet(pageName, key, value); + }, + "indexer.batchSet": async (pageName: string, kvs: KV[]) => { + await space.indexBatchSet(pageName, kvs); + }, + "indexer.delete": async (pageName: string, key: string) => { + await space.indexDelete(pageName, key); + }, +}); diff --git a/webapp/syscalls/space.native.ts b/webapp/syscalls/space.native.ts new file mode 100644 index 0000000..ddc5eae --- /dev/null +++ b/webapp/syscalls/space.native.ts @@ -0,0 +1,28 @@ +import { Editor } from "../editor"; +import { PageMeta } from "../types"; + +export default (editor: Editor) => ({ + "space.listPages": (): PageMeta[] => { + return [...editor.viewState.allPages]; + }, + "space.readPage": async ( + name: string + ): Promise<{ text: string; meta: PageMeta }> => { + return await editor.space.readPage(name); + }, + "space.writePage": async (name: string, text: string): Promise => { + return await editor.space.writePage(name, text); + }, + "space.deletePage": async (name: string) => { + console.log("Clearing page index", name); + await editor.space.indexDeletePrefixForPage(name, ""); + // If we're deleting the current page, navigate to the start page + if (editor.currentPage === name) { + await editor.navigate("start"); + } + // Remove page from open pages in editor + editor.openPages.delete(name); + console.log("Deleting page"); + await editor.space.deletePage(name); + }, +}); diff --git a/webapp/syscalls/ui.browser.ts b/webapp/syscalls/ui.browser.ts new file mode 100644 index 0000000..120b022 --- /dev/null +++ b/webapp/syscalls/ui.browser.ts @@ -0,0 +1,20 @@ +// @ts-ignore +let frameTest = document.getElementById("main-frame"); + +window.addEventListener("message", async (event) => { + let messageEvent = event as MessageEvent; + let data = messageEvent.data; + if (data.type === "iframe_event") { + // @ts-ignore + window.mainPlug.dispatchEvent(data.data.event, data.data.data); + } +}); + +export default { + "ui.update": function (doc: any) { + // frameTest.contentWindow.postMessage({ + // type: "loadContent", + // doc: doc, + // }); + }, +}; diff --git a/webapp/types.ts b/webapp/types.ts new file mode 100644 index 0000000..afb89b2 --- /dev/null +++ b/webapp/types.ts @@ -0,0 +1,70 @@ +import * as plugbox from "../plugbox/types"; + +export type NuggetHook = { + commands: { + [key: string]: CommandDef; + }; +}; + +export type Manifest = plugbox.Manifest; + +export type PageMeta = { + name: string; + lastModified: number; + version?: number; + lastOpened?: number; +}; + +export type AppCommand = { + command: CommandDef; + run: (arg: any) => Promise; +}; + +export const slashCommandRegexp = /\/[\w\-]*/; + +export interface CommandDef { + // Function name to invoke + invoke: string; + + // Bind to keyboard shortcut + key?: string; + mac?: string; + + // If to show in slash invoked menu and if so, with what label + // should match slashCommandRegexp + slashCommand?: string; +} + +export type Notification = { + id: number; + message: string; + date: Date; +}; + +export type AppViewState = { + currentPage?: string; + showPageNavigator: boolean; + showCommandPalette: boolean; + allPages: Set; + commands: Map; + notifications: Notification[]; +}; + +export const initialViewState: AppViewState = { + showPageNavigator: false, + showCommandPalette: false, + allPages: new Set(), + commands: new Map(), + notifications: [], +}; + +export type Action = + | { type: "page-loaded"; name: string } + | { type: "pages-listed"; pages: Set } + | { type: "start-navigate" } + | { type: "stop-navigate" } + | { type: "update-commands"; commands: Map } + | { type: "show-palette" } + | { type: "hide-palette" } + | { type: "show-notification"; notification: Notification } + | { type: "dismiss-notification"; id: number }; diff --git a/webapp/util.ts b/webapp/util.ts new file mode 100644 index 0000000..de77473 --- /dev/null +++ b/webapp/util.ts @@ -0,0 +1,31 @@ +export function countWords(str: string): number { + var matches = str.match(/[\w\d\'\'-]+/gi); + return matches ? matches.length : 0; +} + +export function readingTime(wordCount: number): number { + // 225 is average word reading speed for adults + return Math.ceil(wordCount / 225); +} + +export function safeRun(fn: () => Promise) { + fn().catch((e) => { + console.error(e); + }); +} + +export function isMacLike() { + return /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform); +} + +export function throttle(func: () => void, limit: number) { + let timer: any = null; + return function () { + if (!timer) { + timer = setTimeout(() => { + func(); + timer = null; + }, limit); + } + }; +} diff --git a/webapp/watcher.ts b/webapp/watcher.ts new file mode 100644 index 0000000..35b8f24 --- /dev/null +++ b/webapp/watcher.ts @@ -0,0 +1,2 @@ +import { Editor } from "./editor"; +import { safeRun } from "./util"; diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..105bbdb --- /dev/null +++ b/yarn.lock @@ -0,0 +1,6597 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@ampproject/remapping@^2.1.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.1.2.tgz#4edca94973ded9630d20101cd8559cedb8d8bd34" + integrity sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg== + dependencies: + "@jridgewell/trace-mapping" "^0.3.0" + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" + integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== + dependencies: + "@babel/highlight" "^7.16.7" + +"@babel/compat-data@^7.17.7": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.7.tgz#078d8b833fbbcc95286613be8c716cef2b519fa2" + integrity sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ== + +"@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.7.2", "@babel/core@^7.8.0": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.17.7.tgz#f7c28228c83cdf2dbd1b9baa06eaf9df07f0c2f9" + integrity sha512-djHlEfFHnSnTAcPb7dATbiM5HxGOP98+3JLBZtjRb5I7RXrw7kFRoG2dXM8cm3H+o11A8IFH/uprmJpwFynRNQ== + dependencies: + "@ampproject/remapping" "^2.1.0" + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.17.7" + "@babel/helper-compilation-targets" "^7.17.7" + "@babel/helper-module-transforms" "^7.17.7" + "@babel/helpers" "^7.17.7" + "@babel/parser" "^7.17.7" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.17.3" + "@babel/types" "^7.17.0" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.1.2" + semver "^6.3.0" + +"@babel/generator@^7.17.3", "@babel/generator@^7.17.7", "@babel/generator@^7.7.2": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.7.tgz#8da2599beb4a86194a3b24df6c085931d9ee45ad" + integrity sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w== + dependencies: + "@babel/types" "^7.17.0" + jsesc "^2.5.1" + source-map "^0.5.0" + +"@babel/helper-compilation-targets@^7.17.7": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.7.tgz#a3c2924f5e5f0379b356d4cfb313d1414dc30e46" + integrity sha512-UFzlz2jjd8kroj0hmCFV5zr+tQPi1dpC2cRsDV/3IEW8bJfCPrPpmcSN6ZS8RqIq4LXcmpipCQFPddyFA5Yc7w== + dependencies: + "@babel/compat-data" "^7.17.7" + "@babel/helper-validator-option" "^7.16.7" + browserslist "^4.17.5" + semver "^6.3.0" + +"@babel/helper-environment-visitor@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz#ff484094a839bde9d89cd63cba017d7aae80ecd7" + integrity sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-function-name@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz#f1ec51551fb1c8956bc8dd95f38523b6cf375f8f" + integrity sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA== + dependencies: + "@babel/helper-get-function-arity" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/types" "^7.16.7" + +"@babel/helper-get-function-arity@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz#ea08ac753117a669f1508ba06ebcc49156387419" + integrity sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-hoist-variables@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246" + integrity sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-module-imports@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" + integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-module-transforms@^7.17.7": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.17.7.tgz#3943c7f777139e7954a5355c815263741a9c1cbd" + integrity sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw== + dependencies: + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-module-imports" "^7.16.7" + "@babel/helper-simple-access" "^7.17.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/helper-validator-identifier" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.17.3" + "@babel/types" "^7.17.0" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.8.0": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5" + integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA== + +"@babel/helper-simple-access@^7.17.7": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz#aaa473de92b7987c6dfa7ce9a7d9674724823367" + integrity sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA== + dependencies: + "@babel/types" "^7.17.0" + +"@babel/helper-split-export-declaration@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b" + integrity sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-validator-identifier@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" + integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== + +"@babel/helper-validator-option@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" + integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== + +"@babel/helpers@^7.17.7": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.17.7.tgz#6fc0a24280fd00026e85424bbfed4650e76d7127" + integrity sha512-TKsj9NkjJfTBxM7Phfy7kv6yYc4ZcOo+AaWGqQOKTPDOmcGkIFb5xNA746eKisQkm4yavUYh4InYM9S+VnO01w== + dependencies: + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.17.3" + "@babel/types" "^7.17.0" + +"@babel/highlight@^7.16.7": + version "7.16.10" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.10.tgz#744f2eb81579d6eea753c227b0f570ad785aba88" + integrity sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw== + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.16.7", "@babel/parser@^7.17.3", "@babel/parser@^7.17.7": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.7.tgz#fc19b645a5456c8d6fdb6cecd3c66c0173902800" + integrity sha512-bm3AQf45vR4gKggRfvJdYJ0gFLoCbsPxiFLSH6hTVYABptNHY6l9NrhnucVjQ/X+SPtLANT9lc0fFhikj+VBRA== + +"@babel/plugin-syntax-async-generators@^7.8.4": + 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-bigint@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" + integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.8.3": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-import-meta@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-json-strings@^7.8.3": + 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-logical-assignment-operators@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + 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.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.3": + 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.3": + 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.3": + 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.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-typescript@^7.7.2": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz#39c9b55ee153151990fb038651d58d3fd03f98f8" + integrity sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/template@^7.16.7", "@babel/template@^7.3.3": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" + integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w== + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/parser" "^7.16.7" + "@babel/types" "^7.16.7" + +"@babel/traverse@^7.17.3", "@babel/traverse@^7.7.2": + version "7.17.3" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.3.tgz#0ae0f15b27d9a92ba1f2263358ea7c4e7db47b57" + integrity sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw== + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.17.3" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-hoist-variables" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/parser" "^7.17.3" + "@babel/types" "^7.17.0" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.0.0", "@babel/types@^7.16.7", "@babel/types@^7.17.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b" + integrity sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw== + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" + to-fast-properties "^2.0.0" + +"@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== + +"@codemirror/autocomplete@^0.19.0": + version "0.19.14" + resolved "https://registry.yarnpkg.com/@codemirror/autocomplete/-/autocomplete-0.19.14.tgz#5f61b0fced56e7960791063d03b21d11a63f0ec5" + integrity sha512-4PqJG7GGTePc+FQF387RFebDV4ERvKj23gQBmzNtu64ZSHlYEGulwP5EIIfulBiaWEmei9TYVaMFmTdNfofpRQ== + dependencies: + "@codemirror/language" "^0.19.0" + "@codemirror/state" "^0.19.4" + "@codemirror/text" "^0.19.2" + "@codemirror/tooltip" "^0.19.12" + "@codemirror/view" "^0.19.0" + "@lezer/common" "^0.15.0" + +"@codemirror/basic-setup@^0.19.1": + version "0.19.1" + resolved "https://registry.yarnpkg.com/@codemirror/basic-setup/-/basic-setup-0.19.1.tgz#17b27d02f15c628eb62a85d01e3e1b1958933eb4" + integrity sha512-gLjD7YgZU/we6BzS/ecCmD3viw83dsgv5ZUaSydYbYx9X4w4w9RqYnckcJ+0GDyHfNr5Jtfv2Z5ZtFQnBj0UDA== + dependencies: + "@codemirror/autocomplete" "^0.19.0" + "@codemirror/closebrackets" "^0.19.0" + "@codemirror/commands" "^0.19.0" + "@codemirror/comment" "^0.19.0" + "@codemirror/fold" "^0.19.0" + "@codemirror/gutter" "^0.19.0" + "@codemirror/highlight" "^0.19.0" + "@codemirror/history" "^0.19.0" + "@codemirror/language" "^0.19.0" + "@codemirror/lint" "^0.19.0" + "@codemirror/matchbrackets" "^0.19.0" + "@codemirror/rectangular-selection" "^0.19.0" + "@codemirror/search" "^0.19.0" + "@codemirror/state" "^0.19.0" + "@codemirror/view" "^0.19.31" + +"@codemirror/closebrackets@^0.19.0": + version "0.19.1" + resolved "https://registry.yarnpkg.com/@codemirror/closebrackets/-/closebrackets-0.19.1.tgz#c93219d6800c27a880e569135b468cf4a05d903f" + integrity sha512-ZiLXT6u+VuBK5QnfBbt/Vmfd9Pg6449wn1DIOWFZHUOldg5eFn3VGGjYY2XWuHQz5WuK+7dXamV2KE885O1gyA== + dependencies: + "@codemirror/language" "^0.19.0" + "@codemirror/rangeset" "^0.19.0" + "@codemirror/state" "^0.19.2" + "@codemirror/text" "^0.19.0" + "@codemirror/view" "^0.19.44" + +"@codemirror/collab@^0.19.0": + version "0.19.0" + resolved "https://registry.yarnpkg.com/@codemirror/collab/-/collab-0.19.0.tgz#43938671d58ef8f12e43406ddd315410d85ac1c4" + integrity sha512-pyrEXLLkby82y9wzfanEQGl3V3DX/pIuA97Js7gVEbPAqhvse5iXKNyp1Yr37afhkl2TUeoZyUSFTtcimgdI6g== + dependencies: + "@codemirror/state" "^0.19.0" + +"@codemirror/commands@^0.19.0", "@codemirror/commands@^0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@codemirror/commands/-/commands-0.19.8.tgz#1f99c1a8bf200d17c4d6997379099459f3678107" + integrity sha512-65LIMSGUGGpY3oH6mzV46YWRrgao6NmfJ+AuC7jNz3K5NPnH6GCV1H5I6SwOFyVbkiygGyd0EFwrWqywTBD1aw== + dependencies: + "@codemirror/language" "^0.19.0" + "@codemirror/matchbrackets" "^0.19.0" + "@codemirror/state" "^0.19.2" + "@codemirror/text" "^0.19.6" + "@codemirror/view" "^0.19.22" + "@lezer/common" "^0.15.0" + +"@codemirror/comment@^0.19.0": + version "0.19.1" + resolved "https://registry.yarnpkg.com/@codemirror/comment/-/comment-0.19.1.tgz#7def8345eeb9095ef1ef33676fbde1ab4fe33fad" + integrity sha512-uGKteBuVWAC6fW+Yt8u27DOnXMT/xV4Ekk2Z5mRsiADCZDqYvryrJd6PLL5+8t64BVyocwQwNfz1UswYS2CtFQ== + dependencies: + "@codemirror/state" "^0.19.9" + "@codemirror/text" "^0.19.0" + "@codemirror/view" "^0.19.0" + +"@codemirror/fold@^0.19.0": + version "0.19.3" + resolved "https://registry.yarnpkg.com/@codemirror/fold/-/fold-0.19.3.tgz#de55d44a7313f2a8920aefb6ebf9eff34715d8d4" + integrity sha512-8hT+Eq2G68mL0yPRvSD2ewhnLQAX6sbUJmtGVKFcj8oAXtfpYCX8LIcfXsuI19Qs7gZkOSpqZvn+KKj8IhZoAw== + dependencies: + "@codemirror/gutter" "^0.19.0" + "@codemirror/language" "^0.19.0" + "@codemirror/rangeset" "^0.19.0" + "@codemirror/state" "^0.19.0" + "@codemirror/view" "^0.19.22" + +"@codemirror/gutter@^0.19.0", "@codemirror/gutter@^0.19.4": + version "0.19.9" + resolved "https://registry.yarnpkg.com/@codemirror/gutter/-/gutter-0.19.9.tgz#bbb69f4d49570d9c1b3f3df5d134980c516cd42b" + integrity sha512-PFrtmilahin1g6uL27aG5tM/rqR9DZzZYZsIrCXA5Uc2OFTFqx4owuhoU9hqfYxHp5ovfvBwQ+txFzqS4vog6Q== + dependencies: + "@codemirror/rangeset" "^0.19.0" + "@codemirror/state" "^0.19.0" + "@codemirror/view" "^0.19.23" + +"@codemirror/highlight@^0.19.0", "@codemirror/highlight@^0.19.6", "@codemirror/highlight@^0.19.7": + version "0.19.7" + resolved "https://registry.yarnpkg.com/@codemirror/highlight/-/highlight-0.19.7.tgz#91a0c9994c759f5f153861e3aae74ff9e7c7c35b" + integrity sha512-3W32hBCY0pbbv/xidismw+RDMKuIag+fo4kZIbD7WoRj+Ttcaxjf+vP6RttRHXLaaqbWh031lTeON8kMlDhMYw== + dependencies: + "@codemirror/language" "^0.19.0" + "@codemirror/rangeset" "^0.19.0" + "@codemirror/state" "^0.19.3" + "@codemirror/view" "^0.19.0" + "@lezer/common" "^0.15.0" + style-mod "^4.0.0" + +"@codemirror/history@^0.19.0": + version "0.19.2" + resolved "https://registry.yarnpkg.com/@codemirror/history/-/history-0.19.2.tgz#25e3fda755f77ac1223a6ae6e9d7899f5919265e" + integrity sha512-unhP4t3N2smzmHoo/Yio6ueWi+il8gm9VKrvi6wlcdGH5fOfVDNkmjHQ495SiR+EdOG35+3iNebSPYww0vN7ow== + dependencies: + "@codemirror/state" "^0.19.2" + "@codemirror/view" "^0.19.0" + +"@codemirror/lang-css@^0.19.0": + version "0.19.3" + resolved "https://registry.yarnpkg.com/@codemirror/lang-css/-/lang-css-0.19.3.tgz#7a17adf78c6fcdab4ad5ee4e360631c41e949e4a" + integrity sha512-tyCUJR42/UlfOPLb94/p7dN+IPsYSIzHbAHP2KQHANj0I+Orqp+IyIOS++M8TuCX4zkWh9dvi8s92yy/Tn8Ifg== + dependencies: + "@codemirror/autocomplete" "^0.19.0" + "@codemirror/highlight" "^0.19.6" + "@codemirror/language" "^0.19.0" + "@codemirror/state" "^0.19.0" + "@lezer/css" "^0.15.2" + +"@codemirror/lang-html@^0.19.0": + version "0.19.4" + resolved "https://registry.yarnpkg.com/@codemirror/lang-html/-/lang-html-0.19.4.tgz#e6eec28462f18842a0e108732a214a7416b5e333" + integrity sha512-GpiEikNuCBeFnS+/TJSeanwqaOfNm8Kkp9WpVNEPZCLyW1mAMCuFJu/3xlWYeWc778Hc3vJqGn3bn+cLNubgCA== + dependencies: + "@codemirror/autocomplete" "^0.19.0" + "@codemirror/highlight" "^0.19.6" + "@codemirror/lang-css" "^0.19.0" + "@codemirror/lang-javascript" "^0.19.0" + "@codemirror/language" "^0.19.0" + "@codemirror/state" "^0.19.0" + "@lezer/common" "^0.15.0" + "@lezer/html" "^0.15.0" + +"@codemirror/lang-javascript@^0.19.0": + version "0.19.7" + resolved "https://registry.yarnpkg.com/@codemirror/lang-javascript/-/lang-javascript-0.19.7.tgz#84581ef6abf2a16d78f017ffc96c2d6227de5eb5" + integrity sha512-DL9f3JLqOEHH9cIwEqqjnP5bkjdVXeECksLtV+/MbPm+l4H+AG+PkwZaJQ2oR1GfPZKh8MVSIE94aGWNkJP8WQ== + dependencies: + "@codemirror/autocomplete" "^0.19.0" + "@codemirror/highlight" "^0.19.7" + "@codemirror/language" "^0.19.0" + "@codemirror/lint" "^0.19.0" + "@codemirror/state" "^0.19.0" + "@codemirror/view" "^0.19.0" + "@lezer/javascript" "^0.15.1" + +"@codemirror/lang-markdown@^0.19.6": + version "0.19.6" + resolved "https://registry.yarnpkg.com/@codemirror/lang-markdown/-/lang-markdown-0.19.6.tgz#761301d276fcfbdf88440f0333785efd71c2a4f5" + integrity sha512-ojoHeLgv1Rfu0GNGsU0bCtXAIp5dy4VKjndHScITQdlCkS/+SAIfuoeowEx+nMAQwTxI+/9fQZ3xdZVznGFYug== + dependencies: + "@codemirror/highlight" "^0.19.0" + "@codemirror/lang-html" "^0.19.0" + "@codemirror/language" "^0.19.0" + "@codemirror/state" "^0.19.3" + "@codemirror/view" "^0.19.0" + "@lezer/common" "^0.15.0" + "@lezer/markdown" "^0.15.0" + +"@codemirror/language@^0.19.0": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@codemirror/language/-/language-0.19.8.tgz#fddaa76affb44d71e84dfde7308058732b88c064" + integrity sha512-KhRne8qmzSKkaw+qhkwgNsPKxmThlyeJ3umfc33B9kJzVP7xhTkwX2MEPl0almM3brxMi+lPYx7gCPOy1gHsWw== + dependencies: + "@codemirror/state" "^0.19.0" + "@codemirror/text" "^0.19.0" + "@codemirror/view" "^0.19.0" + "@lezer/common" "^0.15.5" + "@lezer/lr" "^0.15.0" + +"@codemirror/lint@^0.19.0": + version "0.19.6" + resolved "https://registry.yarnpkg.com/@codemirror/lint/-/lint-0.19.6.tgz#0379688da3e16739db4a6304c73db857ca85d7ec" + integrity sha512-Pbw1Y5kHVs2J+itQ0uez3dI4qY9ApYVap7eNfV81x1/3/BXgBkKfadaw0gqJ4h4FDG7OnJwb0VbPsjJQllHjaA== + dependencies: + "@codemirror/gutter" "^0.19.4" + "@codemirror/panel" "^0.19.0" + "@codemirror/rangeset" "^0.19.1" + "@codemirror/state" "^0.19.4" + "@codemirror/tooltip" "^0.19.16" + "@codemirror/view" "^0.19.22" + crelt "^1.0.5" + +"@codemirror/matchbrackets@^0.19.0": + version "0.19.4" + resolved "https://registry.yarnpkg.com/@codemirror/matchbrackets/-/matchbrackets-0.19.4.tgz#50b5188eb2d53f32598dca906bf5fd66626a9ebc" + integrity sha512-VFkaOKPNudAA5sGP1zikRHCEKU0hjYmkKpr04pybUpQvfTvNJXlReCyP0rvH/1iEwAGPL990ZTT+QrLdu4MeEA== + dependencies: + "@codemirror/language" "^0.19.0" + "@codemirror/state" "^0.19.0" + "@codemirror/view" "^0.19.0" + "@lezer/common" "^0.15.0" + +"@codemirror/panel@^0.19.0": + version "0.19.1" + resolved "https://registry.yarnpkg.com/@codemirror/panel/-/panel-0.19.1.tgz#bf77d27b962cf16357139e50864d0eb69d634441" + integrity sha512-sYeOCMA3KRYxZYJYn5PNlt9yNsjy3zTNTrbYSfVgjgL9QomIVgOJWPO5hZ2sTN8lufO6lw0vTBsIPL9MSidmBg== + dependencies: + "@codemirror/state" "^0.19.0" + "@codemirror/view" "^0.19.0" + +"@codemirror/rangeset@^0.19.0", "@codemirror/rangeset@^0.19.1", "@codemirror/rangeset@^0.19.5": + version "0.19.9" + resolved "https://registry.yarnpkg.com/@codemirror/rangeset/-/rangeset-0.19.9.tgz#e80895de93c39dc7899f5be31d368c9d88aa4efc" + integrity sha512-V8YUuOvK+ew87Xem+71nKcqu1SXd5QROMRLMS/ljT5/3MCxtgrRie1Cvild0G/Z2f1fpWxzX78V0U4jjXBorBQ== + dependencies: + "@codemirror/state" "^0.19.0" + +"@codemirror/rectangular-selection@^0.19.0": + version "0.19.1" + resolved "https://registry.yarnpkg.com/@codemirror/rectangular-selection/-/rectangular-selection-0.19.1.tgz#5a88ece4fb68ce5682539497db8a64fc015aae63" + integrity sha512-9ElnqOg3mpZIWe0prPRd1SZ48Q9QB3bR8Aocq8UtjboJSUG8ABhRrbuTZMW/rMqpBPSjVpCe9xkCCkEQMYQVmw== + dependencies: + "@codemirror/state" "^0.19.0" + "@codemirror/text" "^0.19.4" + "@codemirror/view" "^0.19.0" + +"@codemirror/search@^0.19.0": + version "0.19.9" + resolved "https://registry.yarnpkg.com/@codemirror/search/-/search-0.19.9.tgz#b9548dfeb2028e6d5ecd1965f8f0ee50e2925603" + integrity sha512-h3MuwbUbiyOp6Np3IB5r4LH0w4inZvbtLO1Ipmz8RhElcGRiYr11Q6Bim8ocLfe08RmZT6B5EkTj1E8eNlugQQ== + dependencies: + "@codemirror/panel" "^0.19.0" + "@codemirror/rangeset" "^0.19.0" + "@codemirror/state" "^0.19.3" + "@codemirror/text" "^0.19.0" + "@codemirror/view" "^0.19.34" + crelt "^1.0.5" + +"@codemirror/state@^0.19.0", "@codemirror/state@^0.19.2", "@codemirror/state@^0.19.3", "@codemirror/state@^0.19.4", "@codemirror/state@^0.19.7", "@codemirror/state@^0.19.9": + version "0.19.9" + resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-0.19.9.tgz#b797f9fbc204d6dc7975485e231693c09001b0dd" + integrity sha512-psOzDolKTZkx4CgUqhBQ8T8gBc0xN5z4gzed109aF6x7D7umpDRoimacI/O6d9UGuyl4eYuDCZmDFr2Rq7aGOw== + dependencies: + "@codemirror/text" "^0.19.0" + +"@codemirror/text@^0.19.0", "@codemirror/text@^0.19.2", "@codemirror/text@^0.19.4", "@codemirror/text@^0.19.6": + version "0.19.6" + resolved "https://registry.yarnpkg.com/@codemirror/text/-/text-0.19.6.tgz#9adcbd8137f69b75518eacd30ddb16fd67bbac45" + integrity sha512-T9jnREMIygx+TPC1bOuepz18maGq/92q2a+n4qTqObKwvNMg+8cMTslb8yxeEDEq7S3kpgGWxgO1UWbQRij0dA== + +"@codemirror/tooltip@^0.19.12", "@codemirror/tooltip@^0.19.16": + version "0.19.16" + resolved "https://registry.yarnpkg.com/@codemirror/tooltip/-/tooltip-0.19.16.tgz#6ba2c43f9d8e3d943d9d7bbae22bf800f7726a22" + integrity sha512-zxKDHryUV5/RS45AQL+wOeN+i7/l81wK56OMnUPoTSzCWNITfxHn7BToDsjtrRKbzHqUxKYmBnn/4hPjpZ4WJQ== + dependencies: + "@codemirror/state" "^0.19.0" + "@codemirror/view" "^0.19.0" + +"@codemirror/view@^0.19.0", "@codemirror/view@^0.19.22", "@codemirror/view@^0.19.23", "@codemirror/view@^0.19.31", "@codemirror/view@^0.19.34", "@codemirror/view@^0.19.42", "@codemirror/view@^0.19.44": + version "0.19.47" + resolved "https://registry.yarnpkg.com/@codemirror/view/-/view-0.19.47.tgz#2163c3016d7680bf50dd695c0e3abdaf80f45363" + integrity sha512-SfbagKvJQl5dtt+9wYpo9sa3ZkMgUxTq+/hXDf0KVwIx+zu3cJIqfEm9xSx6yXkq7it7RsPGHaPasApNffF/8g== + dependencies: + "@codemirror/rangeset" "^0.19.5" + "@codemirror/state" "^0.19.3" + "@codemirror/text" "^0.19.0" + style-mod "^4.0.0" + w3c-keyname "^2.2.4" + +"@fortawesome/fontawesome-common-types@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.3.0.tgz#949995a05c0d8801be7e0a594f775f1dbaa0d893" + integrity sha512-CA3MAZBTxVsF6SkfkHXDerkhcQs0QPofy43eFdbWJJkZiq3SfiaH1msOkac59rQaqto5EqWnASboY1dBuKen5w== + +"@fortawesome/fontawesome-svg-core@1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.3.0.tgz#343fac91fa87daa630d26420bfedfba560f85885" + integrity sha512-UIL6crBWhjTNQcONt96ExjUnKt1D68foe3xjEensLDclqQ6YagwCRYVQdrp/hW0ALRp/5Fv/VKw+MqTUWYYvPg== + dependencies: + "@fortawesome/fontawesome-common-types" "^0.3.0" + +"@fortawesome/free-solid-svg-icons@6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.0.0.tgz#bed4a501b631c6cfa35c09830f7cb63ffca1589d" + integrity sha512-o4FZ1XbndcgeWNb8Wh0y+Hgf73CjmyOQowUSaqQCtgIIdS+XliSBSOwCl330wER+I6CGYE96hT27bHBPmzX2Gg== + dependencies: + "@fortawesome/fontawesome-common-types" "^0.3.0" + +"@fortawesome/react-fontawesome@0.1.17": + version "0.1.17" + resolved "https://registry.yarnpkg.com/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.17.tgz#06fc06cb1a721e38e5b50b4a1cb851e9b9c77d7a" + integrity sha512-dX43Z5IvMaW7fwzU8farosYjKNGfRb2HB/DgjVBHeJZ/NSnuuaujPPx0YOdcAq+n3mqn70tyCde2HM1mqbhiuw== + dependencies: + prop-types "^15.8.1" + +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== + dependencies: + camelcase "^5.3.1" + find-up "^4.1.0" + get-package-type "^0.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" + +"@istanbuljs/schema@^0.1.2": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + +"@jest/console@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.5.1.tgz#260fe7239602fe5130a94f1aa386eff54b014bba" + integrity sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg== + dependencies: + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^27.5.1" + jest-util "^27.5.1" + slash "^3.0.0" + +"@jest/core@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.5.1.tgz#267ac5f704e09dc52de2922cbf3af9edcd64b626" + integrity sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ== + dependencies: + "@jest/console" "^27.5.1" + "@jest/reporters" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.8.1" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-changed-files "^27.5.1" + jest-config "^27.5.1" + jest-haste-map "^27.5.1" + jest-message-util "^27.5.1" + jest-regex-util "^27.5.1" + jest-resolve "^27.5.1" + jest-resolve-dependencies "^27.5.1" + jest-runner "^27.5.1" + jest-runtime "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + jest-validate "^27.5.1" + jest-watcher "^27.5.1" + micromatch "^4.0.4" + rimraf "^3.0.0" + slash "^3.0.0" + strip-ansi "^6.0.0" + +"@jest/environment@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.5.1.tgz#d7425820511fe7158abbecc010140c3fd3be9c74" + integrity sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA== + dependencies: + "@jest/fake-timers" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + jest-mock "^27.5.1" + +"@jest/fake-timers@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.5.1.tgz#76979745ce0579c8a94a4678af7a748eda8ada74" + integrity sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ== + dependencies: + "@jest/types" "^27.5.1" + "@sinonjs/fake-timers" "^8.0.1" + "@types/node" "*" + jest-message-util "^27.5.1" + jest-mock "^27.5.1" + jest-util "^27.5.1" + +"@jest/globals@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.5.1.tgz#7ac06ce57ab966566c7963431cef458434601b2b" + integrity sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/types" "^27.5.1" + expect "^27.5.1" + +"@jest/reporters@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.5.1.tgz#ceda7be96170b03c923c37987b64015812ffec04" + integrity sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.2" + graceful-fs "^4.2.9" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^5.1.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.1.3" + jest-haste-map "^27.5.1" + jest-resolve "^27.5.1" + jest-util "^27.5.1" + jest-worker "^27.5.1" + slash "^3.0.0" + source-map "^0.6.0" + string-length "^4.0.1" + terminal-link "^2.0.0" + v8-to-istanbul "^8.1.0" + +"@jest/source-map@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.5.1.tgz#6608391e465add4205eae073b55e7f279e04e8cf" + integrity sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg== + dependencies: + callsites "^3.0.0" + graceful-fs "^4.2.9" + source-map "^0.6.0" + +"@jest/test-result@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.5.1.tgz#56a6585fa80f7cdab72b8c5fc2e871d03832f5bb" + integrity sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag== + dependencies: + "@jest/console" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + +"@jest/test-sequencer@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz#4057e0e9cea4439e544c6353c6affe58d095745b" + integrity sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ== + dependencies: + "@jest/test-result" "^27.5.1" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-runtime "^27.5.1" + +"@jest/transform@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.5.1.tgz#6c3501dcc00c4c08915f292a600ece5ecfe1f409" + integrity sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw== + dependencies: + "@babel/core" "^7.1.0" + "@jest/types" "^27.5.1" + babel-plugin-istanbul "^6.1.1" + chalk "^4.0.0" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-regex-util "^27.5.1" + jest-util "^27.5.1" + micromatch "^4.0.4" + pirates "^4.0.4" + slash "^3.0.0" + source-map "^0.6.1" + write-file-atomic "^3.0.0" + +"@jest/types@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.5.1.tgz#3c79ec4a8ba61c170bf937bcf9e98a9df175ec80" + integrity sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^16.0.0" + chalk "^4.0.0" + +"@jridgewell/resolve-uri@^3.0.3": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz#68eb521368db76d040a6315cdb24bf2483037b9c" + integrity sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew== + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.11" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz#771a1d8d744eeb71b6adb35808e1a6c7b9b8c8ec" + integrity sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg== + +"@jridgewell/trace-mapping@^0.3.0": + version "0.3.4" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz#f6a0832dffd5b8a6aaa633b7d9f8e8e94c83a0c3" + integrity sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@lezer/common@^0.15.0", "@lezer/common@^0.15.5", "@lezer/common@https://github.com/zefhemel/common.git#046c880d1fcab713cadad327a5b7d8bb5de6522c": + version "0.15.11" + resolved "https://github.com/zefhemel/common.git#046c880d1fcab713cadad327a5b7d8bb5de6522c" + +"@lezer/css@^0.15.2": + version "0.15.2" + resolved "https://registry.yarnpkg.com/@lezer/css/-/css-0.15.2.tgz#e96995da67df90bb4b191aaa8a486349cca5d8e7" + integrity sha512-tnMOMZY0Zs6JQeVjqfmREYMV0GnmZR1NitndLWioZMD6mA7VQF/PPKPmJX1f+ZgVZQc5Am0df9mX3aiJnNJlKQ== + dependencies: + "@lezer/lr" "^0.15.0" + +"@lezer/html@^0.15.0": + version "0.15.1" + resolved "https://registry.yarnpkg.com/@lezer/html/-/html-0.15.1.tgz#973a5a179560d0789bf8737c06e6d143cc211406" + integrity sha512-0ZYVhu+RwN6ZMM0gNnTxenRAdoycKc2wvpLfMjP0JkKR0vMxhtuLaIpsq9KW2Mv6l7ux5vdjq8CQ7fKDvia8KA== + dependencies: + "@lezer/lr" "^0.15.0" + +"@lezer/javascript@^0.15.1": + version "0.15.3" + resolved "https://registry.yarnpkg.com/@lezer/javascript/-/javascript-0.15.3.tgz#833a4c5650bae07805b9af88de6706368844dc55" + integrity sha512-8jA2NpOfpWwSPZxRhd9BxK2ZPvGd7nLE3LFTJ5AbMhXAzMHeMjneV6GEVd7dAIee85dtap0jdb6bgOSO0+lfwA== + dependencies: + "@lezer/lr" "^0.15.0" + +"@lezer/lr@^0.15.0": + version "0.15.8" + resolved "https://registry.yarnpkg.com/@lezer/lr/-/lr-0.15.8.tgz#1564a911e62b0a0f75ca63794a6aa8c5dc63db21" + integrity sha512-bM6oE6VQZ6hIFxDNKk8bKPa14hqFrV07J/vHGOeiAbJReIaQXmkVb6xQu4MR+JBTLa5arGRyAAjJe1qaQt3Uvg== + dependencies: + "@lezer/common" "^0.15.0" + +"@lezer/markdown@^0.15.0": + version "0.15.5" + resolved "https://registry.yarnpkg.com/@lezer/markdown/-/markdown-0.15.5.tgz#0e9ef3e44b452cf0a0f7cd11a4d4ca0ca180a4d2" + integrity sha512-ZWCZn1FTQFw70RZFmyWRKHsKYTw8OTPc1SmYWMf6xwz83SNd/MIlXcOoyLLwE3/THfUMmnnSjj2ozfPtqA3mFg== + dependencies: + "@lezer/common" "^0.15.0" + +"@parcel/bundler-default@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/bundler-default/-/bundler-default-2.3.2.tgz#329f171e210dfb22beaa52ae706ccde1dae384c1" + integrity sha512-JUrto4mjSD0ic9dEqRp0loL5o3HVYHja1ZIYSq+rBl2UWRV6/9cGTb07lXOCqqm0BWE+hQ4krUxB76qWaF0Lqw== + dependencies: + "@parcel/diagnostic" "2.3.2" + "@parcel/hash" "2.3.2" + "@parcel/plugin" "2.3.2" + "@parcel/utils" "2.3.2" + nullthrows "^1.1.1" + +"@parcel/cache@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/cache/-/cache-2.3.2.tgz#ba8c2af02fd45b90c7bc6f829bfc566d1ded0a13" + integrity sha512-Xxq+ekgcFEme6Fn1v7rEOBkyMOUOUu7eNqQw0l6HQS+INZ2Q7YzzfdW7pI8rEOAAICVg5BWKpmBQZpgJlT+HxQ== + dependencies: + "@parcel/fs" "2.3.2" + "@parcel/logger" "2.3.2" + "@parcel/utils" "2.3.2" + lmdb "^2.0.2" + +"@parcel/codeframe@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/codeframe/-/codeframe-2.3.2.tgz#73fb5a89910b977342808ca8f6ece61fa01b7690" + integrity sha512-ireQALcxxrTdIEpzTOoMo/GpfbFm1qlyezeGl3Hce3PMvHLg3a5S6u/Vcy7SAjdld5GfhHEqVY+blME6Z4CyXQ== + dependencies: + chalk "^4.1.0" + +"@parcel/compressor-raw@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/compressor-raw/-/compressor-raw-2.3.2.tgz#1a808ae9e61ed86f655935e1d2a984383b3c00a7" + integrity sha512-8dIoFwinYK6bOTpnZOAwwIv0v73y0ezsctPmfMnIqVQPn7wJwfhw/gbKVcmK5AkgQMkyid98hlLZoaZtGF1Mdg== + dependencies: + "@parcel/plugin" "2.3.2" + +"@parcel/config-default@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/config-default/-/config-default-2.3.2.tgz#3f21a37fa07b22de9cd6b1aea19bc310a02d4abb" + integrity sha512-E7/iA7fGCYvXU3u6zF9nxjeDVsgjCN6MVvDjymjaxYMoDWTIsPV245SBEXqzgtmzbMAV+VAl4rVWLMB4pzMt9g== + dependencies: + "@parcel/bundler-default" "2.3.2" + "@parcel/compressor-raw" "2.3.2" + "@parcel/namer-default" "2.3.2" + "@parcel/optimizer-cssnano" "2.3.2" + "@parcel/optimizer-htmlnano" "2.3.2" + "@parcel/optimizer-image" "2.3.2" + "@parcel/optimizer-svgo" "2.3.2" + "@parcel/optimizer-terser" "2.3.2" + "@parcel/packager-css" "2.3.2" + "@parcel/packager-html" "2.3.2" + "@parcel/packager-js" "2.3.2" + "@parcel/packager-raw" "2.3.2" + "@parcel/packager-svg" "2.3.2" + "@parcel/reporter-dev-server" "2.3.2" + "@parcel/resolver-default" "2.3.2" + "@parcel/runtime-browser-hmr" "2.3.2" + "@parcel/runtime-js" "2.3.2" + "@parcel/runtime-react-refresh" "2.3.2" + "@parcel/runtime-service-worker" "2.3.2" + "@parcel/transformer-babel" "2.3.2" + "@parcel/transformer-css" "2.3.2" + "@parcel/transformer-html" "2.3.2" + "@parcel/transformer-image" "2.3.2" + "@parcel/transformer-js" "2.3.2" + "@parcel/transformer-json" "2.3.2" + "@parcel/transformer-postcss" "2.3.2" + "@parcel/transformer-posthtml" "2.3.2" + "@parcel/transformer-raw" "2.3.2" + "@parcel/transformer-react-refresh-wrap" "2.3.2" + "@parcel/transformer-svg" "2.3.2" + +"@parcel/core@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/core/-/core-2.3.2.tgz#1b9a79c1ff96dba5e0f53d4277bed4e7ab4590d0" + integrity sha512-gdJzpsgeUhv9H8T0UKVmyuptiXdduEfKIUx0ci+/PGhq8cCoiFnlnuhW6H7oLr79OUc+YJStabDJuG4U2A6ysw== + dependencies: + "@parcel/cache" "2.3.2" + "@parcel/diagnostic" "2.3.2" + "@parcel/events" "2.3.2" + "@parcel/fs" "2.3.2" + "@parcel/graph" "2.3.2" + "@parcel/hash" "2.3.2" + "@parcel/logger" "2.3.2" + "@parcel/package-manager" "2.3.2" + "@parcel/plugin" "2.3.2" + "@parcel/source-map" "^2.0.0" + "@parcel/types" "2.3.2" + "@parcel/utils" "2.3.2" + "@parcel/workers" "2.3.2" + abortcontroller-polyfill "^1.1.9" + base-x "^3.0.8" + browserslist "^4.6.6" + clone "^2.1.1" + dotenv "^7.0.0" + dotenv-expand "^5.1.0" + json-source-map "^0.6.1" + json5 "^2.2.0" + msgpackr "^1.5.1" + nullthrows "^1.1.1" + semver "^5.7.1" + +"@parcel/diagnostic@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/diagnostic/-/diagnostic-2.3.2.tgz#1d3f0b55bfd9839c6f41d704ebbc89a96cca88dc" + integrity sha512-/xW93Az4AOiifuYW/c4CDbUcu3lx5FcUDAj9AGiR9NSTsF/ROC/RqnxvQ3AGtqa14R7vido4MXEpY3JEp6FsqA== + dependencies: + json-source-map "^0.6.1" + nullthrows "^1.1.1" + +"@parcel/events@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/events/-/events-2.3.2.tgz#b6bcfbbc96d883716ee9d0e6ab232acdee862790" + integrity sha512-WiYIwXMo4Vd+pi58vRoHkul8TPE5VEfMY+3FYwVCKPl/LYqSD+vz6wMx9uG18mEbB1d/ofefv5ZFQNtPGKO4tQ== + +"@parcel/fs-search@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/fs-search/-/fs-search-2.3.2.tgz#18611877ac1b370932c71987c2ec0e93a4a7e53d" + integrity sha512-u3DTEFnPtKuZvEtgGzfVjQUytegSSn3POi7WfwMwPIaeDPfYcyyhfl+c96z7VL9Gk/pqQ99/cGyAwFdFsnxxXA== + dependencies: + detect-libc "^1.0.3" + +"@parcel/fs@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/fs/-/fs-2.3.2.tgz#9628441a84c2582e1f6e69549feb0da0cc143e40" + integrity sha512-XV+OsnRpN01QKU37lBN0TFKvv7uPKfQGbqFqYOrMbXH++Ae8rBU0Ykz+Yu4tv2h7shMlde+AMKgRnRTAJZpWEQ== + dependencies: + "@parcel/fs-search" "2.3.2" + "@parcel/types" "2.3.2" + "@parcel/utils" "2.3.2" + "@parcel/watcher" "^2.0.0" + "@parcel/workers" "2.3.2" + +"@parcel/graph@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/graph/-/graph-2.3.2.tgz#4194816952ab322ab22a17f7d9ea17befbade64d" + integrity sha512-ltTBM3IEqumgmy4ABBFETT8NtAwSsjD9mY3WCyJ5P8rUshfVCg093rvBPbpuJYMaH/TV1AHVaWfZqaZ4JQDIQQ== + dependencies: + "@parcel/utils" "2.3.2" + nullthrows "^1.1.1" + +"@parcel/hash@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/hash/-/hash-2.3.2.tgz#33b8ff04bb44f6661bdc1054b302ef1b6bd3acb3" + integrity sha512-SMtYTsHihws/wqdVnOr0QAGyGYsW9rJSJkkoRujUxo8l2ctnBN1ztv89eOUrdtgHsmcnj/oz1yw6sN38X+BUng== + dependencies: + detect-libc "^1.0.3" + xxhash-wasm "^0.4.2" + +"@parcel/logger@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/logger/-/logger-2.3.2.tgz#b5fc7a9c1664ee0286d0f67641c7c81c8fec1561" + integrity sha512-jIWd8TXDQf+EnNWSa7Q10lSQ6C1LSH8OZkTlaINrfVIw7s+3tVxO3I4pjp7/ARw7RX2gdNPlw6fH4Gn/HvvYbw== + dependencies: + "@parcel/diagnostic" "2.3.2" + "@parcel/events" "2.3.2" + +"@parcel/markdown-ansi@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/markdown-ansi/-/markdown-ansi-2.3.2.tgz#2a5be7ce76a506a9d238ea2257cb28e43abe4902" + integrity sha512-l01ggmag5QScCk9mYA0xHh5TWSffR84uPFP2KvaAMQQ9NLNufcFiU0mn/Mtr3pCb5L5dSzmJ+Oo9s7P1Kh/Fmg== + dependencies: + chalk "^4.1.0" + +"@parcel/namer-default@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/namer-default/-/namer-default-2.3.2.tgz#84e17abfc84fd293b23b3f405280ed2e279c75d8" + integrity sha512-3QUMC0+5+3KMKfoAxYAbpZtuRqTgyZKsGDWzOpuqwemqp6P8ahAvNPwSCi6QSkGcTmvtYwBu9/NHPSONxIFOfg== + dependencies: + "@parcel/diagnostic" "2.3.2" + "@parcel/plugin" "2.3.2" + nullthrows "^1.1.1" + +"@parcel/node-resolver-core@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/node-resolver-core/-/node-resolver-core-2.3.2.tgz#dd360f405949fdcd62980cd44825052ab28f6135" + integrity sha512-wmrnMNzJN4GuHw2Ftho+BWgSWR6UCkW3XoMdphqcxpw/ieAdS2a+xYSosYkZgQZ6lGutSvLyJ1CkVvP6RLIdQQ== + dependencies: + "@parcel/diagnostic" "2.3.2" + "@parcel/utils" "2.3.2" + nullthrows "^1.1.1" + +"@parcel/optimizer-cssnano@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/optimizer-cssnano/-/optimizer-cssnano-2.3.2.tgz#70758f6646fd4debc26a90ae7dddf398928c0ce1" + integrity sha512-wTBOxMiBI38NAB9XIlQZRCjS59+EWjWR9M04D3TWyxl+dL5gYMc1cl4GNynUnmcPdz+3s1UbOdo5/8V90wjiiw== + dependencies: + "@parcel/plugin" "2.3.2" + "@parcel/source-map" "^2.0.0" + cssnano "^5.0.15" + postcss "^8.4.5" + +"@parcel/optimizer-data-url@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/optimizer-data-url/-/optimizer-data-url-2.3.2.tgz#22c2951eb6bda7d7b589c28283d99f9d21dae568" + integrity sha512-q3Y1J3acGPf8yyAhEG+59qey7liB04T/U4i7nmvggDdDVG9S8aYgIeAjsPUKi/9fBoHLn4l8K/sJq3M7FFdcnw== + dependencies: + "@parcel/plugin" "2.3.2" + "@parcel/utils" "2.3.2" + isbinaryfile "^4.0.2" + mime "^2.4.4" + +"@parcel/optimizer-htmlnano@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/optimizer-htmlnano/-/optimizer-htmlnano-2.3.2.tgz#4086736866621182f5dd1a8abe78e9f5764e1a28" + integrity sha512-U8C0TDSxsx8HmHaLW0Zc7ha1fXQynzhvBjCRMGYnOiLiw0MOfLQxzQ2WKVSeCotmdlF63ayCwxWsd6BuqStiKQ== + dependencies: + "@parcel/plugin" "2.3.2" + htmlnano "^2.0.0" + nullthrows "^1.1.1" + posthtml "^0.16.5" + svgo "^2.4.0" + +"@parcel/optimizer-image@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/optimizer-image/-/optimizer-image-2.3.2.tgz#0549cc1abc99fdd6f46bd44ce8551eb135e44d4f" + integrity sha512-HOk3r5qdvY/PmI7Q3i2qEgFH3kP2QWG4Wq3wmC4suaF1+c2gpiQc+HKHWp4QvfbH3jhT00c5NxQyqPhbXeNI9Q== + dependencies: + "@parcel/diagnostic" "2.3.2" + "@parcel/plugin" "2.3.2" + "@parcel/utils" "2.3.2" + "@parcel/workers" "2.3.2" + detect-libc "^1.0.3" + +"@parcel/optimizer-svgo@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/optimizer-svgo/-/optimizer-svgo-2.3.2.tgz#ebf2f48f356ad557d2bbfae361520d3d29bc1c37" + integrity sha512-l7WvZ5+e7D1mVmLUxMVaSb29cviXzuvSY2OpQs0ukdPACDqag+C65hWMzwTiOSSRGPMIu96kQKpeVru2YjibhA== + dependencies: + "@parcel/diagnostic" "2.3.2" + "@parcel/plugin" "2.3.2" + "@parcel/utils" "2.3.2" + svgo "^2.4.0" + +"@parcel/optimizer-terser@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/optimizer-terser/-/optimizer-terser-2.3.2.tgz#790b69e6ecc6ef0d8f25b57e9a13806e1f1c2943" + integrity sha512-dOapHhfy0xiNZa2IoEyHGkhhla07xsja79NPem14e5jCqY6Oi40jKNV4ab5uu5u1elWUjJuw69tiYbkDZWbKQw== + dependencies: + "@parcel/diagnostic" "2.3.2" + "@parcel/plugin" "2.3.2" + "@parcel/source-map" "^2.0.0" + "@parcel/utils" "2.3.2" + nullthrows "^1.1.1" + terser "^5.2.0" + +"@parcel/package-manager@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/package-manager/-/package-manager-2.3.2.tgz#380f0741c9d0c79c170c437efae02506484df315" + integrity sha512-pAQfywKVORY8Ee+NHAyKzzQrKbnz8otWRejps7urwhDaTVLfAd5C/1ZV64ATZ9ALYP9jyoQ8bTaxVd4opcSuwg== + dependencies: + "@parcel/diagnostic" "2.3.2" + "@parcel/fs" "2.3.2" + "@parcel/logger" "2.3.2" + "@parcel/types" "2.3.2" + "@parcel/utils" "2.3.2" + "@parcel/workers" "2.3.2" + semver "^5.7.1" + +"@parcel/packager-css@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/packager-css/-/packager-css-2.3.2.tgz#4994d872449843c1c0cda524b6df3327e2f0a121" + integrity sha512-ByuF9xDnQnpVL1Hdu9aY6SpxOuZowd3TH7joh1qdRPLeMHTEvUywHBXoiAyNdrhnLGum8uPEdY8Ra5Xuo1U7kg== + dependencies: + "@parcel/plugin" "2.3.2" + "@parcel/source-map" "^2.0.0" + "@parcel/utils" "2.3.2" + nullthrows "^1.1.1" + +"@parcel/packager-html@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/packager-html/-/packager-html-2.3.2.tgz#e54085fbaa49bed4258ffef80bc36b421895965f" + integrity sha512-YqAptdU+uqfgwSii76mRGcA/3TpuC6yHr8xG+11brqj/tEFLsurmX0naombzd7FgmrTE9w+kb0HUIMl2vRBn0A== + dependencies: + "@parcel/plugin" "2.3.2" + "@parcel/types" "2.3.2" + "@parcel/utils" "2.3.2" + nullthrows "^1.1.1" + posthtml "^0.16.5" + +"@parcel/packager-js@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/packager-js/-/packager-js-2.3.2.tgz#2d2566bde0da921042b79aa827c71109665d795c" + integrity sha512-3OP0Ro9M1J+PIKZK4Ec2N5hjIPiqk++B2kMFeiUqvaNZjJgKrPPEICBhjS52rma4IE/NgmIMB3aI5pWqE/KwNA== + dependencies: + "@parcel/diagnostic" "2.3.2" + "@parcel/hash" "2.3.2" + "@parcel/plugin" "2.3.2" + "@parcel/source-map" "^2.0.0" + "@parcel/utils" "2.3.2" + globals "^13.2.0" + nullthrows "^1.1.1" + +"@parcel/packager-raw-url@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/packager-raw-url/-/packager-raw-url-2.3.2.tgz#9dc8e9a5cb3f12a41ec15603aa81e973e015fcd4" + integrity sha512-xkV/fC5OtMi8xIOO6aRAQcIR2rmRfKvVCME4aXfMj4pKSqvZKyF75/UsIezAt41GTaO0H/hYIUTQUJdzI0wq5g== + dependencies: + "@parcel/plugin" "2.3.2" + "@parcel/utils" "2.3.2" + +"@parcel/packager-raw@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/packager-raw/-/packager-raw-2.3.2.tgz#869cc3e7bee8ff3655891a0af400cf4e7dd4f144" + integrity sha512-RnoZ7WgNAFWkEPrEefvyDqus7xfv9XGprHyTbfLittPaVAZpl+4eAv43nXyMfzk77Cgds6KcNpkosj3acEpNIQ== + dependencies: + "@parcel/plugin" "2.3.2" + +"@parcel/packager-svg@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/packager-svg/-/packager-svg-2.3.2.tgz#a7a02e22642ae93f42b8bfd7d122b4a159988743" + integrity sha512-iIC0VeczOXynS7M5jCi3naMBRyAznBVJ3iMg92/GaI9duxPlUMGAlHzLAKNtoXkc00HMXDH7rrmMb04VX6FYSg== + dependencies: + "@parcel/plugin" "2.3.2" + "@parcel/types" "2.3.2" + "@parcel/utils" "2.3.2" + posthtml "^0.16.4" + +"@parcel/plugin@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/plugin/-/plugin-2.3.2.tgz#7701c40567d2eddd5d5b2b6298949cd03a2a22fa" + integrity sha512-SaLZAJX4KH+mrAmqmcy9KJN+V7L+6YNTlgyqYmfKlNiHu7aIjLL+3prX8QRcgGtjAYziCxvPj0cl1CCJssaiGg== + dependencies: + "@parcel/types" "2.3.2" + +"@parcel/reporter-cli@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/reporter-cli/-/reporter-cli-2.3.2.tgz#0617e088aac5ef7fa255d088e7016bb4f9d66a53" + integrity sha512-VYetmTXqW83npsvVvqlQZTbF3yVL3k/FCCl3kSWvOr9LZA0lmyqJWPjMHq37yIIOszQN/p5guLtgCjsP0UQw1Q== + dependencies: + "@parcel/plugin" "2.3.2" + "@parcel/types" "2.3.2" + "@parcel/utils" "2.3.2" + chalk "^4.1.0" + +"@parcel/reporter-dev-server@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/reporter-dev-server/-/reporter-dev-server-2.3.2.tgz#46ee4c53ad08c8b8afd2c79fb37381b6ba55cfb5" + integrity sha512-E7LtnjAX4iiWMw2qKUyFBi3+bDz0UGjqgHoPQylUYYLi6opXjJz/oC+cCcCy4e3RZlkrl187XonvagS59YjDxA== + dependencies: + "@parcel/plugin" "2.3.2" + "@parcel/utils" "2.3.2" + +"@parcel/resolver-default@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/resolver-default/-/resolver-default-2.3.2.tgz#286070412ad7fe506f7c88409f39b362d2041798" + integrity sha512-y3r+xOwWsATrNGUWuZ6soA7q24f8E5tY1AZ9lHCufnkK2cdKZJ5O1cyd7ohkAiKZx2/pMd+FgmVZ/J3oxetXkA== + dependencies: + "@parcel/node-resolver-core" "2.3.2" + "@parcel/plugin" "2.3.2" + +"@parcel/runtime-browser-hmr@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/runtime-browser-hmr/-/runtime-browser-hmr-2.3.2.tgz#cb23a850324ea792168438a9be6a345ebb66eb6d" + integrity sha512-nRD6uOyF1+HGylP9GASbYmvUDOsDaNwvaxuGTSh8+5M0mmCgib+hVBiPEKbwdmKjGbUPt9wRFPyMa/JpeQZsIQ== + dependencies: + "@parcel/plugin" "2.3.2" + "@parcel/utils" "2.3.2" + +"@parcel/runtime-js@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/runtime-js/-/runtime-js-2.3.2.tgz#c0e14251ce43f95977577e23bb9ac5c2487f3bb1" + integrity sha512-SJepcHvYO/7CEe/Q85sngk+smcJ6TypuPh4D2R8kN+cAJPi5WvbQEe7+x5BEgbN+5Jumi/Uo3FfOOE5mYh+F6g== + dependencies: + "@parcel/plugin" "2.3.2" + "@parcel/utils" "2.3.2" + nullthrows "^1.1.1" + +"@parcel/runtime-react-refresh@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/runtime-react-refresh/-/runtime-react-refresh-2.3.2.tgz#11961d7429ae3333b7efe14c4f57515df57eb5f2" + integrity sha512-P+GRPO2XVDSBQ4HmRSj2xfbHSQvL9+ahTE/AB74IJExLTITv5l4SHAV3VsiKohuHYUAYHW3A/Oe7tEFCAb6Cug== + dependencies: + "@parcel/plugin" "2.3.2" + "@parcel/utils" "2.3.2" + react-refresh "^0.9.0" + +"@parcel/runtime-service-worker@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/runtime-service-worker/-/runtime-service-worker-2.3.2.tgz#aa91797e57d1bb5b2aac04ac62c5410709ae0a27" + integrity sha512-iREHj/eapphC4uS/zGUkiTJvG57q+CVbTrfE42kB8ECtf/RYNo5YC9htdvPZjRSXDPrEPc5NCoKp4X09ENNikw== + dependencies: + "@parcel/plugin" "2.3.2" + "@parcel/utils" "2.3.2" + nullthrows "^1.1.1" + +"@parcel/service-worker@^2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/service-worker/-/service-worker-2.3.2.tgz#c5d5ca876249fc39dbfd55e7f6be94645244cf5c" + integrity sha512-snBZYe8MV4suTtbQAABQ8OBWdccO07onxayReiDLUzTRffNB2V1ikLDYkngLMmpRAa1lp0bnB0KfvVX8jeLLOg== + +"@parcel/source-map@^2.0.0": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@parcel/source-map/-/source-map-2.0.2.tgz#9aa0b00518cee31d5634de6e9c924a5539b142c1" + integrity sha512-NnUrPYLpYB6qyx2v6bcRPn/gVigmGG6M6xL8wIg/i0dP1GLkuY1nf+Hqdf63FzPTqqT7K3k6eE5yHPQVMO5jcA== + dependencies: + detect-libc "^1.0.3" + +"@parcel/transformer-babel@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/transformer-babel/-/transformer-babel-2.3.2.tgz#2d8c0d1f95d9747936d132dc4c34edb0b6b80d39" + integrity sha512-QpWfH2V6jJ+kcUBIMM/uBBG8dGFvNaOGS+8jD6b+eTP+1owzm83RoWgqhRV2D/hhv2qMXEQzIljoc/wg2y+X4g== + dependencies: + "@parcel/diagnostic" "2.3.2" + "@parcel/plugin" "2.3.2" + "@parcel/source-map" "^2.0.0" + "@parcel/utils" "2.3.2" + browserslist "^4.6.6" + json5 "^2.2.0" + nullthrows "^1.1.1" + semver "^5.7.0" + +"@parcel/transformer-css@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/transformer-css/-/transformer-css-2.3.2.tgz#968826e42d7cac9963dc0a67a30d393ef996e48c" + integrity sha512-8lzvDny+78DIAqhcXam2Bf9FyaUoqzHdUQdNFn+PuXTHroG/QGPvln1kvqngJjn4/cpJS9vYmAPVXe+nai3P8g== + dependencies: + "@parcel/hash" "2.3.2" + "@parcel/plugin" "2.3.2" + "@parcel/source-map" "^2.0.0" + "@parcel/utils" "2.3.2" + nullthrows "^1.1.1" + postcss "^8.4.5" + postcss-value-parser "^4.2.0" + semver "^5.7.1" + +"@parcel/transformer-html@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/transformer-html/-/transformer-html-2.3.2.tgz#c240f09369445d287d16beba207407c925532d90" + integrity sha512-idT1I/8WM65IFYBqzRwpwT7sf0xGur4EDQDHhuPX1w+pIVZnh0lkLMAnEqs6ar1SPRMys4chzkuDNnqh0d76hg== + dependencies: + "@parcel/diagnostic" "2.3.2" + "@parcel/hash" "2.3.2" + "@parcel/plugin" "2.3.2" + nullthrows "^1.1.1" + posthtml "^0.16.5" + posthtml-parser "^0.10.1" + posthtml-render "^3.0.0" + semver "^5.7.1" + +"@parcel/transformer-image@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/transformer-image/-/transformer-image-2.3.2.tgz#24b6eda51a6b07c195886bbb67fb2ade14c325f3" + integrity sha512-0K7cJHXysli6hZsUz/zVGO7WCoaaIeVdzAxKpLA1Yl3LKw/ODiMyXKt08LiV/ljQ2xT5qb9EsXUWDRvcZ0b96A== + dependencies: + "@parcel/plugin" "2.3.2" + "@parcel/workers" "2.3.2" + nullthrows "^1.1.1" + +"@parcel/transformer-inline-string@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/transformer-inline-string/-/transformer-inline-string-2.3.2.tgz#bec5d376d00b5c41abf11c8cf8e3d917036c0646" + integrity sha512-nitgU+YHnJpJjdUEyRqXD3DjIAstcdHDwwKgloTfpt7EDe2VspVuWhA054kH75Kn/Tvn4s0G4VGCTpDw5KxzSw== + dependencies: + "@parcel/plugin" "2.3.2" + +"@parcel/transformer-js@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/transformer-js/-/transformer-js-2.3.2.tgz#24bcb488d5f82678343a5630fe4bbe822789ac33" + integrity sha512-U1fbIoAoqR5P49S+DMhH8BUd9IHRPwrTTv6ARYGsYnhuNsjTFhNYE0kkfRYboe/e0z7vEbeJICZXjnZ7eQDw5A== + dependencies: + "@parcel/diagnostic" "2.3.2" + "@parcel/plugin" "2.3.2" + "@parcel/source-map" "^2.0.0" + "@parcel/utils" "2.3.2" + "@parcel/workers" "2.3.2" + "@swc/helpers" "^0.2.11" + browserslist "^4.6.6" + detect-libc "^1.0.3" + nullthrows "^1.1.1" + regenerator-runtime "^0.13.7" + semver "^5.7.1" + +"@parcel/transformer-json@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/transformer-json/-/transformer-json-2.3.2.tgz#4c470e86659e87ee13b1f31e75a3621d3615b6bd" + integrity sha512-Pv2iPaxKINtFwOk5fDbHjQlSm2Vza/NLimQY896FLxiXPNAJxWGvMwdutgOPEBKksxRx9LZPyIOHiRVZ0KcA3w== + dependencies: + "@parcel/plugin" "2.3.2" + json5 "^2.2.0" + +"@parcel/transformer-postcss@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/transformer-postcss/-/transformer-postcss-2.3.2.tgz#a428c81569dd66758c5fab866dca69b4c6e59743" + integrity sha512-Rpdxc1rt2aJFCh/y/ccaBc9J1crDjNY5o44xYoOemBoUNDMREsmg5sR5iO81qKKO5GxfoosGb2zh59aeTmywcg== + dependencies: + "@parcel/hash" "2.3.2" + "@parcel/plugin" "2.3.2" + "@parcel/utils" "2.3.2" + clone "^2.1.1" + nullthrows "^1.1.1" + postcss-value-parser "^4.2.0" + semver "^5.7.1" + +"@parcel/transformer-posthtml@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/transformer-posthtml/-/transformer-posthtml-2.3.2.tgz#5da3f24bf240c3c49b2fdb17dcda5988d3057a30" + integrity sha512-tMdVExfdM+1G8A9KSHDsjg+S9xEGbhH5mApF2NslPnNZ4ciLKRNuHU2sSV/v8i0a6kacKvDTrwQXYBQJGOodBw== + dependencies: + "@parcel/plugin" "2.3.2" + "@parcel/utils" "2.3.2" + nullthrows "^1.1.1" + posthtml "^0.16.5" + posthtml-parser "^0.10.1" + posthtml-render "^3.0.0" + semver "^5.7.1" + +"@parcel/transformer-raw@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/transformer-raw/-/transformer-raw-2.3.2.tgz#40d21773e295bae3b16bfe7a89e414ccf534b9c5" + integrity sha512-lY7eOCaALZ90+GH+4PZRmAPGQRXoZ66NakSdhEtH6JSSAYOmZKDvNLGTMRo/vK1oELzWMuAHGdqvbcPDtNLLVw== + dependencies: + "@parcel/plugin" "2.3.2" + +"@parcel/transformer-react-refresh-wrap@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/transformer-react-refresh-wrap/-/transformer-react-refresh-wrap-2.3.2.tgz#43ecfe6f4567b88abb81db9fe56b8d860d6a69f7" + integrity sha512-FZaderyCExn0SBZ6D+zHPWc8JSn9YDcbfibv0wkCl+D7sYfeWZ22i7MRp5NwCe/TZ21WuxDWySCggEp/Waz2xg== + dependencies: + "@parcel/plugin" "2.3.2" + "@parcel/utils" "2.3.2" + react-refresh "^0.9.0" + +"@parcel/transformer-sass@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/transformer-sass/-/transformer-sass-2.3.2.tgz#ee124d02acb1f44417f0d78d366302dd68aa412b" + integrity sha512-jVDdhyzfCYLY/91gOfMAT0Cj3a3czETD71WpvnXhzfctnhZZ/lhC1aFUJxlhIF1hkVNyZ1b9USCCBAD4fje2Jg== + dependencies: + "@parcel/plugin" "2.3.2" + "@parcel/source-map" "^2.0.0" + sass "^1.38.0" + +"@parcel/transformer-svg@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/transformer-svg/-/transformer-svg-2.3.2.tgz#9a66aef5011c7bbb1fa3ce9bb52ca56d8f0f964d" + integrity sha512-k9My6bePsaGgUh+tidDjFbbVgKPTzwCAQfoloZRMt7y396KgUbvCfqDruk04k6k+cJn7Jl1o/5lUpTEruBze7g== + dependencies: + "@parcel/diagnostic" "2.3.2" + "@parcel/hash" "2.3.2" + "@parcel/plugin" "2.3.2" + nullthrows "^1.1.1" + posthtml "^0.16.5" + posthtml-parser "^0.10.1" + posthtml-render "^3.0.0" + semver "^5.7.1" + +"@parcel/transformer-webmanifest@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/transformer-webmanifest/-/transformer-webmanifest-2.3.2.tgz#8796d396049b0db62e87ed5d981a21654ffe1b30" + integrity sha512-aaiDhhfag5ygjoNI1SmE3wVI/C63gABvfzp6BgkXNV/kKsqk/lSftukgcDTekSUtZNOhGJk7LeWkhm8RF38jIw== + dependencies: + "@parcel/diagnostic" "2.3.2" + "@parcel/plugin" "2.3.2" + "@parcel/utils" "2.3.2" + json-source-map "^0.6.1" + +"@parcel/ts-utils@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/ts-utils/-/ts-utils-2.3.2.tgz#d63f7027574f3c1a128e1c865d683d6aacb4476d" + integrity sha512-jYCHoSmU+oVtFA4q0BygVf74FpVnCDSNtVfLzd1EfGVHlBFMo9GzSY5luMTG4qhnNCDEEco89bkMIgjPHQ3qnA== + dependencies: + nullthrows "^1.1.1" + +"@parcel/types@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/types/-/types-2.3.2.tgz#7eb6925bc852a518dd75b742419e51292418769f" + integrity sha512-C77Ct1xNM7LWjPTfe/dQ/9rq1efdsX5VJu2o8/TVi6qoFh64Wp/c5/vCHwKInOTBZUTchVO6z4PGJNIZoUVJuA== + dependencies: + "@parcel/cache" "2.3.2" + "@parcel/diagnostic" "2.3.2" + "@parcel/fs" "2.3.2" + "@parcel/package-manager" "2.3.2" + "@parcel/source-map" "^2.0.0" + "@parcel/workers" "2.3.2" + utility-types "^3.10.0" + +"@parcel/utils@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/utils/-/utils-2.3.2.tgz#4aab052fc9f3227811a504da7b9663ca75004f55" + integrity sha512-xzZ+0vWhrXlLzGoz7WlANaO5IPtyWGeCZruGtepUL3yheRWb1UU4zFN9xz7Z+j++Dmf1Fgkc3qdk/t4O8u9HLQ== + dependencies: + "@parcel/codeframe" "2.3.2" + "@parcel/diagnostic" "2.3.2" + "@parcel/hash" "2.3.2" + "@parcel/logger" "2.3.2" + "@parcel/markdown-ansi" "2.3.2" + "@parcel/source-map" "^2.0.0" + chalk "^4.1.0" + +"@parcel/validator-typescript@^2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/validator-typescript/-/validator-typescript-2.3.2.tgz#4372c3e459106c2ed36fb6e66e0253227d0c88d4" + integrity sha512-IGGYx35lnblHwpIOWUZJusyIcn2a9L7pZmwnKXKDPONUP3lgHhbCv6Ix2WBwTRb+AztNBvXudR5PytBJ4DrovA== + dependencies: + "@parcel/diagnostic" "2.3.2" + "@parcel/plugin" "2.3.2" + "@parcel/ts-utils" "2.3.2" + "@parcel/types" "2.3.2" + "@parcel/utils" "2.3.2" + +"@parcel/watcher@^2.0.0": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@parcel/watcher/-/watcher-2.0.5.tgz#f913a54e1601b0aac972803829b0eece48de215b" + integrity sha512-x0hUbjv891omnkcHD7ZOhiyyUqUUR6MNjq89JhEI3BxppeKWAm6NPQsqqRrAkCJBogdT/o/My21sXtTI9rJIsw== + dependencies: + node-addon-api "^3.2.1" + node-gyp-build "^4.3.0" + +"@parcel/workers@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@parcel/workers/-/workers-2.3.2.tgz#05ffa2da9169bfb83335892c2b8abce55686ceb1" + integrity sha512-JbOm+Ceuyymd1SuKGgodC2EXAiPuFRpaNUSJpz3NAsS3lVIt2TDAPMOWBivS7sML/KltspUfl/Q9YwO0TPUFNw== + dependencies: + "@parcel/diagnostic" "2.3.2" + "@parcel/logger" "2.3.2" + "@parcel/types" "2.3.2" + "@parcel/utils" "2.3.2" + chrome-trace-event "^1.0.2" + nullthrows "^1.1.1" + +"@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== + +"@sinonjs/commons@^1.7.0": + version "1.8.3" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" + integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ== + dependencies: + type-detect "4.0.8" + +"@sinonjs/fake-timers@^8.0.1": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz#3fdc2b6cb58935b21bfb8d1625eb1300484316e7" + integrity sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg== + dependencies: + "@sinonjs/commons" "^1.7.0" + +"@socket.io/base64-arraybuffer@~1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@socket.io/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz#568d9beae00b0d835f4f8c53fd55714986492e61" + integrity sha512-dOlCBKnDw4iShaIsH/bxujKTM18+2TOAsYz+KSc11Am38H4q5Xw8Bbz97ZYdrVNM+um3p7w86Bvvmcn9q+5+eQ== + +"@socket.io/component-emitter@~3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.0.0.tgz#8863915676f837d9dad7b76f50cb500c1e9422e9" + integrity sha512-2pTGuibAXJswAPJjaKisthqS/NOK5ypG4LYT6tEAV0S/mxW0zOIvYvGK0V8w8+SHxAm6vRMSjqSalFXeBAqs+Q== + +"@swc/helpers@^0.2.11": + version "0.2.14" + resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.2.14.tgz#20288c3627442339dd3d743c944f7043ee3590f0" + integrity sha512-wpCQMhf5p5GhNg2MmGKXzUNwxe7zRiCsmqYsamez2beP7mKPCSiu+BjZcdN95yYSzO857kr0VfQewmGpS77nqA== + +"@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" + +"@tootallnate/once@1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" + integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== + +"@trysound/sax@0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" + integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== + +"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14": + version "7.1.18" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.18.tgz#1a29abcc411a9c05e2094c98f9a1b7da6cdf49f8" + integrity sha512-S7unDjm/C7z2A2R9NzfKCK1I+BAALDtxEmsJBwlB3EzNfb929ykjL++1CK9LO++EIp2fQrC8O+BwjKvz6UeDyQ== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.6.4" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.4.tgz#1f20ce4c5b1990b37900b63f050182d28c2439b7" + integrity sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.4.1" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.1.tgz#3d1a48fd9d6c0edfd56f2ff578daed48f36c8969" + integrity sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.14.2.tgz#ffcd470bbb3f8bf30481678fb5502278ca833a43" + integrity sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA== + dependencies: + "@babel/types" "^7.3.0" + +"@types/body-parser@*": + version "1.19.2" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" + integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/component-emitter@^1.2.10": + version "1.2.11" + resolved "https://registry.yarnpkg.com/@types/component-emitter/-/component-emitter-1.2.11.tgz#50d47d42b347253817a39709fef03ce66a108506" + integrity sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ== + +"@types/connect@*": + version "3.4.35" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" + integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== + dependencies: + "@types/node" "*" + +"@types/cookie@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" + integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q== + +"@types/cors@^2.8.12": + version "2.8.12" + resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.12.tgz#6b2c510a7ad7039e98e7b8d3d6598f4359e5c080" + integrity sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw== + +"@types/events@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" + integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== + +"@types/express-serve-static-core@^4.17.18": + version "4.17.28" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz#c47def9f34ec81dc6328d0b1b5303d1ec98d86b8" + integrity sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express@^4.17.13": + version "4.17.13" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034" + integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.18" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/graceful-fs@^4.1.2": + version "4.1.5" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" + integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== + dependencies: + "@types/node" "*" + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" + integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== + +"@types/istanbul-lib-report@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" + integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff" + integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== + dependencies: + "@types/istanbul-lib-report" "*" + +"@types/jest@^27.4.1": + version "27.4.1" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.4.1.tgz#185cbe2926eaaf9662d340cc02e548ce9e11ab6d" + integrity sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw== + dependencies: + jest-matcher-utils "^27.0.0" + pretty-format "^27.0.0" + +"@types/mime@^1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" + integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== + +"@types/node@*", "@types/node@>=10.0.0", "@types/node@^17.0.21": + version "17.0.21" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.21.tgz#864b987c0c68d07b4345845c3e63b75edd143644" + integrity sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ== + +"@types/parse-json@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" + integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== + +"@types/prettier@^2.1.5": + version "2.4.4" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.4.4.tgz#5d9b63132df54d8909fce1c3f8ca260fdd693e17" + integrity sha512-ReVR2rLTV1kvtlWFyuot+d1pkpG2Fw/XKE3PDAdj57rbM97ttSp9JZ2UsP+2EHTylra9cUf6JA7tGwW1INzUrA== + +"@types/prop-types@*": + version "15.7.4" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.4.tgz#fcf7205c25dff795ee79af1e30da2c9790808f11" + integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ== + +"@types/qs@*": + version "6.9.7" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" + integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + +"@types/range-parser@*": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" + integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== + +"@types/react-dom@^17.0.11": + version "17.0.13" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.13.tgz#a3323b974ee4280070982b3112351bb1952a7809" + integrity sha512-wEP+B8hzvy6ORDv1QBhcQia4j6ea4SFIBttHYpXKPFZRviBvknq0FRh3VrIxeXUmsPkwuXVZrVGG7KUVONmXCQ== + dependencies: + "@types/react" "*" + +"@types/react@*", "@types/react@^17.0.39": + version "17.0.40" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.40.tgz#dc010cee6254d5239a138083f3799a16638e6bad" + integrity sha512-UrXhD/JyLH+W70nNSufXqMZNuUD2cXHu6UjCllC6pmOQgBX4SGXOH8fjRka0O0Ee0HrFxapDD8Bwn81Kmiz6jQ== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + +"@types/scheduler@*": + version "0.16.2" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" + integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== + +"@types/serve-static@*": + version "1.13.10" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.10.tgz#f5e0ce8797d2d7cc5ebeda48a52c96c4fa47a8d9" + integrity sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@types/stack-utils@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" + integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== + +"@types/yargs-parser@*": + version "21.0.0" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" + integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== + +"@types/yargs@^16.0.0": + version "16.0.4" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.4.tgz#26aad98dd2c2a38e421086ea9ad42b9e51642977" + integrity sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw== + dependencies: + "@types/yargs-parser" "*" + +"@vscode/sqlite3@^5.0.7": + version "5.0.7" + resolved "https://registry.yarnpkg.com/@vscode/sqlite3/-/sqlite3-5.0.7.tgz#358df36bb0e9e735c54785e3e4b9b2dce1d32895" + integrity sha512-NlsOf+Hir2r4zopI1qMvzWXPwPJuFscirkmFTniTAT24Yz2FWcyZxzK7UT8iSNiTqOCPz48yF55ZVHaz7tTuVQ== + dependencies: + node-addon-api "^4.2.0" + +abab@^2.0.3, abab@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" + integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== + +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== + +abortcontroller-polyfill@^1.1.9: + version "1.7.3" + resolved "https://registry.yarnpkg.com/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.3.tgz#1b5b487bd6436b5b764fd52a612509702c3144b5" + integrity sha512-zetDJxd89y3X99Kvo4qFx8GKlt6GsvN3UcRZHwU6iFA/0KiOmhkTVhe8oRoTBiTVPZu09x3vCra47+w8Yz1+2Q== + +accepts@~1.3.4, accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +acorn-globals@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" + integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== + dependencies: + acorn "^7.1.1" + acorn-walk "^7.1.1" + +acorn-walk@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" + integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== + +acorn-walk@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" + integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + +acorn@^7.1.1: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== + +acorn@^8.2.4, acorn@^8.5.0, acorn@^8.7.0: + version "8.7.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" + integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== + +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +ansi-align@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" + integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w== + dependencies: + string-width "^4.1.0" + +ansi-escapes@^4.2.1: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + +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@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +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, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + +anymatch@^3.0.3, anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +aproba@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +are-we-there-yet@~1.1.2: + version "1.1.7" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz#b15474a932adab4ff8a50d9adfa7e4e926f21146" + integrity sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g== + 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" + +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= + +asn1.js@^5.2.0: + version "5.4.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07" + integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + safer-buffer "^2.1.0" + +assert@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-2.0.0.tgz#95fc1c616d48713510680f2eaf2d10dd22e02d32" + integrity sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A== + dependencies: + es6-object-assign "^1.1.0" + is-nan "^1.2.1" + object-is "^1.0.1" + util "^0.12.0" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +available-typed-arrays@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" + integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== + +babel-jest@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.5.1.tgz#a1bf8d61928edfefd21da27eb86a695bfd691444" + integrity sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg== + dependencies: + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^27.5.1" + chalk "^4.0.0" + graceful-fs "^4.2.9" + slash "^3.0.0" + +babel-plugin-istanbul@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" + integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^5.0.4" + test-exclude "^6.0.0" + +babel-plugin-jest-hoist@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz#9be98ecf28c331eb9f5df9c72d6f89deb8181c2e" + integrity sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.0.0" + "@types/babel__traverse" "^7.0.6" + +babel-preset-current-node-syntax@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" + integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== + dependencies: + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-bigint" "^7.8.3" + "@babel/plugin-syntax-class-properties" "^7.8.3" + "@babel/plugin-syntax-import-meta" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.8.3" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-top-level-await" "^7.8.3" + +babel-preset-jest@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz#91f10f58034cb7989cb4f962b69fa6eef6a6bc81" + integrity sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag== + dependencies: + babel-plugin-jest-hoist "^27.5.1" + babel-preset-current-node-syntax "^1.0.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.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base-x@^3.0.8: + version "3.0.9" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" + integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== + dependencies: + safe-buffer "^5.0.1" + +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +base64id@2.0.0, base64id@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" + integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== + +better-sqlite3@^7.5.0: + version "7.5.0" + resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-7.5.0.tgz#2a91cb616453f002096743b0e5b66a7021cd1c63" + integrity sha512-6FdG9DoytYGDhLW7VWW1vxjEz7xHkqK6LnaUQYA8d6GHNgZhu9PFX2xwKEEnSBRoT1J4PjTUPeg217ShxNmuPg== + dependencies: + bindings "^1.5.0" + prebuild-install "^7.0.0" + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +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@^4.0.3: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" + integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== + +bn.js@^5.0.0, bn.js@^5.1.1: + version "5.2.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" + integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== + +body-parser@1.19.2, body-parser@^1.19.2: + version "1.19.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.2.tgz#4714ccd9c157d44797b8b5607d72c0b89952f26e" + integrity sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "1.8.1" + iconv-lite "0.4.24" + on-finished "~2.3.0" + qs "6.9.7" + raw-body "2.4.3" + type-is "~1.6.18" + +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= + +boxen@^5.0.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" + integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ== + dependencies: + ansi-align "^3.0.0" + camelcase "^6.2.0" + chalk "^4.1.0" + cli-boxes "^2.2.1" + string-width "^4.2.2" + type-fest "^0.20.2" + widest-line "^3.1.0" + wrap-ansi "^7.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@^3.0.1, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +brorand@^1.0.1, brorand@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + +browser-process-hrtime@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" + integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== + +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, browserify-rsa@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" + integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== + dependencies: + bn.js "^5.0.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.1.tgz#eaf4add46dd54be3bb3b36c0cf15abbeba7956c3" + integrity sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg== + dependencies: + bn.js "^5.1.1" + browserify-rsa "^4.0.1" + create-hash "^1.2.0" + create-hmac "^1.1.7" + elliptic "^6.5.3" + inherits "^2.0.4" + parse-asn1 "^5.1.5" + readable-stream "^3.6.0" + safe-buffer "^5.2.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.16.6, browserslist@^4.17.5, browserslist@^4.6.6: + version "4.20.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.2.tgz#567b41508757ecd904dab4d1c646c612cd3d4f88" + integrity sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA== + dependencies: + caniuse-lite "^1.0.30001317" + electron-to-chromium "^1.4.84" + escalade "^3.1.1" + node-releases "^2.0.2" + picocolors "^1.0.0" + +bs-logger@0.x: + version "0.2.6" + resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" + integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== + dependencies: + fast-json-stable-stringify "2.x" + +bser@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" + integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== + dependencies: + node-int64 "^0.4.0" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +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@^5.5.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +buffer@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + +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.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +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" + +call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +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== + +camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +camelcase@^6.2.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +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.30001317: + version "1.0.30001317" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001317.tgz#0548fb28fd5bc259a70b8c1ffdbe598037666a1b" + integrity sha512-xIZLh8gBm4dqNX0gkzrBeyI86J2eCjWzYAs40q88smG844YIrN4tVQl/RhquHvKEKImWWFIVh1Lxe5n1G/N+GQ== + +chalk@^2.0.0: + 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@^4.0.0, chalk@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== + +"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.2: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +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.3" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== + +ci-info@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== + +ci-info@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.0.tgz#b4ed1fb6818dea4803a55c623041f9165d2066b2" + integrity sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw== + +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" + +cjs-module-lexer@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" + integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== + +cli-boxes@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" + integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +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@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= + +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= + +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= + +collect-v8-coverage@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" + integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== + +color-convert@^1.9.0: + 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.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== + +colord@^2.9.1: + version "2.9.2" + resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.2.tgz#25e2bacbbaa65991422c07ea209e2089428effb1" + integrity sha512-Uqbg+J445nc1TKn4FoDPS6ZZqAvEDnwrH42yo8B40JSOgSLxMZ/gt3h4nmCtPLQeXhjJJkqBx7SCY35WnIixaQ== + +colorette@2.0.16: + version "2.0.16" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" + integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== + +combined-stream@^1.0.8: + 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.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@^7.0.0, commander@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + +commander@^8.3.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" + integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== + +component-emitter@~1.3.0: + 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== + +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= + +configstore@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96" + integrity sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA== + dependencies: + dot-prop "^5.2.0" + graceful-fs "^4.1.2" + make-dir "^3.0.0" + unique-string "^2.0.0" + write-file-atomic "^3.0.0" + xdg-basedir "^4.0.0" + +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= + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +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.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" + integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== + 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.4.2, cookie@~0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" + integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +cors@^2.8.5, cors@~2.8.5: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + +cosmiconfig@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d" + integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.2.1" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.10.0" + +create-ecdh@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" + integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A== + dependencies: + bn.js "^4.1.0" + elliptic "^6.5.3" + +create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: + 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.4, create-hmac@^1.1.7: + 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" + +crelt@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/crelt/-/crelt-1.0.5.tgz#57c0d52af8c859e354bace1883eb2e1eb182bb94" + integrity sha512-+BO9wPPi+DWTDcNYhr/W90myha8ptzftZT+LwcmUbbok0rcP/fequmFYCw8NMoH7pkAZQzU78b3kYrlua5a9eA== + +cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +crypto-browserify@^3.12.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-random-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" + integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== + +css-declaration-sorter@^6.0.3: + version "6.1.4" + resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.1.4.tgz#b9bfb4ed9a41f8dcca9bf7184d849ea94a8294b4" + integrity sha512-lpfkqS0fctcmZotJGhnxkIyJWvBXgpyi2wsFd4J8VB7wzyrT6Ch/3Q+FMNJpjK4gu1+GN5khOnpU2ZVKrLbhCw== + dependencies: + timsort "^0.3.0" + +css-select@^4.1.3: + version "4.2.1" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.2.1.tgz#9e665d6ae4c7f9d65dbe69d0316e3221fb274cdd" + integrity sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ== + dependencies: + boolbase "^1.0.0" + css-what "^5.1.0" + domhandler "^4.3.0" + domutils "^2.8.0" + nth-check "^2.0.1" + +css-tree@^1.1.2, css-tree@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" + integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== + dependencies: + mdn-data "2.0.14" + source-map "^0.6.1" + +css-what@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.1.0.tgz#3f7b707aadf633baf62c2ceb8579b545bb40f7fe" + integrity sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw== + +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-default@^*: + version "5.2.4" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.2.4.tgz#eced79bbc1ab7270337c4038a21891daac2329bc" + integrity sha512-w1Gg8xsebln6/axZ6qDFQHuglrGfbIHOIx0g4y9+etRlRab8CGpSpe6UMsrgJe4zhCaJ0LwLmc+PhdLRTwnhIA== + dependencies: + css-declaration-sorter "^6.0.3" + cssnano-utils "^*" + postcss-calc "^8.2.3" + postcss-colormin "^*" + postcss-convert-values "^*" + postcss-discard-comments "^*" + postcss-discard-duplicates "^*" + postcss-discard-empty "^*" + postcss-discard-overridden "^*" + postcss-merge-longhand "^*" + postcss-merge-rules "^*" + postcss-minify-font-values "^*" + postcss-minify-gradients "^*" + postcss-minify-params "^*" + postcss-minify-selectors "^*" + postcss-normalize-charset "^*" + postcss-normalize-display-values "^*" + postcss-normalize-positions "^*" + postcss-normalize-repeat-style "^*" + postcss-normalize-string "^*" + postcss-normalize-timing-functions "^*" + postcss-normalize-unicode "^*" + postcss-normalize-url "^*" + postcss-normalize-whitespace "^*" + postcss-ordered-values "^*" + postcss-reduce-initial "^*" + postcss-reduce-transforms "^*" + postcss-svgo "^*" + postcss-unique-selectors "^*" + +cssnano-utils@^*, cssnano-utils@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-3.1.0.tgz#95684d08c91511edfc70d2636338ca37ef3a6861" + integrity sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA== + +cssnano@^5.0.15: + version "5.1.4" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.1.4.tgz#c648192e8e2f1aacb7d839e6aa3706b50cc7f8e4" + integrity sha512-hbfhVZreEPyzl+NbvRsjNo54JOX80b+j6nqG2biLVLaZHJEiqGyMh4xDGHtwhUKd5p59mj2GlDqlUBwJUuIu5A== + dependencies: + cssnano-preset-default "^*" + lilconfig "^2.0.3" + yaml "^1.10.2" + +csso@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" + integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== + dependencies: + css-tree "^1.1.2" + +cssom@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" + integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== + +cssom@~0.3.6: + version "0.3.8" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" + integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== + +cssstyle@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" + integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== + dependencies: + cssom "~0.3.6" + +csstype@^3.0.2: + version "3.0.11" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.11.tgz#d66700c5eacfac1940deb4e3ee5642792d85cd33" + integrity sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw== + +data-urls@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" + integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ== + dependencies: + abab "^2.0.3" + whatwg-mimetype "^2.3.0" + whatwg-url "^8.0.0" + +debug@2.6.9: + 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, debug@^4.1.0, debug@^4.1.1, debug@~4.3.1, debug@~4.3.2: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +debug@4.3.3: + version "4.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== + dependencies: + ms "2.1.2" + +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +decimal.js@^10.2.1: + version "10.3.1" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" + integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== + +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-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + +dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= + +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.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + +defer-to-connect@^1.0.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" + integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== + +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" + +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= + +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-libc@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= + +detect-libc@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.1.tgz#e1897aa88fa6ad197862937fbc0441ef352ee0cd" + integrity sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w== + +detect-newline@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" + integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== + +dexie@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/dexie/-/dexie-3.2.1.tgz#ef21456d725e700c1ab7ac4307896e4fdabaf753" + integrity sha512-Y8oz3t2XC9hvjkP35B5I8rUkKKwM36GGRjWQCMjzIYScg7W+GHKDXobSYswkisW7CxL1/tKQtggMDsiWqDUc1g== + +diff-sequences@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327" + integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ== + +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" + +dom-serializer@^1.0.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.2.tgz#6206437d32ceefaec7161803230c7a20bc1b4d91" + integrity sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.2.0" + entities "^2.0.0" + +domelementtype@^2.0.1, domelementtype@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57" + integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A== + +domexception@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" + integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg== + dependencies: + webidl-conversions "^5.0.0" + +domhandler@^4.2.0, domhandler@^4.2.2, domhandler@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.0.tgz#16c658c626cf966967e306f966b431f77d4a5626" + integrity sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g== + dependencies: + domelementtype "^2.2.0" + +domutils@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" + integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== + dependencies: + dom-serializer "^1.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" + +dot-prop@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" + integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q== + dependencies: + is-obj "^2.0.0" + +dotenv-expand@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" + integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== + +dotenv@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-7.0.0.tgz#a2be3cd52736673206e8a85fb5210eea29628e7c" + integrity sha512-M3NhsLbV1i6HuGzBUH8vXrtxOk+tWmzWKDMbAVSUp3Zsjm7ywFeuwrUXhmhQyRK1q5B5GGy7hcXPbj3bnfZg2g== + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= + +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= + +electron-to-chromium@^1.4.84: + version "1.4.87" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.87.tgz#1aeacfa50b2fbf3ecf50a78fbebd8f259d4fe208" + integrity sha512-EXXTtDHFUKdFVkCnhauU7Xp8wmFC1ZG6GK9a1BeI2vvNhy61IwfNPo/CRexhf7mh4ajxAHJPind62BzpzVUeuQ== + +elliptic@^6.5.3: + version "6.5.4" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" + integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== + dependencies: + bn.js "^4.11.9" + brorand "^1.1.0" + hash.js "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" + +emittery@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" + integrity sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg== + +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== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +end-of-stream@^1.1.0, end-of-stream@^1.4.1: + 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@~6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-6.1.1.tgz#800d4b9db5487d169686729e5bd887afa78d36b0" + integrity sha512-V05mmDo4gjimYW+FGujoGmmmxRaDsrVr7AXA3ZIfa04MWM1jOfZfUwou0oNqhNwy/votUDvGDt4JA4QF4e0b4g== + dependencies: + "@socket.io/component-emitter" "~3.0.0" + debug "~4.3.1" + engine.io-parser "~5.0.0" + has-cors "1.1.0" + parseqs "0.0.6" + parseuri "0.0.6" + ws "~8.2.3" + xmlhttprequest-ssl "~2.0.0" + yeast "0.1.2" + +engine.io-parser@~5.0.0, engine.io-parser@~5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.0.3.tgz#ca1f0d7b11e290b4bfda251803baea765ed89c09" + integrity sha512-BtQxwF27XUNnSafQLvDi0dQ8s3i6VgzSoQMJacpIcGNrlUdfHSKbgm3jmjCVvQluGzqwujQMPAoMai3oYSTurg== + dependencies: + "@socket.io/base64-arraybuffer" "~1.0.2" + +engine.io@~6.1.0: + version "6.1.3" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-6.1.3.tgz#f156293d011d99a3df5691ac29d63737c3302e6f" + integrity sha512-rqs60YwkvWTLLnfazqgZqLa/aKo+9cueVfEi/dZ8PyGyaf8TLOxj++4QMIgeG3Gn0AhrWiFXvghsoY9L9h25GA== + dependencies: + "@types/cookie" "^0.4.1" + "@types/cors" "^2.8.12" + "@types/node" ">=10.0.0" + accepts "~1.3.4" + base64id "2.0.0" + cookie "~0.4.1" + cors "~2.8.5" + debug "~4.3.1" + engine.io-parser "~5.0.3" + ws "~8.2.3" + +entities@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" + integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== + +entities@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4" + integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q== + +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.18.5: + version "1.19.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3" + integrity sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w== + dependencies: + call-bind "^1.0.2" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + get-intrinsic "^1.1.1" + get-symbol-description "^1.0.0" + has "^1.0.3" + has-symbols "^1.0.2" + internal-slot "^1.0.3" + is-callable "^1.2.4" + is-negative-zero "^2.0.1" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.1" + is-string "^1.0.7" + is-weakref "^1.0.1" + object-inspect "^1.11.0" + object-keys "^1.1.1" + object.assign "^4.1.2" + string.prototype.trimend "^1.0.4" + string.prototype.trimstart "^1.0.4" + unbox-primitive "^1.0.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-object-assign@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/es6-object-assign/-/es6-object-assign-1.1.0.tgz#c2c3582656247c39ea107cb1e6652b6f9f24523c" + integrity sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw= + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-goat@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675" + integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q== + +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.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= + +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + +escodegen@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" + integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== + dependencies: + esprima "^4.0.1" + estraverse "^5.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +esm@^3.2.25: + version "3.2.25" + resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10" + integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA== + +esprima@^4.0.0, esprima@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +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: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +events@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +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@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= + +expand-template@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" + integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== + +expect@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/expect/-/expect-27.5.1.tgz#83ce59f1e5bdf5f9d2b94b61d2050db48f3fef74" + integrity sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw== + dependencies: + "@jest/types" "^27.5.1" + jest-get-type "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + +express@^4.17.3: + version "4.17.3" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.3.tgz#f6c7302194a4fb54271b73a1fe7a06478c8f85a1" + integrity sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.19.2" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.4.2" + 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.7" + qs "6.9.7" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.17.2" + serve-static "1.14.2" + setprototypeof "1.2.0" + statuses "~1.5.0" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +fast-json-stable-stringify@2.x, 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= + +fb-watchman@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" + integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg== + dependencies: + bser "2.1.1" + +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== + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +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-up@^4.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" + +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= + +form-data@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" + integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +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.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@^2.3.2, fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +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== + +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" + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-caller-file@^2.0.5: + 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-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + +get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + +get-port@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/get-port/-/get-port-4.2.0.tgz#e37368b1e863b7629c43c5a323625f95cf24b119" + integrity sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw== + +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.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +get-symbol-description@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + +getopts@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/getopts/-/getopts-2.3.0.tgz#71e5593284807e03e2427449d4f6712a268666f4" + integrity sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA== + +github-from-package@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" + integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4= + +glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + 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-dirs@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.0.tgz#70a76fe84ea315ab37b1f5576cbde7d48ef72686" + integrity sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA== + dependencies: + ini "2.0.0" + +globals@^11.1.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@^13.2.0: + version "13.13.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.13.0.tgz#ac32261060d8070e2719dd6998406e27d2b5727b" + integrity sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A== + dependencies: + type-fest "^0.20.2" + +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@^4.1.2, graceful-fs@^4.2.9: + version "4.2.9" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" + integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== + +has-bigints@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" + integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== + +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@^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-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbols@^1.0.1, has-symbols@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + +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-yarn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77" + integrity sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw== + +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.1.0" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" + integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== + dependencies: + inherits "^2.0.4" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +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" + +hmac-drbg@^1.0.1: + 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" + +html-encoding-sniffer@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" + integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ== + dependencies: + whatwg-encoding "^1.0.5" + +html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + +htmlnano@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/htmlnano/-/htmlnano-2.0.0.tgz#07376faa064f7e1e832dfd91e1a9f606b0bc9b78" + integrity sha512-thKQfhcp2xgtsWNE27A2bliEeqVL5xjAgGn0wajyttvFFsvFWWah1ntV9aEX61gz0T6MBQ5xK/1lXuEumhJTcg== + dependencies: + cosmiconfig "^7.0.1" + posthtml "^0.16.5" + timsort "^0.3.0" + +htmlparser2@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-7.2.0.tgz#8817cdea38bbc324392a90b1990908e81a65f5a5" + integrity sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.2.2" + domutils "^2.8.0" + entities "^3.0.1" + +http-cache-semantics@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" + integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== + +http-errors@1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c" + integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.1" + +http-proxy-agent@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" + integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== + dependencies: + "@tootallnate/once" "1" + agent-base "6" + debug "4" + +https-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" + integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== + dependencies: + agent-base "6" + debug "4" + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +iconv-lite@0.4.24: + 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" + +idb@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/idb/-/idb-7.0.1.tgz#d2875b3a2f205d854ee307f6d196f246fea590a7" + integrity sha512-UUxlE7vGWK5RfB/fDwEGgRf84DY/ieqNha6msMV99UsEMQhJ1RwbCd8AYBj3QMgnE3VZnfQvm4oKVCJTYlqIgg== + +ieee754@^1.1.13, ieee754@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +ignore-by-default@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" + integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk= + +immutable@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.0.0.tgz#b86f78de6adef3608395efb269a91462797e2c23" + integrity sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw== + +import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +import-lazy@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" + integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= + +import-local@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.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= + +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.4, inherits@~2.0.3, inherits@~2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ini@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" + integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== + +ini@~1.3.0: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + +internal-slot@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" + integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== + dependencies: + get-intrinsic "^1.1.0" + has "^1.0.3" + side-channel "^1.0.4" + +interpret@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" + integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== + +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-arguments@^1.0.4: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.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-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-callable@^1.1.4, is-callable@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" + integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== + +is-ci@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" + integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== + dependencies: + ci-info "^2.0.0" + +is-core-module@^2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" + integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA== + dependencies: + has "^1.0.3" + +is-date-object@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.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-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@^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-generator-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" + integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== + +is-generator-function@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" + integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== + dependencies: + has-tostringtag "^1.0.0" + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-installed-globally@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520" + integrity sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ== + dependencies: + global-dirs "^3.0.0" + is-path-inside "^3.0.2" + +is-json@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-json/-/is-json-2.0.1.tgz#6be166d144828a131d686891b983df62c39491ff" + integrity sha1-a+Fm0USCihMdaGiRuYPfYsOUkf8= + +is-nan@^1.2.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.3.2.tgz#043a54adea31748b55b6cd4e09aadafa69bd9e1d" + integrity sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + +is-negative-zero@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" + integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== + +is-npm@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-5.0.0.tgz#43e8d65cc56e1b67f8d47262cf667099193f45a8" + integrity sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA== + +is-number-object@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.6.tgz#6a7aaf838c7f0686a50b4553f7e54a96494e89f0" + integrity sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g== + dependencies: + has-tostringtag "^1.0.0" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +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-path-inside@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + +is-potential-custom-element-name@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" + integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== + +is-regex@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-shared-array-buffer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6" + integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA== + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" + +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" + +is-typed-array@^1.1.3, is-typed-array@^1.1.7: + version "1.1.8" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.8.tgz#cbaa6585dc7db43318bc5b89523ea384a6f65e79" + integrity sha512-HqH41TNZq2fgtGT8WHVFVJhBVGuY3AnP3Q36K8JKXUxSxRgk/d+7NjmwG2vo2mYmXK8UYZKu0qH8bVP5gEisjA== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + es-abstract "^1.18.5" + foreach "^2.0.5" + has-tostringtag "^1.0.0" + +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-weakref@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" + integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== + dependencies: + call-bind "^1.0.2" + +is-yarn-global@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232" + integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw== + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isbinaryfile@^4.0.2: + version "4.0.8" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.8.tgz#5d34b94865bd4946633ecc78a026fc76c5b11fcf" + integrity sha512-53h6XFniq77YdW+spoRrebh0mnmTxRPTlcuIArO57lmMdq4uBKFKaeTjnb92oYWrSn/LVL+LT+Hap2tFQj8V+w== + +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= + +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" + integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== + +istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz#7b49198b657b27a730b8e9cb601f1e1bff24c59a" + integrity sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" + +istanbul-lib-report@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" + integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^3.0.0" + supports-color "^7.1.0" + +istanbul-lib-source-maps@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + source-map "^0.6.1" + +istanbul-reports@^3.1.3: + version "3.1.4" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.4.tgz#1b6f068ecbc6c331040aab5741991273e609e40c" + integrity sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + +jest-changed-files@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.5.1.tgz#a348aed00ec9bf671cc58a66fcbe7c3dfd6a68f5" + integrity sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw== + dependencies: + "@jest/types" "^27.5.1" + execa "^5.0.0" + throat "^6.0.1" + +jest-circus@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.5.1.tgz#37a5a4459b7bf4406e53d637b49d22c65d125ecc" + integrity sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^0.7.0" + expect "^27.5.1" + is-generator-fn "^2.0.0" + jest-each "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-runtime "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" + slash "^3.0.0" + stack-utils "^2.0.3" + throat "^6.0.1" + +jest-cli@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.5.1.tgz#278794a6e6458ea8029547e6c6cbf673bd30b145" + integrity sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw== + dependencies: + "@jest/core" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + import-local "^3.0.2" + jest-config "^27.5.1" + jest-util "^27.5.1" + jest-validate "^27.5.1" + prompts "^2.0.1" + yargs "^16.2.0" + +jest-config@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.5.1.tgz#5c387de33dca3f99ad6357ddeccd91bf3a0e4a41" + integrity sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA== + dependencies: + "@babel/core" "^7.8.0" + "@jest/test-sequencer" "^27.5.1" + "@jest/types" "^27.5.1" + babel-jest "^27.5.1" + chalk "^4.0.0" + ci-info "^3.2.0" + deepmerge "^4.2.2" + glob "^7.1.1" + graceful-fs "^4.2.9" + jest-circus "^27.5.1" + jest-environment-jsdom "^27.5.1" + jest-environment-node "^27.5.1" + jest-get-type "^27.5.1" + jest-jasmine2 "^27.5.1" + jest-regex-util "^27.5.1" + jest-resolve "^27.5.1" + jest-runner "^27.5.1" + jest-util "^27.5.1" + jest-validate "^27.5.1" + micromatch "^4.0.4" + parse-json "^5.2.0" + pretty-format "^27.5.1" + slash "^3.0.0" + strip-json-comments "^3.1.1" + +jest-diff@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.5.1.tgz#a07f5011ac9e6643cf8a95a462b7b1ecf6680def" + integrity sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw== + dependencies: + chalk "^4.0.0" + diff-sequences "^27.5.1" + jest-get-type "^27.5.1" + pretty-format "^27.5.1" + +jest-docblock@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.5.1.tgz#14092f364a42c6108d42c33c8cf30e058e25f6c0" + integrity sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ== + dependencies: + detect-newline "^3.0.0" + +jest-each@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.5.1.tgz#5bc87016f45ed9507fed6e4702a5b468a5b2c44e" + integrity sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ== + dependencies: + "@jest/types" "^27.5.1" + chalk "^4.0.0" + jest-get-type "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" + +jest-environment-jsdom@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz#ea9ccd1fc610209655a77898f86b2b559516a546" + integrity sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + jest-mock "^27.5.1" + jest-util "^27.5.1" + jsdom "^16.6.0" + +jest-environment-node@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.5.1.tgz#dedc2cfe52fab6b8f5714b4808aefa85357a365e" + integrity sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + jest-mock "^27.5.1" + jest-util "^27.5.1" + +jest-get-type@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.5.1.tgz#3cd613c507b0f7ace013df407a1c1cd578bcb4f1" + integrity sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw== + +jest-haste-map@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz#9fd8bd7e7b4fa502d9c6164c5640512b4e811e7f" + integrity sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng== + dependencies: + "@jest/types" "^27.5.1" + "@types/graceful-fs" "^4.1.2" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.9" + jest-regex-util "^27.5.1" + jest-serializer "^27.5.1" + jest-util "^27.5.1" + jest-worker "^27.5.1" + micromatch "^4.0.4" + walker "^1.0.7" + optionalDependencies: + fsevents "^2.3.2" + +jest-jasmine2@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz#a037b0034ef49a9f3d71c4375a796f3b230d1ac4" + integrity sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/source-map" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + expect "^27.5.1" + is-generator-fn "^2.0.0" + jest-each "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-runtime "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" + throat "^6.0.1" + +jest-leak-detector@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz#6ec9d54c3579dd6e3e66d70e3498adf80fde3fb8" + integrity sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ== + dependencies: + jest-get-type "^27.5.1" + pretty-format "^27.5.1" + +jest-matcher-utils@^27.0.0, jest-matcher-utils@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz#9c0cdbda8245bc22d2331729d1091308b40cf8ab" + integrity sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw== + dependencies: + chalk "^4.0.0" + jest-diff "^27.5.1" + jest-get-type "^27.5.1" + pretty-format "^27.5.1" + +jest-message-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.5.1.tgz#bdda72806da10d9ed6425e12afff38cd1458b6cf" + integrity sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^27.5.1" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^27.5.1" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-mock@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.5.1.tgz#19948336d49ef4d9c52021d34ac7b5f36ff967d6" + integrity sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og== + dependencies: + "@jest/types" "^27.5.1" + "@types/node" "*" + +jest-pnp-resolver@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" + integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== + +jest-regex-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz#4da143f7e9fd1e542d4aa69617b38e4a78365b95" + integrity sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg== + +jest-resolve-dependencies@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz#d811ecc8305e731cc86dd79741ee98fed06f1da8" + integrity sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg== + dependencies: + "@jest/types" "^27.5.1" + jest-regex-util "^27.5.1" + jest-snapshot "^27.5.1" + +jest-resolve@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.5.1.tgz#a2f1c5a0796ec18fe9eb1536ac3814c23617b384" + integrity sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw== + dependencies: + "@jest/types" "^27.5.1" + chalk "^4.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-pnp-resolver "^1.2.2" + jest-util "^27.5.1" + jest-validate "^27.5.1" + resolve "^1.20.0" + resolve.exports "^1.1.0" + slash "^3.0.0" + +jest-runner@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.5.1.tgz#071b27c1fa30d90540805c5645a0ec167c7b62e5" + integrity sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ== + dependencies: + "@jest/console" "^27.5.1" + "@jest/environment" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.8.1" + graceful-fs "^4.2.9" + jest-docblock "^27.5.1" + jest-environment-jsdom "^27.5.1" + jest-environment-node "^27.5.1" + jest-haste-map "^27.5.1" + jest-leak-detector "^27.5.1" + jest-message-util "^27.5.1" + jest-resolve "^27.5.1" + jest-runtime "^27.5.1" + jest-util "^27.5.1" + jest-worker "^27.5.1" + source-map-support "^0.5.6" + throat "^6.0.1" + +jest-runtime@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.5.1.tgz#4896003d7a334f7e8e4a53ba93fb9bcd3db0a1af" + integrity sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/globals" "^27.5.1" + "@jest/source-map" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + chalk "^4.0.0" + cjs-module-lexer "^1.0.0" + collect-v8-coverage "^1.0.0" + execa "^5.0.0" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-message-util "^27.5.1" + jest-mock "^27.5.1" + jest-regex-util "^27.5.1" + jest-resolve "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + slash "^3.0.0" + strip-bom "^4.0.0" + +jest-serializer@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.5.1.tgz#81438410a30ea66fd57ff730835123dea1fb1f64" + integrity sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w== + dependencies: + "@types/node" "*" + graceful-fs "^4.2.9" + +jest-snapshot@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.5.1.tgz#b668d50d23d38054a51b42c4039cab59ae6eb6a1" + integrity sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA== + dependencies: + "@babel/core" "^7.7.2" + "@babel/generator" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/traverse" "^7.7.2" + "@babel/types" "^7.0.0" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/babel__traverse" "^7.0.4" + "@types/prettier" "^2.1.5" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^27.5.1" + graceful-fs "^4.2.9" + jest-diff "^27.5.1" + jest-get-type "^27.5.1" + jest-haste-map "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-util "^27.5.1" + natural-compare "^1.4.0" + pretty-format "^27.5.1" + semver "^7.3.2" + +jest-util@^27.0.0, jest-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.5.1.tgz#3ba9771e8e31a0b85da48fe0b0891fb86c01c2f9" + integrity sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw== + dependencies: + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + +jest-validate@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.5.1.tgz#9197d54dc0bdb52260b8db40b46ae668e04df067" + integrity sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ== + dependencies: + "@jest/types" "^27.5.1" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^27.5.1" + leven "^3.1.0" + pretty-format "^27.5.1" + +jest-watcher@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.5.1.tgz#71bd85fb9bde3a2c2ec4dc353437971c43c642a2" + integrity sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw== + dependencies: + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + jest-util "^27.5.1" + string-length "^4.0.1" + +jest-worker@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jest@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest/-/jest-27.5.1.tgz#dadf33ba70a779be7a6fc33015843b51494f63fc" + integrity sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ== + dependencies: + "@jest/core" "^27.5.1" + import-local "^3.0.2" + jest-cli "^27.5.1" + +"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.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsdom@^16.6.0: + version "16.7.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" + integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw== + dependencies: + abab "^2.0.5" + acorn "^8.2.4" + acorn-globals "^6.0.0" + cssom "^0.4.4" + cssstyle "^2.3.0" + data-urls "^2.0.0" + decimal.js "^10.2.1" + domexception "^2.0.1" + escodegen "^2.0.0" + form-data "^3.0.0" + html-encoding-sniffer "^2.0.1" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-potential-custom-element-name "^1.0.1" + nwsapi "^2.2.0" + parse5 "6.0.1" + saxes "^5.0.1" + symbol-tree "^3.2.4" + tough-cookie "^4.0.0" + w3c-hr-time "^1.0.2" + w3c-xmlserializer "^2.0.0" + webidl-conversions "^6.1.0" + whatwg-encoding "^1.0.5" + whatwg-mimetype "^2.3.0" + whatwg-url "^8.5.0" + ws "^7.4.6" + 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== + +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-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/json-source-map/-/json-source-map-0.6.1.tgz#e0b1f6f4ce13a9ad57e2ae165a24d06e62c79a0f" + integrity sha512-1QoztHPsMQqhDq0hlXY5ZqcEdUzxQEIxgFkKl4WUp2pgShObl+9ovi4kRh2TfvAfxAoHOJ9vIMEqk3k4iex7tg== + +json5@2.x, json5@^2.1.2, json5@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" + integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== + dependencies: + minimist "^1.2.5" + +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" + +kleur@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + +knex@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/knex/-/knex-1.0.4.tgz#b9db3c60d0e3a4af37239bb879244e50eb748124" + integrity sha512-cMQ81fpkVmr4ia20BtyrD3oPere/ir/Q6IGLAgcREKOzRVhMsasQ4nx1VQuDRJjqq6oK5kfcxmvWoYkHKrnuMA== + dependencies: + colorette "2.0.16" + commander "^8.3.0" + debug "4.3.3" + escalade "^3.1.1" + esm "^3.2.25" + getopts "2.3.0" + interpret "^2.2.0" + lodash "^4.17.21" + pg-connection-string "2.5.0" + rechoir "^0.8.0" + resolve-from "^5.0.0" + tarn "^3.0.2" + tildify "2.0.0" + +latest-version@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face" + integrity sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA== + dependencies: + package-json "^6.3.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== + +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" + +lilconfig@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.4.tgz#f4507d043d7058b380b6a8f5cb7bcd4b34cee082" + integrity sha512-bfTIN7lEsiooCocSISTWXkiWJkRqtL9wYtYy+8EK3Y41qh3mpwPU0ycTOgjdY9ErwXCc8QyrQp82bdL0Xkm9yA== + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +lmdb@^2.0.2: + version "2.2.6" + resolved "https://registry.yarnpkg.com/lmdb/-/lmdb-2.2.6.tgz#a52ef533812b8abcbe0033fc9d74d215e7dfc0a0" + integrity sha512-UmQV0oZZcV3EN6rjcAjIiuWcc3MYZGWQ0GUYz46Ron5fuTa/dUow7WSQa6leFkvZIKVUdECBWVw96tckfEzUFQ== + dependencies: + msgpackr "^1.5.4" + nan "^2.14.2" + node-gyp-build "^4.2.3" + ordered-binary "^1.2.4" + weak-lru-cache "^1.2.2" + +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.memoize@4.x, 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.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.17.21, lodash@^4.7.0: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +loose-envify@^1.1.0, loose-envify@^1.4.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" + +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== + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +make-dir@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +make-error@1.x: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +makeerror@1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" + integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== + dependencies: + tmpl "1.0.5" + +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" + +mdn-data@2.0.14: + version "2.0.14" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" + integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== + +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= + +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@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +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@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" + integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== + dependencies: + braces "^3.0.1" + picomatch "^2.2.3" + +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.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +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== + +mime@^2.4.4: + version "2.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== + +mimic-fn@^2.1.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== + +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + +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.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.4: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.0, minimist@^1.2.3, 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-classic@^0.5.2, mkdirp-classic@^0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + +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.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +msgpackr-extract@^1.0.14: + version "1.0.16" + resolved "https://registry.yarnpkg.com/msgpackr-extract/-/msgpackr-extract-1.0.16.tgz#701c4f6e6f25c100ae84557092274e8fffeefe45" + integrity sha512-fxdRfQUxPrL/TizyfYfMn09dK58e+d65bRD/fcaVH4052vj30QOzzqxcQIS7B0NsqlypEQ/6Du3QmP2DhWFfCA== + dependencies: + nan "^2.14.2" + node-gyp-build "^4.2.3" + +msgpackr@^1.5.1, msgpackr@^1.5.4: + version "1.5.5" + resolved "https://registry.yarnpkg.com/msgpackr/-/msgpackr-1.5.5.tgz#c0562abc2951d7e29f75d77a8656b01f103a042c" + integrity sha512-JG0V47xRIQ9pyUnx6Hb4+3TrQoia2nA3UIdmyTldhxaxtKFkekkKpUW/N6fwHwod9o4BGuJGtouxOk+yCP5PEA== + optionalDependencies: + msgpackr-extract "^1.0.14" + +nan@^2.14.2: + version "2.15.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee" + integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ== + +nanoid@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" + integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== + +napi-build-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" + integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== + +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.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +node-abi@^3.3.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.8.0.tgz#679957dc8e7aa47b0a02589dbfde4f77b29ccb32" + integrity sha512-tzua9qWWi7iW4I42vUPKM+SfaF0vQSLAm4yO5J83mSwB7GeoWrDKC/K+8YCnYNwqP5duwazbw2X9l4m8SC2cUw== + dependencies: + semver "^7.3.5" + +node-addon-api@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161" + integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A== + +node-addon-api@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-4.3.0.tgz#52a1a0b475193e0928e98e0426a0d1254782b77f" + integrity sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ== + +node-gyp-build@^4.2.3, node-gyp-build@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.3.0.tgz#9f256b03e5826150be39c764bf51e993946d71a3" + integrity sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q== + +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= + +node-releases@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.2.tgz#7139fe71e2f4f11b47d4d2986aaf8c48699e0c01" + integrity sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg== + +nodemon@^2.0.15: + version "2.0.15" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.15.tgz#504516ce3b43d9dc9a955ccd9ec57550a31a8d4e" + integrity sha512-gdHMNx47Gw7b3kWxJV64NI+Q5nfl0y5DgDbiVtShiwa7Z0IZ07Ll4RLFo6AjrhzMtoEZn5PDE3/c2AbVsiCkpA== + dependencies: + chokidar "^3.5.2" + debug "^3.2.7" + ignore-by-default "^1.0.1" + minimatch "^3.0.4" + pstree.remy "^1.1.8" + semver "^5.7.1" + supports-color "^5.5.0" + touch "^3.1.0" + undefsafe "^2.0.5" + update-notifier "^5.1.0" + +nopt@~1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" + integrity sha1-bd0hvSoxQXuScn3Vhfim83YI6+4= + dependencies: + abbrev "1" + +normalize-path@^3.0.0, 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-url@^4.1.0: + version "4.5.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" + integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== + +normalize-url@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" + integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +npmlog@^4.0.1: + 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@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.1.tgz#2efe162f5c3da06a28959fbd3db75dbeea9f0fc2" + integrity sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w== + dependencies: + boolbase "^1.0.0" + +nullthrows@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/nullthrows/-/nullthrows-1.1.1.tgz#7818258843856ae971eae4208ad7d7eb19a431b1" + integrity sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw== + +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.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" + integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== + +object-assign@^4, 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-inspect@^1.11.0, object-inspect@^1.9.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" + integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== + +object-is@^1.0.1: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +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.assign@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" + +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" + +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +optionator@^0.8.1: + 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" + +ordered-binary@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/ordered-binary/-/ordered-binary-1.2.4.tgz#51d3a03af078a0bdba6c7bc8f4fedd1f5d45d83e" + integrity sha512-A/csN0d3n+igxBPfUrjbV5GC69LWj2pjZzAAeeHXLukQ4+fytfP4T1Lg0ju7MSPSwq7KtHkGaiwO8URZN5IpLg== + +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= + +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-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@^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-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== + +package-json@^6.3.0: + version "6.5.0" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0" + integrity sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ== + dependencies: + got "^9.6.0" + registry-auth-token "^4.0.0" + registry-url "^5.0.0" + semver "^6.2.0" + +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== + +parcel@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/parcel/-/parcel-2.3.2.tgz#d1cb475f27edae981edea7a7104e04d3a35a87ca" + integrity sha512-4jhgoBcQaiGKmnmBvNyKyOvZrxCgzgUzdEoVup/fRCOP99hNmvYIN5IErIIJxsU9ObcG/RGCFF8wa4kVRsWfIg== + dependencies: + "@parcel/config-default" "2.3.2" + "@parcel/core" "2.3.2" + "@parcel/diagnostic" "2.3.2" + "@parcel/events" "2.3.2" + "@parcel/fs" "2.3.2" + "@parcel/logger" "2.3.2" + "@parcel/package-manager" "2.3.2" + "@parcel/reporter-cli" "2.3.2" + "@parcel/reporter-dev-server" "2.3.2" + "@parcel/utils" "2.3.2" + chalk "^4.1.0" + commander "^7.0.0" + get-port "^4.2.0" + v8-compile-cache "^2.0.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, parse-asn1@^5.1.5: + version "5.1.6" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" + integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw== + dependencies: + asn1.js "^5.2.0" + browserify-aes "^1.0.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" + +parse-json@^5.0.0, parse-json@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +parse5@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== + +parseqs@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.6.tgz#8e4bb5a19d1cdc844a08ac974d34e273afa670d5" + integrity sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w== + +parseuri@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.6.tgz#e1496e829e3ac2ff47f39a4dd044b32823c4a25a" + integrity sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow== + +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== + +path-browserify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" + integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== + +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-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +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@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +pbkdf2@^3.0.3: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" + integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== + 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" + +pg-connection-string@2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.5.0.tgz#538cadd0f7e603fc09a12590f3b8a452c2c0cf34" + integrity sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pirates@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" + integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== + +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +postcss-calc@^8.2.3: + version "8.2.4" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-8.2.4.tgz#77b9c29bfcbe8a07ff6693dc87050828889739a5" + integrity sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q== + dependencies: + postcss-selector-parser "^6.0.9" + postcss-value-parser "^4.2.0" + +postcss-colormin@^*: + version "5.3.0" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.3.0.tgz#3cee9e5ca62b2c27e84fce63affc0cfb5901956a" + integrity sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg== + dependencies: + browserslist "^4.16.6" + caniuse-api "^3.0.0" + colord "^2.9.1" + postcss-value-parser "^4.2.0" + +postcss-convert-values@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-5.1.0.tgz#f8d3abe40b4ce4b1470702a0706343eac17e7c10" + integrity sha512-GkyPbZEYJiWtQB0KZ0X6qusqFHUepguBCNFi9t5JJc7I2OTXG7C0twbTLvCfaKOLl3rSXmpAwV7W5txd91V84g== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-discard-comments@^*: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-5.1.1.tgz#e90019e1a0e5b99de05f63516ce640bd0df3d369" + integrity sha512-5JscyFmvkUxz/5/+TB3QTTT9Gi9jHkcn8dcmmuN68JQcv3aQg4y88yEHHhwFB52l/NkaJ43O0dbksGMAo49nfQ== + +postcss-discard-duplicates@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz#9eb4fe8456706a4eebd6d3b7b777d07bad03e848" + integrity sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw== + +postcss-discard-empty@^*: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz#e57762343ff7f503fe53fca553d18d7f0c369c6c" + integrity sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A== + +postcss-discard-overridden@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz#7e8c5b53325747e9d90131bb88635282fb4a276e" + integrity sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw== + +postcss-merge-longhand@^*: + version "5.1.2" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-5.1.2.tgz#fe3002f38ad5827c1d6f7d5bb3f71d2566a2a138" + integrity sha512-18/bp9DZnY1ai9RlahOfLBbmIUKfKFPASxRCiZ1vlpZqWPCn8qWPFlEozqmWL+kBtcEQmG8W9YqGCstDImvp/Q== + dependencies: + postcss-value-parser "^4.2.0" + stylehacks "^*" + +postcss-merge-rules@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.1.0.tgz#a2d5117eba09c8686a5471d97bd9afcf30d1b41f" + integrity sha512-NecukEJovQ0mG7h7xV8wbYAkXGTO3MPKnXvuiXzOKcxoOodfTTKYjeo8TMhAswlSkjcPIBlnKbSFcTuVSDaPyQ== + dependencies: + browserslist "^4.16.6" + caniuse-api "^3.0.0" + cssnano-utils "^3.1.0" + postcss-selector-parser "^6.0.5" + +postcss-minify-font-values@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz#f1df0014a726083d260d3bd85d7385fb89d1f01b" + integrity sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-minify-gradients@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-5.1.0.tgz#de0260a67a13b7b321a8adc3150725f2c6612377" + integrity sha512-J/TMLklkONn3LuL8wCwfwU8zKC1hpS6VcxFkNUNjmVt53uKqrrykR3ov11mdUYyqVMEx67slMce0tE14cE4DTg== + dependencies: + colord "^2.9.1" + cssnano-utils "^3.1.0" + postcss-value-parser "^4.2.0" + +postcss-minify-params@^*: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-5.1.1.tgz#c5f8e7dac565e577dd99904787fbec576cbdbfb2" + integrity sha512-WCpr+J9Uz8XzMpAfg3UL8z5rde6MifBbh5L8bn8S2F5hq/YDJJzASYCnCHvAB4Fqb94ys8v95ULQkW2EhCFvNg== + dependencies: + browserslist "^4.16.6" + cssnano-utils "^3.1.0" + postcss-value-parser "^4.2.0" + +postcss-minify-selectors@^*: + version "5.2.0" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-5.2.0.tgz#17c2be233e12b28ffa8a421a02fc8b839825536c" + integrity sha512-vYxvHkW+iULstA+ctVNx0VoRAR4THQQRkG77o0oa4/mBS0OzGvvzLIvHDv/nNEM0crzN2WIyFU5X7wZhaUK3RA== + dependencies: + postcss-selector-parser "^6.0.5" + +postcss-normalize-charset@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz#9302de0b29094b52c259e9b2cf8dc0879879f0ed" + integrity sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg== + +postcss-normalize-display-values@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz#72abbae58081960e9edd7200fcf21ab8325c3da8" + integrity sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-positions@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-5.1.0.tgz#902a7cb97cf0b9e8b1b654d4a43d451e48966458" + integrity sha512-8gmItgA4H5xiUxgN/3TVvXRoJxkAWLW6f/KKhdsH03atg0cB8ilXnrB5PpSshwVu/dD2ZsRFQcR1OEmSBDAgcQ== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-repeat-style@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.0.tgz#f6d6fd5a54f51a741cc84a37f7459e60ef7a6398" + integrity sha512-IR3uBjc+7mcWGL6CtniKNQ4Rr5fTxwkaDHwMBDGGs1x9IVRkYIT/M4NelZWkAOBdV6v3Z9S46zqaKGlyzHSchw== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-string@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz#411961169e07308c82c1f8c55f3e8a337757e228" + integrity sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-timing-functions@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz#d5614410f8f0b2388e9f240aa6011ba6f52dafbb" + integrity sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-unicode@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.0.tgz#3d23aede35e160089a285e27bf715de11dc9db75" + integrity sha512-J6M3MizAAZ2dOdSjy2caayJLQT8E8K9XjLce8AUQMwOrCvjCHv24aLC/Lps1R1ylOfol5VIDMaM/Lo9NGlk1SQ== + dependencies: + browserslist "^4.16.6" + postcss-value-parser "^4.2.0" + +postcss-normalize-url@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz#ed9d88ca82e21abef99f743457d3729a042adcdc" + integrity sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew== + dependencies: + normalize-url "^6.0.1" + postcss-value-parser "^4.2.0" + +postcss-normalize-whitespace@^*: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz#08a1a0d1ffa17a7cc6efe1e6c9da969cc4493cfa" + integrity sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-ordered-values@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-5.1.0.tgz#04ef429e0991b0292bc918b135cd4c038f7b889f" + integrity sha512-wU4Z4D4uOIH+BUKkYid36gGDJNQtkVJT7Twv8qH6UyfttbbJWyw4/xIPuVEkkCtQLAJ0EdsNSh8dlvqkXb49TA== + dependencies: + cssnano-utils "^3.1.0" + postcss-value-parser "^4.2.0" + +postcss-reduce-initial@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.1.0.tgz#fc31659ea6e85c492fb2a7b545370c215822c5d6" + integrity sha512-5OgTUviz0aeH6MtBjHfbr57tml13PuedK/Ecg8szzd4XRMbYxH4572JFG067z+FqBIf6Zp/d+0581glkvvWMFw== + dependencies: + browserslist "^4.16.6" + caniuse-api "^3.0.0" + +postcss-reduce-transforms@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz#333b70e7758b802f3dd0ddfe98bb1ccfef96b6e9" + integrity sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.9: + version "6.0.9" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.9.tgz#ee71c3b9ff63d9cd130838876c13a2ec1a992b2f" + integrity sha512-UO3SgnZOVTwu4kyLR22UQ1xZh086RyNZppb7lLAKBFK8a32ttG5i87Y/P3+2bRSjZNyJ1B7hfFNo273tKe9YxQ== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-svgo@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-5.1.0.tgz#0a317400ced789f233a28826e77523f15857d80d" + integrity sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA== + dependencies: + postcss-value-parser "^4.2.0" + svgo "^2.7.0" + +postcss-unique-selectors@^*: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz#a9f273d1eacd09e9aa6088f4b0507b18b1b541b6" + integrity sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA== + dependencies: + postcss-selector-parser "^6.0.5" + +postcss-value-parser@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== + +postcss@^8.4.5: + version "8.4.12" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.12.tgz#1e7de78733b28970fa4743f7da6f3763648b1905" + integrity sha512-lg6eITwYe9v6Hr5CncVbK70SoioNQIq81nsaG86ev5hAidQvmOeETBqs7jm43K2F5/Ley3ytDtriImV6TpNiSg== + dependencies: + nanoid "^3.3.1" + picocolors "^1.0.0" + source-map-js "^1.0.2" + +posthtml-parser@^0.10.1: + version "0.10.2" + resolved "https://registry.yarnpkg.com/posthtml-parser/-/posthtml-parser-0.10.2.tgz#df364d7b179f2a6bf0466b56be7b98fd4e97c573" + integrity sha512-PId6zZ/2lyJi9LiKfe+i2xv57oEjJgWbsHGGANwos5AvdQp98i6AtamAl8gzSVFGfQ43Glb5D614cvZf012VKg== + dependencies: + htmlparser2 "^7.1.1" + +posthtml-parser@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/posthtml-parser/-/posthtml-parser-0.11.0.tgz#25d1c7bf811ea83559bc4c21c189a29747a24b7a" + integrity sha512-QecJtfLekJbWVo/dMAA+OSwY79wpRmbqS5TeXvXSX+f0c6pW4/SE6inzZ2qkU7oAMCPqIDkZDvd/bQsSFUnKyw== + dependencies: + htmlparser2 "^7.1.1" + +posthtml-render@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/posthtml-render/-/posthtml-render-3.0.0.tgz#97be44931496f495b4f07b99e903cc70ad6a3205" + integrity sha512-z+16RoxK3fUPgwaIgH9NGnK1HKY9XIDpydky5eQGgAFVXTCSezalv9U2jQuNV+Z9qV1fDWNzldcw4eK0SSbqKA== + dependencies: + is-json "^2.0.1" + +posthtml@^0.16.4, posthtml@^0.16.5: + version "0.16.6" + resolved "https://registry.yarnpkg.com/posthtml/-/posthtml-0.16.6.tgz#e2fc407f67a64d2fa3567afe770409ffdadafe59" + integrity sha512-JcEmHlyLK/o0uGAlj65vgg+7LIms0xKXe60lcDOTU7oVX/3LuEuLwrQpW3VJ7de5TaFKiW4kWkaIpJL42FEgxQ== + dependencies: + posthtml-parser "^0.11.0" + posthtml-render "^3.0.0" + +prebuild-install@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.0.1.tgz#c10075727c318efe72412f333e0ef625beaf3870" + integrity sha512-QBSab31WqkyxpnMWQxubYAHR5S9B2+r81ucocew34Fkl98FhvKIF50jIJnNOBmAZfyNV7vE5T6gd3hTVWgY6tg== + dependencies: + detect-libc "^2.0.0" + expand-template "^2.0.3" + github-from-package "0.0.0" + minimist "^1.2.3" + mkdirp-classic "^0.5.3" + napi-build-utils "^1.0.1" + node-abi "^3.3.0" + npmlog "^4.0.1" + pump "^3.0.0" + rc "^1.2.7" + simple-get "^4.0.0" + tar-fs "^2.0.0" + tunnel-agent "^0.6.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@^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.5.1: + version "2.6.0" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.6.0.tgz#12f8f504c4d8ddb76475f441337542fa799207d4" + integrity sha512-m2FgJibYrBGGgQXNzfd0PuDGShJgRavjUoRCw1mZERIWVSXF0iLzLm+aOqTAbLnC3n6JzUhAA8uZnFVghHJ86A== + +pretty-format@^27.0.0, pretty-format@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" + integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== + dependencies: + ansi-regex "^5.0.1" + ansi-styles "^5.0.0" + react-is "^17.0.1" + +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== + +prompts@^2.0.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" + integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.5" + +prop-types@^15.8.1: + version "15.8.1" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.13.1" + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +psl@^1.1.33: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + +pstree.remy@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" + integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== + +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@^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" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + +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== + +pupa@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.1.1.tgz#f5e8fd4afc2c5d97828faa523549ed8744a20d62" + integrity sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A== + dependencies: + escape-goat "^2.0.0" + +qs@6.9.7: + version "6.9.7" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.7.tgz#4610846871485e1e048f44ae3b94033f0e675afe" + integrity sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw== + +querystring-es3@^0.2.1: + 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.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.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.3.tgz#8f80305d11c2a0a545c2d9d89d7a0286fcead43c" + integrity sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g== + dependencies: + bytes "3.1.2" + http-errors "1.8.1" + iconv-lite "0.4.24" + unpipe "1.0.0" + +rc@^1.2.7, rc@^1.2.8: + 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" + +react-dom@^17.0.2: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" + integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + scheduler "^0.20.2" + +react-is@^16.13.1: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + +react-is@^17.0.1: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== + +react-refresh@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.9.0.tgz#71863337adc3e5c2f8a6bfddd12ae3bfe32aafbf" + integrity sha512-Gvzk7OZpiqKSkxsQvO/mbTN1poglhmAV7gR/DdIrRrSMXraRQQlfikRJOr3Nb9GTMPC5kof948Zy6jJZIFtDvQ== + +react@^17.0.2: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" + integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + +readable-stream@^2.0.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" + +readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.5.0, readable-stream@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +rechoir@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.8.0.tgz#49f866e0d32146142da3ad8f0eff352b3215ff22" + integrity sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ== + dependencies: + resolve "^1.20.0" + +regenerator-runtime@^0.13.7: + version "0.13.9" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" + integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== + +registry-auth-token@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.1.tgz#6d7b4006441918972ccd5fedcd41dc322c79b250" + integrity sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw== + dependencies: + rc "^1.2.8" + +registry-url@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-5.1.0.tgz#e98334b50d5434b81136b44ec638d9c2009c5009" + integrity sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw== + dependencies: + rc "^1.2.8" + +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= + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + +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-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve.exports@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" + integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== + +resolve@^1.20.0: + version "1.22.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" + integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== + dependencies: + is-core-module "^2.8.1" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +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" + +rimraf@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + 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" + +safe-buffer@5.2.1, 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, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +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== + +"safer-buffer@>= 2.1.2 < 3", 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== + +sass@^1.38.0: + version "1.49.9" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.49.9.tgz#b15a189ecb0ca9e24634bae5d1ebc191809712f9" + integrity sha512-YlYWkkHP9fbwaFRZQRXgDi3mXZShslVmmo+FVK3kHLUELHHEYrCmL1x6IUjC7wLS6VuJSAFXRQS/DxdsC4xL1A== + dependencies: + chokidar ">=3.0.0 <4.0.0" + immutable "^4.0.0" + source-map-js ">=0.6.2 <2.0.0" + +saxes@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" + integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== + dependencies: + xmlchars "^2.2.0" + +scheduler@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" + integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + +semver-diff@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b" + integrity sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg== + dependencies: + semver "^6.3.0" + +semver@7.x, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + +semver@^5.7.0, semver@^5.7.1: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@^6.0.0, semver@^6.2.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== + +send@0.17.2: + version "0.17.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.2.tgz#926622f76601c41808012c8bf1688fe3906f7820" + integrity sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww== + 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.8.1" + mime "1.6.0" + ms "2.1.3" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + +serve-static@1.14.2: + version "1.14.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.2.tgz#722d6294b1d62626d41b43a013ece4598d292bfa" + integrity sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.2" + +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= + +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.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +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@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +simple-concat@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" + integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== + +simple-get@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543" + integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA== + dependencies: + decompress-response "^6.0.0" + once "^1.3.1" + simple-concat "^1.0.0" + +sisteransi@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +socket.io-adapter@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.3.3.tgz#4d6111e4d42e9f7646e365b4f578269821f13486" + integrity sha512-Qd/iwn3VskrpNO60BeRyCyr8ZWw9CPZyitW4AQwmRZ8zCiyDiL+znRnWX6tDHXnWn1sJrM1+b6Mn6wEDJJ4aYQ== + +socket.io-client@^4.4.1: + version "4.4.1" + resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-4.4.1.tgz#b6aa9448149d09b8d0b2bbf3d2fac310631fdec9" + integrity sha512-N5C/L5fLNha5Ojd7Yeb/puKcPWWcoB/A09fEjjNsg91EDVr5twk/OEyO6VT9dlLSUNY85NpW6KBhVMvaLKQ3vQ== + dependencies: + "@socket.io/component-emitter" "~3.0.0" + backo2 "~1.0.2" + debug "~4.3.2" + engine.io-client "~6.1.1" + parseuri "0.0.6" + socket.io-parser "~4.1.1" + +socket.io-parser@~4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.0.4.tgz#9ea21b0d61508d18196ef04a2c6b9ab630f4c2b0" + integrity sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g== + dependencies: + "@types/component-emitter" "^1.2.10" + component-emitter "~1.3.0" + debug "~4.3.1" + +socket.io-parser@~4.1.1: + version "4.1.2" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.1.2.tgz#0a97d4fb8e67022158a568450a6e41887e42035e" + integrity sha512-j3kk71QLJuyQ/hh5F/L2t1goqzdTL0gvDzuhTuNSwihfuFUrcSji0qFZmJJPtG6Rmug153eOPsUizeirf1IIog== + dependencies: + "@socket.io/component-emitter" "~3.0.0" + debug "~4.3.1" + +socket.io@^4.4.1: + version "4.4.1" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-4.4.1.tgz#cd6de29e277a161d176832bb24f64ee045c56ab8" + integrity sha512-s04vrBswdQBUmuWJuuNTmXUVJhP0cVky8bBDhdkf8y0Ptsu7fKU2LuLbts9g+pdmAdyMMn8F/9Mf1/wbtUN0fg== + dependencies: + accepts "~1.3.4" + base64id "~2.0.0" + debug "~4.3.2" + engine.io "~6.1.0" + socket.io-adapter "~2.3.3" + socket.io-parser "~4.0.4" + +"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + +source-map-support@^0.5.6, source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +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.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.7.3, source-map@~0.7.2: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + +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= + +stable@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" + integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== + +stack-utils@^2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" + integrity sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA== + dependencies: + escape-string-regexp "^2.0.0" + +"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= + +stream-browserify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-3.0.0.tgz#22b0a2850cdf6503e73085da1fc7b7d0c2122f2f" + integrity sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA== + dependencies: + inherits "~2.0.4" + readable-stream "^3.5.0" + +stream-http@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-3.2.0.tgz#1872dfcf24cb15752677e40e5c3f9cc1926028b5" + integrity sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A== + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.4" + readable-stream "^3.6.0" + xtend "^4.0.2" + +string-length@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" + integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== + dependencies: + char-regex "^1.0.2" + strip-ansi "^6.0.0" + +string-width@^1.0.1: + 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 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string.prototype.trimend@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" + integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +string.prototype.trimstart@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" + integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +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@~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@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +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= + +style-mod@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/style-mod/-/style-mod-4.0.0.tgz#97e7c2d68b592975f2ca7a63d0dd6fcacfe35a01" + integrity sha512-OPhtyEjyyN9x3nhPsu76f52yUGXiZcgvsrFVtvTkyGRQJ0XK+GPc6ov1z+lRpbeabka+MYEQxOYRnt5nF30aMw== + +stylehacks@^*: + version "5.1.0" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.1.0.tgz#a40066490ca0caca04e96c6b02153ddc39913520" + integrity sha512-SzLmvHQTrIWfSgljkQCw2++C9+Ne91d/6Sp92I8c5uHTcy/PgeHamwITIbBW9wnFTY/3ZfSXR9HIL6Ikqmcu6Q== + dependencies: + browserslist "^4.16.6" + postcss-selector-parser "^6.0.4" + +supports-color@^5.3.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" + +supports-color@^7.0.0, supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-hyperlinks@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb" + integrity sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ== + dependencies: + has-flag "^4.0.0" + supports-color "^7.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +svgo@^2.4.0, svgo@^2.7.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.8.0.tgz#4ff80cce6710dc2795f0c7c74101e6764cfccd24" + integrity sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg== + dependencies: + "@trysound/sax" "0.2.0" + commander "^7.2.0" + css-select "^4.1.3" + css-tree "^1.1.3" + csso "^4.2.0" + picocolors "^1.0.0" + stable "^0.1.8" + +symbol-tree@^3.2.4: + 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== + +tar-fs@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" + integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.1.4" + +tar-stream@^2.1.4: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" + integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== + dependencies: + bl "^4.0.3" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + +tarn@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/tarn/-/tarn-3.0.2.tgz#73b6140fbb881b71559c4f8bfde3d9a4b3d27693" + integrity sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ== + +terminal-link@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" + integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== + dependencies: + ansi-escapes "^4.2.1" + supports-hyperlinks "^2.0.0" + +terser@^5.2.0: + version "5.12.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.12.1.tgz#4cf2ebed1f5bceef5c83b9f60104ac4a78b49e9c" + integrity sha512-NXbs+7nisos5E+yXwAD+y7zrcTkMqb0dEJxIGtSKPdCBzopf7ni4odPul2aechpV7EXNvOudYOX2bb5tln1jbQ== + dependencies: + acorn "^8.5.0" + commander "^2.20.0" + source-map "~0.7.2" + source-map-support "~0.5.20" + +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" + minimatch "^3.0.4" + +throat@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" + integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w== + +tildify@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/tildify/-/tildify-2.0.0.tgz#f205f3674d677ce698b7067a99e949ce03b4754a" + integrity sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw== + +timers-browserify@^2.0.12: + version "2.0.12" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee" + integrity sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ== + dependencies: + setimmediate "^1.0.4" + +timsort@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" + integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= + +tmpl@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" + integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== + +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-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@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +touch@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" + integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== + dependencies: + nopt "~1.0.10" + +tough-cookie@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" + integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg== + dependencies: + psl "^1.1.33" + punycode "^2.1.1" + universalify "^0.1.2" + +tr46@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" + integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw== + dependencies: + punycode "^2.1.1" + +ts-jest@^27.1.3: + version "27.1.3" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-27.1.3.tgz#1f723e7e74027c4da92c0ffbd73287e8af2b2957" + integrity sha512-6Nlura7s6uM9BVUAoqLH7JHyMXjz8gluryjpPXxr3IxZdAXnU6FhjvVLHFtfd1vsE1p8zD1OJfskkc0jhTSnkA== + dependencies: + bs-logger "0.x" + fast-json-stable-stringify "2.x" + jest-util "^27.0.0" + json5 "2.x" + lodash.memoize "4.x" + make-error "1.x" + semver "7.x" + yargs-parser "20.x" + +tty-browserify@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.1.tgz#3f05251ee17904dfd0677546670db9651682b811" + integrity sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw== + +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-detect@4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +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-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + +typescript@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.2.tgz#fe12d2727b708f4eef40f51598b3398baa9611d4" + integrity sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg== + +uglify-js@^3.15.1: + version "3.15.3" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.15.3.tgz#9aa82ca22419ba4c0137642ba0df800cb06e0471" + integrity sha512-6iCVm2omGJbsu3JWac+p6kUiOpg3wFO2f8lIXjfEb8RrmLjzog1wTPMmwKB7swfzzqxj9YM+sGUM++u1qN4qJg== + +unbox-primitive@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" + integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== + dependencies: + function-bind "^1.1.1" + has-bigints "^1.0.1" + has-symbols "^1.0.2" + which-boxed-primitive "^1.0.2" + +undefsafe@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" + integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== + +unique-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" + integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg== + dependencies: + crypto-random-string "^2.0.0" + +universalify@^0.1.2: + 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= + +update-notifier@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-5.1.0.tgz#4ab0d7c7f36a231dd7316cf7729313f0214d9ad9" + integrity sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw== + dependencies: + boxen "^5.0.0" + chalk "^4.1.0" + configstore "^5.0.1" + has-yarn "^2.1.0" + import-lazy "^2.1.0" + is-ci "^2.0.0" + is-installed-globally "^0.4.0" + is-npm "^5.0.0" + is-yarn-global "^0.3.0" + latest-version "^5.1.0" + pupa "^2.1.1" + semver "^7.3.4" + semver-diff "^3.1.1" + xdg-basedir "^4.0.0" + +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@^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" + +util-deprecate@^1.0.1, util-deprecate@^1.0.2, 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@^0.12.0, util@^0.12.4: + version "0.12.4" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.4.tgz#66121a31420df8f01ca0c464be15dfa1d1850253" + integrity sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw== + dependencies: + inherits "^2.0.3" + is-arguments "^1.0.4" + is-generator-function "^1.0.7" + is-typed-array "^1.1.3" + safe-buffer "^5.1.2" + which-typed-array "^1.1.2" + +utility-types@^3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/utility-types/-/utility-types-3.10.0.tgz#ea4148f9a741015f05ed74fd615e1d20e6bed82b" + integrity sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg== + +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= + +v8-compile-cache@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" + integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== + +v8-to-istanbul@^8.1.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz#77b752fd3975e31bbcef938f85e9bd1c7a8d60ed" + integrity sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" + source-map "^0.7.3" + +vary@^1, vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +vm2@^3.9.9: + version "3.9.9" + resolved "https://registry.yarnpkg.com/vm2/-/vm2-3.9.9.tgz#c0507bc5fbb99388fad837d228badaaeb499ddc5" + integrity sha512-xwTm7NLh/uOjARRBs8/95H0e8fT3Ukw5D/JJWhxMbhKzNh1Nu981jQKvkep9iKYNxzlVrdzD0mlBGkDKZWprlw== + dependencies: + acorn "^8.7.0" + acorn-walk "^8.2.0" + +w3c-hr-time@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" + integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== + dependencies: + browser-process-hrtime "^1.0.0" + +w3c-keyname@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/w3c-keyname/-/w3c-keyname-2.2.4.tgz#4ade6916f6290224cdbd1db8ac49eab03d0eef6b" + integrity sha512-tOhfEwEzFLJzf6d1ZPkYfGj+FWhIpBux9ppoP3rlclw3Z0BZv3N7b7030Z1kYth+6rDuAsXUFr+d0VE6Ed1ikw== + +w3c-xmlserializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a" + integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA== + dependencies: + xml-name-validator "^3.0.0" + +walker@^1.0.7: + version "1.0.8" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" + integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== + dependencies: + makeerror "1.0.12" + +weak-lru-cache@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz#fdbb6741f36bae9540d12f480ce8254060dccd19" + integrity sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw== + +webidl-conversions@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" + integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA== + +webidl-conversions@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" + integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== + +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-mimetype@^2.3.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@^8.0.0, whatwg-url@^8.5.0: + version "8.7.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" + integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg== + dependencies: + lodash "^4.7.0" + tr46 "^2.1.0" + webidl-conversions "^6.1.0" + +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + +which-typed-array@^1.1.2: + version "1.1.7" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.7.tgz#2761799b9a22d4b8660b3c1b40abaa7739691793" + integrity sha512-vjxaB4nfDqwKI0ws7wZpxIlde1XrLX5uB0ZjpfshgmapJMD7jJWhZI+yToJTqaFByF0eNBcYxbjmCzoRP7CfEw== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + es-abstract "^1.18.5" + foreach "^2.0.5" + has-tostringtag "^1.0.0" + is-typed-array "^1.1.7" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" + integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== + dependencies: + string-width "^1.0.2 || 2 || 3 || 4" + +widest-line@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" + integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== + dependencies: + string-width "^4.0.0" + +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== + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + 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-file-atomic@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" + integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== + dependencies: + imurmurhash "^0.1.4" + is-typedarray "^1.0.0" + signal-exit "^3.0.2" + typedarray-to-buffer "^3.1.5" + +ws@^7.4.6: + version "7.5.7" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.7.tgz#9e0ac77ee50af70d58326ecff7e85eb3fa375e67" + integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A== + +ws@~8.2.3: + version "8.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" + integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA== + +xdg-basedir@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" + integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== + +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== + +xmlchars@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" + integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== + +xmlhttprequest-ssl@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz#91360c86b914e67f44dce769180027c0da618c67" + integrity sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A== + +xtend@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +xxhash-wasm@^0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/xxhash-wasm/-/xxhash-wasm-0.4.2.tgz#752398c131a4dd407b5132ba62ad372029be6f79" + integrity sha512-/eyHVRJQCirEkSZ1agRSCwriMhwlyUcFkXD5TPVSLP+IPzjsqMVzZwdoczLp1SoQU0R3dxz1RpIK+4YNQbCVOA== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yaml@^1.10.0, yaml@^1.10.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + +yargs-parser@20.x, yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs-parser@^21.0.0: + version "21.0.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.0.1.tgz#0267f286c877a4f0f728fceb6f8a3e4cb95c6e35" + integrity sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg== + +yargs@^16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yargs@^17.3.1: + version "17.3.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.3.1.tgz#da56b28f32e2fd45aefb402ed9c26f42be4c07b9" + integrity sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.0.0" + +yeast@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" + integrity sha1-AI4G2AlDIMNy28L47XagymyKxBk=