diff --git a/build.js b/build.js deleted file mode 100644 index c7f229e..0000000 --- a/build.js +++ /dev/null @@ -1,100 +0,0 @@ -const { promises: fs } = require("fs"); -const path = require("path"); -const { html: beautifyHtml } = require('js-beautify'); - -const buildConfig = require("./buildconfig"); - -// source: https://stackoverflow.com/a/41407246 -const escapeCodes = { - reset: "\x1b[0m", - bright: "\x1b[1m", - dim: "\x1b[2m", - underscore: "\x1b[4m", - blink: "\x1b[5m", - reverse: "\x1b[7m", - hidden: "\x1b[8m", - - fgBlack: "\x1b[30m", - fgRed: "\x1b[31m", - fgGreen: "\x1b[32m", - fgYellow: "\x1b[33m", - fgBlue: "\x1b[34m", - fgMagenta: "\x1b[35m", - fgCyan: "\x1b[36m", - fgWhite: "\x1b[37m", - - bgBlack: "\x1b[40m", - bgRed: "\x1b[41m", - bgGreen: "\x1b[42m", - bgYellow: "\x1b[43m", - bgBlue: "\x1b[44m", - bgMagenta: "\x1b[45m", - bgCyan: "\x1b[46m", - bgWhite: "\x1b[47m", -}; - -if (!buildConfig.allowSpecialCharacters) { - for (i in escapeCodes) { - escapeCodes[i] = ""; - } -} - -const specialCharacter = (c) => { - if (buildConfig.allowSpecialCharacters) { - return c; - } - return ""; -} - -const processPageOutput = async (out) => { - if (typeof out === "function") - out = await out(); - if (typeof out !== "string") - throw new Error("got non-string page output (maybe one of the pages isn't exporting a string?)"); - - if (buildConfig.postProcessing.trimOutput) { - out = out.trim(); - } - - if (buildConfig.postProcessing.beautifyOutput) { - out = beautifyHtml(out, buildConfig.postProcessing.beautifyOutputOptions); - } - - return out; -}; - -const findAllPages = async (directory) => - (await fs.readdir(directory)) - .filter( - f => f.endsWith(buildConfig.pageExtension) - ) - .map(f => directory + "/" + f); // TODO: hack - -const buildPage = async (pagePath) => { - const processed = await processPageOutput(require(pagePath)); - console.log(`${escapeCodes.fgGreen}${specialCharacter("→")}${escapeCodes.reset} Built ${escapeCodes.fgBlue}${path.parse(path.basename(pagePath, buildConfig.pageExtension)).name}${escapeCodes.reset}`); - return processed -}; - -const buildAllPages = async (directory) => - await Promise.all((await findAllPages(directory)) - .map( - async p => [p, (await buildPage(p))] - )); - -const exportAllPages = async (sourcePath, outputPath) => { - const pages = await buildAllPages(sourcePath); - for (const [pagePath, pageContent] of pages) { - const pageName = path.parse(path.basename(pagePath, buildConfig.pageExtension)).name; - await fs.writeFile(path.join(outputPath, pageName + ".html"), pageContent); - } - return pages.length; -}; - -const main = async () => { - const startTime = new Date(); - const builtPages = await exportAllPages(buildConfig.sourceDirectory, buildConfig.outputDirectory); - console.log(`${escapeCodes.fgGreen}${specialCharacter("✓")} Done! ${escapeCodes.fgBlue}Built ${builtPages} pages in ${((new Date()) - startTime)}ms.${escapeCodes.reset}`); -}; - -main(); \ No newline at end of file diff --git a/buildconfig.js b/buildconfig.js deleted file mode 100644 index 4cd394f..0000000 --- a/buildconfig.js +++ /dev/null @@ -1,14 +0,0 @@ -module.exports = { - sourceDirectory: "./src", - outputDirectory: "./out", - pageExtension: ".page.js", - postProcessing: { - trimOutput: false, - beautifyOutput: true, - beautifyOutputOptions: { - indent_size: 2, - preserve_newlines: false - } - }, - allowSpecialCharacters: true -}; \ No newline at end of file diff --git a/out/_/jd3ymgfg3gk6vrlaxhbn/GatewayClient.js b/out/_/jd3ymgfg3gk6vrlaxhbn/GatewayClient.js deleted file mode 100644 index 8c594a0..0000000 --- a/out/_/jd3ymgfg3gk6vrlaxhbn/GatewayClient.js +++ /dev/null @@ -1,105 +0,0 @@ -window.modules.register("GatewayClient", () => { - const messageSchema = { t: "number", d: "object" }; - const messageTypes = { - HELLO: 0, - YOO: 1, - READY: 2, - EVENT: 3 - }; - - class GatewayClient { - constructor(gatewayPath) { - this.gatewayPath = gatewayPath; - this.ws = null; - this.token = null; - this.user = null; - this.onEvent = (e) => {}; - this.onConnected = () => {}; - this.onDisconnected = () => {}; - } - - connect(token) { - if (!token) - token = this.token; - - console.log("gateway: connecting"); - - this.ws = new WebSocket(this.gatewayPath); - - this.ws.addEventListener("message", ({ data }) => { - if (typeof data !== "string") { - console.warn("gateway: got non-string data from server, ignoring..."); - return; - } - - let message; - try { - message = JSON.parse(data); - } catch(e) { - console.warn("gateway: got invalid JSON from server (failed to parse), ignoring..."); - return; - } - - if (!this._checkMessageSchema(message)) { - console.warn("gateway: got invalid JSON from server (does not match schema), ignoring..."); - return; - } - - switch (message.t) { - case messageTypes.HELLO: { - console.log("gateway: HELLO"); - this.ws.send(JSON.stringify({ - t: messageTypes.YOO, - d: { - token - } - })); - break; - } - case messageTypes.READY: { - console.log("gateway: READY"); - this.user = message.d.user; - this.onConnected(); - break; - } - case messageTypes.EVENT: { - this.onEvent(message.d); - break; - } - default: { - console.warn("gateway: got invalid JSON from server (invalid type), ignoring..."); - return; - } - } - }); - this.ws.addEventListener("open", () => { - console.log("gateway: open"); - }); - this.ws.addEventListener("close", ({ code }) => { - console.log("gateway: closed"); - this.onDisconnected(code); - if (code === 4001) { - console.log(`gateway: disconnect code is ${code} (bad auth), will not attempt reconnect`); - return; - } - setTimeout(() => { - console.log("gateway: reconnecting"); - this.connect(token); - }, 4000); - }); - } - - _checkMessageSchema(message) { - for (const [key, value] of Object.entries(message)) { - if (!messageSchema[key]) - return false; - - if (typeof value !== messageSchema[key]) - return false; - } - return true; - } - } - - return GatewayClient; -}); diff --git a/out/_/jd3ymgfg3gk6vrlaxhbn/app.js b/out/_/jd3ymgfg3gk6vrlaxhbn/app.js deleted file mode 100644 index 83d72df..0000000 --- a/out/_/jd3ymgfg3gk6vrlaxhbn/app.js +++ /dev/null @@ -1,21 +0,0 @@ -window.modules.register("$app", () => { - const App = window.modules.require("App"); - - if (!window._APP_ENV) - throw new Error("$app: could not find window._APP_ENV"); - if (!App) - throw new Error("$app: require('App') returned undefined"); - - const initialLoading = document.getElementById("initial-loading"); - if (initialLoading) { - initialLoading.parentElement.removeChild(initialLoading); - } - - const appMountElement = document.createElement("div"); - document.body.appendChild(appMountElement); - - const app = new App(appMountElement); - app.mount(); - - return app; -}); diff --git a/out/_/jd3ymgfg3gk6vrlaxhbn/components.js b/out/_/jd3ymgfg3gk6vrlaxhbn/components.js deleted file mode 100644 index db9f1bb..0000000 --- a/out/_/jd3ymgfg3gk6vrlaxhbn/components.js +++ /dev/null @@ -1,185 +0,0 @@ -window.modules.register("AuthPromptRoute", () => { - class AuthPromptRoute { - constructor() { - this.element = null; - } - - mountOn(target) { - if (this.element) - return; // Already mounted - - this.element = document.createRange().createContextualFragment(` -
- - -
- `).children[0]; - - this.element.querySelector("#continue-button").addEventListener("click", () => { - if (this.onPasswordSubmitted) - this.onPasswordSubmitted(this.element.querySelector("#code-input").value); - }); - - target.appendChild(this.element); - } - - unmount() { - if (!this.element) - return; // Already unmounted - this.element.parentElement.removeChild(this.element); - this.element = null; - } - } - - return AuthPromptRoute; -}); - -window.modules.register("MainChatView", () => { - class MainChatView { - constructor() { - this.element = null; - } - - mountOn(target) { - if (this.element) - return; // Already mounted - - this.element = document.createRange().createContextualFragment(` -
-
-
- - -
- `).children[0]; - - const textInput = this.element.querySelector("#message-input"); - this.element.querySelector("#message-submit").addEventListener("click", () => { - const message = textInput.value; - if (this.onSendMessage) - this.onSendMessage(message); - - textInput.value = ""; - }); - - target.appendChild(this.element); - } - - appendMessage(messageObject) { - const { author, content } = messageObject; - if (!this.element) - return; - - const usernameLetters = author.username - .split(""); - let authorUsernameNumber = 150; - usernameLetters.forEach(l => { - authorUsernameNumber += l.charCodeAt(0); - }); - - const messageElement = document.createRange().createContextualFragment(` -
- [author could not be loaded] - [content could not be loaded] -
- `).children[0]; - - messageElement.querySelector("b").innerText = `User ${authorUsernameNumber} `; - messageElement.querySelector("span").innerText = content; - - const container = this.element.querySelector("#messages-container"); - container.appendChild(messageElement); - container.scrollTop = container.scrollHeight; - } - - unmount() { - if (!this.element) - return; // Already unmounted - this.element.parentElement.removeChild(this.element); - this.element = null; - } - } - - return MainChatView; -}); - - -window.modules.register("App", () => { - const AuthPromptRoute = window.modules.require("AuthPromptRoute"); - const MainChatView = window.modules.require("MainChatView"); - const GatewayClient = window.modules.require("GatewayClient"); - - - class App { - constructor(mountElement) { - this.mountElement = mountElement; - this.currentMountedElement = null; - - this.authPromptRoute = new AuthPromptRoute(); - this.mainChatView = new MainChatView(); - this.gatewayClient = new GatewayClient(window._APP_ENV.gatewayBase); - } - - _mountElement(element) { - if (this.currentMountedElement) { - this.currentMountedElement.unmount(); - } - this.currentMountedElement = element; - this.currentMountedElement.mountOn(this.mountElement); - } - - _unmountAll() { - if (this.currentMountedElement) { - this.currentMountedElement.unmount(); - } - } - - mount() { - let serverId; - let channelId; - let token; - - this._mountElement(this.authPromptRoute); - - this.gatewayClient.onEvent = (e) => { - if (e.eventType === "MESSAGE_CREATE" && e.message && e.message.guild_id === serverId && e.message.channel_id === channelId) { - this.mainChatView.appendMessage(e.message); - } - }; - this.gatewayClient.onConnected = () => { - this._mountElement(this.mainChatView); - }; - this.gatewayClient.onDisconnected = () => { - this._mountElement(this.authPromptRoute); - }; - this.authPromptRoute.onPasswordSubmitted = (auth) => { - const parts = auth.split(",,"); - if (parts.length !== 3) - return; - - const [userToken, userServerId, userChannelId] = parts; - serverId = userServerId; - channelId = userChannelId; - token = userToken - this.gatewayClient.connect(token); - }; - this.mainChatView.onSendMessage = async (message) => { - if (typeof message === "string" && message.trim() === "") - return; - - await fetch(`${window._APP_ENV.apiBase}/guilds/${serverId}/channels/${channelId}/messages/create`, { - method: "POST", - body: JSON.stringify({ - content: message - }), - headers: { - "content-type": "application/json", - "authorization": token - } - }); - }; - } - } - - return App; -}); diff --git a/out/_/jd3ymgfg3gk6vrlaxhbn/index.html b/out/_/jd3ymgfg3gk6vrlaxhbn/index.html deleted file mode 100644 index eeedea7..0000000 --- a/out/_/jd3ymgfg3gk6vrlaxhbn/index.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - . - - - -

loading

- - - - - - - \ No newline at end of file diff --git a/out/_/jd3ymgfg3gk6vrlaxhbn/moduleruntime.js b/out/_/jd3ymgfg3gk6vrlaxhbn/moduleruntime.js deleted file mode 100644 index ebb5905..0000000 --- a/out/_/jd3ymgfg3gk6vrlaxhbn/moduleruntime.js +++ /dev/null @@ -1,26 +0,0 @@ -const modules = { - _cache: {}, - _registry: {}, - require(moduleName) { - if (this._cache[moduleName]) { - return this._cache[moduleName]; - } - - if (this._registry[moduleName]) { - const loaderFunction = this._registry[moduleName]; - this._cache[moduleName] = loaderFunction(1); - return this._cache[moduleName]; - } - - return null; - }, - register(moduleName, loaderFunction) { - this._registry[moduleName] = loaderFunction; - this._cache[moduleName] = loaderFunction(0); - }, - registerLazy(moduleName, loaderFunction) { - this._registry[moduleName] = loaderFunction; - } -}; - -window.modules = modules; diff --git a/out/res/fastnav.js b/out/res/fastnav.js new file mode 100644 index 0000000..3fdd4f1 --- /dev/null +++ b/out/res/fastnav.js @@ -0,0 +1,26 @@ +const map = {"projects.html":"
📘 waffleview >>

Mysterious! This project has no description.

📘 brainlet-reactview >>

a react frontend for waffle (brainlet)

📘 ravenview >>

Simple experimental low-level UI library written in C++.

📘 bridgecordview >>

bridge bot api for discord servers

📘 riceview >>

my personal forks of various software and my dotfiles

📘 hippOSview >>

simple osdev testing

📘 homepageview >>

Mysterious! This project has no description.

📘 brainletview >>

🎤🐢 An open source, self-hosted alternative to Discord

📘 portalview >>

waffletv's interface app

📘 capybaraview >>

simple and fast remote touchpad

📘 rotcpuview >>

Mysterious! This project has no description.

📘 quad-jview >>

a simple upload server

📘 blocklistsview >>

Some pi-hole blocklists

📘 wormholeview >>

A simple websocket abstraction.

📘 mcliview >>

a command-line minecraft launcher written in rust

📘 mustview >>

Helper program for deploying protocol associations needed for running Roblox on Linux

🍴 brainlet-clientview >>

Mysterious! This project has no description.

📘 luapageview >>

Mysterious! This project has no description.

📘 page-simplifyview >>

turn pages into pure html

","index.html":"

hippoz's website

i think

"}; +const content = document.getElementById("content"); + +const load = (page) => content.innerHTML = map[page.substring(1, page.length) || "_notfound"]; +const navigate = (page) => { + history.pushState(null, "", page); + load(page); +}; + +const populate = () => { + const elements = document.querySelectorAll("[href]"); + elements.forEach(element => { + const existingLink = element.getAttribute("href"); + if (map[existingLink]) { + element.setAttribute("href", "#"); + element.onclick = () => navigate(existingLink); + } + }); +}; + +const main = () => { + populate(); + window.onpopstate = () => {load(location.pathname); console.log("a");}; +}; + +main(); diff --git a/src/assets/fastnav.js b/src/assets/fastnav.js new file mode 100644 index 0000000..97a5a08 --- /dev/null +++ b/src/assets/fastnav.js @@ -0,0 +1,29 @@ +const map = "{{NAV_DATA}}"; +const content = document.getElementById("content"); + +const load = (page) => { + content.innerHTML = map[page.substring(1, page.length) || "_notfound"]; + console.log("a"); +}; +const navigate = (page) => { + history.pushState(null, "", page); + load(page); +}; + +const populate = () => { + const elements = document.querySelectorAll("[href]"); + elements.forEach(element => { + const existingLink = element.getAttribute("href"); + if (map[existingLink]) { + element.setAttribute("href", ""); + element.onclick = () => navigate(existingLink); + } + }); +}; + +const main = () => { + populate(); + window.onpopstate = () => load(location.pathname); +}; + +main(); diff --git a/src/blog.page.js b/src/blog.page.js deleted file mode 100644 index 09b961b..0000000 --- a/src/blog.page.js +++ /dev/null @@ -1,13 +0,0 @@ -const Page = require("./components/Page.component"); - -module.exports = Page({ - title: "hippoz blog", - description: "hippoz blog", - name: "blog", -})(` -

