From 116a6d8b2ab57852c2866100bb10fe74402c8d05 Mon Sep 17 00:00:00 2001 From: Travis Vachon Date: Thu, 16 Feb 2023 12:59:27 +0800 Subject: [PATCH] chore: update linter, prettier configs (#380) Per #296, update linter configs to match https://github.com/web3-storage/w3protocol, minus prettier because it wouldn't stop having bare knuckle boxing matches with eslint that I got sick of mediating. Use @hugomrdias's `hd-scripts` configs, but turn off a few eslint rules that either a) I didn't like (no-negated-conditions, no-null) or b) feel duplicative in TypeScript (all of the jsdoc rules). Also turn off `import/extensions` because as far as I can tell it recommends the wrong thing. Without disabling these rules I got errors like this: Screenshot 2023-02-07 at 4 32 03 PM I'm definitely open to leaving some of these on if anyone likes them. --- .github/actions/pnpm/action.yml | 3 +- .github/actions/preview/action.yml | 5 +- babel.config.js | 19 +- eslint.packages.js | 23 + examples/react/file-upload/package.json | 2 +- examples/react/file-upload/vite.config.js | 4 +- .../react/multi-file-upload/vite.config.js | 4 +- .../react/playground/.storybook/preview.js | 8 +- .../AuthenticationSubmitted.stories.tsx | 6 +- .../src/stories/Authenticator.stories.tsx | 6 +- .../src/stories/SpaceCreator.stories.tsx | 6 +- .../stories/SpaceCreatorCreating.stories.tsx | 6 +- .../src/stories/SpaceFinder.stories.tsx | 18 +- .../src/stories/Uploader.stories.tsx | 10 +- .../src/stories/UploadsList.stories.tsx | 38 +- examples/react/playground/vite.config.js | 4 +- examples/react/sign-up-in/vite.config.js | 4 +- examples/react/template/vite.config.js | 4 +- examples/react/uploads-list/package.json | 1 - examples/react/uploads-list/vite.config.js | 4 +- examples/react/w3console/package.json | 2 +- examples/react/w3console/src/app.tsx | 130 ++- .../w3console/src/components/did-icon.tsx | 10 +- examples/react/w3console/src/share.tsx | 77 +- examples/react/w3console/vite.config.ts | 18 +- examples/serve.json | 14 +- examples/solid/file-upload/vite.config.js | 6 +- .../solid/multi-file-upload/vite.config.js | 6 +- examples/solid/sign-up-in/vite.config.js | 6 +- examples/solid/template/vite.config.js | 6 +- examples/solid/uploads-list/vite.config.js | 6 +- examples/test/playwright/playwright.config.ts | 22 +- .../test/playwright/src/file-upload.spec.ts | 2 +- .../playwright/src/multi-file-upload.spec.ts | 5 +- .../test/playwright/src/sign-up-in.spec.ts | 2 +- .../test/playwright/src/uploads-list.spec.ts | 2 +- examples/vanilla/file-upload/src/main.js | 9 +- examples/vanilla/file-upload/src/register.js | 51 +- examples/vanilla/file-upload/src/upload.js | 53 +- examples/vanilla/file-upload/vite.config.js | 2 +- .../vanilla/multi-file-upload/src/main.js | 9 +- .../vanilla/multi-file-upload/src/register.js | 51 +- .../vanilla/multi-file-upload/src/upload.js | 75 +- .../vanilla/multi-file-upload/vite.config.js | 2 +- examples/vanilla/sign-up-in/src/main.js | 61 +- .../vanilla/sign-up-in/src/staging-service.js | 20 +- examples/vanilla/sign-up-in/vite.config.js | 2 +- examples/vanilla/template/package.json | 3 +- examples/vanilla/template/vite.config.js | 6 +- examples/vanilla/uploads-list/src/list.js | 18 +- examples/vanilla/uploads-list/src/main.js | 9 +- examples/vanilla/uploads-list/src/register.js | 51 +- examples/vanilla/uploads-list/vite.config.js | 2 +- examples/vue/file-upload/vite.config.js | 6 +- examples/vue/sign-up-in/vite.config.js | 6 +- examples/vue/template/vite.config.js | 6 +- examples/vue/uploads-list/vite.config.js | 6 +- package.json | 11 +- packages/keyring-core/package.json | 12 +- packages/keyring-core/src/index.ts | 43 +- packages/keyring-core/tsconfig.json | 5 +- packages/react-keyring/package.json | 12 +- packages/react-keyring/src/Authenticator.tsx | 176 ++-- .../react-keyring/src/providers/Keyring.tsx | 75 +- .../react-keyring/test/Authenticator.spec.tsx | 6 +- packages/react-keyring/tsconfig.json | 2 +- packages/react-uploader/package.json | 12 +- packages/react-uploader/src/Uploader.tsx | 139 ++-- .../react-uploader/src/providers/Uploader.tsx | 35 +- .../react-uploader/test/Uploader.spec.tsx | 6 +- packages/react-uploader/tsconfig.json | 2 +- packages/react-uploads-list/package.json | 14 +- .../react-uploads-list/src/UploadsList.tsx | 149 ++-- .../src/providers/UploadsList.tsx | 37 +- .../test/UploadsList.spec.tsx | 6 +- packages/react-uploads-list/tsconfig.json | 2 +- packages/react/package.json | 14 +- packages/react/src/Authenticator.tsx | 38 +- packages/react/src/SpaceCreator.tsx | 82 +- packages/react/src/SpaceFinder.tsx | 82 +- packages/react/src/Uploader.tsx | 97 ++- packages/react/src/UploadsList.tsx | 16 +- packages/react/src/providers/W3API.tsx | 34 +- packages/solid-keyring/package.json | 14 +- .../solid-keyring/src/providers/Keyring.ts | 67 +- packages/solid-uploader/package.json | 14 +- .../solid-uploader/src/providers/Uploader.ts | 36 +- packages/solid-uploads-list/package.json | 14 +- .../src/resources/UploadsList.ts | 30 +- packages/uploader-core/package.json | 14 +- packages/uploader-core/src/index.ts | 4 +- packages/uploads-list-core/package.json | 14 +- packages/uploads-list-core/src/index.ts | 6 +- packages/vitest-environment-w3ui/src/index.ts | 8 +- packages/vue-keyring/package.json | 14 +- packages/vue-keyring/src/providers/Keyring.ts | 105 ++- packages/vue-uploader/package.json | 14 +- .../vue-uploader/src/providers/Uploader.ts | 36 +- packages/vue-uploads-list/package.json | 14 +- .../src/providers/UploadsList.ts | 72 +- pnpm-lock.yaml | 768 ++++++++++++------ rollup.config.js | 4 +- rollup.config.ts | 102 +-- tsconfig.eslint.json | 3 - tsconfig.json | 8 +- vitest.config.ts | 4 +- 106 files changed, 2286 insertions(+), 1123 deletions(-) create mode 100644 eslint.packages.js delete mode 100644 tsconfig.eslint.json diff --git a/.github/actions/pnpm/action.yml b/.github/actions/pnpm/action.yml index 154ff158..3fbb3f64 100644 --- a/.github/actions/pnpm/action.yml +++ b/.github/actions/pnpm/action.yml @@ -2,7 +2,7 @@ name: pnpm description: 'Setup node & pnpm' runs: - using: "composite" + using: 'composite' steps: - uses: pnpm/action-setup@v2 with: @@ -15,4 +15,3 @@ runs: node-version: 18 registry-url: 'https://registry.npmjs.org' cache: 'pnpm' - diff --git a/.github/actions/preview/action.yml b/.github/actions/preview/action.yml index ba5529ac..965149da 100644 --- a/.github/actions/preview/action.yml +++ b/.github/actions/preview/action.yml @@ -39,7 +39,7 @@ outputs: value: ${{ steps.set_summary.outputs.summary }} runs: - using: "composite" + using: 'composite' steps: - name: Add to web3.storage uses: web3-storage/add-to-web3@v2 @@ -47,7 +47,7 @@ runs: with: path_to_add: ${{ inputs.path_to_add }} web3_token: ${{ inputs.web3_token }} - + - name: Update IPFS DNSLink if: inputs.dnslink_domain != '' && github.event_name == 'push' && github.ref == 'refs/heads/main' run: npx dnslink-cloudflare --record ${{ inputs.dnslink_record }} --domain ${{ inputs.dnslink_domain }} --link /ipfs/${{ steps.ipfs.outputs.cid }} @@ -78,4 +78,3 @@ runs: core.setOutput('summary', `### Website preview 🔗✨ - 🙂 https://w3s.link/ipfs/${{ steps.ipfs.outputs.cid }} - ⛅️ ${{ steps.cloudflare_url.outputs.stdout }}`) - diff --git a/babel.config.js b/babel.config.js index 25a37038..4281eb47 100644 --- a/babel.config.js +++ b/babel.config.js @@ -8,19 +8,22 @@ module.exports = { modules: false, exclude: [ '@babel/plugin-transform-regenerator', - '@babel/plugin-transform-parameters' - ] - } + '@babel/plugin-transform-parameters', + ], + }, ], '@babel/preset-typescript', - '@babel/preset-react' + '@babel/preset-react', ], env: { test: { plugins: [ // everything needs to be cjs for jest - ['@babel/plugin-transform-modules-commonjs', { loose: true, importInterop: 'node' }] - ] - } - } + [ + '@babel/plugin-transform-modules-commonjs', + { loose: true, importInterop: 'node' }, + ], + ], + }, + }, } diff --git a/eslint.packages.js b/eslint.packages.js new file mode 100644 index 00000000..1a5295d0 --- /dev/null +++ b/eslint.packages.js @@ -0,0 +1,23 @@ +module.exports = { + extends: ['./node_modules/hd-scripts/eslint/ts.js'], + parserOptions: { + project: './tsconfig.json', + ecmaFeatures: { + jsx: true, + }, + }, + env: {}, + globals: {}, + rules: { + 'unicorn/prefer-number-properties': 'off', + 'unicorn/no-negated-condition': 'off', + 'unicorn/no-null': 'off', + 'unicorn/prefer-export-from': 'off', + 'unicorn/filename-case': 'off', + 'unicorn/no-useless-undefined': 'off', + 'jsdoc/require-param': 'off', + 'jsdoc/newline-after-description': 'off', + 'jsdoc/require-param-type': 'off', + 'import/extensions': 'off' + }, +} diff --git a/examples/react/file-upload/package.json b/examples/react/file-upload/package.json index e6681a2e..b90ca051 100644 --- a/examples/react/file-upload/package.json +++ b/examples/react/file-upload/package.json @@ -21,4 +21,4 @@ "@vitejs/plugin-react": "^3.0.0", "vite": "^4.0.0" } -} \ No newline at end of file +} diff --git a/examples/react/file-upload/vite.config.js b/examples/react/file-upload/vite.config.js index 2dfec155..516225b9 100644 --- a/examples/react/file-upload/vite.config.js +++ b/examples/react/file-upload/vite.config.js @@ -6,6 +6,6 @@ export default defineConfig({ base: '', plugins: [react()], server: { - port: 3000 - } + port: 3000, + }, }) diff --git a/examples/react/multi-file-upload/vite.config.js b/examples/react/multi-file-upload/vite.config.js index 2dfec155..516225b9 100644 --- a/examples/react/multi-file-upload/vite.config.js +++ b/examples/react/multi-file-upload/vite.config.js @@ -6,6 +6,6 @@ export default defineConfig({ base: '', plugins: [react()], server: { - port: 3000 - } + port: 3000, + }, }) diff --git a/examples/react/playground/.storybook/preview.js b/examples/react/playground/.storybook/preview.js index d6cfb683..2e61c40a 100644 --- a/examples/react/playground/.storybook/preview.js +++ b/examples/react/playground/.storybook/preview.js @@ -1,5 +1,5 @@ export const parameters = { - actions: { argTypesRegex: "^on[A-Z].*" }, + actions: { argTypesRegex: '^on[A-Z].*' }, controls: { matchers: { color: /(background|color)$/i, @@ -7,6 +7,6 @@ export const parameters = { }, }, backgrounds: { - default: 'dark' - } -} \ No newline at end of file + default: 'dark', + }, +} diff --git a/examples/react/playground/src/stories/AuthenticationSubmitted.stories.tsx b/examples/react/playground/src/stories/AuthenticationSubmitted.stories.tsx index 2e2c1ed3..55f6621c 100644 --- a/examples/react/playground/src/stories/AuthenticationSubmitted.stories.tsx +++ b/examples/react/playground/src/stories/AuthenticationSubmitted.stories.tsx @@ -5,11 +5,9 @@ export default { title: 'w3ui/Authenticator', component: AuthenticationSubmitted, tags: ['autodocs'], - argTypes: { - } + argTypes: {}, } export const Submitted = { - args: { - } + args: {}, } diff --git a/examples/react/playground/src/stories/Authenticator.stories.tsx b/examples/react/playground/src/stories/Authenticator.stories.tsx index 9f88e7d2..13ed9eac 100644 --- a/examples/react/playground/src/stories/Authenticator.stories.tsx +++ b/examples/react/playground/src/stories/Authenticator.stories.tsx @@ -5,11 +5,9 @@ export default { title: 'w3ui/Authenticator', component: Authenticator, tags: ['autodocs'], - argTypes: { - } + argTypes: {}, } export const Primary = { - args: { - } + args: {}, } diff --git a/examples/react/playground/src/stories/SpaceCreator.stories.tsx b/examples/react/playground/src/stories/SpaceCreator.stories.tsx index 25e55c85..6a7d6b1e 100644 --- a/examples/react/playground/src/stories/SpaceCreator.stories.tsx +++ b/examples/react/playground/src/stories/SpaceCreator.stories.tsx @@ -5,11 +5,9 @@ export default { title: 'w3ui/SpaceCreator', component: SpaceCreator, tags: ['autodocs'], - argTypes: { - } + argTypes: {}, } export const Primary = { - args: { - } + args: {}, } diff --git a/examples/react/playground/src/stories/SpaceCreatorCreating.stories.tsx b/examples/react/playground/src/stories/SpaceCreatorCreating.stories.tsx index 54ae9023..66f324a5 100644 --- a/examples/react/playground/src/stories/SpaceCreatorCreating.stories.tsx +++ b/examples/react/playground/src/stories/SpaceCreatorCreating.stories.tsx @@ -5,11 +5,9 @@ export default { title: 'w3ui/SpaceCreator', component: SpaceCreatorCreating, tags: ['autodocs'], - argTypes: { - } + argTypes: {}, } export const Creating = { - args: { - } + args: {}, } diff --git a/examples/react/playground/src/stories/SpaceFinder.stories.tsx b/examples/react/playground/src/stories/SpaceFinder.stories.tsx index c6410249..7b2980ad 100644 --- a/examples/react/playground/src/stories/SpaceFinder.stories.tsx +++ b/examples/react/playground/src/stories/SpaceFinder.stories.tsx @@ -9,24 +9,26 @@ export default { component: SpaceFinder, tags: ['autodocs'], argTypes: { - setSelected: { action: 'set space' } - } + setSelected: { action: 'set space' }, + }, } -const spaces = ['did:example:abc123', 'did:example:xyz789', 'did:example:lmn456'].map( - (did: string, i) => new Space(did as DID, { name: `Space ${i}` }) -) +const spaces = [ + 'did:example:abc123', + 'did:example:xyz789', + 'did:example:lmn456', +].map((did: string, i) => new Space(did as DID, { name: `Space ${i}` })) export const Primary = { args: { spaces, - selected: spaces[0] + selected: spaces[0], }, decorators: [ (Story) => (
- ) - ] + ), + ], } diff --git a/examples/react/playground/src/stories/Uploader.stories.tsx b/examples/react/playground/src/stories/Uploader.stories.tsx index c0d6602f..3f314ca4 100644 --- a/examples/react/playground/src/stories/Uploader.stories.tsx +++ b/examples/react/playground/src/stories/Uploader.stories.tsx @@ -5,14 +5,10 @@ export default { title: 'w3ui/Uploader', component: Uploader, tags: ['autodocs'], - argTypes: { - }, - parameters: { - - } + argTypes: {}, + parameters: {}, } export const Primary = { - args: { - } + args: {}, } diff --git a/examples/react/playground/src/stories/UploadsList.stories.tsx b/examples/react/playground/src/stories/UploadsList.stories.tsx index 34dd304e..3975a839 100644 --- a/examples/react/playground/src/stories/UploadsList.stories.tsx +++ b/examples/react/playground/src/stories/UploadsList.stories.tsx @@ -11,7 +11,7 @@ import '@w3ui/react/src/styles/uploads-list.css' export default { title: 'w3ui/UploadsList', component: UploadsList, - tags: ['autodocs'] + tags: ['autodocs'], } // More on writing stories with args: https://storybook.js.org/docs/7.0/react/writing-stories/args @@ -19,45 +19,55 @@ export const Empty = { render: () => { const state = { data: [], loading: false } const actions = { - next: async (): Promise => { }, - reload: async (): Promise => { } + next: async (): Promise => {}, + reload: async (): Promise => {}, } return ( ) - } + }, } export const OneItem = { render: () => { - const state = { data: [{ root: Link.parse('QmPr755CxWUwt39C2Yiw4UGKrv16uZhSgeZJmoHUUS9TSJ') }], loading: false } + const state = { + data: [ + { root: Link.parse('QmPr755CxWUwt39C2Yiw4UGKrv16uZhSgeZJmoHUUS9TSJ') }, + ], + loading: false, + } const actions = { - next: async (): Promise => { console.log('NEXT') }, - reload: async (): Promise => { } + next: async (): Promise => { + console.log('NEXT') + }, + reload: async (): Promise => {}, } return ( ) - } + }, } export const OneHundredItems = { render: () => { - const state = { data: oneHundredCids.map(root => ({ root })), loading: false } + const state = { + data: oneHundredCids.map((root) => ({ root })), + loading: false, + } const actions = { - next: async (): Promise => { }, - reload: async (): Promise => { } + next: async (): Promise => {}, + reload: async (): Promise => {}, } return ( ) - } + }, } /* commenting because currently unused but potentially useful soon @@ -175,5 +185,5 @@ const oneHundredCids = [ 'bafkreiaivicxyj4zanjcvtkn2csw2eyr2zhdu3pk7r7xsdrmgv2yjzfwp4', 'bafkreidvyaevch6silpmqqd5gmacqdpy3ujwxcsjnbukhitpn6eclfpfse', 'bafkreicebeagd3i4yxxsoxpfmibq3t6ebx2evab2xlitsqabdzptae6o4m', - 'bafkreids7gwr2igplug6lluxzjmj7l7cy63ckmabhfaciy62zqtw4telyy' -].map(cid => Link.parse(cid)) + 'bafkreids7gwr2igplug6lluxzjmj7l7cy63ckmabhfaciy62zqtw4telyy', +].map((cid) => Link.parse(cid)) diff --git a/examples/react/playground/vite.config.js b/examples/react/playground/vite.config.js index 335126d5..c72ca71d 100644 --- a/examples/react/playground/vite.config.js +++ b/examples/react/playground/vite.config.js @@ -5,6 +5,6 @@ import react from '@vitejs/plugin-react' export default defineConfig({ plugins: [react()], server: { - port: 3000 - } + port: 3000, + }, }) diff --git a/examples/react/sign-up-in/vite.config.js b/examples/react/sign-up-in/vite.config.js index 2dfec155..516225b9 100644 --- a/examples/react/sign-up-in/vite.config.js +++ b/examples/react/sign-up-in/vite.config.js @@ -6,6 +6,6 @@ export default defineConfig({ base: '', plugins: [react()], server: { - port: 3000 - } + port: 3000, + }, }) diff --git a/examples/react/template/vite.config.js b/examples/react/template/vite.config.js index 2dfec155..516225b9 100644 --- a/examples/react/template/vite.config.js +++ b/examples/react/template/vite.config.js @@ -6,6 +6,6 @@ export default defineConfig({ base: '', plugins: [react()], server: { - port: 3000 - } + port: 3000, + }, }) diff --git a/examples/react/uploads-list/package.json b/examples/react/uploads-list/package.json index c669f8db..daa40326 100644 --- a/examples/react/uploads-list/package.json +++ b/examples/react/uploads-list/package.json @@ -1,6 +1,5 @@ { "name": "@w3ui/example-react-uploads-list", - "private": true, "version": "0.0.0", "type": "module", diff --git a/examples/react/uploads-list/vite.config.js b/examples/react/uploads-list/vite.config.js index 2dfec155..516225b9 100644 --- a/examples/react/uploads-list/vite.config.js +++ b/examples/react/uploads-list/vite.config.js @@ -6,6 +6,6 @@ export default defineConfig({ base: '', plugins: [react()], server: { - port: 3000 - } + port: 3000, + }, }) diff --git a/examples/react/w3console/package.json b/examples/react/w3console/package.json index 7c799d1d..d5c94ae0 100644 --- a/examples/react/w3console/package.json +++ b/examples/react/w3console/package.json @@ -31,4 +31,4 @@ "typescript": "^4.9.3", "vite": "^4.0.0" } -} \ No newline at end of file +} diff --git a/examples/react/w3console/src/app.tsx b/examples/react/w3console/src/app.tsx index ca970a08..1de192eb 100644 --- a/examples/react/w3console/src/app.tsx +++ b/examples/react/w3console/src/app.tsx @@ -2,7 +2,14 @@ import type { ChangeEvent } from 'react' import type { Space } from '@w3ui/keyring-core' import { useEffect, useState } from 'react' -import { Authenticator, Uploader, UploadsList, W3APIProvider, SpaceFinder, SpaceCreator } from '@w3ui/react' +import { + Authenticator, + Uploader, + UploadsList, + W3APIProvider, + SpaceFinder, + SpaceCreator, +} from '@w3ui/react' import { useKeyring } from '@w3ui/react-keyring' import { useUploadsList } from '@w3ui/react-uploads-list' import { ShareIcon } from '@heroicons/react/20/solid' @@ -11,14 +18,14 @@ import '@w3ui/react/src/styles/all.css' import { SpaceShare } from './share' import { DIDKey } from '@ucanto/interface' -function SpaceRegistrar (): JSX.Element { +function SpaceRegistrar(): JSX.Element { const [, { registerSpace }] = useKeyring() const [email, setEmail] = useState('') const [submitted, setSubmitted] = useState(false) - function resetForm (): void { + function resetForm(): void { setEmail('') } - async function onSubmit (e: React.FormEvent): Promise { + async function onSubmit(e: React.FormEvent): Promise { e.preventDefault() setSubmitted(true) try { @@ -35,31 +42,40 @@ function SpaceRegistrar (): JSX.Element {

