Compare commits

..

15 Commits

Author SHA1 Message Date
Thomas Camlong
d3d69ace47 chore: Remove 'Companies' category 2025-04-19 11:09:30 +02:00
Thomas Camlong
40bb2ac4fe update metadata 2025-04-19 11:09:18 +02:00
Thomas Camlong
a0fe0ccde3 wip 2025-04-19 10:37:04 +02:00
Thomas Camlong
f87ccb7475 update categories for part 3 2025-04-19 10:22:57 +02:00
Thomas Camlong
de4b2179d0 chore: Add 'Companies' category to issue templates 2025-04-19 10:21:15 +02:00
Thomas Camlong
6b45bf1ae7 chore: Update github issue templates 2025-04-19 10:19:36 +02:00
Thomas Camlong
93d5204553 remove old categories 2025-04-19 10:16:54 +02:00
Thomas Camlong
6a572dfcc8 wip 2025-04-19 10:14:43 +02:00
Thomas Camlong
1c5e55aa0c wip 2025-04-18 23:55:47 +02:00
Thomas Camlong
2993b39d1b update metadata 2025-04-18 22:56:30 +02:00
Thomas Camlong
f593c37c19 update metadata 2025-04-18 22:56:07 +02:00
Thomas Camlong
39620c27b1 Merge branch 'main' into feat/ai-categories 2025-04-18 22:39:01 +02:00
Thomas Camlong
38ae50ed8a Merge branch 'main' into feat/ai-categories 2025-04-18 18:34:08 +02:00
Thomas Camlong
0ae0b7fdc8 use google studio to add categories 2025-04-16 17:07:15 +02:00
Thomas Camlong
47b775ee48 Fix favicons 2025-04-16 16:34:38 +02:00
113 changed files with 5031 additions and 5511 deletions

View File

@@ -1,5 +1,5 @@
name: "Add light/dark icon"
description: Submit a new icon with light and dark versions.
name: "Add light & dark icon"
description: Use this template to add a new icon to the project. Monochrome icons need both light and dark versions.
title: "feat(icons): add [NAME]"
labels: ["monochrome-icon"]
body:
@@ -35,32 +35,37 @@ body:
label: Categories
multiple: true
options:
- Animal
- Cloud
- Communication
- Design
- Development
- E-Commerce
- Education
- File
- Finance
- Food
- Gaming
- Hardware
- Health
- Location
- Logistics
- Media
- Music
- Nature
- News
- Organization
- Search
- Security
- SocialMedia
- Streaming
- Travel
- Video
- Operating-Systems
- Web-Browsers
- Cloud-Computing
- Databases
- Media-Servers
- Password-Managers
- Monitoring-Tools
- Version-Control-Systems
- Home-Automation
- Download-Managers
- VPN
- Social-Media
- Office-Suites
- File-Sharing-&-Sync
- Search-Engines
- Graphics-Editors
- Containerization-&-Orchestration
- Networking-Tools
- Note-taking-Apps
- AI-&-LLM-Platforms
- Music-Streaming
- Video-Streaming
- Linux-Distributions
- Gaming-Platforms
- E-commerce-Platforms
- Finance-&-Banking
- Email-Providers
- Smart-Home
- Server-Panels
- Programming-Languages
- Developper-Tools
- type: input
attributes:
label: Aliases

View File

@@ -1,5 +1,5 @@
name: "Add standard icon"
description: Submit a new icon for both light and dark themes.
name: "Add normal icon"
description: Use this template to add a new icon to the project. Normal icons work for both light and dark themes.
title: "feat(icons): add [NAME]"
labels: ["normal-icon"]
body:
@@ -30,32 +30,37 @@ body:
label: Categories
multiple: true
options:
- Animal
- Cloud
- Communication
- Design
- Development
- E-Commerce
- Education
- File
- Finance
- Food
- Gaming
- Hardware
- Health
- Location
- Logistics
- Media
- Music
- Nature
- News
- Organization
- Search
- Security
- SocialMedia
- Streaming
- Travel
- Video
- Operating-Systems
- Web-Browsers
- Cloud-Computing
- Databases
- Media-Servers
- Password-Managers
- Monitoring-Tools
- Version-Control-Systems
- Home-Automation
- Download-Managers
- VPN
- Social-Media
- Office-Suites
- File-Sharing-&-Sync
- Search-Engines
- Graphics-Editors
- Containerization-&-Orchestration
- Networking-Tools
- Note-taking-Apps
- AI-&-LLM-Platforms
- Music-Streaming
- Video-Streaming
- Linux-Distributions
- Gaming-Platforms
- E-commerce-Platforms
- Finance-&-Banking
- Email-Providers
- Smart-Home
- Server-Panels
- Programming-Languages
- Developper-Tools
- type: input
attributes:
label: Aliases

View File

@@ -1,5 +1,5 @@
name: "Update light/dark icon"
description: Improve or update an existing light/dark icon.
name: "Update light & dark icon"
description: Use this template to update an existing icon. Monochrome icons need both light and dark versions.
title: "feat(icons): update [NAME]"
labels: ["monochrome-icon"]
body:

View File

@@ -1,5 +1,5 @@
name: "Update standard icon"
description: Improve or update an existing standard icon.
name: "Update normal icon"
description: Use this template to update an existing icon. Normal icons work for both light and dark themes.
title: "feat(icons): update [NAME]"
labels: ["normal-icon"]
body:

View File

@@ -1,14 +0,0 @@
{
"base": "svg",
"aliases": [],
"categories": [
"Finance"
],
"update": {
"timestamp": "2025-04-22T18:36:00.262663",
"author": {
"id": 41155244,
"login": "giovannicalabro"
}
}
}

View File

@@ -1,14 +0,0 @@
{
"base": "png",
"aliases": [],
"categories": [
"Media"
],
"update": {
"timestamp": "2025-04-22T17:31:36.311538",
"author": {
"id": 2319445,
"login": "samcro1967"
}
}
}

View File

@@ -1,14 +0,0 @@
{
"base": "svg",
"aliases": [],
"categories": [
"Media"
],
"update": {
"timestamp": "2025-04-22T17:34:50.612136",
"author": {
"id": 2319445,
"login": "samcro1967"
}
}
}

View File

@@ -1,16 +0,0 @@
{
"base": "svg",
"aliases": [
"ems-esp"
],
"categories": [
"Cloud"
],
"update": {
"timestamp": "2025-04-22T16:56:16.429675",
"author": {
"id": 33312839,
"login": "vladbejenaru"
}
}
}

View File

@@ -1,14 +0,0 @@
{
"base": "svg",
"aliases": [],
"categories": [
"Finance"
],
"update": {
"timestamp": "2025-04-22T18:33:50.980132",
"author": {
"id": 41155244,
"login": "giovannicalabro"
}
}
}

View File

@@ -1,15 +0,0 @@
{
"base": "svg",
"aliases": [],
"categories": [
"File",
"Cloud"
],
"update": {
"timestamp": "2025-04-22T17:02:14.266586",
"author": {
"id": 105980537,
"login": "keywal"
}
}
}

View File

@@ -1,12 +0,0 @@
{
"base": "png",
"aliases": [],
"categories": [],
"update": {
"timestamp": "2025-04-22T17:37:06.429465",
"author": {
"id": 2319445,
"login": "samcro1967"
}
}
}

View File

@@ -1,14 +0,0 @@
{
"base": "png",
"aliases": [],
"categories": [
"Media"
],
"update": {
"timestamp": "2025-04-22T18:22:01.834809",
"author": {
"id": 2319445,
"login": "samcro1967"
}
}
}

View File

@@ -1,14 +0,0 @@
{
"base": "png",
"aliases": [],
"categories": [
"Media"
],
"update": {
"timestamp": "2025-04-22T17:43:20.146082",
"author": {
"id": 2319445,
"login": "samcro1967"
}
}
}

View File

@@ -1,16 +0,0 @@
{
"base": "svg",
"aliases": [
"libre-chat"
],
"categories": [
"Development"
],
"update": {
"timestamp": "2025-04-22T19:10:20.864971",
"author": {
"id": 1473979,
"login": "lukacat10"
}
}
}

View File

@@ -1,14 +0,0 @@
{
"base": "svg",
"aliases": [],
"categories": [
"Hardware"
],
"update": {
"timestamp": "2025-04-22T18:55:13.785687",
"author": {
"id": 63781622,
"login": "Meierschlumpf"
}
}
}

View File

@@ -1,14 +0,0 @@
{
"base": "svg",
"aliases": [],
"categories": [
"Hardware"
],
"update": {
"timestamp": "2025-04-22T18:51:42.311628",
"author": {
"id": 39389502,
"login": "TeHtloTs"
}
}
}

View File

@@ -1,14 +0,0 @@
{
"base": "png",
"aliases": [],
"categories": [
"Security"
],
"update": {
"timestamp": "2025-04-22T17:17:13.363083",
"author": {
"id": 27157792,
"login": "nazarukroman"
}
}
}

View File

@@ -1,14 +0,0 @@
{
"base": "svg",
"aliases": [],
"categories": [
"Media"
],
"update": {
"timestamp": "2025-04-22T17:48:13.427885",
"author": {
"id": 2319445,
"login": "samcro1967"
}
}
}

View File

@@ -1,17 +0,0 @@
{
"base": "svg",
"aliases": [
"pangolin",
"pangolin-newt"
],
"categories": [
"Cloud"
],
"update": {
"timestamp": "2025-04-22T18:57:05.718417",
"author": {
"id": 7034912,
"login": "leodr99"
}
}
}

View File

@@ -1,14 +0,0 @@
{
"base": "svg",
"aliases": [],
"categories": [
"E-Commerce"
],
"update": {
"timestamp": "2025-04-22T18:58:38.751308",
"author": {
"id": 1832823,
"login": "alemairebe"
}
}
}

View File

@@ -1,12 +0,0 @@
{
"base": "svg",
"aliases": [],
"categories": [],
"update": {
"timestamp": "2025-04-22T19:06:08.669890",
"author": {
"id": 100090983,
"login": "Dan-Ev"
}
}
}

View File

@@ -1,12 +0,0 @@
{
"base": "svg",
"aliases": [],
"categories": [],
"update": {
"timestamp": "2025-04-22T17:25:54.525668",
"author": {
"id": 2319445,
"login": "samcro1967"
}
}
}

View File

@@ -1,14 +0,0 @@
{
"base": "svg",
"aliases": [],
"categories": [
"Media"
],
"update": {
"timestamp": "2025-04-22T18:25:38.709896",
"author": {
"id": 2319445,
"login": "samcro1967"
}
}
}

View File

@@ -1,14 +0,0 @@
{
"base": "png",
"aliases": [],
"categories": [
"Media"
],
"update": {
"timestamp": "2025-04-22T18:28:27.157439",
"author": {
"id": 2319445,
"login": "samcro1967"
}
}
}

View File

@@ -1,7 +1,7 @@
{
"base": "svg",
"aliases": [
"vodafone"
"vodacom"
],
"categories": [],
"update": {
@@ -11,4 +11,4 @@
"login": "JonasJoKuJonas"
}
}
}
}

View File

