Browse Source

feat(111): 微前端项目

master
丁翠 7 months ago
parent
commit
984a0993e1
371 changed files with 57851 additions and 0 deletions
  1. +45
    -0
      gpt-mf-demo/.gitignore
  2. +17
    -0
      gpt-mf-demo/mfe1/.browserslistrc
  3. +16
    -0
      gpt-mf-demo/mfe1/.editorconfig
  4. +45
    -0
      gpt-mf-demo/mfe1/.gitignore
  5. +27
    -0
      gpt-mf-demo/mfe1/README.md
  6. +124
    -0
      gpt-mf-demo/mfe1/angular.json
  7. +44
    -0
      gpt-mf-demo/mfe1/karma.conf.js
  8. +11941
    -0
      gpt-mf-demo/mfe1/package-lock.json
  9. +46
    -0
      gpt-mf-demo/mfe1/package.json
  10. +19
    -0
      gpt-mf-demo/mfe1/src/app/app-routing.module.ts
  11. +1
    -0
      gpt-mf-demo/mfe1/src/app/app.component.html
  12. +13
    -0
      gpt-mf-demo/mfe1/src/app/app.component.scss
  13. +35
    -0
      gpt-mf-demo/mfe1/src/app/app.component.spec.ts
  14. +24
    -0
      gpt-mf-demo/mfe1/src/app/app.component.ts
  15. +23
    -0
      gpt-mf-demo/mfe1/src/app/app.module.ts
  16. +55
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/directives/element-src.directive.ts
  17. +13
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/layout/home/home.component.html
  18. +35
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/layout/home/home.component.scss
  19. +25
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/layout/home/home.component.spec.ts
  20. +16
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/layout/home/home.component.ts
  21. +26
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/layout/layout-routing.module.ts
  22. +5
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/layout/layout.component.html
  23. +1
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/layout/layout.component.scss
  24. +25
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/layout/layout.component.spec.ts
  25. +27
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/layout/layout.component.ts
  26. +9
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/layout/layout.module.ts
  27. +26
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/microfrontend-routing.module.ts
  28. +18
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/microfrontend.module.ts
  29. +1
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/microfrontend/microfrontend.component.html
  30. +0
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/microfrontend/microfrontend.component.scss
  31. +25
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/microfrontend/microfrontend.component.spec.ts
  32. +15
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/microfrontend/microfrontend.component.ts
  33. +1
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/page-not-found/page-not-found.component.html
  34. +0
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/page-not-found/page-not-found.component.scss
  35. +25
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/page-not-found/page-not-found.component.spec.ts
  36. +15
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/page-not-found/page-not-found.component.ts
  37. +10
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/shared/shared.module.ts
  38. +10
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/task/detail/detail-routing.module.ts
  39. +1
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/task/detail/detail.component.html
  40. +0
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/task/detail/detail.component.scss
  41. +25
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/task/detail/detail.component.spec.ts
  42. +15
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/task/detail/detail.component.ts
  43. +17
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/task/detail/detail.module.ts
  44. +1
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/task/dynamic-component/dynamic-component.component.html
  45. +0
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/task/dynamic-component/dynamic-component.component.scss
  46. +25
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/task/dynamic-component/dynamic-component.component.spec.ts
  47. +15
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/task/dynamic-component/dynamic-component.component.ts
  48. +10
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/task/list/list.component.html
  49. +35
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/task/list/list.component.scss
  50. +25
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/task/list/list.component.spec.ts
  51. +20
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/task/list/list.component.ts
  52. +4
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/task/task-content/task-content.component.html
  53. +0
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/task/task-content/task-content.component.scss
  54. +25
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/task/task-content/task-content.component.spec.ts
  55. +17
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/task/task-content/task-content.component.ts
  56. +27
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/task/task-routing.module.ts
  57. +2
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/task/task.component.html
  58. +0
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/task/task.component.scss
  59. +25
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/task/task.component.spec.ts
  60. +16
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/task/task.component.ts
  61. +20
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/task/task.module.ts
  62. +22
    -0
      gpt-mf-demo/mfe1/src/app/microfrontend/util/asset-url.ts
  63. +0
    -0
      gpt-mf-demo/mfe1/src/assets/.gitkeep
  64. BIN
      gpt-mf-demo/mfe1/src/assets/img/appealed.png
  65. BIN
      gpt-mf-demo/mfe1/src/assets/img/artificial.png
  66. BIN
      gpt-mf-demo/mfe1/src/assets/img/bg.png
  67. BIN
      gpt-mf-demo/mfe1/src/assets/img/confirm.png
  68. +281
    -0
      gpt-mf-demo/mfe1/src/assets/img/dwLogo.svg
  69. BIN
      gpt-mf-demo/mfe1/src/assets/img/fail.png
  70. BIN
      gpt-mf-demo/mfe1/src/assets/img/logo.png
  71. BIN
      gpt-mf-demo/mfe1/src/assets/img/other.png
  72. BIN
      gpt-mf-demo/mfe1/src/assets/img/receivable.png
  73. BIN
      gpt-mf-demo/mfe1/src/assets/img/success.png
  74. BIN
      gpt-mf-demo/mfe1/src/assets/img/user-pic.png
  75. +12
    -0
      gpt-mf-demo/mfe1/src/bootstrap.ts
  76. +3
    -0
      gpt-mf-demo/mfe1/src/environments/environment.prod.ts
  77. +16
    -0
      gpt-mf-demo/mfe1/src/environments/environment.ts
  78. BIN
      gpt-mf-demo/mfe1/src/favicon.ico
  79. +13
    -0
      gpt-mf-demo/mfe1/src/index.html
  80. +2
    -0
      gpt-mf-demo/mfe1/src/main.ts
  81. +65
    -0
      gpt-mf-demo/mfe1/src/polyfills.ts
  82. +15
    -0
      gpt-mf-demo/mfe1/src/styles.scss
  83. +27
    -0
      gpt-mf-demo/mfe1/src/test.ts
  84. +15
    -0
      gpt-mf-demo/mfe1/tsconfig.app.json
  85. +38
    -0
      gpt-mf-demo/mfe1/tsconfig.json
  86. +18
    -0
      gpt-mf-demo/mfe1/tsconfig.spec.json
  87. +77
    -0
      gpt-mf-demo/mfe1/webpack.config.js
  88. +1
    -0
      gpt-mf-demo/mfe1/webpack.prod.config.js
  89. +17
    -0
      gpt-mf-demo/mfe2/.browserslistrc
  90. +16
    -0
      gpt-mf-demo/mfe2/.editorconfig
  91. +45
    -0
      gpt-mf-demo/mfe2/.gitignore
  92. +27
    -0
      gpt-mf-demo/mfe2/README.md
  93. +123
    -0
      gpt-mf-demo/mfe2/angular.json
  94. +44
    -0
      gpt-mf-demo/mfe2/karma.conf.js
  95. +11852
    -0
      gpt-mf-demo/mfe2/package-lock.json
  96. +43
    -0
      gpt-mf-demo/mfe2/package.json
  97. +19
    -0
      gpt-mf-demo/mfe2/src/app/app-routing.module.ts
  98. +2
    -0
      gpt-mf-demo/mfe2/src/app/app.component.html
  99. +0
    -0
      gpt-mf-demo/mfe2/src/app/app.component.scss
  100. +35
    -0
      gpt-mf-demo/mfe2/src/app/app.component.spec.ts

+ 45
- 0
gpt-mf-demo/.gitignore View File

