@digitaldefiance/express-suite-starter 2.3.5 → 2.3.6
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/package.json +2 -1
- package/scaffolding/api/.env.example.mustache +52 -0
- package/scaffolding/api/src/assets/.gitkeep +0 -0
- package/scaffolding/api/src/main.ts.mustache +19 -0
- package/scaffolding/api/src/views/index.ejs +34 -0
- package/scaffolding/api-lib/src/index.ts +9 -0
- package/scaffolding/api-lib/src/lib/application.ts +35 -0
- package/scaffolding/api-lib/src/lib/constants.ts.mustache +10 -0
- package/scaffolding/api-lib/src/lib/documents/index.ts +1 -0
- package/scaffolding/api-lib/src/lib/documents/user.ts +17 -0
- package/scaffolding/api-lib/src/lib/environment.ts +52 -0
- package/scaffolding/api-lib/src/lib/interfaces/constants.ts +9 -0
- package/scaffolding/api-lib/src/lib/interfaces/environment-aws.ts +7 -0
- package/scaffolding/api-lib/src/lib/interfaces/environment.ts +9 -0
- package/scaffolding/api-lib/src/lib/middlewares.ts.mustache +113 -0
- package/scaffolding/api-lib/src/lib/models/email-token.ts +12 -0
- package/scaffolding/api-lib/src/lib/models/mnemonic.ts +12 -0
- package/scaffolding/api-lib/src/lib/models/role.ts +12 -0
- package/scaffolding/api-lib/src/lib/models/used-direct-login-token.ts +12 -0
- package/scaffolding/api-lib/src/lib/models/user-role.ts +12 -0
- package/scaffolding/api-lib/src/lib/models/user.ts +14 -0
- package/scaffolding/api-lib/src/lib/routers/api.ts +23 -0
- package/scaffolding/api-lib/src/lib/routers/app.ts +31 -0
- package/scaffolding/api-lib/src/lib/routers/index.ts +2 -0
- package/scaffolding/api-lib/src/lib/schemas/index.ts +2 -0
- package/scaffolding/api-lib/src/lib/schemas/schema.ts +53 -0
- package/scaffolding/api-lib/src/lib/schemas/user.ts +13 -0
- package/scaffolding/api-lib/src/lib/services/email.ts +109 -0
- package/scaffolding/api-lib/src/lib/services/index.ts +1 -0
- package/scaffolding/api-lib/src/lib/shared-types.ts +172 -0
- package/scaffolding/devcontainer-mongodb/.devcontainer/.env.example +3 -0
- package/scaffolding/devcontainer-mongodb/.devcontainer/Dockerfile +6 -0
- package/scaffolding/devcontainer-mongodb/.devcontainer/devcontainer.json.mustache +31 -0
- package/scaffolding/devcontainer-mongodb/.devcontainer/docker-compose.yml +31 -0
- package/scaffolding/devcontainer-mongodb/.devcontainer/load-env.sh +20 -0
- package/scaffolding/devcontainer-mongodb/.devcontainer/post-create.sh.hbs +54 -0
- package/scaffolding/devcontainer-mongodb-replicaset/.devcontainer/.env.example +14 -0
- package/scaffolding/devcontainer-mongodb-replicaset/.devcontainer/Dockerfile +38 -0
- package/scaffolding/devcontainer-mongodb-replicaset/.devcontainer/Mongo.Dockerfile +24 -0
- package/scaffolding/devcontainer-mongodb-replicaset/.devcontainer/devcontainer.json +69 -0
- package/scaffolding/devcontainer-mongodb-replicaset/.devcontainer/docker-compose.yml +66 -0
- package/scaffolding/devcontainer-mongodb-replicaset/.devcontainer/entrypoint.sh +29 -0
- package/scaffolding/devcontainer-mongodb-replicaset/.devcontainer/load-env.sh +20 -0
- package/scaffolding/devcontainer-mongodb-replicaset/.devcontainer/mongodb_entrypoint.sh +124 -0
- package/scaffolding/devcontainer-mongodb-replicaset/.devcontainer/mongodb_healthcheck.sh +36 -0
- package/scaffolding/devcontainer-mongodb-replicaset/.devcontainer/post-create.sh.hbs +54 -0
- package/scaffolding/devcontainer-simple/.devcontainer/.env.example +4 -0
- package/scaffolding/devcontainer-simple/.devcontainer/devcontainer.json.mustache +60 -0
- package/scaffolding/devcontainer-simple/.devcontainer/post-create.sh.hbs +72 -0
- package/scaffolding/inituserdb/.env.example.mustache +9 -0
- package/scaffolding/inituserdb/src/main.ts.mustache +178 -0
- package/scaffolding/lib/src/index.ts.mustache +6 -0
- package/scaffolding/lib/src/lib/constants.ts.mustache +15 -0
- package/scaffolding/lib/src/lib/ecies-config.ts +10 -0
- package/scaffolding/lib/src/lib/enumerations/{{workspaceName}}-string-key.ts.mustache +5 -0
- package/scaffolding/lib/src/lib/i18n-setup.ts.mustache +99 -0
- package/scaffolding/lib/src/lib/interfaces/constants.ts +13 -0
- package/scaffolding/lib/src/lib/strings-collection.ts.mustache +45 -0
- package/scaffolding/react/src/app/app.tsx.mustache +170 -0
- package/scaffolding/react/src/app/menus/extraMenu.tsx +20 -0
- package/scaffolding/react/src/app/menus/index.ts +5 -0
- package/scaffolding/react/src/app/pages/SplashPage.tsx +60 -0
- package/scaffolding/react/src/app/theme.tsx.mustache +91 -0
- package/scaffolding/react/src/assets/albatross.ico +0 -0
- package/scaffolding/react/src/assets/albatross.png +0 -0
- package/scaffolding/react/src/assets/albatross.svg +108 -0
- package/scaffolding/react/src/assets/fonts/allroundgothic-xlig.otf +0 -0
- package/scaffolding/react/src/assets/fonts/allroundgothic-xlig.ttf +0 -0
- package/scaffolding/react/src/assets/fonts/allroundgothic-xlig.woff +0 -0
- package/scaffolding/react/src/assets/fonts/allroundgothic-xlig.woff2 +0 -0
- package/scaffolding/react/src/assets/gen-by-albatross.png +0 -0
- package/scaffolding/react/src/assets/gen-by-albatross.svg +124 -0
- package/scaffolding/react/src/config/ecies.ts +10 -0
- package/scaffolding/react/src/config/runtime-config.ts +25 -0
- package/scaffolding/react/src/environments/environment.prod.ts.mustache +16 -0
- package/scaffolding/react/src/environments/environment.ts +15 -0
- package/scaffolding/react/src/interfaces/environment.ts +5 -0
- package/scaffolding/react/src/main.tsx +22 -0
- package/scaffolding/react/src/styles.scss +103 -0
- package/scaffolding/react/src/test-setup.ts +1 -0
- package/scaffolding/react-lib/src/index.ts +6 -0
- package/scaffolding/react-lib/src/theme/theme.tsx +67 -0
- package/scaffolding/root/.github/dependabot.yml +11 -0
- package/scaffolding/root/.github/workflows/ci.yml +44 -0
- package/scaffolding/root/.vscode/extensions.json +9 -0
- package/scaffolding/root/DEPLOYMENT.md +104 -0
- package/scaffolding/root/do-yarn.sh +148 -0
- package/scaffolding/root/ensure-git-globals.sh +30 -0
- package/scaffolding/root/eslint.config.mjs +70 -0
- package/scaffolding/root/list-scripts.sh +12 -0
- package/scaffolding/root/npm-install-globals.sh +5 -0
- package/scaffolding/root/nuke-node-modules.sh +23 -0
- package/scaffolding/root/recover-yarn.sh +37 -0
- package/scaffolding/root/reset.sh.mustache +25 -0
- package/scaffolding/root/setup-nvm.sh +15 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CoreLanguageCode,
|
|
3
|
+
LanguageCodes,
|
|
4
|
+
GlobalActiveContext,
|
|
5
|
+
IActiveContext,
|
|
6
|
+
LanguageContextSpace,
|
|
7
|
+
getCoreLanguageDefinitions,
|
|
8
|
+
I18nBuilder,
|
|
9
|
+
I18nEngine,
|
|
10
|
+
} from '@digitaldefiance/i18n-lib';
|
|
11
|
+
import { AppConstants } from './constants';
|
|
12
|
+
import { {{WorkspaceName}}StringKey } from './enumerations/{{workspaceName}}-string-key';
|
|
13
|
+
import { Strings } from './strings-collection';
|
|
14
|
+
import { createSuiteCoreComponentConfig } from '@digitaldefiance/suite-core-lib';
|
|
15
|
+
|
|
16
|
+
export const ComponentId = '{{WorkspaceName}}';
|
|
17
|
+
|
|
18
|
+
const componentStrings = {
|
|
19
|
+
[LanguageCodes.EN_US]: Strings[LanguageCodes.EN_US],
|
|
20
|
+
[LanguageCodes.EN_GB]: Strings[LanguageCodes.EN_GB],
|
|
21
|
+
[LanguageCodes.FR]: Strings[LanguageCodes.FR],
|
|
22
|
+
[LanguageCodes.ES]: Strings[LanguageCodes.ES],
|
|
23
|
+
[LanguageCodes.DE]: Strings[LanguageCodes.DE],
|
|
24
|
+
[LanguageCodes.ZH_CN]: Strings[LanguageCodes.ZH_CN],
|
|
25
|
+
[LanguageCodes.JA]: Strings[LanguageCodes.JA],
|
|
26
|
+
[LanguageCodes.UK]: Strings[LanguageCodes.UK],
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
let i18nEngine: I18nEngine;
|
|
30
|
+
if (I18nEngine.hasInstance('default')) {
|
|
31
|
+
i18nEngine = I18nEngine.getInstance('default');
|
|
32
|
+
i18nEngine.mergeConstants(AppConstants);
|
|
33
|
+
} else {
|
|
34
|
+
i18nEngine = I18nBuilder.create()
|
|
35
|
+
.withLanguages(getCoreLanguageDefinitions())
|
|
36
|
+
.withDefaultLanguage(LanguageCodes.EN_US)
|
|
37
|
+
.withFallbackLanguage(LanguageCodes.EN_US)
|
|
38
|
+
.withValidation({
|
|
39
|
+
requireCompleteStrings: false,
|
|
40
|
+
allowPartialRegistration: true,
|
|
41
|
+
})
|
|
42
|
+
.withConstants(AppConstants)
|
|
43
|
+
.withInstanceKey('default')
|
|
44
|
+
.build();
|
|
45
|
+
|
|
46
|
+
i18nEngine.register(createSuiteCoreComponentConfig());
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export { i18nEngine };
|
|
50
|
+
|
|
51
|
+
const registrationResult = i18nEngine.registerIfNotExists({
|
|
52
|
+
id: ComponentId,
|
|
53
|
+
strings: componentStrings,
|
|
54
|
+
aliases: ['{{WorkspaceName}}StringKey'],
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
if (!registrationResult.isValid) {
|
|
58
|
+
console.warn('Component has missing translations:', registrationResult.errors);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const globalContext = GlobalActiveContext.getInstance<CoreLanguageCode, IActiveContext<CoreLanguageCode>>();
|
|
62
|
+
globalContext.createContext(LanguageCodes.EN_US, LanguageCodes.EN_US, ComponentId);
|
|
63
|
+
|
|
64
|
+
export const i18nContext: IActiveContext<CoreLanguageCode> = {
|
|
65
|
+
get language() {
|
|
66
|
+
return globalContext.getContext(ComponentId).language;
|
|
67
|
+
},
|
|
68
|
+
get adminLanguage() {
|
|
69
|
+
return globalContext.getContext(ComponentId).adminLanguage;
|
|
70
|
+
},
|
|
71
|
+
get currentContext() {
|
|
72
|
+
return globalContext.getContext(ComponentId).currentContext;
|
|
73
|
+
},
|
|
74
|
+
get currencyCode() {
|
|
75
|
+
return globalContext.getContext(ComponentId).currencyCode;
|
|
76
|
+
},
|
|
77
|
+
get timezone() {
|
|
78
|
+
return globalContext.getContext(ComponentId).timezone;
|
|
79
|
+
},
|
|
80
|
+
get adminTimezone() {
|
|
81
|
+
return globalContext.getContext(ComponentId).adminTimezone;
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export const translate = (
|
|
86
|
+
name: {{WorkspaceName}}StringKey,
|
|
87
|
+
variables?: Record<string, string | number>,
|
|
88
|
+
language?: CoreLanguageCode,
|
|
89
|
+
context?: LanguageContextSpace,
|
|
90
|
+
): string => {
|
|
91
|
+
const activeContext = context ?? globalContext.getContext(ComponentId).currentContext;
|
|
92
|
+
const lang =
|
|
93
|
+
language ??
|
|
94
|
+
(activeContext === 'admin'
|
|
95
|
+
? globalContext.getContext(ComponentId).adminLanguage
|
|
96
|
+
: globalContext.getContext(ComponentId).language);
|
|
97
|
+
|
|
98
|
+
return i18nEngine.translate(ComponentId, name, variables, lang);
|
|
99
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { IConstants as ISuiteCoreConstants } from '@digitaldefiance/suite-core-lib';
|
|
2
|
+
|
|
3
|
+
export interface IConstants extends ISuiteCoreConstants {
|
|
4
|
+
readonly Site: string;
|
|
5
|
+
readonly SiteTagline: string;
|
|
6
|
+
readonly SiteDescription: string;
|
|
7
|
+
readonly SiteHostname: string;
|
|
8
|
+
readonly PasswordRegex: RegExp;
|
|
9
|
+
readonly UsernameMinLength: number;
|
|
10
|
+
readonly UsernameMaxLength: number;
|
|
11
|
+
readonly UsernameRegex: RegExp;
|
|
12
|
+
readonly PasswordMinLength: number;
|
|
13
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { LanguageCodes } from '@digitaldefiance/i18n-lib';
|
|
2
|
+
import { {{WorkspaceName}}StringKey } from './enumerations/{{workspaceName}}-string-key';
|
|
3
|
+
|
|
4
|
+
export const Strings = {
|
|
5
|
+
[LanguageCodes.EN_US]: {
|
|
6
|
+
[{{WorkspaceName}}StringKey.SiteTitle]: '{{#isEnUs}}{{siteTitle}}{{/isEnUs}}{{^isEnUs}}Your Site Title{{/isEnUs}}',
|
|
7
|
+
[{{WorkspaceName}}StringKey.SiteDescription]: '{{#isEnUs}}{{siteDescription}}{{/isEnUs}}{{^isEnUs}}Your description here{{/isEnUs}}',
|
|
8
|
+
[{{WorkspaceName}}StringKey.SiteTagline]: '{{#isEnUs}}{{siteTagline}}{{/isEnUs}}{{^isEnUs}}Your tagline here{{/isEnUs}}',
|
|
9
|
+
},
|
|
10
|
+
[LanguageCodes.EN_GB]: {
|
|
11
|
+
[{{WorkspaceName}}StringKey.SiteTitle]: '{{#isEnGb}}{{siteTitle}}{{/isEnGb}}{{^isEnGb}}Your Site Title{{/isEnGb}}',
|
|
12
|
+
[{{WorkspaceName}}StringKey.SiteDescription]: '{{#isEnGb}}{{siteDescription}}{{/isEnGb}}{{^isEnGb}}Your description here{{/isEnGb}}',
|
|
13
|
+
[{{WorkspaceName}}StringKey.SiteTagline]: '{{#isEnGb}}{{siteTagline}}{{/isEnGb}}{{^isEnGb}}Your tagline here{{/isEnGb}}',
|
|
14
|
+
},
|
|
15
|
+
[LanguageCodes.FR]: {
|
|
16
|
+
[{{WorkspaceName}}StringKey.SiteTitle]: '{{#isFr}}{{siteTitle}}{{/isFr}}{{^isFr}}Titre de votre site{{/isFr}}',
|
|
17
|
+
[{{WorkspaceName}}StringKey.SiteDescription]: '{{#isFr}}{{siteDescription}}{{/isFr}}{{^isFr}}Votre description ici{{/isFr}}',
|
|
18
|
+
[{{WorkspaceName}}StringKey.SiteTagline]: '{{#isFr}}{{siteTagline}}{{/isFr}}{{^isFr}}Votre slogan ici{{/isFr}}',
|
|
19
|
+
},
|
|
20
|
+
[LanguageCodes.ES]: {
|
|
21
|
+
[{{WorkspaceName}}StringKey.SiteTitle]: '{{#isEs}}{{siteTitle}}{{/isEs}}{{^isEs}}Título de su sitio{{/isEs}}',
|
|
22
|
+
[{{WorkspaceName}}StringKey.SiteDescription]: '{{#isEs}}{{siteDescription}}{{/isEs}}{{^isEs}}Su descripción aquí{{/isEs}}',
|
|
23
|
+
[{{WorkspaceName}}StringKey.SiteTagline]: '{{#isEs}}{{siteTagline}}{{/isEs}}{{^isEs}}Su eslogan aquí{{/isEs}}',
|
|
24
|
+
},
|
|
25
|
+
[LanguageCodes.DE]: {
|
|
26
|
+
[{{WorkspaceName}}StringKey.SiteTitle]: '{{#isDe}}{{siteTitle}}{{/isDe}}{{^isDe}}Ihr Seitentitel{{/isDe}}',
|
|
27
|
+
[{{WorkspaceName}}StringKey.SiteDescription]: '{{#isDe}}{{siteDescription}}{{/isDe}}{{^isDe}}Ihre Beschreibung hier{{/isDe}}',
|
|
28
|
+
[{{WorkspaceName}}StringKey.SiteTagline]: '{{#isDe}}{{siteTagline}}{{/isDe}}{{^isDe}}Ihr Slogan hier{{/isDe}}',
|
|
29
|
+
},
|
|
30
|
+
[LanguageCodes.ZH_CN]: {
|
|
31
|
+
[{{WorkspaceName}}StringKey.SiteTitle]: '{{#isZhCn}}{{siteTitle}}{{/isZhCn}}{{^isZhCn}}您的网站标题{{/isZhCn}}',
|
|
32
|
+
[{{WorkspaceName}}StringKey.SiteDescription]: '{{#isZhCn}}{{siteDescription}}{{/isZhCn}}{{^isZhCn}}您的描述在这里{{/isZhCn}}',
|
|
33
|
+
[{{WorkspaceName}}StringKey.SiteTagline]: '{{#isZhCn}}{{siteTagline}}{{/isZhCn}}{{^isZhCn}}您的标语在这里{{/isZhCn}}',
|
|
34
|
+
},
|
|
35
|
+
[LanguageCodes.JA]: {
|
|
36
|
+
[{{WorkspaceName}}StringKey.SiteTitle]: '{{#isJa}}{{siteTitle}}{{/isJa}}{{^isJa}}サイトのタイトル{{/isJa}}',
|
|
37
|
+
[{{WorkspaceName}}StringKey.SiteDescription]: '{{#isJa}}{{siteDescription}}{{/isJa}}{{^isJa}}ここに説明を入力{{/isJa}}',
|
|
38
|
+
[{{WorkspaceName}}StringKey.SiteTagline]: '{{#isJa}}{{siteTagline}}{{/isJa}}{{^isJa}}ここにキャッチフレーズを入力{{/isJa}}',
|
|
39
|
+
},
|
|
40
|
+
[LanguageCodes.UK]: {
|
|
41
|
+
[{{WorkspaceName}}StringKey.SiteTitle]: '{{#isUk}}{{siteTitle}}{{/isUk}}{{^isUk}}Назва вашого сайту{{/isUk}}',
|
|
42
|
+
[{{WorkspaceName}}StringKey.SiteDescription]: '{{#isUk}}{{siteDescription}}{{/isUk}}{{^isUk}}Ваш опис тут{{/isUk}}',
|
|
43
|
+
[{{WorkspaceName}}StringKey.SiteTagline]: '{{#isUk}}{{siteTagline}}{{/isUk}}{{^isUk}}Ваш слоган тут{{/isUk}}',
|
|
44
|
+
},
|
|
45
|
+
};
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { Box, CssBaseline } from '@mui/material';
|
|
2
|
+
import { LocalizationProvider } from '@mui/x-date-pickers';
|
|
3
|
+
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
|
|
4
|
+
import { FC, useCallback } from 'react';
|
|
5
|
+
import { Route, Routes, useNavigate } from 'react-router-dom';
|
|
6
|
+
import '../styles.scss';
|
|
7
|
+
import SplashPage from './pages/SplashPage';
|
|
8
|
+
import { createAppTheme } from './theme.tsx';
|
|
9
|
+
import { AppThemeProvider, DashboardPage, MenuProvider, I18nProvider as TranslationProvider, AuthProvider, SuiteConfigProvider, ApiAccess, ChangePasswordFormWrapper, VerifyEmailPageWrapper, RegisterFormWrapper, UserSettingsFormWrapper, LogoutPageWrapper, LoginFormWrapper, PrivateRoute, UnAuthRoute, TopMenu, TranslatedTitle, BackupCodeLoginWrapper, BackupCodesWrapper } from '@digitaldefiance/express-suite-react-components';
|
|
10
|
+
import { environment } from '../environments/environment';
|
|
11
|
+
import { {{WorkspaceName}}StringKey, ComponentId, i18nEngine } from '{{namespace}}/lib';
|
|
12
|
+
import AlbatrossLogo from '../assets/albatross.svg';
|
|
13
|
+
import { AppConstants, EciesConfig } from '{{namespace}}/lib';
|
|
14
|
+
import { appMenuConfigs } from './menus';
|
|
15
|
+
import { LanguageRegistry } from '@digitaldefiance/i18n-lib';
|
|
16
|
+
import { SuiteCoreComponentId, SuiteCoreStringKey } from '@digitaldefiance/suite-core-lib';
|
|
17
|
+
|
|
18
|
+
const getApiBaseUrl = () => {
|
|
19
|
+
if (
|
|
20
|
+
typeof window !== 'undefined' &&
|
|
21
|
+
(window as any).APP_CONFIG &&
|
|
22
|
+
(window as any).APP_CONFIG.apiUrl
|
|
23
|
+
) {
|
|
24
|
+
return (window as any).APP_CONFIG.apiUrl;
|
|
25
|
+
}
|
|
26
|
+
return environment.apiUrl;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const API_BASE_URL = getApiBaseUrl();
|
|
30
|
+
|
|
31
|
+
const AuthProviderWithNavigation: FC<{ children: React.ReactNode }> = ({
|
|
32
|
+
children,
|
|
33
|
+
}) => {
|
|
34
|
+
const navigate = useNavigate();
|
|
35
|
+
|
|
36
|
+
const handleLogout = useCallback(() => {
|
|
37
|
+
navigate('/');
|
|
38
|
+
}, [navigate]);
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<SuiteConfigProvider
|
|
42
|
+
baseUrl={API_BASE_URL}
|
|
43
|
+
routes={ {
|
|
44
|
+
dashboard: '/dashboard',
|
|
45
|
+
login: '/login',
|
|
46
|
+
register: '/register',
|
|
47
|
+
verifyEmail: '/verify-email',
|
|
48
|
+
settings: '/user-settings',
|
|
49
|
+
} }
|
|
50
|
+
languages={LanguageRegistry.getCodeLabelMap()}
|
|
51
|
+
>
|
|
52
|
+
<AuthProvider
|
|
53
|
+
baseUrl={API_BASE_URL}
|
|
54
|
+
constants={AppConstants}
|
|
55
|
+
eciesConfig={EciesConfig}
|
|
56
|
+
onLogout={handleLogout}
|
|
57
|
+
>
|
|
58
|
+
{children}
|
|
59
|
+
</AuthProvider>
|
|
60
|
+
</SuiteConfigProvider>
|
|
61
|
+
);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const App: FC = () => {
|
|
65
|
+
return (
|
|
66
|
+
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
|
67
|
+
<TranslationProvider i18nEngine={i18nEngine}>
|
|
68
|
+
<TranslatedTitle<SuiteCoreStringKey>
|
|
69
|
+
componentId={SuiteCoreComponentId}
|
|
70
|
+
stringKey={SuiteCoreStringKey.Common_SiteTemplate} />
|
|
71
|
+
<AppThemeProvider customTheme={createAppTheme}>
|
|
72
|
+
<CssBaseline />
|
|
73
|
+
<AuthProviderWithNavigation>
|
|
74
|
+
<InnerApp />
|
|
75
|
+
</AuthProviderWithNavigation>
|
|
76
|
+
</AppThemeProvider>
|
|
77
|
+
</TranslationProvider>
|
|
78
|
+
</LocalizationProvider>
|
|
79
|
+
);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const LogoComponent = () => <img src={AlbatrossLogo} alt="Logo" />;
|
|
83
|
+
|
|
84
|
+
const InnerApp: FC = () => {
|
|
85
|
+
return (
|
|
86
|
+
<MenuProvider menuConfigs={appMenuConfigs}>
|
|
87
|
+
<Box className="app-container" sx={ { paddingTop: '64px' } }>
|
|
88
|
+
<TopMenu Logo={<LogoComponent />} />
|
|
89
|
+
<Routes>
|
|
90
|
+
<Route path="/" element={<SplashPage />} />
|
|
91
|
+
<Route
|
|
92
|
+
path="/api-access"
|
|
93
|
+
element={
|
|
94
|
+
<PrivateRoute>
|
|
95
|
+
<ApiAccess />
|
|
96
|
+
</PrivateRoute>
|
|
97
|
+
}
|
|
98
|
+
/>
|
|
99
|
+
<Route path="/backup-code" element={<BackupCodeLoginWrapper />} />
|
|
100
|
+
<Route
|
|
101
|
+
path="/backup-codes"
|
|
102
|
+
element={
|
|
103
|
+
<PrivateRoute>
|
|
104
|
+
<BackupCodesWrapper />
|
|
105
|
+
</PrivateRoute>
|
|
106
|
+
}
|
|
107
|
+
/>
|
|
108
|
+
<Route
|
|
109
|
+
path="/login"
|
|
110
|
+
element={
|
|
111
|
+
<UnAuthRoute>
|
|
112
|
+
<LoginFormWrapper />
|
|
113
|
+
</UnAuthRoute>
|
|
114
|
+
}
|
|
115
|
+
/>
|
|
116
|
+
<Route
|
|
117
|
+
path="/logout"
|
|
118
|
+
element={
|
|
119
|
+
<PrivateRoute>
|
|
120
|
+
<LogoutPageWrapper />
|
|
121
|
+
</PrivateRoute>
|
|
122
|
+
}
|
|
123
|
+
/>
|
|
124
|
+
<Route
|
|
125
|
+
path="/register"
|
|
126
|
+
element={
|
|
127
|
+
<UnAuthRoute>
|
|
128
|
+
<RegisterFormWrapper />
|
|
129
|
+
</UnAuthRoute>
|
|
130
|
+
}
|
|
131
|
+
/>
|
|
132
|
+
<Route
|
|
133
|
+
path="/dashboard"
|
|
134
|
+
element={
|
|
135
|
+
<PrivateRoute>
|
|
136
|
+
<DashboardPage />
|
|
137
|
+
</PrivateRoute>
|
|
138
|
+
}
|
|
139
|
+
/>
|
|
140
|
+
<Route
|
|
141
|
+
path="/change-password"
|
|
142
|
+
element={
|
|
143
|
+
<PrivateRoute>
|
|
144
|
+
<ChangePasswordFormWrapper />
|
|
145
|
+
</PrivateRoute>
|
|
146
|
+
}
|
|
147
|
+
/>
|
|
148
|
+
<Route
|
|
149
|
+
path="/verify-email"
|
|
150
|
+
element={
|
|
151
|
+
<UnAuthRoute>
|
|
152
|
+
<VerifyEmailPageWrapper />
|
|
153
|
+
</UnAuthRoute>
|
|
154
|
+
}
|
|
155
|
+
/>
|
|
156
|
+
<Route
|
|
157
|
+
path="/user-settings"
|
|
158
|
+
element={
|
|
159
|
+
<PrivateRoute>
|
|
160
|
+
<UserSettingsFormWrapper />
|
|
161
|
+
</PrivateRoute>
|
|
162
|
+
}
|
|
163
|
+
/>
|
|
164
|
+
</Routes>
|
|
165
|
+
</Box>
|
|
166
|
+
</MenuProvider>
|
|
167
|
+
);
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
export default App;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { createMenuType, IMenuConfig } from '@digitaldefiance/express-suite-react-components';
|
|
2
|
+
import { Dashboard } from '@mui/icons-material';
|
|
3
|
+
|
|
4
|
+
const ExtraMenu = createMenuType('ExtraMenu');
|
|
5
|
+
|
|
6
|
+
export const extraMenuConfig: IMenuConfig = {
|
|
7
|
+
menuType: ExtraMenu,
|
|
8
|
+
menuIcon: <Dashboard />,
|
|
9
|
+
priority: 1,
|
|
10
|
+
options: [
|
|
11
|
+
{
|
|
12
|
+
id: 'extra-option-1',
|
|
13
|
+
label: 'Extra Option 1',
|
|
14
|
+
link: '/extra-1',
|
|
15
|
+
requiresAuth: true,
|
|
16
|
+
includeOnMenus: [ExtraMenu],
|
|
17
|
+
index: 0,
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Box, Button, Container, Typography } from '@mui/material';
|
|
2
|
+
import { useNavigate } from 'react-router-dom';
|
|
3
|
+
import { useAuth } from '@digitaldefiance/express-suite-react-components';
|
|
4
|
+
|
|
5
|
+
const SplashPage = () => {
|
|
6
|
+
const navigate = useNavigate();
|
|
7
|
+
const { isAuthenticated } = useAuth();
|
|
8
|
+
|
|
9
|
+
return (
|
|
10
|
+
<Container maxWidth="md">
|
|
11
|
+
<Box
|
|
12
|
+
sx={{
|
|
13
|
+
display: 'flex',
|
|
14
|
+
flexDirection: 'column',
|
|
15
|
+
alignItems: 'center',
|
|
16
|
+
justifyContent: 'center',
|
|
17
|
+
minHeight: '80vh',
|
|
18
|
+
textAlign: 'center',
|
|
19
|
+
}}
|
|
20
|
+
>
|
|
21
|
+
<Typography variant="h2" component="h1" gutterBottom>
|
|
22
|
+
Welcome to @WORKSPACENAME@
|
|
23
|
+
</Typography>
|
|
24
|
+
<Typography variant="h5" color="text.secondary" paragraph>
|
|
25
|
+
A modern MERN stack application built with Express Suite
|
|
26
|
+
</Typography>
|
|
27
|
+
<Box sx={{ mt: 4, display: 'flex', gap: 2 }}>
|
|
28
|
+
{isAuthenticated ? (
|
|
29
|
+
<Button
|
|
30
|
+
variant="contained"
|
|
31
|
+
size="large"
|
|
32
|
+
onClick={() => navigate('/dashboard')}
|
|
33
|
+
>
|
|
34
|
+
Go to Dashboard
|
|
35
|
+
</Button>
|
|
36
|
+
) : (
|
|
37
|
+
<>
|
|
38
|
+
<Button
|
|
39
|
+
variant="contained"
|
|
40
|
+
size="large"
|
|
41
|
+
onClick={() => navigate('/login')}
|
|
42
|
+
>
|
|
43
|
+
Login
|
|
44
|
+
</Button>
|
|
45
|
+
<Button
|
|
46
|
+
variant="outlined"
|
|
47
|
+
size="large"
|
|
48
|
+
onClick={() => navigate('/register')}
|
|
49
|
+
>
|
|
50
|
+
Register
|
|
51
|
+
</Button>
|
|
52
|
+
</>
|
|
53
|
+
)}
|
|
54
|
+
</Box>
|
|
55
|
+
</Box>
|
|
56
|
+
</Container>
|
|
57
|
+
);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export default SplashPage;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// src/app/theme.tsx
|
|
2
|
+
|
|
3
|
+
import { AppConstants } from '{{namespace}}/lib';
|
|
4
|
+
import { createTheme, PaletteMode } from '@mui/material/styles';
|
|
5
|
+
|
|
6
|
+
export const createAppTheme = (mode: PaletteMode) => createTheme({
|
|
7
|
+
palette: {
|
|
8
|
+
mode,
|
|
9
|
+
primary: {
|
|
10
|
+
main: AppConstants.logo_primary_color,
|
|
11
|
+
light: AppConstants.primary_text_light,
|
|
12
|
+
dark: AppConstants.primary_text_dark,
|
|
13
|
+
contrastText: '#ffffff',
|
|
14
|
+
},
|
|
15
|
+
secondary: {
|
|
16
|
+
main: AppConstants.logo_secondary_text,
|
|
17
|
+
light: AppConstants.secondary_text_light,
|
|
18
|
+
dark: AppConstants.secondary_text_dark,
|
|
19
|
+
contrastText: '#000000',
|
|
20
|
+
},
|
|
21
|
+
background: mode === 'light' ? {
|
|
22
|
+
default: '#f8f9fa',
|
|
23
|
+
paper: '#ffffff',
|
|
24
|
+
} : {
|
|
25
|
+
default: '#121212',
|
|
26
|
+
paper: '#1e1e1e',
|
|
27
|
+
},
|
|
28
|
+
text: {
|
|
29
|
+
primary: AppConstants.logo_primary_text,
|
|
30
|
+
},
|
|
31
|
+
error: {
|
|
32
|
+
main: AppConstants.failure_color,
|
|
33
|
+
},
|
|
34
|
+
warning: {
|
|
35
|
+
main: AppConstants.warning_color,
|
|
36
|
+
},
|
|
37
|
+
success: {
|
|
38
|
+
main: AppConstants.success_color,
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
typography: {
|
|
42
|
+
fontFamily: "'Roboto', sans-serif",
|
|
43
|
+
h1: {
|
|
44
|
+
fontFamily: "'ConneqtRegular', sans-serif",
|
|
45
|
+
fontWeight: 400,
|
|
46
|
+
},
|
|
47
|
+
h2: {
|
|
48
|
+
fontFamily: "'ConneqtRegular', sans-serif",
|
|
49
|
+
fontWeight: 400,
|
|
50
|
+
},
|
|
51
|
+
h3: {
|
|
52
|
+
fontFamily: "'ConneqtRegular', sans-serif",
|
|
53
|
+
fontWeight: 400,
|
|
54
|
+
},
|
|
55
|
+
h4: {
|
|
56
|
+
fontFamily: "'ConneqtRegular', sans-serif",
|
|
57
|
+
fontWeight: 400,
|
|
58
|
+
},
|
|
59
|
+
h5: {
|
|
60
|
+
fontFamily: "'ConneqtRegular', sans-serif",
|
|
61
|
+
fontWeight: 400,
|
|
62
|
+
},
|
|
63
|
+
h6: {
|
|
64
|
+
fontFamily: "'ConneqtRegular', sans-serif",
|
|
65
|
+
fontWeight: 400,
|
|
66
|
+
},
|
|
67
|
+
subtitle1: {
|
|
68
|
+
fontFamily: "'ConneqtRegular', sans-serif",
|
|
69
|
+
fontWeight: 400,
|
|
70
|
+
textTransform: 'uppercase',
|
|
71
|
+
},
|
|
72
|
+
body1: {
|
|
73
|
+
fontFamily: "'Roboto', sans-serif",
|
|
74
|
+
fontWeight: 400,
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
components: {
|
|
78
|
+
MuiButton: {
|
|
79
|
+
styleOverrides: {
|
|
80
|
+
root: {
|
|
81
|
+
borderRadius: '4px',
|
|
82
|
+
textTransform: 'none',
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// Export a light theme as default for backward compatibility
|
|
90
|
+
const theme = createAppTheme('light');
|
|
91
|
+
export default theme;
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 800">
|
|
3
|
+
<defs>
|
|
4
|
+
<style>
|
|
5
|
+
.cls-1 {
|
|
6
|
+
fill: #433834;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.cls-2, .cls-3, .cls-4, .cls-5, .cls-6 {
|
|
10
|
+
mix-blend-mode: multiply;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.cls-2, .cls-5 {
|
|
14
|
+
opacity: .2;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.cls-2, .cls-7 {
|
|
18
|
+
fill: #bebfaf;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.cls-3, .cls-4, .cls-6 {
|
|
22
|
+
opacity: .3;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.cls-8 {
|
|
26
|
+
fill: #9ca6b2;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.cls-9 {
|
|
30
|
+
fill: #d5561e;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.cls-10 {
|
|
34
|
+
isolation: isolate;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.cls-4 {
|
|
38
|
+
fill: #60260f;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.cls-11 {
|
|
42
|
+
fill: #fcfcf5;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.cls-12 {
|
|
46
|
+
fill: #352b28;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.cls-5 {
|
|
50
|
+
fill: #a7a9ac;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.cls-6 {
|
|
54
|
+
fill: #4d5156;
|
|
55
|
+
}
|
|
56
|
+
</style>
|
|
57
|
+
</defs>
|
|
58
|
+
<g class="cls-10">
|
|
59
|
+
<g id="Layer_2" data-name="Layer 2">
|
|
60
|
+
<ellipse class="cls-5" cx="422.34" cy="641.36" rx="190.28" ry="38.87"/>
|
|
61
|
+
<g>
|
|
62
|
+
<g>
|
|
63
|
+
<path class="cls-8" d="M474.23,603.27c0-1.54.09-3.07.26-4.59.23-2.03-1.57-3.84-4.11-4.16-5.67-.7-11.71-1.08-17.99-1.08-32.28,0-58.45,10.03-58.45,22.4s26.17,22.4,58.45,22.4c10.62,0,20.57-1.09,29.14-2.98,2.51-.56,3.71-2.83,2.39-4.61-9.33-12.64,11.48-11.25,9.57-17.3-1.28-4.05-19.27-5.77-19.27-10.09Z"/>
|
|
64
|
+
<g class="cls-3">
|
|
65
|
+
<path class="cls-7" d="M489.51,617.85c-36.17.26-64.58,2.85-64.58,6,0,2.98,25.23,5.45,58.41,5.94-5.01-7.56,1.45-9.75,6.17-11.94Z"/>
|
|
66
|
+
</g>
|
|
67
|
+
<g class="cls-3">
|
|
68
|
+
<path class="cls-7" d="M424.93,603.63c0,4.4,29.8,7.99,67.21,8.2-4.47-3.03-17.9-4.82-17.9-8.56,0-1.54.09-3.07.26-4.59.12-1.07-.33-2.08-1.15-2.84-28.12,1.08-48.41,4.16-48.41,7.79Z"/>
|
|
69
|
+
</g>
|
|
70
|
+
<path class="cls-8" d="M404.26,617.51h0c-4.67,1.15-9.63-.91-11.09-4.6l-31.76-80.65,16.91-4.16,31.76,80.65c1.45,3.69-1.15,7.62-5.82,8.76Z"/>
|
|
71
|
+
<g class="cls-3">
|
|
72
|
+
<path class="cls-7" d="M403.4,612.9l-31.76-80.65,7.58-1.87-.9-2.3-16.91,4.16,31.76,80.65c1.45,3.69,6.42,5.75,11.09,4.6.92-.23,1.75-.56,2.49-.98-1.53-.86-2.74-2.1-3.34-3.63Z"/>
|
|
73
|
+
</g>
|
|
74
|
+
<path class="cls-8" d="M364.15,554.59c3.13,8.54,10.63,10.08,18.12,8.36,7.49-1.72,12.14-6.03,9.01-14.57-3.13-8.54-12.85-18.07-20.35-16.35s-9.92,14.03-6.79,22.57Z"/>
|
|
75
|
+
<path class="cls-11" d="M440.5,490.46c0,24.38-11.57,9.98-42.4,49.12-6.99,8.88-40.02,8.39-50.99-1.47-11.39-10.24-.6-30.26-.6-42.67,0-24.38,21.04-44.14,47-44.14s47,14.79,47,39.17Z"/>
|
|
76
|
+
</g>
|
|
77
|
+
<path class="cls-6" d="M482.25,627.86s-.03-.06-.04-.09c-.27-.59-.45-1.14-.56-1.66,0-.03-.01-.06-.02-.08-.1-.52-.13-1-.1-1.45,0-.02,0-.03,0-.05.07-.75.31-1.41.68-2,.01-.02.02-.04.04-.06.22-.34.49-.66.79-.96.03-.03.05-.05.08-.08.19-.18.39-.36.61-.52.02-.01.03-.03.05-.04.11-.09.22-.17.34-.25.04-.03.09-.06.14-.09.19-.13.39-.26.59-.38.06-.04.12-.08.19-.11.11-.07.23-.13.34-.2.1-.05.19-.11.29-.16.16-.09.32-.17.48-.26.1-.05.2-.1.29-.15.1-.05.2-.1.3-.15.18-.09.36-.17.53-.25.09-.04.18-.08.27-.13.16-.08.33-.15.49-.22.05-.02.11-.05.16-.07.25-.11.49-.22.74-.33.18-.08.35-.16.53-.24,2.6-1.21,4.68-2.41,4.02-4.51-.84-2.66-8.87-4.31-14.3-6.35,0,0,0,0,0,0-.24-.09-.47-.18-.7-.27-.04-.01-.07-.03-.11-.04-.2-.08-.39-.16-.57-.24-.05-.02-.09-.04-.14-.06-.18-.08-.35-.16-.51-.24-.04-.02-.09-.04-.13-.06-.18-.09-.36-.18-.53-.27-.02,0-.04-.02-.06-.03-.19-.1-.37-.21-.54-.32-.01,0-.02-.01-.03-.02-.15-.1-.29-.19-.42-.29-.04-.03-.08-.06-.12-.1-.09-.07-.18-.15-.27-.23-.04-.04-.08-.08-.12-.12-.07-.07-.14-.14-.2-.21-.04-.04-.07-.09-.1-.13-.05-.07-.1-.15-.14-.22-.03-.04-.05-.09-.08-.13-.04-.08-.07-.16-.1-.24-.01-.04-.03-.08-.04-.12-.03-.12-.05-.25-.05-.37,0-1.54.09-3.07.26-4.59.01-.13.02-.26.02-.39,0-.03,0-.06,0-.1,0-.1-.01-.19-.02-.29,0-.03-.01-.06-.02-.1-.02-.1-.03-.19-.06-.28,0-.03-.02-.05-.02-.08-.03-.1-.06-.2-.1-.29,0-.02-.02-.04-.02-.05-.04-.1-.09-.21-.15-.3,0-.01-.01-.02-.02-.03-.06-.11-.13-.21-.2-.31,0,0,0,0,0-.01-.08-.11-.16-.21-.25-.31,0,0,0,0,0,0-.09-.1-.19-.2-.29-.3,0,0,0,0,0,0h0c-.73-.68-1.76-1.16-2.97-1.31-5.67-.7-11.71-1.08-17.99-1.08-18.17,0-34.4,3.18-45.12,8.16l-16.89-42.89c2.03-2.4,2.59-5.76.91-10.34-.49-1.35-1.15-2.72-1.94-4.06,3.95-1.05,7.09-2.63,8.75-4.73,30.83-39.14,42.4-24.74,42.4-49.12s-21.04-39.17-47-39.17-47,19.76-47,44.14c0,12.41-10.78,32.44.6,42.67,3.52,3.17,9.32,5.36,15.8,6.6-.27,3.34.14,6.85,1.25,9.89,1.88,5.14,5.35,7.74,9.45,8.62l19.57,49.69c.09.23.2.46.31.67.17.31.37.6.58.88-.07.46-.12.92-.12,1.38,0,12.37,26.17,22.4,58.45,22.4,10.62,0,20.57-1.09,29.14-2.98,2.51-.56,3.71-2.83,2.39-4.61-.22-.3-.41-.58-.59-.86h0c-.15-.22-.28-.43-.41-.64-.03-.05-.06-.1-.09-.15-.23-.39-.43-.77-.59-1.13Z"/>
|
|
78
|
+
</g>
|
|
79
|
+
<path class="cls-11" d="M583.23,393.7c0-31.91-14.48-151.42-1.02-180.35,3.34-7.17,7.01-12.76,10.69-15.5,4.25-3.17-1.45-27.18-7.16-37.24-9.06-15.95-31.5-32.22-70.35-31.35-49.31,1.11-59.79,65.78-64.66,114.88-1.71,17.22-8.38,33.59-19.28,47.04-24.5,30.22-282.51,32.6-276.03,44.9,87.85,166.81,211.62,187.5,275.59,187.5s152.23-72.02,152.23-129.88Z"/>
|
|
80
|
+
<path class="cls-12" d="M498.56,164.68c-.74-.4.6-1.19,1.38-.88,8.67,3.44,14.63,6.95,24.89,8.14,3.49.41,21.48-.97,21.97,2.41s-3.04,7.61-4.5,9.11c-1.8,1.84-4.63,3.5-8.28,2.45-11.15-3.21-23.68-14.89-35.46-21.23Z"/>
|
|
81
|
+
<path class="cls-2" d="M593.41,197.28c.08-.11.15-.23.22-.36.04-.07.07-.16.11-.24.06-.13.11-.27.16-.42.03-.09.06-.19.09-.29.04-.16.08-.33.12-.5.02-.1.04-.21.06-.32.03-.2.06-.4.09-.61.01-.1.03-.2.04-.31.03-.27.05-.55.06-.84,0-.06,0-.12.01-.18.03-.74.02-1.53-.03-2.39,0-.07,0-.14-.01-.21-.02-.36-.05-.72-.08-1.1,0-.09-.02-.19-.03-.28-.03-.37-.07-.74-.12-1.12-.01-.09-.02-.18-.03-.27-.05-.41-.1-.82-.16-1.24,0-.06-.02-.13-.03-.19-.37-2.53-.93-5.28-1.62-8.06-14.52,10.95-7.32,30.8-53.77,48.91-12.21,4.76,26.78,8.73,43.96,147.69-2.82-45.76-11.76-136.83-.24-161.59,3.34-7.17,7.01-12.76,10.69-15.5.14-.11.27-.24.4-.4.04-.05.07-.11.11-.17Z"/>
|
|
82
|
+
<path class="cls-9" d="M669.22,195.54c-.9-14.38-6.37-22.75-15.74-24.4-11.04-1.94-17.36,4.16-38.14,1.91-11.8-1.28-29.51-16.25-38.23-13.33-.19.06-.36.14-.54.22,1.18,9.92,1.83,20.82,1.83,32.27v.06c0,3.32,2.25,6.03,5.05,6.03h76.86c2.74,0,4.96,2.63,4.96,5.87,2.11,2.13,4.13-5.58,3.94-8.62Z"/>
|
|
83
|
+
<path class="cls-4" d="M578.17,180.38c.15,3.86.24,7.81.24,11.82v.06c0,3.32,2.25,6.03,5.05,6.03h76.86c.72,0,1.41.19,2.02.52-7.28-6.71-13.11-6.27-51.08-8.31-15.83-.85-21.28-9.62-33.1-10.12Z"/>
|
|
84
|
+
<path class="cls-4" d="M583.23,167.25s13.22,1.2,12.27,6.47c-.94,5.26-12.27-6.47-12.27-6.47Z"/>
|
|
85
|
+
<path class="cls-1" d="M475.91,325.57l-44.46-34.39-204.19,5.87c-22.9.66-45.08,8.15-63.69,21.5l-40.55,29.1,245.71,107.73c13.86,6.08,30.06,2.42,39.97-9.01l71.06-82c10.09-11.64,8.32-29.37-3.86-38.79Z"/>
|
|
86
|
+
<path class="cls-1" d="M228.43,408.36c-46.45-5.79-108.22-20.11-150.98-56.31-5.65-4.78-1.74-13.94,5.62-13.23,37.28,3.59,57.44,2.96,97.7-12.42l47.67,81.96Z"/>
|
|
87
|
+
<path class="cls-6" d="M144.52,332.23l-21.5,15.43,245.71,107.73c13.86,6.08,30.06,2.42,39.97-9.01l44.62-51.49c-127.73-.17-240.55-24.9-308.8-62.65Z"/>
|
|
88
|
+
<g>
|
|
89
|
+
<path class="cls-8" d="M502.63,634.23c0-1.26.09-2.51.26-3.74.23-1.66-1.57-3.14-4.11-3.39-5.67-.57-11.71-.88-17.99-.88-32.28,0-58.45,8.18-58.45,18.28s26.17,18.28,58.45,18.28c10.62,0,20.57-.89,29.14-2.44,2.51-.45,3.71-2.31,2.39-3.76-9.33-10.31,11.48-9.18,9.57-14.12-1.28-3.3-19.27-4.71-19.27-8.23Z"/>
|
|
90
|
+
<g class="cls-3">
|
|
91
|
+
<path class="cls-7" d="M517.91,646.13c-36.17.21-64.58,2.32-64.58,4.9,0,2.43,25.23,4.45,58.41,4.85-5.01-6.17,1.45-7.96,6.17-9.75Z"/>
|
|
92
|
+
</g>
|
|
93
|
+
<g class="cls-3">
|
|
94
|
+
<path class="cls-7" d="M453.33,634.53c0,3.59,29.8,6.52,67.21,6.69-4.47-2.47-17.9-3.94-17.9-6.98,0-1.26.09-2.51.26-3.74.12-.88-.33-1.7-1.15-2.32-28.12.88-48.41,3.39-48.41,6.36Z"/>
|
|
95
|
+
</g>
|
|
96
|
+
<path class="cls-8" d="M432.66,647.69h0c-4.67,1.28-9.63-1.02-11.09-5.13l-31.76-89.8,16.91-4.63,31.76,89.8c1.45,4.11-1.15,8.48-5.82,9.76Z"/>
|
|
97
|
+
<g class="cls-3">
|
|
98
|
+
<path class="cls-7" d="M431.8,642.56l-31.76-89.8,7.58-2.08-.9-2.56-16.91,4.63,31.76,89.8c1.45,4.11,6.42,6.4,11.09,5.13.92-.25,1.75-.62,2.49-1.09-1.53-.95-2.74-2.34-3.34-4.04Z"/>
|
|
99
|
+
</g>
|
|
100
|
+
<path class="cls-8" d="M392.55,577.64c3.13,9.51,10.63,11.22,18.12,9.31,7.49-1.91,12.14-6.72,9.01-16.23-3.13-9.51-12.85-20.12-20.35-18.21-7.49,1.91-9.92,15.62-6.79,25.13Z"/>
|
|
101
|
+
<path class="cls-11" d="M502.59,500.61c-26.16,17.71-45.26,16.73-76.09,60.31-6.99,9.89-40.02,9.35-50.99-1.64-11.39-11.4-.6-33.69-.6-47.51,0-27.15,21.04-49.15,47-49.15s103.17,22.78,80.69,38Z"/>
|
|
102
|
+
<g class="cls-3">
|
|
103
|
+
<path class="cls-7" d="M374.9,511.77c0-11.32,3.67-21.73,9.81-30.04-48.73-7.75-103.44-25.32-163.2-51.21,51.77,54.95,107.23,78.18,152.85,87.43.33-2.19.54-4.27.54-6.18Z"/>
|
|
104
|
+
</g>
|
|
105
|
+
</g>
|
|
106
|
+
</g>
|
|
107
|
+
</g>
|
|
108
|
+
</svg>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|