2
VERSION
|
@ -1 +1 @@
|
|||
0.4.0
|
||||
0.4.1
|
||||
|
|
45
app/admin.py
|
@ -2,7 +2,9 @@ from django.contrib import admin
|
|||
from guardian.admin import GuardedModelAdmin
|
||||
|
||||
from app.models import Preset
|
||||
from .models import Project, Task, ImageUpload
|
||||
from .models import Project, Task, ImageUpload, Setting, Theme
|
||||
from django import forms
|
||||
from codemirror2.widgets import CodeMirrorEditor
|
||||
|
||||
admin.site.register(Project, GuardedModelAdmin)
|
||||
|
||||
|
@ -17,3 +19,44 @@ admin.site.register(ImageUpload, ImageUploadAdmin)
|
|||
|
||||
admin.site.register(Preset, admin.ModelAdmin)
|
||||
|
||||
|
||||
class SettingAdmin(admin.ModelAdmin):
|
||||
|
||||
|
||||
def has_add_permission(self, request):
|
||||
# if there's already an entry, do not allow adding
|
||||
count = Setting.objects.all().count()
|
||||
return count == 0
|
||||
|
||||
admin.site.register(Setting, SettingAdmin)
|
||||
|
||||
|
||||
class ThemeModelForm(forms.ModelForm):
|
||||
css = forms.CharField(help_text="Enter custom CSS",
|
||||
required=False,
|
||||
widget=CodeMirrorEditor(options={'mode': 'css', 'lineNumbers': True}))
|
||||
html_before_header = forms.CharField(help_text="HTML that will be displayed above site header",
|
||||
required=False,
|
||||
widget=CodeMirrorEditor(options={'mode': 'xml', 'lineNumbers': True}))
|
||||
html_after_header = forms.CharField(help_text="HTML that will be displayed after site header",
|
||||
required=False,
|
||||
widget=CodeMirrorEditor(options={'mode': 'xml', 'lineNumbers': True}))
|
||||
html_after_body = forms.CharField(help_text="HTML that will be displayed after the </body> tag",
|
||||
required=False,
|
||||
widget=CodeMirrorEditor(options={'mode': 'xml', 'lineNumbers': True}))
|
||||
html_footer = forms.CharField(help_text="HTML that will be displayed in the footer. You can also use the special tags:"
|
||||
"<p class='help'>{ORGANIZATION}: show a link to your organization.</p>"
|
||||
"<p class='help'>{YEAR}: show current year</p>",
|
||||
required=False,
|
||||
widget=CodeMirrorEditor(options={'mode': 'xml', 'lineNumbers': True}))
|
||||
|
||||
class Meta:
|
||||
model = Theme
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class ThemeAdmin(admin.ModelAdmin):
|
||||
form = ThemeModelForm
|
||||
|
||||
|
||||
admin.site.register(Theme, ThemeAdmin)
|
22
app/boot.py
|
@ -1,15 +1,20 @@
|
|||
import os
|
||||
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.contrib.auth.models import User, Group
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.core.files import File
|
||||
from django.db.utils import ProgrammingError
|
||||
from guardian.shortcuts import assign_perm
|
||||
|
||||
from app.models import Preset
|
||||
from app.models import Theme
|
||||
from nodeodm.models import ProcessingNode
|
||||
# noinspection PyUnresolvedReferences
|
||||
from webodm.settings import MEDIA_ROOT
|
||||
from . import scheduler, signals
|
||||
import logging
|
||||
from .models import Task
|
||||
from .models import Task, Setting
|
||||
from webodm import settings
|
||||
from webodm.wsgi import booted
|
||||
|
||||
|
@ -65,6 +70,21 @@ def boot():
|
|||
])
|
||||
Preset.objects.get_or_create(name='Default', system=True, options=[{'name': 'dsm', 'value': True}])
|
||||
|
||||
# Add settings
|
||||
default_theme, created = Theme.objects.get_or_create(name='Default')
|
||||
if created:
|
||||
logger.info("Created default theme")
|
||||
|
||||
if Setting.objects.all().count() == 0:
|
||||
default_logo = os.path.join('app', 'static', 'app', 'img', 'logo512.png')
|
||||
|
||||
s = Setting.objects.create(
|
||||
app_name='WebODM',
|
||||
theme=default_theme)
|
||||
s.app_logo.save(os.path.basename(default_logo), File(open(default_logo, 'rb')))
|
||||
|
||||
logger.info("Created settings")
|
||||
|
||||
# Unlock any Task that might have been locked
|
||||
Task.objects.filter(processing_lock=True).update(processing_lock=False)
|
||||
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
import logging
|
||||
|
||||
from app.models import Setting
|
||||
|
||||
logger = logging.getLogger('app.logger')
|
||||
|
||||
# Make the SETTINGS object available to all templates
|
||||
def load(request=None):
|
||||
return {'SETTINGS': Setting.objects.first()}
|
||||
|
||||
# Helper functions for libsass
|
||||
|
||||
def theme(color):
|
||||
"""Return a theme color from the currently selected theme"""
|
||||
try:
|
||||
return getattr(load()['SETTINGS'].theme, color)
|
||||
except Exception as e:
|
||||
logger.warning("Cannot load configuration from theme(): " + e.message)
|
||||
return "blue" # dah buh dih ah buh daa..
|
||||
|
||||
|
||||
def complementary(hexcolor):
|
||||
"""Returns complementary RGB color
|
||||
Example: complementaryColor('#FFFFFF') --> '#000000'
|
||||
"""
|
||||
if hexcolor[0] == '#':
|
||||
hexcolor = hexcolor[1:]
|
||||
rgb = (hexcolor[0:2], hexcolor[2:4], hexcolor[4:6])
|
||||
comp = ['%02X' % (255 - int(a, 16)) for a in rgb]
|
||||
return '#' + ''.join(comp)
|
||||
|
||||
|
||||
def scaleby(hexcolor, scalefactor, ignore_value = False):
|
||||
"""
|
||||
Scales a hex string by ``scalefactor``, but is color dependent, unless ignore_value is True
|
||||
scalefactor is now always between 0 and 1. A value of 0.8
|
||||
will cause bright colors to become darker and
|
||||
dark colors to become brigther by 20%
|
||||
"""
|
||||
|
||||
def calculate(hexcolor, scalefactor):
|
||||
"""
|
||||
Scales a hex string by ``scalefactor``. Returns scaled hex string.
|
||||
To darken the color, use a float value between 0 and 1.
|
||||
To brighten the color, use a float value greater than 1.
|
||||
|
||||
>>> colorscale("#DF3C3C", .5)
|
||||
#6F1E1E
|
||||
>>> colorscale("#52D24F", 1.6)
|
||||
#83FF7E
|
||||
>>> colorscale("#4F75D2", 1)
|
||||
#4F75D2
|
||||
"""
|
||||
|
||||
def clamp(val, minimum=0, maximum=255):
|
||||
if val < minimum:
|
||||
return minimum
|
||||
if val > maximum:
|
||||
return maximum
|
||||
return int(val)
|
||||
|
||||
hexcolor = hexcolor.strip('#')
|
||||
|
||||
if scalefactor < 0 or len(hexcolor) != 6:
|
||||
return hexcolor
|
||||
|
||||
r, g, b = int(hexcolor[:2], 16), int(hexcolor[2:4], 16), int(hexcolor[4:], 16)
|
||||
|
||||
r = clamp(r * scalefactor)
|
||||
g = clamp(g * scalefactor)
|
||||
b = clamp(b * scalefactor)
|
||||
|
||||
return "#%02x%02x%02x" % (r, g, b)
|
||||
|
||||
|
||||
hexcolor = hexcolor.strip('#')
|
||||
scalefactor = abs(float(scalefactor.value))
|
||||
scalefactor = min(1.0, max(0, scalefactor))
|
||||
|
||||
r, g, b = int(hexcolor[:2], 16), int(hexcolor[2:4], 16), int(hexcolor[4:], 16)
|
||||
value = max(r, g, b)
|
||||
|
||||
return calculate(hexcolor, scalefactor if ignore_value or value >= 127 else 2 - scalefactor)
|
|
@ -0,0 +1,57 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.1 on 2017-11-09 17:37
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import colorfield.fields
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('app', '0010_auto_20170725_1324'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Setting',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('app_name', models.CharField(help_text='The name of your application', max_length=255)),
|
||||
('app_logo', models.ImageField(help_text='A 512x512 logo of your application (.png or .jpeg)', upload_to='settings/')),
|
||||
('organization_name', models.CharField(blank=True, default='WebODM', help_text='The name of your organization', max_length=255, null=True)),
|
||||
('organization_website', models.URLField(blank=True, default='https://github.com/OpenDroneMap/WebODM/', help_text='The website URL of your organization', max_length=255, null=True)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Theme',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(help_text='Name of theme', max_length=255)),
|
||||
('primary', colorfield.fields.ColorField(default='#2c3e50', help_text='Most text, icons, and borders.', max_length=18)),
|
||||
('secondary', colorfield.fields.ColorField(default='#ffffff', help_text='The main background color, and text color of some buttons.', max_length=18)),
|
||||
('tertiary', colorfield.fields.ColorField(default='#18bc9c', help_text='Navigation links.', max_length=18)),
|
||||
('button_primary', colorfield.fields.ColorField(default='#2c3e50', help_text='Primary button color.', max_length=18)),
|
||||
('button_default', colorfield.fields.ColorField(default='#95a5a6', help_text='Default button color.', max_length=18)),
|
||||
('button_danger', colorfield.fields.ColorField(default='#e74c3c', help_text='Delete button color.', max_length=18)),
|
||||
('header_background', colorfield.fields.ColorField(default='#18bc9c', help_text="Background color of the site's header.", max_length=18)),
|
||||
('header_primary', colorfield.fields.ColorField(default='#ffffff', help_text="Text and icons in the site's header.", max_length=18)),
|
||||
('border', colorfield.fields.ColorField(default='#e7e7e7', help_text='The color of most borders.', max_length=18)),
|
||||
('highlight', colorfield.fields.ColorField(default='#f7f7f7', help_text='The background color of panels and some borders.', max_length=18)),
|
||||
('dialog_warning', colorfield.fields.ColorField(default='#f39c12', help_text='The border color of warning dialogs.', max_length=18)),
|
||||
('failed', colorfield.fields.ColorField(default='#ffcbcb', help_text='The background color of failed notifications.', max_length=18)),
|
||||
('success', colorfield.fields.ColorField(default='#cbffcd', help_text='The background color of success notifications.', max_length=18)),
|
||||
('css', models.TextField(blank=True, default='')),
|
||||
('html_before_header', models.TextField(blank=True, default='')),
|
||||
('html_after_header', models.TextField(blank=True, default='')),
|
||||
('html_after_body', models.TextField(blank=True, default='')),
|
||||
('html_footer', models.TextField(blank=True, default='')),
|
||||
],
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='setting',
|
||||
name='theme',
|
||||
field=models.ForeignKey(help_text='Active theme', on_delete=django.db.models.deletion.DO_NOTHING, to='app.Theme'),
|
||||
),
|
||||
]
|
|
@ -2,3 +2,6 @@ from .image_upload import ImageUpload, image_directory_path
|
|||
from .project import Project
|
||||
from .task import Task, validate_task_options, gcp_directory_path
|
||||
from .preset import Preset
|
||||
from .theme import Theme
|
||||
from .setting import Setting
|
||||
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
import logging
|
||||
import os
|
||||
from shutil import rmtree
|
||||
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.db import models
|
||||
from django.db.models import signals
|
||||
from django.dispatch import receiver
|
||||
from imagekit.models import ImageSpecField
|
||||
from imagekit.processors import ResizeToFit
|
||||
|
||||
from webodm import settings
|
||||
from .theme import Theme, update_theme_css
|
||||
|
||||
logger = logging.getLogger('app.logger')
|
||||
|
||||
|
||||
class Setting(models.Model):
|
||||
app_name = models.CharField(max_length=255, blank=False, null=False, help_text="The name of your application")
|
||||
app_logo = models.ImageField(upload_to="settings/", blank=False, null=False, help_text="A 512x512 logo of your application (.png or .jpeg)")
|
||||
app_logo_36 = ImageSpecField(source='app_logo',
|
||||
processors=[ResizeToFit(36, 36)],
|
||||
format='PNG',
|
||||
options={'quality': 90})
|
||||
app_logo_favicon = ImageSpecField(source='app_logo',
|
||||
processors=[ResizeToFit(48, 48)],
|
||||
format='PNG',
|
||||
options={'quality': 90})
|
||||
|
||||
organization_name = models.CharField(default='WebODM', max_length=255, blank=True, null=True, help_text="The name of your organization")
|
||||
organization_website = models.URLField(default='https://github.com/OpenDroneMap/WebODM/', max_length=255, blank=True, null=True, help_text="The website URL of your organization")
|
||||
theme = models.ForeignKey(Theme, blank=False, null=False, on_delete=models.DO_NOTHING,
|
||||
help_text="Active theme")
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Setting, self).__init__(*args, **kwargs)
|
||||
|
||||
# To help keep track of changes to the app_logo
|
||||
self.__original_app_logo_name = self.app_logo.name
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
# Cleanup old logo files if needed
|
||||
if self.__original_app_logo_name != "" and \
|
||||
self.app_logo.name != self.__original_app_logo_name and \
|
||||
os.path.basename(self.app_logo.name) != os.path.basename(self.__original_app_logo_name): # This last line will leave an old copy in the cache if the filename is the same name as the previous, but we don't care
|
||||
|
||||
old_logo_path = os.path.join(settings.MEDIA_ROOT, self.__original_app_logo_name)
|
||||
old_logo_path_caches = os.path.join(settings.MEDIA_ROOT,
|
||||
"CACHE",
|
||||
"images",
|
||||
os.path.splitext(self.__original_app_logo_name)[0])
|
||||
|
||||
if os.path.exists(old_logo_path):
|
||||
try:
|
||||
os.unlink(old_logo_path)
|
||||
logger.info("Removed {}".format(old_logo_path))
|
||||
except:
|
||||
logger.warning("Cannot cleanup {}".format(old_logo_path))
|
||||
|
||||
if os.path.exists(old_logo_path_caches):
|
||||
try:
|
||||
rmtree(old_logo_path_caches)
|
||||
logger.info("Removed {}".format(old_logo_path_caches))
|
||||
except:
|
||||
logger.warning("Cannot cleanup {}".format(old_logo_path_caches))
|
||||
|
||||
self.__original_app_logo_name = self.app_logo.name
|
||||
|
||||
super(Setting, self).save(*args, **kwargs)
|
||||
|
||||
def __str__(self):
|
||||
return "Application"
|
||||
|
||||
|
||||
@receiver(signals.pre_save, sender=Setting, dispatch_uid="setting_pre_save")
|
||||
def setting_pre_save(sender, instance, **kwargs):
|
||||
if Setting.objects.count() > 0 and instance.id != Setting.objects.get().id:
|
||||
raise ValidationError("Can only create 1 %s instance" % Setting.__name__)
|
||||
|
||||
|
||||
@receiver(signals.post_save, sender=Setting, dispatch_uid="setting_post_save")
|
||||
def setting_post_save(sender, instance, created, **kwargs):
|
||||
update_theme_css()
|
||||
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from django.db.models import signals
|
||||
from django.db import models
|
||||
from colorfield.fields import ColorField
|
||||
from django.dispatch import receiver
|
||||
|
||||
from webodm import settings
|
||||
|
||||
logger = logging.getLogger('app.logger')
|
||||
|
||||
class Theme(models.Model):
|
||||
name = models.CharField(max_length=255, blank=False, null=False, help_text="Name of theme")
|
||||
|
||||
# Similar to how discourse.org does it
|
||||
primary = ColorField(default='#2c3e50', help_text="Most text, icons, and borders.")
|
||||
secondary = ColorField(default='#ffffff', help_text="The main background color, and text color of some buttons.")
|
||||
tertiary = ColorField(default='#18bc9c', help_text="Navigation links.")
|
||||
|
||||
button_primary = ColorField(default='#2c3e50', help_text="Primary button color.")
|
||||
button_default = ColorField(default='#95a5a6', help_text="Default button color.")
|
||||
button_danger = ColorField(default='#e74c3c', help_text="Delete button color.")
|
||||
|
||||
header_background = ColorField(default='#18bc9c', help_text="Background color of the site's header.")
|
||||
header_primary = ColorField(default='#ffffff', help_text="Text and icons in the site's header.")
|
||||
|
||||
border = ColorField(default='#e7e7e7', help_text="The color of most borders.")
|
||||
highlight = ColorField(default='#f7f7f7', help_text="The background color of panels and some borders.")
|
||||
|
||||
dialog_warning = ColorField(default='#f39c12', help_text="The border color of warning dialogs.")
|
||||
|
||||
failed = ColorField(default='#ffcbcb', help_text="The background color of failed notifications.")
|
||||
success = ColorField(default='#cbffcd', help_text="The background color of success notifications.")
|
||||
|
||||
css = models.TextField(default='', blank=True)
|
||||
html_before_header = models.TextField(default='', blank=True)
|
||||
html_after_header = models.TextField(default='', blank=True)
|
||||
html_after_body = models.TextField(default='', blank=True)
|
||||
html_footer = models.TextField(default='', blank=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
@receiver(signals.post_save, sender=Theme, dispatch_uid="theme_post_save")
|
||||
def theme_post_save(sender, instance, created, **kwargs):
|
||||
update_theme_css()
|
||||
|
||||
|
||||
def update_theme_css():
|
||||
"""
|
||||
Touch theme.scss to invalidate its cache and force
|
||||
compressor to regenerate it
|
||||
"""
|
||||
|
||||
theme_file = os.path.join('app', 'static', 'app', 'css', 'theme.scss')
|
||||
try:
|
||||
Path(theme_file).touch()
|
||||
logger.info("Regenerate cache for {}".format(theme_file))
|
||||
except:
|
||||
logger.warning("Failed to touch {}".format(theme_file))
|
|
@ -2,6 +2,7 @@
|
|||
DJANGO Admin styles
|
||||
*/
|
||||
.admin-area {
|
||||
background-color: #fff;
|
||||
/* GLOBAL DEFAULTS */
|
||||
/* TEXT STYLES & MODIFIERS */
|
||||
/* TABLES */
|
||||
|
@ -19,6 +20,8 @@
|
|||
/* HEADER */
|
||||
/* SIDEBAR */
|
||||
/* POPUP */ }
|
||||
.admin-area .CodeMirror-scroll, .admin-area .CodeMirror {
|
||||
height: 150px !important; }
|
||||
.admin-area #changelist-filter {
|
||||
display: none; }
|
||||
.admin-area a:link, .admin-area a:visited {
|
||||
|
|
|
@ -3,6 +3,12 @@
|
|||
*/
|
||||
|
||||
.admin-area{
|
||||
background-color: #fff;
|
||||
|
||||
.CodeMirror-scroll, .CodeMirror{
|
||||
height: 150px !important;
|
||||
}
|
||||
|
||||
#changelist-filter{
|
||||
display: none;
|
||||
}
|
||||
|
|
Przed Szerokość: | Wysokość: | Rozmiar: 2.3 KiB |
Przed Szerokość: | Wysokość: | Rozmiar: 10 KiB |
Przed Szerokość: | Wysokość: | Rozmiar: 2.3 KiB |
|
@ -1,9 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square150x150logo src="/static/app/mstile-150x150.png"/>
|
||||
<TileColor>#00aba9</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
</browserconfig>
|
|
@ -1,12 +1,12 @@
|
|||
html, body, #wrapper, #page-wrapper, section.main, .content{
|
||||
height: 100%;
|
||||
html, body, section.main, .content, #wrapper, #page-wrapper{
|
||||
height: auto;
|
||||
}
|
||||
#page-wrapper{
|
||||
margin-top: 1px;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
#navbar-top{
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
height: 50px;
|
||||
min-height: 50px;
|
||||
background-color: #18bc9c;
|
||||
|
@ -41,7 +41,6 @@ html, body, #wrapper, #page-wrapper, section.main, .content{
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
ul#side-menu{
|
||||
a:hover, a:focus{
|
||||
color: white;
|
||||
|
@ -51,6 +50,10 @@ html, body, #wrapper, #page-wrapper, section.main, .content{
|
|||
|
||||
li{
|
||||
word-break: break-word;
|
||||
&:first-child{
|
||||
border-top-width: 1px;
|
||||
border-top-style: solid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,7 +66,7 @@ html, body, #wrapper, #page-wrapper, section.main, .content{
|
|||
|
||||
.email{
|
||||
font-size: 90%;
|
||||
color: gray;
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -77,7 +80,7 @@ ul#side-menu.nav{
|
|||
|
||||
.content{
|
||||
clear: both;
|
||||
padding-top: 60px;
|
||||
padding-top: 8px;
|
||||
|
||||
h1,h2,h3,h4,h5{
|
||||
padding-top: 4px;
|
||||
|
@ -89,8 +92,8 @@ ul#side-menu.nav{
|
|||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.navbar-default{
|
||||
background-color: white;
|
||||
.navbar-default.sidebar{
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
||||
.alert{
|
||||
|
@ -98,8 +101,12 @@ ul#side-menu.nav{
|
|||
background-color: #fff;
|
||||
border-width: 2px;
|
||||
color: #000;
|
||||
.close{
|
||||
opacity: 0.6;
|
||||
}
|
||||
.close:hover, .close:focus{
|
||||
color: #000;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -163,19 +170,6 @@ button i.glyphicon{
|
|||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.btn.btn-secondary{
|
||||
background-color: #dddddd;
|
||||
}
|
||||
|
||||
.btn.btn-white{
|
||||
background-color: #fff;
|
||||
color: #111;
|
||||
|
||||
&:hover{
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-menu>li>a{
|
||||
padding-left: 10px;
|
||||
color: #222;
|
||||
|
@ -219,8 +213,19 @@ button i.glyphicon{
|
|||
left: 50px;
|
||||
}
|
||||
|
||||
.navbar-link {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
footer{
|
||||
font-size: 80%;
|
||||
height: 36px;
|
||||
border-top: 1px solid #efefef;
|
||||
text-align: center;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.list-group-item{
|
||||
background-color: inherit;
|
||||
border-top-width: 0px;
|
||||
|
||||
&:first-child{
|
||||
border-top-width: 1px;
|
||||
}
|
||||
}
|
|
@ -15,7 +15,6 @@ body {
|
|||
#page-wrapper {
|
||||
padding: 0 15px;
|
||||
min-height: 568px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
@media(min-width:768px) {
|
||||
|
|
|
@ -0,0 +1,233 @@
|
|||
/* Primary */
|
||||
body,
|
||||
ul#side-menu.nav a,
|
||||
.console,
|
||||
.alert,
|
||||
.form-control,
|
||||
.dropdown-menu > li > a,
|
||||
.theme-color-primary,
|
||||
{
|
||||
color: theme("primary");
|
||||
}
|
||||
.tooltip{
|
||||
.tooltip-inner{
|
||||
background-color: theme("primary");
|
||||
}
|
||||
&.left .tooltip-arrow{ border-left-color: theme("primary"); }
|
||||
&.top .tooltip-arrow{ border-top-color: theme("primary"); }
|
||||
&.bottom .tooltip-arrow{ border-bottom-color: theme("primary"); }
|
||||
&.right .tooltip-arrow{ border-right-color: theme("primary"); }
|
||||
}
|
||||
|
||||
/* Secondary */
|
||||
body,
|
||||
.navbar-default,
|
||||
.console,
|
||||
.alert,
|
||||
.modal-content,
|
||||
.form-control,
|
||||
.dropdown-menu,
|
||||
.theme-secondary
|
||||
{
|
||||
background-color: theme("secondary");
|
||||
}
|
||||
|
||||
.tooltip > .tooltip-inner{
|
||||
color: theme("secondary");
|
||||
}
|
||||
|
||||
.alert{
|
||||
.close:hover, .close:focus{
|
||||
color: complementary(theme("secondary"));
|
||||
}
|
||||
}
|
||||
|
||||
.pagination li > a,
|
||||
.pagination .disabled > a,
|
||||
.pagination .disabled > a:hover, .pagination .disabled > a:focus{
|
||||
color: scaleby(theme("primary"), 0.7);
|
||||
background-color: theme("secondary");
|
||||
border-color: scaleby(theme("secondary"), 0.7);
|
||||
}
|
||||
.pagination li > a{
|
||||
color: theme("primary");
|
||||
}
|
||||
|
||||
.btn-secondary, .btn-secondary:active, .btn-secondary.active, .open>.dropdown-toggle.btn-secondary{
|
||||
background-color: theme("secondary");
|
||||
border-color: theme("secondary");
|
||||
color: theme("primary");
|
||||
|
||||
&:hover, &:active, &:focus{
|
||||
background-color: scalebyiv(theme("secondary"), 0.90);
|
||||
border-color: scalebyiv(theme("secondary"), 0.90);
|
||||
color: theme("primary");
|
||||
}
|
||||
}
|
||||
|
||||
/* Tertiary */
|
||||
a, a:hover, a:focus{
|
||||
color: theme("tertiary");
|
||||
}
|
||||
|
||||
/* Button primary */
|
||||
#navbar-top .navbar-top-links,{
|
||||
a:hover,a:focus,.open > a{
|
||||
background-color: theme("button_primary");
|
||||
color: theme("secondary");
|
||||
}
|
||||
}
|
||||
|
||||
#navbar-top ul#side-menu a:hover, #navbar-top ul#side-menu a:focus{
|
||||
background-color: theme("button_primary");
|
||||
color: theme("secondary");
|
||||
}
|
||||
|
||||
.btn-primary, .btn-primary:active, .btn-primary.active, .open>.dropdown-toggle.btn-primary{
|
||||
background-color: theme("button_primary");
|
||||
border-color: theme("button_primary");
|
||||
color: theme("secondary");
|
||||
|
||||
&:hover, &:active, &:focus, &[disabled]:hover, &[disabled]:focus, &[disabled]:active{
|
||||
background-color: scalebyiv(theme("button_primary"), 0.90);
|
||||
border-color: scalebyiv(theme("button_primary"), 0.90);
|
||||
color: theme("secondary");
|
||||
}
|
||||
}
|
||||
|
||||
/* Button default */
|
||||
.btn-default, .btn-default:active, .btn-default.active, .open>.dropdown-toggle.btn-default{
|
||||
background-color: theme("button_default");
|
||||
border-color: theme("button_default");
|
||||
color: theme("secondary");
|
||||
|
||||
&:hover, &:active, &:focus, &[disabled]:hover, &[disabled]:focus, &[disabled]:active{
|
||||
background-color: scalebyiv(theme("button_default"), 0.90);
|
||||
border-color: scalebyiv(theme("button_default"), 0.90);
|
||||
color: theme("secondary");
|
||||
}
|
||||
}
|
||||
|
||||
.pagination>.active>a, .pagination>.active>span, .pagination>.active>a:hover, .pagination>.active>span:hover, .pagination>.active>a:focus, .pagination>.active>span:focus,
|
||||
.pagination .active > a:hover, .pagination .active > a:focus,
|
||||
.pagination li > a:hover, .pagination li > a:focus{
|
||||
background-color: theme("button_default");
|
||||
color: theme("secondary");
|
||||
}
|
||||
|
||||
/* Button danger */
|
||||
.btn-danger, .btn-danger:active, .btn-danger.active, .open>.dropdown-toggle.btn-danger{
|
||||
background-color: theme("button_danger");
|
||||
border-color: theme("button_danger");
|
||||
color: theme("secondary");
|
||||
|
||||
&:hover, &:active, &:focus, &[disabled]:hover, &[disabled]:focus, &[disabled]:active {
|
||||
background-color: scalebyiv(theme("button_danger"), 0.90);
|
||||
border-color: scalebyiv(theme("button_danger"), 0.90);
|
||||
color: theme("secondary");
|
||||
}
|
||||
}
|
||||
|
||||
/* Header background */
|
||||
#navbar-top{
|
||||
background-color: theme("header_background");
|
||||
}
|
||||
|
||||
/* Header primary */
|
||||
.navbar-default .navbar-link,
|
||||
#navbar-top .navbar-top-links a.dropdown-toggle{
|
||||
color: theme("header_primary");
|
||||
|
||||
&:hover{
|
||||
color: theme("secondary");
|
||||
}
|
||||
}
|
||||
|
||||
/* Border */
|
||||
.sidebar ul li,
|
||||
.project-list-item,
|
||||
#page-wrapper,
|
||||
table-bordered>thead>tr>th, .table-bordered>thead>tr>th, table-bordered>tbody>tr>th, .table-bordered>tbody>tr>th, table-bordered>tfoot>tr>th, .table-bordered>tfoot>tr>th, table-bordered>thead>tr>td, .table-bordered>thead>tr>td, table-bordered>tbody>tr>td, .table-bordered>tbody>tr>td, table-bordered>tfoot>tr>td, .table-bordered>tfoot>tr>td,
|
||||
footer,
|
||||
.modal-content,
|
||||
.modal-header,
|
||||
.modal-footer,
|
||||
.dropdown-menu
|
||||
{
|
||||
border-color: theme("border");
|
||||
}
|
||||
.dropdown-menu .divider{
|
||||
background-color: theme("border");
|
||||
}
|
||||
|
||||
/* Highlight */
|
||||
.task-list-item:nth-child(odd),
|
||||
.table-striped>tbody>tr:nth-of-type(odd),
|
||||
.theme-background-highlight{
|
||||
background-color: theme("highlight");
|
||||
}
|
||||
.dropdown-menu > li > a{
|
||||
&:hover, &:focus{
|
||||
background-color: theme("highlight");
|
||||
color: theme("primary");
|
||||
}
|
||||
}
|
||||
pre.prettyprint,
|
||||
.form-control{
|
||||
border-color: theme('highlight');
|
||||
&:focus{
|
||||
border-color: scalebyiv(theme('highlight'), 0.7);
|
||||
}
|
||||
}
|
||||
|
||||
/* Dialog warning */
|
||||
.alert-warning{
|
||||
border-color: theme("dialog_warning");
|
||||
}
|
||||
|
||||
/* Success */
|
||||
.task-list-item .status-label.done{
|
||||
background-color: theme("success");
|
||||
}
|
||||
|
||||
/* Failed */
|
||||
.task-list-item .status-label.error{
|
||||
background-color: theme("failed");
|
||||
}
|
||||
|
||||
|
||||
/* ModelView.jsx specific */
|
||||
.model-view #potree_sidebar_container {
|
||||
.dropdown-menu > li > a{
|
||||
color: theme("primary");
|
||||
}
|
||||
}
|
||||
|
||||
/* MapView.jsx specific */
|
||||
.leaflet-bar a, .leaflet-control > a{
|
||||
background-color: theme("secondary") !important;
|
||||
border-color: theme("secondary") !important;
|
||||
color: theme("primary") !important;
|
||||
|
||||
&:hover{
|
||||
background-color: scalebyiv(theme("secondary"), 0.90) !important;
|
||||
border-color: scalebyiv(theme("secondary"), 0.90) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.leaflet-popup-content-wrapper{
|
||||
background-color: theme("secondary") !important;
|
||||
color: theme("primary") !important;
|
||||
a{
|
||||
color: theme("tertiary") !important;
|
||||
}
|
||||
}
|
||||
|
||||
.leaflet-container{
|
||||
a.leaflet-popup-close-button{
|
||||
color: theme("primary") !important;
|
||||
&:hover{
|
||||
color: complementary(theme("secondary")) !important;
|
||||
}
|
||||
}
|
||||
}
|
Przed Szerokość: | Wysokość: | Rozmiar: 383 B |
Przed Szerokość: | Wysokość: | Rozmiar: 561 B |
Przed Szerokość: | Wysokość: | Rozmiar: 15 KiB |
Przed Szerokość: | Wysokość: | Rozmiar: 1.3 KiB |
|
@ -89,7 +89,7 @@ class MapView extends React.Component {
|
|||
<button
|
||||
key={mapType.type}
|
||||
onClick={this.handleMapTypeButton(mapType.type)}
|
||||
className={"btn btn-sm " + (mapType.type === this.state.selectedMapType ? "btn-default" : "btn-secondary")}>{mapType.label}</button>
|
||||
className={"btn btn-sm " + (mapType.type === this.state.selectedMapType ? "btn-primary" : "btn-default")}>{mapType.label}</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
|
@ -102,7 +102,7 @@ class MapView extends React.Component {
|
|||
showBackground={true}
|
||||
opacity={opacity}
|
||||
mapType={this.state.selectedMapType} />
|
||||
<div className="opacity-slider">
|
||||
<div className="opacity-slider theme-secondary">
|
||||
Opacity: <input type="range" step="1" value={opacity} onChange={this.updateOpacity} />
|
||||
</div>
|
||||
</div>);
|
||||
|
|
|
@ -206,7 +206,10 @@ class ModelView extends React.Component {
|
|||
checked={this.state.showTexturedModel}
|
||||
/> Textured Model</label>
|
||||
</div>
|
||||
<AssetDownloadButtons task={this.props.task} direction="down" />
|
||||
<AssetDownloadButtons
|
||||
task={this.props.task}
|
||||
direction="down"
|
||||
buttonClass="btn-secondary" />
|
||||
{showSwitchModeButton ?
|
||||
<SwitchModeButton
|
||||
task={this.props.task}
|
||||
|
|
|
@ -6,14 +6,16 @@ import PropTypes from 'prop-types';
|
|||
class AssetDownloadButtons extends React.Component {
|
||||
static defaultProps = {
|
||||
disabled: false,
|
||||
direction: "down", // or "up"
|
||||
direction: "down", // or "up",
|
||||
buttonClass: "btn-primary",
|
||||
task: null
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
disabled: PropTypes.bool,
|
||||
task: PropTypes.object.isRequired,
|
||||
direction: PropTypes.string
|
||||
direction: PropTypes.string,
|
||||
buttonClass: PropTypes.string
|
||||
};
|
||||
|
||||
constructor(props){
|
||||
|
@ -33,10 +35,10 @@ class AssetDownloadButtons extends React.Component {
|
|||
const assetDownloads = AssetDownloads.only(this.props.task.available_assets);
|
||||
|
||||
return (<div className={"asset-download-buttons btn-group " + (this.props.direction === "up" ? "dropup" : "")}>
|
||||
<button type="button" className="btn btn-sm btn-primary" disabled={this.props.disabled} data-toggle="dropdown">
|
||||
<button type="button" className={"btn btn-sm " + this.props.buttonClass} disabled={this.props.disabled} data-toggle="dropdown">
|
||||
<i className="glyphicon glyphicon-download"></i> Download Assets
|
||||
</button>
|
||||
<button type="button" className="btn btn-primary btn-sm dropdown-toggle" data-toggle="dropdown" disabled={this.props.disabled}>
|
||||
<button type="button" className={"btn btn-sm dropdown-toggle " + this.props.buttonClass} data-toggle="dropdown" disabled={this.props.disabled}>
|
||||
<span className="caret"></span>
|
||||
</button>
|
||||
<ul className="dropdown-menu">
|
||||
|
|
|
@ -136,7 +136,7 @@ class Map extends React.Component {
|
|||
<button
|
||||
onclick="location.href='/3d/project/${task.project}/task/${task.id}/';"
|
||||
type="button"
|
||||
class="switchModeButton btn btn-sm btn-default btn-white">
|
||||
class="switchModeButton btn btn-sm btn-default">
|
||||
<i class="fa fa-cube"></i> 3D
|
||||
</button>`;
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ class NewTaskPanel extends React.Component {
|
|||
if (this.props.uploading || this.state.editing){
|
||||
// Done editing, but still uploading
|
||||
return (
|
||||
<div className="new-task-panel">
|
||||
<div className="new-task-panel theme-background-highlight">
|
||||
<div className={"form-horizontal " + (this.state.editing ? "" : "hide")}>
|
||||
<p>{this.props.uploading ?
|
||||
"Your images are being uploaded. In the meanwhile, check these additional options:"
|
||||
|
|
|
@ -112,7 +112,7 @@ class ProcessingNodeOption extends React.Component {
|
|||
<div className="processing-node-option form-inline form-group form-horizontal" ref={this.setTooltips}>
|
||||
<label>{this.props.name} {(!this.isEnumType() && this.props.domain ? `(${this.props.domain})` : "")}</label><br/>
|
||||
{inputControl}
|
||||
<button type="submit" className="btn glyphicon glyphicon-info-sign btn-info" data-toggle="tooltip" data-placement="left" title={this.props.help} onClick={e => e.preventDefault()}></button>
|
||||
<button type="submit" className="btn glyphicon glyphicon-info-sign btn-primary" data-toggle="tooltip" data-placement="left" title={this.props.help} onClick={e => e.preventDefault()}></button>
|
||||
<button type="submit" className="btn glyphicon glyphicon glyphicon-repeat btn-default" data-toggle="tooltip" data-placement="top" title="Reset to default" onClick={this.resetToDefault}></button>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -42,7 +42,7 @@ class SwitchModeButton extends React.Component {
|
|||
<button
|
||||
onClick={this.handleClick}
|
||||
type="button"
|
||||
className={"switchModeButton btn btn-sm btn-default btn-white " + (!this.props.task ? "hide" : "")}>
|
||||
className={"switchModeButton btn btn-sm btn-secondary " + (!this.props.task ? "hide" : "")}>
|
||||
<i className={"fa " + (this.icon())}></i> {this.text()}
|
||||
</button>
|
||||
);
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
.console{
|
||||
background: #fbfbfb;
|
||||
color: black;
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
[data-mapview]{
|
||||
height: 100%;
|
||||
height: calc(100vh - 100px);
|
||||
}
|
||||
|
||||
.map-view{
|
||||
height: 80%;
|
||||
height: calc(100% - 20px);
|
||||
position: relative;
|
||||
|
||||
input[type="range"]{
|
||||
|
@ -23,7 +23,6 @@
|
|||
margin-left: -100px;
|
||||
z-index: 400;
|
||||
padding-bottom: 6px;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.map-type-selector{
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
@import '../vendor/potree/js/jquery-ui.css';
|
||||
|
||||
[data-modelview]{
|
||||
height: 90%;
|
||||
height: calc(100vh - 100px);
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
.model-view{
|
||||
position: relative;
|
||||
|
@ -61,24 +62,10 @@
|
|||
.asset-download-buttons{
|
||||
margin-right: 8px;
|
||||
&.open{
|
||||
.dropdown-toggle{
|
||||
background-color: #f4f4f4;
|
||||
color: #111;
|
||||
}
|
||||
button{
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
button{
|
||||
background-color: #fff;
|
||||
color: #111;
|
||||
border-width: 1px;
|
||||
|
||||
&:hover{
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
.new-task-panel{
|
||||
background-color: #ecf0f1;
|
||||
padding: 10px;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
.task-list-item{
|
||||
&:nth-child(odd){
|
||||
background-color: #f7f7f7;
|
||||
}
|
||||
|
||||
.row{
|
||||
margin: 0;
|
||||
padding: 4px;
|
||||
|
@ -45,13 +41,6 @@
|
|||
padding: 4px;
|
||||
width: 100%;
|
||||
font-size: 90%;
|
||||
|
||||
&.done{
|
||||
background-color: #cbffcd;
|
||||
}
|
||||
&.error{
|
||||
background-color: #ffcbcb;
|
||||
}
|
||||
}
|
||||
|
||||
.clickable:hover{
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
{
|
||||
"name": "WebODM",
|
||||
"icons": [
|
||||
{
|
||||
"src": "\/static\/app\/android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image\/png"
|
||||
},
|
||||
{
|
||||
"src": "\/static\/app\/android-chrome-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image\/png"
|
||||
}
|
||||
],
|
||||
"theme_color": "#ffffff",
|
||||
"display": "standalone"
|
||||
}
|
Przed Szerokość: | Wysokość: | Rozmiar: 1.5 KiB |
|
@ -1,448 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="560.000000pt" height="560.000000pt" viewBox="0 0 560.000000 560.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.11, written by Peter Selinger 2001-2013
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,560.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M0 2800 l0 -2800 2800 0 2800 0 0 2800 0 2800 -2800 0 -2800 0 0
|
||||
-2800z m1498 2473 c-21 -2 -57 -2 -80 0 -24 2 -7 4 37 4 44 0 63 -2 43 -4z
|
||||
m2690 0 c-21 -2 -57 -2 -80 0 -24 2 -7 4 37 4 44 0 63 -2 43 -4z m-2865 -10
|
||||
c-7 -2 -21 -2 -30 0 -10 3 -4 5 12 5 17 0 24 -2 18 -5z m290 0 c-7 -2 -21 -2
|
||||
-30 0 -10 3 -4 5 12 5 17 0 24 -2 18 -5z m2400 0 c-7 -2 -21 -2 -30 0 -10 3
|
||||
-4 5 12 5 17 0 24 -2 18 -5z m290 0 c-7 -2 -19 -2 -25 0 -7 3 -2 5 12 5 14 0
|
||||
19 -2 13 -5z m-3046 -9 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z
|
||||
m420 0 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m2270 0 c-3 -3
|
||||
-12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m420 0 c-3 -3 -12 -4 -19 -1
|
||||
-8 3 -5 6 6 6 11 1 17 -2 13 -5z m-3160 -10 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6
|
||||
6 11 1 17 -2 13 -5z m520 0 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13
|
||||
-5z m2690 0 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m-3250 -10
|
||||
c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m600 0 c-3 -3 -12 -4
|
||||
-19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m2690 0 c-3 -3 -12 -4 -19 -1 -8 3 -5
|
||||
6 6 6 11 1 17 -2 13 -5z m193 -69 c14 -8 21 -14 15 -14 -5 0 -21 6 -35 14 -14
|
||||
8 -20 14 -15 14 6 0 21 -6 35 -14z m-3681 1 c-10 -9 -89 -46 -89 -41 0 6 72
|
||||
44 84 45 5 0 7 -2 5 -4z m1001 -6 c8 -5 11 -10 5 -10 -5 0 -17 5 -25 10 -8 5
|
||||
-10 10 -5 10 6 0 17 -5 25 -10z m1689 6 c-10 -9 -89 -46 -89 -41 0 6 72 44 84
|
||||
45 5 0 7 -2 5 -4z m-1629 -42 c0 -2 -9 0 -20 6 -11 6 -20 13 -20 16 0 2 9 0
|
||||
20 -6 11 -6 20 -13 20 -16z m2690 0 c0 -2 -9 0 -20 6 -11 6 -20 13 -20 16 0 2
|
||||
9 0 20 -6 11 -6 20 -13 20 -16z m-2540 -100 c0 -3 -13 4 -30 16 -16 12 -30 24
|
||||
-30 26 0 3 14 -4 30 -16 17 -12 30 -24 30 -26z m-1420 22 c0 -2 -8 -10 -17
|
||||
-17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m2690 0 c0 -2 -8 -10 -17 -17
|
||||
-16 -13 -17 -12 -4 4 13 16 21 21 21 13z m1411 -13 c13 -16 12 -17 -3 -4 -17
|
||||
13 -22 21 -14 21 2 0 10 -8 17 -17z m-4141 -16 c0 -2 -17 -19 -37 -38 l-38
|
||||
-34 34 38 c33 34 41 42 41 34z m1510 -32 c19 -19 32 -35 29 -35 -3 0 -20 16
|
||||
-39 35 -19 19 -32 35 -29 35 3 0 20 -16 39 -35z m1180 32 c0 -2 -15 -16 -32
|
||||
-33 l-33 -29 29 33 c28 30 36 37 36 29z m1500 -22 c13 -14 21 -25 18 -25 -2 0
|
||||
-15 11 -28 25 -13 14 -21 25 -18 25 2 0 15 -11 28 -25z m-3477 -32 c-13 -2
|
||||
-35 -2 -50 0 -16 2 -5 4 22 4 28 0 40 -2 28 -4z m105 0 c-16 -2 -40 -2 -55 0
|
||||
-16 2 -3 4 27 4 30 0 43 -2 28 -4z m2580 0 c-16 -2 -40 -2 -55 0 -16 2 -3 4
|
||||
27 4 30 0 43 -2 28 -4z m110 0 c-16 -2 -40 -2 -55 0 -16 2 -3 4 27 4 30 0 43
|
||||
-2 28 -4z m-2911 -9 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z
|
||||
m300 0 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m2390 0 c-3 -3
|
||||
-12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m300 0 c-3 -3 -12 -4 -19 -1
|
||||
-8 3 -5 6 6 6 11 1 17 -2 13 -5z m-3040 -10 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6
|
||||
6 11 1 17 -2 13 -5z m400 0 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13
|
||||
-5z m2290 0 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m400 0 c-3
|
||||
-3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m-2577 -34 c8 -5 11 -10 5
|
||||
-10 -5 0 -17 5 -25 10 -8 5 -10 10 -5 10 6 0 17 -5 25 -10z m-1190 -23 c0 -2
|
||||
-12 -14 -27 -28 l-28 -24 24 28 c23 25 31 32 31 24z m1760 -22 c13 -14 21 -25
|
||||
18 -25 -2 0 -15 11 -28 25 -13 14 -21 25 -18 25 2 0 15 -11 28 -25z m930 22
|
||||
c0 -2 -12 -14 -27 -28 l-28 -24 24 28 c23 25 31 32 31 24z m1760 -22 c13 -14
|
||||
21 -25 18 -25 -2 0 -15 11 -28 25 -13 14 -21 25 -18 25 2 0 15 -11 28 -25z
|
||||
m-4010 -10 c0 -2 -10 -9 -22 -15 -22 -11 -22 -10 -4 4 21 17 26 19 26 11z
|
||||
m890 -21 c0 -2 -9 0 -20 6 -11 6 -20 13 -20 16 0 2 9 0 20 -6 11 -6 20 -13 20
|
||||
-16z m1800 21 c0 -2 -10 -9 -22 -15 -22 -11 -22 -10 -4 4 21 17 26 19 26 11z
|
||||
m890 -21 c0 -2 -9 0 -20 6 -11 6 -20 13 -20 16 0 2 9 0 20 -6 11 -6 20 -13 20
|
||||
-16z m-4070 -8 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z
|
||||
m1851 -13 c13 -16 12 -17 -3 -4 -17 13 -22 21 -14 21 2 0 10 -8 17 -17z m839
|
||||
13 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m1851 -13
|
||||
c13 -16 12 -17 -3 -4 -17 13 -22 21 -14 21 2 0 10 -8 17 -17z m-4131 -7 c0 -2
|
||||
-8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m1031 -13 c13 -16 12
|
||||
-17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z m1659 13 c0 -2 -8 -10 -17 -17
|
||||
-16 -13 -17 -12 -4 4 13 16 21 21 21 13z m1035 -16 c10 -11 16 -20 13 -20 -3
|
||||
0 -13 9 -23 20 -10 11 -16 20 -13 20 3 0 13 -9 23 -20z m-4165 -4 c0 -2 -8
|
||||
-10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m1911 -13 c13 -16 12
|
||||
-17 -3 -4 -17 13 -22 21 -14 21 2 0 10 -8 17 -17z m753 -23 c-15 -22 -29 -40
|
||||
-31 -40 -5 0 3 15 29 53 30 43 31 32 2 -13z m1959 -9 c27 -46 14 -38 -18 12
|
||||
-16 23 -22 37 -14 30 8 -6 22 -25 32 -42z m-4223 36 c0 -1 -30 -32 -67 -67
|
||||
l-68 -65 65 68 c60 62 70 72 70 64z m1155 -57 c33 -33 57 -60 54 -60 -2 0 -31
|
||||
27 -64 60 -33 33 -57 60 -54 60 2 0 31 -27 64 -60z m1535 57 c0 -1 -30 -32
|
||||
-67 -67 l-68 -65 65 68 c60 62 70 72 70 64z m1160 -62 c30 -30 52 -55 49 -55
|
||||
-2 0 -29 25 -59 55 -30 30 -52 55 -49 55 2 0 29 -25 59 -55z m-4290 15 c-6
|
||||
-11 -13 -20 -16 -20 -2 0 0 9 6 20 6 11 13 20 16 20 2 0 0 -9 -6 -20z m1980 0
|
||||
c6 -11 8 -20 6 -20 -3 0 -10 9 -16 20 -6 11 -8 20 -6 20 3 0 10 -9 16 -20z
|
||||
m-2010 -50 c-6 -11 -13 -20 -16 -20 -2 0 0 9 6 20 6 11 13 20 16 20 2 0 0 -9
|
||||
-6 -20z m2045 -10 c9 -16 13 -30 11 -30 -3 0 -12 14 -21 30 -9 17 -13 30 -11
|
||||
30 3 0 12 -13 21 -30z m2685 10 c6 -11 8 -20 6 -20 -3 0 -10 9 -16 20 -6 11
|
||||
-8 20 -6 20 3 0 10 -9 16 -20z m-4759 -53 c-10 -9 -11 -8 -5 6 3 10 9 15 12
|
||||
12 3 -3 0 -11 -7 -18z m1739 -2 c14 -19 14 -19 -2 -6 -10 7 -18 18 -18 24 0 6
|
||||
1 8 3 6 1 -2 9 -13 17 -24z m951 2 c-10 -9 -11 -8 -5 6 3 10 9 15 12 12 3 -3
|
||||
0 -11 -7 -18z m-2321 9 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21
|
||||
21 21 13z m2668 -26 c-22 -30 -35 -41 -22 -17 9 16 36 47 41 47 2 0 -6 -13
|
||||
-19 -30z m1413 -12 c15 -28 5 -21 -21 15 -15 20 -17 27 -6 18 9 -8 22 -23 27
|
||||
-33z m-2347 16 c3 -8 2 -12 -4 -9 -6 3 -10 10 -10 16 0 14 7 11 14 -7z m2715
|
||||
-59 c0 -5 -6 1 -14 15 -8 14 -14 30 -14 35 0 6 6 -1 14 -15 8 -14 14 -29 14
|
||||
-35z m-4495 20 c-9 -14 -18 -25 -21 -25 -5 0 5 18 20 38 17 22 18 13 1 -13z
|
||||
m1456 -6 c15 -28 5 -23 -15 7 -9 15 -12 23 -6 20 6 -4 16 -16 21 -27z m-1809
|
||||
-6 c-12 -20 -14 -14 -5 12 4 9 9 14 11 11 3 -2 0 -13 -6 -23z m2159 -8 c0 -5
|
||||
-5 -3 -10 5 -5 8 -10 20 -10 25 0 6 5 3 10 -5 5 -8 10 -19 10 -25z m531 8
|
||||
c-12 -20 -14 -14 -5 12 4 9 9 14 11 11 3 -2 0 -13 -6 -23z m-511 -58 c0 -5 -5
|
||||
-3 -10 5 -5 8 -10 20 -10 25 0 6 5 3 10 -5 5 -8 10 -19 10 -25z m833 20 c-3
|
||||
-9 -8 -14 -10 -11 -3 3 -2 9 2 15 9 16 15 13 8 -4z m1857 -20 c0 -5 -5 -3 -10
|
||||
5 -5 8 -10 20 -10 25 0 6 5 3 10 -5 5 -8 10 -19 10 -25z m-4567 -20 c-9 -19
|
||||
-18 -33 -21 -31 -4 5 26 66 33 66 3 0 -3 -16 -12 -35z m1552 4 c9 -17 15 -33
|
||||
13 -35 -3 -2 -12 12 -21 31 -21 43 -13 47 8 4z m2690 0 c9 -17 15 -33 13 -35
|
||||
-3 -2 -12 12 -21 31 -21 43 -13 47 8 4z m-1557 -14 c-6 -14 -13 -23 -15 -21
|
||||
-5 5 15 46 22 46 3 0 -1 -11 -7 -25z m-3038 -52 c-11 -17 -11 -17 -6 0 3 10 6
|
||||
24 7 30 0 9 2 9 5 0 3 -7 0 -20 -6 -30z m2257 -15 c-3 -8 -6 -5 -6 6 -1 11 2
|
||||
17 5 13 3 -3 4 -12 1 -19z m430 0 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4
|
||||
-12 1 -19z m2260 0 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z
|
||||
m-4960 -40 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m2280 0 c-3
|
||||
-8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m410 0 c-3 -8 -6 -5 -6 6 -1
|
||||
11 2 17 5 13 3 -3 4 -12 1 -19z m2280 0 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3
|
||||
-3 4 -12 1 -19z m-4980 -50 c-3 -7 -5 -2 -5 12 0 14 2 19 5 13 2 -7 2 -19 0
|
||||
-25z m2300 10 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m390 -10
|
||||
c-3 -7 -5 -2 -5 12 0 14 2 19 5 13 2 -7 2 -19 0 -25z m2300 10 c-3 -8 -6 -5
|
||||
-6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m-4680 -20 c-3 -8 -6 -5 -6 6 -1 11 2
|
||||
17 5 13 3 -3 4 -12 1 -19z m1680 0 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4
|
||||
-12 1 -19z m1010 0 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z
|
||||
m1680 0 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m-4690 -50 c-3
|
||||
-7 -5 -2 -5 12 0 14 2 19 5 13 2 -7 2 -19 0 -25z m310 0 c-3 -7 -5 -2 -5 12 0
|
||||
14 2 19 5 13 2 -7 2 -19 0 -25z m1700 0 c-3 -7 -5 -2 -5 12 0 14 2 19 5 13 2
|
||||
-7 2 -19 0 -25z m310 0 c-3 -7 -5 -2 -5 12 0 14 2 19 5 13 2 -7 2 -19 0 -25z
|
||||
m370 10 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m310 -10 c-3 -7
|
||||
-5 -2 -5 12 0 14 2 19 5 13 2 -7 2 -19 0 -25z m1700 0 c-3 -7 -5 -2 -5 12 0
|
||||
14 2 19 5 13 2 -7 2 -19 0 -25z m310 -5 c-3 -10 -5 -4 -5 12 0 17 2 24 5 18 2
|
||||
-7 2 -21 0 -30z m-4710 -60 c-3 -10 -5 -4 -5 12 0 17 2 24 5 18 2 -7 2 -21 0
|
||||
-30z m1720 0 c-3 -10 -5 -4 -5 12 0 17 2 24 5 18 2 -7 2 -21 0 -30z m970 0
|
||||
c-3 -10 -5 -4 -5 12 0 17 2 24 5 18 2 -7 2 -21 0 -30z m-3000 -35 c-2 -13 -4
|
||||
-3 -4 22 0 25 2 35 4 23 2 -13 2 -33 0 -45z m2340 -15 c-2 -16 -4 -3 -4 27 0
|
||||
30 2 43 4 28 2 -16 2 -40 0 -55z m350 15 c-2 -13 -4 -3 -4 22 0 25 2 35 4 23
|
||||
2 -13 2 -33 0 -45z m2030 30 c-3 -7 -5 -2 -5 12 0 14 2 19 5 13 2 -7 2 -19 0
|
||||
-25z m310 -20 c-2 -13 -4 -5 -4 17 -1 22 1 32 4 23 2 -10 2 -28 0 -40z m0 -50
|
||||
c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m-2340 -105 c-2 -16 -4
|
||||
-5 -4 22 0 28 2 40 4 28 2 -13 2 -35 0 -50z m-2690 -10 c-2 -16 -4 -5 -4 22 0
|
||||
28 2 40 4 28 2 -13 2 -35 0 -50z m2340 5 c-2 -13 -4 -5 -4 17 -1 22 1 32 4 23
|
||||
2 -10 2 -28 0 -40z m2690 0 c-2 -13 -4 -5 -4 17 -1 22 1 32 4 23 2 -10 2 -28
|
||||
0 -40z m-4720 -25 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z
|
||||
m1720 0 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z m970 0 c-3
|
||||
-10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z m1720 0 c-3 -10 -5 -2 -5
|
||||
17 0 19 2 27 5 18 2 -10 2 -26 0 -35z m-2390 -60 c-3 -10 -5 -4 -5 12 0 17 2
|
||||
24 5 18 2 -7 2 -21 0 -30z m-2320 -5 c-3 -7 -5 -2 -5 12 0 14 2 19 5 13 2 -7
|
||||
2 -19 0 -25z m310 10 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z
|
||||
m1700 0 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m680 -10 c-3 -7
|
||||
-5 -2 -5 12 0 14 2 19 5 13 2 -7 2 -19 0 -25z m310 10 c-3 -8 -6 -5 -6 6 -1
|
||||
11 2 17 5 13 3 -3 4 -12 1 -19z m1700 0 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3
|
||||
-3 4 -12 1 -19z m310 -10 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z
|
||||
m-4690 -40 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m1680 0 c-3
|
||||
-8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m2690 0 c-3 -8 -6 -5 -6 6
|
||||
-1 11 2 17 5 13 3 -3 4 -12 1 -19z m-4680 -10 c-3 -8 -6 -5 -6 6 -1 11 2 17 5
|
||||
13 3 -3 4 -12 1 -19z m2300 0 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1
|
||||
-19z m390 0 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m2300 0 c-3
|
||||
-8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m-4980 -50 c-3 -8 -6 -5 -6
|
||||
6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m2280 0 c-3 -8 -6 -5 -6 6 -1 11 2 17 5
|
||||
13 3 -3 4 -12 1 -19z m410 0 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1
|
||||
-19z m2280 0 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m-4627 -53
|
||||
c0 -5 -5 -3 -10 5 -5 8 -10 20 -10 25 0 6 5 3 10 -5 5 -8 10 -19 10 -25z
|
||||
m2690 0 c0 -5 -5 -3 -10 5 -5 8 -10 20 -10 25 0 6 5 3 10 -5 5 -8 10 -19 10
|
||||
-25z m1601 8 c-12 -20 -14 -14 -5 12 4 9 9 14 11 11 3 -2 0 -13 -6 -23z
|
||||
m-4602 -53 c0 -10 -3 -8 -9 5 -12 27 -12 43 0 25 5 -8 9 -22 9 -30z m2222 9
|
||||
c-5 -13 -10 -19 -10 -12 -1 15 10 45 15 40 3 -2 0 -15 -5 -28z m2690 0 c-5
|
||||
-13 -10 -19 -10 -12 -1 15 10 45 15 40 3 -2 0 -15 -5 -28z m-4493 -149 l33
|
||||
-45 -33 37 c-18 20 -41 51 -51 70 -17 32 -17 32 0 8 10 -13 33 -45 51 -70z
|
||||
m2690 3 c17 -24 32 -46 32 -49 0 -11 -65 74 -84 109 -16 31 -16 31 1 7 10 -13
|
||||
33 -44 51 -67z m1432 68 c-5 -11 -15 -23 -21 -27 -6 -3 -3 5 6 20 20 30 30 35
|
||||
15 7z m-2710 -30 c-5 -11 -15 -23 -21 -27 -6 -3 -3 5 6 20 20 30 30 35 15 7z
|
||||
m-1771 -46 c0 -5 -6 1 -14 15 -8 14 -14 30 -14 35 0 6 6 -1 14 -15 8 -14 14
|
||||
-29 14 -35z m2097 -4 c-15 -28 -28 -51 -31 -51 -3 0 7 25 22 55 15 30 29 53
|
||||
31 51 2 -2 -8 -27 -22 -55z m598 2 c14 -29 24 -53 21 -53 -5 0 -55 95 -55 106
|
||||
0 12 6 2 34 -53z m2092 -2 c-15 -28 -28 -51 -31 -51 -3 0 7 25 22 55 15 30 29
|
||||
53 31 51 2 -2 -8 -27 -22 -55z m-3063 -15 c-10 -13 -20 -22 -22 -20 -4 4 29
|
||||
44 36 44 2 0 -4 -11 -14 -24z m2690 0 c-10 -13 -20 -22 -22 -20 -4 4 29 44 36
|
||||
44 2 0 -4 -11 -14 -24z m-4393 -16 c6 -11 8 -20 6 -20 -3 0 -10 9 -16 20 -6
|
||||
11 -8 20 -6 20 3 0 10 -9 16 -20z m410 -45 c13 -14 21 -25 18 -25 -2 0 -15 11
|
||||
-28 25 -13 14 -21 25 -18 25 2 0 15 -11 28 -25z m1260 22 c0 -2 -17 -19 -37
|
||||
-38 l-38 -34 34 38 c33 34 41 42 41 34z m1440 -32 c19 -19 32 -35 29 -35 -3 0
|
||||
-20 16 -39 35 -19 19 -32 35 -29 35 3 0 20 -16 39 -35z m1250 32 c0 -2 -17
|
||||
-19 -37 -38 l-38 -34 34 38 c33 34 41 42 41 34z m-4330 -27 c6 -11 8 -20 6
|
||||
-20 -3 0 -10 9 -16 20 -6 11 -8 20 -6 20 3 0 10 -9 16 -20z m2000 0 c-6 -11
|
||||
-13 -20 -16 -20 -2 0 0 9 6 20 6 11 13 20 16 20 2 0 0 -9 -6 -20z m2690 0 c-6
|
||||
-11 -13 -20 -16 -20 -2 0 0 9 6 20 6 11 13 20 16 20 2 0 0 -9 -6 -20z m-1980
|
||||
-31 c15 -28 5 -23 -15 7 -9 15 -12 23 -6 20 6 -4 16 -16 21 -27z m-1150 -12
|
||||
c0 -2 -10 -12 -22 -23 l-23 -19 19 23 c18 21 26 27 26 19z m2690 -5 c0 -4 -10
|
||||
-13 -22 -21 -23 -14 -23 -14 -4 8 20 22 26 25 26 13z m-3775 -30 c34 -30 25
|
||||
-27 -19 6 -16 12 -25 22 -20 22 5 0 23 -13 39 -28z m2725 -29 c0 -7 -58 36
|
||||
-66 49 -4 7 9 -1 29 -16 20 -16 37 -30 37 -33z m-3149 30 c13 -16 12 -17 -3
|
||||
-4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z m2514 -215 l190 187 -190 -192 c-104
|
||||
-106 -190 -191 -192 -190 -14 11 -384 382 -403 404 -13 15 72 -68 190 -184
|
||||
l215 -213 190 188z m2085 228 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13
|
||||
16 21 21 21 13z m-3140 -20 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16
|
||||
21 21 21 13z m2690 0 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21
|
||||
21 13z m-4119 -33 c13 -16 12 -17 -3 -4 -17 13 -22 21 -14 21 2 0 10 -8 17
|
||||
-17z m4539 13 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z
|
||||
m-4001 -62 c14 -12 -19 -1 -35 12 -18 14 -18 14 6 3 14 -6 27 -13 29 -15z
|
||||
m787 11 c-11 -8 -25 -15 -30 -15 -6 1 0 7 14 15 32 19 40 18 16 0z m1920 -23
|
||||
c-5 -4 -66 26 -66 33 0 3 16 -3 35 -12 19 -9 33 -18 31 -21z m784 33 c0 -6
|
||||
-56 -35 -67 -35 -4 1 8 9 27 20 39 22 40 22 40 15z m400 -78 l-74 -72 69 75
|
||||
c39 42 72 74 75 72 2 -1 -29 -35 -70 -75z m-4335 3 c38 -38 67 -70 64 -70 -2
|
||||
0 -36 32 -74 70 -38 39 -67 70 -64 70 2 0 36 -31 74 -70z m480 32 c-3 -3 -11
|
||||
0 -18 7 -9 10 -8 11 6 5 10 -3 15 -9 12 -12z m700 8 c-3 -5 -12 -10 -18 -10
|
||||
-7 0 -6 4 3 10 19 12 23 12 15 0z m2645 -20 c-8 -5 -19 -10 -25 -10 -5 0 -3 5
|
||||
5 10 8 5 20 10 25 10 6 0 3 -5 -5 -10z m-3253 -16 c-3 -3 -12 -4 -19 -1 -8 3
|
||||
-5 6 6 6 11 1 17 -2 13 -5z m503 -4 c-8 -5 -22 -9 -30 -9 -10 0 -8 3 5 9 27
|
||||
12 43 12 25 0z m2187 4 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z
|
||||
m520 0 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m-3130 -20 c-3
|
||||
-3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m360 0 c-3 -3 -12 -4 -19
|
||||
-1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m-304 -11 c-7 -2 -19 -2 -25 0 -7 3 -2 5
|
||||
12 5 14 0 19 -2 13 -5z m250 0 c-7 -2 -19 -2 -25 0 -7 3 -2 5 12 5 14 0 19 -2
|
||||
13 -5z m2440 0 c-7 -2 -21 -2 -30 0 -10 3 -4 5 12 5 17 0 24 -2 18 -5z m260 0
|
||||
c-7 -2 -21 -2 -30 0 -10 3 -4 5 12 5 17 0 24 -2 18 -5z m-2795 -10 c-21 -2
|
||||
-55 -2 -75 0 -21 2 -4 4 37 4 41 0 58 -2 38 -4z m2685 0 c-18 -2 -48 -2 -65 0
|
||||
-18 2 -4 4 32 4 36 0 50 -2 33 -4z m-3448 -53 c10 -11 16 -20 13 -20 -3 0 -13
|
||||
9 -23 20 -10 11 -16 20 -13 20 3 0 13 -9 23 -20z m1680 -187 l206 -207 -198
|
||||
-198 c-109 -109 -200 -198 -203 -198 -3 0 83 89 192 198 l198 197 -204 204
|
||||
-204 204 -38 -28 -39 -27 35 30 c19 18 38 32 42 32 3 0 99 -93 213 -207z
|
||||
m2470 197 c-3 -5 -20 -19 -38 -30 -32 -22 -32 -22 3 9 37 32 45 37 35 21z
|
||||
m-1639 -210 l-191 -190 180 -180 c104 -104 186 -178 193 -175 7 3 10 0 7 -5
|
||||
-3 -6 -10 -10 -14 -10 -6 0 -317 307 -371 366 -4 5 371 384 380 384 4 0 -80
|
||||
-85 -184 -190z m-2336 84 c0 -2 -13 2 -30 11 -16 9 -30 18 -30 21 0 2 14 -2
|
||||
30 -11 17 -9 30 -18 30 -21z m1150 31 c0 -2 -10 -9 -22 -15 -22 -11 -22 -10
|
||||
-4 4 21 17 26 19 26 11z m1520 -21 c0 -2 -9 0 -20 6 -11 6 -20 13 -20 16 0 2
|
||||
9 0 20 -6 11 -6 20 -13 20 -16z m1170 21 c0 -2 -10 -9 -22 -15 -22 -11 -22
|
||||
-10 -4 4 21 17 26 19 26 11z m-2740 -29 c0 -2 -7 -7 -16 -10 -8 -3 -12 -2 -9
|
||||
4 6 10 25 14 25 6z m1605 -6 c3 -6 -1 -7 -9 -4 -18 7 -21 14 -7 14 6 0 13 -4
|
||||
16 -10z m1085 6 c0 -2 -7 -7 -16 -10 -8 -3 -12 -2 -9 4 6 10 25 14 25 6z
|
||||
m-3755 -16 c3 -6 -1 -7 -9 -4 -18 7 -21 14 -7 14 6 0 13 -4 16 -10z m45 -20
|
||||
c8 -5 11 -10 5 -10 -5 0 -17 5 -25 10 -8 5 -10 10 -5 10 6 0 17 -5 25 -10z
|
||||
m2690 0 c8 -5 11 -10 5 -10 -5 0 -17 5 -25 10 -8 5 -10 10 -5 10 6 0 17 -5 25
|
||||
-10z m950 0 c-8 -5 -19 -10 -25 -10 -5 0 -3 5 5 10 8 5 20 10 25 10 6 0 3 -5
|
||||
-5 -10z m-3453 -66 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z
|
||||
m580 0 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m2110 0 c-3 -3
|
||||
-12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m580 0 c-3 -3 -12 -4 -19 -1
|
||||
-8 3 -5 6 6 6 11 1 17 -2 13 -5z m-2740 -10 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6
|
||||
6 11 1 17 -2 13 -5z m2690 0 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2
|
||||
13 -5z m-3114 -11 c-7 -2 -21 -2 -30 0 -10 3 -4 5 12 5 17 0 24 -2 18 -5z
|
||||
m374 1 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m2306 -1 c-7 -2
|
||||
-19 -2 -25 0 -7 3 -2 5 12 5 14 0 19 -2 13 -5z m384 1 c-3 -3 -12 -4 -19 -1
|
||||
-8 3 -5 6 6 6 11 1 17 -2 13 -5z m-2979 -11 c-10 -2 -28 -2 -40 0 -13 2 -5 4
|
||||
17 4 22 1 32 -1 23 -4z m225 0 c-7 -2 -21 -2 -30 0 -10 3 -4 5 12 5 17 0 24
|
||||
-2 18 -5z m2450 0 c-7 -2 -21 -2 -30 0 -10 3 -4 5 12 5 17 0 24 -2 18 -5z
|
||||
m235 0 c-10 -2 -28 -2 -40 0 -13 2 -5 4 17 4 22 1 32 -1 23 -4z m-2910 -270
|
||||
c-10 -2 -28 -2 -40 0 -13 2 -5 4 17 4 22 1 32 -1 23 -4z m220 0 c-10 -2 -26
|
||||
-2 -35 0 -10 3 -2 5 17 5 19 0 27 -2 18 -5z m2455 0 c-7 -2 -21 -2 -30 0 -10
|
||||
3 -4 5 12 5 17 0 24 -2 18 -5z m235 0 c-10 -2 -26 -2 -35 0 -10 3 -2 5 17 5
|
||||
19 0 27 -2 18 -5z m-2995 -10 c-7 -2 -21 -2 -30 0 -10 3 -4 5 12 5 17 0 24 -2
|
||||
18 -5z m380 0 c-7 -2 -19 -2 -25 0 -7 3 -2 5 12 5 14 0 19 -2 13 -5z m2294 1
|
||||
c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m396 -1 c-7 -2 -21 -2
|
||||
-30 0 -10 3 -4 5 12 5 17 0 24 -2 18 -5z m-3176 -19 c-3 -3 -12 -4 -19 -1 -8
|
||||
3 -5 6 6 6 11 1 17 -2 13 -5z m580 0 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1
|
||||
17 -2 13 -5z m2110 0 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z
|
||||
m580 0 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m163 -54 c8 -5
|
||||
11 -10 5 -10 -5 0 -17 5 -25 10 -8 5 -10 10 -5 10 6 0 17 -5 25 -10z m-3620
|
||||
-10 c-8 -5 -19 -10 -25 -10 -5 0 -3 5 5 10 8 5 20 10 25 10 6 0 3 -5 -5 -10z
|
||||
m960 -5 c14 -8 21 -14 15 -14 -5 0 -21 6 -35 14 -14 8 -20 14 -15 14 6 0 21
|
||||
-6 35 -14z m1074 -181 l186 -186 -21 -29 c-11 -16 -23 -29 -25 -29 -3 0 4 13
|
||||
15 28 l20 28 -185 185 -184 184 -200 -200 c-135 -135 -198 -205 -195 -215 5
|
||||
-12 4 -13 -7 -2 -10 10 26 51 192 217 113 113 208 205 211 205 4 0 90 -84 193
|
||||
-186z m-2099 156 c-3 -5 -12 -10 -18 -10 -7 0 -6 4 3 10 19 12 23 12 15 0z
|
||||
m2690 0 c-3 -5 -12 -10 -18 -10 -7 0 -6 4 3 10 19 12 23 12 15 0z m1080 -8
|
||||
c-3 -3 -11 0 -18 7 -9 10 -8 11 6 5 10 -3 15 -9 12 -12z m-2635 -28 c0 -2 -13
|
||||
2 -30 11 -16 9 -30 18 -30 21 0 2 14 -2 30 -11 17 -9 30 -18 30 -21z m-1170
|
||||
21 c0 -2 -10 -9 -22 -15 -22 -11 -22 -10 -4 4 21 17 26 19 26 11z m2690 0 c0
|
||||
-2 -10 -9 -22 -15 -22 -11 -22 -10 -4 4 21 17 26 19 26 11z m1170 -21 c0 -2
|
||||
-9 0 -20 6 -11 6 -20 13 -20 16 0 2 9 0 20 -6 11 -6 20 -13 20 -16z m-3970
|
||||
-48 c0 -3 -15 -14 -32 -26 l-33 -22 30 26 c31 27 35 29 35 22z m1416 -48 c4
|
||||
-7 -9 1 -29 16 -20 16 -37 30 -37 33 0 7 58 -36 66 -49z m2679 12 c10 -11 16
|
||||
-20 13 -20 -3 0 -13 9 -23 20 -10 11 -16 20 -13 20 3 0 13 -9 23 -20z m-4182
|
||||
-35 c-11 -8 -56 -52 -99 -97 -43 -46 -70 -72 -59 -58 35 46 159 170 169 170 6
|
||||
0 1 -7 -11 -15z m4282 -55 c38 -38 67 -70 64 -70 -2 0 -36 32 -74 70 -38 39
|
||||
-67 70 -64 70 2 0 36 -31 74 -70z m-3492 33 c-18 -2 -48 -2 -65 0 -18 2 -4 4
|
||||
32 4 36 0 50 -2 33 -4z m2705 0 c-16 -2 -40 -2 -55 0 -16 2 -3 4 27 4 30 0 43
|
||||
-2 28 -4z m-2841 -9 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z
|
||||
m256 -1 c-7 -2 -21 -2 -30 0 -10 3 -4 5 12 5 17 0 24 -2 18 -5z m2430 0 c-7
|
||||
-2 -21 -2 -30 0 -10 3 -4 5 12 5 17 0 24 -2 18 -5z m250 0 c-7 -2 -19 -2 -25
|
||||
0 -7 3 -2 5 12 5 14 0 19 -2 13 -5z m-3046 -19 c-3 -3 -12 -4 -19 -1 -8 3 -5
|
||||
6 6 6 11 1 17 -2 13 -5z m3150 0 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17
|
||||
-2 13 -5z m-2660 -10 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z
|
||||
m-567 -14 c-8 -5 -19 -10 -25 -10 -5 0 -3 5 5 10 8 5 20 10 25 10 6 0 3 -5 -5
|
||||
-10z m-61 -24 c-10 -9 -69 -36 -69 -32 0 7 52 35 64 36 5 0 7 -2 5 -4z m751
|
||||
-11 c17 -9 30 -18 30 -21 0 -4 -59 23 -69 32 -10 9 13 3 39 -11z m1939 11
|
||||
c-10 -9 -69 -36 -69 -32 0 7 52 35 64 36 5 0 7 -2 5 -4z m751 -11 c17 -9 30
|
||||
-18 30 -21 0 -4 -59 23 -69 32 -10 9 13 3 39 -11z m530 -50 c13 -14 21 -25 18
|
||||
-25 -2 0 -15 11 -28 25 -13 14 -21 25 -18 25 2 0 15 -11 28 -25z m-3109 -22
|
||||
c13 -16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z m2735 -35 c4 -7 -9
|
||||
1 -29 16 -20 16 -37 30 -37 33 0 7 58 -36 66 -49z m-4176 28 c0 -2 -8 -10 -17
|
||||
-17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m420 1 c0 -2 -10 -12 -22 -23
|
||||
l-23 -19 19 23 c18 21 26 27 26 19z m2690 0 c0 -2 -10 -12 -22 -23 l-23 -19
|
||||
19 23 c18 21 26 27 26 19z m-1616 -36 c-2 -3 -12 3 -22 13 -16 17 -16 18 5 5
|
||||
12 -7 20 -15 17 -18z m3101 3 c9 -15 12 -23 6 -20 -11 7 -35 46 -28 46 3 0 12
|
||||
-12 22 -26z m-4235 -17 c0 -2 -19 -21 -42 -42 l-43 -40 40 43 c36 39 45 47 45
|
||||
39z m1195 -37 c21 -22 37 -40 34 -40 -3 0 -23 18 -44 40 -21 22 -37 40 -34 40
|
||||
3 0 23 -18 44 -40z m1495 37 c0 -2 -19 -21 -42 -42 l-43 -40 40 43 c36 39 45
|
||||
47 45 39z m1195 -37 c21 -22 37 -40 34 -40 -3 0 -23 18 -44 40 -21 22 -37 40
|
||||
-34 40 3 0 23 -18 44 -40z m-2305 0 c6 -11 8 -20 6 -20 -3 0 -10 9 -16 20 -6
|
||||
11 -8 20 -6 20 3 0 10 -9 16 -20z m690 0 c-6 -11 -13 -20 -16 -20 -2 0 0 9 6
|
||||
20 6 11 13 20 16 20 2 0 0 -9 -6 -20z m2000 0 c6 -11 8 -20 6 -20 -3 0 -10 9
|
||||
-16 20 -6 11 -8 20 -6 20 3 0 10 -9 16 -20z m-4725 -60 c-9 -16 -18 -30 -21
|
||||
-30 -2 0 2 14 11 30 9 17 18 30 21 30 2 0 -2 -13 -11 -30z m2081 -21 c14 -28
|
||||
24 -53 22 -55 -2 -2 -16 21 -31 51 -15 30 -25 55 -22 55 3 0 16 -23 31 -51z
|
||||
m609 21 c-9 -16 -18 -30 -21 -30 -2 0 2 14 11 30 9 17 18 30 21 30 2 0 -2 -13
|
||||
-11 -30z m2065 10 c6 -11 8 -20 6 -20 -3 0 -10 9 -16 20 -6 11 -8 20 -6 20 3
|
||||
0 10 -9 16 -20z m-4413 -43 c-17 -23 -40 -54 -50 -67 -17 -24 -17 -24 0 8 18
|
||||
34 71 102 79 102 2 0 -11 -19 -29 -43z m1368 23 c10 -11 16 -20 13 -20 -3 0
|
||||
-13 9 -23 20 -10 11 -16 20 -13 20 3 0 13 -9 23 -20z m1355 17 c0 -2 -10 -12
|
||||
-22 -23 l-23 -19 19 23 c18 21 26 27 26 19z m1362 -52 c11 -21 8 -18 -32 30
|
||||
-24 29 -24 29 -2 10 13 -11 28 -29 34 -40z m367 -30 c0 -5 -6 1 -14 15 -8 14
|
||||
-14 30 -14 35 0 6 6 -1 14 -15 8 -14 14 -29 14 -35z m-4828 8 c-12 -20 -14
|
||||
-14 -5 12 4 9 9 14 11 11 3 -2 0 -13 -6 -23z m1802 -22 c27 -46 14 -38 -18 12
|
||||
-16 23 -22 37 -14 30 8 -6 22 -25 32 -42z m888 22 c-12 -20 -14 -14 -5 12 4 9
|
||||
9 14 11 11 3 -2 0 -13 -6 -23z m353 2 c-9 -14 -18 -25 -21 -25 -5 0 5 18 20
|
||||
38 17 22 18 13 1 -13z m1456 -36 c15 -28 5 -23 -15 7 -9 15 -12 23 -6 20 6 -4
|
||||
16 -16 21 -27z m-1507 -44 c-3 -9 -8 -14 -10 -11 -3 3 -2 9 2 15 9 16 15 13 8
|
||||
-4z m-3032 -22 c-12 -20 -14 -14 -5 12 4 9 9 14 11 11 3 -2 0 -13 -6 -23z
|
||||
m4909 -8 c0 -5 -5 -3 -10 5 -5 8 -10 20 -10 25 0 6 5 3 10 -5 5 -8 10 -19 10
|
||||
-25z m-4577 10 c-3 -9 -8 -14 -10 -11 -3 3 -2 9 2 15 9 16 15 13 8 -4z m4245
|
||||
-10 c-3 -3 -9 2 -12 12 -6 14 -5 15 5 6 7 -7 10 -15 7 -18z m-1898 -22 c-11
|
||||
-17 -11 -17 -6 0 3 10 6 24 7 30 0 9 2 9 5 0 3 -7 0 -20 -6 -30z m-2693 -15
|
||||
c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m2240 0 c-3 -8 -6 -5 -6
|
||||
6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m-2260 -70 c-3 -8 -6 -5 -6 6 -1 11 2 17
|
||||
5 13 3 -3 4 -12 1 -19z m2280 0 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12
|
||||
1 -19z m410 0 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m2280 0
|
||||
c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m-4980 -50 c-3 -8 -6 -5
|
||||
-6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m2300 0 c-3 -8 -6 -5 -6 6 -1 11 2 17
|
||||
5 13 3 -3 4 -12 1 -19z m390 0 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12
|
||||
1 -19z m2300 0 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m-4680
|
||||
-10 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m-320 -50 c-3 -7 -5
|
||||
-2 -5 12 0 14 2 19 5 13 2 -7 2 -19 0 -25z m2320 0 c-3 -7 -5 -2 -5 12 0 14 2
|
||||
19 5 13 2 -7 2 -19 0 -25z m370 0 c-3 -7 -5 -2 -5 12 0 14 2 19 5 13 2 -7 2
|
||||
-19 0 -25z m2010 0 c-3 -7 -5 -2 -5 12 0 14 2 19 5 13 2 -7 2 -19 0 -25z m310
|
||||
0 c-3 -7 -5 -2 -5 12 0 14 2 19 5 13 2 -7 2 -19 0 -25z m-4700 0 c-3 -8 -6 -5
|
||||
-6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m1700 0 c-3 -8 -6 -5 -6 6 -1 11 2 17
|
||||
5 13 3 -3 4 -12 1 -19z m990 0 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12
|
||||
1 -19z m-3010 -90 c-2 -13 -4 -5 -4 17 -1 22 1 32 4 23 2 -10 2 -28 0 -40z
|
||||
m310 15 c-3 -10 -5 -4 -5 12 0 17 2 24 5 18 2 -7 2 -21 0 -30z m1720 0 c-3
|
||||
-10 -5 -4 -5 12 0 17 2 24 5 18 2 -7 2 -21 0 -30z m970 0 c-3 -10 -5 -4 -5 12
|
||||
0 17 2 24 5 18 2 -7 2 -21 0 -30z m1720 0 c-3 -10 -5 -4 -5 12 0 17 2 24 5 18
|
||||
2 -7 2 -21 0 -30z m-2380 -55 c-2 -18 -4 -6 -4 27 0 33 2 48 4 33 2 -15 2 -42
|
||||
0 -60z m350 20 c-2 -13 -4 -3 -4 22 0 25 2 35 4 23 2 -13 2 -33 0 -45z m2340
|
||||
0 c-2 -13 -4 -3 -4 22 0 25 2 35 4 23 2 -13 2 -33 0 -45z m-5030 -30 c-3 -8
|
||||
-6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m2690 -110 c-2 -18 -4 -6 -4 27
|
||||
0 33 2 48 4 33 2 -15 2 -42 0 -60z m-2690 -5 c-2 -16 -4 -3 -4 27 0 30 2 43 4
|
||||
28 2 -16 2 -40 0 -55z m2340 -5 c-2 -13 -4 -3 -4 22 0 25 2 35 4 23 2 -13 2
|
||||
-33 0 -45z m2690 0 c-2 -13 -4 -3 -4 22 0 25 2 35 4 23 2 -13 2 -33 0 -45z
|
||||
m-4720 -10 c-3 -7 -5 -2 -5 12 0 14 2 19 5 13 2 -7 2 -19 0 -25z m1720 -5 c-3
|
||||
-10 -5 -4 -5 12 0 17 2 24 5 18 2 -7 2 -21 0 -30z m970 0 c-3 -10 -5 -4 -5 12
|
||||
0 17 2 24 5 18 2 -7 2 -21 0 -30z m1720 5 c-3 -7 -5 -2 -5 12 0 14 2 19 5 13
|
||||
2 -7 2 -19 0 -25z m300 -65 c-3 -10 -5 -4 -5 12 0 17 2 24 5 18 2 -7 2 -21 0
|
||||
-30z m-5010 -5 c-3 -7 -5 -2 -5 12 0 14 2 19 5 13 2 -7 2 -19 0 -25z m310 0
|
||||
c-3 -7 -5 -2 -5 12 0 14 2 19 5 13 2 -7 2 -19 0 -25z m1700 0 c-3 -7 -5 -2 -5
|
||||
12 0 14 2 19 5 13 2 -7 2 -19 0 -25z m680 0 c-3 -7 -5 -2 -5 12 0 14 2 19 5
|
||||
13 2 -7 2 -19 0 -25z m310 0 c-3 -7 -5 -2 -5 12 0 14 2 19 5 13 2 -7 2 -19 0
|
||||
-25z m1700 0 c-3 -7 -5 -2 -5 12 0 14 2 19 5 13 2 -7 2 -19 0 -25z m-2380 0
|
||||
c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m-2000 -40 c-3 -8 -6 -5
|
||||
-6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m1680 0 c-3 -8 -6 -5 -6 6 -1 11 2 17
|
||||
5 13 3 -3 4 -12 1 -19z m1010 0 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12
|
||||
1 -19z m1680 0 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m-4680
|
||||
-20 c-3 -7 -5 -2 -5 12 0 14 2 19 5 13 2 -7 2 -19 0 -25z m2300 0 c-3 -7 -5
|
||||
-2 -5 12 0 14 2 19 5 13 2 -7 2 -19 0 -25z m390 0 c-3 -7 -5 -2 -5 12 0 14 2
|
||||
19 5 13 2 -7 2 -19 0 -25z m2300 0 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4
|
||||
-12 1 -19z m-4980 -40 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z
|
||||
m2280 0 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m410 0 c-3 -8
|
||||
-6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m2280 0 c-3 -8 -6 -5 -6 6 -1
|
||||
11 2 17 5 13 3 -3 4 -12 1 -19z m-4960 -40 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13
|
||||
3 -3 4 -12 1 -19z m2260 0 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1
|
||||
-19z m430 0 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m2260 0 c-3
|
||||
-8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m-4593 -65 c9 -18 14 -33 12
|
||||
-33 -6 0 -36 55 -36 66 0 11 5 3 24 -33z m1557 14 c-10 -9 -11 -8 -5 6 3 10 9
|
||||
15 12 12 3 -3 0 -11 -7 -18z m1128 -7 c11 -24 11 -24 -3 -6 -9 11 -16 24 -16
|
||||
30 0 12 5 7 19 -24z m1556 -9 c-21 -43 -29 -39 -8 4 9 19 18 33 21 31 2 -2 -4
|
||||
-18 -13 -35z m-2704 -24 c-10 -9 -11 -8 -5 6 3 10 9 15 12 12 3 -3 0 -11 -7
|
||||
-18z m839 -22 c0 -5 -5 -3 -10 5 -5 8 -10 20 -10 25 0 6 5 3 10 -5 5 -8 10
|
||||
-19 10 -25z m334 9 c3 -8 2 -12 -4 -9 -6 3 -10 10 -10 16 0 14 7 11 14 -7z
|
||||
m-3004 -59 c0 -5 -5 -3 -10 5 -5 8 -10 20 -10 25 0 6 5 3 10 -5 5 -8 10 -19
|
||||
10 -25z m1800 16 c-5 -11 -15 -23 -21 -27 -6 -3 -3 5 6 20 20 30 30 35 15 7z
|
||||
m336 -18 c-8 -15 -15 -25 -16 -21 0 12 23 58 27 54 3 -2 -2 -17 -11 -33z m563
|
||||
-18 c0 -5 -6 1 -14 15 -8 14 -14 30 -14 35 0 6 6 -1 14 -15 8 -14 14 -29 14
|
||||
-35z m2132 28 c-12 -20 -14 -14 -5 12 4 9 9 14 11 11 3 -2 0 -13 -6 -23z
|
||||
m-4450 -50 c13 -16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z m1389
|
||||
13 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m1309 -30
|
||||
c-3 -3 -11 5 -18 17 -13 21 -12 21 5 5 10 -10 16 -20 13 -22z m1381 30 c0 -2
|
||||
-8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m-2347 -21 c-3 -9 -8
|
||||
-14 -10 -11 -3 3 -2 9 2 15 9 16 15 13 8 -4z m2690 0 c-3 -9 -8 -14 -10 -11
|
||||
-3 3 -2 9 2 15 9 16 15 13 8 -4z m-3063 -18 c0 -1 -28 -29 -62 -62 l-63 -60
|
||||
60 63 c55 58 65 67 65 59z m2690 0 c0 -1 -28 -29 -62 -62 l-63 -60 60 63 c55
|
||||
58 65 67 65 59z m-4380 -27 c6 -11 8 -20 6 -20 -3 0 -10 9 -16 20 -6 11 -8 20
|
||||
-6 20 3 0 10 -9 16 -20z m410 -35 c30 -30 52 -55 49 -55 -2 0 -29 25 -59 55
|
||||
-30 30 -52 55 -49 55 2 0 29 -25 59 -55z m1630 35 c-6 -11 -13 -20 -16 -20 -2
|
||||
0 0 9 6 20 6 11 13 20 16 20 2 0 0 -9 -6 -20z m650 0 c6 -11 8 -20 6 -20 -3 0
|
||||
-10 9 -16 20 -6 11 -8 20 -6 20 3 0 10 -9 16 -20z m500 -119 c8 -8 -3 -1 -25
|
||||
16 -22 17 -60 53 -85 79 -34 37 -29 34 25 -16 39 -35 77 -70 85 -79z m1540
|
||||
119 c-6 -11 -13 -20 -16 -20 -2 0 0 9 6 20 6 11 13 20 16 20 2 0 0 -9 -6 -20z
|
||||
m-4685 -72 c16 -24 22 -38 14 -31 -15 12 -53 73 -46 73 2 0 17 -19 32 -42z
|
||||
m1958 11 c-10 -17 -24 -36 -32 -42 -8 -7 -2 7 14 31 32 49 45 57 18 11z m717
|
||||
11 c6 -11 8 -20 6 -20 -3 0 -10 9 -16 20 -6 11 -8 20 -6 20 3 0 10 -9 16 -20z
|
||||
m1980 0 c-6 -11 -13 -20 -16 -20 -2 0 0 9 6 20 6 11 13 20 16 20 2 0 0 -9 -6
|
||||
-20z m-1949 -47 c13 -16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z
|
||||
m1929 13 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z
|
||||
m-4185 -26 c10 -11 16 -20 13 -20 -3 0 -13 9 -23 20 -10 11 -16 20 -13 20 3 0
|
||||
13 -9 23 -20z m1065 16 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21
|
||||
21 21 13z m2690 0 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21
|
||||
13z m-4159 -43 c13 -16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z
|
||||
m1429 13 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m412
|
||||
-33 c-16 -21 -40 -47 -53 -58 -13 -11 -1 6 26 38 55 64 73 77 27 20z m2278 33
|
||||
c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m440 0 c0 -2
|
||||
-8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m-4060 -52 c0 -2 -9
|
||||
0 -20 6 -11 6 -20 13 -20 16 0 2 9 0 20 -6 11 -6 20 -13 20 -16z m890 21 c0
|
||||
-2 -10 -9 -22 -15 -22 -11 -22 -10 -4 4 21 17 26 19 26 11z m1345 -35 l30 -35
|
||||
-32 29 c-18 17 -33 34 -33 40 0 5 1 7 3 5 1 -2 16 -20 32 -39z m455 14 c0 -2
|
||||
-9 0 -20 6 -11 6 -20 13 -20 16 0 2 9 0 20 -6 11 -6 20 -13 20 -16z m890 21
|
||||
c0 -2 -10 -9 -22 -15 -22 -11 -22 -10 -4 4 21 17 26 19 26 11z m-4040 -30 c13
|
||||
-14 21 -25 18 -25 -2 0 -15 11 -28 25 -13 14 -21 25 -18 25 2 0 15 -11 28 -25z
|
||||
m4490 22 c0 -2 -17 -19 -37 -38 l-38 -34 34 38 c33 34 41 42 41 34z m-3875
|
||||
-77 c13 -6 15 -9 5 -9 -8 0 -22 4 -30 9 -18 12 -2 12 25 0z m565 0 c-8 -5 -19
|
||||
-10 -25 -10 -5 0 -3 5 5 10 8 5 20 10 25 10 6 0 3 -5 -5 -10z m2647 -16 c-3
|
||||
-3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m-3130 -10 c-3 -3 -12 -4
|
||||
-19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m400 0 c-3 -3 -12 -4 -19 -1 -8 3 -5
|
||||
6 6 6 11 1 17 -2 13 -5z m2290 0 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17
|
||||
-2 13 -5z m400 0 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z
|
||||
m-3597 -102 c0 -7 -74 55 -95 79 -11 13 6 1 38 -26 31 -27 57 -51 57 -53z
|
||||
m557 92 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m300 0 c-3 -3
|
||||
-12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m2390 0 c-3 -3 -12 -4 -19 -1
|
||||
-8 3 -5 6 6 6 11 1 17 -2 13 -5z m300 0 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6
|
||||
11 1 17 -2 13 -5z m-2879 -11 c-16 -2 -40 -2 -55 0 -16 2 -3 4 27 4 30 0 43
|
||||
-2 28 -4z m110 0 c-16 -2 -40 -2 -55 0 -16 2 -3 4 27 4 30 0 43 -2 28 -4z
|
||||
m702 -8 c-7 -9 -32 -30 -54 -47 -35 -26 -34 -24 9 15 52 48 67 58 45 32z
|
||||
m1146 -17 l29 -33 -32 29 c-31 28 -38 36 -30 36 2 0 16 -15 33 -32z m732 25
|
||||
c-16 -2 -40 -2 -55 0 -16 2 -3 4 27 4 30 0 43 -2 28 -4z m105 0 c-13 -2 -35
|
||||
-2 -50 0 -16 2 -5 4 22 4 28 0 40 -2 28 -4z m717 4 c0 -2 -15 -16 -32 -33
|
||||
l-33 -29 29 33 c28 30 36 37 36 29z m-1460 -103 c0 -3 -13 4 -30 16 -16 12
|
||||
-30 24 -30 26 0 3 14 -4 30 -16 17 -12 30 -24 30 -26z m1390 42 c0 -2 -8 -10
|
||||
-17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m-4050 -63 c0 -7 -39 17 -46
|
||||
28 -3 6 5 3 20 -6 14 -10 26 -19 26 -22z m50 -29 c0 -2 -9 0 -20 6 -11 6 -20
|
||||
13 -20 16 0 2 9 0 20 -6 11 -6 20 -13 20 -16z m96 -52 c-5 -4 -86 36 -86 43 0
|
||||
3 20 -5 45 -17 24 -12 43 -23 41 -26z m1064 43 c0 -6 -97 -55 -107 -55 -4 1
|
||||
17 14 47 30 61 32 60 32 60 25z m1626 -43 c-5 -4 -86 36 -86 43 0 3 20 -5 45
|
||||
-17 24 -12 43 -23 41 -26z m1064 43 c0 -6 -76 -45 -87 -45 -4 1 12 12 37 25
|
||||
50 27 50 27 50 20z m-1000 -65 c8 -5 11 -10 5 -10 -5 0 -17 5 -25 10 -8 5 -10
|
||||
10 -5 10 6 0 17 -5 25 -10z m-2553 -46 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11
|
||||
1 17 -2 13 -5z m600 0 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z
|
||||
m2090 0 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m600 0 c-3 -3
|
||||
-12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m-3250 -10 c-3 -3 -12 -4 -19
|
||||
-1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m520 0 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6
|
||||
6 11 1 17 -2 13 -5z m2170 0 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2
|
||||
13 -5z m520 0 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m-3160
|
||||
-10 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m420 0 c-3 -3 -12
|
||||
-4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m2276 -1 c-7 -2 -19 -2 -25 0 -7 3
|
||||
-2 5 12 5 14 0 19 -2 13 -5z m410 0 c-7 -2 -19 -2 -25 0 -7 3 -2 5 12 5 14 0
|
||||
19 -2 13 -5z m-3040 -10 c-7 -2 -19 -2 -25 0 -7 3 -2 5 12 5 14 0 19 -2 13 -5z
|
||||
m290 0 c-7 -2 -19 -2 -25 0 -7 3 -2 5 12 5 14 0 19 -2 13 -5z m2400 0 c-7 -2
|
||||
-19 -2 -25 0 -7 3 -2 5 12 5 14 0 19 -2 13 -5z m290 0 c-7 -2 -19 -2 -25 0 -7
|
||||
3 -2 5 12 5 14 0 19 -2 13 -5z m-2805 -10 c-21 -2 -57 -2 -80 0 -24 2 -7 4 37
|
||||
4 44 0 63 -2 43 -4z m2690 0 c-21 -2 -57 -2 -80 0 -24 2 -7 4 37 4 44 0 63 -2
|
||||
43 -4z"/>
|
||||
</g>
|
||||
</svg>
|
Przed Szerokość: | Wysokość: | Rozmiar: 32 KiB |
|
@ -13,6 +13,7 @@
|
|||
<!-- Content -->
|
||||
<section class="main">
|
||||
<div class="content {% block coltype %}colM{% endblock %}">
|
||||
{{ SETTINGS.theme.html_after_header|safe }}
|
||||
{% block breadcrumbs %}
|
||||
<div class="breadcrumbs">
|
||||
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
|
||||
|
|
|
@ -1,21 +1,14 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
{% load i18n static %}
|
||||
{% load i18n static settings compress %}
|
||||
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="description" content="Web OpenDroneMap. Open Source Aerial Imagery Processing Platform">
|
||||
<meta name="author" content="">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/static/app/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" href="/static/app/favicon-32x32.png" sizes="32x32">
|
||||
<link rel="icon" type="image/png" href="/static/app/favicon-16x16.png" sizes="16x16">
|
||||
<link rel="manifest" href="/static/app/manifest.json">
|
||||
<link rel="mask-icon" href="/static/app/safari-pinned-tab.svg" color="#5bbad5">
|
||||
<link rel="shortcut icon" href="/static/app/favicon.ico">
|
||||
<meta name="msapplication-config" content="/static/app/browserconfig.xml">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<meta name="author" content="WebODM Contributors">
|
||||
<link rel="icon" type="image/png" href="{% settings_image_url 'app_logo_favicon' %}" sizes="32x32">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'app/css/bootstrap.min.css' %}" />
|
||||
|
||||
<link href="{% static 'app/css/font-awesome.min.css' %}" rel="stylesheet" type="text/css">
|
||||
|
@ -29,7 +22,15 @@
|
|||
{% load render_bundle from webpack_loader %}
|
||||
{% render_bundle 'main' %}
|
||||
|
||||
<title>{{title|default:"Login"}} - WebODM</title>
|
||||
<title>{{title|default:"Login"}} - {{ SETTINGS.app_name }}</title>
|
||||
|
||||
{% compress css %}
|
||||
<link rel="stylesheet" type="text/x-scss" href="{% static 'app/css/theme.scss' %}" />
|
||||
{% endcompress %}
|
||||
|
||||
<style type="text/css">
|
||||
{{ SETTINGS.theme.css|safe }}
|
||||
</style>
|
||||
</head>
|
||||
<body data-admin-utc-offset="{% now "Z" %}">
|
||||
<!--[if lt IE 8]>
|
||||
|
@ -53,6 +54,8 @@
|
|||
</ul>
|
||||
-->
|
||||
<div id="wrapper">
|
||||
{{ SETTINGS.theme.html_before_header|safe }}
|
||||
|
||||
<nav id="navbar-top" class="navbar navbar-default navbar-static-top" role="navigation" style="margin-bottom: 0">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
||||
|
@ -62,15 +65,19 @@
|
|||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
{% block navbar-top-links %}{% endblock %}
|
||||
<a class="navbar-brand" href="/"><img src="{% static 'app/img/logo36.png' %}" alt="WebODM" /></a>
|
||||
<a class="navbar-link" href="/"><p class="navbar-text">WebODM</a></p>
|
||||
<a class="navbar-brand" href="/"><img src="{% settings_image_url 'app_logo_36' %}" alt="{{ SETTINGS.app_name }}" /></a>
|
||||
<a class="navbar-link" href="/"><p class="navbar-text">{{ SETTINGS.app_name }}</a></p>
|
||||
</div>
|
||||
|
||||
{% block navbar-sidebar %}{% endblock %}
|
||||
</nav>
|
||||
|
||||
{% block page-wrapper %}{% endblock %}
|
||||
|
||||
{% block page-wrapper %}{{ SETTINGS.theme.html_after_header|safe }}{% endblock %}
|
||||
</div>
|
||||
|
||||
{% autoescape off %}
|
||||
{% get_footer %}
|
||||
{% endautoescape %}
|
||||
</body>
|
||||
<script src="{% static 'app/js/vendor/metisMenu.min.js' %}"></script>
|
||||
<script>
|
||||
|
@ -111,4 +118,5 @@ $(function(){
|
|||
|
||||
</script>
|
||||
<script src="{% static 'app/js/vendor/bootstrap.min.js' %}"></script>
|
||||
{{ SETTINGS.theme.html_after_body|safe }}
|
||||
</html>
|
|
@ -1,22 +1,7 @@
|
|||
{% extends "app/base.html" %}
|
||||
{% load i18n static %}
|
||||
|
||||
<!--{% if request.user.is_authenticated %}
|
||||
{% if user.is_superuser %}
|
||||
<li>
|
||||
<a class="page-scroll" href="/admin/">Admin Panel</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li>
|
||||
<a class="page-scroll" href="/logout/">Logout</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li>
|
||||
<a class="page-scroll" href="/login/">Login</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
-->
|
||||
|
||||
{% block navbar-top-links %}
|
||||
<ul class="nav navbar-top-links navbar-right">
|
||||
<!--<li class="dropdown">
|
||||
|
@ -278,6 +263,20 @@
|
|||
<li>
|
||||
<a href="http://docs.webodm.org" target="_blank"><i class="fa fa-life-saver fa-fw"></i> {% trans 'Documentation' %}</a>
|
||||
</li>
|
||||
|
||||
{% if user.is_staff %}
|
||||
<li>
|
||||
<a href="#"><i class="fa fa-magic fa-fw"></i> {% trans 'Customize' %}<span class="fa arrow"></span></a>
|
||||
<ul class="nav nav-second-level">
|
||||
<li>
|
||||
<a href="{% url 'admin:app_setting_change' SETTINGS.id %}"><i class="fa fa-hand-o-right"></i> {% trans 'Brand' %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{% url 'admin:app_theme_change' SETTINGS.theme.id %}"><i class="fa fa-paint-brush"></i> {% trans 'Theme' %}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
<!-- /.sidebar-collapse -->
|
||||
|
@ -290,6 +289,8 @@
|
|||
<div id="page-wrapper">
|
||||
<section class="main">
|
||||
<div class="content">
|
||||
{{ SETTINGS.theme.html_after_header|safe }}
|
||||
|
||||
{% block messages %}
|
||||
{% for message in messages %}
|
||||
<div class="alert alert-{{ message.tags }} alert-dismissible">
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
{% include 'registration/form_field.html' %}
|
||||
{% endfor %}
|
||||
<div class="actions">
|
||||
<input type="submit" class="btn primary" value="{% trans 'Change My Password' %}">
|
||||
<input type="submit" class="btn btn-primary" value="{% trans 'Change My Password' %}">
|
||||
</div>
|
||||
</form>
|
||||
{% else %}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
{% endfor %}
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-2 col-sm-10">
|
||||
<button id='submit' class="btn primary" type="submit" data-loading-text="{% trans 'loading' %}..." accesskey="Enter">{% trans 'Reset My Password' %}</button>
|
||||
<button id='submit' class="btn btn-primary" type="submit" data-loading-text="{% trans 'loading' %}..." accesskey="Enter">{% trans 'Reset My Password' %}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -1,6 +1,14 @@
|
|||
{% extends 'base.html' %}
|
||||
|
||||
{% block page-wrapper %}
|
||||
<style type="text/css">
|
||||
footer{
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
</style>
|
||||
<section class="main">
|
||||
<div class="content">
|
||||
{% block registration_header %}{% endblock %}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
import datetime
|
||||
|
||||
from django import template
|
||||
|
||||
register = template.Library()
|
||||
|
||||
|
||||
@register.assignment_tag(takes_context=True)
|
||||
def settings_image_url(context, image):
|
||||
return "/media/" + getattr(context['SETTINGS'], image).url
|
||||
|
||||
|
||||
@register.simple_tag(takes_context=True)
|
||||
def get_footer(context):
|
||||
settings = context['SETTINGS']
|
||||
if settings.theme.html_footer == "": return ""
|
||||
|
||||
organization = ""
|
||||
if settings.organization_name != "" and settings.organization_website != "":
|
||||
organization = "<a href='{}'>{}</a>".format(settings.organization_website, settings.organization_name)
|
||||
elif settings.organization_name != "":
|
||||
organization = settings.organization_name
|
||||
|
||||
footer = settings.theme.html_footer
|
||||
footer = footer.replace("{ORGANIZATION}", organization)
|
||||
footer = footer.replace("{YEAR}", str(datetime.datetime.now().year))
|
||||
|
||||
return "<footer>" + \
|
||||
footer + \
|
||||
"</footer>"
|
|
@ -1,10 +1,14 @@
|
|||
import os
|
||||
|
||||
from django import db
|
||||
from django.contrib.auth.models import User
|
||||
from django.test import TestCase
|
||||
from django.test import TransactionTestCase
|
||||
from shutil import rmtree
|
||||
|
||||
from app.boot import boot
|
||||
from app.models import Project
|
||||
from webodm import settings
|
||||
|
||||
|
||||
def setupUsers():
|
||||
|
@ -36,6 +40,15 @@ def setupProjects():
|
|||
description="This is a test project"
|
||||
)
|
||||
|
||||
|
||||
def cleanup():
|
||||
if settings.TESTING and \
|
||||
os.path.exists(settings.MEDIA_ROOT) and \
|
||||
"_test" in settings.MEDIA_ROOT[-6:]:
|
||||
rmtree(settings.MEDIA_ROOT)
|
||||
print("Cleaned " + settings.MEDIA_ROOT)
|
||||
|
||||
|
||||
class BootTestCase(TestCase):
|
||||
'''
|
||||
This class provides optional default mock data as well as
|
||||
|
@ -48,6 +61,7 @@ class BootTestCase(TestCase):
|
|||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
super(BootTestCase, cls).setUpTestData()
|
||||
cleanup()
|
||||
boot()
|
||||
setupUsers()
|
||||
setupProjects()
|
||||
|
@ -63,6 +77,7 @@ class BootTransactionTestCase(TransactionTestCase):
|
|||
'''
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
cleanup()
|
||||
boot()
|
||||
setupUsers()
|
||||
setupProjects()
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
import os
|
||||
import time
|
||||
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.core.files import File
|
||||
from django.test import Client
|
||||
|
||||
from app.contexts.settings import load as load_settings
|
||||
from app.models import Setting
|
||||
from app.models import Theme
|
||||
from webodm import settings as webodm_settings
|
||||
from .classes import BootTestCase
|
||||
|
||||
class TestSettings(BootTestCase):
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def test_settings(self):
|
||||
c = Client()
|
||||
|
||||
# There should always be a Setting object
|
||||
self.assertTrue(Setting.objects.count() == 1, "There's a settings object")
|
||||
|
||||
# There should be "default" Theme object
|
||||
self.assertTrue(Theme.objects.filter(name="Default").count() == 1, "Default theme found")
|
||||
|
||||
# The default settings use the default theme
|
||||
self.assertTrue(Setting.objects.first().theme.id == Theme.objects.get(name="Default").id, "Default theme is associated to settings")
|
||||
|
||||
# We can create a new theme object
|
||||
second_theme = Theme.objects.create(name="Second")
|
||||
|
||||
# We cannot add another setting objects
|
||||
with self.assertRaises(ValidationError):
|
||||
Setting.objects.create(app_name="Test", theme=second_theme)
|
||||
|
||||
# We can retrieve the settings
|
||||
settings = load_settings()['SETTINGS']
|
||||
self.assertTrue(settings is not None, "Can retrieve settings")
|
||||
|
||||
# The default logo has been created in the proper destination
|
||||
default_logo_path = os.path.join(webodm_settings.MEDIA_ROOT, settings.app_logo.name)
|
||||
self.assertTrue(os.path.exists(default_logo_path), "Default logo exists in MEDIA_ROOT/settings")
|
||||
|
||||
# We can update the logo
|
||||
logo = os.path.join('app', 'static', 'app', 'img', 'favicon.png')
|
||||
settings.app_logo.save(os.path.basename(logo), File(open(logo, 'rb')))
|
||||
settings.save()
|
||||
|
||||
# The main logo has been uploaded
|
||||
self.assertTrue("favicon" in settings.app_logo.name, "Logo has been updated")
|
||||
self.assertTrue(os.path.exists(os.path.join(webodm_settings.MEDIA_ROOT, settings.app_logo.name)),
|
||||
"New logo exists in MEDIA_ROOT/settings")
|
||||
|
||||
# The old logo does not exist anymore
|
||||
self.assertFalse(os.path.exists(default_logo_path),
|
||||
"Old logo has been deleted")
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
import os
|
||||
import re
|
||||
|
||||
from django.contrib.staticfiles import finders
|
||||
from django.test import Client
|
||||
|
||||
from .classes import BootTestCase
|
||||
from app.contexts.settings import load as load_settings
|
||||
|
||||
class TestSettings(BootTestCase):
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def test_settings(self):
|
||||
c = Client()
|
||||
c.login(username="testuser", password="test1234")
|
||||
|
||||
# Get a page
|
||||
res = c.get('/dashboard/', follow=True)
|
||||
body = res.content.decode("utf-8")
|
||||
|
||||
# There shouldn't be a footer by default
|
||||
self.assertFalse("<footer>" in body)
|
||||
|
||||
# Find the theme.scss file
|
||||
matches = re.search(r'/static/(CACHE/css/theme\.[\w\d]+\.css)', body)
|
||||
self.assertTrue(matches is not None, "Found theme.css")
|
||||
|
||||
# We can find it in the file system
|
||||
css_file = finders.find(matches.group(1))
|
||||
self.assertTrue(os.path.exists(css_file), "theme.css exists in file system")
|
||||
|
||||
css_content = ""
|
||||
with open(css_file, "r") as f:
|
||||
css_content = f.read()
|
||||
|
||||
# A strong purple color is not part of the default theme
|
||||
purple = "8400ff"
|
||||
self.assertFalse(purple in css_content)
|
||||
|
||||
# But colors from the theme are
|
||||
theme = load_settings()["SETTINGS"].theme
|
||||
self.assertTrue(theme.primary in css_content)
|
||||
|
||||
# Let's change the theme
|
||||
theme.primary = purple # add color
|
||||
theme.html_footer = "<p>hello</p>"
|
||||
theme.save()
|
||||
|
||||
# A new cache file should have been created for the CSS
|
||||
|
||||
# Get a page
|
||||
res = c.get('/dashboard/', follow=True)
|
||||
body = res.content.decode("utf-8")
|
||||
|
||||
# We now have a footer
|
||||
self.assertTrue("<footer><p>hello</p></footer>" in body)
|
||||
|
||||
# Find the theme.scss file
|
||||
matches = re.search(r'/static/(CACHE/css/theme\.[\w\d]+\.css)', body)
|
||||
self.assertTrue(matches is not None, "Found theme.css")
|
||||
|
||||
new_css_file = finders.find(matches.group(1))
|
||||
self.assertTrue(os.path.exists(new_css_file), "new theme.css exists in file system")
|
||||
|
||||
# It's not the same file
|
||||
self.assertTrue(new_css_file != css_file, "It's a new file")
|
||||
|
||||
# Purple color is in there
|
||||
css_content = ""
|
||||
with open(new_css_file, "r") as f:
|
||||
css_content = f.read()
|
||||
|
||||
self.assertTrue(purple in css_content)
|
||||
|
||||
|
||||
|
|
@ -44,6 +44,14 @@ http {
|
|||
root /webodm/build;
|
||||
}
|
||||
|
||||
# path for certain media files that don't need permissions enforced
|
||||
location /media/CACHE {
|
||||
root /webodm/app/media/CACHE;
|
||||
}
|
||||
location /media/settings {
|
||||
root /webodm/app/media/settings;
|
||||
}
|
||||
|
||||
location / {
|
||||
# CORS settings
|
||||
|
||||
|
|
|
@ -3,10 +3,16 @@ appdirs==1.4.0
|
|||
APScheduler==3.2.0
|
||||
coreapi==2.0.9
|
||||
Django==1.11.1
|
||||
django-appconf==1.0.2
|
||||
django-codemirror2==0.2
|
||||
django-colorfield==0.1.14
|
||||
django-compressor==2.2
|
||||
django-cors-headers==2.0.2
|
||||
django-debug-toolbar==1.6
|
||||
django-filter==1.0.4
|
||||
django-guardian==1.4.6
|
||||
django-imagekit==4.0.1
|
||||
django-libsass==0.7
|
||||
django-webpack-loader==0.3.3
|
||||
djangorestframework==3.6.3
|
||||
djangorestframework-jwt==1.9.0
|
||||
|
@ -15,17 +21,21 @@ funcsigs==1.0.2
|
|||
futures==3.0.5
|
||||
gunicorn==19.7.1
|
||||
itypes==1.1.0
|
||||
libsass==0.13.3
|
||||
Markdown==2.6.7
|
||||
openapi-codec==1.1.7
|
||||
packaging==16.8
|
||||
pilkit==2.0
|
||||
Pillow==3.3.1
|
||||
pip-autoremove==0.9.0
|
||||
psycopg2==2.6.2
|
||||
PyJWT==1.4.2
|
||||
pyparsing==2.1.10
|
||||
pytz==2017.2
|
||||
rcssmin==1.0.6
|
||||
requests==2.11.1
|
||||
rfc3987==1.3.7
|
||||
rjsmin==1.0.12
|
||||
simplejson==3.10.0
|
||||
six==1.10.0
|
||||
sqlparse==0.2.2
|
||||
|
|
|
@ -69,6 +69,10 @@ INSTALLED_APPS = [
|
|||
'rest_framework_nested',
|
||||
'webpack_loader',
|
||||
'corsheaders',
|
||||
'colorfield',
|
||||
'imagekit',
|
||||
'codemirror2',
|
||||
'compressor',
|
||||
# 'debug_toolbar',
|
||||
'app',
|
||||
'nodeodm',
|
||||
|
@ -103,6 +107,7 @@ TEMPLATES = [
|
|||
'django.template.context_processors.request',
|
||||
'django.contrib.auth.context_processors.auth',
|
||||
'django.contrib.messages.context_processors.messages',
|
||||
'app.contexts.settings.load',
|
||||
],
|
||||
},
|
||||
},
|
||||
|
@ -168,6 +173,11 @@ STATIC_ROOT = os.path.join(BASE_DIR, 'build', 'static')
|
|||
STATICFILES_DIRS = [
|
||||
os.path.join(BASE_DIR, 'app', 'static'),
|
||||
]
|
||||
STATICFILES_FINDERS = [
|
||||
'django.contrib.staticfiles.finders.FileSystemFinder',
|
||||
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
|
||||
'compressor.finders.CompressorFinder',
|
||||
]
|
||||
|
||||
# File Uploads
|
||||
FILE_UPLOAD_MAX_MEMORY_SIZE = 4718592 # 4.5 MB
|
||||
|
@ -270,6 +280,39 @@ JWT_AUTH = {
|
|||
'JWT_EXPIRATION_DELTA': datetime.timedelta(hours=6),
|
||||
}
|
||||
|
||||
# Compressor
|
||||
COMPRESS_PRECOMPILERS = (
|
||||
('text/x-scss', 'django_libsass.SassCompiler'),
|
||||
)
|
||||
|
||||
# Sass
|
||||
def theme(color):
|
||||
from app.contexts.settings import theme as f
|
||||
return f(color)
|
||||
|
||||
|
||||
def complementary(color):
|
||||
from app.contexts.settings import complementary as f
|
||||
return f(color)
|
||||
|
||||
|
||||
def scaleby(color, n):
|
||||
from app.contexts.settings import scaleby as f
|
||||
return f(color, n)
|
||||
|
||||
|
||||
def scalebyiv(color, n):
|
||||
from app.contexts.settings import scaleby as f
|
||||
return f(color, n, True)
|
||||
|
||||
|
||||
LIBSASS_CUSTOM_FUNCTIONS = {
|
||||
'theme': theme,
|
||||
'complementary': complementary,
|
||||
'scaleby': scaleby,
|
||||
'scalebyiv': scalebyiv
|
||||
}
|
||||
|
||||
if TESTING:
|
||||
MEDIA_ROOT = os.path.join(BASE_DIR, 'app', 'media_test')
|
||||
|
||||
|
|
|
@ -13,9 +13,12 @@ Including another URLconf
|
|||
1. Import the include() function: from django.conf.urls import url, include
|
||||
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
|
||||
"""
|
||||
import os
|
||||
|
||||
from django.conf.urls import include, url
|
||||
from django.contrib import admin
|
||||
from . import settings
|
||||
from django.views.static import serve
|
||||
|
||||
admin.site.site_header = 'WebODM Administration'
|
||||
|
||||
|
@ -29,7 +32,17 @@ if settings.DEBUG:
|
|||
import debug_toolbar
|
||||
urlpatterns += [
|
||||
url(r'^__debug__/', include(debug_toolbar.urls)),
|
||||
|
||||
# Expose imagekit generated files and settings file uploads
|
||||
url(r'^media/CACHE/(?P<path>.*)$', serve, {
|
||||
'document_root': os.path.join(settings.MEDIA_ROOT, 'CACHE')
|
||||
}),
|
||||
url(r'^media/settings/(?P<path>.*)$', serve, {
|
||||
'document_root': os.path.join(settings.MEDIA_ROOT, 'settings')
|
||||
}),
|
||||
|
||||
]
|
||||
|
||||
|
||||
#from django.contrib.staticfiles.urls import staticfiles_urlpatterns
|
||||
#urlpatterns += staticfiles_urlpatterns()
|
||||
#urlpatterns += staticfiles_urlpatterns()
|
||||
|
|