Compare commits
	
		
			41 Commits
		
	
	
		
			feat/persi
			...
			fix/do-not
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					3e7c7b1969 | ||
| 
						 | 
					0c6c60ed29 | ||
| 
						 | 
					5490e7205a | ||
| 
						 | 
					052a1e5b60 | ||
| 
						 | 
					ddb043c104 | ||
| 
						 | 
					d2ad6537d7 | ||
| 
						 | 
					8f004ee4da | ||
| 
						 | 
					b90bf67c20 | ||
| 
						 | 
					746112e637 | ||
| 
						 | 
					13bfd42093 | ||
| 
						 | 
					c1f7d7d51c | ||
| 
						 | 
					38a097a8f9 | ||
| 
						 | 
					db0ffe999e | ||
| 
						 | 
					6d88c4e546 | ||
| 
						 | 
					e11ddaffb0 | ||
| 
						 | 
					2e88f568b8 | ||
| 
						 | 
					237d504f17 | ||
| 
						 | 
					197fc09e1d | ||
| 
						 | 
					2c74a93aee | ||
| 
						 | 
					5209644780 | ||
| 
						 | 
					ed37427da8 | ||
| 
						 | 
					daee9de96c | ||
| 
						 | 
					e4b10d12c2 | ||
| 
						 | 
					64eabb4502 | ||
| 
						 | 
					12a24d3d86 | ||
| 
						 | 
					ce91182c7b | ||
| 
						 | 
					2e3a0e557e | ||
| 
						 | 
					395e02343b | ||
| 
						 | 
					3682dd4946 | ||
| 
						 | 
					3070ed706e | ||
| 
						 | 
					4b73687779 | ||
| 
						 | 
					6b9a9ef978 | ||
| 
						 | 
					bc5bb5be39 | ||
| 
						 | 
					0fe83811b9 | ||
| 
						 | 
					c6359aa853 | ||
| 
						 | 
					c9c818c8f3 | ||
| 
						 | 
					c521246393 | ||
| 
						 | 
					8936b34361 | ||
| 
						 | 
					5993d2762f | ||
| 
						 | 
					0a44b5b5d1 | ||
| 
						 | 
					0def1d30a6 | 
							
								
								
									
										1
									
								
								.prettierignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.prettierignore
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
*.md
 | 
			
		||||
