Compare commits

..

20 Commits

Author SHA1 Message Date
Valtteri Karesto
746112e637 fixes issue #115 2022-03-09 11:57:06 +02:00
Valtteri Karesto
13bfd42093 Decorations should now work correctly 2022-03-09 11:14:43 +02:00
Valtteri Karesto
c1f7d7d51c Make sure not all files are defined as C files 2022-03-09 11:14:14 +02:00
Valtteri Karesto
e11ddaffb0 Remove html from md now that the paragraph styling works 2022-03-08 11:36:43 +02:00
Valtteri Karesto
2e88f568b8 Add imports 2022-03-08 11:24:14 +02:00
Valtteri Karesto
237d504f17 Add better styling for markdown 2022-03-08 11:24:02 +02:00
Valtteri Karesto
197fc09e1d delete unused files 2022-03-08 11:23:51 +02:00
Valtteri Karesto
2c74a93aee Add better logic for markdown files 2022-03-08 11:22:58 +02:00
Valtteri Karesto
5209644780 Add raw-loader 2022-03-08 11:22:39 +02:00
Valtteri Karesto
ed37427da8 Add new markdown files 2022-03-08 09:56:07 +02:00
Valtteri Karesto
daee9de96c Update md script and readme 2022-03-08 09:55:40 +02:00
Valtteri Karesto
e4b10d12c2 Remove unused script 2022-03-08 09:54:47 +02:00
Valtteri Karesto
64eabb4502 Remove unused dependencies 2022-03-08 09:54:21 +02:00
Valtteri Karesto
12a24d3d86 Remove rst files 2022-03-08 09:54:11 +02:00
Valtteri Karesto
395e02343b Add logic to enrich the hover messages with rst file contents 2022-03-04 12:48:03 +02:00
Valtteri Karesto
3682dd4946 Add readme how to use the script 2022-03-04 12:38:39 +02:00
Valtteri Karesto
3070ed706e Add script that converts rst to json which contains md 2022-03-04 12:38:24 +02:00
Valtteri Karesto
4b73687779 Add lodash.uniqby 2022-03-04 12:37:51 +02:00
muzamil
0a44b5b5d1 Merge pull request #94 from eqlabs/feat/wasm-stats
Compiled wasm file stats
2022-03-01 15:14:14 +05:30
muzam
0def1d30a6 compiled wasm file stats 2022-02-09 19:06:29 +05:30
67 changed files with 1567 additions and 166 deletions

1
.prettierignore Normal file
View File

@@ -0,0 +1 @@
*.md

View File