@ -0,0 +1,45 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.
# compiled output
/dist
/tmp
/out-tsc
# Only exists if Bazel was run
/bazel-out
# dependencies
/node_modules
# profiling files
chrome-profiler-events*.json
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.history/*
# misc
/.sass-cache
/connect.lock
/coverage
/libpeerconnection.log
npm-debug.log
yarn-error.log
testem.log
/typings
# System Files
.DS_Store
Thumbs.db

+ 17
- 0
gpt-mf-demo/mfe1/.browserslistrc View File

@ -0,0 +1,17 @@
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
# For additional information regarding the format and rule options, please see:
# https://github.com/browserslist/browserslist#queries
# For the full list of supported browsers by the Angular framework, please see:
# https://angular.io/guide/browser-support
# You can see what browsers were selected by your queries by running:
# npx browserslist
last 1 Chrome version
last 1 Firefox version
last 2 Edge major versions
last 2 Safari major versions
last 2 iOS major versions
Firefox ESR
not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line.

+ 16
- 0
gpt-mf-demo/mfe1/.editorconfig View File

@ -0,0 +1,16 @@
# Editor configuration, see https://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
[*.ts]
quote_type = single
[*.md]
max_line_length = off
trim_trailing_whitespace = false

+ 45
- 0
gpt-mf-demo/mfe1/.gitignore View File

@ -0,0 +1,45 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.
# compiled output
/dist
/tmp
/out-tsc
# Only exists if Bazel was run
/bazel-out
# dependencies
/node_modules
# profiling files
chrome-profiler-events*.json
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.history/*
# misc
/.sass-cache
/connect.lock
/coverage
/libpeerconnection.log
npm-debug.log
yarn-error.log
testem.log
/typings
# System Files
.DS_Store
Thumbs.db

+ 27
- 0
gpt-mf-demo/mfe1/README.md View File

@ -0,0 +1,27 @@
# Remote
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 12.2.8.
## Development server
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
## Code scaffolding
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
## Build
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory.
## Running unit tests
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
## Running end-to-end tests
Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities.
## Further help
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.

+ 124
- 0
gpt-mf-demo/mfe1/angular.json View File

@ -0,0 +1,124 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"cli": {
"analytics": false
},
"version": 1,
"newProjectRoot": "projects",
"projects": {
"remote": {
"projectType": "application",
"schematics": {
"@schematics/angular:component": {
"style": "scss"
},
"@schematics/angular:application": {
"strict": true
}
},
"root": "",
"sourceRoot": "src",
"prefix": "remote",
"architect": {
"build": {
"builder": "ngx-build-plus:browser",
"options": {
"outputPath": "dist/remote",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"inlineStyleLanguage": "scss",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.scss"
],
"scripts": [],
"extraWebpackConfig": "webpack.config.js",
"commonChunk": false
},
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "500kb",
"maximumError": "1mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "2kb",
"maximumError": "4kb"
}
],
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"outputHashing": "all",
"extraWebpackConfig": "webpack.prod.config.js"
},
"development": {
"buildOptimizer": false,
"optimization": false,
"vendorChunk": true,
"extractLicenses": false,
"sourceMap": true,
"namedChunks": true
}
},
"defaultConfiguration": "production"
},
"serve": {
"builder": "ngx-build-plus:dev-server",
"configurations": {
"production": {
"browserTarget": "remote:build:production",
"extraWebpackConfig": "webpack.prod.config.js"
},
"development": {
"browserTarget": "remote:build:development"
}
},
"defaultConfiguration": "development",
"options": {
"port": 3000,
"extraWebpackConfig": "webpack.config.js"
}
},
"extract-i18n": {
"builder": "ngx-build-plus:extract-i18n",
"options": {
"browserTarget": "remote:build",
"extraWebpackConfig": "webpack.config.js"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.spec.json",
"karmaConfig": "karma.conf.js",
"inlineStyleLanguage": "scss",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.scss",
"node_modules/ng-zorro-antd/ng-zorro-antd.min.css"
],
"scripts": []
}
}
}
}
},
"defaultProject": "remote"
}

+ 44
- 0
gpt-mf-demo/mfe1/karma.conf.js View File

@ -0,0 +1,44 @@
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage'),
require('@angular-devkit/build-angular/plugins/karma')
],
client: {
jasmine: {
// you can add configuration options for Jasmine here
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
// for example, you can disable the random execution with `random: false`
// or set a specific seed with `seed: 4321`
},
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
jasmineHtmlReporter: {
suppressAll: true // removes the duplicated traces
},
coverageReporter: {
dir: require('path').join(__dirname, './coverage/remote'),
subdir: '.',
reporters: [
{ type: 'html' },
{ type: 'text-summary' }
]
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
restartOnFileChange: true
});
};

+ 11941
- 0
gpt-mf-demo/mfe1/package-lock.json
File diff suppressed because it is too large
View File


+ 46
- 0
gpt-mf-demo/mfe1/package.json View File

@ -0,0 +1,46 @@
{
"name": "remote",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve --port 3001 --open",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test",
"run:all": "node node_modules/@angular-architects/module-federation/src/server/mf-dev-server.js"
},
"private": true,
"dependencies": {
"@angular-architects/module-federation": "^12.5.3",
"@angular/animations": "~12.2.0",
"@angular/common": "~12.2.0",
"@angular/compiler": "~12.2.0",
"@angular/core": "~12.2.0",
"@angular/forms": "~12.2.0",
"@angular/platform-browser": "~12.2.0",
"@angular/platform-browser-dynamic": "~12.2.0",
"@angular/router": "~12.2.0",
"my-shared": "file:../shell/dist/my-shared",
"less": "^4.2.0",
"less-loader": "^12.2.0",
"ng-zorro-antd": "^12.1.1",
"rxjs": "~6.6.0",
"tslib": "^2.3.0",
"zone.js": "~0.11.4"
},
"devDependencies": {
"@angular-devkit/build-angular": "~12.2.8",
"@angular/cli": "~12.2.8",
"@angular/compiler-cli": "~12.2.0",
"@types/jasmine": "~3.8.0",
"@types/node": "^12.11.1",
"jasmine-core": "~3.8.0",
"karma": "~6.3.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage": "~2.0.3",
"karma-jasmine": "~4.0.0",
"karma-jasmine-html-reporter": "~1.7.0",
"typescript": "~4.3.5",
"url-loader": "^4.1.1"
}
}

+ 19
- 0
gpt-mf-demo/mfe1/src/app/app-routing.module.ts View File

@ -0,0 +1,19 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [
{
path: '',
loadChildren: () =>
import('./microfrontend/microfrontend.module').then(
(m) => m.MicrofrontendModule
),
pathMatch: 'prefix',
},
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
})
export class AppRoutingModule { }

+ 1
- 0
gpt-mf-demo/mfe1/src/app/app.component.html View File

@ -0,0 +1 @@
<router-outlet></router-outlet>

+ 13
- 0
gpt-mf-demo/mfe1/src/app/app.component.scss View File

@ -0,0 +1,13 @@
:host {
display: block;
padding: 16px;
font-size: 14px;
.button{
height: 32px;
background-color: #b60816;
border: none;
font-weight: 700;
color: aliceblue;
}
}

+ 35
- 0
gpt-mf-demo/mfe1/src/app/app.component.spec.ts View File

@ -0,0 +1,35 @@
import { TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [
RouterTestingModule
],
declarations: [
AppComponent
],
}).compileComponents();
});
it('should create the app', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
});
it(`should have as title 'remote'`, () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app.title).toEqual('remote');
});
it('should render title', () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.nativeElement as HTMLElement;
expect(compiled.querySelector('.content span')?.textContent).toContain('remote app is running!');
});
});

+ 24
- 0
gpt-mf-demo/mfe1/src/app/app.component.ts View File

@ -0,0 +1,24 @@
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent implements OnInit,OnDestroy {
ngOnInit(): void {
//Called after the constructor, initializing input properties, and the first call to ngOnChanges.
//Add 'implements OnInit' to the class.
console.log('remote AppComponent ngOnInit');
}
ngOnDestroy(): void {
console.log('remote AppComponent ngOnDestroy');
}
title = 'remote';
goToRemote1():void {
}
}

+ 23
- 0
gpt-mf-demo/mfe1/src/app/app.module.ts View File

@ -0,0 +1,23 @@
import { MicrofrontendModule } from './microfrontend/microfrontend.module';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
// import { NzTableModule } from 'ng-zorro-antd/table';
// import { NzButtonModule } from 'ng-zorro-antd/button';
import { NzListModule } from 'ng-zorro-antd/list';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
@NgModule({
declarations: [AppComponent],
imports: [
// NzTableModule,
// NzButtonModule,
NzListModule,
BrowserModule,
AppRoutingModule,
MicrofrontendModule,
],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}

+ 55
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/directives/element-src.directive.ts View File

@ -0,0 +1,55 @@
import {
Directive,
ElementRef,
Input,
OnChanges,
Renderer2,
SimpleChanges,
} from '@angular/core';
import { assetUrl } from '../util/asset-url';
@Directive({
// eslint-disable-next-line @angular-eslint/directive-selector
selector:
'img[src],audio[src],embed[src],iframe[src],input[src],script[src],source[src],track[src],video[src]',
})
export class MfaElementSrcDirective implements OnChanges {
private _src: string = '';
@Input() src: string = '';
constructor(private element: ElementRef, private renderer2: Renderer2) {}
setSrc(src: string): void {
//debugger;
// 非微前端環境不轉換 判断是否是微前端环境
if (!(window as any).__DW_MFA_ENV__) {
this.renderer2.setAttribute(this.element.nativeElement, 'src', src);
return;
}
// 絕對路徑,不轉換
if (
src.startsWith('http://') ||
src.startsWith('https://') ||
src.startsWith('//') ||
src.startsWith('data:')
) {
this.renderer2.setAttribute(this.element.nativeElement, 'src', src);
return;
}
if (src && src.startsWith('./')) {
src = assetUrl(src.substring(1));
} else {
src = assetUrl(src);
}
this.renderer2.setAttribute(this.element.nativeElement, 'src', src);
}
ngOnChanges(changes: SimpleChanges): void {
if (this._src !== changes.src.currentValue) {
this._src = changes.src.currentValue;
this.setSrc(this._src);
}
}
}

+ 13
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/layout/home/home.component.html View File

@ -0,0 +1,13 @@
<div class="container">
<header>
<h1>用户信息</h1>
</header>
<main>
<div class="card" *ngFor="let item of cards">
{{item}}
</div>
</main>
<footer>
底部内容
</footer>
</div>

+ 35
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/layout/home/home.component.scss View File

@ -0,0 +1,35 @@
.container {
display: flex;
flex-direction: column;
min-height: 100vh;
}
header {
background-color: #1a81e8;
padding: 20px;
text-align: center;
}
main {
flex: 1;
display: flex;
flex-wrap: wrap;
justify-content: space-around;
background-color: #9f9b9b;
}
.card {
width: 320px;
height: 180px;
padding: 16px;
background-image: linear-gradient(180deg, #f3f6f8 0%, #fefefe 100%);
box-shadow: 0 6px 16px 0 #00194a1a;
border-radius: 2px;
}
footer {
background-color: #151618;
padding: 20px;
text-align: center;
}

+ 25
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/layout/home/home.component.spec.ts View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { HomeComponent } from './home.component';
describe('HomeComponent', () => {
let component: HomeComponent;
let fixture: ComponentFixture<HomeComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ HomeComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(HomeComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

+ 16
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/layout/home/home.component.ts View File

@ -0,0 +1,16 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {
cards = ['卡片1', '卡片2', '卡片3', '卡片4', '卡片5'];
constructor() { }
ngOnInit(): void {
}
}

+ 26
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/layout/layout-routing.module.ts View File

@ -0,0 +1,26 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { LayoutComponent } from './layout.component';
const routes: Routes = [
{
path: '',
component: LayoutComponent,
children: [
{
path: '',
loadChildren: () =>
import('../task/task.module').then(
(m) => m.TaskModule
),
pathMatch: 'prefix',
}
]
},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class LayoutRoutingModule { }

+ 5
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/layout/layout.component.html View File

@ -0,0 +1,5 @@
<h3>到款认领系统</h3>
<!-- <img style="width:20px;height:20px" src="assets/img/logo.png" alt="" srcset=""> -->
<button class="button" (click)="goToRemote1()" style="margin-bottom: 20px;">goToShell</button>
<router-outlet></router-outlet>

+ 1
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/layout/layout.component.scss View File

@ -0,0 +1 @@
// @import '../../../../src/styles.scss';

+ 25
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/layout/layout.component.spec.ts View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { LayoutComponent } from './layout.component';
describe('LayoutComponent', () => {
let component: LayoutComponent;
let fixture: ComponentFixture<LayoutComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ LayoutComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(LayoutComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

+ 27
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/layout/layout.component.ts View File

@ -0,0 +1,27 @@
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { MySharedService } from 'my-shared';
@Component({
selector: 'remote-layout',
templateUrl: './layout.component.html',
styleUrls: ['./layout.component.scss'],
})
export class LayoutComponent implements OnInit, OnDestroy {
constructor(
private router: Router,
private mySharedService: MySharedService
) {}
ngOnInit(): void {
console.log(this);
console.log('Remote LayoutComponent Init');
}
ngOnDestroy(): void {
console.log('Remote LayoutComponent Destroy');
}
goToRemote1(): void {
this.mySharedService.setData('我是到款认领系统发送过来的数据');
// this.router.navigate(['']);
}
}

+ 9
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/layout/layout.module.ts View File

@ -0,0 +1,9 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { LayoutRoutingModule } from './layout-routing.module';
import { SharedModule } from '../shared/shared.module';
@NgModule({
declarations: [],
imports: [CommonModule, LayoutRoutingModule, SharedModule],
})
export class LayoutModule {}

+ 26
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/microfrontend-routing.module.ts View File

@ -0,0 +1,26 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
import { HomeComponent } from './layout/home/home.component';
const routes: Routes = [
{
path: '',
loadChildren: () =>
import('./layout/layout.module').then(
(m) => m.LayoutModule
),
pathMatch: 'prefix',
},
{
path: 'home',
component: HomeComponent,
},
{ path: '**', component: PageNotFoundComponent }
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class MicrofrontendRoutingModule { }

+ 18
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/microfrontend.module.ts View File

@ -0,0 +1,18 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MicrofrontendRoutingModule } from './microfrontend-routing.module';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
import { HomeComponent } from './layout/home/home.component';
import { MicrofrontendComponent } from './microfrontend/microfrontend.component';
import { LayoutComponent } from './layout/layout.component';
import { TaskModule } from './task/task.module';
@NgModule({
declarations: [
PageNotFoundComponent,
HomeComponent,
MicrofrontendComponent,
LayoutComponent,
],
imports: [CommonModule, MicrofrontendRoutingModule, TaskModule],
})
export class MicrofrontendModule {}

+ 1
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/microfrontend/microfrontend.component.html View File

@ -0,0 +1 @@
<p>microfrontend works!</p>

+ 0
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/microfrontend/microfrontend.component.scss View File


+ 25
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/microfrontend/microfrontend.component.spec.ts View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MicrofrontendComponent } from './microfrontend.component';
describe('MicrofrontendComponent', () => {
let component: MicrofrontendComponent;
let fixture: ComponentFixture<MicrofrontendComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ MicrofrontendComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(MicrofrontendComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

+ 15
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/microfrontend/microfrontend.component.ts View File

@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'remote-microfrontend',
templateUrl: './microfrontend.component.html',
styleUrls: ['./microfrontend.component.scss']
})
export class MicrofrontendComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}

+ 1
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/page-not-found/page-not-found.component.html View File

@ -0,0 +1 @@
<p>page-not-found works!</p>

+ 0
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/page-not-found/page-not-found.component.scss View File


+ 25
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/page-not-found/page-not-found.component.spec.ts View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PageNotFoundComponent } from './page-not-found.component';
describe('PageNotFoundComponent', () => {
let component: PageNotFoundComponent;
let fixture: ComponentFixture<PageNotFoundComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PageNotFoundComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PageNotFoundComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

+ 15
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/page-not-found/page-not-found.component.ts View File

@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'remote-page-not-found',
templateUrl: './page-not-found.component.html',
styleUrls: ['./page-not-found.component.scss']
})
export class PageNotFoundComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}

+ 10
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/shared/shared.module.ts View File

@ -0,0 +1,10 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MfaElementSrcDirective } from '../directives/element-src.directive';
@NgModule({
declarations: [MfaElementSrcDirective],
imports: [CommonModule],
exports: [MfaElementSrcDirective],
})
export class SharedModule {}

+ 10
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/task/detail/detail-routing.module.ts View File

@ -0,0 +1,10 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class DetailRoutingModule { }

+ 1
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/task/detail/detail.component.html View File

@ -0,0 +1 @@
<p>detail works!</p>

+ 0
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/task/detail/detail.component.scss View File


+ 25
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/task/detail/detail.component.spec.ts View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { DetailComponent } from './detail.component';
describe('DetailComponent', () => {
let component: DetailComponent;
let fixture: ComponentFixture<DetailComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ DetailComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(DetailComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

+ 15
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/task/detail/detail.component.ts View File

@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'remote-detail',
templateUrl: './detail.component.html',
styleUrls: ['./detail.component.scss']
})
export class DetailComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}

+ 17
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/task/detail/detail.module.ts View File

@ -0,0 +1,17 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { DetailRoutingModule } from './detail-routing.module';
import { DetailComponent } from './detail.component';
@NgModule({
declarations: [
DetailComponent
],
imports: [
CommonModule,
DetailRoutingModule
]
})
export class DetailModule { }

+ 1
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/task/dynamic-component/dynamic-component.component.html View File

@ -0,0 +1 @@
<ng-container #componentViewContainer></ng-container>

+ 0
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/task/dynamic-component/dynamic-component.component.scss View File


+ 25
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/task/dynamic-component/dynamic-component.component.spec.ts View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { DynamicComponentComponent } from './dynamic-component.component';
describe('DynamicComponentComponent', () => {
let component: DynamicComponentComponent;
let fixture: ComponentFixture<DynamicComponentComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ DynamicComponentComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(DynamicComponentComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

+ 15
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/task/dynamic-component/dynamic-component.component.ts View File

@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'shell-dynamic-component,div[dynamic-component]',
templateUrl: './dynamic-component.component.html',
styleUrls: ['./dynamic-component.component.scss']
})
export class DynamicComponentComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}

+ 10
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/task/list/list.component.html View File

@ -0,0 +1,10 @@
<div class="task-card-list">
<div *ngFor="let task of tasks" class="task-card" (click)="goToDetail(task.id)">
<h3>{{ task.title }}</h3>
<div>
<img src="assets/img/appealed.png" alt="" srcset="">
</div>
<p>{{ task.description }}</p>
</div>
</div>

+ 35
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/task/list/list.component.scss View File

@ -0,0 +1,35 @@
.task-card-list {
display: flex;
flex-wrap: wrap;
gap: 16px;
}
.task-card {
background-color: #fdf3f4;
border-radius: 8px;
padding: 16px;
width: 300px;
}
.circle {
width: 200px;
height: 200px;
position: relative;
overflow: hidden;
}
.circle img {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
animation: rotate 10s linear infinite;
}
@keyframes rotate {
from {
transform: translate(-50%, -50%) rotate(0deg);
}
to {
transform: translate(-50%, -50%) rotate(360deg);
}
}

+ 25
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/task/list/list.component.spec.ts View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ListComponent } from './list.component';
describe('ListComponent', () => {
let component: ListComponent;
let fixture: ComponentFixture<ListComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ ListComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(ListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

+ 20
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/task/list/list.component.ts View File

@ -0,0 +1,20 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
@Component({
selector: 'remote-list',
templateUrl: './list.component.html',
styleUrls: ['./list.component.scss'],
})
export class ListComponent implements OnInit {
tasks = [
{ title: 'Task 1', description: 'Description for Task 1', id: '1' },
{ title: 'Task 2', description: 'Description for Task 2', id: '2' },
];
constructor(private route: ActivatedRoute, private router: Router) {}
ngOnInit(): void {}
goToDetail(id: string): void {
this.router.navigate(['./detail'], { relativeTo: this.route });
}
}

+ 4
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/task/task-content/task-content.component.html View File

@ -0,0 +1,4 @@
<h3>task-content works!</h3>
<div #contentArea>
<div dynamic-ant-form-control></div>
</div>

+ 0
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/task/task-content/task-content.component.scss View File


+ 25
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/task/task-content/task-content.component.spec.ts View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { TaskContentComponent } from './task-content.component';
describe('TaskContentComponent', () => {
let component: TaskContentComponent;
let fixture: ComponentFixture<TaskContentComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ TaskContentComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(TaskContentComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

+ 17
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/task/task-content/task-content.component.ts View File

@ -0,0 +1,17 @@
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
@Component({
selector: 'remote-task-content',
templateUrl: './task-content.component.html',
styleUrls: ['./task-content.component.scss']
})
export class TaskContentComponent implements OnInit {
// @ViewChild('contentArea')
// contentAreaContainer: ElementRef;
constructor() { }
ngOnInit(): void {
}
}

+ 27
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/task/task-routing.module.ts View File

@ -0,0 +1,27 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { TaskComponent } from './task.component';
import { ListComponent } from './list/list.component';
import { TaskContentComponent } from './task-content/task-content.component';
const routes: Routes = [
{
path: '',
component: TaskComponent,
children:[{
path:'',
component: ListComponent,
},
{
path:'detail',
component: TaskContentComponent,
}
]
},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class TaskRoutingModule { }

+ 2
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/task/task.component.html View File

@ -0,0 +1,2 @@
<router-outlet></router-outlet>

+ 0
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/task/task.component.scss View File


+ 25
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/task/task.component.spec.ts View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { TaskComponent } from './task.component';
describe('TaskComponent', () => {
let component: TaskComponent;
let fixture: ComponentFixture<TaskComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ TaskComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(TaskComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

+ 16
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/task/task.component.ts View File

@ -0,0 +1,16 @@
import { Component, OnDestroy, OnInit } from '@angular/core';
@Component({
selector: 'remote-task',
templateUrl: './task.component.html',
styleUrls: ['./task.component.scss']
})
export class TaskComponent implements OnInit, OnDestroy {
constructor() { }
ngOnInit(): void {
}
ngOnDestroy(): void {
}
}

+ 20
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/task/task.module.ts View File

@ -0,0 +1,20 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { TaskRoutingModule } from './task-routing.module';
import { TaskComponent } from './task.component';
import { ListComponent } from './list/list.component';
import { TaskContentComponent } from './task-content/task-content.component';
import { DynamicComponentComponent } from './dynamic-component/dynamic-component.component';
import { SharedModule } from '../shared/shared.module';
@NgModule({
declarations: [
TaskComponent,
ListComponent,
TaskContentComponent,
DynamicComponentComponent,
TaskContentComponent,
],
imports: [CommonModule, TaskRoutingModule, SharedModule],
})
export class TaskModule {}

+ 22
- 0
gpt-mf-demo/mfe1/src/app/microfrontend/util/asset-url.ts View File

@ -0,0 +1,22 @@
export function assetUrl(url: string): string {
//debugger
if (!(window as any).__DW_MFA_ENV__) {
return url;
}
// @ts-ignore
const publicPath = __webpack_public_path__;
console.log('没法儿', publicPath);
const urlPrefix = publicPath.endsWith('/')
? ''
: url.startsWith('/')
? ''
: '/';
if (publicPath.endsWith('/') && url.startsWith('/')) {
url = url.substring(1);
}
return `${publicPath}${urlPrefix}${url}`;
}

+ 0
- 0
gpt-mf-demo/mfe1/src/assets/.gitkeep View File


BIN
gpt-mf-demo/mfe1/src/assets/img/appealed.png View File

Before After
Width: 71  |  Height: 20  |  Size: 2.0 KiB

BIN
gpt-mf-demo/mfe1/src/assets/img/artificial.png View File

Before After
Width: 80  |  Height: 80  |  Size: 10 KiB

BIN
gpt-mf-demo/mfe1/src/assets/img/bg.png View File

Before After
Width: 1440  |  Height: 480  |  Size: 124 KiB

BIN
gpt-mf-demo/mfe1/src/assets/img/confirm.png View File

Before After
Width: 24  |  Height: 24  |  Size: 620 B

+ 281
- 0
gpt-mf-demo/mfe1/src/assets/img/dwLogo.svg View File

@ -0,0 +1,281 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="141 248 278 64" enable-background="new 141 248 278 64" xml:space="preserve">
<g id="Layer_4" display="none">
<rect x="-20.1" y="194.4" display="inline" fill="#404040" stroke="#FFFFFF" stroke-width="3" stroke-linejoin="round" stroke-miterlimit="10" width="596.3" height="174.2"/>
</g>
<g>
<g>
<path fill="#FFFFFF" d="M210.5,253.4C210.5,253.4,210.5,253.4,210.5,253.4C210.5,253.4,210.5,253.4,210.5,253.4z"/>
<path fill="#FFFFFF" d="M210.5,253.4C210.5,253.4,210.5,253.4,210.5,253.4C210.5,253.4,210.5,253.4,210.5,253.4 M210.5,253.4
C210.5,253.4,210.5,253.5,210.5,253.4C210.5,253.5,210.5,253.4,210.5,253.4 M210.1,253.2L210.1,253.2L210.1,253.2l0.2,0.1l0.7,0.3
l0,0l0,0l-0.3-0.1L210.1,253.2L210.1,253.2z"/>
</g>
<g>
<path fill="#FFFFFF" d="M184.8,308.9c-0.3,0-0.6-0.1-0.8-0.3l-0.1,0c-0.6,0-1.1-0.4-1.3-0.9l-3.7-8.1l-5.5,8
c-0.1,0.1-0.1,0.1-0.2,0.2l-0.3,0.3c-0.1,0.1-0.2,0.2-0.4,0.3c-0.2,0.1-0.8,0.4-1.4,0.4c-0.4,0-0.7-0.1-1-0.3
c-0.3-0.2-0.8-0.6-0.9-1.4L149,264.4c-0.3-0.6-0.2-1.3,0.3-1.7l0.3-0.3c0.3-0.3,0.7-0.4,1.1-0.4h0.3c0.3,0,0.5,0.1,0.7,0.2
c6.6,3.8,13.5,5.7,20.5,5.7c4.5,0,9.1-0.8,13.8-2.4c7.4-2.6,14.9-7.2,22.1-13.6c0.2-0.2,0.4-0.3,0.6-0.3c0,0,0.1,0,0.1-0.1
c0.2-0.1,0.4-0.1,0.6-0.1c0.5,0,0.9,0.2,1.3,0.6c0.3,0.3,0.4,0.7,0.4,1.1v0.4h-0.6v-0.1l0,0v0.1l0.2,0.1c0,0,0,0,0,0.1l0.4,0.3
l-17.9,25.7c4.8-1.5,9.8-4.4,14.7-8.6c0.1-0.4,0.4-0.7,0.8-0.9c0.2-0.1,0.4-0.2,0.7-0.2c0.3,0,0.6,0.1,0.9,0.3l0.4,0.3
c0.6,0.5,0.8,1.4,0.3,2.1L186.4,308c-0.1,0.1-0.1,0.1-0.2,0.2l-0.3,0.3C185.6,308.8,185.2,308.9,184.8,308.9z"/>
<path fill="#FFFFFF" d="M209.5,251.6c0.3,0,0.7,0.1,1.1,0.5c0.2,0.2,0.4,0.6,0.4,0.9v0.2h-0.3c0,0,0,0.1,0,0.1c0,0,0-0.1,0-0.1
h-0.8l0.6,0.4c0.1-0.1,0.1-0.1,0.1-0.2c0,0.1,0,0.2-0.1,0.2l0.4,0.2l-18.2,26.1c5.1-1.5,10.3-4.4,15.6-8.9
c0.1-0.3,0.3-0.6,0.6-0.8c0.2-0.1,0.4-0.1,0.6-0.1c0.3,0,0.5,0.1,0.7,0.2l0.4,0.3c0.5,0.4,0.7,1.2,0.3,1.7l-24.6,35.3
c0,0.1-0.1,0.1-0.1,0.2l-0.3,0.3c-0.2,0.2-0.6,0.4-0.9,0.4c-0.2,0-0.5-0.1-0.7-0.2l-0.1-0.1c0,0,0,0-0.1,0c-0.5,0-0.9-0.3-1.1-0.7
l-3.9-8.5l-5.8,8.4c0,0.1-0.1,0.1-0.1,0.2l-0.3,0.3c-0.1,0.1-0.2,0.2-0.3,0.2c-0.2,0.1-0.7,0.4-1.3,0.4c-0.3,0-0.6-0.1-0.9-0.2
c-0.3-0.2-0.7-0.5-0.8-1.2l-20.2-42.8c-0.2-0.5-0.1-1,0.2-1.4l0.3-0.3c0.2-0.2,0.6-0.4,0.9-0.4h0.3c0.2,0,0.4,0.1,0.6,0.2
c6.7,3.8,13.6,5.8,20.6,5.8c4.6,0,9.2-0.8,13.8-2.4c7.5-2.6,14.9-7.2,22.2-13.6c0.2-0.1,0.3-0.2,0.5-0.3c0.1,0,0.1-0.1,0.2-0.1
C209.1,251.7,209.2,251.6,209.5,251.6 M210.6,253.4C210.6,253.4,210.5,253.4,210.6,253.4C210.5,253.4,210.6,253.4,210.6,253.4
M209.5,251.1c-0.2,0-0.5,0-0.7,0.1c-0.1,0-0.1,0-0.2,0.1c-0.2,0.1-0.5,0.2-0.7,0.4c-7.2,6.4-14.6,10.9-22,13.5
c-4.6,1.6-9.2,2.4-13.7,2.4c-7,0-13.8-1.9-20.4-5.7c-0.3-0.2-0.6-0.2-0.9-0.2h-0.3c-0.5,0-0.9,0.2-1.2,0.5l-0.3,0.3
c-0.5,0.5-0.7,1.3-0.3,2l20.2,42.7c0.1,0.8,0.7,1.3,1,1.5c0.3,0.2,0.7,0.3,1.1,0.3c0.7,0,1.3-0.3,1.5-0.4c0.2-0.1,0.3-0.2,0.5-0.3
l0.3-0.3c0.1-0.1,0.1-0.2,0.2-0.2l5.3-7.6l3.5,7.7c0.3,0.6,0.9,1,1.5,1c0.3,0.2,0.6,0.3,1,0.3c0.5,0,0.9-0.2,1.2-0.5l0.3-0.3
c0.1-0.1,0.1-0.2,0.2-0.2l24.6-35.3c0.5-0.8,0.4-1.8-0.4-2.4l-0.4-0.3c-0.3-0.2-0.7-0.3-1-0.3c-0.3,0-0.5,0.1-0.8,0.2
c-0.4,0.2-0.7,0.5-0.9,0.9c-4.7,3.9-9.4,6.7-13.9,8.2l17.4-24.9l0.3-0.4l-0.1-0.1h0.1v-0.5V253c0-0.5-0.2-0.9-0.5-1.2
C210.4,251.3,209.8,251.1,209.5,251.1L209.5,251.1z"/>
</g>
<g>
<path fill="#FFFFFF" d="M236.7,308.7c-0.4,0-0.8-0.2-1.1-0.5c-0.5-0.5-0.5-1.3-0.1-1.9c1-1.5,2.1-4.2,2.1-7.2v-0.4
c-0.2,0-0.8,0-0.8,0c-0.1,0-0.2,0-0.4,0c-0.1,0-0.2,0-0.3,0c-0.1,0-0.2,0-0.3,0c-0.4,0-0.8-0.2-1.1-0.4c-0.3-0.3-0.5-0.8-0.4-1.3
c0-0.1,0-0.2-0.2-0.7c-0.3-0.5-0.2-1.1,0.1-1.6c0.3-0.4,0.7-0.6,1.2-0.6c0.1,0,0.2,0,0.2,0c0.2,0,0.4,0.1,0.6,0.1
c-0.3-0.3-0.4-0.7-0.4-1.1c0,0,0.3-4.5,0.3-6.3v-2.3c0-1.2-0.1-5.3-0.2-7l0-0.1c0-0.5,0.2-0.9,0.5-1.2c0.3-0.2,0.6-0.4,1-0.4
c0.1,0,0.2,0,0.3,0l3.6,0.7c0.1-0.8,0.7-1.4,1.5-1.4h14.4c0.5,0,1.1,0.3,1.4,0.7c0.1,0,0.3,0,0.4,0l0.1,0l4.8,0.4
c0.6,0,1.1,0.5,1.3,1.1c0.2,0.6,0,1.2-0.5,1.6c0,0-0.6,0.5-0.7,1.5l0,12.8c0,0.4-0.2,0.8-0.5,1.1h1.2c0.8,0,1.4,0.6,1.5,1.4
c0,0.5-0.1,0.9-0.5,1.2c0,0.1,0,0.1,0,0.3c0,0.8-0.7,1.5-1.5,1.5h-1.1v7c0,0.7-0.4,1.2-1.1,1.4l-3.4,1.1c-0.1,0-0.3,0.1-0.4,0.1
c-0.3,0-0.6-0.1-0.9-0.3c-0.4-0.3-0.6-0.7-0.6-1.2v-8h-0.4v7c0,0.7-0.4,1.2-1,1.4l-3.4,1.1c-0.1,0-0.3,0.1-0.5,0.1
c-0.3,0-0.6-0.1-0.9-0.3c-0.4-0.3-0.6-0.7-0.6-1.1c-0.1,0.1-0.2,0.1-0.4,0.2l-3.4,1.1c-0.1,0-0.3,0.1-0.4,0.1
c-0.3,0-0.6-0.1-0.9-0.3c-0.4-0.3-0.6-0.7-0.6-1.2v-8h-0.3v0.7c0,3.3-1.5,5.9-4.4,7.8c-1,0.6-2.2,1.4-2.2,1.4
C237.3,308.6,237,308.7,236.7,308.7z"/>
<path fill="#FFFFFF" d="M257.4,275.5c0.5,0,1,0.3,1.2,0.8c0.2-0.1,0.3-0.1,0.5-0.1c0,0,0.1,0,0.1,0l4.8,0.4c0.5,0,1,0.4,1.1,0.9
c0.1,0.5,0,1-0.5,1.3c0,0-0.7,0.6-0.8,1.7v12.8c0,0.7-0.6,1.3-1.3,1.3h-6.4v0.1h8.6c0.6,0,1.2,0.5,1.2,1.1c0,0.4-0.1,0.8-0.4,1.1
c0,0.1,0,0.2,0,0.4c0,0.7-0.6,1.3-1.3,1.3H263v7.2c0,0.5-0.4,1-0.9,1.2l-3.4,1.1c-0.1,0-0.2,0.1-0.4,0.1c-0.3,0-0.5-0.1-0.7-0.2
c-0.3-0.2-0.5-0.6-0.5-1v-8.3h-0.9v7.2c0,0.5-0.4,1-0.9,1.2l-3.4,1.1c-0.1,0-0.2,0.1-0.4,0.1c-0.3,0-0.5-0.1-0.7-0.2
c-0.3-0.2-0.5-0.6-0.5-1v-0.5c-0.2,0.2-0.4,0.4-0.7,0.5l-3.4,1.1c-0.1,0-0.2,0.1-0.4,0.1c-0.3,0-0.5-0.1-0.7-0.2
c-0.3-0.2-0.5-0.6-0.5-1v-8.3h-0.8v1c0,3.2-1.5,5.7-4.3,7.6c-1,0.6-2.2,1.4-2.2,1.4c-0.2,0.1-0.4,0.2-0.7,0.2
c-0.3,0-0.7-0.1-0.9-0.4c-0.4-0.4-0.5-1.1-0.1-1.6c1.1-1.5,2.2-4.3,2.2-7.4v-0.7c-0.3,0-0.6,0-0.9,0c-0.2,0-0.3,0-0.5,0
c-0.1,0-0.2,0-0.4,0c-0.1,0-0.1,0-0.2,0c-0.3,0-0.6-0.1-0.9-0.4c-0.3-0.3-0.4-0.7-0.3-1.1c0-0.2,0-0.3-0.3-0.9
c-0.2-0.4-0.2-0.9,0.1-1.3c0.2-0.3,0.6-0.5,1-0.5c0.1,0,0.1,0,0.2,0c1.1,0.2,1.7,0.2,3.1,0.2h5.8v-0.1h-7.1
c-0.3,0-0.7-0.1-0.9-0.4s-0.4-0.6-0.3-0.9c0,0,0.3-4.5,0.3-6.3v-2.3c0-1.5-0.2-7-0.2-7.1c0-0.4,0.1-0.7,0.4-1
c0.2-0.2,0.5-0.3,0.8-0.3c0.1,0,0.1,0,0.2,0l3.7,0.7c0.1,0,0.2,0,0.3,0.1v-0.2c0-0.7,0.6-1.3,1.3-1.3H257.4 M247.6,279.5h5.2v-0.3
h-5.2V279.5 M247.6,283.6h5.2v-0.3h-5.2V283.6 M247.6,287.7h5.2v-0.3h-5.2V287.7 M257.4,275H243c-0.8,0-1.5,0.6-1.7,1.3l-3.4-0.6
c-0.1,0-0.2,0-0.3,0c-0.4,0-0.8,0.2-1.1,0.4c-0.4,0.3-0.6,0.9-0.6,1.4l0,0.1c0.1,1.7,0.2,5.7,0.2,6.9v2.3c0,1.7-0.3,6.2-0.3,6.2
c0,0.3,0,0.5,0.1,0.8c0,0,0,0,0,0c-0.1,0-0.2,0-0.3,0c-0.6,0-1.1,0.3-1.4,0.7c-0.4,0.5-0.5,1.2-0.2,1.8c0.2,0.4,0.2,0.5,0.2,0.6
c-0.1,0.6,0.1,1.1,0.5,1.5c0.3,0.3,0.8,0.5,1.2,0.5c0.1,0,0.2,0,0.3,0c0.1,0,0.2,0,0.3,0c0.1,0,0.2,0,0.3,0l0.1,0
c0.1,0,0.2,0,0.4,0v0.2c0,3-1.1,5.6-2.1,7.1c-0.5,0.7-0.4,1.6,0.2,2.2c0.3,0.3,0.8,0.5,1.3,0.5c0.3,0,0.6-0.1,0.9-0.3
c0,0,1.2-0.8,2.2-1.4c2.4-1.5,3.8-3.5,4.3-5.9v5.2c0,0.6,0.3,1.1,0.7,1.4c0.3,0.2,0.7,0.3,1,0.3c0.2,0,0.4,0,0.5-0.1l3.4-1.1
c0,0,0.1,0,0.1,0c0.1,0.4,0.3,0.7,0.6,0.9c0.3,0.2,0.7,0.3,1,0.3c0.2,0,0.4,0,0.5-0.1l3.4-1.1c0.5-0.2,0.9-0.5,1.1-1v0.4
c0,0.6,0.3,1.1,0.7,1.4c0.3,0.2,0.7,0.3,1,0.3c0.2,0,0.4,0,0.5-0.1l3.4-1.1c0.7-0.2,1.2-0.9,1.2-1.7V299h0.8c1,0,1.8-0.8,1.8-1.8
c0-0.1,0-0.1,0-0.1c0.3-0.4,0.5-0.9,0.5-1.4c-0.1-0.9-0.8-1.6-1.7-1.6h-0.7c0.1-0.3,0.2-0.5,0.2-0.8v-12.8
c0.1-0.9,0.7-1.3,0.7-1.3c0.6-0.4,0.8-1.2,0.6-1.9c-0.2-0.7-0.8-1.2-1.5-1.3l-4.8-0.4c0,0-0.1,0-0.1,0c-0.1,0-0.2,0-0.3,0
C258.5,275.2,258,275,257.4,275L257.4,275z"/>
</g>
<g>
<path fill="#FFFFFF" d="M280.9,308.7c-0.5,0-0.9-0.2-1.2-0.5c-0.9-0.9-0.4-1.8,0.4-3.4c0,0,0-0.1,0.1-0.1
c-0.3-0.1-0.8-0.3-1.1-0.9c0-0.1-0.1-0.2-0.1-0.3c0,0,0-0.1,0-0.1v2.5c0,0.7-0.4,1.2-1.1,1.4l-3.4,1.1c-0.1,0-0.3,0.1-0.4,0.1
c-0.3,0-0.6-0.1-0.9-0.3c-0.4-0.3-0.6-0.7-0.6-1.2v-2.4c-0.8,0.7-1.6,1.3-2.6,1.8c-1.1,0.5-2.5,1.2-2.5,1.2
c-0.2,0.1-0.4,0.1-0.6,0.1c-0.5,0-0.9-0.2-1.2-0.6c-0.4-0.6-0.4-1.3,0-1.9c2.5-3,4-5.7,4.6-8.4c0-0.1,0-0.2,0.1-0.3H269
c-0.8,0-1.5-0.7-1.5-1.5c0-0.2,0-0.3-0.2-0.8c-0.3-0.5-0.2-1.1,0.2-1.6c0.3-0.4,0.7-0.6,1.2-0.6c0.1,0,0.2,0,0.3,0
c0.2,0,1.8,0.1,3.5,0.2v-1.5c-4.3,0-4.9,0-4.9-1.6c0-0.2,0-0.3-0.2-0.8c-0.3-0.5-0.2-1.2,0.2-1.6c0.3-0.4,0.7-0.6,1.2-0.6
c0.1,0,0.2,0,0.4,0c0.2,0,1.4,0.1,2.4,0.1c-0.6-1.2-1.1-2.3-1.3-2.7c-0.1-0.2-0.1-0.4-0.1-0.6c0-0.4,0.2-0.8,0.4-1.1h-1.2
c-0.8,0-1.4-0.6-1.5-1.4c0-0.3-0.1-0.8-0.2-1c-0.3-0.5-0.2-1.1,0.1-1.5c0.3-0.4,0.7-0.6,1.2-0.6c0.1,0,0.1,0,0.2,0
c0.4,0.1,2.3,0.1,3.9,0.2v-1.8c0-0.5,0.2-0.9,0.6-1.2c0.3-0.2,0.6-0.3,0.9-0.3c0.1,0,0.2,0,0.3,0l4.3,1c0.6,0.1,1,0.6,1.1,1.1
c0.1,0.5,0,1-0.3,1.3h3c0.4-0.7,1-0.9,1.5-0.9c0.2,0,0.5,0.1,0.7,0.2c0.5,0.2,1.3,0.6,2.5,1.1c1.4-0.7,5.6-2.6,6.4-3l0.2-0.1
c0.4-0.2,0.8-0.4,1.3-0.4c1,0,1.5,0.7,1.8,0.9c0.1,0.1,2.8,3.2,3,4.2c0.2,0.7-0.2,1.5-0.9,1.8c-0.3,0.1-0.6,0.2-0.9,0.2
c-0.1,0-0.2,0-0.3,0l-0.2,0c-0.3,0-0.9,0-1.7,0.2c-3.4,0.5-4.7,0.7-7.1,1l0,3.1c1.1,0,5-0.2,6.3-0.2c0.4,0,2.6-0.3,3.1-0.4
c0.1,0,0.2,0,0.4,0c0.8,0,1.4,0.6,1.5,1.3c0.1,0.5-0.1,1-0.5,1.3c-0.1,0.2-0.2,0.5-0.3,1.1c-0.1,0.7-0.7,1.3-1.5,1.3h-2.1v15.5
c0,0.7-0.4,1.2-1,1.4l-3.4,1.1c-0.1,0-0.3,0.1-0.5,0.1c-0.3,0-0.6-0.1-0.9-0.3c-0.4-0.3-0.6-0.7-0.6-1.2v-16.6h-0.7
c-0.1,1.7-0.3,4-0.5,5.8c-0.8,5.7-2.9,9.7-6.1,12.2c-0.1,0.1-0.3,0.2-0.4,0.2C281.4,308.6,281.2,308.7,280.9,308.7z M281.2,296.6
c0.2,0.1,0.4,0.3,0.6,0.4c0-0.1,0-0.3,0.1-0.4H281.2z M282.3,292.2c0-0.5,0.1-1.1,0.1-1.6c-0.2,0.1-0.3,0.1-0.5,0.1h-2.1
c0,0.1,0,0.1,0,0.2c0,0.5-0.2,1-0.6,1.3H282.3z M282.5,286.4v-3.7c-0.8,1-1.9,2.4-3,3.7C279.5,286.4,282.5,286.4,282.5,286.4z
M273.2,282c0.5,0.1,1.1,0.2,1.7,0.2c0.6,0,1.2-0.1,1.8-0.2H273.2z"/>
<path fill="#FFFFFF" d="M274.3,274.5c0.1,0,0.2,0,0.3,0l4.3,1c0.5,0.1,0.8,0.5,0.9,0.9c0.1,0.5-0.1,1-0.4,1.3c0,0-0.1,0.1-0.2,0.3
h3.7c0.4-0.7,0.9-0.9,1.4-0.9c0.2,0,0.4,0,0.6,0.1c0.6,0.3,1.9,0.9,2.6,1.2c1.5-0.7,5.7-2.7,6.5-3c0.1,0,0.2-0.1,0.2-0.1
c0.3-0.2,0.7-0.4,1.2-0.4c0.8,0,1.4,0.6,1.6,0.8c0,0,2.7,3.2,3,4.1c0.2,0.6-0.2,1.2-0.7,1.5c-0.3,0.1-0.5,0.1-0.8,0.1
c-0.1,0-0.2,0-0.3,0c-0.1,0-0.1,0-0.2,0c-0.4,0-1,0-1.8,0.2c-3.4,0.5-4.8,0.7-7.3,1l0,3.6c0.2,0,5.1-0.2,6.5-0.2
c0.4,0,2.7-0.3,3.2-0.4c0.1,0,0.2,0,0.3,0c0.6,0,1.2,0.5,1.2,1.1c0.1,0.5-0.1,0.9-0.5,1.2c-0.1,0.2-0.3,0.6-0.4,1.2
c-0.1,0.6-0.6,1-1.2,1h-2.3v15.8c0,0.5-0.4,1-0.9,1.2l-3.4,1.1c-0.1,0-0.2,0.1-0.4,0.1c-0.3,0-0.5-0.1-0.7-0.2
c-0.3-0.2-0.5-0.6-0.5-1V290h-1.2c-0.1,1.6-0.3,4.1-0.5,6c-0.8,5.6-2.8,9.6-6.1,12.1c-0.1,0.1-0.2,0.2-0.4,0.2
c-0.2,0.1-0.4,0.1-0.7,0.1c-0.4,0-0.8-0.2-1.1-0.4c-0.7-0.7-0.4-1.5,0.4-3.1c0.1-0.1,0.1-0.3,0.2-0.5c-0.3,0-0.9-0.1-1.2-0.8
c0-0.1-0.1-0.2-0.1-0.3c0-0.1-0.1-0.3-0.2-0.4c-0.1-0.2-0.2-0.4-0.2-0.6c-0.1-0.1-0.1-0.3-0.2-0.4v4c0,0.5-0.4,1-0.9,1.2l-3.4,1.1
c-0.1,0-0.2,0.1-0.4,0.1c-0.3,0-0.5-0.1-0.7-0.2c-0.3-0.2-0.5-0.6-0.5-1v-3c-0.8,0.9-1.8,1.6-3,2.2c-1.1,0.5-2.5,1.2-2.5,1.2
c-0.2,0.1-0.4,0.1-0.5,0.1c-0.4,0-0.7-0.2-1-0.5c-0.4-0.5-0.3-1.1,0-1.6c2.5-3,4-5.8,4.7-8.5c0-0.2,0.1-0.4,0.1-0.6H269
c-0.7,0-1.3-0.6-1.3-1.3c0-0.3,0-0.5-0.3-0.9c-0.2-0.4-0.2-0.9,0.1-1.3c0.2-0.3,0.6-0.5,1-0.5c0.1,0,0.2,0,0.2,0
c0.3,0,2.2,0.1,3.7,0.2h0.1v-2c-4.6,0-4.9,0-4.9-1.3c0-0.3,0-0.5-0.3-0.9c-0.2-0.4-0.2-1,0.1-1.3c0.2-0.3,0.6-0.5,1-0.5
c0.1,0,0.2,0,0.3,0c0.3,0,1.9,0.1,2.9,0.1c-0.7-1.4-1.3-2.6-1.5-3c-0.1-0.2-0.1-0.3-0.1-0.5c0-0.7,0.6-1.3,1.3-1.3
c0.2,0,0.5,0,0.6,0.1c0.9,0.4,1.8,0.6,2.8,0.6c1.2,0,2.3-0.3,3.3-0.7h-9c-0.6,0-1.2-0.5-1.2-1.1c0-0.3-0.1-0.9-0.3-1.1
c-0.2-0.4-0.2-0.9,0.1-1.3c0.2-0.3,0.6-0.5,1-0.5c0.1,0,0.1,0,0.2,0c0.4,0.1,2.5,0.1,4.2,0.2v-2.1c0-0.4,0.2-0.7,0.5-1
C273.8,274.6,274.1,274.5,274.3,274.5 M279,286.6h3.5c0.1,0,0.2,0,0.3,0v-4.7C281.9,283,280.4,284.9,279,286.6 M278.7,292.5h3.9
c0.1-0.8,0.1-1.5,0.1-2.3c-0.2,0.2-0.5,0.2-0.7,0.2h-2.5c0.1,0.1,0.1,0.3,0.1,0.5c0,0.5-0.3,1-0.7,1.2
C278.9,292.2,278.8,292.3,278.7,292.5 M282,297.4c0.1-0.4,0.1-0.7,0.2-1.1h-1.9C280.9,296.7,281.5,297,282,297.4 M274.3,274
C274.3,274,274.3,274,274.3,274c-0.4,0-0.8,0.1-1.1,0.4c-0.4,0.3-0.7,0.8-0.7,1.4v1.6c-1.6,0-3.3-0.1-3.6-0.1c-0.1,0-0.2,0-0.3,0
c-0.6,0-1.1,0.3-1.4,0.7c-0.4,0.5-0.4,1.2-0.1,1.8c0.1,0.2,0.2,0.6,0.2,0.9c0.1,0.9,0.8,1.6,1.7,1.6h0.8c-0.1,0.3-0.2,0.5-0.2,0.8
c0,0.2,0.1,0.5,0.2,0.7c0.2,0.3,0.6,1.3,1.1,2.3c-0.9,0-1.8-0.1-2-0.1c-0.1,0-0.2,0-0.4,0c-0.5,0-1,0.2-1.4,0.7
c-0.4,0.5-0.5,1.3-0.2,1.9c0.2,0.4,0.2,0.5,0.2,0.7c0,1.8,0.8,1.8,4.9,1.8v1c-1.5,0-3-0.1-3.2-0.1c-0.1,0-0.2,0-0.3,0
c-0.5,0-1.1,0.3-1.4,0.7c-0.4,0.5-0.5,1.2-0.2,1.8c0.2,0.4,0.2,0.5,0.2,0.7c0,1,0.8,1.8,1.8,1.8h0.9c-0.6,2.6-2.1,5.4-4.5,8.3
c-0.5,0.6-0.5,1.5,0,2.2c0.3,0.4,0.8,0.7,1.4,0.7c0.3,0,0.5-0.1,0.7-0.2l0.1,0l0,0c0.3-0.1,1.5-0.7,2.4-1.1
c0.9-0.4,1.6-0.9,2.3-1.5v1.8c0,0.6,0.3,1.1,0.7,1.4c0.3,0.2,0.7,0.3,1,0.3c0.2,0,0.4,0,0.5-0.1l3.4-1.1c0.7-0.2,1.2-0.9,1.2-1.7
v-1.5c0.2,0.2,0.4,0.4,0.7,0.5c-0.8,1.6-1.3,2.6-0.3,3.5c0.4,0.4,0.9,0.6,1.4,0.6c0.3,0,0.6-0.1,0.9-0.2c0.2-0.1,0.4-0.2,0.5-0.3
c3.3-2.6,5.4-6.6,6.2-12.4c0.3-1.8,0.4-3.9,0.5-5.6h0.2v16.3c0,0.6,0.3,1.1,0.7,1.4c0.3,0.2,0.7,0.3,1,0.3c0.2,0,0.4,0,0.5-0.1
l3.4-1.1c0.7-0.2,1.2-0.9,1.2-1.7v-15.3h1.8c0.9,0,1.6-0.6,1.7-1.5c0.1-0.5,0.2-0.8,0.3-1c0.4-0.4,0.7-1,0.6-1.5
c-0.1-0.9-0.9-1.5-1.7-1.5c-0.1,0-0.3,0-0.4,0.1c-0.5,0.1-2.7,0.4-3,0.4c-1.2,0-4.7,0.1-6,0.2l0-2.6c2.3-0.2,3.8-0.4,6.9-0.9
c0.9-0.2,1.4-0.2,1.7-0.2c0.1,0,0.1,0,0.2,0c0.1,0,0.2,0,0.3,0c0.4,0,0.7-0.1,1-0.2c0.8-0.3,1.3-1.2,1-2.1c-0.3-1-2.8-3.9-3.1-4.3
c-0.2-0.2-0.9-1-1.9-1c-0.6,0-1.1,0.2-1.4,0.4c-0.1,0-0.1,0.1-0.2,0.1c-0.8,0.3-4.8,2.2-6.3,2.9c-1.1-0.5-1.9-0.9-2.4-1.1
c-0.2-0.1-0.5-0.2-0.8-0.2c-0.7,0-1.3,0.3-1.6,0.9h-2.4c0.2-0.4,0.2-0.8,0.1-1.1c-0.2-0.7-0.7-1.2-1.3-1.3l-4.3-1
C274.6,274,274.5,274,274.3,274L274.3,274L274.3,274z M280,286.1c0.8-1,1.6-2,2.2-2.8v2.8H280L280,286.1z M280.1,291h1.8
c0.1,0,0.1,0,0.2,0c0,0.3,0,0.7-0.1,1h-2.2C280,291.7,280.1,291.3,280.1,291L280.1,291z"/>
</g>
<g>
<path fill="#FFFFFF" d="M332.1,308.9c-0.4,0-0.8-0.2-1.1-0.5c-0.5-0.5-0.5-1.3-0.1-1.9c0.5-0.7,2.1-3.4,2.1-7v-0.4
c-0.2,0-0.7,0-0.7,0c-0.1,0-0.2,0-0.4,0c-0.1,0-0.2,0-0.3,0c-0.1,0-0.2,0-0.2,0c-0.4,0-0.8-0.2-1.1-0.4c-0.3-0.3-0.5-0.8-0.4-1.3
c0-0.1,0-0.1-0.2-0.6c-0.3-0.5-0.2-1.1,0.1-1.6c0.3-0.4,0.7-0.6,1.2-0.6c0.1,0,0.2,0,0.3,0c0.2,0,0.3,0.1,0.4,0.1
c-0.3-0.3-0.4-0.7-0.4-1.1c0,0,0.3-4.4,0.3-6.2v-2.3c0-1.4-0.2-6.8-0.2-6.9c0-0.4,0.2-0.9,0.5-1.2c0.3-0.2,0.6-0.4,1-0.4
c0.1,0,0.2,0,0.2,0c0,0,3.6,0.6,3.6,0.6c0.1-0.8,0.7-1.3,1.5-1.3h14.2c0.5,0,1.1,0.3,1.3,0.8c0,0,0.1,0,0.1,0l4.9,0.3
c0.6,0,1.2,0.5,1.4,1.1c0.2,0.6-0.1,1.3-0.6,1.6c0,0-0.6,0.5-0.7,1.4l0,12.4c0,0.5-0.2,0.9-0.6,1.2h1.3c0.7,0,1.3,0.5,1.5,1.2
c0.1,0.5-0.1,1-0.4,1.4c0,0.1,0,0.1,0,0.3c0,0.8-0.7,1.5-1.5,1.5h-1.1v6.8c0,0.7-0.4,1.2-1,1.4l-3.4,1.1c-0.1,0-0.3,0.1-0.5,0.1
c-0.3,0-0.6-0.1-0.9-0.3c-0.4-0.3-0.6-0.7-0.6-1.2v-7.8h-0.4v6.8c0,0.7-0.4,1.2-1,1.4l-3.3,1.1c-0.1,0-0.3,0.1-0.5,0.1
c-0.3,0-0.6-0.1-0.9-0.3c-0.3-0.2-0.5-0.5-0.6-0.9c0,0-0.1,0-0.1,0l-3.3,1.1c-0.1,0-0.3,0.1-0.5,0.1c-0.3,0-0.6-0.1-0.9-0.3
c-0.4-0.3-0.6-0.7-0.6-1.2v-7.8h-0.3v0.7c0,3.2-1.5,5.8-4.4,7.6c-0.9,0.5-2,1.2-2.1,1.3C332.6,308.8,332.4,308.9,332.1,308.9z"/>
<path fill="#FFFFFF" d="M352.4,276.2c0.5,0,1,0.3,1.2,0.8c0.1,0,0.2,0,0.3,0c0,0,0,0,0.1,0l4.8,0.3c0.5,0,1,0.4,1.1,0.9
c0.1,0.5-0.1,1.1-0.5,1.4c0,0-0.7,0.5-0.8,1.5v12.4c0,0.7-0.6,1.3-1.3,1.3h-6.2v0.2h8.4c0.6,0,1.1,0.4,1.2,1
c0.1,0.5-0.1,0.9-0.4,1.2c0,0.1,0,0.2,0,0.4c0,0.7-0.6,1.3-1.3,1.3h-1.3v7c0,0.5-0.4,1-0.9,1.2l-3.4,1.1c-0.1,0-0.2,0.1-0.4,0.1
c-0.3,0-0.5-0.1-0.7-0.2c-0.3-0.2-0.5-0.6-0.5-1v-8.1h-0.9v7c0,0.5-0.3,1-0.9,1.2l-3.3,1.1c-0.1,0-0.3,0.1-0.4,0.1
c-0.3,0-0.5-0.1-0.7-0.2c-0.3-0.2-0.5-0.6-0.5-1v-0.1c-0.1,0.1-0.2,0.2-0.4,0.2l-3.3,1.1c-0.1,0-0.3,0.1-0.4,0.1
c-0.3,0-0.5-0.1-0.7-0.2c-0.3-0.2-0.5-0.6-0.5-1v-8.1h-0.8v1c0,3.1-1.4,5.6-4.2,7.4c-0.9,0.5-2.1,1.3-2.1,1.3
c-0.2,0.1-0.4,0.2-0.7,0.2c-0.3,0-0.7-0.1-0.9-0.4c-0.4-0.4-0.5-1.1-0.1-1.6c0.5-0.7,2.2-3.5,2.2-7.2v-0.7c-0.3,0-0.6,0-0.9,0
c-0.2,0-0.3,0-0.5,0c-0.1,0-0.2,0-0.4,0c-0.1,0-0.1,0-0.2,0c-0.3,0-0.7-0.1-0.9-0.4c-0.3-0.3-0.4-0.7-0.3-1.1c0-0.1,0-0.2-0.3-0.8
c-0.2-0.4-0.2-0.9,0.1-1.3c0.2-0.3,0.6-0.5,1-0.5c0.1,0,0.1,0,0.2,0c0.9,0.2,1.6,0.2,3,0.2h5.7v-0.1h-7c-0.3,0-0.7-0.1-0.9-0.4
s-0.4-0.6-0.3-0.9c0,0,0.3-4.4,0.3-6.2v-2.3c0-1.4-0.2-6.8-0.2-6.9c0-0.4,0.1-0.7,0.4-1c0.2-0.2,0.5-0.3,0.8-0.3
c0.1,0,0.1,0,0.2,0l3.6,0.6c0.1,0,0.2,0,0.3,0.1v-0.1c0-0.7,0.6-1.3,1.3-1.3H352.4 M342.7,280.2h5.1V280h-5.1V280.2 M342.7,284.2
h5.1V284h-5.1V284.2 M342.7,288.2h5.1V288h-5.1V288.2 M352.4,275.7h-14.2c-0.8,0-1.5,0.5-1.7,1.2l-3.3-0.5c-0.1,0-0.2,0-0.3,0
c-0.4,0-0.8,0.2-1.2,0.4c-0.4,0.3-0.6,0.9-0.6,1.4c0,0.1,0.2,5.5,0.2,6.9v2.3c0,1.7-0.3,6.1-0.3,6.1c0,0.3,0,0.5,0.1,0.8
c-0.1,0-0.1,0-0.2,0c-0.5,0-1.1,0.3-1.4,0.7c-0.4,0.5-0.5,1.2-0.2,1.8c0.1,0.1,0.2,0.4,0.2,0.5c-0.1,0.5,0.1,1.1,0.5,1.5
c0.3,0.3,0.8,0.5,1.2,0.5c0.1,0,0.2,0,0.3,0c0.1,0,0.2,0,0.3,0c0.1,0,0.2,0,0.3,0l0.1,0c0.1,0,0.2,0,0.4,0v0.2
c0,3.6-1.6,6.2-2.1,6.9c-0.5,0.7-0.4,1.6,0.2,2.2c0.3,0.3,0.8,0.5,1.3,0.5c0.3,0,0.6-0.1,0.9-0.3c0.2-0.1,1.3-0.8,2.1-1.3
c2.3-1.5,3.7-3.4,4.3-5.7v5c0,0.6,0.3,1.1,0.7,1.4c0.3,0.2,0.7,0.3,1,0.3c0.2,0,0.4,0,0.5-0.1l3.1-1c0.1,0.3,0.3,0.6,0.6,0.8
c0.3,0.2,0.7,0.3,1,0.3c0.2,0,0.4,0,0.5-0.1l3.3-1.1c0.5-0.2,0.9-0.5,1.1-1v0.4c0,0.6,0.3,1.1,0.7,1.4c0.3,0.2,0.7,0.3,1,0.3
c0.2,0,0.4,0,0.5-0.1l3.4-1.1c0.7-0.2,1.2-0.9,1.2-1.7v-6.5h0.8c1,0,1.8-0.8,1.8-1.8c0-0.1,0-0.1,0-0.1c0.4-0.4,0.6-1,0.4-1.5
c-0.2-0.8-0.9-1.4-1.7-1.4h-0.7c0.2-0.3,0.3-0.6,0.3-0.9v-12.4c0.1-0.8,0.6-1.2,0.6-1.2c0.6-0.4,0.9-1.2,0.7-1.9
c-0.2-0.7-0.8-1.2-1.6-1.3l-4.8-0.3l-0.1,0C353.5,276,353,275.7,352.4,275.7L352.4,275.7z"/>
</g>
<g>
<path fill="#FFFFFF" d="M391.4,308.6c-4.2,0-7.5-0.7-10-2c-1.2-0.7-2.2-1.6-3.1-2.6c-0.6,0.8-1.2,1.5-2,2.1
c-0.9,0.7-2.5,1.5-2.7,1.5c-0.2,0.1-0.4,0.1-0.6,0.1c-0.5,0-0.9-0.2-1.2-0.5c-0.2-0.2-0.3-0.5-0.3-0.8c-1,0.7-2.1,1-3.2,1
c-0.7,0-1.7-0.4-2-2c0-0.4-0.5-1.1-1.7-1.7c-0.5-0.3-0.8-0.8-0.8-1.3v-0.4c0-0.4,0.2-0.9,0.5-1.1c0.2-0.1,0.3-0.2,0.5-0.3
c-0.7-1.7-3.8-8.6-4.5-10.8c0,0,0-0.1-0.1-0.2c-0.2-0.6-0.1-1.3,0.4-1.7c0.3-0.3,0.7-0.4,1.1-0.4c0.3,0,0.6,0.1,0.9,0.2
c1.4,0.8,2.7,1.3,4.1,1.3c0.2,0,0.4,0,0.5,0v-2.7c-0.6,0-1.3,0-2,0c-1.5,0-1.8,0-2.3-0.5c-0.3-0.3-0.5-0.8-0.4-1.3
c0,0-0.1-0.2-0.2-0.3l-0.1-0.2c-0.3-0.5-0.2-1.1,0.1-1.6c0.3-0.4,0.7-0.6,1.2-0.6c0.1,0,0.2,0,0.2,0c0.3,0,1.8,0.1,3.3,0.2v-4.8
c0-0.5,0.2-0.9,0.6-1.2c0.3-0.2,0.6-0.3,0.9-0.3c0.1,0,0.2,0,0.3,0l4.2,1c0.5,0.1,0.9,0.5,1.1,1c0.1,0.4,0.1,0.9-0.2,1.3
c0,0-0.1,0.1-0.1,0.1c0,0-0.1,0.1-0.2,0.3c0.2-0.1,0.4-0.2,0.7-0.2c0.1,0,0.1,0,0.2,0c0.6,0.1,4.1,0.2,5.2,0.2
c0-0.9-0.1-1.8-0.2-2.8c-0.1-0.5,0.1-0.9,0.4-1.2c0.3-0.3,0.7-0.5,1.1-0.5c0.1,0,0.1,0,0.2,0c1,0.1,5,0.5,5,0.5
c0.7,0.1,1.2,0.5,1.3,1.2c0.1,0.6-0.2,1.3-0.7,1.6c-0.1,0.1-0.4,0.4-0.5,1.2l5.7,0c0.8,0,1.5,0.7,1.5,1.5c0,0.4-0.2,0.8-0.5,1.1
c0,0,0,0.1,0,0.2c0,0.8-0.7,1.5-1.5,1.5h-5.2v0.3h5.3c0.7,0,1.3,0.5,1.4,1.1c0.2,0.6-0.1,1.3-0.6,1.7c-0.1,0.1-0.3,0.4-0.4,1v0
h1.6c0.8,0,1.5,0.7,1.5,1.5c0,0.4-0.2,0.8-0.5,1.1c0,0,0,0.1,0,0.2c0,0.8-0.7,1.5-1.5,1.5h-1v2.3c0,0.8-0.7,1.5-1.5,1.5h-4.4v0.6
h5.2c0.8,0,1.5,0.7,1.5,1.5c0,0.4-0.2,0.8-0.5,1.1c0,0,0,0.1,0,0.2c0,0.4-0.2,0.8-0.5,1.1c0.3-0.1,0.7-0.3,1.1-0.5
c0.2-0.1,0.4-0.1,0.6-0.1c0.5,0,1,0.3,1.3,0.7c0.4,0.7,0.2,1.5-0.4,2c-1.2,0.9-1.9,2.4-1.8,4.1l0,0.5
C392.9,307.9,392.2,308.6,391.4,308.6z M372.9,293.1c0.3,0.3,0.4,0.6,0.4,1v8c0.1-0.3,0.2-0.7,0.4-1c0.6-1.6,1-3.6,1.3-5.9
c-0.2-0.3-0.3-0.7-0.3-1.1c0-0.1,0-0.1-0.2-0.6c-0.2-0.5-0.2-1,0.1-1.4c-0.2-0.1-0.5-0.2-0.7-0.3L372.9,293.1z M386.3,301.8l0.7,0
c1.2-0.1,2-0.2,4.1-1c0,0-4.8,0-4.8,0V301.8z M377.5,284c0.8,0,1.9,0.1,2.5,0.1v-0.3l-2.5,0C377.5,283.9,377.5,283.9,377.5,284z"
/>
<path fill="#FFFFFF" d="M381.1,275.3c0,0,0.1,0,0.1,0c1,0.1,5,0.5,5,0.5c0.5,0.1,1,0.5,1.1,1c0.1,0.5-0.1,1.1-0.6,1.3
c0,0-0.6,0.4-0.6,1.7v0h6c0.7,0,1.3,0.6,1.3,1.3c0,0.4-0.2,0.7-0.5,1c0,0.1,0,0.2,0,0.3c0,0.7-0.6,1.3-1.3,1.3h-5.5v0.8h5.6
c0.6,0,1.1,0.4,1.2,0.9c0.1,0.5-0.1,1.1-0.6,1.4c0,0-0.4,0.3-0.5,1.2v0.3h1.8c0.7,0,1.3,0.6,1.3,1.3c0,0.4-0.2,0.7-0.5,1
c0,0.1,0,0.2,0,0.3c0,0.7-0.6,1.3-1.3,1.3h-1.3v2.5c0,0.7-0.6,1.3-1.3,1.3h-4.6v1.1h5.5c0.7,0,1.3,0.6,1.3,1.3
c0,0.4-0.2,0.7-0.5,1c0,0.1,0,0.2,0,0.3c0,0.7-0.6,1.3-1.3,1.3h-5v1.5l1,0c1.5-0.2,2.4-0.2,6.2-1.9c0.2-0.1,0.3-0.1,0.5-0.1
c0.4,0,0.9,0.2,1.1,0.6c0.3,0.5,0.2,1.2-0.3,1.6c-1.3,1-2,2.5-1.9,4.3l0,0.5c0,0.7-0.6,1.3-1.3,1.3c-4.1,0-7.4-0.7-9.9-2
c-1.5-0.9-2.5-1.9-3.2-2.8c-0.5,0.8-1.2,1.6-2.1,2.4c-0.9,0.7-2.5,1.4-2.7,1.5c-0.2,0.1-0.4,0.1-0.5,0.1c-0.4,0-0.7-0.2-1-0.5
c-0.3-0.3-0.3-0.8-0.2-1.1c-0.1,0.1-0.2,0.2-0.3,0.2c-1,0.7-2.1,1.1-3.2,1.1c-0.9,0-1.5-0.6-1.7-1.8c0-0.4-0.5-1.2-1.9-1.9
c-0.4-0.2-0.7-0.6-0.7-1.1v-0.4c0-0.4,0.2-0.7,0.4-1c0.2-0.2,0.5-0.3,0.8-0.3c-0.1-0.1-0.1-0.2-0.2-0.3c-0.6-1.4-3.8-8.6-4.5-10.8
c0-0.1-0.1-0.1-0.1-0.2c-0.2-0.5,0-1.1,0.3-1.4c0.2-0.2,0.6-0.4,0.9-0.4c0.2,0,0.6,0.1,0.8,0.2c1.4,0.9,2.8,1.3,4.2,1.3
c0.3,0,0.5,0,0.8,0v-3.2c-0.7,0-1.5,0-2.2,0c-1.4,0-1.7,0-2.2-0.4c-0.3-0.3-0.4-0.7-0.3-1.1c0-0.1,0-0.1-0.2-0.5l-0.1-0.2
c-0.2-0.4-0.2-0.9,0.1-1.3c0.2-0.3,0.6-0.5,1-0.5c0.1,0,0.1,0,0.2,0c0.3,0.1,2.1,0.1,3.5,0.2v-5.1c0-0.4,0.2-0.7,0.5-1
c0.2-0.2,0.5-0.3,0.8-0.3c0.1,0,0.2,0,0.3,0l4.2,1c0.4,0.1,0.8,0.4,0.9,0.8c0.1,0.4,0.1,0.9-0.2,1.2c0,0-0.7,0.9-0.7,2v1.4h0.5
c0-0.1,0-0.2,0-0.3c0-0.1,0-0.2-0.3-0.8c-0.2-0.4-0.2-0.9,0.1-1.3c0.2-0.3,0.6-0.5,1-0.5c0,0,0.1,0,0.1,0c0.7,0.1,4.7,0.2,5.4,0.2
h0.1c0-1.1-0.1-2-0.3-3.1c0-0.4,0.1-0.8,0.3-1C380.4,275.4,380.7,275.3,381.1,275.3 M380.2,284.3v-0.8H380c0,0-1.4,0-2.8,0.1
c0,0.2,0,0.4-0.1,0.6C378.1,284.3,379.6,284.3,380.2,284.3 M373.1,286.9c0.3-0.2,0.6-0.5,0.8-0.7h-0.8V286.9 M373,303.7
c0.4-0.8,0.6-1.6,0.9-2.5c0.6-1.6,1-3.7,1.3-6c0,0,0,0,0,0c-0.2-0.3-0.3-0.6-0.3-1c0-0.1,0-0.2-0.3-0.8c-0.2-0.4-0.2-0.9,0.1-1.3
c0.1-0.1,0.1-0.2,0.2-0.2c0,0-0.1,0-0.1,0c-0.3,0-0.7-0.1-0.9-0.4c-0.1-0.1-0.1-0.1-0.1-0.2c-0.4,0.6-0.8,1.2-1.2,1.8
c0.3,0.2,0.5,0.6,0.5,1v8.4C373.1,302.9,373,303.3,373,303.7 M380,291.8l0.2,0L380,291.8c-0.1,0-0.2,0-0.3,0
C379.8,291.8,379.9,291.8,380,291.8 M380.3,296v-0.4h-0.2c-0.2,0-0.3,0-0.5,0C379.9,295.7,380.1,295.9,380.3,296 M380.3,300v-0.7
c-0.1,0.2-0.1,0.3-0.2,0.5C380.2,299.9,380.2,299.9,380.3,300 M381.1,274.8L381.1,274.8c-0.5,0-0.9,0.2-1.3,0.5
c-0.4,0.4-0.5,0.9-0.5,1.4c0.1,0.9,0.2,1.7,0.2,2.5c-1.3,0-4.4-0.1-4.9-0.2c-0.1,0-0.1,0-0.2,0c0,0-0.1,0-0.1,0l0,0
c0.2-0.4,0.3-0.9,0.1-1.4c-0.2-0.6-0.7-1-1.3-1.1l-4.2-1c-0.1,0-0.3,0-0.4,0c-0.4,0-0.8,0.1-1.1,0.4c-0.4,0.3-0.7,0.8-0.7,1.4v4.6
c-1.5,0-2.7-0.1-3-0.1c-0.1,0-0.2,0-0.3,0c-0.6,0-1.1,0.3-1.4,0.7c-0.4,0.5-0.5,1.2-0.2,1.8l0.1,0.2c0.1,0.1,0.1,0.2,0.1,0.2
c-0.1,0.5,0.1,1.1,0.5,1.5c0.6,0.6,1,0.6,2.5,0.6c0.5,0,1.1,0,1.7,0v2.2c-0.1,0-0.2,0-0.3,0c-1.3,0-2.6-0.4-4-1.2
c-0.3-0.2-0.7-0.3-1-0.3c-0.5,0-0.9,0.2-1.2,0.5c-0.5,0.5-0.7,1.3-0.4,2c0,0.1,0.1,0.1,0.1,0.2c0.7,2.1,3.5,8.5,4.4,10.5
c-0.1,0.1-0.3,0.1-0.4,0.2c-0.4,0.3-0.6,0.8-0.6,1.3v0.4c0,0.6,0.4,1.2,0.9,1.5c1.2,0.6,1.6,1.3,1.6,1.5c0.3,2,1.5,2.3,2.2,2.3
c1.1,0,2.1-0.3,3.1-0.9c0.1,0.2,0.2,0.4,0.3,0.5c0.3,0.4,0.8,0.6,1.4,0.6c0.3,0,0.5-0.1,0.7-0.2c0.2-0.1,1.8-0.9,2.7-1.6
c0.7-0.6,1.3-1.2,1.9-2c0.8,0.9,1.8,1.7,2.9,2.4c2.6,1.4,6,2,10.2,2c1,0,1.8-0.8,1.8-1.8l0-0.5c-0.1-1.6,0.6-3.1,1.7-3.9
c0.7-0.5,0.9-1.5,0.5-2.3c-0.3-0.5-0.9-0.9-1.5-0.9c-0.2,0-0.5,0-0.7,0.1c-0.1,0.1-0.2,0.1-0.3,0.1c0.1-0.2,0.1-0.4,0.1-0.6
c0,0,0,0,0,0c0.3-0.3,0.5-0.8,0.5-1.2c0-1-0.8-1.8-1.8-1.8h-5v-0.1h4.1c1,0,1.8-0.8,1.8-1.8v-2h0.8c1,0,1.8-0.8,1.8-1.8
c0,0,0,0,0,0c0.3-0.3,0.5-0.8,0.5-1.2c0-1-0.8-1.8-1.8-1.8h-1.3c0.1-0.4,0.2-0.6,0.3-0.6c0.6-0.4,0.9-1.2,0.7-1.9
c-0.2-0.6-0.6-1-1.1-1.2c0.6-0.3,1.1-0.9,1.1-1.6c0,0,0,0,0,0c0.3-0.3,0.5-0.8,0.5-1.2c0-1-0.8-1.8-1.8-1.8h-5.4
c0.1-0.5,0.3-0.7,0.3-0.8c0.6-0.4,1-1.1,0.8-1.9c-0.2-0.8-0.8-1.3-1.6-1.4c0,0-4-0.4-5-0.5C381.2,274.8,381.1,274.8,381.1,274.8
L381.1,274.8L381.1,274.8z M373.2,293.1l0.4-0.6l0.2-0.4c0.1,0.1,0.2,0.1,0.3,0.1c-0.2,0.4-0.1,1,0.1,1.4c0.1,0.1,0.2,0.4,0.2,0.5
c-0.1,0.4,0,0.8,0.3,1.2c-0.2,2-0.6,3.8-1.1,5.3v-6.5C373.6,293.8,373.5,293.4,373.2,293.1L373.2,293.1z M386.6,301h3.1
c-1.1,0.4-1.8,0.4-2.7,0.5l-0.4,0V301L386.6,301z"/>
</g>
<g>
<path fill="#FFFFFF" d="M314.8,298.1c-2.6,0-4.7-2.1-4.7-4.7s2.1-4.7,4.7-4.7s4.7,2.1,4.7,4.7S317.3,298.1,314.8,298.1z"/>
<path fill="#FFFFFF" d="M314.8,289c2.4,0,4.4,2,4.4,4.4s-2,4.4-4.4,4.4s-4.4-2-4.4-4.4S312.3,289,314.8,289 M314.8,288.5
c-2.7,0-4.9,2.2-4.9,4.9s2.2,4.9,4.9,4.9s4.9-2.2,4.9-4.9S317.5,288.5,314.8,288.5L314.8,288.5z"/>
</g>
</g>
<g id="Layer_1_copy">
<g>
<path fill="#DF0012" d="M209.8,253.2l-18.6,26.7l-6.1,0.5c-4.6,0-8.9-1.3-13-3.8l-1.2-0.3c-1.3-0.2-2,0.5-2,2l0.3,1.2l8.7,18.9
l-5.8,8.4l-0.3,0.3c-0.8,0.4-1.2,0.3-1.2-0.3l-20.3-43l0.3-0.3h0.3c11.4,6.5,23.2,7.7,35.5,3.5c7.7-2.7,15.2-7.3,22.6-13.9h0.3
c0-0.2,0.1-0.2,0.3,0L209.8,253.2"/>
<path fill="#DF0012" d="M209.8,271.8l-24.6,35.3l-0.3,0.3l-0.9-0.6v0.3l-13-28.4v-0.3h0.3c12.1,6.9,24.8,4.7,38.1-6.6v-0.3
L209.8,271.8"/>
</g>
<g>
<path fill="#3E3A39" d="M255,295.9v-2.6h7.6v-12.9c0.2-1.7,1.3-2.6,1.3-2.6l-4.8-0.4v14.5h-7.5v14.8l3.4-1.1v-8.5h3.4l0,0v9.5
l3.4-1.1v-8.5h2.5h0.1c0-1.3,0.5-1.3,0.5-1.3S255,295.9,255,295.9z M257.4,276.7H243v13.5h14.5L257.4,276.7L257.4,276.7z
M254,288.9h-7.7v-2.8h7.7V288.9z M254,284.9h-7.7v-2.8h7.7V284.9z M254,280.8h-7.7V278h7.7V280.8z M241.2,291.9v-13.9l-3.7-0.7
c0,0,0.2,5.6,0.2,7.1v2.3c0,1.8-0.3,6.4-0.3,6.4h8.4v2.6c0,0-6.8,0-7,0c-1.3,0-2.1,0-3.3-0.2c0.3,0.6,0.5,1.1,0.4,1.6
c0.6-0.1,1.1,0,2.1,0h1.1c0,0,0,1.1,0,1.9c0,3.6-1.3,6.5-2.4,8.1c0,0,1.3-0.8,2.2-1.3c3.3-2.1,3.8-4.8,3.8-6.5c0-0.6,0-2.2,0-2.2
h3.3v9.5l3.4-1.1v-13.7H241.2z"/>
<path fill="#DF0012" d="M282.4,299.6c-0.9-1.3-3.6-2.7-5.1-3.2v-1.3c2.7,0,5,0,5,0c0.1-0.8,0.5-1.3,0.5-1.3h-5.6v-0.3
c0.1-2,1.2-2.4,1.2-2.4l-4.5-1v2.8v0.9h-1.3c0,0-3.5-0.1-3.9-0.2c0.3,0.6,0.4,1,0.4,1.4c0,0,1.3,0,3,0c-0.1,0.6-0.2,1.3-0.4,2.1
c-1,4-3.6,7.4-4.9,9c0,0,1.4-0.7,2.5-1.2c3.1-1.5,4.2-3.8,4.8-5.8v7.7l3.4-1.1v-8.3c1,1.1,1.9,2.5,2.6,4.3
c0.1,0.4,0.3,0.8,0.4,1.2c0.1,0.2,0.2,0.2,0.4-0.1c0.5-1,1.1-1.8,1.9-2.8C282.6,300,282.5,299.8,282.4,299.6z M295.3,287.2
c-1.4,0-6.5,0.2-6.5,0.2s-0.6,0-1.3,0c0-0.8,0-1.3,0-1.8c0,0,0-4,0-4.1c3.4-0.3,4.6-0.5,8.3-1.1c2.2-0.5,2.4-0.1,2.9-0.3
c-0.1-0.4-2-2.8-2.7-3.6c-0.6-0.7-0.8-0.4-1.5,0c-0.8,0.3-7,3.3-7,3.3s-2.2-1-3.2-1.4c-0.2,0-0.2,0.1-0.3,0.3c0,0.7,0,1,0,2v4.9
v3.2c0,4.7-1,12.7-2.6,16.7c-0.5,1-0.8,1.5-0.7,1.6c0.1,0.1,0.2,0.1,0.5,0c3-2.3,4.8-6.1,5.6-11.3c0.3-2,0.5-4.9,0.6-7.1
c1.1,0,2.3,0,3.7,0v18.1l3.4-1.1v-17c2.4,0,3.6,0,3.6,0c0.2-1.2,0.7-2,0.9-2C298.4,286.8,295.8,287.2,295.3,287.2z M282.4,287.9
h-4.2c-0.4,0.5-0.8,1-1.1,1.3c2.6,0,4.8,0,4.8,0C282,288.5,282.4,287.9,282.4,287.9z M272.9,289.2c-0.2-0.4-0.4-0.9-0.7-1.3
c-0.8,0-3.3-0.1-3.7-0.2c0.3,0.6,0.4,1,0.4,1.4C269,289.2,270.7,289.2,272.9,289.2z M283.1,280.6c0.1-0.8,0.5-1.3,0.5-1.3h-5.9
c0-0.1,0,0.2,0-0.1c0-1.6,1-2.4,1-2.4l-4.3-1v3.4c-1.3,0-4.9-0.1-5.6-0.2c0.3,0.6,0.4,1.5,0.4,1.5L283.1,280.6L283.1,280.6z
M274.6,289.7L274.6,289.7L274.6,289.7L274.6,289.7z M274.8,289.7C274.9,289.7,274.9,289.6,274.8,289.7c1.1-1.3,5.9-7.2,7.2-8.9
l0,0l0,0l0,0l0,0l0,0c-1.7,1.4-6,4.3-10.5,2.2l0,0h-0.1c0,0,0,0,0,0.1l0,0c0.4,0.9,2.7,5.6,3.2,6.6
C274.7,289.7,274.8,289.8,274.8,289.7z"/>
</g>
<g>
<path fill="#3E3A39" d="M349.9,296.2v-2.6h7.4V281c0.2-1.7,1.3-2.5,1.3-2.5l-4.8-0.3v14.1h-7.4v14.5l3.3-1.1v-8.3h3.4l0,0v9.3
l3.4-1.1v-8.3h2.5h0.1c0-1.2,0.5-1.3,0.5-1.3L349.9,296.2L349.9,296.2z M352.4,277.5h-14.2v13.2h14.2V277.5z M349,289.4h-7.6v-2.7
h7.6V289.4z M349,285.5h-7.6v-2.7h7.6V285.5z M349,281.4h-7.6v-2.7h7.6V281.4z M336.4,292.3v-13.6l-3.6-0.6c0,0,0.2,5.5,0.2,6.9
v2.3c0,1.8-0.3,6.3-0.3,6.3h8.3v2.6c0,0-6.7,0-6.9,0c-1.3,0-2.1,0-3.2-0.2c0.3,0.6,0.5,1,0.4,1.5c0.6-0.1,1.1,0,2.1,0h1.1
c0,0,0,1.1,0,1.9c0,3.5-1.3,6.4-2.4,7.9c0,0,1.3-0.8,2.1-1.3c3.2-2,3.7-4.6,3.7-6.4c0-0.6,0-2.2,0-2.2h3.3v9.3l3.3-1.1v-13.5
L336.4,292.3L336.4,292.3z"/>
<path fill="#DF0012" d="M366.2,300.1c0.1,0.1,0.2,0.2,0.3,0.1c0.1,0,0.1-0.1,0.1-0.1c1.2-1.7,7-10.7,8.8-13.3l0,0c0,0,0,0,0-0.1
h-0.1l0,0l0,0c-0.8,0.8-1.9,1.7-3.4,2.5V285h3.7c0.1-0.8,0.5-1.3,0.5-1.3h-4.1c0,0,0-1.6,0-2.7c0-1.6,1-2.8,1-2.8l-4.2-1v6.4
c-1.3,0-4.4-0.1-5-0.2c0.3,0.6,0.5,0.9,0.4,1.4c0.1,0.1,4.7,0,4.7,0v5.5c-2.1,0.5-4.4,0.3-6.9-1.3l0,0c0,0,0,0-0.1,0
c0,0-0.1,0.1,0,0.1l0,0C362.1,290.9,365.4,298.4,366.2,300.1L366.2,300.1z M368.6,301.9c0,0.3-0.3,0.5-0.8,0.5
c-0.5,0-1.4-0.1-2.6-0.3v0.4c1.6,0.9,2.4,1.9,2.5,2.8c0.1,0.6,0.2,0.8,0.5,0.8c0.9,0,1.7-0.3,2.5-0.9c0.8-0.5,1.2-1.3,1.2-2.7
v-8.4l-3.3,4.8V301.9L368.6,301.9z M393.8,301.3c-4.2,1.8-5.1,1.8-6.9,2h-2v-4h6.3c0-1.3,0.5-1.3,0.5-1.3h-6.7v-3.6h5.9v-3.8h2.5
c0-1.3,0.5-1.3,0.5-1.3h-3.1v-1.6c0.1-1.6,1.1-2.2,1.1-2.2h-6.8v-3.3h6.7c0-1.3,0.5-1.3,0.5-1.3h-7.2c0-0.4,0-1.2,0-1.3
c0-2.1,1.3-2.8,1.3-2.8s-4-0.4-5-0.5c0.2,1.4,0.3,2.8,0.3,4.5H380l0,0c-0.7,0-4.8-0.1-5.6-0.2c0.3,0.6,0.5,1,0.4,1.5
c0.1,0,5.2-0.1,5.2-0.1h1.4v3.3h-1.1l0,0l0,0l0,0c-0.7,0-3.6-0.1-4.3-0.2c0.3,0.6,0.5,1,0.4,1.5c0.5-0.1,3.9-0.1,3.9-0.1h1.1v2.5
H380l0,0c-0.6,0-5.5-0.2-5.6-0.2c0.3,0.6,0.5,1,0.4,1.5c0.5-0.1,5.2-0.1,5.2-0.1h1.4v2.5H380l0,0c-0.7,0-3.6-0.1-4.2-0.2
c0.3,0.6,0.5,1,0.4,1.5c0.5-0.1,3.9-0.1,3.9-0.1c0.1,0,1.4,0,1.4,0v8.3c-0.5-0.2-2-1.3-2.8-2.6c0.1-0.5,0.3-1,0.5-1.4
c0-0.2,0.7-1.3,0.7-1.3s-2.4-1.4-3.5-1.8c-0.3,2.5-0.8,4.6-1.3,6.3c-0.6,1.6-1.2,3.3-2.2,4.7c0,0,1.6-0.8,2.4-1.3
c2-1.6,2.8-3.8,2.8-3.8s1,2.3,3.9,4.1c3.3,1.7,7.5,1.8,9.3,1.8c0-0.2,0-0.3,0-0.5C391.3,304.3,392.2,302.4,393.8,301.3z
M384.8,286.8h2.4v2.5h-2.4V286.8z M384.8,290.6h2.4v2.5h-2.4V290.6z"/>
</g>
<circle fill="#3E3A39" cx="314.8" cy="293.5" r="3.2"/>
</g>
</svg>

BIN
gpt-mf-demo/mfe1/src/assets/img/fail.png View File

Before After
Width: 64  |  Height: 64  |  Size: 1.9 KiB

BIN
gpt-mf-demo/mfe1/src/assets/img/logo.png View File

Before After
Width: 46  |  Height: 32  |  Size: 1.4 KiB

BIN
gpt-mf-demo/mfe1/src/assets/img/other.png View File

Before After
Width: 80  |  Height: 80  |  Size: 11 KiB

BIN
gpt-mf-demo/mfe1/src/assets/img/receivable.png View File

Before After
Width: 80  |  Height: 80  |  Size: 10 KiB

BIN
gpt-mf-demo/mfe1/src/assets/img/success.png View File

Before After
Width: 64  |  Height: 64  |  Size: 2.1 KiB

BIN
gpt-mf-demo/mfe1/src/assets/img/user-pic.png View File

Before After
Width: 86  |  Height: 86  |  Size: 3.2 KiB

+ 12
- 0
gpt-mf-demo/mfe1/src/bootstrap.ts View File

@ -0,0 +1,12 @@
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));

+ 3
- 0
gpt-mf-demo/mfe1/src/environments/environment.prod.ts View File

@ -0,0 +1,3 @@
export const environment = {
production: true
};

+ 16
- 0
gpt-mf-demo/mfe1/src/environments/environment.ts View File

@ -0,0 +1,16 @@
// This file can be replaced during build by using the `fileReplacements` array.
// `ng build` replaces `environment.ts` with `environment.prod.ts`.
// The list of file replacements can be found in `angular.json`.
export const environment = {
production: false
};
/*
* For easier debugging in development mode, you can import the following file
* to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
*
* This import should be commented out in production mode because it will have a negative impact
* on performance if an error is thrown.
*/
// import 'zone.js/plugins/zone-error'; // Included with Angular CLI.

