Merge pull request 'Publish Dev State' (#11) from dev into senpai

Reviewed-on: #11
This commit is contained in:
Daniel Kluge 2022-01-16 16:19:48 +01:00
commit cc05d78e81
21 changed files with 761 additions and 156 deletions

View File

@ -71,6 +71,7 @@ steps:
#- docker login -u $${DOCKER_USER} -p $${DOCKER_PASS}
- docker-compose -p website-dev -f docker-compose.dev.yml rm -s -v -f
- docker rmi $${REGISTRY_HOST}/$${IMAGE} || true
- docker rmi localhost:5000/$${IMAGE} || true
- docker pull $${REGISTRY_HOST}/$${IMAGE}
- docker-compose -p website-dev -f docker-compose.dev.yml up --no-build -d
- name: deploy-stable
@ -89,5 +90,6 @@ steps:
#- docker login -u $${DOCKER_USER} -p $${DOCKER_PASS}
- docker-compose -p website -f docker-compose.stable.yml rm -s -v -f
- docker rmi $${REGISTRY_HOST}/$${IMAGE} || true
- docker rmi localhost:5000/$${IMAGE} || true
- docker pull $${REGISTRY_HOST}/$${IMAGE}
- docker-compose -p website -f docker-compose.stable.yml up --no-build -d

View File

@ -1,7 +1,7 @@
{
"extends": "next/core-web-vitals",
"rules": {
"semi": ["warn", "always"],
"semi": ["warn", "always", { "omitLastInOneLineBlock": true }],
"quotes": ["warn", "double"],
"eqeqeq": "error"
}

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "public/projects"]
path = public/projects
url = git@git.c0ntroller.de:c0ntroller/frontpage-projects.git

View File

@ -0,0 +1,63 @@
import type { NextPage } from "next";
import { useEffect, useRef, useState } from "react";
import asciidoctor from "asciidoctor";
import styles from "../styles/ProjectModal.module.css";
interface ModalInput {
project: string;
visible: boolean;
setVisible: CallableFunction;
}
const ad = asciidoctor();
const ProjectModal: NextPage<ModalInput> = ({ project, visible, setVisible }) => {
const projectEmpty = "<div>Kein Projekt ausgewählt.</div>";
const [projectData, setProjectData] = useState<string>(projectEmpty);
const containerRef = useRef<HTMLDivElement>(null);
const projectNotFoundHtml = `<div class="${"error"}">Sorry! There is no data for this project. Please check back later to see if that changed!</div>`;
const projectServerErrorHtml = `<div class="${"error"}">Sorry! A server error happend when the project data was fetched!</div>`;
useEffect(() => {
if (project && project !== "") {
// TODO
// set Spinner
fetch(`/api/projects/${project}`).then((res) => {
if (res.status === 404) setProjectData(projectNotFoundHtml);
if (res.status !== 200) setProjectData(projectServerErrorHtml);
res.text().then(data => {
try {
setProjectData(ad.convert(data).toString());
} catch {
setProjectData(projectServerErrorHtml);
}
});
});
} else if (project === "") setProjectData(projectEmpty);
}, [project, projectEmpty, projectNotFoundHtml, projectServerErrorHtml]);
useEffect(() => {
if (projectData && containerRef.current && projectData !== "") {
containerRef.current.innerHTML = projectData;
}
}, [projectData, visible]);
const onEscClose = (e: React.KeyboardEvent) => {
if (e.key === "Escape") {
e.preventDefault();
setVisible(false);
}
};
if (!visible) return <></>;
return <div className={styles.modal} onKeyDown={onEscClose}>
<div ref={containerRef} className={styles.modalContainer}>
</div>
</div>;
};
export default ProjectModal;

View File

@ -1,24 +1,48 @@
import type { NextPage } from "next";
import React, { MutableRefObject } from "react";
import { commandCompletion, executeCommand } from "../../lib/commands";
import useSWR from "swr";
import { MutableRefObject, useState, createRef, useEffect } from "react";
import { CommandInterface } from "../../lib/commands";
import styles from "../../styles/REPL/REPLInput.module.css";
import { Project } from "../../lib/projects/types";
interface REPLInputParams {
historyCallback: CallableFunction;
historyClear: CallableFunction;
inputRef: MutableRefObject<HTMLInputElement|undefined>;
modalManipulation: {
setModalVisible: CallableFunction;
setModalProject: CallableFunction;
}
}
const REPLInput: NextPage<REPLInputParams> = ({historyCallback, historyClear, inputRef}) => {
const typed = React.createRef<HTMLSpanElement>();
const completion = React.createRef<HTMLSpanElement>();
const [currentCmd, setCurrentCmd] = React.useState<string[]>([]);
const [justTabbed, setJustTabbed] = React.useState<number>(0);
async function fetchProjects(endpoint: string): Promise<Project[]> {
const res = await fetch(endpoint);
return res.json();
}
const REPLInput: NextPage<REPLInputParams> = ({historyCallback, historyClear, inputRef, modalManipulation}) => {
const typed = createRef<HTMLSpanElement>();
const completion = createRef<HTMLSpanElement>();
const [currentCmd, setCurrentCmd] = useState<string[]>([]);
const [justTabbed, setJustTabbed] = useState<number>(0);
const [inCmdHistory, setInCmdHistory] = useState<number>(-1);
const [cmdHistory, setCmdHistory] = useState<string[]>([]);
const [usrInputTmp, setUsrInputTmp] = useState<string>("");
const [cmdIf, setCmdIf] = useState<CommandInterface>(new CommandInterface(modalManipulation, []));
const { data: projects, error: projectsError } = useSWR("/api/projects", fetchProjects);
const setInput = (inputRef: HTMLInputElement, input: string) => {
const nativeSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value")?.set;
if (!nativeSetter) return;
nativeSetter.call(inputRef, input);
//if(typed.current) typed.current.innerHTML = input;
//if(completion.current) completion.current.innerHTML = "";
const event = new Event("input", { bubbles: true });
inputRef.dispatchEvent(event);
};
const clearInput = (inputRef: HTMLInputElement) => {
inputRef.value = "";
if(typed.current) typed.current.innerHTML = "";
if(completion.current) completion.current.innerHTML = "";
setInput(inputRef, "");
};
const replinOnChange = (e: React.FormEvent<HTMLInputElement>) => {
@ -37,7 +61,7 @@ const REPLInput: NextPage<REPLInputParams> = ({historyCallback, historyClear, in
} else {
input.maxLength = 20;
// Get completion hint
const suggest = commandCompletion(currentInput);
const suggest = CommandInterface.commandCompletion(currentInput);
setCurrentCmd(suggest);
if (suggest.length === 0) suggest.push("");
if (typed.current) typed.current.innerHTML = currentInput;
@ -47,11 +71,12 @@ const REPLInput: NextPage<REPLInputParams> = ({historyCallback, historyClear, in
const keyEvent = (e: React.KeyboardEvent<HTMLInputElement>) => {
const input = (e.target as HTMLInputElement);
if (e.key === "Tab" && currentCmd.length !== 0) {
if (e.key === "Tab") {
e.preventDefault();
input.value = currentCmd[justTabbed % currentCmd.length];
if(typed.current) typed.current.innerHTML = currentCmd[justTabbed % currentCmd.length];
if(completion.current) completion.current.innerHTML = "";
}
if (e.key === "Tab" && currentCmd.length !== 0) {
const cmd = `${currentCmd[justTabbed % currentCmd.length]}${currentCmd.length === 1 ? " " : ""}`;
setInput(input, cmd);
setJustTabbed(justTabbed + 1);
return false;
} else setJustTabbed(0);
@ -59,20 +84,22 @@ const REPLInput: NextPage<REPLInputParams> = ({historyCallback, historyClear, in
if (e.key === "Enter") {
e.preventDefault();
const command = (e.target as HTMLInputElement).value;
setCmdHistory(cmdHistory.concat([command]).splice(0, 100));
clearInput(input);
setInCmdHistory(-1);
setCurrentCmd([]);
if (command === "clear") {
clearInput(input);
historyClear();
return false;
}
const result = executeCommand(command);
clearInput(input);
const result = cmdIf.executeCommand(command);
historyCallback(result);
return false;
}
if (e.key === "d" && e.ctrlKey) {
e.preventDefault();
const result = executeCommand("exit");
const result = cmdIf.executeCommand("exit");
clearInput(input);
historyCallback(result);
return false;
@ -91,8 +118,37 @@ const REPLInput: NextPage<REPLInputParams> = ({historyCallback, historyClear, in
return false;
}
if (e.key === "ArrowUp") {
e.preventDefault();
const idx = inCmdHistory + 1;
if (idx < cmdHistory.length) {
if (inCmdHistory === -1) setUsrInputTmp(input.value);
const cmd = cmdHistory[cmdHistory.length - idx - 1];
setInput(input, cmd);
setInCmdHistory(idx);
}
}
if (e.key === "ArrowDown") {
e.preventDefault();
const idx = inCmdHistory - 1;
if (0 <= idx) {
const cmd = cmdHistory[cmdHistory.length - idx - 1];
setInput(input, cmd);
setInCmdHistory(idx);
} else if (idx === -1) {
setInput(input, usrInputTmp);
setInCmdHistory(-1);
}
}
};
useEffect(() => {
if (!projectsError && projects) setCmdIf(new CommandInterface(modalManipulation, projects));
// In any other case we just don't create another interface.
}, [projects, projectsError, modalManipulation]);
return <div className={styles.wrapperwrapper}>
<span className={styles.inputstart}>$&nbsp;</span>
<div className={styles.wrapper}>

View File

@ -4,7 +4,15 @@ import REPLHistory from "./REPLHistory";
import styles from "../../styles/REPL/REPLComplete.module.css";
import type { NextPage } from "next";
const REPL: NextPage<{inputRef: MutableRefObject<HTMLInputElement|undefined>}> = ({ inputRef }) => {
interface IREPLProps {
inputRef: MutableRefObject<HTMLInputElement|undefined>;
modalManipulation: {
setModalVisible: CallableFunction;
setModalProject: CallableFunction;
}
}
const REPL: NextPage<IREPLProps> = ({ inputRef, modalManipulation }) => {
const [history, manipulateHistory] = useState<string[]>([]);
const onCommandExecuted = (result: string[]) => manipulateHistory(result.reverse().concat(history).slice(0, 1000));
const onClearHistory = () => manipulateHistory([]);
@ -15,7 +23,7 @@ const REPL: NextPage<{inputRef: MutableRefObject<HTMLInputElement|undefined>}> =
return (<div className={styles.container}>
<REPLHistory history={history} inputRef={inputRef} />
<REPLInput historyCallback={onCommandExecuted} historyClear={onClearHistory} inputRef={inputRef} />
<REPLInput historyCallback={onCommandExecuted} historyClear={onClearHistory} inputRef={inputRef} modalManipulation={modalManipulation} />
<div style={{flexGrow: 2}} onClick={focusInput}></div>
</div>);
};

View File

@ -4,6 +4,10 @@ services:
server:
image: localhost:5000/c0ntroller.de:dev
restart: always
volumes:
# Relative paths are located in the tmp folder where the projet is clones
- /srv/website/projects:/app/public/projects:ro
- git_mask:/app/public/projects/.git
networks:
- traefik
labels:
@ -22,4 +26,6 @@ services:
networks:
traefik:
external: true
external: true
volumes:
git_mask:

View File

@ -1,6 +1,4 @@
import type { Command, Flag } from "./types";
import type { Project } from "../projects/types";
import projectList from "../projects";
function getCommandByName(name: string): Command|undefined {
return commandList.find(cmd => cmd.name === name);
@ -145,10 +143,10 @@ const project: Command = {
list: {short: "l", long: "list", desc: "Show list of projects."}
},
subcommands: {name: {name: "name", desc: "Name of the project."}},
execute: (flags, args) => {
execute: (flags, args, _raw, cmdIf) => {
if (project.flags && checkFlagInclude(flags, project.flags.list)) {
const result = ["Found the following projects:"];
projectList.forEach(project => result.push(`\t${project.name}\t${project.short}`));
cmdIf.projects.forEach(project => result.push(`\t${project.name}\t${project.short}`));
return result;
}
@ -156,7 +154,7 @@ const project: Command = {
if (args[0] === "this") args[0] = "homepage";
const pjt = projectList.find(p => p.name === args[0]);
const pjt = cmdIf.projects.find(p => p.name === args[0]);
if (!pjt) return [
`Cannot find project ${args[0]}!`,
"You can see available projects using 'project -l'."
@ -172,8 +170,8 @@ const project: Command = {
}
if (project.flags && checkFlagInclude(flags, project.flags.minimal)) return pjt.desc;
// TODO
// Open project page here.
cmdIf.callbacks.setModalProject(args[0]);
cmdIf.callbacks.setModalVisible(true);
return [];
}
};

View File

@ -1,29 +1,45 @@
import { Project } from "../projects/types";
import { printSyntax, commandList } from "./definitions";
export function commandCompletion(input: string): string[] {
if (input === "") return [];
const candidates = commandList.filter(cmd => cmd.name.substring(0, input.length) === input).map(cmd => cmd.name);
return candidates;
interface CommandInterfaceCallbacks {
setModalVisible: CallableFunction,
setModalProject: CallableFunction
}
export function executeCommand(command: string): string[] {
if (!command) return [`$ ${command}`].concat(illegalCommand(command));
const args = command.split(" ");
const cmd = commandList.find(cmd => cmd.name === args[0]);
if (!cmd) return [`$ ${command}`].concat(illegalCommand(command));
export class CommandInterface {
callbacks: CommandInterfaceCallbacks;
projects: Project[];
const parsed = seperateFlags(args.splice(1));
const result = parsed.flags.includes("--help") ? printSyntax(cmd) : cmd.execute(parsed.flags, parsed.subcmds, command);
constructor(callbacks: CommandInterfaceCallbacks, projects: Project[]) {
this.callbacks = callbacks;
this.projects = projects;
}
return [`$ ${command}`].concat(result);
}
static commandCompletion(input: string): string[] {
if (input === "") return [];
const candidates = commandList.filter(cmd => cmd.name.substring(0, input.length) === input).map(cmd => cmd.name);
return candidates;
}
function seperateFlags(args: string[]): {flags: string[], subcmds: string[]} {
const flags = args.filter(arg => arg.substring(0,1) === "-");
const subcmds = args.filter(arg => arg.substring(0,1) !== "-");
return {flags, subcmds};
}
executeCommand(command: string): string[] {
if (!command) return [`$ ${command}`].concat(this.illegalCommand(command));
const args = command.split(" ");
const cmd = commandList.find(cmd => cmd.name === args[0]);
if (!cmd) return [`$ ${command}`].concat(this.illegalCommand(command));
const parsed = this.seperateFlags(args.splice(1));
const result = parsed.flags.includes("--help") ? printSyntax(cmd) : cmd.execute(parsed.flags, parsed.subcmds, command, this);
return [`$ ${command}`].concat(result);
}
function illegalCommand(command: string): string[] {
return [`Command '${command}' not found.`, "Type 'help' for help."];
private seperateFlags(args: string[]): {flags: string[], subcmds: string[]} {
const flags = args.filter(arg => arg.substring(0,1) === "-");
const subcmds = args.filter(arg => arg.substring(0,1) !== "-");
return {flags, subcmds};
}
private illegalCommand(command: string): string[] {
return [`Command '${command}' not found.`, "Type 'help' for help."];
}
}

View File

@ -1,3 +1,5 @@
import type { CommandInterface } from ".";
export interface Flag {
short: string;
long: string;
@ -15,5 +17,5 @@ export interface Command {
desc: string;
flags?: Record<string,Flag>;
subcommands?: Record<string,SubCommand>;
execute: (flags: string[], args: string[], raw: string, extra?: any) => string[];
execute: (flags: string[], args: string[], raw: string, cmdIf: CommandInterface) => string[];
}

View File

@ -1,21 +0,0 @@
import type { Project } from "./types";
const projectList: Project[] = [
{
name: "homepage",
short: "This website.",
desc: [
"This is my homepage.",
"What you see here should resemble an CLI. If you ever used Linux this should be pretty easy for you.",
"Everyone else: Have no fear. It is pretty simple. You just type in commands and the output is shown here or it does something on the webite.",
"To find out, which commands are available, you can type just 'help'.",
"",
"Currently everything is still in development. So if you come back in a few days/weeks/months/years something could have been changed!",
"",
"Have fun!"
],
repo: "https://git.c0ntroller.de/c0ntroller/frontpage"
}
];
export default projectList;

456
package-lock.json generated
View File

@ -6,10 +6,12 @@
"": {
"name": "my_website",
"dependencies": {
"asciidoctor": "^2.2.5",
"next": "12.0.7",
"phosphor-react": "^1.3.1",
"react": "17.0.2",
"react-dom": "17.0.2"
"react-dom": "17.0.2",
"swr": "^1.1.2"
},
"devDependencies": {
"@types/node": "16.11.11",
@ -19,6 +21,39 @@
"typescript": "4.5.2"
}
},
"node_modules/@asciidoctor/cli": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/@asciidoctor/cli/-/cli-3.4.0.tgz",
"integrity": "sha512-jOtxA0I6zB+6z+GGwm9+xhlmGTqCTkFPE902L6fauFlE6v7LxjhLYNxvjDVyn0zMrFLybvoSRcAnM3DcticNoQ==",
"dependencies": {
"yargs": "15.3.1"
},
"bin": {
"asciidoctor": "bin/asciidoctor",
"asciidoctorjs": "bin/asciidoctor"
},
"engines": {
"node": ">=8.11",
"npm": ">=5.0.0"
},
"peerDependencies": {
"@asciidoctor/core": "^2.0.0-rc.1"
}
},
"node_modules/@asciidoctor/core": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/@asciidoctor/core/-/core-2.2.5.tgz",
"integrity": "sha512-jtQPQ5EivgFbwvSyGKas4ANnMGGHPbmu791H9xrZKooA65JNI30jM2em5MvUXTTetSPgb6saUf+PJibEuSB6uw==",
"dependencies": {
"asciidoctor-opal-runtime": "0.3.3",
"unxhr": "1.0.1"
},
"engines": {
"node": ">=8.11",
"npm": ">=5.0.0",
"yarn": ">=1.1.0"
}
},
"node_modules/@babel/code-frame": {
"version": "7.12.11",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz",
@ -1534,6 +1569,52 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/asciidoctor": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/asciidoctor/-/asciidoctor-2.2.5.tgz",
"integrity": "sha512-rrmCK34faw+w+xGFQggjwPB0/pcISnwOXaulfJvn7j4Nm0bFwz+x4tG3ZANIA9+9i6Csex/PO0fSLBO8CSdzVA==",
"dependencies": {
"@asciidoctor/cli": "3.4.0",
"@asciidoctor/core": "2.2.5"
},
"bin": {
"asciidoctor": "bin/asciidoctor",
"asciidoctorjs": "bin/asciidoctor"
},
"engines": {
"node": ">=8.11",
"npm": ">=5.0.0",
"yarn": ">=1.1.0"
}
},
"node_modules/asciidoctor-opal-runtime": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/asciidoctor-opal-runtime/-/asciidoctor-opal-runtime-0.3.3.tgz",
"integrity": "sha512-/CEVNiOia8E5BMO9FLooo+Kv18K4+4JBFRJp8vUy/N5dMRAg+fRNV4HA+o6aoSC79jVU/aT5XvUpxSxSsTS8FQ==",
"dependencies": {
"glob": "7.1.3",
"unxhr": "1.0.1"
},
"engines": {
"node": ">=8.11"
}
},
"node_modules/asciidoctor-opal-runtime/node_modules/glob": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
"integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
"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"
},
"engines": {
"node": "*"
}
},
"node_modules/asn1.js": {
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz",
@ -1605,8 +1686,7 @@
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
"node_modules/base64-js": {
"version": "1.5.1",
@ -1652,7 +1732,6 @@
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -1811,6 +1890,14 @@
"node": ">=6"
}
},
"node_modules/camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
"engines": {
"node": ">=6"
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001283",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001283.tgz",
@ -1867,6 +1954,16 @@
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz",
"integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q=="
},
"node_modules/cliui": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
"dependencies": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.0",
"wrap-ansi": "^6.2.0"
}
},
"node_modules/color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
@ -1893,8 +1990,7 @@
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
"node_modules/constants-browserify": {
"version": "1.0.0",
@ -2059,6 +2155,14 @@
"ms": "2.0.0"
}
},
"node_modules/decamelize": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/deep-is": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
@ -3111,8 +3215,7 @@
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"node_modules/fsevents": {
"version": "2.3.2",
@ -3147,6 +3250,14 @@
"node": ">=6.9.0"
}
},
"node_modules/get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"engines": {
"node": "6.* || 8.* || >= 10.*"
}
},
"node_modules/get-intrinsic": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
@ -3456,7 +3567,6 @@
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"dev": true,
"dependencies": {
"once": "^1.3.0",
"wrappy": "1"
@ -3581,7 +3691,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true,
"engines": {
"node": ">=8"
}
@ -4035,7 +4144,6 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"dependencies": {
"brace-expansion": "^1.1.7"
},
@ -4313,7 +4421,6 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"dependencies": {
"wrappy": "1"
}
@ -4433,7 +4540,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
@ -4788,6 +4894,14 @@
"url": "https://github.com/sponsors/mysticatea"
}
},
"node_modules/require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
"integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/require-from-string": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
@ -4797,6 +4911,11 @@
"node": ">=0.10.0"
}
},
"node_modules/require-main-filename": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
},
"node_modules/resolve": {
"version": "1.20.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
@ -4917,6 +5036,11 @@
"semver": "bin/semver.js"
}
},
"node_modules/set-blocking": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
},
"node_modules/setimmediate": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
@ -5118,7 +5242,6 @@
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dev": true,
"dependencies": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
@ -5131,8 +5254,7 @@
"node_modules/string-width/node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
"node_modules/string.prototype.matchall": {
"version": "4.0.6",
@ -5267,6 +5389,14 @@
"node": ">=4"
}
},
"node_modules/swr": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/swr/-/swr-1.1.2.tgz",
"integrity": "sha512-UsM0eo5T+kRPyWFZtWRx2XR5qzohs/LS4lDC0GCyLpCYFmsfTk28UCVDbOE9+KtoXY4FnwHYiF+ZYEU3hnJ1lQ==",
"peerDependencies": {
"react": "^16.11.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/table": {
"version": "6.7.3",
"resolved": "https://registry.npmjs.org/table/-/table-6.7.3.tgz",
@ -5462,6 +5592,14 @@
"node": ">= 0.8"
}
},
"node_modules/unxhr": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/unxhr/-/unxhr-1.0.1.tgz",
"integrity": "sha512-MAhukhVHyaLGDjyDYhy8gVjWJyhTECCdNsLwlMoGFoNJ3o79fpQhtQuzmAE4IxCMDwraF4cW8ZjpAV0m9CRQbg==",
"engines": {
"node": ">=8.11"
}
},
"node_modules/uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
@ -5568,6 +5706,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/which-module": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
"integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
},
"node_modules/which-typed-array": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.7.tgz",
@ -5596,11 +5739,53 @@
"node": ">=0.10.0"
}
},
"node_modules/wrap-ansi": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
"dependencies": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/wrap-ansi/node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dependencies": {
"color-convert": "^2.0.1"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/wrap-ansi/node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dependencies": {
"color-name": "~1.1.4"
},
"engines": {
"node": ">=7.0.0"
}
},
"node_modules/wrap-ansi/node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
},
"node_modules/xtend": {
"version": "4.0.2",
@ -5610,12 +5795,50 @@
"node": ">=0.4"
}
},
"node_modules/y18n": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
},
"node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
},
"node_modules/yargs": {
"version": "15.3.1",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz",
"integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==",
"dependencies": {
"cliui": "^6.0.0",
"decamelize": "^1.2.0",
"find-up": "^4.1.0",
"get-caller-file": "^2.0.1",
"require-directory": "^2.1.1",
"require-main-filename": "^2.0.0",
"set-blocking": "^2.0.0",
"string-width": "^4.2.0",
"which-module": "^2.0.0",
"y18n": "^4.0.0",
"yargs-parser": "^18.1.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/yargs-parser": {
"version": "18.1.3",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
"dependencies": {
"camelcase": "^5.0.0",
"decamelize": "^1.2.0"
},
"engines": {
"node": ">=6"
}
},
"node_modules/yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
@ -5629,6 +5852,23 @@
}
},
"dependencies": {
"@asciidoctor/cli": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/@asciidoctor/cli/-/cli-3.4.0.tgz",
"integrity": "sha512-jOtxA0I6zB+6z+GGwm9+xhlmGTqCTkFPE902L6fauFlE6v7LxjhLYNxvjDVyn0zMrFLybvoSRcAnM3DcticNoQ==",
"requires": {
"yargs": "15.3.1"
}
},
"@asciidoctor/core": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/@asciidoctor/core/-/core-2.2.5.tgz",
"integrity": "sha512-jtQPQ5EivgFbwvSyGKas4ANnMGGHPbmu791H9xrZKooA65JNI30jM2em5MvUXTTetSPgb6saUf+PJibEuSB6uw==",
"requires": {
"asciidoctor-opal-runtime": "0.3.3",
"unxhr": "1.0.1"
}
},
"@babel/code-frame": {
"version": "7.12.11",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz",
@ -6710,6 +6950,39 @@
"es-abstract": "^1.19.0"
}
},
"asciidoctor": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/asciidoctor/-/asciidoctor-2.2.5.tgz",
"integrity": "sha512-rrmCK34faw+w+xGFQggjwPB0/pcISnwOXaulfJvn7j4Nm0bFwz+x4tG3ZANIA9+9i6Csex/PO0fSLBO8CSdzVA==",
"requires": {
"@asciidoctor/cli": "3.4.0",
"@asciidoctor/core": "2.2.5"
}
},
"asciidoctor-opal-runtime": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/asciidoctor-opal-runtime/-/asciidoctor-opal-runtime-0.3.3.tgz",
"integrity": "sha512-/CEVNiOia8E5BMO9FLooo+Kv18K4+4JBFRJp8vUy/N5dMRAg+fRNV4HA+o6aoSC79jVU/aT5XvUpxSxSsTS8FQ==",
"requires": {
"glob": "7.1.3",
"unxhr": "1.0.1"
},
"dependencies": {
"glob": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
"integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
"requires": {
"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"
}
}
}
},
"asn1.js": {
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz",
@ -6771,8 +7044,7 @@
"balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
"base64-js": {
"version": "1.5.1",
@ -6798,7 +7070,6 @@
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -6935,6 +7206,11 @@
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
"dev": true
},
"camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
},
"caniuse-lite": {
"version": "1.0.30001283",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001283.tgz",
@ -6979,6 +7255,16 @@
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz",
"integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q=="
},
"cliui": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
"requires": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.0",
"wrap-ansi": "^6.2.0"
}
},
"color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
@ -7005,8 +7291,7 @@
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
"constants-browserify": {
"version": "1.0.0",
@ -7150,6 +7435,11 @@
"ms": "2.0.0"
}
},
"decamelize": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
},
"deep-is": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
@ -7962,8 +8252,7 @@
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"fsevents": {
"version": "2.3.2",
@ -7988,6 +8277,11 @@
"integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
"peer": true
},
"get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
},
"get-intrinsic": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
@ -8204,7 +8498,6 @@
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"dev": true,
"requires": {
"once": "^1.3.0",
"wrappy": "1"
@ -8289,8 +8582,7 @@
"is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
},
"is-generator-function": {
"version": "1.0.10",
@ -8624,7 +8916,6 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@ -8822,7 +9113,6 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"requires": {
"wrappy": "1"
}
@ -8916,8 +9206,7 @@
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
},
"path-key": {
"version": "3.1.1",
@ -9182,12 +9471,22 @@
"integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
"dev": true
},
"require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
"integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
},
"require-from-string": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
"dev": true
},
"require-main-filename": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
},
"resolve": {
"version": "1.20.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
@ -9261,6 +9560,11 @@
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
},
"set-blocking": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
},
"setimmediate": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
@ -9425,7 +9729,6 @@
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dev": true,
"requires": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
@ -9435,8 +9738,7 @@
"emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
}
}
},
@ -9535,6 +9837,12 @@
"has-flag": "^3.0.0"
}
},
"swr": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/swr/-/swr-1.1.2.tgz",
"integrity": "sha512-UsM0eo5T+kRPyWFZtWRx2XR5qzohs/LS4lDC0GCyLpCYFmsfTk28UCVDbOE9+KtoXY4FnwHYiF+ZYEU3hnJ1lQ==",
"requires": {}
},
"table": {
"version": "6.7.3",
"resolved": "https://registry.npmjs.org/table/-/table-6.7.3.tgz",
@ -9687,6 +9995,11 @@
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
},
"unxhr": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/unxhr/-/unxhr-1.0.1.tgz",
"integrity": "sha512-MAhukhVHyaLGDjyDYhy8gVjWJyhTECCdNsLwlMoGFoNJ3o79fpQhtQuzmAE4IxCMDwraF4cW8ZjpAV0m9CRQbg=="
},
"uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
@ -9778,6 +10091,11 @@
"is-symbol": "^1.0.3"
}
},
"which-module": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
"integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
},
"which-typed-array": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.7.tgz",
@ -9797,23 +10115,87 @@
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
"dev": true
},
"wrap-ansi": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
"requires": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
},
"dependencies": {
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"requires": {
"color-convert": "^2.0.1"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
}
}
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
},
"xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
},
"y18n": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
},
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
},
"yargs": {
"version": "15.3.1",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz",
"integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==",
"requires": {
"cliui": "^6.0.0",
"decamelize": "^1.2.0",
"find-up": "^4.1.0",
"get-caller-file": "^2.0.1",
"require-directory": "^2.1.1",
"require-main-filename": "^2.0.0",
"set-blocking": "^2.0.0",
"string-width": "^4.2.0",
"which-module": "^2.0.0",
"y18n": "^4.0.0",
"yargs-parser": "^18.1.1"
}
},
"yargs-parser": {
"version": "18.1.3",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
"requires": {
"camelcase": "^5.0.0",
"decamelize": "^1.2.0"
}
},
"yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",