@@ -364,7 +364,7 @@ const Accounts: FC<AccountProps> = props => {
<Text>{account.name} </Text>
<Text
css={{
color: "$mauve9",
color: "$textMuted",
wordBreak: "break-word",
}}
>

View File

@@ -66,6 +66,12 @@ export const StyledButton = styled("button", {
},
},
variant: {
link: {
textDecoration: "underline",
fontSize: "inherit",
color: "$textMuted",
textUnderlineOffset: "2px",
},
default: {
backgroundColor: "$mauve12",
boxShadow: "inset 0 0 0 1px $colors$mauve12",
@@ -81,8 +87,7 @@ export const StyledButton = styled("button", {
boxShadow: "inset 0 0 0 1px $colors$mauve11",
},
"&:focus": {
boxShadow:
"inset 0 0 0 1px $colors$mauve12, inset 0 0 0 2px $colors$mauve12",
boxShadow: "inset 0 0 0 1px $colors$mauve12, inset 0 0 0 2px $colors$mauve12",
},
'&[data-radix-popover-trigger][data-state="open"], &[data-radix-dropdown-menu-trigger][data-state="open"]':
{
@@ -137,7 +142,11 @@ export const StyledButton = styled("button", {
},
},
},
muted: {
true: {
color: "$textMuted",
},
},
outline: {
true: {
backgroundColor: "transparent",
@@ -227,21 +236,16 @@ export const StyledButton = styled("button", {
},
});
const CustomButton: React.FC<
React.ComponentProps<typeof StyledButton> & { as?: string }
> = React.forwardRef(({ children, as = "button", ...rest }, ref) => (
// @ts-expect-error
<StyledButton {...rest} ref={ref} as={as}>
<Flex
as="span"
css={{ gap: "$2", alignItems: "center" }}
className="button-content"
>
{children}
</Flex>
{rest.isLoading && <Spinner css={{ position: "absolute" }} />}
</StyledButton>
));
const CustomButton: React.FC<React.ComponentProps<typeof StyledButton> & { as?: string }> =
React.forwardRef(({ children, as = "button", ...rest }, ref) => (
// @ts-expect-error
<StyledButton {...rest} ref={ref} as={as}>
<Flex as="span" css={{ gap: "$2", alignItems: "center" }} className="button-content">
{children}
</Flex>
{rest.isLoading && <Spinner css={{ position: "absolute" }} />}
</StyledButton>
));
CustomButton.displayName = "CustomButton";

View File

@@ -1,20 +1,22 @@
import React, { useRef } from "react";
import React, { useRef, useState } from "react";
import { useSnapshot, ref } from "valtio";
import Editor, { loader } from "@monaco-editor/react";
import type monaco from "monaco-editor";
import { useTheme } from "next-themes";
import { useRouter } from "next/router";
import NextLink from "next/link";
import ReactTimeAgo from "react-time-ago";
import filesize from "filesize";
import Box from "./Box";
import Container from "./Container";
import dark from "../theme/editor/amy.json";
import light from "../theme/editor/xcode_default.json";
import state from "../state";
import wat from "../utils/wat-highlight";
import EditorNavigation from "./EditorNavigation";
import Text from "./Text";
import Link from "./Link";
import { Button, Text, Link, Flex } from ".";
loader.config({
paths: {
@@ -22,11 +24,72 @@ loader.config({
},
});
const FILESIZE_BREAKPOINTS: [number, number] = [2 * 1024, 5 * 1024];
const DeployEditor = () => {
const editorRef = useRef<monaco.editor.IStandaloneCodeEditor>();
const snap = useSnapshot(state);
const router = useRouter();
const { theme } = useTheme();
const [showContent, setShowContent] = useState(false);
const activeFile = snap.files[snap.active];
const compiledSize = activeFile?.compiledContent?.byteLength || 0;
const color =
compiledSize > FILESIZE_BREAKPOINTS[1]
? "$error"
: compiledSize > FILESIZE_BREAKPOINTS[0]
? "$warning"
: "$success";
const CompiledStatView = activeFile && (
<Flex
column
align="center"
css={{
fontSize: "$sm",
fontFamily: "$monospace",
textAlign: "center",
}}
>
<Flex row align="center">
<Text css={{ mr: "$1" }}>
Compiled {activeFile.name.split(".")[0] + ".wasm"}
</Text>
{activeFile?.lastCompiled && (
<ReactTimeAgo date={activeFile.lastCompiled} locale="en-US" />
)}
{activeFile.compiledContent?.byteLength && (
<Text css={{ ml: "$2", color }}>
({filesize(activeFile.compiledContent.byteLength)})
</Text>
)}
</Flex>
<Button variant="link" onClick={() => setShowContent(true)}>
View as WAT-file
</Button>
</Flex>
);
const NoContentView = !snap.loading && router.isReady && (
<Text
css={{
mt: "-60px",
fontSize: "$sm",
fontFamily: "$monospace",
maxWidth: "300px",
textAlign: "center",
}}
>
{`You haven't compiled any files yet, compile files on `}
<NextLink shallow href={`/develop/${router.query.slug}`} passHref>
<Link as="a">develop view</Link>
</NextLink>
</Text>
);
const isContent =
snap.files?.filter((file) => file.compiledWatContent).length > 0 &&
router.isReady;
return (
<Box
css={{
@@ -39,60 +102,48 @@ const DeployEditor = () => {
}}
>
<EditorNavigation showWat />
{snap.files?.filter((file) => file.compiledWatContent).length > 0 &&
router.isReady ? (
<Editor
className="hooks-editor"
// keepCurrentModel
defaultLanguage={snap.files?.[snap.active]?.language}
language={snap.files?.[snap.active]?.language}
path={`file://tmp/c/${snap.files?.[snap.active]?.name}.wat`}
value={snap.files?.[snap.active]?.compiledWatContent || ""}
beforeMount={(monaco) => {
if (!state.editorCtx) {
state.editorCtx = ref(monaco.editor);
// @ts-expect-error
monaco.editor.defineTheme("dark", dark);
// @ts-expect-error
monaco.editor.defineTheme("light", light);
}
}}
onMount={(editor, monaco) => {
editorRef.current = editor;
editor.updateOptions({
glyphMargin: true,
readOnly: true,
});
}}
theme={theme === "dark" ? "dark" : "light"}
/>
) : (
<Container
css={{
display: "flex",
flex: 1,
justifyContent: "center",
alignItems: "center",
}}
>
{!snap.loading && router.isReady && (
<Text
css={{
mt: "-60px",
fontSize: "14px",
fontFamily: "$monospace",
maxWidth: "300px",
textAlign: "center",
}}
>
{`You haven't compiled any files yet, compile files on `}
<NextLink shallow href={`/develop/${router.query.slug}`} passHref>
<Link as="a">develop view</Link>
</NextLink>
</Text>
)}
</Container>
)}
<Container
css={{
display: "flex",
flex: 1,
justifyContent: "center",
alignItems: "center",
}}
>
{!isContent ? (
NoContentView
) : !showContent ? (
CompiledStatView
) : (
<Editor
className="hooks-editor"
defaultLanguage={"wat"}
language={"wat"}
path={`file://tmp/c/${snap.files?.[snap.active]?.name}.wat`}
value={snap.files?.[snap.active]?.compiledWatContent || ""}
beforeMount={(monaco) => {
monaco.languages.register({ id: "wat" });
monaco.languages.setLanguageConfiguration("wat", wat.config);
monaco.languages.setMonarchTokensProvider("wat", wat.tokens);
if (!state.editorCtx) {
state.editorCtx = ref(monaco.editor);
// @ts-expect-error
monaco.editor.defineTheme("dark", dark);
// @ts-expect-error
monaco.editor.defineTheme("light", light);
}
}}
onMount={(editor, monaco) => {
editorRef.current = editor;
editor.updateOptions({
glyphMargin: true,
readOnly: true,
});
}}
theme={theme === "dark" ? "dark" : "light"}
/>
)}
</Container>
</Box>
);
};

View File

@@ -62,7 +62,7 @@ import { styled } from "../stitches.config";
const DEFAULT_EXTENSION = ".c";
const ErrorText = styled(Text, {
color: "$crimson9",
color: "$error",
mt: "$1",
display: "block",
});

View File

@@ -16,9 +16,37 @@ const Flex = styled(Box, {
},
fluid: {
true: {
width: '100%'
}
}
width: "100%",
},
},
align: {
start: {
alignItems: "start",
},
center: {
alignItems: "center",
},
end: {
alignItems: "end",
},
},
justify: {
start: {
justifyContent: "start",
},
center: {
justifyContent: "center",
},
end: {
justifyContent: "end",
},
"space-between": {
justifyContent: "space-between",
},
"space-around": {
justifyContent: "space-around",
},
},
},
});

View File

@@ -5,6 +5,7 @@ import type monaco from "monaco-editor";
import { ArrowBendLeftUp } from "phosphor-react";
import { useTheme } from "next-themes";
import { useRouter } from "next/router";
import uniqBy from "lodash.uniqby";
import Box from "./Box";
import Container from "./Container";
@@ -21,6 +22,8 @@ import { createLanguageClient, createWebSocket } from "../utils/languageClient";
import { listen } from "@codingame/monaco-jsonrpc";
import ReconnectingWebSocket from "reconnecting-websocket";
import docs from "../xrpl-hooks-docs/docs";
loader.config({
paths: {
vs: "https://cdn.jsdelivr.net/npm/monaco-editor@0.30.1/min/vs",
@@ -36,8 +39,73 @@ const validateWritability = (editor: monaco.editor.IStandaloneCodeEditor) => {
}
};
let decorations: { [key: string]: string[] } = {};
const setMarkers = (monacoE: typeof monaco) => {
// Get all the markers that are active at the moment,
// Also if same error is there twice, we can show the content
// only once (that's why we're using uniqBy)
const markers = uniqBy(
monacoE.editor
.getModelMarkers({})
// Filter out the markers that are hooks specific
.filter(
(marker) =>
typeof marker?.code === "string" &&
// Take only markers that starts with "hooks-"
marker?.code?.includes("hooks-")
),
"code"
);
// Get the active model (aka active file you're editing)
// const model = monacoE.editor?.getModel(
// monacoE.Uri.parse(`file:///work/c/${state.files?.[state.active]?.name}`)
// );
// console.log(state.active);
// Add decoration (aka extra hoverMessages) to markers in the
// exact same range (location) where the markers are
const models = monacoE.editor.getModels();
models.forEach((model) => {
console.log(decorations);
decorations[model.id] = model?.deltaDecorations(
decorations?.[model.id] || [],
markers
.filter((marker) =>
marker?.resource.path
.split("/")
.includes(`${state.files?.[state.active]?.name}`)
)
.map((marker) => ({
range: new monacoE.Range(
marker.startLineNumber,
marker.startColumn,
marker.endLineNumber,
marker.endColumn
),
options: {
hoverMessage: {
value:
// Find the related hover message markdown from the
// /xrpl-hooks-docs/xrpl-hooks-docs-files.json file
// which was generated from rst files
(typeof marker.code === "string" &&
docs[marker?.code]?.toString()) ||
"",
supportHtml: true,
isTrusted: true,
},
},
}))
);
});
console.log("decorat", decorations);
};
const HooksEditor = () => {
const editorRef = useRef<monaco.editor.IStandaloneCodeEditor>();
const monacoRef = useRef<typeof monaco>();
const subscriptionRef = useRef<ReconnectingWebSocket | null>(null);
const snap = useSnapshot(state);
const router = useRouter();
@@ -52,6 +120,11 @@ const HooksEditor = () => {
subscriptionRef?.current?.close();
};
}, []);
useEffect(() => {
if (monacoRef.current) {
setMarkers(monacoRef.current);
}
}, [snap.active]);
return (
<Box
css={{
@@ -65,6 +138,7 @@ const HooksEditor = () => {
}}
>
<EditorNavigation />
{console.log(snap)}
{snap.files.length > 0 && router.isReady ? (
<Editor
className="hooks-editor"
@@ -74,6 +148,7 @@ const HooksEditor = () => {
path={`file:///work/c/${snap.files?.[snap.active]?.name}`}
defaultValue={snap.files?.[snap.active]?.content}
beforeMount={(monaco) => {
console.log(monaco.languages.getLanguages());
if (!snap.editorCtx) {
snap.files.forEach((file) =>
monaco.editor.createModel(
@@ -133,6 +208,7 @@ const HooksEditor = () => {
}}
onMount={(editor, monaco) => {
editorRef.current = editor;
monacoRef.current = monaco;
editor.updateOptions({
glyphMargin: true,
lightbulb: {
@@ -145,6 +221,15 @@ const HooksEditor = () => {
saveFile();
}
);
// When the markers (errors/warnings from clangd language server) change
// Lets improve the markers by adding extra content to them from related
// md files
monaco.editor.onDidChangeMarkers(() => {
if (monacoRef.current) {
setMarkers(monacoRef.current);
}
});
validateWritability(editor);
}}
theme={theme === "dark" ? "dark" : "light"}

View File

@@ -11,13 +11,13 @@ const Text = styled("span", {
color: "$text",
},
warning: {
color: "$amber11",
color: "$warning",
},
error: {
color: "$crimson11",
color: "$error",
},
success: {
color: "$grass11",
color: "$success",
},
},
capitalize: {

View File

@@ -19,7 +19,7 @@ import { Plus, X } from "phosphor-react";
import { styled } from "../stitches.config";
const ErrorText = styled(Text, {
color: "$crimson9",
color: "$error",
mt: "$1",
display: "block",
});

View File

@@ -1,15 +1,16 @@
export { default as Flex } from './Flex'
export { default as Container } from './Container'
export { default as Heading } from './Heading'
export { default as Stack } from './Stack'
export { default as Text } from './Text'
export { default as Input } from './Input'
export { default as Select } from './Select'
export * from './Tabs'
export * from './AlertDialog'
export { default as Box } from './Box'
export { default as Button } from './Button'
export { default as ButtonGroup } from './ButtonGroup'
export { default as DeployFooter } from './DeployFooter'
export * from './Dialog'
export * from './DropdownMenu'
export { default as Flex } from "./Flex";
export { default as Link } from "./Link";
export { default as Container } from "./Container";
export { default as Heading } from "./Heading";
export { default as Stack } from "./Stack";
export { default as Text } from "./Text";
export { default as Input } from "./Input";
export { default as Select } from "./Select";
export * from "./Tabs";
export * from "./AlertDialog";
export { default as Box } from "./Box";
export { default as Button } from "./Button";
export { default as ButtonGroup } from "./ButtonGroup";
export { default as DeployFooter } from "./DeployFooter";
export * from "./Dialog";
export * from "./DropdownMenu";

View File

@@ -11,6 +11,10 @@ module.exports = {
if (!isServer) {
config.resolve.fallback.fs = false;
}
config.module.rules.push({
test: /\.md$/,
use: "raw-loader",
});
return config;
},
};

View File

@@ -23,7 +23,10 @@
"base64-js": "^1.5.1",
"dinero.js": "^1.9.1",
"file-saver": "^2.0.5",
"filesize": "^8.0.7",
"javascript-time-ago": "^2.3.11",
"jszip": "^3.7.1",
"lodash.uniqby": "^4.7.0",
"monaco-editor": "^0.30.1",
"next": "^12.0.4",
"next-auth": "^4.0.0-beta.5",
@@ -43,6 +46,7 @@
"react-select": "^5.2.1",
"react-split": "^2.0.14",
"react-stay-scrolled": "^7.4.0",
"react-time-ago": "^7.1.9",
"reconnecting-websocket": "^4.4.0",
"valtio": "^1.2.5",
"vscode-languageserver": "^7.0.0",
@@ -54,10 +58,12 @@
"devDependencies": {
"@types/dinero.js": "^1.9.0",
"@types/file-saver": "^2.0.4",
"@types/lodash.uniqby": "^4.7.6",
"@types/pako": "^1.0.2",
"@types/react": "17.0.31",
"eslint": "7.32.0",
"eslint-config-next": "11.1.2",
"raw-loader": "^4.0.2",
"typescript": "4.4.4"
}
}

View File

@@ -13,6 +13,10 @@ import Navigation from "../components/Navigation";
import { fetchFiles } from "../state/actions";
import state from "../state";
import TimeAgo from "javascript-time-ago";
import en from "javascript-time-ago/locale/en.json";
TimeAgo.addDefaultLocale(en);
function MyApp({ Component, pageProps: { session, ...pageProps } }: AppProps) {
const router = useRouter();
const slug = router.query?.slug;

View File

@@ -1,9 +1,8 @@
import dynamic from "next/dynamic";
import React from "react";
import Split from "react-split";
import dynamic from "next/dynamic";
import { useSnapshot } from "valtio";
import state from "../../state";
import { getSplit, saveSplit } from "../../state/actions/persistSplits";
import Split from "react-split";
const DeployEditor = dynamic(() => import("../../components/DeployEditor"), {
ssr: false,
@@ -18,22 +17,21 @@ const LogBox = dynamic(() => import("../../components/LogBox"), {
});
const Deploy = () => {
const { deployLogs } = useSnapshot(state);
const snap = useSnapshot(state);
return (
<Split
direction="vertical"
gutterSize={4}
gutterAlign="center"
sizes={getSplit("deployVertical") || [40, 60]}
sizes={[40, 60]}
style={{ height: "calc(100vh - 60px)" }}
onDragEnd={(e) => saveSplit("deployVertical", e)}
>
<main style={{ display: "flex", flex: 1, position: "relative" }}>
<DeployEditor />
</main>
<Split
direction="horizontal"
sizes={getSplit("deployHorizontal") || [50, 50]}
sizes={[50, 50]}
minSize={[320, 160]}
gutterSize={4}
gutterAlign="center"
@@ -43,7 +41,6 @@ const Deploy = () => {
width: "100%",
height: "100%",
}}
onDragEnd={(e) => saveSplit("deployHorizontal", e)}
>
<div style={{ alignItems: "stretch", display: "flex" }}>
<Accounts />
@@ -51,7 +48,7 @@ const Deploy = () => {
<div>
<LogBox
title="Deploy Log"
logs={deployLogs}
logs={snap.deployLogs}
clearLog={() => (state.deployLogs = [])}
/>
</div>

View File

@@ -1,15 +1,14 @@
import type { NextPage } from "next";
import dynamic from "next/dynamic";
import { Play } from "phosphor-react";
import Hotkeys from "react-hot-keys";
import Split from "react-split";
import { useSnapshot } from "valtio";
import Box from "../../components/Box";
import Button from "../../components/Button";
import state from "../../state";
import { compileCode } from "../../state/actions";
import { getSplit, saveSplit } from "../../state/actions/persistSplits";
import Hotkeys from "react-hot-keys";
import { Play } from "phosphor-react";
import Split from "react-split";
import type { NextPage } from "next";
import { compileCode } from "../../state/actions";
import state from "../../state";
import Button from "../../components/Button";
import Box from "../../components/Box";
const HooksEditor = dynamic(() => import("../../components/HooksEditor"), {
ssr: false,
@@ -25,12 +24,11 @@ const Home: NextPage = () => {
return (
<Split
direction="vertical"
sizes={getSplit("developVertical") || [70, 30]}
sizes={[70, 30]}
minSize={[100, 100]}
gutterAlign="center"
gutterSize={4}
style={{ height: "calc(100vh - 60px)" }}
onDragEnd={(e) => saveSplit("developVertical", e)}
>
<main style={{ display: "flex", flex: 1, position: "relative" }}>
<HooksEditor />

View File

@@ -1,17 +1,22 @@
import dynamic from "next/dynamic";
import { Play } from "phosphor-react";
import { FC, useCallback, useEffect, useState } from "react";
import Split from "react-split";
import { useSnapshot } from "valtio";
import {
Box, Button, Container,
Flex, Input,
Select, Tab, Tabs, Text
Container,
Flex,
Box,
Tabs,
Tab,
Input,
Select,
Text,
Button,
} from "../../components";
import transactionsData from "../../content/transactions.json";
import { Play } from "phosphor-react";
import dynamic from "next/dynamic";
import { useSnapshot } from "valtio";
import Split from "react-split";
import state from "../../state";
import { sendTransaction } from "../../state/actions";
import { getSplit, saveSplit } from "../../state/actions/persistSplits";
import { useCallback, useEffect, useState, FC } from "react";
import transactionsData from "../../content/transactions.json";
const DebugStream = dynamic(() => import("../../components/DebugStream"), {
ssr: false,
@@ -344,17 +349,16 @@ const Transaction: FC<Props> = ({ header, ...props }) => {
};
const Test = () => {
const { transactionLogs } = useSnapshot(state);
const snap = useSnapshot(state);
const [tabHeaders, setTabHeaders] = useState<string[]>(["test1.json"]);
return (
<Container css={{ px: 0 }}>
<Split
direction="vertical"
sizes={getSplit("testVertical") || [50, 50]}
sizes={[50, 50]}
gutterSize={4}
gutterAlign="center"
style={{ height: "calc(100vh - 60px)" }}
onDragEnd={(e) => saveSplit("testVertical", e)}
>
<Flex
row
@@ -366,7 +370,7 @@ const Test = () => {
>
<Split
direction="horizontal"
sizes={getSplit("testHorizontal") || [50, 50]}
sizes={[50, 50]}
minSize={[180, 320]}
gutterSize={4}
gutterAlign="center"
@@ -376,7 +380,6 @@ const Test = () => {
width: "100%",
height: "100%",
}}
onDragEnd={(e) => saveSplit("testHorizontal", e)}
>
<Box css={{ width: "55%", px: "$2" }}>
<Tabs
@@ -425,7 +428,7 @@ const Test = () => {
>
<LogBox
title="Development Log"
logs={transactionLogs}
logs={snap.transactionLogs}
clearLog={() => (state.transactionLogs = [])}
/>
</Box>

4
raw-loader.d.ts vendored Normal file
View File

@@ -0,0 +1,4 @@
declare module "*.md" {
const content: string;
export default content;
};

View File

@@ -66,6 +66,7 @@ export const compileCode = async (activeId: number) => {
// Decode base64 encoded wasm that is coming back from the endpoint
const bufferData = await decodeBinary(json.output);
state.files[state.active].compiledContent = ref(bufferData);
state.files[state.active].lastCompiled = new Date();
// Import wabt from and create human readable version of wasm file and
// put it into state
import("wabt").then((wabt) => {

View File

@@ -1,8 +1,17 @@
import state, { IFile } from '../index';
/* Initializes empty file to global state */
const languageMapping = {
'ts': 'typescript',
'js': 'javascript',
'md': 'markdown',
'c': 'c',
'h': 'c',
'other': ''
} /* Initializes empty file to global state */
export const createNewFile = (name: string) => {
const emptyFile: IFile = { name, language: "c", content: "" };
const tempName = name.split('.');
const fileExt = tempName[tempName.length - 1] || 'other';
const emptyFile: IFile = { name, language: languageMapping[fileExt as 'ts' | 'js' | 'md' | 'c' | 'h' | 'other'], content: "" };
state.files.push(emptyFile);
state.active = state.files.length - 1;
};

View File

@@ -1,15 +0,0 @@
import { snapshot } from "valtio"
import state from ".."
export type SplitSize = number[]
export const saveSplit = (splitId: string, event: SplitSize) => {
state.splits[splitId] = event
}
export const getSplit = (splitId: string): SplitSize | null => {
const { splits } = snapshot(state)
const split = splits[splitId]
return split ? split : null
}

View File

@@ -1,8 +1,7 @@
import type monaco from "monaco-editor";
import { proxy, ref, subscribe } from "valtio";
import { devtools } from 'valtio/utils';
import { devtools } from 'valtio/utils'
import type monaco from "monaco-editor";
import { XrplClient } from "xrpl-client";
import { SplitSize } from "./actions/persistSplits";
export interface IFile {
name: string;
@@ -10,6 +9,7 @@ export interface IFile {
content: string;
compiledContent?: ArrayBuffer | null;
compiledWatContent?: string | null;
lastCompiled?: Date
}
export interface FaucetAccountRes {
@@ -56,9 +56,6 @@ export interface IState {
editorSettings: {
tabSize: number;
};
splits: {
[id: string]: SplitSize
};
client: XrplClient | null;
clientStatus: "offline" | "online";
mainModalOpen: boolean;
@@ -87,7 +84,6 @@ let initialState: IState = {
editorSettings: {
tabSize: 2,
},
splits: {},
client: null,
clientStatus: "offline" as "offline",
mainModalOpen: false,
@@ -96,9 +92,6 @@ let initialState: IState = {
let localStorageAccounts: string | null = null;
let initialAccounts: IAccount[] = [];
// TODO: What exactly should we store in localStorage? editorSettings, splits, accounts?
// Check if there's a persited accounts in localStorage
if (typeof window !== "undefined") {
try {
@@ -147,4 +140,4 @@ if (typeof window !== "undefined") {
}
});
}
export default state
export default state

View File

@@ -19,6 +19,8 @@ import {
mauveDark,
amberDark,
purpleDark,
red,
redDark,
} from "@radix-ui/colors";
export const {
@@ -41,11 +43,16 @@ export const {
...mauve,
...amber,
...purple,
...red,
accent: "#9D2DFF",
background: "$gray1",
backgroundAlt: "$gray4",
text: "$gray12",
textMuted: "$gray10",
primary: "$plum",
error: '$red9',
warning: '$amber11',
success: "$grass11",
white: "white",
black: "black",
deep: "rgb(244, 244, 244)",
@@ -348,6 +355,7 @@ export const darkTheme = createTheme("dark", {
...mauveDark,
...amberDark,
...purpleDark,
...redDark,
deep: "rgb(10, 10, 10)",
// backgroundA: transparentize(0.1, grayDark.gray1),
},

View File

@@ -13,6 +13,10 @@ body,
box-sizing: border-box;
}
.monaco-hover p {
margin-bottom: 10px !important;
}
.gutter {
position: relative;
transition: border-color 0.3s, background-color 0.3s;

View File

@@ -26,6 +26,7 @@
"**/*.tsx"
],
"exclude": [
"node_modules"
"node_modules",
"*.md"
]
}

714
utils/wat-highlight.ts Normal file
View File

@@ -0,0 +1,714 @@
// 'WebAssembly Text Format' Monarch language
import type monaco from 'monaco-editor';
const WebAssemblyTextLanguage: { config: monaco.languages.LanguageConfiguration, tokens: monaco.languages.IMonarchLanguage } = {
config: {
brackets: [
["(", ")"],
["if", "end"],
["loop", "end"],
["block", "end"],
],
autoClosingPairs: [
{ open: "(", close: ")" },
{ open: "if", close: "end" },
{ open: "loop", close: "end" },
{ open: "block", close: "end" },
],
surroundingPairs: [
{ open: "(", close: ")" },
{ open: "if", close: "end" },
{ open: "loop", close: "end" },
{ open: "block", close: "end" },
],
},
tokens: {
keywords: [
"module",
"import",
"export",
"memory",
"data",
"table",
"elem",
"start",
"func",
"tag",
"type",
"param",
"result",
"global",
"local",
"mut",
"struct",
"array",
"field",
],
types: [
"i8",
"i16",
"i32",
"i64",
"f32",
"f64",
"v128",
"i31ref",
"eqref",
"anyref",
"dataref",
"externref",
"funcref",
"exnref",
"extern",
"null",
"any",
"eq",
],
instructions: [
"pop",
"nop",
"drop",
"data.drop",
"elem.drop",
"local.get",
"local.set",
"local.tee",
"global.get",
"global.set",
"tuple.make",
"tuple.extract",
"select",
"v128.const",
"v128.and",
"v128.or",
"v128.xor",
"v128.not",
"v128.andnot",
"v128.bitselect",
"v128.load",
"v128.load8x8_s",
"v128.load8x8_u",
"v128.load16x4_s",
"v128.load16x4_u",
"v128.load32x2_s",
"v128.load32x2_u",
"v128.load8_lane",
"v128.load16_lane",
"v128.load32_lane",
"v128.load64_lane",
"v128.load8_splat",
"v128.load16_splat",
"v128.load32_splat",
"v128.load64_splat",
"v128.load32_zero",
"v128.load64_zero",
"v128.store",
"v128.store8_lane",
"v128.store16_lane",
"v128.store32_lane",
"v128.store64_lane",
"v128.any_true",
"i8x16.shuffle",
"i8x16.swizzle",
"i8x16.bitmask",
"i8x16.splat",
"i8x16.popcnt",
"i8x16.replace_lane",
"i8x16.extract_lane_s",
"i8x16.extract_lane_u",
"i8x16.all_true",
"i8x16.abs",
"i8x16.add",
"i8x16.add_sat_s",
"i8x16.add_sat_u",
"i8x16.sub",
"i8x16.sub_sat_s",
"i8x16.sub_sat_u",
"i8x16.mul",
"i8x16.neg",
"i8x16.shl",
"i8x16.shr_s",
"i8x16.shr_u",
"i8x16.eq",
"i8x16.ne",
"i8x16.lt_s",
"i8x16.lt_u",
"i8x16.le_s",
"i8x16.le_u",
"i8x16.gt_s",
"i8x16.gt_u",
"i8x16.ge_s",
"i8x16.ge_u",
"i8x16.min_s",
"i8x16.min_u",
"i8x16.max_s",
"i8x16.max_u",
"i8x16.avgr_u",
"i8x16.narrow_i16x8_s",
"i8x16.narrow_i16x8_u",
"i16x8.bitmask",
"i16x8.splat",
"i16x8.load_8x8_s",
"i16x8.load_8x8_u",
"i16x8.replace_lane",
"i16x8.extract_lane_s",
"i16x8.extract_lane_u",
"i16x8.extend_low_i8x16_s",
"i16x8.extend_high_i8x16_s",
"i16x8.extend_low_i8x16_u",
"i16x8.extend_high_i8x16_u",
"i16x8.all_true",
"i16x8.abs",
"i16x8.add",
"i16x8.add_sat_s",
"i16x8.add_sat_u",
"i16x8.extadd_pairwise_i8x16_s",
"i16x8.extadd_pairwise_i8x16_u",
"i16x8.sub",
"i16x8.sub_sat_s",
"i16x8.sub_sat_u",
"i16x8.q15mulr_sat_s",
"i16x8.mul",
"i16x8.extmul_low_i8x16_s",
"i16x8.extmul_high_i8x16_s",
"i16x8.extmul_low_i8x16_u",
"i16x8.extmul_high_i8x16_u",
"i16x8.neg",
"i16x8.shl",
"i16x8.shr_s",
"i16x8.shr_u",
"i16x8.eq",
"i16x8.ne",
"i16x8.lt_s",
"i16x8.lt_u",
"i16x8.le_s",
"i16x8.le_u",
"i16x8.gt_s",
"i16x8.gt_u",
"i16x8.ge_s",
"i16x8.ge_u",
"i16x8.min_s",
"i16x8.min_u",
"i16x8.max_s",
"i16x8.max_u",
"i16x8.avgr_u",
"i16x8.narrow_i32x4_s",
"i16x8.narrow_i32x4_u",
"i32x4.bitmask",
"i32x4.splat",
"i32x4.load_16x4_s",
"i32x4.load_16x4_u",
"i32x4.replace_lane",
"i32x4.extract_lane",
"i32x4.extend_low_i16x8_s",
"i32x4.extend_high_i16x8_s",
"i32x4.extend_low_i16x8_u",
"i32x4.extend_high_i16x8_u",
"i32x4.all_true",
"i32x4.abs",
"i32x4.add",
"i32x4.extadd_pairwise_i16x8_s",
"i32x4.extadd_pairwise_i16x8_u",
"i32x4.sub",
"i32x4.mul",
"i32x4.extmul_low_i16x8_s",
"i32x4.extmul_high_i16x8_s",
"i32x4.extmul_low_i16x8_u",
"i32x4.extmul_high_i16x8_u",
"i32x4.neg",
"i32x4.shl",
"i32x4.shr_s",
"i32x4.shr_u",
"i32x4.eq",
"i32x4.ne",
"i32x4.lt_s",
"i32x4.lt_u",
"i32x4.le_s",
"i32x4.le_u",
"i32x4.gt_s",
"i32x4.gt_u",
"i32x4.ge_s",
"i32x4.ge_u",
"i32x4.min_s",
"i32x4.min_u",
"i32x4.max_s",
"i32x4.max_u",
"i32x4.trunc_sat_f32x4_s",
"i32x4.trunc_sat_f32x4_u",
"i32x4.trunc_sat_f64x2_s_zero",
"i32x4.trunc_sat_f64x2_u_zero",
"i32x4.dot_i16x8_s",
"i64x2.bitmask",
"i64x2.splat",
"i64x2.load32x2_s",
"i64x2.load32x2_u",
"i64x2.replace_lane",
"i64x2.extract_lane",
"i64x2.extend_low_i32x4_s",
"i64x2.extend_high_i32x4_s",
"i64x2.extend_low_i32x4_u",
"i64x2.extend_high_i32x4_u",
"i64x2.all_true",
"i64x2.abs",
"i64x2.add",
"i64x2.sub",
"i64x2.mul",
"i64x2.neg",
"i64x2.shl",
"i64x2.shr_s",
"i64x2.shr_u",
"f32x4.splat",
"f32x4.replace_lane",
"f32x4.extract_lane",
"f32x4.add",
"f32x4.sub",
"f32x4.mul",
"i64x2.extmul_low_i32x4_s",
"i64x2.extmul_high_i32x4_s",
"i64x2.extmul_low_i32x4_u",
"i64x2.extmul_high_i32x4_u",
"i64x2.eq",
"i64x2.ne",
"i64x2.lt_s",
"i64x2.le_s",
"i64x2.gt_s",
"i64x2.ge_s",
"f32x4.neg",
"f32x4.eq",
"f32x4.ne",
"f32x4.lt",
"f32x4.le",
"f32x4.gt",
"f32x4.ge",
"f32x4.abs",
"f32x4.min",
"f32x4.pmin",
"f32x4.max",
"f32x4.pmax",
"f32x4.div",
"f32x4.sqrt",
"f32x4.ceil",
"f32x4.floor",
"f32x4.trunc",
"f32x4.nearest",
"f32x4.demote_f64x2_zero",
"f32x4.convert_i32x4_s",
"f32x4.convert_i32x4_u",
"f64x2.splat",
"f64x2.replace_lane",
"f64x2.extract_lane",
"f64x2.add",
"f64x2.sub",
"f64x2.mul",
"f64x2.neg",
"f64x2.eq",
"f64x2.ne",
"f64x2.lt",
"f64x2.le",
"f64x2.gt",
"f64x2.ge",
"f64x2.abs",
"f64x2.min",
"f64x2.max",
"f64x2.pmin",
"f64x2.pmax",
"f64x2.div",
"f64x2.sqrt",
"f64x2.ceil",
"f64x2.floor",
"f64x2.trunc",
"f64x2.nearest",
"f64x2.promote_low_f32x4",
"f64x2.convert_low_i32x4_s",
"f64x2.convert_low_i32x4_u",
"i32.atomic.load",
"i32.atomic.load8_u",
"i32.atomic.load16_u",
"i32.atomic.store",
"i32.atomic.store8",
"i32.atomic.store16",
"i32.atomic.rmw.add",
"i32.atomic.rmw.sub",
"i32.atomic.rmw.and",
"i32.atomic.rmw.or",
"i32.atomic.rmw.xor",
"i32.atomic.rmw.xchg",
"i32.atomic.rmw.cmpxchg",
"i32.atomic.rmw8.add_u",
"i32.atomic.rmw8.sub_u",
"i32.atomic.rmw8.and_u",
"i32.atomic.rmw8.or_u",
"i32.atomic.rmw8.xor_u",
"i32.atomic.rmw8.xchg_u",
"i32.atomic.rmw8.cmpxchg_u",
"i32.atomic.rmw16.add_u",
"i32.atomic.rmw16.sub_u",
"i32.atomic.rmw16.and_u",
"i32.atomic.rmw16.or_u",
"i32.atomic.rmw16.xor_u",
"i32.atomic.rmw16.xchg_u",
"i32.atomic.rmw16.cmpxchg_u",
"i64.atomic.load",
"i64.atomic.load8_u",
"i64.atomic.load16_u",
"i64.atomic.load32_u",
"i64.atomic.store",
"i64.atomic.store8",
"i64.atomic.store16",
"i64.atomic.store32",
"i64.atomic.rmw.add",
"i64.atomic.rmw.sub",
"i64.atomic.rmw.and",
"i64.atomic.rmw.or",
"i64.atomic.rmw.xor",
"i64.atomic.rmw.xchg",
"i64.atomic.rmw.cmpxchg",
"i64.atomic.rmw8.add_u",
"i64.atomic.rmw8.sub_u",
"i64.atomic.rmw8.and_u",
"i64.atomic.rmw8.or_u",
"i64.atomic.rmw8.xor_u",
"i64.atomic.rmw8.xchg_u",
"i64.atomic.rmw8.cmpxchg_u",
"i64.atomic.rmw16.add_u",
"i64.atomic.rmw16.sub_u",
"i64.atomic.rmw16.and_u",
"i64.atomic.rmw16.or_u",
"i64.atomic.rmw16.xor_u",
"i64.atomic.rmw16.xchg_u",
"i64.atomic.rmw16.cmpxchg_u",
"i64.atomic.rmw32.add_u",
"i64.atomic.rmw32.sub_u",
"i64.atomic.rmw32.and_u",
"i64.atomic.rmw32.or_u",
"i64.atomic.rmw32.xor_u",
"i64.atomic.rmw32.xchg_u",
"i64.atomic.rmw32.cmpxchg_u",
"atomic.fence",
"func.bind",
"ref",
"ref.eq",
"ref.null",
"ref.is_null",
"ref.is_func",
"ref.is_data",
"ref.is_i31",
"ref.as_func",
"ref.as_non_null",
"ref.as_data",
"ref.as_i31",
"ref.func",
"ref.cast",
"ref.cast_static",
"ref.test",
"ref.test_static",
"table.get",
"table.set",
"table.size",
"table.grow",
"table.fill",
"table.init",
"table.copy",
"throw",
"rethrow",
"i32.load",
"i32.load8_s",
"i32.load8_u",
"i32.load16_s",
"i32.load16_u",
"i32.store",
"i32.store8",
"i32.store16",
"i32.const",
"i32.eqz",
"i32.eq",
"i32.ne",
"i32.lt_s",
"i32.lt_u",
"i32.le_s",
"i32.le_u",
"i32.gt_s",
"i32.gt_u",
"i32.ge_s",
"i32.ge_u",
"i32.clz",
"i32.ctz",
"i32.popcnt",
"i32.add",
"i32.sub",
"i32.mul",
"i32.div_s",
"i32.div_u",
"i32.rem_s",
"i32.rem_u",
"i32.and",
"i32.or",
"i32.xor",
"i32.shl",
"i32.shr_s",
"i32.shr_u",
"i32.rotl",
"i32.rotr",
"i32.wrap_i64",
"i32.trunc_f32_s",
"i32.trunc_f32_u",
"i32.trunc_f64_s",
"i32.trunc_f64_u",
"i32.reinterpret_f32",
"i64.load",
"i64.load8_s",
"i64.load8_u",
"i64.load16_s",
"i64.load16_u",
"i64.load32_s",
"i64.load32_u",
"i64.store",
"i64.store8",
"i64.store16",
"i64.store32",
"i64.const",
"i64.eqz",
"i64.eq",
"i64.ne",
"i64.lt_s",
"i64.lt_u",
"i64.le_s",
"i64.le_u",
"i64.gt_s",
"i64.gt_u",
"i64.ge_s",
"i64.ge_u",
"i64.clz",
"i64.ctz",
"i64.popcnt",
"i64.add",
"i64.sub",
"i64.mul",
"i64.div_s",
"i64.div_u",
"i64.rem_s",
"i64.rem_u",
"i64.and",
"i64.or",
"i64.xor",
"i64.shl",
"i64.shr_s",
"i64.shr_u",
"i64.rotl",
"i64.rotr",
"i64.extend_i32_s",
"i64.extend_i32_u",
"i64.trunc_f32_s",
"i64.trunc_f32_u",
"i64.trunc_f64_s",
"i64.trunc_f64_u",
"i64.reinterpret_f64",
"f32.load",
"f32.store",
"f32.const",
"f32.eq",
"f32.ne",
"f32.lt",
"f32.le",
"f32.gt",
"f32.ge",
"f32.abs",
"f32.neg",
"f32.ceil",
"f32.floor",
"f32.trunc",
"f32.nearest",
"f32.sqrt",
"f32.add",
"f32.sub",
"f32.mul",
"f32.div",
"f32.min",
"f32.max",
"f32.copysign",
"f32.convert_i32_s",
"f32.convert_i32_u",
"f32.convert_i64_s",
"f32.convert_i64_u",
"f32.demote_f64",
"f32.reinterpret_i32",
"f64.load",
"f64.store",
"f64.const",
"f64.eq",
"f64.ne",
"f64.lt",
"f64.le",
"f64.gt",
"f64.ge",
"f64.abs",
"f64.neg",
"f64.ceil",
"f64.floor",
"f64.trunc",
"f64.nearest",
"f64.sqrt",
"f64.add",
"f64.sub",
"f64.mul",
"f64.div",
"f64.min",
"f64.max",
"f64.copysign",
"f64.convert_i32_s",
"f64.convert_i32_u",
"f64.convert_i64_s",
"f64.convert_i64_u",
"f64.promote_f32",
"f64.reinterpret_i64",
"i32.extend8_s",
"i32.extend16_s",
"i64.extend8_s",
"i64.extend16_s",
"i64.extend32_s",
"i32.trunc_sat_f32_s",
"i32.trunc_sat_f32_u",
"i32.trunc_sat_f64_s",
"i32.trunc_sat_f64_u",
"i64.trunc_sat_f32_s",
"i64.trunc_sat_f32_u",
"i64.trunc_sat_f64_s",
"i64.trunc_sat_f64_u",
"memory.size",
"memory.grow",
"memory.copy",
"memory.fill",
"memory.init",
"memory.atomic.notify",
"memory.atomic.wait32",
"memory.atomic.wait64",
"i31.new",
"i31.get_u",
"i31.get_s",
"array.new",
"array.new_default",
"array.init",
"array.init_static",
"array.get",
"array.get_s",
"array.get_u",
"array.set",
"array.len",
"array.copy",
"struct.new",
"struct.new_default",
"struct.new_with_rtt",
"struct.new_default_with_rtt",
"struct.get",
"struct.get_s",
"struct.get_u",
"struct.set",
"rtt.canon",
"rtt.sub",
"rtt.fresh_sub",
],
controlInstructions: [
"block",
"loop",
"if",
"else",
"then",
"end",
"do",
"let",
"br",
"br_if",
"br_table",
"br_on_exn",
"br_on_null",
"br_on_non_null",
"br_on_cast",
"br_on_cast_static",
"br_on_cast_fail",
"br_on_cast_static_fail",
"br_on_func",
"br_on_non_func",
"br_on_data",
"br_on_non_data",
"br_on_i31",
"br_on_non_i31",
"call",
"call_indirect",
"call_ref",
"return",
"return_call",
"return_call_indirect",
"return_call_ref",
"try",
"catch",
"catch_all",
"delegate",
"unreachable",
],
escapes:
/\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,
digits: /\d+(_+\d+)*/,
octaldigits: /[0-7]+(_+[0-7]+)*/,
binarydigits: /[0-1]+(_+[0-1]+)*/,
hexdigits: /[[0-9a-fA-F]+(_+[0-9a-fA-F]+)*/,
tokenizer: {
root: [
// whitespace
{ include: "@whitespace" },
// strings
[/"([^"\\]|\\.)*$/, "string.invalid"], // non-teminated string
[/"/, "string", "@string"],
// numbers (not all of these are generated, but here to be sure)
[/(@digits)[eE]([\-+]?(@digits))?[fFdD]?/, "number.float"],
[/(@digits)\.(@digits)([eE][\-+]?(@digits))?[fFdD]?/, "number.float"],
[/0[xX](@hexdigits)[Ll]?/, "number.hex"],
[/0(@octaldigits)[Ll]?/, "number.octal"],
[/0[bB](@binarydigits)[Ll]?/, "number.binary"],
[/(@digits)[fFdD]/, "number.float"],
[/(@digits)[lL]?/, "number"],
// variable names
[/\$[^\s\)]*/, { token: "identifier" }],
// instructions and types
[
/[a-z0-9_]+(?:\.[a-z0-9_]+)*/,
{
cases: {
"@types": { token: "type.$0" },
"@keywords": { token: "keyword.$0" },
"@controlInstructions": { token: "controlInstruction.$0" },
"@instructions": { token: "instruction.$0" },
"@default": "identifier",
},
},
],
],
string: [
[/[^\\"]+/, "string"],
[/@escapes/, "string.escape"],
[/\\./, "string.escape.invalid"],
[/"/, "string", "@pop"],
],
whitespace: [
[/[ \t\r\n]+/, ""],
[/(;; )(ERROR |FAILURE )([^\n]*)/, ["comment", "error", ""]],
[/(;; )(WARNING )([^\n]*)/, ["comment", "warning", ""]],
[/(;; )(INFO )([^\n]*)/, ["comment", "info", ""]],
[/(;; )(PEDANTIC )([^\n]*)/, ["comment", "pedantic", ""]],
[/(;; +)(~+|\^)$/, ["comment", "underline"]],
[/(;; )([^\n]*)/, ["comment", ""]],
[/;;[^\n]*/, "comment"],
],
},
},
};
export default WebAssemblyTextLanguage;

87
xrpl-hooks-docs/docs.ts Normal file
View File

@@ -0,0 +1,87 @@
import hooksAccountBufLen from "./md/hooks-account-buf-len.md";
import hooksAccountConvBufLen from "./md/hooks-account-conv-buf-len.md";
import hooksAccountConvPure from "./md/hooks-account-conv-pure.md";
import hooksArrayBufLen from "./md/hooks-array-buf-len.md";
import hooksBurdenPrereq from "./md/hooks-burden-prereq.md";
import hooksDetailBufLen from "./md/hooks-detail-buf-len.md";
import hooksDetailPrereq from "./md/hooks-detail-prereq.md";
import hooksEmitBufLen from "./md/hooks-emit-buf-len.md";
import hooksEmitPrereq from "./md/hooks-emit-prereq.md";
import hooksEntryPointRecursion from "./md/hooks-entry-point-recursion.md";
import hooksEntryPointsNeg from "./md/hooks-entry-points-neg.md";
import hooksEntryPoints from "./md/hooks-entry-points.md";
import hooksFeePrereq from "./md/hooks-fee-prereq.md";
import hooksFieldAddBufLen from "./md/hooks-field-add-buf-len.md";
import hooksFieldBufLen from "./md/hooks-field-buf-len.md";
import hooksFieldDelBufLen from "./md/hooks-field-del-buf-len.md";
import hooksFloatArithPure from "./md/hooks-float-arith-pure.md";
import hooksFloatComparePure from "./md/hooks-float-compare-pure.md";
import hooksFloatIntPure from "./md/hooks-float-int-pure.md";
import hooksFloatManipPure from "./md/hooks-float-manip-pure.md";
import hooksFloatOnePure from "./md/hooks-float-one-pure.md";
import hooksFloatPure from "./md/hooks-float-pure.md";
import hooksGuardCalled from "./md/hooks-guard-called.md";
import hooksGuardInFor from "./md/hooks-guard-in-for.md";
import hooksGuardInWhile from "./md/hooks-guard-in-while.md";
import hooksHashBufLen from "./md/hooks-hash-buf-len.md";
import hooksKeyletBufLen from "./md/hooks-keylet-buf-len.md";
import hooksRaddrConvBufLen from "./md/hooks-raddr-conv-buf-len.md";
import hooksRaddrConvPure from "./md/hooks-raddr-conv-pure.md";
import hooksReserveLimit from "./md/hooks-reserve-limit.md";
import hooksSlotHashBufLen from "./md/hooks-slot-hash-buf-len.md";
import hooksSlotKeyletBufLen from "./md/hooks-slot-keylet-buf-len.md";
import hooksSlotLimit from "./md/hooks-slot-limit.md";
import hooksSlotSubLimit from "./md/hooks-slot-sub-limit.md";
import hooksSlotTypeLimit from "./md/hooks-slot-type-limit.md";
import hooksStateBufLen from "./md/hooks-state-buf-len.md";
import hooksTransactionHashBufLen from "./md/hooks-transaction-hash-buf-len.md";
import hooksTransactionSlotLimit from "./md/hooks-transaction-slot-limit.md";
import hooksValidateBufLen from "./md/hooks-validate-buf-len.md";
import hooksVerifyBufLen from "./md/hooks-verify-buf-len.md";
const docs: { [key: string]: string; } = {
"hooks-account-buf-len": hooksAccountBufLen,
"hooks-account-conv-buf-len": hooksAccountConvBufLen,
"hooks-account-conv-pure": hooksAccountConvPure,
"hooks-array-buf-len": hooksArrayBufLen,
"hooks-burden-prereq": hooksBurdenPrereq,
"hooks-detail-buf-len": hooksDetailBufLen,
"hooks-detail-prereq": hooksDetailPrereq,
"hooks-emit-buf-len": hooksEmitBufLen,
"hooks-emit-prereq": hooksEmitPrereq,
"hooks-entry-point-recursion": hooksEntryPointRecursion,
"hooks-entry-points-neg": hooksEntryPointsNeg,
"hooks-entry-points": hooksEntryPoints,
"hooks-fee-prereq": hooksFeePrereq,
"hooks-field-add-buf-len": hooksFieldAddBufLen,
"hooks-field-buf-len": hooksFieldBufLen,
"hooks-field-del-buf-len": hooksFieldDelBufLen,
"hooks-float-arith-pure": hooksFloatArithPure,
"hooks-float-compare-pure": hooksFloatComparePure,
"hooks-float-int-pure": hooksFloatIntPure,
"hooks-float-manip-pure": hooksFloatManipPure,
"hooks-float-one-pure": hooksFloatOnePure,
"hooks-float-pure": hooksFloatPure,
"hooks-guard-called": hooksGuardCalled,
"hooks-guard-in-for": hooksGuardInFor,
"hooks-guard-in-while": hooksGuardInWhile,
"hooks-hash-buf-len": hooksHashBufLen,
"hooks-keylet-buf-len": hooksKeyletBufLen,
"hooks-raddr-conv-buf-len": hooksRaddrConvBufLen,
"hooks-raddr-conv-pure": hooksRaddrConvPure,
"hooks-reserve-limit": hooksReserveLimit,
"hooks-slot-hash-buf-len": hooksSlotHashBufLen,
"hooks-slot-keylet-buf-len": hooksSlotKeyletBufLen,
"hooks-slot-limit": hooksSlotLimit,
"hooks-slot-sub-limit": hooksSlotSubLimit,
"hooks-slot-type-limit": hooksSlotTypeLimit,
"hooks-state-buf-len": hooksStateBufLen,
"hooks-transaction-hash-buf-len": hooksTransactionHashBufLen,
"hooks-transaction-slot-limit": hooksTransactionSlotLimit,
"hooks-validate-buf-len": hooksValidateBufLen,
"hooks-verify-buf-len": hooksVerifyBufLen,
};
export default docs;

View File

@@ -0,0 +1,6 @@
# hooks-account-buf-len
Function `hook_account` has fixed-size account ID output.
This check warns about too-small size of its output buffer (if it's
specified by a constant - variable parameter is ignored).

View File

@@ -0,0 +1,7 @@
# hooks-account-conv-buf-len
Function `util_raddr` has fixed-size account ID input.
This check warns unless the correct size is passed in the input size
parameter (if it's specified by a constant - variable parameter is
ignored).

View File

@@ -0,0 +1,10 @@
# hooks-account-conv-pure
Hooks identify accounts by the 20 byte account ID, which can be
converted to an raddr using the `util_raddr` function. If the account
ID never changes, a more efficient way to do this is precompute the
raddr from the account ID.
This check warns about calls of `util_raddr` with constant input and
proposes to add a tracing statement showing the computed value (so
that the user can use it to replace the call).

View File

@@ -0,0 +1,9 @@
# hooks-array-buf-len
Hook API `sto_subarray` requires non-empty input buffer and takes a
parameter specifying the array index, whose value is limited - the
sought object cannot be found if the limit is exceeded.
This check warns about empty input as well as too-large values of the
index specified in calls to `sto_subarray` (if they're specified by
constants - variable parameters are ignored).

View File

@@ -0,0 +1,5 @@
# hooks-burden-prereq
Hook API `etxn_burden` computes transaction burden, based on (i.a.)
the number of reserved transactions, so a call to it must be preceded
by a call to `etxn_reserve`.

View File

@@ -0,0 +1,6 @@
# hooks-detail-buf-len
Function `etxn_details` has fixed-size sfEmitDetails output.
This check warns about too-small size of its output buffer (if it's
specified by a constant - variable parameter is ignored).

View File

@@ -0,0 +1,5 @@
# hooks-detail-prereq
Hook API `etxn_details` serializes emit details, based on (i.a.) the
number of reserved transactions, so a call to it must be preceded by a
call to `etxn_reserve`.

View File

@@ -0,0 +1,6 @@
# hooks-emit-buf-len
Function `emit` has fixed-size transaction hash output.
This check warns about too-small size of its output buffer (if it's
specified by a constant - variable parameter is ignored).

View File

@@ -0,0 +1,5 @@
# hooks-emit-prereq
Before emitting a transaction using `emit` Hook API, a hook must set a
maximal count of transactions it plans to emit, by calling
`etxn_reserve`.

View File

@@ -0,0 +1,4 @@
# hooks-entry-point-recursion
Recursive calls are disallowed in the implementation of hook entry
points.

View File

@@ -0,0 +1,4 @@
# hooks-entry-points-neg
Shows error on function definitions with unexpected (that is, neither
`hook` nor `cbak`) names.

View File

@@ -0,0 +1,6 @@
# hooks-entry-points
A Hook always implements and exports exactly two functions: `cbak` and
`hook`.
This check shows error on translation units that do not have them.

View File

@@ -0,0 +1,5 @@
# hooks-fee-prereq
Hook API `etxn_fee_base` estimates a transaction fee, based on (i.a.)
the number of reserved transactions, so a call to it must be preceded
by a call to `etxn_reserve`.

View File

@@ -0,0 +1,9 @@
# hooks-field-add-buf-len
Emplacing a new field into STObject by calling `sto_emplace` requires
enough space to serialize the new STObject into; the API also limits
sizes of the old object and field.
This check warns about insufficient output buffer space as well as
too-large values of the inputs in calls to `sto_emplace` (if they're
specified by constants - variable parameters are ignored).

View File

@@ -0,0 +1,6 @@
# hooks-field-buf-len
Hook API `sto_subfield` requires non-empty input buffer.
This check warns about empty input in calls to `sto_subfield` (if it's
specified by a constant - variable parameter is ignored).

View File

@@ -0,0 +1,9 @@
# hooks-field-del-buf-len
Erasing a field from STObject by calling `sto_erase` requires enough
space to serialize the new STObject into; the API also limits size of
the old object.
This check warns about insufficient output buffer space as well as
too-large value of the input STObject in calls to `sto_erase` (if
they're specified by constants - variable parameters are ignored).

View File

@@ -0,0 +1,15 @@
# hooks-float-arith-pure
Hooks can compute floating-point values in XFL format by calling
functions `float_multiply`, `float_mulratio`, `float_negate`,
`float_sum`, `float_invert` and `float_divide` and access their
constituent parts by calling `float_exponent`, `float_mantissa` and
`float_sign`. If the inputs of the computation never change, a more
efficient way to do this is to precompute it.
This check warns about calls of the aforementioned functions with
constant inputs and in simple cases proposes to add a tracing
statement showing the computed value (so that the user can use it to
replace the call). It also checks that the divisor passed to
`float_divide`, `float_mulratio` and `float_invert` is not 0 (if it's
specified by a constant - variable parameters are ignored).

View File

@@ -0,0 +1,9 @@
# hooks-float-compare-pure
Hooks can compare floating-point values in XFL format by calling the
`float_compare` function. If the inputs of the comparison never
change, its result is fixed and the function need not be called.
This check warns about calls of `float_compare` with constant inputs
as well as invalid values of the comparison mode parameter (if it's
specified by a constant - variable parameter is ignored).

View File

@@ -0,0 +1,10 @@
# hooks-float-int-pure
Hooks can convert floating-point values in XFL format to integers by
calling the `float_int` function. If the inputs of this function never
change, a more efficient way to do this is to precompute the integer
value.
This check warns about calls of `float_int` with constant inputs as
well as invalid values of the decimal places parameter (if it's
specified by a constant - variable parameter is ignored).

View File

@@ -0,0 +1,13 @@
# hooks-float-manip-pure
Hooks can directly manipulate floating-point values in XFL format by
calling functions `float_exponent_set`, `float_mantissa_set` and
`float_sign_set`. If the inputs of the update never change, a more
efficient way to do this is to precompute it.
This check warns about calls of the aforementioned functions with
constant inputs and in simple cases proposes to add a tracing
statement showing the computed value (so that the user can use it to
replace the call). It also checks documented bounds of the second
parameter of these functions (if it's specified by a constant -
variable parameter is ignored).

View File

@@ -0,0 +1,5 @@
# hooks-float-one-pure
Hooks can obtain XFL enclosing number 1 by calling the float_one
function. Since the number never changes, a more efficient way is to
use its precomputed value.

View File

@@ -0,0 +1,12 @@
# hooks-float-pure
Hooks can use floating-point values in XFL format, creating them from
mantissa and exponent by calling the `float_set` function. If the
mantissa and exponent never change, a more efficient way to do this is
to precompute the floating-point value.
This check warns about calls of `float_set` with constant inputs and
proposes to add a tracing statement showing the computed value (so
that the user can use it to replace the call). In the special case of
0 mantissa and 0 exponent ("canonical 0"), a replacement value of 0 is
proposed directly, with no need to trace it.

View File

@@ -0,0 +1,5 @@
# hooks-guard-called
Every hook needs to import the guard function `_g` and use it at least once.
[Read documentation](https://xrpl-hooks.readme.io/docs/loops-and-guarding)

View File

@@ -0,0 +1,12 @@
# hooks-guard-in-for
Consider the following for-loop in C:
```c
#define GUARD(maxiter) _g(__LINE__, (maxiter)+1)
for (int i = 0; GUARD(3), i < 3; ++i)
```
This is the only way to satisfy the guard rule when using a for-loop
in C.

View File

@@ -0,0 +1,11 @@
# hooks-guard-in-while
Like for loops, while loops must have a guard in their condition:
```c
#define GUARD(maxiter) _g(__LINE__, (maxiter)+1)
int i = 0;
while (GUARD(3), i < 3)
```

View File

@@ -0,0 +1,7 @@
# hooks-hash-buf-len
Functions `util_sha512h`, `hook_hash`, `ledger_last_hash` and `nonce`
have fixed-size hash output.
This check warns about too-small size of their output buffer (if it's
specified by a constant - variable parameter is ignored).

View File

@@ -0,0 +1,8 @@
# hooks-keylet-buf-len
Computing a ripple keylet by calling `util_keylet` requires valid
parameters dependent on the keylet type.
This check does not fully parse these parameters, but warns about
invalid keylet type as well as buffer sizes that cannot be valid (if
they're specified by constants - variable parameters are ignored).

View File

@@ -0,0 +1,8 @@
# hooks-raddr-conv-buf-len
Hook API `util_accid` has upper limit on the length of its input
(because it expects it to be a raddr) and fixed-size account ID
output.
This check warns about invalid sizes of input and output parameters
(if they're specified by constants - variable parameters are ignored).

View File

@@ -0,0 +1,10 @@
# hooks-raddr-conv-pure
Hooks identify accounts by the 20 byte account ID, which can be
converted from a raddr using the `util_accid` function. If the raddr
never changes, a more efficient way to do this is precompute the
account-id from the raddr.
This check warns about calls of `util_accid` with constant input and
proposes to add a tracing statement showing the computed value (so
that the user can use it to replace the call).

View File

@@ -0,0 +1,9 @@
# hooks-reserve-limit
Hook API `etxn_reserve` takes a parameter specifying the number of
transactions intended to emit from the calling hook. Value of this
parameter is limited, and the function fails if the limit is exceeded.
This check warns about too-large values of the number of reserved
transactions (if they're specified by a constant - variable parameter
is ignored).

View File

@@ -0,0 +1,7 @@
# hooks-slot-hash-buf-len
Function `slot_id` has fixed-size canonical hash output.
This check warns about too-small size of its output buffer as well as
invalid values of the slot number parameter (if they're specified by
constants - variable parameters are ignored).

View File

@@ -0,0 +1,7 @@
# hooks-slot-keylet-buf-len
Function `slot_set` has structured keylet input.
This check does not parse the input, but warns about its sizes that
cannot be valid as well as invalid values of the slot number parameter
(if they're specified by constants - variable parameters are ignored).

View File

@@ -0,0 +1,9 @@
# hooks-slot-limit
Hook APIs `slot`, `slot_count`, `slot_clear`, `slot_size`,
`slot_float` and `trace_slot` take a parameter specifying the accessed
slot number. Value of this parameter is limited, and the functions
fail if the limit is exceeded.
This check warns about too-large values of the slot number (if it's
specified by a constant - variable parameter is ignored).

View File

@@ -0,0 +1,8 @@
# hooks-slot-sub-limit
Hook APIs `slot_subarray` and `slot_subfield` take parameters
specifying parent and child slot numbers. Values of these parameters
are limited, and the functions fail if the limit is exceeded.
This check warns about too-large values of the slot numbers (if
they're specified by a constant - variable parameters are ignored).

View File

@@ -0,0 +1,9 @@
# hooks-slot-type-limit
Hook API `slot_type` takes a parameter specifying the accessed slot
number. Value of this parameter is limited, and the function fails if
the limit is exceeded.
This check warns about too-large values of the slot number as well as
invalid values of the flags parameter (if they're specified by
constants - variable parameters are ignored).

View File

@@ -0,0 +1,6 @@
# hooks-state-buf-len
Functions state and state_set accept fixed-size Hook State key.
This check warns about invalid size of its input buffer (if it's
specified by a constant - variable parameter is ignored).

View File

@@ -0,0 +1,6 @@
# hooks-transaction-hash-buf-len
Function `otxn_id` has fixed-size canonical hash output.
This check warns about too-small size of its output buffer (if it's
specified by a constant - variable parameter is ignored).

View File

@@ -0,0 +1,8 @@
# hooks-transaction-slot-limit
Function `otxn_slot` takes a parameter specifying the accessed slot
number. Value of this parameter is limited, and the function fails if
the limit is exceeded.
This check warns about too-large values of the slot number (if it's
specified by a constant - variable parameter is ignored).

View File

@@ -0,0 +1,6 @@
# hooks-validate-buf-len
Hook API `sto_validate` requires non-empty input buffer.
This check warns about empty input in calls to `sto_validate` (if it's
specified by a constant - variable parameter is ignored).

View File

@@ -0,0 +1,8 @@
# hooks-verify-buf-len
Verifying a cryptographic signature by calling `util_verify` requires
valid public key & data signature.
This check does not fully parse these parameters, but warns about
their sizes that cannot be valid (if they're specified by constants -
variable parameters are ignored).

107
yarn.lock
View File

@@ -886,6 +886,11 @@
resolved "https://registry.yarnpkg.com/@types/file-saver/-/file-saver-2.0.4.tgz#aaf9b96296150d737b2fefa535ced05ed8013d84"
integrity sha512-sPZYQEIF/SOnLAvaz9lTuydniP+afBMtElRTdYkeV1QtEgvtJ7qolCPjly6O32QI8CbEmP5O/fztMXEDWfEcrg==
"@types/json-schema@^7.0.8":
version "7.0.9"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d"
integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==
"@types/json5@^0.0.29":
version "0.0.29"
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
@@ -898,6 +903,18 @@
dependencies:
"@types/node" "*"
"@types/lodash.uniqby@^4.7.6":
version "4.7.6"
resolved "https://registry.yarnpkg.com/@types/lodash.uniqby/-/lodash.uniqby-4.7.6.tgz#672827a701403f07904fe37f0721ae92abfa80e8"
integrity sha512-9wBhrm1y6asW50Joj6tsySCNUgzK2tCqL7vtKIej0E9RyeBFdcte7fxUosmFuMoOU0eHqOMK76kCCrK99jxHgg==
dependencies:
"@types/lodash" "*"
"@types/lodash@*":
version "4.14.179"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.179.tgz#490ec3288088c91295780237d2497a3aa9dfb5c5"
integrity sha512-uwc1x90yCKqGcIOAT6DwOSuxnrAbpkdPsUOZtwrXb4D/6wZs+6qG7QnIawDuZWg0sWpxl+ltIKCaLoMlna678w==
"@types/lodash@^4.14.136":
version "4.14.177"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.177.tgz#f70c0d19c30fab101cad46b52be60363c43c4578"
@@ -1049,7 +1066,12 @@ aggregate-error@^3.1.0:
clean-stack "^2.0.0"
indent-string "^4.0.0"
ajv@^6.10.0, ajv@^6.12.4:
ajv-keywords@^3.5.2:
version "3.5.2"
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d"
integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==
ajv@^6.10.0, ajv@^6.12.4, ajv@^6.12.5:
version "6.12.6"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
@@ -1880,6 +1902,11 @@ emojis-list@^2.0.0:
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389"
integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k=
emojis-list@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78"
integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==
encoding@0.1.13:
version "0.1.13"
resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9"
@@ -2273,6 +2300,11 @@ file-uri-to-path@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==
filesize@^8.0.7:
version "8.0.7"
resolved "https://registry.yarnpkg.com/filesize/-/filesize-8.0.7.tgz#695e70d80f4e47012c132d57a059e80c6b580bd8"
integrity sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==
fill-range@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
@@ -2833,6 +2865,13 @@ isexe@^2.0.0:
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
javascript-time-ago@^2.3.11:
version "2.3.11"
resolved "https://registry.yarnpkg.com/javascript-time-ago/-/javascript-time-ago-2.3.11.tgz#b488ae765b7f42ff003f3830977a92411ef1fe92"
integrity sha512-R6Ux0IGv7RmAZ7vB04r/gevGaLDJeZY7+6jTYyYsPAF5x4PSv6up+dW2hLK99+OUY8xwdeXPItZFiUppIRUaoQ==
dependencies:
relative-time-format "^1.0.6"
jest-worker@27.0.0-next.5:
version "27.0.0-next.5"
resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.0.0-next.5.tgz#5985ee29b12a4e191f4aae4bb73b97971d86ec28"
@@ -2882,6 +2921,13 @@ json5@^1.0.1:
dependencies:
minimist "^1.2.0"
json5@^2.1.2:
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"
jsonfile@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
@@ -2988,6 +3034,15 @@ loader-utils@1.2.3:
emojis-list "^2.0.0"
json5 "^1.0.1"
loader-utils@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.2.tgz#d6e3b4fb81870721ae4e0868ab11dd638368c129"
integrity sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==
dependencies:
big.js "^5.2.2"
emojis-list "^3.0.0"
json5 "^2.1.2"
locate-path@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e"
@@ -3058,6 +3113,11 @@ lodash.truncate@^4.4.2:
resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193"
integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=
lodash.uniqby@^4.7.0:
version "4.7.0"
resolved "https://registry.yarnpkg.com/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz#d99c07a669e9e6d24e1362dfe266c67616af1302"
integrity sha1-2ZwHpmnp5tJOE2Lf4mbGdhavEwI=
lodash@^4.17.15, lodash@^4.17.4:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
@@ -3146,7 +3206,7 @@ minimatch@^3.0.4:
dependencies:
brace-expansion "^1.1.7"
minimist@^1.2.0:
minimist@^1.2.0, minimist@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
@@ -3608,6 +3668,11 @@ pbkdf2@^3.0.3, pbkdf2@^3.0.9:
safe-buffer "^5.0.1"
sha.js "^2.4.8"
performance-now@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
phosphor-react@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/phosphor-react/-/phosphor-react-1.3.1.tgz#96e33f44370d83cda15b60cccc17087ad0060684"
@@ -3754,6 +3819,13 @@ queue@6.0.2:
dependencies:
inherits "~2.0.3"
raf@^3.4.1:
version "3.4.1"
resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39"
integrity sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==
dependencies:
performance-now "^2.1.0"
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"
@@ -3779,6 +3851,14 @@ raw-body@2.4.1:
iconv-lite "0.4.24"
unpipe "1.0.0"
raw-loader@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-4.0.2.tgz#1aac6b7d1ad1501e66efdac1522c73e59a584eb6"
integrity sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA==
dependencies:
loader-utils "^2.0.0"
schema-utils "^3.0.0"
re-resizable@^6.9.1:
version "6.9.1"
resolved "https://registry.yarnpkg.com/re-resizable/-/re-resizable-6.9.1.tgz#6be082b55d02364ca4bfee139e04feebdf52441c"
@@ -3889,6 +3969,15 @@ react-style-singleton@^2.1.0:
invariant "^2.2.4"
tslib "^1.0.0"
react-time-ago@^7.1.9:
version "7.1.9"
resolved "https://registry.yarnpkg.com/react-time-ago/-/react-time-ago-7.1.9.tgz#df3999f1184b71ab09aaf1d05dda2a19b76e0bb8"
integrity sha512-jN4EsEgqm3a5eLJV0ZrRpom3iG+w4bullS2NHc2htIucGUIr2FbgHXjU0wIkuN9uWM87aFvIfkUDpS/ju7Mazg==
dependencies:
memoize-one "^6.0.0"
prop-types "^15.7.2"
raf "^3.4.1"
react-transition-group@^4.3.0:
version "4.4.2"
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.2.tgz#8b59a56f09ced7b55cbd53c36768b922890d5470"
@@ -3969,6 +4058,11 @@ regexpp@^3.1.0:
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2"
integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==
relative-time-format@^1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/relative-time-format/-/relative-time-format-1.0.6.tgz#4956f6aa161f63cbab8a7f2d8b2e92d7b6a888a3"
integrity sha512-voemOJLxlKun4P1fAo4PEg2WXNGjhqfE/G8Xen4gcy24Hyu/djn5bT5axmhx4MnjynoZ8f0HCOjk3RZpsY6X/g==
require-from-string@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
@@ -4162,6 +4256,15 @@ scheduler@^0.20.2:
loose-envify "^1.1.0"
object-assign "^4.1.1"
schema-utils@^3.0.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281"
integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==
dependencies:
"@types/json-schema" "^7.0.8"
ajv "^6.12.5"
ajv-keywords "^3.5.2"
semver@^5.5.0, semver@^5.6.0:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"