browse the protocol like its 2008 ibex.desertthunder.dev
ubuntu atproto svelte
7

Configure Feed

Select the types of activity you want to include in your feed.

feat: add repo route helpers and browser routes

* expand routing and app roadmap

Owais Jamil (Jun 16, 2026, 9:04 PM -0500) 1d3f90d8 50d987bd

+709 -46
+98 -22
TODO.md
··· 6 6 7 7 ## Routing 8 8 9 - - Done: shareable record routes at `/records/:did/:collection/:rkey`. 10 - - Done: direct record routes boot the desktop shell, select the repo/collection in 11 - Nautilus, and open the record in gedit. 12 - - Done: record routes fetch client-side with public ATProto and use DIDs as the 13 - canonical identity. 14 - - Done: record routes opportunistically hydrate public identity metadata for nicer 15 - labels: handle, display name, avatar, DID, and PDS. 16 - 17 - ## Browser 18 - 19 - - Preserve the first-run public handle setup flow for browsing a repo. 20 - - Add handle typeahead to setup using `app.bsky.actor.searchActorsTypeahead`. 21 - - Keep repository collection browsing in Nautilus. 22 - - Keep cursor-based pagination / “Load more records” for large collections. 23 - - Keep public record JSON viewing in gedit. 24 - - Keep local record caching and full-text search across cached records. 25 - - Keep user-readable network and cache errors. 9 + - Keep `/` as the desktop home. 10 + - Keep `/browse` as the configured/default public repo in Nautilus. 11 + - Add canonical repo routes under `/repos/:did`. 12 + - Add collection routes at `/repos/:did/collections/:collection`. 13 + - Add record routes at `/repos/:did/collections/:collection/:rkey`. 14 + - Add app routes that open the matching GNOME-style window: 15 + - `/repos/:did/map` -> Network Map. 16 + - `/repos/:did/identity` -> Identity Inspector. 17 + - `/repos/:did/logs` -> Log Viewer. 18 + - `/repos/:did/blobs` and `/repos/:did/blobs/:cid` -> Eye of GNOME. 19 + - `/live`, `/live/jetstream`, `/live/firehose`, `/live/spacedust` -> System Monitor. 20 + - `/labels` -> Label Browser. 21 + - `/car` -> Archive Manager. 22 + - `/servers/:host` -> Network Servers. 23 + - Route loaders should stay browser-only and public/read-only. 24 + - DIDs remain canonical in URLs; handles are accepted as lookup/input affordances and 25 + resolved client-side. 26 26 27 27 ## Apps 28 28 29 29 Every new surface should feel like a GNOME 2 app that happens to speak `at://`. 30 30 31 31 - **Nautilus** 32 + - Preserve the first-run public handle setup flow for browsing a repo. 33 + - Add handle typeahead to setup using `app.bsky.actor.searchActorsTypeahead`. 32 34 - Browse public repo collections. 33 35 - Select collections and records. 34 36 - Open records in gedit or media blobs in Eye of GNOME. 37 + - Keep cursor-based pagination / “Load more records” for large collections. 38 + - Keep local record caching and full-text search across cached records. 39 + - Keep user-readable network and cache errors. 35 40 - Surface cached/search states clearly. 41 + - Add collection filtering, reverse order, page-size controls, and preview field 42 + selection. 43 + - Add collection schema tabs and links into System Monitor for the selected repo or 44 + collection. 36 45 - **gedit** 37 46 - Read-only JSON viewer for records. 38 47 - Preserve copy, wrapping, syntax highlighting, and native GTK-style window behavior. 48 + - Add record tabs for JSON, schema, backlinks, and info. 49 + - Show AT URI, CID, raw PDS link, external app links, and read-only verification status. 39 50 - **Eye of GNOME (eog)** 40 - - Add image/blob viewing. 51 + - List public repo blob CIDs via `com.atproto.sync.listBlobs`. 41 52 - Open from Nautilus when a record contains embedded images or media blobs. 42 - - Support `app.bsky.feed.post` embedded images as the first target. 53 + - Preview image/video blobs, with `app.bsky.feed.post` embedded images as the first 54 + target. 55 + - Link each blob back to its repo and raw PDS URL when possible. 56 + - **Network Map** 57 + - Visualize an account at the center with app namespaces around it. 58 + - Show app count, record-type count, PDS hosting status, and app/domain validation. 59 + - Let users hide unresolved apps and jump from an app namespace into Nautilus. 60 + - **System Monitor** 61 + - Icon: `/icons/humanity/apps/utilities-system-monitor.svg`. 62 + - Read-only live ATProto monitor for Jetstream, Firehose, and Spacedust-style backlink 63 + streams. 64 + - Filter by DID, collection, cursor, and stream instance where supported. 65 + - Show event rate, total events, top collections/sources, expandable JSON, and copy. 66 + - **Identity Inspector** 67 + - Icon: `/icons/humanity/apps/identity-inspector.svg`. 68 + - Show DID document, aliases, services, verification methods, and rotation keys. 69 + - Validate handles through DNS TXT and `.well-known` when possible. 70 + - Link out to PDS endpoints and copy identity fields. 71 + - **Log Viewer** 72 + - Show PLC audit history for `did:plc` identities. 73 + - Present alias, service, verification method, and rotation-key diffs. 74 + - Include event filters, validation status, and hash links to individual log entries. 75 + - **Archive Manager** 76 + - Icon: `/icons/humanity/apps/archive-manager.svg`. 77 + - Open local CAR files without requiring a live PDS connection. 78 + - Browse archive collections and records in the same read-only style as Nautilus/gedit. 79 + - Export archive contents to a ZIP of JSON files. 80 + - **Label Browser** 81 + - Query public labeler services with URI patterns. 82 + - Show label value, target, CID, negation, created/expiry timestamps, and pagination. 83 + - Add client-side label filtering with wildcard include and `-exclude` support. 84 + - **Network Servers** 85 + - Inspect public PDS host info, version, available domains, and repo list. 86 + - Link repos into Nautilus and open server firehose views in System Monitor. 43 87 - **About This Computer** 44 88 - Show OS/theme info and current public repo identity metadata when available. 45 89 - **Desktop shell** 46 90 - Preserve brown panels, tan chrome, Humanity icons, small dense spacing, task buttons, 47 91 tray affordances, and movable/resizable windows. 48 92 93 + ## Priority Order 94 + 95 + - [x] Add canonical `/repos/:did/...` routing. 96 + - [ ] Deepen Nautilus and gedit with collection controls plus record JSON/schema/info tabs. 97 + - [ ] Add Identity Inspector. 98 + - [ ] Add System Monitor with Jetstream first. 99 + - [ ] Add Network Map. 100 + - [ ] Add Archive Manager. 101 + - [ ] Add Eye of GNOME blob browsing and previews. 102 + - [ ] Add Label Browser. 103 + - [ ] Add Log Viewer. 104 + - [ ] Add Network Servers. 105 + 106 + ## Tests 107 + 108 + - Vitest unit tests for pure helpers and data behavior: 109 + - ATProto route helpers. 110 + - identity normalization and DID/PDS resolution helpers. 111 + - repo record summarization and collection grouping. 112 + - pagination behavior. 113 + - local DB migrations, cache repositories, and search. 114 + - Browser/component tests for desktop UI behavior: 115 + - first-run setup and handle typeahead states. 116 + - Nautilus collection selection, search, pagination, and record opening. 117 + - gedit JSON display, copy behavior, and record metadata tabs. 118 + - window manager open, focus, minimize, maximize, and route-driven gedit opening. 119 + - Playwright E2E/smoke tests for critical flows: 120 + - `/` boots the desktop. 121 + - `/browse` opens the configured repo after setup. 122 + - `/repos/:did` hydrates identity and opens Nautilus. 123 + - `/repos/:did/collections/:collection` selects the collection. 124 + - `/repos/:did/collections/:collection/:rkey` opens Nautilus and gedit around the record. 125 + - Mock external ATProto boundaries in tests unless the test is explicitly an integration 126 + smoke test. 127 + 49 128 ## V2 50 129 51 130 - **gnome-terminal** ··· 58 137 - **Contacts** 59 138 - Follows / followers graph browser built on `app.bsky.graph.follow`; show avatar, 60 139 handle, and mutual-follow status in an address-book layout. 61 - - **File Roller** 62 - - Export any collection to a `.json` archive or CAR file for local backup. 63 - - Import archives to preview records without a live PDS connection. 64 140 - Local starred/bookmarked records surfaced as a “Bookmarks” sidebar item in Nautilus. 65 141 - Sync indicator in the panel showing last-synced time per repo/collection. 66 142 - Multi-repo switching from the panel without implying authentication.
+4
pnpm-workspace.yaml
··· 1 + allowBuilds: 2 + esbuild: true 3 + sharp: true 4 + workerd: true 1 5 onlyBuiltDependencies: 2 6 - esbuild 3 7 - sharp
+1
src/lib/atproto/repo.svelte.ts
··· 63 63 64 64 async selectCollection(identity: AccountIdentity, collectionName: string) { 65 65 this.selectedCollection = collectionName; 66 + this.selectedRecord = null; 66 67 this.searchQuery = ''; 67 68 this.isLoadingRecords = true; 68 69 this.canLoadMoreRecords = false;
+20
src/lib/atproto/routes.test.ts
··· 1 + import { describe, expect, it } from 'vitest'; 2 + import { collectionPath, recordPath, repoPath } from './routes'; 3 + 4 + describe('ATProto route helpers', () => { 5 + it('builds canonical repo routes', () => { 6 + expect(repoPath('did:plc:abc123')).toBe('/repos/did:plc:abc123'); 7 + }); 8 + 9 + it('builds canonical collection routes', () => { 10 + expect(collectionPath({ did: 'did:plc:abc123', collection: 'app.bsky.feed.post' })).toBe( 11 + '/repos/did:plc:abc123/collections/app.bsky.feed.post' 12 + ); 13 + }); 14 + 15 + it('encodes record keys in canonical record routes', () => { 16 + expect(recordPath({ did: 'did:plc:abc123', collection: 'app.bsky.feed.post', rkey: 'post/key' })).toBe( 17 + '/repos/did:plc:abc123/collections/app.bsky.feed.post/post%2Fkey' 18 + ); 19 + }); 20 + });
+11 -1
src/lib/atproto/routes.ts
··· 1 1 export type RecordRouteParams = { did: string; collection: string; rkey: string }; 2 2 3 + export type CollectionRouteParams = Pick<RecordRouteParams, 'did' | 'collection'>; 4 + 5 + export function repoPath(did: string) { 6 + return `/repos/${did}`; 7 + } 8 + 9 + export function collectionPath({ did, collection }: CollectionRouteParams) { 10 + return `${repoPath(did)}/collections/${collection}`; 11 + } 12 + 3 13 export function recordPath({ did, collection, rkey }: RecordRouteParams) { 4 - return `/records/${did}/${collection}/${encodeURIComponent(rkey)}`; 14 + return `${collectionPath({ did, collection })}/${encodeURIComponent(rkey)}`; 5 15 }
+5 -5
src/lib/components/WelcomeScreen.svelte
··· 84 84 <ol> 85 85 <li>Choose a public ATProto repo by handle.</li> 86 86 <li>Open Nautilus to browse collections and records.</li> 87 - <li>Open records in gedit, then share stable DID-based URLs.</li> 87 + <li>Open records in gedit to view or share them.</li> 88 88 </ol> 89 - <p> 90 - Direct links look like 91 - <code>/records/:did/:collection/:rkey</code> and reopen the desktop around that record. 92 - </p> 89 + <p>You can direct link a record with the following structure:</p> 90 + <pre> 91 + <code>/repos/:did/collections/:collection/:rkey</code> 92 + </pre> 93 93 </section> 94 94 </div> 95 95
+27 -17
src/routes/+layout.svelte
··· 30 30 let bootStep = $state('Loading database'); 31 31 let bootError = $state<string | null>(null); 32 32 let cacheDisabled = $state(false); 33 - let handledRecordRoute = $state<string | null>(null); 33 + let handledRepoRoute = $state<string | null>(null); 34 34 35 35 const routeRequiresSetup = $derived(page.route.id === '/browse' && !accountSetup.isConfigured); 36 36 const routeUsesNativeWindow = $derived(page.route.id === '/' || page.route.id?.startsWith('/docs')); ··· 41 41 if (page.route.id?.startsWith('/docs')) return 'Document Viewer'; 42 42 return 'AT Protocol Collections - Intrepid Ibex'; 43 43 }); 44 + 44 45 const windowIcon = $derived.by(() => { 45 46 if (routeRequiresSetup) return '/icons/humanity/places/user-home.svg'; 46 47 if (page.route.id === '/') return '/icons/humanity/devices/computer.svg'; 47 48 if (page.route.id?.startsWith('/docs')) return '/icons/humanity/mimes/gnome-mime-application-pdf.svg'; 48 49 return '/icons/humanity/apps/internet-feed-reader.svg'; 49 50 }); 51 + 50 52 const mainWindow = $derived(windowManager.getWindow('main')); 51 53 const aboutWindow = $derived(windowManager.getWindow('about-computer')); 52 54 const geditWindow = $derived(windowManager.getWindow('gedit')); 53 55 const documentViewerWindow = $derived(windowManager.getWindow('document-viewer')); 54 - 55 56 const shortcuts = $derived([ 56 57 { 57 58 label: 'ibex Home', ··· 65 66 { 66 67 label: 'Collections', 67 68 icon: '/icons/humanity/places/folder.svg', 68 - selected: page.route.id === '/browse' || page.route.id?.startsWith('/records'), 69 + selected: page.route.id === '/browse' || page.route.id?.startsWith('/repos'), 69 70 onactivate: () => { 70 71 windowManager.restore('main'); 71 72 void goto(resolve('/browse')); ··· 111 112 }); 112 113 113 114 $effect(() => { 114 - const route = recordRouteFromParams(); 115 + const route = repoRouteFromParams(); 115 116 if (bootStatus !== 'ready' || !route) return; 116 117 117 - const routeKey = `${route.did}/${route.collection}/${route.rkey}`; 118 - if (handledRecordRoute === routeKey) return; 118 + const routeKey = [route.did, route.collection, route.rkey].filter(Boolean).join('/'); 119 + if (handledRepoRoute === routeKey) return; 119 120 120 - handledRecordRoute = routeKey; 121 - void openRecordRoute(route); 121 + handledRepoRoute = routeKey; 122 + void openRepoRoute(route); 122 123 }); 123 124 124 125 onMount(() => { ··· 176 177 accountSetup.load(); 177 178 } 178 179 179 - async function openRecordRoute(route: { did: string; collection: string; rkey: string }) { 180 + async function openRepoRoute(route: { did: string; collection?: string; rkey?: string }) { 180 181 try { 181 182 const { hydratePublicIdentity } = await import('$lib/atproto/identity'); 182 183 const identity = await hydratePublicIdentity(route.did); 183 184 184 - await repoBrowser.openRecordRoute(identity, route.collection, route.rkey); 185 185 accountSetup.save(identity); 186 - 187 186 windowManager.restore('main'); 188 - if (repoBrowser.selectedRecord) { 189 - windowManager.open('gedit'); 187 + 188 + if (route.collection && route.rkey) { 189 + await repoBrowser.openRecordRoute(identity, route.collection, route.rkey); 190 + if (repoBrowser.selectedRecord) { 191 + windowManager.open('gedit'); 192 + } 193 + return; 194 + } 195 + 196 + await repoBrowser.load(identity); 197 + 198 + if (route.collection) { 199 + await repoBrowser.selectCollection(identity, route.collection); 190 200 } 191 201 } catch (unknownError) { 192 - repoBrowser.error = errorMessage(unknownError, 'Could not open that record route.'); 202 + repoBrowser.error = errorMessage(unknownError, 'Could not open that repository route.'); 193 203 } 194 204 } 195 205 196 - function recordRouteFromParams() { 197 - if (page.route.id !== '/records/[did]/[collection]/[rkey]') return null; 206 + function repoRouteFromParams() { 207 + if (!page.route.id?.startsWith('/repos/[did]')) return null; 198 208 199 209 const { did, collection, rkey } = page.params; 200 - if (!did || !collection || !rkey) return null; 210 + if (!did) return null; 201 211 202 212 return { did, collection, rkey }; 203 213 }
+1 -1
src/routes/docs/getting-started.md
··· 16 16 Record windows use stable DID-based URLs: 17 17 18 18 ```txt 19 - /records/:did/:collection/:rkey 19 + /repos/:did/collections/:collection/:rkey 20 20 ``` 21 21 22 22 Opening one of those links boots the desktop, selects the collection in Nautilus, and
+3
src/routes/records/[did]/[collection]/[rkey]/+page.svelte src/routes/repos/+layout.svelte
··· 1 1 <script lang="ts"> 2 2 import CollectionBrowser from '$lib/components/CollectionBrowser.svelte'; 3 + 4 + let { children } = $props(); 3 5 </script> 4 6 5 7 <CollectionBrowser /> 8 + {@render children()}
src/routes/records/[did]/[collection]/[rkey]/+page.ts src/routes/repos/+layout.ts
+1
src/routes/repos/[did]/+page.svelte
··· 1 + <script lang="ts"></script>
+1
src/routes/repos/[did]/collections/[collection]/+page.svelte
··· 1 + <script lang="ts"></script>
+1
src/routes/repos/[did]/collections/[collection]/[rkey]/+page.svelte
··· 1 + <script lang="ts"></script>
+61
static/icons/humanity/apps/archive-manager.svg
··· 1 + <?xml version="1.0" encoding="UTF-8" standalone="no"?> 2 + <!-- Created with Inkscape (http://www.inkscape.org/) --> 3 + <svg id="svg3263" xmlns="http://www.w3.org/2000/svg" height="48" width="48" version="1.0" xmlns:xlink="http://www.w3.org/1999/xlink"> 4 + <defs id="defs3265"> 5 + <radialGradient id="radialGradient3314" xlink:href="#linearGradient3681" gradientUnits="userSpaceOnUse" cy="41.5" cx="5" gradientTransform="matrix(.59382 0 0 1.5367 41.141 -103.94)" r="5"/> 6 + <linearGradient id="linearGradient3312" y2="35" gradientUnits="userSpaceOnUse" x2="17.554" gradientTransform="matrix(1.757 0 0 1.397 -17.394 -16.412)" y1="46" x1="17.554"> 7 + <stop id="stop3705" style="stop-opacity:0" offset="0"/> 8 + <stop id="stop3711" offset=".5"/> 9 + <stop id="stop3707" style="stop-opacity:0" offset="1"/> 10 + </linearGradient> 11 + <linearGradient id="linearGradient3681"> 12 + <stop id="stop3683" offset="0"/> 13 + <stop id="stop3685" style="stop-opacity:0" offset="1"/> 14 + </linearGradient> 15 + <radialGradient id="radialGradient3310" xlink:href="#linearGradient3681" gradientUnits="userSpaceOnUse" cy="41.5" cx="5" gradientTransform="matrix(.59382 0 0 1.5367 -6.6595 -103.94)" r="5"/> 16 + <linearGradient id="linearGradient3293" y2="45.042" gradientUnits="userSpaceOnUse" x2="15.464" y1="7.9757" x1="15.464"> 17 + <stop id="stop3297" style="stop-color:#c9af8b" offset="0"/> 18 + <stop id="stop3299" style="stop-color:#ad8757" offset=".23942"/> 19 + <stop id="stop3301" style="stop-color:#c2a57f" offset=".27582"/> 20 + <stop id="stop3303" style="stop-color:#9d7d53" offset="1"/> 21 + </linearGradient> 22 + <linearGradient id="linearGradient3197" y2="37.277" gradientUnits="userSpaceOnUse" x2="24.997" gradientTransform="matrix(1.2822 0 0 1.5573 -6.0702 -15.291)" y1="15.378" x1="24.823"> 23 + <stop id="stop3201" style="stop-color:#dac197" offset="0"/> 24 + <stop id="stop3203" style="stop-color:#c1a581" offset=".23942"/> 25 + <stop id="stop3205" style="stop-color:#dac197" offset=".27582"/> 26 + <stop id="stop3207" style="stop-color:#a68b60" offset="1"/> 27 + </linearGradient> 28 + <radialGradient id="radialGradient3217" gradientUnits="userSpaceOnUse" cy="31" cx="24" gradientTransform="matrix(1.6547 0 0 .65 -15.714 10.85)" r="20"> 29 + <stop id="stop3225" style="stop-color:#cbad7a" offset="0"/> 30 + <stop id="stop3227" style="stop-color:#cbae7d;stop-opacity:0" offset="1"/> 31 + </radialGradient> 32 + <linearGradient id="linearGradient2659" y2="45.934" gradientUnits="userSpaceOnUse" x2="43.007" gradientTransform="matrix(1.2822 0 0 1.1747 -6.0702 -5.3032)" y1="30.555" x1="23.452"> 33 + <stop id="stop4561" style="stop-color:#fff;stop-opacity:0" offset="0"/> 34 + <stop id="stop4563" style="stop-color:#fff;stop-opacity:0" offset="1"/> 35 + </linearGradient> 36 + <linearGradient id="linearGradient3834" y2="8" gradientUnits="userSpaceOnUse" x2="26" y1="22" x1="26"> 37 + <stop id="stop3829" style="stop-color:#fff" offset="0"/> 38 + <stop id="stop4295" style="stop-color:#fff" offset=".30213"/> 39 + <stop id="stop4293" style="stop-color:#fff;stop-opacity:.69020" offset=".34361"/> 40 + <stop id="stop3832" style="stop-color:#fff;stop-opacity:0" offset="1"/> 41 + </linearGradient> 42 + <linearGradient id="linearGradient3281" y2="17.5" spreadMethod="reflect" gradientUnits="userSpaceOnUse" x2="3.0052" y1="17.5" x1="44.995"> 43 + <stop id="stop3277" style="stop-color:#fff;stop-opacity:0" offset="0"/> 44 + <stop id="stop3283" style="stop-color:#fff" offset=".16682"/> 45 + <stop id="stop3285" style="stop-color:#fff" offset=".83238"/> 46 + <stop id="stop3279" style="stop-color:#fff;stop-opacity:0" offset="1"/> 47 + </linearGradient> 48 + </defs> 49 + <g id="layer1"> 50 + <g id="g3305" style="opacity:.4" transform="matrix(.99266 0 0 .97615 .27519 1.293)"> 51 + <rect id="rect2484" style="opacity:1;fill:url(#radialGradient3310)" transform="scale(-1)" height="15.367" width="2.9602" y="-47.848" x="-3.6904"/> 52 + <rect id="rect2486" style="opacity:1;fill:url(#linearGradient3312)" height="15.367" width="40.412" y="32.482" x="3.6904"/> 53 + <rect id="rect3444" style="opacity:1;fill:url(#radialGradient3314)" transform="scale(1,-1)" height="15.367" width="2.9602" y="-47.848" x="44.11"/> 54 + </g> 55 + <path id="path2488" style="stroke:url(#linearGradient3293);stroke-linecap:round;stroke-width:.99420;display:block;fill:url(#linearGradient3197)" d="m9.0107 8.5h29.497c1.722 0 2.497-0.2866 2.992 1l3.002 8v25.674c0 1.553 0.103 1.316-1.619 1.316h-37.766c-1.7217 0-1.6187 0.237-1.6187-1.316v-25.674l3.0017-8c0.4808-1.2606 0.7887-1 2.5107-1z"/> 56 + <rect id="rect3209" style="fill-rule:evenodd;fill:url(#radialGradient3217)" height="26" width="40" y="18" x="4"/> 57 + <path id="path2490" style="opacity:.50549;stroke:url(#linearGradient2659);stroke-width:.74212;display:block;fill:none" d="m9.9482 9.5129h27.653c1.614 0 2.613 0.5561 3.29 2.0861l2.329 6.42v23.144c0 1.461-0.819 2.196-2.434 2.196h-33.733c-1.614 0-2.2725-0.808-2.2725-2.269v-23.071l2.2538-6.558c0.4508-1.185 1.2996-1.9481 2.9139-1.9481z"/> 58 + <path id="rect3326" style="opacity:.4;fill:url(#linearGradient3834)" d="m22 8h4v14h-1.181-1.21-0.973-0.636v-14z"/> 59 + <path id="path3273" style="opacity:.3;stroke:url(#linearGradient3281);stroke-linecap:square;stroke-width:1px;fill:none" d="m3.5052 17.5h40.99"/> 60 + </g> 61 + </svg>
+410
static/icons/humanity/apps/identity-inspector.svg
··· 1 + <?xml version="1.0" encoding="UTF-8" standalone="no"?> 2 + <!-- Created with Inkscape (http://www.inkscape.org/) --> 3 + 4 + <svg 5 + xmlns:svg="http://www.w3.org/2000/svg" 6 + xmlns="http://www.w3.org/2000/svg" 7 + xmlns:xlink="http://www.w3.org/1999/xlink" 8 + version="1.1" 9 + width="48" 10 + height="48" 11 + id="svg2467"> 12 + <defs 13 + id="defs2469"> 14 + <radialGradient 15 + cx="20" 16 + cy="46" 17 + r="8" 18 + fx="20" 19 + fy="46" 20 + id="radialGradient7612" 21 + xlink:href="#linearGradient7604" 22 + gradientUnits="userSpaceOnUse" 23 + gradientTransform="matrix(1,0,0,0.25,0,34.5)" /> 24 + <linearGradient 25 + id="linearGradient7604"> 26 + <stop 27 + id="stop7606" 28 + style="stop-color:black;stop-opacity:1" 29 + offset="0" /> 30 + <stop 31 + id="stop7608" 32 + style="stop-color:black;stop-opacity:0" 33 + offset="1" /> 34 + </linearGradient> 35 + <radialGradient 36 + cx="20" 37 + cy="46" 38 + r="8" 39 + fx="20" 40 + fy="46" 41 + id="radialGradient7610" 42 + xlink:href="#linearGradient7604" 43 + gradientUnits="userSpaceOnUse" 44 + gradientTransform="matrix(1,0,0,0.25,0,34.5)" /> 45 + <linearGradient 46 + id="linearGradient7557"> 47 + <stop 48 + id="stop7559" 49 + style="stop-color:#eeeeec;stop-opacity:1" 50 + offset="0" /> 51 + <stop 52 + id="stop7561" 53 + style="stop-color:#eeeeec;stop-opacity:1" 54 + offset="1" /> 55 + </linearGradient> 56 + <radialGradient 57 + cx="17.812502" 58 + cy="14.729167" 59 + r="9.500001" 60 + fx="17.812502" 61 + fy="14.729167" 62 + id="radialGradient6179" 63 + xlink:href="#linearGradient7557" 64 + gradientUnits="userSpaceOnUse" 65 + gradientTransform="matrix(1,0,0,0.6315789,0,2.947369)" /> 66 + <linearGradient 67 + id="linearGradient7582"> 68 + <stop 69 + id="stop7584" 70 + style="stop-color:white;stop-opacity:1" 71 + offset="0" /> 72 + <stop 73 + id="stop7586" 74 + style="stop-color:white;stop-opacity:0" 75 + offset="1" /> 76 + </linearGradient> 77 + <radialGradient 78 + cx="11.15625" 79 + cy="2.0625" 80 + r="0.90625" 81 + fx="11.15625" 82 + fy="2.0625" 83 + id="radialGradient6201" 84 + xlink:href="#linearGradient7582" 85 + gradientUnits="userSpaceOnUse" 86 + gradientTransform="matrix(1,0,0,0.6206897,0,0.7823276)" /> 87 + <linearGradient 88 + x1="33.120464" 89 + y1="20.5" 90 + x2="22.328388" 91 + y2="20.5" 92 + id="linearGradient7433" 93 + xlink:href="#linearGradient4542" 94 + gradientUnits="userSpaceOnUse" 95 + gradientTransform="matrix(0.727273,0,0,0.999999,12.27273,-34.84375)" /> 96 + <linearGradient 97 + x1="15.406166" 98 + y1="37.34367" 99 + x2="16.864777" 100 + y2="24.249567" 101 + id="linearGradient7431" 102 + xlink:href="#linearGradient2816" 103 + gradientUnits="userSpaceOnUse" 104 + gradientTransform="matrix(0,0.673693,-0.676136,0,37.10227,14.81577)" /> 105 + <linearGradient 106 + x1="17" 107 + y1="45.248375" 108 + x2="17" 109 + y2="30.759407" 110 + id="linearGradient7427" 111 + xlink:href="#linearGradient6958" 112 + gradientUnits="userSpaceOnUse" 113 + gradientTransform="matrix(0,0.625,-0.676136,0,37.10227,15.875)" /> 114 + <linearGradient 115 + id="linearGradient6826"> 116 + <stop 117 + id="stop6828" 118 + style="stop-color:#babdb6;stop-opacity:1" 119 + offset="0" /> 120 + <stop 121 + id="stop6830" 122 + style="stop-color:#eeeeec;stop-opacity:1" 123 + offset="1" /> 124 + </linearGradient> 125 + <linearGradient 126 + x1="13.819278" 127 + y1="30.029789" 128 + x2="36.227631" 129 + y2="45.194965" 130 + id="linearGradient7425" 131 + xlink:href="#linearGradient6826" 132 + gradientUnits="userSpaceOnUse" 133 + gradientTransform="matrix(0,0.673693,-0.676136,0,37.10227,14.81577)" /> 134 + <linearGradient 135 + id="linearGradient4542"> 136 + <stop 137 + id="stop4544" 138 + style="stop-color:#888a85;stop-opacity:1" 139 + offset="0" /> 140 + <stop 141 + id="stop4546" 142 + style="stop-color:#888a85;stop-opacity:0" 143 + offset="1" /> 144 + </linearGradient> 145 + <linearGradient 146 + x1="33.120464" 147 + y1="20.5" 148 + x2="22.328388" 149 + y2="20.5" 150 + id="linearGradient6798" 151 + xlink:href="#linearGradient4542" 152 + gradientUnits="userSpaceOnUse" 153 + gradientTransform="matrix(0.727273,0,0,0.999999,12.27273,-34.84375)" /> 154 + <linearGradient 155 + id="linearGradient2816"> 156 + <stop 157 + id="stop2818" 158 + style="stop-color:white;stop-opacity:1" 159 + offset="0" /> 160 + <stop 161 + id="stop2820" 162 + style="stop-color:white;stop-opacity:0" 163 + offset="1" /> 164 + </linearGradient> 165 + <linearGradient 166 + x1="15.406166" 167 + y1="37.34367" 168 + x2="16.864777" 169 + y2="24.249567" 170 + id="linearGradient6834" 171 + xlink:href="#linearGradient2816" 172 + gradientUnits="userSpaceOnUse" 173 + gradientTransform="matrix(0,0.673693,-0.676136,0,37.10227,14.81577)" /> 174 + <linearGradient 175 + id="linearGradient6958"> 176 + <stop 177 + id="stop6960" 178 + style="stop-color:black;stop-opacity:1" 179 + offset="0" /> 180 + <stop 181 + id="stop6962" 182 + style="stop-color:#888a85;stop-opacity:0" 183 + offset="1" /> 184 + </linearGradient> 185 + <linearGradient 186 + x1="17" 187 + y1="45.248375" 188 + x2="17" 189 + y2="30.759407" 190 + id="linearGradient6791" 191 + xlink:href="#linearGradient6958" 192 + gradientUnits="userSpaceOnUse" 193 + gradientTransform="matrix(0,0.625,-0.676136,0,37.10227,15.875)" /> 194 + <linearGradient 195 + id="linearGradient7614"> 196 + <stop 197 + id="stop7616" 198 + style="stop-color:#babdb6;stop-opacity:1" 199 + offset="0" /> 200 + <stop 201 + id="stop7628" 202 + style="stop-color:white;stop-opacity:1" 203 + offset="0.4873454" /> 204 + <stop 205 + id="stop7618" 206 + style="stop-color:#d3d7cf;stop-opacity:1" 207 + offset="1" /> 208 + </linearGradient> 209 + <linearGradient 210 + x1="6.7188582" 211 + y1="22.936218" 212 + x2="44.344444" 213 + y2="42.604996" 214 + id="linearGradient6789" 215 + xlink:href="#linearGradient7614" 216 + gradientUnits="userSpaceOnUse" 217 + gradientTransform="matrix(0,0.673693,-0.676136,0,37.10227,14.81577)" /> 218 + <linearGradient 219 + id="linearGradient7491"> 220 + <stop 221 + id="stop7493" 222 + style="stop-color:#eeeeec;stop-opacity:1" 223 + offset="0" /> 224 + <stop 225 + id="stop7495" 226 + style="stop-color:#babdb6;stop-opacity:1" 227 + offset="1" /> 228 + </linearGradient> 229 + <radialGradient 230 + cx="23.681061" 231 + cy="5.3414755" 232 + r="5.055244" 233 + fx="23.681061" 234 + fy="5.3414755" 235 + id="radialGradient6183" 236 + xlink:href="#linearGradient7491" 237 + gradientUnits="userSpaceOnUse" 238 + gradientTransform="matrix(-1.5922835,-0.1907818,-1.1802872,-1.4345654,57.810344,15.557175)" /> 239 + <linearGradient 240 + id="linearGradient7592"> 241 + <stop 242 + id="stop7594" 243 + style="stop-color:white;stop-opacity:1" 244 + offset="0" /> 245 + <stop 246 + id="stop7596" 247 + style="stop-color:white;stop-opacity:0" 248 + offset="1" /> 249 + </linearGradient> 250 + <radialGradient 251 + cx="11.15625" 252 + cy="2.0625" 253 + r="0.90625" 254 + fx="11.15625" 255 + fy="2.0625" 256 + id="radialGradient6187" 257 + xlink:href="#linearGradient7592" 258 + gradientUnits="userSpaceOnUse" 259 + gradientTransform="matrix(1,0,0,0.6206897,0,0.7823276)" /> 260 + <linearGradient 261 + id="linearGradient7549"> 262 + <stop 263 + id="stop7551" 264 + style="stop-color:white;stop-opacity:1" 265 + offset="0" /> 266 + <stop 267 + id="stop7553" 268 + style="stop-color:#eeeeec;stop-opacity:1" 269 + offset="1" /> 270 + </linearGradient> 271 + <radialGradient 272 + cx="24.090876" 273 + cy="5.052979" 274 + r="4.4921517" 275 + fx="24.090876" 276 + fy="5.052979" 277 + id="radialGradient6191" 278 + xlink:href="#linearGradient7549" 279 + gradientUnits="userSpaceOnUse" 280 + gradientTransform="matrix(1.6372128,-0.3629926,2.1525103,1.8500902,-36.53018,2.08716)" /> 281 + <linearGradient 282 + id="linearGradient7567"> 283 + <stop 284 + id="stop7569" 285 + style="stop-color:black;stop-opacity:1" 286 + offset="0" /> 287 + <stop 288 + id="stop7571" 289 + style="stop-color:black;stop-opacity:0" 290 + offset="1" /> 291 + </linearGradient> 292 + <linearGradient 293 + x1="20.722668" 294 + y1="16.830494" 295 + x2="22.697027" 296 + y2="15.894469" 297 + id="linearGradient6195" 298 + xlink:href="#linearGradient7567" 299 + gradientUnits="userSpaceOnUse" 300 + gradientTransform="matrix(1.1304264,-0.235981,0.915432,0.6373638,-15.020125,7.538008)" /> 301 + </defs> 302 + <g 303 + id="layer1"> 304 + <path 305 + d="m 28,46 a 8,2 0 1 1 -16,0 8,2 0 1 1 16,0 z" 306 + transform="matrix(1.1875,0,0,1.75,9.75,-37.5)" 307 + id="path7600" 308 + style="opacity:0.16289595;fill:url(#radialGradient7612);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> 309 + <path 310 + d="m 28,46 a 8,2 0 1 1 -16,0 8,2 0 1 1 16,0 z" 311 + transform="matrix(1.25,0,0,1.75,-8,-37.5)" 312 + id="path7602" 313 + style="opacity:0.16289595;fill:url(#radialGradient7610);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> 314 + <path 315 + d="M 24.281173,13.417592 C 21.785192,13.938638 16.273503,11.934434 11.978296,8.943923 7.683089,5.953412 6.222848,3.103453 8.718829,2.582407" 316 + id="use6159" 317 + style="fill:none;stroke:#babdb6;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0.69999992" /> 318 + <path 319 + d="m 21.021707,7.056075 c 4.295207,2.990511 5.755448,5.840471 3.259466,6.361517 C 21.785192,13.938638 16.273503,11.934434 11.978296,8.943923 7.683089,5.953412 6.222848,3.103453 8.718829,2.582407 11.214811,2.061361 16.7265,4.065564 21.021707,7.056075 z" 320 + id="use6161" 321 + style="fill:none;stroke:url(#radialGradient6179);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0.69999992" /> 322 + <path 323 + d="m 12.0625,2.0625 a 0.90625,0.5625 0 1 1 -1.8125,0 0.90625,0.5625 0 1 1 1.8125,0 z" 324 + transform="matrix(1.1034483,0,0,1.7777778,2.636801,7.009256)" 325 + id="use6173" 326 + style="fill:url(#radialGradient6201);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> 327 + <g 328 + transform="matrix(1.222459,0.3275569,-0.3275569,1.222459,15.102844,-16.514282)" 329 + id="g7413"> 330 + <path 331 + d="m 13.4375,16.5 c -3.9188838,-1e-6 -7.09375,3.157775 -7.09375,7.0625 2e-7,2.818198 1.6046259,5.300595 4,6.4375 l 0,1.5 1.5,1.5 -1.5,1.5 0,1 2,1 0,1 -2,1 0,1 1.5,1.5 -1.5,1.5 0,1 2.5,2 2.5,0 1,-1.5 0,-14 c 2.372429,-1.145434 4,-3.698516 4,-6.5 0,-3.904724 -2.987366,-7 -6.90625,-7 z m -0.09375,2 c 1.104,0 2,0.896 2,2 0,1.104 -0.896,2 -2,2 -1.104,0 -2,-0.896 -2,-2 0,-1.104 0.896,-2 2,-2 z" 332 + id="path7415" 333 + style="fill:url(#linearGradient7425);fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:0.79014969;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> 334 + <path 335 + d="M 18.846598,24 8.028422,24 c 0,2.76 2.423271,5 5.409088,5 2.985817,0 5.409088,-2.24 5.409088,-5 z" 336 + id="path7417" 337 + style="opacity:0.3;fill:url(#linearGradient7427);fill-opacity:1;fill-rule:evenodd;stroke:none" /> 338 + <path 339 + d="m 13.4375,17.28125 c -3.5016836,-1e-6 -6.3125,2.797504 -6.3125,6.28125 2e-7,2.523398 1.4413689,4.743258 3.5625,5.75 A 0.7767123,0.7767123 0 0 1 11.125,30 l 0,1.15625 1.28125,1.28125 a 0.7767123,0.7767123 0 0 1 0,1.125 l -1.28125,1.28125 0,0.1875 1.5625,0.78125 A 0.7767123,0.7767123 0 0 1 13.125,36.5 l 0,1 a 0.7767123,0.7767123 0 0 1 -0.4375,0.6875 l -1.5625,0.78125 0,0.1875 1.28125,1.28125 a 0.7767123,0.7767123 0 0 1 0,1.125 l -1.28125,1.28125 0,0.28125 2,1.59375 1.78125,0 0.65625,-0.96875 0,-13.75 A 0.7767123,0.7767123 0 0 1 16,29.3125 c 2.090762,-1.009442 3.5625,-3.311816 3.5625,-5.8125 0,-3.508607 -2.615059,-6.21875 -6.125,-6.21875 z m -0.09375,0.4375 c 1.524208,0 2.78125,1.257042 2.78125,2.78125 0,1.524208 -1.257042,2.78125 -2.78125,2.78125 -1.524208,0 -2.78125,-1.257042 -2.78125,-2.78125 0,-1.524208 1.257042,-2.78125 2.78125,-2.78125 z" 340 + id="path7419" 341 + style="fill:none;stroke:white;stroke-width:0.79014969;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> 342 + <path 343 + d="m 13.40625,17.625 c -0.218712,0.0043 -0.466555,0.03416 -0.6875,0.0625 -0.93254,0.119629 -1.775868,0.460272 -2.53125,0.9375 0.173643,0.634817 0.42464,1.158079 0.71875,1.625 0.125954,-1.319354 1.241853,-2.34375 2.59375,-2.34375 1.436081,0 2.59375,1.157668 2.59375,2.59375 0,1.436083 -1.157669,2.59375 -2.59375,2.59375 -0.07717,0 -0.14697,-0.02119 -0.21875,-0.03125 1.059311,1.270254 2.021943,2.944267 2.28125,6.09375 2.266237,-0.909044 3.875,-2.925566 3.875,-5.59375 -0.08555,-2.601924 -1.541462,-4.611423 -4,-5.625 -0.680148,-0.225329 -1.363612,-0.325754 -2.03125,-0.3125 z M 15.375,34.6875 c -0.279435,2.585586 -0.854558,5.742004 -1.8125,9.6875 l 1.15625,0 0.65625,-1.3125 0,-8.375 z" 344 + id="path7421" 345 + style="opacity:0.6;fill:url(#linearGradient7431);fill-opacity:1;fill-rule:evenodd;stroke:none" /> 346 + <rect 347 + width="16.311773" 348 + height="0.98128641" 349 + x="29" 350 + y="-14.84375" 351 + transform="matrix(0,1,-1,0,0,0)" 352 + id="rect7423" 353 + style="opacity:0.61538463;fill:url(#linearGradient7433);fill-opacity:1;fill-rule:evenodd;stroke:none" /> 354 + </g> 355 + <path 356 + d="m 25.6875,8.875 c -0.588561,0.036819 -1.182416,0.1207928 -1.78125,0.28125 -4.790674,1.283657 -7.65402,6.195384 -6.375,10.96875 0.923121,3.44513 3.699353,5.957302 7,6.5625 l 0.1875,0.75 L 25.25,25.5 c 3.275392,-0.623141 6.113605,-3.200301 7.03125,-6.625 1.018029,-3.799341 -0.444599,-7.588204 -3.5,-9.625 C 27.800972,8.9441375 26.762022,8.8077801 25.6875,8.875 z m -0.84375,1.5 c 0.167842,0.01005 0.331301,0.04855 0.5,0.09375 1.075458,0.288168 1.806766,1.228158 1.875,2.28125 0.129462,0.207411 0.245957,0.439157 0.3125,0.6875 0.361623,1.349595 -0.431656,2.732127 -1.78125,3.09375 -1.349595,0.361624 -2.732127,-0.431656 -3.09375,-1.78125 -0.04247,-0.158514 -0.08238,-0.310882 -0.09375,-0.46875 -0.0047,-0.0073 0.0046,-0.02393 0,-0.03125 -0.359793,-0.574923 -0.501749,-1.293712 -0.3125,-2 0.316419,-1.180896 1.418855,-1.945332 2.59375,-1.875 z" 357 + id="path7441" 358 + style="opacity:0.15;fill:black;fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:0.99999976;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> 359 + <g 360 + transform="matrix(1.222459,-0.3275569,0.3275569,1.222459,2.064799,-7.6041513)" 361 + id="g6765"> 362 + <path 363 + d="m 13.4375,16.5 c -3.9188838,-1e-6 -7.09375,3.157775 -7.09375,7.0625 2e-7,2.818198 1.6046259,5.300595 4,6.4375 l 0,1.5 1.5,1.5 -1.5,1.5 0,1 2,1 0,1 -2,1 0,1 1.5,1.5 -1.5,1.5 0,1 2.5,2 2.5,0 1,-1.5 0,-14 c 2.372429,-1.145434 4,-3.698516 4,-6.5 0,-3.904724 -2.987366,-7 -6.90625,-7 z m -0.09375,2 c 1.104,0 2,0.896 2,2 0,1.104 -0.896,2 -2,2 -1.104,0 -2,-0.896 -2,-2 0,-1.104 0.896,-2 2,-2 z" 364 + id="path6767" 365 + style="fill:url(#linearGradient6789);fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:0.79014969;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> 366 + <path 367 + d="M 18.846598,24 8.028422,24 c 0,2.76 2.423271,5 5.409088,5 2.985817,0 5.409088,-2.24 5.409088,-5 z" 368 + id="path6769" 369 + style="opacity:0.3;fill:url(#linearGradient6791);fill-opacity:1;fill-rule:evenodd;stroke:none" /> 370 + <path 371 + d="m 13.4375,17.28125 c -3.5016836,-1e-6 -6.3125,2.797504 -6.3125,6.28125 2e-7,2.523398 1.4413689,4.743258 3.5625,5.75 A 0.7767123,0.7767123 0 0 1 11.125,30 l 0,1.15625 1.28125,1.28125 a 0.7767123,0.7767123 0 0 1 0,1.125 l -1.28125,1.28125 0,0.1875 1.5625,0.78125 A 0.7767123,0.7767123 0 0 1 13.125,36.5 l 0,1 a 0.7767123,0.7767123 0 0 1 -0.4375,0.6875 l -1.5625,0.78125 0,0.1875 1.28125,1.28125 a 0.7767123,0.7767123 0 0 1 0,1.125 l -1.28125,1.28125 0,0.28125 2,1.59375 1.78125,0 0.65625,-0.96875 0,-13.75 A 0.7767123,0.7767123 0 0 1 16,29.3125 c 2.090762,-1.009442 3.5625,-3.311816 3.5625,-5.8125 0,-3.508607 -2.615059,-6.21875 -6.125,-6.21875 z m -0.09375,0.4375 c 1.524208,0 2.78125,1.257042 2.78125,2.78125 0,1.524208 -1.257042,2.78125 -2.78125,2.78125 -1.524208,0 -2.78125,-1.257042 -2.78125,-2.78125 0,-1.524208 1.257042,-2.78125 2.78125,-2.78125 z" 372 + id="path6771" 373 + style="fill:none;stroke:white;stroke-width:0.79014969;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> 374 + <path 375 + d="m 13.40625,17.625 c -0.218712,0.0043 -0.466555,0.03416 -0.6875,0.0625 -0.93254,0.119629 -1.775868,0.460272 -2.53125,0.9375 0.173643,0.634817 0.42464,1.158079 0.71875,1.625 0.125954,-1.319354 1.241853,-2.34375 2.59375,-2.34375 1.436081,0 2.59375,1.157668 2.59375,2.59375 0,1.436083 -1.157669,2.59375 -2.59375,2.59375 -0.07717,0 -0.14697,-0.02119 -0.21875,-0.03125 1.059311,1.270254 2.021943,2.944267 2.28125,6.09375 2.266237,-0.909044 3.875,-2.925566 3.875,-5.59375 -0.08555,-2.601924 -1.541462,-4.611423 -4,-5.625 -0.680148,-0.225329 -1.363612,-0.325754 -2.03125,-0.3125 z M 15.375,34.6875 c -0.279435,2.585586 -0.854558,5.742004 -1.8125,9.6875 l 1.15625,0 0.65625,-1.3125 0,-8.375 z" 376 + id="path6832" 377 + style="opacity:0.6;fill:url(#linearGradient6834);fill-opacity:1;fill-rule:evenodd;stroke:none" /> 378 + <rect 379 + width="16.311773" 380 + height="0.98128641" 381 + x="29" 382 + y="-14.84375" 383 + transform="matrix(0,1,-1,0,0,0)" 384 + id="rect6776" 385 + style="opacity:0.61538463;fill:url(#linearGradient6798);fill-opacity:1;fill-rule:evenodd;stroke:none" /> 386 + </g> 387 + <path 388 + d="M 7.973909,5.14413 C 6.383785,2.550006 8.912938,1.724058 13.619341,3.300498 c 4.706403,1.57644 9.816629,4.961246 11.406753,7.555371 0.789043,1.287243 0.643566,2.112963 -0.43671,2.478739" 389 + id="use6163" 390 + style="fill:none;stroke:url(#radialGradient6183);stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0.69999992" /> 391 + <path 392 + d="m 12.0625,2.0625 a 0.90625,0.5625 0 1 1 -1.8125,0 0.90625,0.5625 0 1 1 1.8125,0 z" 393 + transform="matrix(1.5911082,0,0,2.563452,-6.228703,-2.588246)" 394 + id="use6165" 395 + style="fill:url(#radialGradient6187);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> 396 + <path 397 + d="M 10.813348,8.082144 C 6.962997,5.046919 6.385696,2.546748 9.524729,2.501404 12.663762,2.45606 18.336305,4.88263 22.186655,7.917855 c 3.791641,2.988943 4.422284,5.460973 1.422808,5.577195" 398 + id="use6167" 399 + style="fill:none;stroke:url(#radialGradient6191);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0.69999992" /> 400 + <path 401 + d="m 22.186054,7.917381 c 3.792118,2.989106 4.423052,5.46144 1.423409,5.577669" 402 + id="use6169" 403 + style="opacity:0.10407242;fill:none;stroke:url(#linearGradient6195);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0.69999992" /> 404 + <path 405 + d="m 12.0625,2.0625 a 0.90625,0.5625 0 1 1 -1.8125,0 0.90625,0.5625 0 1 1 1.8125,0 z" 406 + transform="matrix(1.1034483,0,0,1.7777778,-0.69986,-0.945696)" 407 + id="use6171" 408 + style="fill:white;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> 409 + </g> 410 + </svg>
+65
static/icons/humanity/apps/utilities-system-monitor.svg
··· 1 + <?xml version="1.0" encoding="UTF-8" standalone="no"?> 2 + <!-- Created with Inkscape (http://www.inkscape.org/) --> 3 + <svg id="svg3769" xmlns="http://www.w3.org/2000/svg" height="48" width="48" version="1.0" xmlns:xlink="http://www.w3.org/1999/xlink"> 4 + <defs id="defs3771"> 5 + <linearGradient id="linearGradient2605" y2="609.51" gradientUnits="userSpaceOnUse" x2="302.86" gradientTransform="matrix(.065534 0 0 .024706 .31399 31.942)" y1="366.65" x1="302.86"> 6 + <stop id="stop5050-5" style="stop-opacity:0" offset="0"/> 7 + <stop id="stop5056-9" offset=".5"/> 8 + <stop id="stop5052-6" style="stop-opacity:0" offset="1"/> 9 + </linearGradient> 10 + <radialGradient id="radialGradient2602" xlink:href="#linearGradient5060-6" gradientUnits="userSpaceOnUse" cy="486.65" cx="605.71" gradientTransform="matrix(.065534 0 0 .024706 .32688 31.942)" r="117.14"/> 11 + <linearGradient id="linearGradient5060-6"> 12 + <stop id="stop5062-3" offset="0"/> 13 + <stop id="stop5064-1" style="stop-opacity:0" offset="1"/> 14 + </linearGradient> 15 + <radialGradient id="radialGradient2599" xlink:href="#linearGradient5060-6" gradientUnits="userSpaceOnUse" cy="486.65" cx="605.71" gradientTransform="matrix(-.065534 0 0 .024706 47.673 31.942)" r="117.14"/> 16 + <linearGradient id="linearGradient2596" y2="2.8765" gradientUnits="userSpaceOnUse" x2="10.014" gradientTransform="matrix(.95745 0 0 .90347 1.0212 4.3056)" y1="44.96" x1="10.014"> 17 + <stop id="stop4334" style="stop-color:#595959" offset="0"/> 18 + <stop id="stop4336" style="stop-color:#b3b3b3" offset="1"/> 19 + </linearGradient> 20 + <linearGradient id="linearGradient2594" y2="43.865" gradientUnits="userSpaceOnUse" x2="24" y1="7.96" x1="24"> 21 + <stop id="stop4324" style="stop-color:#d8d8d8" offset="0"/> 22 + <stop id="stop2860" style="stop-color:#afafaf" offset=".085525"/> 23 + <stop id="stop2862" style="stop-color:#aaa" offset=".92166"/> 24 + <stop id="stop4326" style="stop-color:#8f8f8f" offset="1"/> 25 + </linearGradient> 26 + <radialGradient id="radialGradient2591" gradientUnits="userSpaceOnUse" cy="12.225" cx="16.352" gradientTransform="matrix(0 .96364 -2.2356 0 48.282 6.3239)" r="19.17"> 27 + <stop id="stop4130" style="stop-color:#3d434a" offset="0"/> 28 + <stop id="stop4132" offset="1"/> 29 + </radialGradient> 30 + <linearGradient id="linearGradient2588" y2="33.296" gradientUnits="userSpaceOnUse" x2="23.071" gradientTransform="matrix(.99105 0 0 1.0115 .22050 5.8121)" y1="36.047" x1="23.071"> 31 + <stop id="stop2225-6" style="stop-color:#fff" offset="0"/> 32 + <stop id="stop2229-2" style="stop-color:#fff;stop-opacity:0" offset="1"/> 33 + </linearGradient> 34 + <linearGradient id="linearGradient2582" y2="24.628" gradientUnits="userSpaceOnUse" x2="20.055" gradientTransform="matrix(.95782 0 0 1.0183 1.0122 1.9221)" y1="15.298" x1="16.626"> 35 + <stop id="stop2687-1-9" style="stop-color:#fff" offset="0"/> 36 + <stop id="stop2689-5-4" style="stop-color:#fff;stop-opacity:0" offset="1"/> 37 + </linearGradient> 38 + <linearGradient id="linearGradient2579" y2="41.827" gradientUnits="userSpaceOnUse" x2="12.579" gradientTransform="matrix(.95464 0 0 .89653 1.0875 5.3852)" y1="-7.8074" x1="12.579"> 39 + <stop id="stop2240-1-6" style="stop-color:#fff" offset="0"/> 40 + <stop id="stop2242-7-3" style="stop-color:#fff;stop-opacity:0" offset="1"/> 41 + </linearGradient> 42 + <filter id="filter3499" height="1.3069" width="1.1397" color-interpolation-filters="sRGB" y="-.15347" x="-.069845"> 43 + <feGaussianBlur id="feGaussianBlur3501" stdDeviation="1.0231264"/> 44 + </filter> 45 + </defs> 46 + <g id="layer1"> 47 + <rect id="rect2512" style="opacity:.40206;fill:url(#linearGradient2605)" height="6" width="31.644" y="41" x="8.1781"/> 48 + <path id="path2514" style="opacity:.40206;fill:url(#radialGradient2602)" d="m39.822 41v5.9997c3.3749 0.01129 8.1588-1.3442 8.1588-3.0002s-3.7661-2.9994-8.1588-2.9994z"/> 49 + <path id="path2516" style="opacity:.40206;fill:url(#radialGradient2599)" d="m8.1781 41v5.9997c-3.3749 0.01129-8.1588-1.3442-8.1588-3.0002s3.7661-2.9994 8.1588-2.9994z"/> 50 + <rect id="rect2551" style="stroke-linejoin:round;fill-rule:evenodd;stroke:url(#linearGradient2596);stroke-linecap:round;stroke-width:1.0021;fill:url(#linearGradient2594)" rx="1.4989" ry="1.4989" height="36.998" width="44.998" y="7.5011" x="1.5011"/> 51 + <rect id="rect1314" style="stroke-linejoin:round;fill-rule:evenodd;stroke:#1e1f1f;stroke-linecap:round;stroke-width:1.0021;fill:url(#radialGradient2591)" rx="0" ry="0" height="28.998" width="36.998" y="11.501" x="5.5011"/> 52 + <rect id="rect2221" style="opacity:.4;stroke-linejoin:round;stroke:url(#linearGradient2588);stroke-linecap:round;stroke-width:1.0021;fill:none" rx="0" ry="0" height="30.998" width="38.998" y="10.501" x="4.5011"/> 53 + <path id="path3333" style="opacity:.2;fill:url(#linearGradient2582);fill-rule:evenodd" d="m4.0952 8c-1.1573 0-2.0952 0.99713-2.0952 2.2275v16.293c0.0027 0.13706 0.05919 0.26668 0.15589 0.35738 0.09669 0.0907 0.2247 0.1342 0.35296 0.11994l43.102-7.2553c0.22172-0.03717 0.38602-0.23872 0.38912-0.47732v-9.0373c0-1.2304-0.93792-2.2275-2.0952-2.2275h-39.81z"/> 54 + <rect id="rect2556" style="opacity:.4;stroke-linejoin:round;stroke:url(#linearGradient2579);stroke-linecap:round;stroke-width:1.0037;fill:none" rx=".49813" ry=".49813" height="34.996" width="42.996" y="8.5019" x="2.5019"/> 55 + <path id="path2233" style="opacity:.1;stroke-width:1px;stroke:#b9ffeb;stroke-linecap:square;fill:none" d="m6.5 13.5h35"/> 56 + <path id="path2235" style="opacity:.1;stroke-width:1px;stroke:#b9ffeb;stroke-linecap:square;fill:none" d="m6.5 17.5h35"/> 57 + <path id="path2237" style="opacity:.1;stroke-width:1px;stroke:#b9ffeb;stroke-linecap:square;fill:none" d="m6.5 21.5h35"/> 58 + <path id="path2239" style="opacity:.1;stroke-width:1px;stroke:#b9ffeb;stroke-linecap:square;fill:none" d="m6.5 25.5h35"/> 59 + <path id="path2241" style="opacity:.1;stroke-width:1px;stroke:#b9ffeb;stroke-linecap:square;fill:none" d="m6.5 29.5h35"/> 60 + <path id="path2243" style="opacity:.1;stroke-width:1px;stroke:#b9ffeb;stroke-linecap:square;fill:none" d="m6.5 33.5h35"/> 61 + <path id="path2245" style="opacity:.1;stroke-width:1px;stroke:#b9ffeb;stroke-linecap:square;fill:none" d="m6.5 37.5h35"/> 62 + <path id="path3497" style="stroke-linejoin:round;filter:url(#filter3499);stroke:#3a7d6b;stroke-linecap:round;stroke-width:2;fill:none" d="m6.9276 27.5h6.5724l2-10 4 15 3-9 3 6 3-2h12.584"/> 63 + <path id="path3477" style="stroke-linejoin:round;stroke:#b9ffeb;stroke-linecap:round;stroke-width:1px;fill:none" d="m6.9276 27.5h6.5724l2-10 4 15 3-9 3 6 3-2h12.584"/> 64 + </g> 65 + </svg>