diff --git a/package-lock.json b/package-lock.json index efd70f75343df381236b6883a451306dd7f82c31..421c5b5dad73a743b2f99845c955eefbd67914d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16536,6 +16536,14 @@ "scheduler": "^0.19.1" } }, + "react-easy-swipe": { + "version": "0.0.21", + "resolved": "https://registry.npmjs.org/react-easy-swipe/-/react-easy-swipe-0.0.21.tgz", + "integrity": "sha512-OeR2jAxdoqUMHIn/nS9fgreI5hSpgGoL5ezdal4+oO7YSSgJR8ga+PkYGJrSrJ9MKlPcQjMQXnketrD7WNmNsg==", + "requires": { + "prop-types": "^15.5.8" + } + }, "react-error-overlay": { "version": "6.0.9", "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz", @@ -16765,6 +16773,16 @@ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz", "integrity": "sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg==" }, + "react-responsive-carousel": { + "version": "3.2.18", + "resolved": "https://registry.npmjs.org/react-responsive-carousel/-/react-responsive-carousel-3.2.18.tgz", + "integrity": "sha512-A6eXp/HofjZ8p23Q/b25dqtokHFFXKhKKn82ZJkCI0edxjtAUid8SImr8rHp0rRi9aEYXej3ynWOzaUHFE4RKA==", + "requires": { + "classnames": "^2.2.5", + "prop-types": "^15.5.8", + "react-easy-swipe": "^0.0.21" + } + }, "react-router": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz", @@ -20334,7 +20352,8 @@ }, "ssri": { "version": "6.0.1", - "resolved": "", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", "requires": { "figgy-pudding": "^3.5.1" } diff --git a/package.json b/package.json index 633cf51df5b97b002d1850ffc02c40316c5f65a0..caa1bf065dbec219a197e47081dcad1e4aa0a1ae 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "axios": "^0.21.1", "bootstrap": "^4.6.0", "date-fns": "^2.21.1", + "lodash": "^4.17.21", "moment": "^2.29.1", "moment-timezone": "^0.5.33", "postcss": "^8.2.15", @@ -35,6 +36,7 @@ "react-google-maps": "^9.4.5", "react-hooks-helper": "^1.6.0", "react-redux": "^7.2.3", + "react-responsive-carousel": "^3.2.18", "react-router-dom": "^5.2.0", "react-scripts": "4.0.3", "react-select": "^4.3.0", diff --git a/src/App.js b/src/App.js index c21e117a863cd8842b0e9b388da72a956e7d5123..ee28c0f5c73b4aa19baf0d7550c2300d9171d6ce 100644 --- a/src/App.js +++ b/src/App.js @@ -4,6 +4,9 @@ import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'; import Activate from './page/Aktivasi/Aktivasi'; import DaftarToko from './page/DaftarToko/DaftarToko'; import PengadaanMainan from './page/PengadaanMainan/PengadaanMainan'; +import DetailPengadaan from './page/DetailPengadaan/DetailPengadaan'; +import HomepageInvestor from './page/HomepageInvestor/HomepageInvestor'; +import HomepagePemilikToko from './page/HomepagePemilikToko/HomepagePemilikToko'; import Navbar from './components/Navbar/Navbar'; import Footer from './components/Footer/Footer'; import Home from './components/Home/Home'; @@ -14,6 +17,7 @@ import Login from './page/Login'; import Layout from './hocs/Layout'; import { fetch_user } from './util/prerender'; import { Provider } from 'react-redux'; +import MembuatInvestasi from './page/MembuatInvestasi/MembuatInvestasi' import store from './store'; @@ -38,8 +42,7 @@ function App() { <Route path="/daftar-mitra"> <RegistrasiMitra /> </Route> - <Route path="/bantuan"> - </Route> + <Route path="/bantuan"></Route> <Route path="/profile"> <Profile /> </Route> @@ -51,6 +54,17 @@ function App() { <Route path="/pengadaan-mainan"> <PengadaanMainan /> </Route> + <Route path={"/investasi/:pk"} component={MembuatInvestasi}> + </Route> + <Route path="/investor"> + <HomepageInvestor /> + </Route> + <Route path="/detail-pengadaan"> + <DetailPengadaan /> + </Route> + <Route path="/pemilik-toko"> + <HomepagePemilikToko /> + </Route> <Route exact path="/"> <Home /> </Route> diff --git a/src/actions/auth.js b/src/actions/auth.js index cd385bea2a02ae1963767b259183c7b254972f35..85ec48d4d2e90ebd5833fd4f96edb46085c3772f 100644 --- a/src/actions/auth.js +++ b/src/actions/auth.js @@ -13,6 +13,102 @@ import { } from './types'; import axios from 'axios'; +export const post_profile = async (email, full_name, address, phone_number, ktp_number, birth_date, profile_picture) => { + var formDataToSend = new FormData(); + const config = { + headers: { + 'content-type': 'multipart/form-data' + } + }; + + formDataToSend.append('email', email); + formDataToSend.append('full_name', full_name); + formDataToSend.append('address', address); + formDataToSend.append('phone_number', phone_number); + formDataToSend.append('ktp_number', ktp_number); + formDataToSend.append('birth_date', birth_date); + formDataToSend.append('profile_picture', profile_picture); + + try { + const res = await axios.post(`${process.env.REACT_APP_BACKEND_API_URL}/api/profile/post`, formDataToSend, config); + + return { + success: true, + res + } + } catch (err) { + return { + success: false, + err + } + } +}; + +export const update_profile = async (email, full_name, address, phone_number, ktp_number, birth_date, profile_picture, imageChanged) => { + var formDataToSend = new FormData(); + const config = { + headers: { + 'content-type': 'multipart/form-data' + } + }; + + formDataToSend.append('email', email); + formDataToSend.append('full_name', full_name); + formDataToSend.append('address', address); + formDataToSend.append('phone_number', phone_number); + formDataToSend.append('ktp_number', ktp_number); + formDataToSend.append('birth_date', birth_date); + if (imageChanged){ + formDataToSend.append('profile_picture', profile_picture); + } + + + try { + const res = await axios.put(`${process.env.REACT_APP_BACKEND_API_URL}/api/profile/update/${email}`, formDataToSend, config); + + return { + success: true, + res + } + } catch (err) { + return { + success: false, + err + } + } +}; + +export const load_profile = () => async (email) => { + if (localStorage.getItem('access')) { + const config = { + headers: { + 'Content-Type': 'application/json', + 'Authorization': `JWT ${localStorage.getItem('access')}`, + 'Accept': 'application/json' + } + }; + + try { + const res = await axios.get(`${process.env.REACT_APP_BACKEND_API_URL}/api/profile/${email}`, config); + + return { + success: true, + res + } + } catch (err) { + return { + success: false, + err + } + } + } else { + return { + success: false, + err: new Error('missing token') + } + } +}; + export const load_user = () => async dispatch => { if (localStorage.getItem('access')) { const config = { @@ -25,6 +121,7 @@ export const load_user = () => async dispatch => { try { const res = await axios.get(`${process.env.REACT_APP_BACKEND_API_URL}/auth/users/me/`, config); + // const res = await axios.get(`${process.env.REACT_APP_API_URL}/auth/users/me/`, config); dispatch({ type: USER_LOADED_SUCCESS, @@ -32,7 +129,8 @@ export const load_user = () => async dispatch => { }); return { login: true, - userLoaded: true + userLoaded: true, + res } } catch (err) { dispatch({ @@ -166,6 +264,7 @@ export const signupMitra = (first_name, last_name, email, password, re_password) try { const res = await axios.post(`${process.env.REACT_APP_BACKEND_API_URL}/auth/users/`, body, config); + // const res = await axios.post(`${process.env.REACT_APP_API_URL}/auth/users/`, body, config); dispatch({ type: SIGNUP_SUCCESS, payload: res.data @@ -190,10 +289,12 @@ export const verify = (uid, token) => async dispatch => { } }; + const body = JSON.stringify({ uid, token }); try { await axios.post(`${process.env.REACT_APP_BACKEND_API_URL}/auth/users/activation/`, body, config); + // await axios.post(`${process.env.REACT_APP_API_URL}/auth/users/activation/`, body, config); dispatch({ type: ACTIVATION_SUCCESS, diff --git a/src/components/Cards/Cards.css b/src/components/Cards/Cards.css new file mode 100644 index 0000000000000000000000000000000000000000..31614cc76d8071e4667cd8b8505e383c9ae26121 --- /dev/null +++ b/src/components/Cards/Cards.css @@ -0,0 +1,36 @@ + +.card-flex-item { + min-height: 400px; + display: 'flex'; + flex-wrap: 'wrap'; + flex: 50%; +} + +.card-content-limit { + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-box-orient: vertical; + text-align: left; +} + +.card-text { + -webkit-line-clamp: 3; /* number of lines to show */ + margin-top: 20px; +} + +.card-title { + -webkit-line-clamp: 1; /* number of lines to show */ +} + +@media (max-width: 800px) { + .card-flex-item { + flex: 100%; + } +} + +.toko-profil-img { + border-radius: 50%; + max-width: 50px; + margin-right: 10px; +} \ No newline at end of file diff --git a/src/components/Cards/Cards.js b/src/components/Cards/Cards.js new file mode 100644 index 0000000000000000000000000000000000000000..9bd7da825cef80f9b80319b6e1cdeb426dabe5a2 --- /dev/null +++ b/src/components/Cards/Cards.js @@ -0,0 +1,33 @@ +import React from 'react'; +import './Cards.css'; +import Card from 'react-bootstrap/Card' +import CardColumns from 'react-bootstrap/CardColumns' +import ProgressBar from 'react-bootstrap/ProgressBar' + +const Cards = ({ posts, loading }) => { + if (loading) { + return <h2>Loading...</h2>; + } + + return ( + <CardColumns> + {posts.map(post => ( + <Card className="card-flex-item" key={post.pk}> + <Card.Img variant="top" src="https://i.stack.imgur.com/y9DpT.jpg" /> + <Card.Body> + <Card.Title className="card-content-limit card-title"> + <img className="toko-profil-img" src="https://cwdaust.com.au/wpress/wp-content/uploads/2015/04/placeholder-store.png" alt="Avatar"></img> + {post.namaToko} + </Card.Title> + <ProgressBar variant="success" now={10000/post.totalBiaya*100} label={(10000/post.totalBiaya*100) + "%"} /> + <Card.Text className="card-content-limit card-text"> + {post.deskripsiToko} + </Card.Text> + </Card.Body> + </Card> + ))} + </CardColumns> + ); +}; + +export default Cards; \ No newline at end of file diff --git a/src/components/Cards/Cards.test.js b/src/components/Cards/Cards.test.js new file mode 100644 index 0000000000000000000000000000000000000000..3bffa79fbbc29bb054b267a8258b72209468b787 --- /dev/null +++ b/src/components/Cards/Cards.test.js @@ -0,0 +1,93 @@ +import Cards from './Cards'; +import { render } from '@testing-library/react'; +import '@testing-library/jest-dom'; +import { BrowserRouter } from 'react-router-dom' +import { Provider } from 'react-redux' +import configureStore from 'redux-mock-store' +import thunk from 'redux-thunk' + +jest.mock('axios') + +const middlewares = [thunk] +const mockStore = configureStore(middlewares) + +describe('<Cards />', () => { + + it('not loading when card test', () => { + const mockCurrentPosts = [ + { + "userId": 1, + "id": 1, + "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", + "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto" + }, + { + "userId": 1, + "id": 2, + "title": "qui est esse", + "body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla" + }, + { + "userId": 1, + "id": 3, + "title": "ea molestias quasi exercitationem repellat qui ipsa sit aut", + "body": "et iusto sed quo iure\nvoluptatem occaecati omnis eligendi aut ad\nvoluptatem doloribus vel accusantium quis pariatur\nmolestiae porro eius odio et labore et velit aut" + } + ] + const initialState = { auth: { + isAuthenticated: true, + user: { + role: "Investor" + } + } + } + localStorage.setItem('access', 'token') + const store = mockStore(initialState) + render( + <Provider store={store}> + <BrowserRouter> + <Cards posts={mockCurrentPosts} loading={false}/> + </BrowserRouter> + </Provider>); + localStorage.removeItem('access', 'token') + }); + + it('loading when card test', () => { + const mockCurrentPosts = [ + { + "userId": 1, + "id": 1, + "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", + "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto" + }, + { + "userId": 1, + "id": 2, + "title": "qui est esse", + "body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla" + }, + { + "userId": 1, + "id": 3, + "title": "ea molestias quasi exercitationem repellat qui ipsa sit aut", + "body": "et iusto sed quo iure\nvoluptatem occaecati omnis eligendi aut ad\nvoluptatem doloribus vel accusantium quis pariatur\nmolestiae porro eius odio et labore et velit aut" + } + ] + const initialState = { auth: { + isAuthenticated: true, + user: { + role: "Investor" + } + } + } + localStorage.setItem('access', 'token') + const store = mockStore(initialState) + render( + <Provider store={store}> + <BrowserRouter> + <Cards posts={mockCurrentPosts} loading={true}/> + </BrowserRouter> + </Provider>); + localStorage.removeItem('access', 'token') + }); +}) \ No newline at end of file diff --git a/src/components/Form/LoginForm.jsx b/src/components/Form/LoginForm.jsx index 6fe8ce27ac7c237160baef723e0e8f1228505c92..72660baf773b24c0dd0c147d1644dcbe8774e73f 100755 --- a/src/components/Form/LoginForm.jsx +++ b/src/components/Form/LoginForm.jsx @@ -4,7 +4,6 @@ import { Link } from 'react-router-dom'; import { useState } from 'react'; import { connect } from 'react-redux'; import { login as loginAction } from '../../actions/auth'; -import axios from 'axios'; const initialState = { email: '', @@ -29,15 +28,15 @@ function LoginForm({ login }) { } } - const continueWithGoogle = async () => { - try { - const res = await axios.get(`${process.env.REACT_APP_API_URL}/auth/o/google-oauth2/?redirect_uri=http://localhost:3000`) + // const continueWithGoogle = async () => { + // try { + // const res = await axios.get(`${process.env.REACT_APP_API_URL}/auth/o/google-oauth2/?redirect_uri=http://localhost:3000`) - window.location.replace(res.data.authorization_url); - } catch (err) { + // window.location.replace(res.data.authorization_url); + // } catch (err) { - } - }; + // } + // }; return ( <div id="login"> @@ -76,7 +75,7 @@ function LoginForm({ login }) { <div className="line" /> </div> <div id="other-method"> - <button id="login-google" onClick={continueWithGoogle}> + <button id="login-google"> <img id="google-logo" src="https://upload.wikimedia.org/wikipedia/commons/5/53/Google_%22G%22_Logo.svg" diff --git a/src/components/Home/Home.js b/src/components/Home/Home.js index 8be83ec0806d0b8a15ecb5f5a159526bda2a8c39..9ca06a4f9e0d5ab82cfeaff1def8264432f3cf15 100644 --- a/src/components/Home/Home.js +++ b/src/components/Home/Home.js @@ -3,9 +3,19 @@ import InvestorIcon from './investor-icon.svg'; import MitraIcon from './mitra-icon.svg'; import Sect1 from './sect-1.svg'; import Sect2Icon from './sect-2-icon.svg'; -import { Link } from 'react-router-dom'; +import { connect } from 'react-redux'; +import { Link, Redirect } from 'react-router-dom'; + +const Home = ({user}) => { + + if (user !== null) { + if (user.role === "Mitra") { + return <Redirect to="/pemilik-toko" /> + } else if (user.role === "Investor") { + return <Redirect to="/investor" /> + } + } -const Home = () => { return ( <div> <div className="wkd-home-sect-1-container"> @@ -82,4 +92,8 @@ const Home = () => { ); } -export default Home; \ No newline at end of file +const mapStateToProps = (state) => ({ + user: state.auth.user +}) + +export default connect(mapStateToProps)(Home); \ No newline at end of file diff --git a/src/components/Home/Home.test.js b/src/components/Home/Home.test.js index 0361fc65dc3dfd5c84935230e421f33d95a30ad3..dd19c5104f8c5bc4f6d489c94e1bc425e47c76be 100644 --- a/src/components/Home/Home.test.js +++ b/src/components/Home/Home.test.js @@ -2,16 +2,34 @@ import Home from './Home' import { render } from '@testing-library/react'; import '@testing-library/jest-dom'; import { BrowserRouter, MemoryRouter, Route } from 'react-router-dom'; +import { Provider } from 'react-redux' import userEvent from '@testing-library/user-event'; +import configureStore from 'redux-mock-store' +import thunk from 'redux-thunk' + +const middlewares = [thunk] +const mockStore = configureStore(middlewares) describe('<Home />',() => { it('renders correctly', () => { - const { getByText } = render(<BrowserRouter><Home /></BrowserRouter>); + const mockUser = jest.fn() + const initialState = { auth: { + user: null + } + } + const store = mockStore(initialState) + const { getByText } = render(<Provider store={store}><BrowserRouter><Home user={mockUser}/></BrowserRouter></Provider>); expect(getByText(/Platform Crowdfunding/)).toBeInTheDocument(); }); test('all register mitra button should have the corrrect link', () => { - const { queryAllByText } = render(<BrowserRouter><Home /></BrowserRouter>); + const mockUser = jest.fn() + const initialState = { auth: { + user: null + } + } + const store = mockStore(initialState) + const { queryAllByText } = render(<Provider store={store}><BrowserRouter><Home user={mockUser}/></BrowserRouter></Provider>); const buttonCount = queryAllByText('Gabung Mitra').length; for (let i = 0; i < buttonCount; i++) { expect(queryAllByText('Gabung Mitra')[i]).toHaveAttribute("href", '/daftar-mitra'); @@ -19,7 +37,13 @@ describe('<Home />',() => { }); test('all register investor button should have the corrrect link', () => { - const { queryAllByText } = render(<BrowserRouter><Home /></BrowserRouter>); + const mockUser = jest.fn() + const initialState = { auth: { + user: null + } + } + const store = mockStore(initialState) + const { queryAllByText } = render(<Provider store={store}><BrowserRouter><Home user={mockUser}/></BrowserRouter></Provider>); const buttonCount = queryAllByText('Mulai Investasi').length; for (let i = 0; i < buttonCount; i++) { expect(queryAllByText('Mulai Investasi')[i]).toHaveAttribute("href", '/daftar-investor'); @@ -27,23 +51,37 @@ describe('<Home />',() => { }); test('hubungi button should have the correct link', () => { - const { getByText } = render(<BrowserRouter><Home /></BrowserRouter>); + const mockUser = jest.fn() + const initialState = { auth: { + user: null + } + } + const store = mockStore(initialState) + const { getByText } = render(<Provider store={store}><BrowserRouter><Home user={mockUser}/></BrowserRouter></Provider>); expect(getByText("Hubungi Kami")).toHaveAttribute("href", expect.stringContaining('mailto')); }); it('should redirect to Daftar Investor page when Mulai Investasi button is clicked', () => { let testLocation; + const mockUser = jest.fn() + const initialState = { auth: { + user: null + } + } + const store = mockStore(initialState) const { queryAllByText } = render( - <MemoryRouter initialEntries={["/"]}> - <Home /> - <Route - path="*" - render={({ history, location }) => { - testLocation = location; - return null; - }} - /> + <Provider store={store}> + <MemoryRouter initialEntries={["/"]}> + <Home user={mockUser}/> + <Route + path="*" + render={({ history, location }) => { + testLocation = location; + return null; + }} + /> </MemoryRouter> + </Provider> ); userEvent.click(queryAllByText('Mulai Investasi')[0]); @@ -52,20 +90,102 @@ describe('<Home />',() => { it('should redirect to Daftar Mitra page when Gabung Mitra button is clicked', () => { let testLocation; + const mockUser = jest.fn() + const initialState = { auth: { + user: null + } + } + const store = mockStore(initialState) const { queryAllByText } = render( - <MemoryRouter initialEntries={["/"]}> - <Home /> - <Route - path="*" - render={({ history, location }) => { - testLocation = location; - return null; - }} - /> - </MemoryRouter> + <Provider store={store}> + <MemoryRouter initialEntries={["/"]}> + <Home user={mockUser}/> + <Route + path="*" + render={({ history, location }) => { + testLocation = location; + return null; + }} + /> + </MemoryRouter> + </Provider> ); userEvent.click(queryAllByText('Gabung Mitra')[0]); expect(testLocation.pathname).toBe("/daftar-mitra"); }); + + it('should redirect if mitra', () => { + let loc; + const mockUser = jest.fn() + const initialState = { + auth: { + user: { + role: "Mitra" + } + } + } + const store = mockStore(initialState) + render( + <> + <Provider store={store}> + <BrowserRouter> + <Home user={mockUser} /> + <Route + path="*" + render={({location}) => { + loc = location; + return null; + }} + /> + </BrowserRouter> + </Provider>); + </>, + {initialState: {auth: { + user: { + role: "Mitra" + } + } + } + } + ); + expect(loc.pathname).toBe('/pemilik-toko'); + }) + + it('should redirect if investor', () => { + let loc; + const mockUser = jest.fn() + const initialState = { + auth: { + user: { + role: "Investor" + } + } + } + const store = mockStore(initialState) + render( + <> + <Provider store={store}> + <BrowserRouter> + <Home user={mockUser} /> + <Route + path="*" + render={({location}) => { + loc = location; + return null; + }} + /> + </BrowserRouter> + </Provider>); + </>, + {initialState: {auth: { + user: { + role: "Investor" + } + } + } + } + ); + expect(loc.pathname).toBe('/investor'); + }) }); \ No newline at end of file diff --git a/src/components/InvestasiOptionCard/CustomOptionCard.js b/src/components/InvestasiOptionCard/CustomOptionCard.js new file mode 100644 index 0000000000000000000000000000000000000000..66e9d0d102fb4451076ec9d818f6b6654ad78180 --- /dev/null +++ b/src/components/InvestasiOptionCard/CustomOptionCard.js @@ -0,0 +1,17 @@ +const CustomOptionCard = ({maxx}) => { + return ( + <div className="px-2 py-1" data-testid="mi-custom-opt-card"> + <label className="mi-card col p-3"> + <input type="radio" className="mi-option-radio" name="mi-amount" value="custom" data-testid="mi-radio-btn"/> + <span className="mi-option-subtitle mi-option-info-margin mt-5">Jumlah lain</span> + <hr className="mi-option-divider mt-2 mb-4"/> + <div className="flex mi-custom-container"> + <span className="mi-option-nominal mi-option-info-margin">Rp </span> + <input type="number" min={10000} max={maxx} className="mi-custom-option" id="mi-custom-amount" data-testid="mi-custom-amount"/> + </div> + </label> + </div> + ); +} + +export default CustomOptionCard; \ No newline at end of file diff --git a/src/components/InvestasiOptionCard/CustomOptionCard.test.js b/src/components/InvestasiOptionCard/CustomOptionCard.test.js new file mode 100644 index 0000000000000000000000000000000000000000..4cebdf90a07fdad00ed9dbea4110a6a490e9047e --- /dev/null +++ b/src/components/InvestasiOptionCard/CustomOptionCard.test.js @@ -0,0 +1,18 @@ +import { render } from '@testing-library/react'; +import CustomOptionCard from './CustomOptionCard'; +import userEvent from '@testing-library/user-event'; + +describe('<CustomOptionCard />', () => { + it('should render correctly', () => { + const { getByText } = render(<CustomOptionCard />) + expect(getByText(/jumlah lain/i)).toBeInTheDocument() + }) + + it('should be checked when clicked', () => { + const { getByTestId } = render(<CustomOptionCard />) + const radioButton = getByTestId("mi-radio-btn"); + + userEvent.click(radioButton) + expect(radioButton).toBeChecked(); + }) +}) \ No newline at end of file diff --git a/src/components/InvestasiOptionCard/OptionCard.js b/src/components/InvestasiOptionCard/OptionCard.js new file mode 100644 index 0000000000000000000000000000000000000000..6f7b3b44d37d2c23cd0cd2f6ddac99932ce060b0 --- /dev/null +++ b/src/components/InvestasiOptionCard/OptionCard.js @@ -0,0 +1,14 @@ +const OptionCard = ({ratio, amount}) => { + return ( + <div className="px-2 py-1" data-testid="mi-opt-card"> + <label className="mi-card col p-3"> + <input type="radio" className="mi-option-radio" name="mi-amount" value={amount} data-testid="mi-radio-btn"/> + <span className="mi-option-subtitle mi-option-info-margin mt-5">{ratio}% dari total pendanaan</span> + <hr className="mi-option-divider mt-2 mb-4"/> + <span className="mi-option-nominal mi-option-info-margin">Rp {amount.toLocaleString()}</span> + </label> + </div> + ); +} + +export default OptionCard; \ No newline at end of file diff --git a/src/components/InvestasiOptionCard/OptionCard.test.js b/src/components/InvestasiOptionCard/OptionCard.test.js new file mode 100644 index 0000000000000000000000000000000000000000..93cd91814cc981dc0759e26fd9dc994a338b246a --- /dev/null +++ b/src/components/InvestasiOptionCard/OptionCard.test.js @@ -0,0 +1,19 @@ +import OptionCard from "./OptionCard" +import { render } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; + +describe('<OptionCard />', () => { + it('should render correctly', () => { + const { getByText } = render(<OptionCard ratio={77} amount={77000}/>) + expect(getByText(/77%/)).toBeInTheDocument() + expect(getByText(/77,000/)).toBeInTheDocument() + }) + + it('should be checked when clicked', () => { + const { getByTestId } = render(<OptionCard ratio={77} amount={77000}/>) + const radioButton = getByTestId("mi-radio-btn"); + + userEvent.click(radioButton) + expect(radioButton).toBeChecked(); + }) +}) \ No newline at end of file diff --git a/src/components/NavProfile/NavProfile.css b/src/components/NavProfile/NavProfile.css index ac2d5f24af2885fb91adaba750304495b1e6e470..0200a659c6aa98bfb96831d07aaefe68b3ef34e6 100644 --- a/src/components/NavProfile/NavProfile.css +++ b/src/components/NavProfile/NavProfile.css @@ -1,4 +1,4 @@ .wkd-profile-toggle { - width: initial; - margin: 0; + width: initial!important; + margin: 0!important; } \ No newline at end of file diff --git a/src/components/NavProfile/NavProfile.js b/src/components/NavProfile/NavProfile.js index 42cf9ebe880b378d400a73bb816fd2b03970ea17..10b46ac67418955da0f3a3959e28ba9bea5ca4f1 100644 --- a/src/components/NavProfile/NavProfile.js +++ b/src/components/NavProfile/NavProfile.js @@ -1,3 +1,4 @@ +import './NavProfile.css'; import React from 'react'; import ClickAwayListener from '@material-ui/core/ClickAwayListener'; import Grow from '@material-ui/core/Grow'; diff --git a/src/components/Pagination/Pagination.js b/src/components/Pagination/Pagination.js new file mode 100644 index 0000000000000000000000000000000000000000..bca91349e90409b9eae810910392128f37819093 --- /dev/null +++ b/src/components/Pagination/Pagination.js @@ -0,0 +1,100 @@ +import React,{ useState } from 'react'; + +const Pagination = ({ currentPage, postsPerPage, totalPosts, paginate }) => { + const pages = []; + const pageNumberLimit = 3; + const [maxPageNumberLimit, setmaxPageNumberLimit] = useState(3); + const [minPageNumberLimit, setminPageNumberLimit] = useState(0); + + for (let i = 1; i <= Math.ceil(totalPosts / postsPerPage); i++) { + pages.push(i); + } + + const handleNextbtn = () => { + paginate(currentPage + 1); + + if (currentPage + 1 > maxPageNumberLimit) { + setmaxPageNumberLimit(maxPageNumberLimit + pageNumberLimit); + setminPageNumberLimit(minPageNumberLimit + pageNumberLimit); + } + }; + + const handlePrevbtn = () => { + paginate(currentPage - 1); + + if ((currentPage - 1) % pageNumberLimit === 0) { + setmaxPageNumberLimit(maxPageNumberLimit - pageNumberLimit); + setminPageNumberLimit(minPageNumberLimit - pageNumberLimit); + } + }; + + let pageIncrementBtn = null; + if (pages.length > maxPageNumberLimit) { + pageIncrementBtn = <li onClick={handleNextbtn}> … </li>; + } + + let pageDecrementBtn = null; + if (minPageNumberLimit >= 1) { + pageDecrementBtn = <li onClick={handlePrevbtn}> … </li>; + } + + const renderPageNumbers = pages.map((number) => { + if (number < maxPageNumberLimit + 1 && number > minPageNumberLimit) { + return ( + <li + key={number} + id={number} + onClick={() => paginate(number)} + className={currentPage === number ? "active" : null} + > + {number} + </li> + ); + } else { + return null; + } + }); + + return ( + <nav> + <ul className='pageNumbers' + style={{ + height: '45px' + }} + > + <li> + <button + style={{ + fontSize: '110%', + height: '15px', + width: '15px' + }} + className="pagination-button" + onClick={handlePrevbtn} + disabled={currentPage === pages[0] ? true : false} + > + < + </button> + </li> + {pageDecrementBtn} + {renderPageNumbers} + {pageIncrementBtn} + <li> + <button + style={{ + fontSize: '110%', + height: '15px', + width: '15px' + }} + onClick={handleNextbtn} + disabled={currentPage === pages[pages.length - 1] ? true : false} + > + > + </button> + </li> + </ul> + </nav> + ); +}; + +export default Pagination; \ No newline at end of file diff --git a/src/components/Pagination/Pagination.test.js b/src/components/Pagination/Pagination.test.js new file mode 100644 index 0000000000000000000000000000000000000000..af274d09ac68f33fd040b083aab935b4c19fe46e --- /dev/null +++ b/src/components/Pagination/Pagination.test.js @@ -0,0 +1,149 @@ +import Pagination from './Pagination'; +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import '@testing-library/jest-dom'; +import { BrowserRouter } from 'react-router-dom' +import { Provider } from 'react-redux' +import configureStore from 'redux-mock-store' +import thunk from 'redux-thunk' + +jest.mock('axios') + +const middlewares = [thunk] +const mockStore = configureStore(middlewares) + +describe('<Pagination />', () => { + + let currentPage = 1; + it('test pagination', () => { + const mockPaginate = jest.fn(n => currentPage = n); + const initialState = { auth: { + isAuthenticated: true, + user: { + role: "Investor" + } + } + } + localStorage.setItem('access', 'token') + const store = mockStore(initialState) + render( + <Provider store={store}> + <BrowserRouter> + <Pagination currentPage={currentPage} postsPerPage={6} totalPosts={12} paginate={mockPaginate}/> + </BrowserRouter> + </Provider>); + localStorage.removeItem('access', 'token') + }); + + it('next button until render new pagintion', () => { + const mockPaginate = jest.fn(n => currentPage = n); + const initialState = { auth: { + isAuthenticated: true, + user: { + role: "Investor" + } + } + } + localStorage.setItem('access', 'token') + const store = mockStore(initialState) + render( + <Provider store={store}> + <BrowserRouter> + <Pagination currentPage={1} postsPerPage={6} totalPosts={100} paginate={mockPaginate}/> + </BrowserRouter> + </Provider>); + const nextButton = screen.getByText(/>/) + userEvent.click(nextButton) + userEvent.click(nextButton) + userEvent.click(nextButton) + userEvent.click(nextButton) + userEvent.click(nextButton) + localStorage.removeItem('access', 'token') + }); + + it('prev button until render new pagintion', () => { + const mockPaginate = jest.fn(n => currentPage = n); + const initialState = { auth: { + isAuthenticated: true, + user: { + role: "Investor" + } + } + } + localStorage.setItem('access', 'token') + const store = mockStore(initialState) + render( + <Provider store={store}> + <BrowserRouter> + <Pagination currentPage={1} postsPerPage={6} totalPosts={36} paginate={mockPaginate}/> + </BrowserRouter> + </Provider>); + const nextButton = screen.getByText(/>/) + userEvent.click(nextButton) + userEvent.click(nextButton) + userEvent.click(nextButton) + userEvent.click(nextButton) + const prevButton = screen.getByText(/</) + userEvent.click(prevButton) + userEvent.click(prevButton) + userEvent.click(prevButton) + userEvent.click(prevButton) + localStorage.removeItem('access', 'token') + }); + + // it('next help button until render new pagintion', () => { + // const mockPaginate = jest.fn(); + // const initialState = { auth: { + // isAuthenticated: true, + // user: { + // role: "Investor" + // } + // } + // } + // localStorage.setItem('access', 'token') + // const store = mockStore(initialState) + // render( + // <Provider store={store}> + // <BrowserRouter> + // <Pagination currentPage={1} postsPerPage={6} totalPosts={100} paginate={mockPaginate}/> + // </BrowserRouter> + // </Provider>); + // const nextButton = screen.getByText(/…/) + // userEvent.click(nextButton) + // userEvent.click(nextButton) + // userEvent.click(nextButton) + // userEvent.click(nextButton) + // userEvent.click(nextButton) + // localStorage.removeItem('access', 'token') + // }); + + // it('prev help button until render new pagintion', () => { + // const mockPaginate = jest.fn(); + // const initialState = { auth: { + // isAuthenticated: true, + // user: { + // role: "Investor" + // } + // } + // } + // localStorage.setItem('access', 'token') + // const store = mockStore(initialState) + // render( + // <Provider store={store}> + // <BrowserRouter> + // <Pagination currentPage={1} postsPerPage={6} totalPosts={36} paginate={mockPaginate}/> + // </BrowserRouter> + // </Provider>); + // const nextButton = screen.getByText(/…/) + // userEvent.click(nextButton) + // userEvent.click(nextButton) + // userEvent.click(nextButton) + // userEvent.click(nextButton) + // const prevButton = screen.getByText(/…/) + // userEvent.click(prevButton) + // userEvent.click(prevButton) + // userEvent.click(prevButton) + // userEvent.click(prevButton) + // localStorage.removeItem('access', 'token') + // }); +}) \ No newline at end of file diff --git a/src/hocs/Layout.js b/src/hocs/Layout.js index e85f467da80b163461709aac5b85cef666752161..67c123130c68b8ce3dc27e00ae721189061b1845 100644 --- a/src/hocs/Layout.js +++ b/src/hocs/Layout.js @@ -16,7 +16,7 @@ const Layout = ({ isLoggedIn, googleAuthenticate, children }) => { console.log('Code: ' + code); if (state && code) { - googleAuthenticate(state, code); + // googleAuthenticate(state, code); } else { load_user(); } diff --git a/src/hocs/Layout.test.js b/src/hocs/Layout.test.js index 4f7e114515e2c3d2c859782d59dc704ef8d3ed16..94f9bfc75e66c32bd7699c5ec3a32b289887aae1 100644 --- a/src/hocs/Layout.test.js +++ b/src/hocs/Layout.test.js @@ -1,10 +1,8 @@ import Layout from './Layout'; import { render, queryByAttribute } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; import '@testing-library/jest-dom'; -import { BrowserRouter,Route } from 'react-router-dom' +import { BrowserRouter } from 'react-router-dom' import { Provider } from 'react-redux' -import axios from 'axios' import configureStore from 'redux-mock-store' import thunk from 'redux-thunk' diff --git a/src/page/Aktivasi/Aktivasi.js b/src/page/Aktivasi/Aktivasi.js index f5ebd53aeb5761de90b061b55e9b253fefd04ba7..0b2470bc781d7de27787e829cd18d8fff1a347f6 100644 --- a/src/page/Aktivasi/Aktivasi.js +++ b/src/page/Aktivasi/Aktivasi.js @@ -22,14 +22,17 @@ const Aktivasi = ({ verify, match }) => { <div className='container'> <div className='d-flex flex-column justify-content-center align-items-center' - style={{ marginTop: '200px' }} + style={{ + marginTop: '20%' , + marginBottom: '20%' + }} > <h1>Verifikasi akun anda</h1> <button onClick={verify_account} - style={{ marginTop: '50px' }} - type='button' - className='btn btn-primary' + type='button' + style={{ marginTop: '1.4%' }} + class='wkd-nav-button wkd-dark-green-button' > Verifikasi </button> diff --git a/src/page/DetailPengadaan/DetailPengadaan.css b/src/page/DetailPengadaan/DetailPengadaan.css new file mode 100644 index 0000000000000000000000000000000000000000..c87496ae8cd640c8fdaadeefc5e549553c95d4ae --- /dev/null +++ b/src/page/DetailPengadaan/DetailPengadaan.css @@ -0,0 +1,218 @@ +.wrapper{ + margin-bottom: 112px; + margin-top: 20px; + margin-left: 112px; + margin-right: 112px; +} + +.back-button{ + font-family: 'DM Sans', sans-serif; + font-weight: 700; + font-size: 25px; + text-align: left; +} + +.back-button .chevron-left{ + width: 40px; + padding-bottom: 5px; + +} + +.store-header{ + position: relative; + text-align: left; +} + +.profile-image{ + border-radius: 50%; + height: 70px; + max-width: 70px; + object-fit: contain; + background-color: black; + margin: 0; + position: absolute; + top: 50%; + -ms-transform: translateY(-50%); + transform: translateY(-50%); +} + +.store-header > img, +.store-header > .store-name{ + display: inline-block; +} + +.store-name{ + padding-left: 90px; + font-weight: 700; + font-size: 22px; + font-family: 'DM Sans', sans-serif; + line-height: 80%; +} + +.carousel-wrapper img{ + object-fit: cover; + max-height: 270px; + border-radius: 10px; +} + +.box-wrapper{ + text-align: start; + box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.25); + padding: 31px 42px 31px; + border-radius: 10px; +} + +.box-wrapper h3{ + font-weight: 700; + font-size: 20px; + font-family: 'DM Sans', sans-serif; +} + +.box-wrapper p{ + font-weight: normal; + font-size: 16px; + font-family: 'DM Sans', sans-serif; +} + +.distance{ + padding-bottom: 20px +} + +.distance-2{ + padding-top: 35px +} + +.invest-button{ + background-color: #146A5F; + color: white; + border-radius: 7.3px; + width: 100%; + height: 42px; + border: none; + font-weight: 700; + font-size: 16px; + font-family: 'DM Sans', sans-serif; + transition-duration: 0.3s; +} + +.invest-button:hover{ + background-color: #0f4e46; +} + +.modal-text{ + font-weight: 700; + font-size: 20px; + font-family: 'DM Sans', sans-serif; + text-align: left; + padding-top: 30px; + color: #1E8E7F; +} + +.modal-target{ + font-weight: 700; + font-size: 20px; + font-family: 'DM Sans', sans-serif; + text-align: left; +} + +.progress-bar { + background-color: #0BBBA8; + color: rgb(255, 255, 255); + font-weight: 500; + font-size: 20px; + font-family: 'DM Sans', sans-serif; +} + +.progress{ + height: 27px; + border-radius: 7px; +} + +.modal-desc{ + font-weight: normal; + font-size: 16px; + font-family: 'DM Sans', sans-serif; + text-align: left; + opacity: 0.6; + padding-top: 5px +} + +.midtext { + width: 100%; + text-align: center; + border-bottom: 1px solid #ccc; + line-height: 0.1em; +} + +.nav-tabs .nav-item.show .nav-link, .nav-tabs .nav-link.active { + color: #146A5F; + background-color: #fff; + border-bottom: 3px solid #146A5F; + border-left: none; + border-right: none; + opacity: 1; +} + +.nav-tabs { + box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.25); + border: none; + font-family: 'DM Sans', sans-serif; + font-weight: 500; +} + +.nav-tabs .nav-link{ + color: black; + opacity: 0.6; +} + +.nav-tabs .nav-link:hover{ + color: #146A5F; + opacity: 1; +} + +.tab-content{ + padding-top: 15px; +} + +.store-information{ + font-weight: 700; + font-size: 15px; + font-family: 'DM Sans', sans-serif; + color: #146A5F; + line-height: 2.0; + text-align: left; +} + +.store-information-span{ + font-weight: normal; + color: black; +} + +.profile-details { + vertical-align: top; + text-align: left; +} + +.review-pengadaan-mainan{ + max-height: 101px; + max-width: 101px; + object-fit: contain; +} + +.toys-summary{ + font-family: 'DM Sans', sans-serif; + font-size: 18px; + font-weight: 700; + line-height: 1.5; + align-items: center; +} + +.mi-card{ + border: 1px solid #b5b5b5; + border-radius: 10px; + text-align: left; +} + +.fade { + transition: opacity .300s linear; +} \ No newline at end of file diff --git a/src/page/DetailPengadaan/DetailPengadaan.js b/src/page/DetailPengadaan/DetailPengadaan.js new file mode 100644 index 0000000000000000000000000000000000000000..507f2040a351a13e92234d67a7785874d95ef40e --- /dev/null +++ b/src/page/DetailPengadaan/DetailPengadaan.js @@ -0,0 +1,173 @@ +import './DetailPengadaan.css'; +import React from 'react'; +import { Link, Redirect } from 'react-router-dom'; +import { Carousel } from "react-responsive-carousel"; +import "react-responsive-carousel/lib/styles/carousel.min.css"; +import { connect } from 'react-redux'; +import { Row } from "react-bootstrap"; +import ProgressBar from 'react-bootstrap/ProgressBar' +import Tabs from 'react-bootstrap/Tabs' +import Tab from 'react-bootstrap/Tab' +import { ChevronLeft } from 'react-feather'; +import image from './resto-bebek.jpg'; +import image2 from './resto-bebek-2.jpg'; +import image3 from './resto-bebek-3.jpg'; +import profil from './profil-bebek.jpg'; + + +const DetailPengadaan = ({ isAuthenticated ,user }) => { + if (!isAuthenticated) return <Redirect to="/masuk" /> + if (user.role !== "Investor") return <Redirect to="/" /> + + return ( + <div className="wrapper"> + <h3 className="back-button"><Link to="/" style={{ color: 'rgb(0, 0, 0)' }} ><ChevronLeft size="40" className="chevron-left"/></Link>Kembali</h3> + <div className="store-header"> + <img src={profil} className="profile-image" alt=""></img> + <div className="store-name"> + Resto Bebek H.Slamet<br /> + <span style={{fontWeight: "500", fontSize: "15px"}}>WKD-02ID2021 - Cabang Maros 05</span> + </div> + </div> + <Row className="justify-content-center distance-2"> + <div className="col-lg-5"> + <div className="carousel-wrapper"> + <Carousel autoPlay infiniteLoop thumbWidth={150} showThumbs={false}> + <div> + <img alt="" src={image3}/> + </div> + <div> + <img alt="" src={image2}/> + </div> + <div> + <img alt="" src={image} /> + </div> + </Carousel> + </div> + <h3 className="modal-text">Kebutuhan Modal</h3> + <p className="midtext"></p> + <h3 className="modal-target">Rp30,000,000.00</h3> + <ProgressBar striped now={55} label={55 + "%"} /> + <p className="modal-desc">Terkumpul dari target: Rp16,500,000.00</p> + </div> + <div className="col-lg-7"> + <div className="box-wrapper"> + <Row className="distance"> + <div className="col-sm"> + <h3>Periode Pengadaan</h3> + <p>05/17/2021 - 07/17/2021</p> + </div> + <div className="col-sm"> + <h3>Email Penggalang</h3> + <p>charles@gmail.com</p> + </div> + </Row> + <Row> + <div className="col-sm"> + <h3>Tipe Usaha</h3> + <p>Restoran</p> + </div> + <div className="col-sm"> + <h3>Nomor Telepon Penggalang</h3> + <p>081318061867</p> + </div> + </Row> + <Row className="justify-content-center"> + <div className="col-sm"> + <Link to="/investasi"><button className="invest-button" type="button"> + Ikut Investasi + </button></Link> + </div> + </Row> + </div> + <br></br> + <Tabs fill justify defaultActiveKey="toko" id="uncontrolled-tab-example"> + <Tab eventKey="toko" title="Informasi Toko"> + <div className="store-information"> + Nama Toko: + <span className="store-information-span"> Resto Bebek H.Slamet</span><br /> + Nama Cabang: + <span className="store-information-span"> Maros 05</span><br /> + Tipe Usaha: + <span className="store-information-span"> Restoran</span><br /> + Nomor Telepon Toko: + <span className="store-information-span"> 081316086814</span><br /> + Lokasi Toko: + <span className="store-information-span"> Jl Tanah Abang III 15 Graha Astri Aniela Anggun,Petojo Selatan</span><br /> + Deskripsi Toko:<br /> + <span className="store-information-span"> + Lorem ipsum dolor sit amet, consectetur adipiscing elit, + sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris + nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in + reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in + culpa qui officia deserunt mollit anim id est laborum</span><br /> + </div> + </Tab> + <Tab eventKey="mainan" title="Pilihan Mainan"> + <Row className="justify-content-center toys-summary"> + <div className="col-sm-2"> + <img src="https://i.stack.imgur.com/y9DpT.jpg" className="review-pengadaan-mainan"></img> + </div> + <div className="col-sm-6 profile-details"> + Spongebob Kiddie Ride<br /> + <span style={{fontWeight: "500", fontSize: "15px"}}>Rp 7,200,000.00</span> + </div> + <div className="col-sm-4" style={{fontSize: "15px"}}> + <div className="line" /> + <span style={{fontWeight: "500"}}>Jumlah: </span>2 buah + </div> + </Row> + <br></br> + <Row className="justify-content-center toys-summary"> + <div className="col-sm-2"> + <img src="https://i.stack.imgur.com/y9DpT.jpg" className="review-pengadaan-mainan"></img> + </div> + <div className="col-sm-6 profile-details"> + Spongebob Kiddie Ride<br /> + <span style={{fontWeight: "500", fontSize: "15px"}}>Rp 7,200,000.00</span> + </div> + <div className="col-sm-4" style={{fontSize: "15px"}}> + <div className="line" /> + <span style={{fontWeight: "500"}}>Jumlah: </span>2 buah + </div> + </Row> + <br></br> + <Row className="justify-content-center toys-summary"> + <div className="col-sm-2"> + <img src="https://i.stack.imgur.com/y9DpT.jpg" className="review-pengadaan-mainan"></img> + </div> + <div className="col-sm-6 profile-details"> + Spongebob Kiddie Ride<br /> + <span style={{fontWeight: "500", fontSize: "15px"}}>Rp 7,200,000.00</span> + </div> + <div className="col-sm-4" style={{fontSize: "15px"}}> + <div className="line" /> + <span style={{fontWeight: "500"}}>Jumlah: </span>2 buah + </div> + </Row> + </Tab> + <Tab eventKey="keuangan" title="Estimasi Keuangan"> + <div className="card mi-card"> + <div className="card-body"> + <p className="card-text"> + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, + quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. + </p> + </div> + </div> + </Tab> + </Tabs> + </div> + </Row> + </div> + ); +} +const mapStateToProps = (state) => ({ + isAuthenticated: state.auth.isAuthenticated, + user: state.auth.user +}); + +export default connect(mapStateToProps)(DetailPengadaan); diff --git a/src/page/DetailPengadaan/profil-bebek.jpg b/src/page/DetailPengadaan/profil-bebek.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f3582d8a829376a7ae0ca55b21328463c9b88091 Binary files /dev/null and b/src/page/DetailPengadaan/profil-bebek.jpg differ diff --git a/src/page/DetailPengadaan/resto-bebek-2.jpg b/src/page/DetailPengadaan/resto-bebek-2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a0ea113c10a207756b9d0997f0f4a5ce388f8ee1 Binary files /dev/null and b/src/page/DetailPengadaan/resto-bebek-2.jpg differ diff --git a/src/page/DetailPengadaan/resto-bebek-3.jpg b/src/page/DetailPengadaan/resto-bebek-3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..74f69875c386010292556753460bc95b5555c81d Binary files /dev/null and b/src/page/DetailPengadaan/resto-bebek-3.jpg differ diff --git a/src/page/DetailPengadaan/resto-bebek.jpg b/src/page/DetailPengadaan/resto-bebek.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a04e6ce3a32b89d039b706ba2d6d98030fc79eca Binary files /dev/null and b/src/page/DetailPengadaan/resto-bebek.jpg differ diff --git a/src/page/HomepageInvestor/HomepageInvestor.css b/src/page/HomepageInvestor/HomepageInvestor.css new file mode 100644 index 0000000000000000000000000000000000000000..05c7cae99532e7ee9128d2e8357169d772a28edf --- /dev/null +++ b/src/page/HomepageInvestor/HomepageInvestor.css @@ -0,0 +1,44 @@ +.row-homepage-investor { + padding: 10px; +} + +.pageNumbers { + list-style: none; + display: flex; + } + + .pageNumbers li { + padding: 10px; + cursor: pointer; + } + + .pageNumbers li:hover { + background-color: #146A5F; + color: rgb(255, 255, 255); + } + + .pageNumbers li.active { + background-color: #146A5F; + color: white; + } + + .pageNumbers li button { + background-color: transparent; + border: none; + color: #146A5F; + font-size: 1.5rem; + cursor: pointer; + } + .pageNumbers li button:hover { + background-color: #146A5F; + color: rgb(255, 255, 255); + } + .pageNumbers li button:focus { + outline: none; + background-color: #146A5F; + color: white; + } + + .css-tlfecz-indicatorContainer{ + width: 70px; + } diff --git a/src/page/HomepageInvestor/HomepageInvestor.js b/src/page/HomepageInvestor/HomepageInvestor.js new file mode 100644 index 0000000000000000000000000000000000000000..3a98b001ab8a08ff9f339844b2b433da8878bf0a --- /dev/null +++ b/src/page/HomepageInvestor/HomepageInvestor.js @@ -0,0 +1,193 @@ +import React, { useState, useEffect } from 'react'; +import Cards from '../../components/Cards/Cards'; +import Pagination from '../../components/Pagination/Pagination'; +import Card from 'react-bootstrap/Card' +import { Row,Col } from "react-bootstrap"; +import Select from 'react-select'; +import axios from 'axios'; +import { connect } from 'react-redux'; +import './HomepageInvestor.css' +import '../HomepagePemilikToko/HomepagePemilikToko.css' +import { Redirect } from 'react-router-dom'; +import _ from 'lodash'; + +const HomepageInvestor = ({ isAuthenticated ,user }) => { +// const HomepageInvestor = () => { + const [posts, setPosts] = useState([]); + const [filteredPosts, setFilteredPosts] = useState(); + const [loading, setLoading] = useState(false); + const [searchTerm, setSearchTerm] = useState(""); + const [currentPage, setCurrentPage] = useState(1); + const [postsPerPage, setPostsPerPage] = useState(6); + const indexOfLastPost = currentPage * postsPerPage; + const indexOfFirstPost = indexOfLastPost - postsPerPage; + let currentPosts = ""; + let postLength = 0; + const [filterChoice, setFilterChoice] = useState([]) + + // console.log(filterChoice) + if (filteredPosts) { + currentPosts = filteredPosts.slice(indexOfFirstPost, indexOfLastPost); + postLength = filteredPosts.length; + } else if(posts !== []){ + currentPosts = posts.slice(indexOfFirstPost, indexOfLastPost); + postLength = posts.length; + } + + const config = { + headers: { + 'Content-Type': 'multipart/form-data', + 'Authorization': `JWT ${localStorage.getItem('access')}`, + } + }; + console.log(searchTerm) + + useEffect(() => { + const fetchPosts = async () => { + // const searchData = []; + try { + setLoading(true); + const res = await axios.get(`${process.env.REACT_APP_BACKEND_API_URL}/api/toko/`,config); + const res2 = await axios.get(`${process.env.REACT_APP_BACKEND_API_URL}/api/pengadaan/`,config); + + var merged = _.merge(_.keyBy(res.data, 'pk'), _.keyBy(res2.data, 'toko')); + var result = _.values(merged); + + const data = filterChange(result, searchTerm, 'namaToko'); + + setPosts(data); + setFilteredPosts(); + setLoading(false); + + let allFilter = []; + for(let i=0; i < data.length; i++){ + let response = data[i]; + let value = response['daerah']; + allFilter.push({value:value, label:value}) + } + setFilterChoice(filterChoice.concat(allFilter)) + } catch { + alert('Terdapat kesalahan pada database. Mohon refresh ulang halaman ini') + } + }; + + fetchPosts(); + }, [searchTerm]); + + const handleChange = async e => { + const res = await axios.get(`${process.env.REACT_APP_BACKEND_API_URL}/api/toko/`, config); + const res2 = await axios.get(`${process.env.REACT_APP_BACKEND_API_URL}/api/pengadaan/`,config); + const filterData = filterChange(res.data, e.value, 'daerah'); + + var merged = _.merge(_.keyBy(filterData, 'pk'), _.keyBy(res2.data, 'toko')); + var result = _.values(merged); + + setFilteredPosts(filterData); + setPosts() + } + + const filterChange = (data, filterTerm, find ) => { + const filteredData = data.filter((e) => { + if (filterTerm === ""){ + return e + } + else if (e[find].toLowerCase().includes(filterTerm.toLowerCase())) { + if (e) { + return e + } + } + }); + return filteredData + } + + const paginate = pageNumber => setCurrentPage(pageNumber); + + if (!isAuthenticated) return <Redirect to="/masuk" /> + if (user.role !== "Investor") return <Redirect to="/" /> + + return ( + <div className='container mt-5 justify-content-center'> + + <h3 className="pemilik-toko-h2 text-align-left" + style={{ padding: '0', margin: '0' }} + >Halo, <span className="pemilik-toko-text-light-green pemilik-toko-text-bold">{user.first_name} {user.last_name} !</span></h3> + <h6 className="text-align-left" + style={{ padding: '0', margin: '0' }} + >Selamat datang kembali di <span className="wkd-green-text pemilik-toko-text-bold">Walkiddie.</span></h6> + <br></br> + <h1>Proyek Pengadaan Barang</h1> + <Row className='justify-content-center row-homepage-investor'> + <button className="wkd-nav-button wkd-dark-green-button" type="submit" style ={{ + padding:"0 40px" + }}>Lihat Investasi yang Dimiliki</button> + <input + style={{ + width: '70%', + heigth: '30px' + }} + type="text" + placeholder="Search" + onChange={(event) => setSearchTerm(event.target.value) + } + > + </input> + </Row> + <Row className="row-homepage-investor"> + <Col sm={4}> + <Card + style={{ + width: '350px', + height: '80px' + }} + > + <p style={{ + marginTop:'7px', + marginBottom: '9px' + }}> + Atur Lokasi yang ingin dicari : + </p> + <div data-testid="select-daerah"> + <Select + style={{ + width: '900px', + height: '110px' + }} + class="form-control" + placeholder="Beji,Depok" + // value={dataPilihanMainan.find(obj => obj.value === selectedValue)} + options={filterChoice} + onChange={handleChange} + /> + </div> + </Card> + </Col> + <Col sm={8}> + <Cards posts={currentPosts} loading={loading} /> + </Col> + </Row> + <Row className="row-homepage-investor" + style={{ + justifyContent: 'center' + }} + > + <Pagination + currentPage={currentPage} + postsPerPage={postsPerPage} + totalPosts={postLength} + paginate={paginate} + /> + </Row> + </div> + ); + +}; + +const mapStateToProps = (state) => ({ + isAuthenticated: state.auth.isAuthenticated, + user: state.auth.user +}) + +export default connect(mapStateToProps)(HomepageInvestor); + + +// export default HomepageInvestor; \ No newline at end of file diff --git a/src/page/HomepageInvestor/HomepageInvestor.test.js b/src/page/HomepageInvestor/HomepageInvestor.test.js new file mode 100644 index 0000000000000000000000000000000000000000..7f9f6a829d279818e10b133be5b9d1aad10b9552 --- /dev/null +++ b/src/page/HomepageInvestor/HomepageInvestor.test.js @@ -0,0 +1,171 @@ +import HomepageInvestor from './HomepageInvestor'; +import { render } from '@testing-library/react'; +import '@testing-library/jest-dom'; +import { BrowserRouter } from 'react-router-dom' +import { Provider } from 'react-redux' +import configureStore from 'redux-mock-store' +import thunk from 'redux-thunk' + +jest.mock('axios') + +const middlewares = [thunk] +const mockStore = configureStore(middlewares) + +describe('<HomepageInvestor />', () => { + + it('renders the right contents', () => { + const mockUser = jest.fn() + const mockAuthenticate = jest.fn() + const initialState = { auth: { + isAuthenticated: true, + user: { + role: "Mitra" + } + } + } + localStorage.setItem('access', 'token') + const store = mockStore(initialState) + render( + <Provider store={store}> + <BrowserRouter> + <HomepageInvestor isAuthenticated={mockAuthenticate} user={mockUser}/> + </BrowserRouter> + </Provider>); + + // expect(screen.getByText('Proyek Pengadaan Barang')).toBeInTheDocument(); + localStorage.removeItem('access', 'token') + }); + + // test('search toko by name in search field', async() => { + // const mockUser = jest.fn() + // const mockAuthenticate = jest.fn() + // const initialState = { + // auth: { + // isAuthenticated: true, + // user: { + // role: "Mitra" + // }, + // refresh: 'token', + // access: 'access' + // } + // } + // localStorage.setItem('access', 'token') + // const store = mockStore(initialState); + // const { getByLabelText, getByRole , getByText, queryByTestId, getByPlaceholderText } = await render( + // <Provider store={store}> + // <BrowserRouter> + // <HomepageInvestor isAuthenticated={mockAuthenticate} user={mockUser}/> + // </BrowserRouter> + // </Provider>); + + // const searchField = getByPlaceholderText("Search"); + // await userEvent.type(searchField, "que"); + // localStorage.removeItem('access', 'token') + // }); + + // test('search toko by filter', async() => { + // const mockUser = jest.fn() + // const mockAuthenticate = jest.fn() + // const initialState = { + // auth: { + // isAuthenticated: true, + // user: { + // role: "Mitra" + // }, + // refresh: 'token', + // access: 'access' + // } + // } + // localStorage.setItem('access', 'token') + // const store = mockStore(initialState); + // const { getByLabelText, getByRole , getByText, queryByTestId, getByPlaceholderText } = await render( + // <Provider store={store}> + // <BrowserRouter> + // <HomepageInvestor isAuthenticated={mockAuthenticate} user={mockUser}/> + // </BrowserRouter> + // </Provider>); + + // const mySelectComponent = queryByTestId('select-daerah'); + + // await fireEvent.keyDown(mySelectComponent.firstChild, { key: 'ArrowDown' }); + // await(() => getByText('aut')); + // await fireEvent.click(getByText('aut')); + + // localStorage.removeItem('access', 'token') + // }); + + // it('should redirect if not Investor', () => { + // let loc; + // const mockUser = jest.fn() + // const mockAuthenticate = jest.fn() + // const initialState = { + // auth: { + // isAuthenticated: true, + // user: { + // role: "Mitra" + // } + // } + // } + // const store = mockStore(initialState) + // render( + // <> + // <Provider store={store}> + // <BrowserRouter> + // <HomepageInvestor user={mockUser} isAuthenticated={mockAuthenticate} /> + // <Route + // path="*" + // render={({location}) => { + // loc = location; + // return null; + // }} + // /> + // </BrowserRouter> + // </Provider>); + // </>, + // {initialState: {auth: { + // isAuthenticated: true, + // user: { + // role: "Investor" + // } + // } + // } + // } + // ); + // expect(loc.pathname).toBe('/'); + // }) + + // it('should redirect if guest', () => { + // let loc; + // const mockUser = jest.fn() + // const mockAuthenticate = jest.fn() + // const initialState = { + // auth: { + // isAuthenticated: false + // } + // } + // const store = mockStore(initialState) + // render( + // <> + // <Provider store={store}> + // <BrowserRouter> + // <HomepageInvestor user={mockUser} isAuthenticated={mockAuthenticate} /> + // <Route + // path="*" + // render={({location}) => { + // loc = location; + // return null; + // }} + // /> + // </BrowserRouter> + // </Provider>); + // </>, + // {initialState: {auth: { + // isAuthenticated: false + // } + // } + // } + // ); + // expect(loc.pathname).toBe('/masuk'); + // }) + +}) \ No newline at end of file diff --git a/src/page/HomepagePemilikToko/HomepagePemilikToko.css b/src/page/HomepagePemilikToko/HomepagePemilikToko.css new file mode 100644 index 0000000000000000000000000000000000000000..18491b47e2ae349ae6745d0e784d908a4b7f4789 --- /dev/null +++ b/src/page/HomepagePemilikToko/HomepagePemilikToko.css @@ -0,0 +1,26 @@ +@import url('https://fonts.googleapis.com/css2?family=DM+Sans:ital,wght@0,400;0,500;0,700;1,400;1,500;1,700&family=Nunito:wght@300;400;600;700;800&display=swap'); +.pemilik-toko-h2 { + font-family: 'Nunito', sans-serif; + font-weight: 600; + font-size: 35px; + margin: 0; +} + +.pemilik-toko-text-light-green { + color: #0BBBA8; + /* color: #146A5F; */ +} + +.pemilik-toko-text-bold { + font-weight: 1000; +} + +.text-align-left { + text-align: left; +} + +.pemilik-toko-img-daftarkan-toko { + max-width: 40%; + margin-right: 20px; + margin-left: 20px; +} \ No newline at end of file diff --git a/src/page/HomepagePemilikToko/HomepagePemilikToko.js b/src/page/HomepagePemilikToko/HomepagePemilikToko.js new file mode 100644 index 0000000000000000000000000000000000000000..70f692f76c3d85ea5be43306bc32ef80d84820df --- /dev/null +++ b/src/page/HomepagePemilikToko/HomepagePemilikToko.js @@ -0,0 +1,134 @@ +import React, { useState, useEffect } from 'react'; +import Cards from '../../components/Cards/Cards'; +import Pagination from '../../components/Pagination/Pagination'; +import './HomepagePemilikToko.css' +import DaftarkanToko from './pemilik-toko-daftarkan-toko.svg'; +import axios from 'axios'; +import { Row } from "react-bootstrap"; +import { connect } from 'react-redux'; +import { Link, Redirect } from 'react-router-dom'; + +const HomepagePemilikToko = ({ isAuthenticated, user }) => { + const [daftarTokoItems, setDaftarTokoItems] = useState([]); + const [daftarTokoLoading, setDaftarTokoLoading] = useState(false); + const [daftarTokoCurrentPage, setDaftarTokoCurrentPage] = useState(1); + const [daftarTokoPostsPerPage, setDaftarTokoPostsPerPage] = useState(3); + const daftarTokoIndexOfLastPost = daftarTokoCurrentPage * daftarTokoPostsPerPage; + const daftarTokoIndexOfFirstPost = daftarTokoIndexOfLastPost - daftarTokoPostsPerPage; + let daftarTokoCurrentPosts = ""; + let daftarTokoPostLength = 0; + + const [daftarPengadaanItems, setDaftarPengadaanItems] = useState([]); + const [daftarPengadaanLoading, setDaftarPengadaanLoading] = useState(false); + const [daftarPengadaanCurrentPage, setDaftarPengadaanCurrentPage] = useState(1); + const [daftarPengadaanPostsPerPage, setDaftarPengadaanPostsPerPage] = useState(3); + const daftarPengadaanIndexOfLastPost = daftarPengadaanCurrentPage * daftarPengadaanPostsPerPage; + const daftarPengadaanIndexOfFirstPost = daftarPengadaanIndexOfLastPost - daftarPengadaanPostsPerPage; + let daftarPengadaanCurrentPosts = ""; + let daftarPengadaanPostLength = 0; + + if (daftarTokoItems !== []) { + daftarTokoCurrentPosts = daftarTokoItems.slice(daftarTokoIndexOfFirstPost, daftarTokoIndexOfLastPost); + daftarTokoPostLength = daftarTokoItems.length; + } + if (daftarPengadaanItems !== []) { + daftarPengadaanCurrentPosts = daftarPengadaanItems.slice(daftarPengadaanIndexOfFirstPost, daftarPengadaanIndexOfLastPost); + daftarPengadaanPostLength = daftarPengadaanItems.length; + } + + const fetchDaftarTokoItems = async () => { + try { + setDaftarTokoLoading(true); + const res = await axios.get('https://jsonplaceholder.typicode.com/posts'); + setDaftarTokoItems(res.data); + setDaftarTokoLoading(false); + } catch { + alert('Terdapat kesalahan pada database. Mohon refresh ulang halaman ini') + } + }; + + const fetchDaftarPengadaanItems = async () => { + try { + setDaftarPengadaanLoading(true); + const res = await axios.get('https://jsonplaceholder.typicode.com/posts'); + setDaftarPengadaanItems(res.data); + setDaftarPengadaanLoading(false); + } catch { + alert('Terdapat kesalahan pada database. Mohon refresh ulang halaman ini') + } + }; + + useEffect(() => { + fetchDaftarTokoItems(); + fetchDaftarPengadaanItems(); + }, []); + + const daftarTokoPaginate = daftarPageNumber => setDaftarTokoCurrentPage(daftarPageNumber); + const daftarPengadaanPaginate = daftarPageNumber => setDaftarPengadaanCurrentPage(daftarPageNumber); + + if (!isAuthenticated) return <Redirect to="/masuk" /> + if (user.role !== "Mitra") return <Redirect to="/" /> + + return ( + <div className='container mt-5'> + + <h3 className="pemilik-toko-h2 text-align-left" + style={{ padding: '0', margin: '0' }} + >Halo, <span className="pemilik-toko-text-light-green pemilik-toko-text-bold">{user.first_name} {user.last_name} !</span></h3> + <h6 className="text-align-left" + style={{ padding: '0', margin: '0' }} + >Selamat datang kembali di <span className="wkd-green-text pemilik-toko-text-bold">Walkiddie.</span></h6> + + <Link to="/daftar-toko"> + <img src={DaftarkanToko} alt="Daftarkan-toko" className="pemilik-toko-img-daftarkan-toko mt-5" /> + </Link> + + <Link to="/daftar-toko"> + <img src={DaftarkanToko} alt="Daftarkan-toko" className="pemilik-toko-img-daftarkan-toko mt-5" /> + </Link> + + <div className="daftar-toko"> + <h3 className="text-align-left mt-5 mb-3" >Daftar Toko</h3> + + <Cards posts={daftarTokoCurrentPosts} loading={daftarTokoLoading} /> + <Row + style={{ + justifyContent: 'center' + }} + > + <Pagination + currentPage={daftarTokoCurrentPage} + postsPerPage={daftarTokoPostsPerPage} + totalPosts={daftarTokoPostLength} + paginate={daftarTokoPaginate} + /> + </Row> + </div> + + <div className="daftar-toko"> + <h3 className="text-align-left mt-5 mb-3" >Daftar Pengadaan</h3> + + <Cards posts={daftarPengadaanCurrentPosts} loading={daftarPengadaanLoading} /> + <Row + style={{ + justifyContent: 'center' + }} + > + <Pagination + currentPage={daftarPengadaanCurrentPage} + postsPerPage={daftarPengadaanPostsPerPage} + totalPosts={daftarPengadaanPostLength} + paginate={daftarPengadaanPaginate} + /> + </Row> + </div> + </div> + ); +} + +const mapStateToProps = (state) => ({ + isAuthenticated: state.auth.isAuthenticated, + user: state.auth.user +}) + +export default connect(mapStateToProps)(HomepagePemilikToko); \ No newline at end of file diff --git a/src/page/HomepagePemilikToko/HomepagePemilikToko.test.js b/src/page/HomepagePemilikToko/HomepagePemilikToko.test.js new file mode 100644 index 0000000000000000000000000000000000000000..5a6df478d061cb9f785c952c88e2c77941e29bd1 --- /dev/null +++ b/src/page/HomepagePemilikToko/HomepagePemilikToko.test.js @@ -0,0 +1,40 @@ +import HomepagePemilikToko from './HomepagePemilikToko'; +import { render, screen } from '@testing-library/react'; +import '@testing-library/jest-dom'; +import { BrowserRouter } from 'react-router-dom' +import { Provider } from 'react-redux' +import configureStore from 'redux-mock-store' +import thunk from 'redux-thunk' + +jest.mock('axios') + +const middlewares = [thunk] +const mockStore = configureStore(middlewares) + +describe('<HomepagePemilikToko />', () => { + + it('renders the right contents', () => { + const mockUser = jest.fn() + const mockAuthenticate = jest.fn() + const initialState = { + auth: { + isAuthenticated: true, + user: { + role: "Mitra" + } + } + } + localStorage.setItem('access', 'token') + const store = mockStore(initialState) + render( + <Provider store={store}> + <BrowserRouter> + <HomepagePemilikToko isAuthenticated={mockAuthenticate} user={mockUser} /> + </BrowserRouter> + </Provider>); + + expect(screen.getByText(/Daftar Toko/)).toBeInTheDocument(); + expect(screen.getByText(/Daftar Pengadaan/)).toBeInTheDocument(); + localStorage.removeItem('access', 'token') + }); +}) \ No newline at end of file diff --git a/src/page/HomepagePemilikToko/pemilik-toko-daftarkan-toko.svg b/src/page/HomepagePemilikToko/pemilik-toko-daftarkan-toko.svg new file mode 100644 index 0000000000000000000000000000000000000000..06752273f16fc6ef934cd9f2b3286e127f57de29 --- /dev/null +++ b/src/page/HomepagePemilikToko/pemilik-toko-daftarkan-toko.svg @@ -0,0 +1,169 @@ +<svg width="616" height="226" viewBox="0 0 616 226" fill="none" xmlns="http://www.w3.org/2000/svg"> +<g filter="url(#filter0_d)"> +<rect x="4" y="4" width="608" height="214" rx="20" fill="#D3F1EE"/> +</g> +<path d="M572.121 162.013C572.121 162.064 535.801 162.107 491.004 162.107C446.206 162.107 409.879 162.064 409.879 162.013C409.879 161.962 446.192 161.918 491.004 161.918C535.816 161.918 572.121 161.958 572.121 162.013Z" fill="#263238"/> +<path d="M453.828 99.008L463.336 131.087C463.541 131.782 463.966 132.391 464.546 132.824C465.125 133.258 465.83 133.493 466.554 133.493L505.138 133.599C505.623 133.6 506.103 133.502 506.55 133.312C506.996 133.121 507.398 132.841 507.733 132.49C508.067 132.138 508.327 131.722 508.495 131.267C508.664 130.812 508.737 130.327 508.712 129.842C508.663 128.93 508.266 128.072 507.603 127.444C506.94 126.815 506.062 126.465 505.149 126.465H490.396L478.58 93.548H457.898C457.236 93.5475 456.584 93.7017 455.992 93.9982C455.401 94.2947 454.887 94.7254 454.492 95.2558C454.096 95.7863 453.83 96.4018 453.715 97.0533C453.6 97.7048 453.639 98.3741 453.828 99.008Z" fill="#455A64"/> +<path d="M486.471 129.1C486.471 129.176 482.536 129.235 477.684 129.235C472.832 129.235 468.9 129.176 468.9 129.1C468.9 129.023 472.832 128.965 477.684 128.965C482.536 128.965 486.471 129.023 486.471 129.1Z" fill="#263238"/> +<path d="M456.669 94.5599C456.738 94.538 459.366 102.222 462.536 111.726C465.707 121.23 468.215 128.954 468.145 128.976C468.076 128.998 465.448 121.332 462.278 111.81C459.107 102.288 456.596 94.5853 456.669 94.5599Z" fill="#263238"/> +<path d="M484.866 162.013L482.515 161.958V133.493H484.866V162.013Z" fill="#455A64"/> +<path d="M472.749 161.882H494.636L484.721 158.435H482.37L472.749 161.882Z" fill="#455A64"/> +<path d="M467.211 86.1806L470.833 104.275L470.185 117.834L494.529 113.786L493.575 101.92L493.546 92.092L499.516 103.66L504.161 94.68L495.654 79.2646C494.105 77.6459 492.199 76.4119 490.088 75.661C488.967 75.2569 487.789 75.0309 486.598 74.9913C483.856 75.8593 480.913 75.8593 478.171 74.9913C477.829 75.035 477.356 75.0823 476.755 75.1514H476.646C474.142 75.469 471.829 76.6563 470.112 78.506C468.395 80.3557 467.382 82.7501 467.251 85.2706L467.211 86.1806Z" fill="#1E8E7F"/> +<path d="M476.764 75.155C476.764 75.155 466.761 75.2315 465.524 85.7947L465.356 93.5479L473.969 93.4751L476.764 75.155Z" fill="#1E8E7F"/> +<path d="M500.661 88.7432C500.661 88.8196 492.791 88.8815 483.084 88.8815C473.376 88.8815 465.521 88.816 465.521 88.7432C465.521 88.6704 473.387 88.6085 483.098 88.6085C492.81 88.6085 500.661 88.6704 500.661 88.7432Z" fill="#FAFAFA"/> +<path d="M500.661 90.4212C500.661 90.494 492.791 90.5559 483.083 90.5559C473.376 90.5559 465.506 90.494 465.506 90.4212C465.506 90.3484 473.372 90.2829 483.083 90.2829C492.795 90.2829 500.661 90.3448 500.661 90.4212Z" fill="#FAFAFA"/> +<path d="M500.101 87.36C500.101 87.4364 492.358 87.4983 482.807 87.4983C473.256 87.4983 465.521 87.4328 465.521 87.36C465.521 87.2872 473.263 87.2253 482.818 87.2253C492.373 87.2253 500.101 87.2836 500.101 87.36Z" fill="#FAFAFA"/> +<path d="M493.427 103.656C493.351 103.656 493.383 99.372 493.5 94.094C493.616 88.816 493.773 84.5353 493.846 84.5353C493.918 84.5353 493.889 88.8196 493.773 94.0976C493.656 99.3756 493.5 103.656 493.427 103.656Z" fill="#263238"/> +<path d="M490.006 96.7111C490.006 96.7111 494.738 97.0496 495.59 98.3018C496.442 99.554 497.741 103.118 497.25 103.143C496.944 103.154 496.644 103.061 496.398 102.877L495.102 100.577C495.102 100.577 495.31 102.797 494.535 102.841C493.759 102.885 489.908 103.656 489.908 103.656L490.006 96.7111Z" fill="#FFBE9D"/> +<path d="M465.359 91.4805L465.341 103.678C465.377 104.348 465.559 105.002 465.873 105.596C466.186 106.189 466.626 106.706 467.159 107.113C467.693 107.52 468.309 107.806 468.964 107.951C469.619 108.097 470.298 108.098 470.954 107.955L490.031 104.024L489.991 96.2015L473.527 99.372L473.309 91.091L465.359 91.4805Z" fill="#1E8E7F"/> +<path d="M476.242 106.976C476.324 106.946 476.408 106.923 476.493 106.907L477.221 106.739L480.024 106.146L489.965 104.104L489.867 104.22C489.867 101.767 489.867 99.0517 489.867 96.187L490.027 96.3217L486.671 96.966L473.567 99.4594L473.425 99.4885V99.372C473.549 95.732 473.654 92.7181 473.727 90.5777C473.771 89.5367 473.803 88.7104 473.829 88.1207C473.829 87.855 473.854 87.6403 473.865 87.4765C473.865 87.4017 473.874 87.3272 473.891 87.2544C473.895 87.3284 473.895 87.4025 473.891 87.4765C473.891 87.6439 473.891 87.8405 473.891 88.1244C473.891 88.7141 473.869 89.5403 473.854 90.5814C473.803 92.7254 473.734 95.7466 473.65 99.3756L473.512 99.2628L486.616 96.7148L489.972 96.0742L490.132 96.0414V96.2052C490.132 99.0699 490.132 101.785 490.132 104.239V104.341L490.034 104.359L480.079 106.288L477.261 106.816L476.515 106.947C476.425 106.966 476.334 106.976 476.242 106.976Z" fill="#263238"/> +<path d="M487.186 75.1551C487.186 75.1551 487.222 75.2133 487.262 75.3334C487.325 75.509 487.375 75.6891 487.411 75.8721C487.543 76.5541 487.512 77.2575 487.32 77.9251C487.025 78.9152 486.451 79.7995 485.668 80.4731C484.714 81.3279 483.476 81.7964 482.195 81.7871C481.559 81.7976 480.927 81.6795 480.337 81.44C479.747 81.2004 479.212 80.8443 478.763 80.393C478.05 79.6342 477.601 78.6649 477.485 77.6303C477.399 76.9402 477.482 76.2396 477.725 75.5882C477.79 75.4131 477.871 75.2448 477.969 75.0859C478.035 74.9767 478.071 74.9221 478.082 74.9257C478.093 74.9294 477.965 75.1696 477.823 75.6246C477.63 76.266 477.579 76.9417 477.674 77.6048C477.812 78.5872 478.255 79.5014 478.941 80.2183C479.37 80.6399 479.879 80.9717 480.437 81.1942C480.996 81.4167 481.594 81.5255 482.195 81.5141C483.41 81.524 484.586 81.0875 485.5 80.2875C486.262 79.6482 486.829 78.8084 487.138 77.8632C487.337 77.2232 487.394 76.5474 487.306 75.8831C487.244 75.4171 487.156 75.1623 487.186 75.1551Z" fill="#263238"/> +<path d="M488.106 104.672C488.064 104.271 488.064 103.867 488.106 103.467C488.135 102.739 488.171 101.705 488.179 100.577C488.186 99.4484 488.179 98.4256 488.139 97.683C488.098 97.2825 488.098 96.8787 488.139 96.4782C488.249 96.8669 488.311 97.2681 488.321 97.6721C488.39 98.4001 488.444 99.4411 488.437 100.584C488.43 101.727 488.364 102.746 488.288 103.496C488.275 103.894 488.214 104.289 488.106 104.672Z" fill="#FAFAFA"/> +<path d="M487.12 104.872C487.069 104.475 487.058 104.074 487.087 103.674C487.087 102.834 487.105 101.854 487.116 100.803V97.916C487.089 97.5176 487.103 97.1174 487.16 96.7221C487.259 97.11 487.309 97.5085 487.309 97.9087C487.357 98.6367 487.397 99.6668 487.389 100.792C487.382 101.916 487.338 102.936 487.28 103.674C487.276 104.079 487.222 104.481 487.12 104.872Z" fill="#FAFAFA"/> +<path d="M506.226 153.335L509.83 163.265L514.948 170.294C515.034 170.414 515.094 170.551 515.125 170.696C515.157 170.841 515.158 170.99 515.13 171.136C515.102 171.281 515.044 171.419 514.961 171.542C514.878 171.664 514.77 171.768 514.646 171.848C514.499 171.939 514.334 171.994 514.162 172.008C513.991 172.023 513.818 171.996 513.659 171.932C511.595 171.076 504.024 167.888 503.798 167.149C503.54 166.29 498.651 155.61 498.651 155.61L506.226 153.335Z" fill="#1E8E7F"/> +<g opacity="0.6"> +<path opacity="0.6" d="M514.66 171.848L503.555 166.483L503.718 166.901C503.856 167.259 504.113 167.557 504.446 167.746C505.356 168.237 507.904 169.537 513.63 171.943C513.794 172.011 513.973 172.038 514.15 172.021C514.327 172.005 514.497 171.945 514.646 171.848H514.66Z" fill="white"/> +</g> +<g opacity="0.6"> +<path opacity="0.6" d="M504.326 162.522C504.482 162.564 504.616 162.661 504.704 162.795C504.792 162.929 504.827 163.092 504.803 163.25C504.767 163.409 504.672 163.548 504.536 163.637C504.4 163.727 504.235 163.76 504.075 163.731C503.91 163.687 503.766 163.583 503.673 163.439C503.58 163.295 503.545 163.121 503.573 162.952C503.628 162.793 503.742 162.66 503.892 162.583C504.042 162.506 504.216 162.489 504.377 162.537" fill="white"/> +</g> +<path d="M510.721 168.423C510.839 168.026 511.031 167.655 511.289 167.331C511.751 166.814 512.348 166.737 512.337 166.672C512.326 166.606 512.181 166.617 511.937 166.672C511.621 166.758 511.337 166.932 511.116 167.172C510.895 167.413 510.747 167.712 510.688 168.033C510.655 168.274 510.695 168.423 510.721 168.423Z" fill="#263238"/> +<path d="M511.938 169.467C512 169.493 512.193 169.049 512.644 168.703C512.938 168.519 513.243 168.353 513.558 168.208C513.558 168.146 513.012 168.121 512.502 168.521C511.993 168.921 511.876 169.46 511.938 169.467Z" fill="#263238"/> +<path d="M508.76 167.24C508.825 167.269 509.124 166.588 509.772 165.991C510.42 165.394 511.122 165.147 511.1 165.081C511.079 165.016 510.311 165.169 509.615 165.809C508.92 166.45 508.702 167.233 508.76 167.24Z" fill="#263238"/> +<path d="M507.412 164.313C507.459 164.364 507.914 163.924 508.613 163.622C509.312 163.32 509.938 163.258 509.935 163.203C509.931 163.148 509.265 163.079 508.519 163.411C507.772 163.742 507.379 164.281 507.412 164.313Z" fill="#263238"/> +<path d="M506.288 161.427C506.339 161.47 506.757 160.932 507.518 160.673C508.279 160.415 508.938 160.56 508.952 160.495C508.967 160.429 508.803 160.386 508.526 160.342C508.161 160.295 507.79 160.333 507.443 160.455C507.095 160.576 506.781 160.777 506.524 161.041C506.328 161.252 506.255 161.408 506.288 161.427Z" fill="#263238"/> +<path d="M507.282 160.131C507.262 160.002 507.216 159.878 507.147 159.767C506.982 159.439 506.753 159.147 506.474 158.908C506.285 158.711 506.037 158.583 505.768 158.544C505.678 158.54 505.589 158.564 505.514 158.612C505.438 158.66 505.38 158.73 505.345 158.813C505.283 158.975 505.283 159.154 505.345 159.316C505.495 159.644 505.755 159.908 506.081 160.063C506.407 160.217 506.777 160.252 507.125 160.16C507.464 160.067 507.768 159.875 507.998 159.608C508.227 159.342 508.372 159.013 508.414 158.664C508.424 158.576 508.415 158.487 508.388 158.403C508.361 158.319 508.317 158.242 508.257 158.176C508.19 158.117 508.105 158.08 508.016 158.071C507.927 158.062 507.837 158.081 507.759 158.125C507.538 158.273 507.359 158.476 507.242 158.715C507.062 159.033 506.939 159.381 506.878 159.741C506.847 159.873 506.847 160.01 506.878 160.142C506.987 159.671 507.166 159.22 507.409 158.802C507.52 158.6 507.679 158.428 507.871 158.3C507.913 158.274 507.963 158.262 508.012 158.267C508.062 158.271 508.108 158.292 508.144 158.325C508.18 158.371 508.207 158.423 508.222 158.478C508.237 158.534 508.24 158.592 508.232 158.649C508.186 158.949 508.055 159.23 507.854 159.458C507.653 159.685 507.392 159.851 507.1 159.934C506.808 160.009 506.5 159.982 506.226 159.857C505.952 159.733 505.728 159.519 505.593 159.25C505.538 159.137 505.528 159.007 505.564 158.886C505.582 158.84 505.614 158.801 505.656 158.774C505.698 158.747 505.747 158.734 505.797 158.737C506.022 158.77 506.232 158.872 506.397 159.028C506.754 159.341 507.054 159.714 507.282 160.131Z" fill="#263238"/> +<path d="M521.444 150.736L521.135 158.806C521.135 158.806 529.23 161.834 529.318 163.33L513.666 163.287L513.622 150.696L521.444 150.736Z" fill="#1E8E7F"/> +<g opacity="0.6"> +<path opacity="0.6" d="M516.29 158.114C516.14 158.16 516.012 158.259 515.93 158.394C515.848 158.528 515.818 158.688 515.846 158.842C515.886 158.997 515.984 159.13 516.12 159.213C516.256 159.297 516.419 159.324 516.574 159.29C516.734 159.241 516.87 159.135 516.956 158.992C517.042 158.848 517.072 158.679 517.04 158.515C516.981 158.361 516.865 158.235 516.716 158.164C516.567 158.093 516.396 158.081 516.239 158.132" fill="white"/> +</g> +<g opacity="0.6"> +<path opacity="0.6" d="M513.65 163.287V162.031L528.705 162.533C528.705 162.533 529.401 162.839 529.321 163.33L513.65 163.287Z" fill="white"/> +</g> +<path d="M521.387 158.726C521.387 158.802 521.005 158.839 520.627 159.09C520.248 159.341 520.048 159.658 519.979 159.625C519.909 159.592 520.022 159.152 520.485 158.864C520.947 158.577 521.406 158.657 521.387 158.726Z" fill="#263238"/> +<path d="M523.033 159.41C523.051 159.487 522.72 159.614 522.458 159.938C522.196 160.262 522.123 160.604 522.047 160.6C521.97 160.597 521.923 160.164 522.254 159.767C522.585 159.37 523.033 159.337 523.033 159.41Z" fill="#263238"/> +<path d="M523.956 161.379C523.886 161.379 523.781 161.015 523.981 160.597C524.181 160.178 524.534 160.011 524.567 160.076C524.6 160.142 524.378 160.364 524.203 160.71C524.028 161.055 524.032 161.372 523.956 161.379Z" fill="#263238"/> +<path d="M521.255 156.884C521.223 156.953 520.873 156.848 520.44 156.884C520.007 156.92 519.668 157.048 519.628 156.982C519.588 156.917 519.916 156.644 520.425 156.618C520.935 156.593 521.292 156.822 521.255 156.884Z" fill="#263238"/> +<g opacity="0.3"> +<path opacity="0.3" d="M521.383 152.334L521.328 153.772L513.629 153.681L513.622 152.385L521.383 152.334Z" fill="black"/> +</g> +<path d="M521.287 155.253C521.03 155.322 520.759 155.322 520.501 155.253C520.219 155.2 519.944 155.115 519.682 154.998C519.526 154.929 519.375 154.849 519.231 154.758C519.144 154.708 519.064 154.645 518.994 154.573C518.944 154.518 518.914 154.448 518.908 154.374C518.902 154.301 518.921 154.227 518.961 154.165C519 154.112 519.05 154.068 519.108 154.038C519.166 154.008 519.231 153.991 519.296 153.99C519.396 153.99 519.496 154.004 519.591 154.034C519.758 154.076 519.921 154.132 520.079 154.201C520.345 154.321 520.591 154.482 520.807 154.678C521.171 155.017 521.295 155.301 521.269 155.319C521.244 155.337 521.058 155.104 520.687 154.824C520.472 154.661 520.237 154.528 519.988 154.427C519.843 154.368 519.693 154.322 519.54 154.289C519.373 154.241 519.231 154.241 519.176 154.314C519.122 154.387 519.158 154.354 519.176 154.402C519.228 154.455 519.287 154.502 519.351 154.54C519.484 154.627 519.623 154.706 519.766 154.776C520.009 154.897 520.262 154.994 520.523 155.068C520.782 155.109 521.038 155.171 521.287 155.253Z" fill="#263238"/> +<path d="M521.186 155.362C521.042 155.136 520.971 154.87 520.983 154.602C520.971 154.311 521.008 154.021 521.092 153.743C521.144 153.579 521.211 153.421 521.292 153.269C521.336 153.167 521.405 153.078 521.493 153.01C521.581 152.942 521.684 152.897 521.794 152.88C521.864 152.881 521.932 152.902 521.99 152.941C522.048 152.98 522.094 153.034 522.122 153.098C522.161 153.191 522.188 153.289 522.202 153.39C522.229 153.564 522.229 153.743 522.202 153.917C522.157 154.21 522.04 154.488 521.863 154.725C521.558 155.13 521.237 155.221 521.23 155.195C521.223 155.17 521.474 155.009 521.707 154.62C521.843 154.399 521.929 154.15 521.958 153.892C521.98 153.741 521.98 153.588 521.958 153.437C521.936 153.273 521.874 153.138 521.812 153.153C521.751 153.168 521.601 153.277 521.536 153.411C521.458 153.546 521.393 153.688 521.339 153.834C521.251 154.086 521.2 154.349 521.186 154.616C521.15 155.064 521.23 155.348 521.186 155.362Z" fill="#263238"/> +<path d="M513.638 112.054C504.382 113.011 492.111 114.271 492.111 114.271L493.786 129.336C493.786 129.336 511.811 124.572 511.684 124.968C511.556 125.365 512.521 157.022 512.521 157.022H523.375L523.579 121.157C523.598 119.884 523.347 118.621 522.843 117.452C522.339 116.282 521.592 115.233 520.653 114.373C519.714 113.513 518.603 112.862 517.394 112.462C516.185 112.062 514.905 111.923 513.638 112.054Z" fill="#263238"/> +<path d="M469.965 118.133V122.803C469.965 125.984 473.587 129.355 476.764 129.355H479.225C481.161 129.355 484.197 127.942 485.777 126.807L486.716 126.119L498.022 161.139C498.022 161.139 510.955 158.82 510.955 158.413C510.955 158.005 502.197 129.73 498.153 116.607C496.5 111.249 490.76 108.133 485.457 109.95C485.278 110.012 485.093 110.081 484.914 110.154C479.105 112.476 469.965 118.133 469.965 118.133Z" fill="#263238"/> +<path d="M510.939 158.409C510.917 158.37 510.899 158.328 510.885 158.285C510.845 158.187 510.797 158.063 510.739 157.921C510.615 157.59 510.437 157.102 510.226 156.465C509.793 155.202 509.199 153.357 508.479 151.075C507.023 146.514 505.101 140.191 502.997 133.202C501.949 129.704 500.955 126.373 500.045 123.338C499.593 121.823 499.168 120.382 498.767 119.032C498.563 118.357 498.369 117.708 498.185 117.084C498.021 116.483 497.824 115.891 497.595 115.312C497.186 114.326 496.564 113.442 495.775 112.723C495.176 112.178 494.536 111.681 493.86 111.235C493.307 110.871 492.867 110.59 492.565 110.408L492.226 110.194C492.185 110.173 492.147 110.146 492.113 110.114C492.157 110.127 492.199 110.146 492.237 110.172L492.601 110.361C492.91 110.529 493.362 110.787 493.926 111.147C494.619 111.577 495.274 112.064 495.884 112.603C496.705 113.324 497.354 114.22 497.784 115.224C498.021 115.808 498.225 116.405 498.396 117.011C498.589 117.634 498.785 118.285 498.993 118.959L500.296 123.254C501.21 126.286 502.214 129.617 503.27 133.111C505.374 140.089 507.274 146.408 508.672 151.009L510.339 156.422L510.805 157.878C510.852 158.034 510.888 158.158 510.921 158.26C510.954 158.362 510.947 158.409 510.939 158.409Z" fill="#455A64"/> +<path d="M513.671 120.44C513.736 120.484 513.121 121.409 512.608 122.664C512.095 123.92 511.862 125.005 511.782 124.99C511.702 124.976 511.818 123.847 512.357 122.559C512.895 121.27 513.616 120.397 513.671 120.44Z" fill="#455A64"/> +<path d="M515.752 121.896C515.781 121.969 514.85 122.38 513.878 123.148C512.906 123.917 512.28 124.721 512.214 124.674C512.149 124.626 512.695 123.727 513.71 122.937C514.726 122.147 515.727 121.831 515.752 121.896Z" fill="#455A64"/> +<path d="M498.127 161.135C498.058 161.157 495.004 151.788 491.306 140.205C487.607 128.623 484.673 119.214 484.754 119.192C484.834 119.17 487.877 128.539 491.575 140.125C495.273 151.712 498.2 161.114 498.127 161.135Z" fill="#455A64"/> +<path d="M484.255 106.503L521.255 106.859L528.157 87.3563L501.243 87.5383L494.997 105.076L484.255 105.24V106.503Z" fill="#455A64"/> +<path d="M512.308 98.7896C512.015 98.7484 511.739 98.6211 511.518 98.4235C511.297 98.226 511.139 97.9672 511.064 97.6799C510.99 97.3926 511.003 97.0897 511.101 96.8096C511.198 96.5294 511.377 96.2846 511.614 96.1062C511.852 95.9277 512.136 95.8236 512.433 95.807C512.729 95.7905 513.023 95.8621 513.279 96.013C513.534 96.1639 513.739 96.3873 513.868 96.6547C513.996 96.9222 514.043 97.2218 514.001 97.5156C513.945 97.9088 513.735 98.2637 513.418 98.5026C513.101 98.7414 512.702 98.8446 512.308 98.7896Z" fill="white"/> +<path d="M481.234 53.7155C481.598 52.416 482.562 51.779 483.832 51.3458C484.472 51.133 485.154 51.0781 485.819 51.1859C486.485 51.2936 487.115 51.5608 487.654 51.9646C488.382 52.5106 488.928 53.3005 489.78 53.5953C491.178 54.0795 492.816 53.0348 494.148 53.6609C494.554 53.8453 494.881 54.1658 495.075 54.5667C495.269 54.9677 495.316 55.4237 495.209 55.8559C495.102 56.2881 494.847 56.6692 494.488 56.9331C494.13 57.197 493.69 57.3271 493.246 57.3009C494.156 57.6357 494.439 58.9352 493.908 59.7469C493.377 60.5587 492.281 60.8644 491.324 60.6861C490.375 60.4549 489.508 59.9691 488.816 59.281C488.088 58.6331 487.447 57.8978 486.675 57.3081C485.926 56.6744 484.977 56.3262 483.996 56.3253C482.682 56.3945 481.557 57.3846 480.971 58.5639C480.385 59.7433 480.243 61.0828 480.178 62.3969C480.112 63.7109 480.083 65.0431 479.694 66.2989C479.646 66.4482 479.577 66.612 479.432 66.6629C479.217 66.7285 479.035 66.5028 478.929 66.2989C477.733 64.0747 476.985 61.6371 476.727 59.1245C476.578 57.6685 476.614 56.2926 477.415 55.0659C478.216 53.8392 480.236 52.9401 481.226 53.7155" fill="#263238"/> +<path d="M478.698 59.8051L478.025 74.5326C477.912 77.0369 478.258 80.7424 482.225 80.7424C485.669 80.4803 486.684 77.2626 486.79 74.9184C486.837 73.8264 486.881 72.8873 486.896 72.7745C486.896 72.7745 490.659 72.5925 491.1 68.8942C491.311 67.107 491.464 63.3869 491.537 60.0235C491.58 58.2835 490.967 56.5908 489.821 55.2809C488.675 53.971 487.079 53.1394 485.349 52.951L484.985 52.9146C481.101 52.7362 478.775 55.9249 478.698 59.8051Z" fill="#FFBE9D"/> +<path d="M486.905 72.7272C485.192 72.578 483.562 71.9216 482.224 70.8417C482.224 70.8417 483.079 73.6263 486.81 73.6882L486.905 72.7272Z" fill="#EB996E"/> +<path d="M490.191 62.3969C490.178 62.5353 490.111 62.6632 490.005 62.753C489.899 62.8429 489.762 62.8875 489.623 62.8774C489.555 62.8755 489.489 62.8601 489.427 62.832C489.365 62.8039 489.31 62.7637 489.264 62.7138C489.218 62.6639 489.183 62.6053 489.16 62.5415C489.137 62.4777 489.128 62.4099 489.132 62.3423C489.145 62.2045 489.211 62.0772 489.316 61.9875C489.422 61.8977 489.558 61.8526 489.696 61.8618C489.764 61.8631 489.831 61.8782 489.893 61.9061C489.955 61.934 490.011 61.9741 490.057 62.0241C490.103 62.074 490.139 62.1328 490.162 62.1968C490.185 62.2609 490.195 62.3289 490.191 62.3969Z" fill="#263238"/> +<path d="M490.546 61.7635C490.474 61.8254 490.106 61.4869 489.534 61.4286C488.963 61.3704 488.519 61.6106 488.464 61.5342C488.41 61.4577 488.519 61.3813 488.715 61.2685C488.98 61.1242 489.282 61.0645 489.582 61.0974C489.878 61.1304 490.157 61.258 490.375 61.4614C490.535 61.607 490.583 61.738 490.546 61.7635Z" fill="#263238"/> +<path d="M484.591 61.9965C484.578 62.1349 484.511 62.2628 484.405 62.3526C484.299 62.4424 484.162 62.4871 484.023 62.4769C483.955 62.4746 483.889 62.4589 483.827 62.4306C483.765 62.4024 483.71 62.3623 483.664 62.3125C483.618 62.2628 483.582 62.2044 483.559 62.1408C483.535 62.0772 483.525 62.0096 483.528 61.9419C483.543 61.8041 483.61 61.6774 483.716 61.5879C483.821 61.4984 483.957 61.4531 484.096 61.4614C484.164 61.4632 484.23 61.4786 484.292 61.5067C484.354 61.5347 484.41 61.5749 484.456 61.6247C484.502 61.6746 484.538 61.7331 484.561 61.797C484.584 61.8608 484.594 61.9286 484.591 61.9965Z" fill="#263238"/> +<path d="M484.939 61.2758C484.866 61.3376 484.498 60.9991 483.927 60.9373C483.355 60.8754 482.911 61.1192 482.857 61.0428C482.802 60.9664 482.911 60.8936 483.108 60.7807C483.372 60.6354 483.675 60.5756 483.974 60.6096C484.271 60.6444 484.548 60.7718 484.768 60.9736C484.928 61.1156 484.975 61.2466 484.939 61.2758Z" fill="#263238"/> +<path d="M486.556 65.7165C486.866 65.6535 487.183 65.6303 487.498 65.6474C487.648 65.6474 487.786 65.6474 487.822 65.5382C487.849 65.3884 487.831 65.234 487.771 65.0941C487.67 64.7301 487.568 64.3443 487.458 63.9439C487.029 62.3059 486.73 60.9627 486.8 60.9445C486.869 60.9263 487.269 62.244 487.699 63.882C487.801 64.286 487.899 64.6719 487.99 65.0395C488.06 65.2261 488.06 65.4317 487.99 65.6183C487.964 65.6674 487.927 65.7101 487.883 65.7429C487.838 65.7757 487.786 65.7978 487.731 65.8075C487.648 65.8181 487.564 65.8181 487.48 65.8075C487.17 65.8143 486.859 65.7838 486.556 65.7165Z" fill="#263238"/> +<path d="M484.841 65.9313C484.932 65.9313 484.87 66.5537 485.351 67.0488C485.831 67.5438 486.497 67.5438 486.494 67.6312C486.49 67.7185 486.333 67.7367 486.053 67.7149C485.691 67.6798 485.352 67.5188 485.096 67.2599C484.851 67.0112 484.713 66.677 484.71 66.328C484.714 66.0696 484.812 65.924 484.841 65.9313Z" fill="#263238"/> +<path d="M485.326 59.059C485.253 59.2082 484.692 59.059 484.015 59.0845C483.338 59.11 482.781 59.2192 482.705 59.0845C482.676 59.0153 482.785 58.8806 483.018 58.7532C483.328 58.6001 483.669 58.5205 484.015 58.5205C484.361 58.5205 484.702 58.6001 485.013 58.7532C485.246 58.8552 485.358 58.9898 485.326 59.059Z" fill="#263238"/> +<path d="M490.512 60.0964C490.399 60.2129 490.021 60.0381 489.551 59.9799C489.082 59.9217 488.67 59.9799 488.594 59.8307C488.557 59.7615 488.634 59.6377 488.823 59.5322C489.072 59.4084 489.353 59.3639 489.628 59.4048C489.9 59.4413 490.154 59.5608 490.356 59.7469C490.523 59.8962 490.563 60.0381 490.512 60.0964Z" fill="#263238"/> +<path d="M478.707 62.5789C478.646 62.5461 476.243 61.556 476.054 64.0968C475.865 66.6375 478.456 66.3026 478.464 66.2298C478.471 66.157 478.707 62.5789 478.707 62.5789Z" fill="#FFBE9D"/> +<path d="M477.762 65.2105C477.762 65.2105 477.714 65.2397 477.638 65.2688C477.529 65.3039 477.411 65.2974 477.307 65.2506C477.15 65.1336 477.028 64.9774 476.951 64.7978C476.874 64.6182 476.846 64.4216 476.87 64.2278C476.88 64.0102 476.939 63.7976 477.041 63.6053C477.071 63.5269 477.12 63.4571 477.184 63.4019C477.247 63.3467 477.323 63.3078 477.405 63.2886C477.457 63.28 477.51 63.2893 477.556 63.3152C477.601 63.341 477.637 63.3818 477.656 63.4306C477.685 63.5034 477.656 63.5544 477.678 63.558C477.7 63.5616 477.736 63.5216 477.725 63.4124C477.715 63.3487 477.683 63.2905 477.634 63.2486C477.602 63.2193 477.564 63.1968 477.523 63.1825C477.481 63.1681 477.438 63.1621 477.394 63.1649C477.288 63.1788 477.187 63.2195 477.101 63.2832C477.015 63.3469 476.947 63.4315 476.903 63.5289C476.78 63.7409 476.71 63.9794 476.699 64.2241C476.677 64.7374 476.903 65.236 477.263 65.3707C477.33 65.395 477.401 65.404 477.471 65.3971C477.542 65.3902 477.61 65.3675 477.671 65.3307C477.751 65.2724 477.769 65.2142 477.762 65.2105Z" fill="#EB996E"/> +<path d="M492.403 59.3319C491.561 59.4541 490.701 59.3749 489.895 59.1009C489.089 58.827 488.359 58.366 487.766 57.7558C486.947 56.8968 486.368 55.7247 485.276 55.2551C484.902 55.1121 484.503 55.0446 484.102 55.0565C483.702 55.0684 483.308 55.1594 482.943 55.3243C482.213 55.6605 481.562 56.1438 481.028 56.7439C481.541 58.7022 480.839 60.7479 480.144 62.6516C480.087 62.8715 479.959 63.0663 479.78 63.2049C479.456 63.4051 479.026 63.1758 478.793 62.8737C478.459 62.3616 478.282 61.7632 478.283 61.1519C478.161 59.7664 478.317 58.3705 478.742 57.046C479.174 55.7196 479.984 54.5482 481.072 53.6754C482.483 52.6334 484.244 52.1817 485.982 52.4159C487.711 52.6517 489.321 53.4275 490.583 54.6327C491.194 55.1616 491.663 55.8348 491.948 56.591" fill="#263238"/> +<path d="M421.231 137.621C422.557 137 424.046 136.818 425.483 137.101C426.254 137.228 427.062 137.465 427.59 138.043C428.118 138.622 428.216 139.649 427.612 140.147C427.221 140.41 426.752 140.528 426.283 140.482C425.155 140.482 423.903 140.271 423.007 140.952C422.49 141.338 422.148 141.982 421.551 142.171C421.244 142.242 420.922 142.211 420.634 142.083C420.346 141.955 420.107 141.737 419.953 141.461C419.666 140.899 419.602 140.249 419.775 139.641C419.845 139.215 420.013 138.811 420.266 138.46C420.518 138.11 420.849 137.822 421.231 137.621Z" fill="#1E8E7F"/> +<path d="M418.257 131.881C419.05 133.013 420.594 132.638 421.307 131.946C422.02 131.255 422.326 130.254 422.599 129.296C423.229 127.112 423.862 124.819 423.396 122.595C423.282 121.921 422.985 121.292 422.537 120.775C422.311 120.52 422.022 120.329 421.699 120.221C421.375 120.113 421.029 120.092 420.695 120.16C419.92 120.368 419.436 121.128 419.087 121.853C418.057 123.992 417.517 126.333 417.507 128.707C417.507 129.799 417.634 130.971 418.257 131.881Z" fill="#1E8E7F"/> +<path d="M416.077 133.508C416.484 132.975 416.756 132.351 416.869 131.689C416.981 131.028 416.93 130.349 416.721 129.711C416.287 128.433 415.509 127.299 414.471 126.435C413.304 125.391 411.944 124.583 410.467 124.058C409.89 123.827 409.269 123.722 408.647 123.753C408.339 123.771 408.039 123.864 407.775 124.023C407.51 124.183 407.289 124.405 407.129 124.67C406.707 125.478 407.111 126.457 407.552 127.258C408.325 128.673 409.208 130.026 410.194 131.302C410.988 132.321 411.894 133.329 413.106 133.792C414.318 134.254 415.567 134.199 416.208 133.362" fill="#1E8E7F"/> +<path d="M418.202 148.974C418.245 148.806 418.269 148.634 418.275 148.461C418.311 148.097 418.358 147.617 418.413 147.056C418.482 146.364 418.586 145.677 418.726 144.996C418.911 144.166 419.162 143.351 419.476 142.561C419.786 141.778 420.206 141.043 420.721 140.377C421.137 139.822 421.674 139.368 422.289 139.048C422.704 138.839 423.151 138.7 423.611 138.637C423.784 138.629 423.956 138.603 424.124 138.56C423.951 138.543 423.777 138.543 423.603 138.56C423.125 138.596 422.658 138.72 422.224 138.924C421.577 139.227 421.01 139.677 420.568 140.238C420.036 140.919 419.606 141.675 419.294 142.481C418.98 143.283 418.736 144.111 418.566 144.956C418.432 145.645 418.339 146.341 418.289 147.041C418.245 147.638 418.231 148.133 418.22 148.457C418.195 148.629 418.189 148.802 418.202 148.974Z" fill="#263238"/> +<path d="M418.301 147.893C418.31 147.815 418.31 147.735 418.301 147.657C418.301 147.475 418.301 147.249 418.301 146.972C418.301 146.379 418.301 145.516 418.334 144.461C418.385 142.342 418.567 140.06 418.92 136.846C419.255 133.821 419.703 130.294 420.176 128.015C420.274 127.495 420.376 127.025 420.474 126.617C420.573 126.21 420.646 125.853 420.718 125.565C420.791 125.278 420.838 125.074 420.879 124.899C420.903 124.824 420.917 124.745 420.922 124.666C420.884 124.736 420.856 124.811 420.838 124.888C420.784 125.059 420.718 125.278 420.638 125.544C420.558 125.809 420.46 126.181 420.358 126.588C420.256 126.996 420.14 127.465 420.027 127.982C419.443 130.688 419.003 133.423 418.709 136.176C418.367 139.412 418.203 142.324 418.203 144.461C418.203 145.52 418.203 146.383 418.24 146.976C418.24 147.253 418.272 147.478 418.283 147.657C418.279 147.736 418.285 147.815 418.301 147.893Z" fill="#263238"/> +<path d="M418.315 142.237C418.334 141.994 418.334 141.751 418.315 141.509C418.275 140.86 418.202 140.214 418.096 139.572C417.941 138.627 417.733 137.691 417.474 136.769C417.166 135.63 416.772 134.515 416.294 133.435C415.475 131.445 414.303 129.62 412.833 128.048C412.575 127.779 412.302 127.527 412.014 127.291C411.886 127.185 411.777 127.083 411.65 127L411.333 126.781C411.143 126.637 410.943 126.508 410.732 126.395C411.425 126.94 412.082 127.527 412.702 128.154C414.124 129.738 415.266 131.553 416.076 133.522C416.544 134.595 416.941 135.698 417.263 136.824C417.572 137.861 417.776 138.811 417.932 139.612C418.089 140.413 418.165 141.068 418.216 141.53C418.229 141.768 418.262 142.004 418.315 142.237Z" fill="#263238"/> +<path d="M412.844 152.217L413.412 159.985H423.392L423.957 152.217H412.844Z" fill="#263238"/> +<path d="M425.147 149.156H411.879V152.217H425.147V149.156Z" fill="#263238"/> +<path d="M411.879 159.69V160.539H412.501H424.928V159.69H411.879Z" fill="#455A64"/> +<path d="M413.114 162.031L412.503 160.539H424.457L423.743 162.031H413.114Z" fill="#455A64"/> +<path d="M423.774 154.758C423.76 154.782 423.744 154.805 423.727 154.827L423.578 155.028L422.995 155.756L422.97 155.788L422.944 155.756L421.517 153.779H421.597L420.192 155.792L420.149 155.854L420.098 155.796C419.581 155.177 419.006 154.507 418.431 153.812H418.525C418.5 153.848 418.467 153.885 418.434 153.925L416.946 155.792L416.895 155.854L416.847 155.788L415.442 153.797H415.522L413.79 155.792L413.761 155.825L413.735 155.785C413.509 155.403 413.327 155.097 413.193 154.875L413.054 154.631L413.011 154.547C413.011 154.547 413.036 154.569 413.069 154.624L413.226 154.856L413.793 155.752H413.739L415.446 153.757L415.486 153.706L415.526 153.761L416.946 155.741H416.851L418.34 153.87L418.431 153.754L418.478 153.695L418.525 153.754L420.189 155.741H420.094L421.517 153.761L421.557 153.703L421.597 153.761L422.995 155.756H422.933L423.541 155.028L423.701 154.838C423.749 154.776 423.771 154.755 423.774 154.758Z" fill="#E0E0E0"/> +<path d="M424.099 152.152C424.099 152.188 421.598 152.214 418.511 152.214C415.425 152.214 412.928 152.188 412.928 152.152C412.928 152.116 415.428 152.09 418.511 152.09C421.595 152.09 424.099 152.152 424.099 152.152Z" fill="#455A64"/> +<path d="M424.601 160.622C424.601 160.655 421.882 160.684 418.533 160.684C415.185 160.684 412.462 160.655 412.462 160.622C412.462 160.59 415.181 160.56 418.533 160.56C421.886 160.56 424.601 160.59 424.601 160.622Z" fill="#263238"/> +<path d="M542.584 71.1838L535.649 100.184H537.59L544.418 71.1838H542.584Z" fill="#263238"/> +<path d="M539.919 90.272C539.795 90.8035 543.06 106.612 543.06 106.612H541.488L539.023 94.0831L539.919 90.272Z" fill="#263238"/> +<path d="M563.011 127.52H530.531V161.951H563.011V127.52Z" fill="#1E8E7F"/> +<path d="M564.601 132.551H563.007V134.145H564.601V132.551Z" fill="#263238"/> +<path d="M564.601 137.614H563.007V139.208H564.601V137.614Z" fill="#263238"/> +<path d="M564.601 142.677H563.007V144.271H564.601V142.677Z" fill="#263238"/> +<path d="M564.601 147.74H563.007V149.335H564.601V147.74Z" fill="#263238"/> +<path d="M564.663 143.143C564.822 143.092 564.986 143.057 565.151 143.037C565.603 142.953 566.061 142.91 566.52 142.906C567.213 142.89 567.897 143.071 568.493 143.427C568.863 143.65 569.163 143.974 569.356 144.36C569.549 144.747 569.629 145.181 569.585 145.611C569.55 146.055 569.407 146.483 569.17 146.859C568.949 147.205 568.665 147.507 568.333 147.748C567.769 148.147 567.117 148.405 566.432 148.497C565.978 148.564 565.518 148.58 565.06 148.545C564.892 148.541 564.725 148.518 564.562 148.476C564.727 148.462 564.894 148.462 565.06 148.476C565.513 148.483 565.965 148.447 566.411 148.37C567.068 148.263 567.691 148.004 568.231 147.613C568.558 147.381 568.832 147.081 569.034 146.734C569.236 146.386 569.36 146 569.399 145.6C569.441 145.203 569.369 144.801 569.192 144.443C569.015 144.085 568.739 143.784 568.398 143.576C567.832 143.229 567.18 143.046 566.516 143.045C566.064 143.035 565.611 143.058 565.162 143.114C564.997 143.141 564.83 143.15 564.663 143.143Z" fill="#263238"/> +<path d="M564.266 138.109C564.311 138.072 564.361 138.042 564.415 138.018C564.567 137.943 564.726 137.879 564.888 137.829C565.491 137.635 566.134 137.599 566.755 137.723C566.966 137.764 567.168 137.844 567.349 137.96C567.551 138.094 567.699 138.295 567.767 138.528C567.848 138.922 567.789 139.333 567.6 139.688C567.41 140.044 567.103 140.322 566.73 140.475C566.589 140.53 566.437 140.555 566.286 140.546C566.135 140.538 565.987 140.498 565.853 140.428C565.708 140.357 565.584 140.249 565.495 140.115C565.406 139.98 565.355 139.824 565.347 139.663C565.353 139.497 565.405 139.336 565.496 139.197C565.587 139.058 565.714 138.946 565.864 138.873C566.153 138.735 566.48 138.7 566.792 138.775C567.088 138.839 567.366 138.972 567.604 139.161C568.055 139.52 568.345 140.044 568.412 140.617C568.466 141.138 568.317 141.659 567.997 142.073C567.731 142.424 567.39 142.712 566.999 142.914C566.43 143.192 565.811 143.353 565.179 143.387C564.961 143.405 564.79 143.412 564.673 143.412C564.614 143.422 564.554 143.422 564.495 143.412C564.495 143.412 564.739 143.38 565.172 143.325C565.783 143.261 566.378 143.086 566.926 142.808C567.295 142.607 567.614 142.327 567.862 141.989C568.146 141.608 568.275 141.133 568.226 140.661C568.158 140.139 567.889 139.665 567.476 139.339C567.264 139.169 567.014 139.05 566.748 138.993C566.479 138.93 566.195 138.958 565.944 139.074C565.825 139.13 565.723 139.218 565.65 139.327C565.577 139.437 565.535 139.564 565.529 139.696C565.538 139.823 565.58 139.945 565.651 140.05C565.722 140.155 565.819 140.24 565.933 140.297C566.044 140.356 566.167 140.39 566.292 140.397C566.418 140.404 566.544 140.383 566.661 140.337C566.896 140.247 567.103 140.096 567.261 139.9C567.42 139.728 567.536 139.521 567.599 139.296C567.663 139.07 567.672 138.833 567.625 138.604C567.559 138.412 567.441 138.242 567.283 138.113C567.126 137.984 566.935 137.902 566.734 137.876C566.132 137.745 565.508 137.76 564.914 137.92C564.488 138.011 564.273 138.127 564.266 138.109Z" fill="#263238"/> +<path d="M564.28 133.169C564.395 133.122 564.52 133.099 564.644 133.104C564.974 133.08 565.306 133.121 565.62 133.224C566.09 133.383 566.509 133.666 566.832 134.043C567.228 134.512 567.45 135.104 567.462 135.717C567.486 136.331 567.301 136.934 566.937 137.428C566.635 137.827 566.23 138.135 565.765 138.32C565.46 138.448 565.132 138.514 564.801 138.517C564.678 138.529 564.553 138.514 564.437 138.473C564.872 138.459 565.301 138.367 565.704 138.2C566.131 138.006 566.501 137.705 566.777 137.326C567.104 136.858 567.272 136.298 567.254 135.727C567.237 135.157 567.037 134.607 566.683 134.16C566.382 133.801 565.995 133.524 565.558 133.355C565.147 133.216 564.714 133.153 564.28 133.169Z" fill="#263238"/> +<path d="M540.173 109.225C540.288 109.429 540.379 109.645 540.446 109.87C540.643 110.508 540.788 111.162 540.879 111.824C541.014 112.683 541.127 113.743 541.243 114.969C541.359 116.196 541.458 117.601 541.654 119.141C541.705 119.523 541.767 119.916 541.847 120.313C541.922 120.717 542.044 121.11 542.211 121.485C542.427 121.85 542.695 122.182 543.008 122.468C544.009 123.429 545.301 124.029 546.681 124.171C547.665 124.284 548.661 124.113 549.549 123.676C550.012 123.449 550.417 123.123 550.738 122.72C551.058 122.317 551.285 121.848 551.402 121.347C551.519 120.832 551.481 120.293 551.293 119.8C551.085 119.303 550.734 118.878 550.285 118.58C549.828 118.274 549.297 118.098 548.749 118.071C548.194 118.04 547.645 118.201 547.194 118.526C546.971 118.687 546.79 118.901 546.667 119.148C546.548 119.395 546.512 119.673 546.565 119.942C546.628 120.216 546.752 120.473 546.926 120.695C547.1 120.916 547.321 121.097 547.573 121.223C548.093 121.478 548.656 121.634 549.233 121.682C549.805 121.754 550.381 121.794 550.958 121.802C552.092 121.809 553.225 121.746 554.351 121.612C556.564 121.365 558.719 121.008 560.768 120.986C562.817 120.964 564.823 121.248 566.486 122.078C567.294 122.462 568.016 123.003 568.612 123.669C569.156 124.293 569.531 125.044 569.704 125.853C569.996 127.25 569.769 128.705 569.067 129.948C568.536 130.873 567.797 131.662 566.909 132.252C566.354 132.628 565.755 132.933 565.125 133.162C564.906 133.243 564.683 133.31 564.455 133.362L564.623 133.3C564.736 133.268 564.899 133.206 565.111 133.126C565.732 132.885 566.322 132.571 566.869 132.19C567.737 131.597 568.458 130.812 568.976 129.897C569.646 128.676 569.857 127.256 569.57 125.893C569.389 125.107 569.013 124.378 568.478 123.775C567.891 123.127 567.182 122.602 566.392 122.231C564.754 121.438 562.785 121.139 560.746 121.187C558.708 121.234 556.567 121.569 554.343 121.82C553.211 121.959 552.07 122.025 550.929 122.016C550.345 122.009 549.762 121.969 549.182 121.896C548.582 121.846 547.996 121.683 547.456 121.416C547.183 121.274 546.943 121.075 546.754 120.831C546.566 120.587 546.433 120.304 546.364 120.004C546.306 119.696 546.346 119.377 546.481 119.094C546.618 118.819 546.819 118.582 547.067 118.402C547.552 118.05 548.143 117.876 548.741 117.907C549.325 117.938 549.89 118.127 550.376 118.453C550.855 118.772 551.228 119.225 551.45 119.756C551.651 120.285 551.691 120.861 551.566 121.412C551.443 121.939 551.204 122.431 550.866 122.854C550.529 123.276 550.101 123.618 549.615 123.855C548.696 124.306 547.665 124.482 546.648 124.361C545.694 124.261 544.775 123.945 543.962 123.436C543.575 123.198 543.215 122.919 542.888 122.602C542.564 122.304 542.286 121.958 542.066 121.576C541.896 121.188 541.774 120.781 541.702 120.364C541.624 119.963 541.562 119.57 541.516 119.185C541.327 117.638 541.236 116.236 541.13 115.006C541.025 113.775 540.923 112.72 540.803 111.861C540.72 111.2 540.587 110.547 540.406 109.906C540.358 109.739 540.301 109.575 540.235 109.415C540.21 109.353 540.19 109.29 540.173 109.225Z" fill="#263238"/> +<path d="M561.16 160.524C561.16 160.524 561.16 160.473 561.16 160.371C561.16 160.269 561.16 160.124 561.16 159.934C561.16 159.541 561.16 158.97 561.16 158.227C561.16 156.731 561.16 154.547 561.139 151.777C561.139 146.233 561.113 138.335 561.095 128.885L561.179 128.969H531.822L531.917 128.874C531.917 140.522 531.917 151.377 531.917 160.513L531.837 160.433L553.109 160.473L559.075 160.495H560.651H561.197H560.669L559.067 160.524L553.123 160.546L531.797 160.586H531.713V160.524C531.713 151.388 531.713 140.504 531.713 128.885V128.79H531.811H561.168H561.251V128.856C561.233 138.32 561.219 146.244 561.208 151.788C561.208 154.554 561.208 156.731 561.186 158.22C561.186 158.948 561.186 159.523 561.186 159.912C561.186 160.098 561.186 160.24 561.186 160.342C561.186 160.444 561.16 160.524 561.16 160.524Z" fill="#263238"/> +<path d="M552.881 132.762C552.881 132.781 552.878 132.801 552.871 132.82C552.863 132.838 552.852 132.855 552.839 132.869C552.825 132.883 552.808 132.895 552.79 132.903C552.771 132.91 552.752 132.914 552.732 132.914C552.71 132.918 552.688 132.916 552.667 132.91C552.645 132.904 552.626 132.894 552.609 132.879C552.592 132.865 552.579 132.847 552.57 132.827C552.56 132.807 552.556 132.785 552.556 132.763C552.556 132.741 552.56 132.72 552.57 132.7C552.579 132.679 552.592 132.662 552.609 132.647C552.626 132.633 552.645 132.622 552.667 132.616C552.688 132.61 552.71 132.609 552.732 132.612C552.771 132.612 552.809 132.628 552.837 132.656C552.865 132.684 552.881 132.722 552.881 132.762Z" fill="#263238"/> +<path d="M553.72 132.762C553.72 132.781 553.717 132.801 553.709 132.82C553.702 132.838 553.691 132.855 553.677 132.869C553.663 132.883 553.647 132.895 553.629 132.903C553.61 132.91 553.591 132.914 553.571 132.914C553.549 132.918 553.527 132.916 553.505 132.91C553.484 132.904 553.465 132.894 553.448 132.879C553.431 132.865 553.418 132.847 553.409 132.827C553.399 132.807 553.395 132.785 553.395 132.763C553.395 132.741 553.399 132.72 553.409 132.7C553.418 132.679 553.431 132.662 553.448 132.647C553.465 132.633 553.484 132.622 553.505 132.616C553.527 132.61 553.549 132.609 553.571 132.612C553.61 132.612 553.648 132.628 553.676 132.656C553.704 132.684 553.72 132.722 553.72 132.762Z" fill="#263238"/> +<path d="M554.551 132.762C554.551 132.781 554.548 132.801 554.541 132.82C554.533 132.838 554.522 132.855 554.508 132.869C554.495 132.883 554.478 132.895 554.46 132.903C554.441 132.91 554.422 132.914 554.402 132.914C554.38 132.918 554.358 132.916 554.337 132.91C554.315 132.904 554.296 132.894 554.279 132.879C554.262 132.865 554.249 132.847 554.24 132.827C554.23 132.807 554.226 132.785 554.226 132.763C554.226 132.741 554.23 132.72 554.24 132.7C554.249 132.679 554.262 132.662 554.279 132.647C554.296 132.633 554.315 132.622 554.337 132.616C554.358 132.61 554.38 132.609 554.402 132.612C554.441 132.612 554.479 132.628 554.507 132.656C554.535 132.684 554.551 132.722 554.551 132.762Z" fill="#263238"/> +<path d="M555.379 132.762C555.38 132.792 555.372 132.822 555.356 132.847C555.339 132.873 555.316 132.893 555.288 132.905C555.26 132.917 555.229 132.921 555.199 132.915C555.169 132.91 555.142 132.896 555.12 132.874C555.099 132.853 555.084 132.826 555.077 132.796C555.071 132.767 555.074 132.736 555.085 132.708C555.097 132.679 555.116 132.655 555.142 132.638C555.167 132.622 555.196 132.612 555.227 132.612C555.267 132.612 555.305 132.628 555.334 132.656C555.362 132.684 555.379 132.722 555.379 132.762Z" fill="#263238"/> +<path d="M556.21 132.762C556.21 132.802 556.194 132.841 556.165 132.869C556.136 132.898 556.097 132.914 556.057 132.914C556.021 132.909 555.988 132.89 555.964 132.863C555.941 132.835 555.928 132.8 555.928 132.763C555.928 132.727 555.941 132.692 555.964 132.664C555.988 132.636 556.021 132.618 556.057 132.612C556.097 132.612 556.135 132.628 556.164 132.656C556.192 132.684 556.209 132.722 556.21 132.762Z" fill="#263238"/> +<path d="M557.04 132.762C557.04 132.802 557.024 132.841 556.995 132.869C556.966 132.898 556.927 132.914 556.887 132.914C556.851 132.909 556.818 132.89 556.795 132.863C556.771 132.835 556.758 132.8 556.758 132.763C556.758 132.727 556.771 132.692 556.795 132.664C556.818 132.636 556.851 132.618 556.887 132.612C556.927 132.612 556.965 132.628 556.994 132.656C557.022 132.684 557.039 132.722 557.04 132.762Z" fill="#263238"/> +<path d="M557.87 132.762C557.87 132.802 557.854 132.841 557.825 132.869C557.796 132.898 557.758 132.914 557.717 132.914C557.681 132.909 557.648 132.89 557.625 132.863C557.601 132.835 557.588 132.8 557.588 132.763C557.588 132.727 557.601 132.692 557.625 132.664C557.648 132.636 557.681 132.618 557.717 132.612C557.757 132.612 557.795 132.628 557.824 132.656C557.852 132.684 557.869 132.722 557.87 132.762Z" fill="#263238"/> +<path d="M557.336 133.471C557.418 133.471 557.485 133.404 557.485 133.322C557.485 133.24 557.418 133.173 557.336 133.173C557.253 133.173 557.187 133.24 557.187 133.322C557.187 133.404 557.253 133.471 557.336 133.471Z" fill="#263238"/> +<path d="M556.488 133.471C556.57 133.471 556.637 133.404 556.637 133.322C556.637 133.24 556.57 133.173 556.488 133.173C556.406 133.173 556.339 133.24 556.339 133.322C556.339 133.404 556.406 133.471 556.488 133.471Z" fill="#263238"/> +<path d="M555.792 133.322C555.792 133.342 555.788 133.361 555.781 133.379C555.773 133.397 555.762 133.414 555.748 133.427C555.734 133.441 555.718 133.452 555.7 133.46C555.682 133.467 555.662 133.471 555.643 133.471C555.623 133.472 555.603 133.468 555.585 133.461C555.566 133.454 555.549 133.443 555.535 133.429C555.521 133.415 555.51 133.398 555.502 133.38C555.494 133.362 555.49 133.342 555.49 133.322C555.49 133.302 555.494 133.282 555.502 133.264C555.51 133.245 555.521 133.228 555.535 133.214C555.549 133.2 555.566 133.189 555.584 133.181C555.603 133.173 555.623 133.169 555.643 133.169C555.663 133.169 555.682 133.173 555.701 133.181C555.719 133.189 555.736 133.2 555.75 133.214C555.763 133.229 555.774 133.245 555.782 133.264C555.789 133.282 555.792 133.302 555.792 133.322Z" fill="#263238"/> +<path d="M554.791 133.471C554.873 133.471 554.94 133.404 554.94 133.322C554.94 133.24 554.873 133.173 554.791 133.173C554.708 133.173 554.642 133.24 554.642 133.322C554.642 133.404 554.708 133.471 554.791 133.471Z" fill="#263238"/> +<path d="M553.939 133.471C554.021 133.471 554.088 133.404 554.088 133.322C554.088 133.24 554.021 133.173 553.939 133.173C553.857 133.173 553.79 133.24 553.79 133.322C553.79 133.404 553.857 133.471 553.939 133.471Z" fill="#263238"/> +<path d="M553.244 133.322C553.244 133.342 553.24 133.362 553.232 133.38C553.225 133.398 553.213 133.415 553.199 133.429C553.185 133.443 553.168 133.454 553.15 133.461C553.131 133.468 553.111 133.472 553.091 133.471C553.052 133.471 553.014 133.455 552.986 133.427C552.958 133.4 552.942 133.362 552.942 133.322C552.942 133.302 552.945 133.282 552.953 133.264C552.96 133.245 552.971 133.229 552.985 133.214C552.999 133.2 553.015 133.189 553.034 133.181C553.052 133.173 553.072 133.169 553.091 133.169C553.111 133.169 553.131 133.173 553.15 133.181C553.168 133.189 553.185 133.2 553.199 133.214C553.214 133.228 553.225 133.245 553.232 133.264C553.24 133.282 553.244 133.302 553.244 133.322Z" fill="#263238"/> +<path d="M552.879 133.952C552.879 133.991 552.863 134.029 552.835 134.057C552.807 134.085 552.769 134.101 552.73 134.101C552.71 134.101 552.69 134.098 552.672 134.091C552.653 134.083 552.636 134.072 552.622 134.059C552.608 134.045 552.597 134.028 552.589 134.01C552.581 133.991 552.577 133.972 552.577 133.952C552.577 133.911 552.593 133.872 552.622 133.844C552.65 133.815 552.689 133.799 552.73 133.799C552.75 133.799 552.769 133.803 552.788 133.811C552.806 133.819 552.823 133.83 552.836 133.844C552.85 133.858 552.861 133.875 552.869 133.894C552.876 133.912 552.879 133.932 552.879 133.952Z" fill="#263238"/> +<path d="M553.72 133.952C553.72 133.991 553.704 134.029 553.676 134.057C553.648 134.085 553.61 134.101 553.571 134.101C553.551 134.101 553.531 134.098 553.512 134.091C553.494 134.083 553.477 134.072 553.463 134.059C553.449 134.045 553.437 134.028 553.43 134.01C553.422 133.991 553.418 133.972 553.418 133.952C553.418 133.911 553.434 133.872 553.463 133.844C553.491 133.815 553.53 133.799 553.571 133.799C553.591 133.799 553.61 133.803 553.629 133.811C553.647 133.819 553.663 133.83 553.677 133.844C553.691 133.858 553.702 133.875 553.709 133.894C553.717 133.912 553.72 133.932 553.72 133.952Z" fill="#263238"/> +<path d="M554.551 133.952C554.551 133.991 554.535 134.029 554.507 134.057C554.479 134.085 554.441 134.101 554.402 134.101C554.382 134.101 554.362 134.098 554.344 134.091C554.325 134.083 554.308 134.072 554.294 134.059C554.28 134.045 554.268 134.028 554.261 134.01C554.253 133.991 554.249 133.972 554.249 133.952C554.249 133.932 554.253 133.912 554.261 133.893C554.268 133.875 554.28 133.858 554.294 133.844C554.308 133.83 554.325 133.818 554.343 133.811C554.362 133.803 554.382 133.799 554.402 133.799C554.422 133.799 554.441 133.803 554.46 133.811C554.478 133.819 554.495 133.83 554.508 133.844C554.522 133.858 554.533 133.875 554.54 133.894C554.548 133.912 554.551 133.932 554.551 133.952Z" fill="#263238"/> +<path d="M555.38 133.952C555.374 133.988 555.356 134.021 555.328 134.044C555.3 134.068 555.265 134.081 555.229 134.081C555.192 134.081 555.157 134.068 555.13 134.044C555.102 134.021 555.084 133.988 555.078 133.952C555.075 133.93 555.076 133.908 555.082 133.887C555.088 133.865 555.099 133.846 555.113 133.829C555.127 133.812 555.145 133.799 555.165 133.79C555.185 133.78 555.207 133.776 555.229 133.776C555.251 133.776 555.273 133.78 555.293 133.79C555.313 133.799 555.33 133.812 555.345 133.829C555.359 133.846 555.37 133.865 555.376 133.887C555.382 133.908 555.383 133.93 555.38 133.952Z" fill="#263238"/> +<path d="M556.211 133.952C556.211 133.972 556.207 133.991 556.199 134.01C556.192 134.028 556.18 134.045 556.166 134.059C556.152 134.072 556.135 134.083 556.116 134.091C556.098 134.098 556.078 134.101 556.058 134.101C556.019 134.101 555.981 134.085 555.953 134.057C555.925 134.029 555.909 133.991 555.909 133.952C555.909 133.932 555.912 133.912 555.92 133.894C555.927 133.875 555.938 133.858 555.952 133.844C555.965 133.83 555.982 133.819 556 133.811C556.019 133.803 556.038 133.799 556.058 133.799C556.099 133.799 556.138 133.815 556.166 133.844C556.195 133.872 556.211 133.911 556.211 133.952Z" fill="#263238"/> +<path d="M557.04 133.952C557.04 133.972 557.036 133.991 557.028 134.01C557.021 134.028 557.009 134.045 556.995 134.059C556.981 134.072 556.964 134.083 556.946 134.091C556.927 134.098 556.907 134.101 556.887 134.101C556.848 134.101 556.81 134.085 556.782 134.057C556.754 134.029 556.738 133.991 556.738 133.952C556.738 133.932 556.741 133.912 556.749 133.894C556.756 133.875 556.767 133.858 556.781 133.844C556.795 133.83 556.811 133.819 556.829 133.811C556.848 133.803 556.867 133.799 556.887 133.799C556.928 133.799 556.967 133.815 556.995 133.844C557.024 133.872 557.04 133.911 557.04 133.952Z" fill="#263238"/> +<path d="M557.87 133.952C557.87 133.972 557.866 133.991 557.858 134.01C557.851 134.028 557.839 134.045 557.825 134.059C557.811 134.072 557.794 134.083 557.776 134.091C557.757 134.098 557.737 134.101 557.717 134.101C557.698 134.101 557.678 134.097 557.66 134.089C557.642 134.082 557.626 134.071 557.612 134.057C557.598 134.043 557.587 134.027 557.58 134.009C557.572 133.991 557.568 133.971 557.568 133.952C557.568 133.932 557.571 133.912 557.579 133.894C557.586 133.875 557.597 133.858 557.611 133.844C557.625 133.83 557.641 133.819 557.66 133.811C557.678 133.803 557.698 133.799 557.717 133.799C557.758 133.799 557.797 133.815 557.825 133.844C557.854 133.872 557.87 133.911 557.87 133.952Z" fill="#263238"/> +<path d="M557.488 134.509C557.488 134.549 557.472 134.588 557.444 134.617C557.415 134.645 557.376 134.661 557.336 134.661C557.316 134.661 557.296 134.657 557.278 134.65C557.259 134.642 557.243 134.631 557.229 134.616C557.215 134.602 557.204 134.585 557.197 134.567C557.19 134.548 557.186 134.529 557.187 134.509C557.187 134.469 557.202 134.431 557.23 134.403C557.258 134.375 557.296 134.36 557.336 134.36C557.355 134.359 557.375 134.363 557.394 134.37C557.412 134.377 557.429 134.388 557.443 134.402C557.458 134.416 557.469 134.433 557.477 134.451C557.484 134.469 557.488 134.489 557.488 134.509Z" fill="#263238"/> +<path d="M556.637 134.509C556.637 134.529 556.634 134.548 556.626 134.567C556.619 134.585 556.608 134.602 556.594 134.616C556.58 134.631 556.564 134.642 556.546 134.65C556.527 134.657 556.508 134.661 556.488 134.661C556.447 134.661 556.408 134.645 556.38 134.617C556.351 134.588 556.335 134.549 556.335 134.509C556.335 134.489 556.339 134.469 556.347 134.451C556.354 134.433 556.366 134.416 556.38 134.402C556.394 134.388 556.411 134.377 556.429 134.37C556.448 134.363 556.468 134.359 556.488 134.36C556.527 134.36 556.565 134.375 556.593 134.403C556.621 134.431 556.637 134.469 556.637 134.509Z" fill="#263238"/> +<path d="M555.792 134.509C555.792 134.529 555.789 134.548 555.782 134.567C555.774 134.585 555.763 134.602 555.75 134.616C555.736 134.631 555.719 134.642 555.701 134.65C555.682 134.657 555.663 134.661 555.643 134.661C555.623 134.661 555.603 134.657 555.584 134.65C555.566 134.642 555.549 134.631 555.535 134.617C555.521 134.603 555.51 134.586 555.502 134.567C555.494 134.549 555.49 134.529 555.49 134.509C555.49 134.489 555.494 134.469 555.502 134.451C555.51 134.433 555.521 134.416 555.535 134.402C555.549 134.388 555.566 134.377 555.585 134.37C555.603 134.363 555.623 134.359 555.643 134.36C555.662 134.36 555.682 134.364 555.7 134.371C555.718 134.379 555.734 134.39 555.748 134.403C555.762 134.417 555.773 134.434 555.781 134.452C555.788 134.47 555.792 134.489 555.792 134.509Z" fill="#263238"/> +<path d="M554.939 134.509C554.94 134.529 554.936 134.548 554.929 134.567C554.922 134.585 554.911 134.602 554.897 134.616C554.883 134.631 554.867 134.642 554.848 134.65C554.83 134.657 554.81 134.661 554.79 134.661C554.75 134.661 554.711 134.645 554.682 134.617C554.654 134.588 554.638 134.549 554.638 134.509C554.638 134.489 554.642 134.469 554.649 134.451C554.657 134.433 554.668 134.416 554.683 134.402C554.697 134.388 554.714 134.377 554.732 134.37C554.751 134.363 554.77 134.359 554.79 134.36C554.83 134.36 554.868 134.375 554.896 134.403C554.924 134.431 554.939 134.469 554.939 134.509Z" fill="#263238"/> +<path d="M554.092 134.509C554.095 134.531 554.094 134.553 554.088 134.574C554.082 134.595 554.071 134.615 554.057 134.632C554.042 134.648 554.025 134.662 554.005 134.671C553.985 134.68 553.963 134.685 553.941 134.685C553.919 134.685 553.897 134.68 553.877 134.671C553.857 134.662 553.839 134.648 553.825 134.632C553.81 134.615 553.8 134.595 553.794 134.574C553.788 134.553 553.787 134.531 553.79 134.509C553.796 134.473 553.814 134.44 553.841 134.416C553.869 134.393 553.904 134.38 553.941 134.38C553.977 134.38 554.012 134.393 554.04 134.416C554.068 134.44 554.086 134.473 554.092 134.509Z" fill="#263238"/> +<path d="M553.244 134.509C553.244 134.549 553.228 134.588 553.199 134.617C553.171 134.645 553.132 134.661 553.091 134.661C553.072 134.661 553.052 134.657 553.034 134.65C553.015 134.642 552.999 134.631 552.985 134.616C552.971 134.602 552.96 134.585 552.953 134.567C552.945 134.548 552.942 134.529 552.942 134.509C552.942 134.469 552.958 134.431 552.986 134.403C553.014 134.375 553.052 134.36 553.091 134.36C553.111 134.359 553.131 134.363 553.15 134.37C553.168 134.377 553.185 134.388 553.199 134.402C553.213 134.416 553.225 134.433 553.232 134.451C553.24 134.469 553.244 134.489 553.244 134.509Z" fill="#263238"/> +<path d="M552.879 135.138C552.879 135.158 552.876 135.178 552.869 135.197C552.861 135.215 552.85 135.232 552.836 135.246C552.823 135.26 552.806 135.272 552.788 135.279C552.769 135.287 552.75 135.291 552.73 135.291C552.689 135.291 552.65 135.275 552.622 135.246C552.593 135.218 552.577 135.179 552.577 135.138C552.577 135.119 552.581 135.099 552.589 135.081C552.597 135.062 552.608 135.046 552.622 135.032C552.636 135.018 552.653 135.007 552.672 135C552.69 134.992 552.71 134.989 552.73 134.989C552.769 134.989 552.807 135.005 552.835 135.033C552.863 135.061 552.879 135.099 552.879 135.138Z" fill="#263238"/> +<path d="M553.72 135.138C553.72 135.158 553.717 135.178 553.709 135.197C553.702 135.215 553.691 135.232 553.677 135.246C553.663 135.26 553.647 135.272 553.629 135.279C553.61 135.287 553.591 135.291 553.571 135.291C553.53 135.291 553.491 135.275 553.463 135.246C553.434 135.218 553.418 135.179 553.418 135.138C553.418 135.119 553.422 135.099 553.43 135.081C553.437 135.062 553.449 135.046 553.463 135.032C553.477 135.018 553.494 135.007 553.512 135C553.531 134.992 553.551 134.989 553.571 134.989C553.61 134.989 553.648 135.005 553.676 135.033C553.704 135.061 553.72 135.099 553.72 135.138Z" fill="#263238"/> +<path d="M554.551 135.138C554.551 135.158 554.548 135.178 554.54 135.197C554.533 135.215 554.522 135.232 554.508 135.246C554.495 135.26 554.478 135.272 554.46 135.279C554.441 135.287 554.422 135.291 554.402 135.291C554.382 135.291 554.362 135.287 554.343 135.28C554.325 135.272 554.308 135.261 554.294 135.246C554.28 135.232 554.268 135.215 554.261 135.197C554.253 135.178 554.249 135.159 554.249 135.138C554.249 135.119 554.253 135.099 554.261 135.081C554.268 135.062 554.28 135.046 554.294 135.032C554.308 135.018 554.325 135.007 554.344 135C554.362 134.992 554.382 134.989 554.402 134.989C554.441 134.989 554.479 135.005 554.507 135.033C554.535 135.061 554.551 135.099 554.551 135.138Z" fill="#263238"/> +<path d="M555.38 135.138C555.383 135.16 555.382 135.182 555.376 135.204C555.37 135.225 555.359 135.245 555.345 135.261C555.33 135.278 555.313 135.291 555.293 135.301C555.273 135.31 555.251 135.315 555.229 135.315C555.207 135.315 555.185 135.31 555.165 135.301C555.145 135.291 555.127 135.278 555.113 135.261C555.099 135.245 555.088 135.225 555.082 135.204C555.076 135.182 555.075 135.16 555.078 135.138C555.084 135.102 555.102 135.07 555.13 135.046C555.157 135.022 555.192 135.009 555.229 135.009C555.265 135.009 555.3 135.022 555.328 135.046C555.356 135.07 555.374 135.102 555.38 135.138Z" fill="#263238"/> +<path d="M556.211 135.138C556.211 135.179 556.195 135.218 556.166 135.246C556.138 135.275 556.099 135.291 556.058 135.291C556.038 135.291 556.019 135.287 556 135.279C555.982 135.272 555.965 135.26 555.952 135.246C555.938 135.232 555.927 135.215 555.92 135.197C555.912 135.178 555.909 135.158 555.909 135.138C555.909 135.099 555.925 135.061 555.953 135.033C555.981 135.005 556.019 134.989 556.058 134.989C556.078 134.989 556.098 134.992 556.116 135C556.135 135.007 556.152 135.018 556.166 135.032C556.18 135.046 556.192 135.062 556.199 135.081C556.207 135.099 556.211 135.119 556.211 135.138Z" fill="#263238"/> +<path d="M557.04 135.138C557.04 135.179 557.024 135.218 556.995 135.246C556.967 135.275 556.928 135.291 556.887 135.291C556.867 135.291 556.848 135.287 556.829 135.279C556.811 135.272 556.795 135.26 556.781 135.246C556.767 135.232 556.756 135.215 556.749 135.197C556.741 135.178 556.738 135.158 556.738 135.138C556.738 135.099 556.754 135.061 556.782 135.033C556.81 135.005 556.848 134.989 556.887 134.989C556.907 134.989 556.927 134.992 556.946 135C556.964 135.007 556.981 135.018 556.995 135.032C557.009 135.046 557.021 135.062 557.028 135.081C557.036 135.099 557.04 135.119 557.04 135.138Z" fill="#263238"/> +<path d="M557.87 135.138C557.87 135.179 557.854 135.218 557.825 135.246C557.797 135.275 557.758 135.291 557.717 135.291C557.698 135.291 557.678 135.287 557.66 135.279C557.641 135.272 557.625 135.26 557.611 135.246C557.597 135.232 557.586 135.215 557.579 135.197C557.571 135.178 557.568 135.158 557.568 135.138C557.568 135.119 557.572 135.1 557.58 135.081C557.587 135.063 557.598 135.047 557.612 135.033C557.626 135.019 557.642 135.008 557.66 135.001C557.678 134.993 557.698 134.989 557.717 134.989C557.737 134.989 557.757 134.992 557.776 135C557.794 135.007 557.811 135.018 557.825 135.032C557.839 135.046 557.851 135.062 557.858 135.081C557.866 135.099 557.87 135.119 557.87 135.138Z" fill="#263238"/> +<path d="M557.336 135.848C557.418 135.848 557.485 135.781 557.485 135.699C557.485 135.617 557.418 135.55 557.336 135.55C557.253 135.55 557.187 135.617 557.187 135.699C557.187 135.781 557.253 135.848 557.336 135.848Z" fill="#263238"/> +<path d="M556.488 135.848C556.57 135.848 556.637 135.781 556.637 135.699C556.637 135.617 556.57 135.55 556.488 135.55C556.406 135.55 556.339 135.617 556.339 135.699C556.339 135.781 556.406 135.848 556.488 135.848Z" fill="#263238"/> +<path d="M555.792 135.699C555.792 135.719 555.788 135.738 555.781 135.756C555.773 135.774 555.762 135.791 555.748 135.804C555.735 135.818 555.718 135.829 555.7 135.837C555.682 135.844 555.663 135.848 555.643 135.848C555.621 135.851 555.599 135.85 555.578 135.844C555.557 135.838 555.537 135.827 555.52 135.813C555.503 135.799 555.49 135.781 555.481 135.761C555.472 135.741 555.467 135.719 555.467 135.697C555.467 135.675 555.472 135.653 555.481 135.633C555.49 135.613 555.503 135.596 555.52 135.581C555.537 135.567 555.557 135.556 555.578 135.55C555.599 135.544 555.621 135.543 555.643 135.546C555.663 135.546 555.683 135.55 555.701 135.558C555.719 135.566 555.736 135.577 555.75 135.591C555.764 135.605 555.774 135.622 555.782 135.641C555.789 135.659 555.792 135.679 555.792 135.699Z" fill="#263238"/> +<path d="M554.791 135.848C554.873 135.848 554.94 135.781 554.94 135.699C554.94 135.617 554.873 135.55 554.791 135.55C554.708 135.55 554.642 135.617 554.642 135.699C554.642 135.781 554.708 135.848 554.791 135.848Z" fill="#263238"/> +<path d="M553.939 135.848C554.021 135.848 554.088 135.781 554.088 135.699C554.088 135.617 554.021 135.55 553.939 135.55C553.857 135.55 553.79 135.617 553.79 135.699C553.79 135.781 553.857 135.848 553.939 135.848Z" fill="#263238"/> +<path d="M553.243 135.699C553.242 135.739 553.225 135.777 553.197 135.805C553.168 135.832 553.13 135.848 553.09 135.848C553.054 135.842 553.021 135.824 552.998 135.796C552.974 135.769 552.961 135.734 552.961 135.697C552.961 135.661 552.974 135.626 552.998 135.598C553.021 135.57 553.054 135.552 553.09 135.546C553.131 135.546 553.169 135.562 553.198 135.591C553.227 135.62 553.243 135.658 553.243 135.699Z" fill="#263238"/> +<path d="M541.414 98.7496C541.615 98.7534 541.814 98.789 542.004 98.8551C542.556 99.0357 543.05 99.3583 543.438 99.7906C544.033 100.488 544.466 101.309 544.708 102.193C545.063 103.344 545.329 104.521 545.505 105.713C545.914 108.82 545.992 111.962 545.738 115.086C545.689 116.007 545.408 116.901 544.923 117.685C544.656 118.086 544.306 118.425 543.896 118.679C543.473 118.942 542.974 119.061 542.477 119.017C541.967 118.97 541.49 118.748 541.126 118.387C540.944 118.202 540.808 117.976 540.73 117.729C540.655 117.473 540.655 117.201 540.73 116.946C540.796 116.688 540.922 116.449 541.099 116.25C541.276 116.051 541.497 115.896 541.745 115.799C542.005 115.707 542.29 115.707 542.55 115.799C542.805 115.896 543.027 116.064 543.19 116.283C543.349 116.497 543.463 116.741 543.525 117C543.588 117.259 543.598 117.528 543.554 117.79C543.47 118.297 543.291 118.784 543.027 119.225C542.314 120.491 541.133 121.427 539.738 121.831C538.342 122.236 536.844 122.076 535.565 121.387C534.8 120.964 534.13 120.388 533.599 119.694C533.092 119.05 532.684 118.335 532.387 117.572C531.898 116.191 531.629 114.741 531.59 113.277C531.52 111.941 531.59 110.729 531.462 109.68C531.406 109.196 531.293 108.719 531.124 108.261C530.976 107.878 530.771 107.519 530.516 107.198C530.167 106.744 529.698 106.398 529.162 106.197C528.972 106.138 528.779 106.092 528.583 106.059C528.785 106.063 528.985 106.098 529.176 106.164C529.727 106.35 530.212 106.693 530.57 107.151C530.839 107.479 531.054 107.847 531.207 108.243C531.388 108.711 531.51 109.2 531.571 109.699C531.713 110.758 531.648 111.97 531.728 113.299C531.777 114.748 532.051 116.181 532.54 117.547C532.827 118.297 533.223 119.001 533.715 119.636C534.235 120.309 534.888 120.868 535.634 121.278C536.872 121.94 538.322 122.092 539.67 121.698C541.019 121.305 542.16 120.398 542.848 119.174C543.1 118.754 543.27 118.291 543.35 117.809C543.393 117.571 543.386 117.327 543.332 117.092C543.278 116.857 543.176 116.635 543.034 116.44C542.89 116.251 542.698 116.105 542.477 116.018C542.258 115.939 542.019 115.939 541.8 116.018C541.581 116.104 541.386 116.242 541.23 116.418C541.075 116.595 540.963 116.805 540.904 117.033C540.848 117.257 540.852 117.492 540.916 117.714C540.98 117.936 541.102 118.137 541.268 118.296C541.6 118.626 542.037 118.829 542.502 118.871C542.96 118.913 543.419 118.805 543.809 118.562C544.197 118.323 544.529 118.003 544.781 117.623C545.251 116.864 545.522 115.999 545.571 115.108C545.831 111.997 545.768 108.868 545.382 105.771C545.212 104.585 544.955 103.414 544.614 102.266C544.384 101.392 543.966 100.578 543.391 99.8816C543.016 99.4507 542.537 99.1235 542 98.9316C541.809 98.8574 541.613 98.7966 541.414 98.7496Z" fill="#E0E0E0"/> +<path d="M538.556 104.017H526.464V106.321H538.556V104.017Z" fill="#E0E0E0"/> +<path d="M451.268 127.837H435.496V161.787H451.268V127.837Z" fill="#263238"/> +<path d="M449.914 158.213C449.914 158.213 449.914 158.162 449.914 158.063C449.914 157.965 449.914 157.823 449.914 157.641C449.914 157.277 449.914 156.72 449.914 156.018C449.914 154.598 449.914 152.541 449.889 149.953C449.889 144.777 449.863 137.49 449.845 129.013L449.936 129.1H436.741L436.836 129.005C436.836 140.347 436.836 150.649 436.81 158.205L436.741 158.136L446.376 158.173L449.012 158.191H449.7C449.856 158.191 449.94 158.191 449.94 158.191H449.714H449.037H446.42L436.741 158.227H436.676V158.158C436.676 150.601 436.676 140.3 436.646 128.958V128.863H450.031V128.954C450.031 137.457 449.998 144.766 449.987 149.957C449.987 152.534 449.987 154.587 449.962 155.999C449.962 156.695 449.962 157.233 449.962 157.605C449.962 157.783 449.962 157.918 449.962 158.016C449.962 158.114 449.914 158.213 449.914 158.213Z" fill="#455A64"/> +<path d="M449.1 131.484C449.1 131.484 449.1 131.357 449.1 131.12C449.1 130.884 449.1 130.552 449.078 130.137L449.118 130.177C447.076 130.21 442.701 130.232 437.645 130.232L437.739 130.137V130.814C437.739 131.036 437.739 131.258 437.739 131.473L437.648 131.379C440.855 131.379 443.709 131.4 445.773 131.419L448.215 131.444H448.881C448.961 131.436 449.042 131.436 449.122 131.444C449.05 131.449 448.978 131.449 448.907 131.444H448.259L445.842 131.47C443.782 131.491 440.895 131.51 437.648 131.51H437.554V130.079L437.652 129.984C442.708 129.984 447.083 130.006 449.125 130.039H449.14V130.079C449.14 130.505 449.14 130.84 449.118 131.087C449.12 131.22 449.114 131.352 449.1 131.484Z" fill="#455A64"/> +<path d="M438.78 132.445C438.78 132.496 438.543 132.54 438.252 132.54C437.961 132.54 437.721 132.496 437.721 132.445C437.721 132.394 437.957 132.35 438.252 132.35C438.547 132.35 438.78 132.39 438.78 132.445Z" fill="#455A64"/> +<path d="M448.795 134.196C448.795 134.247 446.353 134.29 443.335 134.29C440.317 134.29 437.875 134.247 437.875 134.196C437.875 134.145 440.314 134.101 443.335 134.101C446.356 134.101 448.795 134.145 448.795 134.196Z" fill="#455A64"/> +<path d="M448.842 136.311C448.842 136.365 446.439 136.405 443.48 136.405C440.521 136.405 438.118 136.365 438.118 136.311C438.118 136.256 440.517 136.216 443.48 136.216C446.443 136.216 448.842 136.26 448.842 136.311Z" fill="#455A64"/> +<path d="M443.338 142.124C443.816 142.124 444.204 141.736 444.204 141.257C444.204 140.779 443.816 140.391 443.338 140.391C442.86 140.391 442.472 140.779 442.472 141.257C442.472 141.736 442.86 142.124 443.338 142.124Z" fill="#1E8E7F"/> +<path d="M440.893 141.232C440.513 141.325 440.121 141.357 439.732 141.327C439.347 141.356 438.96 141.324 438.585 141.232C438.963 141.137 439.354 141.105 439.742 141.137C440.128 141.106 440.517 141.138 440.893 141.232Z" fill="#455A64"/> +<path d="M447.939 140.992C447.583 141.085 447.214 141.117 446.847 141.086C446.48 141.117 446.111 141.085 445.755 140.992C446.111 140.9 446.48 140.868 446.847 140.897C447.214 140.869 447.583 140.901 447.939 140.992Z" fill="#455A64"/> +<path d="M436.036 144.872C435.837 144.853 435.639 144.817 435.447 144.763C434.889 144.609 434.361 144.363 433.885 144.035C433.13 143.517 432.489 142.849 432.003 142.073C431.371 141.042 430.908 139.916 430.631 138.739C430.259 137.323 430.117 135.857 430.212 134.396C430.305 132.7 430.879 131.066 431.868 129.686C432.406 128.943 433.076 128.307 433.845 127.808C434.246 127.555 434.671 127.344 435.115 127.178C435.571 127.019 436.042 126.906 436.52 126.843C437.481 126.708 438.464 126.727 439.432 126.668C440.427 126.648 441.407 126.422 442.312 126.006C442.756 125.801 443.148 125.498 443.458 125.12C443.768 124.742 443.989 124.298 444.102 123.822C444.206 123.367 444.205 122.894 444.098 122.439C443.991 121.984 443.782 121.56 443.486 121.198C443.191 120.837 442.816 120.547 442.392 120.352C441.968 120.157 441.504 120.062 441.038 120.073C440.596 120.097 440.172 120.254 439.822 120.524C439.656 120.652 439.523 120.819 439.435 121.008C439.346 121.198 439.304 121.407 439.312 121.616C439.357 122.026 439.544 122.407 439.84 122.694C440.137 122.981 440.524 123.154 440.936 123.185C441.33 123.192 441.721 123.112 442.081 122.95C442.441 122.789 442.761 122.549 443.018 122.249C443.505 121.674 443.856 120.996 444.044 120.266C444.225 119.594 444.365 118.912 444.463 118.224C444.724 116.134 444.789 114.024 444.656 111.923C444.619 111.195 444.59 110.609 444.568 110.208C444.568 110.019 444.561 109.87 444.547 109.761C444.542 109.71 444.542 109.659 444.547 109.608C444.559 109.658 444.566 109.709 444.568 109.761C444.568 109.87 444.59 110.015 444.608 110.205C444.638 110.598 444.685 111.173 444.729 111.919C444.892 114.026 444.847 116.144 444.594 118.242C444.5 118.938 444.362 119.627 444.183 120.306C443.996 121.055 443.644 121.753 443.152 122.348C442.881 122.667 442.542 122.922 442.16 123.093C441.777 123.265 441.362 123.35 440.943 123.341C440.49 123.31 440.062 123.12 439.735 122.805C439.408 122.489 439.203 122.068 439.156 121.616C439.146 121.378 439.192 121.141 439.291 120.925C439.391 120.708 439.54 120.519 439.727 120.371C440.104 120.076 440.563 119.904 441.041 119.88C441.663 119.873 442.273 120.044 442.801 120.371C443.329 120.699 443.754 121.17 444.024 121.729C444.295 122.289 444.401 122.914 444.329 123.531C444.258 124.148 444.013 124.733 443.622 125.216C443.286 125.614 442.871 125.938 442.403 126.166C441.475 126.595 440.469 126.828 439.447 126.85C438.453 126.909 437.474 126.89 436.535 127.018C436.069 127.08 435.611 127.189 435.166 127.342C434.734 127.501 434.321 127.706 433.932 127.953C433.181 128.437 432.525 129.054 431.996 129.773C431.024 131.126 430.456 132.726 430.358 134.389C430.263 135.837 430.401 137.29 430.765 138.695C431.034 139.861 431.484 140.977 432.098 142.004C432.566 142.773 433.185 143.439 433.918 143.962C434.385 144.292 434.903 144.545 435.45 144.712C435.636 144.767 435.781 144.799 435.88 144.821C435.934 144.832 435.986 144.849 436.036 144.872Z" fill="#263238"/> +<path d="M468.014 75.1696H430.668V100.817H468.014V75.1696Z" fill="#263238"/> +<path d="M451.539 97.319H446.454V106.994H451.539V97.319Z" fill="#263238"/> +<path d="M434.384 106.623V110.103H453.654V161.958H455.427V110.103L535.903 110.499V161.958H537.643V110.405L550.063 110.503V106.321L434.384 106.623Z" fill="#263238"/> +<path d="M446.718 109.426L454.314 114.897L453.655 115.53L445.993 109.761L446.718 109.426Z" fill="#263238"/> +<path d="M544.803 109.935L535.987 116.214L536.65 116.848L545.528 110.27L544.803 109.935Z" fill="#263238"/> +<path d="M482.322 105.338H462.404V106.805H482.322V105.338Z" fill="#263238"/> +<path opacity="0.6" d="M59.278 118V105.4H63.364C64.84 105.4 66.052 105.658 67 106.174C67.96 106.69 68.668 107.422 69.124 108.37C69.592 109.306 69.826 110.422 69.826 111.718C69.826 113.002 69.592 114.118 69.124 115.066C68.668 116.002 67.96 116.728 67 117.244C66.052 117.748 64.84 118 63.364 118H59.278ZM61.186 116.38H63.292C64.432 116.38 65.332 116.194 65.992 115.822C66.664 115.45 67.144 114.916 67.432 114.22C67.732 113.524 67.882 112.69 67.882 111.718C67.882 110.746 67.732 109.906 67.432 109.198C67.144 108.49 66.664 107.95 65.992 107.578C65.332 107.194 64.432 107.002 63.292 107.002H61.186V116.38ZM74.8863 118.216C74.1303 118.216 73.5063 118.09 73.0143 117.838C72.5223 117.586 72.1563 117.256 71.9163 116.848C71.6763 116.428 71.5563 115.972 71.5563 115.48C71.5563 114.616 71.8923 113.932 72.5643 113.428C73.2363 112.924 74.1963 112.672 75.4443 112.672H77.7843V112.51C77.7843 111.814 77.5923 111.292 77.2083 110.944C76.8363 110.596 76.3503 110.422 75.7503 110.422C75.2223 110.422 74.7603 110.554 74.3643 110.818C73.9803 111.07 73.7463 111.448 73.6623 111.952H71.7543C71.8143 111.304 72.0303 110.752 72.4023 110.296C72.7863 109.828 73.2663 109.474 73.8423 109.234C74.4303 108.982 75.0723 108.856 75.7683 108.856C77.0163 108.856 77.9823 109.186 78.6663 109.846C79.3503 110.494 79.6923 111.382 79.6923 112.51V118H78.0363L77.8743 116.47C77.6223 116.962 77.2563 117.376 76.7763 117.712C76.2963 118.048 75.6663 118.216 74.8863 118.216ZM75.2643 116.668C75.7803 116.668 76.2123 116.548 76.5603 116.308C76.9203 116.056 77.1963 115.726 77.3883 115.318C77.5923 114.91 77.7183 114.46 77.7663 113.968H75.6423C74.8863 113.968 74.3463 114.1 74.0223 114.364C73.7103 114.628 73.5543 114.958 73.5543 115.354C73.5543 115.762 73.7043 116.086 74.0043 116.326C74.3163 116.554 74.7363 116.668 75.2643 116.668ZM82.3669 118V110.674H81.0889V109.072H82.3669V107.776C82.3669 106.804 82.6069 106.108 83.0869 105.688C83.5789 105.256 84.2689 105.04 85.1569 105.04H86.0929V106.66H85.4449C85.0249 106.66 84.7249 106.75 84.5449 106.93C84.3649 107.098 84.2749 107.386 84.2749 107.794V109.072H86.3269V110.674H84.2749V118H82.3669ZM91.8836 118C91.0076 118 90.3116 117.79 89.7956 117.37C89.2796 116.938 89.0216 116.176 89.0216 115.084V110.674H87.4916V109.072H89.0216L89.2556 106.804H90.9296V109.072H93.4496V110.674H90.9296V115.084C90.9296 115.576 91.0316 115.918 91.2356 116.11C91.4516 116.29 91.8176 116.38 92.3336 116.38H93.3596V118H91.8836ZM98.4409 118.216C97.6849 118.216 97.0609 118.09 96.5689 117.838C96.0769 117.586 95.7109 117.256 95.4709 116.848C95.2309 116.428 95.1109 115.972 95.1109 115.48C95.1109 114.616 95.4469 113.932 96.1189 113.428C96.7909 112.924 97.7509 112.672 98.9989 112.672H101.339V112.51C101.339 111.814 101.147 111.292 100.763 110.944C100.391 110.596 99.9049 110.422 99.3049 110.422C98.7769 110.422 98.3149 110.554 97.9189 110.818C97.5349 111.07 97.3009 111.448 97.2169 111.952H95.3089C95.3689 111.304 95.5849 110.752 95.9569 110.296C96.3409 109.828 96.8209 109.474 97.3969 109.234C97.9849 108.982 98.6269 108.856 99.3229 108.856C100.571 108.856 101.537 109.186 102.221 109.846C102.905 110.494 103.247 111.382 103.247 112.51V118H101.591L101.429 116.47C101.177 116.962 100.811 117.376 100.331 117.712C99.8509 118.048 99.2209 118.216 98.4409 118.216ZM98.8189 116.668C99.3349 116.668 99.7669 116.548 100.115 116.308C100.475 116.056 100.751 115.726 100.943 115.318C101.147 114.91 101.273 114.46 101.321 113.968H99.1969C98.4409 113.968 97.9009 114.1 97.5769 114.364C97.2649 114.628 97.1089 114.958 97.1089 115.354C97.1089 115.762 97.2589 116.086 97.5589 116.326C97.8709 116.554 98.2909 116.668 98.8189 116.668ZM105.472 118V109.072H107.182L107.344 110.764C107.656 110.176 108.088 109.714 108.64 109.378C109.204 109.03 109.882 108.856 110.674 108.856V110.854H110.152C109.624 110.854 109.15 110.944 108.73 111.124C108.322 111.292 107.992 111.586 107.74 112.006C107.5 112.414 107.38 112.984 107.38 113.716V118H105.472ZM112.31 118V105.04H114.218V112.762L117.638 109.072H119.924L116.126 113.122L120.482 118H118.07L114.218 113.428V118H112.31ZM124.791 118.216C124.035 118.216 123.411 118.09 122.919 117.838C122.427 117.586 122.061 117.256 121.821 116.848C121.581 116.428 121.461 115.972 121.461 115.48C121.461 114.616 121.797 113.932 122.469 113.428C123.141 112.924 124.101 112.672 125.349 112.672H127.689V112.51C127.689 111.814 127.497 111.292 127.113 110.944C126.741 110.596 126.255 110.422 125.655 110.422C125.127 110.422 124.665 110.554 124.269 110.818C123.885 111.07 123.651 111.448 123.567 111.952H121.659C121.719 111.304 121.935 110.752 122.307 110.296C122.691 109.828 123.171 109.474 123.747 109.234C124.335 108.982 124.977 108.856 125.673 108.856C126.921 108.856 127.887 109.186 128.571 109.846C129.255 110.494 129.597 111.382 129.597 112.51V118H127.941L127.779 116.47C127.527 116.962 127.161 117.376 126.681 117.712C126.201 118.048 125.571 118.216 124.791 118.216ZM125.169 116.668C125.685 116.668 126.117 116.548 126.465 116.308C126.825 116.056 127.101 115.726 127.293 115.318C127.497 114.91 127.623 114.46 127.671 113.968H125.547C124.791 113.968 124.251 114.1 123.927 114.364C123.615 114.628 123.459 114.958 123.459 115.354C123.459 115.762 123.609 116.086 123.909 116.326C124.221 116.554 124.641 116.668 125.169 116.668ZM131.821 118V109.072H133.513L133.657 110.638C133.933 110.086 134.335 109.654 134.863 109.342C135.403 109.018 136.021 108.856 136.717 108.856C137.797 108.856 138.643 109.192 139.255 109.864C139.879 110.536 140.191 111.538 140.191 112.87V118H138.301V113.068C138.301 111.34 137.593 110.476 136.177 110.476C135.469 110.476 134.881 110.728 134.413 111.232C133.957 111.736 133.729 112.456 133.729 113.392V118H131.821ZM150.718 118C149.842 118 149.146 117.79 148.63 117.37C148.114 116.938 147.856 116.176 147.856 115.084V110.674H146.326V109.072H147.856L148.09 106.804H149.764V109.072H152.284V110.674H149.764V115.084C149.764 115.576 149.866 115.918 150.07 116.11C150.286 116.29 150.652 116.38 151.168 116.38H152.194V118H150.718ZM158.198 118.216C157.346 118.216 156.578 118.024 155.894 117.64C155.222 117.244 154.688 116.698 154.292 116.002C153.896 115.294 153.698 114.472 153.698 113.536C153.698 112.6 153.896 111.784 154.292 111.088C154.7 110.38 155.246 109.834 155.93 109.45C156.614 109.054 157.376 108.856 158.216 108.856C159.068 108.856 159.83 109.054 160.502 109.45C161.186 109.834 161.726 110.38 162.122 111.088C162.53 111.784 162.734 112.6 162.734 113.536C162.734 114.472 162.53 115.294 162.122 116.002C161.726 116.698 161.186 117.244 160.502 117.64C159.818 118.024 159.05 118.216 158.198 118.216ZM158.198 116.578C158.654 116.578 159.074 116.464 159.458 116.236C159.854 116.008 160.172 115.672 160.412 115.228C160.652 114.772 160.772 114.208 160.772 113.536C160.772 112.864 160.652 112.306 160.412 111.862C160.184 111.406 159.872 111.064 159.476 110.836C159.092 110.608 158.672 110.494 158.216 110.494C157.76 110.494 157.334 110.608 156.938 110.836C156.554 111.064 156.242 111.406 156.002 111.862C155.762 112.306 155.642 112.864 155.642 113.536C155.642 114.208 155.762 114.772 156.002 115.228C156.242 115.672 156.554 116.008 156.938 116.236C157.322 116.464 157.742 116.578 158.198 116.578ZM164.798 118V105.04H166.706V112.762L170.126 109.072H172.412L168.614 113.122L172.97 118H170.558L166.706 113.428V118H164.798ZM177.939 118.216C177.087 118.216 176.319 118.024 175.635 117.64C174.963 117.244 174.429 116.698 174.033 116.002C173.637 115.294 173.439 114.472 173.439 113.536C173.439 112.6 173.637 111.784 174.033 111.088C174.441 110.38 174.987 109.834 175.671 109.45C176.355 109.054 177.117 108.856 177.957 108.856C178.809 108.856 179.571 109.054 180.243 109.45C180.927 109.834 181.467 110.38 181.863 111.088C182.271 111.784 182.475 112.6 182.475 113.536C182.475 114.472 182.271 115.294 181.863 116.002C181.467 116.698 180.927 117.244 180.243 117.64C179.559 118.024 178.791 118.216 177.939 118.216ZM177.939 116.578C178.395 116.578 178.815 116.464 179.199 116.236C179.595 116.008 179.913 115.672 180.153 115.228C180.393 114.772 180.513 114.208 180.513 113.536C180.513 112.864 180.393 112.306 180.153 111.862C179.925 111.406 179.613 111.064 179.217 110.836C178.833 110.608 178.413 110.494 177.957 110.494C177.501 110.494 177.075 110.608 176.679 110.836C176.295 111.064 175.983 111.406 175.743 111.862C175.503 112.306 175.383 112.864 175.383 113.536C175.383 114.208 175.503 114.772 175.743 115.228C175.983 115.672 176.295 116.008 176.679 116.236C177.063 116.464 177.483 116.578 177.939 116.578ZM188.335 118L192.979 105.4H195.067L199.675 118H197.659L196.579 114.922H191.431L190.351 118H188.335ZM191.971 113.41H196.039L194.005 107.668L191.971 113.41ZM201.36 118V109.072H203.052L203.196 110.638C203.472 110.086 203.874 109.654 204.402 109.342C204.942 109.018 205.56 108.856 206.256 108.856C207.336 108.856 208.182 109.192 208.794 109.864C209.418 110.536 209.73 111.538 209.73 112.87V118H207.84V113.068C207.84 111.34 207.132 110.476 205.716 110.476C205.008 110.476 204.42 110.728 203.952 111.232C203.496 111.736 203.268 112.456 203.268 113.392V118H201.36ZM216.045 118.216C215.181 118.216 214.419 118.012 213.759 117.604C213.099 117.196 212.583 116.638 212.211 115.93C211.839 115.222 211.653 114.418 211.653 113.518C211.653 112.618 211.839 111.82 212.211 111.124C212.583 110.416 213.099 109.864 213.759 109.468C214.431 109.06 215.199 108.856 216.063 108.856C216.771 108.856 217.389 108.994 217.917 109.27C218.457 109.546 218.877 109.936 219.177 110.44V105.04H221.085V118H219.375L219.177 116.614C218.889 117.034 218.493 117.406 217.989 117.73C217.485 118.054 216.837 118.216 216.045 118.216ZM216.387 116.56C217.203 116.56 217.869 116.278 218.385 115.714C218.913 115.15 219.177 114.424 219.177 113.536C219.177 112.636 218.913 111.91 218.385 111.358C217.869 110.794 217.203 110.512 216.387 110.512C215.571 110.512 214.899 110.794 214.371 111.358C213.843 111.91 213.579 112.636 213.579 113.536C213.579 114.124 213.699 114.646 213.939 115.102C214.179 115.558 214.509 115.918 214.929 116.182C215.361 116.434 215.847 116.56 216.387 116.56ZM226.515 118.216C225.759 118.216 225.135 118.09 224.643 117.838C224.151 117.586 223.785 117.256 223.545 116.848C223.305 116.428 223.185 115.972 223.185 115.48C223.185 114.616 223.521 113.932 224.193 113.428C224.865 112.924 225.825 112.672 227.073 112.672H229.413V112.51C229.413 111.814 229.221 111.292 228.837 110.944C228.465 110.596 227.979 110.422 227.379 110.422C226.851 110.422 226.389 110.554 225.993 110.818C225.609 111.07 225.375 111.448 225.291 111.952H223.383C223.443 111.304 223.659 110.752 224.031 110.296C224.415 109.828 224.895 109.474 225.471 109.234C226.059 108.982 226.701 108.856 227.397 108.856C228.645 108.856 229.611 109.186 230.295 109.846C230.979 110.494 231.321 111.382 231.321 112.51V118H229.665L229.503 116.47C229.251 116.962 228.885 117.376 228.405 117.712C227.925 118.048 227.295 118.216 226.515 118.216ZM226.893 116.668C227.409 116.668 227.841 116.548 228.189 116.308C228.549 116.056 228.825 115.726 229.017 115.318C229.221 114.91 229.347 114.46 229.395 113.968H227.271C226.515 113.968 225.975 114.1 225.651 114.364C225.339 114.628 225.183 114.958 225.183 115.354C225.183 115.762 225.333 116.086 225.633 116.326C225.945 116.554 226.365 116.668 226.893 116.668ZM242.149 118.216C241.285 118.216 240.523 118.012 239.863 117.604C239.203 117.196 238.687 116.638 238.315 115.93C237.943 115.222 237.757 114.418 237.757 113.518C237.757 112.618 237.943 111.82 238.315 111.124C238.687 110.416 239.203 109.864 239.863 109.468C240.535 109.06 241.303 108.856 242.167 108.856C242.875 108.856 243.493 108.994 244.021 109.27C244.561 109.546 244.981 109.936 245.281 110.44V105.04H247.189V118H245.479L245.281 116.614C244.993 117.034 244.597 117.406 244.093 117.73C243.589 118.054 242.941 118.216 242.149 118.216ZM242.491 116.56C243.307 116.56 243.973 116.278 244.489 115.714C245.017 115.15 245.281 114.424 245.281 113.536C245.281 112.636 245.017 111.91 244.489 111.358C243.973 110.794 243.307 110.512 242.491 110.512C241.675 110.512 241.003 110.794 240.475 111.358C239.947 111.91 239.683 112.636 239.683 113.536C239.683 114.124 239.803 114.646 240.043 115.102C240.283 115.558 240.613 115.918 241.033 116.182C241.465 116.434 241.951 116.56 242.491 116.56ZM252.619 118.216C251.863 118.216 251.239 118.09 250.747 117.838C250.255 117.586 249.889 117.256 249.649 116.848C249.409 116.428 249.289 115.972 249.289 115.48C249.289 114.616 249.625 113.932 250.297 113.428C250.969 112.924 251.929 112.672 253.177 112.672H255.517V112.51C255.517 111.814 255.325 111.292 254.941 110.944C254.569 110.596 254.083 110.422 253.483 110.422C252.955 110.422 252.493 110.554 252.097 110.818C251.713 111.07 251.479 111.448 251.395 111.952H249.487C249.547 111.304 249.763 110.752 250.135 110.296C250.519 109.828 250.999 109.474 251.575 109.234C252.163 108.982 252.805 108.856 253.501 108.856C254.749 108.856 255.715 109.186 256.399 109.846C257.083 110.494 257.425 111.382 257.425 112.51V118H255.769L255.607 116.47C255.355 116.962 254.989 117.376 254.509 117.712C254.029 118.048 253.399 118.216 252.619 118.216ZM252.997 116.668C253.513 116.668 253.945 116.548 254.293 116.308C254.653 116.056 254.929 115.726 255.121 115.318C255.325 114.91 255.451 114.46 255.499 113.968H253.375C252.619 113.968 252.079 114.1 251.755 114.364C251.443 114.628 251.287 114.958 251.287 115.354C251.287 115.762 251.437 116.086 251.737 116.326C252.049 116.554 252.469 116.668 252.997 116.668ZM259.649 118V109.072H261.341L261.485 110.638C261.761 110.086 262.163 109.654 262.691 109.342C263.231 109.018 263.849 108.856 264.545 108.856C265.625 108.856 266.471 109.192 267.083 109.864C267.707 110.536 268.019 111.538 268.019 112.87V118H266.129V113.068C266.129 111.34 265.421 110.476 264.005 110.476C263.297 110.476 262.709 110.728 262.241 111.232C261.785 111.736 261.557 112.456 261.557 113.392V118H259.649ZM274.802 118V109.072H276.512L276.674 110.764C276.986 110.176 277.418 109.714 277.97 109.378C278.534 109.03 279.212 108.856 280.004 108.856V110.854H279.482C278.954 110.854 278.48 110.944 278.06 111.124C277.652 111.292 277.322 111.586 277.07 112.006C276.83 112.414 276.71 112.984 276.71 113.716V118H274.802ZM284.664 118.216C283.908 118.216 283.284 118.09 282.792 117.838C282.3 117.586 281.934 117.256 281.694 116.848C281.454 116.428 281.334 115.972 281.334 115.48C281.334 114.616 281.67 113.932 282.342 113.428C283.014 112.924 283.974 112.672 285.222 112.672H287.562V112.51C287.562 111.814 287.37 111.292 286.986 110.944C286.614 110.596 286.128 110.422 285.528 110.422C285 110.422 284.538 110.554 284.142 110.818C283.758 111.07 283.524 111.448 283.44 111.952H281.532C281.592 111.304 281.808 110.752 282.18 110.296C282.564 109.828 283.044 109.474 283.62 109.234C284.208 108.982 284.85 108.856 285.546 108.856C286.794 108.856 287.76 109.186 288.444 109.846C289.128 110.494 289.47 111.382 289.47 112.51V118H287.814L287.652 116.47C287.4 116.962 287.034 117.376 286.554 117.712C286.074 118.048 285.444 118.216 284.664 118.216ZM285.042 116.668C285.558 116.668 285.99 116.548 286.338 116.308C286.698 116.056 286.974 115.726 287.166 115.318C287.37 114.91 287.496 114.46 287.544 113.968H285.42C284.664 113.968 284.124 114.1 283.8 114.364C283.488 114.628 283.332 114.958 283.332 115.354C283.332 115.762 283.482 116.086 283.782 116.326C284.094 116.554 284.514 116.668 285.042 116.668ZM292.774 107.38C292.414 107.38 292.114 107.272 291.874 107.056C291.646 106.828 291.532 106.546 291.532 106.21C291.532 105.874 291.646 105.598 291.874 105.382C292.114 105.154 292.414 105.04 292.774 105.04C293.134 105.04 293.428 105.154 293.656 105.382C293.896 105.598 294.016 105.874 294.016 106.21C294.016 106.546 293.896 106.828 293.656 107.056C293.428 107.272 293.134 107.38 292.774 107.38ZM291.82 118V109.072H293.728V118H291.82ZM296.247 118V105.04H298.155V110.512C298.455 109.996 298.869 109.594 299.397 109.306C299.937 109.006 300.531 108.856 301.179 108.856C302.247 108.856 303.087 109.192 303.699 109.864C304.311 110.536 304.617 111.538 304.617 112.87V118H302.727V113.068C302.727 111.34 302.037 110.476 300.657 110.476C299.937 110.476 299.337 110.728 298.857 111.232C298.389 111.736 298.155 112.456 298.155 113.392V118H296.247ZM59.206 143V130.04H61.114V137.762L64.534 134.072H66.82L63.022 138.122L67.378 143H64.966L61.114 138.428V143H59.206ZM72.3468 143.216C71.4708 143.216 70.6908 143.024 70.0068 142.64C69.3348 142.244 68.8068 141.698 68.4228 141.002C68.0388 140.306 67.8468 139.496 67.8468 138.572C67.8468 137.636 68.0328 136.814 68.4048 136.106C68.7888 135.398 69.3168 134.846 69.9888 134.45C70.6728 134.054 71.4648 133.856 72.3648 133.856C73.2408 133.856 74.0028 134.054 74.6508 134.45C75.2988 134.834 75.8028 135.35 76.1628 135.998C76.5228 136.646 76.7028 137.36 76.7028 138.14C76.7028 138.26 76.6968 138.392 76.6848 138.536C76.6848 138.668 76.6788 138.818 76.6668 138.986H69.7188C69.7788 139.85 70.0608 140.51 70.5648 140.966C71.0808 141.41 71.6748 141.632 72.3468 141.632C72.8868 141.632 73.3368 141.512 73.6968 141.272C74.0688 141.02 74.3448 140.684 74.5248 140.264H76.4328C76.1928 141.104 75.7128 141.806 74.9928 142.37C74.2848 142.934 73.4028 143.216 72.3468 143.216ZM72.3468 135.422C71.7108 135.422 71.1468 135.614 70.6548 135.998C70.1628 136.37 69.8628 136.934 69.7548 137.69H74.7948C74.7588 136.994 74.5128 136.442 74.0568 136.034C73.6008 135.626 73.0308 135.422 72.3468 135.422ZM81.9766 143.216C80.8966 143.216 80.0446 142.88 79.4206 142.208C78.8086 141.536 78.5026 140.534 78.5026 139.202V134.072H80.4106V139.004C80.4106 140.732 81.1186 141.596 82.5346 141.596C83.2426 141.596 83.8246 141.344 84.2806 140.84C84.7366 140.336 84.9646 139.616 84.9646 138.68V134.072H86.8726V143H85.1806L85.0366 141.434C84.7606 141.986 84.3526 142.424 83.8126 142.748C83.2846 143.06 82.6726 143.216 81.9766 143.216ZM89.2998 143V134.072H90.9918L91.1358 135.638C91.4118 135.086 91.8138 134.654 92.3418 134.342C92.8818 134.018 93.4998 133.856 94.1958 133.856C95.2758 133.856 96.1218 134.192 96.7338 134.864C97.3578 135.536 97.6698 136.538 97.6698 137.87V143H95.7798V138.068C95.7798 136.34 95.0718 135.476 93.6558 135.476C92.9478 135.476 92.3598 135.728 91.8918 136.232C91.4358 136.736 91.2078 137.456 91.2078 138.392V143H89.2998ZM103.661 143C102.785 143 102.089 142.79 101.573 142.37C101.057 141.938 100.799 141.176 100.799 140.084V135.674H99.2689V134.072H100.799L101.033 131.804H102.707V134.072H105.227V135.674H102.707V140.084C102.707 140.576 102.809 140.918 103.013 141.11C103.229 141.29 103.595 141.38 104.111 141.38H105.137V143H103.661ZM110.488 143.216C109.408 143.216 108.556 142.88 107.932 142.208C107.32 141.536 107.014 140.534 107.014 139.202V134.072H108.922V139.004C108.922 140.732 109.63 141.596 111.046 141.596C111.754 141.596 112.336 141.344 112.792 140.84C113.248 140.336 113.476 139.616 113.476 138.68V134.072H115.384V143H113.692L113.548 141.434C113.272 141.986 112.864 142.424 112.324 142.748C111.796 143.06 111.184 143.216 110.488 143.216ZM117.811 143V134.072H119.503L119.647 135.638C119.923 135.086 120.325 134.654 120.853 134.342C121.393 134.018 122.011 133.856 122.707 133.856C123.787 133.856 124.633 134.192 125.245 134.864C125.869 135.536 126.181 136.538 126.181 137.87V143H124.291V138.068C124.291 136.34 123.583 135.476 122.167 135.476C121.459 135.476 120.871 135.728 120.403 136.232C119.947 136.736 119.719 137.456 119.719 138.392V143H117.811ZM132.083 140.264C131.615 140.264 131.183 140.21 130.787 140.102L130.013 140.858C130.145 140.942 130.307 141.014 130.499 141.074C130.691 141.134 130.961 141.188 131.309 141.236C131.657 141.284 132.131 141.332 132.731 141.38C133.919 141.488 134.777 141.776 135.305 142.244C135.833 142.7 136.097 143.312 136.097 144.08C136.097 144.608 135.953 145.106 135.665 145.574C135.389 146.054 134.951 146.438 134.351 146.726C133.763 147.026 133.007 147.176 132.083 147.176C130.835 147.176 129.821 146.936 129.041 146.456C128.273 145.988 127.889 145.274 127.889 144.314C127.889 143.942 127.985 143.57 128.177 143.198C128.381 142.838 128.699 142.496 129.131 142.172C128.879 142.064 128.657 141.95 128.465 141.83C128.285 141.698 128.123 141.566 127.979 141.434V141.002L129.527 139.418C128.831 138.818 128.483 138.032 128.483 137.06C128.483 136.472 128.621 135.938 128.897 135.458C129.185 134.966 129.599 134.576 130.139 134.288C130.679 134 131.327 133.856 132.083 133.856C132.587 133.856 133.055 133.928 133.487 134.072H136.817V135.332L135.233 135.422C135.521 135.914 135.665 136.46 135.665 137.06C135.665 137.66 135.521 138.2 135.233 138.68C134.957 139.16 134.549 139.544 134.009 139.832C133.481 140.12 132.839 140.264 132.083 140.264ZM132.083 138.77C132.635 138.77 133.079 138.626 133.415 138.338C133.763 138.038 133.937 137.618 133.937 137.078C133.937 136.526 133.763 136.106 133.415 135.818C133.079 135.53 132.635 135.386 132.083 135.386C131.519 135.386 131.063 135.53 130.715 135.818C130.379 136.106 130.211 136.526 130.211 137.078C130.211 137.618 130.379 138.038 130.715 138.338C131.063 138.626 131.519 138.77 132.083 138.77ZM129.689 144.134C129.689 144.65 129.917 145.034 130.373 145.286C130.829 145.55 131.399 145.682 132.083 145.682C132.743 145.682 133.277 145.538 133.685 145.25C134.093 144.974 134.297 144.602 134.297 144.134C134.297 143.786 134.159 143.486 133.883 143.234C133.607 142.994 133.085 142.844 132.317 142.784C131.741 142.748 131.231 142.694 130.787 142.622C130.367 142.85 130.079 143.096 129.923 143.36C129.767 143.624 129.689 143.882 129.689 144.134ZM141.543 143.216C140.787 143.216 140.163 143.09 139.671 142.838C139.179 142.586 138.813 142.256 138.573 141.848C138.333 141.428 138.213 140.972 138.213 140.48C138.213 139.616 138.549 138.932 139.221 138.428C139.893 137.924 140.853 137.672 142.101 137.672H144.441V137.51C144.441 136.814 144.249 136.292 143.865 135.944C143.493 135.596 143.007 135.422 142.407 135.422C141.879 135.422 141.417 135.554 141.021 135.818C140.637 136.07 140.403 136.448 140.319 136.952H138.411C138.471 136.304 138.687 135.752 139.059 135.296C139.443 134.828 139.923 134.474 140.499 134.234C141.087 133.982 141.729 133.856 142.425 133.856C143.673 133.856 144.639 134.186 145.323 134.846C146.007 135.494 146.349 136.382 146.349 137.51V143H144.693L144.531 141.47C144.279 141.962 143.913 142.376 143.433 142.712C142.953 143.048 142.323 143.216 141.543 143.216ZM141.921 141.668C142.437 141.668 142.869 141.548 143.217 141.308C143.577 141.056 143.853 140.726 144.045 140.318C144.249 139.91 144.375 139.46 144.423 138.968H142.299C141.543 138.968 141.003 139.1 140.679 139.364C140.367 139.628 140.211 139.958 140.211 140.354C140.211 140.762 140.361 141.086 140.661 141.326C140.973 141.554 141.393 141.668 141.921 141.668ZM148.573 143V134.072H150.265L150.409 135.638C150.685 135.086 151.087 134.654 151.615 134.342C152.155 134.018 152.773 133.856 153.469 133.856C154.549 133.856 155.395 134.192 156.007 134.864C156.631 135.536 156.943 136.538 156.943 137.87V143H155.053V138.068C155.053 136.34 154.345 135.476 152.929 135.476C152.221 135.476 151.633 135.728 151.165 136.232C150.709 136.736 150.481 137.456 150.481 138.392V143H148.573ZM159.19 143V134.072H160.882L161.026 135.638C161.302 135.086 161.704 134.654 162.232 134.342C162.772 134.018 163.39 133.856 164.086 133.856C165.166 133.856 166.012 134.192 166.624 134.864C167.248 135.536 167.56 136.538 167.56 137.87V143H165.67V138.068C165.67 136.34 164.962 135.476 163.546 135.476C162.838 135.476 162.25 135.728 161.782 136.232C161.326 136.736 161.098 137.456 161.098 138.392V143H159.19ZM170.57 146.96L172.712 142.262H172.19L168.662 134.072H170.732L173.468 140.678L176.33 134.072H178.346L172.586 146.96H170.57ZM182.306 143.216C181.55 143.216 180.926 143.09 180.434 142.838C179.942 142.586 179.576 142.256 179.336 141.848C179.096 141.428 178.976 140.972 178.976 140.48C178.976 139.616 179.312 138.932 179.984 138.428C180.656 137.924 181.616 137.672 182.864 137.672H185.204V137.51C185.204 136.814 185.012 136.292 184.628 135.944C184.256 135.596 183.77 135.422 183.17 135.422C182.642 135.422 182.18 135.554 181.784 135.818C181.4 136.07 181.166 136.448 181.082 136.952H179.174C179.234 136.304 179.45 135.752 179.822 135.296C180.206 134.828 180.686 134.474 181.262 134.234C181.85 133.982 182.492 133.856 183.188 133.856C184.436 133.856 185.402 134.186 186.086 134.846C186.77 135.494 187.112 136.382 187.112 137.51V143H185.456L185.294 141.47C185.042 141.962 184.676 142.376 184.196 142.712C183.716 143.048 183.086 143.216 182.306 143.216ZM182.684 141.668C183.2 141.668 183.632 141.548 183.98 141.308C184.34 141.056 184.616 140.726 184.808 140.318C185.012 139.91 185.138 139.46 185.186 138.968H183.062C182.306 138.968 181.766 139.1 181.442 139.364C181.13 139.628 180.974 139.958 180.974 140.354C180.974 140.762 181.124 141.086 181.424 141.326C181.736 141.554 182.156 141.668 182.684 141.668ZM190.093 143.108C189.733 143.108 189.433 142.994 189.193 142.766C188.965 142.526 188.851 142.244 188.851 141.92C188.851 141.584 188.965 141.302 189.193 141.074C189.433 140.834 189.733 140.714 190.093 140.714C190.453 140.714 190.747 140.834 190.975 141.074C191.203 141.302 191.317 141.584 191.317 141.92C191.317 142.244 191.203 142.526 190.975 142.766C190.747 142.994 190.453 143.108 190.093 143.108Z" fill="black" fill-opacity="0.8"/> +<path d="M63.72 84C62.7867 84 62.0667 83.7467 61.56 83.24C61.0533 82.7333 60.8 82.0133 60.8 81.08V58.72C60.8 57.7867 61.0533 57.0667 61.56 56.56C62.0667 56.0533 62.7867 55.8 63.72 55.8H71.76C74.8267 55.8 77.4667 56.36 79.68 57.48C81.8933 58.6 83.5867 60.2133 84.76 62.32C85.9333 64.4267 86.52 66.9467 86.52 69.88C86.52 72.8133 85.9333 75.3467 84.76 77.48C83.6133 79.5867 81.9333 81.2 79.72 82.32C77.5067 83.44 74.8533 84 71.76 84H63.72ZM71.32 78.96C77.32 78.96 80.32 75.9333 80.32 69.88C80.32 63.8533 77.32 60.84 71.32 60.84H67.04V78.96H71.32ZM99.6678 63.88C102.548 63.88 104.681 64.5867 106.068 66C107.454 67.3867 108.148 69.52 108.148 72.4V81.44C108.148 82.32 107.894 83.0133 107.388 83.52C106.881 84 106.174 84.24 105.268 84.24C104.414 84.24 103.721 83.9867 103.188 83.48C102.681 82.9467 102.428 82.2667 102.428 81.44V81.16C102.028 82.1467 101.361 82.92 100.428 83.48C99.4945 84.04 98.4011 84.32 97.1478 84.32C95.8145 84.32 94.6011 84.0533 93.5078 83.52C92.4411 82.9867 91.5878 82.24 90.9478 81.28C90.3345 80.32 90.0278 79.2533 90.0278 78.08C90.0278 76.64 90.3878 75.5067 91.1078 74.68C91.8545 73.8533 93.0411 73.2533 94.6678 72.88C96.2945 72.5067 98.5211 72.32 101.348 72.32H102.388V71.6C102.388 70.48 102.134 69.6667 101.628 69.16C101.148 68.6533 100.334 68.4 99.1878 68.4C98.0411 68.4 96.3878 68.8 94.2278 69.6C93.6145 69.8933 93.0945 70.04 92.6678 70.04C92.0811 70.04 91.6145 69.84 91.2678 69.44C90.9211 69.0133 90.7478 68.4667 90.7478 67.8C90.7478 67.2667 90.8678 66.8267 91.1078 66.48C91.3478 66.1333 91.7345 65.8133 92.2678 65.52C93.2011 65.0133 94.3345 64.6133 95.6678 64.32C97.0278 64.0267 98.3611 63.88 99.6678 63.88ZM98.4678 80.16C99.6411 80.16 100.588 79.7733 101.308 79C102.028 78.2 102.388 77.1733 102.388 75.92V75.24H101.708C99.5478 75.24 98.0278 75.4133 97.1478 75.76C96.2945 76.1067 95.8678 76.7333 95.8678 77.64C95.8678 78.3867 96.1078 79 96.5878 79.48C97.0945 79.9333 97.7211 80.16 98.4678 80.16ZM123.344 60.2C122.25 60.28 121.464 60.6133 120.984 61.2C120.504 61.7867 120.264 62.6133 120.264 63.68V64.36H123.064C124.877 64.36 125.784 65.12 125.784 66.64C125.784 68.1333 124.877 68.88 123.064 68.88H120.264V81.36C120.264 82.2933 119.97 83 119.384 83.48C118.824 83.96 118.117 84.2 117.264 84.2C116.384 84.2 115.65 83.96 115.064 83.48C114.504 83 114.224 82.2933 114.224 81.36V68.88H112.624C110.837 68.88 109.944 68.1333 109.944 66.64C109.944 65.12 110.837 64.36 112.624 64.36H114.224C114.224 61.8 114.93 59.7867 116.344 58.32C117.757 56.8533 119.704 56.0267 122.184 55.84L123.224 55.76L123.944 55.72C125.784 55.72 126.704 56.4267 126.704 57.84C126.704 59.2267 125.93 59.9867 124.384 60.12L123.344 60.2ZM137.412 79.84C138.212 79.8933 138.799 80.0933 139.172 80.44C139.545 80.7867 139.732 81.2933 139.732 81.96C139.732 82.7333 139.425 83.32 138.812 83.72C138.199 84.12 137.319 84.28 136.172 84.2L135.052 84.12C130.385 83.7467 128.052 81.3067 128.052 76.8V68.88H126.452C125.572 68.88 124.905 68.6933 124.452 68.32C123.999 67.92 123.772 67.36 123.772 66.64C123.772 65.8933 123.999 65.3333 124.452 64.96C124.905 64.56 125.572 64.36 126.452 64.36H128.052V61.24C128.052 60.36 128.319 59.6667 128.852 59.16C129.412 58.6533 130.159 58.4 131.092 58.4C132.025 58.4 132.759 58.6533 133.292 59.16C133.825 59.6667 134.092 60.36 134.092 61.24V64.36H136.892C138.705 64.36 139.612 65.12 139.612 66.64C139.612 67.36 139.385 67.92 138.932 68.32C138.479 68.6933 137.799 68.88 136.892 68.88H134.092V77.24C134.092 78.04 134.279 78.6533 134.652 79.08C135.025 79.48 135.572 79.7067 136.292 79.76L137.412 79.84ZM150.801 63.88C153.681 63.88 155.814 64.5867 157.201 66C158.587 67.3867 159.281 69.52 159.281 72.4V81.44C159.281 82.32 159.027 83.0133 158.521 83.52C158.014 84 157.307 84.24 156.401 84.24C155.547 84.24 154.854 83.9867 154.321 83.48C153.814 82.9467 153.561 82.2667 153.561 81.44V81.16C153.161 82.1467 152.494 82.92 151.561 83.48C150.627 84.04 149.534 84.32 148.281 84.32C146.947 84.32 145.734 84.0533 144.641 83.52C143.574 82.9867 142.721 82.24 142.081 81.28C141.467 80.32 141.161 79.2533 141.161 78.08C141.161 76.64 141.521 75.5067 142.241 74.68C142.987 73.8533 144.174 73.2533 145.801 72.88C147.427 72.5067 149.654 72.32 152.481 72.32H153.521V71.6C153.521 70.48 153.267 69.6667 152.761 69.16C152.281 68.6533 151.467 68.4 150.321 68.4C149.174 68.4 147.521 68.8 145.361 69.6C144.747 69.8933 144.227 70.04 143.801 70.04C143.214 70.04 142.747 69.84 142.401 69.44C142.054 69.0133 141.881 68.4667 141.881 67.8C141.881 67.2667 142.001 66.8267 142.241 66.48C142.481 66.1333 142.867 65.8133 143.401 65.52C144.334 65.0133 145.467 64.6133 146.801 64.32C148.161 64.0267 149.494 63.88 150.801 63.88ZM149.601 80.16C150.774 80.16 151.721 79.7733 152.441 79C153.161 78.2 153.521 77.1733 153.521 75.92V75.24H152.841C150.681 75.24 149.161 75.4133 148.281 75.76C147.427 76.1067 147.001 76.7333 147.001 77.64C147.001 78.3867 147.241 79 147.721 79.48C148.227 79.9333 148.854 80.16 149.601 80.16ZM175.517 63.96C176.317 63.9067 176.943 64.0933 177.397 64.52C177.877 64.92 178.117 65.5333 178.117 66.36C178.117 67.24 177.903 67.8933 177.477 68.32C177.05 68.7467 176.29 69.0133 175.197 69.12L173.997 69.24C172.53 69.4 171.463 69.88 170.797 70.68C170.157 71.48 169.837 72.5067 169.837 73.76V81.4C169.837 82.3333 169.543 83.04 168.957 83.52C168.397 84 167.69 84.24 166.837 84.24C165.957 84.24 165.223 84 164.637 83.52C164.077 83.04 163.797 82.3333 163.797 81.4V66.72C163.797 65.84 164.09 65.16 164.677 64.68C165.263 64.2 165.97 63.96 166.797 63.96C167.597 63.96 168.263 64.2 168.797 64.68C169.33 65.1333 169.597 65.7733 169.597 66.6V67.68C170.077 66.5333 170.797 65.6533 171.757 65.04C172.743 64.4267 173.81 64.08 174.957 64L175.517 63.96ZM198.371 79.32C198.985 79.9067 199.291 80.5733 199.291 81.32C199.291 82.0667 199.011 82.7333 198.451 83.32C197.918 83.9067 197.291 84.2 196.571 84.2C195.878 84.2 195.238 83.92 194.651 83.36L185.891 75.24V81.36C185.891 82.2933 185.598 83 185.011 83.48C184.451 83.96 183.745 84.2 182.891 84.2C182.011 84.2 181.278 83.96 180.691 83.48C180.131 83 179.851 82.2933 179.851 81.36V58.44C179.851 57.5067 180.131 56.8 180.691 56.32C181.278 55.84 182.011 55.6 182.891 55.6C183.745 55.6 184.451 55.84 185.011 56.32C185.598 56.8 185.891 57.5067 185.891 58.44V72.76L193.891 64.88C194.478 64.2933 195.131 64 195.851 64C196.598 64 197.251 64.28 197.811 64.84C198.371 65.3733 198.651 66.0133 198.651 66.76C198.651 67.4533 198.345 68.1067 197.731 68.72L192.411 73.8L198.371 79.32ZM210.996 63.88C213.876 63.88 216.009 64.5867 217.396 66C218.783 67.3867 219.476 69.52 219.476 72.4V81.44C219.476 82.32 219.223 83.0133 218.716 83.52C218.209 84 217.503 84.24 216.596 84.24C215.743 84.24 215.049 83.9867 214.516 83.48C214.009 82.9467 213.756 82.2667 213.756 81.44V81.16C213.356 82.1467 212.689 82.92 211.756 83.48C210.823 84.04 209.729 84.32 208.476 84.32C207.143 84.32 205.929 84.0533 204.836 83.52C203.769 82.9867 202.916 82.24 202.276 81.28C201.663 80.32 201.356 79.2533 201.356 78.08C201.356 76.64 201.716 75.5067 202.436 74.68C203.183 73.8533 204.369 73.2533 205.996 72.88C207.623 72.5067 209.849 72.32 212.676 72.32H213.716V71.6C213.716 70.48 213.463 69.6667 212.956 69.16C212.476 68.6533 211.663 68.4 210.516 68.4C209.369 68.4 207.716 68.8 205.556 69.6C204.943 69.8933 204.423 70.04 203.996 70.04C203.409 70.04 202.943 69.84 202.596 69.44C202.249 69.0133 202.076 68.4667 202.076 67.8C202.076 67.2667 202.196 66.8267 202.436 66.48C202.676 66.1333 203.063 65.8133 203.596 65.52C204.529 65.0133 205.663 64.6133 206.996 64.32C208.356 64.0267 209.689 63.88 210.996 63.88ZM209.796 80.16C210.969 80.16 211.916 79.7733 212.636 79C213.356 78.2 213.716 77.1733 213.716 75.92V75.24H213.036C210.876 75.24 209.356 75.4133 208.476 75.76C207.623 76.1067 207.196 76.7333 207.196 77.64C207.196 78.3867 207.436 79 207.916 79.48C208.423 79.9333 209.049 80.16 209.796 80.16ZM236.312 63.88C238.659 63.88 240.405 64.5733 241.552 65.96C242.699 67.32 243.272 69.3867 243.272 72.16V81.4C243.272 82.28 242.992 82.9733 242.432 83.48C241.899 83.9867 241.165 84.24 240.232 84.24C239.299 84.24 238.565 83.9867 238.032 83.48C237.499 82.9733 237.232 82.28 237.232 81.4V72.44C237.232 71.1067 236.979 70.1333 236.472 69.52C235.992 68.9067 235.232 68.6 234.192 68.6C232.939 68.6 231.925 69 231.152 69.8C230.405 70.6 230.032 71.6667 230.032 73V81.4C230.032 82.28 229.765 82.9733 229.232 83.48C228.699 83.9867 227.965 84.24 227.032 84.24C226.099 84.24 225.352 83.9867 224.792 83.48C224.259 82.9733 223.992 82.28 223.992 81.4V66.72C223.992 65.8933 224.272 65.2267 224.832 64.72C225.419 64.2133 226.165 63.96 227.072 63.96C227.899 63.96 228.565 64.2133 229.072 64.72C229.605 65.2 229.872 65.8267 229.872 66.6V67.16C230.565 66.0933 231.459 65.28 232.552 64.72C233.672 64.16 234.925 63.88 236.312 63.88ZM269.073 84.2C268.139 84.2 267.379 83.92 266.793 83.36C266.233 82.8 265.953 82.0533 265.953 81.12V60.88H259.473C257.499 60.88 256.513 60.0267 256.513 58.32C256.513 56.64 257.499 55.8 259.473 55.8H278.673C280.646 55.8 281.633 56.64 281.633 58.32C281.633 60.0267 280.646 60.88 278.673 60.88H272.193V81.12C272.193 82.0533 271.913 82.8 271.353 83.36C270.793 83.92 270.033 84.2 269.073 84.2ZM290.072 84.32C287.993 84.32 286.166 83.9067 284.593 83.08C283.019 82.2267 281.806 81.04 280.952 79.52C280.099 77.9733 279.673 76.16 279.673 74.08C279.673 72 280.099 70.2 280.952 68.68C281.806 67.1333 283.019 65.9467 284.593 65.12C286.166 64.2933 287.993 63.88 290.072 63.88C292.153 63.88 293.979 64.2933 295.553 65.12C297.126 65.9467 298.339 67.1333 299.193 68.68C300.046 70.2 300.473 72 300.473 74.08C300.473 76.16 300.046 77.9733 299.193 79.52C298.339 81.04 297.126 82.2267 295.553 83.08C293.979 83.9067 292.153 84.32 290.072 84.32ZM290.072 79.72C293.006 79.72 294.473 77.84 294.473 74.08C294.473 72.1867 294.086 70.7733 293.313 69.84C292.566 68.9067 291.486 68.44 290.072 68.44C287.139 68.44 285.673 70.32 285.673 74.08C285.673 77.84 287.139 79.72 290.072 79.72ZM322.668 79.32C323.281 79.9067 323.588 80.5733 323.588 81.32C323.588 82.0667 323.308 82.7333 322.748 83.32C322.215 83.9067 321.588 84.2 320.868 84.2C320.175 84.2 319.535 83.92 318.948 83.36L310.188 75.24V81.36C310.188 82.2933 309.895 83 309.308 83.48C308.748 83.96 308.041 84.2 307.188 84.2C306.308 84.2 305.575 83.96 304.988 83.48C304.428 83 304.148 82.2933 304.148 81.36V58.44C304.148 57.5067 304.428 56.8 304.988 56.32C305.575 55.84 306.308 55.6 307.188 55.6C308.041 55.6 308.748 55.84 309.308 56.32C309.895 56.8 310.188 57.5067 310.188 58.44V72.76L318.188 64.88C318.775 64.2933 319.428 64 320.148 64C320.895 64 321.548 64.28 322.108 64.84C322.668 65.3733 322.948 66.0133 322.948 66.76C322.948 67.4533 322.641 68.1067 322.028 68.72L316.708 73.8L322.668 79.32ZM335.697 84.32C333.618 84.32 331.791 83.9067 330.218 83.08C328.644 82.2267 327.431 81.04 326.577 79.52C325.724 77.9733 325.298 76.16 325.298 74.08C325.298 72 325.724 70.2 326.577 68.68C327.431 67.1333 328.644 65.9467 330.218 65.12C331.791 64.2933 333.618 63.88 335.697 63.88C337.778 63.88 339.604 64.2933 341.178 65.12C342.751 65.9467 343.964 67.1333 344.818 68.68C345.671 70.2 346.098 72 346.098 74.08C346.098 76.16 345.671 77.9733 344.818 79.52C343.964 81.04 342.751 82.2267 341.178 83.08C339.604 83.9067 337.778 84.32 335.697 84.32ZM335.697 79.72C338.631 79.72 340.098 77.84 340.098 74.08C340.098 72.1867 339.711 70.7733 338.938 69.84C338.191 68.9067 337.111 68.44 335.697 68.44C332.764 68.44 331.298 70.32 331.298 74.08C331.298 77.84 332.764 79.72 335.697 79.72Z" fill="#146A5F"/> +<defs> +<filter id="filter0_d" x="0" y="4" width="616" height="222" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"> +<feFlood flood-opacity="0" result="BackgroundImageFix"/> +<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/> +<feOffset dy="4"/> +<feGaussianBlur stdDeviation="2"/> +<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/> +<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/> +<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/> +</filter> +</defs> +</svg> diff --git a/src/page/MembuatInvestasi/MembuatInvestasi.css b/src/page/MembuatInvestasi/MembuatInvestasi.css new file mode 100644 index 0000000000000000000000000000000000000000..1c9cb546059529c4e9fa367f56e9b1e64add950b --- /dev/null +++ b/src/page/MembuatInvestasi/MembuatInvestasi.css @@ -0,0 +1,86 @@ +@import url('https://fonts.googleapis.com/css2?family=DM+Sans:ital,wght@0,400;0,500;0,700;1,400;1,500;1,700'); + +.mi-ctn { + font-family: 'DM Sans', sans-serif; +} + +.mi-title { + font-weight: bolder; +} + +.mi-subtitle { + font-weight: lighter; +} + +.mi-text-start { + text-align: start; +} + +.mi-card { + border: 1px solid #b5b5b5; + border-radius: 10px; +} + +.mi-title-divider { + border-top: 1px solid #146A5F; + width: 40vw; +} + +.mi-option-subtitle { + font-size: small; +} + +.mi-option-nominal { + font-size: large; + font-weight: 400; +} + +.mi-option-divider { + border-top: 1px solid black; + margin-left: 35px; +} + +.mi-option-radio { + width: 20px; + height: 20px; + position: absolute; + left: 0; + margin-left: 10px; +} + +.mi-option-info-margin { + margin-left: 45px; +} + +.mi-custom-option { + width: 220px; + height: inherit; + text-align: end; + font-size: large; + outline: none; + background-color: #b5b5b5; +} + +.mi-option-radio, .mi-card:hover { + cursor: pointer; +} + +.mi-card:hover { + box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.15); +} + +.mi-card-estimasi-keuangan:hover { + cursor: initial; + box-shadow: none; +} + +@media (min-width: 768px) { + + .mi-card-estimasi-keuangan { + margin-right: 5rem!important; + } + .mi-option-nominal, .mi-custom-option { + font-size: x-large; + } + +} \ No newline at end of file diff --git a/src/page/MembuatInvestasi/MembuatInvestasi.js b/src/page/MembuatInvestasi/MembuatInvestasi.js new file mode 100644 index 0000000000000000000000000000000000000000..5171f0c5ea5f1f955aa71f0cca0e244191749dbc --- /dev/null +++ b/src/page/MembuatInvestasi/MembuatInvestasi.js @@ -0,0 +1,173 @@ +import './MembuatInvestasi.css' +import OptionCard from '../../components/InvestasiOptionCard/OptionCard' +import CustomOptionCard from '../../components/InvestasiOptionCard/CustomOptionCard' +import { connect } from 'react-redux'; +import { Redirect } from 'react-router-dom'; +import axios from 'axios'; +import { useState, useEffect } from 'react'; + +export let utils = { + getPengadaanData: getPengadaan, + getTokoData: getToko, + getCardValue: getCheckedValue, + getCustomCardValue: getCustomValue, + postInvestasiData: postInvestasi +} + +const MembuatInvestasi = ({ isAuthenticated, match }) => { + + const [pengadaan, setPengadaan] = useState({'totalBiaya':0, 'estimasiKeuangan':''}) + const [toko, setToko] = useState({}) + + useEffect(() => { + utils.getPengadaanData(match.params.pk, setPengadaan) + utils.getTokoData(pengadaan.toko, setToko) + }, [match.params.pk, pengadaan]); + + const handleSubmit = e => { + <Redirect to="/" /> + utils.postInvestasiData(match.params.pk, utils.getCardValue()); + } + + if (!isAuthenticated) return <Redirect to="/masuk" /> + + return ( + <div className="container mt-5 overflow-hidden mi-ctn"> + <h4 className="mi-title">{toko.namaCabang}</h4> + <h6 className="mi-subtitle">{toko.namaToko}</h6> + + <hr className="mi-title-divider"/> + + <div className="row row-cols-1 row-cols-lg-2 mi-text-start mt-5"> + <div className="col px-4"> + <div className="row row-cols-1 row-cols-sm-2 gx-2"> + <OptionCard ratio={5} amount={pengadaan.totalBiaya*5/100} /> + <OptionCard ratio={10} amount={pengadaan.totalBiaya*10/100} /> + <OptionCard ratio={20} amount={pengadaan.totalBiaya*20/100} /> + <OptionCard ratio={50} amount={pengadaan.totalBiaya*50/100} /> + <OptionCard ratio={70} amount={pengadaan.totalBiaya*70/100} /> + <OptionCard ratio={100} amount={pengadaan.totalBiaya} /> + </div> + <div className="row"> + <CustomOptionCard maxx={pengadaan.totalBiaya} /> + </div> + </div> + + <div className="col px-5"> + <h5>Tata Cara Pembayaran</h5> + <ol className="text-start"> + <li>Lakukan pembayaran dengan nominal yang sesuai ke rekening XXXX-XXXX-XXXX-XXXX (a.n. Walkiddie Toys).</li> + <li>Konfirmasi pembayaran melalui XXXXXXXXXXX</li> + </ol> + + <h5 className="mt-4">Estimasi Keuangan</h5> + <div className="card mi-card mi-card-estimasi-keuangan"> + <div className="card-body"> + <p className="card-text">{pengadaan.estimasiKeuangan}</p> + </div> + </div> + </div> + </div> + <div className="row mt-4 mb-5"> + <div className="col"> + <button className="wkd-nav-button wkd-light-tosca-button" onClick={() => window.history.back()}>Kembali</button> + <button className="wkd-nav-button wkd-dark-green-button" onClick={() => handleSubmit()}>Buat Investasi</button> + </div> + </div> + </div> + ); +} + +const mapStateToProps = (state) => ({ + isAuthenticated: state.auth.isAuthenticated +}) + +export default connect(mapStateToProps)(MembuatInvestasi); + +function getCheckedValue() { + var val; + var radios = document.getElementsByName("mi-amount") + for (var i=0, len=radios.length; i<len; i++) { + if ( radios[i].checked ) { + val = radios[i].value; + break; + } + } + return val === "custom" ? utils.getCustomCardValue() : val; +} + +function getCustomValue() { + return document.getElementById("mi-custom-amount").value +} + +function postInvestasi(pk, nominal) { + if (localStorage.getItem('access')) { + var investasiFormData = new FormData(); + + const config = { + headers: { + 'Content-Type': 'application/json', + 'Authorization': `JWT ${localStorage.getItem('access')}`, + } + }; + + investasiFormData.append('nominal', nominal); + investasiFormData.append('pengadaan', pk); + + + try { + axios.post(`${process.env.REACT_APP_BACKEND_API_URL}/api/investasi/`, investasiFormData, config) + alert('Success post'); + } catch (err) { + alert('Error post'); + } + } else { + alert('missing token'); + } +} + +function getPengadaan(pk, callback) { + if (localStorage.getItem('access')) { + const config = { + headers: { + 'Authorization': `JWT ${localStorage.getItem('access')}`, + } + }; + + try { + axios.get(`${process.env.REACT_APP_BACKEND_API_URL}/api/pengadaan/${pk}`, config) + .then((response) => { + callback(response.data); + }) + } catch (err) { + console.log('Error get pengadaan'); + return null; + } + } else { + console.log('missing token'); + return null; + } +} + +function getToko(pk, callback) { + if (localStorage.getItem('access')) { + const config = { + headers: { + 'Authorization': `JWT ${localStorage.getItem('access')}`, + } + }; + + try { + axios.get(`${process.env.REACT_APP_BACKEND_API_URL}/api/toko/${pk}`, config) + .then((response) => { + callback(response.data); + }) + } catch (err) { + console.log('Error get toko'); + return null; + } + } else { + console.log('missing token'); + return null; + } +} diff --git a/src/page/MembuatInvestasi/MembuatInvestasi.test.js b/src/page/MembuatInvestasi/MembuatInvestasi.test.js new file mode 100644 index 0000000000000000000000000000000000000000..968d5e8fb4fcc8960671cbc8dc4062e05c9906cb --- /dev/null +++ b/src/page/MembuatInvestasi/MembuatInvestasi.test.js @@ -0,0 +1,163 @@ +import { render as rtlRender, act, fireEvent } from '@testing-library/react'; +import { MemoryRouter, Route } from 'react-router-dom'; +import { Provider } from 'react-redux'; +import { createStore } from 'redux'; +import MembuatInvestasi, { utils } from './MembuatInvestasi'; +import userEvent from '@testing-library/user-event'; +import axios from 'axios'; + +jest.mock('axios'); + +function render( + ui, + { + initialState = {auth: {isAuthenticated: true}}, + store = createStore(state => state, initialState), + ...renderOptions + } = {}, + ) { + function Wrapper({ children }) { + return <Provider store={store}><MemoryRouter initialEntries={["/investasi/1"]}>{children}</MemoryRouter></Provider> + } + return rtlRender(ui, { wrapper: Wrapper, ...renderOptions }) +} + +const mockMatch = { + params : { + pk : 1 + } +} + +describe('<Membuat Investasi />', () => { + it('should render correctly', () => { + const { getByText } = render(<MembuatInvestasi match={mockMatch} />); + expect(getByText(/Tata Cara Pembayaran/)).toBeInTheDocument() + expect(getByText(/Estimasi Keuangan/)).toBeInTheDocument() + }) + + it('should contains Option Cards components', () => { + const { getAllByTestId } = render(<MembuatInvestasi match={mockMatch} />); + expect(getAllByTestId("mi-opt-card")).not.toHaveLength(0) + expect(getAllByTestId("mi-custom-opt-card")).not.toHaveLength(0) + }) + + it('should contains Buat Investasi button', () => { + const { getByText } = render(<MembuatInvestasi match={mockMatch} />); + expect(getByText('Buat Investasi', {selector: "button"})).toBeInTheDocument() + }) + + it('should contains back button', () => { + const { getByText } = render(<MembuatInvestasi match={mockMatch} />); + expect(getByText('Kembali', {selector: "button"})).toBeInTheDocument() + }) + + it('should redirect to login page if not authenticated', () => { + let testLoc; + render( + <MemoryRouter initialEntries={["/investasi/1"]}> + <MembuatInvestasi match={mockMatch} /> + <Route + path="*" + render={({ location }) => { + testLoc = location; + return null; + }} + /> + </MemoryRouter>, + {initialState: {auth: {isAuthenticated: false}}} + ); + + expect(testLoc.pathname).toBe("/masuk"); + }) + + test('back button work correctly', () => { + const historyBack = jest.spyOn(window.history, 'back'); + historyBack.mockImplementation(() => {}); + + const { getByText } = render(<MembuatInvestasi match={mockMatch} />); + const backButton = getByText('Kembali', {selector: "button"}); + userEvent.click(backButton); + + expect(historyBack).toHaveBeenCalledTimes(1); + historyBack.mockRestore() + }) + + test('submit investasi form success and gives alert', () => { + const alert = jest.spyOn(window, 'alert'); + alert.mockImplementation(() => {}); + + axios.post.mockImplementationOnce(() => Promise.resolve()) + localStorage.setItem('access', 'token') + + const { getByText } = render(<MembuatInvestasi match={mockMatch} />); + const submitButton = getByText('Buat Investasi', {selector: "button"}); + + act(() => {fireEvent.click(submitButton)}); + expect(axios.post).toHaveBeenCalledTimes(1); + expect(alert).toHaveBeenCalledTimes(1); + alert.mockRestore(); + }) + + test('submit investasi form failed and gives alert', () => { + const alert = jest.spyOn(window, 'alert'); + alert.mockImplementation(() => {}); + + axios.post.mockImplementationOnce(() => Promise.reject()); + localStorage.setItem('access', 'token') + + const { getByText } = render(<MembuatInvestasi match={mockMatch} />); + const submitButton = getByText('Buat Investasi', {selector: "button"}); + + act(() => {fireEvent.click(submitButton)}); + expect(axios.post).toHaveBeenCalledTimes(1); + expect(alert).toHaveBeenCalledTimes(1); + alert.mockRestore(); + }) + + test('submit investasi form unauthenticated and gives alert', () => { + const alert = jest.spyOn(window, 'alert'); + alert.mockImplementation(() => {}); + + localStorage.removeItem('access','token'); + + const { getByText } = render(<MembuatInvestasi match={mockMatch} />); + const submitButton = getByText('Buat Investasi', {selector: "button"}); + + act(() => {fireEvent.click(submitButton)}); + expect(axios.post).not.toHaveBeenCalled(); + expect(alert).toHaveBeenCalledTimes(1); + alert.mockRestore(); + }) + + test('submit investasi form error and gives alert', () => { + const alert = jest.spyOn(window, 'alert'); + alert.mockImplementation(() => {}); + + axios.post.mockImplementationOnce(() => {throw new Error('Network Error')}); + localStorage.setItem('access', 'token') + + const { getByText } = render(<MembuatInvestasi match={mockMatch} />); + const submitButton = getByText('Buat Investasi', {selector: "button"}); + + act(() => {fireEvent.click(submitButton)}); + expect(alert).toHaveBeenCalledTimes(1); + alert.mockRestore(); + }) + + test('select investasi option card using the right function', () => { + const getCardValueMock = jest.spyOn(utils, 'getCardValue'); + const { getAllByTestId, getByText } = render(<MembuatInvestasi match={mockMatch} />); + + axios.post.mockImplementationOnce(() => Promise.resolve()) + localStorage.setItem('access', 'token') + + const submitButton = getByText('Buat Investasi', {selector: "button"}); + const optionCards = getAllByTestId("mi-radio-btn"); + + act(() => { + fireEvent.click(optionCards[0]); + fireEvent.click(submitButton); + }); + expect(getCardValueMock).toHaveBeenCalled(); + }) +}) \ No newline at end of file diff --git a/src/page/Profile/Profile.css b/src/page/Profile/Profile.css index 4ea20fcbc8d02a8b652066350ef13129ee5a3ba6..966a6c4ec3b87246a46d5efaff14cb8ffd8d652f 100644 --- a/src/page/Profile/Profile.css +++ b/src/page/Profile/Profile.css @@ -1,4 +1,4 @@ -@import url('https://fonts.googleapis.com/css2?family=DM+Sans:ital,wght@0,400;0,500;0,700;1,400;1,500;1,700&family=Nunito:wght@300;400;600;700;800&display=swap'); +@import url('https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;700&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Manrope:wght@500&display=swap'); /* latin-ext */ @@ -9,12 +9,12 @@ .profile-form{ margin-bottom: 120px; - margin-top: 50px; + margin-top: 20px; padding: 0 112px 0; } .profile-header{ - font-weight: 500; + font-weight: 700; font-size: 30px; line-height: 39px; text-align: left; @@ -43,6 +43,12 @@ label{ font-size: 14px; font-weight: bold; border-radius: 5px; + transition-duration: 0.3s; +} + +.password-button:hover { + background-color: #D3F1EE;/* Green */ + color: #146A5F; } .save-button { @@ -55,30 +61,41 @@ label{ font-size: 14px; font-weight: bold; border-radius: 5px; + transition-duration: 0.3s; +} + +.save-button:hover { + background-color: #0f4e46;/* Green */ } .cancel-button { height: 42px; width: 100%; - background-color: #D3F1EE;; /* Green */ + background-color: #D3F1EE; /* Green */ border: none; color: #146A5F; font-family: 'Manrope', sans-serif; font-size: 14px; font-weight: bold; border-radius: 5px; + transition-duration: 0.3s; } +.cancel-button:hover { + background-color: #bbdfdb;/* Green */ +} + + .button-wrapper{ padding-top: 16px; } .square-box-1{ box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.25); - padding: 31px 0px 0px; + padding: 30px 0px 0px; border-radius: 10px; width: 100%; - height: 260px; + height: 255px; text-align: center; } @@ -95,12 +112,14 @@ label{ } .data-type h3{ - font-weight: 700; + font-family: 'Manrope', sans-serif; + font-weight: 800; font-size: 30px; line-height: 60px; } .centered{ + font-family: 'DM Sans', sans-serif; text-align: left; display: block; margin-left: auto; @@ -166,14 +185,15 @@ input[type=number] { transition: .5s ease; } -.username-display{ - padding-top: 15px; +.name-display{ + padding-top: 18px; font-size: 22px; - font-weight: 600; + font-weight: bold; line-height: 20px; } .email-display{ + color:rgba(0, 0, 0, 0.568); font-size: 15px; line-height: 20px; padding-bottom: 15px; @@ -184,5 +204,4 @@ input[type=number] { text-align: center; border-bottom: 1px solid #ccc; line-height: 0.1em; - margin: 10px 0 20px; } diff --git a/src/page/Profile/Profile.js b/src/page/Profile/Profile.js index fc8a0f4dc8d9bed6aac9d2799c19a50914c6c5b1..88f52412ea12b9ea8d2a3006624ce8a4cefa55c2 100644 --- a/src/page/Profile/Profile.js +++ b/src/page/Profile/Profile.js @@ -1,48 +1,148 @@ import './Profile.css'; -import DefaultIcon from './default-profile.svg'; -import EditIcon from './pictures.svg'; +import defaultIcon from './user.svg'; +import editIcon from './pictures.svg'; import { ChevronLeft } from 'react-feather'; -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import { Row } from "react-bootstrap"; +import { connect } from 'react-redux'; +import { load_user, post_profile, update_profile, load_profile } from '../../actions/auth'; +import { Link, Redirect } from 'react-router-dom'; +import loadingIcon from '../../media/loading-icon.jpg'; -const Profile = () => { +const Profile = ({ load_user, isAuthenticated }) => { + const [data, setData] = useState([]); + const [profile, setProfile] = useState([]); + const [email, setEmail] = useState(''); + const [isFilled, setIsFilled] = useState(false); + const [imageChanged, setImageChaged] = useState(false); + const [preview, setPreview] = useState() + const [loading, setLoading] = useState(false); const [formData, setFormData] = useState({ - username: '', - email: '', - password: '', - full_name: '', address: '', phone_number: '', ktp_number: '', - birth_date:'' + birth_date:'', + profile_picture: null }); - const { username, email, password, full_name, address, phone_number, ktp_number, birth_date } = formData; + const imageUploader = React.useRef(null); + + useEffect(() => { + const fetchData = async () => { + try { + setLoading(true); + const result = await load_user(); + setLoading(false); + setData(result.res.data); + setEmail(result.res.data.email); + } + catch (err) { + + } + } + + fetchData(); + }, []); + + useEffect(() => { + const fetchData = async () => { + try { + const result = await load_profile()(email); + setProfile(result.res.data); + setIsFilled(true); + } + catch (err) { + setIsFilled(false); + } + } + + fetchData(); + }, [email]); + + useEffect(() => { + const setInitial = async () => { + setFormData({ + address: profile.address, + phone_number: profile.phone_number, + ktp_number: profile.ktp_number, + birth_date: profile.birth_date, + }); + } + setInitial(); + }, [profile]); + + const handleSubmit = async e => { + e.preventDefault(); + setLoading(true); + if(!isFilled){ + const res = await post_profile(email, full_name, address, phone_number, ktp_number, birth_date, profile_picture); + if (res.success){ + window.location.reload(false); + } else { + setLoading(false); + alert('Terjadi kesalahan, pastikan Anda mengisi semua data (termasuk foto profil)') + } + } else { + const res = await update_profile(email, full_name, address, phone_number, ktp_number, birth_date, profile_picture, imageChanged); + if (res.success){ + window.location.reload(false); + } else { + setLoading(false); + alert('Terjadi kesalahan, data anda gagal diubah') + } + } + }; + + const onFileChange = event => { + setFormData({ ...formData, profile_picture: event.target.files[0] }); + setImageChaged(true); + }; + + const { address, phone_number, ktp_number, birth_date, profile_picture } = formData; const onChange = e => setFormData({ ...formData, [e.target.name]: e.target.value }); + useEffect(() => { + if (!profile_picture) { + setPreview(undefined) + return + } + + const objectUrl = URL.createObjectURL(profile_picture) + setPreview(objectUrl) + + }, [profile_picture]) + + const full_name = data.first_name + " " + data.last_name; + + if (!isAuthenticated) { + return <Redirect to='/masuk' /> + } + return ( <div className="profile-form"> - <form className="centered"> - <h3 className="profile-header"><ChevronLeft size="40" className="chevron-left"/>Ubah Profile</h3> + <form className="centered" onSubmit={handleSubmit}> + <h3 className="profile-header"><Link to="/" style={{ color: 'rgb(0, 0, 0)' }} ><ChevronLeft size="40" className="chevron-left"/></Link>Ubah Profil</h3> <Row className="justify-content-center"> <div className="col-lg-3"> <div className="square-box-1"> <div className="default-icon"> - <img className="profile-icon" src={DefaultIcon} alt=""></img> - <div className="edit-wrapper"> - <img src={EditIcon} alt=""></img> + {!profile_picture && !isFilled && <img className="profile-icon" src={defaultIcon} alt=""></img>} + {!profile_picture && profile.profile_picture && <img className="profile-icon" src={profile.profile_picture} alt=""></img>} + {profile_picture && <img className="profile-icon" src={preview} alt=""></img>} + <div onClick={() => imageUploader.current.click()} className="edit-wrapper"> + <img src={editIcon} alt="change icon"></img> </div> </div> - <h4 className="username-display">@username12345</h4> - <p className="email-display">user12345@gmail.com</p> + <h4 className="name-display">{data.first_name}</h4> + <p className="email-display">{data.email}</p> <p className="midtext"></p> </div> - <Row className="justify-content-center button-wrapper"> + <Row className="button-wrapper"> <div className="col"> - <button className="cancel-button"> + <Link to="/"><button className="cancel-button" type="button"> Batalkan - </button> + </button></Link> </div> <div className="col"> <button className="save-button submit-button" type="submit"> @@ -51,6 +151,7 @@ const Profile = () => { </div> </Row> </div> + {loading && <img src={loadingIcon} id="loading-icon" alt="loading..." />} <div className="col-lg-9"> <div className="square-box-2"> <Row className="justify-content-center"> @@ -61,48 +162,16 @@ const Profile = () => { <h3>Data Pribadi</h3> </div> </Row> - <Row className="justify-content-center"> - <div className="col-sm"> - <div className="form-container centered"> - <label htmlFor='username'> Username </label> - <br></br> - <input - id='username' - type='text' - // placeholder='Tuliskan Nama Depan' - name='username' - value='username12345' - // onChange={e => onChange(e)} - disabled - /> - </div> - </div> - <div className="col-sm"> - <div className="form-container centered"> - <label htmlFor='full_name'> Nama Lengkap </label> - <br></br> - <input - id='full_name' - type='text' - name='full_name' - value='User Anon' - // onChange={e => onChange(e)} - disabled - /> - </div> - </div> - </Row> <Row className="justify-content-center"> <div className="col-sm"> <div className="form-container centered"> - <label htmlFor='email'> Email </label> + <label htmlFor='full_name'> Nama Lengkap </label> <br></br> <input - id='email' - type='email' - name='email' - value='user12345@gmail.com' - // onChange={e => onChange(e)} + id='full_name' + type='text' + name='full_name' + value= {full_name} disabled /> </div> @@ -128,14 +197,13 @@ const Profile = () => { <Row className="justify-content-center"> <div className="col-sm"> <div className="form-container centered"> - <label htmlFor='password'> Kata Sandi </label> + <label htmlFor='email'> Email </label> <br></br> <input - id='password' - type='password' - name='password' - value='useruser123' - // onChange={e => onChange(e)} + id='email' + type='email' + name='email' + value={data.email} disabled /> </div> @@ -160,14 +228,21 @@ const Profile = () => { </Row> <Row className="justify-content-center"> <div className="col-sm"> - <div className="form-container centered"></div> - <button className="password-button"> - Ubah Kata Sandi - </button> + <div className="form-container centered"> + <label htmlFor='password'> Kata Sandi </label> + <br></br> + <input + id='password' + type='password' + name='password' + value='useruser123' + disabled + /> + </div> </div> <div className="col-sm"> <div className="form-container centered"> - <label htmlFor='birth_date'> Tanggal Lahir </label> + <label htmlFor='birth_date'> Tanggal Lahir </label> <br></br> <input id='birth_date' @@ -182,8 +257,10 @@ const Profile = () => { </Row> <Row className="justify-content-center"> <div className="col-sm"> - <div className="form-container centered"> - </div> + <div className="form-container"></div> + <Link to="/reset-password"><button className="password-button" type="button"> + Lupa Kata Sandi + </button></Link> </div> <div className="col-sm"> <div className="form-container centered"> @@ -195,12 +272,23 @@ const Profile = () => { value={address} onChange={e => onChange(e)} required - rows="5" - max-rows="8" + rows="8" + max-rows="10" /> </div> </div> </Row> + <Row className="justify-content-center"> + <div className="col-sm"> + + </div> + <div className="col-sm"> + <div className="form-container" style={{display: "none"}}> + <label htmlFor='profile_picture'> Foto Profil </label> + <input type="file" id='profile_picture' accept="image/*" ref={imageUploader} onChange={onFileChange} /> + </div> + </div> + </Row> </div> </div> </Row> @@ -209,4 +297,9 @@ const Profile = () => { ); } -export default Profile; +const mapStateToProps = state => ({ + userData: state.auth.user, + isAuthenticated: state.auth.isAuthenticated +}); + +export default connect(mapStateToProps, { load_user })(Profile); diff --git a/src/page/Profile/Profile.test.js b/src/page/Profile/Profile.test.js index d55a3b0702fc18b58c534368cc4a8a6160357f6d..19a9a08b20ca026e17c298767102354578cd7f66 100644 --- a/src/page/Profile/Profile.test.js +++ b/src/page/Profile/Profile.test.js @@ -1,18 +1,47 @@ import Profile from './Profile'; +import { update_profile } from '../../actions/auth'; import '@testing-library/jest-dom'; -import { BrowserRouter } from 'react-router-dom' +import { BrowserRouter, Route } from 'react-router-dom' import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import axios from 'axios' +import configureStore from 'redux-mock-store' +import thunk from 'redux-thunk' +import { Provider } from 'react-redux' + +jest.mock('axios') + +const middlewares = [thunk] +const mockStore = configureStore(middlewares) describe('<Profile />', () => { it('renders correctly', () => { - const { getByText } = render(<BrowserRouter><Profile /></BrowserRouter>); - expect(getByText(/Ubah Profile/)).toBeInTheDocument(); + const mockLoadUser = jest.fn() + const mockAuthenticate = jest.fn() + const initialState = { auth: {isAuthenticated: true}} + const store = mockStore(initialState) + + const { getByText } = render( + <Provider store={store}> + <BrowserRouter> + <Profile load_user={mockLoadUser} isAuthenticated={mockAuthenticate}/> + </BrowserRouter> + </Provider>); + expect(getByText(/Ubah Profil/)).toBeInTheDocument(); }); it('renders the right contents', () => { - render(<BrowserRouter><Profile /></BrowserRouter>); - expect(screen.getByLabelText(/Username/)).toBeInTheDocument(); + const mockLoadUser = jest.fn() + const mockAuthenticate = jest.fn() + const initialState = { auth: {isAuthenticated: true}} + const store = mockStore(initialState) + render( + <Provider store={store}> + <BrowserRouter> + <Profile load_user={mockLoadUser} isAuthenticated={mockAuthenticate}/> + </BrowserRouter> + </Provider>); + expect(screen.getByLabelText(/Nama Lengkap/)).toBeInTheDocument(); expect(screen.getByLabelText(/Email/)).toBeInTheDocument(); expect(screen.getByLabelText(/Nomor Handphone/)).toBeInTheDocument(); @@ -20,38 +49,209 @@ describe('<Profile />', () => { expect(screen.getByLabelText(/Nomor KTP/)).toBeInTheDocument(); expect(screen.getByLabelText(/Tanggal Lahir/)).toBeInTheDocument(); expect(screen.getByLabelText(/Alamat Lengkap/)).toBeInTheDocument(); + expect(screen.getByAltText("loading...")).toBeInTheDocument(); }); + it('should redirect if not authenticated', () => { + let loc; + const mockLoadUser = jest.fn() + const initialState = { auth: {isAuthenticated: false}} + const store = mockStore(initialState) + render( + <Provider store={store}> + <BrowserRouter> + <Profile load_user={mockLoadUser} isAuthenticated={false}/> + <Route + path="*" + render={({location}) => { + loc = location; + return null; + }} + /> + </BrowserRouter> + </Provider> + ); + expect(loc.pathname).toBe('/masuk'); + }); + test('useState Function testing', () => { - const { getByLabelText } = render(<BrowserRouter><Profile /></BrowserRouter>); + const mockLoadUser = jest.fn() + const mockAuthenticate = jest.fn() + const initialState = { auth: {isAuthenticated: true}} + const store = mockStore(initialState) + const { getByLabelText } = render( + <Provider store={store}> + <BrowserRouter> + <Profile load_user={mockLoadUser} isAuthenticated={mockAuthenticate}/> + </BrowserRouter> + </Provider>); - const username = getByLabelText('Username'); - const nama_lengkap = getByLabelText('Nama Lengkap'); - const email = getByLabelText('Email'); - const password = getByLabelText('Kata Sandi'); const nomor_handphone = getByLabelText('Nomor Handphone'); const nomor_KTP = getByLabelText('Nomor KTP'); const tanggal_lahir = getByLabelText('Tanggal Lahir'); const alamat_lengkap = getByLabelText('Alamat Lengkap'); - userEvent.type(username, "username12345"); - userEvent.type(nama_lengkap, 'User Anon'); - userEvent.type(email, 'user12345@gmail.com'); - userEvent.type(password, 'useruser123'); userEvent.type(nomor_handphone, '081316086814'); userEvent.type(nomor_KTP, '1234567899876543'); userEvent.type(tanggal_lahir, '2021-03-21'); userEvent.type(alamat_lengkap, 'Jakarta Timur'); - expect(screen.getByLabelText('Username')).toHaveValue('username12345'); - expect(screen.getByLabelText('Nama Lengkap')).toHaveValue('User Anon'); - expect(screen.getByLabelText('Email')).toHaveValue('user12345@gmail.com'); - expect(screen.getByLabelText('Kata Sandi')).toHaveValue('useruser123'); expect(screen.getByLabelText('Nomor Handphone')).toHaveValue('081316086814'); expect(screen.getByLabelText('Nomor KTP')).toHaveValue('1234567899876543'); expect(screen.getByLabelText('Tanggal Lahir')).toHaveValue('2021-03-21'); expect(screen.getByLabelText('Alamat Lengkap')).toHaveValue('Jakarta Timur'); + }); + + test('submit through form', () => { + const mockLoadUser = jest.fn() + const mockAuthenticate = jest.fn() + global.URL.createObjectURL = jest.fn(); + const initialState = { auth: {isAuthenticated: true}} + const store = mockStore(initialState) + const { getByLabelText } = render( + <Provider store={store}> + <BrowserRouter> + <Profile load_user={mockLoadUser} isAuthenticated={mockAuthenticate}/> + </BrowserRouter> + </Provider>); + + const file = new File(['user'], 'user.png', { type: 'image/png' }) + + const profileData = { + data: { + email: "user12345@gmail.com", + full_name: "User Anon", + address: "Jakarta Timur", + phone_number: "081316086814", + ktp_number: "1234567899876543", + birth_date: "2021-03-21", + profile_picture: file + } + } + + const nama_lengkap = getByLabelText('Nama Lengkap'); + const email = getByLabelText('Email'); + const nomor_handphone = getByLabelText('Nomor Handphone'); + const nomor_KTP = getByLabelText('Nomor KTP'); + const tanggal_lahir = getByLabelText('Tanggal Lahir'); + const alamat_lengkap = getByLabelText('Alamat Lengkap'); + const profile_picture = getByLabelText('Foto Profil'); + + axios.post.mockImplementationOnce(() => Promise.resolve(profileData)); + + userEvent.type(nama_lengkap, 'User Anon'); + userEvent.type(email, 'user12345@gmail.com'); + userEvent.type(nomor_handphone, '081316086814'); + userEvent.type(nomor_KTP, '1234567899876543'); + userEvent.type(tanggal_lahir, '2021-03-21'); + userEvent.type(alamat_lengkap, 'Jakarta Timur'); + userEvent.click(screen.getByAltText("change icon")); + userEvent.upload(profile_picture, profile_picture, file); + userEvent.click(screen.getByText('Simpan')); + expect(axios.post).toHaveBeenCalledTimes(1); }); + test('Fail submit through form', () => { + const mockLoadUser = jest.fn() + const mockAuthenticate = jest.fn() + const initialState = { auth: {isAuthenticated: true}} + const store = mockStore(initialState) + const { getByLabelText } = render( + <Provider store={store}> + <BrowserRouter> + <Profile load_user={mockLoadUser} isAuthenticated={mockAuthenticate}/> + </BrowserRouter> + </Provider>); + + const profileData = { + data: { + email: "user12345@gmail.com", + full_name: "User Anon", + address: "Jakarta Timur", + phone_number: "081316086814", + ktp_number: "1234567899876543", + birth_date: "2021-03-21" + } + } + + const nama_lengkap = getByLabelText('Nama Lengkap'); + const email = getByLabelText('Email'); + const nomor_handphone = getByLabelText('Nomor Handphone'); + const nomor_KTP = getByLabelText('Nomor KTP'); + const tanggal_lahir = getByLabelText('Tanggal Lahir'); + const alamat_lengkap = getByLabelText('Alamat Lengkap'); + + axios.post.mockImplementationOnce(() => Promise.reject(profileData)); + + userEvent.type(nama_lengkap, 'User Anon'); + userEvent.type(email, 'user12345@gmail.com'); + userEvent.type(nomor_handphone, '081316086814'); + userEvent.type(nomor_KTP, '1234567899876543'); + userEvent.type(tanggal_lahir, '2021-03-21'); + userEvent.type(alamat_lengkap, 'Jakarta Timur'); + userEvent.click(screen.getByText('Simpan')); + + expect(axios.post).toHaveBeenCalledTimes(1); + }); + + test('update through form', () => { + const mockLoadUser = jest.fn() + const mockAuthenticate = jest.fn() + const initialState = { auth: {isAuthenticated: true}} + const store = mockStore(initialState) + render( + <Provider store={store}> + <BrowserRouter> + <Profile load_user={mockLoadUser} isAuthenticated={mockAuthenticate}/> + </BrowserRouter> + </Provider>); + + const file = new File(['user'], 'user.png', { type: 'image/png' }) + + const profileData = { + data: { + email: "user12345@gmail.com", + full_name: "User Anon", + address: "Jakarta Timur", + phone_number: "081316086814", + ktp_number: "1234567899876543", + birth_date: "2021-03-21", + profile_picture: file + } + } + + axios.put.mockImplementationOnce(() => Promise.resolve(profileData)); + + update_profile("user12345@gmail.com", "User Anon", "Jakarta Timur", "081316086814", "1234567899876543", "2021-03-21", file, true) + + expect(axios.put).toHaveBeenCalledTimes(1); + }); + + it('fetches successfully data from an API', async () => { + const mockLoadUser = jest.fn() + const mockAuthenticate = jest.fn() + const initialState = { auth: {isAuthenticated: true}} + const store = mockStore(initialState) + render( + <Provider store={store}> + <BrowserRouter> + <Profile load_user={mockLoadUser} isAuthenticated={mockAuthenticate}/> + </BrowserRouter> + </Provider>); + + const profileData = { + data: { + email: "user12345@gmail.com", + full_name: "User Anon", + address: "Jakarta Timur", + phone_number: "081316086814", + ktp_number: "1234567899876543", + birth_date: "2021-03-21" + } + } + + axios.get.mockImplementationOnce(() => Promise.resolve(profileData)); + }); + }); \ No newline at end of file diff --git a/src/page/Profile/default-profile.svg b/src/page/Profile/default-profile.svg deleted file mode 100644 index bc56b7f5a6a92412569ecb8ce56cce84697fa58a..0000000000000000000000000000000000000000 --- a/src/page/Profile/default-profile.svg +++ /dev/null @@ -1,3 +0,0 @@ -<svg width="102" height="102" viewBox="0 0 102 102" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M51 0C22.8364 0 0 22.8319 0 50.9978C0 79.1636 22.8342 101.996 51 101.996C79.1681 101.996 102 79.1636 102 50.9978C102 22.8319 79.1681 0 51 0ZM51 15.2489C60.3192 15.2489 67.8708 22.8028 67.8708 32.1175C67.8708 41.4344 60.3192 48.9861 51 48.9861C41.6853 48.9861 34.1337 41.4344 34.1337 32.1175C34.1337 22.8028 41.6853 15.2489 51 15.2489ZM50.9888 88.662C41.6943 88.662 33.1816 85.277 26.6156 79.6743C25.0161 78.3101 24.0932 76.3096 24.0932 74.2105C24.0932 64.7637 31.7389 57.2031 41.188 57.2031H60.8165C70.2678 57.2031 77.8844 64.7637 77.8844 74.2105C77.8844 76.3118 76.966 78.3078 75.3642 79.6721C68.8005 85.277 60.2856 88.662 50.9888 88.662Z" fill="#146A5F"/> -</svg> diff --git a/src/page/Profile/user.svg b/src/page/Profile/user.svg new file mode 100644 index 0000000000000000000000000000000000000000..496620905dd01443d111425bcb85ebad04cc393c --- /dev/null +++ b/src/page/Profile/user.svg @@ -0,0 +1,124 @@ +<?xml version="1.0" encoding="iso-8859-1"?> +<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> +<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" + viewBox="0 0 464 464" style="enable-background:new 0 0 464 464;" xml:space="preserve"> +<g> + <path style="fill:#F9EDE0;" d="M305.872,451.92c-2.416,0.816-4.848,1.608-7.296,2.336 + C301.032,453.52,303.456,452.728,305.872,451.92z"/> + <path style="fill:#F9EDE0;" d="M317.992,447.472c-2.608,1.04-5.216,2.064-7.872,3.008 + C312.776,449.528,315.392,448.512,317.992,447.472z"/> +</g> +<circle style="fill:#EFECE8;" cx="232" cy="232" r="232"/> +<g> + <path style="fill:#F9EDE0;" d="M293.896,455.584c-2.368,0.656-4.752,1.28-7.16,1.864 + C289.144,456.864,291.528,456.24,293.896,455.584z"/> + <path style="fill:#F9EDE0;" d="M215.192,463.328c-2.832-0.2-5.656-0.416-8.448-0.72 + C209.544,462.912,212.368,463.128,215.192,463.328z"/> + <path style="fill:#F9EDE0;" d="M177.256,457.44c-2.4-0.584-4.784-1.208-7.16-1.864C172.472,456.24,174.856,456.864,177.256,457.44z + "/> + <path style="fill:#F9EDE0;" d="M201.944,462c-2.536-0.328-5.064-0.672-7.576-1.08C196.872,461.328,199.408,461.664,201.944,462z"/> + <path style="fill:#F9EDE0;" d="M232,464c-4.272,0-8.504-0.136-12.72-0.36C223.496,463.864,227.728,464,232,464z"/> + <path style="fill:#F9EDE0;" d="M189.416,460.032c-2.432-0.448-4.856-0.928-7.256-1.456 + C184.56,459.104,186.984,459.584,189.416,460.032z"/> + <path style="fill:#F9EDE0;" d="M142.608,446.128c-3.608-1.512-7.176-3.096-10.688-4.776 + C135.44,443.032,139.008,444.624,142.608,446.128z"/> + <path style="fill:#F9EDE0;" d="M153.872,450.48c-2.648-0.952-5.264-1.968-7.872-3.008 + C148.608,448.512,151.224,449.528,153.872,450.48z"/> + <path style="fill:#F9EDE0;" d="M244.72,463.64c-4.216,0.224-8.448,0.36-12.72,0.36C236.272,464,240.504,463.864,244.72,463.64z"/> + <path style="fill:#F9EDE0;" d="M257.256,462.608c-2.8,0.304-5.624,0.52-8.448,0.72 + C251.632,463.128,254.456,462.912,257.256,462.608z"/> + <path style="fill:#F9EDE0;" d="M281.848,458.576c-2.408,0.528-4.824,1.008-7.256,1.456 + C277.016,459.584,279.44,459.104,281.848,458.576z"/> + <path style="fill:#F9EDE0;" d="M269.64,460.912c-2.512,0.408-5.04,0.752-7.576,1.08 + C264.592,461.664,267.128,461.328,269.64,460.912z"/> + <path style="fill:#F9EDE0;" d="M332.032,441.368c-3.496,1.672-7.048,3.256-10.64,4.76 + C324.984,444.624,328.536,443.048,332.032,441.368z"/> + <path style="fill:#F9EDE0;" d="M165.424,454.256c-2.456-0.736-4.88-1.528-7.296-2.336 + C160.544,452.728,162.968,453.52,165.424,454.256z"/> + <path style="fill:#F9EDE0;" d="M321.392,446.128c-1.12,0.472-2.264,0.888-3.392,1.336 + C319.12,447.016,320.264,446.6,321.392,446.128z"/> + <path style="fill:#F9EDE0;" d="M332.352,441.224c-0.104,0.048-0.216,0.096-0.32,0.144 + C332.136,441.32,332.248,441.28,332.352,441.224z"/> + <path style="fill:#F9EDE0;" d="M182.152,458.576c-1.64-0.36-3.272-0.736-4.896-1.128 + C178.88,457.84,180.512,458.216,182.152,458.576z"/> + <path style="fill:#F9EDE0;" d="M194.36,460.912c-1.656-0.272-3.304-0.576-4.952-0.88 + C191.064,460.336,192.704,460.648,194.36,460.912z"/> + <path style="fill:#F9EDE0;" d="M219.28,463.64c-1.368-0.072-2.728-0.216-4.088-0.312C216.56,463.424,217.912,463.568,219.28,463.64 + z"/> + <path style="fill:#F9EDE0;" d="M206.744,462.608c-1.608-0.176-3.2-0.4-4.8-0.608C203.544,462.208,205.136,462.432,206.744,462.608z + "/> + <path style="fill:#F9EDE0;" d="M131.928,441.352c-0.088-0.04-0.184-0.08-0.272-0.12 + C131.744,441.272,131.84,441.312,131.928,441.352z"/> + <path style="fill:#F9EDE0;" d="M248.808,463.328c-1.368,0.096-2.72,0.24-4.088,0.312 + C246.088,463.568,247.44,463.424,248.808,463.328z"/> + <path style="fill:#F9EDE0;" d="M298.576,454.256c-1.552,0.464-3.112,0.896-4.68,1.328 + C295.464,455.152,297.024,454.72,298.576,454.256z"/> + <path style="fill:#F9EDE0;" d="M310.128,450.48c-1.408,0.504-2.832,0.96-4.248,1.44C307.296,451.44,308.72,450.984,310.128,450.48z + "/> + <path style="fill:#F9EDE0;" d="M146.008,447.472c-1.128-0.448-2.272-0.872-3.392-1.336 + C143.736,446.6,144.88,447.016,146.008,447.472z"/> + <path style="fill:#F9EDE0;" d="M158.128,451.92c-1.416-0.48-2.848-0.936-4.248-1.44C155.28,450.984,156.704,451.44,158.128,451.92z + "/> + <path style="fill:#F9EDE0;" d="M262.056,462c-1.6,0.208-3.192,0.44-4.8,0.608C258.864,462.432,260.456,462.208,262.056,462z"/> + <path style="fill:#F9EDE0;" d="M286.744,457.44c-1.624,0.392-3.256,0.768-4.896,1.128 + C283.488,458.216,285.12,457.84,286.744,457.44z"/> + <path style="fill:#F9EDE0;" d="M274.584,460.032c-1.648,0.304-3.288,0.616-4.952,0.88 + C271.296,460.648,272.936,460.336,274.584,460.032z"/> + <path style="fill:#F9EDE0;" d="M170.104,455.584c-1.56-0.432-3.128-0.864-4.68-1.328 + C166.976,454.72,168.536,455.152,170.104,455.584z"/> +</g> +<path style="fill:#C6C3BD;" d="M285.104,247.952C310.952,230.744,328,201.376,328,168c0-53.016-42.984-96-96-96s-96,42.984-96,96 + c0,33.376,17.048,62.744,42.896,79.952c0,0,0.008,0.008,0.016,0.008c-0.008,0-0.008-0.008-0.008-0.008 + c-61.872,18.648-110.048,68.864-125.56,132.04L53.352,380c2.528,3.048,5.152,6.024,7.832,8.944c0.648,0.712,1.328,1.392,1.992,2.088 + c2.064,2.192,4.152,4.352,6.296,6.464c0.888,0.872,1.792,1.712,2.696,2.568c1.984,1.888,3.992,3.752,6.04,5.568 + c1.016,0.896,2.048,1.784,3.072,2.664c2.008,1.72,4.04,3.408,6.112,5.056c1.088,0.872,2.184,1.728,3.28,2.584 + c2.096,1.616,4.224,3.184,6.376,4.72c1.112,0.792,2.208,1.6,3.336,2.376c2.272,1.568,4.584,3.072,6.912,4.56 + c1.048,0.664,2.072,1.352,3.128,2.008c2.688,1.656,5.424,3.24,8.184,4.792c0.728,0.408,1.44,0.848,2.176,1.248 + c3.568,1.952,7.192,3.824,10.872,5.592c0.088,0.04,0.184,0.08,0.272,0.12c3.512,1.68,7.08,3.272,10.688,4.776 + c1.12,0.472,2.264,0.888,3.392,1.336c2.608,1.04,5.216,2.064,7.872,3.008c1.408,0.504,2.832,0.96,4.248,1.44 + c2.416,0.816,4.848,1.608,7.296,2.336c1.552,0.464,3.112,0.896,4.68,1.328c2.368,0.656,4.752,1.28,7.16,1.864 + c1.624,0.392,3.256,0.768,4.896,1.128c2.408,0.528,4.824,1.008,7.256,1.456c1.648,0.304,3.288,0.616,4.952,0.88 + c2.512,0.408,5.04,0.752,7.576,1.08c1.6,0.208,3.192,0.44,4.8,0.608c2.8,0.304,5.624,0.52,8.448,0.72 + c1.368,0.096,2.72,0.24,4.088,0.312c4.216,0.24,8.448,0.376,12.72,0.376s8.504-0.136,12.72-0.36 + c1.368-0.072,2.728-0.216,4.088-0.312c2.832-0.2,5.656-0.416,8.448-0.72c1.608-0.176,3.2-0.4,4.8-0.608 + c2.536-0.328,5.064-0.672,7.576-1.08c1.656-0.272,3.304-0.576,4.952-0.88c2.432-0.448,4.856-0.928,7.256-1.456 + c1.64-0.36,3.272-0.736,4.896-1.128c2.4-0.584,4.784-1.208,7.16-1.864c1.56-0.432,3.128-0.864,4.68-1.328 + c2.456-0.736,4.88-1.528,7.296-2.336c1.416-0.48,2.848-0.936,4.248-1.44c2.648-0.952,5.264-1.968,7.872-3.008 + c1.128-0.448,2.272-0.872,3.392-1.336c3.592-1.504,7.144-3.08,10.64-4.76c0.104-0.048,0.216-0.096,0.32-0.144 + c3.68-1.768,7.304-3.64,10.872-5.592c0.736-0.4,1.448-0.84,2.176-1.248c2.76-1.552,5.496-3.136,8.184-4.792 + c1.056-0.648,2.088-1.336,3.128-2.008c2.328-1.488,4.64-3,6.912-4.56c1.12-0.776,2.224-1.576,3.336-2.376 + c2.152-1.544,4.28-3.112,6.376-4.72c1.104-0.848,2.192-1.712,3.28-2.584c2.064-1.648,4.104-3.336,6.112-5.056 + c1.032-0.88,2.064-1.768,3.072-2.664c2.048-1.816,4.056-3.68,6.04-5.568c0.896-0.856,1.808-1.704,2.696-2.568 + c2.144-2.112,4.24-4.272,6.296-6.464c0.656-0.704,1.336-1.384,1.992-2.088c2.68-2.92,5.304-5.896,7.832-8.944l0.008-0.008 + C395.152,316.816,346.976,266.6,285.104,247.952z"/> +<g> +</g> +<g> +</g> +<g> +</g> +<g> +</g> +<g> +</g> +<g> +</g> +<g> +</g> +<g> +</g> +<g> +</g> +<g> +</g> +<g> +</g> +<g> +</g> +<g> +</g> +<g> +</g> +<g> +</g> +</svg> diff --git a/src/page/RegistrasiInvestor/RegistrasiInvestor.js b/src/page/RegistrasiInvestor/RegistrasiInvestor.js index d833771606e639235b5d6876556b7dde20dcf4d5..a283a8bdb1e9d5ac95e7fe2fdf39bc01da79c411 100644 --- a/src/page/RegistrasiInvestor/RegistrasiInvestor.js +++ b/src/page/RegistrasiInvestor/RegistrasiInvestor.js @@ -6,7 +6,6 @@ import { Link, Redirect } from 'react-router-dom'; import { Row } from "react-bootstrap"; import { connect } from 'react-redux'; import { signup } from '../../actions/auth'; -import axios from 'axios'; const RegistrasiInvestor = ({ signup, isAuthenticated })=> { const [formData, setFormData] = useState({ @@ -51,23 +50,23 @@ const RegistrasiInvestor = ({ signup, isAuthenticated })=> { return <Redirect to='/' /> } - const continueWithGoogle = async () => { - try { - // const res = await axios.get(`${process.env.REACT_APP_API_URL}/auth/o/google-oauth2/?redirect_uri=http://localhost:3000`) - const res = await axios.get(`${process.env.REACT_APP_BACKEND_API_URL}/auth/o/google-oauth2/?redirect_uri=https://walkiddie-toys-dev.herokuapp.com`) + // const continueWithGoogle = async () => { + // try { + // // const res = await axios.get(`${process.env.REACT_APP_API_URL}/auth/o/google-oauth2/?redirect_uri=http://localhost:3000`) + // const res = await axios.get(`${process.env.REACT_APP_BACKEND_API_URL}/auth/o/google-oauth2/?redirect_uri=https://walkiddie-toys-dev.herokuapp.com`) - window.location.replace(res.data.authorization_url); - } catch (err) { + // window.location.replace(res.data.authorization_url); + // } catch (err) { - } - }; + // } + // }; return ( <div id="signup"> <h1>< Buat Akun Baru <span id="walkiddie">Investor</span></h1> <div className="square-box"> <Row className="justify-content-center"> - <button className="submit-button google-button" type="button" onClick={continueWithGoogle}> + <button className="submit-button google-button" type="button"> <img className="google-image" src="https://www.freepnglogos.com/uploads/google-logo-png/google-logo-png-webinar-optimizing-for-success-google-business-webinar-13.png" alt="Google.png"/> <span> Daftar dengan Google diff --git a/src/page/RegistrasiMitra/RegistrasiMitra.js b/src/page/RegistrasiMitra/RegistrasiMitra.js index b0adfb4df8a103a9800c84b276b7f2270c0b4885..ec3672f95255d3c03a8bb54a1edb64ce69faee48 100644 --- a/src/page/RegistrasiMitra/RegistrasiMitra.js +++ b/src/page/RegistrasiMitra/RegistrasiMitra.js @@ -6,7 +6,6 @@ import { Link, Redirect } from 'react-router-dom'; import { Row } from "react-bootstrap"; import { connect } from 'react-redux'; import { signupMitra } from '../../actions/auth'; -import axios from 'axios'; const RegistrasiMitra = ({ signupMitra, isAuthenticated })=> { const [formData, setFormData] = useState({ @@ -51,23 +50,23 @@ const RegistrasiMitra = ({ signupMitra, isAuthenticated })=> { return <Redirect to='/' /> } - const continueWithGoogle = async () => { - try { - // const res = await axios.get(`${process.env.REACT_APP_API_URL}/auth/o/google-oauth2/?redirect_uri=http://localhost:3000`) - const res = await axios.get(`${process.env.REACT_APP_BACKEND_API_URL}/auth/o/google-oauth2/?redirect_uri=https://walkiddie-toys-dev.herokuapp.com`) + // const continueWithGoogle = async () => { + // try { + // // const res = await axios.get(`${process.env.REACT_APP_API_URL}/auth/o/google-oauth2/?redirect_uri=http://localhost:3000`) + // const res = await axios.get(`${process.env.REACT_APP_BACKEND_API_URL}/auth/o/google-oauth2/?redirect_uri=https://walkiddie-toys-dev.herokuapp.com`) - window.location.replace(res.data.authorization_url); - } catch (err) { + // window.location.replace(res.data.authorization_url); + // } catch (err) { - } - }; + // } + // }; return ( <div id="signup"> <h1>< Buat Akun Baru <span id="walkiddie">Mitra</span></h1> <div className="square-box"> <Row className="justify-content-center"> - <button className="submit-button google-button" type="button" onClick={continueWithGoogle}> + <button className="submit-button google-button" type="button"> <img className="google-image" src="https://www.freepnglogos.com/uploads/google-logo-png/google-logo-png-webinar-optimizing-for-success-google-business-webinar-13.png" alt="Google.png"/> <span> Daftar dengan Google