diff --git a/createService.ts b/createService.ts index e94acd4..9b7d8ce 100644 --- a/createService.ts +++ b/createService.ts @@ -51,7 +51,7 @@ import {parse, stringify} from 'yaml'; } else if (confirm('Permissions not specified, would you like to add specific permissions?')) { let permsPrompt: string | null = ''; while (!permsPrompt) { - permsPrompt = prompt('Please enter the permission short code or names of permissions you would like'); + permsPrompt = prompt('Please enter the permission short code or names of permissions you would like:'); if (!permsPrompt) continue let permNames; if (permsPrompt?.match(' ')) { diff --git a/deno.lock b/deno.lock index 05654d2..432047f 100644 --- a/deno.lock +++ b/deno.lock @@ -580,6 +580,7 @@ "npm": { "specifiers": { "bcryptjs": "bcryptjs@2.4.3", + "create-vite-extra": "create-vite-extra@1.1.0", "mongoose": "mongoose@7.0.4", "play-sound": "play-sound@1.1.5", "yaml": "yaml@2.2.2" @@ -608,6 +609,14 @@ "integrity": "sha512-HevkSpDbpUfsrHWmWiAsNavANKYIErV2ePXllp1bwq5CDreAaFVj6RVlZpJnxK4WWDCJ/5jMUpaY6G526q3Hjg==", "dependencies": {} }, + "create-vite-extra@1.1.0": { + "integrity": "sha512-Gi5ZLFhgULy6DU9QpZZ6ko4STOrg5dT4/2sCqszjoMZTSyQl1B95eiZaeByBGt+HCSffXAFvhSzkt5iqlqW6eA==", + "dependencies": { + "kolorist": "kolorist@1.8.0", + "minimist": "minimist@1.2.8", + "prompts": "prompts@2.4.2" + } + }, "debug@4.3.4": { "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { @@ -626,10 +635,22 @@ "integrity": "sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA==", "dependencies": {} }, + "kleur@3.0.3": { + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dependencies": {} + }, + "kolorist@1.8.0": { + "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", + "dependencies": {} + }, "memory-pager@1.5.0": { "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", "dependencies": {} }, + "minimist@1.2.8": { + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dependencies": {} + }, "mongodb-connection-string-url@2.6.0": { "integrity": "sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==", "dependencies": { @@ -682,6 +703,13 @@ "find-exec": "find-exec@1.0.2" } }, + "prompts@2.4.2": { + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dependencies": { + "kleur": "kleur@3.0.3", + "sisteransi": "sisteransi@1.0.5" + } + }, "punycode@2.3.0": { "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dependencies": {} @@ -696,6 +724,10 @@ "integrity": "sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ==", "dependencies": {} }, + "sisteransi@1.0.5": { + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dependencies": {} + }, "smart-buffer@4.2.0": { "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", "dependencies": {} diff --git a/docker-compose.yml b/docker-compose.yml index 5906579..13cdd01 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -22,3 +22,7 @@ services: build: context: ./ dockerfile: ./game-systems-service/Dockerfile + warstone-web: + build: + context: ./ + dockerfile: ./warstone-web-service/Dockerfile diff --git a/project-warstone/.eslintrc.cjs b/project-warstone/.eslintrc.cjs index 4020bcb..b8b94b2 100644 --- a/project-warstone/.eslintrc.cjs +++ b/project-warstone/.eslintrc.cjs @@ -10,5 +10,12 @@ module.exports = { plugins: ['react-refresh'], rules: { 'react-refresh/only-export-components': 'warn', + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": [ + "warn", + { + "argsIgnorePattern": "^_" + } + ], }, } diff --git a/project-warstone/package.json b/project-warstone/package.json index d6a311c..c78782c 100644 --- a/project-warstone/package.json +++ b/project-warstone/package.json @@ -7,7 +7,8 @@ "dev": "vite", "build": "tsc && vite build", "lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0", - "preview": "vite preview" + "preview": "vite preview", + "build-dev": "vite build" }, "dependencies": { "@types/react-router-dom": "^5.3.3", @@ -17,7 +18,8 @@ "react-dom": "^18.2.0", "react-router-dom": "^6.12.0", "recoil": "^0.7.7", - "tailwindcss": "^3.3.2" + "tailwindcss": "^3.3.2", + "vite-plugin-svgr": "^3.2.0" }, "devDependencies": { "@types/react": "^18.0.37", diff --git a/project-warstone/src/App.tsx b/project-warstone/src/App.tsx index 26fabc2..91a0005 100644 --- a/project-warstone/src/App.tsx +++ b/project-warstone/src/App.tsx @@ -1,11 +1,9 @@ import { RecoilRoot } from 'recoil' -import { TextMapper } from './components/Importer/text-mapper' import { SchemaBuilder } from './components/SchemaBuilder' function App() { return ( - {/* */} ) diff --git a/project-warstone/src/assets/icons/Help Icon copy.min.svg b/project-warstone/src/assets/icons/Help Icon copy.min.svg new file mode 100644 index 0000000..19f9af0 --- /dev/null +++ b/project-warstone/src/assets/icons/Help Icon copy.min.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/project-warstone/src/assets/icons/Help Icon copy.svg b/project-warstone/src/assets/icons/Help Icon copy.svg new file mode 100644 index 0000000..521d056 --- /dev/null +++ b/project-warstone/src/assets/icons/Help Icon copy.svg @@ -0,0 +1,70 @@ + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/project-warstone/src/assets/icons/Help Icon.svg b/project-warstone/src/assets/icons/Help Icon.svg new file mode 100644 index 0000000..521d056 --- /dev/null +++ b/project-warstone/src/assets/icons/Help Icon.svg @@ -0,0 +1,70 @@ + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/project-warstone/src/components/Icon/index.tsx b/project-warstone/src/components/Icon/index.tsx new file mode 100644 index 0000000..71867e4 --- /dev/null +++ b/project-warstone/src/components/Icon/index.tsx @@ -0,0 +1,19 @@ +import { FC } from 'react' +import { ReactComponent as help } from '../../assets/icons/Help Icon.svg'; + +const library = { + help +} + +interface IProps { + className: string; + icon: keyof typeof library; +} + +export const Icon: FC = ({ className, icon }) => { + const ICON = library[icon]; + + return ( + + ) +} \ No newline at end of file diff --git a/project-warstone/src/components/Poppables/help.tsx b/project-warstone/src/components/Poppables/help.tsx new file mode 100644 index 0000000..b74f2a9 --- /dev/null +++ b/project-warstone/src/components/Poppables/help.tsx @@ -0,0 +1,16 @@ +import { FC, PropsWithChildren } from 'react' +import { Poppable } from '../../lib/poppables/components/poppable' +import { Icon } from '../Icon' + +export const HelpPopper: FC = ({children}) => { + + return ( + + + + ) +} \ No newline at end of file diff --git a/project-warstone/src/components/SchemaBuilder/field-editor.tsx b/project-warstone/src/components/SchemaBuilder/field-editor.tsx index 0c861a4..ad3e159 100644 --- a/project-warstone/src/components/SchemaBuilder/field-editor.tsx +++ b/project-warstone/src/components/SchemaBuilder/field-editor.tsx @@ -4,6 +4,7 @@ import { useObjectStateWrapper } from '../../hooks/useObjectState'; import { FieldTypeInput } from './field-type-input'; import { InputBinder } from '../../types/inputBinder'; import { ValueField } from './value-field'; +import { HelpPopper } from '../Poppables/help'; interface IProps { update: (arg: FieldType) => void; @@ -21,33 +22,31 @@ export const FieldEditor: FC = ({ update, field, fieldName }) => { }, [field]) return ( -
  • +
  • {fieldName}

    - - {shouldShowValueField() && ( - // <> - // {field.type === FieldTypes.dice && ( - // - // )} - // {field.type === FieldTypes.type && ( - // - - // )} - // - - )} - +
    + + {shouldShowValueField() && ( + + )} + + + +

    Constant values can't be overwritten in publications. When a dice field is set to a constant value, it instead rolls a dice of that value whenever this field is displayed (unless exported). This could be useful for a randomly generated scenario or for cards being drawn as the dice value will automatically be determined by the dice roll.

    +
    +
    + +
  • ) } diff --git a/project-warstone/src/components/SchemaBuilder/index.tsx b/project-warstone/src/components/SchemaBuilder/index.tsx index 1805ae8..43ce854 100644 --- a/project-warstone/src/components/SchemaBuilder/index.tsx +++ b/project-warstone/src/components/SchemaBuilder/index.tsx @@ -1,4 +1,4 @@ -import { FC, useCallback, useState } from 'react' +import { FC, useCallback, useEffect, useState } from 'react' import AnimatedPageContainer from '../AnimatedPageContainer'; import { TypeEditor } from './type-editor'; import { useObjectState, useObjectStateWrapper } from '../../hooks/useObjectState'; @@ -6,25 +6,58 @@ import { Schema, TypeType } from '../../types/schema'; import { useInput } from '../../hooks/useInput'; import { useRecoilState } from 'recoil'; import { SchemaEditAtom } from '../../recoil/atoms/schema'; +import { GameSystemsService } from '../../services/game-systems'; +import { SchemaViewer } from './schema-viewer'; export const SchemaBuilder: FC = () => { const [schema, setSchema] = useRecoilState(SchemaEditAtom); - const {update: updateSchema} = useObjectStateWrapper(schema, setSchema); + const { update: updateSchema } = useObjectStateWrapper(schema, setSchema); - const {value: typeName, bind: bindTypeName, reset: resetTypeName} = useInput(''); + const { value: typeName, bind: bindTypeName, reset: resetTypeName } = useInput(''); - const [pageNumber, setPageNumber] = useState(1); + const [pageNumber, setPageNumber] = useState(0); + + const [lastSaved, setLastSaved] = useState(schema); + + const fetchSchema = useCallback(async () => { + const result = await GameSystemsService.getSchema('') + if (result.status !== 200) return; + const fetchedSchema = await result.json(); + // if (fetchedSchema.name === schema.name) return; + setSchema(fetchedSchema); + setLastSaved(fetchedSchema); + }, [setSchema]) + + useEffect(() => { + fetchSchema(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []) + + const [selectedType, setSelectedType] = useState(''); const saveType = useCallback((name: string, type: TypeType) => { updateSchema(e => ({ types: { ...e.types, + [name]: type } })); resetTypeName(); + setPageNumber(0); + setSelectedType(''); }, [resetTypeName, updateSchema]); - + + const saveSchema = useCallback(() => { + GameSystemsService.saveSchema(schema); + setLastSaved(schema); + }, [schema]) + + const selectTypeForEdit = useCallback((typeKey: string) => { + setSelectedType(typeKey); + setPageNumber(1); + }, []) + return (
    @@ -34,11 +67,26 @@ export const SchemaBuilder: FC = () => {
    - +
    -
    - {JSON.stringify(schema, null, 2)} +
    + +
    + + +
    ) diff --git a/project-warstone/src/components/SchemaBuilder/schema-viewer.tsx b/project-warstone/src/components/SchemaBuilder/schema-viewer.tsx new file mode 100644 index 0000000..dbfda13 --- /dev/null +++ b/project-warstone/src/components/SchemaBuilder/schema-viewer.tsx @@ -0,0 +1,53 @@ +import { FC, useCallback } from 'react' +import { FieldType, FieldTypes, Schema, TypeType, fieldTypesWithValues } from '../../types/schema' + +interface IProps { + schema: Schema; + onTypeClick?: (arg: string, arg1: TypeType) => void; +} + +export const SchemaViewer: FC = ({ schema, onTypeClick }) => { + + const createValueLable = useCallback((field: FieldType) => { + if (field.isConstant) { + if (field.type === FieldTypes.dice) return 'Auto-rolled' + return 'Constant value:' + } + switch (field.type) { + case FieldTypes.type: return 'Type' + case FieldTypes.dice: return 'Dice' + default: return ''; + } + }, []) + + return ( + <> + {/*
    {JSON.stringify(schema, null, 2)}
    */} +
    +

    {schema.name}

    +
      + {Object.entries(schema.types).map(([typeKey, type]) => ( +
    • onTypeClick && onTypeClick(typeKey, type)} + data-clickable={!!onTypeClick} + className="odd:bg-black/50 p-2 data-[clickable=true]:cursor-pointer" + > +

      {typeKey}

      +
      + {Object.entries(type).map(([fieldKey, field]) => ( +
      +

      {fieldKey}

      +

      {field.type}

      +

      Maximum entries: {field.limit === 0 ? 'unlimited ' : field.limit}

      + {(field.isConstant || fieldTypesWithValues.includes(field.type)) &&

      {createValueLable(field)} {field.value}

      } +
      + ))} +
      +
    • + ))} +
    +
    + + ) +} \ No newline at end of file diff --git a/project-warstone/src/components/SchemaBuilder/type-editor.tsx b/project-warstone/src/components/SchemaBuilder/type-editor.tsx index a138c69..bf810fc 100644 --- a/project-warstone/src/components/SchemaBuilder/type-editor.tsx +++ b/project-warstone/src/components/SchemaBuilder/type-editor.tsx @@ -1,4 +1,4 @@ -import { FC, useCallback } from 'react' +import { FC, useCallback, useEffect } from 'react' import { FCC } from '../../types' import { FieldType, FieldTypes, TypeType } from '../../types/schema' import { useObjectState } from '../../hooks/useObjectState'; @@ -8,12 +8,13 @@ import { FieldEditor } from './field-editor'; interface IProps { name: string; saveType: (arg0: string, arg1: TypeType) => void; + type?: TypeType } const constantProperties = ['metadata']; -export const TypeEditor: FCC = ({ saveType, name }) => { - const { update: updateType, reset: resetType, state: type } = useObjectState({}); +export const TypeEditor: FCC = ({ saveType, name, type: passedType }) => { + const { update: updateType, reset: resetType, state: type, setState: setType } = useObjectState({}); const { value: propertyName, setValue: setPropertyName, bind: bindPropertyName, reset: resetPropertyName } = useInput(''); @@ -31,22 +32,29 @@ export const TypeEditor: FCC = ({ saveType, name }) => { limit: 1, } }) - }, [propertyName, updateType]) + }, [propertyName, updateType]); const updateField = useCallback((k: keyof typeof type) => (field: FieldType) => { updateType({ [k]: field }) - }, [updateType]) + }, [updateType]); + + useEffect(() => { + passedType && setType(passedType); + }, [passedType, setType]); return (
    -

    Creating type "{name}"

    +

    {passedType ? 'Editing' : 'Creating'} type "{name}"

    -
      +
        {Object.entries(type).filter(([k]) => !constantProperties.includes(k)).map(([key, value]) => ( ))}
      +
      + +
    ) } \ No newline at end of file diff --git a/project-warstone/src/components/SchemaBuilder/value-field.tsx b/project-warstone/src/components/SchemaBuilder/value-field.tsx index 9ba11f5..9f14a26 100644 --- a/project-warstone/src/components/SchemaBuilder/value-field.tsx +++ b/project-warstone/src/components/SchemaBuilder/value-field.tsx @@ -1,37 +1,68 @@ -import { FC } from 'react'; +import { ChangeEvent, EventHandler, FC, useCallback, useEffect, useRef } from 'react'; import { FieldTypes } from '../../types/schema'; import { InputBinder } from '../../types/inputBinder'; import { FieldTypeInput } from './field-type-input'; +import { useInput } from '../../hooks/useInput'; interface IValueProps { type: FieldTypes; bind: InputBinder; } -const diceSides = [3, 4, 6, 8, 10, 12, 20, 100]; +const DICE_SIDES = [3, 4, 6, 8, 10, 12, 20, 100]; + +export const ValueField: FC = ({ type, bind }) => { + const { value: diceCount, bind: bindDiceCount } = useInput(1); + const { value: diceSides, bind: bindDiceSides } = useInput(''); + + const diceInputRef = useRef(null); -export const ValueField: FC = ({type, bind}) => { switch (type) { - case FieldTypes.dice: + case FieldTypes.dice: { + const onChange = (handler: (arg: ChangeEvent) => void) => (e: ChangeEvent) => { + handler(e) + setTimeout(() => { + if (!diceInputRef.current) return; + e.target = diceInputRef.current; + bind.onChange(e); + }, 0) + } return ( - + <> + + + + ); + } case FieldTypes.type: return ( ) case FieldTypes.number: return ( - + + ) + case FieldTypes.text: + return ( + ) default: - return <>; + return <>; } } diff --git a/project-warstone/src/hooks/useDebounce.ts b/project-warstone/src/hooks/useDebounce.ts new file mode 100644 index 0000000..cd4646a --- /dev/null +++ b/project-warstone/src/hooks/useDebounce.ts @@ -0,0 +1,12 @@ +import { useEffect, useState } from 'react'; + +export const useDebounce = (value: any, delay: number) => { + const [debouncedValue, setDebouncedValue] = useState(value); + + useEffect(() => { + const handler = setTimeout(() => setDebouncedValue(value), delay); + return () => clearTimeout(handler); + }, [value, delay]); + + return debouncedValue; +}; \ No newline at end of file diff --git a/project-warstone/src/index.css b/project-warstone/src/index.css index 5c4fdac..02a28a2 100644 --- a/project-warstone/src/index.css +++ b/project-warstone/src/index.css @@ -1,3 +1,5 @@ +@import url('https://fonts.googleapis.com/css2?family=Chakra+Petch:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,500;1,600;1,700&family=Open+Sans:ital,wght@0,300;0,400;0,500;0,700;0,800;1,300;1,400;1,500;1,600;1,700;1,800&family=Orbitron:wght@400;500;600;700;800;900&display=swap'); + @tailwind base; @tailwind components; @tailwind utilities; @@ -6,8 +8,14 @@ body { @apply bg-bastille text-white } - input, select { - @apply p-1 rounded-lg text-cinder-500 + + input, + select { + @apply p-1 rounded-lg text-cinder-500 interactive + } + + * { + font-family: 'Open Sans', sans-serif; } } @@ -15,25 +23,47 @@ .panel { @apply bg-cinder shadow-xl p-8 rounded-xl } + .header { @apply text-2xl font-bold } + .subheader { @apply text-xl font-bold } + button { @apply interactive bg-olive-drab p-1 } -} -@layer utilities { .interactive { @apply border-2 rounded-lg border-falcon cursor-pointer } + .interactive svg { @apply fill-falcon } + .interactive:disabled { @apply border-falcon-300 brightness-50 cursor-default } + + .fade-in { + animation: fade 300ms forwards ease-in; + animation-delay: 300ms; + } + .fade-out { + animation: fade 300ms forwards ease-in reverse; + } +} + +@layer utilities {} + +@keyframes fade { + from { + opacity: 0; + } + to { + opacity: 1; + } } diff --git a/project-warstone/src/lib/poppables/components/poppable-content.tsx b/project-warstone/src/lib/poppables/components/poppable-content.tsx new file mode 100644 index 0000000..744545f --- /dev/null +++ b/project-warstone/src/lib/poppables/components/poppable-content.tsx @@ -0,0 +1,117 @@ +import { Dispatch, SetStateAction, useCallback, useEffect, useState } from 'react'; +import { FCC } from '../../../types'; +import { bulkRound } from '../../utils/bulkRound'; +import { clamp } from '../../utils/clamp'; +import { Portal } from '../../portal/components'; + +type edge = 'top' | 'bottom' | 'left' | 'right'; +type alignment = edge | 'centered'; + +interface IProps { + preferredEdge: edge; + preferredAlign: alignment; + relativeElement: HTMLElement; + spacing?: number; + isClosing: boolean; + isClosed: boolean; + setHover: Dispatch>; +} + +type position = { top: number, left: number, width?: number }; + +export const PoppableContent: FCC = ({ preferredAlign, preferredEdge, children, relativeElement, spacing = 10, setHover, isClosing, isClosed }) => { + const [popRef, setPopRef] = useState(); + const updateRef = useCallback((node: HTMLDivElement) => { + if (!node) return; + setPopRef(node); + }, []) + + const getAlignment = useCallback((relX: number, relY: number, relWidth: number, relHeight: number, popWidth: number, popHeight: number, edge: edge, align: alignment): position => { + const pos = { + top: relY, + left: relX, + } + + switch (align) { + case 'centered': + pos.top = relY + (relHeight / 2) - (popHeight / 2); + pos.left = relX + (relWidth / 2) - (popWidth / 2); + break; + case 'top': + pos.top = relY; + break; + case 'bottom': + pos.top = relY + relHeight - popHeight; + break; + case 'left': + pos.left = relX; + break; + case 'right': + pos.left = relX + relWidth - popWidth; + break; + } + + return pos; + }, []) + + const getPosition = useCallback((popWidth: number, popHeight: number, edge: edge, align: alignment) => { + const rel = relativeElement.getBoundingClientRect(); + const [relX, relY, relWidth, relHeight] = bulkRound(rel.x, rel.y, rel.width, rel.height); + + const pos: position = { top: 100, left: 100 }; + const alignment = getAlignment(relX, relY, relWidth, relHeight, popWidth, popHeight, edge, align); + + switch (edge) { + case 'top': + pos.top = relY - popHeight - spacing + document.documentElement.scrollTop; + pos.left = alignment.left; + break; + case 'bottom': + pos.top = relY + relHeight + spacing + document.documentElement.scrollTop; + pos.left = alignment.left; + break; + case 'left': + pos.left = relX - popWidth - spacing; + pos.top = alignment.top + document.documentElement.scrollTop; + break; + case 'right': + pos.left = relX + relWidth + spacing; + pos.top = alignment.top + document.documentElement.scrollTop; + break; + } + + return pos; + }, [getAlignment, relativeElement, spacing]) + + const getClampedPosition = useCallback(() => { + if (!popRef) return { opacity: 0 } + + const pop = popRef.getBoundingClientRect(); + const [popWidth, popHeight] = bulkRound(pop.width, pop.height); + + const pos = getPosition(popWidth, popHeight, preferredEdge, preferredAlign); + const { innerHeight, innerWidth } = window; + + pos.top = ['left', 'right'].includes(preferredEdge) ? clamp(pos.top, spacing, innerHeight - popHeight - spacing) : pos.top; + pos.left = ['top', 'bottom'].includes(preferredEdge) ? clamp(pos.left, spacing, innerWidth - popWidth - spacing): pos.left; + + return pos; + }, [popRef, getPosition, preferredEdge, preferredAlign, spacing]) + + return ( + +
    setHover(true)} + onMouseLeave={() => setHover(false)} + // className="absolute w-[400px] border" + className="bg-cinder border-2 border-falcon p-2 rounded-lg absolute transition-opacity data-[visible=true]:z-10 data-[visible=true]:opacity-100 data-[visible=false]:opacity-0 -z-10 max-w-[400px]" + > + {children} +
    +
    + ) +} \ No newline at end of file diff --git a/project-warstone/src/lib/poppables/components/poppable.tsx b/project-warstone/src/lib/poppables/components/poppable.tsx new file mode 100644 index 0000000..1d58759 --- /dev/null +++ b/project-warstone/src/lib/poppables/components/poppable.tsx @@ -0,0 +1,47 @@ +import { FC, ReactNode, useCallback, useEffect, useState } from 'react' +import { PoppableContent } from './poppable-content'; +import { FCC } from '../../../types'; +import { useDebounce } from '../../../hooks/useDebounce'; + +interface IProps { + content: ReactNode; + className?: string; + preferredEdge: 'top' | 'bottom' | 'left' | 'right'; + preferredAlign: 'centered' | 'top' | 'bottom' | 'left' | 'right'; + spacing?: number; +} + +export const Poppable: FCC = ({ className, content, children, preferredEdge, preferredAlign, spacing }) => { + const [isHovered, setIsHovered] = useState(false); + const closing = useDebounce(!isHovered, 1000); + const closed = useDebounce(closing, 300); + + const [ref, setRef] = useState(); + + const updateRef = useCallback((node: HTMLElement) => { + if (!node) return; + setRef(node) + }, []) + + return ( + <> + setIsHovered(true)} + onMouseLeave={() => setIsHovered(false)} + > + {children} + + {!!ref && {content}} + + ) +} \ No newline at end of file diff --git a/project-warstone/src/lib/portal/components/index.ts b/project-warstone/src/lib/portal/components/index.ts new file mode 100644 index 0000000..9d5ebed --- /dev/null +++ b/project-warstone/src/lib/portal/components/index.ts @@ -0,0 +1,26 @@ +import { useEffect, useState } from 'react'; +import { FCC } from '../../../types'; +import { createPortal } from 'react-dom'; + +interface IProps { + className?: string; + el?: string; +} + +export const Portal: FCC = ({ children, className = 'root-portal', el = 'div' }) => { + const [container] = useState(() => { + // This will be executed only on the initial render + // https://reactjs.org/docs/hooks-reference.html#lazy-initial-state + return document.createElement(el); + }); + + useEffect(() => { + container.classList.add(className); + document.body.appendChild(container); + return () => { + document.body.removeChild(container); + } + }, [className, container]); + + return createPortal(children, container); +} \ No newline at end of file diff --git a/project-warstone/src/lib/utils/bulkRound.ts b/project-warstone/src/lib/utils/bulkRound.ts new file mode 100644 index 0000000..f984c78 --- /dev/null +++ b/project-warstone/src/lib/utils/bulkRound.ts @@ -0,0 +1 @@ +export const bulkRound = (...args: number[]): number[] => args.map(n => Math.round(n)); \ No newline at end of file diff --git a/project-warstone/src/lib/utils/clamp.ts b/project-warstone/src/lib/utils/clamp.ts new file mode 100644 index 0000000..a03d7d1 --- /dev/null +++ b/project-warstone/src/lib/utils/clamp.ts @@ -0,0 +1,2 @@ +export const clamp = (value: number, min: number, max: number) => + Math.max(Math.min(value, max), min) \ No newline at end of file diff --git a/project-warstone/src/recoil/atoms/schema.ts b/project-warstone/src/recoil/atoms/schema.ts index 0599fec..9590034 100644 --- a/project-warstone/src/recoil/atoms/schema.ts +++ b/project-warstone/src/recoil/atoms/schema.ts @@ -1,5 +1,5 @@ import { atom } from 'recoil'; -import { Schema, TypeType } from '../../types/schema'; +import { Schema } from '../../types/schema'; export const SchemaEditAtom = atom({ key: 'schema-edit', diff --git a/project-warstone/src/services/game-systems.ts b/project-warstone/src/services/game-systems.ts index e8aeaa2..9f0d1e4 100644 --- a/project-warstone/src/services/game-systems.ts +++ b/project-warstone/src/services/game-systems.ts @@ -8,7 +8,7 @@ export const GameSystemsService = { return { status: 200 } }, // todo - connect to service to fetch schema for game - getSchema: async (id: string) => { + getSchema: async (id: string): Promise<{status: 200 | 404, json: () => Promise}> => { const schema = localStorage.getItem('schema'); if (schema) @@ -18,7 +18,8 @@ export const GameSystemsService = { } return { - status: 404 + status: 404, + json: async () => ({name:'', types: {}}) } } } \ No newline at end of file diff --git a/project-warstone/src/svg.d.ts b/project-warstone/src/svg.d.ts new file mode 100644 index 0000000..cffd163 --- /dev/null +++ b/project-warstone/src/svg.d.ts @@ -0,0 +1,7 @@ +declare module "*.svg" { + import * as React from "react"; + + export const ReactComponent: React.FC>; + const src: string; + export default src; +} \ No newline at end of file diff --git a/project-warstone/src/types/schema.ts b/project-warstone/src/types/schema.ts index dbdf973..0fcf26a 100644 --- a/project-warstone/src/types/schema.ts +++ b/project-warstone/src/types/schema.ts @@ -19,10 +19,11 @@ export type Schema = { export enum FieldTypes { number = 'number', text = 'text', + 'long text' = 'long text', checkbox = 'checkbox', type = '@type', dice = 'dice' } -export const fieldTypeOptions: (keyof typeof FieldTypes)[] = ['number', 'text', 'checkbox', 'type', 'dice'] +export const fieldTypeOptions: (keyof typeof FieldTypes)[] = ['number', 'text', 'long text', 'checkbox', 'type', 'dice'] export const fieldTypesWithValues = [FieldTypes.dice, FieldTypes.type]; diff --git a/project-warstone/tailwind.config.js b/project-warstone/tailwind.config.js index 009d817..74211b9 100644 --- a/project-warstone/tailwind.config.js +++ b/project-warstone/tailwind.config.js @@ -1,3 +1,7 @@ +import plugin from 'tailwindcss/plugin'; +import flattenColorPalette from 'tailwindcss/lib/util/flattenColorPalette' +import {parseColor} from 'tailwindcss/lib/util/color' + /** @type {import('tailwindcss').Config} */ export default { content: [ @@ -49,6 +53,26 @@ export default { } }, }, - plugins: [], + plugins: [ + plugin(({matchUtilities, theme}) => { + matchUtilities({ + 'svg': (value) => { + const ignored = ['inherit', 'currentColor',] + if (ignored.includes(value)) { + return { + fill: value, + stroke: value, + } + } + const {color, alpha} = parseColor(value) + + return { + fill: `rgba(${color[0]} ${color[1]} ${color[2]} / ${alpha || 1})`, + stroke: `rgba(${color[0]} ${color[1]} ${color[2]} / ${alpha || 1})` + } + } + }, {values: flattenColorPalette(theme('colors')), type: 'color'}) + }) + ], } diff --git a/project-warstone/tsconfig.json b/project-warstone/tsconfig.json index a7fc6fb..6bec4ef 100644 --- a/project-warstone/tsconfig.json +++ b/project-warstone/tsconfig.json @@ -18,8 +18,9 @@ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true + "noFallthroughCasesInSwitch": true, + }, - "include": ["src"], + "include": ["src", "src/svg.d.ts"], "references": [{ "path": "./tsconfig.node.json" }] } diff --git a/project-warstone/vite.config.ts b/project-warstone/vite.config.ts index 1c782e9..33acf40 100644 --- a/project-warstone/vite.config.ts +++ b/project-warstone/vite.config.ts @@ -1,9 +1,10 @@ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react-swc' +import svgr from 'vite-plugin-svgr' // https://vitejs.dev/config/ export default defineConfig({ - plugins: [react()], + plugins: [react(), svgr()], appType: 'spa', preview: { port: 6969 diff --git a/project-warstone/yarn.lock b/project-warstone/yarn.lock index f4bd998..e174b6c 100644 --- a/project-warstone/yarn.lock +++ b/project-warstone/yarn.lock @@ -7,6 +7,195 @@ resolved "https://registry.yarnpkg.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz#7bf68b20c0a350f936915fcae06f58e32007ce30" integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw== +"@ampproject/remapping@^2.2.0": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" + integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.5.tgz#234d98e1551960604f1246e6475891a570ad5658" + integrity sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ== + dependencies: + "@babel/highlight" "^7.22.5" + +"@babel/compat-data@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.5.tgz#b1f6c86a02d85d2dd3368a2b67c09add8cd0c255" + integrity sha512-4Jc/YuIaYqKnDDz892kPIledykKg12Aw1PYX5i/TY28anJtacvM1Rrr8wbieB9GfEJwlzqT0hUEao0CxEebiDA== + +"@babel/core@^7.21.3": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.5.tgz#d67d9747ecf26ee7ecd3ebae1ee22225fe902a89" + integrity sha512-SBuTAjg91A3eKOvD+bPEz3LlhHZRNu1nFOVts9lzDJTXshHTjII0BAtDS3Y2DAkdZdDKWVZGVwkDfc4Clxn1dg== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.22.5" + "@babel/generator" "^7.22.5" + "@babel/helper-compilation-targets" "^7.22.5" + "@babel/helper-module-transforms" "^7.22.5" + "@babel/helpers" "^7.22.5" + "@babel/parser" "^7.22.5" + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.5" + "@babel/types" "^7.22.5" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.2" + semver "^6.3.0" + +"@babel/generator@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.5.tgz#1e7bf768688acfb05cf30b2369ef855e82d984f7" + integrity sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA== + dependencies: + "@babel/types" "^7.22.5" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" + +"@babel/helper-compilation-targets@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.5.tgz#fc7319fc54c5e2fa14b2909cf3c5fd3046813e02" + integrity sha512-Ji+ywpHeuqxB8WDxraCiqR0xfhYjiDE/e6k7FuIaANnoOFxAHskHChz4vA1mJC9Lbm01s1PVAGhQY4FUKSkGZw== + dependencies: + "@babel/compat-data" "^7.22.5" + "@babel/helper-validator-option" "^7.22.5" + browserslist "^4.21.3" + lru-cache "^5.1.1" + semver "^6.3.0" + +"@babel/helper-environment-visitor@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz#f06dd41b7c1f44e1f8da6c4055b41ab3a09a7e98" + integrity sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q== + +"@babel/helper-function-name@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz#ede300828905bb15e582c037162f99d5183af1be" + integrity sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ== + dependencies: + "@babel/template" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/helper-hoist-variables@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" + integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-module-imports@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz#1a8f4c9f4027d23f520bd76b364d44434a72660c" + integrity sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-module-transforms@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.5.tgz#0f65daa0716961b6e96b164034e737f60a80d2ef" + integrity sha512-+hGKDt/Ze8GFExiVHno/2dvG5IdstpzCq0y4Qc9OJ25D4q3pKfiIP/4Vp3/JvhDkLKsDK2api3q3fpIgiIF5bw== + dependencies: + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.5" + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/helper-simple-access@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" + integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-split-export-declaration@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.5.tgz#88cf11050edb95ed08d596f7a044462189127a08" + integrity sha512-thqK5QFghPKWLhAV321lxF95yCg2K3Ob5yw+M3VHWfdia0IkPXUtoLH8x/6Fh486QUvzhb8YOWHChTVen2/PoQ== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-string-parser@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" + integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== + +"@babel/helper-validator-identifier@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193" + integrity sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ== + +"@babel/helper-validator-option@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz#de52000a15a177413c8234fa3a8af4ee8102d0ac" + integrity sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw== + +"@babel/helpers@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.22.5.tgz#74bb4373eb390d1ceed74a15ef97767e63120820" + integrity sha512-pSXRmfE1vzcUIDFQcSGA5Mr+GxBV9oiRKDuDxXvWQQBCh8HoIjs/2DlDB7H8smac1IVrB9/xdXj2N3Wol9Cr+Q== + dependencies: + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/highlight@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.5.tgz#aa6c05c5407a67ebce408162b7ede789b4d22031" + integrity sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw== + dependencies: + "@babel/helper-validator-identifier" "^7.22.5" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.5.tgz#721fd042f3ce1896238cf1b341c77eb7dee7dbea" + integrity sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q== + +"@babel/template@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.5.tgz#0c8c4d944509875849bd0344ff0050756eefc6ec" + integrity sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw== + dependencies: + "@babel/code-frame" "^7.22.5" + "@babel/parser" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/traverse@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.5.tgz#44bd276690db6f4940fdb84e1cb4abd2f729ccd1" + integrity sha512-7DuIjPgERaNo6r+PZwItpjCZEa5vyw4eJGufeLxrPdBXBoLcCJCIasvK6pK/9DVNrLZTLFhUGqaC6X/PA007TQ== + dependencies: + "@babel/code-frame" "^7.22.5" + "@babel/generator" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.5" + "@babel/parser" "^7.22.5" + "@babel/types" "^7.22.5" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.21.3", "@babel/types@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.5.tgz#cd93eeaab025880a3a47ec881f4b096a5b786fbe" + integrity sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA== + dependencies: + "@babel/helper-string-parser" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.5" + to-fast-properties "^2.0.0" + "@esbuild/android-arm64@0.17.19": version "0.17.19" resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz#bafb75234a5d3d1b690e7c2956a599345e84a2fd" @@ -168,7 +357,7 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== -"@jridgewell/gen-mapping@^0.3.2": +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": version "0.3.3" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== @@ -197,7 +386,7 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== -"@jridgewell/trace-mapping@^0.3.9": +"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": version "0.3.18" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz#25783b2086daf6ff1dcb53c9249ae480e4dd4cd6" integrity sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA== @@ -231,6 +420,97 @@ resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.6.3.tgz#8205baf6e17ef93be35bf62c37d2d594e9be0dad" integrity sha512-EXJysQ7J3veRECd0kZFQwYYd5sJMcq2O/m60zu1W2l3oVQ9xtub8jTOtYRE0+M2iomyG/W3Ps7+vp2kna0C27Q== +"@rollup/pluginutils@^5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.0.2.tgz#012b8f53c71e4f6f9cb317e311df1404f56e7a33" + integrity sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA== + dependencies: + "@types/estree" "^1.0.0" + estree-walker "^2.0.2" + picomatch "^2.3.1" + +"@svgr/babel-plugin-add-jsx-attribute@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-7.0.0.tgz#80856c1b7a3b7422d232f6e079f0beb90c4a13e9" + integrity sha512-khWbXesWIP9v8HuKCl2NU2HNAyqpSQ/vkIl36Nbn4HIwEYSRWL0H7Gs6idJdha2DkpFDWlsqMELvoCE8lfFY6Q== + +"@svgr/babel-plugin-remove-jsx-attribute@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-7.0.0.tgz#91da77a009dc38e8d30da45d9b62ef8736f2d90a" + integrity sha512-iiZaIvb3H/c7d3TH2HBeK91uI2rMhZNwnsIrvd7ZwGLkFw6mmunOCoVnjdYua662MqGFxlN9xTq4fv9hgR4VXQ== + +"@svgr/babel-plugin-remove-jsx-empty-expression@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-7.0.0.tgz#5154ff1213509e36ab315974c8c2fd48dafb827b" + integrity sha512-sQQmyo+qegBx8DfFc04PFmIO1FP1MHI1/QEpzcIcclo5OAISsOJPW76ZIs0bDyO/DBSJEa/tDa1W26pVtt0FRw== + +"@svgr/babel-plugin-replace-jsx-attribute-value@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-7.0.0.tgz#7e72f44ee57fdbcb02fb0d4a7629466c5242725e" + integrity sha512-i6MaAqIZXDOJeikJuzocByBf8zO+meLwfQ/qMHIjCcvpnfvWf82PFvredEZElErB5glQFJa2KVKk8N2xV6tRRA== + +"@svgr/babel-plugin-svg-dynamic-title@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-7.0.0.tgz#8caf0449c678ea29be756b89960b2b16c9f33f00" + integrity sha512-BoVSh6ge3SLLpKC0pmmN9DFlqgFy4NxNgdZNLPNJWBUU7TQpDWeBuyVuDW88iXydb5Cv0ReC+ffa5h3VrKfk1w== + +"@svgr/babel-plugin-svg-em-dimensions@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-7.0.0.tgz#4db6b5af6d29e93db236b1a013fa953754071d41" + integrity sha512-tNDcBa+hYn0gO+GkP/AuNKdVtMufVhU9fdzu+vUQsR18RIJ9RWe7h/pSBY338RO08wArntwbDk5WhQBmhf2PaA== + +"@svgr/babel-plugin-transform-react-native-svg@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-7.0.0.tgz#236995e58b5e36ff06365d5310509ce5391aeec9" + integrity sha512-qw54u8ljCJYL2KtBOjI5z7Nzg8LnSvQOP5hPKj77H4VQL4+HdKbAT5pnkkZLmHKYwzsIHSYKXxHouD8zZamCFQ== + +"@svgr/babel-plugin-transform-svg-component@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-7.0.0.tgz#a9b62730acf10d22a2aa57e0f701c0ecbc270430" + integrity sha512-CcFECkDj98daOg9jE3Bh3uyD9kzevCAnZ+UtzG6+BQG/jOQ2OA3jHnX6iG4G1MCJkUQFnUvEv33NvQfqrb/F3A== + +"@svgr/babel-preset@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-preset/-/babel-preset-7.0.0.tgz#55aaca4cec2ff6515a571715b6b6fa98675b66d9" + integrity sha512-EX/NHeFa30j5UjldQGVQikuuQNHUdGmbh9kEpBKofGUtF0GUPJ4T4rhoYiqDAOmBOxojyot36JIFiDUHUK1ilQ== + dependencies: + "@svgr/babel-plugin-add-jsx-attribute" "^7.0.0" + "@svgr/babel-plugin-remove-jsx-attribute" "^7.0.0" + "@svgr/babel-plugin-remove-jsx-empty-expression" "^7.0.0" + "@svgr/babel-plugin-replace-jsx-attribute-value" "^7.0.0" + "@svgr/babel-plugin-svg-dynamic-title" "^7.0.0" + "@svgr/babel-plugin-svg-em-dimensions" "^7.0.0" + "@svgr/babel-plugin-transform-react-native-svg" "^7.0.0" + "@svgr/babel-plugin-transform-svg-component" "^7.0.0" + +"@svgr/core@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@svgr/core/-/core-7.0.0.tgz#def863d2670c682615583c80b408e83c095c2233" + integrity sha512-ztAoxkaKhRVloa3XydohgQQCb0/8x9T63yXovpmHzKMkHO6pkjdsIAWKOS4bE95P/2quVh1NtjSKlMRNzSBffw== + dependencies: + "@babel/core" "^7.21.3" + "@svgr/babel-preset" "^7.0.0" + camelcase "^6.2.0" + cosmiconfig "^8.1.3" + +"@svgr/hast-util-to-babel-ast@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-7.0.0.tgz#d457dfbe74ebc1e5a6daf97ded49e9576a3a00cf" + integrity sha512-42Ej9sDDEmsJKjrfQ1PHmiDiHagh/u9AHO9QWbeNx4KmD9yS5d1XHmXUNINfUcykAU+4431Cn+k6Vn5mWBYimQ== + dependencies: + "@babel/types" "^7.21.3" + entities "^4.4.0" + +"@svgr/plugin-jsx@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-7.0.0.tgz#b9e0c7d05bc890d70163ac0490ba8c41f1afab90" + integrity sha512-SWlTpPQmBUtLKxXWgpv8syzqIU8XgFRvyhfkam2So8b3BE0OS0HPe5UfmlJ2KIC+a7dpuuYovPR2WAQuSyMoPw== + dependencies: + "@babel/core" "^7.21.3" + "@svgr/babel-preset" "^7.0.0" + "@svgr/hast-util-to-babel-ast" "^7.0.0" + svg-parser "^2.0.4" + "@swc/core-darwin-arm64@1.3.62": version "1.3.62" resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.62.tgz#dafb50bf784c6b7b40dce6d8cf0605f6729812cb" @@ -297,6 +577,11 @@ "@swc/core-win32-ia32-msvc" "1.3.62" "@swc/core-win32-x64-msvc" "1.3.62" +"@types/estree@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.1.tgz#aa22750962f3bf0e79d753d3cc067f010c95f194" + integrity sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA== + "@types/history@^4.7.11": version "4.7.11" resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.11.tgz#56588b17ae8f50c53983a524fc3cc47437969d64" @@ -471,6 +756,13 @@ ansi-regex@^5.0.1: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" @@ -543,7 +835,7 @@ braces@^3.0.2, braces@~3.0.2: dependencies: fill-range "^7.0.1" -browserslist@^4.21.5: +browserslist@^4.21.3, browserslist@^4.21.5: version "4.21.7" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.7.tgz#e2b420947e5fb0a58e8f4668ae6e23488127e551" integrity sha512-BauCXrQ7I2ftSqd2mvKHGo85XR0u7Ru3C/Hxsy/0TkfCtjrmAbPdzLGasmoiBxplpDXlPvdjX9u7srIMfgasNA== @@ -563,11 +855,25 @@ camelcase-css@^2.0.1: resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== +camelcase@^6.2.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + caniuse-lite@^1.0.30001464, caniuse-lite@^1.0.30001489: version "1.0.30001495" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001495.tgz#64a0ccef1911a9dcff647115b4430f8eff1ef2d9" integrity sha512-F6x5IEuigtUfU5ZMQK2jsy5JqUUlEFRVZq8bO2a+ysq5K7jD6PPc9YXZj78xDNS3uNchesp1Jw47YXEqr+Viyg== +chalk@^2.0.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + chalk@^4.0.0: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" @@ -591,6 +897,13 @@ chokidar@^3.5.3: optionalDependencies: fsevents "~2.3.2" +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + color-convert@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" @@ -598,6 +911,11 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" @@ -613,6 +931,21 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== +convert-source-map@^1.7.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" + integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== + +cosmiconfig@^8.1.3: + version "8.2.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.2.0.tgz#f7d17c56a590856cd1e7cee98734dca272b0d8fd" + integrity sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ== + dependencies: + import-fresh "^3.2.1" + js-yaml "^4.1.0" + parse-json "^5.0.0" + path-type "^4.0.0" + cross-spawn@^7.0.2: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" @@ -632,7 +965,7 @@ csstype@^3.0.2: resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== -debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: +debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -673,6 +1006,18 @@ electron-to-chromium@^1.4.411: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.421.tgz#2b8c0ef98ba00d4aef4c664933d570922da52161" integrity sha512-wZOyn3s/aQOtLGAwXMZfteQPN68kgls2wDAnYOA8kCjBvKVrW5RwmWVspxJYTqrcN7Y263XJVsC66VCIGzDO3g== +entities@^4.4.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" + integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + esbuild@^0.17.5: version "0.17.19" resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.19.tgz#087a727e98299f0462a3d0bcdd9cd7ff100bd955" @@ -706,6 +1051,11 @@ escalade@^3.1.1: resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + escape-string-regexp@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" @@ -820,6 +1170,11 @@ estraverse@^5.1.0, estraverse@^5.2.0: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== +estree-walker@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" + integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== + esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" @@ -913,6 +1268,11 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -951,6 +1311,11 @@ glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + globals@^13.19.0: version "13.20.0" resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" @@ -985,6 +1350,11 @@ hamt_plus@1.0.2: resolved "https://registry.yarnpkg.com/hamt_plus/-/hamt_plus-1.0.2.tgz#e21c252968c7e33b20f6a1b094cd85787a265601" integrity sha512-t2JXKaehnMb9paaYA7J0BX8QQAY8lwfQ9Gjf4pg/mk4krt+cmwmU652HOoWonf+7+EQV97ARPMhhVgU1ra2GhA== +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + has-flag@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" @@ -1028,6 +1398,11 @@ inherits@2: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + is-binary-path@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" @@ -1074,7 +1449,7 @@ jiti@^1.18.2: resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.18.2.tgz#80c3ef3d486ebf2450d9335122b32d121f2a83cd" integrity sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg== -"js-tokens@^3.0.0 || ^4.0.0": +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== @@ -1086,6 +1461,16 @@ js-yaml@^4.1.0: dependencies: argparse "^2.0.1" +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -1096,6 +1481,11 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== +json5@^2.2.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + levn@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" @@ -1133,6 +1523,13 @@ loose-envify@^1.1.0: dependencies: js-tokens "^3.0.0 || ^4.0.0" +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -1254,6 +1651,16 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" +parse-json@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + path-exists@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" @@ -1465,6 +1872,11 @@ scheduler@^0.23.0: dependencies: loose-envify "^1.1.0" +semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + semver@^7.3.7: version "7.5.1" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.1.tgz#c90c4d631cf74720e46b21c1d37ea07edfab91ec" @@ -1519,6 +1931,13 @@ sucrase@^3.32.0: pirates "^4.0.1" ts-interface-checker "^0.1.9" +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" @@ -1531,6 +1950,11 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== +svg-parser@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/svg-parser/-/svg-parser-2.0.4.tgz#fdc2e29e13951736140b76cb122c8ee6630eb6b5" + integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ== + tailwindcss@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.3.2.tgz#2f9e35d715fdf0bbf674d90147a0684d7054a2d3" @@ -1579,6 +2003,11 @@ thenify-all@^1.0.0: dependencies: any-promise "^1.0.0" +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" @@ -1640,6 +2069,15 @@ util-deprecate@^1.0.2: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== +vite-plugin-svgr@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/vite-plugin-svgr/-/vite-plugin-svgr-3.2.0.tgz#920375aaf6635091c9ac8e467825f92d32544476" + integrity sha512-Uvq6niTvhqJU6ga78qLKBFJSDvxWhOnyfQSoKpDPMAGxJPo5S3+9hyjExE5YDj6Lpa4uaLkGc1cBgxXov+LjSw== + dependencies: + "@rollup/pluginutils" "^5.0.2" + "@svgr/core" "^7.0.0" + "@svgr/plugin-jsx" "^7.0.0" + vite@^4.3.9: version "4.3.9" resolved "https://registry.yarnpkg.com/vite/-/vite-4.3.9.tgz#db896200c0b1aa13b37cdc35c9e99ee2fdd5f96d" @@ -1668,6 +2106,11 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" diff --git a/warstone-web-service/Dockerfile b/warstone-web-service/Dockerfile new file mode 100644 index 0000000..81481f9 --- /dev/null +++ b/warstone-web-service/Dockerfile @@ -0,0 +1,15 @@ + +FROM denoland/deno:1.33.2 +EXPOSE 6904 + +WORKDIR /warstone-web + +ADD ./warstone-web-service/ . +ADD ./deno.jsonc . +ADD ./secrets.json . +ADD ./key.txt . +ADD ./common ./common +ADD ./lib ./lib +ADD ./middleware ./middleware + +CMD ["run", "[object Object]", "[object Object]", main.ts, "6904"] diff --git a/warstone-web-service/main.ts b/warstone-web-service/main.ts new file mode 100644 index 0000000..1d35115 --- /dev/null +++ b/warstone-web-service/main.ts @@ -0,0 +1,24 @@ + +import { CGGService } from 'cgg/Application.ts'; +import { Router, send } from 'oak'; + +const app = new CGGService({ prefix: '/' }); + +// app.route(new Router() +// .get('/', ctx => ctx.response.body = 'warstone-web service') +// ); +const ROOT_DIR = "./public/testdata", ROOT_DIR_PATH = "/public"; + +app.use(async (ctx, next) => { + if (!ctx.request.url.pathname.startsWith(ROOT_DIR_PATH)) { + next(); + return; + } + const filePath = ctx.request.url.pathname.replace(ROOT_DIR_PATH, ""); + await send(ctx, filePath, { + root: ROOT_DIR, + }); +}); + +app.start(); +console.log('warstone-web service running on ' + Deno.args.at(0)); diff --git a/warstone-web-service/perms b/warstone-web-service/perms new file mode 100644 index 0000000..a292aef --- /dev/null +++ b/warstone-web-service/perms @@ -0,0 +1,2 @@ +--allow-read +--allow-net \ No newline at end of file diff --git a/warstone-web-service/port b/warstone-web-service/port new file mode 100644 index 0000000..2bbe672 --- /dev/null +++ b/warstone-web-service/port @@ -0,0 +1 @@ +6904 \ No newline at end of file diff --git a/warstone-web-service/prefix b/warstone-web-service/prefix new file mode 100644 index 0000000..e69de29