BIN
gpt-mf-demo/mfe1/src/favicon.ico View File

Before After
Width: 28  |  Height: 30  |  Size: 948 B

+ 13
- 0
gpt-mf-demo/mfe1/src/index.html View File

@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Remote</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>

+ 2
- 0
gpt-mf-demo/mfe1/src/main.ts View File

@ -0,0 +1,2 @@
import('./bootstrap')
.catch(err => console.error(err));

+ 65
- 0
gpt-mf-demo/mfe1/src/polyfills.ts View File

@ -0,0 +1,65 @@
/**
* This file includes polyfills needed by Angular and is loaded before the app.
* You can add your own extra polyfills to this file.
*
* This file is divided into 2 sections:
* 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
* 2. Application imports. Files imported after ZoneJS that should be loaded before your main
* file.
*
* The current setup is for so-called "evergreen" browsers; the last versions of browsers that
* automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
* Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
*
* Learn more in https://angular.io/guide/browser-support
*/
/***************************************************************************************************
* BROWSER POLYFILLS
*/
/**
* IE11 requires the following for NgClass support on SVG elements
*/
// import 'classlist.js'; // Run `npm install --save classlist.js`.
/**
* Web Animations `@angular/platform-browser/animations`
* Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
* Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
*/
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
/**
* By default, zone.js will patch all possible macroTask and DomEvents
* user can disable parts of macroTask/DomEvents patch by setting following flags
* because those flags need to be set before `zone.js` being loaded, and webpack
* will put import in the top of bundle, so user need to create a separate file
* in this directory (for example: zone-flags.ts), and put the following flags
* into that file, and then add the following code before importing zone.js.
* import './zone-flags';
*
* The flags allowed in zone-flags.ts are listed here.
*
* The following flags will work for all browsers.
*
* (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
* (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
* (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
*
* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
* with the following flag, it will bypass `zone.js` patch for IE/Edge
*
* (window as any).__Zone_enable_cross_context_check = true;
*
*/
/***************************************************************************************************
* Zone JS is required by default for Angular itself.
*/
import 'zone.js'; // Included with Angular CLI.
/***************************************************************************************************
* APPLICATION IMPORTS
*/

