Refactored dashboard icons and menu registration

This commit is contained in:
Marc Aymerich 2015-05-07 14:09:37 +00:00
parent 524b1ce15f
commit 17974d41fa
79 changed files with 2515 additions and 317 deletions

15
TODO.md
View File

@ -376,3 +376,18 @@ TODO mount the filesystem with "nosuid" option
# orchestrate async stdout stderr (inspired on pangea managemengt commands)
# orchestra-beat support for uwsgi cron
# message.log if 1: return changeform
# generate nginx certs on project dir rather than nginx
# Register icons
# send_message doesn't log task
make django admin taskstate uncollapse fucking traceback, ( if exists ?)
# receive tass stuck at RECEIVED
# monitor tasks in started and backend already in success?
# custom message on admin save

View File

@ -1,45 +1,61 @@
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _
from fluent_dashboard import dashboard
from fluent_dashboard.modules import CmsAppIconList
from orchestra.core import services
from orchestra.core import services, accounts, administration
class AppDefaultIconList(CmsAppIconList):
def __init__(self, *args, **kwargs):
self.icons = kwargs.pop('icons')
super(AppDefaultIconList, self).__init__(*args, **kwargs)
def get_icon_for_model(self, app_name, model_name, default=None):
icon = self.icons.get('.'.join((app_name, model_name)))
return super(AppDefaultIconList, self).get_icon_for_model(app_name, model_name, default=icon)
class OrchestraIndexDashboard(dashboard.FluentIndexDashboard):
_registry = {}
@classmethod
def register_link(cls, module, view_name, title):
registered = cls._registry.get(module, [])
registered.append((view_name, title))
cls._registry[module] = registered
def process_registered_view(self, module, view_name, options):
app_name, name = view_name.split('_')[:-1]
module.icons['.'.join((app_name, name))] = options.get('icon')
url = reverse('admin:' + view_name)
add_url = '/'.join(url.split('/')[:-2])
module.children.append({
'models': [{
'add_url': add_url,
'app_name': app_name,
'change_url': url,
'name': name,
'title': options.get('verbose_name')}],
'name': app_name,
'title': options.get('verbose_name'),
'url': add_url,
})
def get_application_modules(self):
modules = super(OrchestraIndexDashboard, self).get_application_modules()
models = []
for model, options in services.get().items():
if options.get('menu', True):
models.append("%s.%s" % (model.__module__, model._meta.object_name))
for module in modules:
registered = self._registry.get(module.title, None)
if registered:
for view_name, title in registered:
# This values are shit, but it is how fluent dashboard will look for the icon
app_name, name = view_name.split('_')[:-1]
url = reverse('admin:' + view_name)
add_url = '/'.join(url.split('/')[:-2])
module.children.append({
'models': [{
'add_url': add_url,
'app_name': app_name,
'change_url': url,
'name': name,
'title': title }],
'name': app_name,
'title': title,
'url': add_url,
})
service_icon_list = CmsAppIconList('Services', models=models, collapsible=True)
modules.append(service_icon_list)
from fluent_dashboard import appsettings
modules = []
# Honor settings override, hacky. I Know
if appsettings.FLUENT_DASHBOARD_APP_GROUPS[0][0] != _('CMS'):
modules = super(OrchestraIndexDashboard, self).get_application_modules()
for register in (accounts, administration, services):
title = register.verbose_name
models = []
icons = {}
views = []
for model, options in register.get().items():
if isinstance(model, str):
views.append((model, options))
elif options.get('dashboard', True):
opts = model._meta
label = "%s.%s" % (model.__module__, opts.object_name)
models.append(label)
label = '.'.join((opts.app_label, opts.model_name))
icons[label] = options.get('icon')
module = AppDefaultIconList(title, models=models, icons=icons, collapsible=True)
for view_name, options in views:
self.process_registered_view(module, view_name, options)
modules.append(module)
return modules

View File

@ -27,80 +27,37 @@ def api_link(context):
return reverse('api-root')
def process_registered_models(register):
childrens = []
for model, options in register.get().items():
if options.get('menu', True):
from copy import copy
def process_registry(register):
def get_item(model, options):
if isinstance(model, str):
url = reverse('admin:'+model)
else:
opts = model._meta
url = reverse('admin:{}_{}_changelist'.format(
opts.app_label, opts.model_name))
name = capfirst(options.get('verbose_name_plural'))
childrens.append(items.MenuItem(name, url))
return childrens
def get_services():
childrens = process_registered_models(services)
return sorted(childrens, key=lambda i: i.title)
def get_accounts():
childrens=[]
if isinstalled('orchestra.contrib.payments'):
url = reverse('admin:payments_transactionprocess_changelist')
childrens.append(items.MenuItem(_("Transaction processes"), url))
if isinstalled('orchestra.contrib.issues'):
url = reverse('admin:issues_ticket_changelist')
childrens.append(items.MenuItem(_("Tickets"), url))
childrens.extend(process_registered_models(accounts))
return sorted(childrens, key=lambda i: i.title)
def get_administration_items():
childrens = []
if isinstalled('orchestra.contrib.settings'):
url = reverse('admin:settings_setting_change')
childrens.append(items.MenuItem(_("Settings"), url))
if isinstalled('orchestra.contrib.services'):
url = reverse('admin:services_service_changelist')
childrens.append(items.MenuItem(_("Services"), url))
url = reverse('admin:plans_plan_changelist')
childrens.append(items.MenuItem(_("Plans"), url))
if isinstalled('orchestra.contrib.orchestration'):
route = reverse('admin:orchestration_route_changelist')
backendlog = reverse('admin:orchestration_backendlog_changelist')
server = reverse('admin:orchestration_server_changelist')
childrens.append(items.MenuItem(_("Orchestration"), route, children=[
items.MenuItem(_("Routes"), route),
items.MenuItem(_("Backend logs"), backendlog),
items.MenuItem(_("Servers"), server),
]))
if isinstalled('orchestra.contrib.resources'):
resource = reverse('admin:resources_resource_changelist')
data = reverse('admin:resources_resourcedata_changelist')
monitor = reverse('admin:resources_monitordata_changelist')
childrens.append(items.MenuItem(_("Resources"), resource, children=[
items.MenuItem(_("Resources"), resource),
items.MenuItem(_("Data"), data),
items.MenuItem(_("Monitoring"), monitor),
]))
if isinstalled('orchestra.contrib.miscellaneous'):
url = reverse('admin:miscellaneous_miscservice_changelist')
childrens.append(items.MenuItem(_("Miscellaneous"), url))
if isinstalled('orchestra.contrib.issues'):
url = reverse('admin:issues_queue_changelist')
childrens.append(items.MenuItem(_("Ticket queues"), url))
if isinstalled('djcelery'):
task = reverse('admin:djcelery_taskstate_changelist')
periodic = reverse('admin:djcelery_periodictask_changelist')
worker = reverse('admin:djcelery_workerstate_changelist')
childrens.append(items.MenuItem(_("Tasks"), task, children=[
items.MenuItem(_("Logs"), task),
items.MenuItem(_("Periodic tasks"), periodic),
items.MenuItem(_("Workers"), worker),
]))
childrens.extend(process_registered_models(administration))
return childrens
opts.app_label, opts.model_name))
name = capfirst(options.get('verbose_name_plural'))
return items.MenuItem(name, url)
childrens = {}
for model, options in register.get().items():
if options.get('menu', True):
parent = options.get('parent')
if parent:
parent_item = childrens.get(parent)
if parent_item:
if not parent_item.children:
parent_item.children.append(copy(parent_item))
else:
parent_item = get_item(parent, register[parent])
parent_item.children = []
parent_item.children.append(get_item(model, options))
childrens[parent] = parent_item
elif model not in childrens:
childrens[model] = get_item(model, options)
else:
childrens[model].children.insert(0, get_item(model, options))
return sorted(childrens.values(), key=lambda i: i.title)
class OrchestraMenu(Menu):
@ -122,16 +79,16 @@ class OrchestraMenu(Menu):
# items.Bookmarks(),
items.MenuItem(
_("Services"),
children=get_services()
children=process_registry(services)
),
items.MenuItem(
_("Accounts"),
reverse('admin:accounts_account_changelist'),
children=get_accounts()
children=process_registry(accounts)
),
items.MenuItem(
_("Administration"),
children=get_administration_items()
children=process_registry(administration)
),
items.MenuItem("API", api_link(context)),
]

View File

@ -233,75 +233,6 @@ ADMIN_TOOLS_MENU = 'orchestra.admin.menu.OrchestraMenu'
# Fluent dashboard
ADMIN_TOOLS_INDEX_DASHBOARD = 'orchestra.admin.dashboard.OrchestraIndexDashboard'
FLUENT_DASHBOARD_ICON_THEME = '../orchestra/icons'
FLUENT_DASHBOARD_APP_GROUPS = (
# Services group is generated by orchestra.admin.dashboard
('Accounts', {
'models': (
'orchestra.contrib.accounts.models.Account',
'orchestra.contrib.contacts.models.Contact',
'orchestra.contrib.orders.models.Order',
'orchestra.contrib.plans.models.ContractedPlan',
'orchestra.contrib.bills.models.Bill',
'orchestra.contrib.payments.models.Transaction',
'orchestra.contrib.issues.models.Ticket',
),
'collapsible': True,
}),
('Administration', {
'models': (
'djcelery.models.TaskState',
'orchestra.contrib.orchestration.models.Route',
'orchestra.contrib.orchestration.models.BackendLog',
'orchestra.contrib.orchestration.models.Server',
'orchestra.contrib.resources.models.Resource',
'orchestra.contrib.resources.models.ResourceData',
'orchestra.contrib.services.models.Service',
'orchestra.contrib.plans.models.Plan',
'orchestra.contrib.miscellaneous.models.MiscService',
),
'collapsible': True,
}),
)
FLUENT_DASHBOARD_APP_ICONS = {
# Services
'webs/web': 'web.png',
'mail/address': 'X-office-address-book.png',
'mailboxes/mailbox': 'email.png',
'mailboxes/address': 'X-office-address-book.png',
'lists/list': 'email-alter.png',
'domains/domain': 'domain.png',
'multitenance/tenant': 'apps.png',
'webapps/webapp': 'Applications-other.png',
'websites/website': 'Applications-internet.png',
'databases/database': 'database.png',
'databases/databaseuser': 'postgresql.png',
'vps/vps': 'TuxBox.png',
'miscellaneous/miscellaneous': 'applications-other.png',
'saas/saas': 'saas.png',
'systemusers/systemuser': 'roleplaying.png',
# Accounts
'accounts/account': 'Face-monkey.png',
'contacts/contact': 'contact_book.png',
'orders/order': 'basket.png',
'plans/contractedplan': 'ContractedPack.png',
'services/service': 'price.png',
'bills/bill': 'invoice.png',
'payments/paymentsource': 'card_in_use.png',
'payments/transaction': 'transaction.png',
'payments/transactionprocess': 'transactionprocess.png',
'issues/ticket': 'Ticket_star.png',
'miscellaneous/miscservice': 'Misc-Misc-Box-icon.png',
# Administration
'settings/setting': 'preferences.png',
'djcelery/taskstate': 'taskstate.png',
'orchestration/server': 'vps.png',
'orchestration/route': 'hal.png',
'orchestration/backendlog': 'scriptlog.png',
'resources/resource': "gauge.png",
'resources/resourcedata': "monitor.png",
'plans/plan': 'Pack.png',
}
# Django-celery

View File

@ -12,7 +12,7 @@ class AccountConfig(AppConfig):
def ready(self):
from .management import create_initial_superuser
from .models import Account
services.register(Account, menu=False)
accounts.register(Account)
services.register(Account, menu=False, dashboard=False)
accounts.register(Account, icon='Face-monkey.png')
post_migrate.connect(create_initial_superuser,
dispatch_uid="orchestra.contrib.accounts.management.createsuperuser")

View File

@ -0,0 +1 @@
default_app_config = 'orchestra.contrib.bills.apps.BillsConfig'

View File

@ -0,0 +1,12 @@
from django.apps import AppConfig
from orchestra.core import accounts
class BillsConfig(AppConfig):
name = 'orchestra.contrib.bills'
verbose_name = 'Bills'
def ready(self):
from .models import Bill
accounts.register(Bill, icon='invoice.png')

View File

@ -13,7 +13,7 @@ from django.utils.translation import ugettext_lazy as _
from orchestra.contrib.accounts.models import Account
from orchestra.contrib.contacts.models import Contact
from orchestra.core import accounts, validators
from orchestra.core import validators
from orchestra.utils.html import html_to_pdf
from . import settings
@ -351,6 +351,3 @@ class BillSubline(models.Model):
# if self.line.bill.is_open:
# self.line.bill.total = self.line.bill.get_total()
# self.line.bill.save(update_fields=['total'])
accounts.register(Bill)

View File

@ -0,0 +1 @@
default_app_config = 'orchestra.contrib.contacts.apps.ContactsConfig'

View File

@ -0,0 +1,12 @@
from django.apps import AppConfig
from orchestra.core import accounts
class ContactsConfig(AppConfig):
name = 'orchestra.contrib.contacts'
verbose_name = 'Contacts'
def ready(self):
from .models import Contact
accounts.register(Contact, icon='contact_book.png')