hippoz's blog

-

i think

-
-
-

no articles yet

-`); diff --git a/src/components/LinkButton.component.js b/src/components/LinkButton.component.js deleted file mode 100644 index bc5c801..0000000 --- a/src/components/LinkButton.component.js +++ /dev/null @@ -1,2 +0,0 @@ -module.exports = ({ link, text, selected=false }) => - `${text}`; \ No newline at end of file diff --git a/src/components/Navigation.component.js b/src/components/Navigation.component.js deleted file mode 100644 index 6cf105a..0000000 --- a/src/components/Navigation.component.js +++ /dev/null @@ -1,21 +0,0 @@ -const { navigationLinks, navigationBrandingText } = require("../env"); -const LinkButtonComponent = require("./LinkButton.component"); - -module.exports = ({ pageName }) => ` -
-
- ${navigationBrandingText} -
-
- ${ - navigationLinks.map( - ({link, text, name}) => - LinkButtonComponent({ - link, - text, - selected: name === pageName - }) - ).join("") - } -
-
`; \ No newline at end of file diff --git a/src/components/Page.component.js b/src/components/Page.component.js deleted file mode 100644 index 3d732c7..0000000 --- a/src/components/Page.component.js +++ /dev/null @@ -1,21 +0,0 @@ -const NavigationComponent = require("./Navigation.component"); - -module.exports = ({ title="page", description="a page", name="page" }) => (content) => -` - - - - - - ${title} - - - - ${NavigationComponent({ - pageName: name - })} -
- ${content} -
- -`; diff --git a/src/env/index.js b/src/env/index.js deleted file mode 100644 index f8962a2..0000000 --- a/src/env/index.js +++ /dev/null @@ -1,25 +0,0 @@ -const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args)); - -module.exports = { - navigationLinks: [ - {link: "index.html", text: "home", name: "home"}, - {link: "blog.html", text: "blog", name: "blog"}, - {link: "projects.html", text: "projects", name: "projects"}, - {link: "https://git.hippoz.xyz", text: "git", name: "__ext_git"}, - ], - repositoryList: { - gitTargetUsername: "hippoz", - repositoryFetchUrl: `https://git.hippoz.xyz/api/v1/users/hippoz/repos?page=1&limit=100`, - _cache: null, - fetchProjects: async function() { - if (this._cache) return this._cache; - - const response = await fetch(this.repositoryFetchUrl); - const json = await response.json(); - this._cache = json; - - return json; - } - }, - navigationBrandingText: "hippoz." -} \ No newline at end of file diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..74d2ab3 --- /dev/null +++ b/src/index.js @@ -0,0 +1,162 @@ +const fs = require("node:fs/promises"); +const path = require("node:path"); +const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args)); +const { html: beautifyHtml } = require('js-beautify'); + +const data = { + outputDirectory: "./out", + navigationLinks: [ + {link: "index.html", text: "home", name: "home"}, + {link: "projects.html", text: "projects", name: "projects"}, + {link: "https://git.hippoz.xyz", text: "git", name: "__ext_git"}, + ], + postProcessing: { + beautifyOutput: true, + beautifyOutputOptions: { + indent_size: 2, + preserve_newlines: false + }, + minifyOutputOptions: { + indent_size: 0, + preserve_newlines: false, + end_with_newline: false, + eol: "" + } + }, + repositoryList: { + gitTargetUsername: "hippoz", + repositoryFetchUrl: `https://git.hippoz.xyz/api/v1/users/hippoz/repos?page=1&limit=100`, + _cache: null, + fetchProjects: async function() { + if (this._cache) return this._cache; + + const response = await fetch(this.repositoryFetchUrl); + const json = await response.json(); + this._cache = json; + + return json; + } + }, + navigationBrandingText: "hippoz." +}; + +const linkButton = ({ link, text, selected=false }) => ` + ${text} +`; + +const navigation = ({currentName}) => ` +
+
+ ${data.navigationBrandingText} +
+
+ ${data.navigationLinks.map(e => linkButton({ ...e, selected: currentName === e.name })).join("")} +
+
+`; + +const makePage = ({ name, description, title }) => content => [` + + + + + + + ${title} + + + + ${navigation({currentName: name})} +
+ ${content} +
+ + + + +`, content]; + +const indexPage = () => makePage({ + title: "hippoz", + description: "hippoz website homepage", + name: "home", +})(` +