@@ -1,14 +0,0 @@
{
"base": "png",
"aliases": [],
"categories": [
"Media"
],
"update": {
"timestamp": "2025-04-22T18:31:18.100212",
"author": {
"id": 2319445,
"login": "samcro1967"
}
}
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 199 KiB

View File

@@ -1,21 +0,0 @@
<svg xmlns:x="ns_extend;" xmlns:i="ns_ai;" xmlns:graph="ns_graphs;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" style="enable-background:new 0 0 100 100;" xml:space="preserve" viewBox="0 0 100 100">
<style type="text/css">
.st0{fill:#70B37F;}
</style>
<metadata>
<sfw xmlns="ns_sfw;">
<slices>
</slices>
<sliceSourceBounds bottomLeftOrigin="true" height="100" width="100" x="-125.6" y="67.8">
</sliceSourceBounds>
</sfw>
</metadata>
<g>
<g>
<g>
<path class="st0" d="M0,0v100h100V0H0z M54.4,49v34l-16.6-5c-1.1-0.3-2-1.6-2-2.7V49h-7l20.8-26.2c0.7-0.9,2.3-1.8,3.4-2.1 l18.2-4.4L45.4,49H54.4z">
</path>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 743 B

View File

@@ -1,21 +0,0 @@
<svg xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" version="1.1" id="svg5" inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20, custom)" sodipodi:docname="logo.svg" inkscape:export-filename="/home/kiran/Projects/Clojure/Doplarr/logos/logo.png" inkscape:export-xdpi="300" inkscape:export-ydpi="300" viewBox="0 0 100 100">
<sodipodi:namedview id="namedview7" pagecolor="#ffffff" bordercolor="#111111" borderopacity="1" inkscape:pageshadow="0" inkscape:pageopacity="0" inkscape:pagecheckerboard="true" inkscape:document-units="mm" showgrid="false" height="100mm" scale-x="1" inkscape:zoom="0.97213405" inkscape:cx="261.79517" inkscape:cy="523.07601" inkscape:window-width="1758" inkscape:window-height="1350" inkscape:window-x="3338" inkscape:window-y="66" inkscape:window-maximized="1" inkscape:current-layer="text1822"/>
<defs id="defs2">
<inkscape:path-effect effect="mirror_symmetry" start_point="28.682452,9.1988852" end_point="28.682452,90.801115" center_point="28.682452,50" id="path-effect20182" is_visible="true" lpeversion="1.1" mode="vertical" discard_orig_path="false" fuse_paths="false" oposite_fuse="false" split_items="false" split_open="false"/>
</defs>
<g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1">
<circle style="fill:#7289da;fill-opacity:1;stroke:none;stroke-width:0.262264;stroke-linecap:square;stroke-dasharray:1.5736, 0.262264" id="path866" cx="50" cy="50" r="50"/>
<g aria-label="D" id="text1956" style="font-size:83.3059px;line-height:1.25;font-family:Impact;-inkscape-font-specification:'Impact, Normal';fill:#ffffff;stroke-width:2.08265" transform="matrix(0.92504678,0,0,0.92504678,71.71317,13.992208)">
<path d="m -43.302405,5.9975786 h 12.813163 c 8.270931,0 13.857199,0.3796489 16.758804,1.1389467 2.928723,0.7592987 5.1523828,2.0067177 6.6709798,3.7422577 1.518597,1.735539 2.46772,3.674462 2.847369,5.816769 0.379649,2.115189 0.569474,6.291331 0.569474,12.528426 v 23.063695 c 0,5.911681 -0.284737,9.870881 -0.854211,11.877599 -0.542356,1.9796 -1.505038,3.538874 -2.888046,4.677821 -1.383008,1.11183 -3.0914288,1.898246 -5.1252648,2.359249 -2.033835,0.433885 -5.098147,0.650828 -9.192936,0.650828 h -21.599332 z" id="path23416" sodipodi:nodetypes="cscscsscccscc"/>
</g>
<path id="path21610" style="fill:#fffffe;stroke:#000000;stroke-width:0.264583" d="M 50.0178,51.760883 A 0.01779476,0.01779476 0 0 1 50,51.778673 0.01779476,0.01779476 0 0 1 49.9822,51.760883 0.01779476,0.01779476 0 0 1 50,51.743093 a 0.01779476,0.01779476 0 0 1 0.0178,0.01779 z"/>
<path id="path21612" style="fill:#fffffe;stroke:#000000;stroke-width:0.264583" d="M 50.0178,51.760883 A 0.01779476,0.01779476 0 0 1 50,51.778673 0.01779476,0.01779476 0 0 1 49.9822,51.760883 0.01779476,0.01779476 0 0 1 50,51.743093 a 0.01779476,0.01779476 0 0 1 0.0178,0.01779 z"/>
<g aria-label="λ" id="text24934" style="font-size:47.894px;line-height:1.25;font-family:Impact;-inkscape-font-specification:Impact;fill:#7289da;stroke-width:1.19735">
<path d="m 38.342206,68.802139 5.168249,-28.50722 q 0.3274,-1.824088 0.3274,-3.016761 0,-1.473302 -1.941017,-1.473302 h -1.26283 v -4.88762 h 5.752893 q 4.770692,0 6.852023,1.052359 2.081331,1.052358 2.806289,3.507861 0.748344,2.432117 1.356373,8.325324 l 1.870859,17.773165 q 0.140315,1.520073 0.420944,1.870859 0.304014,0.327401 0.724958,0.327401 0.350786,0 1.239444,-0.04677 v 5.027935 q -2.736132,0.3274 -5.402107,0.3274 -4.560219,0 -4.934391,-5.355335 L 50.035077,45.322854 46.924773,68.802139 Z" id="path2772"/>
</g>
<g aria-label="(" id="text16135" style="font-size:89.8502px;line-height:1.25;font-family:'Times New Roman';-inkscape-font-specification:'Times New Roman, Normal';fill:#ffffff;stroke-width:2.24626" inkscape:path-effect="#path-effect20182" transform="translate(4.5800001,-0.28635574)">
<path d="m 28.682452,89.464201 v 1.62327 C 24.265987,88.864614 20.580725,86.261532 17.626666,83.278225 13.414938,79.037249 10.168398,74.035822 7.8870448,68.273944 5.6056921,62.512066 4.4650158,56.530827 4.4650158,50.330228 c 0,-9.066914 2.2374804,-17.329505 6.7124412,-24.787774 4.474961,-7.487516 10.30996,-12.83992 17.504995,-16.0572134 v 1.8426314 c -3.597518,1.988872 -6.551577,4.708946 -8.862178,8.160223 -2.310601,3.451277 -4.036239,7.82387 -5.176916,13.117778 -1.140676,5.293908 -1.711014,10.821801 -1.711014,16.583679 0,6.259095 0.482594,11.947853 1.447781,17.066273 0.760451,4.036239 1.681767,7.268155 2.763947,9.695748 1.08218,2.456841 2.529961,4.811314 4.343344,7.063419 1.842631,2.252105 4.240977,4.401841 7.195036,6.449209 z m 33.475096,0 v 1.62327 c 4.416465,-2.222857 8.101727,-4.825939 11.055786,-7.809246 4.211728,-4.240976 7.458268,-9.242403 9.739621,-15.004281 2.281353,-5.761878 3.422029,-11.743117 3.422029,-17.943716 0,-9.066914 -2.23748,-17.329505 -6.712441,-24.787774 C 75.187582,18.054938 69.352583,12.702534 62.157548,9.4852406 v 1.8426314 c 3.597518,1.988872 6.551577,4.708946 8.862178,8.160223 2.310601,3.451277 4.036239,7.82387 5.176916,13.117778 1.140676,5.293908 1.711014,10.821801 1.711014,16.583679 0,6.259095 -0.482594,11.947853 -1.447781,17.066273 -0.760451,4.036239 -1.681767,7.268155 -2.763947,9.695748 -1.08218,2.456841 -2.529961,4.811314 -4.343344,7.063419 -1.842631,2.252105 -4.240977,4.401841 -7.195036,6.449209 z" id="path20161" inkscape:original-d="m 28.682452,89.464201 v 1.62327 Q 22.057755,87.753186 17.626666,83.278225 11.309074,76.916761 7.8870448,68.273944 4.4650158,59.631127 4.4650158,50.330228 q 0,-13.600371 6.7124412,-24.787774 Q 17.889899,14.31118 28.682452,9.4852406 v 1.8426314 q -5.396277,2.983308 -8.862178,8.160223 -3.465901,5.176916 -5.176916,13.117778 -1.711014,7.940862 -1.711014,16.583679 0,9.388643 1.447781,17.066273 1.140677,6.054359 2.763947,9.695748 1.62327,3.685262 4.343344,7.063419 2.763947,3.378157 7.195036,6.449209 z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 5.9 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" id="Capa_1" enable-background="new 0 0 511.728 511.728" viewBox="95.04 0 321.64 511.73"><path d="m228.871 504.5v-50.088l-29.153-6.478v56.566z" fill="#878b91"/><path d="m312.01 504.5v-56.566l-29.153 6.478v50.088z" fill="#878b91"/><path d="m102.542 50.49c0-11.848 7.837-22.269 19.228-25.532 24.567-7.037 71.513-17.458 134.094-17.458 64.244 0 110.286 10.267 134.291 17.3 11.296 3.31 19.031 13.704 19.031 25.473v327.727c0 11.848-7.837 22.269-19.228 25.532-24.566 7.037-71.513 17.458-134.094 17.458-64.244 0-110.286-10.267-134.291-17.3-11.296-3.31-19.031-13.704-19.031-25.473z" fill="#e2faff"/><path d="m390.155 24.8c-24.005-7.033-70.047-17.3-134.291-17.3-5.539 0-10.949.085-16.238.239 55.521 1.571 95.667 10.655 117.529 17.061 11.296 3.31 19.031 13.704 19.031 25.473v327.727c0 11.848-7.837 22.269-19.228 25.532-22.392 6.414-63.385 15.636-117.855 17.219 5.443.154 11.026.239 16.762.239 62.581 0 109.527-10.421 134.094-17.458 11.391-3.263 19.228-13.684 19.228-25.532v-327.727c-.002-11.769-7.736-22.163-19.032-25.473z" fill="#cbf4ff"/><path d="m363.05 400.273v34.338c0 7.466-4.905 14.058-12.07 16.159-16.762 4.913-50.172 12.602-95.116 12.602-46.074 0-78.756-7.553-95.152-12.471-7.14-2.141-12.034-8.695-12.034-16.148v-34.479h214.372z" fill="#82d5f2"/><path d="m330.05 400.273v34.338c0 7.466-4.905 14.058-12.07 16.159-14.672 4.301-42.1 10.728-78.854 12.264 5.364.219 10.945.338 16.738.338 44.944 0 78.354-7.689 95.116-12.602 7.165-2.1 12.07-8.693 12.07-16.159v-34.338z" fill="#67c6e4"/><ellipse cx="255.864" cy="131.961" fill="#82d5f2" rx="49.872" ry="49.866"/><path d="m102.542 308.121v70.094c0 11.77 7.735 22.164 19.031 25.473 24.005 7.033 70.047 17.3 134.291 17.3 62.581 0 109.527-10.421 134.094-17.458 11.391-3.263 19.228-13.684 19.228-25.532v-69.878h-306.644z" fill="#baeefc"/><path d="m376.185 308.121v69.879c0 11.848-7.837 22.269-19.228 25.532-22.392 6.414-63.385 15.636-117.855 17.219 5.443.154 11.026.239 16.762.239 62.581 0 109.527-10.421 134.094-17.458 11.391-3.263 19.228-13.684 19.228-25.532v-69.878h-33.001z" fill="#a2e1f8"/><path d="m313.235 131.961c0-31.632-25.737-57.366-57.372-57.366s-57.372 25.734-57.372 57.366 25.737 57.366 57.372 57.366 57.372-25.734 57.372-57.366zm-99.743 0c0-23.361 19.008-42.366 42.372-42.366s42.372 19.005 42.372 42.366-19.008 42.366-42.372 42.366-42.372-19.005-42.372-42.366z"/><path d="m275.702 122.48c6.81-6.809-3.786-17.427-10.605-10.607l-15.037 15.035c-6.713 6.712 3.738 17.475 10.605 10.607z"/><path d="m416.686 50.273c0-15.023-10.043-28.458-24.422-32.67-22.437-6.574-69.991-17.603-136.4-17.603-15.982 0-32.011.681-47.642 2.023-9.595.824-8.324 15.772 1.283 14.945 15.206-1.306 30.803-1.968 46.359-1.968 64.536 0 110.517 10.649 132.182 16.998 8.031 2.353 13.64 9.868 13.64 18.276v250.348h-291.644v-250.132c0-8.461 5.672-15.996 13.793-18.322 11.309-3.239 23.561-6.107 36.416-8.525 9.464-1.78 6.705-16.528-2.773-14.741-13.31 2.503-26.019 5.48-37.772 8.847-14.521 4.159-24.663 17.623-24.663 32.742v327.726c0 15.023 10.043 28.458 24.422 32.67 5.667 1.661 12.942 3.605 21.713 5.585v18.281c0 10.837 6.984 20.214 17.38 23.333 7.447 2.233 18.809 5.175 33.661 7.673v38.741c0 9.63 15 9.644 15 0v-36.56c4.486.556 9.207 1.055 14.153 1.478v35.082c0 9.63 15 9.644 15 0v-34.09c6.213.293 12.708.461 19.493.461 6.55 0 13.051-.16 19.493-.475v34.104c0 9.63 15 9.644 15 0v-35.135c4.758-.42 9.477-.929 14.153-1.525v36.66c0 9.63 15 9.644 15 0v-38.899c3.651-.626 7.275-1.3 10.862-2.036 9.434-1.936 6.432-16.631-3.016-14.693-53.191 10.916-112.262 10.508-164.49-5.155-4.001-1.2-6.689-4.803-6.689-8.965v-15.181c25.125 4.743 58.83 8.919 99.687 8.919 40.222 0 74.192-4.317 99.687-9.174v15.295c0 9.63 15 9.644 15 0v-18.411c8.587-1.936 15.796-3.833 21.472-5.458 14.521-4.159 24.663-17.623 24.663-32.742v-327.727zm-28.793 346.048c-22.385 6.412-69.304 17.168-132.029 17.168-64.536 0-110.517-10.649-132.182-16.998-8.031-2.353-13.64-9.868-13.64-18.276v-62.595h291.644v62.38c0 8.461-5.672 15.995-13.793 18.321z"/><path d="m203.737 351.74c-9.652 0-9.668 15 0 15 9.651 0 9.667-15 0-15z"/><path d="m255.864 351.74c-9.652 0-9.668 15 0 15 9.652 0 9.668-15 0-15z"/><path d="m307.991 351.74c-9.652 0-9.668 15 0 15 9.652 0 9.668-15 0-15z"/></svg>

Before

Width:  |  Height:  |  Size: 4.1 KiB

View File

@@ -1,14 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0.01 115.52 143.76">
<title>horizLogo</title>
<defs>
<linearGradient x1="76.6452875%" y1="106.733429%" x2="28.7462587%" y2="3.49216114%" id="linearGradient-1">
<stop stop-color="#8026FF" offset="25%"/>
<stop stop-color="#FF1A58" offset="75%"/>
</linearGradient>
</defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="horizLogo" transform="translate(0.000000, 0.009657)" fill-rule="nonzero">
<path d="M3.22,65.9903428 C7.36,48.9903428 20.85,39.4403428 38.69,39.4403428 C56.1,39.4403428 70.25,48.8003428 74.38,65.9903428 L3.22,65.9903428 Z M105.22,38.5203428 C95.0100528,20.8238516 78.1856989,7.91046115 58.4510992,2.62326895 C38.7164996,-2.66392325 17.6896641,0.108571645 1.42108547e-14,10.3303428 L9.71,27.1503428 C18.6760705,22.5434556 28.6302113,20.1922189 38.71,20.3003428 C72.66,20.3003428 96.16,44.2403428 96.16,76.8803428 L96.16,84.5003428 L2.57,84.5003428 C5.62,103.650343 19.98,114.310343 38.69,114.310343 C52.62,114.310343 62.41,109.960343 68.69,100.600343 L91.54,100.600343 C86.8570334,112.00133 78.2280851,121.336638 67.23,126.900343 L77,143.760343 C94.6992057,133.550362 107.614545,116.724187 112.901881,96.9871749 C118.189217,77.2501625 115.414946,56.220907 105.19,38.5303428 L105.22,38.5203428 Z" id="Shape" fill="url(#linearGradient-1)"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -1,450 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="113.424mm"
height="135.52705mm"
viewBox="0 0 113.424 135.52705"
version="1.1"
id="svg1"
xml:space="preserve"
inkscape:version="1.4 (e7c3feb1, 2024-10-09)"
sodipodi:docname="gomft_golpher.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="true"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="true"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="1"
inkscape:cx="182"
inkscape:cy="298"
inkscape:window-width="1512"
inkscape:window-height="831"
inkscape:window-x="0"
inkscape:window-y="38"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
showborder="true" /><defs
id="defs1"><clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath3542"><rect
style="fill:#0000ff;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="rect3544"
width="1093.424"
height="1518.2074"
x="-1174.7097"
y="-295.40738" /></clipPath></defs><g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-48.260679,-4.7323055)"
style="display:inline"><g
style="enable-background:new"
id="g1"
transform="matrix(0.28222222,0,0,0.28222222,43.26068,-0.26769346)"
inkscape:label="golpher"><g
id="layer11"
inkscape:label="background"
style="display:inline"
transform="translate(-159.49345,-229.70978)" /><g
id="layer5"
inkscape:label="gopher-body"
style="display:inline;opacity:1"
transform="matrix(0.99955497,0,0,0.99955497,-159.32544,-229.49282)"><g
id="g4815"
transform="matrix(-0.32879267,0.17361606,0.20143296,0.28338802,93.068619,282.82497)"
style="opacity:1"><path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#96d6ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m -626.54672,402.3529 c 2.22767,10.86299 0.34493,21.82632 -3.86747,31.42527 -4.21252,9.59894 -10.55173,17.86115 -17.72096,24.29983 -7.1694,6.43883 -15.25476,11.10591 -24.5716,13.61353 -9.31698,2.50761 -20.94966,4.46936 -31.63903,1.98398 -10.68939,-2.48537 -18.0688,-9.22838 -24.09401,-15.89285 -6.02508,-6.66442 -12.35923,-14.47524 -22.96531,-22.06805 -10.60584,-7.59266 -20.8648,-15.59839 -25.16123,-23.3775 -4.29632,-7.77931 -7.008,-15.66934 -7.81517,-23.39095 -0.80717,-7.7215 0.35908,-14.55922 3.12288,-20.54462 2.76393,-5.98548 7.12557,-11.1208 12.7854,-15.40902 5.65998,-4.28811 12.61751,-7.73606 20.64204,-10.24271 8.02465,-2.50651 17.11262,-4.07552 27.13941,-4.41504 10.0268,-0.3395 20.06604,0.59388 29.76158,2.87504 9.69543,2.2813 19.05511,5.92037 27.47739,11.02309 8.42215,5.10286 15.89307,11.69212 21.60465,19.6287 5.71147,7.93674 13.0738,19.62846 15.30143,30.4913 z"
id="path4806"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sssssssssssssssss" /><path
transform="matrix(13.851095,0,0,13.851095,10133.213,-6001.611)"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#394655;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m -784.21409,457.33922 c -0.56136,0.0656 -1.08141,0.1809 -1.55606,0.33615 -0.63289,0.20699 -1.18396,0.48516 -1.6349,0.82686 -0.45093,0.3417 -0.80184,0.74659 -1.02778,1.21891 -0.22595,0.47234 -0.32669,1.01119 -0.27449,1.62035 0.0522,0.60917 0.25282,1.23371 0.57968,1.84938 0.32687,0.61567 0.98957,1.25218 1.83531,1.84156 0.84574,0.58937 1.35671,1.20529 1.82543,1.72857 0.46713,0.52147 1.13451,0.85371 2.02424,0.92674 0.10253,0.008 0.12328,-0.30471 0.0344,-0.32876 -0.78083,-0.20262 -1.25826,-0.72023 -1.71877,-1.11076 -0.4254,-0.46645 -0.87231,-1.01406 -1.62104,-1.54604 -0.74871,-0.53197 -1.47289,-1.09304 -1.77689,-1.63886 -0.30398,-0.54584 -0.49685,-1.10009 -0.55469,-1.64239 -0.0579,-0.54231 0.0245,-1.0222 0.21918,-1.44322 0.19469,-0.42103 0.50198,-0.78371 0.90168,-1.08623 0.39973,-0.30252 0.89062,-0.54587 1.4577,-0.7237 0.28355,-0.0889 0.5872,-0.16119 0.90722,-0.21465 0.32002,-0.0535 0.6576,-0.0885 1.01178,-0.10163 0.70839,-0.0255 1.4163,0.0392 2.10043,0.1987 0.68412,0.15947 1.34499,0.41522 1.93838,0.77329 0.59338,0.35806 1.11885,0.81986 1.52108,1.37653 0.40222,0.55667 0.92117,1.37523 1.07925,2.13677 0.12981,0.62539 0.0734,1.25844 -0.13288,1.83379 -0.0385,0.10712 0.4977,0.29416 0.62787,-0.0111 0.24265,-0.5698 0.23445,-1.24057 0.1026,-1.8741 -0.17834,-0.85666 -0.69031,-1.76937 -1.13671,-2.40019 -0.4464,-0.6308 -1.03123,-1.15292 -1.68895,-1.55276 -0.65772,-0.39984 -1.38674,-0.68003 -2.14271,-0.85021 -0.75599,-0.17016 -1.54036,-0.23166 -2.32498,-0.19142 -0.19617,0.0101 -0.38815,0.0268 -0.57528,0.0484 z"
id="path4808"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csssccscsccscscccsccscsssscscscc" /><path
sodipodi:nodetypes="cssscsssc"
inkscape:connector-curvature="0"
id="path4810"
d="m -753.77185,413.0219 c -0.13663,-2.61847 2.18018,-4.94804 7.2193,-6.20054 7.65443,-1.90257 20.03831,1.84566 27.93811,5.67152 4.33357,2.09883 8.88981,3.89076 12.66635,7.19411 1.28185,1.12133 2.51799,2.28349 3.36855,4.40869 -1.65849,0.577 -4.10492,-0.92134 -5.87278,-2.13046 -6.96771,-4.76531 -14.69502,-8.08983 -22.67695,-9.12646 -6.71591,-0.87187 -8.86923,-3.11022 -14.75541,-2.56175 -3.72583,0.34716 -4.90626,2.13878 -7.88716,2.74489 z"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#394655;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /><path
sodipodi:nodetypes="sssssssss"
inkscape:connector-curvature="0"
id="path4813"
d="m -720.16989,411.68353 c 0.28532,-2.32502 0.86962,3.90377 -0.31886,5.45995 -4.46007,5.84 -8.20289,12.32072 -12.42083,18.36519 -1.37385,1.96787 -3.29463,0.0414 -2.42738,-2.09874 0.88118,-2.1739 2.06053,-3.99898 3.34915,-5.8153 1.20809,-1.70147 2.81353,-3.0576 3.88834,-4.85958 2.06619,-3.46267 2.39577,-6.62873 4.25443,-10.2393 0.63712,-1.23818 3.5225,0.42546 3.67386,-0.80905 z"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#394655;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /></g><g
style="display:inline;enable-background:new"
id="g4710"
transform="matrix(-0.69719495,0.22290406,0.41767232,0.92198706,562.8644,-101.63567)"><path
sodipodi:nodetypes="sssssssssssssssss"
inkscape:connector-curvature="0"
id="path4706"
d="m 423.50332,581.83521 c -0.004,4.40048 -1.19837,7.58856 -3.37524,9.82844 -2.17687,2.23987 -5.33154,3.55156 -9.14619,4.44292 -3.81465,0.89135 -8.28246,1.39523 -13.05675,1.83828 -4.77428,0.44304 -9.85163,0.79076 -14.95001,1.09928 -5.09838,0.30851 -9.94541,0.34741 -14.40217,0.0862 -4.45676,-0.26122 -8.52354,-0.79908 -11.99271,-1.71189 -3.46915,-0.91282 -6.33736,-2.21356 -8.3562,-4.09288 -2.01885,-1.87935 -3.18709,-4.34475 -3.25466,-7.51083 -0.0676,-3.16607 0.9983,-5.4859 2.92534,-7.0838 1.92703,-1.5979 4.71248,-2.46394 8.09977,-2.84688 3.38729,-0.38293 7.37282,-0.28336 11.77044,-0.16051 4.39762,0.12284 9.21051,0.23456 14.33166,-0.12202 5.12115,-0.35659 10.27171,-1.47349 15.16022,-2.54099 4.88852,-1.06749 9.50395,-2.05149 13.43823,-2.27114 3.9343,-0.21967 7.17754,0.32322 9.39823,2.04598 2.22069,1.72276 3.41425,4.59936 3.41004,8.99986 z"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#e1d6b9;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /><path
sodipodi:nodetypes="ssscsscssssssssssssssssssssccsss"
inkscape:connector-curvature="0"
id="path4708"
d="m 411.91406,568.54883 c -3.75011,-0.0271 -8.08701,0.53975 -12.76172,1.28711 -5.34251,0.85413 -11.10706,1.92059 -17.00976,2.32617 -5.9027,0.40562 -11.41103,0.38326 -16.44727,0.41406 -5.03624,0.0309 -9.6045,0.1607 -13.50781,0.85938 -3.9033,0.69867 -7.13503,1.96743 -9.4082,3.96875 -2.27316,2.00131 -3.58535,4.71676 -3.65235,8.17578 -0.067,3.45901 1.21821,6.3073 3.54297,8.58008 2.32476,2.27278 5.68789,3.9795 9.76172,5.25 4.07385,1.27051 8.85237,2.11894 14.05664,2.59765 5.20427,0.47871 10.83381,0.56134 16.70313,0.22266 5.86931,-0.33868 11.47146,-0.78653 16.60547,-1.34961 5.13399,-0.56309 9.79334,-1.22365 13.70703,-2.34375 1.48913,-0.4262 2.86677,-0.9287 4.12695,-1.51953 2.54507,-1.19325 2.05015,-6.17249 -0.0996,-4.54102 -1.99172,1.51153 -4.55969,2.50355 -7.57031,3.20703 -3.66893,0.85731 -7.96668,1.34146 -12.5586,1.76758 -4.59191,0.42612 -9.47527,0.75991 -14.3789,1.05664 -4.90363,0.29673 -9.56506,0.33523 -13.85156,0.084 -4.28652,-0.25124 -8.19851,-0.76855 -11.53516,-1.64649 -3.33664,-0.87795 -6.09539,-2.12996 -8.03711,-3.9375 -1.94173,-1.80756 -3.06587,-4.17751 -3.13086,-7.22265 -0.065,-3.04513 0.96102,-5.2776 2.81445,-6.81446 1.85342,-1.53686 4.53117,-2.36997 7.78907,-2.73828 3.2579,-0.36831 7.09262,-0.27244 11.32226,-0.1543 4.22963,0.11816 8.85767,0.22578 13.7832,-0.11718 4.92553,-0.34297 9.88026,-1.41664 14.58204,-2.44336 4.70178,-1.02671 9.13982,-1.97234 12.92382,-2.1836 0.473,-0.0264 0.93707,-0.0422 1.38868,-0.0449 1.16046,-0.007 2.25007,0.0442 3.25,0.23633 1.15313,0.22156 2.31543,-2.86146 -0.83789,-2.92773 -0.51177,-0.0108 -1.03459,-0.045 -1.57032,-0.0488 z"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#394655;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /></g><g
style="display:inline;opacity:1"
id="g4682"
transform="matrix(-0.11933103,0.60316395,1.3605999,0.30916083,88.824519,44.52189)"><path
sodipodi:nodetypes="sssssssssssssssss"
inkscape:connector-curvature="0"
id="path4678"
d="m 767.29926,387.32674 c 11.1235,7.96555 31.77795,11.29978 44.73159,15.54502 12.95363,4.24526 18.14889,9.35948 22.12936,13.37285 3.98046,4.01338 5.94428,7.14463 4.71807,9.52723 -1.2262,2.38259 -5.54351,3.99405 -14.00119,4.81166 -8.45765,0.81761 -15.90978,0.12055 -23.02358,-1.72572 -7.11381,-1.84628 -13.80694,-4.86649 -21.70559,-8.603 -7.89866,-3.73649 -17.3272,-8.0507 -25.81115,-14.18439 -8.48395,-6.13369 -17.62324,-13.90003 -23.14238,-24.13356 -5.51915,-10.23352 -5.78201,-21.34406 -5.37146,-30.88264 0.41055,-9.53859 1.51092,-17.55377 2.71572,-23.74931 1.20482,-6.19553 2.71509,-10.67437 4.77102,-13.66952 2.05591,-2.99513 4.65165,-4.52673 7.71923,-4.52673 3.06759,0 5.70357,1.83092 7.62535,5.49926 1.9218,3.66832 3.04778,9.24444 3.28639,16.76004 0.23861,7.51561 -0.67126,17.08072 0.34029,27.19831 1.01155,10.1176 3.89485,20.79494 15.01833,28.7605 z"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#394655;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /><path
sodipodi:nodetypes="sssssssssssssssss"
inkscape:connector-curvature="0"
id="path4680"
d="m 760.81735,387.61463 c 8.35351,7.22933 23.40419,11.34465 36.92829,14.85447 13.52408,3.50986 21.76315,7.50998 26.41399,11.29491 4.65086,3.78492 7.04347,6.96136 6.89289,9.28045 -0.15059,2.31908 -3.07202,3.85186 -9.99413,4.53735 -6.92209,0.68549 -13.12478,-0.17957 -19.18856,-2.15841 -6.06375,-1.97886 -12.01277,-5.06603 -19.62326,-8.64782 -7.61047,-3.5818 -16.94465,-7.61787 -24.98938,-13.21535 -8.04472,-5.59749 -15.82286,-12.65396 -20.9022,-21.24583 -5.07935,-8.59186 -6.01346,-17.801 -5.99188,-25.91871 0.0216,-8.1177 0.93462,-15.14861 1.86635,-20.66954 0.93173,-5.52092 2.01706,-9.59713 3.38259,-12.30465 1.36554,-2.70753 3.03466,-4.06947 5.01979,-4.01398 1.98511,0.0555 3.57672,1.84704 4.61437,5.2751 1.03765,3.42807 1.44745,8.54444 1.4737,15.15288 0.0262,6.60845 -0.43638,14.76057 0.91317,23.27473 1.34954,8.51418 4.83074,17.27506 13.18427,24.5044 z"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#e1d6b9;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /></g><g
style="display:inline"
id="g4533-2"
transform="matrix(-0.60102903,0.32221978,0.53870829,0.77401445,526.12645,47.501077)" /><path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#394655;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.42763;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 367.21812,281.2111 c 1.26906,4.8e-4 2.53948,0.0178 3.81226,0.0513 42.77724,1.12555 90.70354,5.69495 122.10388,40.54871 32.84028,36.45207 50.86245,87.73981 42.4768,134.73998 -3.70559,20.76925 -10.98111,49.47352 -17.74195,62.40674 -7.11403,13.60881 -19.80467,12.64104 -20.03271,14.6001 -0.95849,8.23388 28.65775,0.0351 45.92102,17.56348 14.06339,14.27947 18.47143,40.7184 18.81226,59.65026 0.0821,4.5609 -0.0281,9.27804 -0.3772,14.04236 -14.49094,35.53359 -47.68736,57.07915 -104.82056,72.23694 -16.35254,4.33843 -32.98332,6.84124 -49.34143,8.0127 -33.94749,-1.39556 -67.79597,-6.13242 -100.13854,-17.26685 -32.65579,-11.24226 -56.145,-40.89976 -74.77295,-73.88489 -29.47508,-52.19252 -35.755,-116.16519 -27.31567,-176.46789 7.06058,-50.45097 11.6574,-86.98057 52.22351,-116.77185 32.34621,-23.75469 69.85025,-39.47592 109.19128,-39.46106 z"
id="path4609"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssssccscscsssssc" /><path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#96d6ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.42763;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 367.42685,286.88188 c 42.99236,0.29098 91.45399,4.58065 122.97913,39.77783 29.3149,32.72949 43.70846,77.17043 40.47912,119.64477 -1.85014,24.33459 -4.2527,46.89446 -15.33809,68.52471 -7.40578,14.45044 -25.66197,16.94779 -25.75077,21.45698 -0.0598,3.03823 12.8172,2.29092 36.45996,9.33838 18.23589,5.43578 21.08736,15.45128 27.9657,34.84863 3.54426,9.99504 3.63562,21.40294 3.86353,32.07459 0.0987,4.62319 -0.16021,9.28578 -0.71778,13.93066 -15.76071,31.8161 -48.31041,51.69261 -101.98425,65.93262 -19.90398,5.28064 -40.22223,7.84987 -59.95606,8.5968 -23.42101,-1.57782 -46.67598,-5.15666 -69.29992,-11.41663 -36.53114,-10.10803 -65.44663,-39.43363 -86.5155,-75.75622 -29.60753,-51.04315 -36.18916,-113.60515 -29.37012,-173.2251 5.79548,-50.67089 11.02944,-86.89891 51.97998,-115.98999 31.47751,-22.36148 67.20785,-37.99521 105.20507,-37.73803 z"
id="path4611"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sssscssccscsssss" /><path
style="opacity:1;fill:#394655;fill-opacity:1;stroke:none;stroke-width:4.6875;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.633166"
d="m 550.04547,566.15505 c -8.01527,-17.95204 -33.2969,-29.54939 -59.90815,-26.35079 -36.4344,4.37932 -107.00869,29.17307 -108.83839,27.45259 32.95965,-15.3268 80.70019,-26.25455 112.65433,-35.45314 11.18054,-3.21853 19.35455,-9.69456 24.10347,-20.91405 0,0 -4.41927,9.99274 -4.75073,10.24133 -0.33145,0.24859 -7.78922,5.96622 -7.78922,5.96622 0,0 -6.79486,3.48029 -7.29204,3.72887 -0.49719,0.2486 -4.80611,3.39744 -4.80611,3.39744 0,0 2.15446,1.57441 2.9831,1.823 0.82864,0.24859 2.98311,1.65729 4.64039,1.82301 1.65728,0.16573 7.12631,0.66292 11.93243,1.4087 4.80611,0.74577 15.08126,3.23169 17.48432,4.39179 2.40305,1.16009 7.62349,4.06034 7.87208,4.47466 0.2486,0.41432 11.71452,18.01037 11.71452,18.01037 z"
id="path4629"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cscscccccsccccc" /><g
style="display:inline;opacity:1"
transform="matrix(-0.19755642,-0.64741346,0.92085299,-0.16781481,-30.330781,1045.2275)"
id="g4674"><path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#e1d6b9;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 423.50332,581.83521 c -0.004,4.40048 -1.19837,7.58856 -3.37524,9.82844 -2.17687,2.23987 -5.33154,3.55156 -9.14619,4.44292 -3.81465,0.89135 -8.28246,1.39523 -13.05675,1.83828 -4.77428,0.44304 -9.85163,0.79076 -14.95001,1.09928 -5.09838,0.30851 -9.94541,0.34741 -14.40217,0.0862 -4.45676,-0.26122 -8.52354,-0.79908 -11.99271,-1.71189 -3.46915,-0.91282 -6.33736,-2.21356 -8.3562,-4.09288 -2.01885,-1.87935 -3.18709,-4.34475 -3.25466,-7.51083 -0.0676,-3.16607 0.9983,-5.4859 2.92534,-7.0838 1.92703,-1.5979 4.71248,-2.46394 8.09977,-2.84688 3.38729,-0.38293 7.37282,-0.28336 11.77044,-0.16051 4.39762,0.12284 9.21051,0.23456 14.33166,-0.12202 5.12115,-0.35659 10.27171,-1.47349 15.16022,-2.54099 4.88852,-1.06749 9.50395,-2.05149 13.43823,-2.27114 3.9343,-0.21967 7.17754,0.32322 9.39823,2.04598 2.22069,1.72276 3.41425,4.59936 3.41004,8.99986 z"
id="path4670"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sssssssssssssssss" /><path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#394655;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 411.91406,568.54883 c -3.75011,-0.0271 -8.08701,0.53975 -12.76172,1.28711 -5.34251,0.85413 -11.10706,1.92059 -17.00976,2.32617 -5.9027,0.40562 -11.41103,0.38326 -16.44727,0.41406 -5.03624,0.0309 -9.6045,0.1607 -13.50781,0.85938 -3.9033,0.69867 -7.13503,1.96743 -9.4082,3.96875 -2.27316,2.00131 -3.58535,4.71676 -3.65235,8.17578 -0.067,3.45901 1.21821,6.3073 3.54297,8.58008 2.32476,2.27278 5.68789,3.9795 9.76172,5.25 4.07385,1.27051 8.85237,2.11894 14.05664,2.59765 5.20427,0.47871 10.83381,0.56134 16.70313,0.22266 5.86931,-0.33868 11.47146,-0.78653 16.60547,-1.34961 5.13399,-0.56309 9.79334,-1.22365 13.70703,-2.34375 1.48913,-0.4262 2.86677,-0.9287 4.12695,-1.51953 2.54507,-1.19325 2.05015,-6.17249 -0.0996,-4.54102 -1.99172,1.51153 -4.14364,1.68162 -7.15735,2.35061 -3.67269,0.81527 -8.18136,0.99111 -12.55008,1.3428 -4.3687,0.35167 -8.7789,1.78431 -13.31332,2.07736 -4.53444,0.29304 -8.86787,0.32801 -12.93181,0.0702 -4.06396,-0.25785 -7.85651,-0.78075 -11.12475,-1.64296 -3.26823,-0.86221 -5.99695,-2.08037 -7.8846,-3.81399 -1.88765,-1.73365 -2.92537,-3.9871 -2.97865,-6.80086 -0.0533,-2.81374 0.90176,-4.8192 2.66881,-6.10562 1.76704,-1.28641 5.61732,-0.58475 8.69196,-0.71399 3.07463,-0.12925 6.90624,-0.54484 10.78772,-0.41733 3.88147,0.12754 6.54592,-0.48119 11.04844,-1.2139 4.50252,-0.73264 9.15212,-2.3434 13.88736,-3.72101 4.73523,-1.37761 9.22461,-2.34259 13.00861,-2.55385 0.473,-0.0264 0.93707,-0.0422 1.38868,-0.0449 1.16046,-0.007 2.25007,0.0442 3.25,0.23633 1.15313,0.22156 2.31543,-2.86146 -0.83789,-2.92773 -0.51177,-0.0108 -1.03459,-0.045 -1.57032,-0.0488 z"
id="path4672"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csscsscssssssssssssssssssssccsssc" /></g><g
style="opacity:1"
transform="matrix(0.38329319,-0.18164886,0.18164886,0.38329319,415.72605,54.494616)"
id="g4804"><path
sodipodi:nodetypes="sssssssssssssssss"
inkscape:connector-curvature="0"
id="path4796"
d="m -626.57295,401.69566 c 2.24713,11.35067 0.36741,22.38948 -3.843,32.03835 -4.21053,9.64886 -10.54997,17.90531 -17.7192,24.34399 -7.1694,6.43883 -15.25457,11.1106 -24.57171,13.61082 -9.31727,2.5002 -20.94956,4.47176 -31.64526,1.82793 -10.69571,-2.64383 -18.09209,-9.81214 -24.14818,-17.25062 -6.05597,-7.43843 -12.44269,-16.56671 -23.09665,-25.35944 -10.65372,-8.79255 -20.95218,-17.78817 -25.30072,-26.87318 -4.34843,-9.08528 -7.1154,-18.36084 -7.98,-27.52156 -0.86459,-9.1606 0.24716,-17.36404 2.9617,-24.58398 2.71467,-7.22004 7.03243,-13.45488 12.66059,-18.5369 5.6283,-5.08191 12.56665,-9.01064 20.59229,-11.48936 8.02576,-2.47858 17.13537,-3.50537 27.20916,-2.66707 10.0738,0.83832 20.1809,3.47234 29.95223,7.6529 9.77122,4.18068 19.21426,9.9086 27.71179,16.89733 8.49741,6.98886 16.03465,15.24007 21.79567,24.41557 5.7609,9.17565 13.1742,22.14471 15.42129,33.49522 z"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#96d6ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /><path
transform="matrix(13.851095,0,0,13.851095,10133.213,-6001.611)"
sodipodi:nodetypes="csssccscsccscscccsccscsssscscscc"
inkscape:connector-curvature="0"
id="path4798"
d="m -784.27135,455.90422 c -0.56339,0.0147 -1.08437,0.10666 -1.55902,0.26191 -0.63289,0.20699 -1.18231,0.52669 -1.63059,0.93484 -0.44828,0.40815 -0.79558,0.90361 -1.01756,1.4752 -0.22199,0.5716 -0.31844,1.21792 -0.26185,1.93717 0.0566,0.71926 0.26134,1.4471 0.59196,2.157 0.33063,0.7099 0.99621,1.41858 1.84494,2.08284 0.84872,0.66425 1.36325,1.36931 1.83382,1.93901 0.46898,0.56774 1.13678,0.9105 2.02675,0.98962 0.10256,0.009 0.12294,-0.31321 0.034,-0.33899 -0.78143,-0.21746 -1.26048,-0.77583 -1.72293,-1.21489 -0.42768,-0.5236 -0.87838,-1.16625 -1.63058,-1.78505 -0.75217,-0.61879 -1.47924,-1.25213 -1.78697,-1.89162 -0.30772,-0.63951 -0.50455,-1.29287 -0.56648,-1.9378 -0.062,-0.64492 0.0165,-1.22191 0.20772,-1.73042 0.1912,-0.50852 0.49539,-0.94884 0.89287,-1.30706 0.3975,-0.35822 0.88707,-0.63484 1.45426,-0.80994 0.2836,-0.0875 0.58767,-0.1494 0.90851,-0.1822 0.32084,-0.0328 0.65966,-0.0369 1.01552,-0.008 0.71174,0.0585 1.42446,0.24383 2.11396,0.53794 0.6895,0.29412 1.35628,0.69807 1.95502,1.19025 0.59873,0.49218 1.12894,1.07271 1.53474,1.71893 0.4058,0.64623 0.9285,1.5589 1.08808,2.35795 0.13104,0.65619 0.075,1.29927 -0.13103,1.88026 -0.0384,0.10817 0.49808,0.30362 0.62824,-0.002 0.24262,-0.57052 0.23429,-1.24452 0.10166,-1.89748 -0.17938,-0.88293 -0.69436,-1.871 -1.14416,-2.58711 -0.44981,-0.71609 -1.03943,-1.35821 -1.70275,-1.89855 -0.66333,-0.54034 -1.3987,-0.97968 -2.16052,-1.29649 -0.76184,-0.31679 -1.55154,-0.51173 -2.33984,-0.56369 -0.19709,-0.013 -0.38986,-0.0163 -0.57767,-0.0116 z"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#394655;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /><path
sodipodi:nodetypes="cssscsssc"
inkscape:connector-curvature="0"
id="path4800"
d="m -730.27274,382.91266 c 1.8068,-2.76405 6.31309,-3.63001 13.24575,-1.6171 10.53068,3.05761 22.43414,14.97755 28.94834,24.04709 3.57338,4.97534 7.6424,9.78266 9.64772,15.62449 0.68055,1.98294 1.27611,3.97774 0.68898,6.70435 -2.4056,-0.49416 -4.1871,-3.62313 -5.37952,-6.01329 -4.69962,-9.4202 -11.38574,-17.86492 -20.09536,-24.13889 -7.3284,-5.27852 -8.20487,-8.9719 -15.61502,-12.25742 -4.69053,-2.07967 -7.44128,-1.02076 -11.44089,-2.34923 z"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#394655;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /><path
sodipodi:nodetypes="sssssssss"
inkscape:connector-curvature="0"
id="path4802"
d="m -689.31909,403.49962 c 2.08771,-2.1886 -1.9021,4.5559 -4.48533,5.36905 -9.69439,3.05157 -19.01784,7.22624 -28.57811,10.64488 -3.11327,1.11257 -3.94795,-2.11026 -1.30738,-3.72982 2.68251,-1.64492 5.45711,-2.73872 8.35507,-3.75217 2.71578,-0.94874 5.64428,-1.2851 8.27731,-2.4236 5.06052,-2.18718 7.83343,-5.20599 12.75841,-7.67984 1.68866,-0.84854 3.86766,2.73608 4.97603,1.5739 z"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#394655;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /></g></g><g
id="layer6"
inkscape:label="gopher-body-shadow"
style="opacity:0.07"
transform="translate(-22.468606,-107.81499)"><path
style="opacity:1;fill:#1e1e1e;fill-opacity:1;stroke:none;stroke-width:3.53553;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 410.73438,402.67383 c -22.12212,5.91178 -47.244,11.63106 -70.61524,16.37305 -48.79037,9.89949 -67.17652,36.06247 -78.49023,54.44726 l 6.87695,-1.67969 c 36.64463,-15.30695 75.75822,-23.23183 113.48437,-35.26953 12.09814,-3.47331 21.06002,-13.5287 25.50391,-25.00976 1.18561,-2.92243 2.25783,-5.87876 3.24024,-8.86133 z"
transform="scale(0.93749999)"
id="path4829"
inkscape:connector-curvature="0" /><path
style="opacity:1;fill:#1e1e1e;fill-opacity:1;stroke:none;stroke-width:5;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 176.74023,191.19336 c -12.02297,5.35584 -23.55765,11.8602 -34.44531,19.05273 -5.41851,4.11086 -12.04772,7.05917 -16.45703,12.31055 0.0894,0.61993 -0.23486,1.1597 -0.71484,1.54883 -0.66228,4.1883 -1.36755,8.37707 -2.08594,12.50781 -5.65684,32.5269 -33.941548,3.53554 -50.91211,0 -10.52665,-2.19305 -19.680537,-11.20026 -16.179688,-32.73437 -1.579179,1.23479 -3.051377,2.63841 -4.392578,4.22461 -5.278878,6.02984 -6.059769,15.29458 -3.236328,22.56836 4.226081,7.59968 10.487816,15.22544 19.425782,17.11523 7.922144,1.96176 15.28729,5.43641 22.820312,8.4375 3.386589,1.47244 7.752358,0.61137 10.76562,2.42773 -2.433965,1.64193 -6.471862,1.23181 -7.285151,4.85743 -9.479196,22.45139 -12.471269,46.96783 -15.552735,70.95117 -3.621752,29.34547 -3.810268,59.0771 -1.185546,88.50976 5.062186,45.87599 20.801047,91.1762 49.363282,127.80469 19.95688,26.39173 47.3522,48.60821 80.10937,56.24414 22.47395,5.53265 45.44736,9.51266 68.57813,10.69727 8.5266,-0.40063 17.18762,-0.50715 25.58008,-2.02539 0.38196,-2.81994 -2.61781,-5.57722 -3.4961,-8.2461 -1.44653,-3.42348 -4.19801,-6.88649 -4.1582,-10.63867 2.13967,-1.54285 1.84049,-4.80023 4.6582,-5.89648 5.55455,-3.57415 12.83988,-2.42032 18.94141,-1.75782 5.75306,0.52405 7.14734,7.19265 9.875,11.22852 2.12351,3.09028 2.41953,7.87377 5.55859,10.0625 26.17162,-6.52384 52.36044,-14.89116 75.51172,-29.04492 17.05316,-10.54934 31.72418,-25.28626 40.90821,-43.20117 -0.321,-7.86722 0.0972,-15.83004 0.0234,-23.74805 -36.4662,9.9142 -97.74588,26.5181 -128.4375,31.87695 -44.54772,7.77818 -96.87505,9.19053 -150.61515,-30.40744 -65.69966,-48.41028 -44.54795,-229.80948 -35.35555,-265.16482 4.79814,-18.45438 17.9071,-38.64402 42.39062,-59.56055 z"
transform="scale(0.93749999)"
id="path4834"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccssccccccccccccccccccccccsssc" /><path
style="opacity:1;fill:#1e1e1e;fill-opacity:1;stroke:none;stroke-width:4.6875;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 221.25,457.42331 c 0,0 15,15.23437 22.03125,18.04687 7.03125,2.8125 20.85937,11.01563 28.125,14.76563 7.26562,3.75 7.73437,10.07812 22.96875,4.21875 15.23437,-5.85938 20.39062,-10.07813 30.9375,-11.71875 10.54687,-1.64063 18.04687,-0.9375 25.07812,-3.98438 7.03125,-3.04687 23.90625,-10.78125 28.59375,-13.35937 4.6875,-2.57813 9.60938,-2.57813 13.82813,-3.98438 4.21875,-1.40625 17.10937,-0.23437 19.45312,-3.75 2.34375,-3.51562 3.75,-3.98437 3.04688,-6.5625 -0.70313,-2.57812 -7.03125,-15 -15,-16.875 -7.96875,-1.875 -14.76563,-2.34375 -36.5625,-1.875 -21.79688,0.46875 -18.75,-1.17187 -39.14063,4.45313 -20.39062,5.625 -14.76562,10.78125 -37.26562,12.89062 -22.5,2.10938 -17.10938,2.10938 -29.53125,1.64063 -12.42188,-0.46875 -11.71875,-0.23438 -19.6875,-1.64063 -7.96875,-1.40625 -16.875,7.73438 -16.875,7.73438 z"
id="path4842"
inkscape:connector-curvature="0" /><path
style="opacity:1;fill:#1e1e1e;fill-opacity:1;stroke:none;stroke-width:4.6875;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 364.92187,465.15768 c 15,5.85938 16.875,39.60938 16.875,39.60938 0,0 3.98438,3.28125 4.21875,-0.70313 5.3692,-7.3069 -8.34035,-45.03528 -13.82812,-41.48437 z"
id="path4844"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" /><path
style="display:inline;opacity:1;fill:#1e1e1e;fill-opacity:1;stroke:none;stroke-width:0.883883;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;enable-background:new"
d="m 280.10156,140.0293 c -3.31241,1.49194 -6.45666,3.36696 -9.3457,5.52929 -5.80006,4.43544 -10.87913,10.55536 -12.1543,17.92774 -0.29285,2.25732 -0.37829,4.57376 -0.32617,6.82812 0.54553,0.71731 1.76636,0.2809 2.5957,0.47852 3.60567,0.16435 7.21143,0.36527 10.8125,0.60937 -3.09385,-7.05751 -2.40538,-18.24537 8.41797,-31.37304 z"
transform="scale(0.93749999)"
id="path4846"
inkscape:connector-curvature="0" /></g><g
id="layer2"
inkscape:label="gopher-face"
style="display:inline"
transform="translate(-159.49345,-229.70978)"><g
transform="matrix(-0.70545801,0,0,0.70545801,653.3373,199.47893)"
id="g4639"><path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#394655;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 547.42756,318.16456 c -0.44046,14.77191 -4.12869,29.02667 -10.38967,42.25266 -6.26099,13.22599 -15.09198,25.42687 -25.80466,35.99686 -10.71268,10.57 -23.30432,19.50822 -37.11826,26.08983 -13.81394,6.58161 -28.85103,10.80263 -44.50193,11.8618 -15.65091,1.05917 -30.4406,-1.15844 -43.81781,-6.16756 -13.37721,-5.00911 -25.3405,-12.8075 -35.30087,-22.80416 -9.96037,-9.99666 -17.91599,-22.19037 -23.26581,-35.90798 -5.34983,-13.71761 -8.0915,-28.95913 -7.64195,-44.98105 0.44955,-16.02192 4.04447,-31.2937 10.1422,-45.07896 6.09773,-13.78526 14.69591,-26.08175 25.16951,-36.25747 10.4736,-10.17571 22.82245,-18.23043 36.46168,-23.66123 13.63924,-5.4308 28.57214,-8.24285 44.22923,-8.02541 15.6571,0.21745 30.56095,3.42714 44.11009,8.94154 13.54914,5.5144 25.7404,13.33722 35.92568,22.91495 10.18529,9.57774 18.36233,20.91345 23.87736,33.53282 5.51504,12.61936 8.36566,26.52144 7.92521,41.29336 z"
id="path4631"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sssssssssssssssss" /><path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 539.72249,314.79002 c 10e-4,13.89984 -3.01572,27.53808 -8.51346,40.35257 -5.49774,12.81449 -13.48047,24.80543 -23.37659,35.2527 -9.89612,10.44726 -21.70519,19.34133 -34.78531,25.87862 -13.08011,6.53727 -27.4256,10.71236 -42.3773,11.7667 -14.9517,1.05435 -29.09103,-1.11258 -41.85904,-5.93108 -12.76803,-4.81852 -24.16883,-12.28715 -33.66552,-21.79076 -9.49671,-9.50362 -17.08979,-21.04298 -22.23241,-33.95465 -5.14261,-12.91166 -7.83328,-27.19561 -7.52333,-42.13595 0.30995,-14.94034 3.58995,-29.10832 9.22975,-41.85842 5.63981,-12.7501 13.63743,-24.08168 23.39638,-33.47108 9.75897,-9.38941 21.27795,-16.83842 34.00359,-21.94183 12.72563,-5.10342 26.66067,-7.86812 41.28534,-7.94317 14.62467,-0.0751 28.55938,2.53224 41.26083,7.24431 12.70145,4.71207 24.16709,11.5339 33.81555,20.03646 9.64847,8.50257 17.47884,18.68937 22.90117,30.21241 5.42232,11.52304 8.43889,24.38332 8.44035,38.28317 z"
id="path4633"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sssssssssssssssss" /><circle
r="30.809652"
cy="314.25491"
cx="420.48679"
id="circle4635"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#394455;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /><circle
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="circle4637"
cx="406.84973"
cy="300.11276"
r="15.152287" /></g><g
id="g4651"
transform="matrix(-0.3718816,-0.33035833,-0.33035833,0.3718816,807.54151,424.47556)"><path
sodipodi:nodetypes="sssssssssssssssss"
inkscape:connector-curvature="0"
id="path4643"
d="m 549.05152,326.95134 c -3.75547,13.70752 -9.94485,27.49753 -18.134,40.75742 -8.18917,13.2599 -18.55963,25.88871 -30.48613,36.73483 -11.9265,10.84612 -25.26726,19.91416 -38.40631,26.7046 -13.13906,6.79044 -26.00962,11.35394 -38.37684,13.00513 -12.36722,1.6512 -23.25032,0.18545 -33.06847,-4.02278 -9.81817,-4.20823 -22.90634,-9.21469 -29.99096,-18.16657 -7.08461,-8.95188 -12.84054,-20.18257 -16.5035,-33.03389 -3.66297,-12.85133 -5.229,-27.32914 -3.92417,-42.72858 1.30484,-15.39944 5.36688,-30.24976 11.81788,-43.75488 6.45101,-13.5051 15.29008,-25.65823 26.00811,-35.78271 10.71803,-10.12447 28.44246,-20.29305 42.24879,-25.86698 13.80633,-5.57394 28.83304,-8.62768 44.20973,-8.80364 15.3767,-0.17594 29.62737,2.52591 41.94358,7.37479 12.31622,4.84887 22.69735,11.85058 30.35956,20.34718 7.66222,8.49661 12.72593,18.56023 14.82358,29.82149 2.09769,11.26125 1.23461,23.70707 -2.52085,37.41459 z"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#394655;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /><path
sodipodi:nodetypes="sssssssssssssssss"
inkscape:connector-curvature="0"
id="path4645"
d="m 543.48686,325.96521 c -3.05527,12.95406 -8.32379,26.18736 -15.65713,38.96025 -7.33335,12.77289 -16.92422,24.96643 -28.32938,35.27691 -11.40514,10.31051 -24.49416,18.73032 -37.45951,24.88997 -12.96533,6.15964 -25.70084,10.13776 -37.71064,11.47666 -12.00982,1.33889 -22.34344,-0.13174 -31.49437,-4.07588 -9.15093,-3.94412 -22.12504,-8.81495 -28.38237,-17.0256 -6.25732,-8.21068 -11.24381,-18.53447 -14.30417,-30.37519 -3.06035,-11.84072 -4.18965,-25.20221 -2.68634,-39.42576 1.5033,-14.22354 5.50837,-27.94818 11.67956,-40.43838 6.17119,-12.4902 14.50792,-23.74111 24.54768,-33.13895 10.03978,-9.39782 26.99021,-19.0621 39.83566,-24.2929 12.84546,-5.2308 26.78412,-8.15811 41.0009,-8.45853 14.21678,-0.30038 27.34319,2.03758 38.64284,6.33106 11.29965,4.29349 20.72984,10.51935 27.81498,18.21491 7.08513,7.69557 11.8105,16.84485 13.92296,27.20306 2.11247,10.35821 1.63459,21.92432 -1.42067,34.87837 z"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /><circle
transform="rotate(9.4590451)"
r="27.721321"
cy="221.94495"
cx="451.74091"
id="circle4647"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#394455;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /><circle
transform="rotate(9.4590451)"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="circle4649"
cx="444.28159"
cy="208.59291"
r="13.633434" /></g></g><g
id="layer8"
inkscape:label="gopher-eye-shadow"
style="opacity:0.07"
transform="translate(-22.468606,-107.81499)"><path
style="opacity:1;fill:#1e1e1e;fill-opacity:1;stroke:none;stroke-width:2.5;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 183.98633,257.10938 c -12.96514,6.80368 -24.09238,16.98928 -31.2461,29.85742 -6.62306,11.80983 -9.18947,25.58787 -7.96289,39.02734 1.67308,22.69639 14.45708,43.56009 31.54688,58.10156 14.06811,11.68944 31.68858,19.74781 50.07226,20.84571 11.72752,0.49232 23.74714,-0.51041 34.5586,-5.42579 7.00377,-3.01395 13.43915,-7.17995 19.12109,-12.20898 -12.36895,1.55403 -17.4885,4.99626 -41.57617,5.11133 -34.01431,0.16249 -53,-11.5 -68.5,-36.5 -14.1749,-22.86275 -23.28438,-60.80338 13.98633,-98.80859 z"
transform="scale(0.93749999)"
id="path4853"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccssc" /><path
style="opacity:1;fill:#1e1e1e;fill-opacity:1;stroke:none;stroke-width:2.5;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 407.00195,240.87891 c -9.28173,2.40304 -16.98081,9.77947 -21.58398,18.09375 -9.07687,16.02983 -11.91205,35.42287 -8.52539,53.46875 3.18065,14.4141 9.49376,28.957 20.97265,38.67382 5.72719,4.40424 12.92201,6.42783 19.83399,8.13477 6.81141,1.14046 13.43258,-1.454 19.35351,-4.83008 -10.63686,0.15673 -18.09098,-0.62412 -29.80273,-7.00195 -16.87155,-9.18769 -20.86545,-23.47661 -24.25,-43.5 -2.91982,-17.27395 -3.79826,-39.70251 24.00195,-63.03906 z"
transform="scale(0.93749999)"
id="path4855"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccssc" /></g><g
id="layer7"
inkscape:label="gopher-mouth"
style="display:inline"
transform="translate(-159.49345,-229.70978)"><path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#1e1e1e;fill-opacity:0.0854271;fill-rule:nonzero;stroke:none;stroke-width:11.1413;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 479.16003,446.53263 c -0.5609,0.0108 -1.13139,0.0418 -1.70837,0.0934 -2.30796,0.20633 -4.51646,0.72546 -6.51307,1.48133 -1.9966,0.75587 -3.78067,1.74769 -5.22583,2.89856 -1.0355,0.82461 -1.88701,1.73417 -2.51953,2.69165 -0.49936,0.12274 -1.0048,0.23296 -1.49781,0.36987 -3.81399,1.05919 -7.40798,2.54289 -10.40404,4.35608 -2.99605,1.81321 -5.4585,3.90209 -6.89576,6.26037 -1.4722,2.41563 -1.97188,5.13866 -1.80359,7.29493 0.19753,2.5307 1.75758,4.81955 3.97339,6.88111 2.21579,2.06154 5.27574,3.88827 8.8202,5.38513 1.41204,0.59632 2.90966,1.1203 4.4403,1.59484 l -0.83679,5.84107 -1.56738,7.92297 c -0.28234,1.42686 0.0936,2.6844 0.78552,3.59985 0.69199,0.91542 1.75347,1.43692 3.00476,1.46668 l 4.17114,0.10071 8.25256,-0.19226 c 1.58268,-0.0369 3.05271,-0.65206 4.13086,-1.59668 1.07816,-0.94464 1.71703,-2.22901 1.84571,-3.63098 l 0.72143,-7.86255 0.29663,-3.98255 c 3.44589,-0.52696 6.56272,-1.40104 9.31274,-2.44995 3.13519,-1.19582 5.76942,-2.61386 7.84425,-4.18763 2.07486,-1.57375 3.60911,-3.3186 4.57763,-5.26427 0.96853,-1.94567 1.36942,-4.09866 1.01807,-6.41968 -0.35134,-2.32102 -1.43875,-4.58369 -3.11829,-6.66321 -1.39778,-1.73064 -3.21452,-3.31999 -5.30822,-4.7168 0.0111,-0.55256 -0.0197,-1.11781 -0.13001,-1.69922 -0.26781,-1.4117 -0.89157,-2.76339 -1.83655,-3.9862 -0.94497,-1.22282 -2.2106,-2.31507 -3.73901,-3.20068 -1.52841,-0.88563 -3.32124,-1.56509 -5.31189,-1.96839 -1.49298,-0.30248 -3.09635,-0.44985 -4.77905,-0.41748 z"
id="path4863"
inkscape:connector-curvature="0" /><g
id="g4823"
transform="translate(12.595339,-3.9774756)"><path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:11.1413;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 467.31675,478.77402 -7.09437,0.0922 -4.13468,-0.0915 c -1.31882,-0.0292 -2.49364,0.59671 -3.34977,1.51944 -0.85615,0.92274 -1.27744,2.20064 -1.47679,3.59515 l -1.12865,7.8943 -1.5677,7.92258 c -0.28234,1.42686 0.0937,2.68467 0.78566,3.60012 0.69199,0.91542 1.75323,1.43698 3.00452,1.46674 l 4.17197,0.0993 8.25189,-0.19228 c 1.58268,-0.0369 3.05287,-0.65192 4.13103,-1.59654 1.07815,-0.94464 1.7158,-2.22919 1.84447,-3.63117 l 0.72151,-7.86154 0.58517,-7.8491 c 0.10417,-1.3971 -0.52004,-2.64858 -1.39674,-3.54475 -0.8767,-0.89618 -2.06937,-1.43077 -3.34749,-1.42293 z"
id="path4686"
inkscape:connector-curvature="0"
sodipodi:nodetypes="scssscssscssscsss" /><path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:11.1413;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 466.02149,481.16374 -5.78995,0.0778 -2.75744,-0.11307 c -1.04748,-0.043 -2.01463,0.4856 -2.74214,1.24096 -0.72751,0.75535 -1.15228,1.80234 -1.35005,2.94507 l -1.11703,6.45444 -1.39816,6.47122 c -0.24964,1.15537 0.002,2.19546 0.54523,2.94311 0.5435,0.74764 1.41108,1.15214 2.44988,1.1934 l 2.83204,0.11253 6.55718,-0.1421 c 1.24167,-0.027 2.42344,-0.526 3.31255,-1.29718 0.88911,-0.77118 1.45844,-1.82149 1.60367,-2.96928 l 0.81341,-6.4286 0.70226,-6.42074 c 0.12544,-1.14351 -0.31817,-2.1697 -0.99356,-2.90365 -0.67536,-0.73395 -1.62282,-1.178 -2.66787,-1.16394 z"
id="path4688"
inkscape:connector-curvature="0"
sodipodi:nodetypes="scssscssscssscsss" /><path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#394655;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:11.1413;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 433.73526,472.08025 c 0.19752,2.5307 1.75649,4.82026 3.9723,6.88181 2.21579,2.06155 5.27599,3.88893 8.82045,5.38579 3.54446,1.49687 7.54259,2.64799 11.59243,3.26302 4.04985,0.61505 8.15288,0.68338 12.18571,0.19715 4.03281,-0.48626 7.64449,-1.45413 10.77968,-2.64995 3.13518,-1.19582 5.76946,-2.61453 7.84429,-4.18829 2.07486,-1.57376 3.60891,-3.31701 4.57744,-5.26269 0.96853,-1.94567 1.37034,-4.09954 1.01899,-6.42056 -0.35134,-2.32102 -1.4393,-4.58444 -3.11884,-6.66396 -1.67955,-2.07951 -3.93835,-3.97272 -6.59166,-5.54818 -2.6533,-1.57546 -5.69659,-2.83225 -9.05614,-3.65611 -3.35955,-0.82385 -7.03889,-1.21547 -11.06436,-1.08264 -4.02547,0.13285 -8.04246,0.77372 -11.85647,1.83293 -3.814,1.05919 -7.40852,2.54378 -10.40458,4.35697 -2.99604,1.81321 -5.45804,3.90231 -6.89529,6.26059 -1.4722,2.41563 -1.97224,5.13785 -1.80395,7.29412 z"
id="path4690"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sssssssssssssssss" /><path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#e1d0cb;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:11.1413;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 442.25761,471.51199 c 0.34559,2.01022 1.52164,3.88762 3.32749,5.56973 1.80585,1.68211 4.23932,3.17214 7.00457,4.36112 2.76524,1.18899 5.84856,2.06805 8.99234,2.52986 3.14378,0.46181 6.35142,0.50432 9.50541,0.11936 3.15398,-0.38496 5.97075,-1.14729 8.41503,-2.12187 2.44428,-0.97459 4.50648,-2.15972 6.12437,-3.48208 1.61791,-1.32236 2.79548,-2.78732 3.48967,-4.38292 0.69419,-1.59559 0.90742,-3.32616 0.54576,-5.15905 -0.36166,-1.8329 -1.26917,-3.59361 -2.60863,-5.20009 -1.33945,-1.60649 -3.10784,-3.05657 -5.19076,-4.25685 -2.08293,-1.20029 -4.4781,-2.15007 -7.11901,-2.76427 -2.6409,-0.61421 -5.52795,-0.89311 -8.65369,-0.76365 -3.12573,0.12948 -6.20924,0.65323 -9.12183,1.4947 -2.91261,0.84148 -5.65005,2.00273 -7.96189,3.4111 -2.31186,1.40839 -4.18867,3.06443 -5.38415,4.87182 -1.19548,1.8074 -1.71029,3.76288 -1.36468,5.77309 z"
id="path4692"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sssssssssssssssss" /><path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#394655;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:11.1413;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 453.44155,459.24387 c 0.50394,1.4405 1.59973,2.71976 3.11582,3.79941 1.51609,1.07966 3.44645,1.96175 5.54093,2.63816 2.09447,0.67641 4.34429,1.14922 6.54588,1.40092 2.20159,0.25168 4.3549,0.28101 6.37262,0.0579 2.01772,-0.22314 3.7207,-0.67675 5.162,-1.30838 1.44132,-0.63166 2.6208,-1.44105 3.55014,-2.39383 0.92933,-0.95279 1.60959,-2.05056 2.00449,-3.26657 0.39491,-1.21603 0.50374,-2.55168 0.23592,-3.96339 -0.26781,-1.41171 -0.89241,-2.76478 -1.83739,-3.98759 -0.94498,-1.22282 -2.20943,-2.31451 -3.73784,-3.20012 -1.52841,-0.88562 -3.32073,-1.5647 -5.31138,-1.968 -1.99064,-0.40331 -4.17987,-0.53049 -6.48783,-0.32418 -2.30795,0.20632 -4.51621,0.7257 -6.51282,1.48157 -1.9966,0.75587 -3.78172,1.74809 -5.22688,2.89895 -1.44517,1.15085 -2.55022,2.46103 -3.16907,3.84701 -0.61885,1.38597 -0.74853,2.84764 -0.24459,4.28815 z"
id="path4694"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sssssssssssssssss" /></g></g><g
id="layer3"
inkscape:label="gopher-eye-lashes"
style="display:inline"
transform="translate(-159.49345,-229.70978)" /><g
id="g2"
transform="matrix(0.29908034,-0.07349009,0.08149446,0.24234368,225.1279,272.80177)"
inkscape:label="folder"
style="display:inline"><path
id="SVGCleanerId_0"
style="fill:#ffc36e"
d="M 183.295,123.586 H 55.05 c -6.687,0 -12.801,-3.778 -15.791,-9.76 L 26.483,88.276 39.259,62.726 c 2.99,-5.982 9.103,-9.76 15.791,-9.76 h 128.246 c 6.687,0 12.801,3.778 15.791,9.76 l 12.775,25.55 -12.776,25.55 c -2.99,5.982 -9.103,9.76 -15.791,9.76 z" /><g
id="g1-9">
<path
id="SVGCleanerId_0_1_"
style="fill:#ffc36e"
d="M 183.295,123.586 H 55.05 c -6.687,0 -12.801,-3.778 -15.791,-9.76 L 26.483,88.276 39.259,62.726 c 2.99,-5.982 9.103,-9.76 15.791,-9.76 h 128.246 c 6.687,0 12.801,3.778 15.791,9.76 l 12.775,25.55 -12.776,25.55 c -2.99,5.982 -9.103,9.76 -15.791,9.76 z" />
</g><path
style="fill:#eff2fa"
d="M 485.517,70.621 H 26.483 c -4.875,0 -8.828,3.953 -8.828,8.828 v 44.138 h 476.69 V 79.448 c 0,-4.875 -3.953,-8.827 -8.828,-8.827 z"
id="path1" /><rect
x="17.655001"
y="105.931"
style="fill:#e1e6f2"
width="476.69"
height="17.655001"
id="rect1" /><path
style="fill:#ffd782"
d="M 494.345,88.276 H 217.318 c -3.343,0 -6.4,1.889 -7.895,4.879 l -10.336,20.671 c -2.99,5.982 -9.105,9.76 -15.791,9.76 H 55.05 c -6.687,0 -12.801,-3.778 -15.791,-9.76 L 28.922,93.155 C 27.427,90.165 24.37,88.276 21.027,88.276 H 17.655 C 7.904,88.276 0,96.18 0,105.931 v 335.448 c 0,9.751 7.904,17.655 17.655,17.655 h 476.69 c 9.751,0 17.655,-7.904 17.655,-17.655 V 105.931 c 0,-9.751 -7.904,-17.655 -17.655,-17.655 z"
id="path2" /><path
style="fill:#ffc36e"
d="M 485.517,441.379 H 26.483 c -4.875,0 -8.828,-3.953 -8.828,-8.828 v 0 c 0,-4.875 3.953,-8.828 8.828,-8.828 h 459.034 c 4.875,0 8.828,3.953 8.828,8.828 v 0 c 0,4.876 -3.953,8.828 -8.828,8.828 z"
id="path3" /><path
style="fill:#eff2fa"
d="m 326.621,220.69 h 132.414 c 4.875,0 8.828,-3.953 8.828,-8.828 v -70.621 c 0,-4.875 -3.953,-8.828 -8.828,-8.828 H 326.621 c -4.875,0 -8.828,3.953 -8.828,8.828 v 70.621 c 0,4.875 3.953,8.828 8.828,8.828 z"
id="path4" /><path
style="fill:#c7cfe2"
d="m 441.379,167.724 h -97.103 c -4.875,0 -8.828,-3.953 -8.828,-8.828 v 0 c 0,-4.875 3.953,-8.828 8.828,-8.828 h 97.103 c 4.875,0 8.828,3.953 8.828,8.828 v 0 c 0,4.876 -3.953,8.828 -8.828,8.828 z"
id="path5" /><path
style="fill:#d7deed"
d="m 441.379,203.034 h -97.103 c -4.875,0 -8.828,-3.953 -8.828,-8.828 v 0 c 0,-4.875 3.953,-8.828 8.828,-8.828 h 97.103 c 4.875,0 8.828,3.953 8.828,8.828 v 0 c 0,4.876 -3.953,8.828 -8.828,8.828 z"
id="path6" /></g><g
id="layer12"
inkscape:label="gopher-hands"
style="display:inline"
transform="translate(-159.49345,-229.70978)"><g
transform="matrix(-0.73022337,-0.0504068,0.04754695,1.0110636,636.13477,-6.0140033)"
id="g4702"><path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#e1d6b9;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 423.50332,581.83521 c -0.004,4.40048 -1.19837,7.58856 -3.37524,9.82844 -2.17687,2.23987 -5.33154,3.55156 -9.14619,4.44292 -3.81465,0.89135 -8.28246,1.39523 -13.05675,1.83828 -4.77428,0.44304 -9.85163,0.79076 -14.95001,1.09928 -5.09838,0.30851 -9.94541,0.34741 -14.40217,0.0862 -4.45676,-0.26122 -8.52354,-0.79908 -11.99271,-1.71189 -3.46915,-0.91282 -6.33736,-2.21356 -8.3562,-4.09288 -2.01885,-1.87935 -3.18709,-4.34475 -3.25466,-7.51083 -0.0676,-3.16607 0.9983,-5.4859 2.92534,-7.0838 1.92703,-1.5979 4.71248,-2.46394 8.09977,-2.84688 3.38729,-0.38293 7.37282,-0.28336 11.77044,-0.16051 4.39762,0.12284 9.21051,0.23456 14.33166,-0.12202 5.12115,-0.35659 10.27171,-1.47349 15.16022,-2.54099 4.88852,-1.06749 9.50395,-2.05149 13.43823,-2.27114 3.9343,-0.21967 7.17754,0.32322 9.39823,2.04598 2.22069,1.72276 3.41425,4.59936 3.41004,8.99986 z"
id="path4698"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sssssssssssssssss" /><path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#394655;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 411.91406,568.54883 c -3.75011,-0.0271 -8.08701,0.53975 -12.76172,1.28711 -5.34251,0.85413 -11.10706,1.92059 -17.00976,2.32617 -5.9027,0.40562 -11.41103,0.38326 -16.44727,0.41406 -5.03624,0.0309 -9.6045,0.1607 -13.50781,0.85938 -3.9033,0.69867 -7.13503,1.96743 -9.4082,3.96875 -2.27316,2.00131 -3.58535,4.71676 -3.65235,8.17578 -0.067,3.45901 1.21821,6.3073 3.54297,8.58008 2.32476,2.27278 5.68789,3.9795 9.76172,5.25 4.07385,1.27051 8.85237,2.11894 14.05664,2.59765 5.20427,0.47871 10.83381,0.56134 16.70313,0.22266 5.86931,-0.33868 11.47146,-0.78653 16.60547,-1.34961 5.13399,-0.56309 9.79334,-1.22365 13.70703,-2.34375 1.48913,-0.4262 2.86677,-0.9287 4.12695,-1.51953 2.54507,-1.19325 2.05015,-6.17249 -0.0996,-4.54102 -1.99172,1.51153 -4.55969,2.50355 -7.57031,3.20703 -3.66893,0.85731 -7.96668,1.34146 -12.5586,1.76758 -4.59191,0.42612 -9.47527,0.75991 -14.3789,1.05664 -4.90363,0.29673 -9.56506,0.33523 -13.85156,0.084 -4.28652,-0.25124 -8.19851,-0.76855 -11.53516,-1.64649 -3.33664,-0.87795 -6.09539,-2.12996 -8.03711,-3.9375 -1.94173,-1.80756 -3.06587,-4.17751 -3.13086,-7.22265 -0.065,-3.04513 0.96102,-5.2776 2.81445,-6.81446 1.85342,-1.53686 4.53117,-2.36997 7.78907,-2.73828 3.2579,-0.36831 7.09262,-0.27244 11.32226,-0.1543 4.22963,0.11816 8.85767,0.22578 13.7832,-0.11718 4.92553,-0.34297 9.88026,-1.41664 14.58204,-2.44336 4.70178,-1.02671 9.13982,-1.97234 12.92382,-2.1836 0.473,-0.0264 0.93707,-0.0422 1.38868,-0.0449 1.16046,-0.007 2.25007,0.0442 3.25,0.23633 1.15313,0.22156 2.31543,-2.86146 -0.83789,-2.92773 -0.51177,-0.0108 -1.03459,-0.045 -1.57032,-0.0488 z"
id="path4700"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ssscsscssssssssssssssssssssccsss" /></g></g><g
id="layer4"
inkscape:label="palette"
style="display:none"
transform="translate(-159.49345,-229.70978)"><rect
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#394655;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:9.21053;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="rect4162"
width="40.789474"
height="40.789474"
x="779.60529"
y="21.967466" /><rect
y="21.967466"
x="824.60529"
height="40.789474"
width="40.789474"
id="rect4170"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:9.21053;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /><rect
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#bce8ff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:9.21053;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="rect4208"
width="40.789474"
height="40.789474"
x="779.60529"
y="86.967468" /><rect
y="-127.75694"
x="824.60529"
height="40.789474"
width="40.789474"
id="rect4223"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#abccd9;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:9.21053;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
transform="scale(1,-1)" /><rect
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#c3b0cb;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:9.21053;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="rect4227"
width="40.789474"
height="40.789474"
x="779.60529"
y="131.96747" /><rect
y="131.96747"
x="824.60529"
height="40.789474"
width="40.789474"
id="rect4231"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#e1d0cb;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:9.21053;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /><rect
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#f5c3d2;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:9.21053;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="rect4233"
width="40.789474"
height="40.789474"
x="869.60529"
y="131.96747" /><rect
y="176.96747"
x="779.60529"
height="40.789474"
width="40.789474"
id="rect4248"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#cec4ad;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:9.21053;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /><rect
transform="scale(1,-1)"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#96d6ff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:9.21053;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="rect4263"
width="40.789474"
height="40.789474"
x="869.60529"
y="-127.75694" /><rect
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#f2f2ce;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:9.21053;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="rect4267"
width="40.789474"
height="40.789474"
x="824.60529"
y="176.96747" /><rect
y="-327.75693"
x="779.60529"
height="40.789474"
width="40.789474"
id="rect4280"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#24b8eb;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:9.21053;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
transform="scale(1,-1)" /><rect
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#8aa9ff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:9.21053;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="rect4284"
width="40.789474"
height="40.789474"
x="824.60529"
y="286.96747" /><rect
y="331.96747"
x="779.60529"
height="40.789474"
width="40.789474"
id="rect4297"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#d4edf1;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:9.21053;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /><rect
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#394d54;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:9.21053;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="rect4301"
width="40.789474"
height="40.789474"
x="779.60529"
y="241.96747" /><rect
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#d6e2ff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:9.21053;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="rect4303"
width="40.789474"
height="40.789474"
x="824.60529"
y="331.96747" /></g></g></g></svg>

Before

Width:  |  Height:  |  Size: 72 KiB

View File

@@ -1,32 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="39.31 0 433.4 512.01">
<defs>
<linearGradient id="linearGradient22708">
<stop stop-color="#21facf" offset="0"/>
<stop stop-color="#0970ef" offset="1"/>
</linearGradient>
<linearGradient id="linearGradient6949" x1="68.454" x2="198.59" y1="246.73" y2="96.35" gradientTransform="translate(-5.754,-56.594)" gradientUnits="userSpaceOnUse">
<stop stop-color="#72004e" offset="0"/>
<stop stop-color="#0015b1" offset="1"/>
</linearGradient>
<linearGradient id="linearGradient22718" x1="56.735" x2="155.2" y1="246.96" y2="58.575" gradientUnits="userSpaceOnUse">
<stop stop-color="#4f00da" offset="0"/>
<stop stop-color="#e5311b" offset="1"/>
</linearGradient>
<linearGradient id="linearGradient23463" x1="68.454" x2="198.59" y1="246.73" y2="96.35" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient22708"/>
<linearGradient id="linearGradient903" x1="54.478" x2="192.1" y1="247.56" y2="9.8095" gradientTransform="matrix(.87923 0 0 .87923 -9.551 48.787)" gradientUnits="userSpaceOnUse">
<stop stop-color="#dc180d" offset="0"/>
<stop stop-color="#f96e20" offset=".5"/>
<stop stop-color="#f4ce41" offset="1"/>
</linearGradient>
<linearGradient id="linearGradient918" x1="39.468" x2="154.99" y1="204.22" y2="124.47" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient22708"/>
</defs>
<g transform="matrix(2.473 0 0 2.473 -4.8978 -4.8812)">
<path transform="translate(-5.5496,-57.412)" d="m148.16 59.393c-7.7098 9.3985-19.951 42.888-20.696 49.204-0.16994 4.6737 1.3731 14.231 0.67182 15.805-0.71909 1.6134-5.117-9.4461-7.2151-6.3266-12.219 18.168-10.7 17.731-15.582 31.378-1.8357 5.1315-0.42447 21.99-1.5666 23.773-1.273 1.9866-3.962-12.31-6.8063-9.236-11.603 12.54-16.279 20.379-22.336 30.607-3.3589 5.6725-2.1817 23.33-3.506 24.674-1.3023 1.3215-3.8566-18.326-7.6437-14.309-8.5193 9.038-14.054 13.441-18.946 19.252-5.1981 6.1739-0.78251 17.584-5.0672 35.383l0.1448 0.22073c77.447-50.308 101.52-127.16 107.61-181.19-0.68051 63.93-29.41 142.78-105.33 184.65l0.1127 0.17141c20.241-2.181 22.307 10.458 44.562-4.2837 55.792-48.277 81.856-124.29 61.593-199.78z" display="none" fill="url(#linearGradient903)"/>
<path transform="translate(-5.5498,-57.412)" d="m148.16 59.393c-7.7098 9.3985-19.951 42.888-20.696 49.204-0.16994 4.6737 1.3731 14.231 0.67182 15.805-0.71909 1.6134-5.117-9.4461-7.2151-6.3266-12.219 18.168-10.7 17.731-15.582 31.378-1.8357 5.1315-0.42447 21.99-1.5666 23.773-1.273 1.9866-3.962-12.31-6.8063-9.236-11.603 12.54-16.279 20.379-22.336 30.607-3.3589 5.6725-2.1817 23.33-3.506 24.674-1.3023 1.3215-3.8566-18.326-7.6437-14.309-8.5193 9.038-14.054 13.441-18.946 19.252-5.1981 6.1739-0.78251 17.584-5.0672 35.383l0.1448 0.22073c77.447-50.308 101.52-127.16 107.61-181.19-0.68051 63.93-29.41 142.78-105.33 184.65l0.1127 0.17141c20.241-2.181 22.307 10.458 44.562-4.2837 55.792-48.277 81.856-124.29 61.593-199.78z" fill="url(#linearGradient918)"/>
<g transform="translate(0 2.0218e-5)">
<path transform="translate(-5.7543,-56.594)" d="m111.25 81.024c-48.394-1.5e-5 -87.625 39.231-87.625 87.625 0.0174 20.443 7.1818 40.236 20.253 55.954 0.2523-0.42224 0.53629-0.82423 0.85783-1.2061 4.892-5.8104 10.427-10.214 18.946-19.252 3.7871-4.0176 6.3412 15.63 7.6435 14.309 1.3243-1.3439 0.1473-19.001 3.5062-24.674 6.0563-10.228 10.733-18.067 22.336-30.607 2.8443-3.0741 5.5333 11.223 6.8063 9.2361 1.1421-1.7823-0.26941-18.641 1.5663-23.773 4.8819-13.647 3.3631-13.21 15.582-31.378 2.098-3.1195 6.496 7.9402 7.2151 6.3268 0.70126-1.5734-0.84173-11.131-0.67179-15.805 0.37161-3.1498 3.6036-13.059 7.7055-23.367-7.8432-2.2472-15.962-3.3881-24.12-3.3895zm43.142 11.356c5.5662 61.595-18.426 120.7-62.796 161.65 6.446 1.4857 13.04 2.2367 19.655 2.2386 48.394 1e-5 87.625-39.231 87.625-87.625-3.1e-4 -31.581-16.995-60.719-44.484-76.268z" display="none" fill="url(#linearGradient22718)"/>
<path transform="translate(-5.754,-56.594)" d="m111.25 81.024c-48.394-1.5e-5 -87.625 39.231-87.625 87.625 0.0174 20.443 7.1818 40.236 20.253 55.954 0.2523-0.42224 0.53629-0.82423 0.85783-1.2061 4.892-5.8104 10.427-10.214 18.946-19.252 3.7871-4.0176 6.3412 15.63 7.6435 14.309 1.3243-1.3439 0.1473-19.001 3.5062-24.674 6.0563-10.228 10.733-18.067 22.336-30.607 2.8443-3.0741 5.5333 11.223 6.8063 9.2361 1.1421-1.7823-0.26941-18.641 1.5663-23.773 4.8819-13.647 3.3631-13.21 15.582-31.378 2.098-3.1195 6.496 7.9402 7.2151 6.3268 0.70126-1.5734-0.84173-11.131-0.67179-15.805 0.37161-3.1498 3.6036-13.059 7.7055-23.367-7.8432-2.2472-15.962-3.3881-24.12-3.3895zm43.142 11.356c5.5662 61.595-18.426 120.7-62.796 161.65 6.446 1.4857 13.04 2.2367 19.655 2.2386 48.394 1e-5 87.625-39.231 87.625-87.625-3.1e-4 -31.581-16.995-60.719-44.484-76.268z" display="none" fill="url(#linearGradient23463)"/>
<path d="m105.5 24.43c-48.394-1.5e-5 -87.625 39.231-87.625 87.625 0.0174 20.443 7.1818 40.236 20.253 55.954 0.2523-0.42224 0.53629-0.82423 0.85783-1.2061 4.892-5.8104 10.427-10.214 18.946-19.252 3.7871-4.0176 6.3412 15.63 7.6435 14.309 1.3243-1.3439 0.1473-19.001 3.5062-24.674 6.0563-10.228 10.733-18.067 22.336-30.607 2.8443-3.0741 5.5333 11.223 6.8063 9.2361 1.1421-1.7823-0.26941-18.641 1.5663-23.773 4.8819-13.647 3.3631-13.21 15.582-31.378 2.098-3.1195 6.496 7.9402 7.2151 6.3268 0.70126-1.5734-0.84173-11.131-0.67179-15.805 0.37161-3.1498 3.6036-13.059 7.7055-23.367-7.8432-2.2472-15.962-3.3881-24.12-3.3895zm43.142 11.356c5.5662 61.595-18.426 120.7-62.796 161.65 6.446 1.4857 13.04 2.2367 19.655 2.2386 48.394 1e-5 87.625-39.231 87.625-87.625-3.1e-4 -31.581-16.995-60.719-44.484-76.268z" fill="url(#linearGradient6949)"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 5.6 KiB

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 100 22.09">
<path fill-rule="evenodd" clip-rule="evenodd" d="M91.4149 18.1044V12.2562H96.9392V8.69613H91.4149V5.93341L90.1667 4.01636H92.8082H100V0.456299H87.6289V0.471142V4.01636V18.1044V19.7067L88.9035 21.6644H100V18.1044H91.4149ZM83.4455 21.6508H83.8794V0.471191H80.4177V15.7242L72.6247 0.471191H71.489H68.8387H68.0273V21.6508H71.489V5.65867L79.6594 21.6508H80.4177H83.4455ZM63.5224 18.7948C64.4444 17.1971 64.544 15.5118 64.544 14.8618V7.21299C64.5051 3.63618 62.7241 1.86947 61.2373 1.01732C59.6341 0.0989541 57.9447 0 57.2933 0H56.0908C52.5047 0.0384399 50.7329 1.81467 49.8784 3.29784C48.958 4.89632 48.8584 6.58083 48.8584 7.23126L48.8587 14.8804C48.8973 18.4572 50.6783 20.2236 52.1651 21.0761C53.7683 21.9941 55.4573 22.093 56.1091 22.093H57.2967H57.3062C60.8942 22.0534 62.6672 20.2776 63.5224 18.7948ZM61.1099 14.8617C61.1099 16.2661 60.6111 18.6265 57.2773 18.6676H56.1095C54.6998 18.6676 52.3292 18.171 52.293 14.8617V7.23122C52.293 5.82531 52.7917 3.46069 56.1095 3.42529H57.2937C58.703 3.42529 61.0744 3.92197 61.1099 7.23122V14.8617ZM44.0577 21.6861H48.2971L42.3396 12.5366L40.2197 15.7922L44.0577 21.6861ZM42.3396 9.62064L48.2971 0.471191H44.0577L40.2197 6.36505L42.3396 9.62064ZM41.3893 11.0787L34.482 0.471191H30.2422L37.1495 11.0787L30.2422 21.6862H34.482L41.3893 11.0787ZM28.6586 18.7948C29.5806 17.1971 29.6798 15.5118 29.6798 14.8618V7.21299C29.6416 3.63618 27.8602 1.86947 26.3731 1.01732C24.7703 0.0989541 23.0809 0 22.429 0H21.227C17.6405 0.0384399 15.869 1.81467 15.0146 3.29784C14.0937 4.89632 13.9941 6.58083 13.9941 7.23126V14.8804C14.0331 18.4572 15.8141 20.2236 17.3016 21.0761C18.904 21.9941 20.5931 22.093 21.2453 22.093H22.4329H22.442C26.0308 22.0534 27.8034 20.2776 28.6586 18.7948ZM26.2443 14.8617C26.2443 16.2661 25.7462 18.6265 22.4121 18.6676H21.2443C19.8346 18.6676 17.464 18.171 17.4277 14.8617V7.23122C17.4277 5.82531 17.9261 3.46069 21.2443 3.42529H22.4281C23.8382 3.42529 26.2092 3.92197 26.2443 7.23122V14.8617ZM1.25362 21.6644H12.3717V18.1044H3.78565V0.471133H0V18.1044V19.7398L1.25362 21.6644Z" fill="#69C350"/>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128">
<rect fill="#69C350" width="128" height="128"/>
<path xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" d="M91.4149 18.1044V12.2562H96.9392V8.69613H91.4149V5.93341L90.1667 4.01636H92.8082H100V0.456299H87.6289V0.471142V4.01636V18.1044V19.7067L88.9035 21.6644H100V18.1044H91.4149ZM83.4455 21.6508H83.8794V0.471191H80.4177V15.7242L72.6247 0.471191H71.489H68.8387H68.0273V21.6508H71.489V5.65867L79.6594 21.6508H80.4177H83.4455ZM63.5224 18.7948C64.4444 17.1971 64.544 15.5118 64.544 14.8618V7.21299C64.5051 3.63618 62.7241 1.86947 61.2373 1.01732C59.6341 0.0989541 57.9447 0 57.2933 0H56.0908C52.5047 0.0384399 50.7329 1.81467 49.8784 3.29784C48.958 4.89632 48.8584 6.58083 48.8584 7.23126L48.8587 14.8804C48.8973 18.4572 50.6783 20.2236 52.1651 21.0761C53.7683 21.9941 55.4573 22.093 56.1091 22.093H57.2967H57.3062C60.8942 22.0534 62.6672 20.2776 63.5224 18.7948ZM61.1099 14.8617C61.1099 16.2661 60.6111 18.6265 57.2773 18.6676H56.1095C54.6998 18.6676 52.3292 18.171 52.293 14.8617V7.23122C52.293 5.82531 52.7917 3.46069 56.1095 3.42529H57.2937C58.703 3.42529 61.0744 3.92197 61.1099 7.23122V14.8617ZM44.0577 21.6861H48.2971L42.3396 12.5366L40.2197 15.7922L44.0577 21.6861ZM42.3396 9.62064L48.2971 0.471191H44.0577L40.2197 6.36505L42.3396 9.62064ZM41.3893 11.0787L34.482 0.471191H30.2422L37.1495 11.0787L30.2422 21.6862H34.482L41.3893 11.0787ZM28.6586 18.7948C29.5806 17.1971 29.6798 15.5118 29.6798 14.8618V7.21299C29.6416 3.63618 27.8602 1.86947 26.3731 1.01732C24.7703 0.0989541 23.0809 0 22.429 0H21.227C17.6405 0.0384399 15.869 1.81467 15.0146 3.29784C14.0937 4.89632 13.9941 6.58083 13.9941 7.23126V14.8804C14.0331 18.4572 15.8141 20.2236 17.3016 21.0761C18.904 21.9941 20.5931 22.093 21.2453 22.093H22.4329H22.442C26.0308 22.0534 27.8034 20.2776 28.6586 18.7948ZM26.2443 14.8617C26.2443 16.2661 25.7462 18.6265 22.4121 18.6676H21.2443C19.8346 18.6676 17.464 18.171 17.4277 14.8617V7.23122C17.4277 5.82531 17.9261 3.46069 21.2443 3.42529H22.4281C23.8382 3.42529 26.2092 3.92197 26.2443 7.23122V14.8617ZM1.25362 21.6644H12.3717V18.1044H3.78565V0.471133H0V18.1044V19.7398L1.25362 21.6644Z" fill="#ffffff" style="transform: translate(14px, 53px);"/> </svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -1 +0,0 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 87.5 100"><defs><style>.cls-1{fill:#1697f6;}.cls-2{fill:#7bc6ff;}.cls-3{fill:#1867c0;}.cls-4{fill:#aeddff;}</style></defs><title>Artboard 46</title><polyline class="cls-1" points="43.75 0 23.31 0 43.75 48.32"/><polygon class="cls-2" points="43.75 62.5 43.75 100 0 14.58 22.92 14.58 43.75 62.5"/><polyline class="cls-3" points="43.75 0 64.19 0 43.75 48.32"/><polygon class="cls-4" points="64.58 14.58 87.5 14.58 43.75 100 43.75 62.5 64.58 14.58"/></svg>

Before

Width:  |  Height:  |  Size: 539 B

View File

@@ -1 +0,0 @@
<svg xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" version="1.1" x="0px" y="0px" enable-background="new 0 0 419.528 419.528" xml:space="preserve" id="svg52" sodipodi:docname="pangolin_orange.svg" inkscape:version="1.2.2 (b0a8486541, 2022-12-01)" viewBox="18.18 30 360.87 338.3"><defs id="defs56"/><sodipodi:namedview id="namedview54" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:showpageshadow="2" inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" showgrid="false" inkscape:zoom="1.9583914" inkscape:cx="127.40048" inkscape:cy="262.71561" inkscape:window-width="1436" inkscape:window-height="1236" inkscape:window-x="2208" inkscape:window-y="511" inkscape:window-maximized="0" inkscape:current-layer="svg52"/><path d="m 62.232921,184.91974 c 0,2.431 -1.97,4.402 -4.399,4.402 -2.429,0 -4.399,-1.972 -4.399,-4.402 0,-2.429 1.97,-4.399 4.399,-4.399 2.429,-10e-4 4.399,1.97 4.399,4.399 z m 58.993999,-4.821 c -25.943999,-2.826 -38.978999,7.453 -71.181999,31.357 -27.572,20.467 -32.767,4.381 -31.748,-2.614 1.499,-10.282 25.222,-58.573 48.079,-88.461 28.273,7.34 49.869999,30.727 54.850999,59.718 z m -55.915999,4.821 c 0,-4.131 -3.349,-7.478 -7.478,-7.478 -4.129,0 -7.478,3.347 -7.478,7.478 0,4.131 3.349,7.481 7.478,7.481 4.13,0 7.478,-3.35 7.478,-7.481 z m -15.032,48.424 -0.234,14.041 20.413,22.687 -9.818,7.353 33.306,27.492 -11.759,8.124 42.631999,19.939 -10.825,9.747 48.291,8.078 -7.526,10.307 48.758,-4.531 -3.997,11.725 53.916,-18.153 -2.76,13.357 48.077,-34.345 1.479,13.562 34.087,-48.576 7.478,14.206 15.187,-58.89 10.391,8.533 -2.14,-57.884 13.814,5.13 -21.082,-51.204 13.404,0.048 -33.696,-42.131 15.312,-1.366 -47.026,-32.831002 14.255,-8.399 -54.817,-14.682 9.257,-11.695 -49.625,0.352 0.6,-13.337 -38.537,14.084 -1.597,-12.689 -29.984,21.429 -6.446,-10.852 -22.59,26.504 -7.021,-9.572 -18.923,30.294 -9.595999,-8.744 -16.754,30.138002 c 31.509999,10.197 54.979999,37.951 59.126999,71.547 0.404,0.087 -22.37,31.257 10.955,57.85 -0.576,-2.985 -6.113,-53.902 47.496,-57.61 26.668,-1.844 48.4,21.666 48.4,48.399 0,8.184 -2.05,15.883 -5.636,22.64 -15.927,29.611 -64.858,30.755 -80.429,30.596 -45.154,-0.459 -104.051999,-51.521 -104.051999,-51.521 z" id="path46" style="fill:#f97315;fill-opacity:1"/></svg>

Before

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" version="1.1" viewBox="20.41 20.41 108.77 108.77"><g transform="matrix(.9375 0 0 .9375 20.413 20.413)"><path d="M45.52 48.98c-.74 0-1.28.13-1.75.27v17.43c.4.13.94.27 1.61.27 3.63 0 5.18-3.03 5.18-8.95s-1.35-9.02-5.05-9.02z" fill="#3b1c4a"/><path d="M114.72 36.13c.74-.07 1.28-.61 1.28-1.35V1.35c0-.74-.61-1.35-1.35-1.35H75.99v5.38c0 1.15-.94 2.09-2.09 2.09s-2.09-.94-2.09-2.09V0H1.35C.61 0 0 .61 0 1.35v33.44c0 .74.54 1.28 1.28 1.35 11.51.67 20.66 10.23 20.66 21.94s-9.15 21.2-20.66 21.8c-.74.07-1.28.61-1.28 1.35v33.44c0 .74.61 1.35 1.35 1.35h70.48v-5.38c0-1.19.9-2.09 2.09-2.09s2.09.94 2.09 2.09v5.38h38.66c.74 0 1.35-.61 1.35-1.35V81.23c0-.74-.54-1.28-1.28-1.35-11.51-.67-20.66-10.16-20.66-21.87s9.15-21.26 20.66-21.87zM47.87 72.87c-1.82 0-3.36-.2-4.1-.4v11.64H33.54V45.22C36.3 43.94 40 43 45.58 43c8.95 0 15.07 4.78 15.07 14.94 0 9.15-5.32 14.94-12.78 14.94zm28.12 25.3c0 1.15-.94 2.09-2.09 2.09s-2.09-.94-2.09-2.09V87.4c0-1.15.94-2.09 2.09-2.09s2.09.97 2.09 2.09zm0-23.28c0 1.11-.97 2.09-2.09 2.09-1.12 0-2.09-.97-2.09-2.09V64.12c0-1.19.9-2.09 2.09-2.09s2.09.94 2.09 2.09zm0-23.15c0 1.15-.94 2.09-2.09 2.09s-2.09-.94-2.09-2.09V40.97c0-1.15.94-2.09 2.09-2.09s2.09.97 2.09 2.09zm0-23.28c0 1.11-.97 2.09-2.09 2.09-1.12 0-2.09-.97-2.09-2.09V17.69c0-1.19.9-2.09 2.09-2.09s2.09.94 2.09 2.09z" fill="#3b1c4a"/></g></svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -1,17 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" style="enable-background:new 0 0 1920 1080;" xml:space="preserve" viewBox="762.04 306.21 401.81 459.59">
<style type="text/css">
.st0{fill:#FEFEFE;}
.st1{fill:#6DB653;}
</style>
<g>
<path class="st1" d="M962.86,420.95c52.13,0,104.27,0,156.4,0c10.34,0,14.29,3.85,13.74,14.34c-1.15,21.76-2.65,43.5-3.95,65.25 c-2.45,41.02-4.84,82.04-7.29,123.06c-1.65,27.56-3.17,55.14-5.18,82.67c-0.66,9.09-0.13,18.37-2.71,27.25 c-4.62,15.89-15.62,25.12-31.1,30.06c-7.01,2.24-14.01,2.12-21.1,2.12c-69.12,0.02-138.25,0.31-207.37-0.18 c-19.52-0.14-38.4-11.46-43.69-32.65c-2.58-10.33-2.1-21.14-2.74-31.77c-2.07-34.04-4.33-68.06-6.44-102.09 c-1.25-20.08-2.28-40.18-3.54-60.27c-2.11-33.7-4.33-67.38-6.48-101.08c-0.3-4.66-0.56-9.23,3.16-13.08c2.82-2.91,6-3.7,9.87-3.69 C857.26,420.98,910.06,420.95,962.86,420.95z"/>
<path class="st1" d="M962.25,392.98c-61.96,0-123.92-0.01-185.88,0.02c-3.37,0-6.8,0.07-9.6-1.97c-2.88-2.1-4.81-4.8-4.73-8.82 c0.2-8.82-0.02-17.65,0.04-26.48c0.09-11.44,9.18-20.45,20.72-20.46c31.81-0.04,63.63-0.05,95.44,0.05 c3.55,0.01,5.82-0.65,7.19-4.44c1.56-4.32,4.04-8.32,6.16-12.44c4.09-7.94,10.79-12.08,19.54-12.12 c34.14-0.16,68.29-0.13,102.43-0.02c8.63,0.03,15.23,4.16,19.45,11.67c2.43,4.32,4.76,8.77,6.42,13.41 c1.24,3.47,3.27,3.94,6.41,3.93c30.98-0.08,61.96-0.05,92.94-0.05c12.57,0,20.61,5.4,24.67,16.93c0.68,1.94,0.29,4.28,0.3,6.44 c0.03,6.66,0.01,13.32,0.01,19.99c0,9.54-4.85,14.36-14.63,14.36C1086.83,392.99,1024.54,392.98,962.25,392.98z"/>
<path class="st0" d="M1043.97,491.95c-1.3,4.31-3.67,7.25-5.52,10.43c-6.34,10.87-12.72,21.72-19.06,32.59 c-1.48,2.54-3.04,4.4-6.56,4.2c-15.92-0.92-31.86-1.58-47.79-2.37c-0.23-0.01-0.45-0.39-0.95-0.85c3.67-3.41,8.24-5.36,12.51-7.6 c4.05-2.13,4.89-4.04,2.95-8.5c-7.91-18.24-17.55-35.23-32.58-48.7c1.6-1.76,3.36-1.07,4.91-1.07c15.8-0.03,31.61,0.03,47.41,0.06 c6.05,0.01,10.46,2.92,13.53,7.91c4.08,6.63,8.13,13.28,11.89,20.09c1.51,2.74,2.6,3.09,5.33,1.4 C1034.32,496.89,1038.48,493.93,1043.97,491.95z"/>
<path class="st0" d="M875.62,638.11c-8.67-16.31-16.96-31.76-25.1-47.28c-2.8-5.35-1.77-10.7,1.14-15.7 c3.76-6.45,7.51-12.91,11.63-19.14c1.81-2.73,1.19-3.99-1.31-5.44c-4.36-2.53-8.6-5.25-12.7-7.78c11.2,0,22.22-0.06,33.24,0.02 c5.83,0.04,11.65,0.44,17.48,0.44c2.31,0,3.81,0.73,4.77,2.77c7,14.8,14.01,29.59,20.98,44.39c0.11,0.22-0.14,0.61-0.37,1.54 c-4.72-2.87-9.54-5.3-13.77-8.52c-3.14-2.39-4.76-1.51-6.87,1.04c-12.62,15.24-22.96,31.71-27.95,51.12 C876.63,636.18,876.26,636.73,875.62,638.11z"/>
<path class="st0" d="M997.95,687.53c-4.01-3.79-5.57-7.62-7.73-11c-6.86-10.76-13.55-21.63-20.36-32.42 c-1.21-1.92-2.02-3.53-0.62-5.89c7.95-13.38,15.75-26.85,23.6-40.28c0.5-0.85,1.02-1.71,3.26-1.68c0,5.34-0.01,10.73,0,16.11 c0.01,2.02-0.16,4.13,2.77,4.36c17.63,1.37,35.19,1.77,52.47-2.99c0.64-0.18,1.27-0.41,1.92-0.55c2.48-0.5,5.28-3.59,7.14-1.47 c1.38,1.57-1.6,4.28-2.7,6.43c-6.48,12.66-13.09,25.26-19.63,37.9c-3.17,6.13-8.17,9.45-15.05,9.85 c-7.13,0.41-14.27,0.96-21.41,1.04c-3.55,0.04-4.77,1.33-4.52,4.72C997.47,676.54,997.64,681.43,997.95,687.53z"/>
<path class="st0" d="M928.28,468.79c5.76-0.28,10.77,1.86,15.26,5.15c5.81,4.25,10.58,9.6,15.26,15.04 c1.54,1.8,1.66,3.17,0.36,5.28c-9.99,16.24-19.92,32.52-29.65,48.91c-2.01,3.39-3.45,4.42-7.25,2.06 c-11.41-7.09-23.05-13.8-34.71-20.47c-3.44-1.97-4.2-3.57-1.79-7.24c8.46-12.9,16.66-25.98,24.67-39.17 C914.61,471.49,920.49,468.55,928.28,468.79z"/>
<path class="st0" d="M1074.28,583.98c-0.68,11.35-6.36,18.12-14.99,22.52c-6.37,3.25-13.48,4.6-20.34,6.54 c-1.8,0.51-3.04-0.08-4.06-1.86c-9.83-17.28-20.48-34.07-31.18-50.82c-1.66-2.61-0.71-3.79,1.47-5.14 c12.4-7.67,24.8-15.35,37.1-23.19c2.33-1.49,3.4-0.39,4.38,1.27c8.64,14.69,17.29,29.37,25.75,44.17 C1073.69,579.71,1074.51,582.38,1074.28,583.98z"/>
<path class="st0" d="M953.01,630.07c-0.55,11.62-1.27,23.23-1.57,34.85c-0.1,3.74-1.61,4.48-4.85,4.25 c-16.41-1.17-32.83-2.14-49.24-3.37c-8.47-0.64-16.49-9.9-17.16-19.99c-0.67-10.23,3.25-19.52,6.78-28.84 c0.77-2.03,2.57-1.65,4.26-1.48c18.2,1.86,36.47,2.33,54.73,3.06c7.28,0.29,7.28,0.16,7.16,7.52c-0.02,1.33,0,2.66,0,3.99 C953.09,630.07,953.05,630.07,953.01,630.07z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -1,16 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" version="1.1" id="svg1" viewBox="4.5 0 58.74 67.73">
<defs id="defs1">
<linearGradient id="linearGradient4">
<stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop4"/>
<stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop5"/>
</linearGradient>
</defs>
<g id="layer2">
<rect style="fill:#0082c7;fill-opacity:1;stroke-width:78.4285" id="rect6" width="7.2357788" height="16.960531" x="37.661629" y="50.772774" rx="2.9794366"/>
<rect style="fill:#0082c7;fill-opacity:1;stroke-width:78.4285" id="rect6-6" width="7.2357788" height="16.960531" x="22.835808" y="50.772804" rx="2.9794366"/>
<ellipse style="fill:#0eabff;fill-opacity:1;stroke-width:63.9157" id="path6" cx="33.866619" cy="29.256916" rx="29.36875" ry="29.256916"/>
<ellipse style="fill:#0081c7;fill-opacity:1;stroke-width:96.3698" id="path7-9" cx="33.866619" cy="29.256916" rx="27.95863" ry="19.221935"/>
<ellipse style="fill:#ffffff;fill-opacity:1;stroke-width:82.2933" id="path7" cx="33.866619" cy="29.256916" rx="26.034615" ry="15.05247"/>
<ellipse style="fill:#004970;fill-opacity:1;stroke-width:124.026" id="path8" cx="33.866619" cy="29.256916" rx="4.8238525" ry="4.8054838"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -1,32 +0,0 @@
<svg xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" version="1.1" id="svg1" inkscape:version="1.3 (0e150ed6c4, 2023-07-21)" sodipodi:docname="series-troxide.svg" inkscape:export-filename="series-troxide.png" inkscape:export-xdpi="179.29411" inkscape:export-ydpi="179.29411" viewBox="9.47 5.66 83.47 87.95">
<sodipodi:namedview id="namedview1" pagecolor="#ffffff" bordercolor="#000000" borderopacity="0.25" inkscape:showpageshadow="2" inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" inkscape:document-units="mm" inkscape:zoom="1.0721378" inkscape:cx="200.06757" inkscape:cy="226.18362" inkscape:window-width="1920" inkscape:window-height="1055" inkscape:window-x="0" inkscape:window-y="25" inkscape:window-maximized="1" inkscape:current-layer="layer2"/>
<defs id="defs1">
<inkscape:path-effect effect="skeletal" id="path-effect11" is_visible="true" lpeversion="1" pattern="M 0,4.9921382 C 0,2.2364779 2.2364779,0 4.9921382,0 c 2.7556604,0 4.9921383,2.2364779 4.9921383,4.9921382 0,2.7556604 -2.2364779,4.9921383 -4.9921383,4.9921383 C 2.2364779,9.9842765 0,7.7477986 0,4.9921382 Z" copytype="single_stretched" prop_scale="0.1221914" scale_y_rel="false" spacing="0" normal_offset="0" tang_offset="0" prop_units="false" vertical_pattern="false" hide_knot="false" fuse_tolerance="0"/>
<inkscape:path-effect effect="skeletal" id="path-effect11-7" is_visible="true" lpeversion="1" pattern="M 0,4.9921382 C 0,2.2364779 2.2364779,0 4.9921382,0 c 2.7556604,0 4.9921383,2.2364779 4.9921383,4.9921382 0,2.7556604 -2.2364779,4.9921383 -4.9921383,4.9921383 C 2.2364779,9.9842765 0,7.7477986 0,4.9921382 Z" copytype="single_stretched" prop_scale="0.3067289" scale_y_rel="false" spacing="0" normal_offset="0" tang_offset="0" prop_units="false" vertical_pattern="false" hide_knot="false" fuse_tolerance="0"/>
</defs>
<g inkscape:groupmode="layer" id="layer7" inkscape:label="stand" style="display:inline">
<ellipse style="fill:#b3b3b3;fill-opacity:1;stroke:#000000;stroke-width:0.362231" id="path10" cx="53.734413" cy="88.932671" rx="18.540586" ry="4.4936233"/>
</g>
<g inkscape:groupmode="layer" id="layer2" inkscape:label="body">
<ellipse style="fill:#8f6593;fill-opacity:1;stroke:#000000;stroke-width:0.264583" id="path2" cx="53.173447" cy="59.926918" rx="39.631786" ry="31.20598"/>
</g>
<g inkscape:groupmode="layer" id="layer6" inkscape:label="right-antenna" transform="rotate(26.626716,63.663425,91.348082)" style="display:inline">
<rect style="fill:#b3b3b3;stroke:#000000;stroke-width:0.264583" id="rect5" width="2.0064371" height="21.225708" x="27.764742" y="25.941788"/>
<rect style="fill:#b3b3b3;stroke:#000000;stroke-width:0.264583" id="rect6" width="0.87785858" height="11.139125" x="28.320299" y="14.803336"/>
<rect style="fill:#b3b3b3;stroke:#000000;stroke-width:0.264583" id="rect7" width="1.7391598" height="1.0371615" x="27.84543" y="13.598304"/>
</g>
<g inkscape:groupmode="layer" id="g10" inkscape:label="left-antenna" transform="matrix(0.78455439,-0.39703989,0.36681053,0.84921059,-42.959282,47.424815)" style="display:inline">
<rect style="fill:#b3b3b3;stroke:#000000;stroke-width:0.264583" id="rect8" width="2.0064371" height="21.225708" x="88.477699" y="6.2007856"/>
<rect style="fill:#b3b3b3;stroke:#000000;stroke-width:0.264583" id="rect9" width="0.87785858" height="11.139125" x="89.033257" y="-4.9376626"/>
<rect style="fill:#b3b3b3;stroke:#000000;stroke-width:0.264583" id="rect10" width="1.7391598" height="1.0371615" x="88.558388" y="-6.142695"/>
</g>
<g inkscape:label="screen" inkscape:groupmode="layer" id="layer1" style="display:inline">
<ellipse style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.264583" id="path3" cx="38.638641" cy="60.920479" rx="29.03672" ry="22.062567"/>
<ellipse style="fill:#666666;stroke:#000000;stroke-width:0.247975" id="ellipse3" cx="38.034561" cy="60.978752" rx="27.778275" ry="20.257765"/>
<path style="fill:#b3b3b3;fill-opacity:1;stroke:none;stroke-width:0.264583" d="m 34.697799,122.55314 c 0.01833,0.006 0.0316,0.0245 0.04135,0.0555 0,0 0,0 0,0 0.0092,0.0295 0.01472,0.0703 0.0168,0.12182 v 0 0 0 c 0.0042,0.10159 -0.005,0.24651 -0.02457,0.42892 v 0 c -0.03801,0.35347 -0.118996,0.87532 -0.215147,1.50114 v 0 c -0.185128,1.20614 -0.442822,2.88292 -0.559325,4.78641 -0.04494,0.75002 -0.07046,1.54169 -0.05525,2.34859 0.02287,1.21336 0.135161,2.31717 0.339835,3.3493 0,0 0,0 0,0 0.650332,3.24476 2.351371,5.07761 2.173869,5.2629 -0.149012,0.15556 -2.3584,-1.29697 -3.279062,-5.01429 0,0 0,0 0,0 -0.274838,-1.0998 -0.429558,-2.29119 -0.455419,-3.57407 -0.01726,-0.85628 0.02422,-1.68546 0.100139,-2.4653 0.190754,-1.9852 0.603085,-3.67762 0.988428,-4.87091 v 0 c 0.201418,-0.62408 0.395557,-1.10979 0.558632,-1.44128 v 0 c 0.08263,-0.16796 0.156338,-0.2943 0.218718,-0.37713 v 0 0 0 c 0.03135,-0.0416 0.05963,-0.0719 0.0846,-0.0907 0,0 0,0 0,0 0.02622,-0.0197 0.04803,-0.0268 0.06641,-0.0208 z" id="path11" inkscape:path-effect="#path-effect11" inkscape:original-d="m 34.697819,122.55308 c 0,0 -4.11305,12.26932 1.717536,17.85462" sodipodi:nodetypes="cc" transform="matrix(0.97122863,0.08809259,-0.09412623,0.90897134,-6.1653708,-61.757664)"/>
</g>
<g inkscape:groupmode="layer" id="layer3" inkscape:label="knob" style="display:inline">
<ellipse style="fill:#000000;stroke:#000000;stroke-width:0.264583" id="ellipse10" cx="84.35968" cy="58.413628" rx="2.9122553" ry="4.9937477"/>
<ellipse style="fill:#b3b3b3;stroke:#000000;stroke-width:0.22029" id="path4" cx="84.715714" cy="58.418968" rx="2.3879521" ry="4.2217774"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 5.6 KiB

View File

@@ -225,7 +225,6 @@
"budgetbee.png",
"budibase.png",
"buffalo.png",
"buildium.png",
"bunkerweb.png",
"buxfer.png",
"bytestash.png",
@@ -238,7 +237,6 @@
"cal-com.png",
"calckey.png",
"caldera.png",
"calibre-web-automated-book-downloader.png",
"calibre-web.png",
"calibre.png",
"camera-ui.png",
@@ -442,7 +440,6 @@
"domainmod.png",
"domoticz.png",
"donetick.png",
"doplarr.png",
"dopplertask.png",
"double-commander.png",
"double-take-dark.png",
@@ -494,7 +491,6 @@
"emq-light.png",
"emq.png",
"emqx.png",
"emsesp.png",
"emulatorjs.png",
"enbizcard.png",
"enclosed-light.png",
@@ -503,7 +499,6 @@
"endless.png",
"endurain.png",
"enhance.png",
"entergy.png",
"epic-games-light.png",
"epic-games.png",
"epson-iprint.png",
@@ -679,8 +674,6 @@
"godaddy.png",
"gogs.png",
"gollum.png",
"gomft.png",
"gone-man-switch.png",
"gonic.png",
"goodreads.png",
"google-admin.png",
@@ -850,7 +843,6 @@
"idrac.png",
"ihatemoney.png",
"ilo.png",
"image-maid.png",
"immich-frame-light.png",
"immich-frame.png",
"immich-kiosk-light.png",
@@ -934,7 +926,6 @@
"kapowarr.png",
"karakeep-dark.png",
"karakeep.png",
"karaoke-eternal.png",
"kasm-workspaces.png",
"kasm.png",
"kasten-k10.png",
@@ -995,7 +986,6 @@
"lemmy.png",
"lemonldap-ng.png",
"lets-encrypt.png",
"librechat.png",
"libreddit-light.png",
"libreddit.png",
"libremdb.png",
@@ -1044,8 +1034,6 @@
"logto.png",
"loki.png",
"longhorn.png",
"loxone-full.png",
"loxone.png",
"lsio.png",
"lua.png",
"lubelogger.png",
@@ -1078,7 +1066,6 @@
"marginalia.png",
"mariadb.png",
"marktplaats.png",
"marzban.png",
"mastodon.png",
"matomo.png",
"matrix-light.png",
@@ -1285,7 +1272,6 @@
"nodebb.png",
"nodejs-alt.png",
"nodejs.png",
"noisedash.png",
"nomad.png",
"nomie.png",
"nordvpn.png",
@@ -1418,7 +1404,6 @@
"pairdrop.png",
"palemoon.png",
"palo-alto.png",
"pangolin.png",
"paperless-ng.png",
"paperless-ngx.png",
"paperless.png",
@@ -1570,7 +1555,6 @@
"powerpanel.png",
"premium-mobile.png",
"premiumize.png",
"pretix.png",
"prime-video-alt-dark.png",
"prime-video-alt.png",
"prime-video-light.png",
@@ -1648,14 +1632,12 @@
"receipt-wrangler.png",
"recipesage.png",
"recipya.png",
"recyclarr.png",
"reddit.png",
"redict.png",
"redis.png",
"redlib-light.png",
"redlib.png",
"rekor.png",
"release-argus.png",
"remmina.png",
"remotely.png",
"renovate.png",
@@ -1744,7 +1726,6 @@
"sentry-light.png",
"sentry.png",
"seq.png",
"series-troxide.png",
"serpbear.png",
"servarr-light.png",
"servarr.png",
@@ -1847,7 +1828,6 @@
"storm.png",
"stormkit.png",
"strapi.png",
"stream-harvestarr.png",
"streama.png",
"stremio.png",
"stump-alt.png",
@@ -2102,7 +2082,6 @@
"watcharr-light.png",
"watcharr.png",
"watcher.png",
"watchlistarr.png",
"watchtower.png",
"watchyourlan.png",
"watchyourports.png",
@@ -2411,7 +2390,6 @@
"budgetbee-light.svg",
"budgetbee.svg",
"budibase.svg",
"buildium.svg",
"bunkerweb.svg",
"bytestash.svg",
"c.svg",
@@ -2571,7 +2549,6 @@
"dokemon.svg",
"dokuwiki.svg",
"donetick.svg",
"doplarr.svg",
"double-commander.svg",
"double-take-dark.svg",
"double-take.svg",
@@ -2617,7 +2594,6 @@
"emq-light.svg",
"emq.svg",
"emqx.svg",
"emsesp.svg",
"emulatorjs.svg",
"enbizcard.svg",
"enclosed-light.svg",
@@ -2626,7 +2602,6 @@
"endless.svg",
"endurain.svg",
"enhance.svg",
"entergy.svg",
"epic-games-light.svg",
"epic-games.svg",
"erste-george.svg",
@@ -2768,7 +2743,6 @@
"godaddy-alt.svg",
"godaddy.svg",
"gollum.svg",
"gomft.svg",
"gonic.svg",
"goodreads.svg",
"google-admin.svg",
@@ -3049,7 +3023,6 @@
"lemmy-light.svg",
"lemmy.svg",
"lets-encrypt.svg",
"librechat.svg",
"libreddit-light.svg",
"libreddit.svg",
"librenms.svg",
@@ -3090,8 +3063,6 @@
"logto.svg",
"loki.svg",
"longhorn.svg",
"loxone-full.svg",
"loxone.svg",
"lua.svg",
"lunasea.svg",
"lynx-light.svg",
@@ -3289,7 +3260,6 @@
"nodebb.svg",
"nodejs-alt.svg",
"nodejs.svg",
"noisedash.svg",
"nomad.svg",
"nomie.svg",
"nordvpn.svg",
@@ -3396,7 +3366,6 @@
"pagerduty.svg",
"palemoon.svg",
"palo-alto.svg",
"pangolin.svg",
"paperless-ng.svg",
"paperless-ngx.svg",
"paperless.svg",
@@ -3523,7 +3492,6 @@
"powerbi.svg",
"powerdns.svg",
"premiumize.svg",
"pretix.svg",
"prime-video-alt-dark.svg",
"prime-video-alt.svg",
"prime-video-light.svg",
@@ -3586,14 +3554,12 @@
"recalbox.svg",
"receipt-wrangler.svg",
"recipesage.svg",
"recyclarr.svg",
"reddit.svg",
"redict.svg",
"redis.svg",
"redlib-light.svg",
"redlib.svg",
"rekor.svg",
"release-argus.svg",
"remmina.svg",
"renovate.svg",
"reolink.svg",
@@ -3665,7 +3631,6 @@
"sensu.svg",
"sentry-light.svg",
"sentry.svg",
"series-troxide.svg",
"servarr-light.svg",
"servarr.svg",
"serviio-light.svg",
@@ -4257,7 +4222,6 @@
"budgetbee.webp",
"budibase.webp",
"buffalo.webp",
"buildium.webp",
"bunkerweb.webp",
"buxfer.webp",
"bytestash.webp",
@@ -4270,7 +4234,6 @@
"cal-com.webp",
"calckey.webp",
"caldera.webp",
"calibre-web-automated-book-downloader.webp",
"calibre-web.webp",
"calibre.webp",
"camera-ui.webp",
@@ -4474,7 +4437,6 @@
"domainmod.webp",
"domoticz.webp",
"donetick.webp",
"doplarr.webp",
"dopplertask.webp",
"double-commander.webp",
"double-take-dark.webp",
@@ -4526,7 +4488,6 @@
"emq-light.webp",
"emq.webp",
"emqx.webp",
"emsesp.webp",
"emulatorjs.webp",
"enbizcard.webp",
"enclosed-light.webp",
@@ -4535,7 +4496,6 @@
"endless.webp",
"endurain.webp",
"enhance.webp",
"entergy.webp",
"epic-games-light.webp",
"epic-games.webp",
"epson-iprint.webp",
@@ -4711,8 +4671,6 @@
"godaddy.webp",
"gogs.webp",
"gollum.webp",
"gomft.webp",
"gone-man-switch.webp",
"gonic.webp",
"goodreads.webp",
"google-admin.webp",
@@ -4882,7 +4840,6 @@
"idrac.webp",
"ihatemoney.webp",
"ilo.webp",
"image-maid.webp",
"immich-frame-light.webp",
"immich-frame.webp",
"immich-kiosk-light.webp",
@@ -4966,7 +4923,6 @@
"kapowarr.webp",
"karakeep-dark.webp",
"karakeep.webp",
"karaoke-eternal.webp",
"kasm-workspaces.webp",
"kasm.webp",
"kasten-k10.webp",
@@ -5027,7 +4983,6 @@
"lemmy.webp",
"lemonldap-ng.webp",
"lets-encrypt.webp",
"librechat.webp",
"libreddit-light.webp",
"libreddit.webp",
"libremdb.webp",
@@ -5076,8 +5031,6 @@
"logto.webp",
"loki.webp",
"longhorn.webp",
"loxone-full.webp",
"loxone.webp",
"lsio.webp",
"lua.webp",
"lubelogger.webp",
@@ -5110,7 +5063,6 @@
"marginalia.webp",
"mariadb.webp",
"marktplaats.webp",
"marzban.webp",
"mastodon.webp",
"matomo.webp",
"matrix-light.webp",
@@ -5317,7 +5269,6 @@
"nodebb.webp",
"nodejs-alt.webp",
"nodejs.webp",
"noisedash.webp",
"nomad.webp",
"nomie.webp",
"nordvpn.webp",
@@ -5450,7 +5401,6 @@
"pairdrop.webp",
"palemoon.webp",
"palo-alto.webp",
"pangolin.webp",
"paperless-ng.webp",
"paperless-ngx.webp",
"paperless.webp",
@@ -5602,7 +5552,6 @@
"powerpanel.webp",
"premium-mobile.webp",
"premiumize.webp",
"pretix.webp",
"prime-video-alt-dark.webp",
"prime-video-alt.webp",
"prime-video-light.webp",
@@ -5680,14 +5629,12 @@
"receipt-wrangler.webp",
"recipesage.webp",
"recipya.webp",
"recyclarr.webp",
"reddit.webp",
"redict.webp",
"redis.webp",
"redlib-light.webp",
"redlib.webp",
"rekor.webp",
"release-argus.webp",
"remmina.webp",
"remotely.webp",
"renovate.webp",
@@ -5776,7 +5723,6 @@
"sentry-light.webp",
"sentry.webp",
"seq.webp",
"series-troxide.webp",
"serpbear.webp",
"servarr-light.webp",
"servarr.webp",
@@ -5879,7 +5825,6 @@
"storm.webp",
"stormkit.webp",
"strapi.webp",
"stream-harvestarr.webp",
"streama.webp",
"stremio.webp",
"stump-alt.webp",
@@ -6134,7 +6079,6 @@
"watcharr-light.webp",
"watcharr.webp",
"watcher.webp",
"watchlistarr.webp",
"watchtower.webp",
"watchyourlan.webp",
"watchyourports.webp",

View File

@@ -42,6 +42,7 @@
"canvas-confetti": "^1.9.3",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cmdk": "^1.1.1",
"date-fns": "^4.1.0",
"embla-carousel-react": "^8.6.0",
"framer-motion": "^12.7.3",

249
web/pnpm-lock.yaml generated
View File

@@ -101,6 +101,9 @@ importers:
clsx:
specifier: ^2.1.1
version: 2.1.1
cmdk:
specifier: ^1.1.1
version: 1.1.1(@types/react-dom@19.1.2(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
date-fns:
specifier: ^4.1.0
version: 4.1.0
@@ -157,7 +160,7 @@ importers:
version: 3.2.0
tailwindcss-motion:
specifier: ^1.1.0
version: 1.1.0(tailwindcss@4.1.4)
version: 1.1.0(tailwindcss@4.1.3)
tw-animate-css:
specifier: ^1.2.5
version: 1.2.5
@@ -173,13 +176,13 @@ importers:
version: 1.9.4
'@tailwindcss/postcss':
specifier: ^4.1.3
version: 4.1.4
version: 4.1.3
'@types/canvas-confetti':
specifier: ^1.9.0
version: 1.9.0
'@types/node':
specifier: ^22.14.0
version: 22.14.1
version: 22.14.0
'@types/react':
specifier: ^19.1.0
version: 19.1.0
@@ -188,13 +191,13 @@ importers:
version: 19.1.2(@types/react@19.1.0)
tailwindcss:
specifier: ^4.1.3
version: 4.1.4
version: 4.1.3
typescript:
specifier: ^5.8.3
version: 5.8.3
wrangler:
specifier: ^4.12.0
version: 4.12.1
version: 4.12.0
packages:
@@ -272,32 +275,32 @@ packages:
workerd:
optional: true
'@cloudflare/workerd-darwin-64@1.20250417.0':
resolution: {integrity: sha512-4Adfl92aKepjxb8e6af2d+xpD2sBOADgHqvkyXsFmoLb80weMEDDRGJi1p1m5q1M78/oVnGcpdmuRCAathanRg==}
'@cloudflare/workerd-darwin-64@1.20250416.0':
resolution: {integrity: sha512-aZgF8Swp9eVYxJPWOoZbAgAaYjWuYqGmEA+QJ2ecRGDBqm87rT4GEw7/mmLpxrpllny3VfEEhkk9iYCGv8nlFw==}
engines: {node: '>=16'}
cpu: [x64]
os: [darwin]
'@cloudflare/workerd-darwin-arm64@1.20250417.0':
resolution: {integrity: sha512-dSlk18F4i3T1OTzFBxx3pKpXRMP6w2xZ26+oIV32BFWrCi/HxGzUd6gVA0q37oLGqITRt8xU693J4Gl1CwC/Ag==}
'@cloudflare/workerd-darwin-arm64@1.20250416.0':
resolution: {integrity: sha512-FhswG1QYRfaTZ4FAlUkfVWaoM2lrlqumiBTrhbo9czMJdGR/oBXS4SGynuI6zyhApHeBf3/fZpA/SBAe4cXdgg==}
engines: {node: '>=16'}
cpu: [arm64]
os: [darwin]
'@cloudflare/workerd-linux-64@1.20250417.0':
resolution: {integrity: sha512-27MVzOa/lENcqewC2L9EcqstXW843UhjBMcwV1umDfsjwLyZOEv6Gtm/6j5r0L0gASvkRTam3fAmtPk/gt48TA==}
'@cloudflare/workerd-linux-64@1.20250416.0':
resolution: {integrity: sha512-G+nXEAJ/9y+A857XShwxKeRdfxok6UcjiQe6G+wQeCn/Ofkp/EWydacKdyeVU6QIm1oHS78DwJ7AzbCYywf9aw==}
engines: {node: '>=16'}
cpu: [x64]
os: [linux]
'@cloudflare/workerd-linux-arm64@1.20250417.0':
resolution: {integrity: sha512-34qBk0htAXmUneOTQxW6/g6pjNVR91r0vJzz2FID84cAIOYVl4hZLijkjmVl+MMDU6boXUs+yDwhItdg06YvAg==}
'@cloudflare/workerd-linux-arm64@1.20250416.0':
resolution: {integrity: sha512-U6oVW0d9w1fpnDYNrjPJ9SFkDlGJWJWbXHlTBObXl6vccP16WewvuxyHkKqyUhUc8hyBaph7sxeKzKmuCFQ4SA==}
engines: {node: '>=16'}
cpu: [arm64]
os: [linux]
'@cloudflare/workerd-windows-64@1.20250417.0':
resolution: {integrity: sha512-PDwATFioff+geVHfgTzSWsxgwjgotrdXStb0EL0lMyMT5zNmHArAnOx83CbDtud63Uv9rVX1BAfPP4tyD1O+5A==}
'@cloudflare/workerd-windows-64@1.20250416.0':
resolution: {integrity: sha512-YAjjTzL1z9YYeN4sqYfj1dtQXd2Bblj+B+hl4Rz2aOhblpZEZAdhapZlOCRvLLkOJshKJUnRD3mDlytAdgwybQ==}
engines: {node: '>=16'}
cpu: [x64]
os: [win32]
@@ -1362,93 +1365,81 @@ packages:
'@swc/helpers@0.5.15':
resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==}
'@tailwindcss/node@4.1.4':
resolution: {integrity: sha512-MT5118zaiO6x6hNA04OWInuAiP1YISXql8Z+/Y8iisV5nuhM8VXlyhRuqc2PEviPszcXI66W44bCIk500Oolhw==}
'@tailwindcss/node@4.1.3':
resolution: {integrity: sha512-H/6r6IPFJkCfBJZ2dKZiPJ7Ueb2wbL592+9bQEl2r73qbX6yGnmQVIfiUvDRB2YI0a3PWDrzUwkvQx1XW1bNkA==}
'@tailwindcss/oxide-android-arm64@4.1.4':
resolution: {integrity: sha512-xMMAe/SaCN/vHfQYui3fqaBDEXMu22BVwQ33veLc8ep+DNy7CWN52L+TTG9y1K397w9nkzv+Mw+mZWISiqhmlA==}
'@tailwindcss/oxide-android-arm64@4.1.3':
resolution: {integrity: sha512-cxklKjtNLwFl3mDYw4XpEfBY+G8ssSg9ADL4Wm6//5woi3XGqlxFsnV5Zb6v07dxw1NvEX2uoqsxO/zWQsgR+g==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [android]
'@tailwindcss/oxide-darwin-arm64@4.1.4':
resolution: {integrity: sha512-JGRj0SYFuDuAGilWFBlshcexev2hOKfNkoX+0QTksKYq2zgF9VY/vVMq9m8IObYnLna0Xlg+ytCi2FN2rOL0Sg==}
'@tailwindcss/oxide-darwin-arm64@4.1.3':
resolution: {integrity: sha512-mqkf2tLR5VCrjBvuRDwzKNShRu99gCAVMkVsaEOFvv6cCjlEKXRecPu9DEnxp6STk5z+Vlbh1M5zY3nQCXMXhw==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [darwin]
'@tailwindcss/oxide-darwin-x64@4.1.4':
resolution: {integrity: sha512-sdDeLNvs3cYeWsEJ4H1DvjOzaGios4QbBTNLVLVs0XQ0V95bffT3+scptzYGPMjm7xv4+qMhCDrkHwhnUySEzA==}
'@tailwindcss/oxide-darwin-x64@4.1.3':
resolution: {integrity: sha512-7sGraGaWzXvCLyxrc7d+CCpUN3fYnkkcso3rCzwUmo/LteAl2ZGCDlGvDD8Y/1D3ngxT8KgDj1DSwOnNewKhmg==}
engines: {node: '>= 10'}
cpu: [x64]
os: [darwin]
'@tailwindcss/oxide-freebsd-x64@4.1.4':
resolution: {integrity: sha512-VHxAqxqdghM83HslPhRsNhHo91McsxRJaEnShJOMu8mHmEj9Ig7ToHJtDukkuLWLzLboh2XSjq/0zO6wgvykNA==}
'@tailwindcss/oxide-freebsd-x64@4.1.3':
resolution: {integrity: sha512-E2+PbcbzIReaAYZe997wb9rId246yDkCwAakllAWSGqe6VTg9hHle67hfH6ExjpV2LSK/siRzBUs5wVff3RW9w==}
engines: {node: '>= 10'}
cpu: [x64]
os: [freebsd]
'@tailwindcss/oxide-linux-arm-gnueabihf@4.1.4':
resolution: {integrity: sha512-OTU/m/eV4gQKxy9r5acuesqaymyeSCnsx1cFto/I1WhPmi5HDxX1nkzb8KYBiwkHIGg7CTfo/AcGzoXAJBxLfg==}
'@tailwindcss/oxide-linux-arm-gnueabihf@4.1.3':
resolution: {integrity: sha512-GvfbJ8wjSSjbLFFE3UYz4Eh8i4L6GiEYqCtA8j2Zd2oXriPuom/Ah/64pg/szWycQpzRnbDiJozoxFU2oJZyfg==}
engines: {node: '>= 10'}
cpu: [arm]
os: [linux]
'@tailwindcss/oxide-linux-arm64-gnu@4.1.4':
resolution: {integrity: sha512-hKlLNvbmUC6z5g/J4H+Zx7f7w15whSVImokLPmP6ff1QqTVE+TxUM9PGuNsjHvkvlHUtGTdDnOvGNSEUiXI1Ww==}
'@tailwindcss/oxide-linux-arm64-gnu@4.1.3':
resolution: {integrity: sha512-35UkuCWQTeG9BHcBQXndDOrpsnt3Pj9NVIB4CgNiKmpG8GnCNXeMczkUpOoqcOhO6Cc/mM2W7kaQ/MTEENDDXg==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
'@tailwindcss/oxide-linux-arm64-musl@4.1.4':
resolution: {integrity: sha512-X3As2xhtgPTY/m5edUtddmZ8rCruvBvtxYLMw9OsZdH01L2gS2icsHRwxdU0dMItNfVmrBezueXZCHxVeeb7Aw==}
'@tailwindcss/oxide-linux-arm64-musl@4.1.3':
resolution: {integrity: sha512-dm18aQiML5QCj9DQo7wMbt1Z2tl3Giht54uVR87a84X8qRtuXxUqnKQkRDK5B4bCOmcZ580lF9YcoMkbDYTXHQ==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
'@tailwindcss/oxide-linux-x64-gnu@4.1.4':
resolution: {integrity: sha512-2VG4DqhGaDSmYIu6C4ua2vSLXnJsb/C9liej7TuSO04NK+JJJgJucDUgmX6sn7Gw3Cs5ZJ9ZLrnI0QRDOjLfNQ==}
'@tailwindcss/oxide-linux-x64-gnu@4.1.3':
resolution: {integrity: sha512-LMdTmGe/NPtGOaOfV2HuO7w07jI3cflPrVq5CXl+2O93DCewADK0uW1ORNAcfu2YxDUS035eY2W38TxrsqngxA==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
'@tailwindcss/oxide-linux-x64-musl@4.1.4':
resolution: {integrity: sha512-v+mxVgH2kmur/X5Mdrz9m7TsoVjbdYQT0b4Z+dr+I4RvreCNXyCFELZL/DO0M1RsidZTrm6O1eMnV6zlgEzTMQ==}
'@tailwindcss/oxide-linux-x64-musl@4.1.3':
resolution: {integrity: sha512-aalNWwIi54bbFEizwl1/XpmdDrOaCjRFQRgtbv9slWjmNPuJJTIKPHf5/XXDARc9CneW9FkSTqTbyvNecYAEGw==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
'@tailwindcss/oxide-wasm32-wasi@4.1.4':
resolution: {integrity: sha512-2TLe9ir+9esCf6Wm+lLWTMbgklIjiF0pbmDnwmhR9MksVOq+e8aP3TSsXySnBDDvTTVd/vKu1aNttEGj3P6l8Q==}
engines: {node: '>=14.0.0'}
cpu: [wasm32]
bundledDependencies:
- '@napi-rs/wasm-runtime'
- '@emnapi/core'
- '@emnapi/runtime'
- '@tybys/wasm-util'
- '@emnapi/wasi-threads'
- tslib
'@tailwindcss/oxide-win32-arm64-msvc@4.1.4':
resolution: {integrity: sha512-VlnhfilPlO0ltxW9/BgfLI5547PYzqBMPIzRrk4W7uupgCt8z6Trw/tAj6QUtF2om+1MH281Pg+HHUJoLesmng==}
'@tailwindcss/oxide-win32-arm64-msvc@4.1.3':
resolution: {integrity: sha512-PEj7XR4OGTGoboTIAdXicKuWl4EQIjKHKuR+bFy9oYN7CFZo0eu74+70O4XuERX4yjqVZGAkCdglBODlgqcCXg==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [win32]
'@tailwindcss/oxide-win32-x64-msvc@4.1.4':
resolution: {integrity: sha512-+7S63t5zhYjslUGb8NcgLpFXD+Kq1F/zt5Xv5qTv7HaFTG/DHyHD9GA6ieNAxhgyA4IcKa/zy7Xx4Oad2/wuhw==}
'@tailwindcss/oxide-win32-x64-msvc@4.1.3':
resolution: {integrity: sha512-T8gfxECWDBENotpw3HR9SmNiHC9AOJdxs+woasRZ8Q/J4VHN0OMs7F+4yVNZ9EVN26Wv6mZbK0jv7eHYuLJLwA==}
engines: {node: '>= 10'}
cpu: [x64]
os: [win32]
'@tailwindcss/oxide@4.1.4':
resolution: {integrity: sha512-p5wOpXyOJx7mKh5MXh5oKk+kqcz8T+bA3z/5VWWeQwFrmuBItGwz8Y2CHk/sJ+dNb9B0nYFfn0rj/cKHZyjahQ==}
'@tailwindcss/oxide@4.1.3':
resolution: {integrity: sha512-t16lpHCU7LBxDe/8dCj9ntyNpXaSTAgxWm1u2XQP5NiIu4KGSyrDJJRlK9hJ4U9yJxx0UKCVI67MJWFNll5mOQ==}
engines: {node: '>= 10'}
'@tailwindcss/postcss@4.1.4':
resolution: {integrity: sha512-bjV6sqycCEa+AQSt2Kr7wpGF1bOZJ5wsqnLEkqSbM/JEHxx/yhMH8wHmdkPyApF9xhHeMSwnnkDUUMMM/hYnXw==}
'@tailwindcss/postcss@4.1.3':
resolution: {integrity: sha512-6s5nJODm98F++QT49qn8xJKHQRamhYHfMi3X7/ltxiSQ9dyRsaFSfFkfaMsanWzf+TMYQtbk8mt5f6cCVXJwfg==}
'@tanstack/react-virtual@3.13.6':
resolution: {integrity: sha512-WT7nWs8ximoQ0CDx/ngoFP7HbQF9Q2wQe4nh2NB+u2486eX3nZRE40P9g6ccCVq7ZfTSH5gFOuCoVH5DLNS/aA==}
@@ -1489,8 +1480,8 @@ packages:
'@types/d3-timer@3.0.2':
resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==}
'@types/node@22.14.1':
resolution: {integrity: sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw==}
'@types/node@22.14.0':
resolution: {integrity: sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA==}
'@types/react-dom@19.1.2':
resolution: {integrity: sha512-XGJkWF41Qq305SKWEILa1O8vzhb3aOo3ogBlSmiqNko/WmRb6QIaweuZCXjKygVDXpzXb5wyxKTSOsmkuqj+Qw==}
@@ -1549,6 +1540,12 @@ packages:
resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
engines: {node: '>=6'}
cmdk@1.1.1:
resolution: {integrity: sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg==}
peerDependencies:
react: ^18 || ^19 || ^19.0.0-rc
react-dom: ^18 || ^19 || ^19.0.0-rc
color-convert@2.0.1:
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
engines: {node: '>=7.0.0'}
@@ -1891,8 +1888,8 @@ packages:
engines: {node: '>=10.0.0'}
hasBin: true
miniflare@4.20250417.0:
resolution: {integrity: sha512-bROKLQKr4CoS93tnGuw5e08VaNwM3VowTL3Z2Cps1HzY6a4Bq8uNtggQ7WogriMq77jcHn6kbz64bvWyF//Jkw==}
miniflare@4.20250416.0:
resolution: {integrity: sha512-261PhPgD9zs5/BTdbWqwiaXtWxb+Av5zKCwTU+HXrA5E4tf3qnULwh3u6SVUOAEArEroFuKJzawsQ9COtNBurQ==}
engines: {node: '>=18.0.0'}
hasBin: true
@@ -2156,8 +2153,8 @@ packages:
peerDependencies:
tailwindcss: '>=3.0.0 || insiders'
tailwindcss@4.1.4:
resolution: {integrity: sha512-1ZIUqtPITFbv/DxRmDr5/agPqJwF69d24m9qmM1939TJehgY539CtzeZRjbLt5G6fSy/7YqqYsfvoTEw9xUI2A==}
tailwindcss@4.1.3:
resolution: {integrity: sha512-2Q+rw9vy1WFXu5cIxlvsabCwhU2qUwodGq03ODhLJ0jW4ek5BUtoCsnLB0qG+m8AHgEsSJcJGDSDe06FXlP74g==}
tapable@2.2.1:
resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==}
@@ -2222,17 +2219,17 @@ packages:
web-vitals@4.2.4:
resolution: {integrity: sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==}
workerd@1.20250417.0:
resolution: {integrity: sha512-naz6oJiVODd3/Lkp9l3vtc56HKOOvx+AWDvEsTa5eSfi5SI9V0HYpLYSPblAwrfazbQ4ff1Vl3jkTl/5JxqCAA==}
workerd@1.20250416.0:
resolution: {integrity: sha512-Yrx/bZAKbmSvomdTAzzIpOHwpYhs0ldr2wqed22UEhQ0mIplAHY4xmY+SjAJhP/TydZrciOVzBxwM1+4T40KNA==}
engines: {node: '>=16'}
hasBin: true
wrangler@4.12.1:
resolution: {integrity: sha512-jYrz8y2ffhsRqvQLO2dXFi9HLvPUJk3jn7U71GWfBBCHm0I6r2ik7Vs9ajpRcTGlbNw1RY0uIHVJBVR/7bEN5A==}
wrangler@4.12.0:
resolution: {integrity: sha512-4rfAXOi5KqM3ECvOrZJ97k3zEqxVwtdt4bijd8jcRBZ6iJYvEtjgjVi4TsfkVa/eXGhpfHTUnKu2uk8UHa8M2w==}
engines: {node: '>=18.0.0'}
hasBin: true
peerDependencies:
'@cloudflare/workers-types': ^4.20250417.0
'@cloudflare/workers-types': ^4.20250415.0
peerDependenciesMeta:
'@cloudflare/workers-types':
optional: true
@@ -2305,25 +2302,25 @@ snapshots:
dependencies:
mime: 3.0.0
'@cloudflare/unenv-preset@2.3.1(unenv@2.0.0-rc.15)(workerd@1.20250417.0)':
'@cloudflare/unenv-preset@2.3.1(unenv@2.0.0-rc.15)(workerd@1.20250416.0)':
dependencies:
unenv: 2.0.0-rc.15
optionalDependencies:
workerd: 1.20250417.0
workerd: 1.20250416.0
'@cloudflare/workerd-darwin-64@1.20250417.0':
'@cloudflare/workerd-darwin-64@1.20250416.0':
optional: true
'@cloudflare/workerd-darwin-arm64@1.20250417.0':
'@cloudflare/workerd-darwin-arm64@1.20250416.0':
optional: true
'@cloudflare/workerd-linux-64@1.20250417.0':
'@cloudflare/workerd-linux-64@1.20250416.0':
optional: true
'@cloudflare/workerd-linux-arm64@1.20250417.0':
'@cloudflare/workerd-linux-arm64@1.20250416.0':
optional: true
'@cloudflare/workerd-windows-64@1.20250417.0':
'@cloudflare/workerd-windows-64@1.20250416.0':
optional: true
'@cspotcode/source-map-support@0.8.1':
@@ -3267,71 +3264,67 @@ snapshots:
dependencies:
tslib: 2.8.1
'@tailwindcss/node@4.1.4':
'@tailwindcss/node@4.1.3':
dependencies:
enhanced-resolve: 5.18.1
jiti: 2.4.2
lightningcss: 1.29.2
tailwindcss: 4.1.4
tailwindcss: 4.1.3
'@tailwindcss/oxide-android-arm64@4.1.4':
'@tailwindcss/oxide-android-arm64@4.1.3':
optional: true
'@tailwindcss/oxide-darwin-arm64@4.1.4':
'@tailwindcss/oxide-darwin-arm64@4.1.3':
optional: true
'@tailwindcss/oxide-darwin-x64@4.1.4':
'@tailwindcss/oxide-darwin-x64@4.1.3':
optional: true
'@tailwindcss/oxide-freebsd-x64@4.1.4':
'@tailwindcss/oxide-freebsd-x64@4.1.3':
optional: true
'@tailwindcss/oxide-linux-arm-gnueabihf@4.1.4':
'@tailwindcss/oxide-linux-arm-gnueabihf@4.1.3':
optional: true
'@tailwindcss/oxide-linux-arm64-gnu@4.1.4':
'@tailwindcss/oxide-linux-arm64-gnu@4.1.3':
optional: true
'@tailwindcss/oxide-linux-arm64-musl@4.1.4':
'@tailwindcss/oxide-linux-arm64-musl@4.1.3':
optional: true
'@tailwindcss/oxide-linux-x64-gnu@4.1.4':
'@tailwindcss/oxide-linux-x64-gnu@4.1.3':
optional: true
'@tailwindcss/oxide-linux-x64-musl@4.1.4':
'@tailwindcss/oxide-linux-x64-musl@4.1.3':
optional: true
'@tailwindcss/oxide-wasm32-wasi@4.1.4':
'@tailwindcss/oxide-win32-arm64-msvc@4.1.3':
optional: true
'@tailwindcss/oxide-win32-arm64-msvc@4.1.4':
'@tailwindcss/oxide-win32-x64-msvc@4.1.3':
optional: true
'@tailwindcss/oxide-win32-x64-msvc@4.1.4':
optional: true
'@tailwindcss/oxide@4.1.4':
'@tailwindcss/oxide@4.1.3':
optionalDependencies:
'@tailwindcss/oxide-android-arm64': 4.1.4
'@tailwindcss/oxide-darwin-arm64': 4.1.4
'@tailwindcss/oxide-darwin-x64': 4.1.4
'@tailwindcss/oxide-freebsd-x64': 4.1.4
'@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.4
'@tailwindcss/oxide-linux-arm64-gnu': 4.1.4
'@tailwindcss/oxide-linux-arm64-musl': 4.1.4
'@tailwindcss/oxide-linux-x64-gnu': 4.1.4
'@tailwindcss/oxide-linux-x64-musl': 4.1.4
'@tailwindcss/oxide-wasm32-wasi': 4.1.4
'@tailwindcss/oxide-win32-arm64-msvc': 4.1.4
'@tailwindcss/oxide-win32-x64-msvc': 4.1.4
'@tailwindcss/oxide-android-arm64': 4.1.3
'@tailwindcss/oxide-darwin-arm64': 4.1.3
'@tailwindcss/oxide-darwin-x64': 4.1.3
'@tailwindcss/oxide-freebsd-x64': 4.1.3
'@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.3
'@tailwindcss/oxide-linux-arm64-gnu': 4.1.3
'@tailwindcss/oxide-linux-arm64-musl': 4.1.3
'@tailwindcss/oxide-linux-x64-gnu': 4.1.3
'@tailwindcss/oxide-linux-x64-musl': 4.1.3
'@tailwindcss/oxide-win32-arm64-msvc': 4.1.3
'@tailwindcss/oxide-win32-x64-msvc': 4.1.3
'@tailwindcss/postcss@4.1.4':
'@tailwindcss/postcss@4.1.3':
dependencies:
'@alloc/quick-lru': 5.2.0
'@tailwindcss/node': 4.1.4
'@tailwindcss/oxide': 4.1.4
'@tailwindcss/node': 4.1.3
'@tailwindcss/oxide': 4.1.3
postcss: 8.5.3
tailwindcss: 4.1.4
tailwindcss: 4.1.3
'@tanstack/react-virtual@3.13.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0)':
dependencies:
@@ -3367,7 +3360,7 @@ snapshots:
'@types/d3-timer@3.0.2': {}
'@types/node@22.14.1':
'@types/node@22.14.0':
dependencies:
undici-types: 6.21.0
@@ -3424,6 +3417,18 @@ snapshots:
clsx@2.1.1: {}
cmdk@1.1.1(@types/react-dom@19.1.2(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0):
dependencies:
'@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.0)(react@19.1.0)
'@radix-ui/react-dialog': 1.1.7(@types/react-dom@19.1.2(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
'@radix-ui/react-id': 1.1.1(@types/react@19.1.0)(react@19.1.0)
'@radix-ui/react-primitive': 2.0.3(@types/react-dom@19.1.2(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
react: 19.1.0
react-dom: 19.1.0(react@19.1.0)
transitivePeerDependencies:
- '@types/react'
- '@types/react-dom'
color-convert@2.0.1:
dependencies:
color-name: 1.1.4
@@ -3730,7 +3735,7 @@ snapshots:
mime@3.0.0: {}
miniflare@4.20250417.0:
miniflare@4.20250416.0:
dependencies:
'@cspotcode/source-map-support': 0.8.1
acorn: 8.14.0
@@ -3739,7 +3744,7 @@ snapshots:
glob-to-regexp: 0.4.1
stoppable: 1.1.0
undici: 5.29.0
workerd: 1.20250417.0
workerd: 1.20250416.0
ws: 8.18.0
youch: 3.3.4
zod: 3.22.3
@@ -4020,11 +4025,11 @@ snapshots:
tailwind-merge@3.2.0: {}
tailwindcss-motion@1.1.0(tailwindcss@4.1.4):
tailwindcss-motion@1.1.0(tailwindcss@4.1.3):
dependencies:
tailwindcss: 4.1.4
tailwindcss: 4.1.3
tailwindcss@4.1.4: {}
tailwindcss@4.1.3: {}
tapable@2.2.1: {}
@@ -4095,24 +4100,24 @@ snapshots:
web-vitals@4.2.4: {}
workerd@1.20250417.0:
workerd@1.20250416.0:
optionalDependencies:
'@cloudflare/workerd-darwin-64': 1.20250417.0
'@cloudflare/workerd-darwin-arm64': 1.20250417.0
'@cloudflare/workerd-linux-64': 1.20250417.0
'@cloudflare/workerd-linux-arm64': 1.20250417.0
'@cloudflare/workerd-windows-64': 1.20250417.0
'@cloudflare/workerd-darwin-64': 1.20250416.0
'@cloudflare/workerd-darwin-arm64': 1.20250416.0
'@cloudflare/workerd-linux-64': 1.20250416.0
'@cloudflare/workerd-linux-arm64': 1.20250416.0
'@cloudflare/workerd-windows-64': 1.20250416.0
wrangler@4.12.1:
wrangler@4.12.0:
dependencies:
'@cloudflare/kv-asset-handler': 0.4.0
'@cloudflare/unenv-preset': 2.3.1(unenv@2.0.0-rc.15)(workerd@1.20250417.0)
'@cloudflare/unenv-preset': 2.3.1(unenv@2.0.0-rc.15)(workerd@1.20250416.0)
blake3-wasm: 2.1.5
esbuild: 0.25.2
miniflare: 4.20250417.0
miniflare: 4.20250416.0
path-to-regexp: 6.3.0
unenv: 2.0.0-rc.15
workerd: 1.20250417.0
workerd: 1.20250416.0
optionalDependencies:
fsevents: 2.3.3
sharp: 0.33.5

View File

@@ -32,16 +32,16 @@ export default function ErrorPage({
</div>
<h1 className="text-2xl font-bold">Something went wrong</h1>
<p className="text-muted-foreground">
Unable to load this page. We're looking into the issue.
An unexpected error occurred while loading this page. We've been notified and are looking into it.
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center pt-4">
<Button variant="outline" onClick={() => reset()} className="cursor-pointer">
<RefreshCcw className="mr-2 h-4 w-4" />
Retry
Try again
</Button>
<Button onClick={handleGoBack} className="cursor-pointer">
<ArrowLeft className="mr-2 h-4 w-4" />
Back
Go back
</Button>
</div>
{error.digest && <p className="text-xs text-muted-foreground mt-6">Error ID: {error.digest}</p>}

View File

@@ -118,6 +118,19 @@
transform: rotate(-5deg) scale(0.9);
}
}
--animate-shiny-text: shiny-text 8s infinite;
@keyframes shiny-text {
0%,
90%,
100% {
background-position: calc(-100% - var(--shiny-width)) 0;
}
30%,
60% {
background-position: calc(100% + var(--shiny-width)) 0;
}
}
}
:root {
@@ -170,8 +183,6 @@
--shadow-xl: 0px 1px 3px 0px hsl(0 0% 0% / 0.1), 0px 8px 10px -1px
hsl(0 0% 0% / 0.1);
--shadow-2xl: 0px 1px 3px 0px hsl(0 0% 0% / 0.25);
--magic-gradient-color: oklch(0.67 0.2 23.8 / 15%);
}
.dark {
@@ -186,7 +197,7 @@
--secondary: oklch(0.31 0.03 266.71);
--secondary-foreground: oklch(0.92 0 0);
--muted: oklch(0.31 0.03 266.71);
--muted-foreground: oklch(0.78 0 0);
--muted-foreground: oklch(0.72 0 0);
--accent: oklch(0.34 0.06 267.59);
--accent-foreground: oklch(0.88 0.06 254.13);
--destructive: oklch(0.64 0.21 25.33);
@@ -222,8 +233,6 @@
--shadow-xl: 0px 1px 3px 0px hsl(0 0% 0% / 0.1), 0px 8px 10px -1px
hsl(0 0% 0% / 0.1);
--shadow-2xl: 0px 1px 3px 0px hsl(0 0% 0% / 0.25);
--magic-gradient-color: oklch(0.27 0 0);
}
@layer base {

View File

@@ -1,13 +1,7 @@
import { readFile } from "node:fs/promises"
import { join } from "node:path"
import { getAllIcons } from "@/lib/api"
import { ImageResponse } from "next/og"
import {
SITE_NAME,
SITE_TAGLINE,
getIconDescription,
WEB_URL
} from "@/constants"
import { readFile } from "node:fs/promises"
import { join } from "node:path"
export const dynamic = "force-static"
@@ -58,9 +52,9 @@ export default async function Image({ params }: { params: { icon: string } }) {
position: "relative",
fontFamily: "Inter, system-ui, sans-serif",
overflow: "hidden",
backgroundColor: "#0f172a", // Dark background (slate-900)
backgroundColor: "white",
backgroundImage:
"radial-gradient(circle at 25px 25px, #1e293b 2%, transparent 0%), radial-gradient(circle at 75px 75px, #1e293b 2%, transparent 0%)",
"radial-gradient(circle at 25px 25px, lightgray 2%, transparent 0%), radial-gradient(circle at 75px 75px, lightgray 2%, transparent 0%)",
backgroundSize: "100px 100px",
}}
>
@@ -73,7 +67,7 @@ export default async function Image({ params }: { params: { icon: string } }) {
width: 400,
height: 400,
borderRadius: "50%",
background: "linear-gradient(135deg, rgba(56, 189, 248, 0.15) 0%, rgba(59, 130, 246, 0.15) 100%)",
background: "linear-gradient(135deg, rgba(56, 189, 248, 0.1) 0%, rgba(59, 130, 246, 0.1) 100%)",
filter: "blur(80px)",
zIndex: 2,
}}
@@ -86,7 +80,7 @@ export default async function Image({ params }: { params: { icon: string } }) {
width: 500,
height: 500,
borderRadius: "50%",
background: "linear-gradient(135deg, rgba(249, 115, 22, 0.15) 0%, rgba(234, 88, 12, 0.15) 100%)",
background: "linear-gradient(135deg, rgba(249, 115, 22, 0.1) 0%, rgba(234, 88, 12, 0.1) 100%)",
filter: "blur(100px)",
zIndex: 2,
}}
@@ -115,8 +109,8 @@ export default async function Image({ params }: { params: { icon: string } }) {
width: 320,
height: 320,
borderRadius: 32,
background: "#1e293b", // Dark container (slate-800)
boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.1)",
background: "white",
boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(0, 0, 0, 0.05)",
padding: 30,
flexShrink: 0,
position: "relative",
@@ -127,7 +121,7 @@ export default async function Image({ params }: { params: { icon: string } }) {
style={{
position: "absolute",
inset: 0,
background: "linear-gradient(145deg, #1e293b 0%, #0f172a 100%)",
background: "linear-gradient(145deg, #ffffff 0%, #f8fafc 100%)",
zIndex: 0,
}}
/>
@@ -140,7 +134,7 @@ export default async function Image({ params }: { params: { icon: string } }) {
objectFit: "contain",
position: "relative",
zIndex: 1,
filter: "drop-shadow(0 10px 15px rgba(0, 0, 0, 0.3))",
filter: "drop-shadow(0 10px 15px rgba(0, 0, 0, 0.1))",
}}
/>
</div>
@@ -160,7 +154,7 @@ export default async function Image({ params }: { params: { icon: string } }) {
display: "flex",
fontSize: 64,
fontWeight: 800,
color: "#f8fafc", // Light text for dark background (slate-50)
color: "#0f172a",
lineHeight: 1.1,
letterSpacing: "-0.02em",
}}
@@ -173,14 +167,14 @@ export default async function Image({ params }: { params: { icon: string } }) {
display: "flex",
fontSize: 32,
fontWeight: 500,
color: "#94a3b8", // Muted text (slate-400)
color: "#64748b",
lineHeight: 1.4,
position: "relative",
paddingLeft: 16,
borderLeft: "4px solid #64748b", // slate-500
borderLeft: "4px solid #94a3b8",
}}
>
{getIconDescription(formattedIconName, totalIcons)}
Amongst {totalIcons} other high-quality dashboard icons
</div>
<div
@@ -197,14 +191,14 @@ export default async function Image({ params }: { params: { icon: string } }) {
display: "flex",
alignItems: "center",
justifyContent: "center",
backgroundColor: "#334155", // slate-700
color: "#e2e8f0", // slate-200
border: "2px solid #475569", // slate-600
backgroundColor: "#f1f5f9",
color: "#475569",
border: "2px solid #e2e8f0",
borderRadius: 12,
padding: "8px 16px",
fontSize: 18,
fontWeight: 600,
boxShadow: "0 1px 2px rgba(0, 0, 0, 0.2)",
boxShadow: "0 1px 2px rgba(0, 0, 0, 0.05)",
}}
>
{format}
@@ -225,8 +219,8 @@ export default async function Image({ params }: { params: { icon: string } }) {
display: "flex",
alignItems: "center",
justifyContent: "center",
background: "#1e293b", // slate-800
borderTop: "2px solid rgba(255, 255, 255, 0.1)",
background: "#ffffff",
borderTop: "2px solid rgba(0, 0, 0, 0.05)",
zIndex: 20,
}}
>
@@ -235,7 +229,7 @@ export default async function Image({ params }: { params: { icon: string } }) {
display: "flex",
fontSize: 24,
fontWeight: 600,
color: "#e2e8f0", // slate-200
color: "#334155",
alignItems: "center",
gap: 10,
}}
@@ -245,11 +239,11 @@ export default async function Image({ params }: { params: { icon: string } }) {
width: 8,
height: 8,
borderRadius: "50%",
backgroundColor: "#3b82f6", // blue-500
backgroundColor: "#3b82f6",
marginRight: 4,
}}
/>
{WEB_URL.replace("https://", "")}
dashboardicons.com
</div>
</div>
</div>,

View File

@@ -1,9 +1,7 @@
import { IconDetails } from "@/components/icon-details"
import { StructuredData } from "@/components/structured-data"
import { BASE_URL, GITHUB_URL, ICON_DETAIL_KEYWORDS, SITE_NAME, SITE_TAGLINE, TITLE_SEPARATOR, WEB_URL, getIconDescription, getIconSchema } from "@/constants"
import { BASE_URL, WEB_URL } from "@/constants"
import { getAllIcons, getAuthorData } from "@/lib/api"
import type { Metadata, ResolvingMetadata } from "next"
import Script from "next/script"
import { notFound } from "next/navigation"
export const dynamicParams = false
@@ -42,52 +40,47 @@ export async function generateMetadata({ params, searchParams }: Props, parent:
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
.join(" ")
const title = `${formattedIconName} Icon ${TITLE_SEPARATOR} ${SITE_NAME}`
const fullTitle = `${formattedIconName} Icon ${TITLE_SEPARATOR} ${SITE_NAME} ${TITLE_SEPARATOR} ${SITE_TAGLINE}`
const description = getIconDescription(formattedIconName, totalIcons)
return {
title,
description,
assets: [iconImageUrl],
category: "Icons",
keywords: ICON_DETAIL_KEYWORDS(formattedIconName),
icons: {
icon: iconImageUrl,
},
abstract: description,
robots: {
index: true,
follow: true,
},
title: `${formattedIconName} Icon | Dashboard Icons`,
description: `Download the ${formattedIconName} icon in SVG, PNG, and WEBP formats for FREE. Part of a collection of ${totalIcons} curated icons for services, applications and tools, designed specifically for dashboards and app directories.`,
keywords: [
`${formattedIconName} icon`,
"dashboard icon",
"service icon",
"application icon",
"tool icon",
"web dashboard",
"app directory",
],
authors: [
{
name: "homarr",
url: "https://homarr.dev",
},
{
name: authorName,
url: authorData.html_url,
},
],
openGraph: {
title: fullTitle,
description,
title: `${formattedIconName} Icon | Dashboard Icons`,
description: `Download the ${formattedIconName} icon in SVG, PNG, and WEBP formats for FREE. Part of a collection of ${totalIcons} curated icons for services, applications and tools, designed specifically for dashboards and app directories.`,
type: "article",
url: pageUrl,
authors: [authorName],
authors: [authorName, "homarr"],
publishedTime: updateDate.toISOString(),
modifiedTime: updateDate.toISOString(),
section: "Icons",
tags: [formattedIconName, ...ICON_DETAIL_KEYWORDS(formattedIconName)],
},
twitter: {
card: "summary_large_image",
title: fullTitle,
description,
title: `${formattedIconName} Icon | Dashboard Icons`,
description: `Download the ${formattedIconName} icon in SVG, PNG, and WEBP formats for FREE. Part of a collection of ${totalIcons} curated icons for services, applications and tools, designed specifically for dashboards and app directories.`,
images: [iconImageUrl],
creator: "@homarr_app",
},
alternates: {
canonical: pageUrl,
media: {
png: iconImageUrl,
svg: `${BASE_URL}/svg/${icon}.svg`,
webp: `${BASE_URL}/webp/${icon}.webp`,
},
},
other: {
"revisit-after": "7 days",
}
}
}
@@ -101,26 +94,6 @@ export default async function IconPage({ params }: { params: Promise<{ icon: str
}
const authorData = await getAuthorData(originalIconData.update.author.id)
const updateDate = new Date(originalIconData.update.timestamp)
const authorName = authorData.name || authorData.login
const formattedIconName = icon
.split("-")
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
.join(" ")
const imageSchema = getIconSchema(
formattedIconName,
icon,
authorName,
authorData.html_url,
updateDate.toISOString(),
Object.keys(iconsData).length
)
return (
<>
<StructuredData data={imageSchema} id="image-schema" />
<IconDetails icon={icon} iconData={originalIconData} authorData={authorData} />
</>
)
return <IconDetails icon={icon} iconData={originalIconData} authorData={authorData} />
}

View File

@@ -0,0 +1,87 @@
"use client"
import { Input } from "@/components/ui/input"
import { BASE_URL } from "@/constants"
import type { IconSearchProps, IconWithName } from "@/types/icons"
import { Search } from "lucide-react"
import Image from "next/image"
import Link from "next/link"
import { useState } from "react"
export function IconSearch({ icons, initialQuery = "" }: IconSearchProps) {
const [searchQuery, setSearchQuery] = useState(initialQuery)
const [filteredIcons, setFilteredIcons] = useState<IconWithName[]>(() => {
if (!initialQuery.trim()) return icons
const q = initialQuery.toLowerCase()
return icons.filter(({ name, data }) => {
if (name.toLowerCase().includes(q)) return true
if (data.aliases.some((alias) => alias.toLowerCase().includes(q))) return true
if (data.categories.some((category) => category.toLowerCase().includes(q))) return true
return false
})
})
const handleSearch = (query: string) => {
setSearchQuery(query)
if (!query.trim()) {
setFilteredIcons(icons)
return
}
const q = query.toLowerCase()
const filtered = icons.filter(({ name, data }) => {
if (name.toLowerCase().includes(q)) return true
if (data.aliases.some((alias) => alias.toLowerCase().includes(q))) return true
if (data.categories.some((category) => category.toLowerCase().includes(q))) return true
return false
})
setFilteredIcons(filtered)
}
return (
<>
<div className="relative w-full max-w-md">
<Search className="absolute left-2.5 top-1/2 transform -translate-y-1/2 h-4 w-4 text-muted-foreground transition-all duration-300" />
<Input
type="search"
placeholder="Search icons by name, aliases, or categories..."
className="w-full pl-8 transition-all duration-300 text-sm md:text-base"
value={searchQuery}
onChange={(e) => handleSearch(e.target.value)}
/>
</div>
{filteredIcons.length === 0 ? (
<div className="text-center py-12">
<h2 className="text-xl font-semibold">No icons found</h2>
<p className="text-muted-foreground mt-2">Try a different search term.</p>
</div>
) : (
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 xl:grid-cols-8 gap-4 mt-8">
{filteredIcons.map(({ name, data }) => (
<Link
key={name}
href={`/icons/${name}`}
className="group flex flex-col items-center p-4 rounded-lg border border-border hover:border-primary hover:bg-accent transition-colors"
>
<div className="relative h-16 w-16 mb-2">
<Image
src={`${BASE_URL}/${data.base}/${name}.${data.base}`}
alt={`${name} icon`}
fill
className="object-contain p-1 group-hover:scale-110 transition-transform"
/>
</div>
<span className="text-sm text-center truncate w-full">{name.replace(/-/g, " ")}</span>
</Link>
))}
</div>
)}
</>
)
}

View File

@@ -19,97 +19,27 @@ import { Input } from "@/components/ui/input"
import { Separator } from "@/components/ui/separator"
import { BASE_URL } from "@/constants"
import type { Icon, IconSearchProps } from "@/types/icons"
import { ArrowDownAZ, ArrowUpZA, Calendar, ChevronLeft, ChevronRight, Filter, Search, SortAsc, X } from "lucide-react"
import { ArrowDownAZ, ArrowUpZA, Calendar, Filter, Search, SortAsc, X } from "lucide-react"
import { useTheme } from "next-themes"
import Image from "next/image"
import Link from "next/link"
import { usePathname, useRouter, useSearchParams } from "next/navigation"
import posthog from "posthog-js"
import { useCallback, useEffect, useMemo, useRef, useState } from "react"
import { toast } from "sonner"
import { motion, AnimatePresence } from "framer-motion"
type SortOption = "relevance" | "alphabetical-asc" | "alphabetical-desc" | "newest"
// Get the display rows count based on viewport size
function getDefaultRowsPerPage() {
if (typeof window === "undefined") return 3; // Default for SSR
// Calculate based on viewport height and width
const vh = window.innerHeight;
const vw = window.innerWidth;
// Determine number of columns based on viewport width
let columns = 2; // Default for small screens (sm)
if (vw >= 1280) columns = 8; // xl breakpoint
else if (vw >= 1024) columns = 6; // lg breakpoint
else if (vw >= 768) columns = 4; // md breakpoint
else if (vw >= 640) columns = 3; // sm breakpoint
// Calculate rows (accounting for pagination UI space)
const rowHeight = 130; // Approximate height of each row in pixels
const availableHeight = vh * 0.6; // 60% of viewport height
// Ensure at least 1 row, maximum 5 rows
return Math.max(1, Math.min(5, Math.floor(availableHeight / rowHeight)));
}
export function IconSearch({ icons }: IconSearchProps) {
const searchParams = useSearchParams()
const initialQuery = searchParams.get("q")
const initialCategories = searchParams.getAll("category")
const initialSort = (searchParams.get("sort") as SortOption) || "relevance"
const initialPage = Number(searchParams.get("page") || "1")
const router = useRouter()
const pathname = usePathname()
const [searchQuery, setSearchQuery] = useState(initialQuery ?? "")
const [debouncedQuery, setDebouncedQuery] = useState(initialQuery ?? "")
const [selectedCategories, setSelectedCategories] = useState<string[]>(initialCategories ?? [])
const [sortOption, setSortOption] = useState<SortOption>(initialSort)
const [currentPage, setCurrentPage] = useState(initialPage)
const [iconsPerPage, setIconsPerPage] = useState(getDefaultRowsPerPage() * 8) // Default cols is 8 for xl screens
const timeoutRef = useRef<NodeJS.Timeout | null>(null)
const { resolvedTheme } = useTheme()
const [isLazyRequestSubmitted, setIsLazyRequestSubmitted] = useState(false)
// Add resize observer to update iconsPerPage when window size changes
useEffect(() => {
const updateIconsPerPage = () => {
const rows = getDefaultRowsPerPage();
// Determine columns based on current viewport
const vw = window.innerWidth;
let columns = 2; // Default for small screens
if (vw >= 1280) columns = 8; // xl breakpoint
else if (vw >= 1024) columns = 6; // lg breakpoint
else if (vw >= 768) columns = 4; // md breakpoint
else if (vw >= 640) columns = 3; // sm breakpoint
setIconsPerPage(rows * columns);
};
// Initial setup
updateIconsPerPage();
// Add resize listener
window.addEventListener('resize', updateIconsPerPage);
// Cleanup
return () => window.removeEventListener('resize', updateIconsPerPage);
}, []);
// Reset page when search parameters change
useEffect(() => {
setCurrentPage(1);
}, [debouncedQuery, selectedCategories, sortOption]);
useEffect(() => {
const timer = setTimeout(() => {
setDebouncedQuery(searchQuery)
}, 200)
return () => clearTimeout(timer)
}, [searchQuery])
// Extract all unique categories
const allCategories = useMemo(() => {
@@ -135,17 +65,11 @@ export function IconSearch({ icons }: IconSearchProps) {
// Then filter by search query
if (query.trim()) {
// Normalization function: lowercase, remove spaces and hyphens
const normalizeString = (str: string) => str.toLowerCase().replace(/[-\s]/g, "")
const normalizedQuery = normalizeString(query)
const q = query.toLowerCase()
filtered = filtered.filter(({ name, data }) => {
// Check normalized name
if (normalizeString(name).includes(normalizedQuery)) return true
// Check normalized aliases
if (data.aliases.some((alias) => normalizeString(alias).includes(normalizedQuery))) return true
// Check normalized categories
if (data.categories.some((category) => normalizeString(category).includes(normalizedQuery))) return true
if (name.toLowerCase().includes(q)) return true
if (data.aliases.some((alias) => alias.toLowerCase().includes(q))) return true
if (data.categories.some((category) => category.toLowerCase().includes(q))) return true
return false
})
}
@@ -164,7 +88,6 @@ export function IconSearch({ icons }: IconSearchProps) {
}
// Default sort (relevance or fallback to alphabetical)
// TODO: Implement actual relevance sorting
return filtered.sort((a, b) => a.name.localeCompare(b.name))
},
[icons],
@@ -190,13 +113,13 @@ export function IconSearch({ icons }: IconSearchProps) {
return matches
}, [icons, searchQuery])
// Use useMemo for filtered icons with debounced query
// Use useMemo for filtered icons
const filteredIcons = useMemo(() => {
return filterIcons(debouncedQuery, selectedCategories, sortOption)
}, [filterIcons, debouncedQuery, selectedCategories, sortOption])
return filterIcons(searchQuery, selectedCategories, sortOption)
}, [filterIcons, searchQuery, selectedCategories, sortOption])
const updateResults = useCallback(
(query: string, categories: string[], sort: SortOption, page = 1) => {
(query: string, categories: string[], sort: SortOption) => {
const params = new URLSearchParams()
if (query) params.set("q", query)
@@ -210,11 +133,6 @@ export function IconSearch({ icons }: IconSearchProps) {
params.set("sort", sort)
}
// Add page parameter if not the first page
if (page > 1) {
params.set("page", page.toString())
}
const newUrl = params.toString() ? `${pathname}?${params.toString()}` : pathname
router.push(newUrl, { scroll: false })
},
@@ -260,20 +178,11 @@ export function IconSearch({ icons }: IconSearchProps) {
[updateResults, searchQuery, selectedCategories],
)
const handlePageChange = useCallback(
(page: number) => {
setCurrentPage(page);
updateResults(searchQuery, selectedCategories, sortOption, page);
},
[updateResults, searchQuery, selectedCategories, sortOption],
)
const clearFilters = useCallback(() => {
setSearchQuery("")
setSelectedCategories([])
setSortOption("relevance")
setCurrentPage(1)
updateResults("", [], "relevance", 1)
updateResults("", [], "relevance")
}, [updateResults])
useEffect(() => {
@@ -284,27 +193,16 @@ export function IconSearch({ icons }: IconSearchProps) {
}
}, [])
useEffect(() => {
if (filteredIcons.length === 0 && searchQuery) {
console.log("no icons found", {
query: searchQuery,
})
posthog.capture("no icons found", {
query: searchQuery,
})
}
}, [filteredIcons, searchQuery])
if (!searchParams) return null
const getSortLabel = (sort: SortOption) => {
switch (sort) {
case "relevance":
return "Relevance"
return "Best match"
case "alphabetical-asc":
return "Name (A-Z)"
return "A to Z"
case "alphabetical-desc":
return "Name (Z-A)"
return "Z to A"
case "newest":
return "Newest first"
default:
@@ -337,7 +235,7 @@ export function IconSearch({ icons }: IconSearchProps) {
</div>
<Input
type="search"
placeholder="Search for icons..."
placeholder="Search icons by name, alias, or category..."
className="w-full h-10 pl-9 cursor-text transition-all duration-300 text-sm md:text-base border-border shadow-sm"
value={searchQuery}
onChange={(e) => handleSearch(e.target.value)}
@@ -349,18 +247,18 @@ export function IconSearch({ icons }: IconSearchProps) {
{/* Filter dropdown */}
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
variant="outline"
size="sm"
className="flex-1 sm:flex-none cursor-pointer bg-background border-border shadow-sm"
aria-label="Filter icons"
>
<Button variant="outline" size="sm" className="flex-1 sm:flex-none cursor-pointer bg-background border-border shadow-sm ">
<Filter className="h-4 w-4 mr-2" />
<span>{selectedCategories.length > 0 ? `Filters (${selectedCategories.length})` : "Filter"}</span>
<span>Filter</span>
{selectedCategories.length > 0 && (
<Badge variant="secondary" className="ml-2 px-1.5">
{selectedCategories.length}
</Badge>
)}
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="start" className="w-64 sm:w-56">
<DropdownMenuLabel className="font-semibold">Select Categories</DropdownMenuLabel>
<DropdownMenuLabel className="font-semibold">Categories</DropdownMenuLabel>
<DropdownMenuSeparator />
<div className="max-h-[40vh] overflow-y-auto p-1">
@@ -386,7 +284,7 @@ export function IconSearch({ icons }: IconSearchProps) {
}}
className="cursor-pointer focus: focus:bg-rose-50 dark:focus:bg-rose-950/20"
>
Clear categories
Clear all filters
</DropdownMenuItem>
</>
)}
@@ -402,18 +300,18 @@ export function IconSearch({ icons }: IconSearchProps) {
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="start" className="w-56">
<DropdownMenuLabel className="font-semibold">Sort Icons</DropdownMenuLabel>
<DropdownMenuLabel className="font-semibold">Sort By</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuRadioGroup value={sortOption} onValueChange={(value) => handleSortChange(value as SortOption)}>
<DropdownMenuRadioItem value="relevance" className="cursor-pointer">
<Search className="h-4 w-4 mr-2" />
Relevance
Best match
</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="alphabetical-asc" className="cursor-pointer">
<ArrowDownAZ className="h-4 w-4 mr-2" />Name (A-Z)
<ArrowDownAZ className="h-4 w-4 mr-2" />A to Z
</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="alphabetical-desc" className="cursor-pointer">
<ArrowUpZA className="h-4 w-4 mr-2" />Name (Z-A)
<ArrowUpZA className="h-4 w-4 mr-2" />Z to A
</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="newest" className="cursor-pointer">
<Calendar className="h-4 w-4 mr-2" />
@@ -425,15 +323,9 @@ export function IconSearch({ icons }: IconSearchProps) {
{/* Clear all button */}
{(searchQuery || selectedCategories.length > 0 || sortOption !== "relevance") && (
<Button
variant="outline"
size="sm"
onClick={clearFilters}
className="flex-1 sm:flex-none cursor-pointer bg-background"
aria-label="Reset all filters"
>
<Button variant="outline" size="sm" onClick={clearFilters} className="flex-1 sm:flex-none cursor-pointer bg-background">
<X className="h-4 w-4 mr-2" />
<span>Reset</span>
<span>Clear all</span>
</Button>
)}
</div>
@@ -441,7 +333,7 @@ export function IconSearch({ icons }: IconSearchProps) {
{/* Active filter badges */}
{selectedCategories.length > 0 && (
<div className="flex flex-wrap items-center gap-2 mt-2">
<span className="text-sm text-muted-foreground">Selected:</span>
<span className="text-sm text-muted-foreground">Filters:</span>
<div className="flex flex-wrap gap-2">
{selectedCategories.map((category) => (
<Badge key={category} variant="secondary" className="flex items-center gap-1 pl-2 pr-1">
@@ -467,7 +359,7 @@ export function IconSearch({ icons }: IconSearchProps) {
}}
className="text-xs h-7 px-2 cursor-pointer"
>
Clear
Clear all
</Button>
</div>
)}
@@ -476,35 +368,20 @@ export function IconSearch({ icons }: IconSearchProps) {
</div>
{filteredIcons.length === 0 ? (
<div className="flex flex-col gap-8 py-12 max-w-2xl mx-auto items-center">
<div className="flex flex-col gap-8 py-12 max-w-2xl mx-auto">
<div className="text-center">
<h2 className="text-3xl sm:text-5xl font-semibold">Icon not found</h2>
<p className="text-lg text-muted-foreground mt-2">Help us expand our collection</p>
</div>
<div className="flex flex-col gap-4 items-center w-full">
<IconSubmissionContent />
<div className="mt-4 flex items-center gap-2 justify-center">
<span className="text-sm text-muted-foreground">Can't submit it yourself?</span>
<Button
className="cursor-pointer"
variant="outline"
size="sm"
onClick={() => {
setIsLazyRequestSubmitted(true)
toast("Request received!", {
description: `We've noted your request for "${searchQuery || "this icon"}". Thanks for your suggestion.`,
})
posthog.capture("lazy icon request", {
query: searchQuery,
categories: selectedCategories,
})
}}
disabled={isLazyRequestSubmitted}
>
Request this icon
</Button>
</div>
<h2 className="text-3xl sm:text-5xl font-semibold">We don't have this one...yet!</h2>
<p className="mt-4 text-muted-foreground">
{searchQuery && selectedCategories.length > 0
? `No icons found matching "${searchQuery}" with the selected filters.`
: searchQuery
? `No icons found matching "${searchQuery}".`
: selectedCategories.length > 0
? "No icons found with the selected filters."
: "No icons found matching your criteria."}
</p>
</div>
<IconSubmissionContent />
</div>
) : (
<>
@@ -519,14 +396,7 @@ export function IconSearch({ icons }: IconSearchProps) {
</div>
</div>
<IconsGrid
filteredIcons={filteredIcons}
matchedAliases={matchedAliases}
currentPage={currentPage}
iconsPerPage={iconsPerPage}
onPageChange={handlePageChange}
totalIcons={filteredIcons.length}
/>
<IconsGrid filteredIcons={filteredIcons} matchedAliases={matchedAliases} />
</>
)}
</>
@@ -536,13 +406,15 @@ export function IconSearch({ icons }: IconSearchProps) {
function IconCard({
name,
data: iconData,
matchedAlias,
}: {
name: string
data: Icon
matchedAlias?: string | null
}) {
return (
<MagicCard className="rounded-md shadow-md cursor-pointer">
<Link prefetch={false} href={`/icons/${name}`} className="group flex flex-col items-center p-3 sm:p-4">
<MagicCard className="rounded-md shadow-md">
<Link prefetch={false} href={`/icons/${name}`} className="group flex flex-col items-center p-3 sm:p-4 cursor-pointer">
<div className="relative h-12 w-12 sm:h-16 sm:w-16 mb-2">
<Image
src={`${BASE_URL}/${iconData.base}/${name}.${iconData.base}`}
@@ -551,9 +423,11 @@ function IconCard({
className="object-contain p-1 group-hover:scale-110 transition-transform duration-300"
/>
</div>
<span className="text-xs sm:text-sm text-center truncate w-full capitalize group-hover:text-rose-500 dark:group-hover:text-rose-400 transition-colors duration-200 font-medium">
<span className="text-xs sm:text-sm text-center truncate w-full capitalize group- dark:group-hover:text-rose-400 transition-colors duration-200 font-medium">
{name.replace(/-/g, " ")}
</span>
{matchedAlias && <span className="text-[10px] text-center truncate w-full mt-1">Alias: {matchedAlias}</span>}
</Link>
</MagicCard>
)
@@ -562,253 +436,17 @@ function IconCard({
interface IconsGridProps {
filteredIcons: { name: string; data: Icon }[]
matchedAliases: Record<string, string>
currentPage: number
iconsPerPage: number
onPageChange: (page: number) => void
totalIcons: number
}
function IconsGrid({ filteredIcons, matchedAliases, currentPage, iconsPerPage, onPageChange, totalIcons }: IconsGridProps) {
// Calculate pagination values
const totalPages = Math.ceil(totalIcons / iconsPerPage)
const indexOfLastIcon = currentPage * iconsPerPage
const indexOfFirstIcon = indexOfLastIcon - iconsPerPage
const currentIcons = filteredIcons.slice(indexOfFirstIcon, indexOfLastIcon)
// Calculate letter ranges for each page
const getLetterRange = (pageNum: number) => {
if (filteredIcons.length === 0) return '';
const start = (pageNum - 1) * iconsPerPage;
const end = Math.min(start + iconsPerPage - 1, filteredIcons.length - 1);
if (start >= filteredIcons.length) return '';
const firstLetter = filteredIcons[start].name.charAt(0).toUpperCase();
const lastLetter = filteredIcons[end].name.charAt(0).toUpperCase();
return firstLetter === lastLetter ? firstLetter : `${firstLetter} - ${lastLetter}`;
};
// Get current page letter range
const currentLetterRange = getLetterRange(currentPage);
// Handle direct page input
const [pageInput, setPageInput] = useState(currentPage.toString());
useEffect(() => {
setPageInput(currentPage.toString());
}, [currentPage]);
const handlePageInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setPageInput(e.target.value);
};
const handlePageInputSubmit = (e: React.FormEvent) => {
e.preventDefault();
const pageNumber = parseInt(pageInput);
if (!isNaN(pageNumber) && pageNumber >= 1 && pageNumber <= totalPages) {
onPageChange(pageNumber);
} else {
// Reset to current page if invalid
setPageInput(currentPage.toString());
}
};
function IconsGrid({ filteredIcons, matchedAliases }: IconsGridProps) {
return (
<>
<AnimatePresence mode="wait">
<motion.div
key={currentPage}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -20 }}
transition={{ duration: 0.3 }}
className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 xl:grid-cols-8 gap-4 mt-2"
>
{currentIcons.map(({ name, data }) => (
<IconCard key={name} name={name} data={data} />
))}
</motion.div>
</AnimatePresence>
{totalPages > 1 && (
<div className="flex flex-col gap-4 mt-8">
{/* Mobile view: centered content */}
<div className="text-sm text-muted-foreground text-center md:text-left md:hidden">
Showing {indexOfFirstIcon + 1}-{Math.min(indexOfLastIcon, totalIcons)} of {totalIcons} icons
{currentLetterRange && (
<span className="ml-2 font-medium">({currentLetterRange})</span>
)}
</div>
{/* Desktop view layout */}
<div className="hidden md:flex justify-between items-center">
<div className="text-sm text-muted-foreground">
Showing {indexOfFirstIcon + 1}-{Math.min(indexOfLastIcon, totalIcons)} of {totalIcons} icons
{currentLetterRange && (
<span className="ml-2 font-medium">({currentLetterRange})</span>
)}
</div>
<div className="flex items-center gap-4">
{/* Page input and total count */}
<form onSubmit={handlePageInputSubmit} className="flex items-center gap-2">
<Input
type="number"
min={1}
max={totalPages}
value={pageInput}
onChange={handlePageInputChange}
className="w-16 h-8 text-center cursor-text"
aria-label="Go to page"
/>
<span className="text-sm whitespace-nowrap">of {totalPages}</span>
<Button type="submit" size="sm" variant="outline" className="h-8 cursor-pointer">Go</Button>
</form>
{/* Pagination controls */}
<div className="flex items-center">
<Button
onClick={() => onPageChange(currentPage - 1)}
disabled={currentPage === 1}
size="sm"
variant="outline"
className="h-8 rounded-r-none cursor-pointer"
aria-label="Previous page"
>
<ChevronLeft className="h-4 w-4" />
</Button>
<div className="flex items-center overflow-hidden">
{Array.from({ length: Math.min(5, totalPages) }, (_, i) => {
// Show pages around current page
let pageNum;
if (totalPages <= 5) {
pageNum = i + 1;
} else if (currentPage <= 3) {
pageNum = i + 1;
} else if (currentPage >= totalPages - 2) {
pageNum = totalPages - 4 + i;
} else {
pageNum = currentPage - 2 + i;
}
// Calculate letter range for this page
const letterRange = getLetterRange(pageNum);
return (
<Button
key={pageNum}
onClick={() => onPageChange(pageNum)}
variant={pageNum === currentPage ? "default" : "outline"}
size="sm"
className={`h-8 w-8 p-0 rounded-none relative group cursor-pointer transition-colors duration-200 ${
pageNum === currentPage ? "font-medium" : ""
}`}
aria-label={`Page ${pageNum}`}
aria-current={pageNum === currentPage ? "page" : undefined}
>
{pageNum}
{letterRange && (
<span className="absolute -top-8 left-1/2 transform -translate-x-1/2 bg-popover text-popover-foreground px-2 py-1 rounded text-xs opacity-0 group-hover:opacity-100 transition-opacity shadow-md whitespace-nowrap">
{letterRange}
</span>
)}
</Button>
);
})}
</div>
<Button
onClick={() => onPageChange(currentPage + 1)}
disabled={currentPage === totalPages}
size="sm"
variant="outline"
className="h-8 rounded-l-none cursor-pointer"
aria-label="Next page"
>
<ChevronRight className="h-4 w-4" />
</Button>
</div>
</div>
</div>
{/* Mobile-only pagination layout - centered */}
<div className="flex flex-col items-center gap-4 md:hidden">
{/* Mobile pagination controls */}
<div className="flex items-center">
<Button
onClick={() => onPageChange(currentPage - 1)}
disabled={currentPage === 1}
size="sm"
variant="outline"
className="h-8 rounded-r-none cursor-pointer"
aria-label="Previous page"
>
<ChevronLeft className="h-4 w-4" />
</Button>
<div className="flex items-center overflow-hidden">
{Array.from({ length: Math.min(5, totalPages) }, (_, i) => {
// Show pages around current page - same logic as desktop
let pageNum;
if (totalPages <= 5) {
pageNum = i + 1;
} else if (currentPage <= 3) {
pageNum = i + 1;
} else if (currentPage >= totalPages - 2) {
pageNum = totalPages - 4 + i;
} else {
pageNum = currentPage - 2 + i;
}
return (
<Button
key={pageNum}
onClick={() => onPageChange(pageNum)}
variant={pageNum === currentPage ? "default" : "outline"}
size="sm"
className={`h-8 w-8 p-0 rounded-none cursor-pointer ${
pageNum === currentPage ? "font-medium" : ""
}`}
aria-label={`Page ${pageNum}`}
aria-current={pageNum === currentPage ? "page" : undefined}
>
{pageNum}
</Button>
);
})}
</div>
<Button
onClick={() => onPageChange(currentPage + 1)}
disabled={currentPage === totalPages}
size="sm"
variant="outline"
className="h-8 rounded-l-none cursor-pointer"
aria-label="Next page"
>
<ChevronRight className="h-4 w-4" />
</Button>
</div>
{/* Mobile page input */}
<form onSubmit={handlePageInputSubmit} className="flex items-center gap-2">
<Input
type="number"
min={1}
max={totalPages}
value={pageInput}
onChange={handlePageInputChange}
className="w-16 h-8 text-center cursor-text"
aria-label="Go to page"
/>
<span className="text-sm whitespace-nowrap">of {totalPages}</span>
<Button type="submit" size="sm" variant="outline" className="h-8 cursor-pointer">Go</Button>
</form>
</div>
</div>
)}
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 xl:grid-cols-8 gap-4 mt-2">
{filteredIcons.slice(0, 120).map(({ name, data }) => (
<IconCard key={name} name={name} data={data} matchedAlias={matchedAliases[name] || null} />
))}
</div>
{filteredIcons.length > 120 && <p className="text-sm text-muted-foreground">And {filteredIcons.length - 120} more...</p>}
</>
)
}

View File

@@ -1,39 +1,49 @@
import { BASE_URL, BROWSE_KEYWORDS, DEFAULT_OG_IMAGE, GITHUB_URL, ORGANIZATION_NAME, ORGANIZATION_SCHEMA, SITE_NAME, SITE_TAGLINE, TITLE_SEPARATOR, WEB_URL, getBrowseDescription } from "@/constants"
import { BASE_URL } from "@/constants"
import { getIconsArray } from "@/lib/api"
import type { Metadata } from "next"
import { IconSearch } from "./components/icon-search"
import { StructuredData } from "@/components/structured-data"
export async function generateMetadata(): Promise<Metadata> {
const icons = await getIconsArray()
const totalIcons = icons.length
const title = `Browse Icons ${TITLE_SEPARATOR} ${SITE_NAME}`
const description = getBrowseDescription(totalIcons)
return {
title,
description,
keywords: BROWSE_KEYWORDS,
title: "Browse Icons | Free Dashboard Icons",
description: `Search and browse through our collection of ${totalIcons} curated icons for services, applications and tools, designed specifically for dashboards and app directories.`,
keywords: [
"browse icons",
"dashboard icons",
"icon search",
"service icons",
"application icons",
"tool icons",
"web dashboard",
"app directory",
],
openGraph: {
title: `Browse Icons ${TITLE_SEPARATOR} ${SITE_NAME} ${TITLE_SEPARATOR} ${SITE_TAGLINE}`,
description,
title: "Browse Icons | Free Dashboard Icons",
description: `Search and browse through our collection of ${totalIcons} curated icons for services, applications and tools, designed specifically for dashboards and app directories.`,
type: "website",
url: `${WEB_URL}/icons`,
images: [DEFAULT_OG_IMAGE],
url: `${BASE_URL}/icons`,
images: [
{
url: "/og-image.png",
width: 1200,
height: 630,
alt: "Browse Dashboard Icons Collection",
type: "image/png",
},
],
},
twitter: {
card: "summary_large_image",
title: `Browse Icons ${TITLE_SEPARATOR} ${SITE_NAME} ${TITLE_SEPARATOR} ${SITE_TAGLINE}`,
description,
images: [DEFAULT_OG_IMAGE.url],
title: "Browse Icons | Free Dashboard Icons",
description: `Search and browse through our collection of ${totalIcons} curated icons for services, applications and tools, designed specifically for dashboards and app directories.`,
images: ["/og-image-browse.png"],
},
alternates: {
canonical: `${WEB_URL}/icons`,
canonical: `${BASE_URL}/icons`,
},
other: {
"revisit-after": "3 days",
}
}
}
@@ -41,38 +51,20 @@ export const dynamic = "force-static"
export default async function IconsPage() {
const icons = await getIconsArray()
const gallerySchema = {
"@context": "https://schema.org",
"@type": "ImageGallery",
"name": `${SITE_NAME} - Browse ${icons.length} Icons - ${SITE_TAGLINE}`,
"description": getBrowseDescription(icons.length),
"url": `${WEB_URL}/icons`,
"numberOfItems": icons.length,
"creator": {
"@type": "Organization",
"name": ORGANIZATION_NAME,
"url": GITHUB_URL
}
}
return (
<>
<StructuredData data={gallerySchema} id="gallery-schema" />
<div className="isolate overflow-hidden">
<div className="py-8">
<div className="space-y-4 mb-8 mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
<div>
<h1 className="text-3xl font-bold">Icons</h1>
<p className="text-muted-foreground">Search our collection of {icons.length} icons - {SITE_TAGLINE}.</p>
</div>
<div className="isolate overflow-hidden">
<div className="py-8">
<div className="space-y-4 mb-8 mx-auto max-w-7xl">
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
<div>
<h1 className="text-3xl font-bold">Browse icons</h1>
<p className="text-muted-foreground">Search through our collection of {icons.length} beautiful icons.</p>
</div>
<IconSearch icons={icons} />
</div>
<IconSearch icons={icons} />
</div>
</div>
</>
</div>
)
}

View File

@@ -2,14 +2,13 @@ import { PostHogProvider } from "@/components/PostHogProvider"
import { Footer } from "@/components/footer"
import { HeaderWrapper } from "@/components/header-wrapper"
import { LicenseNotice } from "@/components/license-notice"
import { WebsiteStructuredData } from "@/components/structured-data"
import { getTotalIcons } from "@/lib/api"
import type { Metadata, Viewport } from "next"
import { Inter } from "next/font/google"
import { Toaster } from "sonner"
import "./globals.css"
import { DEFAULT_KEYWORDS, DEFAULT_OG_IMAGE, GITHUB_URL, ORGANIZATION_NAME, ORGANIZATION_SCHEMA, SITE_NAME, SITE_TAGLINE, WEB_URL, getDescription, getWebsiteSchema, websiteFullTitle, websiteTitle } from "@/constants"
import { ThemeProvider } from "./theme-provider"
import { getDescription, websiteTitle } from "@/constants"
const inter = Inter({
variable: "--font-inter",
@@ -28,13 +27,12 @@ export const viewport: Viewport = {
export async function generateMetadata(): Promise<Metadata> {
const { totalIcons } = await getTotalIcons()
const description = getDescription(totalIcons)
return {
metadataBase: new URL(WEB_URL),
metadataBase: new URL("https://dashboardicons.com"),
title: websiteTitle,
description,
keywords: DEFAULT_KEYWORDS,
description: getDescription(totalIcons),
keywords: ["dashboard icons", "service icons", "application icons", "tool icons", "web dashboard", "app directory"],
robots: {
index: true,
follow: true,
@@ -44,23 +42,33 @@ export async function generateMetadata(): Promise<Metadata> {
googleBot: "index, follow",
},
openGraph: {
siteName: SITE_NAME,
siteName: "Dashboard Icons",
type: "website",
locale: "en_US",
title: websiteFullTitle,
description,
url: WEB_URL,
images: [DEFAULT_OG_IMAGE],
title: websiteTitle,
description: getDescription(totalIcons),
url: "https://dashboardicons.com",
images: [
{
url: "/og-image.png",
width: 1200,
height: 630,
alt: "Dashboard Icons",
type: "image/png",
},
],
},
twitter: {
card: "summary_large_image",
title: websiteFullTitle,
description,
images: [DEFAULT_OG_IMAGE.url],
site: "@homarr_app",
creator: "@homarr_app",
title: websiteTitle,
description: getDescription(totalIcons),
images: ["/og-image.png"],
},
applicationName: SITE_NAME,
applicationName: "Dashboard Icons",
appleWebApp: {
title: SITE_NAME,
title: "Dashboard Icons",
statusBarStyle: "default",
capable: true,
},
@@ -80,29 +88,14 @@ export async function generateMetadata(): Promise<Metadata> {
],
},
manifest: "/site.webmanifest",
authors: [{ name: ORGANIZATION_NAME, url: GITHUB_URL }],
creator: ORGANIZATION_NAME,
publisher: ORGANIZATION_NAME,
category: "Icons",
classification: "Dashboard Design Resources",
other: {
"revisit-after": "7 days",
},
}
}
export default async function RootLayout({ children }: Readonly<{ children: React.ReactNode }>) {
const { totalIcons } = await getTotalIcons()
const websiteSchema = getWebsiteSchema(totalIcons)
export default function RootLayout({ children }: Readonly<{ children: React.ReactNode }>) {
return (
<html lang="en" suppressHydrationWarning>
<body className={`${inter.variable} antialiased bg-background flex flex-col min-h-screen`}>
<PostHogProvider>
<WebsiteStructuredData
websiteSchema={websiteSchema}
organizationSchema={ORGANIZATION_SCHEMA}
/>
<ThemeProvider attribute="class" defaultTheme="system" enableSystem disableTransitionOnChange>
<HeaderWrapper />
<main className="flex-grow">{children}</main>

View File

@@ -15,9 +15,9 @@ export default function NotFound({
<div className="mx-auto w-16 h-16 bg-red-100 dark:bg-red-900/20 rounded-full flex items-center justify-center text-red-600 dark:text-red-400">
<AlertTriangle className="w-8 h-8" />
</div>
<h1 className="text-2xl sm:text-3xl font-bold mt-6">Not found</h1>
<h1 className="text-2xl sm:text-3xl font-bold mt-6">Icon not found</h1>
<p className="text-muted-foreground mt-3 max-w-md">
This icon does not exist or could not be loaded.
The icon you are looking for could not be found or there was an error loading it.
</p>
</div>
@@ -25,16 +25,16 @@ export default function NotFound({
<Button asChild variant="outline">
<Link href="/icons">
<ArrowLeft className="mr-2 h-4 w-4" />
Back to icons
Back to all icons
</Link>
</Button>
</div>
<div className="border-t border-border pt-8 mt-8">
<div className="text-center mb-6">
<h2 className="text-xl font-semibold">Missing an icon?</h2>
<h2 className="text-xl font-semibold">Can't find what you're looking for?</h2>
<p className="text-muted-foreground mt-2">
Submit a new icon or suggest improvements to our collection.
Contribute to our icon collection by suggesting a new icon or improving an existing one.
</p>
</div>

View File

@@ -1,37 +1,38 @@
import { HeroSection } from "@/components/hero"
import { RecentlyAddedIcons } from "@/components/recently-added-icons"
import { StructuredData } from "@/components/structured-data"
import { BASE_URL, DEFAULT_KEYWORDS, DEFAULT_OG_IMAGE, GITHUB_URL, ORGANIZATION_NAME, ORGANIZATION_SCHEMA, SITE_NAME, SITE_TAGLINE, WEB_URL, REPO_NAME, getHomeDescription, websiteFullTitle, websiteTitle } from "@/constants"
import { BASE_URL, getDescription, REPO_NAME, websiteTitle } from "@/constants"
import { getRecentlyAddedIcons, getTotalIcons } from "@/lib/api"
import type { Metadata } from "next"
export async function generateMetadata(): Promise<Metadata> {
const { totalIcons } = await getTotalIcons()
const description = getHomeDescription(totalIcons)
return {
title: websiteTitle,
description,
keywords: DEFAULT_KEYWORDS,
robots: {
index: true,
follow: true,
},
description: getDescription(totalIcons),
keywords: ["dashboard icons", "service icons", "application icons", "tool icons", "web dashboard", "app directory"],
openGraph: {
title: websiteFullTitle,
description,
title: websiteTitle,
description: getDescription(totalIcons),
type: "website",
url: WEB_URL,
images: [DEFAULT_OG_IMAGE],
url: BASE_URL,
images: [
{
url: "/og-image.png",
width: 1200,
height: 630,
alt: "Dashboard Icons",
},
],
},
twitter: {
title: websiteFullTitle,
description,
title: websiteTitle,
description: getDescription(totalIcons),
card: "summary_large_image",
images: [DEFAULT_OG_IMAGE.url],
images: ["/og-image.png"],
},
alternates: {
canonical: WEB_URL,
canonical: BASE_URL,
},
}
}
@@ -49,11 +50,9 @@ export default async function Home() {
const stars = await getGitHubStars()
return (
<>
<div className="flex flex-col min-h-screen">
<HeroSection totalIcons={totalIcons} stars={stars} />
<RecentlyAddedIcons icons={recentIcons} />
</div>
</>
<div className="flex flex-col min-h-screen">
<HeroSection totalIcons={totalIcons} stars={stars} />
<RecentlyAddedIcons icons={recentIcons} />
</div>
)
}

View File

@@ -7,7 +7,7 @@ import { Suspense, useEffect } from "react"
export function PostHogProvider({ children }: { children: React.ReactNode }) {
useEffect(() => {
if (process.env.DISABLE_POSTHOG === "true") return
if (process.env.NODE_ENV === "development" || process.env.DISABLE_POSTHOG === "true") return
// biome-ignore lint/style/noNonNullAssertion: The NEXT_PUBLIC_POSTHOG_KEY environment variable is guaranteed to be set in production.
posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {
ui_host: "https://eu.posthog.com",

View File

@@ -1,14 +1,15 @@
import { useEffect, useRef } from "react"
import React from "react"
export function Carbon() {
// biome-ignore lint/style/noNonNullAssertion: <explanation>
const ref = useRef<HTMLDivElement>(null!)
const ref = React.useRef<HTMLDivElement>(null!)
if (process.env.NODE_ENV === "development") {
return null
}
useEffect(() => {
React.useEffect(() => {
const serve = "CW7IP27L"
const placement = "dashboardiconscom"
const placement = "homarrdev"
ref.current.innerHTML = ""
const s = document.createElement("script")
s.id = "_carbonads_js"
@@ -20,6 +21,7 @@ export function Carbon() {
<>
<style>
{`
#carbonads_1 { display: none; }
#carbonads * { margin: initial; padding: initial; }
#carbonads {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
@@ -77,7 +79,7 @@ export function Carbon() {
}
`}
</style>
<div className="m-4">
<div className=" shadow-xl flex flex-col m-4 space-y-2 rounded-l-lg">
<div ref={ref} className="carbon-outer" />
</div>
</>

View File

@@ -0,0 +1,138 @@
"use client"
import { CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command"
import { useMediaQuery } from "@/hooks/use-media-query"
import { fuzzySearch } from "@/lib/utils"
import { Icon } from "@/types/icons"
import { useRouter } from "next/navigation"
import { useCallback, useEffect, useState } from "react"
interface CommandMenuProps {
icons: {
name: string
data: {
categories: string[]
aliases: string[]
[key: string]: unknown
}
}[]
triggerButtonId?: string
open?: boolean
onOpenChange?: (open: boolean) => void
}
export function CommandMenu({ icons, open: externalOpen, onOpenChange: externalOnOpenChange }: CommandMenuProps) {
const router = useRouter()
const [internalOpen, setInternalOpen] = useState(false)
const [query, setQuery] = useState("")
const isDesktop = useMediaQuery("(min-width: 768px)")
// Use either external or internal state for controlling open state
const isOpen = externalOpen !== undefined ? externalOpen : internalOpen
// Wrap setIsOpen in useCallback to fix dependency issue
const setIsOpen = useCallback(
(value: boolean) => {
if (externalOnOpenChange) {
externalOnOpenChange(value)
} else {
setInternalOpen(value)
}
},
[externalOnOpenChange],
)
const filteredIcons = getFilteredIcons(icons, query)
useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
if (
(e.key === "k" && (e.metaKey || e.ctrlKey)) ||
(e.key === "/" && document.activeElement?.tagName !== "INPUT" && document.activeElement?.tagName !== "TEXTAREA")
) {
e.preventDefault()
setIsOpen(!isOpen)
}
}
document.addEventListener("keydown", handleKeyDown)
return () => document.removeEventListener("keydown", handleKeyDown)
}, [isOpen, setIsOpen])
function getFilteredIcons(iconList: CommandMenuProps["icons"], query: string) {
if (!query) {
// Return a limited number of icons when no query is provided
return iconList.slice(0, 8)
}
// Calculate scores for each icon
const scoredIcons = iconList.map((icon) => {
// Calculate scores for different fields
const nameScore = fuzzySearch(icon.name, query) * 2.0 // Give more weight to name matches
// Get max score from aliases
const aliasScore =
icon.data.aliases && icon.data.aliases.length > 0
? Math.max(...icon.data.aliases.map((alias) => fuzzySearch(alias, query))) * 1.8 // Increased weight for aliases
: 0
// Get max score from categories
const categoryScore =
icon.data.categories && icon.data.categories.length > 0
? Math.max(...icon.data.categories.map((category) => fuzzySearch(category, query)))
: 0
// Use the highest score
const score = Math.max(nameScore, aliasScore, categoryScore)
return { icon, score, matchedField: score === nameScore ? "name" : score === aliasScore ? "alias" : "category" }
})
// Filter icons with a minimum score and sort by highest score
return scoredIcons
.filter((item) => item.score > 0.3) // Higher threshold for more accurate results
.sort((a, b) => b.score - a.score)
.slice(0, 20) // Limit the number of results
.map((item) => item.icon)
}
const handleSelect = (name: string) => {
setIsOpen(false)
router.push(`/icons/${name}`)
}
return (
<CommandDialog open={isOpen} onOpenChange={setIsOpen}>
<CommandInput placeholder="Search for icons by name, category, or purpose..." value={query} onValueChange={setQuery} />
<CommandList>
<CommandEmpty>No matching icons found. Try a different search term or browse all icons.</CommandEmpty>
<CommandGroup heading="Icons">
{filteredIcons.map(({ name, data }) => {
// Find matched alias for display if available
const matchedAlias =
query && data.aliases && data.aliases.length > 0
? data.aliases.find((alias) => alias.toLowerCase().includes(query.toLowerCase()))
: null
return (
<CommandItem key={name} value={name} onSelect={() => handleSelect(name)} className="flex items-center gap-2 cursor-pointer">
<div className="flex-shrink-0 h-5 w-5 relative">
<div className="h-5 w-5 bg-rose-100 dark:bg-rose-900/30 rounded-md flex items-center justify-center">
<span className="text-[10px] font-medium text-rose-800 dark:text-rose-300">{name.substring(0, 2).toUpperCase()}</span>
</div>
</div>
<span className="flex-grow capitalize">{name.replace(/-/g, " ")}</span>
{matchedAlias && <span className="text-xs text-primary-500 truncate max-w-[100px]">alias: {matchedAlias}</span>}
{!matchedAlias && data.categories && data.categories.length > 0 && (
<span className="text-xs text-muted-foreground truncate max-w-[100px]">
{data.categories[0].replace(/-/g, " ").replace(/\b\w/g, (c) => c.toUpperCase())}
</span>
)}
</CommandItem>
)
})}
</CommandGroup>
</CommandList>
</CommandDialog>
)
}

View File

@@ -37,7 +37,7 @@ export function Footer() {
<div className="flex flex-col gap-3">
<h3 className="font-bold text-lg text-foreground/90">Dashboard Icons</h3>
<p className="text-sm text-muted-foreground leading-relaxed">
Collection of icons for applications, services, and tools - designed for dashboards and app directories.
A collection of curated icons for services, applications and tools, designed specifically for dashboards and app directories.
</p>
</div>

View File

@@ -3,14 +3,42 @@
import { IconSubmissionForm } from "@/components/icon-submission-form"
import { ThemeSwitcher } from "@/components/theme-switcher"
import { REPO_PATH } from "@/constants"
import { getIconsArray } from "@/lib/api"
import type { IconWithName } from "@/types/icons"
import { motion } from "framer-motion"
import { Github } from "lucide-react"
import { Github, Search } from "lucide-react"
import Link from "next/link"
import { useEffect, useState } from "react"
import { CommandMenu } from "./command-menu"
import { HeaderNav } from "./header-nav"
import { Button } from "./ui/button"
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./ui/tooltip"
export function Header() {
const [iconsData, setIconsData] = useState<IconWithName[]>([])
const [isLoaded, setIsLoaded] = useState(false)
const [commandMenuOpen, setCommandMenuOpen] = useState(false)
useEffect(() => {
async function loadIcons() {
try {
const icons = await getIconsArray()
setIconsData(icons)
setIsLoaded(true)
} catch (error) {
console.error("Failed to load icons:", error)
setIsLoaded(true)
}
}
loadIcons()
}, [])
// Function to open the command menu
const openCommandMenu = () => {
setCommandMenuOpen(true)
}
return (
<motion.header
className="border-b sticky top-0 z-50 backdrop-blur-2xl bg-background/50 border-border/50"
@@ -28,6 +56,34 @@ export function Header() {
</div>
</div>
<div className="flex items-center gap-2 md:gap-4">
{/* Desktop search button */}
<div className="hidden md:block">
<Button
variant="outline"
className="gap-2 cursor-pointer transition-all duration-300"
onClick={openCommandMenu}
>
<Search className="h-4 w-4 transition-all duration-300" />
<span>Find icons</span>
<kbd className="pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border border-border/80 bg-muted/80 px-1.5 font-mono text-[10px] font-medium opacity-100">
<span className="text-xs"></span>K
</kbd>
</Button>
</div>
{/* Mobile search button */}
<div className="md:hidden">
<Button
variant="ghost"
size="icon"
className="rounded-lg cursor-pointer transition-all duration-300 hover:ring-2 "
onClick={openCommandMenu}
>
<Search className="h-5 w-5 transition-all duration-300" />
<span className="sr-only">Find icons</span>
</Button>
</div>
<div className="hidden md:flex items-center gap-2 md:gap-4">
<IconSubmissionForm />
<TooltipProvider>
@@ -54,6 +110,9 @@ export function Header() {
<ThemeSwitcher />
</div>
</div>
{/* Single instance of CommandMenu */}
{isLoaded && <CommandMenu icons={iconsData} open={commandMenuOpen} onOpenChange={setCommandMenuOpen} />}
</motion.header>
)
}

View File

@@ -205,74 +205,25 @@ export function HeroSection({ totalIcons, stars }: { totalIcons: number; stars:
/>
</div>
<div className="relative z-10 container mx-auto px-4 sm:px-6 lg:px-8 mt-4 py-20">
<div className="relative z-10 container mx-auto px-4 md:px-6 mt-4 py-20">
<div className="max-w-4xl mx-auto text-center flex flex-col gap-4 ">
<h1 className="relative text-3xl sm:text-5xl md:text-7xl font-bold mb-4 md:mb-8 tracking-tight motion-preset-slide-up motion-duration-500 ">
<h1 className="relative text-3xl sm:text-5xl md:text-7xl font-bold mb-4 md:mb-8 tracking-tight motion-preset-slide-up motion-duration-2000 ">
Your definitive source for
<motion.span
className="absolute -right-1 -bottom-3"
initial={{ opacity: 0, scale: 0.5, x: -20, y: -10 }}
animate={{ opacity: 1, scale: 1, x: 0, y: 0 }}
transition={{
duration: 0.5,
delay: 0.3,
ease: "easeOut"
}}
>
<motion.div
animate={{
y: [0, -3, 0],
rotate: [0, 5, 0]
}}
transition={{
duration: 3,
repeat: Infinity,
repeatType: "reverse",
ease: "easeInOut"
}}
>
<Sparkles className="text-rose-500 h-8 w-8 sm:h-12 sm:w-12 md:h-16 md:w-12" />
</motion.div>
</motion.span>
<Sparkles className="absolute -right-1 -bottom-3 text-rose-500 h-8 w-8 sm:h-12 sm:w-12 md:h-16 md:w-12 motion-delay-300 motion-preset-seesaw-lg motion-scale-in-[0.5] motion-translate-x-in-[-120%] motion-translate-y-in-[-60%] motion-opacity-in-[33%] motion-rotate-in-[-1080deg] motion-blur-in-[10px] motion-duration-[1s] motion-delay-[0.13s]/scale motion-duration-[0.13s]/opacity motion-duration-[0.40s]/rotate motion-duration-[0.05s]/blur motion-delay-[0.20s]/blur motion-ease-spring-bouncier" />
<br />
<motion.span
className="absolute -left-1 -top-3"
initial={{ opacity: 0, scale: 0.5, x: 20, y: -10 }}
animate={{ opacity: 1, scale: 1, x: 0, y: 0 }}
transition={{
duration: 0.5,
delay: 0.3,
ease: "easeOut"
}}
>
<motion.div
animate={{
y: [0, -3, 0],
rotate: [0, -5, 0]
}}
transition={{
duration: 4,
repeat: Infinity,
repeatType: "reverse",
ease: "easeInOut"
}}
>
<Sparkles className="text-rose-500 h-5 w-5 sm:h-8 sm:w-8 md:h-12 md:w-12" />
</motion.div>
</motion.span>
<Sparkles className="absolute -left-1 -top-3 text-rose-500 h-5 w-5 sm:h-8 sm:w-8 md:h-12 md:w-12 motion-delay-300 motion-preset-seesaw-lg motion-scale-in-[0.5] motion-translate-x-in-[159%] motion-translate-y-in-[-60%] motion-opacity-in-[33%] motion-rotate-in-[-1080deg] motion-blur-in-[10px] motion-duration-[1s] motion-delay-[0.13s]/scale motion-duration-[0.13s]/opacity motion-duration-[0.40s]/rotate motion-duration-[0.05s]/blur motion-delay-[0.20s]/blur motion-ease-spring-bouncier" />
<AuroraText colors={["#FA5352", "#FA5352", "orange"]}>dashboard icons</AuroraText>
</h1>
<p className="text-sm sm:text-base md:text-xl text-muted-foreground leading-relaxed mb-8 font-light tracking-wide max-w-2xl mx-auto px-4 motion-preset-slide-down motion-duration-500">
A collection of{" "}
<NumberTicker value={totalIcons} startValue={1000} className="font-bold tracking-tighter text-muted-foreground" /> curated icons
<p className="text-sm sm:text-base md:text-xl text-muted-foreground leading-relaxed mb-8 font-light tracking-wide max-w-2xl mx-auto px-4 motion-preset-slide-down motion-duration-2000">
A collection of <NumberTicker value={totalIcons} className="font-bold tracking-tighter text-muted-foreground" /> curated icons
for services, applications and tools, designed specifically for dashboards and app directories.
</p>
<div className="flex flex-col gap-4 max-w-3xl mx-auto">
<SearchInput searchQuery={searchQuery} setSearchQuery={setSearchQuery} totalIcons={totalIcons} />
<div className="w-full flex gap-3 md:gap-4 flex-wrap justify-center motion-preset-slide-down motion-duration-500">
<div className="w-full flex gap-3 md:gap-4 flex-wrap justify-center motion-preset-slide-down motion-duration-2000">
<Link href="/icons">
<InteractiveHoverButton className="rounded-md bg-input/30">Browse icons</InteractiveHoverButton>
<InteractiveHoverButton className="rounded-md bg-input/30">Explore icons</InteractiveHoverButton>
</Link>
<GiveUsAStarButton stars={stars} />
<GiveUsMoneyButton />
@@ -497,12 +448,12 @@ export function GiveUsMoneyButton() {
<div className="flex justify-between items-center pt-2">
<Link href={openCollectiveUrl} target="_blank" rel="noopener noreferrer">
<Button variant="default" size="sm" className="bg-primary hover:bg-primary/90">
Support
Donate
</Button>
</Link>
<Link href={`${openCollectiveUrl}/transactions`} target="_blank" rel="noopener noreferrer">
<Button variant="link" size="sm" className="flex items-center gap-1 text-xs text-secondary-foreground">
View transactions
View expenses
<ExternalLink className="h-3 w-3" />
</Button>
</Link>
@@ -526,7 +477,7 @@ function SearchInput({ searchQuery, setSearchQuery, totalIcons }: SearchInputPro
name="q"
autoFocus
type="search"
placeholder="Search for icons..."
placeholder={`Find any of ${totalIcons} icons by name or category...`}
className="pl-10 h-10 md:h-12 rounded-lg w-full border-border focus:border-primary/20 text-sm md:text-base"
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}

View File

@@ -142,6 +142,7 @@ export function IconDetails({ icon, iconData, authorData }: IconDetailsProps) {
}
const renderVariant = (format: string, iconName: string, theme?: "light" | "dark") => {
const { resolvedTheme } = useTheme()
const variantName = theme && iconColorVariants?.[theme] ? iconColorVariants[theme] : iconName
const imageUrl = `${BASE_URL}/${format}/${variantName}.${format}`
const githubUrl = `${REPO_PATH}/tree/main/${format}/${iconName}.${format}`
@@ -150,7 +151,7 @@ export function IconDetails({ icon, iconData, authorData }: IconDetailsProps) {
return (
<TooltipProvider key={variantKey} delayDuration={500}>
<MagicCard className="p-0 rounded-md">
<MagicCard gradientColor={resolvedTheme === "dark" ? "#262626" : "#D9D9D955"} className="p-0 rounded-md">
<div className="flex flex-col items-center p-4 transition-all">
<Tooltip>
<TooltipTrigger asChild>
@@ -207,7 +208,6 @@ export function IconDetails({ icon, iconData, authorData }: IconDetailsProps) {
size="icon"
className="h-8 w-8 rounded-lg cursor-pointer"
onClick={(e) => handleDownload(e, imageUrl, `${iconName}.${format}`)}
aria-label={`Download ${iconName} in ${format} format${theme ? ` (${theme} theme)` : ""}`}
>
<Download className="w-4 h-4" />
</Button>
@@ -224,7 +224,6 @@ export function IconDetails({ icon, iconData, authorData }: IconDetailsProps) {
size="icon"
className="h-8 w-8 rounded-lg cursor-pointer"
onClick={(e) => handleCopy(imageUrl, `btn-${variantKey}`, e)}
aria-label={`Copy URL for ${iconName} in ${format} format${theme ? ` (${theme} theme)` : ""}`}
>
{copiedVariants[`btn-${variantKey}`] ? <Check className="w-4 h-4 text-green-500" /> : <Copy className="w-4 h-4" />}
</Button>
@@ -236,18 +235,8 @@ export function IconDetails({ icon, iconData, authorData }: IconDetailsProps) {
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="outline"
size="icon"
className="h-8 w-8 rounded-lg"
asChild
>
<Link
href={githubUrl}
target="_blank"
rel="noopener noreferrer"
aria-label={`View ${iconName} ${format} file on GitHub`}
>
<Button variant="outline" size="icon" className="h-8 w-8 rounded-lg" asChild>
<Link href={githubUrl} target="_blank" rel="noopener noreferrer">
<Github className="w-4 h-4" />
</Link>
</Button>
@@ -264,7 +253,7 @@ export function IconDetails({ icon, iconData, authorData }: IconDetailsProps) {
}
return (
<div className="container mx-auto pt-12 pb-14 px-4 sm:px-6 lg:px-8">
<div className="container mx-auto pt-12 pb-14">
<div className="grid grid-cols-1 lg:grid-cols-4 gap-6">
{/* Left Column: Icon Info and Author */}
<div className="lg:col-span-1">
@@ -318,7 +307,7 @@ export function IconDetails({ icon, iconData, authorData }: IconDetailsProps) {
{iconData.categories && iconData.categories.length > 0 && (
<div>
<h3 className="text-sm font-semibold text-muted-foreground mb-2">Categories</h3>
<h3 className="text-sm font-semibold text-muted-foreground">Categories</h3>
<div className="flex flex-wrap gap-2">
{iconData.categories.map((category) => (
<Link key={category} href={`/icons?category=${encodeURIComponent(category)}`} className="cursor-pointer">
@@ -339,7 +328,7 @@ export function IconDetails({ icon, iconData, authorData }: IconDetailsProps) {
{iconData.aliases && iconData.aliases.length > 0 && (
<div>
<h3 className="text-sm font-semibold text-muted-foreground mb-2">Aliases</h3>
<h3 className="text-sm font-semibold text-muted-foreground">Aliases</h3>
<div className="flex flex-wrap gap-2">
{iconData.aliases.map((alias) => (
<Badge
@@ -356,17 +345,19 @@ export function IconDetails({ icon, iconData, authorData }: IconDetailsProps) {
)}
<div>
<h3 className="text-sm font-semibold text-muted-foreground mb-2">About this icon</h3>
<h3 className="text-sm font-semibold text-muted-foreground">About this icon</h3>
<div className="text-xs text-muted-foreground space-y-2">
<p>
Available in {availableFormats.length > 1
? `${availableFormats.length} formats (${availableFormats.map((f) => f.toUpperCase()).join(", ")}) `
: `${availableFormats[0].toUpperCase()} format `}
Available in{" "}
{availableFormats.length > 1
? `${availableFormats.length} formats (${availableFormats.map((f) => f.toUpperCase()).join(", ")})`
: `${availableFormats[0].toUpperCase()} format`}{" "}
with a base format of {iconData.base.toUpperCase()}.
{iconData.colors && " Includes both light and dark theme variants for better integration with different UI designs."}
</p>
<p>
Perfect for adding to dashboards, app directories, documentation, or anywhere you need the {icon.replace(/-/g, " ")} logo.
Use the {icon} icon in your web applications, dashboards, or documentation to enhance visual communication and user
experience.
</p>
</div>
</div>
@@ -422,7 +413,7 @@ export function IconDetails({ icon, iconData, authorData }: IconDetailsProps) {
<CardContent>
<div className="space-y-6">
<div className="">
<h3 className="text-sm font-semibold text-muted-foreground mb-2">Base format</h3>
<h3 className="text-sm font-semibold text-muted-foreground">Base format</h3>
<div className="flex items-center gap-2">
<FileType className="w-4 h-4 text-blue-500" />
<div className="px-3 py-1.5 border border-border rounded-lg text-sm font-medium">{iconData.base.toUpperCase()}</div>
@@ -430,7 +421,7 @@ export function IconDetails({ icon, iconData, authorData }: IconDetailsProps) {
</div>
<div className="">
<h3 className="text-sm font-semibold text-muted-foreground mb-2">Available formats</h3>
<h3 className="text-sm font-semibold text-muted-foreground">Available formats</h3>
<div className="flex flex-wrap gap-2">
{availableFormats.map((format) => (
<div key={format} className="px-3 py-1.5 border border-border rounded-lg text-xs font-medium">
@@ -442,7 +433,7 @@ export function IconDetails({ icon, iconData, authorData }: IconDetailsProps) {
{iconData.colors && (
<div className="">
<h3 className="text-sm font-semibold text-muted-foreground mb-2">Color variants</h3>
<h3 className="text-sm font-semibold text-muted-foreground">Color variants</h3>
<div className="space-y-2">
{Object.entries(iconData.colors).map(([theme, variant]) => (
<div key={theme} className="flex items-center gap-2">
@@ -456,7 +447,7 @@ export function IconDetails({ icon, iconData, authorData }: IconDetailsProps) {
)}
<div className="">
<h3 className="text-sm font-semibold text-muted-foreground mb-2">Source</h3>
<h3 className="text-sm font-semibold text-muted-foreground">Source</h3>
<Button variant="outline" className="w-full" asChild>
<Link href={`${REPO_PATH}/blob/main/meta/${icon}.json`} target="_blank" rel="noopener noreferrer">
<Github className="w-4 h-4 mr-2" />

View File

@@ -11,32 +11,32 @@ import { useState } from "react"
export const ISSUE_TEMPLATES = [
{
id: "add_monochrome_icon",
name: "Add light/dark icon",
description: "Submit a new icon with light and dark versions.",
name: "Add light & dark icon",
description: "Submit a new icon with both light and dark versions for optimal theme compatibility.",
url: `${REPO_PATH}/issues/new?template=add_monochrome_icon.yml`,
},
{
id: "add_normal_icon",
name: "Add standard icon",
description: "Submit a new icon for both themes.",
name: "Add normal icon",
description: "Submit a new icon that works well across both light and dark themes.",
url: `${REPO_PATH}/issues/new?template=add_normal_icon.yml`,
},
{
id: "update_monochrome_icon",
name: "Update light/dark icon",
description: "Improve or update an existing light/dark icon.",
name: "Update light & dark icon",
description: "Improve an existing icon by updating both light and dark versions.",
url: `${REPO_PATH}/issues/new?template=update_monochrome_icon.yml`,
},
{
id: "update_normal_icon",
name: "Update standard icon",
description: "Improve or update an existing standard icon.",
name: "Update normal icon",
description: "Improve an existing icon that works across both light and dark themes.",
url: `${REPO_PATH}/issues/new?template=update_normal_icon.yml`,
},
{
id: "blank_issue",
name: "Other request",
description: "Submit another type of request.",
name: "Something else",
description: "Create a custom issue for other suggestions, bug reports, or improvements.",
url: `${REPO_PATH}/issues/new?template=BLANK_ISSUE`,
},
]
@@ -72,14 +72,17 @@ export function IconSubmissionForm() {
return (
<Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger asChild>
<Button variant="outline" className="hidden md:inline-flex cursor-pointer transition-all duration-300">
<PlusCircle className="h-4 w-4 transition-all duration-300" /> Submit icon(s)
<Button
variant="outline"
className="hidden md:inline-flex cursor-pointer transition-all duration-300"
>
<PlusCircle className="h-4 w-4 transition-all duration-300" /> Contribute new icon
</Button>
</DialogTrigger>
<DialogContent className="md:max-w-4xl backdrop-blur-2xl bg-background">
<DialogHeader>
<DialogTitle>Submit an icon</DialogTitle>
<DialogDescription>Select an option below to submit or update an icon.</DialogDescription>
<DialogTitle>Contribute a new icon</DialogTitle>
<DialogDescription>Choose a template below to suggest a new icon or improve an existing one.</DialogDescription>
</DialogHeader>
<div className="mt-4">
<IconSubmissionContent onClose={() => setOpen(false)} />

View File

@@ -0,0 +1,33 @@
import type { CSSProperties, ComponentPropsWithoutRef, FC } from "react"
import { cn } from "@/lib/utils"
export interface AnimatedShinyTextProps extends ComponentPropsWithoutRef<"span"> {
shimmerWidth?: number
}
export const AnimatedShinyText: FC<AnimatedShinyTextProps> = ({ children, className, shimmerWidth = 100, ...props }) => {
return (
<span
style={
{
"--shiny-width": `${shimmerWidth}px`,
} as CSSProperties
}
className={cn(
"mx-auto max-w-md text-neutral-600/70 dark:text-neutral-400/70",
// Shine effect
"animate-shiny-text bg-clip-text bg-no-repeat [background-position:0_0] [background-size:var(--shiny-width)_100%] [transition:background-position_1s_cubic-bezier(.6,.6,0,1)_infinite]",
// Shine gradient
"bg-gradient-to-r from-transparent via-black/80 via-50% to-transparent dark:via-white/80",
className,
)}
{...props}
>
{children}
</span>
)
}

View File

@@ -2,7 +2,7 @@
import { motion, useMotionTemplate, useMotionValue } from "motion/react"
import type React from "react"
import { useCallback, useEffect, useRef, useState } from "react"
import { useCallback, useEffect, useRef } from "react"
import { cn } from "@/lib/utils"
@@ -28,7 +28,6 @@ export function MagicCard({
const cardRef = useRef<HTMLDivElement>(null)
const mouseX = useMotionValue(-gradientSize)
const mouseY = useMotionValue(-gradientSize)
const [isMounted, setIsMounted] = useState(false)
const handleMouseMove = useCallback(
(e: MouseEvent) => {
@@ -61,14 +60,6 @@ export function MagicCard({
}, [handleMouseMove, mouseX, gradientSize, mouseY])
useEffect(() => {
setIsMounted(true)
mouseX.set(-gradientSize)
mouseY.set(-gradientSize)
}, [gradientSize, mouseX, mouseY])
useEffect(() => {
if (!isMounted) return
document.addEventListener("mousemove", handleMouseMove)
document.addEventListener("mouseout", handleMouseOut)
document.addEventListener("mouseenter", handleMouseEnter)
@@ -78,17 +69,22 @@ export function MagicCard({
document.removeEventListener("mouseout", handleMouseOut)
document.removeEventListener("mouseenter", handleMouseEnter)
}
}, [isMounted, handleMouseEnter, handleMouseMove, handleMouseOut])
}, [handleMouseEnter, handleMouseMove, handleMouseOut])
useEffect(() => {
mouseX.set(-gradientSize)
mouseY.set(-gradientSize)
}, [gradientSize, mouseX, mouseY])
return (
<div className={cn("group relative rounded-[inherit]", className)}>
<div ref={cardRef} className={cn("group relative rounded-[inherit]", className)}>
<motion.div
className="pointer-events-none absolute inset-0 rounded-[inherit] bg-border duration-300 group-hover:opacity-100"
style={{
background: useMotionTemplate`
radial-gradient(${gradientSize}px circle at ${mouseX}px ${mouseY}px,
${gradientFrom},
${gradientTo},
${gradientFrom},
${gradientTo},
var(--border) 100%
)
`,
@@ -99,12 +95,12 @@ export function MagicCard({
className="pointer-events-none absolute inset-px rounded-[inherit] opacity-0 transition-opacity duration-300 group-hover:opacity-100"
style={{
background: useMotionTemplate`
radial-gradient(${gradientSize}px circle at ${mouseX}px ${mouseY}px, var(--magic-gradient-color, ${gradientColor}), transparent 100%)
radial-gradient(${gradientSize}px circle at ${mouseX}px ${mouseY}px, ${gradientColor}, transparent 100%)
`,
opacity: gradientOpacity,
}}
/>
<div ref={cardRef} className="relative">{children}</div>
<div className="relative">{children}</div>
</div>
)
}

View File

@@ -1,57 +1,67 @@
"use client"
"use client";
import { useInView, useMotionValue, useSpring } from "motion/react"
import { type ComponentPropsWithoutRef, useEffect, useRef } from "react"
import { useInView, useMotionValue, useSpring } from "motion/react";
import { ComponentPropsWithoutRef, useEffect, useRef } from "react";
import { cn } from "@/lib/utils"
import { cn } from "@/lib/utils";
interface NumberTickerProps extends ComponentPropsWithoutRef<"span"> {
value: number
startValue?: number
direction?: "up" | "down"
delay?: number
decimalPlaces?: number
value: number;
startValue?: number;
direction?: "up" | "down";
delay?: number;
decimalPlaces?: number;
}
export function NumberTicker({
value,
startValue = 0,
direction = "up",
delay = 0,
className,
decimalPlaces = 0,
...props
value,
startValue = 0,
direction = "up",
delay = 0,
className,
decimalPlaces = 0,
...props
}: NumberTickerProps) {
const ref = useRef<HTMLSpanElement>(null)
const motionValue = useMotionValue(direction === "down" ? value : startValue)
const springValue = useSpring(motionValue, {
damping: 30,
stiffness: 200,
})
const isInView = useInView(ref, { once: true, margin: "0px" })
const ref = useRef<HTMLSpanElement>(null);
const motionValue = useMotionValue(direction === "down" ? value : startValue);
const springValue = useSpring(motionValue, {
damping: 30,
stiffness: 100,
});
const isInView = useInView(ref, { once: true, margin: "0px" });
useEffect(() => {
if (isInView) {
const timer = setTimeout(() => {
motionValue.set(direction === "down" ? startValue : value)
}, delay * 1000)
return () => clearTimeout(timer)
}
}, [motionValue, isInView, delay, value, direction, startValue])
useEffect(() => {
if (isInView) {
const timer = setTimeout(() => {
motionValue.set(direction === "down" ? startValue : value);
}, delay * 1000);
return () => clearTimeout(timer);
}
}, [motionValue, isInView, delay, value, direction, startValue]);
useEffect(
() =>
springValue.on("change", (latest) => {
if (ref.current) {
ref.current.textContent = Number(latest.toFixed(decimalPlaces)).toString()
}
}),
[springValue, decimalPlaces],
)
useEffect(
() =>
springValue.on("change", (latest) => {
if (ref.current) {
ref.current.textContent = Intl.NumberFormat("en-US", {
minimumFractionDigits: decimalPlaces,
maximumFractionDigits: decimalPlaces,
}).format(Number(latest.toFixed(decimalPlaces)));
}
}),
[springValue, decimalPlaces],
);
return (
<span ref={ref} className={cn("inline-block tabular-nums tracking-wider", className)} {...props}>
{startValue}
</span>
)
return (
<span
ref={ref}
className={cn(
"inline-block tabular-nums tracking-wider",
className,
)}
{...props}
>
{startValue}
</span>
);
}

View File

@@ -30,9 +30,9 @@ export function RecentlyAddedIcons({ icons }: { icons: IconWithName[] }) {
{/* Background glow */}
<div className="absolute inset-x-0 -top-40 -z-10 transform-gpu overflow-hidden blur-3xl sm:-top-80" aria-hidden="true" />
<div className="mx-auto px-4 sm:px-6 lg:px-8">
<div className="mx-auto px-6 lg:px-8">
<div className="mx-auto max-w-2xl text-center my-4">
<h2 className="text-3xl font-bold tracking-tight sm:text-4xl bg-clip-text text-transparent bg-gradient-to-r from-rose-600 to-rose-500 motion-safe:motion-preset-fade-lg motion-duration-500">
<h2 className="text-3xl font-bold tracking-tight sm:text-4xl bg-clip-text text-transparent bg-gradient-to-r from-rose-600 to-rose-500 motion-safe:motion-preset-fade-lg motion-duration-2000">
Recently Added Icons
</h2>
</div>
@@ -61,7 +61,7 @@ export function RecentlyAddedIcons({ icons }: { icons: IconWithName[] }) {
href="/icons"
className="font-medium inline-flex items-center py-2 px-4 rounded-full border transition-all duration-200 group hover-lift soft-shadow"
>
View all icons
View complete collection
<ArrowRight className="w-4 h-4 ml-1.5 transition-transform duration-200 group-hover:translate-x-1" />
</Link>
</div>

View File

@@ -1,33 +0,0 @@
"use client"
type StructuredDataProps = {
data: any
id?: string
}
export const StructuredData = ({ data, id }: StructuredDataProps) => {
return (
<script
id={id}
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(data) }}
/>
)
}
type WebsiteStructuredDataProps = {
websiteSchema: any
organizationSchema: any
}
export const WebsiteStructuredData = ({
websiteSchema,
organizationSchema
}: WebsiteStructuredDataProps) => {
return (
<>
<StructuredData data={websiteSchema} id="website-schema" />
<StructuredData data={organizationSchema} id="organization-schema" />
</>
)
}

View File

@@ -18,7 +18,11 @@ export function ThemeSwitcher() {
<Tooltip>
<TooltipTrigger asChild>
<DropdownMenuTrigger asChild>
<Button className=" transition-colors duration-200 group hover:ring-2 rounded-lg cursor-pointer" variant="ghost" size="icon">
<Button
className=" transition-colors duration-200 group hover:ring-2 rounded-lg cursor-pointer"
variant="ghost"
size="icon"
>
<Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0 group-hover:" />
<Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100 group-hover:" />
<span className="sr-only">Toggle theme</span>

View File

@@ -0,0 +1,177 @@
"use client"
import * as React from "react"
import { Command as CommandPrimitive } from "cmdk"
import { SearchIcon } from "lucide-react"
import { cn } from "@/lib/utils"
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog"
function Command({
className,
...props
}: React.ComponentProps<typeof CommandPrimitive>) {
return (
<CommandPrimitive
data-slot="command"
className={cn(
"bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md",
className
)}
{...props}
/>
)
}
function CommandDialog({
title = "Command Palette",
description = "Search for a command to run...",
children,
...props
}: React.ComponentProps<typeof Dialog> & {
title?: string
description?: string
}) {
return (
<Dialog {...props}>
<DialogHeader className="sr-only">
<DialogTitle>{title}</DialogTitle>
<DialogDescription>{description}</DialogDescription>
</DialogHeader>
<DialogContent className="overflow-hidden p-0">
<Command className="[&_[cmdk-group-heading]]:text-muted-foreground **:data-[slot=command-input-wrapper]:h-12 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group]]:px-2 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
{children}
</Command>
</DialogContent>
</Dialog>
)
}
function CommandInput({
className,
...props
}: React.ComponentProps<typeof CommandPrimitive.Input>) {
return (
<div
data-slot="command-input-wrapper"
className="flex h-9 items-center gap-2 border-b px-3"
>
<SearchIcon className="size-4 shrink-0 opacity-50" />
<CommandPrimitive.Input
data-slot="command-input"
className={cn(
"placeholder:text-muted-foreground flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50",
className
)}
{...props}
/>
</div>
)
}
function CommandList({
className,
...props
}: React.ComponentProps<typeof CommandPrimitive.List>) {
return (
<CommandPrimitive.List
data-slot="command-list"
className={cn(
"max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto",
className
)}
{...props}
/>
)
}
function CommandEmpty({
...props
}: React.ComponentProps<typeof CommandPrimitive.Empty>) {
return (
<CommandPrimitive.Empty
data-slot="command-empty"
className="py-6 text-center text-sm"
{...props}
/>
)
}
function CommandGroup({
className,
...props
}: React.ComponentProps<typeof CommandPrimitive.Group>) {
return (
<CommandPrimitive.Group
data-slot="command-group"
className={cn(
"text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium",
className
)}
{...props}
/>
)
}
function CommandSeparator({
className,
...props
}: React.ComponentProps<typeof CommandPrimitive.Separator>) {
return (
<CommandPrimitive.Separator
data-slot="command-separator"
className={cn("bg-border -mx-1 h-px", className)}
{...props}
/>
)
}
function CommandItem({
className,
...props
}: React.ComponentProps<typeof CommandPrimitive.Item>) {
return (
<CommandPrimitive.Item
data-slot="command-item"
className={cn(
"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
className
)}
{...props}
/>
)
}
function CommandShortcut({
className,
...props
}: React.ComponentProps<"span">) {
return (
<span
data-slot="command-shortcut"
className={cn(
"text-muted-foreground ml-auto text-xs tracking-widest",
className
)}
{...props}
/>
)
}
export {
Command,
CommandDialog,
CommandInput,
CommandList,
CommandEmpty,
CommandGroup,
CommandItem,
CommandShortcut,
CommandSeparator,
}

View File

@@ -4,119 +4,7 @@ export const METADATA_URL = "https://raw.githubusercontent.com/homarr-labs/dashb
export const WEB_URL = "https://dashboardicons.com"
export const REPO_NAME = "homarr-labs/dashboard-icons"
// Site-wide metadata constants
export const SITE_NAME = "Dashboard Icons"
export const TITLE_SEPARATOR = " | "
export const SITE_TAGLINE = "Your definitive source for dashboard icons"
export const ORGANIZATION_NAME = "Homarr Labs"
export const getDescription = (totalIcons: number) =>
`A curated collection of ${totalIcons} free icons for dashboards and app directories. Available in SVG, PNG, and WEBP formats. ${SITE_TAGLINE}.`
`A collection of ${totalIcons} curated icons for services, applications and tools, designed specifically for dashboards and app directories.`
export const getHomeDescription = (totalIcons: number) =>
`Discover our curated collection of ${totalIcons} icons designed specifically for dashboards and app directories. ${SITE_TAGLINE}.`
export const getBrowseDescription = (totalIcons: number) =>
`Browse, search and download from our collection of ${totalIcons} curated icons. All icons available in SVG, PNG, and WEBP formats. ${SITE_TAGLINE}.`
export const getIconDescription = (iconName: string, totalIcons: number) =>
`Download the ${iconName} icon in SVG, PNG, and WEBP formats. Part of our curated collection of ${totalIcons} free icons for dashboards. ${SITE_TAGLINE}.`
export const websiteTitle = `${SITE_NAME} ${TITLE_SEPARATOR} Free, Curated Icons for Apps & Services`
export const websiteFullTitle = `${SITE_NAME} ${TITLE_SEPARATOR} Free, Curated Icons for Apps & Services ${TITLE_SEPARATOR} ${SITE_TAGLINE}`
// Various keyword sets for different pages
export const DEFAULT_KEYWORDS = [
"dashboard icons",
"app icons",
"service icons",
"curated icons",
"free icons",
"SVG icons",
"web dashboard",
"app directory"
]
export const BROWSE_KEYWORDS = [
"browse icons",
"search icons",
"download icons",
"minimal icons",
"dashboard design",
"UI icons",
...DEFAULT_KEYWORDS
]
export const ICON_DETAIL_KEYWORDS = (iconName: string) => [
`${iconName} icon`,
`${iconName} logo`,
`${iconName} svg`,
`${iconName} download`,
`${iconName} dashboard icon`,
...DEFAULT_KEYWORDS
]
// Core structured data for the website (JSON-LD)
export const getWebsiteSchema = (totalIcons: number) => ({
"@context": "https://schema.org",
"@type": "WebSite",
"name": SITE_NAME,
"url": WEB_URL,
"description": getDescription(totalIcons),
"potentialAction": {
"@type": "SearchAction",
"target": {
"@type": "EntryPoint",
"urlTemplate": `${WEB_URL}/icons?q={search_term_string}`
},
"query-input": "required name=search_term_string"
},
"slogan": SITE_TAGLINE
})
// Organization schema
export const ORGANIZATION_SCHEMA = {
"@context": "https://schema.org",
"@type": "Organization",
"name": ORGANIZATION_NAME,
"url": `https://github.com/${REPO_NAME}`,
"logo": `${WEB_URL}/og-image.png`,
"sameAs": [
`https://github.com/${REPO_NAME}`,
"https://homarr.dev"
],
"slogan": SITE_TAGLINE
}
// Social media
export const GITHUB_URL = `https://github.com/${REPO_NAME}`
// Image schemas
export const getIconSchema = (iconName: string, iconId: string, authorName: string, authorUrl: string, updateDate: string, totalIcons: number) => ({
"@context": "https://schema.org",
"@type": "ImageObject",
"name": `${iconName} Icon`,
"description": getIconDescription(iconName, totalIcons),
"contentUrl": `${BASE_URL}/png/${iconId}.png`,
"thumbnailUrl": `${BASE_URL}/png/${iconId}.png`,
"uploadDate": updateDate,
"author": {
"@type": "Person",
"name": authorName,
"url": authorUrl
},
"encodingFormat": ["image/png", "image/svg+xml", "image/webp"],
"contentSize": "Variable",
"representativeOfPage": true,
"creditText": `Icon contributed by ${authorName} to the ${SITE_NAME} collection by ${ORGANIZATION_NAME}`,
"embedUrl": `${WEB_URL}/icons/${iconId}`
})
// OpenGraph defaults
export const DEFAULT_OG_IMAGE = {
url: "/og-image.png",
width: 1200,
height: 630,
alt: `${SITE_NAME} - ${SITE_TAGLINE}`,
type: "image/png"
}
export const websiteTitle = "Free Dashboard Icons - Download High-Quality UI & App Icons"

View File

@@ -0,0 +1,25 @@
"use client"
import { useEffect, useState } from "react"
export function useMediaQuery(query: string): boolean {
const [matches, setMatches] = useState(false)
useEffect(() => {
const media = window.matchMedia(query)
// Initial check
if (media.matches !== matches) {
setMatches(media.matches)
}
// Setup listener for changes
const listener = () => setMatches(media.matches)
media.addEventListener("change", listener)
// Cleanup
return () => media.removeEventListener("change", listener)
}, [query, matches])
return matches
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

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