Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
35656cd416 |
No files matched your search
@@ -11,10 +11,10 @@ jobs:
|
||||
build_n_push:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: setup-node
|
||||
uses: actions/setup-node@v3
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '16'
|
||||
cache: 'npm'
|
||||
@@ -27,26 +27,26 @@ jobs:
|
||||
run: CI=false npm run build
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
uses: docker/setup-qemu-action@v1
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
uses: docker/setup-buildx-action@v1
|
||||
-
|
||||
name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
uses: docker/metadata-action@v3
|
||||
with:
|
||||
images: wiretrustee/dashboard
|
||||
-
|
||||
name: Login to DockerHub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v2
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USER }}
|
||||
password: ${{ secrets.DOCKER_TOKEN }}
|
||||
-
|
||||
name: Docker build and push
|
||||
uses: docker/build-push-action@v3
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
file: docker/Dockerfile
|
||||
|
||||
@@ -26,6 +26,6 @@ yarn-error.log*
|
||||
src/auth_config.json
|
||||
.idea
|
||||
.eslintcache
|
||||
src/.local-config*.json
|
||||
src/.local-config.json
|
||||
/public/OidcServiceWorker.js
|
||||
/public/OidcTrustedDomains.js
|
||||
@@ -36,43 +36,24 @@ Disclaimer. We believe that proper user management system is not a trivial task
|
||||
use Auth0 service that covers all our needs (user management, social login, JTW for the management API).
|
||||
Auth0 so far is the only 3rd party dependency that can't be really self-hosted.
|
||||
|
||||
1. Install [Docker](https://docs.docker.com/get-docker/)
|
||||
2. Register [Auth0](https://auth0.com/) account
|
||||
3. Running Wiretrustee UI Dashboard requires the following Auth0 environmental variables to be set (see docker command below):
|
||||
1. install [Docker](https://docs.docker.com/get-docker/)
|
||||
2. register [Auth0](https://auth0.com/) account
|
||||
3. running Wiretrustee UI Dashboard requires the following Auth0 environmental variables to be set (see docker command below):
|
||||
|
||||
`AUTH0_DOMAIN` `AUTH0_CLIENT_ID` `AUTH0_AUDIENCE`
|
||||
```AUTH0_DOMAIN``` ```AUTH0_CLIENT_ID``` ```AUTH0_AUDIENCE```
|
||||
|
||||
To obtain these, please use [Auth0 React SDK Guide](https://auth0.com/docs/quickstart/spa/react/01-login#configure-auth0) up until "Configure Allowed Web Origins"
|
||||
|
||||
4. Wiretrustee UI Dashboard uses Wiretrustee Management Service HTTP API, so setting `NETBIRD_MGMT_API_ENDPOINT` is required. Most likely it will be `http://localhost:33071` if you are hosting Management API on the same server.
|
||||
4. Wiretrustee UI Dashboard uses Wiretrustee Management Service HTTP API, so setting ```WIRETRUSTEE_MGMT_API_ENDPOINT``` is required. Most likely it will be ```http://localhost:33071``` if you are hosting Management API on the same server.
|
||||
5. Run docker container without SSL (Let's Encrypt):
|
||||
|
||||
```shell
|
||||
docker run -d --name wiretrustee-dashboard \
|
||||
--rm -p 80:80 -p 443:443 \
|
||||
-e AUTH0_DOMAIN=<SET YOUR AUTH DOMAIN> \
|
||||
-e AUTH0_CLIENT_ID=<SET YOUR CLIENT ID> \
|
||||
-e AUTH0_AUDIENCE=<SET YOUR AUDIENCE> \
|
||||
-e NETBIRD_MGMT_API_ENDPOINT=<SET YOUR MANAGEMETN API URL> \
|
||||
wiretrustee/dashboard:main
|
||||
```
|
||||
```docker run -d --name wiretrustee-dashboard --rm -p 80:80 -p 443:443 -e AUTH0_DOMAIN=<SET YOUR AUTH DOMAIN> -e AUTH0_CLIENT_ID=<SET YOUR CLIENT ID> -e AUTH0_AUDIENCE=<SET YOUR AUDIENCE> -e WIRETRUSTEE_MGMT_API_ENDPOINT=<SET YOUR MANAGEMETN API URL> wiretrustee/dashboard:main```
|
||||
6. Run docker container with SSL (Let's Encrypt):
|
||||
|
||||
```shell
|
||||
docker run -d --name wiretrustee-dashboard \
|
||||
--rm -p 80:80 -p 443:443 \
|
||||
-e NGINX_SSL_PORT=443 \
|
||||
-e LETSENCRYPT_DOMAIN=<YOUR PUBLIC DOMAIN> \
|
||||
-e LETSENCRYPT_EMAIL=<YOUR EMAIL> \
|
||||
-e AUTH0_DOMAIN=<SET YOUR AUTH DOMAIN> \
|
||||
-e AUTH0_CLIENT_ID=<SET YOUR CLEITN ID> \
|
||||
-e AUTH0_AUDIENCE=<SET YOUR AUDIENCE> \
|
||||
-e NETBIRD_MGMT_API_ENDPOINT=<SET YOUR MANAGEMETN API URL> \
|
||||
wiretrustee/dashboard:main
|
||||
```
|
||||
```docker run -d --name wiretrustee-dashboard --rm -p 80:80 -p 443:443 -e NGINX_SSL_PORT=443 -e LETSENCRYPT_DOMAIN=<YOUR PUBLIC DOMAIN> -e LETSENCRYPT_EMAIL=<YOUR EMAIL> -e AUTH0_DOMAIN=<SET YOUR AUTH DOMAIN> -e AUTH0_CLIENT_ID=<SET YOUR CLEITN ID> -e AUTH0_AUDIENCE=<SET YOUR AUDIENCE> -e WIRETRUSTEE_MGMT_API_ENDPOINT=<SET YOUR MANAGEMETN API URL> wiretrustee/dashboard:main```
|
||||
|
||||
## How to run local development
|
||||
1. Install node 16
|
||||
2. create and update the `src/.local-config.json` file. This file should contain values to be replaced from `src/config.json`
|
||||
2. create and update the src/.local-config.json file. This file should contain values to be replaced from src/config.json
|
||||
3. run `npm install`
|
||||
4. run `npm run start dev`
|
||||
4. run `npm run start dev`
|
||||
@@ -22,10 +22,6 @@ if [[ -z "${AUTH_AUDIENCE}" ]]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "${AUTH_AUDIENCE}" == "none" ]]; then
|
||||
unset AUTH_AUDIENCE
|
||||
fi
|
||||
|
||||
if [[ -z "${AUTH_SUPPORTED_SCOPES}" ]]; then
|
||||
if [[ -z "${AUTH0_DOMAIN}" ]]; then
|
||||
echo "AUTH_SUPPORTED_SCOPES environment variable must be set"
|
||||
@@ -47,24 +43,20 @@ fi
|
||||
|
||||
export AUTH_AUTHORITY=${AUTH_AUTHORITY:-https://$AUTH0_DOMAIN}
|
||||
export AUTH_CLIENT_ID=${AUTH_CLIENT_ID:-$AUTH0_CLIENT_ID}
|
||||
export AUTH_CLIENT_SECRET=${AUTH_CLIENT_SECRET}
|
||||
export AUTH_AUDIENCE=${AUTH_AUDIENCE:-$AUTH0_AUDIENCE}
|
||||
export AUTH_REDIRECT_URI=${AUTH_REDIRECT_URI}
|
||||
export AUTH_SILENT_REDIRECT_URI=${AUTH_SILENT_REDIRECT_URI}
|
||||
export USE_AUTH0=${USE_AUTH0:-true}
|
||||
export AUTH_SUPPORTED_SCOPES=${AUTH_SUPPORTED_SCOPES:-openid profile email api offline_access email_verified}
|
||||
|
||||
export NETBIRD_MGMT_API_ENDPOINT=$(echo $NETBIRD_MGMT_API_ENDPOINT | sed -E 's/(:80|:443)$//')
|
||||
export NETBIRD_MGMT_GRPC_API_ENDPOINT=${NETBIRD_MGMT_GRPC_API_ENDPOINT}
|
||||
export NETBIRD_HOTJAR_TRACK_ID=${NETBIRD_HOTJAR_TRACK_ID}
|
||||
export NETBIRD_TOKEN_SOURCE=${NETBIRD_TOKEN_SOURCE:-accessToken}
|
||||
export NETBIRD_DRAG_QUERY_PARAMS=${NETBIRD_DRAG_QUERY_PARAMS:-false}
|
||||
|
||||
REPO="https://github.com/netbirdio/netbird/"
|
||||
# this command will fetch the latest release e.g. v0.6.3
|
||||
export NETBIRD_LATEST_VERSION=$(basename $(curl -fs -o/dev/null -w %{redirect_url} ${REPO}releases/latest))
|
||||
echo "NetBird latest version: ${NETBIRD_LATEST_VERSION}"
|
||||
|
||||
# replace ENVs in the config
|
||||
ENV_STR="\$\$USE_AUTH0 \$\$AUTH_AUDIENCE \$\$AUTH_AUTHORITY \$\$AUTH_CLIENT_ID \$\$AUTH_CLIENT_SECRET \$\$AUTH_SUPPORTED_SCOPES \$\$NETBIRD_MGMT_API_ENDPOINT \$\$NETBIRD_MGMT_GRPC_API_ENDPOINT \$\$NETBIRD_HOTJAR_TRACK_ID \$\$AUTH_REDIRECT_URI \$\$AUTH_SILENT_REDIRECT_URI \$\$NETBIRD_TOKEN_SOURCE \$\$NETBIRD_DRAG_QUERY_PARAMS"
|
||||
|
||||
ENV_STR="\$\$USE_AUTH0 \$\$AUTH_AUDIENCE \$\$AUTH_AUTHORITY \$\$AUTH_CLIENT_ID \$\$AUTH_SUPPORTED_SCOPES \$\$NETBIRD_MGMT_API_ENDPOINT \$\$NETBIRD_MGMT_GRPC_API_ENDPOINT \$\$NETBIRD_LATEST_VERSION"
|
||||
MAIN_JS=$(find /usr/share/nginx/html/static/js/main.*js)
|
||||
OIDC_TRUSTED_DOMAINS="/usr/share/nginx/html/OidcTrustedDomains.js"
|
||||
cp "$MAIN_JS" "$MAIN_JS".copy
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^4.8.0",
|
||||
"@ant-design/icons": "^4.7.0",
|
||||
"@axa-fr/react-oidc": "^5.14.0",
|
||||
"@headlessui/react": "^1.5.0",
|
||||
"@heroicons/react": "^1.0.4",
|
||||
@@ -18,28 +18,22 @@
|
||||
"@types/react-redux": "^7.1.24",
|
||||
"@types/react-router-dom": "^5.3.3",
|
||||
"@types/styled-components": "^5.1.25",
|
||||
"antd": "^5.3.1",
|
||||
"antd": "^4.20.6",
|
||||
"autoprefixer": "^10.4.4",
|
||||
"axios": "^0.27.2",
|
||||
"cidr-regex": "^3.1.1",
|
||||
"copyfiles": "^2.4.1",
|
||||
"heroicons": "^1.0.6",
|
||||
"highlight.js": "^11.2.0",
|
||||
"history": "^5.0.1",
|
||||
"lodash": "^4.17.21",
|
||||
"moment": "^2.29.4",
|
||||
"postcss": "^8.4.12",
|
||||
"prop-types": "^15.7.2",
|
||||
"punycode": "^2.1.1",
|
||||
"rc-overflow": "^1.2.8",
|
||||
"react": "^18.2.0",
|
||||
"react-copy-to-clipboard": "^5.1.0",
|
||||
"react-dom": "^18.1.0",
|
||||
"react-hotjar": "^5.1.0",
|
||||
"react-redux": "^8.0.2",
|
||||
"react-router-dom": "^5.3.3",
|
||||
"react-scripts": "^5.0.1",
|
||||
"react-select": "^5.7.3",
|
||||
"react-syntax-highlighter": "^15.5.0",
|
||||
"react-table": "^7.7.0",
|
||||
"redux": "^4.2.0",
|
||||
@@ -47,7 +41,6 @@
|
||||
"redux-saga": "^1.1.3",
|
||||
"styled-components": "^5.3.5",
|
||||
"tailwindcss": "^3.0.23",
|
||||
"ts-md5": "^1.3.1",
|
||||
"typesafe-actions": "^5.1.0",
|
||||
"typescript": "^4.6.4",
|
||||
"web-vitals": "^2.1.4"
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta name="robots" content="noindex">
|
||||
<meta
|
||||
name="description"
|
||||
content="NetBird Management Dashboard"
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
Disallow: /
|
||||
Disallow:
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"auth0Auth": "true",
|
||||
"authAuthority": "https://netbird-localdev.eu.auth0.com",
|
||||
"authClientId": "kBRMAOqIZ7hvpVCaypQLCJvTzkYYIXVt",
|
||||
"authScopesSupported": "openid profile email api offline_access email_verified",
|
||||
"authAudience": "http://localhost:3000/",
|
||||
|
||||
"apiOrigin": "http://0.0.0.0",
|
||||
"grpcApiOrigin": "http://0.0.0.0:80",
|
||||
"latestVersion": "v0.6.3"
|
||||
}
|
||||
@@ -1,41 +1,22 @@
|
||||
import React, {useEffect, useRef, useState} from 'react';
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import {Provider} from "react-redux";
|
||||
import {apiClient, store} from "./store";
|
||||
import {hotjar} from 'react-hotjar';
|
||||
import {getConfig} from "./config";
|
||||
import Banner from "./components/Banner";
|
||||
import {Col, ConfigProvider, Layout, Row} from "antd";
|
||||
import {Container} from "./components/Container";
|
||||
import Navbar from "./components/Navbar";
|
||||
import {Redirect, Route, Switch} from "react-router-dom";
|
||||
import {withOidcSecure} from "@axa-fr/react-oidc";
|
||||
import Peers from "./views/Peers";
|
||||
import Routes from "./views/Routes";
|
||||
import AddPeer from "./views/AddPeer";
|
||||
import {Redirect, Route, Switch} from 'react-router-dom';
|
||||
import Navbar from './components/Navbar';
|
||||
import Peers from './views/Peers';
|
||||
import FooterComponent from './components/FooterComponent';
|
||||
import SetupKeys from "./views/SetupKeys";
|
||||
import AccessControl from "./views/AccessControl";
|
||||
import Users from "./views/Users";
|
||||
import FooterComponent from "./components/FooterComponent";
|
||||
import {useGetTokenSilently, useTokenSource} from "./utils/token";
|
||||
import {User} from "./store/user/types";
|
||||
import {SecureLoading} from "./components/Loading";
|
||||
import DNS from "./views/DNS";
|
||||
import Activity from "./views/Activity";
|
||||
import Settings from "./views/Settings";
|
||||
|
||||
import AddPeer from "./views/AddPeer";
|
||||
import Users from './views/Users';
|
||||
import AccessControl from './views/AccessControl';
|
||||
import Banner from "./components/Banner";
|
||||
import {store} from "./store";
|
||||
import { Col, Layout, Row} from 'antd';
|
||||
import {Container} from "./components/Container";
|
||||
import {withOidcSecure} from '@axa-fr/react-oidc';
|
||||
|
||||
const {Header, Content} = Layout;
|
||||
|
||||
function App() {
|
||||
const run = useRef(false)
|
||||
const [show, setShow] = useState(false)
|
||||
const {hotjarTrackID,tokenSource} = getConfig();
|
||||
useTokenSource(tokenSource)
|
||||
const {getTokenSilently} = useGetTokenSilently();
|
||||
// @ts-ignore
|
||||
if (hotjarTrackID && window._DATADOG_SYNTHETICS_BROWSER === undefined) {
|
||||
hotjar.initialize(hotjarTrackID, 6);
|
||||
}
|
||||
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
@@ -43,6 +24,7 @@ function App() {
|
||||
const hideMenu = () => {
|
||||
if (window.innerWidth > 768 && isOpen) {
|
||||
setIsOpen(false);
|
||||
console.log('i resized');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -51,72 +33,48 @@ function App() {
|
||||
return () => {
|
||||
window.removeEventListener('resize', hideMenu);
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!run.current) {
|
||||
run.current = true
|
||||
apiClient.request<User[]>('GET', `/api/users`, {getAccessTokenSilently: getTokenSilently})
|
||||
.then(() => {
|
||||
setShow(true)
|
||||
})
|
||||
.catch(e => {
|
||||
setShow(true)
|
||||
console.log(e)
|
||||
})
|
||||
}
|
||||
|
||||
}, [getTokenSilently])
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
<Provider store={store}>
|
||||
{!show && <SecureLoading padding="3em" width={50} height={50}/>}
|
||||
{show &&
|
||||
<Layout>
|
||||
<Banner/>
|
||||
<Header className="header" style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: "space-around",
|
||||
alignContent: "center"
|
||||
}}>
|
||||
<Row justify="space-around" align="middle">
|
||||
<Col span={24}>
|
||||
<Container>
|
||||
<Navbar/>
|
||||
</Container>
|
||||
</Col>
|
||||
</Row>
|
||||
</Header>
|
||||
<Content style={{minHeight: "100vh"}}>
|
||||
<Switch>
|
||||
<Route
|
||||
exact
|
||||
path="/"
|
||||
render={() => {
|
||||
return (
|
||||
<Redirect to="/peers"/>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
<Route path='/peers' exact component={withOidcSecure(Peers)}/>
|
||||
<Route path="/setup-keys" component={withOidcSecure(SetupKeys)}/>
|
||||
<Route path="/acls" component={withOidcSecure(AccessControl)}/>
|
||||
<Route path="/routes" component={withOidcSecure(Routes)}/>
|
||||
<Route path="/users" component={withOidcSecure(Users)}/>
|
||||
<Route path="/dns" component={withOidcSecure(DNS)}/>
|
||||
<Route path="/activity" component={withOidcSecure(Activity)}/>
|
||||
<Route path="/settings" component={withOidcSecure(Settings)}/>
|
||||
</Switch>
|
||||
</Content>
|
||||
<FooterComponent/>
|
||||
</Layout>
|
||||
}
|
||||
</Provider>
|
||||
</>
|
||||
)
|
||||
<Provider store={store}>
|
||||
<Layout>
|
||||
{/*<Banner/>*/}
|
||||
<Header className="header" style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: "space-around",
|
||||
alignContent: "center"
|
||||
}}>
|
||||
<Row justify="space-around" align="middle">
|
||||
<Col span={24}>
|
||||
<Container>
|
||||
<Navbar/>
|
||||
</Container>
|
||||
</Col>
|
||||
</Row>
|
||||
</Header>
|
||||
<Content style={{ minHeight: "100vh"}}>
|
||||
<Switch>
|
||||
<Route
|
||||
exact
|
||||
path="/"
|
||||
render={() => {
|
||||
return (
|
||||
<Redirect to="/peers"/>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
<Route path='/peers' exact component={withOidcSecure(Peers)}/>
|
||||
<Route path="/add-peer" component={withOidcSecure(AddPeer)}/>
|
||||
<Route path="/setup-keys" component={withOidcSecure(SetupKeys)}/>
|
||||
<Route path="/acls" component={withOidcSecure(AccessControl)}/>
|
||||
<Route path="/users" component={withOidcSecure(Users)}/>
|
||||
</Switch>
|
||||
</Content>
|
||||
<FooterComponent/>
|
||||
</Layout>
|
||||
</Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
@@ -1,3 +1,3 @@
|
||||
<svg width="39" height="6" viewBox="0 0 39 6" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0.451731 2.66267C0.315048 2.79935 0.315048 3.02096 0.451731 3.15764L2.67912 5.38503C2.8158 5.52171 3.03741 5.52171 3.17409 5.38503C3.31078 5.24835 3.31078 5.02674 3.17409 4.89006L1.19419 2.91016L3.17409 0.930257C3.31078 0.793574 3.31078 0.571966 3.17409 0.435282C3.03741 0.298599 2.8158 0.298599 2.67912 0.435282L0.451731 2.66267ZM38.3807 3.15764C38.5174 3.02096 38.5174 2.79935 38.3807 2.66267L36.1533 0.435282C36.0166 0.298599 35.795 0.298599 35.6583 0.435282C35.5216 0.571966 35.5216 0.793574 35.6583 0.930257L37.6382 2.91016L35.6583 4.89006C35.5216 5.02674 35.5216 5.24835 35.6583 5.38503C35.795 5.52171 36.0166 5.52171 36.1533 5.38503L38.3807 3.15764ZM0.699219 3.26016H38.1332V2.56016H0.699219V3.26016Z" fill="#03543F"/>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="29.435" height="7.636" viewBox="0 0 29.435 7.636">
|
||||
<path id="direct_bi" d="M3.64,8.158-.178,4.34,3.64.522,4.3,1.17l-2.7,2.7h25.89l-2.7-2.7.656-.648L29.257,4.34,27.213,6.384,25.439,8.158,24.783,7.5l2.7-2.693H1.595L4.3,7.5Z" transform="translate(0.178 -0.522)" fill="#1e429f"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 837 B After Width: | Height: | Size: 332 B |
@@ -1,3 +1,3 @@
|
||||
<svg width="39" height="6" viewBox="0 0 39 6" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M38.3807 3.15764C38.5174 3.02096 38.5174 2.79935 38.3807 2.66267L36.1533 0.435282C36.0166 0.298599 35.795 0.298599 35.6583 0.435282C35.5216 0.571966 35.5216 0.793574 35.6583 0.930257L37.6382 2.91016L35.6583 4.89006C35.5216 5.02674 35.5216 5.24835 35.6583 5.38503C35.795 5.52171 36.0166 5.52171 36.1533 5.38503L38.3807 3.15764ZM0.699219 3.26016H38.1332V2.56016H0.699219V3.26016Z" fill="#1E429F"/>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="29.497" height="7.636" viewBox="0 0 29.497 7.636">
|
||||
<path id="direct_out" d="M26.589,8l-.656-.656,2.7-2.693H.91V3.713H28.635l-2.7-2.7.656-.648,3.818,3.818Z" transform="translate(-0.91 -0.364)" fill="#03543f"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 506 B After Width: | Height: | Size: 265 B |
@@ -1,3 +0,0 @@
|
||||
<svg width="39" height="7" viewBox="0 0 39 7" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M38.3846 3.68889C38.5213 3.55221 38.5213 3.3306 38.3846 3.19392L36.1572 0.966532C36.0205 0.829849 35.7989 0.829849 35.6622 0.966532C35.5255 1.10322 35.5255 1.32482 35.6622 1.46151L37.6421 3.44141L35.6622 5.42131C35.5255 5.55799 35.5255 5.7796 35.6622 5.91628C35.7989 6.05296 36.0205 6.05296 36.1572 5.91628L38.3846 3.68889ZM0.703125 3.79141H38.1371V3.09141H0.703125V3.79141Z" fill="#D9D9D9"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 503 B |
|
Before Width: | Height: | Size: 4.8 KiB |
@@ -1,3 +0,0 @@
|
||||
<svg width="39" height="7" viewBox="0 0 39 7" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0.615425 3.3111C0.478741 3.44779 0.478741 3.66939 0.615425 3.80608L2.84281 6.03346C2.97949 6.17015 3.2011 6.17015 3.33778 6.03346C3.47447 5.89678 3.47447 5.67517 3.33778 5.53849L1.35789 3.55859L3.33778 1.57869C3.47447 1.44201 3.47447 1.2204 3.33778 1.08372C3.2011 0.947033 2.97949 0.947033 2.84281 1.08372L0.615425 3.3111ZM38.2969 3.20859L0.862911 3.20859L0.862911 3.90859L38.2969 3.90859L38.2969 3.20859Z" fill="#2B4DA5"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 535 B |
@@ -1,3 +0,0 @@
|
||||
<svg width="39" height="7" viewBox="0 0 39 7" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M38.3807 3.68889C38.5174 3.55221 38.5174 3.3306 38.3807 3.19392L36.1533 0.966532C36.0166 0.829849 35.795 0.829849 35.6583 0.966532C35.5216 1.10322 35.5216 1.32482 35.6583 1.46151L37.6382 3.44141L35.6583 5.42131C35.5216 5.55799 35.5216 5.7796 35.6583 5.91628C35.795 6.05296 36.0166 6.05296 36.1533 5.91628L38.3807 3.68889ZM0.699219 3.79141L38.1332 3.79141V3.09141L0.699219 3.09141V3.79141Z" fill="#2B4DA5"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 517 B |
@@ -1,3 +0,0 @@
|
||||
<svg width="39" height="7" viewBox="0 0 39 7" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M38.3846 3.68889C38.5213 3.55221 38.5213 3.3306 38.3846 3.19392L36.1572 0.966532C36.0205 0.829849 35.7989 0.829849 35.6622 0.966532C35.5255 1.10322 35.5255 1.32482 35.6622 1.46151L37.6421 3.44141L35.6622 5.42131C35.5255 5.55799 35.5255 5.7796 35.6622 5.91628C35.7989 6.05296 36.0205 6.05296 36.1572 5.91628L38.3846 3.68889ZM0.703125 3.79141H38.1371V3.09141H0.703125V3.79141Z" fill="#03543F"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 503 B |
@@ -1,3 +0,0 @@
|
||||
<svg width="39" height="7" viewBox="0 0 39 7" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0.615425 3.3111C0.478741 3.44779 0.478741 3.66939 0.615425 3.80608L2.84281 6.03346C2.97949 6.17015 3.2011 6.17015 3.33778 6.03346C3.47447 5.89678 3.47447 5.67517 3.33778 5.53849L1.35789 3.55859L3.33778 1.57869C3.47447 1.44201 3.47447 1.2204 3.33778 1.08372C3.2011 0.947033 2.97949 0.947033 2.84281 1.08372L0.615425 3.3111ZM38.2969 3.20859L0.862911 3.20859L0.862911 3.90859L38.2969 3.90859L38.2969 3.20859Z" fill="#D9D9D9"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 535 B |
@@ -1,3 +0,0 @@
|
||||
<svg width="39" height="7" viewBox="0 0 39 7" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0.615425 3.3111C0.478741 3.44779 0.478741 3.66939 0.615425 3.80608L2.84281 6.03346C2.97949 6.17015 3.2011 6.17015 3.33778 6.03346C3.47447 5.89678 3.47447 5.67517 3.33778 5.53849L1.35789 3.55859L3.33778 1.57869C3.47447 1.44201 3.47447 1.2204 3.33778 1.08372C3.2011 0.947033 2.97949 0.947033 2.84281 1.08372L0.615425 3.3111ZM38.2969 3.20859L0.862911 3.20859L0.862911 3.90859L38.2969 3.90859L38.2969 3.20859Z" fill="#03543F"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 535 B |