Compare commits
29 Commits
08a735bda5
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 249ae14a71 | |||
| 86afcefcf5 | |||
| 4621a83d3f | |||
| 8445937922 | |||
| 6e0325e52f | |||
| 0837d9c431 | |||
| 1f8b9c3674 | |||
| 68e9df3246 | |||
| 8b3dbb4846 | |||
| ccd05ffb97 | |||
| 59750206ab | |||
| 7535845a86 | |||
| 3f9f8db72c | |||
| 66fdbdd964 | |||
|
|
6cac9db408 | ||
| 8789963a7b | |||
| 5ee794edf4 | |||
| b59de00642 | |||
| 9f45efc9eb | |||
| a5737e12e6 | |||
| 3020d6b334 | |||
| d3c9662f82 | |||
| 7af549fb1d | |||
| f372ef6fb5 | |||
| d247e41d25 | |||
| 237112c302 | |||
| 2eaa11f790 | |||
| 7e3493005b | |||
| 564f21552d |
@@ -1,5 +1,3 @@
|
|||||||
# syntax=docker/dockerfile:1.7
|
|
||||||
|
|
||||||
FROM public.ecr.aws/docker/library/node:20-alpine AS deps
|
FROM public.ecr.aws/docker/library/node:20-alpine AS deps
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY package.json package-lock.json ./
|
COPY package.json package-lock.json ./
|
||||||
|
|||||||
BIN
dist/assets/BONK-CSOWwKRv.png
vendored
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
dist/assets/DOGE-DGKVmDxD.png
vendored
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
dist/assets/JUP-B5soXSmJ.png
vendored
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
BIN
dist/assets/PUMP-ICTVsk_g.png
vendored
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
dist/assets/RAY-DjdDnD_x.png
vendored
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
dist/assets/TRUMP-DhGGs5Yg.png
vendored
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
BIN
dist/assets/UNI-D58z1jTz.png
vendored
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
dist/assets/WIF-CBkpySMY.png
vendored
Normal file
|
After Width: | Height: | Size: 10 KiB |
189
dist/assets/index-B04m7avt.js
vendored
Normal file
1
dist/assets/index-BP0dDjYZ.css
vendored
1
dist/assets/index-CmBRAAIp.css
vendored
Normal file
161
dist/assets/index-DFLADCGY.js
vendored
97
dist/assets/popcat-DOGy5LFs.svg
vendored
@@ -1,97 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="Слой_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 994.3 1000.5" style="enable-background:new 0 0 994.3 1000.5;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{fill:#F7F5F8;}
|
|
||||||
.st1{fill:#DCC4D4;}
|
|
||||||
.st2{fill:#EFAD93;}
|
|
||||||
.st3{fill:#D68C72;}
|
|
||||||
.st4{fill:#964C49;}
|
|
||||||
.st5{fill:#3A0101;}
|
|
||||||
.st6{fill:#894544;}
|
|
||||||
.st7{fill:#E3746D;}
|
|
||||||
.st8{fill:#FFFFFF;}
|
|
||||||
.st9{fill:#623538;}
|
|
||||||
.st10{fill:#C95755;}
|
|
||||||
</style>
|
|
||||||
<g>
|
|
||||||
<path class="st0" d="M27.4,444.9l471.8-254l124.2-2.5c0,0,129.7,15.8,232.7,116.6c0.1,0.1,0.2,0.1,0.2,0.2
|
|
||||||
c28.2,27.7,54.4,62.5,75.1,106.3c1.4,2.9,2.8,5.9,4.1,8.9c0,0,151.2,244-41.3,456.4c-192.5,212.3-651.4,110.6-789.3-112.5
|
|
||||||
c-1-1.5-2-3.1-3-4.7c-21.2-34.1-37-67.9-48.6-99.2c-14.7-39.6-22.9-75.1-27.4-101.6C20.8,528.5,27.5,444.9,27.4,444.9z"/>
|
|
||||||
<path class="st1" d="M218.8,420.3c-31.3,88.9,7.8,189.9,85.9,99.6c111.2-153,321.4-183.3,405.1-172.5
|
|
||||||
c102.5,19.8,182.5,123.4,207.9,125.4c25.4,2,13.7-61.3,13.7-61.3c1.4,2.9,2.8,5.9,4.1,8.9c0,0,151.2,244-41.3,456.4
|
|
||||||
C701.7,1089.1,242.8,987.4,105,764.2c-1-1.5-2-3.1-3-4.7c-21.2-34.1-37-67.9-48.6-99.2C106.8,572.1,243.9,348.5,218.8,420.3z"/>
|
|
||||||
<path class="st2" d="M680.7,183.7c49.4-48.5,129.9-117.2,190.6-152.4c29.2-17,53.8-26.2,68.1-21.7c2.8,0.8,5.1,2.2,7.1,4.1
|
|
||||||
c23.7,23.2,14.4,169.4,3.6,279.9c-7,70.6-14.6,126.7-14.6,126.7c-15.5-33.2-32-65.7-81.8-118c-20.7-20.3-41.8-37.4-63.2-51.7
|
|
||||||
c-36-24-72.5-40.1-108.3-50.3c-4.8-1.4-9.6-2.6-14.4-3.8C671.8,192.5,676.1,188.2,680.7,183.7z"/>
|
|
||||||
<path class="st3" d="M871.3,31.4c-10.1,73.5-12.2,200.9,78.8,262.3c-7,70.6-14.6,126.7-14.6,126.7c-15.5-33.2-32-65.7-81.8-118
|
|
||||||
c-20.7-20.3-41.8-37.4-63.2-51.7c-36-24-72.5-40.1-108.3-50.3l-1.6-16.6C730.1,135.2,810.6,66.6,871.3,31.4z"/>
|
|
||||||
<path class="st4" d="M51.1,14.9c49.7-15.8,213.2,136.5,315.7,216.5c0,0,141.2-74,301.1-34.9c7.5,1.8,15.1,3.9,22.8,6.3
|
|
||||||
c-46.6-1.7-115.4-3.1-144.9,2.2C499,213.5,329,264,254.7,383.2c-74.3,119.1-71.3,258.8-69.5,320.2c1.4,48.9-34.4,79.5-88.3,48
|
|
||||||
c-44.5-74.3-63.2-146.8-71-192.6c-1.1-10.1-2.2-20.5-3.5-31c-0.8-6-1.4-12-2.1-17.9C-12.3,223.4,2.5,30.3,51.1,14.9z"/>
|
|
||||||
<path class="st4" d="M939.4,9.6c-41.2,32.2-128.1,113.5-148.9,241c-40.8-27.2-82.3-44.2-122.7-54.1C736,126.7,892.6-5,939.4,9.6z"
|
|
||||||
/>
|
|
||||||
<path class="st5" d="M667.3,196.7c18-21.7,38.7-41.3,59-60.8c30.9-28.7,63.1-56.1,97.5-80.5c23.1-16.3,47-31.5,73.2-42.8
|
|
||||||
c13.8-5.3,28.2-11.2,43.7-6.9c3.2,0.8,4.1,5.5,1.3,7.4c-48,35.5-89.8,81.2-115,136l-7.3,16.4l-6.3,16.8c-8.3,23.1-13.5,47.2-19,71
|
|
||||||
c-1.4,2.2-4.4,2.7-6.5,1.3c-9.3-6.2-18.7-12.1-28.3-17.7C730.6,220,699.1,207.3,667.3,196.7L667.3,196.7z M668.3,196.4
|
|
||||||
c33.5,5.2,65.5,17.4,95.4,33c10,5.2,19.8,11.1,29.3,17.3l-7.2,3.2c11.1-73.1,51.8-137.4,99-192.5c15.9-18.4,33.2-35.6,52-51.1
|
|
||||||
l1.3,7.4c-34.7-7-111.7,54.4-141.3,75.9C755.4,121.4,714.9,155,676,189.9C673.8,191.8,670.7,194.7,668.3,196.4L668.3,196.4z"/>
|
|
||||||
<path class="st5" d="M667,196.8c9.8-12.7,21.5-23.8,32.5-35.3c56.3-55.7,115.3-109,185.4-147.2C903.6,5.5,934-9.3,952.6,8
|
|
||||||
c8.6,9.3,11,23.4,12.9,34.8c7.6,63.5,0.5,127.1-5.9,190.2c-7.1,62.7-14.3,125.2-20.2,188c-0.1,1.2-0.9,2.5-2.1,3.1
|
|
||||||
c-1.9,1-4.3,0.2-5.3-1.7c-21.3-43.7-51.6-81.8-85.2-116.5c-29-28.5-61.5-53.6-97.1-73.3C723.7,217.7,695.1,206.6,667,196.8
|
|
||||||
L667,196.8z M668.6,196.3c102.9,16.6,200.3,90.3,251,181.1c7.4,13.4,13.7,27.4,19.6,41.3l-7.6,1.2c15.8-93,21.6-187.6,22.5-281.8
|
|
||||||
c0.1-30.9,0.3-62.6-4.6-92.8c-1.5-8.2-3.1-16-6.7-22.5c-2.2-3.9-5.1-5.3-10-5.6c-13.2-0.3-28,6.5-40.3,12.5
|
|
||||||
c-13.6,6.6-26.9,14.5-39.9,22.9c-62,40.5-119.8,87.7-175.4,136.6C674.9,191.3,671.1,194.7,668.6,196.3L668.6,196.3z"/>
|
|
||||||
<path class="st5" d="M368.1,222.4c0,0-27.7,15.2-48.3,39.2c32.8-26.4,66.9-39.2,66.9-39.2H368.1z"/>
|
|
||||||
<path class="st5" d="M51.4,15.6C-13.1,43.9,7.5,316.1,13.6,383c3.6,42.3,8.6,84.5,13.7,126.7c0.9,16.6,3.4,33.8,6.5,50.3
|
|
||||||
c15.8,83.2,49,164.3,101,231.4c162.6,201.4,596.3,285.2,772.8,64.1c93.2-112.3,103.3-255.1,47.5-387.3c-6.8-15.7-14.3-31.3-23-45.7
|
|
||||||
c-9.8-21.3-21.3-41.7-34.7-60.8C858,307,809.5,265.5,746.8,233.1c-117.3-59-260-50.3-377.9,2.6c-1.6,0.8-3.7,0.7-5.2-0.5
|
|
||||||
c-50.3-40.8-98.5-83.9-148.5-125C183.7,85.2,89.5,5.3,51.4,15.6L51.4,15.6z M50.9,14.1c38.2-10.9,133.1,68.2,166.8,93
|
|
||||||
c51.1,39.6,100.6,81.4,152,120.5l-5.2-0.5c10.1-5.3,20.2-9.7,30.6-13.9c113.6-45.9,247.7-50.1,357.9,7.6
|
|
||||||
c38.5,19.3,80,51.8,106.2,79.6c28.3,26.3,63.5,77.6,79.6,117.9c37.5,68.6,57.7,147.2,55.3,225.5c-2,78.7-32.2,155.1-80.9,216.3
|
|
||||||
c-144.1,184.7-435.8,164.2-626.6,69.8c-70.3-34.9-136.1-83.3-181-148.9c-52.9-79.3-87.3-177.1-92-270.3
|
|
||||||
c-12-126.6-19.9-254.6-7-381.4C10.8,98.9,18.7,25.8,50.9,14.1L50.9,14.1z"/>
|
|
||||||
<path class="st2" d="M56.5,68.9c10.8,4.5,48,42.6,88.9,92c33.1,40,68.6,87.5,94.4,130.5C256.3,318.9,134.9,522,113,560.3
|
|
||||||
c-20.1,35.1-64.5-92-76.1-226c-1.1-12-1.8-23.9-2.3-35.9C28.8,152.3,36.9,60.8,56.5,68.9z"/>
|
|
||||||
<path class="st6" d="M327.6,643.2c7.1-85.1,52.7-166.4,117.6-206.6c75-42,139.1-61.4,202.6-61.1l0,0c15.2,0.1,30.5,1.3,45.8,3.6
|
|
||||||
c15,2.3,30.1,5.6,45.5,9.9c66,18.5,208.6,88.2,186.5,282.8c-0.7,5.8-1.5,11.5-2.5,17.2C891,873.9,688.2,995.2,467.4,887.4
|
|
||||||
C358,834,319.8,736.3,327.6,643.2z"/>
|
|
||||||
<path class="st7" d="M636.5,336.4c9.7,2.9,32.2,11.3,56.1-1c23.9-12.3,33.2,15.1,20.5,22.1c-14.4,7.9-18.4,17-19.6,21.7
|
|
||||||
c-15.3-2.3-30.5-3.5-45.8-3.6l0,0c-4.1-7.4-25.4-8.4-33.2-21.1C606.7,341.7,626.8,333.4,636.5,336.4z"/>
|
|
||||||
<path class="st8" d="M386.7,314c6.2-5.8,12.6-10.9,19.1-15.3c58-40,121.3-28.3,130.8-3.7c10.6,27.3-35.8,36.7-64.2,48.6
|
|
||||||
c-25.9,10.8-56.1,30.6-78.7,43.5c-16.6,9.5-29.3,15.3-33.1,11.1C351.5,388.3,342.5,354.9,386.7,314z"/>
|
|
||||||
<path class="st8" d="M773.8,272.5c33.4,12.4,58.6,33.3,75,50.7c11.4,12.1,18.4,22.5,20.9,27.2c6.1,11.4-12.7,14-36.2,5.3
|
|
||||||
c-1-0.4-2.1-0.8-3.2-1.2c-25.3-9-84.3-25.6-101.1-33C705.1,310.9,717.2,251.5,773.8,272.5z"/>
|
|
||||||
<path class="st5" d="M405.8,298.7c58-40,121.3-28.3,130.8-3.7c10.6,27.3-35.8,36.7-64.2,48.6c-25.9,10.8-56.1,30.6-78.7,43.5
|
|
||||||
C370.3,352.9,386.3,320.8,405.8,298.7z"/>
|
|
||||||
<path class="st5" d="M773.8,272.5c33.4,12.4,58.6,33.3,75,50.7c0.6,10.9-2.7,23.7-18.5,31.3c-25.3-9-84.3-25.6-101.1-33
|
|
||||||
C705.1,310.9,717.2,251.5,773.8,272.5z"/>
|
|
||||||
<path class="st5" d="M504.4,274.3c-72.3-19-136.4,35.7-149,74s-0.5,51.9,0,40.6s0-28.9,18-52.9c18.1-24,76-50.5,76-50.5
|
|
||||||
S477.1,292.5,504.4,274.3z"/>
|
|
||||||
<path class="st5" d="M869.5,341.4c-20.4-25.1-54.2-47.2-54.2-47.2s5.1,17,18.1,25.7c13,8.8,37.3,35.8,37.3,35.8
|
|
||||||
S876.6,352.4,869.5,341.4z"/>
|
|
||||||
<path class="st8" d="M504.4,294.2c-8.5,0.9-74.6,10.1-65.2-3.7s34.7-12.3,55.5-10.7C517.1,281.5,512.9,293.4,504.4,294.2z"/>
|
|
||||||
<path class="st8" d="M803.6,314.5c-12.8-6.2-34.7-17.4-31.5-26s27.8,6.4,42.5,14C833.1,312,816.4,320.7,803.6,314.5z"/>
|
|
||||||
<path class="st9" d="M445.2,436.6c75-42,139.1-61.4,202.6-61.1l0,0c15.2,0.1,30.5,1.3,45.8,3.6c15,2.3,30.1,5.6,45.5,9.9
|
|
||||||
c66,18.5,208.6,88.2,186.5,282.7c-0.7,5.8-1.5,11.5-2.5,17.2C859.5,755.1,757.8,798,643,797.9c-139.3,0-259.6-63.2-315.5-154.7
|
|
||||||
C334.6,558.1,380.2,476.8,445.2,436.6z"/>
|
|
||||||
<path class="st5" d="M467,888.1c-4.1-2.1-15-8-19-10.1c-4.3-2.5-13.8-8.5-18.2-11.3c-5.7-3.9-11.5-8.7-17.3-12.6
|
|
||||||
c-12.8-10.7-25.3-22-35.9-35c-51-59.2-67.4-143.5-50-219.2c14.9-66.8,52.5-130.4,110.4-168.2c74.4-43.3,162.1-73,249-60.2
|
|
||||||
c66.6,9.1,131.6,37.9,178.2,87.3c47.5,48.6,68.8,117.8,66.7,185c-0.4,38.6-7.7,77.3-22.3,113.1C871.9,848.2,785.9,914.7,689,928
|
|
||||||
C613.2,939.7,535.3,921.3,467,888.1L467,888.1z M467.7,886.6c103.1,51,224,52.6,322.3-10.2c62.5-40,109.6-104.2,126.4-177.1
|
|
||||||
c12.6-54.7,12.2-114.2-9.7-166.5C878,462.3,811,414,739.3,394.7C633,365.6,539,391.2,446.1,446.3
|
|
||||||
C361.9,503,321.5,614.9,336.4,714.1c5.5,34.6,19.1,68.2,39.4,96.7c3.2,4,7.6,9.9,10.8,13.9c6.6,7.1,14.9,16.4,22.4,22.6l5.2,4.8
|
|
||||||
l5.6,4.3c6.3,5.3,16.2,11.9,23.2,16.3C449.7,877.2,460.6,882.6,467.7,886.6L467.7,886.6z"/>
|
|
||||||
<path class="st10" d="M624.5,349.4c9.9-5,28,14.1,28,14.1C630,361.9,614.5,354.5,624.5,349.4z"/>
|
|
||||||
<path class="st10" d="M709.7,347.4c-8.3-4.5-19.1,16.1-19.1,16.1C701.2,361.2,718,351.9,709.7,347.4z"/>
|
|
||||||
<path class="st3" d="M145.4,160.9c33.1,40,68.6,87.5,94.4,130.5c16.5,27.5-104.9,230.6-126.9,268.9c-20.1,35.1-64.5-92-76.1-226
|
|
||||||
C134.4,390.3,148.1,261.2,145.4,160.9z"/>
|
|
||||||
<path class="st5" d="M239.3,291.7C203,231.8,156.6,179,109.9,127.3C94.3,110.6,78.5,93.1,61,78.7c-2.4-1.8-4.8-3.7-6.8-4.5
|
|
||||||
c-2.9,2.5-5.2,9.1-6.4,13.8c-7.9,33.4-8.7,68.6-9.8,103.1c-0.4,23.2-0.5,46.6-0.3,69.9c-0.2,70,5.5,140.1,23.6,207.9
|
|
||||||
c5.3,20,24.9,86.9,43.7,93.3c1.6-0.1,2.6-1.2,3.6-2.7l0.9-1.5c3.4-7.1,73.1-128.3,78.8-138.8C201.1,395.1,248.5,315.1,239.3,291.7
|
|
||||||
L239.3,291.7z M240.3,291.1c10.1,18.9-35.6,108.8-46,131.3c-23,47.3-49.2,93.1-76.6,137.9c-2,4.1-7.1,10.6-13.3,9.8
|
|
||||||
c-30.8-4.3-55.4-138.4-61-168.9C30.8,332,27.6,261.4,27.8,191.1c0.8-28.9-0.2-103.5,17.4-124.3c7.7-8.1,16.3-2.5,22.8,3
|
|
||||||
c9.4,7.7,17.6,16.1,25.8,24.6C150,154,197.5,221.4,240.3,291.1L240.3,291.1z"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 8.6 KiB |
52
dist/assets/uni-C5oaqT41.svg
vendored
@@ -1,52 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 400 432.7" style="enable-background:new 0 0 400 432.7;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{fill:#F50DB4;}
|
|
||||||
.st1{fill-rule:evenodd;clip-rule:evenodd;fill:#F50DB4;}
|
|
||||||
</style>
|
|
||||||
<path class="st0" d="M325.1,65.4c0.6-10.2,2-17,4.8-23.1c1.1-2.4,2.1-4.4,2.3-4.4s-0.3,1.8-1.1,4c-2,6-2.4,14.2-1,23.7
|
|
||||||
c1.8,12.1,2.8,13.8,15.6,26.9c6,6.1,13,13.8,15.5,17.1l4.6,6l-4.6-4.3c-5.6-5.3-18.6-15.5-21.4-17c-1.9-1-2.2-1-3.4,0.2
|
|
||||||
c-1.1,1.1-1.3,2.7-1.5,10.4c-0.2,12-1.9,19.7-5.8,27.3c-2.1,4.2-2.5,3.3-0.5-1.4c1.4-3.5,1.6-5,1.6-16.6c0-23.3-2.8-28.9-19.1-38.5
|
|
||||||
c-4.1-2.4-10.9-5.9-15.1-7.8c-4.2-1.9-7.5-3.5-7.4-3.6c0.5-0.5,16.3,4.2,22.7,6.6c9.5,3.6,11.1,4.1,12.2,3.7
|
|
||||||
C324.4,74.2,324.8,72,325.1,65.4z"/>
|
|
||||||
<path class="st0" d="M124.4,31.5c-5.6-0.9-5.9-1-3.2-1.4c5.1-0.8,17.1,0.3,25.4,2.2c19.3,4.6,36.9,16.3,55.6,37l5,5.5l7.1-1.1
|
|
||||||
c30-4.8,60.6-1,86.1,10.8c7,3.2,18.1,9.7,19.5,11.3c0.4,0.5,1.3,3.9,1.8,7.5c1.9,12.5,0.9,22.1-2.9,29.3c-2.1,3.9-2.2,5.1-0.8,8.5
|
|
||||||
c1.1,2.7,4.3,4.6,7.4,4.6c6.3,0,13.2-10.2,16.3-24.4l1.3-5.6l2.5,2.8c13.7,15.4,24.4,36.4,26.2,51.3l0.5,3.9l-2.3-3.5
|
|
||||||
c-4-6.1-7.9-10.2-13-13.6c-9.2-6-18.9-8.1-44.5-9.4c-23.2-1.2-36.3-3.2-49.3-7.4c-22.1-7.2-33.3-16.7-59.6-51.1
|
|
||||||
c-11.7-15.2-18.9-23.7-26.1-30.5C161,42.8,145,34.7,124.4,31.5z"/>
|
|
||||||
<path class="st0" d="M135.4,105.3c-11.4-15.7-18.5-39.7-17-57.6l0.5-5.6l2.6,0.5c4.9,0.9,13.3,4,17.3,6.4
|
|
||||||
c10.8,6.5,15.5,15.2,20.3,37.3c1.4,6.5,3.2,13.8,4.1,16.3c1.4,4,6.5,13.3,10.7,19.4c3,4.4,1,6.4-5.6,5.8
|
|
||||||
C158,126.9,144.2,117.5,135.4,105.3z"/>
|
|
||||||
<path class="st0" d="M311.3,221.9c-53.5-21.4-72.3-40-72.3-71.4c0-4.6,0.2-8.4,0.4-8.4c0.2,0,2.3,1.5,4.6,3.4
|
|
||||||
c10.8,8.6,23,12.3,56.6,17.2c19.8,2.9,30.9,5.2,41.2,8.6c32.6,10.8,52.8,32.6,57.6,62.4c1.4,8.6,0.6,24.9-1.7,33.4
|
|
||||||
c-1.8,6.7-7.3,18.9-8.7,19.4c-0.4,0.1-0.8-1.4-0.9-3.5c-0.6-11.2-6.2-22-15.8-30.2C361.4,243.6,346.9,236.2,311.3,221.9z"/>
|
|
||||||
<path class="st0" d="M273.7,230.8c-0.7-4-1.8-9-2.6-11.3l-1.4-4l2.5,2.8c3.5,3.9,6.3,8.9,8.6,15.6c1.8,5.1,2,6.6,2,14.9
|
|
||||||
c0,8.1-0.2,9.8-1.9,14.4c-2.6,7.2-5.8,12.4-11.3,17.9c-9.8,9.9-22.3,15.4-40.4,17.6c-3.1,0.4-12.3,1.1-20.4,1.5
|
|
||||||
c-20.3,1.1-33.7,3.2-45.8,7.4c-1.7,0.6-3.3,1-3.4,0.8c-0.5-0.5,7.7-5.3,14.5-8.6c9.5-4.6,19-7.1,40.3-10.6
|
|
||||||
c10.5-1.7,21.4-3.9,24.1-4.7C264.6,276.7,278,256.2,273.7,230.8z"/>
|
|
||||||
<path class="st0" d="M298.2,274.1c-7.1-15.2-8.7-29.9-4.8-43.5c0.4-1.5,1.1-2.7,1.5-2.7c0.4,0,2.1,0.9,3.7,2
|
|
||||||
c3.3,2.2,9.8,5.9,27.3,15.4c21.8,11.8,34.3,21,42.7,31.5c7.4,9.2,12,19.6,14.2,32.3c1.3,7.2,0.5,24.6-1.3,31.8
|
|
||||||
c-5.9,22.9-19.5,40.9-39,51.4c-2.9,1.5-5.4,2.8-5.7,2.8c-0.3,0,0.8-2.6,2.3-5.8c6.5-13.6,7.3-26.8,2.3-41.6c-3-9-9.2-20-21.7-38.6
|
|
||||||
C305.4,287.5,301.8,281.7,298.2,274.1z"/>
|
|
||||||
<path class="st0" d="M97.4,356.1c19.8-16.7,44.5-28.5,67-32.1c9.7-1.6,25.8-0.9,34.8,1.3c14.4,3.7,27.3,11.9,33.9,21.6
|
|
||||||
c6.5,9.5,9.3,17.9,12.3,36.4c1.2,7.3,2.4,14.6,2.8,16.3c2.2,9.6,6.5,17.3,11.8,21.1c8.4,6.1,22.9,6.5,37.1,1
|
|
||||||
c2.4-0.9,4.5-1.6,4.7-1.4c0.5,0.5-6.7,5.3-11.7,7.8c-6.8,3.4-12.2,4.7-19.4,4.7c-13,0-23.9-6.6-32.9-20c-1.8-2.6-5.8-10.6-8.9-17.6
|
|
||||||
c-9.5-21.6-14.2-28.2-25.3-35.4c-9.6-6.3-22.1-7.4-31.4-2.8c-12.3,6-15.7,21.6-6.9,31.5c3.5,3.9,10,7.3,15.3,8
|
|
||||||
c10,1.2,18.5-6.3,18.5-16.3c0-6.5-2.5-10.2-8.8-13.1c-8.6-3.9-17.9,0.7-17.9,8.7c0,3.4,1.5,5.6,5,7.2c2.2,1,2.3,1.1,0.5,0.7
|
|
||||||
c-7.9-1.6-9.8-11.1-3.4-17.4c7.7-7.6,23.5-4.2,28.9,6.1c2.3,4.3,2.5,13,0.6,18.2c-4.5,11.7-17.4,17.8-30.6,14.5
|
|
||||||
c-9-2.3-12.6-4.7-23.4-15.8c-18.8-19.3-26.1-23-53.2-27.2l-5.2-0.8L97.4,356.1z"/>
|
|
||||||
<path class="st1" d="M9.2,11.5c62.8,75.7,106,107,110.8,113.6c4,5.5,2.5,10.4-4.3,14.2c-3.8,2.1-11.5,4.3-15.4,4.3
|
|
||||||
c-4.4,0-5.9-1.7-5.9-1.7c-2.6-2.4-4-2-17.1-25.1C59.1,88.8,43.9,65.5,43.5,65.1c-1-0.9-0.9-0.9,32,57.7c5.3,12.2,1.1,16.7,1.1,18.4
|
|
||||||
c0,3.5-1,5.4-5.4,10.3c-7.3,8.1-10.6,17.2-12.9,36.1c-2.6,21.1-10.1,36.1-30.7,61.6c-12.1,15-14,17.7-17.1,23.7
|
|
||||||
c-3.8,7.6-4.9,11.9-5.3,21.4c-0.5,10.1,0.4,16.7,3.5,26.4c2.7,8.5,5.6,14.1,12.9,25.3c6.3,9.7,9.9,16.9,9.9,19.7
|
|
||||||
c0,2.2,0.4,2.2,10.2,0.1c23.3-5.2,42.2-14.4,52.8-25.7c6.6-7,8.1-10.8,8.2-20.4c0-6.3-0.2-7.6-1.9-11.2c-2.8-5.9-7.8-10.7-18.9-18.3
|
|
||||||
c-14.5-9.9-20.8-17.9-22.5-28.8c-1.4-9,0.2-15.3,8.3-32.1c8.3-17.4,10.4-24.8,11.8-42.3c0.9-11.3,2.2-15.8,5.4-19.3
|
|
||||||
c3.4-3.7,6.5-5,14.9-6.1c13.7-1.9,22.5-5.4,29.7-12c6.2-5.7,8.9-11.2,9.3-19.5l0.3-6.3l-3.5-4C122.8,105.1,0.8,0,0,0
|
|
||||||
C-0.2,0,4,5.2,9.2,11.5z M38.5,305.9c2.9-5,1.3-11.5-3.4-14.7c-4.5-3-11.5-1.6-11.5,2.3c0,1.2,0.7,2.1,2.1,2.8
|
|
||||||
c2.5,1.3,2.7,2.7,0.7,5.7c-2,3-1.8,5.6,0.5,7.4C30.5,312.3,35.7,310.7,38.5,305.9z"/>
|
|
||||||
<path class="st1" d="M147.6,164.9c-6.5,2-12.7,8.8-14.7,15.9c-1.2,4.4-0.5,12,1.3,14.3c2.9,3.8,5.6,4.8,13.1,4.8
|
|
||||||
c14.7-0.1,27.5-6.4,29-14.2c1.2-6.4-4.4-15.3-12.1-19.2C160.2,164.4,151.7,163.6,147.6,164.9z M164.8,178.3c2.3-3.2,1.3-6.7-2.6-9
|
|
||||||
c-7.3-4.5-18.4-0.8-18.4,6.1c0,3.4,5.8,7.2,11.1,7.2C158.4,182.6,163.2,180.5,164.8,178.3z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 4.9 KiB |
4
dist/index.html
vendored
@@ -5,8 +5,8 @@
|
|||||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>ЭКСА — Ваш мост в мир цифровых активов</title>
|
<title>ЭКСА — Ваш мост в мир цифровых активов</title>
|
||||||
<script type="module" crossorigin src="/assets/index-DFLADCGY.js"></script>
|
<script type="module" crossorigin src="/assets/index-B04m7avt.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-BP0dDjYZ.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-CmBRAAIp.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
|||||||
154
install.ps1
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
# install.ps1 — One-line installer for codebase-memory-mcp (Windows).
|
||||||
|
#
|
||||||
|
# Usage: see README.md for install instructions.
|
||||||
|
#
|
||||||
|
# Environment:
|
||||||
|
# CBM_DOWNLOAD_URL Override base URL for downloads (for testing)
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
# Enforce TLS 1.2+ (older PowerShell defaults to TLS 1.0 which GitHub rejects)
|
||||||
|
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls13
|
||||||
|
|
||||||
|
$Repo = "DeusData/codebase-memory-mcp"
|
||||||
|
$InstallDir = "$env:LOCALAPPDATA\Programs\codebase-memory-mcp"
|
||||||
|
$BinName = "codebase-memory-mcp.exe"
|
||||||
|
$BaseUrl = if ($env:CBM_DOWNLOAD_URL) { $env:CBM_DOWNLOAD_URL } else { "https://github.com/$Repo/releases/latest/download" }
|
||||||
|
|
||||||
|
# Security: reject non-HTTPS download URLs (defense-in-depth)
|
||||||
|
if (-not $BaseUrl.StartsWith("https://") -and -not $BaseUrl.StartsWith("http://localhost") -and -not $BaseUrl.StartsWith("http://127.0.0.1")) {
|
||||||
|
Write-Host "error: refusing non-HTTPS download URL: $BaseUrl" -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Detect variant from args (--ui or --standard)
|
||||||
|
$Variant = "standard"
|
||||||
|
$SkipConfig = $false
|
||||||
|
foreach ($arg in $args) {
|
||||||
|
if ($arg -eq "--ui") { $Variant = "ui" }
|
||||||
|
if ($arg -eq "--standard") { $Variant = "standard" }
|
||||||
|
if ($arg -eq "--skip-config") { $SkipConfig = $true }
|
||||||
|
if ($arg -like "--dir=*") { $InstallDir = $arg.Substring(6) }
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "codebase-memory-mcp installer (Windows)"
|
||||||
|
Write-Host " variant: $Variant"
|
||||||
|
Write-Host " target: $InstallDir\$BinName"
|
||||||
|
Write-Host ""
|
||||||
|
|
||||||
|
# Build download URL
|
||||||
|
if ($Variant -eq "ui") {
|
||||||
|
$Archive = "codebase-memory-mcp-ui-windows-amd64.zip"
|
||||||
|
} else {
|
||||||
|
$Archive = "codebase-memory-mcp-windows-amd64.zip"
|
||||||
|
}
|
||||||
|
$Url = "$BaseUrl/$Archive"
|
||||||
|
|
||||||
|
# Download
|
||||||
|
$TmpDir = Join-Path ([System.IO.Path]::GetTempPath()) "cbm-install-$(Get-Random)"
|
||||||
|
New-Item -ItemType Directory -Path $TmpDir -Force | Out-Null
|
||||||
|
|
||||||
|
Write-Host "Downloading $Archive..."
|
||||||
|
try {
|
||||||
|
Invoke-WebRequest -Uri $Url -OutFile "$TmpDir\$Archive" -UseBasicParsing
|
||||||
|
} catch {
|
||||||
|
Write-Host "error: download failed: $_" -ForegroundColor Red
|
||||||
|
Remove-Item -Recurse -Force $TmpDir -ErrorAction SilentlyContinue
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Checksum verification
|
||||||
|
$ChecksumUrl = "$BaseUrl/checksums.txt"
|
||||||
|
try {
|
||||||
|
Invoke-WebRequest -Uri $ChecksumUrl -OutFile "$TmpDir\checksums.txt" -UseBasicParsing
|
||||||
|
$checksumLine = Get-Content "$TmpDir\checksums.txt" | Where-Object { $_ -like "*$Archive*" }
|
||||||
|
if ($checksumLine) {
|
||||||
|
$expected = ($checksumLine -split '\s+')[0]
|
||||||
|
$actual = (Get-FileHash -Path "$TmpDir\$Archive" -Algorithm SHA256).Hash.ToLower()
|
||||||
|
if ($expected -ne $actual) {
|
||||||
|
Write-Host "error: CHECKSUM MISMATCH!" -ForegroundColor Red
|
||||||
|
Write-Host " expected: $expected"
|
||||||
|
Write-Host " actual: $actual"
|
||||||
|
Remove-Item -Recurse -Force $TmpDir
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
Write-Host "Checksum verified."
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
Write-Host "warning: could not verify checksum (non-fatal)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Extract
|
||||||
|
Write-Host "Extracting..."
|
||||||
|
Expand-Archive -Path "$TmpDir\$Archive" -DestinationPath $TmpDir -Force
|
||||||
|
|
||||||
|
$DlBin = Join-Path $TmpDir $BinName
|
||||||
|
if (-not (Test-Path $DlBin)) {
|
||||||
|
# UI variant may have different name in zip
|
||||||
|
$UiBin = Join-Path $TmpDir "codebase-memory-mcp-ui.exe"
|
||||||
|
if (Test-Path $UiBin) {
|
||||||
|
Rename-Item $UiBin $BinName
|
||||||
|
$DlBin = Join-Path $TmpDir $BinName
|
||||||
|
} else {
|
||||||
|
Write-Host "error: binary not found after extraction" -ForegroundColor Red
|
||||||
|
Remove-Item -Recurse -Force $TmpDir
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Install
|
||||||
|
New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null
|
||||||
|
$Dest = Join-Path $InstallDir $BinName
|
||||||
|
|
||||||
|
# Handle replace-if-running (rename-aside)
|
||||||
|
if (Test-Path $Dest) {
|
||||||
|
$OldDest = "$Dest.old"
|
||||||
|
Remove-Item $OldDest -Force -ErrorAction SilentlyContinue
|
||||||
|
try {
|
||||||
|
Rename-Item $Dest $OldDest -ErrorAction Stop
|
||||||
|
} catch {
|
||||||
|
Write-Host "warning: could not rename existing binary (may be in use)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Copy-Item $DlBin $Dest -Force
|
||||||
|
|
||||||
|
# Verify
|
||||||
|
try {
|
||||||
|
$ver = & $Dest --version 2>&1
|
||||||
|
Write-Host "Installed: $ver"
|
||||||
|
} catch {
|
||||||
|
Write-Host "error: installed binary failed to run" -ForegroundColor Red
|
||||||
|
Remove-Item -Recurse -Force $TmpDir
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Configure agents
|
||||||
|
if ($SkipConfig) {
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Skipping agent configuration (--skip-config)"
|
||||||
|
} else {
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Configuring coding agents..."
|
||||||
|
try {
|
||||||
|
& $Dest install -y 2>&1 | Write-Host
|
||||||
|
} catch {
|
||||||
|
Write-Host "Agent configuration failed (non-fatal)."
|
||||||
|
Write-Host "Run manually: codebase-memory-mcp install"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add to PATH (user scope, no admin needed)
|
||||||
|
$UserPath = [Environment]::GetEnvironmentVariable("PATH", "User")
|
||||||
|
if ($UserPath -notlike "*$InstallDir*") {
|
||||||
|
[Environment]::SetEnvironmentVariable("PATH", "$UserPath;$InstallDir", "User")
|
||||||
|
$env:PATH = "$env:PATH;$InstallDir"
|
||||||
|
Write-Host "Added $InstallDir to user PATH"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
Remove-Item -Recurse -Force $TmpDir -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Done! Restart your terminal and coding agent to start using codebase-memory-mcp."
|
||||||
@@ -9,6 +9,11 @@ server {
|
|||||||
gzip_min_length 1024;
|
gzip_min_length 1024;
|
||||||
gzip_types text/plain text/css application/javascript application/json image/svg+xml;
|
gzip_types text/plain text/css application/javascript application/json image/svg+xml;
|
||||||
|
|
||||||
|
location = /healthcheck {
|
||||||
|
add_header Content-Type application/json;
|
||||||
|
return 200 'ok';
|
||||||
|
}
|
||||||
|
|
||||||
location /assets/ {
|
location /assets/ {
|
||||||
expires 1y;
|
expires 1y;
|
||||||
add_header Cache-Control "public, immutable";
|
add_header Cache-Control "public, immutable";
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
schema: spec-driven
|
||||||
|
created: 2026-06-29
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
## Context
|
||||||
|
|
||||||
|
Сегодня в `RouterProvider` есть два независимых маршрута под `ProtectedRoute`:
|
||||||
|
|
||||||
|
- `/profile` → `ProfilePage`, которая сама рендерит `WalletHeader` + `KycBanner` + `ProfileSummary` + блоки `ProfileDetails` / `SecuritySection` / `MnemonicSection` одним столбцом (`ProfilePage.module.css`, `.main` — flex с `max-width: 1024px`).
|
||||||
|
- `/transactions` → `TransactionsPage` внутри обёртки `WalletLayout` (`footer`), которая сама даёт `WalletHeader` + `<Outlet/>` + `Footer`. `TransactionsPage` хранит таб «Транзакции/Заявки» в локальном `useState` (заявки только для юр. лиц через `useMe()`).
|
||||||
|
|
||||||
|
Несогласованность обёрток (профиль рисует свой `WalletHeader`, транзакции — через `WalletLayout`) — главный технический момент, который нужно унифицировать при слиянии.
|
||||||
|
|
||||||
|
Существующие переиспользуемые части: виджеты `@widgets/profile` (баррель уже экспортирует `ProfileSummary`, `ProfileDetails`, `SecuritySection`, `MnemonicSection`, `KycBanner`, `ProfileSection`), `@widgets/transactions-list`, `@widgets/purchase-requests-list`, и `Spinner` из `@shared/ui/Spinner` (поддерживает `size`, `label`, `fullscreen`).
|
||||||
|
|
||||||
|
## Goals / Non-Goals
|
||||||
|
|
||||||
|
**Goals:**
|
||||||
|
- Единый раздел `/profile` с боковым меню 25% / контентом 75% и вложенными URL на каждый пункт.
|
||||||
|
- Переиспользовать существующие блоки профиля и виджеты транзакций без переписывания их логики.
|
||||||
|
- Сохранить текущее поведение транзакций (табы «Транзакции/Заявки» для юр. лиц) внутри пункта меню.
|
||||||
|
- Индикатор загрузки контента через существующий `Spinner`; меню остаётся доступным.
|
||||||
|
- Сохранить рабочими старые ссылки (`/transactions` → `/profile/transactions`).
|
||||||
|
- Сохранить мобильное поведение (стек в одну колонку < 1024px).
|
||||||
|
|
||||||
|
**Non-Goals:**
|
||||||
|
- Не меняем бизнес-логику профиля, авторизации, загрузки данных (`useMe`, профильные хуки) и API транзакций.
|
||||||
|
- Не добавляем новые пункты меню сверх перечисленных.
|
||||||
|
- Не трогаем дизайн-токены и глобальные стили, кроме новых модульных CSS для layout/меню.
|
||||||
|
- Не вводим менеджер состояния — навигация через URL (React Router).
|
||||||
|
|
||||||
|
## Decisions
|
||||||
|
|
||||||
|
### D1. Маршрутизация — вложенные routes с `<Outlet/>`, а не локальный `useState`
|
||||||
|
Использовать nested routes React Router: родитель `/profile` рендерит layout профиля (меню + `<Outlet/>`), дети — `details` / `security` / `mnemonic` / `transactions`. `index`-маршрут редиректит на `details` (`<Navigate to="details" replace />`).
|
||||||
|
|
||||||
|
- **Почему:** пользователь выбрал отдельные URL с поддержкой кнопки «Назад» и deep-link. `<Outlet/>` — идиоматичный для проекта способ (так уже сделан `WalletLayout`).
|
||||||
|
- **Альтернатива (отклонена):** один компонент с `useState` для активного пункта — нет deep-link и истории; противоречит выбранному варианту.
|
||||||
|
- **Альтернатива (отклонена):** `?tab=` query — менее явный URL, чем сегментный путь.
|
||||||
|
|
||||||
|
### D2. Структура компонентов
|
||||||
|
- `pages/profile/ui/ProfilePage.tsx` → становится layout-страницей: рендерит обёртку (см. D3), левое меню и `<Outlet/>` в правой колонке с `KycBanner` над `<Outlet/>`.
|
||||||
|
- Новый виджет навигации `@widgets/profile` → `ProfileMenu` (`ProfileSummary` сверху + список ссылок-пунктов через `NavLink`, активный пункт подсвечивается через `aria-current`/класс). Добавить в баррель `widgets/profile/index.ts`.
|
||||||
|
- Контент-пункты — тонкие компоненты-страницы в `pages/profile/ui/` (или существующие виджеты напрямую):
|
||||||
|
- `details` → `<ProfileDetails/>`
|
||||||
|
- `security` → `<SecuritySection/>`
|
||||||
|
- `mnemonic` → `<MnemonicSection/>`
|
||||||
|
- `transactions` → содержимое бывшей `TransactionsPage` (список + табы юр. лиц).
|
||||||
|
- `pages/transactions` сохраняется как тонкая обёртка/переиспользуемый блок, переносимый в пункт меню; маршрут `/transactions` заменяется на редирект.
|
||||||
|
|
||||||
|
### D3. Унификация обёртки (header/footer)
|
||||||
|
Завести профиль под общий `WalletLayout` (как транзакции), убрав собственный `WalletHeader` из `ProfilePage`. В `RouterProvider`:
|
||||||
|
```
|
||||||
|
<Route element={<WalletLayout footer />}>
|
||||||
|
<Route path={ROUTES.PROFILE} element={<ProfilePage />}>
|
||||||
|
<Route index element={<Navigate to="details" replace />} />
|
||||||
|
<Route path="details" element={<ProfileDetailsItem />} />
|
||||||
|
<Route path="security" element={<SecurityItem />} />
|
||||||
|
<Route path="mnemonic" element={<MnemonicItem />} />
|
||||||
|
<Route path="transactions" element={<TransactionsItem />} />
|
||||||
|
</Route>
|
||||||
|
</Route>
|
||||||
|
<Route path={ROUTES.TRANSACTIONS} element={<Navigate to="/profile/transactions" replace />} />
|
||||||
|
```
|
||||||
|
`ProfilePage` рендерит свой `<Outlet/>` для пунктов внутри двухколоночного layout — то есть здесь два уровня `Outlet` (внешний от `WalletLayout`, внутренний от `ProfilePage`). Это допустимо в React Router.
|
||||||
|
|
||||||
|
- **Почему:** единый `WalletHeader`/`Footer` устраняет рассинхрон обёрток и убирает дублирование.
|
||||||
|
- **Альтернатива (отклонена):** оставить профилю собственный header — расходится с остальными разделами и усложняет поддержку.
|
||||||
|
|
||||||
|
### D4. Маршруты в конфиге
|
||||||
|
Добавить в `shared/config/routes.ts` константы для вложенных путей профиля (например `PROFILE_DETAILS`, `PROFILE_SECURITY`, `PROFILE_MNEMONIC`, `PROFILE_TRANSACTIONS`) либо хелпер; `TRANSACTIONS` сохранить для обратного редиректа. Меню (`ProfileMenu`) строит ссылки из этих констант.
|
||||||
|
|
||||||
|
### D5. Состояние загрузки
|
||||||
|
В правой колонке каждый пункт сам отвечает за свою загрузку: пока соответствующий React Query запрос в состоянии загрузки — рендерить `<Spinner label="Загрузка" />` (по центру области контента, `fullscreen` в пределах колонки). Меню вне `<Outlet/>`, поэтому остаётся интерактивным. Сейчас профильные блоки делают `if (!data) return null` — заменить на показ `Spinner`, пока `useMe` грузится.
|
||||||
|
|
||||||
|
### D6. Стили
|
||||||
|
Новый `ProfilePage.module.css`: grid/flex `25% / 75%`, `gap`, и `@media (max-width: 1023px)` — стек в одну колонку (перенести существующие брейкпоинты профиля). Меню — отдельный `ProfileMenu.module.css` (список, активное состояние, sticky сводка по желанию). Всё на CSS Modules, без новых зависимостей.
|
||||||
|
|
||||||
|
## Risks / Trade-offs
|
||||||
|
|
||||||
|
- **Двойной `<Outlet/>` (WalletLayout → ProfilePage)** → может запутать при чтении роутера. Mitigation: явные комментарии в `RouterProvider` и в `ProfilePage`.
|
||||||
|
- **Профиль внутри `WalletLayout footer`** меняет наличие `Footer`/центрирование на странице профиля по сравнению с текущим видом → Mitigation: сверить визуально; при необходимости подобрать пропсы `WalletLayout` (`footer`/`center`).
|
||||||
|
- **Дублирование табов транзакций** при переносе в пункт меню → Mitigation: вынести содержимое `TransactionsPage` в переиспользуемый компонент, не копировать логику.
|
||||||
|
- **Ломающий редирект `/transactions`** → внешние ссылки продолжают работать через `<Navigate replace/>`; зафиксировано как BREAKING в proposal.
|
||||||
|
- **Регрессия мобильного вида профиля** → Mitigation: перенести существующие медиа-брейкпоинты профиля.
|
||||||
|
|
||||||
|
## Migration Plan
|
||||||
|
|
||||||
|
1. Добавить вложенные маршруты профиля и редирект `/transactions` в `RouterProvider` + константы в `routes.ts`.
|
||||||
|
2. Создать `ProfileMenu` и компоненты-пункты, переработать `ProfilePage` в layout.
|
||||||
|
3. Вынести содержимое `TransactionsPage` в переиспользуемый блок, подключить как пункт.
|
||||||
|
4. Добавить состояние загрузки (`Spinner`) в пунктах.
|
||||||
|
5. `npm run build` (tsc) + ручная проверка: deep-link каждого пункта, кнопка «Назад», редиректы `/profile` и `/transactions`, мобильный вид, юр.лицо vs физлицо (табы).
|
||||||
|
|
||||||
|
Откат: вернуть прежние отдельные маршруты `/profile` и `/transactions` (изменения изолированы в `pages/profile`, `pages/transactions`, `widgets/profile`, `routes.ts`, `RouterProvider`).
|
||||||
|
|
||||||
|
## Open Questions
|
||||||
|
|
||||||
|
- Нужно ли подсвечивать пункт «Транзакции» в верхней навигации (`WalletHeader`) как раздел профиля, или ссылка на транзакции из шапки ведёт прямо на `/profile/transactions`? (По умолчанию: шапка ведёт на `/profile/transactions`.)
|
||||||
|
- Делать ли блок `ProfileSummary` sticky при скролле длинного контента (например списка транзакций)? (По умолчанию: обычное позиционирование, без sticky.)
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
## Why
|
||||||
|
|
||||||
|
Сейчас профиль и транзакции — это две отдельные страницы (`/profile` и `/transactions`), между которыми нужно переключаться через общую навигацию. Профиль показывает все свои блоки (данные, безопасность, мнемоника) одним длинным скроллом. Объединение их в единый раздел с боковым меню даёт пользователю одну точку входа в «личный кабинет», убирает длинный скролл и делает транзакции равноправным пунктом наряду с настройками профиля.
|
||||||
|
|
||||||
|
## What Changes
|
||||||
|
|
||||||
|
- Страница профиля превращается в layout «личного кабинета»: слева колонка ~25% (меню), справа колонка ~75% (контент активного пункта).
|
||||||
|
- В левой колонке сверху всегда закреплён блок `ProfileSummary` (аватар + сводка), под ним — список пунктов меню.
|
||||||
|
- Существующие блоки профиля становятся пунктами меню и показываются в правой колонке по клику:
|
||||||
|
- **Данные профиля** (`ProfileDetails`) — пункт по умолчанию.
|
||||||
|
- **Безопасность** (`SecuritySection`).
|
||||||
|
- **Мнемоническая фраза** (`MnemonicSection`).
|
||||||
|
- **Транзакции** добавляются как ещё один пункт меню; в правой колонке рендерится содержимое бывшей `TransactionsPage` (список транзакций + табы «Транзакции / Заявки» для юр. лиц).
|
||||||
|
- Навигация между пунктами — через отдельные вложенные URL (`/profile/details`, `/profile/security`, `/profile/mnemonic`, `/profile/transactions`). Работают кнопка «Назад» и прямые ссылки.
|
||||||
|
- `/profile` редиректит на пункт по умолчанию (`/profile/details`).
|
||||||
|
- **BREAKING**: старый маршрут `/transactions` редиректит на `/profile/transactions`; отдельная страница транзакций в навигации больше не используется как самостоятельная.
|
||||||
|
- `KycBanner` отображается над контентом в правой колонке.
|
||||||
|
- Пока данные активного пункта загружаются, в правой колонке показывается индикатор загрузки (переиспользуется `Spinner` из `@shared/ui/Spinner`); меню остаётся доступным.
|
||||||
|
- Адаптив: на узких экранах (<1024px) меню и контент схлопываются в одну колонку, сохраняя текущее мобильное поведение профиля.
|
||||||
|
|
||||||
|
## Capabilities
|
||||||
|
|
||||||
|
### New Capabilities
|
||||||
|
- `profile-dashboard`: единый раздел личного кабинета с боковым меню (25/75), вложенной маршрутизацией по пунктам, закреплённой сводкой профиля, интеграцией транзакций как пункта меню и состоянием загрузки контента.
|
||||||
|
|
||||||
|
### Modified Capabilities
|
||||||
|
<!-- Нет существующих спеков, требующих изменения требований. -->
|
||||||
|
|
||||||
|
## Impact
|
||||||
|
|
||||||
|
- **pages**: `pages/profile` (переработка `ProfilePage` в layout с `<Outlet/>` или переключателем пунктов), `pages/transactions` (контент переезжает в пункт меню; маршрут редиректится).
|
||||||
|
- **widgets**: `widgets/profile` (новый виджет бокового меню / навигации; `ProfileSummary`, `ProfileDetails`, `SecuritySection`, `MnemonicSection`, `KycBanner` переиспользуются), `widgets/transactions-list`, `widgets/purchase-requests-list` (переиспользуются как контент пункта).
|
||||||
|
- **shared**: `shared/config/routes.ts` — новые вложенные маршруты профиля и редирект со старого `/transactions`; `shared/ui/Spinner` — переиспользуется.
|
||||||
|
- **app**: `app/providers/RouterProvider.tsx` — описание вложенных маршрутов под `ProtectedRoute`, согласование с `WalletLayout` (профиль сейчас рендерит собственный `WalletHeader`, а транзакции живут внутри `WalletLayout` — нужно унифицировать обёртку).
|
||||||
|
- Тестового раннера нет — проверка через `npm run build` (tsc) и ручной прогон.
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
## ADDED Requirements
|
||||||
|
|
||||||
|
### Requirement: Two-column dashboard layout
|
||||||
|
|
||||||
|
The profile section SHALL be presented as a two-column layout: a left menu column occupying approximately 25% of the available width and a right content column occupying approximately 75%. On viewports narrower than 1024px the two columns SHALL collapse into a single stacked column.
|
||||||
|
|
||||||
|
#### Scenario: Wide viewport shows two columns
|
||||||
|
- **WHEN** an authenticated user opens the profile section on a viewport ≥ 1024px wide
|
||||||
|
- **THEN** the left menu column (~25%) and the right content column (~75%) are displayed side by side
|
||||||
|
|
||||||
|
#### Scenario: Narrow viewport stacks columns
|
||||||
|
- **WHEN** an authenticated user opens the profile section on a viewport < 1024px wide
|
||||||
|
- **THEN** the menu and the content are stacked vertically in a single column
|
||||||
|
|
||||||
|
### Requirement: Pinned profile summary
|
||||||
|
|
||||||
|
The left menu column SHALL display the profile summary (`ProfileSummary` — avatar and identity) pinned at the top, above the list of menu items, and it SHALL remain visible regardless of which menu item is active.
|
||||||
|
|
||||||
|
#### Scenario: Summary visible on every item
|
||||||
|
- **WHEN** the user switches between any menu items
|
||||||
|
- **THEN** the profile summary remains displayed at the top of the left column
|
||||||
|
|
||||||
|
### Requirement: Menu items for profile sections and transactions
|
||||||
|
|
||||||
|
The left menu SHALL list selectable items for: Данные профиля (`ProfileDetails`), Безопасность (`SecuritySection`), Мнемоническая фраза (`MnemonicSection`), and Транзакции (transactions content). Selecting an item SHALL render its content in the right column, and the currently active item SHALL be visually highlighted.
|
||||||
|
|
||||||
|
#### Scenario: Selecting a menu item shows its content
|
||||||
|
- **WHEN** the user clicks a menu item
|
||||||
|
- **THEN** the right column renders that item's content and the clicked item is marked as active
|
||||||
|
|
||||||
|
#### Scenario: Transactions appears as a menu item
|
||||||
|
- **WHEN** the user views the profile menu
|
||||||
|
- **THEN** a «Транзакции» item is present alongside the profile section items, and selecting it renders the transactions content (list plus the «Транзакции / Заявки» tabs for legal-entity accounts)
|
||||||
|
|
||||||
|
### Requirement: Per-item routing with default redirect
|
||||||
|
|
||||||
|
Each menu item SHALL have its own URL under `/profile` (`/profile/details`, `/profile/security`, `/profile/mnemonic`, `/profile/transactions`) so that the browser Back button and direct links select the corresponding item. Navigating to `/profile` SHALL redirect to the default item `/profile/details`.
|
||||||
|
|
||||||
|
#### Scenario: Direct link opens the matching item
|
||||||
|
- **WHEN** the user navigates directly to `/profile/transactions`
|
||||||
|
- **THEN** the transactions item is active and its content is shown in the right column
|
||||||
|
|
||||||
|
#### Scenario: Bare profile path redirects to default
|
||||||
|
- **WHEN** the user navigates to `/profile`
|
||||||
|
- **THEN** the app redirects to `/profile/details` and shows the profile data item
|
||||||
|
|
||||||
|
#### Scenario: Back button restores previous item
|
||||||
|
- **WHEN** the user selects one item and then another, and then presses the browser Back button
|
||||||
|
- **THEN** the previously active item is restored
|
||||||
|
|
||||||
|
### Requirement: Legacy transactions route redirect
|
||||||
|
|
||||||
|
The legacy route `/transactions` SHALL redirect to `/profile/transactions` so existing links and bookmarks continue to work.
|
||||||
|
|
||||||
|
#### Scenario: Old transactions URL redirects
|
||||||
|
- **WHEN** the user navigates to `/transactions`
|
||||||
|
- **THEN** the app redirects to `/profile/transactions`
|
||||||
|
|
||||||
|
### Requirement: KYC banner placement
|
||||||
|
|
||||||
|
The KYC banner (`KycBanner`) SHALL be displayed above the content in the right column.
|
||||||
|
|
||||||
|
#### Scenario: KYC banner shown above content
|
||||||
|
- **WHEN** the profile section is displayed and the KYC banner is applicable
|
||||||
|
- **THEN** the banner appears above the active item's content in the right column
|
||||||
|
|
||||||
|
### Requirement: Loading state for content
|
||||||
|
|
||||||
|
While the data for the active menu item is loading, the right column SHALL show a loading indicator (the shared `Spinner`) while the left menu remains interactive.
|
||||||
|
|
||||||
|
#### Scenario: Spinner while data loads
|
||||||
|
- **WHEN** the active item's data is still loading
|
||||||
|
- **THEN** a loading indicator is shown in the right column and the user can still click other menu items
|
||||||
|
|
||||||
|
#### Scenario: Content replaces spinner when ready
|
||||||
|
- **WHEN** the active item's data finishes loading
|
||||||
|
- **THEN** the loading indicator is replaced by the item's content
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
## 1. Маршруты и конфиг
|
||||||
|
|
||||||
|
- [x] 1.1 Добавить в `shared/config/routes.ts` константы вложенных путей профиля (`PROFILE_DETAILS = '/profile/details'`, `PROFILE_SECURITY`, `PROFILE_MNEMONIC`, `PROFILE_TRANSACTIONS`); сохранить `TRANSACTIONS` для обратного редиректа.
|
||||||
|
- [x] 1.2 В `app/providers/RouterProvider.tsx` обернуть `ProfilePage` в `<WalletLayout footer />` и описать вложенные маршруты: `index` → `<Navigate to="details" replace />`, `details`, `security`, `mnemonic`, `transactions`.
|
||||||
|
- [x] 1.3 Заменить маршрут `/transactions` на `<Navigate to="/profile/transactions" replace />`; убрать прямой рендер `TransactionsPage` по `/transactions`.
|
||||||
|
- [x] 1.4 Добавить поясняющие комментарии о двух уровнях `<Outlet/>` (WalletLayout → ProfilePage).
|
||||||
|
|
||||||
|
## 2. Layout страницы профиля
|
||||||
|
|
||||||
|
- [x] 2.1 Переработать `pages/profile/ui/ProfilePage.tsx` в layout: убрать собственный `WalletHeader`; двухколоночная разметка — слева `ProfileMenu`, справа `KycBanner` над `<Outlet/>`.
|
||||||
|
- [x] 2.2 Обновить `pages/profile/ui/ProfilePage.module.css`: колонки ~25% / ~75% + `gap`; перенести медиа-брейкпоинты (< 1024px — стек в одну колонку, < 640px — паддинги).
|
||||||
|
|
||||||
|
## 3. Боковое меню (widget)
|
||||||
|
|
||||||
|
- [x] 3.1 Создать `widgets/profile/ui/ProfileMenu.tsx`: сверху закреплённый `ProfileSummary`, ниже список пунктов через `NavLink` (Данные профиля, Безопасность, Мнемоническая фраза, Транзакции) с подсветкой активного (`aria-current`/класс).
|
||||||
|
- [x] 3.2 Создать `widgets/profile/ui/ProfileMenu.module.css` (список, активное состояние, отступы).
|
||||||
|
- [x] 3.3 Экспортировать `ProfileMenu` из `widgets/profile/index.ts`.
|
||||||
|
|
||||||
|
## 4. Контент-пункты
|
||||||
|
|
||||||
|
- [x] 4.1 Создать компонент-пункт «Данные профиля» (рендерит `<ProfileDetails/>`); показывать `Spinner`, пока `useMe` грузится.
|
||||||
|
- [x] 4.2 Создать компонент-пункт «Безопасность» (`<SecuritySection/>`) с состоянием загрузки.
|
||||||
|
- [x] 4.3 Создать компонент-пункт «Мнемоническая фраза» (`<MnemonicSection/>`) с состоянием загрузки.
|
||||||
|
- [x] 4.4 Вынести содержимое `pages/transactions/ui/TransactionsPage.tsx` (список + табы «Транзакции/Заявки» для юр. лиц через `useMe`) в переиспользуемый блок и подключить как компонент-пункт «Транзакции»; показывать `Spinner` во время загрузки.
|
||||||
|
|
||||||
|
## 5. Состояние загрузки
|
||||||
|
|
||||||
|
- [x] 5.1 Заменить `if (!data) return null` в блоках профиля на отображение `<Spinner label="Загрузка" />` в области контента (меню остаётся доступным).
|
||||||
|
- [x] 5.2 Убедиться, что `Spinner` центрируется в правой колонке (использовать `fullscreen`/класс в пределах контента).
|
||||||
|
|
||||||
|
## 6. Проверка
|
||||||
|
|
||||||
|
- [x] 6.1 `npm run build` (tsc) проходит без ошибок типов и сборки.
|
||||||
|
- [ ] 6.2 Ручная проверка deep-link: прямой переход на `/profile/details`, `/profile/security`, `/profile/mnemonic`, `/profile/transactions` открывает нужный пункт.
|
||||||
|
- [ ] 6.3 `/profile` редиректит на `/profile/details`; `/transactions` редиректит на `/profile/transactions`.
|
||||||
|
- [ ] 6.4 Кнопка «Назад» переключает между ранее открытыми пунктами; активный пункт меню подсвечен.
|
||||||
|
- [ ] 6.5 Транзакции: для юр. лица видны табы «Транзакции/Заявки», для физлица — только список.
|
||||||
|
- [ ] 6.6 Мобильный вид (< 1024px): меню и контент схлопываются в одну колонку; `KycBanner` и `Spinner` отображаются корректно.
|
||||||
51
openspec/config.yaml
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
schema: spec-driven
|
||||||
|
|
||||||
|
# Project context (optional)
|
||||||
|
# This is shown to AI when creating artifacts.
|
||||||
|
# Add your tech stack, conventions, style guides, domain knowledge, etc.
|
||||||
|
context: |
|
||||||
|
Project: elcsa frontend — a crypto/finance web app (currency converter,
|
||||||
|
wallet, networks, auth) for the ЭКСА platform.
|
||||||
|
|
||||||
|
Tech stack:
|
||||||
|
- React 19 + Vite, TypeScript (strict, tsc -b before build)
|
||||||
|
- TanStack Query (React Query) for server state
|
||||||
|
- React Router for routing
|
||||||
|
- Plain CSS Modules (.module.css) — NO Tailwind, NO CSS-in-JS
|
||||||
|
- Design tokens live in src/app/styles/variables.css
|
||||||
|
|
||||||
|
Architecture — Feature-Sliced Design (FSD). Layers are strictly ordered;
|
||||||
|
a lower layer must never import from a higher one:
|
||||||
|
app → pages → widgets → features → entities → shared
|
||||||
|
Path aliases map to layers: @app/* @pages/* @widgets/* @features/*
|
||||||
|
@entities/* @shared/*. Each widget/feature owns its model/, ui/ and a
|
||||||
|
barrel index.ts.
|
||||||
|
|
||||||
|
Key conventions:
|
||||||
|
- Auth is two-step email+code for both register and login. Access token is
|
||||||
|
kept in an in-memory tokenStore (NOT localStorage); refreshed via an
|
||||||
|
HttpOnly cookie against the auth service. Every request attaches a cached
|
||||||
|
CSRF token and retries once on 401 after a silent refresh.
|
||||||
|
- Reusable UI lives in shared/ui (Button, PrimaryButton, FormField, Pill,
|
||||||
|
Title, TokenIcon, Notification), each with its own CSS Module.
|
||||||
|
- Routes are centralized in shared/config/routes.ts (ROUTES const).
|
||||||
|
ProtectedRoute / GuestRoute guard auth-only and guest-only pages.
|
||||||
|
- VITE_API_URL must be set (src/shared/config/env.ts).
|
||||||
|
- No test runner is configured.
|
||||||
|
|
||||||
|
# Per-artifact rules (optional)
|
||||||
|
# Add custom rules for specific artifacts.
|
||||||
|
rules:
|
||||||
|
proposal:
|
||||||
|
- Keep it concise and focused on user-facing behavior and the "why".
|
||||||
|
- State which FSD layer(s) the change touches and any cross-layer impact.
|
||||||
|
specs:
|
||||||
|
- Write requirements as observable behavior, not implementation details.
|
||||||
|
- Cover the error/edge paths (network failure, 401 refresh, validation).
|
||||||
|
design:
|
||||||
|
- Place new code in the correct FSD layer and justify the placement.
|
||||||
|
- Reuse existing shared/ui components and shared/api helpers before adding new ones.
|
||||||
|
- Note any new env vars, routes (ROUTES const), or React Query keys.
|
||||||
|
tasks:
|
||||||
|
- Break work into small, verifiable steps ordered by FSD dependency (shared → up).
|
||||||
|
- Include a "type-check passes (npm run build)" and "npm run lint" step; there are no automated tests.
|
||||||
107
openspec/specs/profile-dashboard/spec.md
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
# profile-dashboard
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
Единый раздел «личного кабинета» на `/profile`: боковое меню (25%) и контент (75%) с вложенной маршрутизацией по разделам. Объединяет блоки профиля (данные, безопасность, мнемоника) и транзакции в одну точку входа, с закреплённой сводкой профиля и состоянием загрузки контента.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
### Requirement: Two-column dashboard layout
|
||||||
|
|
||||||
|
The profile section SHALL be presented as a two-column layout: a left menu column occupying approximately 25% of the available width and a right content column occupying approximately 75%. On viewports narrower than 1024px the two columns SHALL collapse into a single stacked column.
|
||||||
|
|
||||||
|
#### Scenario: Wide viewport shows two columns
|
||||||
|
- **WHEN** an authenticated user opens the profile section on a viewport ≥ 1024px wide
|
||||||
|
- **THEN** the left menu column (~25%) and the right content column (~75%) are displayed side by side
|
||||||
|
|
||||||
|
#### Scenario: Narrow viewport stacks columns
|
||||||
|
- **WHEN** an authenticated user opens the profile section on a viewport < 1024px wide
|
||||||
|
- **THEN** the menu and the content are stacked vertically in a single column
|
||||||
|
|
||||||
|
### Requirement: Pinned profile summary
|
||||||
|
|
||||||
|
The left menu column SHALL display the profile summary (`ProfileSummary` — avatar and identity) pinned at the top, above the menu navigation, and it SHALL remain visible regardless of which menu item is active. On desktop the avatar and the "Добавить фото" button SHALL span the full width of the menu column.
|
||||||
|
|
||||||
|
#### Scenario: Summary visible on every item
|
||||||
|
- **WHEN** the user switches between any menu items
|
||||||
|
- **THEN** the profile summary remains displayed at the top of the left column
|
||||||
|
|
||||||
|
### Requirement: Menu items for profile sections and transactions
|
||||||
|
|
||||||
|
The left menu SHALL list selectable items for: Данные профиля (`ProfileDetails`), Безопасность (`SecuritySection`), Транзакции (transactions content), and Мнемоническая фраза (last item). Selecting an item SHALL render its content in the right column, and the currently active item SHALL be visually highlighted.
|
||||||
|
|
||||||
|
#### Scenario: Selecting a menu item shows its content
|
||||||
|
- **WHEN** the user clicks a menu item
|
||||||
|
- **THEN** the right column renders that item's content and the clicked item is marked as active
|
||||||
|
|
||||||
|
#### Scenario: Transactions appears as a menu item
|
||||||
|
- **WHEN** the user views the profile menu
|
||||||
|
- **THEN** a «Транзакции» item is present alongside the profile section items, and selecting it renders the transactions content (list plus the «Транзакции / Заявки» tabs for legal-entity accounts)
|
||||||
|
|
||||||
|
### Requirement: Mobile navigation via select
|
||||||
|
|
||||||
|
On viewports narrower than 1024px the left menu navigation SHALL be presented as a single select control (the shared `Select` component) instead of the full list, so only the chosen section is shown. Changing the select SHALL navigate to the corresponding section.
|
||||||
|
|
||||||
|
#### Scenario: Mobile uses a select
|
||||||
|
- **WHEN** an authenticated user opens the profile section on a viewport < 1024px wide
|
||||||
|
- **THEN** the section navigation is a select control reflecting the active section
|
||||||
|
|
||||||
|
#### Scenario: Changing the select navigates
|
||||||
|
- **WHEN** the user picks another section in the select
|
||||||
|
- **THEN** the app navigates to that section's URL and renders its content
|
||||||
|
|
||||||
|
### Requirement: Mnemonic reveal requires explicit action
|
||||||
|
|
||||||
|
The «Мнемоническая фраза» item SHALL show the seed-phrase content inline (12-word grid with show/hide and copy), but the mnemonic SHALL be fetched only after the user explicitly requests it via a "Показать мнемонику" button. Until then no mnemonic request is made.
|
||||||
|
|
||||||
|
#### Scenario: Mnemonic gated behind a button
|
||||||
|
- **WHEN** the user opens the «Мнемоническая фраза» item
|
||||||
|
- **THEN** a warning and a "Показать мнемонику" button are shown, and no mnemonic request has been sent
|
||||||
|
|
||||||
|
#### Scenario: Revealing fetches and shows the seed phrase
|
||||||
|
- **WHEN** the user clicks "Показать мнемонику"
|
||||||
|
- **THEN** the mnemonic is fetched (a loading indicator is shown) and the seed-phrase content is rendered inline
|
||||||
|
|
||||||
|
### Requirement: Per-item routing with default redirect
|
||||||
|
|
||||||
|
Each menu item SHALL have its own URL under `/profile` (`/profile/details`, `/profile/security`, `/profile/mnemonic`, `/profile/transactions`) so that the browser Back button and direct links select the corresponding item. Navigating to `/profile` SHALL redirect to the default item `/profile/details`.
|
||||||
|
|
||||||
|
#### Scenario: Direct link opens the matching item
|
||||||
|
- **WHEN** the user navigates directly to `/profile/transactions`
|
||||||
|
- **THEN** the transactions item is active and its content is shown in the right column
|
||||||
|
|
||||||
|
#### Scenario: Bare profile path redirects to default
|
||||||
|
- **WHEN** the user navigates to `/profile`
|
||||||
|
- **THEN** the app redirects to `/profile/details` and shows the profile data item
|
||||||
|
|
||||||
|
#### Scenario: Back button restores previous item
|
||||||
|
- **WHEN** the user selects one item and then another, and then presses the browser Back button
|
||||||
|
- **THEN** the previously active item is restored
|
||||||
|
|
||||||
|
### Requirement: Legacy transactions route redirect
|
||||||
|
|
||||||
|
The legacy route `/transactions` SHALL redirect to `/profile/transactions` so existing links and bookmarks continue to work.
|
||||||
|
|
||||||
|
#### Scenario: Old transactions URL redirects
|
||||||
|
- **WHEN** the user navigates to `/transactions`
|
||||||
|
- **THEN** the app redirects to `/profile/transactions`
|
||||||
|
|
||||||
|
### Requirement: KYC banner placement
|
||||||
|
|
||||||
|
The KYC banner (`KycBanner`) SHALL be displayed above the content in the right column.
|
||||||
|
|
||||||
|
#### Scenario: KYC banner shown above content
|
||||||
|
- **WHEN** the profile section is displayed and the KYC banner is applicable
|
||||||
|
- **THEN** the banner appears above the active item's content in the right column
|
||||||
|
|
||||||
|
### Requirement: Loading state for content
|
||||||
|
|
||||||
|
While the data for the active menu item is loading, the right column SHALL show a loading indicator (the shared `Spinner`) while the left menu remains interactive.
|
||||||
|
|
||||||
|
#### Scenario: Spinner while data loads
|
||||||
|
- **WHEN** the active item's data is still loading
|
||||||
|
- **THEN** a loading indicator is shown in the right column and the user can still navigate to other menu items
|
||||||
|
|
||||||
|
#### Scenario: Content replaces spinner when ready
|
||||||
|
- **WHEN** the active item's data finishes loading
|
||||||
|
- **THEN** the loading indicator is replaced by the item's content
|
||||||
1
payment.json
Normal file
@@ -1,13 +1,14 @@
|
|||||||
import { Navigate, Outlet, useLocation } from 'react-router-dom'
|
import { Navigate, Outlet, useLocation } from 'react-router-dom'
|
||||||
import { useIsAuthenticated } from '@features/auth'
|
import { useIsAuthenticated } from '@features/auth'
|
||||||
import { ROUTES } from '@shared/config/routes'
|
import { ROUTES } from '@shared/config/routes'
|
||||||
|
import { Spinner } from '@shared/ui'
|
||||||
|
|
||||||
export function GuestRoute() {
|
export function GuestRoute() {
|
||||||
const { isAuthenticated, isLoading } = useIsAuthenticated()
|
const { isAuthenticated, isLoading } = useIsAuthenticated()
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
const from = (location.state as { from?: { pathname: string } })?.from?.pathname ?? ROUTES.WALLET
|
const from = (location.state as { from?: { pathname: string } })?.from?.pathname ?? ROUTES.WALLET
|
||||||
|
|
||||||
if (isLoading) return null
|
if (isLoading) return <Spinner overlay size="lg" label="Загрузка" />
|
||||||
if (isAuthenticated) return <Navigate to={from} replace />
|
if (isAuthenticated) return <Navigate to={from} replace />
|
||||||
return <Outlet />
|
return <Outlet />
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import { Navigate, Outlet, useLocation } from 'react-router-dom'
|
import { Navigate, Outlet, useLocation } from 'react-router-dom'
|
||||||
import { useIsAuthenticated } from '@features/auth'
|
import { useIsAuthenticated } from '@features/auth'
|
||||||
import { ROUTES } from '@shared/config/routes'
|
import { ROUTES } from '@shared/config/routes'
|
||||||
|
import { Spinner } from '@shared/ui'
|
||||||
|
|
||||||
export function ProtectedRoute() {
|
export function ProtectedRoute() {
|
||||||
const { isAuthenticated, isLoading } = useIsAuthenticated()
|
const { isAuthenticated, isLoading } = useIsAuthenticated()
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
|
|
||||||
if (isLoading) return null
|
if (isLoading) return <Spinner overlay size="lg" label="Загрузка" />
|
||||||
if (!isAuthenticated) return <Navigate to={ROUTES.LOGIN} state={{ from: location }} replace />
|
if (!isAuthenticated) return <Navigate to={ROUTES.LOGIN} state={{ from: location }} replace />
|
||||||
return <Outlet />
|
return <Outlet />
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { BrowserRouter, Route, Routes } from 'react-router-dom'
|
import { BrowserRouter, Navigate, Route, Routes } from 'react-router-dom'
|
||||||
import { HomePage } from '@pages/home'
|
import { HomePage } from '@pages/home'
|
||||||
import { WalletPage } from '@pages/wallet'
|
import { WalletPage } from '@pages/wallet'
|
||||||
import { SwapPage } from '@pages/swap'
|
import { SwapPage } from '@pages/swap'
|
||||||
import { BridgePage } from '@pages/bridge'
|
import { BridgePage } from '@pages/bridge'
|
||||||
import { ProfilePage } from '@pages/profile'
|
import { ProfilePage, ProfileDetailsItem, SecurityItem, MnemonicItem, TransactionsItem } from '@pages/profile'
|
||||||
import { LoginPage } from '@pages/login'
|
import { LoginPage } from '@pages/login'
|
||||||
import { RegisterPage } from '@pages/register'
|
import { RegisterPage } from '@pages/register'
|
||||||
import { RegisterTestPage } from '@pages/register-test'
|
import { RegisterTestPage } from '@pages/register-test'
|
||||||
@@ -16,9 +16,9 @@ import { PolitikaPage } from '@pages/politika-personalnyh-dannyh'
|
|||||||
import { PolitikaCookiePage } from '@pages/politika-cookie'
|
import { PolitikaCookiePage } from '@pages/politika-cookie'
|
||||||
import { SoglasiePage } from '@pages/soglasie-personalnyh-dannyh'
|
import { SoglasiePage } from '@pages/soglasie-personalnyh-dannyh'
|
||||||
import { ReestryPage } from '@pages/reestr-pd-rkn'
|
import { ReestryPage } from '@pages/reestr-pd-rkn'
|
||||||
import { TransactionsPage } from '@pages/transactions'
|
|
||||||
import { StakingPage } from '@pages/staking'
|
import { StakingPage } from '@pages/staking'
|
||||||
import { PoolsPage } from '@pages/pools'
|
import { PoolsPage } from '@pages/pools'
|
||||||
|
import { NotFoundPage } from '@pages/not-found'
|
||||||
import { WalletLayout } from '@widgets/wallet-layout'
|
import { WalletLayout } from '@widgets/wallet-layout'
|
||||||
import { ROUTES } from '@shared/config/routes'
|
import { ROUTES } from '@shared/config/routes'
|
||||||
import { ScrollToTop } from './ScrollToTop'
|
import { ScrollToTop } from './ScrollToTop'
|
||||||
@@ -52,17 +52,30 @@ export function RouterProvider() {
|
|||||||
<Route element={<WalletLayout footer />}>
|
<Route element={<WalletLayout footer />}>
|
||||||
<Route path={ROUTES.SWAP} element={<SwapPage />} />
|
<Route path={ROUTES.SWAP} element={<SwapPage />} />
|
||||||
<Route path={ROUTES.BRIDGE} element={<BridgePage />} />
|
<Route path={ROUTES.BRIDGE} element={<BridgePage />} />
|
||||||
<Route path={ROUTES.TRANSACTIONS} element={<TransactionsPage />} />
|
|
||||||
<Route path={ROUTES.STAKING} element={<StakingPage />} />
|
<Route path={ROUTES.STAKING} element={<StakingPage />} />
|
||||||
<Route path={ROUTES.POOLS} element={<PoolsPage />} />
|
<Route path={ROUTES.POOLS} element={<PoolsPage />} />
|
||||||
|
|
||||||
|
{/* Profile dashboard: WalletLayout gives header/footer, ProfilePage
|
||||||
|
renders the menu + an inner <Outlet/> for the active item. */}
|
||||||
|
<Route path={ROUTES.PROFILE} element={<ProfilePage />}>
|
||||||
|
<Route index element={<Navigate to="details" replace />} />
|
||||||
|
<Route path="details" element={<ProfileDetailsItem />} />
|
||||||
|
<Route path="security" element={<SecurityItem />} />
|
||||||
|
<Route path="mnemonic" element={<MnemonicItem />} />
|
||||||
|
<Route path="transactions" element={<TransactionsItem />} />
|
||||||
|
</Route>
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
|
{/* Legacy route — transactions now live inside the profile dashboard. */}
|
||||||
|
<Route path={ROUTES.TRANSACTIONS} element={<Navigate to={ROUTES.PROFILE_TRANSACTIONS} replace />} />
|
||||||
|
|
||||||
<Route path={ROUTES.WALLET} element={<WalletPage />} />
|
<Route path={ROUTES.WALLET} element={<WalletPage />} />
|
||||||
<Route path={ROUTES.WALLET_CHAIN} element={<WalletPage />} />
|
<Route path={ROUTES.WALLET_CHAIN} element={<WalletPage />} />
|
||||||
<Route path={ROUTES.PROFILE} element={<ProfilePage />} />
|
|
||||||
<Route path={ROUTES.SEED_PHRASE} element={<SeedPhrasePage />} />
|
<Route path={ROUTES.SEED_PHRASE} element={<SeedPhrasePage />} />
|
||||||
<Route path={ROUTES.KYC} element={<KycPage />} />
|
<Route path={ROUTES.KYC} element={<KycPage />} />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
|
<Route path="*" element={<NotFoundPage />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -68,8 +68,7 @@
|
|||||||
margin: 10px 0;
|
margin: 10px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Вариант абзаца: предупреждение.
|
/* Вариант абзаца: предупреждение (тёмный текст на светло-жёлтом фоне). */
|
||||||
NB: исторический контраст (светлый фон + белый текст) сохранён как было. */
|
|
||||||
.warning {
|
.warning {
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
background: #fff3cd;
|
background: #fff3cd;
|
||||||
@@ -77,6 +76,7 @@
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
margin: 15px 0;
|
margin: 15px 0;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
color: #664d03;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Вариант абзаца: акцент (был `.confirmation`). */
|
/* Вариант абзаца: акцент (был `.confirmation`). */
|
||||||
|
|||||||
@@ -95,8 +95,9 @@ export interface OrgAmountRaw {
|
|||||||
raw: string
|
raw: string
|
||||||
formatted: string
|
formatted: string
|
||||||
decimals: number
|
decimals: number
|
||||||
usd_price: string
|
// null when pricing is unavailable (e.g. an upstream provider error).
|
||||||
usd_value: string
|
usd_price: string | null
|
||||||
|
usd_value: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OrgWalletBalance {
|
export interface OrgWalletBalance {
|
||||||
@@ -107,13 +108,14 @@ export interface OrgWalletBalance {
|
|||||||
native_symbol: string
|
native_symbol: string
|
||||||
native: OrgAmountRaw
|
native: OrgAmountRaw
|
||||||
tokens: Record<string, OrgAmountRaw>
|
tokens: Record<string, OrgAmountRaw>
|
||||||
total_usd: string
|
// null when the wallet's balance could not be fetched (see `error`).
|
||||||
|
total_usd: string | null
|
||||||
error: string | null
|
error: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OrgBalancesResponse {
|
export interface OrgBalancesResponse {
|
||||||
items: OrgWalletBalance[]
|
items: OrgWalletBalance[]
|
||||||
total_usd: string
|
total_usd: string | null
|
||||||
has_errors: boolean
|
has_errors: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -161,17 +161,61 @@ export interface Payment {
|
|||||||
expired_date: string
|
expired_date: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OrderWithPayment {
|
export type SbpWithdrawalStatus =
|
||||||
order: Order
|
| 'created'
|
||||||
|
| 'waiting_usdt'
|
||||||
|
| 'usdt_underpaid'
|
||||||
|
| 'usdt_received'
|
||||||
|
| 'wallet_error'
|
||||||
|
| 'payout_processing'
|
||||||
|
| 'payout_completed'
|
||||||
|
| 'payout_failed'
|
||||||
|
| 'cancelled'
|
||||||
|
| 'expired'
|
||||||
|
|
||||||
|
export interface SbpWithdrawalOperation {
|
||||||
|
id: string | null
|
||||||
|
created_at: string | null
|
||||||
|
updated_at: string | null
|
||||||
|
user_id: string | null
|
||||||
|
bank_id: string | null
|
||||||
|
bank_name: string | null
|
||||||
|
phone: string | null
|
||||||
|
usdt_amount: string | null
|
||||||
|
rub_amount: string | null
|
||||||
|
usdt_exchange_rate: string | null
|
||||||
|
service_fee_rate: string | null
|
||||||
|
service_fee_usdt: string | null
|
||||||
|
mozen_order_id: string | null
|
||||||
|
trace_id: string | null
|
||||||
|
status: SbpWithdrawalStatus | null
|
||||||
|
provider_error: string | null
|
||||||
|
usdt_received_at: string | null
|
||||||
|
payout_created_at: string | null
|
||||||
|
payout_completed_at: string | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ClientOperationType = 'payment' | 'withdrawal'
|
||||||
|
|
||||||
|
export interface ClientOperation {
|
||||||
|
type: ClientOperationType | string
|
||||||
|
created_at: string
|
||||||
payment: Payment | null
|
payment: Payment | null
|
||||||
|
withdrawal: SbpWithdrawalOperation | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OrdersResponse {
|
export interface ClientOperationsResponse {
|
||||||
orders: OrderWithPayment[]
|
status_code: number
|
||||||
|
operations: ClientOperation[]
|
||||||
|
limit: number
|
||||||
|
offset: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ORDERS_LIMIT = 20
|
export const OPERATIONS_LIMIT = 20
|
||||||
|
|
||||||
export function getOrders(offset: number, limit: number = ORDERS_LIMIT): Promise<OrdersResponse> {
|
export function getClientOperations(
|
||||||
return doPaymentRequest(`/payment/orders?offset=${offset}&limit=${limit}`, {}, true)
|
offset: number,
|
||||||
|
limit: number = OPERATIONS_LIMIT,
|
||||||
|
): Promise<ClientOperationsResponse> {
|
||||||
|
return doPaymentRequest(`/payment/payments?offset=${offset}&limit=${limit}`, {}, true)
|
||||||
}
|
}
|
||||||
|
|||||||
15
src/features/payment/hooks/useOperations.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { useInfiniteQuery } from '@tanstack/react-query'
|
||||||
|
import { getClientOperations, OPERATIONS_LIMIT } from '../api/paymentApi'
|
||||||
|
|
||||||
|
export function useOperations() {
|
||||||
|
return useInfiniteQuery({
|
||||||
|
queryKey: ['payment', 'operations'],
|
||||||
|
queryFn: ({ pageParam }) => getClientOperations(pageParam as number),
|
||||||
|
initialPageParam: 0,
|
||||||
|
getNextPageParam: (lastPage, allPages) => {
|
||||||
|
if (lastPage.operations.length < OPERATIONS_LIMIT) return undefined
|
||||||
|
return allPages.length * OPERATIONS_LIMIT
|
||||||
|
},
|
||||||
|
staleTime: 30_000,
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
import { useInfiniteQuery } from '@tanstack/react-query'
|
|
||||||
import { getOrders, ORDERS_LIMIT } from '../api/paymentApi'
|
|
||||||
|
|
||||||
export function useOrders() {
|
|
||||||
return useInfiniteQuery({
|
|
||||||
queryKey: ['payment', 'orders'],
|
|
||||||
queryFn: ({ pageParam }) => getOrders(pageParam as number),
|
|
||||||
initialPageParam: 0,
|
|
||||||
getNextPageParam: (lastPage, allPages) => {
|
|
||||||
if (lastPage.orders.length < ORDERS_LIMIT) return undefined
|
|
||||||
return allPages.length * ORDERS_LIMIT
|
|
||||||
},
|
|
||||||
staleTime: 30_000,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -2,6 +2,20 @@ export { usePaymentConfig } from './hooks/usePaymentConfig'
|
|||||||
export { usePaymentQuote } from './hooks/usePaymentQuote'
|
export { usePaymentQuote } from './hooks/usePaymentQuote'
|
||||||
export { usePaymentQuoteByRub } from './hooks/usePaymentQuoteByRub'
|
export { usePaymentQuoteByRub } from './hooks/usePaymentQuoteByRub'
|
||||||
export { useCreateOrder } from './hooks/useCreateOrder'
|
export { useCreateOrder } from './hooks/useCreateOrder'
|
||||||
export { useOrders } from './hooks/useOrders'
|
export { useOperations } from './hooks/useOperations'
|
||||||
export { useCurrencyConversion } from './model/useCurrencyConversion'
|
export { useCurrencyConversion } from './model/useCurrencyConversion'
|
||||||
export type { PaymentConfig, PaymentQuote, CreateOrderPayload, OrderResult, Order, Payment, OrderWithPayment, OrderStatus, PaymentStatus } from './api/paymentApi'
|
export type {
|
||||||
|
PaymentConfig,
|
||||||
|
PaymentQuote,
|
||||||
|
CreateOrderPayload,
|
||||||
|
OrderResult,
|
||||||
|
Order,
|
||||||
|
Payment,
|
||||||
|
OrderStatus,
|
||||||
|
PaymentStatus,
|
||||||
|
ClientOperation,
|
||||||
|
ClientOperationsResponse,
|
||||||
|
ClientOperationType,
|
||||||
|
SbpWithdrawalOperation,
|
||||||
|
SbpWithdrawalStatus,
|
||||||
|
} from './api/paymentApi'
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ export function useWalletBalance(chain: Chain) {
|
|||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: ['wallet', 'balance', chain, isLegal ? 'org' : 'self'],
|
queryKey: ['wallet', 'balance', chain, isLegal ? 'org' : 'self'],
|
||||||
queryFn: isLegal ? () => getOrgWalletBalance(chain) : () => getWalletBalance(chain),
|
queryFn: isLegal ? () => getOrgWalletBalance(chain) : () => getWalletBalance(chain),
|
||||||
enabled: isLegal ? ready : true,
|
// Wait for `me` before firing: otherwise a legal_entity account would hit
|
||||||
|
// the cryptowallet endpoint during the brief window before account_type is known.
|
||||||
|
enabled: ready,
|
||||||
staleTime: 30_000,
|
staleTime: 30_000,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -48,7 +50,7 @@ export function useWalletAddresses() {
|
|||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: ['wallet', 'addresses', isLegal ? 'org' : 'self'],
|
queryKey: ['wallet', 'addresses', isLegal ? 'org' : 'self'],
|
||||||
queryFn: isLegal ? getOrgWalletAddresses : getWalletAddresses,
|
queryFn: isLegal ? getOrgWalletAddresses : getWalletAddresses,
|
||||||
enabled: isLegal ? ready : true,
|
enabled: ready,
|
||||||
staleTime: 10 * 60 * 1000,
|
staleTime: 10 * 60 * 1000,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -58,7 +60,7 @@ export function usePortfolio() {
|
|||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: ['wallet', 'portfolio', isLegal ? 'org' : 'self'],
|
queryKey: ['wallet', 'portfolio', isLegal ? 'org' : 'self'],
|
||||||
queryFn: isLegal ? getOrgPortfolio : getPortfolio,
|
queryFn: isLegal ? getOrgPortfolio : getPortfolio,
|
||||||
enabled: isLegal ? ready : true,
|
enabled: ready,
|
||||||
staleTime: 30_000,
|
staleTime: 30_000,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -104,12 +106,16 @@ export function useCreateWallet() {
|
|||||||
return useMutation({ mutationFn: createWallet })
|
return useMutation({ mutationFn: createWallet })
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useRevealMnemonic() {
|
// `enabled` gates the request so callers can require an explicit user action
|
||||||
|
// (e.g. a "Показать" button) before the mnemonic is fetched. Defaults to true
|
||||||
|
// to preserve the standalone /seed-phrase page behavior.
|
||||||
|
export function useRevealMnemonic(enabled = true) {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: ['wallet', 'mnemonic'],
|
queryKey: ['wallet', 'mnemonic'],
|
||||||
queryFn: revealMnemonic,
|
queryFn: revealMnemonic,
|
||||||
staleTime: Infinity,
|
staleTime: Infinity,
|
||||||
retry: false,
|
retry: false,
|
||||||
|
enabled,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { useEffect } from 'react'
|
||||||
|
import { useLocation } from 'react-router-dom'
|
||||||
import { About } from '@widgets/about'
|
import { About } from '@widgets/about'
|
||||||
import { Converter } from '@widgets/currency-converter'
|
import { Converter } from '@widgets/currency-converter'
|
||||||
import { Footer } from '@widgets/footer'
|
import { Footer } from '@widgets/footer'
|
||||||
@@ -6,6 +8,16 @@ import { Hero } from '@widgets/hero'
|
|||||||
import { NetworksTable } from '@widgets/networks-table'
|
import { NetworksTable } from '@widgets/networks-table'
|
||||||
|
|
||||||
export function HomePage() {
|
export function HomePage() {
|
||||||
|
const location = useLocation()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if ((location.state as { scrollTo?: string } | null)?.scrollTo === 'about') {
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
document.getElementById('about')?.scrollIntoView({ behavior: 'smooth' })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, [location.state])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Header />
|
<Header />
|
||||||
|
|||||||
1
src/pages/not-found/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export { NotFoundPage } from './ui/NotFoundPage'
|
||||||
143
src/pages/not-found/ui/NotFoundPage.module.css
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
.page {
|
||||||
|
position: relative;
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
/* extra top padding clears the fixed header overlay */
|
||||||
|
padding: 120px 20px 80px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- Falling coins (decorative background) ---- */
|
||||||
|
.rain {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.drop {
|
||||||
|
position: absolute;
|
||||||
|
top: -80px;
|
||||||
|
opacity: 0.55;
|
||||||
|
animation-name: fall;
|
||||||
|
animation-timing-function: linear;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
filter: drop-shadow(0 6px 16px rgba(0, 0, 0, 0.35));
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fall {
|
||||||
|
0% {
|
||||||
|
transform: translateY(-80px) rotate(0deg);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
10% {
|
||||||
|
opacity: 0.55;
|
||||||
|
}
|
||||||
|
90% {
|
||||||
|
opacity: 0.55;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: translateY(85vh) rotate(360deg);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- Foreground content ---- */
|
||||||
|
.content {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
text-align: center;
|
||||||
|
max-width: 520px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.digit {
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-size: 160px;
|
||||||
|
font-weight: 800;
|
||||||
|
line-height: 1;
|
||||||
|
color: var(--text-primary);
|
||||||
|
text-shadow: 0 8px 40px rgba(74, 109, 255, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The middle "0" is a coin that flips like it's spinning in the air. */
|
||||||
|
.coin {
|
||||||
|
display: inline-flex;
|
||||||
|
animation: flip 2.6s ease-in-out infinite;
|
||||||
|
transform-style: preserve-3d;
|
||||||
|
filter: drop-shadow(0 12px 30px rgba(247, 147, 26, 0.45));
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes flip {
|
||||||
|
0%,
|
||||||
|
100% {
|
||||||
|
transform: rotateY(0deg) translateY(0);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: rotateY(180deg) translateY(-16px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
margin: 36px 0 12px;
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtitle {
|
||||||
|
margin: 0 0 32px;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 14px 32px;
|
||||||
|
border-radius: 12px;
|
||||||
|
background: var(--interactive);
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:hover {
|
||||||
|
background: var(--highlight);
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 10px 28px rgba(0, 212, 255, 0.35);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
.digit {
|
||||||
|
font-size: 96px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coin > :global(div) {
|
||||||
|
width: 88px !important;
|
||||||
|
height: 88px !important;
|
||||||
|
font-size: 40px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.drop,
|
||||||
|
.coin {
|
||||||
|
animation: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
78
src/pages/not-found/ui/NotFoundPage.tsx
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
import { Link } from 'react-router-dom'
|
||||||
|
import { Header } from '@widgets/header'
|
||||||
|
import { Footer } from '@widgets/footer'
|
||||||
|
import { TokenIcon } from '@shared/ui/TokenIcon'
|
||||||
|
import { ROUTES } from '@shared/config/routes'
|
||||||
|
import styles from './NotFoundPage.module.css'
|
||||||
|
|
||||||
|
/** Decorative coin set — purely visual, no live rates. */
|
||||||
|
const COINS = [
|
||||||
|
{ letter: '₿', color: '#f7931a' },
|
||||||
|
{ letter: 'Ξ', color: '#627eea' },
|
||||||
|
{ letter: '₮', color: '#26a17b' },
|
||||||
|
{ letter: '◎', color: '#9945ff' },
|
||||||
|
{ letter: '$', color: '#2775ca' },
|
||||||
|
{ letter: '₽', color: '#4a6dff' },
|
||||||
|
{ letter: 'Ʉ', color: '#00d4ff' },
|
||||||
|
]
|
||||||
|
|
||||||
|
/** Pre-baked rain layout so the scene looks the same on every render. */
|
||||||
|
const RAIN = [
|
||||||
|
{ left: 6, size: 34, delay: 0, duration: 7.5 },
|
||||||
|
{ left: 18, size: 26, delay: 2.1, duration: 9 },
|
||||||
|
{ left: 29, size: 44, delay: 4.3, duration: 6.5 },
|
||||||
|
{ left: 41, size: 22, delay: 1.2, duration: 10 },
|
||||||
|
{ left: 54, size: 38, delay: 3.4, duration: 8 },
|
||||||
|
{ left: 67, size: 28, delay: 0.6, duration: 9.5 },
|
||||||
|
{ left: 78, size: 48, delay: 2.8, duration: 7 },
|
||||||
|
{ left: 88, size: 24, delay: 5, duration: 8.5 },
|
||||||
|
{ left: 95, size: 32, delay: 1.7, duration: 9.2 },
|
||||||
|
]
|
||||||
|
|
||||||
|
export function NotFoundPage() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Header />
|
||||||
|
<main className={styles.page}>
|
||||||
|
<div className={styles.rain} aria-hidden="true">
|
||||||
|
{RAIN.map((coin, i) => {
|
||||||
|
const token = COINS[i % COINS.length]
|
||||||
|
return (
|
||||||
|
<span
|
||||||
|
key={i}
|
||||||
|
className={styles.drop}
|
||||||
|
style={{
|
||||||
|
left: `${coin.left}%`,
|
||||||
|
animationDelay: `${coin.delay}s`,
|
||||||
|
animationDuration: `${coin.duration}s`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TokenIcon letter={token.letter} color={token.color} size={coin.size} />
|
||||||
|
</span>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.content}>
|
||||||
|
<div className={styles.code} aria-hidden="true">
|
||||||
|
<span className={styles.digit}>4</span>
|
||||||
|
<span className={styles.coin}>
|
||||||
|
<TokenIcon letter="₿" color="#f7931a" size={140} />
|
||||||
|
</span>
|
||||||
|
<span className={styles.digit}>4</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h1 className={styles.title}>Такой страницы не существует</h1>
|
||||||
|
<p className={styles.subtitle}>
|
||||||
|
Похоже, курс этого маршрута обнулился. Проверьте адрес или вернитесь на главную.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<Link to={ROUTES.HOME} className={styles.button}>
|
||||||
|
На главную
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
<Footer />
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -8,7 +8,7 @@ export const politikaCookieDoc: LegalDocData = {
|
|||||||
blocks: [
|
blocks: [
|
||||||
{
|
{
|
||||||
kind: 'text',
|
kind: 'text',
|
||||||
text: 'Настоящая Политика использования файлов cookie устанавливает порядок обработки файлов cookie и содержащихся в них персональных данных ООО «БИТФОРС» при использовании пользователями интернет-ресурса https://bitforce-foundation.ru.',
|
text: 'Настоящая Политика использования файлов cookie устанавливает порядок обработки файлов cookie и содержащихся в них персональных данных ООО «ЭКСА» при использовании пользователями интернет-ресурса https://elcsa.ru.',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
kind: 'text',
|
kind: 'text',
|
||||||
@@ -27,7 +27,7 @@ export const politikaCookieDoc: LegalDocData = {
|
|||||||
{
|
{
|
||||||
kind: 'infoBox',
|
kind: 'infoBox',
|
||||||
lines: [
|
lines: [
|
||||||
'ООО «БИТФОРС»',
|
'ООО «ЭКСА»',
|
||||||
'ИНН: 9810001062',
|
'ИНН: 9810001062',
|
||||||
'ОГРН: 1257800060990',
|
'ОГРН: 1257800060990',
|
||||||
'Юридический адрес: 196246, город Санкт-Петербург, Московское ш, д. 25 к. 1 литера В, помещ. 3-н',
|
'Юридический адрес: 196246, город Санкт-Петербург, Московское ш, д. 25 к. 1 литера В, помещ. 3-н',
|
||||||
@@ -315,11 +315,11 @@ export const politikaCookieDoc: LegalDocData = {
|
|||||||
{
|
{
|
||||||
kind: 'infoBox',
|
kind: 'infoBox',
|
||||||
lines: [
|
lines: [
|
||||||
'ООО «БИТФОРС»',
|
'ООО «ЭКСА»',
|
||||||
'ИНН: 9810001062',
|
'ИНН: 9810001062',
|
||||||
'ОГРН: 1257800060990',
|
'ОГРН: 1257800060990',
|
||||||
'Юридический адрес: 196246, город Санкт-Петербург, Московское ш, д. 25 к. 1 литера В, помещ. 3-н',
|
'Юридический адрес: 196246, город Санкт-Петербург, Московское ш, д. 25 к. 1 литера В, помещ. 3-н',
|
||||||
'Email компании: company@bitforcefoundation.ru',
|
'Email компании: company@elcsa.ru',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{ kind: 'subheading', text: 'Порядок рассмотрения обращений:' },
|
{ kind: 'subheading', text: 'Порядок рассмотрения обращений:' },
|
||||||
|
|||||||
@@ -2,14 +2,14 @@ import type { LegalDocData } from '@entities/legal-doc'
|
|||||||
|
|
||||||
export const politikaPersonalnyhDannyhDoc: LegalDocData = {
|
export const politikaPersonalnyhDannyhDoc: LegalDocData = {
|
||||||
title: 'ПОЛИТИКА ОБРАБОТКИ ПЕРСОНАЛЬНЫХ ДАННЫХ',
|
title: 'ПОЛИТИКА ОБРАБОТКИ ПЕРСОНАЛЬНЫХ ДАННЫХ',
|
||||||
subtitle: 'ООО «БИТФОРС»',
|
subtitle: 'ООО «ЭКСА»',
|
||||||
sections: [
|
sections: [
|
||||||
{
|
{
|
||||||
title: '1. Общие положения',
|
title: '1. Общие положения',
|
||||||
blocks: [
|
blocks: [
|
||||||
{
|
{
|
||||||
kind: 'text',
|
kind: 'text',
|
||||||
text: 'Настоящая Политика обработки персональных данных разработана в соответствии с Федеральным законом от 27.07.2006 № 152-ФЗ «О персональных данных» и определяет порядок обработки персональных данных и меры по обеспечению безопасности персональных данных, предпринимаемые ООО «БИТФОРС».',
|
text: 'Настоящая Политика обработки персональных данных разработана в соответствии с Федеральным законом от 27.07.2006 № 152-ФЗ «О персональных данных» и определяет порядок обработки персональных данных и меры по обеспечению безопасности персональных данных, предпринимаемые ООО «ЭКСА».',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
kind: 'text',
|
kind: 'text',
|
||||||
@@ -41,7 +41,7 @@ export const politikaPersonalnyhDannyhDoc: LegalDocData = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
term: 'Пользователь',
|
term: 'Пользователь',
|
||||||
text: '— любой посетитель веб-сайта https://bitforce-foundation.ru.',
|
text: '— любой посетитель веб-сайта https://elcsa.ru.',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -53,13 +53,13 @@ export const politikaPersonalnyhDannyhDoc: LegalDocData = {
|
|||||||
{
|
{
|
||||||
kind: 'list',
|
kind: 'list',
|
||||||
items: [
|
items: [
|
||||||
'Полное наименование: Общество с ограниченной ответственностью «БИТФОРС»',
|
'Полное наименование: Общество с ограниченной ответственностью «ЭКСА»',
|
||||||
'Сокращенное наименование: ООО «БИТФОРС»',
|
'Сокращенное наименование: ООО «ЭКСА»',
|
||||||
'ИНН: 9810001062',
|
'ИНН: 9810001062',
|
||||||
'ОГРН: 1257800060990',
|
'ОГРН: 1257800060990',
|
||||||
'Юридический адрес: 196246, город Санкт-Петербург, Московское шоссе, дом 25, корпус 1, литера В, помещение 3-н',
|
'Юридический адрес: 196246, город Санкт-Петербург, Московское шоссе, дом 25, корпус 1, литера В, помещение 3-н',
|
||||||
'Электронная почта: company@bitforcefoundation.ru',
|
'Электронная почта: company@elcsa.ru',
|
||||||
'Веб-сайт: https://bitforce-foundation.ru',
|
'Веб-сайт: https://elcsa.ru',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -352,7 +352,7 @@ export const politikaPersonalnyhDannyhDoc: LegalDocData = {
|
|||||||
kind: 'infoBox',
|
kind: 'infoBox',
|
||||||
lines: [
|
lines: [
|
||||||
'Почтовый адрес: 196246, г. Санкт-Петербург, Московское ш., д. 25, к. 1, лит. В, пом. 3-н',
|
'Почтовый адрес: 196246, г. Санкт-Петербург, Московское ш., д. 25, к. 1, лит. В, пом. 3-н',
|
||||||
'Электронная почта: company@bitforcefoundation.ru',
|
'Электронная почта: company@elcsa.ru',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1 +1,5 @@
|
|||||||
export { ProfilePage } from './ui/ProfilePage'
|
export { ProfilePage } from './ui/ProfilePage'
|
||||||
|
export { ProfileDetailsItem } from './ui/items/ProfileDetailsItem'
|
||||||
|
export { SecurityItem } from './ui/items/SecurityItem'
|
||||||
|
export { MnemonicItem } from './ui/items/MnemonicItem'
|
||||||
|
export { TransactionsItem } from './ui/items/TransactionsItem'
|
||||||
|
|||||||
@@ -1,30 +1,29 @@
|
|||||||
.page {
|
.page {
|
||||||
min-height: 100vh;
|
max-width: 1200px;
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
background: var(--bg-deep);
|
|
||||||
}
|
|
||||||
|
|
||||||
.main {
|
|
||||||
max-width: 1024px;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 40px 32px 60px;
|
padding: 40px 32px 60px;
|
||||||
display: flex;
|
display: grid;
|
||||||
|
grid-template-columns: 25% 1fr;
|
||||||
gap: 32px;
|
gap: 32px;
|
||||||
|
align-items: start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sections {
|
.menu {
|
||||||
flex: 1;
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
min-width: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* < 1024px: avatar + sections stack into a single column */
|
/* < 1024px: menu and content stack into a single column */
|
||||||
@media (max-width: 1023px) {
|
@media (max-width: 1023px) {
|
||||||
.main {
|
.page {
|
||||||
flex-direction: column;
|
grid-template-columns: 1fr;
|
||||||
padding: 24px 20px 40px;
|
padding: 24px 20px 40px;
|
||||||
gap: 24px;
|
gap: 24px;
|
||||||
}
|
}
|
||||||
@@ -32,7 +31,7 @@
|
|||||||
|
|
||||||
/* < 640px: tighter page padding */
|
/* < 640px: tighter page padding */
|
||||||
@media (max-width: 639px) {
|
@media (max-width: 639px) {
|
||||||
.main {
|
.page {
|
||||||
padding: 16px 16px 40px;
|
padding: 16px 16px 40px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
import { WalletHeader } from '@widgets/wallet-header'
|
import { Outlet } from 'react-router-dom'
|
||||||
import { KycBanner, ProfileSummary, ProfileDetails, SecuritySection, MnemonicSection } from '@widgets/profile'
|
import { KycBanner, ProfileMenu } from '@widgets/profile'
|
||||||
import styles from './ProfilePage.module.css'
|
import styles from './ProfilePage.module.css'
|
||||||
|
|
||||||
|
// Profile dashboard layout. The outer WalletLayout (see RouterProvider) renders
|
||||||
|
// the header/footer; here we split into a ~25% menu column and a ~75% content
|
||||||
|
// column. The active item is rendered into the inner <Outlet/>.
|
||||||
export function ProfilePage() {
|
export function ProfilePage() {
|
||||||
return (
|
return (
|
||||||
<div className={styles.page}>
|
<div className={styles.page}>
|
||||||
<WalletHeader />
|
<div className={styles.menu}>
|
||||||
<KycBanner />
|
<ProfileMenu />
|
||||||
<main className={styles.main}>
|
</div>
|
||||||
<ProfileSummary />
|
<main className={styles.content}>
|
||||||
<div className={styles.sections}>
|
<KycBanner />
|
||||||
<ProfileDetails />
|
<Outlet />
|
||||||
<SecuritySection />
|
|
||||||
<MnemonicSection />
|
|
||||||
</div>
|
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
6
src/pages/profile/ui/items/MnemonicItem.module.css
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
.hint {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.6;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
32
src/pages/profile/ui/items/MnemonicItem.tsx
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import { useState } from 'react'
|
||||||
|
import { useRevealMnemonic } from '@features/wallet'
|
||||||
|
import { SeedPhraseWidget } from '@widgets/seed-phrase'
|
||||||
|
import { ProfileSection } from '@widgets/profile'
|
||||||
|
import { Button, Spinner } from '@shared/ui'
|
||||||
|
import styles from './MnemonicItem.module.css'
|
||||||
|
|
||||||
|
// «Мнемоническая фраза» dashboard item. The mnemonic is fetched only after the
|
||||||
|
// user explicitly clicks "Показать мнемонику" (the query stays disabled until
|
||||||
|
// then), then the seed-phrase content is shown inline.
|
||||||
|
export function MnemonicItem() {
|
||||||
|
const [revealed, setRevealed] = useState(false)
|
||||||
|
const { data: mnemonic, isLoading } = useRevealMnemonic(revealed)
|
||||||
|
|
||||||
|
if (!revealed) {
|
||||||
|
return (
|
||||||
|
<ProfileSection
|
||||||
|
title="Мнемоническая фраза"
|
||||||
|
actions={<Button variant="danger" onClick={() => setRevealed(true)}>Показать мнемонику</Button>}
|
||||||
|
>
|
||||||
|
<p className={styles.hint}>
|
||||||
|
Сид-фраза из 12 слов для восстановления кошелька. Никогда не передавайте её третьим лицам.
|
||||||
|
</p>
|
||||||
|
</ProfileSection>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isLoading) return <Spinner fullscreen label="Загрузка" />
|
||||||
|
|
||||||
|
const words = mnemonic ? mnemonic.split(' ') : []
|
||||||
|
return <SeedPhraseWidget words={words} showProfileLink={false} />
|
||||||
|
}
|
||||||
11
src/pages/profile/ui/items/ProfileDetailsItem.tsx
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { useMe } from '@features/auth'
|
||||||
|
import { ProfileDetails } from '@widgets/profile'
|
||||||
|
import { Spinner } from '@shared/ui'
|
||||||
|
|
||||||
|
// «Данные профиля» — default dashboard item. Shows a spinner while the profile
|
||||||
|
// data is still loading, then the details form.
|
||||||
|
export function ProfileDetailsItem() {
|
||||||
|
const { isLoading } = useMe()
|
||||||
|
if (isLoading) return <Spinner fullscreen label="Загрузка" />
|
||||||
|
return <ProfileDetails />
|
||||||
|
}
|
||||||
10
src/pages/profile/ui/items/SecurityItem.tsx
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { useMe } from '@features/auth'
|
||||||
|
import { SecuritySection } from '@widgets/profile'
|
||||||
|
import { Spinner } from '@shared/ui'
|
||||||
|
|
||||||
|
// «Безопасность» dashboard item.
|
||||||
|
export function SecurityItem() {
|
||||||
|
const { isLoading } = useMe()
|
||||||
|
if (isLoading) return <Spinner fullscreen label="Загрузка" />
|
||||||
|
return <SecuritySection />
|
||||||
|
}
|
||||||
7
src/pages/profile/ui/items/TransactionsItem.tsx
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import { TransactionsPanel } from '@widgets/transactions-panel'
|
||||||
|
|
||||||
|
// «Транзакции» dashboard item — the shared transactions panel (list + tabs).
|
||||||
|
// The panel handles its own loading state.
|
||||||
|
export function TransactionsItem() {
|
||||||
|
return <TransactionsPanel />
|
||||||
|
}
|
||||||
@@ -2,14 +2,14 @@ import type { LegalDocData } from '@entities/legal-doc'
|
|||||||
|
|
||||||
export const publichnayaOfertaDoc: LegalDocData = {
|
export const publichnayaOfertaDoc: LegalDocData = {
|
||||||
title: 'ПУБЛИЧНЫЙ ДОГОВОР ОФЕРТЫ',
|
title: 'ПУБЛИЧНЫЙ ДОГОВОР ОФЕРТЫ',
|
||||||
subtitle: 'ООО БИТФОРС',
|
subtitle: 'ООО ЭКСА',
|
||||||
sections: [
|
sections: [
|
||||||
{
|
{
|
||||||
title: 'Агентский договор',
|
title: 'Агентский договор',
|
||||||
blocks: [
|
blocks: [
|
||||||
{
|
{
|
||||||
kind: 'text',
|
kind: 'text',
|
||||||
text: 'Настоящая оферта на заключение агентского договора (далее – Оферта, Договор) является публичным предложением Общества с ограниченной ответственностью «БИТФОРС», заключить договор на условиях и в порядке, определенных настоящей Офертой.',
|
text: 'Настоящая оферта на заключение агентского договора (далее – Оферта, Договор) является публичным предложением Общества с ограниченной ответственностью «ЭКСА», заключить договор на условиях и в порядке, определенных настоящей Офертой.',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
kind: 'text',
|
kind: 'text',
|
||||||
@@ -49,7 +49,7 @@ export const publichnayaOfertaDoc: LegalDocData = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
term: 'Оферта (Договор)',
|
term: 'Оферта (Договор)',
|
||||||
text: '– настоящий документ, который отражает предложение и намерение ООО «БИТФОРС» считать заключенным договор с лицом, которым будет принято предложение на условиях, изложенных ниже.',
|
text: '– настоящий документ, который отражает предложение и намерение ООО «ЭКСА» считать заключенным договор с лицом, которым будет принято предложение на условиях, изложенных ниже.',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -221,13 +221,13 @@ export const publichnayaOfertaDoc: LegalDocData = {
|
|||||||
{
|
{
|
||||||
kind: 'infoBox',
|
kind: 'infoBox',
|
||||||
lines: [
|
lines: [
|
||||||
'Общество с ограниченной ответственностью «БИТФОРС»',
|
'Общество с ограниченной ответственностью «ЭКСА»',
|
||||||
'196246, г. Санкт-Петербург, Московский р-н, Московское шоссе, д.25к1 литера в, помещ. 3-Н',
|
'196246, г. Санкт-Петербург, Московский р-н, Московское шоссе, д.25к1 литера в, помещ. 3-Н',
|
||||||
'ИНН / КПП: 9810001062 / 781001001',
|
'ИНН / КПП: 9810001062 / 781001001',
|
||||||
'ОГРН: 1257800060990',
|
'ОГРН: 1257800060990',
|
||||||
'ОКПО / ОКАТО / ОКТМО: 68342261 / 40284000000 / 40377000000',
|
'ОКПО / ОКАТО / ОКТМО: 68342261 / 40284000000 / 40377000000',
|
||||||
'Руководитель: Кленин Михаил Васильевич',
|
'Руководитель: Кленин Михаил Васильевич',
|
||||||
'Электронная почта: company@bitforcefoundation.ru',
|
'Электронная почта: company@elcsa.ru',
|
||||||
'Наименование банка: ФИЛИАЛ "САНКТ-ПЕТЕРБУРГСКИЙ" АО "АЛЬФА-БАНК"',
|
'Наименование банка: ФИЛИАЛ "САНКТ-ПЕТЕРБУРГСКИЙ" АО "АЛЬФА-БАНК"',
|
||||||
'Корреспондентский счет: 30101810600000000786',
|
'Корреспондентский счет: 30101810600000000786',
|
||||||
'БИК: 044030786',
|
'БИК: 044030786',
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import type { LegalDocData } from '@entities/legal-doc'
|
|||||||
|
|
||||||
export const reestrDoc: LegalDocData = {
|
export const reestrDoc: LegalDocData = {
|
||||||
title: 'Реестр операторов персональных данных',
|
title: 'Реестр операторов персональных данных',
|
||||||
subtitle: 'ООО «БИТФОРС»',
|
subtitle: 'ООО «ЭКСА»',
|
||||||
sections: [
|
sections: [
|
||||||
{
|
{
|
||||||
blocks: [
|
blocks: [
|
||||||
@@ -31,14 +31,14 @@ export const reestrDoc: LegalDocData = {
|
|||||||
{
|
{
|
||||||
kind: 'infoBox',
|
kind: 'infoBox',
|
||||||
lines: [
|
lines: [
|
||||||
{ strong: 'Наименование:', text: 'ООО «БИТФОРС»' },
|
{ strong: 'Наименование:', text: 'ООО «ЭКСА»' },
|
||||||
{ strong: 'ИНН:', text: '9810001062' },
|
{ strong: 'ИНН:', text: '9810001062' },
|
||||||
{ strong: 'ОГРН:', text: '1257800060990' },
|
{ strong: 'ОГРН:', text: '1257800060990' },
|
||||||
{
|
{
|
||||||
strong: 'Юридический адрес:',
|
strong: 'Юридический адрес:',
|
||||||
text: '196246, город Санкт-Петербург, Московское шоссе, дом 25, корпус 1, литера В, помещение 3-н',
|
text: '196246, город Санкт-Петербург, Московское шоссе, дом 25, корпус 1, литера В, помещение 3-н',
|
||||||
},
|
},
|
||||||
{ strong: 'Контактная информация:', text: 'company@bitforcefoundation.ru' },
|
{ strong: 'Контактная информация:', text: 'company@elcsa.ru' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -2,14 +2,14 @@ import type { LegalDocData } from '@entities/legal-doc'
|
|||||||
|
|
||||||
export const soglasieDoc: LegalDocData = {
|
export const soglasieDoc: LegalDocData = {
|
||||||
title: 'СОГЛАСИЕ НА ОБРАБОТКУ ПЕРСОНАЛЬНЫХ ДАННЫХ',
|
title: 'СОГЛАСИЕ НА ОБРАБОТКУ ПЕРСОНАЛЬНЫХ ДАННЫХ',
|
||||||
subtitle: 'ООО «БИТФОРС»',
|
subtitle: 'ООО «ЭКСА»',
|
||||||
sections: [
|
sections: [
|
||||||
{
|
{
|
||||||
title: 'Преамбула',
|
title: 'Преамбула',
|
||||||
blocks: [
|
blocks: [
|
||||||
{
|
{
|
||||||
kind: 'text',
|
kind: 'text',
|
||||||
text: 'Я, субъект персональных данных, действуя своей волей и в своем интересе, в соответствии с требованиями Федерального закона от 27.07.2006 № 152-ФЗ «О персональных данных», предоставляю ООО «БИТФОРС» согласие на обработку моих персональных данных на условиях и для целей, определенных настоящим Согласием.',
|
text: 'Я, субъект персональных данных, действуя своей волей и в своем интересе, в соответствии с требованиями Федерального закона от 27.07.2006 № 152-ФЗ «О персональных данных», предоставляю ООО «ЭКСА» согласие на обработку моих персональных данных на условиях и для целей, определенных настоящим Согласием.',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -19,12 +19,12 @@ export const soglasieDoc: LegalDocData = {
|
|||||||
{
|
{
|
||||||
kind: 'infoBox',
|
kind: 'infoBox',
|
||||||
lines: [
|
lines: [
|
||||||
'Полное наименование: Общество с ограниченной ответственностью «БИТФОРС»',
|
'Полное наименование: Общество с ограниченной ответственностью «ЭКСА»',
|
||||||
'ИНН: 9810001062',
|
'ИНН: 9810001062',
|
||||||
'ОГРН: 1257800060990',
|
'ОГРН: 1257800060990',
|
||||||
'Юридический адрес: 196246, город Санкт-Петербург, Московское шоссе, дом 25, корпус 1, литера В, помещение 3-н',
|
'Юридический адрес: 196246, город Санкт-Петербург, Московское шоссе, дом 25, корпус 1, литера В, помещение 3-н',
|
||||||
'Электронная почта: company@bitforcefoundation.ru',
|
'Электронная почта: company@elcsa.ru',
|
||||||
'Веб-сайт: https://bitforce-foundation.ru',
|
'Веб-сайт: https://elcsa.ru',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -280,7 +280,7 @@ export const soglasieDoc: LegalDocData = {
|
|||||||
{
|
{
|
||||||
kind: 'list',
|
kind: 'list',
|
||||||
items: [
|
items: [
|
||||||
'Обращения направляются на адрес: company@bitforcefoundation.ru',
|
'Обращения направляются на адрес: company@elcsa.ru',
|
||||||
'Обращения рассматриваются в течение 30 дней',
|
'Обращения рассматриваются в течение 30 дней',
|
||||||
'При необходимости срок может быть продлен на 30 дней',
|
'При необходимости срок может быть продлен на 30 дней',
|
||||||
],
|
],
|
||||||
@@ -323,9 +323,9 @@ export const soglasieDoc: LegalDocData = {
|
|||||||
kind: 'infoBox',
|
kind: 'infoBox',
|
||||||
lines: [
|
lines: [
|
||||||
'Почтовый адрес: 196246, г. Санкт-Петербург, Московское ш., д. 25, к. 1, лит. В, пом. 3-н',
|
'Почтовый адрес: 196246, г. Санкт-Петербург, Московское ш., д. 25, к. 1, лит. В, пом. 3-н',
|
||||||
'Электронная почта: company@bitforcefoundation.ru',
|
'Электронная почта: company@elcsa.ru',
|
||||||
'Ответственное лицо: Кленин Михаил Васильевич',
|
'Ответственное лицо: Кленин Михаил Васильевич',
|
||||||
'Официальный сайт: https://bitforce-foundation.ru',
|
'Официальный сайт: https://elcsa.ru',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{ kind: 'subheading', text: '9.5. Подтверждение понимания:' },
|
{ kind: 'subheading', text: '9.5. Подтверждение понимания:' },
|
||||||
|
|||||||
@@ -1,45 +1,15 @@
|
|||||||
import { useState } from 'react'
|
import { TransactionsPanel } from '@widgets/transactions-panel'
|
||||||
import { useMe } from '@features/auth'
|
|
||||||
import { TransactionsList } from '@widgets/transactions-list'
|
|
||||||
import { PurchaseRequestsList } from '@widgets/purchase-requests-list'
|
|
||||||
import styles from './TransactionsPage.module.css'
|
import styles from './TransactionsPage.module.css'
|
||||||
|
|
||||||
type Tab = 'transactions' | 'requests'
|
// The standalone /transactions route now redirects to /profile/transactions
|
||||||
|
// (see RouterProvider). This page is kept as a thin wrapper around the shared
|
||||||
|
// TransactionsPanel for any direct/legacy usage.
|
||||||
export function TransactionsPage() {
|
export function TransactionsPage() {
|
||||||
const { data } = useMe()
|
|
||||||
const [tab, setTab] = useState<Tab>('transactions')
|
|
||||||
|
|
||||||
const isLegal = !!data && data.account_type !== 'individual'
|
|
||||||
const activeTab: Tab = isLegal ? tab : 'transactions'
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.inner}>
|
<div className={styles.inner}>
|
||||||
<div className={styles.glow} />
|
<div className={styles.glow} />
|
||||||
<h1 className={styles.title}>Транзакции</h1>
|
<h1 className={styles.title}>Транзакции</h1>
|
||||||
|
<TransactionsPanel />
|
||||||
{isLegal && (
|
|
||||||
<div className={styles.tabs}>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className={styles.tab}
|
|
||||||
data-active={activeTab === 'transactions' || undefined}
|
|
||||||
onClick={() => setTab('transactions')}
|
|
||||||
>
|
|
||||||
Транзакции
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className={styles.tab}
|
|
||||||
data-active={activeTab === 'requests' || undefined}
|
|
||||||
onClick={() => setTab('requests')}
|
|
||||||
>
|
|
||||||
Заявки
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{activeTab === 'transactions' ? <TransactionsList /> : <PurchaseRequestsList />}
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
src/shared/assets/coins/ARB.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
src/shared/assets/coins/BNB.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
src/shared/assets/coins/BONK.png
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
src/shared/assets/coins/BTC.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
src/shared/assets/coins/BUSD.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
src/shared/assets/coins/DAI.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
src/shared/assets/coins/DOGE.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
src/shared/assets/coins/ETH.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
src/shared/assets/coins/JTO.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
src/shared/assets/coins/JUP.png
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
BIN
src/shared/assets/coins/LINK.png
Normal file
|
After Width: | Height: | Size: 686 B |
BIN
src/shared/assets/coins/ORCA.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
src/shared/assets/coins/PENGU.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
src/shared/assets/coins/POPCAT.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
src/shared/assets/coins/PUMP.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
src/shared/assets/coins/PYTH.png
Normal file
|
After Width: | Height: | Size: 678 B |
BIN
src/shared/assets/coins/RAY.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
src/shared/assets/coins/SOL.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
src/shared/assets/coins/TRUMP.png
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
BIN
src/shared/assets/coins/TRX.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
src/shared/assets/coins/UNI.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
src/shared/assets/coins/USDC.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
src/shared/assets/coins/USDT.png
Normal file
|
After Width: | Height: | Size: 674 B |
BIN
src/shared/assets/coins/W.png
Normal file
|
After Width: | Height: | Size: 632 B |
BIN
src/shared/assets/coins/WBNB.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
src/shared/assets/coins/WBTC.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
src/shared/assets/coins/WIF.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
@@ -1,3 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="151" height="172" viewBox="0 0 151 172" fill="none">
|
|
||||||
<path d="M144.518 39.2113L82.214 3.03438C80.1932 1.87961 77.9919 1.28418 75.7545 1.28418C73.5352 1.28418 71.3158 1.87961 69.3311 3.03438L7.00937 39.2474C3.05788 41.5569 0.585938 45.8151 0.585938 50.4162V122.842C0.585938 127.443 3.05788 131.756 7.00937 134.047L18.2143 140.561L34.5616 150.052L38.2243 139.965L71.8932 47.1143C72.2 46.2121 71.5504 45.2378 70.54 45.2378H54.752C53.5792 45.2378 52.4966 45.9775 52.1177 47.0782L21.8951 130.474L12.2961 124.899C11.5743 124.484 11.1232 123.708 11.1232 122.878V50.4162C11.1232 49.5862 11.5743 48.8103 12.2961 48.3953L74.6178 12.1824C74.9606 11.9658 75.3756 11.8756 75.7725 11.8756C76.1875 11.8756 76.5665 11.9839 76.9454 12.1824L139.285 48.3953C140.007 48.8103 140.458 49.5862 140.458 50.4162V122.842C140.458 123.672 140.007 124.448 139.285 124.863L129.794 130.384L104.822 61.4768C104.371 60.2137 102.639 60.2137 102.188 61.4768L93.9602 84.1392C93.7257 84.7707 93.7257 85.4744 93.9602 86.0879L113.447 139.875L106.969 143.646L91.0192 99.6023C90.5681 98.3393 88.8359 98.3393 88.3848 99.6023L80.1571 122.265C79.9225 122.896 79.9225 123.6 80.1571 124.213L90.6403 153.137L76.9634 161.094C76.6206 161.311 76.2056 161.401 75.7906 161.401C75.3756 161.401 74.9967 161.293 74.6178 161.094L61.1033 153.227L99.5537 47.1323C99.8965 46.1941 99.2108 45.2017 98.2365 45.2017H82.4486C81.2758 45.2017 80.1932 45.9414 79.8142 47.0421L44.756 143.718L41.0932 153.805L57.4405 163.295L69.3672 170.224C71.3519 171.379 73.5713 171.974 75.7906 171.974C78.0099 171.974 80.2292 171.379 82.214 170.224L144.554 134.011C148.541 131.701 150.977 127.443 150.977 122.806V50.4162C150.977 45.8151 148.505 41.5028 144.554 39.2113H144.518Z" fill="white"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.7 KiB |
@@ -1,20 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 2496 2496" style="enable-background:new 0 0 2496 2496;" xml:space="preserve">
|
|
||||||
<g>
|
|
||||||
<path style="fill-rule:evenodd;clip-rule:evenodd;fill:#F0B90B;" d="M1248,0c689.3,0,1248,558.7,1248,1248s-558.7,1248-1248,1248
|
|
||||||
S0,1937.3,0,1248S558.7,0,1248,0L1248,0z"/>
|
|
||||||
<path style="fill:#FFFFFF;" d="M685.9,1248l0.9,330l280.4,165v193.2l-444.5-260.7v-524L685.9,1248L685.9,1248z M685.9,918v192.3
|
|
||||||
l-163.3-96.6V821.4l163.3-96.6l164.1,96.6L685.9,918L685.9,918z M1084.3,821.4l163.3-96.6l164.1,96.6L1247.6,918L1084.3,821.4
|
|
||||||
L1084.3,821.4z"/>
|
|
||||||
<path style="fill:#FFFFFF;" d="M803.9,1509.6v-193.2l163.3,96.6v192.3L803.9,1509.6L803.9,1509.6z M1084.3,1812.2l163.3,96.6
|
|
||||||
l164.1-96.6v192.3l-164.1,96.6l-163.3-96.6V1812.2L1084.3,1812.2z M1645.9,821.4l163.3-96.6l164.1,96.6v192.3l-164.1,96.6V918
|
|
||||||
L1645.9,821.4L1645.9,821.4L1645.9,821.4z M1809.2,1578l0.9-330l163.3-96.6v524l-444.5,260.7v-193.2L1809.2,1578L1809.2,1578
|
|
||||||
L1809.2,1578z"/>
|
|
||||||
<polygon style="fill:#FFFFFF;" points="1692.1,1509.6 1528.8,1605.3 1528.8,1413 1692.1,1316.4 1692.1,1509.6 "/>
|
|
||||||
<path style="fill:#FFFFFF;" d="M1692.1,986.4l0.9,193.2l-281.2,165v330.8l-163.3,95.7l-163.3-95.7v-330.8l-281.2-165V986.4
|
|
||||||
L968,889.8l279.5,165.8l281.2-165.8l164.1,96.6H1692.1L1692.1,986.4z M803.9,656.5l443.7-261.6l444.5,261.6l-163.3,96.6
|
|
||||||
l-281.2-165.8L967.2,753.1L803.9,656.5L803.9,656.5z"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.6 KiB |
@@ -1,43 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="CIRCLE_OUTLINE_BLACK" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
x="0px" y="0px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{fill:#FDDE00;}
|
|
||||||
.st1{fill:#3C2D0C;}
|
|
||||||
.st2{fill:#E78C19;}
|
|
||||||
.st3{fill:#EFB99D;}
|
|
||||||
.st4{fill:#FBFBFB;}
|
|
||||||
.st5{fill:#E72D36;}
|
|
||||||
</style>
|
|
||||||
<circle class="st0" cx="256" cy="256" r="256"/>
|
|
||||||
<path class="st1" d="M131.4,181c0,0-13.2,16.7-8.8,92.2c0,0-28.9,74-19.1,111.8c9.8,37.7,48,35.8,48,35.8s61.3,53.9,108.3,6.4
|
|
||||||
c47.1-47.6-39.2-231.9-39.2-231.9l-10.8-63.7c0,0-11.8,9.3-10.3,70.6s-24,18.1-24,18.1L131.4,181z"/>
|
|
||||||
<path class="st2" d="M136.3,247.7l-16.2,45.6l-5.9,31.9c0,0-20.1,71.1,62.8,70.1c0,0,64.7,57.9,106.9,19.1l11.3-12.3l19.6-30.4
|
|
||||||
l32.4-96.6c0,0-10.3-66.2-75.5-93.6c0,0-5.4-2.9-15.2,1c0,0-27-60.8-44.1-53.4c0,0-14.7,7.8-2,67.7l-23,10.3
|
|
||||||
c0,0-25.2-47.8-48.5-38.2C117.2,177.6,136.3,247.7,136.3,247.7z"/>
|
|
||||||
<path class="st3" d="M220.1,158.9l2,26.5c0,0,1.5,15.2,17.6,9.8c4.6-1.5,8.6-4.7,8.2-9.9c-0.3-3.9-3-7.5-4.8-10.8
|
|
||||||
c-3.3-6.3-6-13-9.9-19.1c-2-3.1-6.1-10-10.6-9.2C222.6,146.2,219.2,145.2,220.1,158.9z"/>
|
|
||||||
<path class="st3" d="M149.3,188.7c0.3-0.2,6.9-8.5,20.6,11.7c13.7,20.2,12.3,17.6,12.3,17.6s7.4,8.1-7.7,18.5
|
|
||||||
c-3.3,2.4-6.9,4.4-10.7,6c-2.4,0.9-4.9,1.4-7.4,1.4c-2.9-0.1-4.2-1.6-4.9-4.3c-2.3-8.8-4.9-17.6-6.2-26.6
|
|
||||||
C144.3,206,142.3,193.2,149.3,188.7z"/>
|
|
||||||
<path class="st4" d="M308.5,229.4c0,4.8-7,8.7-15.7,8.7c-8.7,0-15.7-3.9-15.7-8.7s7.2-11.9,15.8-11.9S308.5,224.6,308.5,229.4z"/>
|
|
||||||
<ellipse transform="matrix(0.4925 -0.8703 0.8703 0.4925 -121.8385 314.1253)" class="st4" cx="208.4" cy="261.5" rx="17.1" ry="11"/>
|
|
||||||
<path class="st4" d="M240.2,306.7l42.9-22.3c0,0,53.4-27.9,66.4-6.4s0,54.4,0,54.4s-5.6,38.5-44.9,41.9l-21.1,2.9l-27,0.7
|
|
||||||
c0,0-43.4,2.5-75.3-21.1l-10.1-12.3c0,0-20.3-27.9-6.1-48s62.8,11,62.8,11S234.6,311.2,240.2,306.7z"/>
|
|
||||||
<circle class="st5" cx="337.5" cy="185.2" r="10.3"/>
|
|
||||||
<circle class="st5" cx="314.7" cy="159.9" r="10.3"/>
|
|
||||||
<circle class="st5" cx="278.2" cy="151.8" r="10.3"/>
|
|
||||||
<path class="st5" d="M286.3,78.8c2.2,30.4-2.2,57.9-9.6,57.9s-17.2-29.7-17.2-57.9c0-11.6,6.1-13.5,13.5-13.5
|
|
||||||
C280.5,65.3,285.5,67.2,286.3,78.8z"/>
|
|
||||||
<path class="st5" d="M354.5,97.7c-11.2,28.3-27.1,51.2-33.7,48c-6.6-3.2-2.6-34.2,9.7-59.6c5.1-10.5,11.4-9.5,18-6.3
|
|
||||||
C355.1,83.1,358.8,86.9,354.5,97.7z"/>
|
|
||||||
<path class="st5" d="M403.3,152.9c-24.7,17.9-50.3,28.7-54.2,22.4c-3.9-6.3,16.2-30.2,40.1-45.1c9.9-6.1,14.7-1.9,18.6,4.3
|
|
||||||
C411.6,140.8,412.7,146,403.3,152.9z"/>
|
|
||||||
<path d="M238.2,276.8c-0.9,0.1-1.8,0.2-2.7,0.3c0.1,0.3,0.2,0.6,0.2,1c0,3.1-4.9,5.7-11,5.9c0,0.3-0.1,0.5,0,0.8
|
|
||||||
c0.3,3.8,6.9,6.4,14.6,5.8c7.8-0.6,13.9-4.2,13.6-8C252.5,278.8,246,276.2,238.2,276.8z"/>
|
|
||||||
<path d="M292.4,263.4c-0.9,0.1-1.8,0.2-2.7,0.3c0.1,0.3,0.2,0.6,0.2,1c0,3.1-4.9,5.7-11,5.9c0,0.3-0.1,0.5,0,0.8
|
|
||||||
c0.3,3.8,6.9,6.4,14.6,5.8c7.8-0.6,13.9-4.2,13.6-8C306.8,265.4,300.2,262.8,292.4,263.4z"/>
|
|
||||||
<path d="M310.2,279.3c0,0-21.5,6.3-20.2,18.4s27.2,18.4,27.2,18.4s7,2.8,11-3.9c4-6.6,9.9-15.6,8.3-28.5
|
|
||||||
C336.5,283.7,336,274.1,310.2,279.3z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 3.1 KiB |
@@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M10 6H15C16.6569 6 18 7.34315 18 9C18 10.6569 16.6569 12 15 12M10 6V12M10 6H7M10 6V3M15 12H10M15 12C16.6569 12 18 13.3431 18 15C18 16.6569 16.6569 18 15 18H10M10 12V18M10 18H7M10 18V21M13 6V3M13 21V18" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 518 B |
@@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 336.41 337.42"><defs><style>.cls-1{fill:#f0b90b;stroke:#f0b90b;}</style></defs><title>Asset 1</title><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M168.2.71l41.5,42.5L105.2,147.71l-41.5-41.5Z"/><path class="cls-1" d="M231.2,63.71l41.5,42.5L105.2,273.71l-41.5-41.5Z"/><path class="cls-1" d="M42.2,126.71l41.5,42.5-41.5,41.5L.7,169.21Z"/><path class="cls-1" d="M294.2,126.71l41.5,42.5L168.2,336.71l-41.5-41.5Z"/></g></g></svg>
|
|
||||||
|
Before Width: | Height: | Size: 528 B |
@@ -1,13 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
||||||
<!-- Creator: CorelDRAW 2019 (64-Bit) -->
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="100%" height="100%" version="1.1" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd"
|
|
||||||
viewBox="0 0 444.44 444.44"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
xmlns:xodm="http://www.corel.com/coreldraw/odm/2003">
|
|
||||||
<g id="Layer_x0020_1">
|
|
||||||
<metadata id="CorelCorpID_0Corel-Layer"/>
|
|
||||||
<path fill="#F5AC37" fill-rule="nonzero" d="M222.22 0c122.74,0 222.22,99.5 222.22,222.22 0,122.74 -99.48,222.22 -222.22,222.22 -122.72,0 -222.22,-99.49 -222.22,-222.22 0,-122.72 99.5,-222.22 222.22,-222.22z"/>
|
|
||||||
<path fill="#FEFEFD" fill-rule="nonzero" d="M230.41 237.91l84.44 0c1.8,0 2.65,0 2.78,-2.36 0.69,-8.59 0.69,-17.23 0,-25.83 0,-1.67 -0.83,-2.36 -2.64,-2.36l-168.05 0c-2.08,0 -2.64,0.69 -2.64,2.64l0 24.72c0,3.19 0,3.19 3.33,3.19l82.78 0zm77.79 -59.44c0.24,-0.63 0.24,-1.32 0,-1.94 -1.41,-3.07 -3.08,-6 -5.02,-8.75 -2.92,-4.7 -6.36,-9.03 -10.28,-12.92 -1.85,-2.35 -3.99,-4.46 -6.39,-6.25 -12.02,-10.23 -26.31,-17.47 -41.67,-21.11 -7.75,-1.74 -15.67,-2.57 -23.61,-2.5l-74.58 0c-2.08,0 -2.36,0.83 -2.36,2.64l0 49.3c0,2.08 0,2.64 2.64,2.64l160.27 0c0,0 1.39,-0.28 1.67,-1.11l-0.68 0zm0 88.33c-2.36,-0.26 -4.74,-0.26 -7.1,0l-154.02 0c-2.08,0 -2.78,0 -2.78,2.78l0 48.2c0,2.22 0,2.78 2.78,2.78l71.11 0c3.4,0.26 6.8,0.02 10.13,-0.69 10.32,-0.74 20.47,-2.98 30.15,-6.67 3.52,-1.22 6.92,-2.81 10.13,-4.72l0.97 0c16.67,-8.67 30.21,-22.29 38.75,-39.01 0,0 0.97,-2.1 -0.12,-2.65zm-191.81 78.75l0 -0.83 0 -32.36 0 -10.97 0 -32.64c0,-1.81 0,-2.08 -2.22,-2.08l-30.14 0c-1.67,0 -2.36,0 -2.36,-2.22l0 -26.39 32.22 0c1.8,0 2.5,0 2.5,-2.36l0 -26.11c0,-1.67 0,-2.08 -2.22,-2.08l-30.14 0c-1.67,0 -2.36,0 -2.36,-2.22l0 -24.44c0,-1.53 0,-1.94 2.22,-1.94l29.86 0c2.08,0 2.64,0 2.64,-2.64l0 -74.86c0,-2.22 0,-2.78 2.78,-2.78l104.16 0c7.56,0.3 15.07,1.13 22.5,2.5 15.31,2.83 30.02,8.3 43.47,16.11 8.92,5.25 17.13,11.59 24.44,18.89 5.5,5.71 10.46,11.89 14.86,18.47 4.37,6.67 8,13.8 10.85,21.25 0.35,1.94 2.21,3.25 4.15,2.92l24.86 0c3.19,0 3.19,0 3.33,3.06l0 22.78c0,2.22 -0.83,2.78 -3.06,2.78l-19.17 0c-1.94,0 -2.5,0 -2.36,2.5 0.76,8.46 0.76,16.95 0,25.41 0,2.36 0,2.64 2.65,2.64l21.93 0c0.97,1.25 0,2.5 0,3.76 0.14,1.61 0.14,3.24 0,4.85l0 16.81c0,2.36 -0.69,3.06 -2.78,3.06l-26.25 0c-1.83,-0.35 -3.61,0.82 -4.03,2.64 -6.25,16.25 -16.25,30.82 -29.17,42.5 -4.72,4.25 -9.68,8.25 -14.86,11.94 -5.56,3.2 -10.97,6.53 -16.67,9.17 -10.49,4.72 -21.49,8.2 -32.78,10.41 -10.72,1.92 -21.59,2.79 -32.5,2.64l-96.39 0 0 -0.14z"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 2.7 KiB |
@@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2000 2000" width="2500" height="2500"><g fill="#c2a633"><path d="M1024 659H881.12v281.69h224.79v117.94H881.12v281.67H1031c38.51 0 316.16 4.35 315.73-327.72S1077.44 659 1024 659z"/><path d="M1000 0C447.71 0 0 447.71 0 1000s447.71 1000 1000 1000 1000-447.71 1000-1000S1552.29 0 1000 0zm39.29 1540.1H677.14v-481.46H549.48V940.7h127.65V459.21h310.82c73.53 0 560.56-15.27 560.56 549.48 0 574.09-509.21 531.41-509.21 531.41z"/></g></svg>
|
|
||||||
|
Before Width: | Height: | Size: 484 B |
@@ -1,35 +0,0 @@
|
|||||||
<?xml version="1.0" ?>
|
|
||||||
|
|
||||||
<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
|
|
||||||
|
|
||||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
<svg width="800px" height="800px" viewBox="0 0 32 32" id="_x3C_Layer_x3E_" version="1.1" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
||||||
|
|
||||||
<style type="text/css">
|
|
||||||
<![CDATA[
|
|
||||||
.st0{fill:none;stroke:#fff;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
|
|
||||||
.st1{fill:none;stroke:#fff;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
|
|
||||||
]]>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<g id="Ethereum_x2C__crypto_x2C__cryptocurrency_1_">
|
|
||||||
|
|
||||||
<g id="XMLID_15_">
|
|
||||||
|
|
||||||
<polygon class="st1" id="XMLID_8_" points="16.01,1.5 7.62,16.23 16.01,21.5 24.38,16.18 "/>
|
|
||||||
|
|
||||||
<line class="st1" id="XMLID_31_" x1="16.01" x2="16.01" y1="30.5" y2="24.1"/>
|
|
||||||
|
|
||||||
<polygon class="st1" id="XMLID_12_" points="16.01,30.5 7.62,18.83 16.01,24.1 24.38,18.78 "/>
|
|
||||||
|
|
||||||
<polygon class="st1" id="XMLID_30_" points="16.01,12.3 7.62,16.23 16.01,21.5 24.38,16.18 "/>
|
|
||||||
|
|
||||||
<line class="st1" id="XMLID_32_" x1="16.01" x2="16.01" y1="1.5" y2="21.5"/>
|
|
||||||
|
|
||||||
<polygon class="st1" id="XMLID_192_" points="16.01,1.5 7.62,16.23 16.01,21.5 24.38,16.18 "/>
|
|
||||||
|
|
||||||
</g>
|
|
||||||
|
|
||||||
</g>
|
|
||||||
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.2 KiB |
@@ -1,49 +1,41 @@
|
|||||||
import btc from './btc.svg'
|
// Единая точка доступа к логотипам монет.
|
||||||
import eth from './eth.svg'
|
// Логотипы автоматически подхватываются из этой папки — чтобы добавить новую
|
||||||
import sol from './sol.svg'
|
// монету, достаточно положить файл `<TICKER>.png` (или `.svg`) рядом с этим
|
||||||
import trx from './trx.svg'
|
// файлом. Ничего дописывать в код не нужно.
|
||||||
import bnb from './bnb.svg'
|
//
|
||||||
import arb from './arb.svg'
|
// При наличии и PNG, и SVG для одного тикера приоритет отдаётся PNG.
|
||||||
import bonk from './bonk.svg'
|
|
||||||
import busd from './busd.svg'
|
|
||||||
import dai from './dai.svg'
|
|
||||||
import doge from './doge.svg'
|
|
||||||
import jup from './jup.svg'
|
|
||||||
import link from './link.svg'
|
|
||||||
import orca from './orca.svg'
|
|
||||||
import popcat from './popcat.svg'
|
|
||||||
import pyth from './pyth.svg'
|
|
||||||
import ray from './ray.svg'
|
|
||||||
import uni from './uni.svg'
|
|
||||||
import usdc from './usdc.svg'
|
|
||||||
import usdt from './usdt.svg'
|
|
||||||
import w from './w.svg'
|
|
||||||
import wif from './wif.svg'
|
|
||||||
|
|
||||||
export const COIN_ICONS: Record<string, string> = {
|
type IconModules = Record<string, string>
|
||||||
BTC: btc,
|
|
||||||
ETH: eth,
|
const svgIcons = import.meta.glob('./*.svg', {
|
||||||
SOL: sol,
|
eager: true,
|
||||||
TRX: trx,
|
query: '?url',
|
||||||
BNB: bnb,
|
import: 'default',
|
||||||
ARB: arb,
|
}) as IconModules
|
||||||
BONK: bonk,
|
|
||||||
BUSD: busd,
|
const pngIcons = import.meta.glob('./*.png', {
|
||||||
DAI: dai,
|
eager: true,
|
||||||
DOGE: doge,
|
query: '?url',
|
||||||
JUP: jup,
|
import: 'default',
|
||||||
LINK: link,
|
}) as IconModules
|
||||||
ORCA: orca,
|
|
||||||
POPCAT: popcat,
|
/** Достаёт тикер из пути вида `./usdt.svg` → `USDT`. */
|
||||||
PYTH: pyth,
|
function tickerFromPath(path: string): string {
|
||||||
RAY: ray,
|
return path.replace(/^\.\//, '').replace(/\.[^.]+$/, '').toUpperCase()
|
||||||
UNI: uni,
|
|
||||||
USDC: usdc,
|
|
||||||
USDT: usdt,
|
|
||||||
W: w,
|
|
||||||
WIF: wif,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function collect(modules: IconModules, target: Record<string, string>) {
|
||||||
|
for (const [path, url] of Object.entries(modules)) {
|
||||||
|
target[tickerFromPath(path)] = url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Карта `ТИКЕР → url логотипа`. PNG перекрывает SVG при совпадении тикера. */
|
||||||
|
export const COIN_ICONS: Record<string, string> = {}
|
||||||
|
collect(svgIcons, COIN_ICONS) // сначала svg…
|
||||||
|
collect(pngIcons, COIN_ICONS) // …затем png перекрывает
|
||||||
|
|
||||||
|
/** Вернуть url логотипа по тикеру (регистр не важен), либо undefined. */
|
||||||
export function getCoinIcon(ticker: string): string | undefined {
|
export function getCoinIcon(ticker: string): string | undefined {
|
||||||
return COIN_ICONS[ticker.toUpperCase()]
|
return COIN_ICONS[ticker.toUpperCase()]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,52 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="katman_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 800 800" style="enable-background:new 0 0 800 800;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{fill:#141726;}
|
|
||||||
.st1{fill:url(#SVGID_1_);}
|
|
||||||
.st2{fill:url(#SVGID_2_);}
|
|
||||||
.st3{fill:url(#SVGID_3_);}
|
|
||||||
.st4{fill:url(#SVGID_4_);}
|
|
||||||
.st5{fill:url(#SVGID_5_);}
|
|
||||||
.st6{fill:url(#SVGID_6_);}
|
|
||||||
</style>
|
|
||||||
<circle class="st0" cx="400" cy="400" r="400"/>
|
|
||||||
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="574.9257" y1="665.8727" x2="248.5257" y2="142.3127" gradientTransform="matrix(1 0 0 -1 0 800)">
|
|
||||||
<stop offset="0.16" style="stop-color:#C6F462"/>
|
|
||||||
<stop offset="0.89" style="stop-color:#33D9FF"/>
|
|
||||||
</linearGradient>
|
|
||||||
<path class="st1" d="M536,568.9c-66.8-108.5-166.4-170-289.4-195.6c-43.5-9-87.2-8.9-129.4,7.7c-28.9,11.4-33.3,23.4-19.7,53.7
|
|
||||||
c92.4-21.9,178.4-1.5,258.9,45c81.1,46.9,141.6,112.2,169.1,205c38.6-11.8,43.6-18.3,34.3-54.2C554.3,609.4,547.4,587.4,536,568.9
|
|
||||||
L536,568.9z"/>
|
|
||||||
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="572.5896" y1="667.3303" x2="246.1996" y2="143.7703" gradientTransform="matrix(1 0 0 -1 0 800)">
|
|
||||||
<stop offset="0.16" style="stop-color:#C6F462"/>
|
|
||||||
<stop offset="0.89" style="stop-color:#33D9FF"/>
|
|
||||||
</linearGradient>
|
|
||||||
<path class="st2" d="M609.1,480.6c-85.8-125-207.3-194.9-355.8-218.3c-39.3-6.2-79.4-4.5-116.2,14.3c-17.6,9-33.2,20.5-37.4,44.9
|
|
||||||
c115.8-31.9,219.7-3.7,317.5,53c98.3,57,175.1,133.5,205,251.1c20.8-18.4,24.5-41,19.1-62C633.9,534.8,625.5,504.5,609.1,480.6
|
|
||||||
L609.1,480.6z"/>
|
|
||||||
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="577.0148" y1="664.5671" x2="250.6247" y2="141.0071" gradientTransform="matrix(1 0 0 -1 0 800)">
|
|
||||||
<stop offset="0.16" style="stop-color:#C6F462"/>
|
|
||||||
<stop offset="0.89" style="stop-color:#33D9FF"/>
|
|
||||||
</linearGradient>
|
|
||||||
<path class="st3" d="M105,488.6c7.3,16.2,12.1,34.5,23,47.6c5.5,6.7,22.2,4.1,33.8,5.7c1.8,0.2,3.6,0.5,5.4,0.7
|
|
||||||
c102.9,15.3,184.1,65.1,242.1,152c3.4,5.1,8.9,12.7,13.4,12.7c17.4-0.1,34.9-2.8,52.5-4.5C449,557.5,232.8,438.3,105,488.6
|
|
||||||
L105,488.6z"/>
|
|
||||||
<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="569.0272" y1="669.5518" x2="242.6272" y2="145.9917" gradientTransform="matrix(1 0 0 -1 0 800)">
|
|
||||||
<stop offset="0.16" style="stop-color:#C6F462"/>
|
|
||||||
<stop offset="0.89" style="stop-color:#33D9FF"/>
|
|
||||||
</linearGradient>
|
|
||||||
<path class="st4" d="M656.6,366.7C599.9,287.4,521.7,234.6,432.9,197c-61.5-26.1-125.2-41.8-192.8-33.7
|
|
||||||
c-23.4,2.8-45.3,9.5-63.4,24.7c230.9,5.8,404.6,105.8,524,303.3c0.2-13.1,2.2-27.7-2.6-39.5C686.1,422.5,674.7,392,656.6,366.7z"/>
|
|
||||||
<linearGradient id="SVGID_5_" gradientUnits="userSpaceOnUse" x1="571.6973" y1="667.8917" x2="245.2973" y2="144.3317" gradientTransform="matrix(1 0 0 -1 0 800)">
|
|
||||||
<stop offset="0.16" style="stop-color:#C6F462"/>
|
|
||||||
<stop offset="0.89" style="stop-color:#33D9FF"/>
|
|
||||||
</linearGradient>
|
|
||||||
<path class="st5" d="M709.8,325.3c-47-178.9-238-265-379.2-221.4C482.7,133.9,607.5,206.4,709.8,325.3z"/>
|
|
||||||
<linearGradient id="SVGID_6_" gradientUnits="userSpaceOnUse" x1="579.0382" y1="663.3111" x2="252.6482" y2="139.7511" gradientTransform="matrix(1 0 0 -1 0 800)">
|
|
||||||
<stop offset="0.16" style="stop-color:#C6F462"/>
|
|
||||||
<stop offset="0.89" style="stop-color:#33D9FF"/>
|
|
||||||
</linearGradient>
|
|
||||||
<path class="st6" d="M155.4,583.9c54.6,69.3,124,109.7,213,122.8C334.4,643.2,214.6,574.5,155.4,583.9L155.4,583.9z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 3.5 KiB |
@@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 37.8 43.6"><defs><style>.cls-1{fill:#2a5ada;}</style></defs><title>Asset 1</title><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M18.9,0l-4,2.3L4,8.6,0,10.9V32.7L4,35l11,6.3,4,2.3,4-2.3L33.8,35l4-2.3V10.9l-4-2.3L22.9,2.3ZM8,28.1V15.5L18.9,9.2l10.9,6.3V28.1L18.9,34.4Z"/></g></g></svg>
|
|
||||||
|
Before Width: | Height: | Size: 387 B |
@@ -1,40 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="CIRCLE_OUTLINE_BLACK" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
x="0px" y="0px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{fill:#FFD15C;}
|
|
||||||
.st1{fill:#FFFFFF;}
|
|
||||||
</style>
|
|
||||||
<path class="st0" d="M512,256c0,141.4-114.6,256-256,256S0,397.4,0,256S114.6,0,256,0S512,114.6,512,256z"/>
|
|
||||||
<path class="st1" d="M193.5,152.3c-10.4,1.5-4.6,10.4-4.6,10.4l-0.3,2.5c14.9,25.7,39.5,52.7,64.6,70.7c18.5,13.2,32.3,32.7,39,54.9
|
|
||||||
c6.6,21.9,5.4,44.6-3.2,62.2c-10.4,21.2-30.1,33.5-55.3,34.7c-25.1,1.2-54.9-8.7-88.6-29.4c-0.3,0.8-0.7,1.6-1.1,2.3
|
|
||||||
c29.2,30.1,63,48.1,98.1,52.2c35.5,4.2,71.9-5.8,102.7-27.9c-0.8,0-1.4-0.2-1.9-0.5C446.5,298.8,276.9,140.4,193.5,152.3
|
|
||||||
L193.5,152.3z"/>
|
|
||||||
<path d="M462.6,267.4c-0.1-1.9-0.2-4.2-0.6-6.9c-1.3-10.5-5.5-26.6-17.7-43.7c-0.6-0.8-1.2-1.6-1.8-2.4c-0.1-0.2-0.3-0.4-0.4-0.6
|
|
||||||
c-0.5-0.7-1.1-1.4-1.6-2.1c0,0-0.1-0.1-0.1-0.1c-0.6-0.7-1.2-1.5-1.8-2.2c-0.1-0.2-0.3-0.3-0.4-0.5c-0.5-0.6-1.1-1.3-1.6-1.9
|
|
||||||
c-0.1-0.1-0.1-0.1-0.2-0.2c-0.6-0.7-1.2-1.3-1.8-2c-0.1-0.1-0.3-0.3-0.4-0.4c-0.5-0.6-1-1.1-1.5-1.6c-0.1-0.1-0.2-0.2-0.2-0.3
|
|
||||||
c-0.6-0.6-1.2-1.2-1.7-1.7c-0.1-0.1-0.2-0.2-0.4-0.4c-0.5-0.5-1-1-1.5-1.4c-0.1-0.1-0.2-0.2-0.3-0.3c-0.6-0.5-1.1-1-1.7-1.5
|
|
||||||
c-0.1-0.1-0.2-0.2-0.3-0.3c-0.5-0.4-1-0.8-1.4-1.2c-0.1-0.1-0.2-0.2-0.3-0.3c-0.5-0.5-1.1-0.9-1.6-1.3c-0.1-0.1-0.2-0.2-0.3-0.3
|
|
||||||
c-0.4-0.4-0.9-0.7-1.3-1.1c-0.1-0.1-0.3-0.2-0.4-0.3c-0.5-0.4-1-0.8-1.5-1.1c-0.1-0.1-0.2-0.2-0.3-0.2c-0.4-0.3-0.8-0.6-1.2-0.9
|
|
||||||
c-0.1-0.1-0.3-0.2-0.4-0.3c-0.5-0.3-0.9-0.6-1.4-1c-0.1-0.1-0.2-0.2-0.4-0.2c-0.4-0.2-0.7-0.5-1-0.7c-0.2-0.1-0.3-0.2-0.5-0.3
|
|
||||||
c-0.4-0.2-0.8-0.5-1.1-0.7c-0.2-0.1-0.4-0.2-0.5-0.3c-0.3-0.2-0.5-0.3-0.8-0.5c-0.2-0.1-0.4-0.2-0.6-0.3c-0.2-0.1-0.5-0.3-0.7-0.4
|
|
||||||
c-0.3-0.2-0.6-0.4-1-0.5c-0.2-0.1-0.3-0.2-0.5-0.3c-0.2-0.1-0.4-0.2-0.7-0.3c-0.1-0.1-0.2-0.1-0.3-0.2c-0.4-0.2-0.9-0.5-1.3-0.7
|
|
||||||
c0,0-0.1,0-0.1,0c-2.7-4.8-5.7-9.6-8.9-14.4c-37.3-54.6-78.2-81.1-124.9-81.2h-0.2c-19.8,0-37.9,4.5-53,8.9c-4.3,1.3-8.8,2.6-13.1,4
|
|
||||||
c-11,3.4-21.4,6.7-30.3,8.1c-5.6,0.9-10,3-13.1,6.2c-2.8,3-4.5,7.1-5,12.1c-1,9.7,2.5,22.8,10.1,37.8c15.3,30.4,44.6,63.9,74.6,85.4
|
|
||||||
c3.5,2.5,6.7,5.2,9.7,8.2c-0.6,0.1-1.2,0.2-1.9,0.3c-23.5,3.4-35.8,28.6-40.7,42.3c-1.3,3.6,2.2,6.8,5.8,5.5
|
|
||||||
c14.6-4.9,44.3-12.9,61-2.6c0.1,0,0.3-0.1,0.4-0.1c3,15,1.6,29.8-4.1,41.3c-7.5,15.1-21.8,24-40.3,24.9
|
|
||||||
c-21.8,1.1-48.6-8.2-79.7-27.6l-0.5-0.3c-0.3-0.1-0.6-0.3-0.8-0.5c24.2-27.5,9.9-69.9,4.3-83.8c-0.7-1.8-3.3-1.8-4.3-0.1
|
|
||||||
c-13,22.1-39.8,20.4-39.3,46.7c0,0,0,0,0-0.1c-20.4-16.6-35.6,5.5-61,2.2c-2-0.3-3.5,1.7-2.5,3.4c7.7,13.3,33.5,52.3,71.6,47.9
|
|
||||||
l-1.8,1.3l6.8,7.5c33.3,36.7,72.9,58.7,114.6,63.6c6,0.7,12,1.1,18,1.1c34.9,0,69.6-11.7,99.4-33.9c34.2-25.4,57.9-61.3,66.8-101
|
|
||||||
c3-13.2,4.2-26.4,3.7-39.5c7.5-3,15.7,0.3,22.2,4.7c0.1,0,0.1,0.1,0.2,0.1c0.3,0.2,0.5,0.4,0.8,0.5c0.1,0,0.1,0.1,0.2,0.1
|
|
||||||
c0.8,0.5,1.5,1.1,2.2,1.6c0.1,0.1,0.3,0.2,0.4,0.3c0.2,0.1,0.3,0.3,0.5,0.4c0.2,0.1,0.3,0.3,0.5,0.4c0.1,0.1,0.3,0.2,0.4,0.4
|
|
||||||
c0.3,0.2,0.6,0.5,0.8,0.7c0.1,0.1,0.2,0.2,0.3,0.2c0.2,0.2,0.4,0.4,0.6,0.5c0.1,0.1,0.2,0.2,0.3,0.3c0.2,0.2,0.4,0.3,0.6,0.5
|
|
||||||
c0.1,0.1,0.2,0.1,0.2,0.2c0.2,0.2,0.5,0.5,0.7,0.7c0.1,0.1,0.2,0.1,0.2,0.2c0.5,0.4,1.1,0.5,1.6,0.5
|
|
||||||
C461.7,269.5,462.7,268.6,462.6,267.4z M342.9,384.5c0.5,0.3,1.1,0.4,1.9,0.5c-30.8,22.2-67.2,32.1-102.7,27.9
|
|
||||||
c-35.2-4.1-68.9-22.1-98.1-52.2c0.4-0.8,0.8-1.5,1.1-2.3c33.7,20.7,63.5,30.6,88.6,29.4c25.2-1.2,44.9-13.6,55.3-34.7
|
|
||||||
c8.7-17.6,9.8-40.2,3.2-62.2c-6.7-22.2-20.5-41.7-39-54.9c-25.2-18-49.7-45-64.6-70.7l0.3-2.5c0,0-5.8-8.9,4.6-10.4
|
|
||||||
C276.9,140.4,446.5,298.8,342.9,384.5z"/>
|
|
||||||
<path class="st1" d="M280.3,146.5c-2.9-4.1-8.7-15.1,9.3-15.1c18,0,45.4,20.3,51,27.8c-1.7,4.6-13.3,5.6-19.1,5.2
|
|
||||||
s-15.6-1.4-23.2-5.2C290.8,155.6,283.2,150.6,280.3,146.5z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 3.8 KiB |
@@ -1,97 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="Слой_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 994.3 1000.5" style="enable-background:new 0 0 994.3 1000.5;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{fill:#F7F5F8;}
|
|
||||||
.st1{fill:#DCC4D4;}
|
|
||||||
.st2{fill:#EFAD93;}
|
|
||||||
.st3{fill:#D68C72;}
|
|
||||||
.st4{fill:#964C49;}
|
|
||||||
.st5{fill:#3A0101;}
|
|
||||||
.st6{fill:#894544;}
|
|
||||||
.st7{fill:#E3746D;}
|
|
||||||
.st8{fill:#FFFFFF;}
|
|
||||||
.st9{fill:#623538;}
|
|
||||||
.st10{fill:#C95755;}
|
|
||||||
</style>
|
|
||||||
<g>
|
|
||||||
<path class="st0" d="M27.4,444.9l471.8-254l124.2-2.5c0,0,129.7,15.8,232.7,116.6c0.1,0.1,0.2,0.1,0.2,0.2
|
|
||||||
c28.2,27.7,54.4,62.5,75.1,106.3c1.4,2.9,2.8,5.9,4.1,8.9c0,0,151.2,244-41.3,456.4c-192.5,212.3-651.4,110.6-789.3-112.5
|
|
||||||
c-1-1.5-2-3.1-3-4.7c-21.2-34.1-37-67.9-48.6-99.2c-14.7-39.6-22.9-75.1-27.4-101.6C20.8,528.5,27.5,444.9,27.4,444.9z"/>
|
|
||||||
<path class="st1" d="M218.8,420.3c-31.3,88.9,7.8,189.9,85.9,99.6c111.2-153,321.4-183.3,405.1-172.5
|
|
||||||
c102.5,19.8,182.5,123.4,207.9,125.4c25.4,2,13.7-61.3,13.7-61.3c1.4,2.9,2.8,5.9,4.1,8.9c0,0,151.2,244-41.3,456.4
|
|
||||||
C701.7,1089.1,242.8,987.4,105,764.2c-1-1.5-2-3.1-3-4.7c-21.2-34.1-37-67.9-48.6-99.2C106.8,572.1,243.9,348.5,218.8,420.3z"/>
|
|
||||||
<path class="st2" d="M680.7,183.7c49.4-48.5,129.9-117.2,190.6-152.4c29.2-17,53.8-26.2,68.1-21.7c2.8,0.8,5.1,2.2,7.1,4.1
|
|
||||||
c23.7,23.2,14.4,169.4,3.6,279.9c-7,70.6-14.6,126.7-14.6,126.7c-15.5-33.2-32-65.7-81.8-118c-20.7-20.3-41.8-37.4-63.2-51.7
|
|
||||||
c-36-24-72.5-40.1-108.3-50.3c-4.8-1.4-9.6-2.6-14.4-3.8C671.8,192.5,676.1,188.2,680.7,183.7z"/>
|
|
||||||
<path class="st3" d="M871.3,31.4c-10.1,73.5-12.2,200.9,78.8,262.3c-7,70.6-14.6,126.7-14.6,126.7c-15.5-33.2-32-65.7-81.8-118
|
|
||||||
c-20.7-20.3-41.8-37.4-63.2-51.7c-36-24-72.5-40.1-108.3-50.3l-1.6-16.6C730.1,135.2,810.6,66.6,871.3,31.4z"/>
|
|
||||||
<path class="st4" d="M51.1,14.9c49.7-15.8,213.2,136.5,315.7,216.5c0,0,141.2-74,301.1-34.9c7.5,1.8,15.1,3.9,22.8,6.3
|
|
||||||
c-46.6-1.7-115.4-3.1-144.9,2.2C499,213.5,329,264,254.7,383.2c-74.3,119.1-71.3,258.8-69.5,320.2c1.4,48.9-34.4,79.5-88.3,48
|
|
||||||
c-44.5-74.3-63.2-146.8-71-192.6c-1.1-10.1-2.2-20.5-3.5-31c-0.8-6-1.4-12-2.1-17.9C-12.3,223.4,2.5,30.3,51.1,14.9z"/>
|
|
||||||
<path class="st4" d="M939.4,9.6c-41.2,32.2-128.1,113.5-148.9,241c-40.8-27.2-82.3-44.2-122.7-54.1C736,126.7,892.6-5,939.4,9.6z"
|
|
||||||
/>
|
|
||||||
<path class="st5" d="M667.3,196.7c18-21.7,38.7-41.3,59-60.8c30.9-28.7,63.1-56.1,97.5-80.5c23.1-16.3,47-31.5,73.2-42.8
|
|
||||||
c13.8-5.3,28.2-11.2,43.7-6.9c3.2,0.8,4.1,5.5,1.3,7.4c-48,35.5-89.8,81.2-115,136l-7.3,16.4l-6.3,16.8c-8.3,23.1-13.5,47.2-19,71
|
|
||||||
c-1.4,2.2-4.4,2.7-6.5,1.3c-9.3-6.2-18.7-12.1-28.3-17.7C730.6,220,699.1,207.3,667.3,196.7L667.3,196.7z M668.3,196.4
|
|
||||||
c33.5,5.2,65.5,17.4,95.4,33c10,5.2,19.8,11.1,29.3,17.3l-7.2,3.2c11.1-73.1,51.8-137.4,99-192.5c15.9-18.4,33.2-35.6,52-51.1
|
|
||||||
l1.3,7.4c-34.7-7-111.7,54.4-141.3,75.9C755.4,121.4,714.9,155,676,189.9C673.8,191.8,670.7,194.7,668.3,196.4L668.3,196.4z"/>
|
|
||||||
<path class="st5" d="M667,196.8c9.8-12.7,21.5-23.8,32.5-35.3c56.3-55.7,115.3-109,185.4-147.2C903.6,5.5,934-9.3,952.6,8
|
|
||||||
c8.6,9.3,11,23.4,12.9,34.8c7.6,63.5,0.5,127.1-5.9,190.2c-7.1,62.7-14.3,125.2-20.2,188c-0.1,1.2-0.9,2.5-2.1,3.1
|
|
||||||
c-1.9,1-4.3,0.2-5.3-1.7c-21.3-43.7-51.6-81.8-85.2-116.5c-29-28.5-61.5-53.6-97.1-73.3C723.7,217.7,695.1,206.6,667,196.8
|
|
||||||
L667,196.8z M668.6,196.3c102.9,16.6,200.3,90.3,251,181.1c7.4,13.4,13.7,27.4,19.6,41.3l-7.6,1.2c15.8-93,21.6-187.6,22.5-281.8
|
|
||||||
c0.1-30.9,0.3-62.6-4.6-92.8c-1.5-8.2-3.1-16-6.7-22.5c-2.2-3.9-5.1-5.3-10-5.6c-13.2-0.3-28,6.5-40.3,12.5
|
|
||||||
c-13.6,6.6-26.9,14.5-39.9,22.9c-62,40.5-119.8,87.7-175.4,136.6C674.9,191.3,671.1,194.7,668.6,196.3L668.6,196.3z"/>
|
|
||||||
<path class="st5" d="M368.1,222.4c0,0-27.7,15.2-48.3,39.2c32.8-26.4,66.9-39.2,66.9-39.2H368.1z"/>
|
|
||||||
<path class="st5" d="M51.4,15.6C-13.1,43.9,7.5,316.1,13.6,383c3.6,42.3,8.6,84.5,13.7,126.7c0.9,16.6,3.4,33.8,6.5,50.3
|
|
||||||
c15.8,83.2,49,164.3,101,231.4c162.6,201.4,596.3,285.2,772.8,64.1c93.2-112.3,103.3-255.1,47.5-387.3c-6.8-15.7-14.3-31.3-23-45.7
|
|
||||||
c-9.8-21.3-21.3-41.7-34.7-60.8C858,307,809.5,265.5,746.8,233.1c-117.3-59-260-50.3-377.9,2.6c-1.6,0.8-3.7,0.7-5.2-0.5
|
|
||||||
c-50.3-40.8-98.5-83.9-148.5-125C183.7,85.2,89.5,5.3,51.4,15.6L51.4,15.6z M50.9,14.1c38.2-10.9,133.1,68.2,166.8,93
|
|
||||||
c51.1,39.6,100.6,81.4,152,120.5l-5.2-0.5c10.1-5.3,20.2-9.7,30.6-13.9c113.6-45.9,247.7-50.1,357.9,7.6
|
|
||||||
c38.5,19.3,80,51.8,106.2,79.6c28.3,26.3,63.5,77.6,79.6,117.9c37.5,68.6,57.7,147.2,55.3,225.5c-2,78.7-32.2,155.1-80.9,216.3
|
|
||||||
c-144.1,184.7-435.8,164.2-626.6,69.8c-70.3-34.9-136.1-83.3-181-148.9c-52.9-79.3-87.3-177.1-92-270.3
|
|
||||||
c-12-126.6-19.9-254.6-7-381.4C10.8,98.9,18.7,25.8,50.9,14.1L50.9,14.1z"/>
|
|
||||||
<path class="st2" d="M56.5,68.9c10.8,4.5,48,42.6,88.9,92c33.1,40,68.6,87.5,94.4,130.5C256.3,318.9,134.9,522,113,560.3
|
|
||||||
c-20.1,35.1-64.5-92-76.1-226c-1.1-12-1.8-23.9-2.3-35.9C28.8,152.3,36.9,60.8,56.5,68.9z"/>
|
|
||||||
<path class="st6" d="M327.6,643.2c7.1-85.1,52.7-166.4,117.6-206.6c75-42,139.1-61.4,202.6-61.1l0,0c15.2,0.1,30.5,1.3,45.8,3.6
|
|
||||||
c15,2.3,30.1,5.6,45.5,9.9c66,18.5,208.6,88.2,186.5,282.8c-0.7,5.8-1.5,11.5-2.5,17.2C891,873.9,688.2,995.2,467.4,887.4
|
|
||||||
C358,834,319.8,736.3,327.6,643.2z"/>
|
|
||||||
<path class="st7" d="M636.5,336.4c9.7,2.9,32.2,11.3,56.1-1c23.9-12.3,33.2,15.1,20.5,22.1c-14.4,7.9-18.4,17-19.6,21.7
|
|
||||||
c-15.3-2.3-30.5-3.5-45.8-3.6l0,0c-4.1-7.4-25.4-8.4-33.2-21.1C606.7,341.7,626.8,333.4,636.5,336.4z"/>
|
|
||||||
<path class="st8" d="M386.7,314c6.2-5.8,12.6-10.9,19.1-15.3c58-40,121.3-28.3,130.8-3.7c10.6,27.3-35.8,36.7-64.2,48.6
|
|
||||||
c-25.9,10.8-56.1,30.6-78.7,43.5c-16.6,9.5-29.3,15.3-33.1,11.1C351.5,388.3,342.5,354.9,386.7,314z"/>
|
|
||||||
<path class="st8" d="M773.8,272.5c33.4,12.4,58.6,33.3,75,50.7c11.4,12.1,18.4,22.5,20.9,27.2c6.1,11.4-12.7,14-36.2,5.3
|
|
||||||
c-1-0.4-2.1-0.8-3.2-1.2c-25.3-9-84.3-25.6-101.1-33C705.1,310.9,717.2,251.5,773.8,272.5z"/>
|
|
||||||
<path class="st5" d="M405.8,298.7c58-40,121.3-28.3,130.8-3.7c10.6,27.3-35.8,36.7-64.2,48.6c-25.9,10.8-56.1,30.6-78.7,43.5
|
|
||||||
C370.3,352.9,386.3,320.8,405.8,298.7z"/>
|
|
||||||
<path class="st5" d="M773.8,272.5c33.4,12.4,58.6,33.3,75,50.7c0.6,10.9-2.7,23.7-18.5,31.3c-25.3-9-84.3-25.6-101.1-33
|
|
||||||
C705.1,310.9,717.2,251.5,773.8,272.5z"/>
|
|
||||||
<path class="st5" d="M504.4,274.3c-72.3-19-136.4,35.7-149,74s-0.5,51.9,0,40.6s0-28.9,18-52.9c18.1-24,76-50.5,76-50.5
|
|
||||||
S477.1,292.5,504.4,274.3z"/>
|
|
||||||
<path class="st5" d="M869.5,341.4c-20.4-25.1-54.2-47.2-54.2-47.2s5.1,17,18.1,25.7c13,8.8,37.3,35.8,37.3,35.8
|
|
||||||
S876.6,352.4,869.5,341.4z"/>
|
|
||||||
<path class="st8" d="M504.4,294.2c-8.5,0.9-74.6,10.1-65.2-3.7s34.7-12.3,55.5-10.7C517.1,281.5,512.9,293.4,504.4,294.2z"/>
|
|
||||||
<path class="st8" d="M803.6,314.5c-12.8-6.2-34.7-17.4-31.5-26s27.8,6.4,42.5,14C833.1,312,816.4,320.7,803.6,314.5z"/>
|
|
||||||
<path class="st9" d="M445.2,436.6c75-42,139.1-61.4,202.6-61.1l0,0c15.2,0.1,30.5,1.3,45.8,3.6c15,2.3,30.1,5.6,45.5,9.9
|
|
||||||
c66,18.5,208.6,88.2,186.5,282.7c-0.7,5.8-1.5,11.5-2.5,17.2C859.5,755.1,757.8,798,643,797.9c-139.3,0-259.6-63.2-315.5-154.7
|
|
||||||
C334.6,558.1,380.2,476.8,445.2,436.6z"/>
|
|
||||||
<path class="st5" d="M467,888.1c-4.1-2.1-15-8-19-10.1c-4.3-2.5-13.8-8.5-18.2-11.3c-5.7-3.9-11.5-8.7-17.3-12.6
|
|
||||||
c-12.8-10.7-25.3-22-35.9-35c-51-59.2-67.4-143.5-50-219.2c14.9-66.8,52.5-130.4,110.4-168.2c74.4-43.3,162.1-73,249-60.2
|
|
||||||
c66.6,9.1,131.6,37.9,178.2,87.3c47.5,48.6,68.8,117.8,66.7,185c-0.4,38.6-7.7,77.3-22.3,113.1C871.9,848.2,785.9,914.7,689,928
|
|
||||||
C613.2,939.7,535.3,921.3,467,888.1L467,888.1z M467.7,886.6c103.1,51,224,52.6,322.3-10.2c62.5-40,109.6-104.2,126.4-177.1
|
|
||||||
c12.6-54.7,12.2-114.2-9.7-166.5C878,462.3,811,414,739.3,394.7C633,365.6,539,391.2,446.1,446.3
|
|
||||||
C361.9,503,321.5,614.9,336.4,714.1c5.5,34.6,19.1,68.2,39.4,96.7c3.2,4,7.6,9.9,10.8,13.9c6.6,7.1,14.9,16.4,22.4,22.6l5.2,4.8
|
|
||||||
l5.6,4.3c6.3,5.3,16.2,11.9,23.2,16.3C449.7,877.2,460.6,882.6,467.7,886.6L467.7,886.6z"/>
|
|
||||||
<path class="st10" d="M624.5,349.4c9.9-5,28,14.1,28,14.1C630,361.9,614.5,354.5,624.5,349.4z"/>
|
|
||||||
<path class="st10" d="M709.7,347.4c-8.3-4.5-19.1,16.1-19.1,16.1C701.2,361.2,718,351.9,709.7,347.4z"/>
|
|
||||||
<path class="st3" d="M145.4,160.9c33.1,40,68.6,87.5,94.4,130.5c16.5,27.5-104.9,230.6-126.9,268.9c-20.1,35.1-64.5-92-76.1-226
|
|
||||||
C134.4,390.3,148.1,261.2,145.4,160.9z"/>
|
|
||||||
<path class="st5" d="M239.3,291.7C203,231.8,156.6,179,109.9,127.3C94.3,110.6,78.5,93.1,61,78.7c-2.4-1.8-4.8-3.7-6.8-4.5
|
|
||||||
c-2.9,2.5-5.2,9.1-6.4,13.8c-7.9,33.4-8.7,68.6-9.8,103.1c-0.4,23.2-0.5,46.6-0.3,69.9c-0.2,70,5.5,140.1,23.6,207.9
|
|
||||||
c5.3,20,24.9,86.9,43.7,93.3c1.6-0.1,2.6-1.2,3.6-2.7l0.9-1.5c3.4-7.1,73.1-128.3,78.8-138.8C201.1,395.1,248.5,315.1,239.3,291.7
|
|
||||||
L239.3,291.7z M240.3,291.1c10.1,18.9-35.6,108.8-46,131.3c-23,47.3-49.2,93.1-76.6,137.9c-2,4.1-7.1,10.6-13.3,9.8
|
|
||||||
c-30.8-4.3-55.4-138.4-61-168.9C30.8,332,27.6,261.4,27.8,191.1c0.8-28.9-0.2-103.5,17.4-124.3c7.7-8.1,16.3-2.5,22.8,3
|
|
||||||
c9.4,7.7,17.6,16.1,25.8,24.6C150,154,197.5,221.4,240.3,291.1L240.3,291.1z"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 8.6 KiB |
@@ -1,14 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="CIRCLE_OUTLINE_BLACK" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
x="0px" y="0px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{fill:#E6DAFE;}
|
|
||||||
</style>
|
|
||||||
<circle class="st0" cx="256" cy="256" r="256"/>
|
|
||||||
<path d="M303.4,228.5c0,20.7-16.7,37.5-37.4,37.5v37.5c41.3,0,74.7-33.5,74.7-74.9s-33.5-74.9-74.7-74.9c-13.6,0-26.4,3.6-37.4,10
|
|
||||||
c-22.3,12.9-37.4,37.2-37.4,64.9v187.3l33.6,33.7l3.8,3.8V228.5c0-20.7,16.7-37.5,37.4-37.5S303.4,207.9,303.4,228.5z"/>
|
|
||||||
<path d="M266,78.7c-27.2,0-52.7,7.3-74.7,20.1c-14.1,8.1-26.7,18.5-37.4,30.7c-23.2,26.4-37.4,61.1-37.4,99.1v112.4l37.4,37.5V228.5
|
|
||||||
c0-33.3,14.4-63.2,37.4-83.8c10.8-9.7,23.4-17.3,37.4-22.2c11.7-4.2,24.3-6.4,37.4-6.4c61.9,0,112.1,50.3,112.1,112.4
|
|
||||||
S327.9,340.9,266,340.9v37.5c82.5,0,149.4-67.1,149.4-149.8S348.5,78.7,266,78.7z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.0 KiB |
@@ -1,37 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 32 36.9" style="enable-background:new 0 0 32 36.9;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{fill:url(#SVGID_1_);}
|
|
||||||
.st1{fill:url(#SVGID_2_);}
|
|
||||||
.st2{fill:url(#SVGID_3_);}
|
|
||||||
.st3{fill:url(#SVGID_4_);}
|
|
||||||
</style>
|
|
||||||
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="32.95" y1="26.3048" x2="-0.9788" y2="12.7367" gradientTransform="matrix(1 0 0 -1 0 38)">
|
|
||||||
<stop offset="0" style="stop-color:#C200FB"/>
|
|
||||||
<stop offset="0.4897" style="stop-color:#3772FF"/>
|
|
||||||
<stop offset="1" style="stop-color:#5AC4BE"/>
|
|
||||||
</linearGradient>
|
|
||||||
<path class="st0" d="M30.3,13.9v12.9L16,35L1.7,26.7V10.2L16,1.9l11,6.4l1.7-1L16,0L0,9.2v18.5l16,9.2l16-9.2V12.9L30.3,13.9z"/>
|
|
||||||
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="32.2949" y1="27.9428" x2="-1.6339" y2="14.3747" gradientTransform="matrix(1 0 0 -1 0 38)">
|
|
||||||
<stop offset="0" style="stop-color:#C200FB"/>
|
|
||||||
<stop offset="0.4897" style="stop-color:#3772FF"/>
|
|
||||||
<stop offset="1" style="stop-color:#5AC4BE"/>
|
|
||||||
</linearGradient>
|
|
||||||
<path class="st1" d="M12,26.8H9.6v-8h8c0.8,0,1.5-0.3,2-0.9c0.5-0.5,0.8-1.3,0.8-2c0-0.4-0.1-0.7-0.2-1.1c-0.1-0.3-0.4-0.7-0.6-0.9
|
|
||||||
c-0.3-0.3-0.6-0.5-0.9-0.6S18,13,17.6,13h-8v-2.4h8c1.4,0,2.7,0.6,3.7,1.6c1,1,1.6,2.3,1.6,3.7c0,1.1-0.3,2.1-0.9,3
|
|
||||||
c-0.6,0.8-1.4,1.5-2.3,1.9c-0.9,0.3-1.9,0.4-2.9,0.4H12V26.8z"/>
|
|
||||||
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="35.6876" y1="19.4591" x2="1.7588" y2="5.891" gradientTransform="matrix(1 0 0 -1 0 38)">
|
|
||||||
<stop offset="0" style="stop-color:#C200FB"/>
|
|
||||||
<stop offset="0.4897" style="stop-color:#3772FF"/>
|
|
||||||
<stop offset="1" style="stop-color:#5AC4BE"/>
|
|
||||||
</linearGradient>
|
|
||||||
<path class="st2" d="M22.8,26.6H20l-2.2-3.8c0.9-0.1,1.7-0.2,2.5-0.5L22.8,26.6z"/>
|
|
||||||
<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="32.0678" y1="28.5037" x2="-1.861" y2="14.9356" gradientTransform="matrix(1 0 0 -1 0 38)">
|
|
||||||
<stop offset="0" style="stop-color:#C200FB"/>
|
|
||||||
<stop offset="0.4897" style="stop-color:#3772FF"/>
|
|
||||||
<stop offset="1" style="stop-color:#5AC4BE"/>
|
|
||||||
</linearGradient>
|
|
||||||
<path class="st3" d="M28.7,11.2l1.7,0.9l1.7-0.9V9.2l-1.7-1l-1.7,1V11.2z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 2.3 KiB |
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.08398 5.22265C7.17671 5.08355 7.33282 5 7.5 5H18.5C18.6844 5 18.8538 5.10149 18.9408 5.26407C19.0278 5.42665 19.0183 5.62392 18.916 5.77735L16.916 8.77735C16.8233 8.91645 16.6672 9 16.5 9H5.5C5.3156 9 5.14617 8.89851 5.05916 8.73593C4.97215 8.57335 4.98169 8.37608 5.08398 8.22265L7.08398 5.22265ZM7.76759 6L6.43426 8H16.2324L17.5657 6H7.76759Z" fill="#fff"/>
|
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.08398 15.2226C7.17671 15.0836 7.33282 15 7.5 15H18.5C18.6844 15 18.8538 15.1015 18.9408 15.2641C19.0278 15.4267 19.0183 15.6239 18.916 15.7774L16.916 18.7774C16.8233 18.9164 16.6672 19 16.5 19H5.5C5.3156 19 5.14617 18.8985 5.05916 18.7359C4.97215 18.5734 4.98169 18.3761 5.08398 18.2226L7.08398 15.2226ZM7.76759 16L6.43426 18H16.2324L17.5657 16H7.76759Z" fill="#fff"/>
|
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.08398 13.7774C7.17671 13.9164 7.33282 14 7.5 14H18.5C18.6844 14 18.8538 13.8985 18.9408 13.7359C19.0278 13.5733 19.0183 13.3761 18.916 13.2226L16.916 10.2226C16.8233 10.0836 16.6672 10 16.5 10H5.5C5.3156 10 5.14617 10.1015 5.05916 10.2641C4.97215 10.4267 4.98169 10.6239 5.08398 10.7774L7.08398 13.7774ZM7.76759 13L6.43426 11H16.2324L17.5657 13H7.76759Z" fill="#fff"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.4 KiB |
@@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.6109 4.68601C4.72546 4.54406 4.90822 4.47575 5.0878 4.50778L16.575 6.55656C16.6715 6.57377 16.7608 6.61896 16.8318 6.68651L19.3446 9.07676C19.5379 9.26064 19.5528 9.5639 19.3784 9.76583L11.122 19.3268C11.0084 19.4583 10.8347 19.5214 10.6632 19.4935C10.4917 19.4656 10.347 19.3506 10.281 19.1898L4.53742 5.18979C4.46819 5.02103 4.49635 4.82796 4.6109 4.68601ZM6.19646 6.59904L10.4853 17.053L11.2894 10.6786L6.19646 6.59904ZM12.2688 10.9045L11.4468 17.4207L17.7491 10.1226L12.2688 10.9045ZM17.9075 9.08986L13.7298 9.68594L16.4453 7.69901L17.9075 9.08986ZM15.2483 7.33573L6.84451 5.83688L11.8343 9.83381L15.2483 7.33573Z" fill="#fff"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 912 B |
@@ -1,52 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 400 432.7" style="enable-background:new 0 0 400 432.7;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{fill:#F50DB4;}
|
|
||||||
.st1{fill-rule:evenodd;clip-rule:evenodd;fill:#F50DB4;}
|
|
||||||
</style>
|
|
||||||
<path class="st0" d="M325.1,65.4c0.6-10.2,2-17,4.8-23.1c1.1-2.4,2.1-4.4,2.3-4.4s-0.3,1.8-1.1,4c-2,6-2.4,14.2-1,23.7
|
|
||||||
c1.8,12.1,2.8,13.8,15.6,26.9c6,6.1,13,13.8,15.5,17.1l4.6,6l-4.6-4.3c-5.6-5.3-18.6-15.5-21.4-17c-1.9-1-2.2-1-3.4,0.2
|
|
||||||
c-1.1,1.1-1.3,2.7-1.5,10.4c-0.2,12-1.9,19.7-5.8,27.3c-2.1,4.2-2.5,3.3-0.5-1.4c1.4-3.5,1.6-5,1.6-16.6c0-23.3-2.8-28.9-19.1-38.5
|
|
||||||
c-4.1-2.4-10.9-5.9-15.1-7.8c-4.2-1.9-7.5-3.5-7.4-3.6c0.5-0.5,16.3,4.2,22.7,6.6c9.5,3.6,11.1,4.1,12.2,3.7
|
|
||||||
C324.4,74.2,324.8,72,325.1,65.4z"/>
|
|
||||||
<path class="st0" d="M124.4,31.5c-5.6-0.9-5.9-1-3.2-1.4c5.1-0.8,17.1,0.3,25.4,2.2c19.3,4.6,36.9,16.3,55.6,37l5,5.5l7.1-1.1
|
|
||||||
c30-4.8,60.6-1,86.1,10.8c7,3.2,18.1,9.7,19.5,11.3c0.4,0.5,1.3,3.9,1.8,7.5c1.9,12.5,0.9,22.1-2.9,29.3c-2.1,3.9-2.2,5.1-0.8,8.5
|
|
||||||
c1.1,2.7,4.3,4.6,7.4,4.6c6.3,0,13.2-10.2,16.3-24.4l1.3-5.6l2.5,2.8c13.7,15.4,24.4,36.4,26.2,51.3l0.5,3.9l-2.3-3.5
|
|
||||||
c-4-6.1-7.9-10.2-13-13.6c-9.2-6-18.9-8.1-44.5-9.4c-23.2-1.2-36.3-3.2-49.3-7.4c-22.1-7.2-33.3-16.7-59.6-51.1
|
|
||||||
c-11.7-15.2-18.9-23.7-26.1-30.5C161,42.8,145,34.7,124.4,31.5z"/>
|
|
||||||
<path class="st0" d="M135.4,105.3c-11.4-15.7-18.5-39.7-17-57.6l0.5-5.6l2.6,0.5c4.9,0.9,13.3,4,17.3,6.4
|
|
||||||
c10.8,6.5,15.5,15.2,20.3,37.3c1.4,6.5,3.2,13.8,4.1,16.3c1.4,4,6.5,13.3,10.7,19.4c3,4.4,1,6.4-5.6,5.8
|
|
||||||
C158,126.9,144.2,117.5,135.4,105.3z"/>
|
|
||||||
<path class="st0" d="M311.3,221.9c-53.5-21.4-72.3-40-72.3-71.4c0-4.6,0.2-8.4,0.4-8.4c0.2,0,2.3,1.5,4.6,3.4
|
|
||||||
c10.8,8.6,23,12.3,56.6,17.2c19.8,2.9,30.9,5.2,41.2,8.6c32.6,10.8,52.8,32.6,57.6,62.4c1.4,8.6,0.6,24.9-1.7,33.4
|
|
||||||
c-1.8,6.7-7.3,18.9-8.7,19.4c-0.4,0.1-0.8-1.4-0.9-3.5c-0.6-11.2-6.2-22-15.8-30.2C361.4,243.6,346.9,236.2,311.3,221.9z"/>
|
|
||||||
<path class="st0" d="M273.7,230.8c-0.7-4-1.8-9-2.6-11.3l-1.4-4l2.5,2.8c3.5,3.9,6.3,8.9,8.6,15.6c1.8,5.1,2,6.6,2,14.9
|
|
||||||
c0,8.1-0.2,9.8-1.9,14.4c-2.6,7.2-5.8,12.4-11.3,17.9c-9.8,9.9-22.3,15.4-40.4,17.6c-3.1,0.4-12.3,1.1-20.4,1.5
|
|
||||||
c-20.3,1.1-33.7,3.2-45.8,7.4c-1.7,0.6-3.3,1-3.4,0.8c-0.5-0.5,7.7-5.3,14.5-8.6c9.5-4.6,19-7.1,40.3-10.6
|
|
||||||
c10.5-1.7,21.4-3.9,24.1-4.7C264.6,276.7,278,256.2,273.7,230.8z"/>
|
|
||||||
<path class="st0" d="M298.2,274.1c-7.1-15.2-8.7-29.9-4.8-43.5c0.4-1.5,1.1-2.7,1.5-2.7c0.4,0,2.1,0.9,3.7,2
|
|
||||||
c3.3,2.2,9.8,5.9,27.3,15.4c21.8,11.8,34.3,21,42.7,31.5c7.4,9.2,12,19.6,14.2,32.3c1.3,7.2,0.5,24.6-1.3,31.8
|
|
||||||
c-5.9,22.9-19.5,40.9-39,51.4c-2.9,1.5-5.4,2.8-5.7,2.8c-0.3,0,0.8-2.6,2.3-5.8c6.5-13.6,7.3-26.8,2.3-41.6c-3-9-9.2-20-21.7-38.6
|
|
||||||
C305.4,287.5,301.8,281.7,298.2,274.1z"/>
|
|
||||||
<path class="st0" d="M97.4,356.1c19.8-16.7,44.5-28.5,67-32.1c9.7-1.6,25.8-0.9,34.8,1.3c14.4,3.7,27.3,11.9,33.9,21.6
|
|
||||||
c6.5,9.5,9.3,17.9,12.3,36.4c1.2,7.3,2.4,14.6,2.8,16.3c2.2,9.6,6.5,17.3,11.8,21.1c8.4,6.1,22.9,6.5,37.1,1
|
|
||||||
c2.4-0.9,4.5-1.6,4.7-1.4c0.5,0.5-6.7,5.3-11.7,7.8c-6.8,3.4-12.2,4.7-19.4,4.7c-13,0-23.9-6.6-32.9-20c-1.8-2.6-5.8-10.6-8.9-17.6
|
|
||||||
c-9.5-21.6-14.2-28.2-25.3-35.4c-9.6-6.3-22.1-7.4-31.4-2.8c-12.3,6-15.7,21.6-6.9,31.5c3.5,3.9,10,7.3,15.3,8
|
|
||||||
c10,1.2,18.5-6.3,18.5-16.3c0-6.5-2.5-10.2-8.8-13.1c-8.6-3.9-17.9,0.7-17.9,8.7c0,3.4,1.5,5.6,5,7.2c2.2,1,2.3,1.1,0.5,0.7
|
|
||||||
c-7.9-1.6-9.8-11.1-3.4-17.4c7.7-7.6,23.5-4.2,28.9,6.1c2.3,4.3,2.5,13,0.6,18.2c-4.5,11.7-17.4,17.8-30.6,14.5
|
|
||||||
c-9-2.3-12.6-4.7-23.4-15.8c-18.8-19.3-26.1-23-53.2-27.2l-5.2-0.8L97.4,356.1z"/>
|
|
||||||
<path class="st1" d="M9.2,11.5c62.8,75.7,106,107,110.8,113.6c4,5.5,2.5,10.4-4.3,14.2c-3.8,2.1-11.5,4.3-15.4,4.3
|
|
||||||
c-4.4,0-5.9-1.7-5.9-1.7c-2.6-2.4-4-2-17.1-25.1C59.1,88.8,43.9,65.5,43.5,65.1c-1-0.9-0.9-0.9,32,57.7c5.3,12.2,1.1,16.7,1.1,18.4
|
|
||||||
c0,3.5-1,5.4-5.4,10.3c-7.3,8.1-10.6,17.2-12.9,36.1c-2.6,21.1-10.1,36.1-30.7,61.6c-12.1,15-14,17.7-17.1,23.7
|
|
||||||
c-3.8,7.6-4.9,11.9-5.3,21.4c-0.5,10.1,0.4,16.7,3.5,26.4c2.7,8.5,5.6,14.1,12.9,25.3c6.3,9.7,9.9,16.9,9.9,19.7
|
|
||||||
c0,2.2,0.4,2.2,10.2,0.1c23.3-5.2,42.2-14.4,52.8-25.7c6.6-7,8.1-10.8,8.2-20.4c0-6.3-0.2-7.6-1.9-11.2c-2.8-5.9-7.8-10.7-18.9-18.3
|
|
||||||
c-14.5-9.9-20.8-17.9-22.5-28.8c-1.4-9,0.2-15.3,8.3-32.1c8.3-17.4,10.4-24.8,11.8-42.3c0.9-11.3,2.2-15.8,5.4-19.3
|
|
||||||
c3.4-3.7,6.5-5,14.9-6.1c13.7-1.9,22.5-5.4,29.7-12c6.2-5.7,8.9-11.2,9.3-19.5l0.3-6.3l-3.5-4C122.8,105.1,0.8,0,0,0
|
|
||||||
C-0.2,0,4,5.2,9.2,11.5z M38.5,305.9c2.9-5,1.3-11.5-3.4-14.7c-4.5-3-11.5-1.6-11.5,2.3c0,1.2,0.7,2.1,2.1,2.8
|
|
||||||
c2.5,1.3,2.7,2.7,0.7,5.7c-2,3-1.8,5.6,0.5,7.4C30.5,312.3,35.7,310.7,38.5,305.9z"/>
|
|
||||||
<path class="st1" d="M147.6,164.9c-6.5,2-12.7,8.8-14.7,15.9c-1.2,4.4-0.5,12,1.3,14.3c2.9,3.8,5.6,4.8,13.1,4.8
|
|
||||||
c14.7-0.1,27.5-6.4,29-14.2c1.2-6.4-4.4-15.3-12.1-19.2C160.2,164.4,151.7,163.6,147.6,164.9z M164.8,178.3c2.3-3.2,1.3-6.7-2.6-9
|
|
||||||
c-7.3-4.5-18.4-0.8-18.4,6.1c0,3.4,5.8,7.2,11.1,7.2C158.4,182.6,163.2,180.5,164.8,178.3z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 4.9 KiB |
@@ -1,6 +0,0 @@
|
|||||||
<svg width="96" height="96" viewBox="0 0 96 96" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M48 95C73.9574 95 95 73.9574 95 48C95 22.0426 73.9574 1 48 1C22.0426 1 1 22.0426 1 48C1 73.9574 22.0426 95 48 95Z" fill="#0B53BF"/>
|
|
||||||
<path d="M56.4609 13.7778V19.8291C68.5341 23.4716 77.3759 34.6928 77.3759 47.9997C77.3759 61.3066 68.5341 72.5278 56.4609 76.1703V82.2216C71.8534 78.4616 83.2509 64.5672 83.2509 47.9997C83.2509 31.4322 71.8534 17.5378 56.4609 13.7778Z" fill="white"/>
|
|
||||||
<path d="M18.625 47.9997C18.625 34.6928 27.4669 23.4716 39.54 19.8291V13.7778C24.1475 17.5378 12.75 31.4322 12.75 47.9997C12.75 64.5672 24.1475 78.4616 39.54 82.2216V76.1703C27.4669 72.5572 18.625 61.3066 18.625 47.9997Z" fill="white"/>
|
|
||||||
<path d="M60.6319 54.5506C60.6319 42.5362 41.8025 47.4713 41.8025 40.8325C41.8025 38.4531 43.7119 36.9256 47.3544 36.9256C51.7019 36.9256 53.2 39.0406 53.67 41.89H59.6625C59.1279 36.5426 56.0588 33.1662 50.9382 32.1604V27.4375H45.0632V31.9918C39.4534 32.7062 35.9275 35.973 35.9275 40.8325C35.9275 52.9056 54.7863 48.3819 54.7863 54.9031C54.7863 57.3706 52.4069 59.0156 48.3825 59.0156C43.1244 59.0156 41.3913 56.695 40.745 53.4931H34.8994C35.2781 59.3502 38.8897 63.0159 45.0632 63.9307V68.5625H50.9382V63.9923C56.9633 63.2139 60.6319 59.7089 60.6319 54.5506Z" fill="white"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.3 KiB |