create-tsrouter-app 0.0.4 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +8 -6
- package/README.md +7 -3
- package/dist/index.js +105 -46
- package/package.json +1 -1
- package/src/index.ts +132 -45
- package/{project-template → templates/base}/README.md.ejs +36 -4
- package/{project-template → templates/base}/package.json +1 -1
- package/{project-template → templates/base}/src/App.tsx.ejs +15 -5
- package/templates/base/src/logo.svg +43 -0
- package/templates/base/vite.config.js.ejs +15 -0
- package/templates/file-router/package.fr.json +5 -0
- package/templates/file-router/src/main.tsx.ejs +35 -0
- package/templates/file-router/src/routes/__root.tsx +11 -0
- package/project-template/src/logo.svg +0 -44
- package/project-template/vite.config.js.ejs +0 -14
- /package/{project-template → templates/base}/.vscode/settings.json +0 -0
- /package/{project-template → templates/base}/gitignore +0 -0
- /package/{project-template → templates/base}/index.html.ejs +0 -0
- /package/{project-template → templates/base}/package.ts.json +0 -0
- /package/{project-template → templates/base}/package.tw.json +0 -0
- /package/{project-template → templates/base}/public/favicon.ico +0 -0
- /package/{project-template → templates/base}/public/logo192.png +0 -0
- /package/{project-template → templates/base}/public/logo512.png +0 -0
- /package/{project-template → templates/base}/public/manifest.json +0 -0
- /package/{project-template → templates/base}/public/robots.txt +0 -0
- /package/{project-template → templates/base}/src/App.css +0 -0
- /package/{project-template → templates/base}/src/App.test.tsx.ejs +0 -0
- /package/{project-template → templates/base}/src/reportWebVitals.ts.ejs +0 -0
- /package/{project-template → templates/base}/src/styles.css.ejs +0 -0
- /package/{project-template → templates/base}/tsconfig.dev.json +0 -0
- /package/{project-template → templates/base}/tsconfig.json +0 -0
- /package/{project-template → templates/code-router}/src/main.tsx.ejs +0 -0
package/CONTRIBUTING.md
CHANGED
|
@@ -24,9 +24,11 @@
|
|
|
24
24
|
|
|
25
25
|
These must all product running applications that can be built (`pnpm build`) and tested (`pnpm test`).
|
|
26
26
|
|
|
27
|
-
| Command
|
|
28
|
-
|
|
|
29
|
-
| `pnpm start app-js`
|
|
30
|
-
| `pnpm start app-ts --template typescript`
|
|
31
|
-
| `pnpm start app-js-tw --tailwind`
|
|
32
|
-
| `pnpm start app-ts-tw --template typescript --tailwind`
|
|
27
|
+
| Command | Description |
|
|
28
|
+
| -------------------------------------------------------- | ------------------------------------------------------------------ |
|
|
29
|
+
| `pnpm start app-js` | Creates a JavaScript app |
|
|
30
|
+
| `pnpm start app-ts --template typescript` | Creates a TypeScript app |
|
|
31
|
+
| `pnpm start app-js-tw --tailwind` | Creates a JavaScript app with Tailwind CSS |
|
|
32
|
+
| `pnpm start app-ts-tw --template typescript --tailwind` | Creates a TypeScript app with Tailwind CSS |
|
|
33
|
+
| `pnpm start app-fr --template file-router` | Creates a TypeScript app with File Based Routing |
|
|
34
|
+
| `pnpm start app-fr-tw --template file-router --tailwind` | Creates a TypeScript app with File Based Routing with Tailwind CSS |
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
This CLI applications builds Tanstack Start applications that are the functional equivalent of [Create React App](https://create-react-app.dev/).
|
|
4
4
|
|
|
5
|
-
To help accelerate the migration away from create-react-app we created the create-tsrouter-app CLI which is a plug-n-play replacement for CRA.
|
|
5
|
+
To help accelerate the migration away from `create-react-app` we created the `create-tsrouter-app` CLI which is a plug-n-play replacement for CRA.
|
|
6
6
|
|
|
7
7
|
Instead of:
|
|
8
8
|
|
|
@@ -13,7 +13,7 @@ npx create-react-app my-app
|
|
|
13
13
|
You can now run:
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
npx create-tsrouter-app my-app
|
|
16
|
+
npx create-tsrouter-app@latest my-app
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
Instead of using:
|
|
@@ -25,7 +25,7 @@ npx create-react-app my-app --template typescript
|
|
|
25
25
|
To create a SPA application using TypeScript. You can now run:
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
|
-
npx create-tsrouter-app my-app --template typescript
|
|
28
|
+
npx create-tsrouter-app@latest my-app --template typescript
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
What you'll get is a Vite application that uses TanStack Router. All the files will still be in the same place as in CRA, but you'll get a fully functional Router setup under in `app/main.tsx`.
|
|
@@ -38,6 +38,10 @@ You can also specify your preferred package manager with `--package-manager` suc
|
|
|
38
38
|
|
|
39
39
|
Extensive documentation on using the TanStack Router, migrating to a File Base Routing approach, as well as integrating [@tanstack/react-query](https://tanstack.com/query/latest) and [@tanstack/store](https://tanstack.com/store/latest) be found in the generated `README.md` for your project.
|
|
40
40
|
|
|
41
|
+
## File Based Routing
|
|
42
|
+
|
|
43
|
+
By default `create-tsrouter-app` will create a Code Based Routing application. If you want to use File Based Routing then you can specify `--template file-router`. The location of the home page will be `app/routes/index.tsx`.
|
|
44
|
+
|
|
41
45
|
# Contributing
|
|
42
46
|
|
|
43
47
|
Check out the [Contributing](CONTRIBUTING.md) guide.
|
package/dist/index.js
CHANGED
|
@@ -1,34 +1,51 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { copyFile, mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { existsSync } from 'node:fs';
|
|
3
4
|
import { resolve } from 'node:path';
|
|
4
5
|
import { fileURLToPath } from 'node:url';
|
|
5
6
|
import { Command, InvalidArgumentError } from 'commander';
|
|
6
|
-
import { intro, outro, spinner } from '@clack/prompts';
|
|
7
|
+
import { intro, outro, spinner, log } from '@clack/prompts';
|
|
7
8
|
import { execa } from 'execa';
|
|
8
9
|
import { render } from 'ejs';
|
|
9
10
|
import { SUPPORTED_PACKAGE_MANAGERS, getPackageManager, } from './utils/getPackageManager.js';
|
|
10
11
|
const program = new Command();
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
12
|
+
const CODE_ROUTER = 'code-router';
|
|
13
|
+
const FILE_ROUTER = 'file-router';
|
|
14
|
+
function sortObject(obj) {
|
|
15
|
+
return Object.keys(obj)
|
|
16
|
+
.sort()
|
|
17
|
+
.reduce((acc, key) => {
|
|
18
|
+
acc[key] = obj[key];
|
|
19
|
+
return acc;
|
|
20
|
+
}, {});
|
|
21
|
+
}
|
|
22
|
+
function createCopyFile(targetDir) {
|
|
23
|
+
return async function copyFiles(templateDir, files) {
|
|
24
|
+
for (const file of files) {
|
|
25
|
+
const targetFileName = file.replace('.tw', '');
|
|
26
|
+
await copyFile(resolve(templateDir, file), resolve(targetDir, targetFileName));
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function createTemplateFile(projectName, options, targetDir) {
|
|
31
|
+
return async function templateFile(templateDir, file, targetFileName) {
|
|
32
|
+
const templateValues = {
|
|
33
|
+
packageManager: options.packageManager,
|
|
34
|
+
projectName: projectName,
|
|
35
|
+
typescript: options.typescript,
|
|
36
|
+
tailwind: options.tailwind,
|
|
37
|
+
js: options.typescript ? 'ts' : 'js',
|
|
38
|
+
jsx: options.typescript ? 'tsx' : 'jsx',
|
|
39
|
+
fileRouter: options.mode === FILE_ROUTER,
|
|
40
|
+
codeRouter: options.mode === CODE_ROUTER,
|
|
41
|
+
};
|
|
42
|
+
const template = await readFile(resolve(templateDir, file), 'utf-8');
|
|
43
|
+
const content = render(template, templateValues);
|
|
44
|
+
const target = targetFileName ?? file.replace('.ejs', '');
|
|
45
|
+
await writeFile(resolve(targetDir, target), content);
|
|
25
46
|
};
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const target = targetFileName ?? file.replace('.ejs', '');
|
|
29
|
-
await writeFile(resolve(targetDir, target), content);
|
|
30
|
-
};
|
|
31
|
-
async function createPackageJSON(projectName, options, templateDir, targetDir) {
|
|
47
|
+
}
|
|
48
|
+
async function createPackageJSON(projectName, options, templateDir, routerDir, targetDir) {
|
|
32
49
|
let packageJSON = JSON.parse(await readFile(resolve(templateDir, 'package.json'), 'utf8'));
|
|
33
50
|
packageJSON.name = projectName;
|
|
34
51
|
if (options.typescript) {
|
|
@@ -51,22 +68,39 @@ async function createPackageJSON(projectName, options, templateDir, targetDir) {
|
|
|
51
68
|
},
|
|
52
69
|
};
|
|
53
70
|
}
|
|
71
|
+
if (options.mode === FILE_ROUTER) {
|
|
72
|
+
const frPackageJSON = JSON.parse(await readFile(resolve(routerDir, 'package.fr.json'), 'utf8'));
|
|
73
|
+
packageJSON = {
|
|
74
|
+
...packageJSON,
|
|
75
|
+
dependencies: {
|
|
76
|
+
...packageJSON.dependencies,
|
|
77
|
+
...frPackageJSON.dependencies,
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
packageJSON.dependencies = sortObject(packageJSON.dependencies);
|
|
82
|
+
packageJSON.devDependencies = sortObject(packageJSON.devDependencies);
|
|
54
83
|
await writeFile(resolve(targetDir, 'package.json'), JSON.stringify(packageJSON, null, 2));
|
|
55
84
|
}
|
|
56
85
|
async function createApp(projectName, options) {
|
|
57
|
-
const
|
|
86
|
+
const templateDirBase = fileURLToPath(new URL('../templates/base', import.meta.url));
|
|
87
|
+
const templateDirRouter = fileURLToPath(new URL(`../templates/${options.mode}`, import.meta.url));
|
|
58
88
|
const targetDir = resolve(process.cwd(), projectName);
|
|
59
|
-
|
|
60
|
-
|
|
89
|
+
if (existsSync(targetDir)) {
|
|
90
|
+
log.error(`Directory "${projectName}" already exists`);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const copyFiles = createCopyFile(targetDir);
|
|
94
|
+
const templateFile = createTemplateFile(projectName, options, targetDir);
|
|
61
95
|
intro(`Creating a new TanStack app in ${targetDir}...`);
|
|
62
96
|
// Make the root directory
|
|
63
97
|
await mkdir(targetDir, { recursive: true });
|
|
64
98
|
// Setup the .vscode directory
|
|
65
99
|
await mkdir(resolve(targetDir, '.vscode'), { recursive: true });
|
|
66
|
-
await copyFile(resolve(
|
|
100
|
+
await copyFile(resolve(templateDirBase, '.vscode/settings.json'), resolve(targetDir, '.vscode/settings.json'));
|
|
67
101
|
// Fill the public directory
|
|
68
102
|
await mkdir(resolve(targetDir, 'public'), { recursive: true });
|
|
69
|
-
copyFiles([
|
|
103
|
+
copyFiles(templateDirBase, [
|
|
70
104
|
'./public/robots.txt',
|
|
71
105
|
'./public/favicon.ico',
|
|
72
106
|
'./public/manifest.json',
|
|
@@ -75,50 +109,74 @@ async function createApp(projectName, options) {
|
|
|
75
109
|
]);
|
|
76
110
|
// Make the src directory
|
|
77
111
|
await mkdir(resolve(targetDir, 'src'), { recursive: true });
|
|
112
|
+
if (options.mode === FILE_ROUTER) {
|
|
113
|
+
await mkdir(resolve(targetDir, 'src/routes'), { recursive: true });
|
|
114
|
+
}
|
|
78
115
|
// Copy in Vite and Tailwind config and CSS
|
|
79
116
|
if (!options.tailwind) {
|
|
80
|
-
await copyFiles(['./src/App.css']);
|
|
117
|
+
await copyFiles(templateDirBase, ['./src/App.css']);
|
|
81
118
|
}
|
|
82
|
-
await templateFile('./vite.config.js.ejs');
|
|
83
|
-
await templateFile('./src/styles.css.ejs');
|
|
84
|
-
copyFiles(['./src/logo.svg']);
|
|
119
|
+
await templateFile(templateDirBase, './vite.config.js.ejs');
|
|
120
|
+
await templateFile(templateDirBase, './src/styles.css.ejs');
|
|
121
|
+
copyFiles(templateDirBase, ['./src/logo.svg']);
|
|
85
122
|
// Setup the app component. There are four variations, typescript/javascript and tailwind/non-tailwind.
|
|
86
|
-
|
|
87
|
-
|
|
123
|
+
if (options.mode === FILE_ROUTER) {
|
|
124
|
+
copyFiles(templateDirRouter, ['./src/routes/__root.tsx']);
|
|
125
|
+
await templateFile(templateDirBase, './src/App.tsx.ejs', './src/routes/index.tsx');
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
await templateFile(templateDirBase, './src/App.tsx.ejs', options.typescript ? undefined : './src/App.jsx');
|
|
129
|
+
await templateFile(templateDirBase, './src/App.test.tsx.ejs', options.typescript ? undefined : './src/App.test.jsx');
|
|
130
|
+
}
|
|
131
|
+
// Create the main entry point
|
|
132
|
+
if (options.typescript) {
|
|
133
|
+
await templateFile(templateDirRouter, './src/main.tsx.ejs');
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
await templateFile(templateDirRouter, './src/main.tsx.ejs', './src/main.jsx');
|
|
137
|
+
}
|
|
88
138
|
// Setup the main, reportWebVitals and index.html files
|
|
89
139
|
if (options.typescript) {
|
|
90
|
-
await templateFile('./src/
|
|
91
|
-
await templateFile('./src/reportWebVitals.ts.ejs');
|
|
140
|
+
await templateFile(templateDirBase, './src/reportWebVitals.ts.ejs');
|
|
92
141
|
}
|
|
93
142
|
else {
|
|
94
|
-
await templateFile('./src/
|
|
95
|
-
await templateFile('./src/reportWebVitals.ts.ejs', './src/reportWebVitals.js');
|
|
143
|
+
await templateFile(templateDirBase, './src/reportWebVitals.ts.ejs', './src/reportWebVitals.js');
|
|
96
144
|
}
|
|
97
|
-
await templateFile('./index.html.ejs');
|
|
145
|
+
await templateFile(templateDirBase, './index.html.ejs');
|
|
98
146
|
// Setup tsconfig
|
|
99
147
|
if (options.typescript) {
|
|
100
|
-
await copyFiles(['./tsconfig.json', './tsconfig.dev.json']);
|
|
148
|
+
await copyFiles(templateDirBase, ['./tsconfig.json', './tsconfig.dev.json']);
|
|
101
149
|
}
|
|
102
150
|
// Setup the package.json file, optionally with typescript and tailwind
|
|
103
|
-
await createPackageJSON(projectName, options,
|
|
151
|
+
await createPackageJSON(projectName, options, templateDirBase, templateDirRouter, targetDir);
|
|
104
152
|
// Add .gitignore
|
|
105
|
-
await copyFile(resolve(
|
|
153
|
+
await copyFile(resolve(templateDirBase, 'gitignore'), resolve(targetDir, '.gitignore'));
|
|
106
154
|
// Create the README.md
|
|
107
|
-
await templateFile('README.md.ejs');
|
|
155
|
+
await templateFile(templateDirBase, 'README.md.ejs');
|
|
108
156
|
// Install dependencies
|
|
109
157
|
const s = spinner();
|
|
110
158
|
s.start(`Installing dependencies via ${options.packageManager}...`);
|
|
111
159
|
await execa(options.packageManager, ['install'], { cwd: targetDir });
|
|
112
160
|
s.stop(`Installed dependencies`);
|
|
113
|
-
outro(`Created your new TanStack app in ${targetDir}
|
|
161
|
+
outro(`Created your new TanStack app in ${targetDir}.
|
|
162
|
+
|
|
163
|
+
Use the following commands to start your app:
|
|
164
|
+
|
|
165
|
+
% cd ${projectName}
|
|
166
|
+
% ${options.packageManager} start
|
|
167
|
+
|
|
168
|
+
Please read README.md for more information on testing, styling, adding routes, react-query, etc.
|
|
169
|
+
`);
|
|
114
170
|
}
|
|
115
171
|
program
|
|
116
172
|
.name('create-tsrouter-app')
|
|
117
173
|
.description('CLI to create a new TanStack application')
|
|
118
174
|
.argument('<project-name>', 'name of the project')
|
|
119
|
-
.option('--template <type>', 'project template (typescript
|
|
120
|
-
if (value !== 'typescript' &&
|
|
121
|
-
|
|
175
|
+
.option('--template <type>', 'project template (typescript, javascript, file-router)', (value) => {
|
|
176
|
+
if (value !== 'typescript' &&
|
|
177
|
+
value !== 'javascript' &&
|
|
178
|
+
value !== 'file-router') {
|
|
179
|
+
throw new InvalidArgumentError(`Invalid template: ${value}. Only the following are allowed: typescript, javascript, file-router`);
|
|
122
180
|
}
|
|
123
181
|
return value;
|
|
124
182
|
}, 'javascript')
|
|
@@ -130,11 +188,12 @@ program
|
|
|
130
188
|
}, getPackageManager())
|
|
131
189
|
.option('--tailwind', 'add Tailwind CSS', false)
|
|
132
190
|
.action((projectName, options) => {
|
|
133
|
-
const typescript = options.template === 'typescript';
|
|
191
|
+
const typescript = options.template === 'typescript' || options.template === 'file-router';
|
|
134
192
|
createApp(projectName, {
|
|
135
193
|
typescript,
|
|
136
194
|
tailwind: options.tailwind,
|
|
137
195
|
packageManager: options.packageManager,
|
|
196
|
+
mode: options.template === 'file-router' ? FILE_ROUTER : CODE_ROUTER,
|
|
138
197
|
});
|
|
139
198
|
});
|
|
140
199
|
program.parse();
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { copyFile, mkdir, readFile, writeFile } from 'node:fs/promises'
|
|
4
|
+
import { existsSync } from 'node:fs'
|
|
4
5
|
import { resolve } from 'node:path'
|
|
5
6
|
import { fileURLToPath } from 'node:url'
|
|
6
7
|
import { Command, InvalidArgumentError } from 'commander'
|
|
7
|
-
import { intro, outro, spinner } from '@clack/prompts'
|
|
8
|
+
import { intro, outro, spinner, log } from '@clack/prompts'
|
|
8
9
|
import { execa } from 'execa'
|
|
9
10
|
import { render } from 'ejs'
|
|
10
11
|
|
|
@@ -17,14 +18,27 @@ import type { PackageManager } from './utils/getPackageManager.js'
|
|
|
17
18
|
|
|
18
19
|
const program = new Command()
|
|
19
20
|
|
|
21
|
+
const CODE_ROUTER = 'code-router'
|
|
22
|
+
const FILE_ROUTER = 'file-router'
|
|
23
|
+
|
|
20
24
|
interface Options {
|
|
21
25
|
typescript: boolean
|
|
22
26
|
tailwind: boolean
|
|
23
27
|
packageManager: PackageManager
|
|
28
|
+
mode: typeof CODE_ROUTER | typeof FILE_ROUTER
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function sortObject(obj: Record<string, string>): Record<string, string> {
|
|
32
|
+
return Object.keys(obj)
|
|
33
|
+
.sort()
|
|
34
|
+
.reduce<Record<string, string>>((acc, key) => {
|
|
35
|
+
acc[key] = obj[key]
|
|
36
|
+
return acc
|
|
37
|
+
}, {})
|
|
24
38
|
}
|
|
25
39
|
|
|
26
|
-
|
|
27
|
-
async function copyFiles(files: Array<string>) {
|
|
40
|
+
function createCopyFile(targetDir: string) {
|
|
41
|
+
return async function copyFiles(templateDir: string, files: Array<string>) {
|
|
28
42
|
for (const file of files) {
|
|
29
43
|
const targetFileName = file.replace('.tw', '')
|
|
30
44
|
await copyFile(
|
|
@@ -33,14 +47,18 @@ const createCopyFile = (templateDir: string, targetDir: string) =>
|
|
|
33
47
|
)
|
|
34
48
|
}
|
|
35
49
|
}
|
|
50
|
+
}
|
|
36
51
|
|
|
37
|
-
|
|
52
|
+
function createTemplateFile(
|
|
38
53
|
projectName: string,
|
|
39
54
|
options: Required<Options>,
|
|
40
|
-
templateDir: string,
|
|
41
55
|
targetDir: string,
|
|
42
|
-
)
|
|
43
|
-
async function templateFile(
|
|
56
|
+
) {
|
|
57
|
+
return async function templateFile(
|
|
58
|
+
templateDir: string,
|
|
59
|
+
file: string,
|
|
60
|
+
targetFileName?: string,
|
|
61
|
+
) {
|
|
44
62
|
const templateValues = {
|
|
45
63
|
packageManager: options.packageManager,
|
|
46
64
|
projectName: projectName,
|
|
@@ -48,6 +66,8 @@ const createTemplateFile = (
|
|
|
48
66
|
tailwind: options.tailwind,
|
|
49
67
|
js: options.typescript ? 'ts' : 'js',
|
|
50
68
|
jsx: options.typescript ? 'tsx' : 'jsx',
|
|
69
|
+
fileRouter: options.mode === FILE_ROUTER,
|
|
70
|
+
codeRouter: options.mode === CODE_ROUTER,
|
|
51
71
|
}
|
|
52
72
|
|
|
53
73
|
const template = await readFile(resolve(templateDir, file), 'utf-8')
|
|
@@ -55,11 +75,13 @@ const createTemplateFile = (
|
|
|
55
75
|
const target = targetFileName ?? file.replace('.ejs', '')
|
|
56
76
|
await writeFile(resolve(targetDir, target), content)
|
|
57
77
|
}
|
|
78
|
+
}
|
|
58
79
|
|
|
59
80
|
async function createPackageJSON(
|
|
60
81
|
projectName: string,
|
|
61
82
|
options: Required<Options>,
|
|
62
83
|
templateDir: string,
|
|
84
|
+
routerDir: string,
|
|
63
85
|
targetDir: string,
|
|
64
86
|
) {
|
|
65
87
|
let packageJSON = JSON.parse(
|
|
@@ -90,6 +112,24 @@ async function createPackageJSON(
|
|
|
90
112
|
},
|
|
91
113
|
}
|
|
92
114
|
}
|
|
115
|
+
if (options.mode === FILE_ROUTER) {
|
|
116
|
+
const frPackageJSON = JSON.parse(
|
|
117
|
+
await readFile(resolve(routerDir, 'package.fr.json'), 'utf8'),
|
|
118
|
+
)
|
|
119
|
+
packageJSON = {
|
|
120
|
+
...packageJSON,
|
|
121
|
+
dependencies: {
|
|
122
|
+
...packageJSON.dependencies,
|
|
123
|
+
...frPackageJSON.dependencies,
|
|
124
|
+
},
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
packageJSON.dependencies = sortObject(
|
|
128
|
+
packageJSON.dependencies as Record<string, string>,
|
|
129
|
+
)
|
|
130
|
+
packageJSON.devDependencies = sortObject(
|
|
131
|
+
packageJSON.devDependencies as Record<string, string>,
|
|
132
|
+
)
|
|
93
133
|
await writeFile(
|
|
94
134
|
resolve(targetDir, 'package.json'),
|
|
95
135
|
JSON.stringify(packageJSON, null, 2),
|
|
@@ -97,18 +137,21 @@ async function createPackageJSON(
|
|
|
97
137
|
}
|
|
98
138
|
|
|
99
139
|
async function createApp(projectName: string, options: Required<Options>) {
|
|
100
|
-
const
|
|
101
|
-
new URL('../
|
|
140
|
+
const templateDirBase = fileURLToPath(
|
|
141
|
+
new URL('../templates/base', import.meta.url),
|
|
142
|
+
)
|
|
143
|
+
const templateDirRouter = fileURLToPath(
|
|
144
|
+
new URL(`../templates/${options.mode}`, import.meta.url),
|
|
102
145
|
)
|
|
103
146
|
const targetDir = resolve(process.cwd(), projectName)
|
|
104
147
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
)
|
|
148
|
+
if (existsSync(targetDir)) {
|
|
149
|
+
log.error(`Directory "${projectName}" already exists`)
|
|
150
|
+
return
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const copyFiles = createCopyFile(targetDir)
|
|
154
|
+
const templateFile = createTemplateFile(projectName, options, targetDir)
|
|
112
155
|
|
|
113
156
|
intro(`Creating a new TanStack app in ${targetDir}...`)
|
|
114
157
|
|
|
@@ -118,13 +161,13 @@ async function createApp(projectName: string, options: Required<Options>) {
|
|
|
118
161
|
// Setup the .vscode directory
|
|
119
162
|
await mkdir(resolve(targetDir, '.vscode'), { recursive: true })
|
|
120
163
|
await copyFile(
|
|
121
|
-
resolve(
|
|
164
|
+
resolve(templateDirBase, '.vscode/settings.json'),
|
|
122
165
|
resolve(targetDir, '.vscode/settings.json'),
|
|
123
166
|
)
|
|
124
167
|
|
|
125
168
|
// Fill the public directory
|
|
126
169
|
await mkdir(resolve(targetDir, 'public'), { recursive: true })
|
|
127
|
-
copyFiles([
|
|
170
|
+
copyFiles(templateDirBase, [
|
|
128
171
|
'./public/robots.txt',
|
|
129
172
|
'./public/favicon.ico',
|
|
130
173
|
'./public/manifest.json',
|
|
@@ -134,55 +177,85 @@ async function createApp(projectName: string, options: Required<Options>) {
|
|
|
134
177
|
|
|
135
178
|
// Make the src directory
|
|
136
179
|
await mkdir(resolve(targetDir, 'src'), { recursive: true })
|
|
180
|
+
if (options.mode === FILE_ROUTER) {
|
|
181
|
+
await mkdir(resolve(targetDir, 'src/routes'), { recursive: true })
|
|
182
|
+
}
|
|
137
183
|
|
|
138
184
|
// Copy in Vite and Tailwind config and CSS
|
|
139
185
|
if (!options.tailwind) {
|
|
140
|
-
await copyFiles(['./src/App.css'])
|
|
186
|
+
await copyFiles(templateDirBase, ['./src/App.css'])
|
|
141
187
|
}
|
|
142
|
-
await templateFile('./vite.config.js.ejs')
|
|
143
|
-
await templateFile('./src/styles.css.ejs')
|
|
188
|
+
await templateFile(templateDirBase, './vite.config.js.ejs')
|
|
189
|
+
await templateFile(templateDirBase, './src/styles.css.ejs')
|
|
144
190
|
|
|
145
|
-
copyFiles(['./src/logo.svg'])
|
|
191
|
+
copyFiles(templateDirBase, ['./src/logo.svg'])
|
|
146
192
|
|
|
147
193
|
// Setup the app component. There are four variations, typescript/javascript and tailwind/non-tailwind.
|
|
148
|
-
|
|
149
|
-
'./src/
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
194
|
+
if (options.mode === FILE_ROUTER) {
|
|
195
|
+
copyFiles(templateDirRouter, ['./src/routes/__root.tsx'])
|
|
196
|
+
await templateFile(
|
|
197
|
+
templateDirBase,
|
|
198
|
+
'./src/App.tsx.ejs',
|
|
199
|
+
'./src/routes/index.tsx',
|
|
200
|
+
)
|
|
201
|
+
} else {
|
|
202
|
+
await templateFile(
|
|
203
|
+
templateDirBase,
|
|
204
|
+
'./src/App.tsx.ejs',
|
|
205
|
+
options.typescript ? undefined : './src/App.jsx',
|
|
206
|
+
)
|
|
207
|
+
await templateFile(
|
|
208
|
+
templateDirBase,
|
|
209
|
+
'./src/App.test.tsx.ejs',
|
|
210
|
+
options.typescript ? undefined : './src/App.test.jsx',
|
|
211
|
+
)
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Create the main entry point
|
|
215
|
+
if (options.typescript) {
|
|
216
|
+
await templateFile(templateDirRouter, './src/main.tsx.ejs')
|
|
217
|
+
} else {
|
|
218
|
+
await templateFile(
|
|
219
|
+
templateDirRouter,
|
|
220
|
+
'./src/main.tsx.ejs',
|
|
221
|
+
'./src/main.jsx',
|
|
222
|
+
)
|
|
223
|
+
}
|
|
156
224
|
|
|
157
225
|
// Setup the main, reportWebVitals and index.html files
|
|
158
226
|
if (options.typescript) {
|
|
159
|
-
await templateFile('./src/
|
|
160
|
-
await templateFile('./src/reportWebVitals.ts.ejs')
|
|
227
|
+
await templateFile(templateDirBase, './src/reportWebVitals.ts.ejs')
|
|
161
228
|
} else {
|
|
162
|
-
await templateFile('./src/main.tsx.ejs', './src/main.jsx')
|
|
163
229
|
await templateFile(
|
|
230
|
+
templateDirBase,
|
|
164
231
|
'./src/reportWebVitals.ts.ejs',
|
|
165
232
|
'./src/reportWebVitals.js',
|
|
166
233
|
)
|
|
167
234
|
}
|
|
168
|
-
await templateFile('./index.html.ejs')
|
|
235
|
+
await templateFile(templateDirBase, './index.html.ejs')
|
|
169
236
|
|
|
170
237
|
// Setup tsconfig
|
|
171
238
|
if (options.typescript) {
|
|
172
|
-
await copyFiles(['./tsconfig.json', './tsconfig.dev.json'])
|
|
239
|
+
await copyFiles(templateDirBase, ['./tsconfig.json', './tsconfig.dev.json'])
|
|
173
240
|
}
|
|
174
241
|
|
|
175
242
|
// Setup the package.json file, optionally with typescript and tailwind
|
|
176
|
-
await createPackageJSON(
|
|
243
|
+
await createPackageJSON(
|
|
244
|
+
projectName,
|
|
245
|
+
options,
|
|
246
|
+
templateDirBase,
|
|
247
|
+
templateDirRouter,
|
|
248
|
+
targetDir,
|
|
249
|
+
)
|
|
177
250
|
|
|
178
251
|
// Add .gitignore
|
|
179
252
|
await copyFile(
|
|
180
|
-
resolve(
|
|
253
|
+
resolve(templateDirBase, 'gitignore'),
|
|
181
254
|
resolve(targetDir, '.gitignore'),
|
|
182
255
|
)
|
|
183
256
|
|
|
184
257
|
// Create the README.md
|
|
185
|
-
await templateFile('README.md.ejs')
|
|
258
|
+
await templateFile(templateDirBase, 'README.md.ejs')
|
|
186
259
|
|
|
187
260
|
// Install dependencies
|
|
188
261
|
const s = spinner()
|
|
@@ -190,20 +263,32 @@ async function createApp(projectName: string, options: Required<Options>) {
|
|
|
190
263
|
await execa(options.packageManager, ['install'], { cwd: targetDir })
|
|
191
264
|
s.stop(`Installed dependencies`)
|
|
192
265
|
|
|
193
|
-
outro(`Created your new TanStack app in ${targetDir}
|
|
266
|
+
outro(`Created your new TanStack app in ${targetDir}.
|
|
267
|
+
|
|
268
|
+
Use the following commands to start your app:
|
|
269
|
+
|
|
270
|
+
% cd ${projectName}
|
|
271
|
+
% ${options.packageManager} start
|
|
272
|
+
|
|
273
|
+
Please read README.md for more information on testing, styling, adding routes, react-query, etc.
|
|
274
|
+
`)
|
|
194
275
|
}
|
|
195
276
|
|
|
196
277
|
program
|
|
197
278
|
.name('create-tsrouter-app')
|
|
198
279
|
.description('CLI to create a new TanStack application')
|
|
199
280
|
.argument('<project-name>', 'name of the project')
|
|
200
|
-
.option<'typescript' | 'javascript'>(
|
|
281
|
+
.option<'typescript' | 'javascript' | 'file-router'>(
|
|
201
282
|
'--template <type>',
|
|
202
|
-
'project template (typescript
|
|
283
|
+
'project template (typescript, javascript, file-router)',
|
|
203
284
|
(value) => {
|
|
204
|
-
if (
|
|
285
|
+
if (
|
|
286
|
+
value !== 'typescript' &&
|
|
287
|
+
value !== 'javascript' &&
|
|
288
|
+
value !== 'file-router'
|
|
289
|
+
) {
|
|
205
290
|
throw new InvalidArgumentError(
|
|
206
|
-
`Invalid template: ${value}. Only the following are allowed: typescript, javascript`,
|
|
291
|
+
`Invalid template: ${value}. Only the following are allowed: typescript, javascript, file-router`,
|
|
207
292
|
)
|
|
208
293
|
}
|
|
209
294
|
return value
|
|
@@ -230,17 +315,19 @@ program
|
|
|
230
315
|
(
|
|
231
316
|
projectName: string,
|
|
232
317
|
options: {
|
|
233
|
-
template:
|
|
318
|
+
template: 'typescript' | 'javascript' | 'file-router'
|
|
234
319
|
tailwind: boolean
|
|
235
320
|
packageManager: PackageManager
|
|
236
321
|
},
|
|
237
322
|
) => {
|
|
238
|
-
const typescript =
|
|
323
|
+
const typescript =
|
|
324
|
+
options.template === 'typescript' || options.template === 'file-router'
|
|
239
325
|
|
|
240
326
|
createApp(projectName, {
|
|
241
327
|
typescript,
|
|
242
328
|
tailwind: options.tailwind,
|
|
243
329
|
packageManager: options.packageManager,
|
|
330
|
+
mode: options.template === 'file-router' ? FILE_ROUTER : CODE_ROUTER,
|
|
244
331
|
})
|
|
245
332
|
},
|
|
246
333
|
)
|
|
@@ -32,11 +32,14 @@ This project uses [Tailwind CSS](https://tailwindcss.com/) for styling.
|
|
|
32
32
|
This project uses CSS for styling.
|
|
33
33
|
<% } %>
|
|
34
34
|
## Routing
|
|
35
|
-
|
|
36
|
-
This project uses [TanStack Router](https://tanstack.com/router). The initial setup is a code based router. Which means that the routes are defined in code (in the `./src/main.<%= jsx %>` file). If you like you can also use a file based routing setup by following the [File Based Routing](https://tanstack.com/router/latest/docs/framework/react/guide/file-based-routing) guide.
|
|
35
|
+
<% if (fileRouter) { %>This project uses [TanStack Router](https://tanstack.com/router). The initial setup is a file based router. Which means that the routes are managed as fiels in `src/routes`.<% } else { %>This project uses [TanStack Router](https://tanstack.com/router). The initial setup is a code based router. Which means that the routes are defined in code (in the `./src/main.<%= jsx %>` file). If you like you can also use a file based routing setup by following the [File Based Routing](https://tanstack.com/router/latest/docs/framework/react/guide/file-based-routing) guide.<% } %>
|
|
37
36
|
|
|
38
37
|
### Adding A Route
|
|
38
|
+
<% if (fileRouter) { %>
|
|
39
|
+
To add a new route to your application just add another a new file in the `./src/routes` directory.
|
|
39
40
|
|
|
41
|
+
TanStack will automatically generate the content of the route file for you.
|
|
42
|
+
<% } else { %>
|
|
40
43
|
To add a new route to your application just add another `createRoute` call to the `./src/main.<%= jsx %>` file. The example below adds a new `/about`route to the root route.
|
|
41
44
|
|
|
42
45
|
```tsx
|
|
@@ -70,7 +73,7 @@ const aboutRoute = createRoute({
|
|
|
70
73
|
That is how we have the `App` component set up with the home page.
|
|
71
74
|
|
|
72
75
|
For more information on the options you have when you are creating code based routes check out the [Code Based Routing](https://tanstack.com/router/latest/docs/framework/react/guide/code-based-routing) documentation.
|
|
73
|
-
|
|
76
|
+
<% } %>
|
|
74
77
|
Now that you have two routes you can use a `Link` component to navigate between them.
|
|
75
78
|
|
|
76
79
|
### Adding Links
|
|
@@ -93,6 +96,7 @@ More information on the `Link` component can be found in the [Link documentation
|
|
|
93
96
|
|
|
94
97
|
### Using A Layout
|
|
95
98
|
|
|
99
|
+
<% if (codeRouter) { %>
|
|
96
100
|
Layouts can be used to wrap the contents of the routes in menus, headers, footers, etc.
|
|
97
101
|
|
|
98
102
|
There is already a layout in the `src/main.<%= jsx %>` file:
|
|
@@ -111,6 +115,8 @@ const rootRoute = createRootRoute({
|
|
|
111
115
|
You can use the React component specified in the `component` property of the `rootRoute` to wrap the contents of the routes. The `<Outlet />` component is used to render the current route within the body of the layout. For example you could add a header to the layout like so:
|
|
112
116
|
|
|
113
117
|
```tsx
|
|
118
|
+
import { Link } from "@tanstack/react-router";
|
|
119
|
+
|
|
114
120
|
const rootRoute = createRootRoute({
|
|
115
121
|
component: () => (
|
|
116
122
|
<>
|
|
@@ -126,11 +132,37 @@ const rootRoute = createRootRoute({
|
|
|
126
132
|
),
|
|
127
133
|
});
|
|
128
134
|
```
|
|
135
|
+
<% } else { %>In the File Based Routing setup the layout is located in `src/routes/__root.tsx`. Anything you add to the root route will appear in all the routes. The route content will appear in the JSX where you use the `<Outlet />` component.
|
|
136
|
+
|
|
137
|
+
Here is an example layout that includes a header:
|
|
129
138
|
|
|
139
|
+
```tsx
|
|
140
|
+
import { createRootRoute, Outlet } from '@tanstack/react-router'
|
|
141
|
+
import { TanStackRouterDevtools } from '@tanstack/router-devtools'
|
|
142
|
+
|
|
143
|
+
import { Link } from "@tanstack/react-router";
|
|
144
|
+
|
|
145
|
+
export const Route = createRootRoute({
|
|
146
|
+
component: () => (
|
|
147
|
+
<>
|
|
148
|
+
<header>
|
|
149
|
+
<nav>
|
|
150
|
+
<Link to="/">Home</Link>
|
|
151
|
+
<Link to="/about">About</Link>
|
|
152
|
+
</nav>
|
|
153
|
+
</header>
|
|
154
|
+
<Outlet />
|
|
155
|
+
<TanStackRouterDevtools />
|
|
156
|
+
</>
|
|
157
|
+
),
|
|
158
|
+
})
|
|
159
|
+
```
|
|
160
|
+
<% } %>
|
|
130
161
|
The `<TanStackRouterDevtools />` component is not required so you can remove it if you don't want it in your layout.
|
|
131
162
|
|
|
132
163
|
More information on layouts can be found in the [Layouts documentation](hthttps://tanstack.com/router/latest/docs/framework/react/guide/routing-concepts#layouts).
|
|
133
164
|
|
|
165
|
+
<% if (codeRouter) { %>
|
|
134
166
|
### Migrating To File Base Routing
|
|
135
167
|
|
|
136
168
|
First you need to add the Vite plugin for Tanstack Router:
|
|
@@ -301,7 +333,7 @@ reportWebVitals();
|
|
|
301
333
|
Now you've got a file based routing setup in your project! Let's have some fun with it! Just create a file in `about.<%= jsx %>` in `src/routes` and it if the application is running TanStack will automatically add contents to the file and you'll have the start of your `/about` route ready to go with no additional work. You can see why folks find File Based Routing so easy to use.
|
|
302
334
|
|
|
303
335
|
You can find out everything you need to know on how to use file based routing in the [File Based Routing](https://tanstack.com/router/latest/docs/framework/react/guide/file-based-routing) documentation.
|
|
304
|
-
|
|
336
|
+
<% } %>
|
|
305
337
|
## Data Fetching
|
|
306
338
|
|
|
307
339
|
There are multiple ways to fetch data in your application. You can use TanStack Query to fetch data from a server. But you can also use the `loader` functionality built into TanStack Router to load the data for a route before it's rendered.
|
|
@@ -1,7 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import "
|
|
1
|
+
<% if (fileRouter) { %>
|
|
2
|
+
import { createFileRoute } from "@tanstack/react-router";
|
|
3
|
+
import logo from "../logo.svg";<% if (!tailwind) { %>
|
|
4
|
+
import "../App.css";
|
|
4
5
|
<% } %>
|
|
6
|
+
<% } else { %>import logo from "./logo.svg";<% if (!tailwind) { %>
|
|
7
|
+
import "./App.css";
|
|
8
|
+
<% } %><% } %><% if (fileRouter) { %>
|
|
9
|
+
|
|
10
|
+
export const Route = createFileRoute("/")({
|
|
11
|
+
component: App,
|
|
12
|
+
});<% } %>
|
|
5
13
|
|
|
6
14
|
function App() {
|
|
7
15
|
return (<% if (tailwind) { %>
|
|
@@ -13,7 +21,7 @@ function App() {
|
|
|
13
21
|
alt="logo"
|
|
14
22
|
/>
|
|
15
23
|
<p>
|
|
16
|
-
Edit <code
|
|
24
|
+
Edit <code><% if (fileRouter) { %>src/routes/index.tsx<% } else {%>src/App.<%= jsx %><% } %></code> and save to reload.
|
|
17
25
|
</p>
|
|
18
26
|
<a
|
|
19
27
|
className="text-[#61dafb] hover:underline"
|
|
@@ -38,7 +46,7 @@ function App() {
|
|
|
38
46
|
<header className="App-header">
|
|
39
47
|
<img src={logo} className="App-logo" alt="logo" />
|
|
40
48
|
<p>
|
|
41
|
-
Edit <code
|
|
49
|
+
Edit <code><% if (fileRouter) { %>src/routes/index.tsx<% } else {%>src/App.<%= jsx %><% } %></code> and save to reload.
|
|
42
50
|
</p>
|
|
43
51
|
<a
|
|
44
52
|
className="App-link"
|
|
@@ -61,4 +69,6 @@ function App() {
|
|
|
61
69
|
<% } %> );
|
|
62
70
|
}
|
|
63
71
|
|
|
72
|
+
<% if (!fileRouter) { %>
|
|
64
73
|
export default App;
|
|
74
|
+
<% } %>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 841.9 595.3">
|
|
3
|
+
<!-- Generator: Adobe Illustrator 29.3.0, SVG Export Plug-In . SVG Version: 2.1.0 Build 146) -->
|
|
4
|
+
<defs>
|
|
5
|
+
<style>
|
|
6
|
+
.st0 {
|
|
7
|
+
fill: #9ae7fc;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.st1 {
|
|
11
|
+
fill: #61dafb;
|
|
12
|
+
}
|
|
13
|
+
</style>
|
|
14
|
+
</defs>
|
|
15
|
+
<g>
|
|
16
|
+
<path class="st1" d="M666.3,296.5c0-32.5-40.7-63.3-103.1-82.4,14.4-63.6,8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6,0,8.3.9,11.4,2.6,13.6,7.8,19.5,37.5,14.9,75.7-1.1,9.4-2.9,19.3-5.1,29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50,32.6-30.3,63.2-46.9,84-46.9v-22.3c-27.5,0-63.5,19.6-99.9,53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7,0,51.4,16.5,84,46.6-14,14.7-28,31.4-41.3,49.9-22.6,2.4-44,6.1-63.6,11-2.3-10-4-19.7-5.2-29-4.7-38.2,1.1-67.9,14.6-75.8,3-1.8,6.9-2.6,11.5-2.6v-22.3c-8.4,0-16,1.8-22.6,5.6-28.1,16.2-34.4,66.7-19.9,130.1-62.2,19.2-102.7,49.9-102.7,82.3s40.7,63.3,103.1,82.4c-14.4,63.6-8,114.2,20.2,130.4,6.5,3.8,14.1,5.6,22.5,5.6,27.5,0,63.5-19.6,99.9-53.6,36.4,33.8,72.4,53.2,99.9,53.2s16-1.8,22.6-5.6c28.1-16.2,34.4-66.7,19.9-130.1,62-19.1,102.5-49.9,102.5-82.3h0ZM536.1,229.8c-3.7,12.9-8.3,26.2-13.5,39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4,14.2,2.1,27.9,4.7,41,7.9h0ZM490.3,336.3c-7.8,13.5-15.8,26.3-24.1,38.2-14.9,1.3-30,2-45.2,2s-30.2-.7-45-1.9c-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8,6.2-13.4,13.2-26.8,20.7-39.9,7.8-13.5,15.8-26.3,24.1-38.2,14.9-1.3,30-2,45.2-2s30.2.7,45,1.9c8.3,11.9,16.4,24.6,24.2,38,7.6,13.1,14.5,26.4,20.8,39.8-6.3,13.4-13.2,26.8-20.7,39.9h0ZM522.6,323.3c5.4,13.4,10,26.8,13.8,39.8-13.1,3.2-26.9,5.9-41.2,8,4.9-7.7,9.8-15.6,14.4-23.7,4.6-8,8.9-16.1,13-24.1h0ZM421.2,430c-9.3-9.6-18.6-20.3-27.8-32,9,.4,18.2.7,27.5.7s18.7-.2,27.8-.7c-9,11.7-18.3,22.4-27.5,32ZM346.8,371.1c-14.2-2.1-27.9-4.7-41-7.9,3.7-12.9,8.3-26.2,13.5-39.5,4.1,8,8.4,16,13.1,24s9.5,15.8,14.4,23.4ZM420.7,163c9.3,9.6,18.6,20.3,27.8,32-9-.4-18.2-.7-27.5-.7s-18.7.2-27.8.7c9-11.7,18.3-22.4,27.5-32ZM346.7,221.9c-4.9,7.7-9.8,15.6-14.4,23.7-4.6,8-8.9,16-13,24-5.4-13.4-10-26.8-13.8-39.8,13.1-3.1,26.9-5.8,41.2-7.9h0ZM256.2,347.1c-35.4-15.1-58.3-34.9-58.3-50.6s22.9-35.6,58.3-50.6c8.6-3.7,18-7,27.7-10.1,5.7,19.6,13.2,40,22.5,60.9-9.2,20.8-16.6,41.1-22.2,60.6-9.9-3.1-19.3-6.5-28-10.2h0ZM310,490c-13.6-7.8-19.5-37.5-14.9-75.7,1.1-9.4,2.9-19.3,5.1-29.4,19.6,4.8,41,8.5,63.5,10.9,13.5,18.5,27.5,35.3,41.6,50-32.6,30.3-63.2,46.9-84,46.9-4.5-.1-8.3-1-11.3-2.7h0ZM547.2,413.8c4.7,38.2-1.1,67.9-14.6,75.8-3,1.8-6.9,2.6-11.5,2.6-20.7,0-51.4-16.5-84-46.6,14-14.7,28-31.4,41.3-49.9,22.6-2.4,44-6.1,63.6-11,2.3,10.1,4.1,19.8,5.2,29.1ZM585.7,347.1c-8.6,3.7-18,7-27.7,10.1-5.7-19.6-13.2-40-22.5-60.9,9.2-20.8,16.6-41.1,22.2-60.6,9.9,3.1,19.3,6.5,28.1,10.2,35.4,15.1,58.3,34.9,58.3,50.6,0,15.7-23,35.6-58.4,50.6h0Z"/>
|
|
17
|
+
<circle class="st1" cx="420.9" cy="296.5" r="45.7"/>
|
|
18
|
+
<path class="st1" d="M520.5,78.1"/>
|
|
19
|
+
</g>
|
|
20
|
+
<circle class="st0" cx="420.8" cy="296.6" r="43"/>
|
|
21
|
+
<path class="st1" d="M466.1,296.6c0,25-20.2,45.2-45.2,45.2s-45.2-20.2-45.2-45.2,20.2-45.2,45.2-45.2,45.2,20.2,45.2,45.2ZM386,295.6v-6.3c0-1.1,1.2-5.1,1.8-6.2,1-1.9,2.9-3.5,4.6-4.7l-3.4-3.4c4-3.6,9.4-3.7,13.7-.7,1.9-4.7,6.6-7.1,11.6-6.7l-.8,4.2c5.9.2,13.1,4.1,13.1,10.8s0,.5-.7.7c-1.7.3-3.4-.4-5-.6s-1.2-.4-1.2.3,2.5,4.1,3,5.5,1,3.5.8,5.3c-5.6-.8-10.5-3.2-14.8-6.7.3,2.6,4.1,21.7,5.3,21.9s.8-.6,1-1.1,1.3-6.3,1.3-6.7c0-1-1.7-1.8-2.2-2.8-1.2-2.7,1.3-4.7,3.7-3.3s5.2,6.2,7.5,7.3,13,1.4,14.8,3.3-2.9,4.6-1.5,7.6c6.7-2.6,13.5-3.3,20.6-2.5,3.1-9.7,3.1-20.3-.9-29.8-7.3,0-14.7-3.6-17.2-10.8-2.5-7.2-.7-8.6-1.3-9.3-.8-1-6.3.6-7.4-1.5s.3-1.1-.2-1.4-1.9-.6-2.6-.8c-26-6.4-51.3,15.7-49.7,42.1,0,1.6,1.6,10.3,2.4,11.1s4.8,0,6.3,0,3.7.3,5,.5c2.9.4,7.2,2.4,9.4,2.5s2.4-.8,2.7-2.4c.4-2.6.5-7.4.5-10.1s-1-7.8-1.3-11.6c-.9-.2-.7,0-.9.5-.7,1.3-1.1,3.2-1.9,4.8s-5.2,8.7-5.7,9-.7-.5-.8-.8c-1.6-3.5-2-7.9-1.9-11.8-.9-1-5.4,4.9-6.7,5.3l-.8-.4v-.3h-.2ZM455.6,276.4c1.1-1.2-6-8.9-7.2-10-3-2.7-5.4-4.5-3.5,1.4s5.7,7.8,10.6,8.5h.1ZM410.9,270.1c-.4-.5-6.1,2.9-5.5,4.6,1.9-1.3,5.9-1.7,5.5-4.6ZM400.4,276.4c-.3-2.4-6.3-2.7-7.2-1s1.6,1.4,1.9,1.4c1.8.3,3.5-.6,5.2-.4h.1ZM411.3,276.8c3.8,1.3,6.6,3.6,10.9,3.7s0-3-1.2-3.9c-2.2-1.7-5.1-2.4-7.8-2.4s-1.6-.3-1.4.4c2.8.6,7.3.7,8.4,3.8-2.3-.3-3.9-1.6-6.2-2s-2.5-.5-2.6.3h0ZM420.6,290.3c-.8-5.1-5.7-10.8-10.9-11.6s-1.3-.4-.8.5,4.7,3.2,5.7,4,4.5,4.2,2.1,3.8-8.4-7.8-9.4-6.7c.2.9,1.1,1.9,1.7,2.7,3,3.8,6.9,6.8,11.8,7.4h-.2ZM395.3,279.8c-5,1.1-6.9,6.3-6.7,11,.7.8,5-3.8,5.4-4.5s2.7-4.6,1.1-4-2.9,4.4-4.2,4.6.2-2.1.4-2.5c1.1-1.6,2.9-3.1,4-4.6h0ZM400.4,281.5c-.4-.5-2,1.3-2.3,1.7-2.9,3.9-2.6,10.2-1.5,14.8.8.2.8-.3,1.2-.7,3-3.8,5.5-10.5,4.5-15.4-2.1,3.1-3.1,7.3-3.6,11h-1.3c0-4,1.9-7.7,3-11.4h0ZM426.9,305.9c0-1.7-1.7-1.4-2.5-1.9s-1.3-1.9-3-1.4c1.3,2.1,3,3.2,5.5,3.4h0ZM417.2,308.5c7.6.7,5.5-1.9,1.4-5.5-1.3-.3-1.5,4.5-1.4,5.5ZM437,309.7c-3.5-.3-7.8-2-11.2-2.1s-1.3,0-1.9.7c4,1.3,8.4,1.7,12.1,4l1-2.5h0ZM420.5,312.8c-7.3,0-15.1,3.7-20.4,8.8s-4.8,5.3-4.8,6.2c0,1.8,8.6,6.2,10.5,6.8,12.1,4.8,27.5,3.5,38.2-4.2s3.1-2.7,0-6.2c-5.7-6.6-14.7-11.4-23.4-11.3h-.1ZM398.7,316.9c-1.4-1.4-5-1.9-7-2.1s-5.3-.3-6.9.6l13.9,1.4h0ZM456.9,314.8h-7.4c-.9,0-4.9,1.1-6,1.6s-.8.6,0,.5c2.4,0,5.1-1,7.6-1.3s3.5.2,5.1,0,1.3-.3.6-.8h0Z"/>
|
|
22
|
+
<path class="st0" d="M386,295.6l.8.4c1.3-.3,5.8-6.2,6.7-5.3,0,3.9.3,8.3,1.9,11.8s0,1.2.8.8,5.1-7.8,5.7-9,1.3-3.5,1.9-4.8,0-.7.9-.5c.3,3.8,1.2,7.8,1.3,11.6s0,7.5-.5,10.1-1.1,2.4-2.7,2.4-6.5-2.1-9.4-2.5-3.7-.5-5-.5-5.4,1.1-6.3,0-2.2-9.5-2.4-11.1c-1.5-26.4,23.7-48.5,49.7-42.1s2.2.4,2.6.8,0,1,.2,1.4c1.1,2,6.5.5,7.4,1.5s.4,6.9,1.3,9.3c2.5,7.2,10,10.9,17.2,10.8,4,9.4,4,20.1.9,29.8-7.2-.7-13.9,0-20.6,2.5-1.3-3.1,4.1-5.1,1.5-7.6s-11.8-1.9-14.8-3.3-5.4-6.1-7.5-7.3-4.9.6-3.7,3.3,2.1,1.8,2.2,2.8-1,6.2-1.3,6.7-.3,1.3-1,1.1c-1.1-.3-5-19.3-5.3-21.9,4.3,3.5,9.2,5.9,14.8,6.7.2-1.9-.3-3.5-.8-5.3s-3-5.1-3-5.5c0-.8.9-.3,1.2-.3,1.6,0,3.3.8,5,.6s.7.3.7-.7c0-6.6-7.2-10.6-13.1-10.8l.8-4.2c-5.1-.3-9.6,2-11.6,6.7-4.3-3-9.8-3-13.7.7l3.4,3.4c-1.8,1.3-3.5,2.8-4.6,4.7s-1.8,5.1-1.8,6.2v6.6h.2ZM431.6,265c7.8,2.1,8.7-3.5.2-1.3l-.2,1.3ZM432.4,270.9c.3.6,6.4-.4,5.8-2.3s-4.6.6-5.7.6l-.2,1.7h.1ZM434.5,276c.8,1.2,5.7-1.8,5.5-2.7-.4-1.9-6.6,1.2-5.5,2.7ZM442.9,276.4c-.9-.9-5,2.8-4.6,4,.6,2.4,5.7-3,4.6-4ZM445.1,279.9c-.3.2-3.1,4.6-1.5,5s3.5-3.4,3.5-4-1.3-1.3-2-.9h0ZM448.9,287.4c2.1.8,3.8-5.1,2.3-5.5-1.9-.6-2.6,5.1-2.3,5.5ZM457.3,288.6c.5-1.7,1.1-4.7-1-5.5-1,.3-.6,3.9-.6,4.8l.3.5,1.3.2h0Z"/>
|
|
23
|
+
<path class="st0" d="M455.6,276.4c-5-.8-9.1-3.6-10.6-8.5s.5-4,3.5-1.4,8.3,8.7,7.2,10h-.1Z"/>
|
|
24
|
+
<path class="st0" d="M420.6,290.3c-4.9-.6-8.9-3.6-11.8-7.4s-1.5-1.8-1.7-2.7c1-1,8.5,6.6,9.4,6.7,2.4.4-1.8-3.5-2.1-3.8-1-.8-5.4-3.5-5.7-4-.4-.8.5-.5.8-.5,5.2.8,10.1,6.6,10.9,11.6h.2Z"/>
|
|
25
|
+
<path class="st0" d="M400.4,281.5c-1.1,3.7-3,7.3-3,11.4h1.3c.5-3.7,1.5-7.8,3.6-11,1,4.8-1.5,11.6-4.5,15.4s-.4.8-1.2.7c-1.1-4.5-1.3-10.8,1.5-14.8s1.9-2.2,2.3-1.7h0Z"/>
|
|
26
|
+
<path class="st0" d="M411.3,276.8c0-.8,2.1-.4,2.6-.3,2.4.4,4,1.7,6.2,2-1.2-3.1-5.7-3.2-8.4-3.8,0-.8.9-.4,1.4-.4,2.8,0,5.6.7,7.8,2.4,2.2,1.7,4,4,1.2,3.9-4.3,0-7.1-2.4-10.9-3.7h0Z"/>
|
|
27
|
+
<path class="st0" d="M395.3,279.8c-1.1,1.6-3,3-4,4.6s-1.9,2.8-.4,2.5,2.8-4,4.2-4.6-.9,3.6-1.1,4c-.4.7-4.7,5.2-5.4,4.5-.2-4.6,1.8-9.9,6.7-11h0Z"/>
|
|
28
|
+
<path class="st0" d="M437,309.7l-1,2.5c-3.6-2.3-8-2.8-12.1-4,.5-.7,1.1-.7,1.9-.7,3.4,0,7.8,1.8,11.2,2.1h0Z"/>
|
|
29
|
+
<path class="st0" d="M417.2,308.5c0-1,0-5.8,1.4-5.5,4,3.5,6.1,6.2-1.4,5.5Z"/>
|
|
30
|
+
<path class="st0" d="M400.4,276.4c-1.8-.3-3.5.7-5.2.4s-2.3-.8-1.9-1.4c.8-1.6,6.9-1.4,7.2,1h-.1Z"/>
|
|
31
|
+
<path class="st0" d="M410.9,270.1c.4,3-3.6,3.3-5.5,4.6-.6-1.8,5-5.1,5.5-4.6Z"/>
|
|
32
|
+
<path class="st0" d="M426.9,305.9c-2.5-.2-4.1-1.3-5.5-3.4,1.7-.4,2,.8,3,1.4s2.6.3,2.5,1.9h0Z"/>
|
|
33
|
+
<path class="st1" d="M432.4,270.9l.2-1.7c1.1,0,5.1-2.2,5.7-.6s-5.5,2.9-5.8,2.3h-.1Z"/>
|
|
34
|
+
<path class="st1" d="M431.6,265l.2-1.3c8.4-2.1,7.7,3.4-.2,1.3Z"/>
|
|
35
|
+
<path class="st1" d="M434.5,276c-1.1-1.5,5.1-4.6,5.5-2.7s-4.6,4-5.5,2.7Z"/>
|
|
36
|
+
<path class="st1" d="M442.9,276.4c1.1,1.1-4,6.4-4.6,4s3.7-4.9,4.6-4Z"/>
|
|
37
|
+
<path class="st1" d="M445.1,279.9c.7-.4,2.1,0,2,.9s-2.4,4.4-3.5,4,1.3-4.8,1.5-5h0Z"/>
|
|
38
|
+
<path class="st1" d="M448.9,287.4c-.3-.3.4-6.1,2.3-5.5,1.4.4-.2,6.2-2.3,5.5Z"/>
|
|
39
|
+
<path class="st1" d="M457.3,288.6l-1.3-.2-.3-.5c0-.9-.4-4.6.6-4.8,2.1.8,1.5,3.8,1,5.5h0Z"/>
|
|
40
|
+
<path class="st0" d="M420.5,312.8c8.9,0,17.9,4.7,23.4,11.3,5.6,6.6,3.8,3.5,0,6.2-10.7,7.7-26.1,9-38.2,4.2-1.9-.8-10.5-5.1-10.5-6.8s4-5.3,4.8-6.2c5.3-5,13.1-8.6,20.4-8.8h.1Z"/>
|
|
41
|
+
<path class="st0" d="M398.7,316.9l-13.9-1.4c1.7-1,5-.8,6.9-.6s5.6.7,7,2.1h0Z"/>
|
|
42
|
+
<path class="st0" d="M456.9,314.8c.7.5,0,.8-.6.8-1.6.2-3.5-.2-5.1,0-2.4.3-5.2,1.2-7.6,1.3s-1.1,0,0-.5,5.1-1.6,6-1.6h7.4,0Z"/>
|
|
43
|
+
</svg>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { defineConfig } from "vite";
|
|
2
|
+
import viteReact from "@vitejs/plugin-react";<% if (tailwind) { %>
|
|
3
|
+
import tailwindcss from "@tailwindcss/vite";
|
|
4
|
+
<% } %><%if (fileRouter) { %>
|
|
5
|
+
import { TanStackRouterVite } from "@tanstack/router-plugin/vite";
|
|
6
|
+
<% } %>
|
|
7
|
+
|
|
8
|
+
// https://vitejs.dev/config/
|
|
9
|
+
export default defineConfig({
|
|
10
|
+
plugins: [<% if(fileRouter) { %>TanStackRouterVite(), <% } %>viteReact()<% if (tailwind) { %>, tailwindcss()<% } %>],
|
|
11
|
+
test: {
|
|
12
|
+
globals: true,
|
|
13
|
+
environment: "jsdom",
|
|
14
|
+
},
|
|
15
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { StrictMode } from "react";
|
|
2
|
+
import ReactDOM from "react-dom/client";
|
|
3
|
+
import { RouterProvider, createRouter } from "@tanstack/react-router";
|
|
4
|
+
|
|
5
|
+
// Import the generated route tree
|
|
6
|
+
import { routeTree } from "./routeTree.gen";
|
|
7
|
+
|
|
8
|
+
import "./styles.css";
|
|
9
|
+
import reportWebVitals from "./reportWebVitals";
|
|
10
|
+
|
|
11
|
+
// Create a new router instance
|
|
12
|
+
const router = createRouter({ routeTree });
|
|
13
|
+
|
|
14
|
+
// Register the router instance for type safety
|
|
15
|
+
declare module "@tanstack/react-router" {
|
|
16
|
+
interface Register {
|
|
17
|
+
router: typeof router;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Render the app
|
|
22
|
+
const rootElement = document.getElementById("app")!;
|
|
23
|
+
if (!rootElement.innerHTML) {
|
|
24
|
+
const root = ReactDOM.createRoot(rootElement);
|
|
25
|
+
root.render(
|
|
26
|
+
<StrictMode>
|
|
27
|
+
<RouterProvider router={router} />
|
|
28
|
+
</StrictMode>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// If you want to start measuring performance in your app, pass a function
|
|
33
|
+
// to log results (for example: reportWebVitals(console.log))
|
|
34
|
+
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
|
|
35
|
+
reportWebVitals();
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createRootRoute, Outlet } from '@tanstack/react-router'
|
|
2
|
+
import { TanStackRouterDevtools } from '@tanstack/router-devtools'
|
|
3
|
+
|
|
4
|
+
export const Route = createRootRoute({
|
|
5
|
+
component: () => (
|
|
6
|
+
<>
|
|
7
|
+
<Outlet />
|
|
8
|
+
<TanStackRouterDevtools />
|
|
9
|
+
</>
|
|
10
|
+
),
|
|
11
|
+
})
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 841.9 595.3">
|
|
3
|
-
<!-- Generator: Adobe Illustrator 29.3.0, SVG Export Plug-In . SVG Version: 2.1.0 Build 146) -->
|
|
4
|
-
<defs>
|
|
5
|
-
<style>
|
|
6
|
-
.st0 {
|
|
7
|
-
fill: #9ae7fc;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
.st1 {
|
|
11
|
-
fill: #61dafb;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
.st2 {
|
|
15
|
-
fill: #61dafb;
|
|
16
|
-
}
|
|
17
|
-
</style>
|
|
18
|
-
</defs>
|
|
19
|
-
<circle class="st0" cx="420.7" cy="297.3" r="51"/>
|
|
20
|
-
<path class="st2" d="M474.4,297.3c0,29.6-24,53.6-53.6,53.6s-53.6-24-53.6-53.6,24-53.6,53.6-53.6,53.6,24,53.6,53.6ZM379.5,296.1v-7.5c0-1.3,1.4-6.1,2.1-7.4,1.2-2.3,3.4-4.1,5.4-5.6l-4-4c4.7-4.3,11.1-4.4,16.2-.8,2.3-5.6,7.8-8.4,13.8-8l-1,5c7,.2,15.5,4.9,15.5,12.8s0,.6-.8.8c-2,.3-4-.5-5.9-.7s-1.4-.5-1.4.4,3,4.9,3.5,6.5,1.2,4.1,1,6.3c-6.6-1-12.4-3.8-17.5-8,.3,3.1,4.9,25.7,6.3,26s1-.7,1.2-1.3,1.5-7.5,1.5-8c0-1.2-2-2.1-2.6-3.3-1.4-3.2,1.5-5.6,4.4-3.9s6.2,7.4,8.9,8.6,15.4,1.7,17.6,3.9-3.4,5.4-1.8,9c8-3.1,16-3.9,24.4-3,3.7-11.5,3.7-24.1-1.1-35.3-8.6,0-17.4-4.3-20.4-12.8s-.8-10.2-1.5-11c-1-1.2-7.5.7-8.8-1.8s.3-1.3-.2-1.7-2.3-.7-3.1-.9c-30.8-7.6-60.8,18.6-58.9,49.9.1,1.9,1.9,12.2,2.8,13.2s5.7,0,7.5,0,4.4.4,5.9.6c3.4.5,8.5,2.9,11.1,3s2.9-1,3.2-2.8c.5-3.1.6-8.8.6-12s-1.2-9.3-1.5-13.7c-1.1-.2-.8,0-1.1.6-.8,1.6-1.3,3.8-2.3,5.7s-6.2,10.3-6.8,10.7-.8-.6-1-1c-1.9-4.2-2.4-9.4-2.3-14-1.1-1.2-6.4,5.8-8,6.3l-1-.5ZM462,273.3c1.3-1.4-7.1-10.5-8.5-11.8-3.6-3.2-6.4-5.3-4.2,1.7s6.8,9.2,12.6,10.1ZM409,265.8c-.5-.6-7.2,3.4-6.5,5.5,2.2-1.6,7-2,6.5-5.5ZM396.5,273.3c-.3-2.9-7.5-3.2-8.5-1.2s1.9,1.7,2.3,1.7c2.1.4,4.1-.7,6.2-.5ZM409.5,273.8c4.5,1.6,7.8,4.3,12.9,4.4s-.1-3.6-1.4-4.6c-2.6-2-6-2.9-9.2-2.8s-1.9-.4-1.7.5c3.3.7,8.6.8,10,4.5-2.7-.3-4.6-1.9-7.4-2.4s-3-.6-3.1.4ZM420.5,289.8c-1-6-6.8-12.8-12.9-13.8s-1.6-.5-1,.6,5.6,3.8,6.7,4.8,5.3,5,2.5,4.5-10-9.2-11.2-8c.2,1.1,1.3,2.3,2,3.2,3.5,4.5,8.2,8.1,14,8.8ZM390.5,277.3c-5.9,1.3-8.2,7.5-8,13,.8.9,5.9-4.5,6.4-5.3s3.2-5.4,1.3-4.7-3.4,5.2-5,5.5.2-2.5.5-3c1.3-1.9,3.4-3.7,4.7-5.5ZM396.5,279.3c-.5-.6-2.4,1.6-2.7,2-3.4,4.6-3.1,12.1-1.8,17.5.9.2,1-.3,1.4-.8,3.5-4.5,6.5-12.5,5.3-18.2-2.5,3.7-3.7,8.6-4.3,13h-1.5c0-4.8,2.2-9.1,3.5-13.5ZM428,308.3c.1-2-2-1.7-3-2.3s-1.6-2.2-3.5-1.7c1.6,2.5,3.5,3.8,6.5,4ZM416.5,311.3c9,.8,6.5-2.3,1.7-6.5-1.6-.4-1.8,5.3-1.7,6.5ZM440,312.8c-4.1-.4-9.3-2.4-13.3-2.5s-1.6,0-2.2.8c4.8,1.5,9.9,2,14.3,4.7l1.2-3ZM420.4,316.4c-8.7.1-17.9,4.4-24.2,10.4s-5.7,6.3-5.7,7.3c0,2.1,10.2,7.3,12.4,8.1,14.3,5.7,32.6,4.1,45.3-5s3.7-3.2.1-7.4c-6.7-7.8-17.4-13.5-27.8-13.4ZM394.5,321.3c-1.7-1.7-5.9-2.3-8.3-2.5s-6.3-.4-8.2.7l16.5,1.7ZM463.5,318.8h-8.8c-1.1,0-5.8,1.3-7.1,1.9s-1,.7.1.6c2.8-.1,6.1-1.2,9-1.5s4.1.2,6,0,1.6-.4.7-1Z"/>
|
|
21
|
-
<path class="st0" d="M379.5,296.1l1,.5c1.6-.4,6.9-7.4,8-6.3-.1,4.6.4,9.8,2.3,14s.1,1.4,1,1,6.1-9.3,6.8-10.7,1.5-4.1,2.3-5.7,0-.8,1.1-.6c.3,4.5,1.4,9.3,1.5,13.7s0,8.9-.6,12-1.3,2.9-3.2,2.8-7.7-2.5-11.1-3-4.4-.6-5.9-.6-6.4,1.3-7.5,0-2.6-11.3-2.8-13.2c-1.8-31.3,28.1-57.5,58.9-49.9s2.6.5,3.1.9,0,1.2.2,1.7c1.3,2.4,7.7.6,8.8,1.8s.5,8.2,1.5,11c3,8.5,11.8,12.9,20.4,12.8,4.7,11.2,4.8,23.8,1.1,35.3-8.5-.8-16.5,0-24.4,3-1.6-3.7,4.9-6,1.8-9s-14-2.2-17.6-3.9-6.4-7.2-8.9-8.6-5.8.7-4.4,3.9,2.5,2.1,2.6,3.3-1.2,7.3-1.5,8-.3,1.5-1.2,1.3c-1.3-.3-5.9-22.9-6.3-26,5.1,4.2,10.9,7,17.5,8,.2-2.2-.3-4.2-1-6.3s-3.5-6.1-3.5-6.5c0-.9,1.1-.4,1.4-.4,1.9.1,3.9,1,5.9.7s.8.3.8-.8c0-7.8-8.5-12.6-15.5-12.8l1-5c-6-.4-11.4,2.4-13.8,8-5.1-3.6-11.6-3.5-16.2.8l4,4c-2.1,1.5-4.2,3.3-5.4,5.6s-2.1,6.1-2.1,7.4v7.5ZM433.5,259.8c9.3,2.5,10.3-4.1.2-1.5l-.2,1.5ZM434.5,266.8c.4.7,7.6-.5,6.9-2.7s-5.4.7-6.7.7l-.2,2ZM437,272.8c1,1.4,6.7-2.1,6.5-3.2-.5-2.2-7.8,1.4-6.5,3.2ZM447,273.3c-1.1-1.1-5.9,3.3-5.5,4.7.7,2.8,6.8-3.5,5.5-4.7ZM449.6,277.4c-.3.2-3.7,5.4-1.8,5.9s4.1-4,4.2-4.8-1.6-1.5-2.4-1.1ZM454,286.3c2.5.9,4.5-6,2.7-6.5-2.2-.7-3.1,6.1-2.7,6.5ZM464,287.8c.6-2,1.3-5.6-1.2-6.5-1.2.3-.7,4.6-.7,5.7l.4.6,1.5.2Z"/>
|
|
22
|
-
<path class="st0" d="M462,273.3c-5.9-.9-10.8-4.3-12.6-10.1s.6-4.8,4.2-1.7,9.8,10.3,8.5,11.8Z"/>
|
|
23
|
-
<path class="st0" d="M420.5,289.8c-5.8-.7-10.5-4.3-14-8.8s-1.8-2.1-2-3.2c1.2-1.2,10.1,7.8,11.2,8,2.8.5-2.1-4.2-2.5-4.5-1.2-1-6.4-4.2-6.7-4.8-.5-1,.6-.6,1-.6,6.2,1,12,7.8,12.9,13.8Z"/>
|
|
24
|
-
<path class="st0" d="M396.5,279.3c-1.3,4.4-3.6,8.7-3.5,13.5h1.5c.6-4.4,1.8-9.3,4.3-13,1.2,5.7-1.8,13.7-5.3,18.2s-.5,1-1.4.8c-1.3-5.3-1.6-12.8,1.8-17.5s2.2-2.6,2.7-2Z"/>
|
|
25
|
-
<path class="st0" d="M409.5,273.8c.1-1,2.5-.5,3.1-.4,2.8.5,4.7,2,7.4,2.4-1.4-3.7-6.7-3.8-10-4.5-.1-.9,1.1-.5,1.7-.5,3.3,0,6.6.8,9.2,2.8s4.8,4.7,1.4,4.6c-5.1-.1-8.4-2.8-12.9-4.4Z"/>
|
|
26
|
-
<path class="st0" d="M390.5,277.3c-1.3,1.9-3.5,3.6-4.7,5.5s-2.3,3.3-.5,3,3.3-4.8,5-5.5-1.1,4.3-1.3,4.7c-.5.8-5.6,6.2-6.4,5.3-.2-5.5,2.1-11.7,8-13Z"/>
|
|
27
|
-
<path class="st0" d="M440,312.8l-1.2,3c-4.3-2.7-9.5-3.3-14.3-4.7.6-.8,1.3-.8,2.2-.8,4,.1,9.2,2.1,13.3,2.5Z"/>
|
|
28
|
-
<path class="st0" d="M416.5,311.3c0-1.2.1-6.9,1.7-6.5,4.7,4.2,7.2,7.3-1.7,6.5Z"/>
|
|
29
|
-
<path class="st0" d="M396.5,273.3c-2.1-.3-4.1.8-6.2.5s-2.7-1-2.3-1.7c1-1.9,8.2-1.7,8.5,1.2Z"/>
|
|
30
|
-
<path class="st0" d="M409,265.8c.5,3.5-4.3,3.9-6.5,5.5-.7-2.1,5.9-6.1,6.5-5.5Z"/>
|
|
31
|
-
<path class="st0" d="M428,308.3c-3-.2-4.9-1.5-6.5-4,2-.5,2.4,1,3.5,1.7s3.1.3,3,2.3Z"/>
|
|
32
|
-
<path class="st2" d="M434.5,266.8l.2-2c1.3,0,6.1-2.6,6.7-.7s-6.5,3.4-6.9,2.7Z"/>
|
|
33
|
-
<path class="st2" d="M433.5,259.8l.2-1.5c10-2.5,9.1,4-.2,1.5Z"/>
|
|
34
|
-
<path class="st2" d="M437,272.8c-1.3-1.8,6-5.5,6.5-3.2s-5.5,4.7-6.5,3.2Z"/>
|
|
35
|
-
<path class="st2" d="M447,273.3c1.3,1.3-4.7,7.6-5.5,4.7s4.4-5.8,5.5-4.7Z"/>
|
|
36
|
-
<path class="st2" d="M449.6,277.4c.8-.5,2.5,0,2.4,1.1s-2.8,5.2-4.2,4.8,1.5-5.7,1.8-5.9Z"/>
|
|
37
|
-
<path class="st2" d="M454,286.3c-.4-.4.5-7.2,2.7-6.5,1.7.5-.2,7.4-2.7,6.5Z"/>
|
|
38
|
-
<path class="st2" d="M464,287.8l-1.5-.2-.4-.6c0-1.1-.5-5.4.7-5.7,2.5.9,1.8,4.5,1.2,6.5Z"/>
|
|
39
|
-
<path class="st0" d="M420.4,316.4c10.5-.1,21.2,5.6,27.8,13.4s4.5,4.1-.1,7.4c-12.7,9.1-30.9,10.7-45.3,5-2.2-.9-12.4-6-12.4-8.1s4.7-6.3,5.7-7.3c6.3-5.9,15.5-10.2,24.2-10.4Z"/>
|
|
40
|
-
<path class="st0" d="M394.5,321.3l-16.5-1.7c2-1.2,5.9-.9,8.2-.7s6.6.8,8.3,2.5Z"/>
|
|
41
|
-
<path class="st0" d="M463.5,318.8c.8.6,0,.9-.7,1-1.9.2-4.1-.2-6,0-2.9.3-6.2,1.4-9,1.5s-1.3-.1-.1-.6,6-1.9,7.1-1.9h8.8Z"/>
|
|
42
|
-
<path class="st2" d="M666.3,296.5c0-32.5-40.7-63.3-103.1-82.4,14.4-63.6,8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6,0,8.3.9,11.4,2.6,13.6,7.8,19.5,37.5,14.9,75.7-1.1,9.4-2.9,19.3-5.1,29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50,32.6-30.3,63.2-46.9,84-46.9v-22.3c-27.5,0-63.5,19.6-99.9,53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7,0,51.4,16.5,84,46.6-14,14.7-28,31.4-41.3,49.9-22.6,2.4-44,6.1-63.6,11-2.3-10-4-19.7-5.2-29-4.7-38.2,1.1-67.9,14.6-75.8,3-1.8,6.9-2.6,11.5-2.6v-22.3c-8.4,0-16,1.8-22.6,5.6-28.1,16.2-34.4,66.7-19.9,130.1-62.2,19.2-102.7,49.9-102.7,82.3s40.7,63.3,103.1,82.4c-14.4,63.6-8,114.2,20.2,130.4,6.5,3.8,14.1,5.6,22.5,5.6,27.5,0,63.5-19.6,99.9-53.6,36.4,33.8,72.4,53.2,99.9,53.2s16-1.8,22.6-5.6c28.1-16.2,34.4-66.7,19.9-130.1,62-19.1,102.5-49.9,102.5-82.3h0ZM536.1,229.8c-3.7,12.9-8.3,26.2-13.5,39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4,14.2,2.1,27.9,4.7,41,7.9h0ZM490.3,336.3c-7.8,13.5-15.8,26.3-24.1,38.2-14.9,1.3-30,2-45.2,2s-30.2-.7-45-1.9c-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8,6.2-13.4,13.2-26.8,20.7-39.9,7.8-13.5,15.8-26.3,24.1-38.2,14.9-1.3,30-2,45.2-2s30.2.7,45,1.9c8.3,11.9,16.4,24.6,24.2,38,7.6,13.1,14.5,26.4,20.8,39.8-6.3,13.4-13.2,26.8-20.7,39.9h0ZM522.6,323.3c5.4,13.4,10,26.8,13.8,39.8-13.1,3.2-26.9,5.9-41.2,8,4.9-7.7,9.8-15.6,14.4-23.7,4.6-8,8.9-16.1,13-24.1h0ZM421.2,430c-9.3-9.6-18.6-20.3-27.8-32,9,.4,18.2.7,27.5.7s18.7-.2,27.8-.7c-9,11.7-18.3,22.4-27.5,32ZM346.8,371.1c-14.2-2.1-27.9-4.7-41-7.9,3.7-12.9,8.3-26.2,13.5-39.5,4.1,8,8.4,16,13.1,24s9.5,15.8,14.4,23.4ZM420.7,163c9.3,9.6,18.6,20.3,27.8,32-9-.4-18.2-.7-27.5-.7s-18.7.2-27.8.7c9-11.7,18.3-22.4,27.5-32ZM346.7,221.9c-4.9,7.7-9.8,15.6-14.4,23.7-4.6,8-8.9,16-13,24-5.4-13.4-10-26.8-13.8-39.8,13.1-3.1,26.9-5.8,41.2-7.9h0ZM256.2,347.1c-35.4-15.1-58.3-34.9-58.3-50.6s22.9-35.6,58.3-50.6c8.6-3.7,18-7,27.7-10.1,5.7,19.6,13.2,40,22.5,60.9-9.2,20.8-16.6,41.1-22.2,60.6-9.9-3.1-19.3-6.5-28-10.2h0ZM310,490c-13.6-7.8-19.5-37.5-14.9-75.7,1.1-9.4,2.9-19.3,5.1-29.4,19.6,4.8,41,8.5,63.5,10.9,13.5,18.5,27.5,35.3,41.6,50-32.6,30.3-63.2,46.9-84,46.9-4.5-.1-8.3-1-11.3-2.7h0ZM547.2,413.8c4.7,38.2-1.1,67.9-14.6,75.8-3,1.8-6.9,2.6-11.5,2.6-20.7,0-51.4-16.5-84-46.6,14-14.7,28-31.4,41.3-49.9,22.6-2.4,44-6.1,63.6-11,2.3,10.1,4.1,19.8,5.2,29.1ZM585.7,347.1c-8.6,3.7-18,7-27.7,10.1-5.7-19.6-13.2-40-22.5-60.9,9.2-20.8,16.6-41.1,22.2-60.6,9.9,3.1,19.3,6.5,28.1,10.2,35.4,15.1,58.3,34.9,58.3,50.6,0,15.7-23,35.6-58.4,50.6h0Z"/>
|
|
43
|
-
<path class="st1" d="M520.5,78.1"/>
|
|
44
|
-
</svg>
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from "vite";
|
|
2
|
-
import viteReact from "@vitejs/plugin-react";
|
|
3
|
-
<% if (tailwind) { %>
|
|
4
|
-
import tailwindcss from "@tailwindcss/vite";
|
|
5
|
-
<% } %>
|
|
6
|
-
|
|
7
|
-
// https://vitejs.dev/config/
|
|
8
|
-
export default defineConfig({
|
|
9
|
-
plugins: [viteReact()<% if (tailwind) { %>, tailwindcss()<% } %>],
|
|
10
|
-
test: {
|
|
11
|
-
globals: true,
|
|
12
|
-
environment: "jsdom",
|
|
13
|
-
},
|
|
14
|
-
});
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|