View File

@ -8,10 +8,12 @@
"lint": "npx next lint"
},
"dependencies": {
"asciidoctor": "^2.2.5",
"next": "12.0.7",
"phosphor-react": "^1.3.1",
"react": "17.0.2",
"react-dom": "17.0.2"
"react-dom": "17.0.2",
"swr": "^1.1.2"
},
"devDependencies": {
"@types/node": "16.11.11",

View File

@ -1,13 +0,0 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from "next";
type Data = {
name: string
}
export default function handler(
req: NextApiRequest,
res: NextApiResponse<Data>
) {
res.status(200).json({ name: "John Doe" });
}

7
pages/api/ping.ts Normal file
View File

@ -0,0 +1,7 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from "next";
export default function handler(_req: NextApiRequest, res: NextApiResponse<string>) {
res.status(200).send("Pong!");
res.end();
}

29
pages/api/projects.ts Normal file
View File

@ -0,0 +1,29 @@
import { readFileSync } from "fs";
import { resolve } from "path";
import type { NextApiRequest, NextApiResponse } from "next";
interface IFileError {
message: string;
name: string;
stack?: string;
code: string;
errno: number;
syscall: string;
path: string;
}
export default function handler(req: NextApiRequest, res: NextApiResponse<string>) {
if (req.method !== "GET") return res.status(405).end();
try {
const path = resolve("./public", "projects", "list.json");
const data = readFileSync(path).toString();
console.debug("[API/projects]\tRequest for project list");
res.status(200).send(data);
} catch (err) {
console.error(`[API/projects]\tError in request for project list! Code: ${(err as IFileError).code}`);
res.status(500);
} finally {
res.end();
}
}

View File

@ -0,0 +1,33 @@
import { readFileSync } from "fs";
import { resolve } from "path";
import type { NextApiRequest, NextApiResponse } from "next";
interface IFileError {
message: string;
name: string;
stack?: string;
code: string;
errno: number;
syscall: string;
path: string;
}
export default function handler(req: NextApiRequest, res: NextApiResponse<string>) {
if (req.method !== "GET") return res.status(405).end();
if (!req.query.name) return res.status(400).end();
const project = req.query.name;
try {
const path = resolve("./public", "projects", `${project}.adoc`);
const data = readFileSync(path).toString();
console.debug(`[API/projects]\tRequest for ${project}`);
res.status(200).send(data);
} catch (err) {
console.error(`[API/projects]\tError in request for ${project}! Code: ${(err as IFileError).code}`);
if ((err as IFileError).code === "ENOENT") res.status(404);
else res.status(500);
} finally {
res.end();
}
}

View File

@ -2,44 +2,55 @@ import type { NextPage } from "next";
import Head from "next/head";
import Link from "next/link";
import { GithubLogo, InstagramLogo, DiscordLogo, GameController } from "phosphor-react";
import { useRef } from "react";
import { useRef, useState } from "react";
import ProjectModal from "../components/ProjectModal";
import REPL from "../components/REPL";
import styles from "../styles/Home.module.css";
const Home: NextPage = () => {
const inputRef = useRef<HTMLInputElement>();
const inputRef = useRef<HTMLInputElement>();
const [modalVisible, setModalVisible] = useState<boolean>(false);
const [modalProject, setModalProject] = useState<string>("");
const focusInput = () => {if (inputRef.current) inputRef.current.focus();};
return (<>
<Head>
<title>c0ntroller.de</title>
</Head>
<div className={styles.container}>
<div className={styles.header}>
<span className={styles.spacer} onClick={focusInput}>&nbsp;</span>
<Link href="https://git.c0ntroller.de/c0ntroller/frontpage"><a>Source</a></Link>
<span className={styles.divider}>|</span>
<Link href="https://git.c0ntroller.de/c0ntroller/frontpage/issues/new"><a>Bug?</a></Link>
<span className={styles.divider}>|</span>
<Link href="https://github.com/C0ntroller" passHref><GithubLogo color="var(--repl-color)" className={styles.iconLink} /></Link>
<span className={styles.divider}>|</span>
<Link href="https://www.instagram.com/c0ntroller/" passHref><InstagramLogo color="var(--repl-color)" className={styles.iconLink} /></Link>
<span className={styles.divider}>|</span>
<Link href="https://steamcommunity.com/id/c0ntroller/" passHref><GameController color="var(--repl-color)" className={styles.iconLink} /></Link>
<span className={styles.divider}>|</span>
<Link href="https://discordapp.com/users/224208617820127233" passHref>
<span className={styles.tooltip} style={{cursor: "pointer"}}>
<DiscordLogo color="var(--repl-color)" className={styles.iconLink} />
<span className={styles.tooltiptext}>
C0ntroller_Z#3883
</span>
</span>
</Link><span className={styles.spacer} onClick={focusInput}>&nbsp;</span>
</div>
<REPL inputRef={inputRef} />
</div>
</>);
const focusInput = () => { if (inputRef.current) inputRef.current.focus(); };
const hideModalOnEsc = (e: React.KeyboardEvent) => {
if (e.key === "Escape") {
e.preventDefault();
setModalVisible(false);
}
};
return (<main onKeyDown={hideModalOnEsc}>
<Head>
<title>c0ntroller.de</title>
</Head>
<ProjectModal visible={modalVisible} project={modalProject} setVisible={setModalVisible}/>
<div className={styles.container}>
<div className={styles.header}>
<span className={styles.spacer} onClick={focusInput}>&nbsp;</span>
<Link href="https://git.c0ntroller.de/c0ntroller/frontpage"><a>Source</a></Link>
<span className={styles.divider}>|</span>
<Link href="https://git.c0ntroller.de/c0ntroller/frontpage/issues/new"><a>Bug?</a></Link>
<span className={styles.divider}>|</span>
<Link href="https://github.com/C0ntroller" passHref><GithubLogo color="var(--repl-color)" className={styles.iconLink} /></Link>
<span className={styles.divider}>|</span>
<Link href="https://www.instagram.com/c0ntroller/" passHref><InstagramLogo color="var(--repl-color)" className={styles.iconLink} /></Link>
<span className={styles.divider}>|</span>
<Link href="https://steamcommunity.com/id/c0ntroller/" passHref><GameController color="var(--repl-color)" className={styles.iconLink} /></Link>
<span className={styles.divider}>|</span>
<Link href="https://discordapp.com/users/224208617820127233" passHref>
<span className={styles.tooltip} style={{ cursor: "pointer" }}>
<DiscordLogo color="var(--repl-color)" className={styles.iconLink} />
<span className={styles.tooltiptext}>
C0ntroller_Z#3883
</span>
</span>
</Link><span className={styles.spacer} onClick={focusInput}>&nbsp;</span>
</div>
<REPL inputRef={inputRef} modalManipulation={{setModalVisible, setModalProject}}/>
</div>
</main>);
};
export default Home;

1
public/projects Submodule

@ -0,0 +1 @@
Subproject commit 0496a88b3610ce432d678bf6d2e418f72e537758

View File

@ -0,0 +1,19 @@
.modal {
z-index: 99;
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
padding: 5%;
background: transparent;
}
.modalContainer {
background: #333;
color: #ccc;
width: 100%;
height: 100%;
padding: 20px;
border-radius: 20px;
}

1
testfile Normal file
View File

@ -0,0 +1 @@
Miau