+ 15
- 0
gpt-mf-demo/mfe1/src/styles.scss View File

@ -0,0 +1,15 @@
/* You can add global styles to this file, and also import other style files */
@import "~ng-zorro-antd/style/index.min.css"; /* 引入基本样式 */
@import "~ng-zorro-antd/button/style/index.min.css"; /* 引入组件样式 */
html {
overflow: hidden;
background-color: #f4dcea;
}
.button{
height: 32px;
background-color: #b60816;
border: none;
font-weight: 700;
color: aliceblue;
}

+ 27
- 0
gpt-mf-demo/mfe1/src/test.ts View File

@ -0,0 +1,27 @@
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
import 'zone.js/testing';
import { getTestBed } from '@angular/core/testing';
import {
BrowserDynamicTestingModule,
platformBrowserDynamicTesting
} from '@angular/platform-browser-dynamic/testing';
declare const require: {
context(path: string, deep?: boolean, filter?: RegExp): {
keys(): string[];
<T>(id: string): T;
};
};
// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting(),
{ teardown: { destroyAfterEach: true }},
);
// Then we find all the tests.
const context = require.context('./', true, /\.spec\.ts$/);
// And load the modules.
context.keys().map(context);

+ 15
- 0
gpt-mf-demo/mfe1/tsconfig.app.json View File