Verify your email address!

-

Click the link in the email we sent to start uploading to this space.

+

+ Click the link in the email we sent to start uploading to this space. +

-
- Need a new verification email? -
+
Need a new verification email?
) => { void onSubmit(e) }} + onSubmit={(e: React.FormEvent) => { + void onSubmit(e) + }} > ) => { setEmail(e.target.value) }} + onChange={(e: ChangeEvent) => { + setEmail(e.target.value) + }} /> - {submitted && + {submitted && (

- Verification re-sent, please check your email for a verification email. -

} + Verification re-sent, please check your email for a verification + email. +

+ )}
) @@ -71,7 +87,7 @@ interface SpaceSectionProps { share: boolean } -function SpaceSection (props: SpaceSectionProps): JSX.Element { +function SpaceSection(props: SpaceSectionProps): JSX.Element { const { viewSpace, share, setShare } = props const [{ space }] = useKeyring() const [, { reload }] = useUploadsList() @@ -80,67 +96,105 @@ function SpaceSection (props: SpaceSectionProps): JSX.Element { // to the latest state we have and revalidate in the background (SWR) // but it's not clear how all that state should work yet - perhaps // we need some sort of state management primitive in the uploads list? - useEffect(() => { void reload() }, [space]) + useEffect(() => { + void reload() + }, [space]) const registered = Boolean(space?.registered()) return (
- {(space !== undefined) && ( + {space !== undefined && (
- +
-

{space.name() ?? 'Untitled'}

- +

+ {space.name() ?? 'Untitled'} +

+
-
)} -
{share && } {registered && !share && ( <> - { void reload() }} /> + { + void reload() + }} + />
)} - {!registered && !share && ( - - )} + {!registered && !share && }
) } -function SpaceSelector (props: any): JSX.Element { +function SpaceSelector(props: any): JSX.Element { const { selected, setSelected, spaces } = props return (
-

Spaces

- { void setSelected(space.did()) }} /> +

+ Spaces +

+ { + void setSelected(space.did()) + }} + />
) } -export function Logo (): JSX.Element { +export function Logo(): JSX.Element { return (

- + + + + console

) } -export function Layout (): JsxElement { +export function Layout(): JsxElement { const [share, setShare] = useState(false) const [{ space, spaces }, { setCurrentSpace }] = useKeyring() - function viewSpace (did: DIDKey): void { + function viewSpace(did: DIDKey): void { setShare(false) void setCurrentSpace(did) } @@ -150,7 +204,11 @@ export function Layout (): JsxElement {