@@ -27,7 +27,7 @@ const labelStyle = css({
 | 
			
		||||
  mb: "$0.5",
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const AccountDialog = ({
 | 
			
		||||
export const AccountDialog = ({
 | 
			
		||||
  activeAccountAddress,
 | 
			
		||||
  setActiveAccountAddress,
 | 
			
		||||
}: {
 | 
			
		||||
@@ -36,11 +36,13 @@ const AccountDialog = ({
 | 
			
		||||
}) => {
 | 
			
		||||
  const snap = useSnapshot(state);
 | 
			
		||||
  const [showSecret, setShowSecret] = useState(false);
 | 
			
		||||
  const activeAccount = snap.accounts.find(account => account.address === activeAccountAddress);
 | 
			
		||||
  const activeAccount = snap.accounts.find(
 | 
			
		||||
    (account) => account.address === activeAccountAddress
 | 
			
		||||
  );
 | 
			
		||||
  return (
 | 
			
		||||
    <Dialog
 | 
			
		||||
      open={Boolean(activeAccountAddress)}
 | 
			
		||||
      onOpenChange={open => {
 | 
			
		||||
      onOpenChange={(open) => {
 | 
			
		||||
        setShowSecret(false);
 | 
			
		||||
        !open && setActiveAccountAddress(null);
 | 
			
		||||
      }}
 | 
			
		||||
@@ -135,7 +137,7 @@ const AccountDialog = ({
 | 
			
		||||
                    }}
 | 
			
		||||
                    ghost
 | 
			
		||||
                    size="xs"
 | 
			
		||||
                    onClick={() => setShowSecret(curr => !curr)}
 | 
			
		||||
                    onClick={() => setShowSecret((curr) => !curr)}
 | 
			
		||||
                  >
 | 
			
		||||
                    {showSecret ? "Hide" : "Show"}
 | 
			
		||||
                  </Button>
 | 
			
		||||
@@ -221,13 +223,15 @@ interface AccountProps {
 | 
			
		||||
  showHookStats?: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const Accounts: FC<AccountProps> = props => {
 | 
			
		||||
const Accounts: FC<AccountProps> = (props) => {
 | 
			
		||||
  const snap = useSnapshot(state);
 | 
			
		||||
  const [activeAccountAddress, setActiveAccountAddress] = useState<string | null>(null);
 | 
			
		||||
  const [activeAccountAddress, setActiveAccountAddress] = useState<
 | 
			
		||||
    string | null
 | 
			
		||||
  >(null);
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    const fetchAccInfo = async () => {
 | 
			
		||||
      if (snap.clientStatus === "online") {
 | 
			
		||||
        const requests = snap.accounts.map(acc =>
 | 
			
		||||
        const requests = snap.accounts.map((acc) =>
 | 
			
		||||
          snap.client?.send({
 | 
			
		||||
            id: acc.address,
 | 
			
		||||
            command: "account_info",
 | 
			
		||||
@@ -239,13 +243,15 @@ const Accounts: FC<AccountProps> = props => {
 | 
			
		||||
          const address = res?.account_data?.Account as string;
 | 
			
		||||
          const balance = res?.account_data?.Balance as string;
 | 
			
		||||
          const sequence = res?.account_data?.Sequence as number;
 | 
			
		||||
          const accountToUpdate = state.accounts.find(acc => acc.address === address);
 | 
			
		||||
          const accountToUpdate = state.accounts.find(
 | 
			
		||||
            (acc) => acc.address === address
 | 
			
		||||
          );
 | 
			
		||||
          if (accountToUpdate) {
 | 
			
		||||
            accountToUpdate.xrp = balance;
 | 
			
		||||
            accountToUpdate.sequence = sequence;
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
        const objectRequests = snap.accounts.map(acc => {
 | 
			
		||||
        const objectRequests = snap.accounts.map((acc) => {
 | 
			
		||||
          return snap.client?.send({
 | 
			
		||||
            id: `${acc.address}-hooks`,
 | 
			
		||||
            command: "account_objects",
 | 
			
		||||
@@ -255,7 +261,9 @@ const Accounts: FC<AccountProps> = props => {
 | 
			
		||||
        const objectResponses = await Promise.all(objectRequests);
 | 
			
		||||
        objectResponses.forEach((res: any) => {
 | 
			
		||||
          const address = res?.account as string;
 | 
			
		||||
          const accountToUpdate = state.accounts.find(acc => acc.address === address);
 | 
			
		||||
          const accountToUpdate = state.accounts.find(
 | 
			
		||||
            (acc) => acc.address === address
 | 
			
		||||
          );
 | 
			
		||||
          if (accountToUpdate) {
 | 
			
		||||
            accountToUpdate.hooks = res.account_objects
 | 
			
		||||
              .filter((ac: any) => ac?.LedgerEntryType === "Hook")
 | 
			
		||||
@@ -337,7 +345,7 @@ const Accounts: FC<AccountProps> = props => {
 | 
			
		||||
            overflowY: "auto",
 | 
			
		||||
          }}
 | 
			
		||||
        >
 | 
			
		||||
          {snap.accounts.map(account => (
 | 
			
		||||
          {snap.accounts.map((account) => (
 | 
			
		||||
            <Flex
 | 
			
		||||
              column
 | 
			
		||||
              key={account.address + account.name}
 | 
			
		||||
@@ -364,7 +372,7 @@ const Accounts: FC<AccountProps> = props => {
 | 
			
		||||
                  <Text>{account.name} </Text>
 | 
			
		||||
                  <Text
 | 
			
		||||
                    css={{
 | 
			
		||||
                      color: "$mauve9",
 | 
			
		||||
                      color: "$textMuted",
 | 
			
		||||
                      wordBreak: "break-word",
 | 
			
		||||
                    }}
 | 
			
		||||
                  >
 | 
			
		||||
@@ -383,28 +391,37 @@ const Accounts: FC<AccountProps> = props => {
 | 
			
		||||
                  </Text>
 | 
			
		||||
                </Box>
 | 
			
		||||
                {!props.hideDeployBtn && (
 | 
			
		||||
                  <Button
 | 
			
		||||
                    css={{ ml: "auto" }}
 | 
			
		||||
                    size="xs"
 | 
			
		||||
                    uppercase
 | 
			
		||||
                    isLoading={account.isLoading}
 | 
			
		||||
                    disabled={
 | 
			
		||||
                      account.isLoading ||
 | 
			
		||||
                      !snap.files.filter(file => file.compiledWatContent).length
 | 
			
		||||
                    }
 | 
			
		||||
                    variant="secondary"
 | 
			
		||||
                    onClick={e => {
 | 
			
		||||
                  <div
 | 
			
		||||
                    onClick={(e) => {
 | 
			
		||||
                      e.preventDefault();
 | 
			
		||||
                      e.stopPropagation();
 | 
			
		||||
                      deployHook(account);
 | 
			
		||||
                    }}
 | 
			
		||||
                  >
 | 
			
		||||
                    Deploy
 | 
			
		||||
                  </Button>
 | 
			
		||||
                    <Button
 | 
			
		||||
                      css={{ ml: "auto" }}
 | 
			
		||||
                      size="xs"
 | 
			
		||||
                      uppercase
 | 
			
		||||
                      isLoading={account.isLoading}
 | 
			
		||||
                      disabled={
 | 
			
		||||
                        account.isLoading ||
 | 
			
		||||
                        !snap.files.filter((file) => file.compiledWatContent)
 | 
			
		||||
                          .length
 | 
			
		||||
                      }
 | 
			
		||||
                      variant="secondary"
 | 
			
		||||
                      onClick={(e) => {
 | 
			
		||||
                        e.stopPropagation();
 | 
			
		||||
                        deployHook(account);
 | 
			
		||||
                      }}
 | 
			
		||||
                    >
 | 
			
		||||
                      Deploy
 | 
			
		||||
                    </Button>
 | 
			
		||||
                  </div>
 | 
			
		||||
                )}
 | 
			
		||||
              </Flex>
 | 
			
		||||
              {props.showHookStats && (
 | 
			
		||||
                <Text muted small css={{ mt: "$2" }}>
 | 
			
		||||
                  {account.hooks.length} hook{account.hooks.length === 1 ? "" : "s"} installed
 | 
			
		||||
                  {account.hooks.length} hook
 | 
			
		||||
                  {account.hooks.length === 1 ? "" : "s"} installed
 | 
			
		||||
                </Text>
 | 
			
		||||
              )}
 | 
			
		||||
            </Flex>
 | 
			
		||||
@@ -436,7 +453,7 @@ const ImportAccountDialog = () => {
 | 
			
		||||
            name="secret"
 | 
			
		||||
            type="password"
 | 
			
		||||
            value={value}
 | 
			
		||||
            onChange={e => setValue(e.target.value)}
 | 
			
		||||
            onChange={(e) => setValue(e.target.value)}
 | 
			
		||||
          />
 | 
			
		||||
        </DialogDescription>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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";
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,84 +1,136 @@
 | 
			
		||||
import { useEffect, useState } from "react";
 | 
			
		||||
import { useSnapshot } from "valtio";
 | 
			
		||||
import { useCallback, useEffect } from "react";
 | 
			
		||||
import { proxy, ref, useSnapshot } from "valtio";
 | 
			
		||||
import { Select } from ".";
 | 
			
		||||
import state from "../state";
 | 
			
		||||
import state, { ILog } from "../state";
 | 
			
		||||
import { extractJSON } from "../utils/json";
 | 
			
		||||
import LogBox from "./LogBox";
 | 
			
		||||
import Text from "./Text";
 | 
			
		||||
 | 
			
		||||
interface ISelect<T = string> {
 | 
			
		||||
  label: string;
 | 
			
		||||
  value: T;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const streamState = proxy({
 | 
			
		||||
  selectedAccount: null as ISelect | null,
 | 
			
		||||
  logs: [] as ILog[],
 | 
			
		||||
  socket: undefined as WebSocket | undefined,
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const DebugStream = () => {
 | 
			
		||||
  const snap = useSnapshot(state);
 | 
			
		||||
  const { selectedAccount, logs, socket } = useSnapshot(streamState);
 | 
			
		||||
  const { accounts } = useSnapshot(state);
 | 
			
		||||
 | 
			
		||||
  const accountOptions = snap.accounts.map(acc => ({
 | 
			
		||||
  const accountOptions = accounts.map(acc => ({
 | 
			
		||||
    label: acc.name,
 | 
			
		||||
    value: acc.address,
 | 
			
		||||
  }));
 | 
			
		||||
  const [selectedAccount, setSelectedAccount] = useState<typeof accountOptions[0] | null>(null);
 | 
			
		||||
 | 
			
		||||
  const renderNav = () => (
 | 
			
		||||
    <>
 | 
			
		||||
      <Text css={{ mx: "$2", fontSize: "inherit" }}>Account: </Text>
 | 
			
		||||
      <Select
 | 
			
		||||
        instanceId="debugStreamAccount"
 | 
			
		||||
        instanceId="DSAccount"
 | 
			
		||||
        placeholder="Select account"
 | 
			
		||||
        options={accountOptions}
 | 
			
		||||
        hideSelectedOptions
 | 
			
		||||
        value={selectedAccount}
 | 
			
		||||
        onChange={acc => setSelectedAccount(acc as any)}
 | 
			
		||||
        css={{ width: "30%" }}
 | 
			
		||||
        onChange={acc => (streamState.selectedAccount = acc as any)}
 | 
			
		||||
        css={{ width: "100%" }}
 | 
			
		||||
      />
 | 
			
		||||
    </>
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  const prepareLog = useCallback((str: any): ILog => {
 | 
			
		||||
    if (typeof str !== "string") throw Error("Unrecognized debug log stream!");
 | 
			
		||||
 | 
			
		||||
    const match = str.match(/([\s\S]+(?:UTC|ISO|GMT[+|-]\d+))\ ?([\s\S]*)/m);
 | 
			
		||||
    const [_, tm, msg] = match || [];
 | 
			
		||||
 | 
			
		||||
    const extracted = extractJSON(msg);
 | 
			
		||||
    const timestamp = isNaN(Date.parse(tm || ""))
 | 
			
		||||
      ? tm
 | 
			
		||||
      : new Date(tm).toLocaleTimeString();
 | 
			
		||||
 | 
			
		||||
    const message = !extracted
 | 
			
		||||
      ? msg
 | 
			
		||||
      : msg.slice(0, extracted.start) + msg.slice(extracted.end + 1);
 | 
			
		||||
 | 
			
		||||
    const jsonData = extracted
 | 
			
		||||
      ? JSON.stringify(extracted.result, null, 2)
 | 
			
		||||
      : undefined;
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
      type: "log",
 | 
			
		||||
      message,
 | 
			
		||||
      timestamp,
 | 
			
		||||
      jsonData,
 | 
			
		||||
      defaultCollapsed: true,
 | 
			
		||||
    };
 | 
			
		||||
  }, []);
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    const account = selectedAccount?.value;
 | 
			
		||||
    if (!account) {
 | 
			
		||||
      return;
 | 
			
		||||
    if (account && (!socket || !socket.url.endsWith(account))) {
 | 
			
		||||
      socket?.close();
 | 
			
		||||
      streamState.socket = ref(
 | 
			
		||||
        new WebSocket(
 | 
			
		||||
          `wss://hooks-testnet-debugstream.xrpl-labs.com/${account}`
 | 
			
		||||
        )
 | 
			
		||||
      );
 | 
			
		||||
    } else if (!account && socket) {
 | 
			
		||||
      socket.close();
 | 
			
		||||
      streamState.socket = undefined;
 | 
			
		||||
    }
 | 
			
		||||
    const socket = new WebSocket(`wss://hooks-testnet-debugstream.xrpl-labs.com/${account}`);
 | 
			
		||||
  }, [selectedAccount?.value, socket]);
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    const account = selectedAccount?.value;
 | 
			
		||||
    const socket = streamState.socket;
 | 
			
		||||
    if (!socket) return;
 | 
			
		||||
 | 
			
		||||
    const onOpen = () => {
 | 
			
		||||
      state.debugLogs = [];
 | 
			
		||||
      state.debugLogs.push({
 | 
			
		||||
      streamState.logs = [];
 | 
			
		||||
      streamState.logs.push({
 | 
			
		||||
        type: "success",
 | 
			
		||||
        message: `Debug stream opened for account ${account}`,
 | 
			
		||||
      });
 | 
			
		||||
    };
 | 
			
		||||
    const onError = () => {
 | 
			
		||||
      state.debugLogs.push({
 | 
			
		||||
      streamState.logs.push({
 | 
			
		||||
        type: "error",
 | 
			
		||||
        message: "Something went wrong in establishing connection!",
 | 
			
		||||
        message: "Something went wrong! Check your connection and try again.",
 | 
			
		||||
      });
 | 
			
		||||
      setSelectedAccount(null);
 | 
			
		||||
    };
 | 
			
		||||
    const onClose = (e: CloseEvent) => {
 | 
			
		||||
      streamState.logs.push({
 | 
			
		||||
        type: "error",
 | 
			
		||||
        message: `Connection was closed. [code: ${e.code}]`,
 | 
			
		||||
      });
 | 
			
		||||
      streamState.selectedAccount = null;
 | 
			
		||||
    };
 | 
			
		||||
    const onMessage = (event: any) => {
 | 
			
		||||
      if (!event.data) return;
 | 
			
		||||
      state.debugLogs.push({
 | 
			
		||||
        type: "log",
 | 
			
		||||
        message: event.data,
 | 
			
		||||
      });
 | 
			
		||||
      streamState.logs.push(prepareLog(event.data));
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    socket.addEventListener("open", onOpen);
 | 
			
		||||
    socket.addEventListener("close", onError);
 | 
			
		||||
    socket.addEventListener("close", onClose);
 | 
			
		||||
    socket.addEventListener("error", onError);
 | 
			
		||||
    socket.addEventListener("message", onMessage);
 | 
			
		||||
 | 
			
		||||
    return () => {
 | 
			
		||||
      socket.removeEventListener("open", onOpen);
 | 
			
		||||
      socket.removeEventListener("close", onError);
 | 
			
		||||
      socket.removeEventListener("close", onClose);
 | 
			
		||||
      socket.removeEventListener("message", onMessage);
 | 
			
		||||
 | 
			
		||||
      socket.close();
 | 
			
		||||
      socket.removeEventListener("error", onError);
 | 
			
		||||
    };
 | 
			
		||||
  }, [selectedAccount]);
 | 
			
		||||
 | 
			
		||||
  }, [prepareLog, selectedAccount?.value, socket]);
 | 
			
		||||
  return (
 | 
			
		||||
    <LogBox
 | 
			
		||||
      enhanced
 | 
			
		||||
      renderNav={renderNav}
 | 
			
		||||
      title="Debug stream"
 | 
			
		||||
      logs={snap.debugLogs}
 | 
			
		||||
      clearLog={() => (state.debugLogs = [])}
 | 
			
		||||
      logs={logs}
 | 
			
		||||
      clearLog={() => (streamState.logs = [])}
 | 
			
		||||
    />
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -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>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -59,10 +59,8 @@ import {
 | 
			
		||||
} from "./AlertDialog";
 | 
			
		||||
import { styled } from "../stitches.config";
 | 
			
		||||
 | 
			
		||||
const DEFAULT_EXTENSION = ".c";
 | 
			
		||||
 | 
			
		||||
const ErrorText = styled(Text, {
 | 
			
		||||
  color: "$crimson9",
 | 
			
		||||
  color: "$error",
 | 
			
		||||
  mt: "$1",
 | 
			
		||||
  display: "block",
 | 
			
		||||
});
 | 
			
		||||
@@ -91,33 +89,38 @@ const EditorNavigation = ({ showWat }: { showWat?: boolean }) => {
 | 
			
		||||
  const validateFilename = useCallback(
 | 
			
		||||
    (filename: string): { error: string | null } => {
 | 
			
		||||
      // check if filename already exists
 | 
			
		||||
      if (snap.files.find(file => file.name === filename)) {
 | 
			
		||||
      if (!filename) {
 | 
			
		||||
        return { error: "You need to add filename" };
 | 
			
		||||
      }
 | 
			
		||||
      if (snap.files.find((file) => file.name === filename)) {
 | 
			
		||||
        return { error: "Filename already exists." };
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // check for illegal characters
 | 
			
		||||
      const ILLEGAL_REGEX = /[/]/gi;
 | 
			
		||||
      if (filename.match(ILLEGAL_REGEX)) {
 | 
			
		||||
        return { error: "Filename contains illegal characters" };
 | 
			
		||||
      if (!filename.includes(".") || filename[filename.length - 1] === ".") {
 | 
			
		||||
        return { error: "Filename should include file extension" };
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // check for illegal characters
 | 
			
		||||
      const ALPHA_NUMERICAL_REGEX = /^[A-Za-z0-9_-]+[.][A-Za-z0-9]{1,4}$/g;
 | 
			
		||||
      if (!filename.match(ALPHA_NUMERICAL_REGEX)) {
 | 
			
		||||
        return {
 | 
			
		||||
          error: `Filename can contain only characters from a-z, A-Z, 0-9, "_" and "-" and it needs to have file extension (e.g. ".c")`,
 | 
			
		||||
        };
 | 
			
		||||
      }
 | 
			
		||||
      // More checks in future
 | 
			
		||||
      return { error: null };
 | 
			
		||||
    },
 | 
			
		||||
    [snap.files]
 | 
			
		||||
  );
 | 
			
		||||
  const handleConfirm = useCallback(() => {
 | 
			
		||||
    // add default extension in case omitted
 | 
			
		||||
    let _filename = filename.includes(".")
 | 
			
		||||
      ? filename
 | 
			
		||||
      : filename + DEFAULT_EXTENSION;
 | 
			
		||||
    const chk = validateFilename(_filename);
 | 
			
		||||
    if (chk.error) {
 | 
			
		||||
    const chk = validateFilename(filename);
 | 
			
		||||
    if (chk && chk.error) {
 | 
			
		||||
      setNewfileError(`Error: ${chk.error}`);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setIsNewfileDialogOpen(false);
 | 
			
		||||
    createNewFile(_filename);
 | 
			
		||||
    createNewFile(filename);
 | 
			
		||||
    setFilename("");
 | 
			
		||||
  }, [filename, setIsNewfileDialogOpen, setFilename, validateFilename]);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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",
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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,71 @@ 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) => {
 | 
			
		||||
    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,
 | 
			
		||||
            },
 | 
			
		||||
          },
 | 
			
		||||
        }))
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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 +118,11 @@ const HooksEditor = () => {
 | 
			
		||||
      subscriptionRef?.current?.close();
 | 
			
		||||
    };
 | 
			
		||||
  }, []);
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    if (monacoRef.current) {
 | 
			
		||||
      setMarkers(monacoRef.current);
 | 
			
		||||
    }
 | 
			
		||||
  }, [snap.active]);
 | 
			
		||||
  return (
 | 
			
		||||
    <Box
 | 
			
		||||
      css={{
 | 
			
		||||
@@ -133,6 +204,7 @@ const HooksEditor = () => {
 | 
			
		||||
          }}
 | 
			
		||||
          onMount={(editor, monaco) => {
 | 
			
		||||
            editorRef.current = editor;
 | 
			
		||||
            monacoRef.current = monaco;
 | 
			
		||||
            editor.updateOptions({
 | 
			
		||||
              glyphMargin: true,
 | 
			
		||||
              lightbulb: {
 | 
			
		||||
@@ -145,6 +217,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"}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,14 @@ import { styled } from "../stitches.config";
 | 
			
		||||
const StyledLink = styled("a", {
 | 
			
		||||
  color: "CurrentColor",
 | 
			
		||||
  textDecoration: "underline",
 | 
			
		||||
  cursor: 'pointer',
 | 
			
		||||
  variants: {
 | 
			
		||||
    highlighted: {
 | 
			
		||||
      true: {
 | 
			
		||||
        color: '$blue9'
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export default StyledLink;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,17 +1,15 @@
 | 
			
		||||
import React, { useRef, useLayoutEffect, ReactNode } from "react";
 | 
			
		||||
import { useRef, useLayoutEffect, ReactNode, FC, useState, useCallback } from "react";
 | 
			
		||||
import { Notepad, Prohibit } from "phosphor-react";
 | 
			
		||||
import useStayScrolled from "react-stay-scrolled";
 | 
			
		||||
import NextLink from "next/link";
 | 
			
		||||
 | 
			
		||||
import Container from "./Container";
 | 
			
		||||
import Box from "./Box";
 | 
			
		||||
import Flex from "./Flex";
 | 
			
		||||
import LogText from "./LogText";
 | 
			
		||||
import { ILog } from "../state";
 | 
			
		||||
import Text from "./Text";
 | 
			
		||||
import Button from "./Button";
 | 
			
		||||
import Heading from "./Heading";
 | 
			
		||||
import Link from "./Link";
 | 
			
		||||
import state, { ILog } from "../state";
 | 
			
		||||
import { Pre, Link, Heading, Button, Text, Flex, Box } from ".";
 | 
			
		||||
import regexifyString from "regexify-string";
 | 
			
		||||
import { useSnapshot } from "valtio";
 | 
			
		||||
import { AccountDialog } from "./Accounts";
 | 
			
		||||
 | 
			
		||||
interface ILogBox {
 | 
			
		||||
  title: string;
 | 
			
		||||
@@ -21,14 +19,7 @@ interface ILogBox {
 | 
			
		||||
  enhanced?: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const LogBox: React.FC<ILogBox> = ({
 | 
			
		||||
  title,
 | 
			
		||||
  clearLog,
 | 
			
		||||
  logs,
 | 
			
		||||
  children,
 | 
			
		||||
  renderNav,
 | 
			
		||||
  enhanced,
 | 
			
		||||
}) => {
 | 
			
		||||
const LogBox: FC<ILogBox> = ({ title, clearLog, logs, children, renderNav, enhanced }) => {
 | 
			
		||||
  const logRef = useRef<HTMLPreElement>(null);
 | 
			
		||||
  const { stayScrolled /*, scrollBottom*/ } = useStayScrolled(logRef);
 | 
			
		||||
 | 
			
		||||
@@ -55,6 +46,7 @@ const LogBox: React.FC<ILogBox> = ({
 | 
			
		||||
        }}
 | 
			
		||||
      >
 | 
			
		||||
        <Flex
 | 
			
		||||
          fluid
 | 
			
		||||
          css={{
 | 
			
		||||
            height: "48px",
 | 
			
		||||
            alignItems: "center",
 | 
			
		||||
@@ -78,7 +70,15 @@ const LogBox: React.FC<ILogBox> = ({
 | 
			
		||||
          >
 | 
			
		||||
            <Notepad size="15px" /> <Text css={{ lineHeight: 1 }}>{title}</Text>
 | 
			
		||||
          </Heading>
 | 
			
		||||
          {renderNav?.()}
 | 
			
		||||
          <Flex
 | 
			
		||||
            row
 | 
			
		||||
            align="center"
 | 
			
		||||
            css={{
 | 
			
		||||
              width: "50%", // TODO make it max without breaking layout!
 | 
			
		||||
            }}
 | 
			
		||||
          >
 | 
			
		||||
            {renderNav?.()}
 | 
			
		||||
          </Flex>
 | 
			
		||||
          <Flex css={{ ml: "auto", gap: "$3", marginRight: "$3" }}>
 | 
			
		||||
            {clearLog && (
 | 
			
		||||
              <Button ghost size="xs" onClick={clearLog}>
 | 
			
		||||
@@ -117,17 +117,11 @@ const LogBox: React.FC<ILogBox> = ({
 | 
			
		||||
                    backgroundColor: enhanced ? "$backgroundAlt" : undefined,
 | 
			
		||||
                  },
 | 
			
		||||
                },
 | 
			
		||||
                p: enhanced ? "$2 $1" : undefined,
 | 
			
		||||
                p: enhanced ? "$1" : undefined,
 | 
			
		||||
                my: enhanced ? "$1" : undefined,
 | 
			
		||||
              }}
 | 
			
		||||
            >
 | 
			
		||||
              <LogText variant={log.type}>
 | 
			
		||||
                {log.message}{" "}
 | 
			
		||||
                {log.link && (
 | 
			
		||||
                  <NextLink href={log.link} shallow passHref>
 | 
			
		||||
                    <Link as="a">{log.linkText}</Link>
 | 
			
		||||
                  </NextLink>
 | 
			
		||||
                )}
 | 
			
		||||
              </LogText>
 | 
			
		||||
              <Log {...log} />
 | 
			
		||||
            </Box>
 | 
			
		||||
          ))}
 | 
			
		||||
          {children}
 | 
			
		||||
@@ -137,4 +131,74 @@ const LogBox: React.FC<ILogBox> = ({
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const Log: FC<ILog> = ({
 | 
			
		||||
  type,
 | 
			
		||||
  timestamp: timestamp,
 | 
			
		||||
  message: _message,
 | 
			
		||||
  link,
 | 
			
		||||
  linkText,
 | 
			
		||||
  defaultCollapsed,
 | 
			
		||||
  jsonData: _jsonData,
 | 
			
		||||
}) => {
 | 
			
		||||
  const [expanded, setExpanded] = useState(!defaultCollapsed);
 | 
			
		||||
  const { accounts } = useSnapshot(state);
 | 
			
		||||
  const [dialogAccount, setDialogAccount] = useState<string | null>(null);
 | 
			
		||||
 | 
			
		||||
  const enrichAccounts = useCallback(
 | 
			
		||||
    (str?: string): ReactNode => {
 | 
			
		||||
      if (!str || !accounts.length) return null;
 | 
			
		||||
 | 
			
		||||
      const pattern = `(${accounts.map(acc => acc.address).join("|")})`;
 | 
			
		||||
      const res = regexifyString({
 | 
			
		||||
        pattern: new RegExp(pattern, "gim"),
 | 
			
		||||
        decorator: (match, idx) => {
 | 
			
		||||
          const name = accounts.find(acc => acc.address === match)?.name;
 | 
			
		||||
          return (
 | 
			
		||||
            <Link
 | 
			
		||||
              key={match + idx}
 | 
			
		||||
              as="a"
 | 
			
		||||
              onClick={() => setDialogAccount(match)}
 | 
			
		||||
              title={match}
 | 
			
		||||
              highlighted
 | 
			
		||||
            >
 | 
			
		||||
              {name || match}
 | 
			
		||||
            </Link>
 | 
			
		||||
          );
 | 
			
		||||
        },
 | 
			
		||||
        input: str,
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      return <>{res}</>;
 | 
			
		||||
    },
 | 
			
		||||
    [accounts]
 | 
			
		||||
  );
 | 
			
		||||
  _message = _message.trim().replace(/\n /gi, "\n");
 | 
			
		||||
  const message = enrichAccounts(_message);
 | 
			
		||||
  const jsonData = enrichAccounts(_jsonData);
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <>
 | 
			
		||||
      <AccountDialog
 | 
			
		||||
        setActiveAccountAddress={setDialogAccount}
 | 
			
		||||
        activeAccountAddress={dialogAccount}
 | 
			
		||||
      />
 | 
			
		||||
      <LogText variant={type}>
 | 
			
		||||
        {timestamp && <Text muted monospace>{timestamp} </Text>}
 | 
			
		||||
        <Pre>{message} </Pre>
 | 
			
		||||
        {link && (
 | 
			
		||||
          <NextLink href={link} shallow passHref>
 | 
			
		||||
            <Link as="a">{linkText}</Link>
 | 
			
		||||
          </NextLink>
 | 
			
		||||
        )}
 | 
			
		||||
        {jsonData && (
 | 
			
		||||
          <Link onClick={() => setExpanded(!expanded)} as="a">
 | 
			
		||||
            {expanded ? "Collapse" : "Expand"}
 | 
			
		||||
          </Link>
 | 
			
		||||
        )}
 | 
			
		||||
        {expanded && jsonData && <Pre block>{jsonData}</Pre>}
 | 
			
		||||
      </LogText>
 | 
			
		||||
    </>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default LogBox;
 | 
			
		||||
 
 | 
			
		||||
@@ -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: {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										27
									
								
								components/Pre.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								components/Pre.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
import { styled } from "../stitches.config";
 | 
			
		||||
 | 
			
		||||
const Pre = styled("span", {
 | 
			
		||||
  m: 0,
 | 
			
		||||
  wordBreak: "break-all",
 | 
			
		||||
  fontFamily: '$monospace',
 | 
			
		||||
  whiteSpace: 'pre-wrap',
 | 
			
		||||
  variants: {
 | 
			
		||||
    fluid: {
 | 
			
		||||
      true: {
 | 
			
		||||
        width: "100%",
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
    line: {
 | 
			
		||||
      true: {
 | 
			
		||||
        whiteSpace: 'pre-line'
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    block: {
 | 
			
		||||
      true: {
 | 
			
		||||
        display: 'block'
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export default Pre;
 | 
			
		||||
@@ -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",
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -14,6 +14,11 @@ const Text = styled("span", {
 | 
			
		||||
      true: {
 | 
			
		||||
        color: '$mauve9'
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    monospace: {
 | 
			
		||||
      true: {
 | 
			
		||||
        fontFamily: '$monospace'
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,15 +1,17 @@
 | 
			
		||||
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 Pre } from "./Pre";
 | 
			
		||||
export { default as ButtonGroup } from "./ButtonGroup";
 | 
			
		||||
export { default as DeployFooter } from "./DeployFooter";
 | 
			
		||||
export * from "./Dialog";
 | 
			
		||||
export * from "./DropdownMenu";
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,10 @@ module.exports = {
 | 
			
		||||
    if (!isServer) {
 | 
			
		||||
      config.resolve.fallback.fs = false;
 | 
			
		||||
    }
 | 
			
		||||
    config.module.rules.push({
 | 
			
		||||
      test: /\.md$/,
 | 
			
		||||
      use: "raw-loader",
 | 
			
		||||
    });
 | 
			
		||||
    return config;
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -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,7 +46,9 @@
 | 
			
		||||
    "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",
 | 
			
		||||
    "regexify-string": "^1.0.17",
 | 
			
		||||
    "valtio": "^1.2.5",
 | 
			
		||||
    "vscode-languageserver": "^7.0.0",
 | 
			
		||||
    "vscode-uri": "^3.0.2",
 | 
			
		||||
@@ -54,10 +59,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"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								raw-loader.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								raw-loader.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
declare module "*.md" {
 | 
			
		||||
  const content: string;
 | 
			
		||||
  export default content;
 | 
			
		||||
};
 | 
			
		||||
@@ -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) => {
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
};
 | 
			
		||||
@@ -10,6 +10,7 @@ export interface IFile {
 | 
			
		||||
  content: string;
 | 
			
		||||
  compiledContent?: ArrayBuffer | null;
 | 
			
		||||
  compiledWatContent?: string | null;
 | 
			
		||||
  lastCompiled?: Date
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface FaucetAccountRes {
 | 
			
		||||
@@ -33,8 +34,11 @@ export interface IAccount {
 | 
			
		||||
export interface ILog {
 | 
			
		||||
  type: "error" | "warning" | "log" | "success";
 | 
			
		||||
  message: string;
 | 
			
		||||
  jsonData?: any,
 | 
			
		||||
  timestamp?: string;
 | 
			
		||||
  link?: string;
 | 
			
		||||
  linkText?: string;
 | 
			
		||||
  defaultCollapsed?: boolean
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IState {
 | 
			
		||||
@@ -51,7 +55,6 @@ export interface IState {
 | 
			
		||||
  logs: ILog[];
 | 
			
		||||
  deployLogs: ILog[];
 | 
			
		||||
  transactionLogs: ILog[];
 | 
			
		||||
  debugLogs: ILog[];
 | 
			
		||||
  editorCtx?: typeof monaco.editor;
 | 
			
		||||
  editorSettings: {
 | 
			
		||||
    tabSize: number;
 | 
			
		||||
@@ -77,7 +80,6 @@ let initialState: IState = {
 | 
			
		||||
  logs: [],
 | 
			
		||||
  deployLogs: [],
 | 
			
		||||
  transactionLogs: [],
 | 
			
		||||
  debugLogs: [],
 | 
			
		||||
  editorCtx: undefined,
 | 
			
		||||
  gistId: undefined,
 | 
			
		||||
  gistOwner: undefined,
 | 
			
		||||
 
 | 
			
		||||
@@ -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),
 | 
			
		||||
  },
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,7 @@
 | 
			
		||||
    "**/*.tsx"
 | 
			
		||||
  ],
 | 
			
		||||
  "exclude": [
 | 
			
		||||
    "node_modules"
 | 
			
		||||
    "node_modules",
 | 
			
		||||
    "*.md"
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										21
									
								
								utils/json.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								utils/json.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
export const extractJSON = (str?: string) => {
 | 
			
		||||
    if (!str) return
 | 
			
		||||
    let firstOpen = 0, firstClose = 0, candidate = '';
 | 
			
		||||
    firstOpen = str.indexOf('{', firstOpen + 1);
 | 
			
		||||
    do {
 | 
			
		||||
        firstClose = str.lastIndexOf('}');
 | 
			
		||||
        if (firstClose <= firstOpen) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        do {
 | 
			
		||||
            candidate = str.substring(firstOpen, firstClose + 1);
 | 
			
		||||
            try {
 | 
			
		||||
                let result = JSON.parse(candidate);
 | 
			
		||||
                return { result, start: firstOpen < 0 ? 0 : firstOpen, end: firstClose }
 | 
			
		||||
            }
 | 
			
		||||
            catch (e) { }
 | 
			
		||||
            firstClose = str.substring(0, firstClose).lastIndexOf('}');
 | 
			
		||||
        } while (firstClose > firstOpen);
 | 
			
		||||
        firstOpen = str.indexOf('{', firstOpen + 1);
 | 
			
		||||
    } while (firstOpen != -1);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										714
									
								
								utils/wat-highlight.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										714
									
								
								utils/wat-highlight.ts
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										87
									
								
								xrpl-hooks-docs/docs.ts
									
									
									
									
									
										Normal 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;
 | 
			
		||||
							
								
								
									
										6
									
								
								xrpl-hooks-docs/md/hooks-account-buf-len.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								xrpl-hooks-docs/md/hooks-account-buf-len.md
									
									
									
									
									
										Normal 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).
 | 
			
		||||
							
								
								
									
										7
									
								
								xrpl-hooks-docs/md/hooks-account-conv-buf-len.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								xrpl-hooks-docs/md/hooks-account-conv-buf-len.md
									
									
									
									
									
										Normal 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).
 | 
			
		||||
							
								
								
									
										10
									
								
								xrpl-hooks-docs/md/hooks-account-conv-pure.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								xrpl-hooks-docs/md/hooks-account-conv-pure.md
									
									
									
									
									
										Normal 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).
 | 
			
		||||
							
								
								
									
										9
									
								
								xrpl-hooks-docs/md/hooks-array-buf-len.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								xrpl-hooks-docs/md/hooks-array-buf-len.md
									
									
									
									
									
										Normal 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).
 | 
			
		||||
							
								
								
									
										5
									
								
								xrpl-hooks-docs/md/hooks-burden-prereq.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								xrpl-hooks-docs/md/hooks-burden-prereq.md
									
									
									
									
									
										Normal 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`.
 | 
			
		||||
							
								
								
									
										6
									
								
								xrpl-hooks-docs/md/hooks-detail-buf-len.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								xrpl-hooks-docs/md/hooks-detail-buf-len.md
									
									
									
									
									
										Normal 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).
 | 
			
		||||
							
								
								
									
										5
									
								
								xrpl-hooks-docs/md/hooks-detail-prereq.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								xrpl-hooks-docs/md/hooks-detail-prereq.md
									
									
									
									
									
										Normal 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`.
 | 
			
		||||
							
								
								
									
										6
									
								
								xrpl-hooks-docs/md/hooks-emit-buf-len.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								xrpl-hooks-docs/md/hooks-emit-buf-len.md
									
									
									
									
									
										Normal 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).
 | 
			
		||||
							
								
								
									
										5
									
								
								xrpl-hooks-docs/md/hooks-emit-prereq.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								xrpl-hooks-docs/md/hooks-emit-prereq.md
									
									
									
									
									
										Normal 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`.
 | 
			
		||||
							
								
								
									
										4
									
								
								xrpl-hooks-docs/md/hooks-entry-point-recursion.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								xrpl-hooks-docs/md/hooks-entry-point-recursion.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
# hooks-entry-point-recursion
 | 
			
		||||
 | 
			
		||||
Recursive calls are disallowed in the implementation of hook entry
 | 
			
		||||
points.
 | 
			
		||||
							
								
								
									
										4
									
								
								xrpl-hooks-docs/md/hooks-entry-points-neg.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								xrpl-hooks-docs/md/hooks-entry-points-neg.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
# hooks-entry-points-neg
 | 
			
		||||
 | 
			
		||||
Shows error on function definitions with unexpected (that is, neither
 | 
			
		||||
`hook` nor `cbak`) names.
 | 
			
		||||
							
								
								
									
										6
									
								
								xrpl-hooks-docs/md/hooks-entry-points.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								xrpl-hooks-docs/md/hooks-entry-points.md
									
									
									
									
									
										Normal 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.
 | 
			
		||||
							
								
								
									
										5
									
								
								xrpl-hooks-docs/md/hooks-fee-prereq.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								xrpl-hooks-docs/md/hooks-fee-prereq.md
									
									
									
									
									
										Normal 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`.
 | 
			
		||||
							
								
								
									
										9
									
								
								xrpl-hooks-docs/md/hooks-field-add-buf-len.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								xrpl-hooks-docs/md/hooks-field-add-buf-len.md
									
									
									
									
									
										Normal 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).
 | 
			
		||||
							
								
								
									
										6
									
								
								xrpl-hooks-docs/md/hooks-field-buf-len.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								xrpl-hooks-docs/md/hooks-field-buf-len.md
									
									
									
									
									
										Normal 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).
 | 
			
		||||
							
								
								
									
										9
									
								
								xrpl-hooks-docs/md/hooks-field-del-buf-len.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								xrpl-hooks-docs/md/hooks-field-del-buf-len.md
									
									
									
									
									
										Normal 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).
 | 
			
		||||
							
								
								
									
										15
									
								
								xrpl-hooks-docs/md/hooks-float-arith-pure.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								xrpl-hooks-docs/md/hooks-float-arith-pure.md
									
									
									
									
									
										Normal 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).
 | 
			
		||||
							
								
								
									
										9
									
								
								xrpl-hooks-docs/md/hooks-float-compare-pure.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								xrpl-hooks-docs/md/hooks-float-compare-pure.md
									
									
									
									
									
										Normal 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).
 | 
			
		||||
							
								
								
									
										10
									
								
								xrpl-hooks-docs/md/hooks-float-int-pure.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								xrpl-hooks-docs/md/hooks-float-int-pure.md
									
									
									
									
									
										Normal 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).
 | 
			
		||||
							
								
								
									
										13
									
								
								xrpl-hooks-docs/md/hooks-float-manip-pure.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								xrpl-hooks-docs/md/hooks-float-manip-pure.md
									
									
									
									
									
										Normal 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).
 | 
			
		||||
							
								
								
									
										5
									
								
								xrpl-hooks-docs/md/hooks-float-one-pure.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								xrpl-hooks-docs/md/hooks-float-one-pure.md
									
									
									
									
									
										Normal 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.
 | 
			
		||||
							
								
								
									
										12
									
								
								xrpl-hooks-docs/md/hooks-float-pure.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								xrpl-hooks-docs/md/hooks-float-pure.md
									
									
									
									
									
										Normal 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.
 | 
			
		||||
							
								
								
									
										5
									
								
								xrpl-hooks-docs/md/hooks-guard-called.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								xrpl-hooks-docs/md/hooks-guard-called.md
									
									
									
									
									
										Normal 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)
 | 
			
		||||
							
								
								
									
										12
									
								
								xrpl-hooks-docs/md/hooks-guard-in-for.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								xrpl-hooks-docs/md/hooks-guard-in-for.md
									
									
									
									
									
										Normal 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.
 | 
			
		||||
							
								
								
									
										11
									
								
								xrpl-hooks-docs/md/hooks-guard-in-while.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								xrpl-hooks-docs/md/hooks-guard-in-while.md
									
									
									
									
									
										Normal 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)
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										7
									
								
								xrpl-hooks-docs/md/hooks-hash-buf-len.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								xrpl-hooks-docs/md/hooks-hash-buf-len.md
									
									
									
									
									
										Normal 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).
 | 
			
		||||
							
								
								
									
										8
									
								
								xrpl-hooks-docs/md/hooks-keylet-buf-len.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								xrpl-hooks-docs/md/hooks-keylet-buf-len.md
									
									
									
									
									
										Normal 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).
 | 
			
		||||
							
								
								
									
										8
									
								
								xrpl-hooks-docs/md/hooks-raddr-conv-buf-len.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								xrpl-hooks-docs/md/hooks-raddr-conv-buf-len.md
									
									
									
									
									
										Normal 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).
 | 
			
		||||
							
								
								
									
										10
									
								
								xrpl-hooks-docs/md/hooks-raddr-conv-pure.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								xrpl-hooks-docs/md/hooks-raddr-conv-pure.md
									
									
									
									
									
										Normal 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).
 | 
			
		||||
							
								
								
									
										9
									
								
								xrpl-hooks-docs/md/hooks-reserve-limit.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								xrpl-hooks-docs/md/hooks-reserve-limit.md
									
									
									
									
									
										Normal 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).
 | 
			
		||||
							
								
								
									
										7
									
								
								xrpl-hooks-docs/md/hooks-slot-hash-buf-len.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								xrpl-hooks-docs/md/hooks-slot-hash-buf-len.md
									
									
									
									
									
										Normal 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).
 | 
			
		||||
							
								
								
									
										7
									
								
								xrpl-hooks-docs/md/hooks-slot-keylet-buf-len.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								xrpl-hooks-docs/md/hooks-slot-keylet-buf-len.md
									
									
									
									
									
										Normal 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).
 | 
			
		||||
							
								
								
									
										9
									
								
								xrpl-hooks-docs/md/hooks-slot-limit.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								xrpl-hooks-docs/md/hooks-slot-limit.md
									
									
									
									
									
										Normal 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).
 | 
			
		||||
							
								
								
									
										8
									
								
								xrpl-hooks-docs/md/hooks-slot-sub-limit.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								xrpl-hooks-docs/md/hooks-slot-sub-limit.md
									
									
									
									
									
										Normal 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).
 | 
			
		||||
							
								
								
									
										9
									
								
								xrpl-hooks-docs/md/hooks-slot-type-limit.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								xrpl-hooks-docs/md/hooks-slot-type-limit.md
									
									
									
									
									
										Normal 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).
 | 
			
		||||
							
								
								
									
										6
									
								
								xrpl-hooks-docs/md/hooks-state-buf-len.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								xrpl-hooks-docs/md/hooks-state-buf-len.md
									
									
									
									
									
										Normal 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).
 | 
			
		||||
							
								
								
									
										6
									
								
								xrpl-hooks-docs/md/hooks-transaction-hash-buf-len.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								xrpl-hooks-docs/md/hooks-transaction-hash-buf-len.md
									
									
									
									
									
										Normal 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).
 | 
			
		||||
							
								
								
									
										8
									
								
								xrpl-hooks-docs/md/hooks-transaction-slot-limit.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								xrpl-hooks-docs/md/hooks-transaction-slot-limit.md
									
									
									
									
									
										Normal 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).
 | 
			
		||||
							
								
								
									
										6
									
								
								xrpl-hooks-docs/md/hooks-validate-buf-len.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								xrpl-hooks-docs/md/hooks-validate-buf-len.md
									
									
									
									
									
										Normal 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).
 | 
			
		||||
							
								
								
									
										8
									
								
								xrpl-hooks-docs/md/hooks-verify-buf-len.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								xrpl-hooks-docs/md/hooks-verify-buf-len.md
									
									
									
									
									
										Normal 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).
 | 
			
		||||
							
								
								
									
										112
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										112
									
								
								yarn.lock
									
									
									
									
									
								
							@@ -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"
 | 
			
		||||
@@ -3956,6 +4045,11 @@ regenerator-runtime@^0.13.4:
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52"
 | 
			
		||||
  integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==
 | 
			
		||||
 | 
			
		||||
regexify-string@^1.0.17:
 | 
			
		||||
  version "1.0.17"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/regexify-string/-/regexify-string-1.0.17.tgz#b9e571b51c8ec566eb82b7121744dae0d8e829de"
 | 
			
		||||
  integrity sha512-mmD0AUNaY/piGW2AyACWdQOjIAwNuWz+KIvxfBZPDdCBAexiROeQxdxTaYAWcIxwtUAOwojdTta6CMMil84jXw==
 | 
			
		||||
 | 
			
		||||
regexp.prototype.flags@^1.3.1:
 | 
			
		||||
  version "1.3.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26"
 | 
			
		||||
@@ -3969,6 +4063,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 +4261,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"
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user