View File

@ -3,7 +3,7 @@ from django.core.validators import RegexValidator
from django.db import models
from django.utils.translation import ugettext_lazy as _
from orchestra.core import accounts, validators
from orchestra.core import validators
from orchestra.models.fields import MultiSelectField
from . import settings
@ -78,6 +78,3 @@ class Contact(models.Model):
errors['zipcode'] = error
if errors:
raise ValidationError(errors)
accounts.register(Contact)

View File

@ -0,0 +1 @@
default_app_config = 'orchestra.contrib.databases.apps.DatabasesConfig'

View File

@ -0,0 +1,14 @@
from django.apps import AppConfig
from django.utils.translation import ugettext_lazy as _
from orchestra.core import services
class DatabasesConfig(AppConfig):
name = 'orchestra.contrib.databases'
verbose_name = 'Databases'
def ready(self):
from .models import Database, DatabaseUser
services.register(Database, icon='database.png')
services.register(DatabaseUser, icon='postgresql.png', verbose_name_plural=_("Database users"))

View File

@ -3,7 +3,7 @@ import hashlib
from django.db import models
from django.utils.translation import ugettext_lazy as _
from orchestra.core import validators, services
from orchestra.core import validators
from . import settings
@ -76,7 +76,3 @@ class DatabaseUser(models.Model):
self.password = '*%s' % hexdigest.upper()
else:
raise TypeError("Database type '%s' not supported" % self.type)
services.register(Database)
services.register(DatabaseUser, verbose_name_plural=_("Database users"))

View File

@ -0,0 +1 @@
default_app_config = 'orchestra.contrib.domains.apps.DomainsConfig'

View File

@ -11,8 +11,8 @@ from orchestra.contrib.accounts.admin import AccountAdminMixin
from orchestra.utils import apps
from .actions import view_zone
from .forms import RecordInlineFormSet, BatchDomainCreationAdminForm
from .filters import TopDomainListFilter
from .forms import RecordInlineFormSet, BatchDomainCreationAdminForm
from .models import Domain, Record
@ -21,11 +21,6 @@ class RecordInline(admin.TabularInline):
formset = RecordInlineFormSet
verbose_name_plural = _("Extra records")
# class Media:
# css = {
# 'all': ('orchestra/css/hide-inline-id.css',)
# }
#
def formfield_for_dbfield(self, db_field, **kwargs):
""" Make value input widget bigger """
if db_field.name == 'value':
@ -73,9 +68,9 @@ class DomainAdmin(AccountAdminMixin, ExtendedModelAdmin):
change_view_actions = [view_zone]
def structured_name(self, domain):
if not domain.is_top:
return ' '*4 + domain.name
return domain.name
if domain.is_top:
return domain.name
return ' '*4 + domain.name
structured_name.short_description = _("name")
structured_name.allow_tags = True
structured_name.admin_order_field = 'structured_name'

View File

@ -0,0 +1,12 @@
from django.apps import AppConfig
from orchestra.core import services
class DomainsConfig(AppConfig):
name = 'orchestra.contrib.domains'
verbose_name = 'Domains'
def ready(self):
from .models import Domain
services.register(Domain, icon='domain.png')

View File

@ -2,7 +2,6 @@ from django.core.exceptions import ValidationError
from django.db import models
from django.utils.translation import ungettext, ugettext_lazy as _
from orchestra.core import services
from orchestra.core.validators import validate_ipv4_address, validate_ipv6_address, validate_ascii
from orchestra.utils.python import AttrDict
@ -271,6 +270,3 @@ class Record(models.Model):
def get_ttl(self):
return self.ttl or settings.DOMAINS_DEFAULT_TTL
services.register(Domain)

View File

@ -1 +1 @@
REQUIRED_APPS = ['slices']
default_app_config = 'orchestra.contrib.issues.apps.IssuesConfig'

View File

@ -0,0 +1,13 @@
from django.apps import AppConfig
from orchestra.core import accounts, administration
class IssuesConfig(AppConfig):
name = 'orchestra.contrib.issues'
verbose_name = "Issues"
def ready(self):
from .models import Queue, Ticket
accounts.register(Ticket, icon='Ticket_star.png')
administration.register(Queue, dashboard=False)

View File

@ -0,0 +1 @@
default_app_config = 'orchestra.contrib.lists.apps.ListsConfig'

View File

@ -0,0 +1,12 @@
from django.apps import AppConfig
from orchestra.core import services
class ListsConfig(AppConfig):
name = 'orchestra.contrib.lists'
verbose_name = 'Lists'
def ready(self):
from .models import List
services.register(List, icon='email-alter.png')

View File

@ -2,7 +2,6 @@ from django.db import models
from django.utils.functional import cached_property
from django.utils.translation import ugettext_lazy as _
from orchestra.core import services
from orchestra.core.validators import validate_name
from . import settings
@ -70,6 +69,3 @@ class List(models.Model):
'name': self.name
}
return settings.LISTS_LIST_URL % context
services.register(List)

View File

@ -0,0 +1 @@
default_app_config = 'orchestra.contrib.mailboxes.apps.MailboxesConfig'

View File

@ -0,0 +1,13 @@
from django.apps import AppConfig
from orchestra.core import services
class MailboxesConfig(AppConfig):
name = 'orchestra.contrib.mailboxes'
verbose_name = 'Mailboxes'
def ready(self):
from .models import Mailbox, Address
services.register(Mailbox, icon='email.png')
services.register(Address, icon='X-office-address-book.png')

View File

@ -6,8 +6,6 @@ from django.db import models
from django.utils.functional import cached_property
from django.utils.translation import ugettext_lazy as _
from orchestra.core import services
from . import validators, settings
@ -152,7 +150,3 @@ class Autoresponse(models.Model):
def __str__(self):
return self.address
services.register(Mailbox)
services.register(Address)

View File

@ -9,4 +9,4 @@ class MailerConfig(AppConfig):
def ready(self):
from .models import Message
administration.register(Message)
administration.register(Message, icon='Mail-send.png')

View File

@ -43,7 +43,7 @@ class Message(models.Model):
# Max tries
if self.retries >= len(settings.MAILER_DEFERE_SECONDS):
self.state = self.FAILED
self.save(update_fields=('state', 'retries'))
self.save(update_fields=('state', 'retries', 'last_retry'))
def sent(self):
self.state = self.SENT

View File

@ -0,0 +1 @@
default_app_config = 'orchestra.contrib.miscellaneous.apps.MiscellaneousConfig'

View File

@ -0,0 +1,15 @@
from django.apps import AppConfig
from orchestra.core import services, administration
from orchestra.core.translations import ModelTranslation
class MiscellaneousConfig(AppConfig):
name = 'orchestra.contrib.miscellaneous'
verbose_name = 'Miscellaneous'
def ready(self):
from .models import MiscService, Miscellaneous
services.register(Miscellaneous, icon='applications-other.png')
administration.register(MiscService, icon='Misc-Misc-Box-icon.png')
ModelTranslation.register(MiscService, ('verbose_name',))

View File

@ -2,8 +2,6 @@ from django.db import models
from django.utils.functional import cached_property
from django.utils.translation import ugettext_lazy as _
from orchestra.core import services
from orchestra.core.translations import ModelTranslation
from orchestra.core.validators import validate_name
from orchestra.models.fields import NullableCharField
@ -69,8 +67,3 @@ class Miscellaneous(models.Model):
if self.identifier:
self.identifier = self.identifier.strip()
self.description = self.description.strip()
services.register(Miscellaneous)
ModelTranslation.register(MiscService, ('verbose_name',))

View File

@ -3,6 +3,9 @@ import copy
from .backends import ServiceBackend, ServiceController, replace
default_app_config = 'orchestra.contrib.orchestration.apps.OrchestrationConfig'
class Operation():
DELETE = 'delete'
SAVE = 'save'
@ -30,10 +33,10 @@ class Operation():
self.routes = routes
@classmethod
def execute(cls, operations, async=False):
def execute(cls, operations, serialize=False, async=False):
from . import manager
scripts, block = manager.generate(operations)
return manager.execute(scripts, block=block, async=async)
scripts, oserialize = manager.generate(operations)
return manager.execute(scripts, serialize=(serialize or oserialize), async=async)
@classmethod
def execute_action(cls, instance, action):

View File

@ -0,0 +1,14 @@
from django.apps import AppConfig
from orchestra.core import administration
class OrchestrationConfig(AppConfig):
name = 'orchestra.contrib.orchestration'
verbose_name = "Orchestration"
def ready(self):
from .models import Server, Route, BackendLog
administration.register(BackendLog, icon='scriptlog.png')
administration.register(Server, parent=BackendLog, icon='vps.png')
administration.register(Route, parent=BackendLog, icon='hal.png')

View File

@ -45,7 +45,7 @@ class ServiceBackend(plugins.Plugin, metaclass=ServiceMount):
actions = []
default_route_match = 'True'
# Force the backend manager to block in multiple backend executions executing them synchronously
block = False
serialize = False
doc_settings = None
# By default backend will not run if actions do not generate insctructions,
# If your backend uses prepare() or commit() only then you should set force_empty_action_execution = True

View File

@ -71,7 +71,7 @@ class Command(BaseCommand):
else:
for instance in queryset:
manager.collect(instance, action, operations=operations, route_cache=route_cache)
scripts, block = manager.generate(operations)
scripts, serialize = manager.generate(operations)
servers = []
# Print scripts
for key, value in scripts.items():
@ -96,7 +96,7 @@ class Command(BaseCommand):
return
break
if not dry:
logs = manager.execute(scripts, block=block)
logs = manager.execute(scripts, serialize=serialize)
for log in logs:
self.stdout.write(log.stdout)
self.stderr.write(log.stderr)

View File

@ -20,7 +20,7 @@ logger = logging.getLogger(__name__)
router = import_class(settings.ORCHESTRATION_ROUTER)
def as_task(execute, log, operations):
def keep_log(execute, log, operations):
def wrapper(*args, **kwargs):
""" send report """
# Remember that threads have their oun connection poll
@ -30,14 +30,14 @@ def as_task(execute, log, operations):
if log.state != log.SUCCESS:
send_report(execute, args, log)
except Exception as e:
subject = 'EXCEPTION executing backend(s) %s %s' % (str(args), str(kwargs))
message = traceback.format_exc()
logger.error(subject)
logger.error(message)
mail_admins(subject, message)
trace = traceback.format_exc()
log.state = BackendLog.EXCEPTION
log.stderr = traceback.format_exc()
log.save(update_fields=('state', 'stderr'))
log.stderr = trace
log.save()
subject = 'EXCEPTION executing backend(s) %s %s' % (str(args), str(kwargs))
logger.error(subject)
logger.error(trace)
mail_admins(subject, trace)
# We don't propagate the exception further to avoid transaction rollback
finally:
# Store and log the operation
@ -56,7 +56,7 @@ def as_task(execute, log, operations):
def generate(operations):
scripts = OrderedDict()
cache = {}
block = False
serialize = False
# Generate scripts per route+backend
for operation in operations:
logger.debug("Queued %s" % str(operation))
@ -86,18 +86,18 @@ def generate(operations):
pre_action.send(**kwargs)
method(operation.instance)
post_action.send(**kwargs)
if backend.block:
block = True
if backend.serialize:
serialize = True
for value in scripts.values():
backend, operations = value
backend.set_tail()
pre_commit.send(sender=backend.__class__, backend=backend)
backend.commit()
post_commit.send(sender=backend.__class__, backend=backend)
return scripts, block
return scripts, serialize
def execute(scripts, block=False, async=False):
def execute(scripts, serialize=False, async=False):
""" executes the operations on the servers """
if settings.ORCHESTRATION_DISABLE_EXECUTION:
logger.info('Orchestration execution is dissabled by ORCHESTRATION_DISABLE_EXECUTION settings.')
@ -110,21 +110,22 @@ def execute(scripts, block=False, async=False):
route, __ = key
backend, operations = value
args = (route.host,)
async = not serialize and (async or route.async)
kwargs = {
'async': async or route.async
'async': async,
}
log = backend.create_log(*args, **kwargs)
kwargs['log'] = log
task = as_task(backend.execute, log, operations)
task = keep_log(backend.execute, log, operations)
logger.debug('%s is going to be executed on %s' % (backend, route.host))
if block:
if serialize:
# Execute one backend at a time, no need for threads
task(*args, **kwargs)
else:
task = close_connection(task)
thread = threading.Thread(target=task, args=args, kwargs=kwargs)
thread.start()
if not route.async:
if not async:
threads_to_join.append(thread)
logs.append(log)
[ thread.join() for thread in threads_to_join ]

View File

@ -97,14 +97,14 @@ class OperationsMiddleware(object):
operations = self.get_pending_operations()
if operations:
try:
scripts, block = manager.generate(operations)
scripts, serialize = manager.generate(operations)
except Exception as exception:
self.leave_transaction_management(exception)
raise
# We commit transaction just before executing operations
# because here is when IntegrityError show up
self.leave_transaction_management()
logs = manager.execute(scripts, block=block)
logs = manager.execute(scripts, serialize=serialize)
if logs and resolve(request.path).app_name == 'admin':
message_user(request, logs)
return response