@ -0,0 +1,15 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/app",
"types": []
},
"files": [
"src/main.ts",
"src/polyfills.ts"
],
"include": [
"src/**/*.d.ts"
]
}

+ 38
- 0
gpt-mf-demo/mfe1/tsconfig.json View File

@ -0,0 +1,38 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"sourceMap": true,
"declaration": false,
"downlevelIteration": true,
"experimentalDecorators": true,
"moduleResolution": "node",
"importHelpers": true,
"target": "es2017",
"module": "es2020",
"paths": {
"my-shared": [
"../shell/dist/my-shared"
],
"my-shared/*": [
"../shell/dist/my-shared/*"
]
},
"lib": [
"es2018",
"dom"
]
},
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"strictTemplates": true
}
}

+ 18
- 0
gpt-mf-demo/mfe1/tsconfig.spec.json View File

@ -0,0 +1,18 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/spec",
"types": [
"jasmine"
]
},
"files": [
"src/test.ts",
"src/polyfills.ts"
],
"include": [
"src/**/*.spec.ts",
"src/**/*.d.ts"
]
}

+ 77
- 0
gpt-mf-demo/mfe1/webpack.config.js View File

@ -0,0 +1,77 @@
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
const mf = require("@angular-architects/module-federation/webpack");
const path = require("path");
const share = mf.share;
const sharedMappings = new mf.SharedMappings();
sharedMappings.register(path.join(__dirname, "tsconfig.json"), []);
module.exports = {
output: {
uniqueName: "mfe1",
publicPath: "http://localhost:3001/",
},
optimization: {
runtimeChunk: false,
},
resolve: {
alias: {
...sharedMappings.getAliases(),
},
},
plugins: [
new ModuleFederationPlugin({
name: "mfe1",
filename: "remoteEntry.js",
exposes: {
"./Module": "./src/app/microfrontend/microfrontend.module.ts",
},
shared: share({
"assets/img": { eager: true },
"@angular/core": {
singleton: true,
strictVersion: true,
requiredVersion: "auto",
},
"@angular/common": {
singleton: true,
strictVersion: true,
requiredVersion: "auto",
},
"@angular/common/http": {
singleton: true,
strictVersion: true,
requiredVersion: "auto",
},
"@angular/router": {
singleton: true,
strictVersion: true,
requiredVersion: "auto",
},
"my-shared": {
singleton: true,
strictVersion: true,
import: "my-shared", // 对应库的npm包名或本地路径
requiredVersion: "*", // 或者具体的版本号,如"0.0.1"
},
...sharedMappings.getDescriptors(),
}),
}),
sharedMappings.getPlugin(),
],
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: "url-loader",
options: {
limit: 8192, // 将小于 8kb 的图片转为 base64
},
},
],
},
],
},
};