hippoz's website

+

i think

+`); + +const projectsPage = async () => makePage({ + title: "hippoz", + description: "hippoz projects", + name: "projects", +})(` + ${ + (await data.repositoryList.fetchProjects()) + .sort((a, b) => b.size - a.size) // biggest projects first + .filter(a => !a.archived) + .map( + repo =>` +
+
+ ${repo.fork ? "🍴" : "📘"} ${repo.name} + view >> +
+ ${repo.description ? `

${repo.description}

` : `

Mysterious! This project has no description.

`} +
` + ) + .join("\n") + } +`); + +const pages = { + "projects.html": projectsPage, + "index.html": indexPage +}; +let renderedPageCache = null; + +const renderPages = async () => { + if (renderedPageCache) return renderedPageCache; + + renderedPageCache = {}; + for (const [pageName, builder] of Object.entries(pages)) { + renderedPageCache[pageName] = await builder(); + } + return renderedPageCache; +}; + +const deployNavScript = async () => { + let script = await fs.readFile("./src/assets/fastnav.js"); + if (script) script = script.toString(); + + const renderedPages = await renderPages(); + let navMap = {}; + for (let [pageName, content] of Object.entries(renderedPages)) { + if (data.postProcessing.beautifyOutput) { + content = beautifyHtml(content[1], data.postProcessing.minifyOutputOptions); + } + + navMap[pageName] = content; + } + + const content = script.replace(`"{{NAV_DATA}}"`, JSON.stringify(navMap)); + + await fs.writeFile("./out/res/fastnav.js", content); +}; + +const deployPages = async () => { + const renderedPages = await renderPages(); + for (let [pageName, content] of Object.entries(renderedPages)) { + if (data.postProcessing.beautifyOutput) { + content = beautifyHtml(content[0], data.postProcessing.beautifyOutputOptions); + } + + await fs.writeFile(path.join(data.outputDirectory, pageName), content); + } +}; + +const deployAll = async () => { + await deployNavScript(); + await deployPages(); +}; + +deployAll(); diff --git a/src/index.page.js b/src/index.page.js deleted file mode 100644 index 0042aaa..0000000 --- a/src/index.page.js +++ /dev/null @@ -1,10 +0,0 @@ -const Page = require("./components/Page.component"); - -module.exports = Page({ - title: "hippoz", - description: "hippoz website homepage", - name: "home", -})(` -

hippoz's website

-

i think

-`); diff --git a/src/projects.page.js b/src/projects.page.js deleted file mode 100644 index dc9d3a4..0000000 --- a/src/projects.page.js +++ /dev/null @@ -1,25 +0,0 @@ -const { repositoryList } = require("./env"); -const Page = require("./components/Page.component"); - -module.exports = async () => Page({ - title: "hippoz", - description: "hippoz website homepage", - name: "projects", -})(` - ${ - (await repositoryList.fetchProjects()) - .sort((a, b) => b.size - a.size) // biggest projects first - .filter(a => !a.archived) - .map( - repo =>` -
-
- ${repo.fork ? "🍴" : "📘"} ${repo.name} - view >> -
- ${repo.description ? `

${repo.description}

` : `

Mysterious! This project has no description.

`} -
` - ) - .join("\n") - } -`); diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..d1e0bd1 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,197 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +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== + +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== + +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" + +commander@^2.19.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== + +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= + +config-chain@^1.1.13: + version "1.1.13" + resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4" + integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ== + dependencies: + ini "^1.3.4" + proto-list "~1.2.1" + +data-uri-to-buffer@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz#b5db46aea50f6176428ac05b73be39a57701a64b" + integrity sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA== + +editorconfig@^0.15.3: + version "0.15.3" + resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-0.15.3.tgz#bef84c4e75fb8dcb0ce5cee8efd51c15999befc5" + integrity sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g== + dependencies: + commander "^2.19.0" + lru-cache "^4.1.5" + semver "^5.6.0" + sigmund "^1.0.1" + +fetch-blob@^3.1.2, fetch-blob@^3.1.4: + version "3.1.5" + resolved "https://registry.yarnpkg.com/fetch-blob/-/fetch-blob-3.1.5.tgz#0077bf5f3fcdbd9d75a0b5362f77dbb743489863" + integrity sha512-N64ZpKqoLejlrwkIAnb9iLSA3Vx/kjgzpcDhygcqJ2KKjky8nCgUQ+dzXtbrLaWZGZNmNfQTsiQ0weZ1svglHg== + dependencies: + node-domexception "^1.0.0" + web-streams-polyfill "^3.0.3" + +formdata-polyfill@^4.0.10: + version "4.0.10" + resolved "https://registry.yarnpkg.com/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz#24807c31c9d402e002ab3d8c720144ceb8848423" + integrity sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g== + dependencies: + fetch-blob "^3.1.2" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +glob@^7.1.3: + version "7.2.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.2.tgz#29deb38e1ef90f132d5958abe9c3ee8e87f3c318" + integrity sha512-NzDgHDiJwKYByLrL5lONmQFpK/2G78SMMfo+E9CuGlX4IkvfKDsiQSNPwAYxEy+e6p7ZQ3uslSLlwlJcqezBmQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +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: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ini@^1.3.4: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + +js-beautify@^1.14.0: + version "1.14.3" + resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.14.3.tgz#3dd11c949178de7f3bdf3f6f752778d3bed95150" + integrity sha512-f1ra8PHtOEu/70EBnmiUlV8nJePS58y9qKjl4JHfYWlFH6bo7ogZBz//FAZp7jDuXtYnGYKymZPlrg2I/9Zo4g== + dependencies: + config-chain "^1.1.13" + editorconfig "^0.15.3" + glob "^7.1.3" + nopt "^5.0.0" + +lru-cache@^4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +minimatch@^3.1.1: + 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" + +node-domexception@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" + integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== + +node-fetch@^3.0.0: + version "3.2.4" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.2.4.tgz#3fbca2d8838111048232de54cb532bd3cf134947" + integrity sha512-WvYJRN7mMyOLurFR2YpysQGuwYrJN+qrrpHjJDuKMcSPdfFccRUla/kng2mz6HWSBxJcqPbvatS6Gb4RhOzCJw== + dependencies: + data-uri-to-buffer "^4.0.0" + fetch-blob "^3.1.4" + formdata-polyfill "^4.0.10" + +nopt@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" + integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== + dependencies: + abbrev "1" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +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= + +proto-list@~1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" + integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= + +semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +sigmund@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" + integrity sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA= + +web-streams-polyfill@^3.0.3: + version "3.2.1" + resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6" + integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q== + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=