View File

@ -10,6 +10,6 @@ class OrdersConfig(AppConfig):
def ready(self):
from .models import Order
accounts.register(Order)
accounts.register(Order, icon='basket.png')
if database_ready():
from . import signals

View File

@ -0,0 +1 @@
default_app_config = 'orchestra.contrib.payments.apps.PaymentsConfig'

View File

@ -0,0 +1,14 @@
from django.apps import AppConfig
from orchestra.core import accounts
class PaymentsConfig(AppConfig):
name = 'orchestra.contrib.payments'
verbose_name = "Payments"
def ready(self):
from .models import PaymentSource, Transaction, TransactionProcess
accounts.register(PaymentSource, dashboard=False)
accounts.register(Transaction, icon='transaction.png')
accounts.register(TransactionProcess, icon='transactionprocess.png', dashboard=False)

View File

@ -4,7 +4,6 @@ from django.utils.functional import cached_property
from django.utils.translation import ugettext_lazy as _
from jsonfield import JSONField
from orchestra.core import accounts
from orchestra.models.queryset import group_by
from . import settings
@ -200,7 +199,3 @@ class TransactionProcess(models.Model):
for transaction in self.transactions.processing():
transaction.mark_as_secured()
self.save(update_fields=['state'])
accounts.register(PaymentSource)
accounts.register(Transaction)

View File

@ -0,0 +1 @@
default_app_config = 'orchestra.contrib.plans.apps.PlansConfig'

View File

@ -0,0 +1,15 @@
from django.apps import AppConfig
from orchestra.core import administration, accounts
from orchestra.core.translations import ModelTranslation
class PlansConfig(AppConfig):
name = 'orchestra.contrib.plans'
verbose_name = 'Plans'
def ready(self):
from .models import Plan, ContractedPlan
accounts.register(ContractedPlan, icon='ContractedPack.png')
administration.register(Plan, icon='Pack.png')
ModelTranslation.register(Plan, ('verbose_name',))

View File

@ -5,7 +5,6 @@ from django.utils.functional import cached_property
from django.utils.translation import ugettext_lazy as _
from orchestra.core import services, accounts
from orchestra.core.translations import ModelTranslation
from orchestra.core.validators import validate_name
from orchestra.models import queryset
@ -100,9 +99,3 @@ class Rate(models.Model):
for name, method in cls.RATE_METHODS.items():
choices.append((name, method.verbose_name))
return choices
accounts.register(ContractedPlan)
services.register(ContractedPlan, menu=False)
ModelTranslation.register(Plan, ('verbose_name',))

View File

@ -1,6 +1,7 @@
from django import db
from django.apps import AppConfig
from orchestra.core import administration
from orchestra.utils.db import database_ready
@ -16,6 +17,10 @@ class ResourcesConfig(AppConfig):
except db.utils.OperationalError:
# Not ready afterall
pass
from .models import Resource, ResourceData, MonitorData
administration.register(Resource, icon='gauge.png')
administration.register(ResourceData, parent=Resource, icon='monitor.png')
administration.register(MonitorData, parent=Resource, dashboard=False)
def reload_relations(self):
from .admin import insert_resource_inlines

View File

@ -72,7 +72,7 @@ class ServiceMonitor(ServiceBackend):
MonitorData.objects.create(monitor=name, object_id=object_id,
content_type=ct, value=value, created_at=self.current_date)
def execute(self, server, async=False):
log = super(ServiceMonitor, self).execute(server, async=async)
def execute(self, *args, **kwargs):
log = super(ServiceMonitor, self).execute(*args, **kwargs)
self.store(log)
return log

View File

@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('resources', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='CrontabSchedule',
fields=[
('id', models.AutoField(serialize=False, primary_key=True, auto_created=True, verbose_name='ID')),
('minute', models.CharField(max_length=64, verbose_name='minute', default='*')),
('hour', models.CharField(max_length=64, verbose_name='hour', default='*')),
('day_of_week', models.CharField(max_length=64, verbose_name='day of week', default='*')),
('day_of_month', models.CharField(max_length=64, verbose_name='day of month', default='*')),
('month_of_year', models.CharField(max_length=64, verbose_name='month of year', default='*')),
],
options={
'verbose_name': 'crontab',
'ordering': ('month_of_year', 'day_of_month', 'day_of_week', 'hour', 'minute'),
'verbose_name_plural': 'crontabs',
},
),
]

View File

@ -0,0 +1,14 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('resources', '0002_auto_20150502_1429'),
]
operations = [
]

View File

@ -0,0 +1,14 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('resources', '0003_auto_20150502_1433'),
]
operations = [
]

View File

@ -148,9 +148,8 @@ class Resource(models.Model):
def monitor(self, async=True):
if async:
print(tasks.monitor.delay)
return tasks.monitor.delay(self.pk, async=async)
return tasks.monitor(self.pk, async=async)
return tasks.monitor.apply_async(self.pk)
return tasks.monitor(self.pk)
class ResourceData(models.Model):

View File

@ -7,7 +7,7 @@ from .backends import ServiceMonitor
@task(name='resources.Monitor')
def monitor(resource_id, ids=None, async=True):
def monitor(resource_id, ids=None):
with LockFile('/dev/shm/resources.monitor-%i.lock' % resource_id, expire=60*60):
from .models import ResourceData, Resource
resource = Resource.objects.get(pk=resource_id)
@ -29,9 +29,7 @@ def monitor(resource_id, ids=None, async=True):
for obj in model.objects.filter(**kwargs):
op = Operation(backend, obj, Operation.MONITOR)
monitorings.append(op)
# TODO async=True only when running with celery
# monitor.request.id
logs += Operation.execute(monitorings, async=async)
logs += Operation.execute(monitorings, async=False)
kwargs = {'id__in': ids} if ids else {}
# Update used resources and trigger resource exceeded and revovery

View File

@ -10,6 +10,4 @@ class SaaSConfig(AppConfig):
def ready(self):
from . import signals
from .models import SaaS
services.register(SaaS)
services.register(SaaS, icon='saas.png')

View File