+ 1
- 0
gpt-mf-demo/mfe1/webpack.prod.config.js View File

@ -0,0 +1 @@
module.exports = require('./webpack.config');

+ 17
- 0
gpt-mf-demo/mfe2/.browserslistrc View File

@ -0,0 +1,17 @@
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
# For additional information regarding the format and rule options, please see:
# https://github.com/browserslist/browserslist#queries
# For the full list of supported browsers by the Angular framework, please see:
# https://angular.io/guide/browser-support
# You can see what browsers were selected by your queries by running:
# npx browserslist
last 1 Chrome version
last 1 Firefox version
last 2 Edge major versions
last 2 Safari major versions
last 2 iOS major versions
Firefox ESR
not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line.

+ 16
- 0
gpt-mf-demo/mfe2/.editorconfig View File

@ -0,0 +1,16 @@
# Editor configuration, see https://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
[*.ts]
quote_type = single
[*.md]
max_line_length = off
trim_trailing_whitespace = false

+ 45
- 0
gpt-mf-demo/mfe2/.gitignore View File

@ -0,0 +1,45 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.
# compiled output
/dist
/tmp
/out-tsc
# Only exists if Bazel was run
/bazel-out
# dependencies
/node_modules
# profiling files
chrome-profiler-events*.json
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.history/*
# misc
/.sass-cache
/connect.lock
/coverage
/libpeerconnection.log
npm-debug.log
yarn-error.log
testem.log
/typings
# System Files
.DS_Store
Thumbs.db

+ 27
- 0
gpt-mf-demo/mfe2/README.md View File

@ -0,0 +1,27 @@
# Remote1
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 12.2.8.
## Development server
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
## Code scaffolding
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
## Build
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory.
## Running unit tests
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
## Running end-to-end tests
Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities.
## Further help
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.

+ 123
- 0
gpt-mf-demo/mfe2/angular.json View File

@ -0,0 +1,123 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"cli": {
"analytics": false
},
"version": 1,
"newProjectRoot": "projects",
"projects": {
"remote1": {
"projectType": "application",
"schematics": {
"@schematics/angular:component": {
"style": "scss"
},
"@schematics/angular:application": {
"strict": true
}
},
"root": "",
"sourceRoot": "src",
"prefix": "remote1",
"architect": {
"build": {
"builder": "ngx-build-plus:browser",
"options": {
"outputPath": "dist/remote1",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"inlineStyleLanguage": "scss",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.scss"
],
"scripts": [],
"extraWebpackConfig": "webpack.config.js",
"commonChunk": false
},
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "500kb",
"maximumError": "1mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "2kb",
"maximumError": "4kb"
}
],
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"outputHashing": "all",
"extraWebpackConfig": "webpack.prod.config.js"
},
"development": {
"buildOptimizer": false,
"optimization": false,
"vendorChunk": true,
"extractLicenses": false,
"sourceMap": true,
"namedChunks": true
}
},
"defaultConfiguration": "production"
},
"serve": {
"builder": "ngx-build-plus:dev-server",
"configurations": {
"production": {
"browserTarget": "remote1:build:production",
"extraWebpackConfig": "webpack.prod.config.js"
},
"development": {
"browserTarget": "remote1:build:development"
}
},
"defaultConfiguration": "development",
"options": {
"port": 7000,
"extraWebpackConfig": "webpack.config.js"
}
},
"extract-i18n": {
"builder": "ngx-build-plus:extract-i18n",
"options": {
"browserTarget": "remote1:build",
"extraWebpackConfig": "webpack.config.js"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.spec.json",
"karmaConfig": "karma.conf.js",
"inlineStyleLanguage": "scss",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.scss"
],
"scripts": []
}
}
}
}
},
"defaultProject": "remote1"
}

+ 44
- 0
gpt-mf-demo/mfe2/karma.conf.js View File

@ -0,0 +1,44 @@
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage'),
require('@angular-devkit/build-angular/plugins/karma')
],
client: {
jasmine: {
// you can add configuration options for Jasmine here
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
// for example, you can disable the random execution with `random: false`
// or set a specific seed with `seed: 4321`
},
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
jasmineHtmlReporter: {
suppressAll: true // removes the duplicated traces
},
coverageReporter: {
dir: require('path').join(__dirname, './coverage/remote1'),
subdir: '.',
reporters: [
{ type: 'html' },
{ type: 'text-summary' }
]
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
restartOnFileChange: true
});
};

+ 11852
- 0
gpt-mf-demo/mfe2/package-lock.json
File diff suppressed because it is too large
View File


+ 43
- 0
gpt-mf-demo/mfe2/package.json View File

@ -0,0 +1,43 @@
{
"name": "remote1",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve --port 3002 --open",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test",
"run:all": "node node_modules/@angular-architects/module-federation/src/server/mf-dev-server.js"
},
"private": true,
"dependencies": {
"@angular-architects/module-federation": "^12.5.3",
"@angular/animations": "~12.2.0",
"@angular/common": "~12.2.0",
"@angular/compiler": "~12.2.0",
"@angular/core": "~12.2.0",
"@angular/forms": "~12.2.0",
"@angular/platform-browser": "~12.2.0",
"@angular/platform-browser-dynamic": "~12.2.0",
"@angular/router": "~12.2.0",
"my-shared": "file:../shell/dist/my-shared",
"ng-zorro-antd": "^17.3.0",
"rxjs": "~6.6.0",
"tslib": "^2.3.0",
"zone.js": "~0.11.4"
},
"devDependencies": {
"@angular-devkit/build-angular": "~12.2.8",
"@angular/cli": "~12.2.8",
"@angular/compiler-cli": "~12.2.0",
"@types/jasmine": "~3.8.0",
"@types/node": "^12.11.1",
"jasmine-core": "~3.8.0",
"karma": "~6.3.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage": "~2.0.3",
"karma-jasmine": "~4.0.0",
"karma-jasmine-html-reporter": "~1.7.0",
"typescript": "~4.3.5"
}
}

+ 19
- 0
gpt-mf-demo/mfe2/src/app/app-routing.module.ts View File

@ -0,0 +1,19 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [
{
path: '',
loadChildren: () =>
import('./microfrontend1/microfrontend1.module').then(
(m) => m.Microfrontend1Module
),
pathMatch: 'full',
},
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
})
export class AppRoutingModule {}

+ 2
- 0
gpt-mf-demo/mfe2/src/app/app.component.html View File

@ -0,0 +1,2 @@
<router-outlet></router-outlet>

+ 0
- 0
gpt-mf-demo/mfe2/src/app/app.component.scss View File


+ 35
- 0
gpt-mf-demo/mfe2/src/app/app.component.spec.ts View File

@ -0,0 +1,35 @@
import { TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [
RouterTestingModule
],
declarations: [
AppComponent
],
}).compileComponents();
});
it('should create the app', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
});
it(`should have as title 'remote1'`, () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app.title).toEqual('remote1');
});
it('should render title', () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.nativeElement as HTMLElement;
expect(compiled.querySelector('.content span')?.textContent).toContain('remote1 app is running!');
});
});

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save