@ -12,7 +12,7 @@ class GitLabSaaSBackend(ServiceController):
verbose_name = _("GitLab SaaS")
model = 'saas.SaaS'
default_route_match = "saas.service == 'gitlab'"
block = True
serialize = True
actions = ('save', 'delete', 'validate_creation')
doc_settings = (settings,
('SAAS_GITLAB_DOMAIN', 'SAAS_GITLAB_ROOT_PASSWORD'),

View File

@ -18,7 +18,7 @@ class PhpListSaaSBackend(ServiceController):
verbose_name = _("phpList SaaS")
model = 'saas.SaaS'
default_route_match = "saas.service == 'phplist'"
block = True
serialize = True
def _save(self, saas, server):
admin_link = 'http://%s/admin/' % saas.get_site_domain()

View File

@ -1,6 +1,14 @@
from django.apps import AppConfig
from orchestra.core import administration, accounts
from orchestra.core.translations import ModelTranslation
class ServicesConfig(AppConfig):
name = 'orchestra.contrib.services'
verbose_name = 'Services'
def ready(self):
from .models import Service
administration.register(Service, icon='price.png')
ModelTranslation.register(Service, ('description',))

View File

@ -8,7 +8,6 @@ from django.utils.module_loading import autodiscover_modules
from django.utils.translation import string_concat, ugettext_lazy as _
from orchestra.core import caches, validators
from orchestra.core.translations import ModelTranslation
from orchestra.utils.python import import_class
from . import settings
@ -244,6 +243,3 @@ class Service(models.Model):
for instance in queryset:
updates += order_model.update_orders(instance, service=self, commit=commit)
return updates
ModelTranslation.register(Service, ('description',))

View File

@ -103,7 +103,5 @@ class SettingFileView(generic.TemplateView):
return context
admin.site.register_url(r'^settings/setting/view/$', SettingFileView.as_view(), 'settings_setting_view')
admin.site.register_url(r'^settings/setting/$', SettingView.as_view(), 'settings_setting_change')
OrchestraIndexDashboard.register_link('Administration', 'settings_setting_change', _("Settings"))

View File

@ -1,13 +1,21 @@
from django.apps import AppConfig
from django.core.checks import register, Error
from django.core.exceptions import ValidationError
from django.utils.translation import ngettext, ugettext_lazy as _
from orchestra.core import administration
from . import Setting
class SettingsConfig(AppConfig):
name = 'orchestra.contrib.settings'
verbose_name = 'Settings'
def ready(self):
administration.register_view('settings_setting_change', verbose_name=_("Settings"),
icon='Multimedia-volume-control.png')
@register()
def check_settings(app_configs, **kwargs):
""" perfroms all the validation """

View File

@ -12,7 +12,7 @@ class SystemUsersConfig(AppConfig):
def ready(self):
from .models import SystemUser
services.register(SystemUser)
services.register(SystemUser, icon='roleplaying.png')
if 'migrate' in sys.argv and 'accounts' not in sys.argv:
post_migrate.connect(self.create_initial_systemuser,
dispatch_uid="orchestra.contrib.systemusers.apps.create_initial_systemuser")

View File

@ -2,3 +2,6 @@ import sys
from . import settings
from .decorators import task, periodic_task, keep_state, apply_async
default_app_config = 'orchestra.contrib.tasks.apps.TasksConfig'

View File

@ -0,0 +1,14 @@
from django.apps import AppConfig
from orchestra.core import administration
class TasksConfig(AppConfig):
name = 'orchestra.contrib.tasks'
verbose_name = "Tasks"
def ready(self):
from djcelery.models import PeriodicTask, TaskState, WorkerState
administration.register(TaskState, icon='Edit-check-sheet.png')
administration.register(PeriodicTask, parent=TaskState, icon='Appointment.png')
administration.register(WorkerState, parent=TaskState, dashboard=False)

View File

@ -6,6 +6,7 @@ from threading import Thread
from celery import shared_task as celery_shared_task
from celery import states
from celery.decorators import periodic_task as celery_periodic_task
from django.core.mail import mail_admins
from django.utils import timezone
from orchestra.utils.db import close_connection
@ -26,11 +27,15 @@ def keep_state(fn):
result = fn(*args, **kwargs)
except Exception as exc:
state.state = states.FAILURE
state.traceback = traceback.format_exc()
state.traceback = trace
state.runtime = (timezone.now()-now).total_seconds()
state.save()
subject = 'EXCEPTION executing task %s(args=%s, kwargs=%s)' % (name, str(args), str(kwargs))
trace = traceback.format_exc()
logger.error(subject)
logger.error(trace)
mail_admins(subject, trace)
return
# TODO send email
else:
state.state = states.SUCCESS
state.result = str(result)

View File

@ -1,2 +1,15 @@
# create crontab entries for defines periodic tasks
from django.core.management.base import BaseCommand, CommandError
from djcelery.app import app
from djcelery.schedulers import DatabaseScheduler
class Command(BaseCommand):
help = 'Runs Orchestra method.'
def handle(self, *args, **options):
dbschedule = DatabaseScheduler(app=app)
self.stdout.write('\033[1m%i periodic tasks have been syncronized:\033[0m' % len(dbschedule.schedule))
size = max([len(name) for name in dbschedule.schedule])+1
for name, task in dbschedule.schedule.items():
spaces = ' '*(size-len(name))
self.stdout.write(' %s%s%s' % (name, spaces, task.schedule))

View File

@ -0,0 +1 @@
default_app_config = 'orchestra.contrib.vps.apps.VPSConfig'

View File

@ -0,0 +1,12 @@
from django.apps import AppConfig
from orchestra.core import services
class VPSConfig(AppConfig):
name = 'orchestra.contrib.vps'
verbose_name = 'VPS'
def ready(self):
from .models import VPS
services.register(VPS, icon='TuxBox.png')

View File

@ -1,8 +1,7 @@
from django.contrib.auth.hashers import make_password
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.hashers import make_password
from orchestra.core import services
from orchestra.core.validators import validate_hostname
from . import settings
@ -32,6 +31,3 @@ class VPS(models.Model):
def get_username(self):
return self.hostname
services.register(VPS)

View File

@ -10,4 +10,4 @@ class WebAppsConfig(AppConfig):
def ready(self):
from . import signals
from .models import WebApp
services.register(WebApp)
services.register(WebApp, icon='Applications-other.png')

View File

@ -0,0 +1 @@
default_app_config = 'orchestra.contrib.websites.apps.WebsitesConfig'

View File

@ -1,17 +1,20 @@
from django.apps import AppConfig
from django.contrib.contenttypes.fields import GenericRelation
from orchestra.core import services
from orchestra.utils.db import database_ready
class WebsiteConfig(AppConfig):
class WebsitesConfig(AppConfig):
name = 'orchestra.contrib.websites'
def ready(self):
if database_ready():
from django.contrib.contenttypes.models import ContentType
from .models import Content
qset = Content.content_type.field.get_limit_choices_to()
for ct in ContentType.objects.filter(qset):
relation = GenericRelation('websites.Content')
ct.model_class().add_to_class('content_set', relation)
# from django.contrib.contenttypes.models import ContentType
# from .models import Content, Website
# qset = Content.content_type.field.get_limit_choices_to()
# for ct in ContentType.objects.filter(qset):
# relation = GenericRelation('websites.Content')
# ct.model_class().add_to_class('content_set', relation)
from .models import Website
services.register(Website, icon='Applications-internet.png')

View File

@ -5,7 +5,7 @@ from django.db import models
from django.utils.functional import cached_property
from django.utils.translation import ugettext_lazy as _
from orchestra.core import validators, services
from orchestra.core import validators
from orchestra.utils.functional import cached
from . import settings
@ -152,6 +152,3 @@ class Content(models.Model):
domain = self.website.domains.first()
if domain:
return '%s://%s%s' % (self.website.get_protocol(), domain, self.path)
services.register(Website)

View File

@ -1,9 +1,12 @@
from django.utils.translation import string_concat
from ..utils.python import AttrDict
class Register(object):
def __init__(self):
def __init__(self, verbose_name=None):
self._registry = {}
self.verbose_name = verbose_name
def __contains__(self, key):
return key in self._registry
@ -13,13 +16,21 @@ class Register(object):
def register(self, model, **kwargs):
if model in self._registry:
raise KeyError("%s already registered" % str(model))
plural = kwargs.get('verbose_name_plural', model._meta.verbose_name_plural)
self._registry[model] = AttrDict(**{
'verbose_name': kwargs.get('verbose_name', model._meta.verbose_name),
'verbose_name_plural': plural,
'menu': kwargs.get('menu', True),
})
raise KeyError("%s already registered" % model)
if 'verbose_name' not in kwargs:
kwargs['verbose_name'] = model._meta.verbose_name
if 'verbose_name_plural' not in kwargs:
kwargs['verbose_name_plural'] = model._meta.verbose_name_plural
self._registry[model] = AttrDict(**kwargs)
def register_view(self, view_name, **kwargs):
if view_name in self._registry:
raise KeyError("%s already registered" % view_name)
if 'verbose_name' not in kwargs:
raise KeyError("%s verbose_name is required for views" % view_name)
if 'verbose_name_plural' not in kwargs:
kwargs['verbose_name_plural'] = string_concat(kwargs['verbose_name'], 's')
self._registry[view_name] = AttrDict(**kwargs)
def get(self, *args):
if args:
@ -27,7 +38,7 @@ class Register(object):
return self._registry
services = Register()
services = Register(verbose_name='Services')
# TODO rename to something else
accounts = Register()
administration = Register()
accounts = Register(verbose_name='Accounts')
administration = Register(verbose_name='Administration')

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -0,0 +1,413 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
inkscape:export-ydpi="90.000000"
inkscape:export-xdpi="90.000000"
inkscape:export-filename="/home/glic3/orchestra/django-orchestra/orchestra/static/orchestra/icons/Appointment.png"
width="48px"
height="48px"
id="svg11300"
sodipodi:version="0.32"
inkscape:version="0.48.3.1 r9886"
sodipodi:docname="Appointment.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.1">
<defs
id="defs3">
<linearGradient
inkscape:collect="always"
id="linearGradient5204">
<stop
style="stop-color:#c4a000;stop-opacity:1;"
offset="0"
id="stop5206" />
<stop
style="stop-color:#c4a000;stop-opacity:0;"
offset="1"
id="stop5208" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient5196">
<stop
style="stop-color:#c4a000;stop-opacity:1;"
offset="0"
id="stop5198" />
<stop
style="stop-color:#c4a000;stop-opacity:0;"
offset="1"
id="stop5200" />
</linearGradient>
<linearGradient
id="linearGradient12512">
<stop
style="stop-color:#ffffff;stop-opacity:1.0000000;"
offset="0.0000000"
id="stop12513" />
<stop
style="stop-color:#fff520;stop-opacity:0.89108908;"
offset="0.50000000"
id="stop12517" />
<stop
style="stop-color:#fff300;stop-opacity:0.0000000;"
offset="1.0000000"
id="stop12514" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient12512"
id="radialGradient278"
gradientUnits="userSpaceOnUse"
cx="55.000000"
cy="125.00000"
fx="55.000000"
fy="125.00000"
r="14.375000" />
<linearGradient
id="linearGradient10653">
<stop
style="stop-color:#f3f4ff;stop-opacity:1.0000000;"
offset="0.0000000"
id="stop10655" />
<stop
style="stop-color:#9193af;stop-opacity:1.0000000;"
offset="1.0000000"
id="stop10657" />
</linearGradient>
<linearGradient
id="linearGradient42174">
<stop
style="stop-color:#a0a0a0;stop-opacity:1.0000000;"
offset="0.0000000"
id="stop42176" />
<stop
style="stop-color:#ffffff;stop-opacity:1.0000000;"
offset="1.0000000"
id="stop42178" />
</linearGradient>
<linearGradient
id="linearGradient2145">
<stop
style="stop-color:#fffffd;stop-opacity:1.0000000;"
offset="0.0000000"
id="stop2147" />
<stop
style="stop-color:#cbcbc9;stop-opacity:1.0000000;"
offset="1.0000000"
id="stop2149" />
</linearGradient>
<linearGradient
id="linearGradient37935">
<stop
id="stop37937"
offset="0.0000000"
style="stop-color:#9497b3;stop-opacity:1.0000000;" />
<stop
id="stop37939"
offset="1.0000000"
style="stop-color:#4c4059;stop-opacity:1.0000000;" />
</linearGradient>
<linearGradient
id="linearGradient2152">
<stop
id="stop2154"
offset="0.0000000"
style="stop-color:#9aa29a;stop-opacity:1.0000000;" />
<stop
id="stop2156"
offset="1.0000000"
style="stop-color:#b5beb5;stop-opacity:1.0000000;" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient3816">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop3818" />
<stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3820" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3816"
id="radialGradient3822"
cx="31.112698"
cy="19.008621"
fx="31.112698"
fy="19.008621"
r="8.6620579"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2152"
id="linearGradient4307"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(3.123841,0.000000,0.000000,0.969691,-31.88758,-19.59492)"
x1="8.9156475"
y1="37.197018"
x2="9.8855033"
y2="52.090678" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient10653"
id="radialGradient4309"
gradientUnits="userSpaceOnUse"
cx="11.329200"
cy="10.583970"
fx="11.329200"
fy="10.583970"
r="15.532059" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2145"
id="radialGradient4311"
gradientUnits="userSpaceOnUse"
cx="11.901996"
cy="10.045444"
fx="11.901996"
fy="10.045444"
r="29.292715" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient42174"
id="linearGradient4313"
gradientUnits="userSpaceOnUse"
x1="6.3422160"
y1="7.7893324"
x2="22.218424"
y2="25.884274" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5196"
id="radialGradient5202"
cx="23.375"
cy="10.972863"
fx="23.375"
fy="10.972863"
r="3.3478092"
gradientTransform="matrix(3.630420,1.654030e-15,-1.608743e-15,3.742066,-61.48607,-29.18618)"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5204"
id="linearGradient5210"
x1="19.667364"
y1="4.2570662"
x2="20.329933"
y2="5.2845874"
gradientUnits="userSpaceOnUse" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient37935"
id="radialGradient5212"
gradientUnits="userSpaceOnUse"
cx="8.7468252"
cy="6.8283234"
fx="8.7468252"
fy="6.8283234"
r="29.889715" />
</defs>
<sodipodi:namedview
stroke="#c4a000"
fill="#babdb6"
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="0.25490196"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="11.313708"
inkscape:cx="27.543713"
inkscape:cy="25.106052"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:showpageshadow="false"
inkscape:window-width="833"
inkscape:window-height="772"
inkscape:window-x="1266"
inkscape:window-y="144"
inkscape:window-maximized="0" />
<metadata
id="metadata4">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:creator>
<cc:Agent>
<dc:title>Jakub Steiner</dc:title>
</cc:Agent>
</dc:creator>
<dc:source>http://jimmac.musichall.cz</dc:source>
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
<dc:title>New Appointment</dc:title>
<dc:subject>
<rdf:Bag>
<rdf:li>appointment</rdf:li>
<rdf:li>new</rdf:li>
<rdf:li>meeting</rdf:li>
<rdf:li>rvsp</rdf:li>
</rdf:Bag>
</dc:subject>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
<cc:permits
rdf:resource="http://web.resource.org/cc/Reproduction" />
<cc:permits
rdf:resource="http://web.resource.org/cc/Distribution" />
<cc:requires
rdf:resource="http://web.resource.org/cc/Notice" />
<cc:requires
rdf:resource="http://web.resource.org/cc/Attribution" />
<cc:permits
rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
<cc:requires
rdf:resource="http://web.resource.org/cc/ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<path
d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.45064,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z"
sodipodi:ry="8.6620579"
sodipodi:rx="8.6620579"
sodipodi:cy="19.008621"
sodipodi:cx="31.112698"
id="path4318"
style="opacity:1;color:#000000;fill:url(#radialGradient3822);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
sodipodi:type="arc"
transform="matrix(2.563158,0.000000,0.000000,1.219602,-55.98414,14.04144)" />
<path
sodipodi:nodetypes="cccc"
id="path14341"
d="M 18.587591,1.403729 L 4.226755,18.096665 L 5.4854717,19.339844 L 18.587591,1.403729 z "
style="color:#000000;fill:url(#linearGradient4307);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
<path
sodipodi:nodetypes="cccc"
id="path18921"
d="M 18.467176,1.3138035 L 5.6605716,19.072612 L 7.4900985,20.687913 L 18.467176,1.3138035 z "
style="fill:#fefefe;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1" />
<path
transform="matrix(1.431529,0.000000,0.000000,1.431529,0.569459,-1.654618)"
d="M 31.160714 16.910715 A 14.910714 14.910714 0 1 1 1.3392859,16.910715 A 14.910714 14.910714 0 1 1 31.160714 16.910715 z"
sodipodi:ry="14.910714"
sodipodi:rx="14.910714"
sodipodi:cy="16.910715"
sodipodi:cx="16.25"
id="path27786"
style="fill:url(#radialGradient5212);fill-opacity:1;fill-rule:evenodd;stroke:#605773;stroke-width:0.69855404;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
sodipodi:type="arc" />
<path
transform="matrix(1.163838,0.000000,0.000000,1.163838,4.824801,2.777556)"
d="M 31.160714 16.910715 A 14.910714 14.910714 0 1 1 1.3392859,16.910715 A 14.910714 14.910714 0 1 1 31.160714 16.910715 z"
sodipodi:ry="14.910714"
sodipodi:rx="14.910714"
sodipodi:cy="16.910715"
sodipodi:cx="16.25"
id="path35549"
style="fill:url(#radialGradient4311);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4313);stroke-width:0.71139598;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
sodipodi:type="arc" />
<path
sodipodi:type="arc"
style="opacity:1;color:#000000;fill:url(#radialGradient5202);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient5210);stroke-width:0.56498736;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="path4120"
sodipodi:cx="23.375"
sodipodi:cy="11.875"
sodipodi:rx="8.5"
sodipodi:ry="8.5"
d="M 16.679382,6.6387137 A 8.5,8.5 0 0 1 23.332691,3.3751053 L 23.375,11.875 z"
transform="matrix(1.769951,0.000000,0.000000,1.769951,-17.02424,1.610741)"
sodipodi:start="3.8052902"
sodipodi:end="4.7074114" />
<path
transform="matrix(2.073295,0.000000,0.000000,2.073295,-7.310224,-13.13682)"
d="M 16.40625 17.28125 A 1.21875 1.21875 0 1 1 13.96875,17.28125 A 1.21875 1.21875 0 1 1 16.40625 17.28125 z"
sodipodi:ry="1.21875"
sodipodi:rx="1.21875"
sodipodi:cy="17.28125"
sodipodi:cx="15.1875"
id="path34778"
style="fill:#f3f3f3;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.48232403;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;stroke-dasharray:none"
sodipodi:type="arc" />
<path
id="path35559"
d="M 22.176614,20.718014 L 13.155702,13.140282"
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path
id="path35561"
d="M 19.408614,29.776506 L 22.368655,25.283228"
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
sodipodi:nodetypes="cc" />
<path
transform="matrix(2.749493,0.000000,0.000000,2.749493,-22.30073,-12.40939)"
d="M 17.324117 7.6932044 A 0.61871845 0.61871845 0 1 1 16.08668,7.6932044 A 0.61871845 0.61871845 0 1 1 17.324117 7.6932044 z"
sodipodi:ry="0.61871845"
sodipodi:rx="0.61871845"
sodipodi:cy="7.6932044"
sodipodi:cx="16.705399"
id="path35563"
style="fill:#b6b9b1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.36871839;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;opacity:1"
sodipodi:type="arc" />
<path
transform="matrix(2.749493,0.000000,0.000000,2.749493,-22.30073,14.80922)"
d="M 17.324117 7.6932044 A 0.61871845 0.61871845 0 1 1 16.08668,7.6932044 A 0.61871845 0.61871845 0 1 1 17.324117 7.6932044 z"
sodipodi:ry="0.61871845"
sodipodi:rx="0.61871845"
sodipodi:cy="7.6932044"
sodipodi:cx="16.705399"
id="path35565"
style="fill:#b6b9b1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.36871839;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;opacity:1"
sodipodi:type="arc" />
<path
transform="matrix(2.749493,0.000000,0.000000,2.749493,-35.91004,1.199890)"
d="M 17.324117 7.6932044 A 0.61871845 0.61871845 0 1 1 16.08668,7.6932044 A 0.61871845 0.61871845 0 1 1 17.324117 7.6932044 z"
sodipodi:ry="0.61871845"
sodipodi:rx="0.61871845"
sodipodi:cy="7.6932044"
sodipodi:cx="16.705399"
id="path35567"
style="fill:#b6b9b1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.36871839;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;opacity:1"
sodipodi:type="arc" />
<path
transform="matrix(2.749493,0.000000,0.000000,2.749493,-8.691448,1.199890)"
d="M 17.324117 7.6932044 A 0.61871845 0.61871845 0 1 1 16.08668,7.6932044 A 0.61871845 0.61871845 0 1 1 17.324117 7.6932044 z"
sodipodi:ry="0.61871845"
sodipodi:rx="0.61871845"
sodipodi:cy="7.6932044"
sodipodi:cx="16.705399"
id="path35569"
style="fill:#b6b9b1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.36871839;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;opacity:1"
sodipodi:type="arc" />
<path
sodipodi:type="arc"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#radialGradient4309);stroke-width:0.73656511;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
id="path10651"
sodipodi:cx="16.25"
sodipodi:cy="16.910715"
sodipodi:rx="14.910714"
sodipodi:ry="14.910714"
d="M 31.160714 16.910715 A 14.910714 14.910714 0 1 1 1.3392859,16.910715 A 14.910714 14.910714 0 1 1 31.160714 16.910715 z"
transform="matrix(1.357654,0.000000,0.000000,1.357654,1.769896,-0.493735)" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -0,0 +1,390 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
height="48px"
width="48px"
id="svg2"
version="1.1"
inkscape:version="0.48.3.1 r9886"
sodipodi:docname="Edit-check-sheet.svg"
inkscape:export-filename="/home/glic3/orchestra/django-orchestra/orchestra/static/orchestra/icons/Edit-check-sheet.png"
inkscape:export-xdpi="503.74228"
inkscape:export-ydpi="503.74228">
<metadata
id="metadata112">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="640"
inkscape:window-height="480"
id="namedview110"
showgrid="false"
inkscape:zoom="4.9166667"
inkscape:cx="24"
inkscape:cy="24"
inkscape:window-x="945"
inkscape:window-y="165"
inkscape:window-maximized="0"
inkscape:current-layer="svg2" />
<defs
id="defs4">
<linearGradient
id="i"
y2="-.2"
gradientUnits="userSpaceOnUse"
y1="12.17"
x2="25.69"
x1="25.68">
<stop
stop-color="#fff"
offset="0"
id="stop7" />
<stop
stop-opacity="0"
stop-color="#fff"
offset="1"
id="stop9" />
</linearGradient>
<linearGradient
id="e"
x1="25.4"
xlink:href="#b"
gradientUnits="userSpaceOnUse"
y1="3.82"
gradientTransform="matrix(1 0 0 .884-.63.84)"
x2="25.46"
y2="9.32" />
<linearGradient
id="h"
x1="33.4"
xlink:href="#i"
gradientUnits="userSpaceOnUse"
x2="34.2"
y1="36.92"
y2="38.1" />
<linearGradient
id="f"
xlink:href="#b"
gradientUnits="userSpaceOnUse"
y1="3.82"
gradientTransform="matrix(.539 0 0 .512 10.8-.58)"
x2="0"
y2="6.48" />
<linearGradient
id="g"
x1="26.1"
xlink:href="#i"
gradientUnits="userSpaceOnUse"
x2="30.81"
y1="26.7"
y2="42" />
<linearGradient
id="j"
y2="37.77"
gradientUnits="userSpaceOnUse"
y1="40.46"
x2="33.66"
x1="36">
<stop
stop-color="#7c7c7c"
offset="0"
id="stop16" />
<stop
stop-color="#b8b8b8"
offset="1"
id="stop18" />
</linearGradient>
<linearGradient
id="b">
<stop
stop-color="#97978a"
offset="0"
id="stop21" />
<stop
stop-color="#c2c2b9"
offset=".5"
id="stop23" />
<stop
stop-color="#7d7d6f"
offset="1"
id="stop25" />
</linearGradient>
<linearGradient
id="n"
y2="37.88"
gradientUnits="userSpaceOnUse"
y1="10.45"
x2="33.86"
x1="6.11">
<stop
stop-color="#c68827"
offset="0"
id="stop28" />
<stop
stop-color="#89601f"
offset="1"
id="stop30" />
</linearGradient>
<linearGradient
id="k"
y2="42.1"
gradientUnits="userSpaceOnUse"
y1="39.2"
x2="39.1"
x1="36.81">
<stop
offset="0"
id="stop33" />
<stop
stop-opacity="0"
offset="1"
id="stop35" />
</linearGradient>
<linearGradient
id="m"
y2="39.5"
gradientUnits="userSpaceOnUse"
y1="18.99"
gradientTransform="matrix(1.066 0 0 .988-1.56.07)"
x2="35.79"
x1="22.31">
<stop
stop-color="#f0f0ef"
offset="0"
id="stop38" />
<stop
stop-color="#e8e8e8"
offset=".6"
id="stop40" />
<stop
stop-color="#fff"
offset=".83"
id="stop42" />
<stop
stop-color="#d8d8d3"
offset="1"
id="stop44" />
</linearGradient>
<linearGradient
id="l"
x1="25.4"
xlink:href="#b"
gradientUnits="userSpaceOnUse"
y1="3.82"
gradientTransform="matrix(1.053 0 0 1-1.79 0)"
x2="25.46"
y2="9.32" />
<radialGradient
id="d"
gradientUnits="userSpaceOnUse"
cy="45.3"
cx="24.65"
gradientTransform="matrix(1 0 0 .111 0 40.3)"
r="21">
<stop
stop-color="#646459"
offset="0"
id="stop48" />
<stop
stop-opacity="0"
stop-color="#646459"
offset="1"
id="stop50" />
</radialGradient>
</defs>
<path
fill="url(#d)"
d="m45.66 45.27a21.01 2.323 0 1 1 -42.02 0 21.01 2.323 0 1 1 42.02 0"
transform="matrix(.913 0 0 1.179 1.92-8.11)"
id="path52" />
<rect
rx="1.39"
height="41"
width="39"
stroke="#714c16"
y="4.5"
x="4.46"
fill="url(#n)"
id="rect54" />
<rect
rx=".57"
height="35.98"
width="30.95"
stroke="#888a85"
y="6.53"
x="8.53"
fill="url(#m)"
id="rect56" />
<rect
rx="1"
height="4"
width="12"
x="18"
fill="#5c5c5c"
id="rect58" />
<rect
id="a"
opacity=".4"
rx="1"
height="3.7"
width="3.7"
stroke="#2e3436"
y="14.4"
x="11.7"
stroke-width=".8"
fill="none" />
<use
y="6.48"
xlink:href="#a"
id="use61" />
<rect
opacity=".5"
rx="1"
height="5"
width="5"
stroke="#2e3436"
y="34.37"
x="11.64"
stroke-width=".8"
fill="none"
id="rect63" />
<use
y="12.96"
xlink:href="#a"
id="use65" />
<g
fill="none"
id="g67">
<path
stroke="url(#g)"
d="m9.52 7.47h29v34h-29z"
id="path69" />
<rect
rx=".5"
height="39.1"
width="37.1"
stroke="#c68827"
y="5.43"
x="5.44"
id="rect71" />
</g>
<rect
opacity=".11"
rx="1.39"
height="7"
width="18.95"
stroke="#000"
y="4.47"
x="14.79"
id="rect73" />
<rect
rx="1.39"
height="7"
width="18.95"
stroke="#5c5c5c"
y="3.5"
x="14.53"
fill="url(#l)"
id="rect75" />
<rect
rx=".33"
height="3.58"
width="9.7"
y="1.21"
x="19.1"
fill="url(#f)"
id="rect77" />
<rect
rx="1"
height="6.19"
width="18.1"
y="3.94"
x="14.95"
fill="url(#e)"
id="rect79" />
<path
opacity=".5"
d="m39 36.3l0.04 5.81-8.5-0.04 8.46-5.77"
fill="url(#k)"
id="path81" />
<path
stroke="#868a84"
d="m30.1 42.1c1.79 0.16 8.99-4.37 9.48-8.39-1.56 2.42-4.96 1.97-9.1 2.13 0 0 0.39 5.76-0.42 6.26z"
fill="url(#j)"
id="path83" />
<g
fill="none"
id="g85">
<path
opacity=".32"
stroke="url(#i)"
d="m19.47 1.47v0.03h-0.03v2.88c0 0.001 0.03 0.03 0.03 0.03v0.03h-3.59c-0.04 0-0.1 0.02-0.13 0.03-0.14 0.06-0.27 0.2-0.31 0.34-0.001 0.04 0 0.11 0 0.16v4.22c0 0.03 0.02 0.09 0.03 0.12 0.001 0.02 0.02 0.07 0.03 0.09 0 0.001 0.03 0.03 0.03 0.03 0.02 0.03 0.07 0.07 0.09 0.09 0.02 0.001 0.05 0.02 0.07 0.03 0.001 0.001 0.04 0.03 0.06 0.03 0.03 0.001 0.09 0.03 0.13 0.03h16.22c0.04-0.001 0.1-0.02 0.13-0.03 0.02-0.001 0.05-0.02 0.06-0.03 0.02-0.001 0.05-0.02 0.07-0.03l0.09-0.09c0-0.001 0.03-0.03 0.03-0.03 0.001-0.02 0.02-0.07 0.03-0.09 0.001-0.03 0.03-0.09 0.03-0.12v-4.22c0-0.04 0.001-0.12 0-0.16-0.04-0.14-0.17-0.29-0.31-0.34-0.03-0.001-0.09-0.03-0.13-0.03h-3.59v-0.03l0.03-0.03v-2.88h-0.03v-0.03h-9.03s-0.03 0-0.03 0z"
id="path87" />
<path
opacity=".37"
stroke="url(#h)"
d="m31.51 40.69c1.37-0.69 4.53-2.6 5.83-4.48-1.79 0.37-2.99 0.58-5.73 0.69 0 0 0.09 3-0.1 3.79z"
id="path89" />
</g>
<g
opacity=".17"
id="g91">
<path
d="m19.76 15h16.34v2h-16.34z"
id="path93" />
<path
d="m19.76 19h15.56v2h-15.56z"
id="path95" />
<path
d="m19.76 23h14v2h-14z"
id="path97" />
<path
d="m19.76 27h16.34v2h-16.34z"
id="path99" />
<path
d="m19.76 31h10.12v2h-10.12z"
id="path101" />
</g>
<path
id="c"
d="m18.57 28.81c3.909-6.26 4.744-6.495 9.012-11.93 1.32-1.47 5.119-5.149 6.888-4.447 1.351 0.537-0.8798 2.34-1.53 3.17-5.72 7.3-9.097 12.28-14.4 19.89-0.817 1.172-2.128 1.514-3.407 1.241-1.3-0.28-2.07-2.68-2.5-3.82-0.6404-1.7-2.255-3.821-2.254-5.641 0.0004468-1.47 0.7726-2.205 2.074-2.305 1.675-0.1285 2.298 2.19 2.789 3.557 0.93 2.58 1.13 3.81 3.33 0.29z"
transform="matrix(.292 0 0 .293 8.7 7.4)"
fill="#4e9a06" />
<use
y="6.46"
xlink:href="#c"
id="use104" />
<use
y="12.92"
xlink:href="#c"
id="use106" />
<use
xlink:href="#c"
transform="matrix(2.076 0 0 2.076 -13.72 1.792)"
stroke="#555753"
stroke-width=".3"
id="use108" />
</svg>

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -0,0 +1,999 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
sodipodi:docname="Mail-send.svg"
inkscape:version="0.48.3.1 r9886"
sodipodi:version="0.32"
id="svg5816"
height="48px"
width="48px"
version="1.1"
inkscape:export-filename="/home/glic3rinu/orchestra/django-orchestra/orchestra/static/orchestra/icons/Mail-send.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<defs
id="defs3">
<linearGradient
inkscape:collect="always"
id="linearGradient5476">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop5478" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop5480" />
</linearGradient>
<linearGradient
id="linearGradient5464">
<stop
style="stop-color:#729fcf;stop-opacity:1;"
offset="0"
id="stop5466" />
<stop
style="stop-color:#afc9e4;stop-opacity:1;"
offset="1"
id="stop5468" />
</linearGradient>
<linearGradient
id="linearGradient2624">
<stop
id="stop2626"
offset="0"
style="stop-color:#dfe0df;stop-opacity:1;" />
<stop
style="stop-color:#a6b0a6;stop-opacity:1;"
offset="0.23809524"
id="stop2630" />
<stop
id="stop2628"
offset="1.0000000"
style="stop-color:#b5beb5;stop-opacity:1.0000000;" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient2573">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop2575" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop2577" />
</linearGradient>
<linearGradient
id="linearGradient2274">
<stop
style="stop-color:#000000;stop-opacity:0.12871288;"
offset="0.0000000"
id="stop2276" />
<stop
style="stop-color:#000000;stop-opacity:0.0000000;"
offset="1.0000000"
id="stop2278" />
</linearGradient>
<linearGradient
id="linearGradient9749">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop9751" />
<stop
style="stop-color:#ededed;stop-opacity:1.0000000;"
offset="1.0000000"
id="stop9753" />
</linearGradient>
<linearGradient
id="linearGradient15107">
<stop
style="stop-color:#ffffff;stop-opacity:1.0000000;"
offset="0.0000000"
id="stop15109" />
<stop
style="stop-color:#e2e2e2;stop-opacity:1.0000000;"
offset="1.0000000"
id="stop15111" />
</linearGradient>
<linearGradient
id="linearGradient10691"
inkscape:collect="always">
<stop
id="stop10693"
offset="0"
style="stop-color:#000000;stop-opacity:1;" />
<stop
id="stop10695"
offset="1"
style="stop-color:#000000;stop-opacity:0;" />
</linearGradient>
<linearGradient
id="linearGradient4274">
<stop
id="stop4276"
offset="0.0000000"
style="stop-color:#ffffff;stop-opacity:0.25490198;" />
<stop
id="stop4278"
offset="1.0000000"
style="stop-color:#ffffff;stop-opacity:1.0000000;" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient2187">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop2189" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop2191" />
</linearGradient>
<linearGradient
id="linearGradient6901"
inkscape:collect="always">
<stop
id="stop6903"
offset="0"
style="stop-color:#3465a4;stop-opacity:1;" />
<stop
id="stop6905"
offset="1"
style="stop-color:#3465a4;stop-opacity:0;" />
</linearGradient>
<linearGradient
id="linearGradient6925"
inkscape:collect="always">
<stop
id="stop6927"
offset="0"
style="stop-color:#204a87;stop-opacity:1;" />
<stop
id="stop6929"
offset="1"
style="stop-color:#204a87;stop-opacity:0;" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient6901"
id="linearGradient2562"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0,1,-1,0,37.07553,-5.879343)"
x1="15.193591"
y1="15.028743"
x2="12.252101"
y2="30.55784" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient6925"
id="linearGradient2564"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0,1,-1,0,37.07553,-5.879343)"
x1="10.791593"
y1="23.332331"
x2="10.112462"
y2="27.145725" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2187"
id="linearGradient2566"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-1.412791e-16,0.914114,-0.914114,-1.412791e-16,39.78243,-9.748047)"
x1="41.093174"
y1="16.612858"
x2="16.588747"
y2="29.698416" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4274"
id="linearGradient2365"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0,1,-1,0,37.07553,-5.879343)"
x1="26.577936"
y1="7.7850504"
x2="38.129341"
y2="12.765438" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient10691"
id="radialGradient1481"
gradientUnits="userSpaceOnUse"
gradientTransform="scale(1.902215,0.525703)"
cx="6.7027131"
cy="73.615714"
fx="6.7027131"
fy="73.615714"
r="7.2284161" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient15107"
id="linearGradient1483"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.357669,0,0,1.505846,2.84291,-2.266018)"
x1="11.572842"
y1="4.7461626"
x2="18.475286"
y2="26.022910" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2624"
id="linearGradient1487"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.454781,0,0,0.762004,2.88175,0.337386)"
x1="9.1643066"
y1="38.070892"
x2="9.8855038"
y2="52.090679" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2274"
id="radialGradient1491"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.629929,0.459373,-0.147675,0.248512,16.51724,9.053737)"
cx="27.741131"
cy="38.711506"
fx="27.741131"
fy="38.711506"
r="17.977943" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient15107"
id="linearGradient1493"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.276531,0,0,-1.406115,24.24763,33.3374)"
x1="11.74217"
y1="11.48487"
x2="13.846983"
y2="11.981981" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient15107"
id="linearGradient1497"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.296015,0,0,-1.43692,3.746576,33.20516)"
x1="11.74217"
y1="11.48487"
x2="13.846983"
y2="11.981981" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient15107"
id="linearGradient1501"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.570607,0,0,-1.231511,2.973436,33.33485)"
x1="10.027"
y1="20.219761"
x2="17.178024"
y2="-7.5274644" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient9749"
id="linearGradient1503"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.370928,0,0,-1.46456,2.525057,33.71269)"
x1="11.841544"
y1="4.2507305"
x2="40.024059"
y2="7.4121075" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2573"
id="linearGradient1505"
gradientUnits="userSpaceOnUse"
x1="17.397203"
y1="33.357376"
x2="22.17771"
y2="31.026741" />
<radialGradient
r="13.565360"
fy="19.836468"
fx="16.214741"
cy="19.836468"
cx="16.214741"
gradientTransform="matrix(1,0,0,0.681917,-1.105561e-15,8.233773)"
gradientUnits="userSpaceOnUse"
id="radialGradient1381"
xlink:href="#linearGradient4344"
inkscape:collect="always" />
<linearGradient
y2="35.803486"
x2="30.935921"
y1="29.553486"
x1="30.935921"
gradientTransform="translate(-12.41789,-7)"
gradientUnits="userSpaceOnUse"
id="linearGradient1372"
xlink:href="#linearGradient3824"
inkscape:collect="always" />
<linearGradient
y2="36.217758"
x2="22.626925"
y1="35.817974"
x1="20.661695"
gradientTransform="matrix(0.983375,0.181588,-0.181588,0.983375,-7.07212,-9.82492)"
gradientUnits="userSpaceOnUse"
id="linearGradient1369"
xlink:href="#linearGradient4356"
inkscape:collect="always" />
<linearGradient
y2="35.739632"
x2="21.408455"
y1="36.390400"
x1="22.686766"
gradientTransform="matrix(-0.977685,0.210075,0.210075,0.977685,41.80576,-11.11866)"
gradientUnits="userSpaceOnUse"
id="linearGradient1366"
xlink:href="#linearGradient4356"
inkscape:collect="always" />
<linearGradient
y2="35.739632"
x2="21.408455"
y1="36.390400"
x1="22.686766"
gradientTransform="matrix(-0.977685,0.210075,0.210075,0.977685,41.80576,-11.11866)"
gradientUnits="userSpaceOnUse"
id="linearGradient4374"
xlink:href="#linearGradient4356"
inkscape:collect="always" />
<linearGradient
y2="36.217758"
x2="22.626925"
y1="35.817974"
x1="20.661695"
gradientTransform="matrix(0.983375,0.181588,-0.181588,0.983375,-7.072120,-9.824920)"
gradientUnits="userSpaceOnUse"
id="linearGradient4372"
xlink:href="#linearGradient4356"
inkscape:collect="always" />
<linearGradient
gradientTransform="matrix(-0.977685,0.210075,0.210075,0.977685,55.1096,-3.945209)"
y2="35.739632"
x2="21.408455"
y1="36.390400"
x1="22.686766"
gradientUnits="userSpaceOnUse"
id="linearGradient4366"
xlink:href="#linearGradient4356"
inkscape:collect="always" />
<linearGradient
gradientTransform="matrix(0.983375,0.181588,-0.181588,0.983375,6.231716,-2.651466)"
gradientUnits="userSpaceOnUse"
y2="36.217758"
x2="22.626925"
y1="35.817974"
x1="20.661695"
id="linearGradient4362"
xlink:href="#linearGradient4356"
inkscape:collect="always" />
<radialGradient
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.000000,0.000000,0.000000,0.681917,0.000000,8.233773)"
r="13.565360"
fy="19.836468"
fx="16.214741"
cy="19.836468"
cx="16.214741"
id="radialGradient4350"
xlink:href="#linearGradient4344"
inkscape:collect="always" />
<radialGradient
r="8.6620579"
fy="19.008621"
fx="31.112698"
cy="19.008621"
cx="31.112698"
gradientUnits="userSpaceOnUse"
id="radialGradient4336"
xlink:href="#linearGradient3816"
inkscape:collect="always" />
<linearGradient
gradientTransform="translate(-13.12500,-7.000000)"
y2="35.803486"
x2="30.935921"
y1="29.553486"
x1="30.935921"
gradientUnits="userSpaceOnUse"
id="linearGradient4332"
xlink:href="#linearGradient3824"
inkscape:collect="always" />
<radialGradient
r="8.6620579"
fy="19.008621"
fx="31.112698"
cy="19.008621"
cx="31.112698"
gradientUnits="userSpaceOnUse"
id="radialGradient4330"
xlink:href="#linearGradient3816"
inkscape:collect="always" />
<radialGradient
r="9.1620579"
fy="17.064077"
fx="29.344931"
cy="17.064077"
cx="29.344931"
gradientTransform="matrix(0.787998,3.877637e-16,-3.877637e-16,0.787998,6.221198,3.617627)"
gradientUnits="userSpaceOnUse"
id="radialGradient4328"
xlink:href="#linearGradient4338"
inkscape:collect="always" />
<linearGradient
y2="35.803486"
x2="30.935921"
y1="29.553486"
x1="30.935921"
gradientTransform="translate(-12.41789,-7.000000)"
gradientUnits="userSpaceOnUse"
id="linearGradient4326"
xlink:href="#linearGradient3824"
inkscape:collect="always" />
<radialGradient
r="8.6620579"
fy="19.008621"
fx="31.112698"
cy="19.008621"
cx="31.112698"
gradientUnits="userSpaceOnUse"
id="radialGradient4179"
xlink:href="#linearGradient3816"
inkscape:collect="always" />
<linearGradient
gradientTransform="translate(0.707108,0.000000)"
y2="35.803486"
x2="30.935921"
y1="29.553486"
x1="30.935921"
gradientUnits="userSpaceOnUse"
id="linearGradient4175"
xlink:href="#linearGradient3824"
inkscape:collect="always" />
<radialGradient
gradientTransform="matrix(0.787998,3.877637e-16,-3.877637e-16,0.787998,6.221198,3.617627)"
r="9.1620579"
fy="17.064077"
fx="29.344931"
cy="17.064077"
cx="29.344931"
gradientUnits="userSpaceOnUse"
id="radialGradient4171"
xlink:href="#linearGradient3800"
inkscape:collect="always" />
<radialGradient
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.297564,2.881172e-16,-1.96472e-16,0.884831,-8.358505,4.940469)"
r="13.565360"
fy="27.203083"
fx="28.089741"
cy="27.203083"
cx="28.089741"
id="radialGradient4169"
xlink:href="#linearGradient4163"
inkscape:collect="always" />
<linearGradient
gradientUnits="userSpaceOnUse"
y2="35.803486"
x2="30.935921"
y1="29.553486"
x1="30.935921"
id="linearGradient3830"
xlink:href="#linearGradient3824"
inkscape:collect="always" />
<radialGradient
gradientUnits="userSpaceOnUse"
r="8.6620579"
fy="19.008621"
fx="31.112698"
cy="19.008621"
cx="31.112698"
id="radialGradient3822"
xlink:href="#linearGradient3816"
inkscape:collect="always" />
<radialGradient
gradientUnits="userSpaceOnUse"
r="9.1620579"
fy="17.064077"
fx="29.344931"
cy="17.064077"
cx="29.344931"
id="radialGradient3806"
xlink:href="#linearGradient3800"
inkscape:collect="always" />
<linearGradient
id="linearGradient3800">
<stop
id="stop3802"
offset="0.0000000"
style="stop-color:#f4d9b1;stop-opacity:1.0000000;" />
<stop
id="stop3804"
offset="1.0000000"
style="stop-color:#df9725;stop-opacity:1.0000000;" />
</linearGradient>
<linearGradient
id="linearGradient3816"
inkscape:collect="always">
<stop
id="stop3818"
offset="0"
style="stop-color:#000000;stop-opacity:1;" />
<stop
id="stop3820"
offset="1"
style="stop-color:#000000;stop-opacity:0;" />
</linearGradient>
<linearGradient
id="linearGradient3824">
<stop
id="stop3826"
offset="0"
style="stop-color:#ffffff;stop-opacity:1;" />
<stop
id="stop3828"
offset="1.0000000"
style="stop-color:#c9c9c9;stop-opacity:1.0000000;" />
</linearGradient>
<linearGradient
id="linearGradient4163">
<stop
id="stop4165"
offset="0.0000000"
style="stop-color:#3b74bc;stop-opacity:1.0000000;" />
<stop
id="stop4167"
offset="1.0000000"
style="stop-color:#2d5990;stop-opacity:1.0000000;" />
</linearGradient>
<linearGradient
id="linearGradient4338">
<stop
style="stop-color:#e9b15e;stop-opacity:1.0000000;"
offset="0.0000000"
id="stop4340" />
<stop
style="stop-color:#966416;stop-opacity:1.0000000;"
offset="1.0000000"
id="stop4342" />
</linearGradient>
<linearGradient
id="linearGradient4344">
<stop
id="stop4346"
offset="0"
style="stop-color:#727e0a;stop-opacity:1;" />
<stop
id="stop4348"
offset="1.0000000"
style="stop-color:#5b6508;stop-opacity:1.0000000;" />
</linearGradient>
<linearGradient
id="linearGradient4356"
inkscape:collect="always">
<stop
id="stop4358"
offset="0"
style="stop-color:#000000;stop-opacity:1;" />
<stop
id="stop4360"
offset="1"
style="stop-color:#000000;stop-opacity:0;" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5464"
id="linearGradient5472"
gradientUnits="userSpaceOnUse"
x1="21.587093"
y1="23.499001"
x2="21.587093"
y2="2.8163671"
gradientTransform="matrix(1.106909,-0.258404,0.259748,1.101665,-19.66697,12.19788)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5476"
id="linearGradient5482"
x1="25.950134"
y1="2.8703361"
x2="29.477814"
y2="46.06208"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.106909,-0.258404,0.259748,1.101665,-19.66697,12.19788)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5476"
id="linearGradient5486"
gradientUnits="userSpaceOnUse"
x1="25.950134"
y1="2.8703361"
x2="29.477814"
y2="46.06208"
gradientTransform="matrix(-0.901805,0.210818,-0.211618,-0.898788,63.54132,37.87423)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient15107"
id="linearGradient5506"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.357669,0,0,1.505846,2.84291,-2.266018)"
x1="11.572842"
y1="4.7461626"
x2="18.475286"
y2="26.022910" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2624"
id="linearGradient5508"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.454781,0,0,0.762004,2.88175,0.337386)"
x1="9.1643066"
y1="38.070892"
x2="9.8855038"
y2="52.090679" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2274"
id="radialGradient5510"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.629929,0.459373,-0.147675,0.248512,16.51724,9.053737)"
cx="27.741131"
cy="38.711506"
fx="27.741131"
fy="38.711506"
r="17.977943" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient15107"
id="linearGradient5512"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.296015,0,0,-1.43692,3.746576,33.20516)"
x1="11.74217"
y1="11.48487"
x2="13.846983"
y2="11.981981" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient15107"
id="linearGradient5514"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.570607,0,0,-1.231511,2.973436,33.33485)"
x1="10.027"
y1="20.219761"
x2="17.178024"
y2="-7.5274644" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient9749"
id="linearGradient5516"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.370928,0,0,-1.46456,2.525057,33.71269)"
x1="11.841544"
y1="4.2507305"
x2="40.024059"
y2="7.4121075" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2573"
id="linearGradient5518"
gradientUnits="userSpaceOnUse"
x1="17.397203"
y1="33.357376"
x2="22.17771"
y2="31.026741" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5476"
id="linearGradient5528"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-0.901805,0.210818,-0.211618,-0.898788,63.54132,37.87423)"
x1="25.950134"
y1="2.8703361"
x2="29.477814"
y2="46.06208" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5464"
id="linearGradient5530"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.106909,-0.258404,0.259748,1.101665,-19.66697,12.19788)"
x1="21.587093"
y1="23.499001"
x2="21.587093"
y2="2.8163671" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5476"
id="linearGradient5532"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.106909,-0.258404,0.259748,1.101665,-19.66697,12.19788)"
x1="25.950134"
y1="2.8703361"
x2="29.477814"
y2="46.06208" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5464"
id="linearGradient3297"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.106909,-0.258404,0.259748,1.101665,-19.66697,12.19788)"
x1="21.587093"
y1="23.499001"
x2="21.587093"
y2="2.8163671" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5476"
id="linearGradient3299"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.106909,-0.258404,0.259748,1.101665,-19.66697,12.19788)"
x1="25.950134"
y1="2.8703361"
x2="29.477814"
y2="46.06208" />
</defs>
<sodipodi:namedview
inkscape:window-y="27"
inkscape:window-x="0"
inkscape:window-height="1024"
inkscape:window-width="1920"
inkscape:document-units="px"
inkscape:grid-bbox="true"
showgrid="false"
inkscape:current-layer="layer1"
inkscape:cy="-14.347029"
inkscape:cx="38.533427"
inkscape:zoom="1.4142136"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
borderopacity="0.16862745"
bordercolor="#666666"
pagecolor="#ffffff"
id="base"
inkscape:grid-points="true"
gridtolerance="2"
inkscape:object-bbox="false"
inkscape:object-points="false"
objecttolerance="2.8"
guidetolerance="2"
showguides="true"
inkscape:guide-bbox="true"
inkscape:showpageshadow="false"
inkscape:object-paths="false"
inkscape:has_abs_tolerance="false"
inkscape:window-maximized="1">
<inkscape:grid
id="GridFromPre046Settings"
type="xygrid"
originx="0px"
originy="0px"
spacingx="1px"
spacingy="1px"
color="#3f3fff"
empcolor="#3f3fff"
opacity="0.15"
empopacity="0.38"
empspacing="2" />
</sodipodi:namedview>
<metadata
id="metadata4">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>Send and Receive Mail</dc:title>
<dc:creator>
<cc:Agent>
<dc:title>Jakub Steiner</dc:title>
</cc:Agent>
</dc:creator>
<dc:contributor>
<cc:Agent>
<dc:title>Andreas Nilsson, Garrett LeSage</dc:title>
</cc:Agent>
</dc:contributor>
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
<dc:subject>
<rdf:Bag>
<rdf:li>mail</rdf:li>
<rdf:li>e-mail</rdf:li>
<rdf:li>send</rdf:li>
<rdf:li>receive</rdf:li>
</rdf:Bag>
</dc:subject>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
<cc:permits
rdf:resource="http://web.resource.org/cc/Reproduction" />
<cc:permits
rdf:resource="http://web.resource.org/cc/Distribution" />
<cc:requires
rdf:resource="http://web.resource.org/cc/Notice" />
<cc:requires
rdf:resource="http://web.resource.org/cc/Attribution" />
<cc:permits
rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
<cc:requires
rdf:resource="http://web.resource.org/cc/ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<g
inkscape:groupmode="layer"
inkscape:label="Layer 1"
id="layer1">
<path
sodipodi:type="arc"
style="opacity:0.3;color:#000000;fill:url(#radialGradient1481);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible"
id="path10699"
sodipodi:cx="12.75"
sodipodi:cy="38.700001"
sodipodi:rx="13.75"
sodipodi:ry="3.8"
d="m 26.5,38.700001 a 13.75,3.8 0 1 1 -27.5,0 13.75,3.8 0 1 1 27.5,0 z"
transform="matrix(1.66707,0,0,1.5930485,5.3581929,-22.843871)"
inkscape:r_cx="true"
inkscape:r_cy="true" />
<g
id="g2570"
transform="matrix(0.7571799,0,0,0.75599508,14.45706,-1.0815005)"
inkscape:r_cx="true"
inkscape:r_cy="true">
<path
id="path12723"
d="m 6.3437483,15.454879 0,25.987281 37.3593247,0 -0.06316,-25.887713 c -1.3e-5,-0.0057 3.78e-4,-0.02709 0,-0.03319 -7.39e-4,-0.0065 0.0011,-0.02633 0,-0.03319 -0.0015,-0.0072 -0.02977,-0.02558 -0.03158,-0.03319 l -37.2645847,0 z"
style="fill:url(#linearGradient1483);fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1.37973988;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
inkscape:r_cx="true"
inkscape:r_cy="true"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="ccccccc"
id="path1634"
d="M 20.490674,29.058712 7.09471,40.0307 l 13.908842,-9.604306 9.018158,0 12.419047,9.482193 -11.863425,-10.849875 -10.086658,0 z"
style="fill:url(#linearGradient1487);fill-opacity:1;fill-rule:evenodd;stroke:none"
inkscape:r_cx="true"
inkscape:r_cy="true"
inkscape:connector-curvature="0" />
<path
id="path15103"
d="m 7.5310575,16.733861 c -0.00667,0.01319 0.00537,0.01943 0,0.03125 -0.00236,0.0056 -0.029093,0.02604 -0.031121,0.03125 -0.0017,0.0049 0.00136,0.02674 0,0.03125 -0.00102,0.0041 6.829e-4,0.02747 0,0.03125 l 0.031121,23.217159 34.7933665,0 -0.06224,-23.092168 c -6.84e-4,-0.0037 0.001,-0.02721 0,-0.03125 -0.0146,-0.04755 -0.04166,-0.130713 -0.09336,-0.218735 l -34.6377615,0 z"
style="fill:none;stroke:#ffffff;stroke-width:1.37974012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
inkscape:r_cx="true"
inkscape:r_cy="true"
inkscape:connector-curvature="0" />
<path
id="path2563"
d="M 23.329298,32.996721 C 20.937189,32.550375 7.9003872,18.771125 6.5966059,16.372022 6.5816495,16.343448 6.5559705,16.288608 6.5446896,16.2636 l 34.5131134,0 c -0.277079,2.502804 -7.524227,16.505746 -9.561279,16.733121 -0.0082,4.68e-4 -0.02128,0 -0.02927,0 l -8.020859,0 c -0.03363,0 -0.07755,0.0074 -0.117094,0 z"
style="fill:url(#radialGradient1491);fill-opacity:1;fill-rule:evenodd;stroke:none"
inkscape:r_cx="true"
inkscape:r_cy="true"
inkscape:connector-curvature="0" />
<path
id="path1613"
d="M 20.77475,31.085394 C 18.407309,30.694257 7.945269,18.619435 7.1185841,16.517089 7.109327,16.49205 7.094677,16.443993 7.088438,16.422079 l 35.542207,0 c -0.823616,2.19322 -11.29845,14.464065 -13.445143,14.663315 -0.0085,4.09e-4 -0.02191,0 -0.03015,0 l -8.260021,0 c -0.03463,0 -0.08145,0.0065 -0.120584,0 z"
style="fill:url(#linearGradient1497);fill-opacity:1;fill-rule:evenodd;stroke:#989898;stroke-width:1.18189096;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
inkscape:r_cx="true"
inkscape:r_cy="true"
inkscape:connector-curvature="0" />
<path
id="path18153"
d="M 20.625174,30.490479 C 18.519211,29.999928 7.7224803,17.987711 7.0314243,16.466377 c -0.00254,-0.006 0.00218,-0.02669 0,-0.03231 -0.00545,-0.01576 -0.029096,-0.0523 -0.03125,-0.06463 2.87e-5,-0.0033 -4.061e-4,-0.02938 0,-0.03231 0.00117,-0.0021 0.029695,0.0017 0.03125,0 l 0.09375,-0.09694 35.4687497,0 c -0.0027,0.02433 -0.02268,0.06687 -0.03125,0.09694 -0.0075,0.0236 -0.02057,0.07023 -0.03125,0.09694 -0.922098,2.180937 -11.507988,13.766449 -13.34375,14.056416 -0.01493,0.0016 -0.04885,0 -0.0625,0 l -8.375,0 c -0.03029,-0.0017 -0.08975,0.0082 -0.125,0 z"
style="fill:url(#linearGradient1501);fill-opacity:1;fill-rule:evenodd;stroke:none"
inkscape:r_cx="true"
inkscape:r_cy="true"
inkscape:connector-curvature="0" />
<path
id="path1616"
d="M 20.875174,30.051141 C 18.427215,29.501671 8.7040003,18.433898 7.5314243,16.451725 l 34.5937497,0 c -1.490188,2.333171 -11.046672,13.411791 -13.15625,13.599416 -0.0087,4.02e-4 -0.02278,0 -0.03125,0 l -7.90625,0 c -0.02639,0 -0.06488,0.0036 -0.09375,0 -0.01979,-0.0031 -0.04165,0.0047 -0.0625,0 z"
style="fill:none;stroke:url(#linearGradient1503);stroke-width:1.18189073;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1"
inkscape:r_cx="true"
inkscape:r_cy="true"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="cccccc"
id="path1636"
d="m 20.959511,30.447113 -11.941499,8.270856 2.219433,0.0061 9.998125,-6.86894 8.821908,-1.422838 -9.097967,0.01482 z"
style="fill:url(#linearGradient1505);fill-opacity:1;fill-rule:evenodd;stroke:none"
inkscape:r_cx="true"
inkscape:r_cy="true"
inkscape:connector-curvature="0" />
</g>
<g
inkscape:r_cy="true"
inkscape:r_cx="true"
transform="matrix(0.7571799,0,0,0.75599508,4.1230464,8.5143759)"
id="g5488">
<path
inkscape:r_cy="true"
inkscape:r_cx="true"
style="fill:url(#linearGradient5506);fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1.37973988;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 6.3437483,15.454879 0,25.987281 37.3593247,0 -0.06316,-25.887713 c -1.3e-5,-0.0057 3.78e-4,-0.02709 0,-0.03319 -7.39e-4,-0.0065 0.0011,-0.02633 0,-0.03319 -0.0015,-0.0072 -0.02977,-0.02558 -0.03158,-0.03319 l -37.2645847,0 z"
id="path5490"
inkscape:connector-curvature="0" />
<path
inkscape:r_cy="true"
inkscape:r_cx="true"
style="fill:url(#linearGradient5508);fill-opacity:1;fill-rule:evenodd;stroke:none"
d="M 20.490674,29.058712 7.09471,40.0307 l 13.908842,-9.604306 9.018158,0 12.419047,9.482193 -11.863425,-10.849875 -10.086658,0 z"
id="path5492"
sodipodi:nodetypes="ccccccc"
inkscape:connector-curvature="0" />
<path
inkscape:r_cy="true"
inkscape:r_cx="true"
style="fill:none;stroke:#ffffff;stroke-width:1.37974012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 7.5310575,16.733861 c -0.00667,0.01319 0.00537,0.01943 0,0.03125 -0.00236,0.0056 -0.029093,0.02604 -0.031121,0.03125 -0.0017,0.0049 0.00136,0.02674 0,0.03125 -0.00102,0.0041 6.829e-4,0.02747 0,0.03125 l 0.031121,23.217159 34.7933665,0 -0.06224,-23.092168 c -6.84e-4,-0.0037 0.001,-0.02721 0,-0.03125 -0.0146,-0.04755 -0.04166,-0.130713 -0.09336,-0.218735 l -34.6377615,0 z"
id="path5494"
inkscape:connector-curvature="0" />
<path
inkscape:r_cy="true"
inkscape:r_cx="true"
style="fill:url(#radialGradient5510);fill-opacity:1;fill-rule:evenodd;stroke:none"
d="M 23.329298,32.996721 C 20.937189,32.550375 7.9003872,18.771125 6.5966059,16.372022 6.5816495,16.343448 6.5559705,16.288608 6.5446896,16.2636 l 34.5131134,0 c -0.277079,2.502804 -7.524227,16.505746 -9.561279,16.733121 -0.0082,4.68e-4 -0.02128,0 -0.02927,0 l -8.020859,0 c -0.03363,0 -0.07755,0.0074 -0.117094,0 z"
id="path5496"
inkscape:connector-curvature="0" />
<path
inkscape:r_cy="true"
inkscape:r_cx="true"
style="fill:url(#linearGradient5512);fill-opacity:1;fill-rule:evenodd;stroke:#989898;stroke-width:1.18189096;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
d="M 20.77475,31.085394 C 18.407309,30.694257 7.945269,18.619435 7.1185841,16.517089 7.109327,16.49205 7.094677,16.443993 7.088438,16.422079 l 35.542207,0 c -0.823616,2.19322 -11.29845,14.464065 -13.445143,14.663315 -0.0085,4.09e-4 -0.02191,0 -0.03015,0 l -8.260021,0 c -0.03463,0 -0.08145,0.0065 -0.120584,0 z"
id="path5498"
inkscape:connector-curvature="0" />
<path
inkscape:r_cy="true"
inkscape:r_cx="true"
style="fill:url(#linearGradient5514);fill-opacity:1;fill-rule:evenodd;stroke:none"
d="M 20.625174,30.490479 C 18.519211,29.999928 7.7224803,17.987711 7.0314243,16.466377 c -0.00254,-0.006 0.00218,-0.02669 0,-0.03231 -0.00545,-0.01576 -0.029096,-0.0523 -0.03125,-0.06463 2.87e-5,-0.0033 -4.061e-4,-0.02938 0,-0.03231 0.00117,-0.0021 0.029695,0.0017 0.03125,0 l 0.09375,-0.09694 35.4687497,0 c -0.0027,0.02433 -0.02268,0.06687 -0.03125,0.09694 -0.0075,0.0236 -0.02057,0.07023 -0.03125,0.09694 -0.922098,2.180937 -11.507988,13.766449 -13.34375,14.056416 -0.01493,0.0016 -0.04885,0 -0.0625,0 l -8.375,0 c -0.03029,-0.0017 -0.08975,0.0082 -0.125,0 z"
id="path5500"
inkscape:connector-curvature="0" />
<path
inkscape:r_cy="true"
inkscape:r_cx="true"
style="fill:none;stroke:url(#linearGradient5516);stroke-width:1.18189073;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1"
d="M 20.875174,30.051141 C 18.427215,29.501671 8.7040003,18.433898 7.5314243,16.451725 l 34.5937497,0 c -1.490188,2.333171 -11.046672,13.411791 -13.15625,13.599416 -0.0087,4.02e-4 -0.02278,0 -0.03125,0 l -7.90625,0 c -0.02639,0 -0.06488,0.0036 -0.09375,0 -0.01979,-0.0031 -0.04165,0.0047 -0.0625,0 z"
id="path5502"
inkscape:connector-curvature="0" />
<path
inkscape:r_cy="true"
inkscape:r_cx="true"
style="fill:url(#linearGradient5518);fill-opacity:1;fill-rule:evenodd;stroke:none"
d="m 20.959511,30.447113 -11.941499,8.270856 2.219433,0.0061 9.998125,-6.86894 8.821908,-1.422838 -9.097967,0.01482 z"
id="path5504"
sodipodi:nodetypes="cccccc"
inkscape:connector-curvature="0" />
</g>
<g
id="g5524"
inkscape:r_cx="true"
inkscape:r_cy="true"
transform="matrix(1.0358731,0.12915398,-0.12915398,1.0358731,3.4793879,-8.4319748)">
<path
sodipodi:nodetypes="cccccccc"
inkscape:r_cy="true"
inkscape:r_cx="true"
id="path4587"
d="M 1.349542,35.242012 7.245074,40.036876 20.092052,24.392047 24.022407,27.588624 30.349935,5.1150928 10.266168,16.400607 14.19652,19.597183 z"
style="color:#000000;fill:url(#linearGradient3297);fill-opacity:1;fill-rule:nonzero;stroke:#3465a4;stroke-width:0.99999911;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
inkscape:connector-curvature="0" />
<path
style="opacity:0.57142861;color:#000000;fill:none;stroke:url(#linearGradient3299);stroke-width:0.99999946;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
d="m 2.982173,35.037884 4.072772,3.399631 12.855565,-15.699276 3.510841,2.868302 4.811841,-17.6344247 -16.088989,8.4894697 3.680552,2.931418 z"
id="path5474"
inkscape:r_cx="true"
inkscape:r_cy="true"
sodipodi:nodetypes="cccccccc"
inkscape:connector-curvature="0" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -0,0 +1,242 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="48px"
height="48px"
id="svg1717"
sodipodi:version="0.32"
inkscape:version="0.48.3.1 r9886"
sodipodi:docname="Multimedia-volume-control.svg"
version="1.1"
inkscape:export-filename="/home/glic3/orchestra/django-orchestra/orchestra/static/orchestra/icons/Multimedia-volume-control.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<defs
id="defs1719">
<linearGradient
inkscape:collect="always"
id="linearGradient2335">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop2337" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop2339" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient2327">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop2329" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop2331" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient3574">
<stop
style="stop-color:#3465a4;stop-opacity:1;"
offset="0"
id="stop3576" />
<stop
style="stop-color:#3465a4;stop-opacity:0;"
offset="1"
id="stop3578" />
</linearGradient>
<linearGradient
id="linearGradient3566">
<stop
style="stop-color:#d3d7cf;stop-opacity:1;"
offset="0"
id="stop3568" />
<stop
style="stop-color:#a6ae9d;stop-opacity:1;"
offset="1"
id="stop3570" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient3558">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop3560" />
<stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3562" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3558"
id="radialGradient3564"
cx="22.571428"
cy="30.857143"
fx="22.571428"
fy="30.857143"
r="15.571428"
gradientTransform="matrix(1.000000,0.000000,0.000000,0.651376,3.763482e-15,10.75754)"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3566"
id="linearGradient3572"
x1="19.544102"
y1="22.640625"
x2="36.0625"
y2="22.640625"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.184060,0.000000,0.000000,1.184060,-5.942398,-5.052390)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3574"
id="linearGradient3580"
x1="22.031542"
y1="22.78162"
x2="20.71196"
y2="4.7503953"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.184060,0.000000,0.000000,1.184060,-5.942398,-5.052390)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2327"
id="linearGradient2333"
x1="17.525631"
y1="20.396902"
x2="33.474358"
y2="15.271904"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.184060,0.000000,0.000000,1.184060,-5.942398,-4.319792)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2335"
id="linearGradient2341"
x1="23.9375"
y1="18.725033"
x2="23.9375"
y2="16.847691"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.184060,0.000000,0.000000,1.184060,-5.942398,-4.319792)" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="0.12156863"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="4"
inkscape:cx="35.22146"
inkscape:cy="15.407751"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:showpageshadow="false"
fill="#3465a4"
stroke="#888a85"
inkscape:window-width="737"
inkscape:window-height="669"
inkscape:window-x="697"
inkscape:window-y="181"
inkscape:window-maximized="0" />
<metadata
id="metadata1722">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
<dc:title>Volume Control</dc:title>
<dc:subject>
<rdf:Bag>
<rdf:li>multimedia</rdf:li>
<rdf:li>sound</rdf:li>
<rdf:li>volume</rdf:li>
<rdf:li>knob</rdf:li>
<rdf:li>control</rdf:li>
<rdf:li>mixer</rdf:li>
</rdf:Bag>
</dc:subject>
<dc:creator>
<cc:Agent>
<dc:title>Jakub Steiner</dc:title>
</cc:Agent>
</dc:creator>
<dc:source>http://jimmac.musichall.cz</dc:source>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
<cc:permits
rdf:resource="http://web.resource.org/cc/Reproduction" />
<cc:permits
rdf:resource="http://web.resource.org/cc/Distribution" />
<cc:requires
rdf:resource="http://web.resource.org/cc/Notice" />
<cc:requires
rdf:resource="http://web.resource.org/cc/Attribution" />
<cc:permits
rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
<cc:requires
rdf:resource="http://web.resource.org/cc/ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<path
style="opacity:1;color:#000000;fill:url(#linearGradient3580);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:1 1 ;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M 3.5532403,33.393643 C -5.5596849,21.573975 6.9131063,9.4946328 20.952673,9.8329353 C 34.99224,10.171238 45.099036,15.118916 47.467155,27.805271 C 47.467155,27.805271 39.728479,27.086378 39.728479,27.086378 C 39.728479,19.305413 32.804297,15.24578 21.121824,15.24578 C 9.107311,15.24578 -2.6269476,18.34756 3.5532403,33.393643 z "
id="path2664"
sodipodi:nodetypes="cscczc" />
<path
sodipodi:type="arc"
style="opacity:0.47368421;color:#000000;fill:url(#radialGradient3564);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="path3556"
sodipodi:cx="22.571428"
sodipodi:cy="30.857143"
sodipodi:rx="15.571428"
sodipodi:ry="10.142858"
d="M 38.142857 30.857143 A 15.571428 10.142858 0 1 1 7,30.857143 A 15.571428 10.142858 0 1 1 38.142857 30.857143 z"
transform="matrix(1.408115,0.000000,0.000000,1.408115,-10.54085,-16.32385)" />
<path
style="opacity:1;color:#000000;fill:#cc0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:1 1 ;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M 39.390175,28.439589 C 39.390175,28.439589 38.882722,30.638557 38.290692,31.399738 L 46.832838,37.235461 C 47.847746,34.021585 47.509443,29.7928 47.509443,29.7928 L 39.390175,28.439589 z "
id="path3539"
sodipodi:nodetypes="ccccc" />
<path
style="opacity:1;color:#000000;fill:url(#linearGradient3572);fill-opacity:1;fill-rule:nonzero;stroke:#888a85;stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M 20.883958,6.1221749 C 13.55429,6.1221749 7.6002852,10.219577 7.6002852,15.261641 C 7.6002852,16.855622 5.2321652,23.956925 5.2321652,26.732222 C 5.2321652,32.609278 12.155451,37.388761 20.698949,37.388762 C 29.242446,37.388762 36.165734,32.609276 36.165733,26.732222 C 36.165733,24.022217 34.13063,15.261641 34.13063,15.261641 L 33.982622,8.1572805 L 29.690405,8.5272993 C 27.34265,7.0620706 24.305772,6.1221749 20.883958,6.1221749 z "
id="path3541"
sodipodi:nodetypes="csssssccc" />
<path
style="opacity:0.73684208;color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient2341);stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M 20.698949,6.6031993 C 14.047951,6.6031993 8.636338,10.051187 8.636338,14.299592 C 8.636338,18.547995 14.047951,21.995982 20.698949,21.995982 C 27.349947,21.995982 32.761559,18.547995 32.76156,14.299592 C 32.76156,13.51384 32.401598,12.793721 32.058525,12.079479 L 33.316588,8.8233143 L 29.653403,9.3043386 C 27.444179,7.6893945 24.31762,6.6031994 20.698949,6.6031993 z "
id="path3545" />
<path
sodipodi:nodetypes="csssssccc"
id="path1452"
d="M 20.87031,7.2748571 C 14.081079,7.2748571 8.5660815,11.070145 8.5660815,15.740442 C 8.5660815,17.216895 6.3725701,23.794597 6.3725701,26.365264 C 6.3725701,31.808986 12.785381,36.236064 20.698941,36.236065 C 28.6125,36.236065 35.025314,31.808986 35.025312,26.365264 C 35.025312,23.855076 33.140264,15.740442 33.140264,15.740442 L 33.003169,9.1599082 L 29.02743,9.5026438 C 26.852782,8.1454517 24.039823,7.2748571 20.87031,7.2748571 z "
style="opacity:0.47368421;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient2333);stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB