Compare commits

...

65 changed files with 42654 additions and 2301 deletions
Unified View
  1. +12
    -1
      README.txt
  2. +0
    -1
      development.ini
  3. +22
    -15
      jm2l/ExtWtforms.py
  4. +86
    -84
      jm2l/__init__.py
  5. +4
    -2
      jm2l/auth.py
  6. +161
    -148
      jm2l/badge.py
  7. +54
    -49
      jm2l/captcha.py
  8. +1
    -1
      jm2l/const.py
  9. +427
    -356
      jm2l/forms.py
  10. +72
    -64
      jm2l/helpers.py
  11. +392
    -365
      jm2l/models.py
  12. +12
    -13
      jm2l/scripts/initializedb.py
  13. +1
    -0
      jm2l/security.py
  14. BIN
      jm2l/static/favicon.ico
  15. +10
    -0
      on_final.svg
  16. +33453
    -0
      jm2l/static/img/2020/Artic_North_Pole_Scene_and_Action_View2.svg
  17. BIN
      jm2l/static/img/2020/Digital-Marketing.jpg
  18. +58
    -0
      jm2l/static/img/2020/Gamepad-White.svg
  19. +812
    -0
      jm2l/static/img/2020/Hair-Tools-And-Accessories-Silhouette.svg
  20. BIN
      jm2l/static/img/2020/Handicap-Symbol-300x300.jpg
  21. BIN
      jm2l/static/img/2020/Spaceport_2006.otf
  22. BIN
      jm2l/static/img/2020/Web-Marketing.jpg
  23. +1863
    -0
      jm2l/static/img/2020/bandeau_2020.svg
  24. +1864
    -0
      jm2l/static/img/2020/bandeau_2020.svg.2020_08_10_10_04_17.0.svg
  25. +1751
    -0
      jm2l/static/img/2020/bandeau_2020_v1.svg
  26. BIN
      jm2l/static/img/2020/biens-communs.jpg
  27. +44
    -0
      jm2l/static/img/2020/caddy.svg
  28. +99
    -0
      jm2l/static/img/2020/disabled-man-icon.svg
  29. BIN
      jm2l/static/img/2020/handicap_Bored.png
  30. BIN
      jm2l/static/img/2020/logo.png
  31. BIN
      jm2l/static/img/2020/rdptcoluche.jpg
  32. +1
    -0
      jm2l/static/img/2020/sapins.svg
  33. +120
    -0
      jm2l/static/img/2020/simple-Gear.svg
  34. +60
    -0
      jm2l/static/img/2020/wifil.svg
  35. +1
    -1
      jm2l/templates/Errors/403.mako
  36. +1
    -1
      jm2l/templates/Errors/404.mako
  37. +12
    -12
      jm2l/templates/Interventions/Interventions.mako
  38. +1
    -1
      jm2l/templates/Logistique/Dialog_Covoit.mako
  39. +1
    -1
      jm2l/templates/Logistique/Dialog_Heberg.mako
  40. +2
    -2
      jm2l/templates/Logistique/Dialog_Matos.mako
  41. +17
    -17
      jm2l/templates/Logistique/Logistique.mako
  42. +4
    -4
      jm2l/templates/Logistique/Tables.mako
  43. +1
    -1
      jm2l/templates/NewIndex.mako
  44. +4
    -4
      jm2l/templates/Profil/Profil.mako
  45. +13
    -13
      jm2l/templates/Profil/Sejour.mako
  46. +2
    -2
      jm2l/templates/Public/Programme.mako
  47. +2
    -2
      jm2l/templates/Salles/list_phy.mako
  48. +2
    -2
      jm2l/templates/Salles/salle.mako
  49. +1
    -1
      jm2l/templates/Staff/compta.mako
  50. +1
    -1
      jm2l/templates/Staff/list.mako
  51. +5
    -5
      jm2l/templates/edit_event.mako
  52. +17
    -17
      jm2l/templates/helpers.mako
  53. +7
    -7
      jm2l/templates/jm2l.mako
  54. +17
    -33
      jm2l/templates/layout.mako
  55. +3
    -3
      jm2l/templates/mail_html.mako
  56. +3
    -3
      jm2l/templates/mail_plain.mako
  57. +1
    -1
      jm2l/templates/show_user.mako
  58. +2
    -2
      jm2l/templates/view_event.mako
  59. +1
    -1
      jm2l/templates/view_tiers.mako
  60. +1
    -1
      jm2l/templates/view_user.mako
  61. +97
    -97
      jm2l/to_print.py
  62. +180
    -174
      jm2l/upload.py
  63. +862
    -781
      jm2l/views.py
  64. +8
    -3
      setup.py
  65. +6
    -9
      wsgi.py

+ 12
- 1
README.txt View File

@@ -35,4 +35,15 @@ If no error occurs, the webserver should be available on http://localhost:8080/
cd jm2l cd jm2l
pserve development.ini pserve development.ini


Enjoy !
Enjoy !


sudo apt install virtualenv git python3-virtualenv imagemagick

sudo mkdir -p /srv/jm2l
cd /srv/jm2l/
cd /srv
sudo chown luna jm2l
cd jm2l/
virtualenv -p python3 .venv_jm2l


+ 0
- 1
development.ini View File

@@ -15,7 +15,6 @@ pyramid.debug_notfound = false
pyramid.debug_routematch = false pyramid.debug_routematch = false
pyramid.default_locale_name = en pyramid.default_locale_name = en
pyramid.includes = pyramid.includes =
pyramid_mailer.testing
pyramid_debugtoolbar pyramid_debugtoolbar
pyramid_tm pyramid_tm
pyramid_mako pyramid_mako


+ 22
- 15
jm2l/ExtWtforms.py View File

@@ -3,10 +3,12 @@ try:
except ImportError: except ImportError:
from cgi import escape from cgi import escape


#from wtforms import widgets
from wtforms.widgets import HTMLString, html_params
# from wtforms import widgets
from wtforms.widgets import html_params
from wtforms.fields.core import Field from wtforms.fields.core import Field
from wtforms.compat import text_type, izip from wtforms.compat import text_type, izip
from markupsafe import Markup



class MySelect(object): class MySelect(object):
""" """
@@ -19,6 +21,7 @@ class MySelect(object):
call on rendering; this method must yield tuples of call on rendering; this method must yield tuples of
`(value, label, selected)`. `(value, label, selected)`.
""" """

def __init__(self, multiple=False): def __init__(self, multiple=False):
self.multiple = multiple self.multiple = multiple


@@ -34,13 +37,13 @@ class MySelect(object):
elif last_group != group: elif last_group != group:
html.append(self.render_optgroup(last_group, group)) html.append(self.render_optgroup(last_group, group))
html.append(self.render_option(val, label, selected)) html.append(self.render_option(val, label, selected))
last_group=group
last_group = group
else: else:
html.append(self.render_option(val, label, selected)) html.append(self.render_option(val, label, selected))
if last_group: if last_group:
html.append(self.render_optgroup(last_group, None)) html.append(self.render_optgroup(last_group, None))
html.append('</select>') html.append('</select>')
return HTMLString(''.join(html))
return Markup(''.join(html))


@classmethod @classmethod
def render_option(cls, value, label, selected, **kwargs): def render_option(cls, value, label, selected, **kwargs):
@@ -51,17 +54,19 @@ class MySelect(object):
options = dict(kwargs, value=value) options = dict(kwargs, value=value)
if selected: if selected:
options['selected'] = True options['selected'] = True
return HTMLString('<option %s>%s</option>' % (html_params(**options), escape(text_type(label), quote=False)))
return Markup('<option %s>%s</option>' % (html_params(**options), escape(text_type(label), quote=False)))


@classmethod @classmethod
def render_optgroup(cls, previous_label, label, **kwargs): def render_optgroup(cls, previous_label, label, **kwargs):
options = dict(kwargs) options = dict(kwargs)
if previous_label is None: if previous_label is None:
return HTMLString('<optgroup %s label="%s">' % (html_params(**options), escape(text_type(label), quote=False)))
return Markup(
'<optgroup %s label="%s">' % (html_params(**options), escape(text_type(label), quote=False)))
elif label is None: elif label is None:
return HTMLString('</optgroup>')
return Markup('</optgroup>')
else: else:
return HTMLString('</optgroup><optgroup %s label="%s">' % (html_params(**options), escape(text_type(label), quote=False)))
return Markup(
'</optgroup><optgroup %s label="%s">' % (html_params(**options), escape(text_type(label), quote=False)))




class MyOption(object): class MyOption(object):
@@ -71,12 +76,13 @@ class MyOption(object):
This is just a convenience for various custom rendering situations, and an This is just a convenience for various custom rendering situations, and an
option by itself does not constitute an entire field. option by itself does not constitute an entire field.
""" """

def __call__(self, field, **kwargs): def __call__(self, field, **kwargs):
return MySelect.render_option(field._value(), field.label.text, field.checked, **kwargs) return MySelect.render_option(field._value(), field.label.text, field.checked, **kwargs)




class MySelectFieldBase(Field): class MySelectFieldBase(Field):
#option_widget = widgets.Option()
# option_widget = widgets.Option()
option_widget = MyOption() option_widget = MyOption()


""" """
@@ -85,6 +91,7 @@ class MySelectFieldBase(Field):
This isn't a field, but an abstract base class for fields which want to This isn't a field, but an abstract base class for fields which want to
provide this functionality. provide this functionality.
""" """

def __init__(self, label=None, validators=None, option_widget=None, **kwargs): def __init__(self, label=None, validators=None, option_widget=None, **kwargs):
super(MySelectFieldBase, self).__init__(label, validators, **kwargs) super(MySelectFieldBase, self).__init__(label, validators, **kwargs)


@@ -114,7 +121,7 @@ class MySelectFieldBase(Field):




class MySelectField(MySelectFieldBase): class MySelectField(MySelectFieldBase):
#widget = widgets.Select()
# widget = widgets.Select()
widget = MySelect() widget = MySelect()


def __init__(self, label=None, validators=None, coerce=text_type, choices=None, **kwargs): def __init__(self, label=None, validators=None, coerce=text_type, choices=None, **kwargs):
@@ -128,15 +135,15 @@ class MySelectField(MySelectFieldBase):
# We should consider choiceA as an optgroup label # We should consider choiceA as an optgroup label
group_label = choiceA group_label = choiceA
for value, label in choiceB: for value, label in choiceB:
yield (group_label, value, label, self.coerce(value) == self.data)
yield group_label, value, label, self.coerce(value) == self.data
else: else:
value, label = choiceA, choiceB value, label = choiceA, choiceB
# Not an optgroup, let's fallback to classic usage # Not an optgroup, let's fallback to classic usage
yield (None, value, label, self.coerce(value) == self.data)
yield None, value, label, self.coerce(value) == self.data


def process_data(self, value):
def process_data(self, value):
try: try:
self.data = self.coerce(value)
self.data = self.coerce(value)
except (ValueError, TypeError): except (ValueError, TypeError):
self.data = None self.data = None


@@ -149,7 +156,7 @@ class MySelectField(MySelectFieldBase):


def pre_validate(self, form): def pre_validate(self, form):
for choiceA, choiceB in self.choices: for choiceA, choiceB in self.choices:
if isinstance(choiceB, (tuple, list)):
if isinstance(choiceB, (tuple, list)):
for value, label in choiceB: for value, label in choiceB:
if self.data == value: if self.data == value:
break break


+ 86
- 84
jm2l/__init__.py View File

@@ -19,51 +19,53 @@ from pyramid.request import Request
from mako.template import Template from mako.template import Template
from .models import User from .models import User
from jm2l.const import CurrentYear from jm2l.const import CurrentYear
from models import JM2L_Year

from .models import JM2L_Year
import logging import logging



def add_renderer_globals(event): def add_renderer_globals(event):
event['mytrip'] = Sejour_helpers(event) event['mytrip'] = Sejour_helpers(event)
event['myorga'] = Orga_helpers(event) event['myorga'] = Orga_helpers(event)
event['SelectedYear'] = CurrentYear event['SelectedYear'] = CurrentYear
event['CurrentYear'] = CurrentYear event['CurrentYear'] = CurrentYear


#@sched.scheduled_job('cron', day_of_week='sun', hour=22, minute=07)

# @sched.scheduled_job('cron', day_of_week='sun', hour=22, minute=7)
def mailer_tasks(config): def mailer_tasks(config):
# Send the Welcome Mail # Send the Welcome Mail
mailer = config.registry['mailer']
Contact = DBSession.query(User).filter(User.uid==1).one()
contact = DBSession.query(User).filter(User.uid == 1).one()
request = Request.blank('/', base_url='http://jm2l.linux-azur.org') request = Request.blank('/', base_url='http://jm2l.linux-azur.org')
request.registry = config.registry request.registry = config.registry
for StaffUser in DBSession.query(User).filter(User.Staff == True):
mailer = request.mailer
for staff_user in DBSession.query(User).filter(User.Staff is True):
# Skip mail to contact # Skip mail to contact
if StaffUser==Contact:
if staff_user == contact:
continue continue
# Skip those that have no task assigned # Skip those that have no task assigned
if len(filter(lambda k:not k.closed, StaffUser.task_assoc))==0:
if len(filter(lambda k: not k.closed, staff_user.task_assoc)) == 0:
continue continue
# Prepare Plain Text Message : # Prepare Plain Text Message :
Mail_template = Template(filename='jm2l/templates/mail_plain.mako')
mail_plain = Mail_template.render(request=request, User=StaffUser, Contact=Contact, action="Tasks")
mail_template = Template(filename='jm2l/templates/mail_plain.mako')
mail_plain = mail_template.render(request=request, User=staff_user, Contact=contact, action="Tasks")
# Prepare HTML Message : # Prepare HTML Message :
Mail_template = Template(filename='jm2l/templates/mail_html.mako')
mail_html = Mail_template.render(request=request, User=StaffUser, Contact=Contact, action="Tasks")
mail_template = Template(filename='jm2l/templates/mail_html.mako')
mail_html = mail_template.render(request=request, User=staff_user, Contact=contact, action="Tasks")
# Prepare Message # Prepare Message
message = Message(subject="[JM2L] Le mail de rappel pour les JM2L !", message = Message(subject="[JM2L] Le mail de rappel pour les JM2L !",
sender="contact@jm2l.linux-azur.org", sender="contact@jm2l.linux-azur.org",
recipients=[StaffUser.mail],
recipients=[staff_user.mail],
body=mail_plain, html=mail_html) body=mail_plain, html=mail_html)
message.add_bcc("spam@style-python.fr") message.add_bcc("spam@style-python.fr")
mailer.send_immediately(message) mailer.send_immediately(message)



def main(global_config, **settings): def main(global_config, **settings):
""" This function returns a Pyramid WSGI application. """ This function returns a Pyramid WSGI application.
""" """
#locale.setlocale(locale.LC_ALL, "fr_FR.UTF-8")
# locale.setlocale(locale.LC_ALL, "fr_FR.UTF-8")
locale.setlocale(locale.LC_ALL, "fr_FR.utf8") locale.setlocale(locale.LC_ALL, "fr_FR.utf8")
engine = engine_from_config(settings, 'sqlalchemy.') engine = engine_from_config(settings, 'sqlalchemy.')
DBSession.configure(bind=engine) DBSession.configure(bind=engine)
@@ -72,19 +74,21 @@ def main(global_config, **settings):
AuthTktPasswd = settings.get('secret_AuthTkt', 'itsthesecondseekreet') AuthTktPasswd = settings.get('secret_AuthTkt', 'itsthesecondseekreet')
my_session_factory = SignedCookieSessionFactory(CookiesPasswd) my_session_factory = SignedCookieSessionFactory(CookiesPasswd)
authentication_policy = AuthTktAuthenticationPolicy(AuthTktPasswd, authentication_policy = AuthTktAuthenticationPolicy(AuthTktPasswd,
callback=groupfinder, hashalg='sha512', debug=True)
callback=groupfinder, hashalg='sha512', debug=True)
authorization_policy = ACLAuthorizationPolicy() authorization_policy = ACLAuthorizationPolicy()
config = Configurator(settings=settings, config = Configurator(settings=settings,
root_factory='.security.RootFactory', root_factory='.security.RootFactory',
authentication_policy=authentication_policy, authentication_policy=authentication_policy,
authorization_policy=authorization_policy authorization_policy=authorization_policy
) )
config.add_subscriber(add_renderer_globals, BeforeRender)
config.registry['mailer'] = mailer_factory_from_settings(settings)
config.include('pyramid_mailer')
config.add_subscriber(add_renderer_globals, BeforeRender)
print(settings)
# config.registry['mailer'] = mailer_factory_from_settings(settings)
config.registry['event_date'] = JM2L_Year.get_latest_jm2l_startdate() config.registry['event_date'] = JM2L_Year.get_latest_jm2l_startdate()
sched = BackgroundScheduler() sched = BackgroundScheduler()
sched.add_job(mailer_tasks, 'cron', day_of_week='fri', hour=18, args=[ config ])
sched.start() # start the scheduler
sched.add_job(mailer_tasks, 'cron', day_of_week='fri', hour=18, args=[config])
sched.start() # start the scheduler
config.add_renderer('json', JSON(indent=4)) config.add_renderer('json', JSON(indent=4))
config.add_renderer('jsonp', JSONP(param_name='callback')) config.add_renderer('jsonp', JSONP(param_name='callback'))
config.set_session_factory(my_session_factory) config.set_session_factory(my_session_factory)
@@ -98,98 +102,96 @@ def main(global_config, **settings):
config.add_static_view('vendor', 'static/vendor', cache_max_age=3600) config.add_static_view('vendor', 'static/vendor', cache_max_age=3600)
config.add_static_view('upload', 'upload', cache_max_age=3600) config.add_static_view('upload', 'upload', cache_max_age=3600)
config.add_static_view('resources', 'resources', cache_max_age=3600) config.add_static_view('resources', 'resources', cache_max_age=3600)
# ICal Routes # ICal Routes
config.add_route('progr_iCal', '/{year:\d+}/JM2L.ics')
config.add_route('progr_dyn_iCal', '/{year:\d+}/JM2L_dyn.ics')
config.add_route('progr_iCal', r'/{year:\d+}/JM2L.ics')
config.add_route('progr_dyn_iCal', r'/{year:\d+}/JM2L_dyn.ics')


# JSON Routes # JSON Routes
config.add_route('users_json', '/json-users') config.add_route('users_json', '/json-users')
config.add_route('tiers_json', '/json-tiers') config.add_route('tiers_json', '/json-tiers')
config.add_route('progr_json', '/{year:\d+}/le-prog-json')
config.add_route('timeline_json', '/{year:\d+}/timeline-json')
config.add_route('progr_json', r'/{year:\d+}/le-prog-json')
config.add_route('timeline_json', r'/{year:\d+}/timeline-json')
# Session setting Routes # Session setting Routes
config.add_route('year', '/year/{year:\d+}')
config.add_route('vote_logo', '/vote_logo/{num:\d+}')
config.add_route('year', r'/year/{year:\d+}')
config.add_route('vote_logo', r'/vote_logo/{num:\d+}')
# HTML Routes - Staff # HTML Routes - Staff
config.add_route('Live', '/Live')
config.add_route('list_expenses', '/{year:\d+}/Staff/compta')
config.add_route('list_task', '/{year:\d+}/Staff')
config.add_route('handle_pole', '/{year:\d+}/Staff/poles{sep:/*}{pole_id:(\d+)?}')
config.add_route('handle_task', '/{year:\d+}/Staff/tasks{sep:/*}{task_id:(\d+)?}')
config.add_route('action_task', '/{year:\d+}/Staff/{action:(\w+)}/{task_id:(\d+)}')
config.add_route('action_task_area', '/{year:\d+}/Staff/pole/{action:(\w+)}/{pole_id:(\d+)}')
config.add_route('list_salles', '/ListSalles')
config.add_route('list_salles_phy', '/ListSallesPhy')
config.add_route('handle_salle', '/Salles{sep:/*}{salle_id:(\d+)?}')
config.add_route('handle_salle_phy', '/PhySalles{sep:/*}{salle_id:(\d+)?}')
config.add_route('action_salle', '/Salles/{action:(\w+)}/{salle_id:(\d+)}')
config.add_route('pict_salle', '/salle_picture/{salle_id:(\d+)}')
config.add_route('list_users', '/{year:\d+}/ListParticipant')
config.add_route('list_users_csv', '/{year:\d+}/ListParticipant.csv')
config.add_route('list_orga', '/{year:\d+}/ListOrga')
config.add_route('Live', '/Live')
config.add_route('list_expenses', r'/{year:\d+}/Staff/compta')
config.add_route('list_task', r'/{year:\d+}/Staff')
config.add_route('handle_pole', r'/{year:\d+}/Staff/poles{sep:/*}{pole_id:(\d+)?}')
config.add_route('handle_task', r'/{year:\d+}/Staff/tasks{sep:/*}{task_id:(\d+)?}')
config.add_route('action_task', r'/{year:\d+}/Staff/{action:(\w+)}/{task_id:(\d+)}')
config.add_route('action_task_area', r'/{year:\d+}/Staff/pole/{action:(\w+)}/{pole_id:(\d+)}')
config.add_route('list_salles', '/ListSalles')
config.add_route('list_salles_phy', '/ListSallesPhy')
config.add_route('handle_salle', r'/Salles{sep:/*}{salle_id:(\d+)?}')
config.add_route('handle_salle_phy', r'/PhySalles{sep:/*}{salle_id:(\d+)?}')
config.add_route('action_salle', r'/Salles/{action:(\w+)}/{salle_id:(\d+)}')
config.add_route('pict_salle', r'/salle_picture/{salle_id:(\d+)}')
config.add_route('list_users', r'/{year:\d+}/ListParticipant')
config.add_route('list_users_csv', r'/{year:\d+}/ListParticipant.csv')
config.add_route('list_orga', r'/{year:\d+}/ListOrga')


# HTML Routes - Public # HTML Routes - Public
config.add_route('home', '/{year:(\d+/)?}')
config.add_route('edit_index', '/{year:\d+}/edit')
config.add_route('presse', '/{year:\d+}/dossier-de-presse')
config.add_route('edit_presse', '/{year:\d+}/dossier-de-presse/edit')
config.add_route('programme', '/{year:\d+}/le-programme')
config.add_route('home', r'/{year:(\d+/)?}')
config.add_route('edit_index', r'/{year:\d+}/edit')
config.add_route('presse', r'/{year:\d+}/dossier-de-presse')
config.add_route('edit_presse', r'/{year:\d+}/dossier-de-presse/edit')
config.add_route('programme', r'/{year:\d+}/le-programme')
config.add_route('plan', 'nous-rejoindre') config.add_route('plan', 'nous-rejoindre')
config.add_route('participer', 'participer-l-evenement') config.add_route('participer', 'participer-l-evenement')
config.add_route('captcha', '/captcha') config.add_route('captcha', '/captcha')
## Events ## Events
config.add_route('event', '/event/{year:\d+}/{event_id:([\w-]+)?}')
config.add_route('link_event_user', '/MesJM2L/{year:\d+}/{intervention:[\s\w]+}/link_user')
config.add_route('delete_link_u', '/MesJM2L/{year:\d+}/{intervention:[\s\w]+}/delete_link_user')
config.add_route('link_event_tiers', '/MesJM2L/{year:\d+}/{intervention:[\s\w]+}/link_tiers')
config.add_route('delete_link_t', '/MesJM2L/{year:\d+}/{intervention:[\s\w]+}/delete_link_tiers')
config.add_route('edit_event', '/MesJM2L/{year:\d+}/{intervention:[\s\w]+}{sep:/*}{event_id:([\w-]+)?}')
config.add_route('delete_event', '/MesJM2L/{year:\d+}/{intervention:[\s\w]+}{sep:/*}{event_id:([\w-]+)?}/delete')
## Entities
config.add_route('entities', '/entities') #{sep:/*}{Nature:\w+?}')
config.add_route('add_entity', '/entity')
config.add_route('delete_entity', '/entity/{entity_id:(\d+)}/delete')
config.add_route('show_entity', '/entity/{tiers_type:(\w+)}/{entity_id:([\w-]+)?}')
config.add_route('edit_entity', '/entity/{tiers_type:(\w+)}/{entity_id:([\w-]+)}/edit')
config.add_route('event', r'/event/{year:\d+}/{event_id:([\w-]+)?}')
config.add_route('link_event_user', r'/MesJM2L/{year:\d+}/{intervention:[\s\w]+}/link_user')
config.add_route('delete_link_u', r'/MesJM2L/{year:\d+}/{intervention:[\s\w]+}/delete_link_user')
config.add_route('link_event_tiers', r'/MesJM2L/{year:\d+}/{intervention:[\s\w]+}/link_tiers')
config.add_route('delete_link_t', r'/MesJM2L/{year:\d+}/{intervention:[\s\w]+}/delete_link_tiers')
config.add_route('edit_event', r'/MesJM2L/{year:\d+}/{intervention:[\s\w]+}{sep:/*}{event_id:([\w-]+)?}')
config.add_route('delete_event', r'/MesJM2L/{year:\d+}/{intervention:[\s\w]+}{sep:/*}{event_id:([\w-]+)?}/delete')
# Entities
config.add_route('entities', '/entities') # {sep:/*}{Nature:\w+?}')
config.add_route('add_entity', '/entity')
config.add_route('delete_entity', r'/entity/{entity_id:(\d+)}/delete')
config.add_route('show_entity', r'/entity/{tiers_type:(\w+)}/{entity_id:([\w-]+)?}')
config.add_route('edit_entity', r'/entity/{tiers_type:(\w+)}/{entity_id:([\w-]+)}/edit')
config.add_route('edit_entity_cat', '/categorie/entity') config.add_route('edit_entity_cat', '/categorie/entity')
## Users
# Users
config.add_route('pict_user', '/user_picture') config.add_route('pict_user', '/user_picture')
config.add_route('show_user', '/user/{user_slug:([\w-]+)?}')
config.add_route('badge_user', '/user/{user_slug:([\w-]+)?}/badge')
config.add_route('show_user', r'/user/{user_slug:([\w-]+)?}')
config.add_route('badge_user', r'/user/{user_slug:([\w-]+)?}/badge')
config.add_route('all_badges', '/badges') config.add_route('all_badges', '/badges')
config.add_route('place_print', '/place_print') config.add_route('place_print', '/place_print')
config.add_route('stand_print', '/stand_print')
config.add_route('stand_print', '/stand_print')
# HTML Routes - Logged # HTML Routes - Logged
#config.add_route('profil', 'MesJM2L')
# config.add_route('profil', 'MesJM2L')
config.add_route('jm2l', '/MesJM2L') config.add_route('jm2l', '/MesJM2L')
config.add_route('drop_sejour', '/DropSejour') config.add_route('drop_sejour', '/DropSejour')
config.add_route('miam', '/MonMiam') config.add_route('miam', '/MonMiam')
config.add_route('sejour', '/MonSejour') config.add_route('sejour', '/MonSejour')
config.add_route('orga', '/MonOrga') config.add_route('orga', '/MonOrga')
config.add_route('modal', '/{year:\d+}/modal/{modtype:\w+}/{id:(\d+)}')
config.add_route('modal', r'/{year:\d+}/modal/{modtype:\w+}/{id:(\d+)}')
# Handle exchanges # Handle exchanges
config.add_route('exchange', '/{year:\d+}/exchange/{modtype:\w+}/{id:(\d+)}/{action:\w+}')
config.add_route('exchange', r'/{year:\d+}/exchange/{modtype:\w+}/{id:(\d+)}/{action:\w+}')


# Handle authentication # Handle authentication
config.add_route('register', '/register') config.add_route('register', '/register')
config.add_route('auth', '/sign/{action}') config.add_route('auth', '/sign/{action}')
config.add_route('bymail', '/sign/jm2l/{hash}') config.add_route('bymail', '/sign/jm2l/{hash}')
# Handle Multimedia and Uploads # Handle Multimedia and Uploads
config.add_route('media_view', '/image/{media_table:\w+}/{uid:\d+}/{name:.+}')
config.add_route('media_upload', '/uploader/{media_table:\w+}/{uid:\d+}/proceed{sep:/*}{name:.*}')
config.add_route('media_view', r'/image/{media_table:\w+}/{uid:\d+}/{name:.+}')
config.add_route('media_upload', r'/uploader/{media_table:\w+}/{uid:\d+}/proceed{sep:/*}{name:.*}')


config.scan() config.scan()
return config.make_wsgi_app() return config.make_wsgi_app()



+ 4
- 2
jm2l/auth.py View File

@@ -8,14 +8,16 @@ from pyramid_mailer import get_mailer
from pyramid_mailer.message import Attachment, Message from pyramid_mailer.message import Attachment, Message
from .forms import UserPasswordForm from .forms import UserPasswordForm
from passlib.hash import argon2 from passlib.hash import argon2
from security import check_logged
from .security import check_logged
import datetime import datetime
import re import re



@view_config(route_name='auth', match_param="action=login", renderer="jm2l:templates/login.mako") @view_config(route_name='auth', match_param="action=login", renderer="jm2l:templates/login.mako")
def login(request): def login(request):
return {"comefrom":request.GET.get('from', "")} return {"comefrom":request.GET.get('from', "")}



@view_config(route_name='auth', match_param="action=forgot", renderer="jm2l:templates/login.mako") @view_config(route_name='auth', match_param="action=forgot", renderer="jm2l:templates/login.mako")
def forgot(request): def forgot(request):
if request.method == 'POST' and request.POST: if request.method == 'POST' and request.POST:
@@ -31,7 +33,7 @@ def forgot(request):
return { 'forgot': True } return { 'forgot': True }
else: else:
# Send the Forgot Mail # Send the Forgot Mail
mailer = request.registry['mailer']
mailer = request.mailer
# Prepare Plain Text Message : # Prepare Plain Text Message :
Mail_template = Template(filename='jm2l/templates/mail_plain.mako') Mail_template = Template(filename='jm2l/templates/mail_plain.mako')
mail_plain = Mail_template.render(request=request, User=UserFound, action="Forgot") mail_plain = Mail_template.render(request=request, User=UserFound, action="Forgot")


+ 161
- 148
jm2l/badge.py View File

@@ -1,7 +1,12 @@
# -*- coding: utf8 -*- # -*- coding: utf8 -*-
from pyramid.httpexceptions import HTTPNotFound, HTTPForbidden from pyramid.httpexceptions import HTTPNotFound, HTTPForbidden
from pyramid.response import Response from pyramid.response import Response
import cStringIO as StringIO

try:
from StringIO import StringIO
except ImportError:
from io import StringIO
import io
from pyramid.view import view_config from pyramid.view import view_config
from .models import DBSession, User from .models import DBSession, User
from reportlab.pdfgen import canvas from reportlab.pdfgen import canvas
@@ -12,78 +17,86 @@ import qrcode
import subprocess import subprocess
from .upload import MediaPath from .upload import MediaPath
from jm2l.const import CurrentYear from jm2l.const import CurrentYear

# Create PDF container # Create PDF container
EXPIRATION_TIME = 300 # seconds
EXPIRATION_TIME = 300 # seconds
WIDTH = 85 * mm WIDTH = 85 * mm
HEIGHT = 60 * mm HEIGHT = 60 * mm
ICONSIZE = 10 * mm ICONSIZE = 10 * mm


def JM2L_Logo(canvas, Offset=(0,0)):
OffX, OffY = Offset
logoobject = canvas.beginText()
logoobject.setFont('Logo', 32)
logoobject.setFillColorRGB(.83,0,.33)
logoobject.setTextOrigin(OffX+5, OffY+17)
logoobject.textLines("JM2L")
canvas.drawText(logoobject)
yearobject = canvas.beginText()
yearobject.setFont("Helvetica-Bold", 10)
yearobject.setFillColorRGB(1,1,1)
yearobject.setTextRenderMode(0)
yearobject.setTextOrigin(OffX+12 , OffY+35)
yearobject.setWordSpace(13)
yearobject.textLines(" ".join(str(CurrentYear)))
canvas.drawText(yearobject)

def Tiers_Logo(canvas, DispUser, StartPos=None, Offset=(0,0)):
Border = 0
OffX, OffY = Offset
if StartPos is None:
StartPos = ( 30 * mm, 2 )
StartX, StartY = StartPos
MaxX, MaxY = 34*mm, 18*mm

def JM2L_Logo(canvas, Offset=(0, 0)):
off_x, off_y = Offset
logo_object = canvas.beginText()
logo_object.setFont('Logo', 32)
logo_object.setFillColorRGB(.83, 0, .33)
logo_object.setTextOrigin(off_x + 5, off_y + 17)
logo_object.textLines("JM2L")
canvas.drawText(logo_object)

year_object = canvas.beginText()
year_object.setFont("Helvetica-Bold", 10)
year_object.setFillColorRGB(1, 1, 1)
year_object.setTextRenderMode(0)
year_object.setTextOrigin(off_x + 12, off_y + 35)
year_object.setWordSpace(13)
year_object.textLines(" ".join(str(CurrentYear)))
canvas.drawText(year_object)


def Tiers_Logo(canvas, DispUser, start_pos=None, Offset=(0, 0)):
border = 0
off_x, off_y = Offset
if start_pos is None:
start_pos = (30 * mm, 2)
start_x, start_y = start_pos
max_x, max_y = 34 * mm, 18 * mm
num = 0 num = 0
canvas.setStrokeColorRGB(0.5,0.5,0.5)
Logos = filter(lambda x:x.ThumbLinks, DispUser.tiers)[:3]
canvas.setStrokeColorRGB(0.5, 0.5, 0.5)
list_logos = list()
for thumb in DispUser.tiers:
if thumb.ThumbLinks:
list_logos.append(thumb.ThumbLinks[:3])
# list_logos = list(filter(lambda x: x.ThumbLinks, DispUser.tiers)[:3])
# Should We compute a better positionning for logos ? # Should We compute a better positionning for logos ?
DicPos = {} DicPos = {}
DicPos[1] = { 0:(1./2, 1./2) }
DicPos[2] = { 0:(1./3, 1./2), 1:(2./3, 1./2) }
DicPos[3] = { 0:(1./2, 1./4), 1:(1./3, 3./4), 2:(2./3, 3./4) }
DicPos[4] = { 0:(1./3, 1./4), 1:(2./3, 1./4), 2:(1./3, 3./4),
3:(2./3, 3./4) }
DicPos[5] = { 0:(1./3, 1./4), 1:(2./3, 1./4), 2:(1./6, 3./4),
3:(3./6, 3./4), 4:(5./6, 3./4) }
DicPos[6] = { 0:(1./6, 1./4), 1:(3./6, 1./4), 2:(5./6, 1./4),
3:(1./6, 3./4), 4:(3./6, 3./4), 5:(5./6, 3./4) }
DicPos[7] = { 0:(1./6, 1./4), 1:(3./6, 1./4), 2:(5./6, 1./4),
3:(1./8, 3./4), 4:(3./8, 3./4), 5:(5./8, 3./4),
6:(7./8, 3./4) }
DicPos[8] = { 0:(1./8, 1./4), 1:(3./8, 1./4), 2:(5./8, 1./4),
3:(7./8, 1./4), 4:(1./8, 3./4), 5:(3./8, 3./4),
6:(5./8, 3./4), 7:(7./8, 3./4) }
DicPos[1] = {0: (1. / 2, 1. / 2)}
DicPos[2] = {0: (1. / 3, 1. / 2), 1: (2. / 3, 1. / 2)}
DicPos[3] = {0: (1. / 2, 1. / 4), 1: (1. / 3, 3. / 4), 2: (2. / 3, 3. / 4)}
DicPos[4] = {0: (1. / 3, 1. / 4), 1: (2. / 3, 1. / 4), 2: (1. / 3, 3. / 4),
3: (2. / 3, 3. / 4)}
DicPos[5] = {0: (1. / 3, 1. / 4), 1: (2. / 3, 1. / 4), 2: (1. / 6, 3. / 4),
3: (3. / 6, 3. / 4), 4: (5. / 6, 3. / 4)}
DicPos[6] = {0: (1. / 6, 1. / 4), 1: (3. / 6, 1. / 4), 2: (5. / 6, 1. / 4),
3: (1. / 6, 3. / 4), 4: (3. / 6, 3. / 4), 5: (5. / 6, 3. / 4)}
DicPos[7] = {0: (1. / 6, 1. / 4), 1: (3. / 6, 1. / 4), 2: (5. / 6, 1. / 4),
3: (1. / 8, 3. / 4), 4: (3. / 8, 3. / 4), 5: (5. / 8, 3. / 4),
6: (7. / 8, 3. / 4)}
DicPos[8] = {0: (1. / 8, 1. / 4), 1: (3. / 8, 1. / 4), 2: (5. / 8, 1. / 4),
3: (7. / 8, 1. / 4), 4: (1. / 8, 3. / 4), 5: (3. / 8, 3. / 4),
6: (5. / 8, 3. / 4), 7: (7. / 8, 3. / 4)}
# draw overall border # draw overall border
# canvas.roundRect(StartX, StartY, MaxX, MaxY, radius=2, stroke=True)
for tiers in Logos:
FileName = tiers.ThumbLinks.pop().split("/")[-1]
ImagePath = "jm2l/upload/images/tiers/%s/%s" % (tiers.slug, FileName)
PosX = OffX+StartX + DicPos[len(Logos)][num][0] * MaxX - (ICONSIZE+Border)/2
PosY = OffY+StartY + DicPos[len(Logos)][num][1] * MaxY - (ICONSIZE+Border)/2
# canvas.roundRect(start_x, start_y, max_x, max_y, radius=2, stroke=True)
for tiers in list_logos:
file_name = tiers.ThumbLinks.pop().split("/")[-1]
image_path = "jm2l/upload/images/tiers/%s/%s" % (tiers.slug, file_name)
pos_x = off_x + start_x + DicPos[len(list_logos)][num][0] * max_x - (ICONSIZE + border) / 2
pos_y = off_y + start_y + DicPos[len(list_logos)][num][1] * max_y - (ICONSIZE + border) / 2
canvas.setLineWidth(.1) canvas.setLineWidth(.1)
if len(Logos)>1:
if len(list_logos) > 1:
size = ICONSIZE size = ICONSIZE
else: else:
size = ICONSIZE*1.5
canvas.drawImage(ImagePath,
PosX, PosY, size, size,\
preserveAspectRatio=True,
anchor='c',
mask='auto'
)
size = ICONSIZE * 1.5
canvas.drawImage(image_path,
pos_x, pos_y, size, size,
preserveAspectRatio=True,
anchor='c',
mask='auto'
)
# draw icon border # draw icon border
# canvas.roundRect(PosX, PosY, ICONSIZE, ICONSIZE, radius=2, stroke=True)
num+=1
# canvas.roundRect(pos_x, pos_y, ICONSIZE, ICONSIZE, radius=2, stroke=True)
num += 1



def QRCode(DispUser): def QRCode(DispUser):
qr = qrcode.QRCode( qr = qrcode.QRCode(
@@ -98,78 +111,79 @@ def QRCode(DispUser):


return qr.make_image() return qr.make_image()


def one_badge(c, DispUser, Offset=(0,0)):

def one_badge(c, DispUser, Offset=(0, 0)):
# Logo on Top # Logo on Top
JM2L_Logo(c, Offset) JM2L_Logo(c, Offset)
OffX, OffY = Offset
c.rect(OffX-3, OffY-3, WIDTH+6, HEIGHT+6, fill=0, stroke=1)
off_x, off_y = Offset
c.rect(off_x - 3, off_y - 3, WIDTH + 6, HEIGHT + 6, fill=0, stroke=1)
if DispUser.Staff: if DispUser.Staff:
# Staff # Staff
c.setFillColorRGB(.83,0,.33)
c.rect(OffX-3, OffY+HEIGHT-30, WIDTH+6, 33, fill=1, stroke=0)
c.setFillColorRGB(1,1,1)
c.setFillColorRGB(.83, 0, .33)
c.rect(off_x - 3, off_y + HEIGHT - 30, WIDTH + 6, 33, fill=1, stroke=0)
c.setFillColorRGB(1, 1, 1)
c.setFont('Liberation', 30) c.setFont('Liberation', 30)
c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT-24, "STAFF")
c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT - 24, "STAFF")
elif DispUser.is_Intervenant: elif DispUser.is_Intervenant:
# Intervenant # Intervenant
c.setFillColorRGB(.21,.67,.78)
c.rect(OffX-3, OffY+HEIGHT-30, WIDTH+6, 33, fill=1, stroke=0)
c.setFillColorRGB(1,1,1)
c.setFillColorRGB(.21, .67, .78)
c.rect(off_x - 3, off_y + HEIGHT - 30, WIDTH + 6, 33, fill=1, stroke=0)
c.setFillColorRGB(1, 1, 1)
c.setFont('Liberation', 30) c.setFont('Liberation', 30)
c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT-24, "Intervenant")
c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT - 24, "Intervenant")
elif DispUser.is_crew: elif DispUser.is_crew:
# Benevole # Benevole
c.setFillColorRGB(.18,.76,.23)
c.rect(OffX-3, OffY+HEIGHT-30, WIDTH+6, 33, fill=1, stroke=0)
c.setFillColorRGB(1,1,1)
c.setFillColorRGB(.18, .76, .23)
c.rect(off_x - 3, off_y + HEIGHT - 30, WIDTH + 6, 33, fill=1, stroke=0)
c.setFillColorRGB(1, 1, 1)
c.setFont('Liberation', 30) c.setFont('Liberation', 30)
c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT-24, "Bénévole")
c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT - 24, "Bénévole")
else: else:
# Visiteur # Visiteur
c.setFillColorRGB(.8,.8,.8)
c.rect(OffX-3, OffY+HEIGHT-30, WIDTH+6, 33, fill=1, stroke=0)
c.setFillColorRGB(1,1,1)
c.setFillColorRGB(.8, .8, .8)
c.rect(off_x - 3, off_y + HEIGHT - 30, WIDTH + 6, 33, fill=1, stroke=0)
c.setFillColorRGB(1, 1, 1)
c.setFont('Liberation', 30) c.setFont('Liberation', 30)
c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT-24, "Visiteur")
c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT - 24, "Visiteur")


c.restoreState() c.restoreState()
c.setFont('Liberation', 18) c.setFont('Liberation', 18)
c.setStrokeColorRGB(0,0,0)
c.setFillColorRGB(0,0,0)
c.setStrokeColorRGB(0, 0, 0)
c.setFillColorRGB(0, 0, 0)
# Feed Name and SurName # Feed Name and SurName
if DispUser.prenom and DispUser.nom and len(DispUser.prenom) + len(DispUser.nom)>18:
if DispUser.prenom and DispUser.nom and len(DispUser.prenom) + len(DispUser.nom) > 18:
if DispUser.pseudo: if DispUser.pseudo:
c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT/2 + 0 * mm , "%s" % DispUser.prenom )
#c.setFont('Courier', 17)
c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT/2 - 8 * mm , "%s" % DispUser.nom )
c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT / 2 + 0 * mm, "%s" % DispUser.prenom)
# c.setFont('Courier', 17)
c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT / 2 - 8 * mm, "%s" % DispUser.nom)
else: else:
c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT/2 + 4 * mm , "%s" % DispUser.prenom )
#c.setFont('Courier', 17)
c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT/2 - 8 * mm , "%s" % DispUser.nom )
c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT / 2 + 4 * mm, "%s" % DispUser.prenom)
# c.setFont('Courier', 17)
c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT / 2 - 8 * mm, "%s" % DispUser.nom)
else: else:
c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT/2 + 0 * mm , "%s %s" % (DispUser.prenom, DispUser.nom) )
c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT / 2 + 0 * mm, "%s %s" % (DispUser.prenom, DispUser.nom))


if DispUser.pseudo: if DispUser.pseudo:
c.setFont("Helvetica-Oblique", 18) c.setFont("Helvetica-Oblique", 18)
c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT/2 + 10 * mm , "%s" % DispUser.pseudo )
# Put QR code to user profile
c.drawInlineImage(QRCode(DispUser), \
OffX+WIDTH - 20 * mm -5, OffY+5, \
20 * mm, 20 * mm, \
preserveAspectRatio=True, \
anchor='s')
Tiers_Logo(c, DispUser, None, Offset)
@view_config(route_name='badge_user', http_cache = (EXPIRATION_TIME, {'public':True}))
c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT / 2 + 10 * mm, "%s" % DispUser.pseudo)
#  Put QR code to user profile
c.drawInlineImage(QRCode(DispUser),
off_x + WIDTH - 20 * mm - 5, off_y + 5,
20 * mm, 20 * mm,
preserveAspectRatio=True,
anchor='s')
Tiers_Logo(c, DispUser, None, Offset)
@view_config(route_name='badge_user') # , http_cache=(EXPIRATION_TIME, {'public': True}))
def badge_user(request): def badge_user(request):
isoutpng = request.params.get('png') isoutpng = request.params.get('png')
user_slug = request.matchdict.get('user_slug', None) user_slug = request.matchdict.get('user_slug', None)
if user_slug is None or len(user_slug)==0:
if user_slug is None or len(user_slug) == 0:
raise HTTPNotFound(u"Cet utilisateur n'a pas été reconnu") raise HTTPNotFound(u"Cet utilisateur n'a pas été reconnu")
# Query database # Query database
DispUser = User.by_slug(user_slug) DispUser = User.by_slug(user_slug)
@@ -177,48 +191,47 @@ def badge_user(request):
raise HTTPNotFound() raise HTTPNotFound()


# Ok let's generate a PDF Badge # Ok let's generate a PDF Badge
# Register LiberationMono font # Register LiberationMono font
ttfFile = "jm2l/static/fonts/LiberationMono-Regular.ttf"
pdfmetrics.registerFont(TTFont("Liberation", ttfFile))
# Import font
ttfFile_Logo = "jm2l/static/fonts/PWTinselLetters.ttf"
pdfmetrics.registerFont(TTFont("Logo", ttfFile_Logo))
pdf = StringIO.StringIO()
out_img = StringIO.StringIO()
c = canvas.Canvas( pdf, pagesize=(WIDTH, HEIGHT) )
ttf_file = "jm2l/static/fonts/LiberationMono-Regular.ttf"
pdfmetrics.registerFont(TTFont("Liberation", ttf_file))
#  Import font
ttf_file_logo = "jm2l/static/fonts/PWTinselLetters.ttf"
pdfmetrics.registerFont(TTFont("Logo", ttf_file_logo))
pdf = io.BytesIO()
out_img = io.BytesIO()
c = canvas.Canvas(pdf, pagesize=(WIDTH, HEIGHT))
c.translate(mm, mm) c.translate(mm, mm)
# Feed some metadata # Feed some metadata
c.setCreator("linux-azur.org") c.setCreator("linux-azur.org")
c.setTitle("Badge") c.setTitle("Badge")


c.saveState() c.saveState()
one_badge(c, DispUser)


one_badge(c, DispUser)
out_pdf = MediaPath().get_mediapath("badge", DispUser.uid, 'badge.pdf')
c.showPage() c.showPage()
c.save() c.save()
pdf.seek(0) pdf.seek(0)
if isoutpng: if isoutpng:
OutPDF = MediaPath().get_mediapath("badge", DispUser.uid, 'badge.pdf')
OutPNG = MediaPath().get_mediapath("badge", DispUser.uid, 'badge.png')
# Let's generate a png file for website
with open( OutPDF ,'wb') as pdff:
out_png = MediaPath().get_mediapath("badge", DispUser.uid, 'badge.png')
#  Let's generate a png file for website
with open("./%s" % out_pdf, 'wb') as pdff:
pdff.write(pdf.read()) pdff.write(pdf.read())
Command = ["convert","-density","150x150", OutPDF, OutPNG]
Command = ["convert", "-density", "150x150", out_pdf, out_png]
subprocess.call(Command) subprocess.call(Command)
with open( OutPNG, 'rb') as pngfile:
out_img.write(pngfile.read())
with open("./%s" % out_png, 'rb') as pngfile:
out_img.write(pngfile.read()) # pngfile.read(), "utf8"))
out_img.seek(0) out_img.seek(0)
return Response(app_iter=out_img, content_type = 'image/png' )
return Response(app_iter=out_img, content_type='image/png')
else: else:
return Response(app_iter=pdf, content_type = 'application/pdf' )
return Response(app_iter=pdf, content_type='application/pdf')




@view_config(route_name='all_badges') @view_config(route_name='all_badges')
@@ -232,34 +245,34 @@ def planche_badge(request):
# .filter(User_Event.year_uid == year) # .filter(User_Event.year_uid == year)


# Register LiberationMono font # Register LiberationMono font
ttfFile = "jm2l/static/fonts/LiberationMono-Regular.ttf"
pdfmetrics.registerFont(TTFont("Liberation", ttfFile))
# Import font
ttfFile_Logo = "jm2l/static/fonts/PWTinselLetters.ttf"
pdfmetrics.registerFont(TTFont("Logo", ttfFile_Logo))
pdf = StringIO.StringIO()
ttf_file = "jm2l/static/fonts/LiberationMono-Regular.ttf"
pdfmetrics.registerFont(TTFont("Liberation", ttf_file))
#  Import font
ttf_file_logo = "jm2l/static/fonts/PWTinselLetters.ttf"
pdfmetrics.registerFont(TTFont("Logo", ttf_file_logo))
pdf = io.BytesIO()


FULLWIDTH = 210 * mm FULLWIDTH = 210 * mm
FULLHEIGHT = 297 * mm FULLHEIGHT = 297 * mm


c = canvas.Canvas( pdf, pagesize=(FULLWIDTH, FULLHEIGHT) )
c = canvas.Canvas(pdf, pagesize=(FULLWIDTH, FULLHEIGHT))
c.translate(mm, mm) c.translate(mm, mm)
# Feed some metadata # Feed some metadata
c.setCreator("linux-azur.org") c.setCreator("linux-azur.org")
c.setTitle("Badge") c.setTitle("Badge")
t=0
ListUser = filter(lambda x: x.is_Intervenant or x.Staff or x.is_crew, Users)
for num, DispUser in enumerate(ListUser):
t = 0
list_user = filter(lambda x: x.is_Intervenant or x.Staff or x.is_crew, Users)
for num, disp_user in enumerate(list_user):
c.saveState() c.saveState()
Offsets = (((num-t)%2)*(WIDTH+40)+40, ((num-t)/2)*(HEIGHT+25)+40)
one_badge(c, DispUser, Offsets)
if num%8==7:
t=num+1
offsets = (((num - t) % 2) * (WIDTH + 40) + 40, int(((num - t) / 2)) * (HEIGHT + 25) + 40)
one_badge(c, disp_user, offsets)
if num % 8 == 7:
t = num + 1
c.showPage() c.showPage()


c.showPage() c.showPage()
c.save() c.save()
pdf.seek(0) pdf.seek(0)
return Response(app_iter=pdf, content_type = 'application/pdf' )
return Response(app_iter=pdf, content_type='application/pdf')

+ 54
- 49
jm2l/captcha.py View File

@@ -3,20 +3,22 @@


import random import random
from PIL import Image, ImageDraw, ImageFont, ImageFilter from PIL import Image, ImageDraw, ImageFont, ImageFilter
import cStringIO as StringIO
import io
# from io import StringIO
import math import math
from pyramid.view import view_config from pyramid.view import view_config
from .words import TabMots from .words import TabMots
from pyramid.response import Response from pyramid.response import Response



class Captcha_Img(object): class Captcha_Img(object):
def __init__( self, width, height):
def __init__(self, width, height):
self.width = width self.width = width
self.height = height self.height = height
self._layers = [ self._layers = [
_PyCaptcha_SineWarp(amplitudeRange = (4, 8) , periodRange=(0.65,0.73) ),
_PyCaptcha_SineWarp(amplitudeRange=(4, 8), periodRange=(0.65, 0.73)),
] ]
def getImg(self): def getImg(self):
"""Get a PIL image representing this CAPTCHA test, creating it if necessary""" """Get a PIL image representing this CAPTCHA test, creating it if necessary"""
if not self._image: if not self._image:
@@ -25,14 +27,15 @@ class Captcha_Img(object):


def render(self): def render(self):
"""Render this CAPTCHA, returning a PIL image""" """Render this CAPTCHA, returning a PIL image"""
size = (self.width,self.height)
#img = Image.new("RGB", size )
size = (self.width, self.height)
# img = Image.new("RGB", size )
img = self._image img = self._image
for layer in self._layers: for layer in self._layers:
img = layer.render( img ) or img
img = layer.render(img) or img
self._image = img self._image = img
return self._image return self._image



class _PyCaptcha_WarpBase(object): class _PyCaptcha_WarpBase(object):
"""Abstract base class for image warping. Subclasses define a """Abstract base class for image warping. Subclasses define a
function that maps points in the output image to points in the input image. function that maps points in the output image to points in the input image.
@@ -55,15 +58,15 @@ class _PyCaptcha_WarpBase(object):
# Create a list of arrays with transformed points # Create a list of arrays with transformed points
xRows = [] xRows = []
yRows = [] yRows = []
for j in xrange(yPoints):
for j in range(int(yPoints)):
xRow = [] xRow = []
yRow = [] yRow = []
for i in xrange(xPoints):
x, y = f(i*r, j*r)
for i in range(int(xPoints)):
x, y = f(i * r, j * r)


# Clamp the edges so we don't get black undefined areas # Clamp the edges so we don't get black undefined areas
x = max(0, min(image.size[0]-1, x))
y = max(0, min(image.size[1]-1, y))
x = max(0, min(image.size[0] - 1, x))
y = max(0, min(image.size[1] - 1, y))


xRow.append(x) xRow.append(x)
yRow.append(y) yRow.append(y)
@@ -73,79 +76,81 @@ class _PyCaptcha_WarpBase(object):
# Create the mesh list, with a transformation for # Create the mesh list, with a transformation for
# each square between points on the grid # each square between points on the grid
mesh = [] mesh = []
for j in xrange(yPoints-1):
for i in xrange(xPoints-1):
for j in range(int(yPoints - 1)):
for i in range(int(xPoints - 1)):
mesh.append(( mesh.append((
# Destination rectangle # Destination rectangle
(i*r, j*r,
(i+1)*r, (j+1)*r),
(i * r, j * r,
(i + 1) * r, (j + 1) * r),
# Source quadrilateral # Source quadrilateral
(xRows[j ][i ], yRows[j ][i ],
xRows[j+1][i ], yRows[j+1][i ],
xRows[j+1][i+1], yRows[j+1][i+1],
xRows[j ][i+1], yRows[j ][i+1]),
))
(xRows[j][i], yRows[j][i],
xRows[j + 1][i], yRows[j + 1][i],
xRows[j + 1][i + 1], yRows[j + 1][i + 1],
xRows[j][i + 1], yRows[j][i + 1]),
))


return image.transform(image.size, Image.MESH, mesh, self.filtering) return image.transform(image.size, Image.MESH, mesh, self.filtering)



class _PyCaptcha_SineWarp(_PyCaptcha_WarpBase): class _PyCaptcha_SineWarp(_PyCaptcha_WarpBase):
"""Warp the image using a random composition of sine waves""" """Warp the image using a random composition of sine waves"""


def __init__(self, def __init__(self,
amplitudeRange = (1,1),#(2, 6),
periodRange = (1,1)#(0.65, 0.73),
amplitudeRange=(1, 1), # (2, 6),
periodRange=(1, 1) # (0.65, 0.73),
): ):
self.amplitude = random.uniform(*amplitudeRange) self.amplitude = random.uniform(*amplitudeRange)
self.period = random.uniform(*periodRange) self.period = random.uniform(*periodRange)
self.offset = (random.uniform(0, math.pi * 2 / self.period), self.offset = (random.uniform(0, math.pi * 2 / self.period),
random.uniform(0, math.pi * 2 / self.period)) random.uniform(0, math.pi * 2 / self.period))
def get_transform(self, image): def get_transform(self, image):
return (lambda x, y, return (lambda x, y,
a = self.amplitude,
p = self.period,
o = self.offset:
(math.sin( (y+o[0])*p )*a + x,
math.sin( (x+o[1])*p )*a + y))
a=self.amplitude,
p=self.period,
o=self.offset:
(math.sin((y + o[0]) * p) * a + x,
math.sin((x + o[1]) * p) * a + y))



@view_config(route_name='captcha') @view_config(route_name='captcha')
def DoCaptcha(request): def DoCaptcha(request):
ImgSize = (230,100)
WorkImg = Image.new( 'RGBA', ImgSize, (255, 255, 255, 0) )
Xmax, Ymax = WorkImg.size
img_size = (230, 100)
work_img = Image.new('RGBA', img_size, (255, 255, 255, 0))
Xmax, Ymax = work_img.size
# Write something on it # Write something on it
draw = ImageDraw.Draw(WorkImg)
draw = ImageDraw.Draw(work_img)


# use a truetype font # use a truetype font
#font = ImageFont.truetype("/var/lib/defoma/gs.d/dirs/fonts/LiberationMono-Regular.ttf", 40)
# font = ImageFont.truetype("/var/lib/defoma/gs.d/dirs/fonts/LiberationMono-Regular.ttf", 40)
# use it # use it
font = ImageFont.truetype("jm2l/static/fonts/LiberationMono-Regular.ttf",40)
font = ImageFont.truetype("jm2l/static/fonts/LiberationMono-Regular.ttf", 40)
# Re-position # Re-position
# Choose a word for captcha # Choose a word for captcha
text = random.choice(TabMots) text = random.choice(TabMots)
Xt, Yt = font.getsize(text) Xt, Yt = font.getsize(text)
OrX, OrY = (ImgSize[0]-Xt)/2, (ImgSize[1]-Yt)/2
OrX, OrY = (img_size[0] - Xt) / 2, (img_size[1] - Yt) / 2
draw.text((OrX, OrY), text, font=font, fill="#000000") draw.text((OrX, OrY), text, font=font, fill="#000000")
# Apply a Blur # Apply a Blur
# WorkImg=WorkImg.filter(ImageFilter.BLUR)
# work_img=work_img.filter(ImageFilter.BLUR)
# Apply a DETAIL # Apply a DETAIL
WorkImg=WorkImg.filter(ImageFilter.DETAIL)
work_img = work_img.filter(ImageFilter.DETAIL)
# randomize parameters for perspective # randomize parameters for perspective
ax, ay = (random.uniform(0.9,1.2) , random.uniform(0.9,1.2))
tx, ty = (random.uniform(0,0.0003),random.uniform(0,0.0003))
bx, by = (random.uniform(0.5,0.8),random.uniform(0,0.2))
ax, ay = (random.uniform(0.9, 1.2), random.uniform(0.9, 1.2))
tx, ty = (random.uniform(0, 0.0003), random.uniform(0, 0.0003))
bx, by = (random.uniform(0.5, 0.8), random.uniform(0, 0.2))
# Apply perspective to Captcha # Apply perspective to Captcha
WorkImg= WorkImg.transform(ImgSize, Image.PERSPECTIVE, (ax, bx, -25, by, ay, -10, tx, ty))
work_img = work_img.transform(img_size, Image.PERSPECTIVE, (ax, bx, -25, by, ay, -10, tx, ty))
# Apply SinWarp to Captcha # Apply SinWarp to Captcha
tr = Captcha_Img(Xmax, Ymax) tr = Captcha_Img(Xmax, Ymax)
tr._image = WorkImg
WorkImg = tr.render()
tr._image = work_img
work_img = tr.render()
# Apply a Smooth on it # Apply a Smooth on it
WorkImg=WorkImg.filter(random.choice([ImageFilter.SMOOTH, ImageFilter.SMOOTH_MORE]))
work_img = work_img.filter(random.choice([ImageFilter.SMOOTH, ImageFilter.SMOOTH_MORE]))
# Save Result # Save Result
request.session['Captcha'] = text request.session['Captcha'] = text
#session.save()
ImgHandle = StringIO.StringIO()
WorkImg.save(ImgHandle,'png')
# session.save()
ImgHandle = io.BytesIO()
work_img.save(ImgHandle, 'png')
ImgHandle.seek(0) ImgHandle.seek(0)
return Response(app_iter=ImgHandle, content_type = 'image/png')
return Response(app_iter=ImgHandle, content_type='image/png')

+ 1
- 1
jm2l/const.py View File

@@ -1 +1 @@
CurrentYear = 2018
CurrentYear = 2020

+ 427
- 356
jm2l/forms.py
File diff suppressed because it is too large
View File


+ 72
- 64
jm2l/helpers.py View File

@@ -4,101 +4,108 @@ from datetime import timedelta, datetime
import itertools import itertools
from jm2l.const import CurrentYear from jm2l.const import CurrentYear



def get_current_year():
""" This function is intended to return the year of the next edition """
return CurrentYear


class DummySejour(object): class DummySejour(object):
def __init__(self, event): def __init__(self, event):
self.Me = event['request'].user self.Me = event['request'].user
self.CurrentEventYear = DBSession.query(JM2L_Year).filter(JM2L_Year.state=='Ongoing').first()
self.CurrentEventYear = DBSession.query(JM2L_Year).filter(JM2L_Year.state == 'Ongoing').first()
self.Sejour = None self.Sejour = None
if self.Me: if self.Me:
self.Sejour = DBSession.query(Sejour)\
.filter(Sejour.user_id==self.Me.uid)\
.filter(Sejour.for_year==self.CurrentEventYear.year_uid)\
self.Sejour = DBSession.query(Sejour) \
.filter(Sejour.user_id == self.Me.uid) \
.filter(Sejour.for_year == self.CurrentEventYear.year_uid) \
.first() .first()



class Sejour_helpers(DummySejour): class Sejour_helpers(DummySejour):


def __init__(self, event): def __init__(self, event):
super(Sejour_helpers, self).__init__(event) super(Sejour_helpers, self).__init__(event)
if self.Sejour and self.Sejour.arrival_time is None: if self.Sejour and self.Sejour.arrival_time is None:
self.Sejour = None self.Sejour = None
def StartEvent(self): def StartEvent(self):
# This function return the start of the event # This function return the start of the event
return self.CurrentYear return self.CurrentYear
def PossibleDate(self, typedate="arrival"):
def PossibleDate(self, type_date="arrival"):
arrival, departure = False, False arrival, departure = False, False
TabResult = list()
if typedate == "arrival":
tab_result = list()
if type_date == "arrival":
# Let's say people should arrive until 2 day before # Let's say people should arrive until 2 day before
arrival = True arrival = True
myDayRange = xrange(2,-1,-1)
elif typedate == "departure":
my_day_range = range(2, -1, -1)
elif type_date == "departure":
# Let's say people should go back home until 2 day after # Let's say people should go back home until 2 day after
departure = True
myDayRange = xrange(3)
departure = True
my_day_range = range(3)
else: else:
return TabResult
return tab_result
if self.Sejour: if self.Sejour:
ArrDate = datetime.strftime(self.Sejour.arrival_time,"%d %B %Y").decode('utf-8')
DepDate = datetime.strftime(self.Sejour.depart_time,"%d %B %Y").decode('utf-8')
arr_date = datetime.strftime(self.Sejour.arrival_time, "%d %B %Y")
dep_date = datetime.strftime(self.Sejour.depart_time, "%d %B %Y")
else: else:
ArrDate = datetime.strftime( self.CurrentEventYear.start_time,"%d %B %Y" ).decode('utf-8')
DepDate = datetime.strftime( self.CurrentEventYear.end_time,"%d %B %Y" ).decode('utf-8')
for oneday in myDayRange:
arr_date = datetime.strftime(self.CurrentEventYear.start_time, "%d %B %Y")
dep_date = datetime.strftime(self.CurrentEventYear.end_time, "%d %B %Y")
for one_day in my_day_range:
if arrival: if arrival:
TmpDay = self.CurrentEventYear.end_time - timedelta(days=oneday)
tmp_day = self.CurrentEventYear.end_time - timedelta(days=one_day)
elif departure: elif departure:
TmpDay = self.CurrentEventYear.start_time + timedelta(days=oneday)
DayName = datetime.strftime(TmpDay,"%A")
DayNum = datetime.strftime(TmpDay,"%d/%m/%y")
DayString = datetime.strftime(TmpDay,"%d %B %Y").decode('utf-8')
if arrival and ArrDate==DayString:
TabResult.append((DayNum, DayName, 'selected="selected"'))
elif departure and DepDate==DayString:
TabResult.append((DayNum, DayName, 'selected="selected"'))
tmp_day = self.CurrentEventYear.start_time + timedelta(days=one_day)
day_name = datetime.strftime(tmp_day, "%A")
day_num = datetime.strftime(tmp_day, "%d/%m/%y")
day_string = datetime.strftime(tmp_day, "%d %B %Y")
if arrival and arr_date == day_string:
tab_result.append((day_num, day_name, 'selected="selected"'))
elif departure and dep_date == day_string:
tab_result.append((day_num, day_name, 'selected="selected"'))
else: else:
TabResult.append((DayNum, DayName, ""))
return TabResult
tab_result.append((day_num, day_name, ""))
return tab_result

def PossibleTime(self, type_date="arrival"):
arr_time, dep_time = "10:00", "19:00"
tab_result = list()


def PossibleTime(self, typedate="arrival"):
ArrTime, DepTime = "10:00", "19:00"
TabResult = list()
if self.Sejour: if self.Sejour:
ArrTime = datetime.strftime(self.Sejour.arrival_time,"%H:%M")
DepTime = datetime.strftime(self.Sejour.depart_time,"%H:%M")
arr_time = datetime.strftime(self.Sejour.arrival_time, "%H:%M")
dep_time = datetime.strftime(self.Sejour.depart_time, "%H:%M")

for hour in range(24): for hour in range(24):
for minutes in range(0,60,10):
StrTime = "%.2d:%.2d" % (hour, minutes)
DispTime = "%dh%.2d" % (hour, minutes)
if typedate == "arrival" and StrTime==ArrTime:
TabResult.append( (StrTime, DispTime, 'selected="selected"') )
elif typedate == "departure" and StrTime==DepTime:
TabResult.append( (StrTime, DispTime, 'selected="selected"') )
for minutes in range(0, 60, 10):
str_time = "%.2d:%.2d" % (hour, minutes)
disp_time = "%dh%.2d" % (hour, minutes)
if type_date == "arrival" and str_time == arr_time:
tab_result.append((str_time, disp_time, 'selected="selected"'))
elif type_date == "departure" and str_time == dep_time:
tab_result.append((str_time, disp_time, 'selected="selected"'))
else: else:
TabResult.append( (StrTime, DispTime, "") )
return TabResult
tab_result.append((str_time, disp_time, ""))
return tab_result


def IsCheck(self, InputControl): def IsCheck(self, InputControl):
ListControlA = ['Arrival', 'Departure']
ListControlB = ['PMR', 'Cov', 'Bras', 'Other']
if InputControl not in map(':'.join, itertools.product(ListControlA, ListControlB)):
list_control_a = ['Arrival', 'Departure']
list_control_b = ['PMR', 'Cov', 'Bras', 'Other']
if InputControl not in map(':'.join, itertools.product(list_control_a, list_control_b)):
return "" return ""
if self.Sejour: if self.Sejour:
if InputControl.startswith('Arrival'): if InputControl.startswith('Arrival'):
CtrlVal = 2**ListControlB.index(InputControl[8:])
if self.Sejour.arrival_check & CtrlVal == CtrlVal:
ctrl_val = 2 ** list_control_b.index(InputControl[8:])
if self.Sejour.arrival_check & ctrl_val == ctrl_val:
return "checked=\"checked\"" return "checked=\"checked\""
else: else:
return "" return ""
elif InputControl.startswith('Departure'): elif InputControl.startswith('Departure'):
CtrlVal = 2**ListControlB.index(InputControl[10:])
if self.Sejour.depart_check & CtrlVal == CtrlVal:
ctrl_val = 2 ** list_control_b.index(InputControl[10:])
if self.Sejour.depart_check & ctrl_val == ctrl_val:
return "checked=\"checked\"" return "checked=\"checked\""
else: else:
return "" return ""
@@ -107,6 +114,7 @@ class Sejour_helpers(DummySejour):
else: else:
return "" return ""



class Orga_helpers(DummySejour): class Orga_helpers(DummySejour):


def __init__(self, event): def __init__(self, event):
@@ -129,10 +137,10 @@ class Orga_helpers(DummySejour):
u"Faire du café et s'assurer de sa disponibilité.", u"Faire du café et s'assurer de sa disponibilité.",
u"Participer à la publication / au montage des vidéos des conférenciers.", u"Participer à la publication / au montage des vidéos des conférenciers.",
u"Autres" u"Autres"
]
]


def IsChecked(self, nb): def IsChecked(self, nb):
nb = 2**nb
nb = 2 ** nb
if self.Sejour and self.Sejour.orga_part: if self.Sejour and self.Sejour.orga_part:
if self.Sejour.orga_part & nb == nb: if self.Sejour.orga_part & nb == nb:
return "checked=\"checked\"" return "checked=\"checked\""
@@ -140,12 +148,12 @@ class Orga_helpers(DummySejour):
return "" return ""
else: else:
return "" return ""
def ChoosedList(self): def ChoosedList(self):
""" Return choice validated by user """ """ Return choice validated by user """
ListOrga = []
for num in range(0,len(self.Orga_tasks)):
curs = 2**num
list_orga = []
for num in range(0, len(self.Orga_tasks)):
curs = 2 ** num
if self.Sejour.orga_part & curs == curs: if self.Sejour.orga_part & curs == curs:
ListOrga.append(self.Orga_tasks[num])
return ListOrga
list_orga.append(self.Orga_tasks[num])
return list_orga

+ 392
- 365
jm2l/models.py
File diff suppressed because it is too large
View File


+ 12
- 13
jm2l/scripts/initializedb.py View File

@@ -48,14 +48,14 @@ def pull_data(from_db, to_db, tables):
destination, dengine = make_session(to_db) destination, dengine = make_session(to_db)


for table_name in tables: for table_name in tables:
print 'Processing', table_name
print 'Pulling schema from source server'
print('Processing', table_name)
print('Pulling schema from source server')
table = Table(table_name, smeta, autoload=True) table = Table(table_name, smeta, autoload=True)
print 'Creating table on destination server'
print('Creating table on destination server')
table.metadata.create_all(dengine) table.metadata.create_all(dengine)
NewRecord = quick_mapper(table) NewRecord = quick_mapper(table)
columns = table.columns.keys() columns = table.columns.keys()
print 'Transferring records'
print('Transferring records')
for record in source.query(table).all(): for record in source.query(table).all():
data = dict( data = dict(
[(str(column), getattr(record, column)) for column in columns] [(str(column), getattr(record, column)) for column in columns]
@@ -69,20 +69,20 @@ def pull_data(from_db, to_db, tables):
try: try:
destination.merge(NewRecord(**data)) destination.merge(NewRecord(**data))
except: except:
print data
print(data)
pass pass
print 'Committing changes'
print('Committing changes')
destination.commit() destination.commit()




def main(argv=sys.argv): def main(argv=sys.argv):
connection_string = "sqlite:////home/tr4ck3ur/Dev/jm2l/JM2L.sqlite"
connection_string = "sqlite:////home/tr4ck3ur/git_repository/jm2l/JM2L.sqlite"
engine = create_engine(connection_string, echo=False, convert_unicode=True) engine = create_engine(connection_string, echo=False, convert_unicode=True)
DBSession.configure(bind=engine) DBSession.configure(bind=engine)
Users = DBSession.query(User) Users = DBSession.query(User)
ListUser = filter(lambda x: x.is_Intervenant, Users) ListUser = filter(lambda x: x.is_Intervenant, Users)
for i in ListUser: for i in ListUser:
print i.mail
print(i.mail)


def main4(argv=sys.argv): def main4(argv=sys.argv):
import csv import csv
@@ -116,7 +116,7 @@ def main4(argv=sys.argv):
u.wifi_user = w_user u.wifi_user = w_user
u.wifi_pass = w_pass u.wifi_pass = w_pass
DBSession.merge(u) DBSession.merge(u)
print row, u
print(row, u)
finally: finally:
f.close() f.close()
@@ -130,7 +130,7 @@ def main_3(argv=sys.argv):
connection_string = "sqlite:////home/tr4ck3ur/Dev/jm2l/JM2L.sqlite" connection_string = "sqlite:////home/tr4ck3ur/Dev/jm2l/JM2L.sqlite"
engine = create_engine(connection_string, echo=True, convert_unicode=True) engine = create_engine(connection_string, echo=True, convert_unicode=True)
DBSession.configure(bind=engine) DBSession.configure(bind=engine)
p0, p1 = orm.aliased(User,name="p0"), orm.aliased(User ,name="p1")
p0, p1 = orm.aliased(User, name="p0"), orm.aliased(User , name="p1")
import pprint import pprint
## permtation ## permtation
@@ -141,7 +141,7 @@ def main_3(argv=sys.argv):
.filter(p0.last_logged<p1.last_logged)\ .filter(p0.last_logged<p1.last_logged)\
.with_entities(p0.slug,p0.uid,p1.uid).all() .with_entities(p0.slug,p0.uid,p1.uid).all()
for slug, idsrc, iddst in Datas: for slug, idsrc, iddst in Datas:
print slug
print(slug)
# Events # Events
Events = DBSession.query(User_Event)\ Events = DBSession.query(User_Event)\
.filter(User_Event.user_uid==idsrc) .filter(User_Event.user_uid==idsrc)
@@ -238,5 +238,4 @@ def Initialize():
u.password = password u.password = password
u.Staff = 0 u.Staff = 0
DBSession.merge(u) DBSession.merge(u)
print u.nom, u.prenom, u.Staff
print(u.nom, u.prenom, u.Staff)

+ 1
- 0
jm2l/security.py View File

@@ -15,6 +15,7 @@ def check_logged(request):
# Don't answer to users that aren't logged # Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.') raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')



def check_staff(request): def check_staff(request):
""" This function is intended to raise an exception if the user is not a Staff member""" """ This function is intended to raise an exception if the user is not a Staff member"""
check_logged(request) check_logged(request)


BIN
jm2l/static/favicon.ico View File

Before After

jm2l/static/img/2020/Accessibility → on_final.svg View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="1224px" height="792px" viewBox="0 0 1224 792" enable-background="new 0 0 1224 792" xml:space="preserve">
<g>
<path d="M833.556,367.574c-7.753-7.955-18.586-12.155-29.656-11.549l-133.981,7.458l73.733-83.975 c10.504-11.962,13.505-27.908,9.444-42.157c-2.143-9.764-8.056-18.648-17.14-24.324c-0.279-0.199-176.247-102.423-176.247-102.423 c-14.369-8.347-32.475-6.508-44.875,4.552l-85.958,76.676c-15.837,14.126-17.224,38.416-3.097,54.254 c14.128,15.836,38.419,17.227,54.255,3.096l65.168-58.131l53.874,31.285l-95.096,108.305 c-39.433,6.431-74.913,24.602-102.765,50.801l49.66,49.66c22.449-20.412,52.256-32.871,84.918-32.871 c69.667,0,126.346,56.68,126.346,126.348c0,32.662-12.459,62.467-32.869,84.916l49.657,49.66 c33.08-35.166,53.382-82.484,53.382-134.576c0-31.035-7.205-60.384-20.016-86.482l51.861-2.889l-12.616,154.75 c-1.725,21.152,14.027,39.695,35.18,41.422c1.059,0.086,2.116,0.127,3.163,0.127c19.806,0,36.621-15.219,38.257-35.306 l16.193-198.685C845.235,386.445,841.305,375.527,833.556,367.574z"/>
<path d="M762.384,202.965c35.523,0,64.317-28.797,64.317-64.322c0-35.523-28.794-64.323-64.317-64.323 c-35.527,0-64.323,28.8-64.323,64.323C698.061,174.168,726.856,202.965,762.384,202.965z"/>
<path d="M535.794,650.926c-69.668,0-126.348-56.68-126.348-126.348c0-26.256,8.056-50.66,21.817-70.887l-50.196-50.195 c-26.155,33.377-41.791,75.393-41.791,121.082c0,108.535,87.983,196.517,196.518,196.517c45.691,0,87.703-15.636,121.079-41.792 l-50.195-50.193C586.452,642.867,562.048,650.926,535.794,650.926z"/>
</g>
</svg>

+ 33453
- 0
jm2l/static/img/2020/Artic_North_Pole_Scene_and_Action_View2.svg
File diff suppressed because it is too large
View File


BIN
jm2l/static/img/2020/Digital-Marketing.jpg View File

Before After
Width: 700  |  Height: 263  |  Size: 32 KiB

+ 58
- 0
jm2l/static/img/2020/Gamepad-White.svg View File

@@ -0,0 +1,58 @@
<?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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.1" viewBox="0 0 325.9702 172.35009" id="Layer_1" xml:space="preserve" inkscape:version="0.48.5 r10040" sodipodi:docname="Gamepad White.svg">
<sodipodi:namedview pagecolor="#ffffff" bordercolor="#666666" borderopacity="1" objecttolerance="10" gridtolerance="10" guidetolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-width="1088" inkscape:window-height="1061" id="namedview30" showgrid="false" inkscape:zoom="1" inkscape:cx="92.633449" inkscape:cy="40.468773" inkscape:window-x="1920" inkscape:window-y="139" inkscape:window-maximized="0" inkscape:current-layer="Layer_1" fit-margin-top="0" fit-margin-left="0" fit-margin-right="0" fit-margin-bottom="0"/>
<defs id="defs3059"/>
<metadata id="metadata3055">
<rdf:RDF>
<cc:Work>
<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/publicdomain/"/>
<dc:publisher>
<cc:Agent rdf:about="http://openclipart.org/">
<dc:title>Openclipart</dc:title>
</cc:Agent>
</dc:publisher>
<dc:title/>
</cc:Work>
<cc:License rdf:about="http://creativecommons.org/licenses/publicdomain/">
<cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction"/>
<cc:permits rdf:resource="http://creativecommons.org/ns#Distribution"/>
<cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks"/>
</cc:License>
</rdf:RDF>
</metadata>
<path style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#1d1d1d;stroke-width:3.00000024;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" id="path5307" d="m 52.919904,8.1875 c -6.031842,0 -11.470893,2.407417 -15.4375,6.3125 -0.04088,0.04024 -0.08444,0.08444 -0.125,0.125 -4.29211,3.308693 -7.596781,7.816291 -9.15625,13.4375 l -25.0312496,90.25 c -4.73921,17.08279 0.48564,36.23227 17.3124996,41.8125 l 26.65625,8.8125 c 16.82685,5.58022 34.179421,-1.29707 41.78125,-17.3125 l 21.031246,-44.28125 106.0625,0 21.03125,44.28125 c 7.60183,16.01543 24.9544,22.89272 41.78125,17.3125 l 26.65625,-8.8125 c 16.82686,-5.58023 22.05171,-24.72971 17.3125,-41.8125 l -25.03125,-90.25 c -2.7742,-9.999793 -11.01427,-16.522009 -20.65625,-18.875 -0.13603,-0.042133 -0.26909,-0.085439 -0.40625,-0.125 -0.01,-0.00229 -0.0213,0.00228 -0.0312,0 -1.94068,-0.5568486 -4.00056,-0.875 -6.125,-0.875 l -1.8125,0 -211.499996,0 -4.3125,0 z" inkscape:connector-curvature="0"/>
<rect width="62.578949" height="31.466251" rx="8" ry="8" x="41.378765" y="0.73722839" id="rect4249" style="fill:#5e5e5e;fill-opacity:1;fill-rule:nonzero;stroke:#1d1d1d;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"/>
<rect width="62.578949" height="31.466251" rx="8" ry="8" x="219.53084" y="0.73722839" id="rect4267" style="fill:#5e5e5e;fill-opacity:1;fill-rule:nonzero;stroke:#1d1d1d;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"/>
<path d="m 52.919904,8.1875 c -6.031842,0 -11.470893,2.407417 -15.4375,6.3125 -0.04088,0.04024 -0.08444,0.08444 -0.125,0.125 -4.29211,3.308693 -7.596781,7.816291 -9.15625,13.4375 l -25.0312496,90.25 c -4.73921,17.08279 0.48564,36.23227 17.3124996,41.8125 l 26.65625,8.8125 c 16.82685,5.58022 34.179421,-1.29707 41.78125,-17.3125 l 21.031246,-44.28125 106.0625,0 21.03125,44.28125 c 7.60183,16.01543 24.9544,22.89272 41.78125,17.3125 l 26.65625,-8.8125 c 16.82686,-5.58023 22.05171,-24.72971 17.3125,-41.8125 l -25.03125,-90.25 c -2.7742,-9.999793 -11.01427,-16.522009 -20.65625,-18.875 -0.13603,-0.042133 -0.26909,-0.085439 -0.40625,-0.125 -0.01,-0.00229 -0.0213,0.00228 -0.0312,0 -1.94068,-0.5568486 -4.00056,-0.875 -6.125,-0.875 l -1.8125,0 -211.499996,0 -4.3125,0 z" id="rect4151" style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" inkscape:connector-curvature="0"/>
<g id="g4358" style="fill:#bdbdbd;fill-opacity:1" transform="translate(1.5007304,0)">
<path d="m 238.20531,32.84774 c -2.18572,0 -3.97143,1.78571 -3.97143,3.97143 v 20.94285 h -20.98571 c -2.18572,0 -3.92858,1.78572 -3.92858,3.97143 v 22.27143 c 0,2.2 1.74286,3.98571 3.92858,3.98571 h 20.98571 v 20.92858 c 0,2.2 1.78571,3.97142 3.97143,3.97142 h 22.28571 c 2.18572,0 3.92857,-1.77142 3.92857,-3.97142 V 87.99059 h 20.97143 c 2.2,0 3.92857,-1.78571 3.92857,-3.98571 V 61.73345 c 0,-2.18571 -1.72857,-3.97143 -3.92857,-3.97143 H 264.41959 V 36.81917 c 0,-2.18572 -1.74285,-3.97143 -3.92857,-3.97143 h -22.28571 z" id="path3219" style="fill:#bdbdbd;fill-opacity:1;fill-rule:evenodd" inkscape:connector-curvature="0"/>
</g>
<g id="g4361" style="fill:#bdbdbd;fill-opacity:1" transform="translate(1.5007304,0)">
<path d="m 60.053224,32.84773 c -2.185714,0 -3.971428,1.78571 -3.971428,3.97143 V 57.76202 H 35.110367 c -2.2,0 -3.942857,1.77142 -3.942857,3.97142 v 22.27143 c 0,2.2 1.742857,3.97143 3.942857,3.97143 h 20.971429 v 20.94286 c 0,2.2 1.785714,3.97143 3.971428,3.97143 h 22.285714 c 2.185714,0 3.928568,-1.77143 3.928568,-3.97143 V 87.9763 h 20.985714 c 2.18572,0 3.91429,-1.77143 3.91429,-3.97143 V 61.73344 c 0,-2.2 -1.72857,-3.97142 -3.91429,-3.97142 H 86.267506 V 36.81916 c 0,-2.18572 -1.742854,-3.97143 -3.928568,-3.97143 H 60.053224 z" id="rect3214" style="fill:#bdbdbd;fill-opacity:1;fill-rule:evenodd" inkscape:connector-curvature="0"/>
</g>
<g transform="matrix(1.4285714,0,0,1.4285714,-369.64604,-683.22368)" id="g3289" style="fill:#3f3f3f"/>
<g id="g5309" style="fill:#e9e9e9;fill-opacity:1" transform="translate(1.5007304,0)">
<path inkscape:connector-curvature="0" style="fill:#e9e9e9;fill-opacity:1;fill-rule:evenodd;stroke:none" id="path3273" d="m 71.235854,36.203603 -6.448691,5.915291 12.897383,0 z"/>
<path inkscape:connector-curvature="0" style="fill:#e9e9e9;fill-opacity:1;fill-rule:evenodd;stroke:none" id="path3295" d="m 71.107253,109.53472 -6.448691,-5.91529 12.897382,0 z"/>
<path inkscape:connector-curvature="0" style="fill:#e9e9e9;fill-opacity:1;fill-rule:evenodd;stroke:none" id="path3303" d="m 107.88086,72.933449 -5.96234,-6.500001 0,13.000001 z"/>
<path inkscape:connector-curvature="0" style="fill:#e9e9e9;fill-opacity:1;fill-rule:evenodd;stroke:none" id="path3305" d="m 34.45415,72.806518 5.962355,-6.500001 0,13.000001 z"/>
</g>
<path inkscape:connector-curvature="0" d="m 135.05424,57.754875 c -2.18571,0 -3.92857,1.78572 -3.92857,3.97143 l 0,22.27143 c 0,2.2 1.74286,3.98571 3.92857,3.98571 l 56.14286,0 c 2.2,0 3.92857,-1.78571 3.92857,-3.98571 l 0,-22.27143 c 0,-2.18571 -1.72857,-3.97143 -3.92857,-3.97143 z" id="path4221" style="fill:#bdbdbd;fill-opacity:1;fill-rule:evenodd"/>
<rect style="fill:#ff4872;fill-opacity:1;fill-rule:nonzero;stroke:none" id="rect3804" width="13.258252" height="4.9497476" x="141.42738" y="45.693382" rx="2" ry="2"/>
<rect ry="2" rx="2" y="45.693382" x="171.56569" height="4.9497476" width="13.258252" id="rect3806" style="fill:#84f446;fill-opacity:1;fill-rule:nonzero;stroke:none"/>
<g id="g3810" style="fill:#bdbdbd;fill-opacity:1" transform="translate(1.5007304,0)">
<path inkscape:connector-curvature="0" style="fill:#5e5e5e;fill-opacity:1;fill-rule:evenodd;stroke:#1d1d1d;stroke-width:1.50000012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" id="path3244" d="m 261.0903,49.663078 a 11.76471,11.76471 0 0 1 -23.52942,0 11.76471,11.76471 0 1 1 23.52942,0 z"/>
<path inkscape:connector-curvature="0" style="fill:#5e5e5e;fill-opacity:1;fill-rule:evenodd;stroke:#1d1d1d;stroke-width:1.50000012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" id="path3246" d="m 261.0903,96.270368 a 11.76471,11.76471 0 0 1 -23.52942,0 11.76471,11.76471 0 1 1 23.52942,0 z"/>
<path inkscape:connector-curvature="0" style="fill:#5e5e5e;fill-opacity:1;fill-rule:evenodd;stroke:#1d1d1d;stroke-width:1.50000012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" id="path3248" d="m 260.8644,73.000822 a 11.76471,11.76471 0 1 1 23.52942,0 11.76471,11.76471 0 0 1 -23.52942,0 z"/>
<path inkscape:connector-curvature="0" style="fill:#5e5e5e;fill-opacity:1;fill-rule:evenodd;stroke:#1d1d1d;stroke-width:1.50000012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" id="path3250" d="m 214.2644,73.000822 a 11.76471,11.76471 0 1 1 23.52942,0 11.76471,11.76471 0 0 1 -23.52942,0 z"/>
<path d="m 84.480854,64.854219 a 1.6842051,1.6842056 0 0 0 -1.205367,0.669649 l -5.000042,6.339341 a 1.6842051,1.6842056 0 0 0 0,2.053589 l 5.000042,6.383984 a 1.6842051,1.6842056 0 0 0 1.339297,0.669649 l 11.607241,0.04457 a 1.6842051,1.6842056 0 0 0 1.696443,-1.696372 l 0,-12.544752 a 1.6842051,1.6842056 0 0 0 -1.6518,-1.696444 L 84.659427,64.854219 a 1.6842051,1.6842056 0 0 0 -0.178573,0 z" id="path3322" style="fill:#5e5e5e;fill-opacity:1;fill-rule:evenodd;stroke:#1d1d1d;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" inkscape:connector-curvature="0"/>
<path d="m 57.854166,64.727289 a 1.6842051,1.6842056 0 0 1 1.205367,0.669649 l 5.000042,6.339341 a 1.6842051,1.6842056 0 0 1 0,2.053589 l -5.000042,6.383984 a 1.6842051,1.6842056 0 0 1 -1.339297,0.669649 l -11.607241,0.04457 a 1.6842051,1.6842056 0 0 1 -1.696443,-1.696372 l 0,-12.544752 a 1.6842051,1.6842056 0 0 1 1.6518,-1.696444 l 11.607241,-0.223216 a 1.6842051,1.6842056 0 0 1 0.178573,0 z" id="path3324" style="fill:#5e5e5e;fill-opacity:1;fill-rule:evenodd;stroke:#1d1d1d;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" inkscape:connector-curvature="0"/>
<path d="m 79.18648,86.181762 a 1.6842051,1.6842056 0 0 0 -0.669648,-1.205368 l -6.339339,-5.000043 a 1.6842051,1.6842056 0 0 0 -2.053589,0 l -6.383983,5.000043 a 1.6842051,1.6842056 0 0 0 -0.669648,1.339298 l -0.04457,11.607244 a 1.6842051,1.6842056 0 0 0 1.696371,1.696443 l 12.544749,0 a 1.6842051,1.6842056 0 0 0 1.696443,-1.6518 L 79.18648,86.360335 a 1.6842051,1.6842056 0 0 0 0,-0.178573 z" id="path3332" style="fill:#5e5e5e;fill-opacity:1;fill-rule:evenodd;stroke:#1d1d1d;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" inkscape:connector-curvature="0"/>
<path d="m 79.31508,59.556558 a 1.6842051,1.6842056 0 0 1 -0.669648,1.205368 l -6.339339,5.000043 a 1.6842051,1.6842056 0 0 1 -2.053589,0 l -6.383983,-5.000043 a 1.6842051,1.6842056 0 0 1 -0.669648,-1.339298 l -0.04457,-11.607244 a 1.6842051,1.6842056 0 0 1 1.696371,-1.696443 l 12.544749,0 a 1.6842051,1.6842056 0 0 1 1.696443,1.6518 l 0.223216,11.607244 a 1.6842051,1.6842056 0 0 1 0,0.178573 z" id="path3334" style="fill:#5e5e5e;fill-opacity:1;fill-rule:evenodd;stroke:#1d1d1d;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" inkscape:connector-curvature="0"/>
<path d="m 181.49066,64.984512 c 0.46409,0.03977 0.90674,0.285619 1.18563,0.658684 l 4.91818,6.235545 c 0.44145,0.573965 0.44145,1.446 0,2.019966 l -4.91818,6.279457 c -0.30647,0.406087 -0.80862,0.657167 -1.31737,0.658684 l -14.22758,0.04384 c -0.87542,0.007 -1.67502,-0.793175 -1.66867,-1.668596 l 0,-12.339354 c -0.007,-0.860892 0.764,-1.652128 1.62476,-1.668667 l 14.22758,-0.219561 c 0.0584,-0.0028 0.11719,-0.0028 0.17565,0 z" id="path4289" style="fill:#5e5e5e;fill-opacity:1;fill-rule:evenodd;stroke:#1d1d1d;stroke-width:1.50000012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" inkscape:connector-curvature="0"/>
<path d="m 141.75921,64.859662 c -0.46409,0.03977 -0.90674,0.285619 -1.18563,0.658684 l -4.91818,6.235545 c -0.44145,0.573965 -0.44145,1.446 0,2.019966 l 4.91818,6.279457 c 0.30647,0.406087 0.80862,0.657167 1.31737,0.658684 l 14.22758,0.04384 c 0.87542,0.007 1.67502,-0.793175 1.66867,-1.668596 l 0,-12.339354 c 0.007,-0.860892 -0.764,-1.652128 -1.62476,-1.668667 L 141.93486,64.85966 c -0.0584,-0.0028 -0.11719,-0.0028 -0.17565,0 z" id="path4291" style="fill:#5e5e5e;fill-opacity:1;fill-rule:evenodd;stroke:#1d1d1d;stroke-width:1.50000012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" inkscape:connector-curvature="0"/>
</g>
</svg>

+ 812
- 0
jm2l/static/img/2020/Hair-Tools-And-Accessories-Silhouette.svg View File

@@ -0,0 +1,812 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1920 1920" enable-background="new 0 0 1920 1920" xml:space="preserve">
<g id="_x23_000000ff">
<path stroke="#000000" stroke-width="0.0938" d="M1698.9879,12.1671c11.09-4.64,23.5599-2.62,34.89,0.1
c2.8099,0.87,6.13,1.12,8.23,3.46c2.5599,2.35,5.1699,4.8,6.5499,8.08c7.77,1.18,14.1901-4.6,21.8101-4.77
c2.6699,3.37,5.6699,6.73,6.41,11.13c-6.91,4.62-15.67,2.78-23.1101,5.82c8.64,3.21,17.4601-2.02,26.2401-0.31
c3.6599,0.72,6.74,3.01,9.5099,5.42c-1.5599,3.97-5.23,6.38-7.99,9.43c3.2301,2.22,7.49,3.18,9.5801,6.79
c-4.0901,5.09-5.85,12.08-2.87,18.17c-2.6801,1.13-5.49,2.22-7.38,4.54c2.51,1.14,6.4199,0.64,7.5599,3.76
c-1.33,4.12-3.95,7.63-6.0599,11.35c2.1699,2.21,4.6699,4.16,6.3199,6.85c-2.15,2.3-4.4399,4.45-6.49,6.82
c2.05,2.84,4.6901,5.22,6.61,8.18c-3.3099,4.91-9.52,5.26-14.78,6.17c5.26,1.72,11.03,2.63,15.2301,6.59
c-1.65,1.88-3.6101,3.75-4.03,6.32c-0.71,4.02,0.6799,7.95,1.5499,11.82c-3.5,3.77-8.6899,4.24-13.47,4.86
c5.39,3.12,13.1,2.91,16.26,9.13c-2.29,5.87-9.15,5.45-14.2,6.85c3.58,3.71,9.76,2.69,13.08,6.96
c-4.5699,5.95-1.62,13.45,1.6901,19.18c-6.01,3.7-13.3201,1.68-19.7201,3.97c3.2101,1.97,6.9701,2.01,10.61,2.37
c3.2101,0.22,5.4601,2.78,7.5901,4.91c-1.03,4.6-5.5,6.63-9.36,8.38c3.5699,0.72,9.49,0.56,10.0299,5.34
c0.5601,4.8-4.25,6.99-7.08,9.84c0.91,2.93,4.89,2.52,7.21,3.93c-0.3199,3.94-1.74,8.04-5.5399,9.88c2.24,2.15,3.96,4.74,5.51,7.42
c-2.39,2.78-5.1001,5.58-8.77,6.5c-4.9301,1.15-9.98-0.27-14.9501,0.26c-0.76,2.49-0.23,5.75-2.46,7.52
c-3.62,2.55-7.8199-0.6-11.74-0.41c-1.87,4.96,0.09,10.05-0.1,15.1c-0.17,4.59-4.61,6.92-6.87,10.41
c-4.39,7.04-6.5901,15.39-6.4,23.68c0.13,10.52,3.46,20.61,6.1,30.69c6.35,22.84,6.75,46.77,6.5,70.31
c-0.26,13.33-0.62,26.66-0.9,39.99c0.3,26.01-1.6799,51.98-1.6699,77.99c-0.8101,14.33-2.7001,28.59-3.05,42.95
c-0.71,7.77-0.61,16.29-5.22,22.96c-5.51,6.68-14.51,9.12-22.8,9.89c-7.97,0.62-17.11,0.09-23.1-5.91
c-7.45-6.77-9.47-17.32-9.74-26.95c0.0599-23.96-0.27-47.93,0.03-71.9c0.11-32.35-1.11-64.71,0.0499-97.05
c0.53-13.11-1.47-26.76,3.25-39.33c2.6-7.33,2.3-15.26,4.25-22.74c2.9301-11.82,7.0701-23.61,6.74-35.94
c-0.1-6.29-2.01-12.6-5.88-17.6c-3.59-4.77-8.38-9.26-9.09-15.51c-1.12-5.29,3.84-9.72,2.59-15.01c-0.7-1.49-2.73-1.41-4.0499-1.86
c-9.73-2.14-19.3,2.05-29.01,1.82c-5.35-3.81-8.5601-10.96-6.48-17.42c0.99-3.26,3.75-5.44,6.25-7.56
c-1.49-1.94-3.62-3.19-5.35-4.87c-0.0601-4.35,0.2999-9.12,3.7899-12.21c-2.23-2.04-4.39-4.19-5.96-6.79
c1.95-3.35,4.64-6.38,8.52-7.44c-2.2201-2.77-5.23-5.72-4.8201-9.57c0.55-2.54,2.92-3.99,4.77-5.57
c-3.0599-1.83-6.13-3.96-7.5499-7.38c1.9099-2.34,4.4099-4.54,7.6699-4.32c3.28,0.16,6.6-0.68,8.76-3.34
c-3.74-3.53-9.63-0.44-13.1799-4.08c-2.4901-1.72-0.79-5.16,0.9099-6.83c4.04-3.14,9.55-2.49,14.1901-4.22
c-3.61-3.82-9.6-1.33-13.55-4.45c-0.74-0.55-1.4399-1.12-2.11-1.71c0.4-3.03,1.26-6.01,1.41-9.07c0.11-2.67-1.85-4.71-2.9401-6.96
c3.3101-5.7,10.66-5.09,16.14-7.04c-4.6-3.01-10.7999-1.17-15.09-4.72c-2.26-1.41-0.8-4.68,0.5-6.33
c3.47-3.14,8.5599-2.77,12.85-3.97c-4.3-3.29-11.65-3.1-13.42-9.13c-1.1399-4.44,4.8401-4.77,7.38-6.8
c-2.14-1.53-4.83-2.34-6.5399-4.4c-0.04-2.34,0.5699-4.63,0.7899-6.95c2.54-3.28,6.74-3.39,10.55-3.36
c-3.13-1.95-6.96-1.46-10.27-2.79c-2.1899-0.99-4.11-4.27-1.86-6.18c3.83-3.83,9.99-2.35,14.42-5.14
c-2.42-4.18-7.36-2.16-11.1801-2.95c-2.3099-0.63-5.21-2.86-4.0599-5.55c1.1599-2.27,3.2799-3.84,4.88-5.79
c-2.14-2.26-4.28-4.79-4.7201-7.99c-0.9399-6.66,1.63-13.08,2.9601-19.5c11.0499-4.77,24.2699-6.08,35.1399-0.09
C1687.6678,21.3471,1692.2079,14.9471,1698.9879,12.1671 M1704.4579,569.4371c-1.51,2.24-1.54,5.02-1.83,7.61
c2.3099,2.69,4.8199,5.61,8.3999,6.56c7.17,2.37,15.39-5.47,13.4701-12.69
C1721.3079,563.2671,1708.7778,562.3671,1704.4579,569.4371z"/>
<path stroke="#000000" stroke-width="0.0938" d="M40.8578,32.8271c15.2-3.81,31.07-2.27,46.51-1.16c4.55,0.3,9.84,0.93,12.49,5.18
c-1.83,1.17-3.8,2.26-6.02,2.43c-8.95,0.81-17.96,0.57-26.95,0.83c-5.31,0.2-10.84,0.45-15.65,2.98
c10.24,1.14,20.5-0.66,30.73-1.06c1.45-0.16,2.27,1.24,3.29,1.98c-8.04,1.29-16.17,2.36-24.33,2.04c-3.28-0.27-6.43,0.78-9.27,2.34
c11.78-0.02,23.54-1.14,35.32-1.44c4.65,0.02,9.87-1.86,13.94,1.27c-16.05,2.83-32.57,1.17-48.62,4.11
c6.13,1.26,12.43,1.13,18.64,0.73c5.16-0.44,11.01-2.48,15.57,1c-11.31,2.36-23.1,0.43-34.33,3.33
c16.18,2.38,32.48-2.02,48.68-0.04c-1.52,0.8-2.99,2.02-4.8,1.97c-10.72-0.34-21.33,1.67-32.03,1.88
c-3.69-0.12-7.62-0.54-10.9,1.53c10.62,0.07,21.28-0.28,31.87-0.98c0.22,0.52,0.66,1.55,0.88,2.06
c-10.63,2.75-21.85,0.67-32.47,3.52c16,1.88,32.07-1.85,48.06-0.15c-1.68,1.05-3.46,2.32-5.56,2.1
c-9.67-0.44-19.28,1.19-28.94,1.44c-4.71,0.33-9.83-0.88-14.08,1.78c10.38,0.84,20.8-1.11,31.18-0.13c1,0.19,1.93,0.57,2.8,1.11
c-4.74,1.94-10.01,1.12-14.98,1.9c-6.15,0.91-13.55-2.22-18.61,2.62c16.26-0.49,32.51-1.5,48.78-1.14
c-3.62,3.88-9.09,1.74-13.69,2.22c-11.3,0.69-22.73,0.54-33.9,2.66c10.98,1.57,22.1-1.14,33.03,0.83
c-6.25,3.43-13.66,2.83-20.54,2.88c-4.11-0.12-8.49-0.62-12.23,1.5c15.66,0.9,31.33-0.55,46.99-0.38
c-3.28,3.69-8.46,1.67-12.72,2.09c-9.01,0.57-18.05,0.66-27.06,1.24c-2.62,0.04-5.04,1.07-7.27,2.37
c10.84,0.56,21.75-1.77,32.55,0.1c-9.98,5.44-21.83,0.52-32.2,4.05c11.61,0.77,23.31,0.13,34.96,0.38
c4.24,0.42,9.54-2.85,12.7,1.34c-15.79,1.99-31.93-0.22-47.57,3.18c10.84,1.43,21.8-1.26,32.6,0.71c-2.58,1.71-5.66,2.44-8.74,2.2
c-7.84-0.43-15.77-0.29-23.48,1.33c15.71,2.31,31.63-0.3,47.41,0.71c-1.47,1.02-2.98,2.35-4.89,2.24
c-12.03-0.73-24.02,1.25-36.05,0.65c-2.42-0.25-4.7,0.67-6.75,1.86c10.98,1.48,22.11-0.84,33.07,0.9
c-10.06,4.98-21.82-0.69-32.1,3.47c11.21,0.79,22.48,0.58,33.72,0.9c4.44,0.4,9.47-2.33,13.22,1.13
c-15.44,2.43-31.3-0.22-46.68,2.84c8.42,1.63,17.03,0.49,25.52,0.21c2.44-0.18,4.73,0.77,6.77,2.02
c-10.79,2.73-22.32-0.85-32.94,2.71c14.02,1.78,28.14-0.78,42.2,0.02c2.08,0.04,3.9,1.14,5.68,2.1c-15.19,2.4-30.79-0.67-45.89,2.6
c6.67,0.22,13.37,1.38,20.04,0.53c3.64-0.39,7.78-1.03,10.75,1.66c-10.46,2.45-21.39-0.5-31.83,2.16
c11.31,1.51,22.76,1.24,34.15,1.47c4.22,0.34,9.11-2.19,12.6,1.28c-15.16,2.16-30.58-0.13-45.73,1.99
c10.44,2.11,21.19-0.69,31.63,1.46c-1.95,1.16-4,2.36-6.36,2.29c-8.52,0.06-17.4-1.61-25.65,1.28c13.81,1.44,27.71,0.03,41.56,0.56
c1.94-0.04,3.44,1.32,4.93,2.35c-13.62,0.72-27.28,0.62-40.92,0.56c-1.7,0.02-3.34,0.49-4.96,0.95
c10.52,1.72,21.27,0.25,31.83,1.69c-9.9,5.57-21.78-0.92-31.91,3.7c15.31,0.96,30.67,0.32,46,1c-1.24,0.8-2.31,2.14-3.9,2.26
c-14.04,1.01-28.31-1.79-42.19,1.26c10.55,1.56,21.32-0.78,31.8,1.51c-10.06,4.64-21.54-0.34-31.92,2.81
c15.49,2.24,31.23,0.5,46.77,2.13c-3.91,3.24-8.99,0.83-13.51,1.27c-11.13,0.46-22.37-0.06-33.42,1.51
c10.69,2.04,22.3-2.21,32.51,2.74c-10.72,2.18-21.88-1.01-32.5,1.99c15.51,1.96,31.26-0.1,46.73,2.25
c-4.29,3.08-9.56,0.72-14.36,1.11c-10.79,0.28-21.71-0.95-32.38,1.16c10.78,1.94,21.83,0.15,32.67,1.72
c-1.64,0.89-3.26,2.01-5.16,2.22c-9.04,0.83-18.7-2.48-27.33,1.36c13.75,1.24,27.57-0.06,41.33,0.69c2.02,0.12,3.81,1.12,5.48,2.16
c-11.19,0.64-22.41,0.67-33.61,0.68c-4.44,0.11-9.16-1.58-13.29,0.82c10.98,0.83,22.1-0.1,32.97,1.95
c-8.1,3.36-17.08,1.64-25.54,1.17c-2.54-0.25-5,0.45-7.35,1.34c15.59,1.42,31.28,1.16,46.9,2c-1.38,1.08-2.78,2.43-4.68,2.33
c-12,0.31-24.01-0.43-35.99-0.98c-1.93-0.1-3.77,0.53-5.59,1.04c9.06,1.77,18.34,0.47,27.49,1.12c1.72-0.12,3.2,0.71,4.51,1.73
c-2.49,1.68-5.62,1.4-8.47,1.28c-7.8-0.46-15.81-1.46-23.42,0.88c1.82,0.31,3.65,0.63,5.51,0.7c13.78,0.33,27.56,0.72,41.3,1.82
c-3.57,3.06-8.18,1.16-12.34,1.27c-7,0.05-13.99,0.41-20.99,0.33c-4.33,0.07-8.9-1.39-12.96,0.74c10.63,0.5,21.33,0.37,31.9,1.81
c-4.85,2.72-10.58,2.1-15.92,1.96c-5.59-0.29-11.55-2.23-16.87,0.48c15.52,2.14,31.36,0.56,46.84,3.18
c-2.2,0.9-4.54,1.63-6.95,1.39c-11.01-0.59-22.05-0.44-33.04-1.3c-2.09-0.34-4.07,0.5-5.92,1.37c10.55,1.15,21.29,0.34,31.72,2.56
c-6.19,3.31-13.18,0.4-19.77,0.96c-4.43,0.51-9.02-1.3-13.27,0.53c15.72,3.79,32.11,1.19,48.03,3.45
c-4.04,3.2-9.18,0.89-13.79,1.13c-11.04,0.01-22.1-0.69-33.11,0.17c10.76,2.18,21.84,1.01,32.65,2.74
c-1.98,1.11-4.1,2.14-6.43,2.08c-5.7,0.11-11.38-0.48-17.07-0.41c-3.54,0.18-7.36-1.51-10.57,0.66c15.94,2.21,32.4-0.16,48.07,4.14
c-8.12,0.69-16.27,0.25-24.4-0.01c-0.7,0.6-1.4,1.2-2.11,1.79c4.14,0.18,8.31,0.49,12.34,1.5c-6.73,3.53-14.24,0.05-21.37,0.88
c-3.9,0.62-8.27-2.12-11.69,0.69c14.62,1.23,29.28,2.28,43.93,2.74c1.39,0.21,2.44,1.25,3.6,1.95c-15.5,1.71-31.13-2.65-46.6-0.04
c10.56,1.8,21.36,0.81,31.94,2.45c-5.11,3.8-11.43,0.89-17.14,0.98c-5.31,0.17-10.99-0.98-15.96,1.38
c15.86,1.39,31.88,1.27,47.69,3.42c-1.75,0.96-3.65,1.84-5.7,1.56c-10.09-0.73-20.22-0.53-30.32-1.11
c-3.53-0.41-7.33-1.29-10.57,0.75c8.33,0.44,16.62,1.47,24.98,1.31c2.69-0.1,5.25,0.86,7.5,2.28c-10.93,1.86-21.98-1.84-32.9,0.14
c13.94,2.54,28.18,2.55,42.28,3.34c1.77-0.03,3.2,1.09,4.62,1.98c-11.21,0.9-22.42-0.62-33.62-0.99
c-4.44-0.06-9.29-1.77-13.31,0.94c11.01,0.49,22.01,1.25,32.94,2.69c-2.07,1.11-4.27,2.2-6.7,1.89
c-8.57-0.54-17.32-2.46-25.83-0.36c15.41,2.78,31.4,0.91,46.65,4.9c-15.13,1.85-30.29-2.27-45.44-0.47c0,0.13,0,0.38,0,0.51
c9.51,0.99,19.1,0.89,28.61,1.88c1.02,0.39,1.71,1.31,2.55,1.98c-10.67,1.79-21.48-2.02-32.11,0.23
c11.48,1.15,23.01,1.96,34.49,3.23c4.05,0.55,8.73-1.03,12.04,2.12c-7.66,0.18-15.34,0.08-23.01-0.14
c-7.5-0.2-15.18-2.85-22.59-0.57c10.39,1.54,21.34,0.25,31.29,4.2c-10.59,1.85-21.28-2.12-31.85,0.11
c15.32,2.09,30.84,2.49,46.16,4.67c-4.6,2.38-9.87,1.28-14.81,1.16c-10.27-0.88-20.53-2.23-30.86-1.7
c10.27,2.88,21.24,1.46,31.67,3.74c-1.81,0.95-3.71,1.86-5.79,1.9c-8.41-0.04-16.9-2.39-25.28-0.78
c14.87,2.4,29.97,2.76,44.92,4.51c-3.31,3.11-7.86,1.35-11.82,1.15c-9.68-0.46-19.31-1.69-29-1.84c-1.94-0.14-3.81,0.44-5.62,1.09
c10.84,0.49,21.62,1.74,32.41,2.85c-1.98,1.3-4.27,2.25-6.69,1.99c-8.43-0.64-16.92-2.28-25.38-1.11
c15.21,3.09,31.28,1.2,46.07,6.48c-15.03,0.59-29.95-3.06-44.97-1.71c10.17,2.26,20.87,0.97,30.89,4.02
c-2.46,0.99-5.09,1.77-7.76,1.2c-7.39-1.19-14.97-1.69-22.38-0.38c14.62,2.25,29.79,1.16,44.02,5.64
c-14.68,1.26-29.23-3.02-43.92-1.7c9.93,1.64,20.05,2.01,29.91,4.07c-1.76,0.74-3.58,1.57-5.55,1.4
c-7.68-0.42-15.29-1.65-22.97-2.13c-1.69-0.27-3.17,0.62-4.6,1.35c16.04,1.57,32.13,3.08,48.08,5.36c-1.36,0.78-2.76,1.7-4.42,1.54
c-10.4-0.01-20.71-1.65-31.06-2.5c-4.42-0.17-8.96-2.2-13.27-0.23c11.19,1.55,22.5,2.21,33.63,4.14c-9.65,3.81-19.8-1.7-29.64,0.39
c14.44,3.42,29.76,1.78,43.88,6.79c-3.06,4.9-9.17,4.25-14.13,4.86c-10.03,1.96-20.19,5.97-27.13,13.75
c-5.39,5.9-8.1,13.76-8.99,21.6c-2.44,19.92-2.45,40.01-3.32,60.03c-3.03,53.66-5.55,107.34-7.92,161.03
c-1.01,16.6801-2.04,33.4-4.98,49.8701c-5.56-3.42-3.99-10.41-3.74-15.82c-0.48-24.67-0.34-49.34-0.23-74
c0.51-155.36,0.23-310.78-6.55-466.02c-0.49-13.56-3.85-27.21-1.21-40.73C28.6578,41.1071,33.6378,34.5071,40.8578,32.8271
M58.5178,232.4071c6,1.02,12.11,0.74,18.16,1.25c0.79-0.59,1.59-1.17,2.39-1.75
C72.2178,232.5071,65.1678,230.1671,58.5178,232.4071z"/>
<path stroke="#000000" stroke-width="0.0938" d="M1479.7878,41.2271c0.03-3.7-0.0399-7.56,1.75-10.93
c2.62,0.25,5.55,0.53,7.51,2.55c3.25,3.26,4.48,7.87,6.88,11.72c8.98,0.84,15.6901,7.7,20.8,14.53
c9.11,12.61,14.9399,27.51,17.37,42.84c1.63,11.19,1.26,23.57-5.4501,33.16c0.99,5.95,2.7201,11.89,1.88,17.98
c-2.34,0.63-5.01,1.98-7.2799,0.45c-2.03-1.53-2.8601-4.04-4.12-6.15c-1.66,3.46-1.77,7.65-4.29,10.66
c-5.48,1.41-7.26-5.32-11.3101-7.42c-0.21,3.5,0.4501,7.08-0.36,10.53c-1.13,3.77-6.83,2.95-8.46,0.01
c-2.05-3.53-2.4401-8.04-5.92-10.65c-2.7,5.69,3.51,11.11,0.73,16.82c-2.3999,0.16-5.1599,0.91-7.23-0.66
c-3.5299-2.93-3.2999-9.13-8.34-10.42c0.4399,5.59,4.5699,10.6,2.8,16.41c-3,0.19-6.4301,0.46-8.74-1.84
c-2.9901-3.12-3.9501-7.52-6.1001-11.16c-3.1499,3.77-0.2799,8.25,0.3101,12.36c0.46,2.16,0.0599,5.09-2.21,6.07
c-2.7401,0.58-5.9801-0.54-7.05-3.28c-1.91-4.1-2.1-9.92-7.2-11.5c-0.2101,4.72,1.73,9.02,2.96,13.46c0.98,2.72-1.01,5-2.63,6.91
c-2.4401-0.35-5.2001-0.97-6.37-3.39c-2.0801-3.98-2.5-9.14-6.6801-11.68c-3.88,6.12,4.2001,11.88,1.8201,18.14
c-1.1801,3.69-6.64,2.21-8.39-0.32c-2.8101-4.31-2.6801-9.87-5.6901-14.11c-1.1699,0.94-3.1599,1.68-2.7799,3.56
c0.2,4.96,4.1899,9.58,2.38,14.62c-1.2201,3.39-6.28,2.34-8.03-0.04c-2.38-3.54-2.62-8.38-6.3-11.04
c-1.36,2.67-1.24,5.71,0.13,8.34c1.39,3.11,3.05,7.59-0.11,10.19c-2.8199,0.54-6.24,0.34-8.04-2.19
c-2.21-3.26-2.64-7.32-4.33-10.83c-3.6,4.11-0.27,9.34-0.03,13.96c0.3101,2.87-3.12,5.37-5.6699,3.82
c-6.38-2.69-4.9401-11.84-10.76-15.13c-1.66-1-3.5901-0.06-5.25,0.32c-4.75,1.52-9.3201,3.59-14.2101,4.64
c0.01,4.15,0,8.3,0.02,12.45c-18.77,7.63-37.39,17.05-57.88,18.79c-9.89,1.06-19.97-1.14-28.61-6.01
c-19.08-2.33-38.11,2.87-55.75,9.76c-20.7999,8.14-41.98,15.25-62.91,23.03c-35.76,13.03-71.59,25.97-108.0699,36.85
c-5.59,1.42-12.09,3.93-17.3301,0.16c-7.46-5.1-10.34-14.33-12.59-22.64c-1.88-7.31-2.91-14.79-4.09-22.23
c45.08-20.78,91.7-37.97,138.3101-54.95c16.6499-6.06,33.3099-12.07,50.1-17.74c17.03-6.01,34.8199-13.19,46.6599-27.45
c1.39-4.48,3.3401-8.8,4.41-13.38c19.25-15.06,42.76-23.15,65.86-30.22c6.1801-1.78,7.0901,7.8,12.99,7.12
c6.62,0.25,11.9401-4.39,18.2101-5.7c-0.4401-6.66-3.1901-13.09-2.01-19.84c2.14,0.74,4.49,1.37,6.1,3.11
c3.1,3.16,4.27,7.57,6.5,11.31c2.05-0.7,2.24-3.33,1.89-5.14c-0.58-4.07-3.15-8.05-1.9301-12.23c1.0601-2.35,4.6801-4.6,6.87-2.32
c3.3201,3.99,3.11,10.5,8.17,13.09c2.58-4.4-1.42-8.35-2.47-12.49c-0.79-2.24,0.5499-4.28,1.6699-6.09
c2.3601,0.22,5.4401-0.16,6.9,2.22c2.62,4.01,2.01,9.68,6.12,12.83c4.97-2.58,0.8301-8.01,0.0901-11.88
c-1.4701-3.24-0.3401-8.03,3.75-8.37c7.48,1.17,4.0599,11.77,10.25,14.58c1.21-1.24,2.23-3.06,1.37-4.8
c-1.8-4.06-4.4601-8.05-3.63-12.73c1.86-0.55,3.63-1.39,5.1599-2.62c7.74,1.14,5.9501,11.04,11.38,14.93
c4.53-5.65-3.85-12.16-0.4299-18.09c1.47-2.84,5.2999-2.05,7.1,0.02c3.25,3.66,3.15,9.2,6.7,12.69
c3.54-6.61-4.23-14.27,1.0901-20.42c2.13,0.57,4.72,0.95,5.9099,3.1c2.2101,3.7,2.66,8.17,4.99,11.84
c1.28-0.74,3.0801-1.39,3.0701-3.19c-0.0701-5.08-3.3201-10.61,0.1699-15.28c2.4,0.28,5.3501,0.14,7.03,2.27
c2.4601,3.1,2.8301,7.23,4.38,10.78c5.14-5.35-3.7899-12.95,1.42-18.17c2.36-0.52,5.24-0.25,6.9,1.74
c2.48,2.98,3.14,7.25,6.5499,9.5c0.8101-5.28-4.2-9.61-2.75-15.05c2.6901-0.15,5.6-0.62,8.12,0.71
C1475.8679,37.6371,1477.7579,39.5371,1479.7878,41.2271z"/>
<path stroke="#000000" stroke-width="0.0938" d="M193.4378,55.2971c5.26-3.95,12.09-5.14,18.52-4.48c14.77,1.45,29.15,5.64,44,6.51
c11.25,1.07,23.23,1.15,33.28,7c-8.17,3.83-17.33,4.87-26.25,4.72c-13.55-0.49-27.39-2.6-40.71,1.01
c18.55,5.34,37.89-1.54,56.6,2.35c3.58,0.69,7.02,1.93,10.36,3.38c-6.12,2.54-12.63,4.11-19.26,4.39
c-15.85,0.8-31.95-3.05-47.58,1.08c17.54,5.11,35.85-0.71,53.64,2.02c4.56,0.63,8.96,2.02,13.21,3.75
c-8.93,6.18-20.21,4.61-30.37,3.66c-13-0.37-26.19-0.69-38.98,2.07c9.13,5.37,20.04,2.42,29.99,2.3
c13.11-0.15,26.75-1.38,39.3,3.24c-10.37,5.92-22.73,4.9-34.21,4.65c-12.38,0.13-25.04-2.63-37.17,0.99
c23.15,8.28,48.35-2.66,71.49,5.75c-2.79,1.97-5.89,3.61-9.31,4.08c-8.97,1.42-17.96-0.82-26.96-0.7
c-11.86,0.16-23.85-0.05-35.51,2.39c1.81,1.25,3.68,2.55,5.91,2.9c21.88,1.85,44.47-4.2,65.88,2.59c-2.34,2.2-5.02,4.21-8.25,4.82
c-9.91,2.31-20-1.2-29.98-0.06c-11.97,1.37-24.07-0.76-36.01,1.03c1.78,2.67,4.82,3.46,7.87,2.79c4.32-0.93,8.63,0.39,12.96-0.12
c4.32-0.41,8.66,0.37,12.98-0.15c4.35-0.64,8.67,0.74,13.04,0.34c9.13-0.48,18.84-1.74,27.32,2.58c-3.36,3.09-7.68,4.96-12.21,5.4
c-9.72,0.98-19.39-1.26-29.11-0.79c-10.88,0.42-21.78,0.47-32.63,1.37c3.03,3.22,7.61,3.44,11.69,2.6
c9.61-1.83,19.26,1.05,28.92,0.4c8.3-0.34,16.75-2.13,24.97-0.13c3.22,0.71,5.97,2.63,8.37,4.82c-24.39,7.41-50.18-1.19-74.75,4.67
c18.72,4.23,37.86-0.32,56.78,0.84c6.25,0.37,14.16-0.29,18.05,5.74c-25.11,7.63-51.57-1.1-76.93,4.54
c12.98,4.67,27.02,3.19,40.55,3.34c12.05-0.21,25.59-4.08,36.33,3.36c-25.17,7.77-51.83-1.08-77.27,4.71
c2.94,3.5,7.8,3.54,11.94,2.75c9.95-1.87,19.95,1.25,29.96,0.36c11.75-0.76,24.66-3.11,35.27,3.49
c-25.19,7.96-51.96-1.41-77.37,4.87c3.22,3.15,7.87,3.45,12.06,2.59c9.98-1.9,20.01,1.25,30.05,0.34
c11.78-0.72,24.68-2.87,35.37,3.56c-25.24,7.88-51.98-1.37-77.47,4.73c5.52,5.61,13.45,1.62,20.13,1.98
c8.62,0.6,17.28,1.71,25.93,0.75c10.49-0.98,21.97-2.02,31.35,3.81c-25.01,9.7-52.19-0.16-77.79,5.67
c25.54,6.31,52.83-4.44,77.76,5.74c-8.36,3.19-17.31,4.58-26.24,4.52c-16.44,0.15-33.18-3.07-49.37,1.1
c24.86,6.13,51.38-4.4,75.62,5.63c-9.3,3.49-19.3,4.66-29.19,4.58c-15.2,0.07-30.5-2.43-45.63,0.05
c10.05,5.41,21.8,2.35,32.62,2.18c14.1-0.02,29.03-1.77,42.2,4.41c-24.21,10.18-50.84-0.54-75.69,5.75
c24.61,8.23,51.11-2.76,75.69,5.62c-10.83,4.39-22.72,5.01-34.27,4.5c-13.85-0.72-27.97-2.16-41.62,1.14
c24.71,8.2,51.28-2.64,75.99,5.67c-10.1,6.52-22.51,4.44-33.77,3.57c-13.36-0.12-26.91-0.65-40.05,2.21
c9.69,5.22,21.04,2.53,31.47,2.2c14.11-0.08,28.66-1.37,42.28,3.22c-5.73,6.01-14.6,6.22-22.3,5.63
c-16.83-1.81-33.77-0.5-50.62,0.28c23.7,7.92,49.34-2.85,72.96,5.59c-8.8,7.08-20.82,5.62-31.35,5.66
c-13.39,0.25-26.82-1.86-40.16-0.05c6.67,4.03,14.75,3.26,22.2,2.93c9.29-0.87,18.64-0.87,27.97-1.02
c7.43-0.01,15.53,0.8,21.35,5.94c-22.57,6.88-46.27,0.38-69.24,3.5c2.75,1.57,5.76,2.71,8.94,2.94c8.69,0.77,17.34-0.91,26.03-0.86
c11.46,0.01,23.25-0.39,34.23,3.43c-7.61,8.04-19.58,5.53-29.39,4.82c-13.48-0.3-27.18-0.75-40.46,2.02
c11.02,2.34,22.37,2.22,33.58,2.25c8.86,0.17,17.72-2.12,26.56-0.66c3.71,0.58,7,2.56,9.62,5.19c-20.9,6.86-42.99,0.32-64.3,3.5
c8.35,2.94,17.34,2.12,26,1.49c13.25-1.02,27.6-1.86,39.49,5.18c-9.35,5.14-20.25,6.35-30.75,5.71c0.02,0.35,0.07,1.06,0.1,1.41
c10.33-1.07,21.16-0.21,30.7,4.19c-2.25,2.63-4.99,5-8.42,5.87c-8.22,2.37-16.68-0.24-25.01-0.22
c-11.39,0.02-22.76,0.73-34.13,1.14c15.36,4.81,31.42-0.01,47.08,1.07c7.12,0.36,14.17,2.25,20.4,5.74
c-5.17,2.43-10.63,4.34-16.32,5.06c-17.48,2.68-35.2-2.83-52.61,0.66c11.95,3.52,24.4,0.79,36.58,0.94
c10.92-0.25,22.67-1.19,32.47,4.6c-5.41,5.89-13.94,6.3-21.38,5.53c-15.79-1.94-31.71-0.39-47.53,0.26
c11.85,3.8,24.35,0.48,36.48,0.92c10.91-0.14,24.14-2.22,32.35,6.77c-23.17,9.46-48.39,0.99-72.37,4.61
c19.46,5.52,39.71-1.78,59.33,2.26c4.55,0.87,8.92,2.5,13.07,4.55c-10.42,7.04-23.51,6.07-35.46,5.68
c-12.65,0.15-25.33-1.75-37.95-0.07c12.16,2.46,24.64,2.19,36.99,2.23c9.12,0.11,18.37-2.64,27.4-0.24
c3.59,0.85,6.51,3.22,8.98,5.86c-23.79,9.36-49.57,0.96-74.1,4.66c19.94,5.63,40.7-2.16,60.78,2.14c4.65,0.88,9.11,2.54,13.34,4.62
c-3.46,2.23-7.21,4.12-11.31,4.84c-9.32,1.88-18.75-0.42-28.13-0.31c-12.07,0.04-24.13,0.59-36.18,1.18
c24.91,5.93,51.41-4.43,75.67,5.56c-3,2.72-6.48,5.04-10.49,5.93c-9.84,2.35-19.99,0.68-29.97,0.8c-11.16-0.08-22.4-1.5-33.52,0.06
c11.97,2.5,24.3,2.09,36.46,2.21c9.44,0.11,18.94-2.59,28.32-0.51c3.51,0.68,6.55,2.7,9.14,5.09c-11.23,5.8-24.19,4.87-36.41,4.57
c-13.08,0.25-26.45-2.77-39.27,1.02c12.54,3.01,25.55,1.93,38.3,1.38c9.34-0.53,18.71-0.36,28.06-0.23
c3.69,0.02,6.82,2.33,8.35,5.63c-9.68,6.24-21.63,4.68-32.47,3.69c-14.07-0.6-28.16,0.46-42.22,0.98
c7.92,2.11,16.19,2.03,24.31,1.57c9.63-0.71,19.3-0.66,28.95-0.95c7.97-0.25,16.56,1.23,22.42,7.09
c-24.64,9.47-51.19,1.04-76.6,4.59c12.24,2.45,24.79,2.21,37.21,2.24c9.65-0.01,19.4-2.43,28.97-0.28
c3.71,0.86,7.28,2.45,10.23,4.88c-6.76,5.38-15.84,6.2-24.16,5.5c-17.03-1.94-34.18-0.41-51.24,0.23
c12.93,2.3,26.11,2.15,39.19,2.03c8.96-0.14,18.05-2.51,26.92-0.24c3.21,0.77,5.9,2.77,8.4,4.85c-6.17,6.14-15.38,6.09-23.45,5.46
c-16.35-1.75-32.82-0.41-49.18,0.35c11.23,2.54,22.85,1.94,34.29,2.07c9.53,0.08,19.11-2.48,28.59-0.51
c3.97,0.75,7.64,2.62,10.81,5.12c-3.31,2.15-6.88,3.98-10.78,4.74c-9.81,2.07-19.76-0.41-29.63-0.21
c-11.55,0.19-23.11,0.44-34.63,1.27c13.41,2.27,27.08,2.19,40.63,1.93c11.49-0.78,24.17-3.11,34.49,3.53
c-2.85,2.53-6.2,4.6-10.01,5.24c-9.13,1.66-18.3-0.75-27.45-0.68c-12.39,0.05-24.91-0.24-37.11,2.24
c12.88,2.61,26.09,2.07,39.15,2.12c8.76-0.03,17.58-2.36,26.28-0.4c3.45,0.71,6.39,2.73,9.06,4.94c-23.9,9.56-49.81,1-74.51,4.63
c18.09,5.05,36.81-0.53,55.16,1.38c6.72,0.61,13.32,2.47,19.38,5.45c-10.05,7-22.79,6.23-34.42,5.71
c-13.05,0.15-26.14-1.83-39.15-0.07c20.28,5.19,41.22-1.48,61.64,2.18c4.08,0.72,8.06,1.93,11.93,3.43
c-2.59,3.02-5.9,5.53-9.87,6.31c-8.82,2-17.73-0.75-26.6-0.64c-11.85,0.09-23.7,0.68-35.54,1.18c16.89,4.85,34.43-0.29,51.59,1.12
c7.07,0.49,14.06,2.34,20.36,5.63c-14.28,7.38-30.81,6.05-46.3,4.95c-8.27-0.5-16.61-0.68-24.83,0.58
c19.65,5.51,40.14-1.5099,59.99,2.38c3.84,0.72,7.56,1.93,11.21,3.34c-5.38,5.94-13.81,7.17-21.41,7.12
c-8.02-0.41-16.06-0.16-24.08-0.58c-8.13-0.31-16.33-0.94-24.41,0.31c14.17,4.09,29,1.06,43.44,0.77
c9.08,0.13,18.43,1.5,26.42,6.08c-5.66,3.81-12.63,5.02-19.34,4.37c-15.44-1.87-31.04-0.7-46.49,0.31
c9.73,5.38,20.97,1.92,31.43,1.93c11.6,0.03,24.31-1.76,34.68,4.75c-5.6,2.45-11.74,3.13-17.73,4.01
c-15.43,2.07-30.97,3.42-46.54,3.69c4.46,0.88,9.04,0.86,13.57,0.93c13.19,0.24,26.41-0.1,39.57,1.06
c3.84,0.47,8.03,0.77,11.11,3.42c-4.3,3.12-9.45,4.73-14.61,5.74c-14.18,2.74-28.8,2.17-42.93,5.26
c-11.35,2.15-23.42,5.01-34.73,1.19c-7.47-2.55-12.71-9.19-15.37-16.4c-4.81-12.7599-6.1-26.47-7.44-39.93
c-1.86-23.36-4.47-46.64-6.19-70.01c-9.6-122.45-8.92-245.88,5.23-367.96c2.08-17.37,1.67-35.15,6.44-52.11
C183.2078,68.1071,186.8078,60.2371,193.4378,55.2971 M225.7078,333.5371c10.15,3.14,20.89,1.82,31.3,1.22
c0.49-0.64,1-1.26,1.53-1.87c-2.19,0.7-4.5,0.24-6.73,0.19C243.1278,332.3671,234.2978,331.7471,225.7078,333.5371z"/>
<path stroke="#000000" stroke-width="0.0938" d="M375.5478,88.5971c6.09-4.49,13.94-5.82,21.35-5.14
c17.61,1.45,34.54,6.86,51.62,11.01c5.19,1.03,12.08,0.5,14.75,6.18c-2.21,1.89-4.81,3.3-7.73,3.66
c-17.88,2.33-36.15,0.14-53.88,3.85c19.82,3.55,40.35-0.36,59.96,4.62c-2.77,1.21-5.64,2.27-8.65,2.71
c-17.03,2.62-34.47-2.3-51.37,1.73c19.26,4.38,39.31-1.02,58.59,3.31c-1.52,1.69-2.99,3.71-5.32,4.29
c-7.19,2.07-14.68,0.22-21.99,0.29c-10.46,0.15-21.17-1.47-31.4,1.41c16.07,5.17,33.14-1.67,49.43,2.04
c2.89,0.59,5.41,2.2,7.58,4.14c-19.15,4.57-39.11-1.36-58.26,3.06c18.58,4.49,37.99-1.51,56.58,3.03c-2.43,1.81-5.23,3.08-8.2,3.69
c-15.94,3.31-32.51-1.63-48.32,2.49c18.59,4.56,38.05-1.6,56.67,2.97c-2.35,1.84-4.99,3.35-7.95,3.92
c-15.62,3.46-31.9-2.08-47.41,2.31c17.66,4.72,36.25-1.78,53.89,3.07c-4.19,4.58-10.86,4.17-16.52,4.6
c-13.54,1.1-27.1-0.73-40.65,0.01c6.6,3.57,14.33,3.54,21.62,3.42c11.8-0.18,23.95-2.3,35.48,1.15c-8,3.49-16.83,4.13-25.44,4.55
c-11.05,0.3-22.11-0.22-33.15,0.29c8.4,4.07,17.99,3.35,27.04,3c10.01-0.34,20.38-1.75,30.11,1.44
c-6.56,6.19-16.04,2.52-23.97,3.03c-11.46,1.07-22.94,2.28-34.46,1.83c7.85,3.52,16.64,3.25,25.06,2.99
c11.12-0.25,22.56-1.82,33.44,1.3c-2.26,2.06-5.1,3.47-8.21,3.52c-8.27,0.42-16.57-1-24.83-0.02c-7.94,0.95-15.92,1.85-23.93,1.39
c5.53,2.76,11.79,3.15,17.85,3.26c8.34-0.21,16.68-0.89,25.02-0.91c4.75,0.11,9.63,0.31,14.06,2.2
c-4.08,5.43-11.35,2.86-17.04,2.94c-13.26,0.27-26.53,0.56-39.76,1.57c5.52,2.64,11.71,3.19,17.74,3.34
c13.02,0.27,26.03-1.65,39.04-0.44c-1.01,1.91-2.07,4.18-4.41,4.7c-5.48,1.45-11.11-0.3-16.66,0.02
c-11.94,0.44-23.98-0.37-35.82,1.49c6.04,2.25,12.53,2.8,18.92,3.12c12.65,0.37,25.29-0.72,37.95-0.21
c-2.23,4.46-7.44,5.61-12,5.47c-6.7,0.03-13.36-0.91-20.06-0.71c-8.36-0.07-16.87-0.7-25.03,1.46c18.79,4.21,38.34-0.98,57.12,3.27
c-2.96,5.39-9.68,5.45-15.05,5.12c-8.66-0.67-17.34-0.74-26.02-0.83c-4.92-0.07-9.9,0.21-14.62,1.7
c15.5,4.79,31.87-1.31,47.57,1.95c3,0.61,5.68,2.19,8.04,4.1c-17.62,4.95-36.26-1.54-53.92,3.22c15.51,4.71,31.86-1.38,47.57,1.91
c2.98,0.59,5.59,2.24,7.91,4.15c-18.21,4.13-37.14-1.08-55.34,3.1c17.68,4.45,36.21-1.53,53.88,3.07
c-2.07,1.81-4.36,3.53-7.11,4.11c-13.97,3.18-28.62-2.57-42.4,1.96c16.67,4.65,34.3-1.55,50.99,3.05c-2.7,2.38-6.03,3.92-9.59,4.44
c-14.22,2.29-28.61-1.37-42.87,0.33c6.94,3.84,15.16,3.53,22.85,3.26c10.33-0.3,21.04-2.05,31.09,1.27
c-2.46,2.02-5.35,3.51-8.51,4.03c-13.06,2.19-26.55-1.62-39.46,1.95c16.12,4.82,33.28-1.53,49.45,3.11
c-16.53,7.02-34.92,3.29-52.3,4.94c7.58,4.05,16.45,3.23,24.73,2.98c9.19-0.32,18.74-1.7,27.62,1.42
c-16.1,6.89-34.06,3.58-51.04,4.71c2.28,1.36,4.7,2.61,7.37,2.95c12.01,1.74,24.1-1.96,36.12-0.26c3.51,0.4,6.67,2.15,9.15,4.63
c-16.99-0.13-33.99,0.58-50.93,1.91c2.1,1.05,4.25,2.09,6.58,2.54c14.71,2.53,29.96-2.65,44.43,1.83c-1.84,1.5-3.89,2.88-6.3,3.19
c-9.64,1.53-19.4-1.13-29.03,0.47c-4.54,0.8-9.09,1.41-13.68,1.77c16.2,6.38,33.95-1.29,50.38,3.76c-2.33,1.38-4.86,2.51-7.56,2.9
c-13.85,2.3-28.11-1.94-41.8,1.77c6.5,3.97,14.47,3.48,21.79,3.3c9.73-0.23,19.89-1.93,29.26,1.46c-3.63,2.38-7.95,3.3-12.23,3.42
c-9.01,0.22-18.01-1.41-27.01-0.59c-3.17,0.21-6.13,1.4-8.86,2.96c16.17,6.93,34.82-0.64,51.02,6.33c-4.25,4-9.6,6.49-15.13,8.15
c-13.59,3.79-23.71,15.22-29.5,27.65c-7.81,16.93-9.2,36-8.67,54.4c1.08,27.79,6.8,55.17,13.96,81.96
c4.6,16.66,9.39,33.31,15.71,49.41c2.52,6.8,5.11,14.42,2.2,21.53c-3.11,9.08-12.77,13.94-21.87,14.5
c-14.08,0.98-28.88-3.4-39.44-12.93c-8.37-8.32-12.12-19.9901-14.86-31.18c-4.89-21.72-5.35-44.17-4.3-66.32
c1.04-26,9.65-50.99,11.12-76.94c1.49-24.87-1.88-49.71-6.54-74.09c-6.03-31.57-14.28-62.8-17.35-94.88
c-1.72-19.96-2.12-40.01-1.66-60.04c0.73-20.16,1.94-40.65,8.42-59.92C361.6678,104.9871,366.7978,94.9471,375.5478,88.5971z"/>
<path stroke="#000000" stroke-width="0.0938" d="M573.9678,88.6071c18.35-0.51,36.63-2.86,55.01-2.59
c2.46,0.15,5.24-0.01,7.2599,1.68c1.51,2.13-0.48,4.35-2.7,4.51c-21.66,3.82-43.69,4.9-65.46,7.83c-0.08,1.85-0.13,3.7-0.16,5.56
c21.69-0.69,43.3101-3.98,65.05-2.87c2.07-0.18,4.38,1.79,3.71,3.98c-0.04,1.32-1.77,1.46-2.73,1.81
c-21.81,3.95-43.98,5.16-65.94,7.92c-0.03,1.92-0.02,3.84,0.02,5.76c13.25-0.89,26.54-1.32,39.77-2.6
c8.06-0.9,16.16,0.19,24.22-0.62c3-0.65,4.33,2.54,4.48,4.97c-4.62,1.85-9.65,2.14-14.49,3.11c-12.21,2.42-24.73,2.21-37.06,3.78
c-5.76,0.82-11.6,0.88-17.34,1.79c-0.06,1.92-0.08,3.83-0.06,5.75c21.81-0.8,43.55-3.46,65.4-3.18c1.83,0.17,2.81,2.01,3.05,3.65
c-0.22,1.8-2.11,1.99-3.52,2.3c-14.09,2.23-28.2401,4.18-42.45,5.48c-7.46,0.86-15,1.08-22.39,2.44c-0.08,1.76-0.11,3.51-0.08,5.27
c17.15-0.05,34.2-2.29,51.35-2.43c4.91,0.07,9.96-0.96,14.77,0.34c2.21,0.53,3.36,4.48,0.55,4.95
c-22.09,4.35-44.64,5.73-66.9901,8.25c-0.06,1.77-0.09,3.55-0.09,5.33c12.3,0.33,24.58-0.98,36.88-1.11
c8.31-0.18,16.6-0.94,24.91-1c2.25-0.01,4.94,0.12,6.31,2.23c0.81,2.22-1.24,3.68-3.2,3.88c-21.56,3.51-43.5,3.76-65.14,6.59
c-0.26,1.97-0.2,3.96-0.17,5.95c20.4-0.81,40.86-0.62,61.23-2.18c2.5-0.02,5.31-0.07,7.34,1.66c0.65,1.53,0.23,3.57-1.71,3.68
c-4.52,0.77-9.07,1.4-13.6,2.19c-17.86,1.44-35.74,3.04-53.57,4.81c-0.1,1.97-0.14,3.95-0.14,5.93
c22.5699,0.04,45.11-1.52,67.67-1.71c0.91,1.55,2.51,4.24,0.02,5.24c-3.94,1-8.09,0.62-12.09,1.25
c-18.47,2.18-37.02,3.52-55.5,5.55c-0.08,2-0.1,4.02-0.06,6.03c20.54-0.06,41.09-0.64,61.62-1.49c2.52-0.08,5.84-0.21,6.88,2.67
c1.27,1.58-0.74,3.34-2.33,3.3c-22.19,2.07-44.43,3.4-66.62,5.39c-0.05,2.18-0.03,4.37,0.13,6.55c21.64-0.7,43.31-0.59,64.93-1.87
c3.31-0.27,4.98,6.1,0.97,6.17c-21.91,2.22-43.97,3.24-65.83,5.94c-0.13,1.9-0.23,3.8-0.27,5.71c21.4,0.05,42.79-0.84,64.19-1.14
c2.89-0.33,4.29,2.63,4.5,5.05c-1.54,0.48-3.06,1.07-4.65,1.29c-21.4301,1.83-42.89,3.19-64.3,5.12c-0.06,2.06-0.06,4.13,0.01,6.19
c18.46,0.17,36.91-0.74,55.37-0.67c3.3,0.09,6.66-0.71,9.93-0.04c2.21,0.61,2.2401,3.26,2.56,5.1c-1.78,0.49-3.56,1.05-5.41,1.18
c-20.8,1.44-41.6,2.87-62.38,4.59c-0.13,1.96-0.21,3.93-0.21,5.9c20.8701,0.28,41.75-0.67,62.6201-0.53
c2.64-0.25,4.41,1.7,5.55,3.85c-0.93,1.25-2.06,2.48-3.75,2.44c-11.34,0.76-22.66,1.76-34.01,2.47c-10.24,0.64-20.5,1.05-30.7,2.22
c-0.03,1.97-0.02,3.94,0.04,5.91c20.26,0,40.54,0.12,60.8-0.16c2.99-0.28,5.52,1.32,6.59,4.11c-0.86,0.92-1.5,2.38-2.97,2.31
c-14.56,0.51-29.09,1.73-43.64,2.4c-7.07,0.48-14.18,0.48-21.21,1.46c-0.07,2.08-0.08,4.16,0,6.24c20.75,0.01,41.52-0.2,62.27-0.24
c2.89-0.05,5.48,1.95,5.58,4.98c-2.33,1.34-5.01,1.75-7.65,1.75c-13.35,0.46-26.63,1.98-39.97,2.41
c-6.57,0.35-13.17,0.5-19.67,1.55c-0.33,1.78-0.42,3.59-0.53,5.41c10.4,0.47,20.8-0.26,31.2-0.23c10.33,0.12,20.66-0.83,30.99-0.27
c2.2,0.06,5.56,1.16,4.84,4.01c0.2,1.65-1.91,1.45-2.95,1.82c-19.66,2.26-39.32,4.51-58.98,6.71c-2.18,0.19-4.47,1.05-5.57,3.07
c-2.37,4.04-1.7599,8.97-1.58,13.45c1.74,28.65,2.82,57.33,4.78,85.96c0.34,13.71,1.83,27.34,2.21,41.05
c1.01,12.71,1.46,25.46,2.57,38.16c1.71,14.59,2.66,29.25,3.77,43.9c0.12,4.03,0.51,8.63-2.0699,12.03
c-1.86,2.45-5.16,2.5-7.94,2.72c-10.4,0.76-20.73,2.38-31.13,3.1c-6.13,0.56-11.8-4.67-11.85-10.79
c-0.72-20.99-0.84-42.01-1.31-63.01c0.35-55.01-0.66-110.03,0.29-165.05c0.29-13.66-0.04-27.33,0.5099-40.99
c0.85-18,0.6-36.02,1.58-54.02c-0.03-15.02,0.74-30.03,1.3-45.04c0.02-22.34,1.86-44.62,2.36-66.94
c0.54-12.65,0.91-25.3,1.81-37.93c0.56-4.56,1.37-11.21,6.81-12.34C548.9378,91.3871,561.3578,88.9671,573.9678,88.6071z"/>
<path stroke="#000000" stroke-width="0.0938" d="M907.9178,176.1771c6.3-0.93,12.72-2.67,19.1-1.23
c7.43,1.59,14.83,3.64,21.76,6.83c-3.44,7.01-11.54,9.34-18.74,9.85c-11.28,0.76-22.38,2.95-33.54,4.65
c-4.79,0.85-10.07,1.11-14.11,4.1c-2.22,1.78-2.06,5.1-0.55,7.29c19.7,1.93,39.48-0.92,59.17-1.59c2.73,0.11,6.98,1.36,6.63,4.81
c0.04,3.79-3.74,5.93-7,6.58c-13.84,2.72-27.77,4.93-41.74,6.87c-5.83,0.6-12.01,0.49-17.17,3.71c-0.17,2.46-0.01,4.93,0.45,7.36
c16.57,1.5,33.19-0.06,49.77-0.53c5.5-0.23,12.03-1.7,16.58,2.31c0.36,1.95,0.15,4.35-1.51,5.68c-2.49,2.08-5.89,2.12-8.93,2.57
c-15.69,2.3-31.27,5.34-47.02,7.09c-2.7,0.42-5.62,0.94-7.71,2.83c-1.74,1.68-1.4,4.47-0.47,6.49c2.38,1.45,5.3,1.64,8.03,1.83
c17,0.47,33.96-1.39,50.96-1.22c2.86,0.19,6.37,1.22,7.4,4.25c0.07,3.44-2.87,5.95-6.08,6.36c-14.71,1.99-29.42,4.08-44.19,5.59
c-4.55,0.54-9.26,0.88-13.48,2.81c-2.41,1.05-3.95,3.82-3.41,6.42c0.92,2.33,3.71,2.91,5.91,3.34c6.6,1,13.26-0.16,19.9,0.04
c11.33-0.24,22.7,0.69,34.01-0.44c2.85-0.09,7.45,0.53,7.91,4.02c0.74,4.56-4.06,6.73-7.77,7.24c-16.77,2.84-33.82,3.61-50.62,6.19
c-2.91,0.57-6.87,1.15-7.82,4.5c-0.01,1.98,0.81,3.84,1.35,5.73c12.27,1.42,24.64,1.2,36.97,1.12c9.75-0.34,19.76-0.85,29.17,2.29
c0.17,3.48-1.7,7.07-5.43,7.57c-13.83,2.1-27.84,2.82-41.75,4.3c-5.79,0.68-11.97,0.14-17.31,2.83c-2.74,1.47-4.63,6.2-1.46,8.19
c3.85,2.13,8.49,1.75,12.74,1.64c15.35-1,30.7,1.71,46.03,0.45c2.57-0.1,4.94,1.04,7.21,2.13c0.52,6.08-5.59,8.78-10.12,10.98
c-6.1801,3.16-13.22,3.6-20.02,3.69c-7.51,0.02-14.54,3.04-21.96,3.7c-7.79,0.75-15.73,0.38-23.33,2.51
c1.65,63.64,2.68,127.31,4.9,190.94c0.14,9.39,1.77,18.86,0.12,28.2c-0.32,1.04-0.19,2.64-1.52,3c-9.11,3.77-18.98-0.85-28.35,1.23
c-1.94-3.09-2.22-6.71-2.08-10.25c-3.58-95.36-6.5-190.74-9.5099-286.12c-1.09-38.63-3.2-77.28-2.08-115.93
c4.99-1.93,10.32-2.63,15.65-2.77c11.73-0.39,23.34-3.57,35.13-2.43C894.5978,176.3371,901.2978,177.2171,907.9178,176.1771z"/>
<path stroke="#000000" stroke-width="0.0938" d="M777.1978,258.6471c2.4-0.28,4.8-0.48,7.22-0.63
c4.09,13.91,3.6801,28.54,5.17,42.83c1.95,19.82,2.61,39.74,4.6,59.55c1.67,19.46,1.66,39.02,2.83,58.51
c1.28,22.65,2.39,45.46-0.27,68.07c-3.29,26.7-7.96,53.24-10.61,80.02c-0.51,2.43-0.67,5.6-3.21,6.85
c-4.33,2.05-9.28,1.98-13.97,2.14c-15.99-0.13-32,0.4-47.97-0.75c-3.05-0.03-4.87-2.87-5.9-5.38c-3.26-7.83-3.51-16.46-5.75-24.57
c-6.21-22.66-12.44-45.36-16.76-68.47c-4.4-24.21-5.44-48.86-6.4-73.39c-1.33-36.18-4.22-72.33-3.5-108.55
c0.06-8.7-0.73-17.57,1.59-26.07c2.42-0.65,5.5-1.97,7.52,0.28c2.64,3.14,2.9,7.49,3.42,11.39c3.13,36.09,5.54,72.25,7.13,108.45
c0.18,4.79,1.11,9.54,2.7,14.07c0.49-1.33,0.89-2.69,1.19-4.07c-1.27-23.99-2.1201-48.02-2.6-72.05c-0.15-13.99-0.65-28,0.49-41.96
c0.5-5.46-1.37-11.09,0.49-16.4c0.9-3.26,5.86-3.45,7.22-0.45c2.09,4.61,1.21,9.86,1.75,14.77c2.91,33.3,5.53,66.64,7.03,100.04
c0.34,6.29-0.91,12.84,1.72,18.81c1.14-0.89,2.39-2.06,1.95-3.68c-1.07-6.29-0.88-12.68-1.24-19.02
c-1.23-25.32-1.9901-50.67-1.88-76.02c-0.01-9.73-0.02-19.46-0.77-29.16c-0.11-2.75-0.2-5.77,1.33-8.19
c1.76-2.45,6.19-1.54,7.03,1.33c1.76,4.74,1.04,9.93,1.54,14.88c3.17,36.66,7.08,73.29,8.29,110.09c0.14,3.1,0.93,6.12,2.04,9.01
c2.05-2.87,2.4-6.52,1.77-9.92c-1.12-5.96-1.39-12.02-1.74-18.06c-0.65-12.02-1.4-24.03-1.58-36.07
c-0.58-13.67,0.07-27.36-0.43-41.04c-0.33-7.99-0.46-15.98-0.83-23.97c0.06-2.88-0.05-6.04,1.54-8.56
c1.66-2.62,6.22-1.89,7.19,0.97c1.84,4.59,1.16,9.68,1.64,14.5c1.28,15.05,3.77,29.96,4.97,45.01c1.27,21.69,2.83,43.37,3.4,65.09
c0.07,3.99,0.76,7.97,2.31,11.66c2.11-3.55,2.41-7.73,1.9901-11.75c-1.9-21.92-3.21-43.92-2.73-65.93c0-17.34-0.22-34.69-0.9-52.02
c0.11-3.48-0.03-7.48,2.37-10.28c1.57-1.58,3.79-0.47,5.64-0.14c2.61,5.16,1.81,11.05,2.31,16.61
c3.03,34.93,6.91,69.81,8.2599,104.85c0.19,5.81-1.44,12.12,1.7401,17.42c4.16-6.15,1.1-13.58,1.17-20.34
c-0.68-16.05-1.81-32.08-2.14-48.14c-0.36-14.31-0.05-28.62-0.58-42.92C775.6478,278.1371,775.4478,268.2871,777.1978,258.6471z"/>
<path stroke="#000000" stroke-width="0.0938" d="M1420.7179,259.5871c0.4399-2.27,3.02-0.94,4.61-1.05
c1.26,6.29-1.6801,12.56-0.15,18.83c4.5,0.44,9.23,1.02,13.59-0.61c1.7201-0.95,3.4701,0.09,5.17,0.57c1.86-4.44,2.28-9.26,2.65-14
c0.25-1.24,0.02-2.82,1.14-3.68c1.6799-0.11,3.7999,0.44,4.25,2.34c-0.3401,0.94-0.76,1.85-1.25,2.71
c-2.6901,4.07-1.4401,9.17-1.5,13.73c3.76,1.19,8.39,1.26,10.9199-2.29c1.3,0.69,2.5801,1.4,3.9,2.09
c1.66-5.09,1.79-10.39,1.97-15.67c1.4401-0.08,2.91-0.12,4.39-0.11c0.8301,6.05-2.4199,11.65-2.3099,17.67
c4.8099,1.95,10.0399,2.14,15.15,2.56c2.0399-4.68,3.6-9.74,2.6599-14.89c-0.21-2.95,3.26-1.68,4.74-0.64
c0.0601,5.02-1.48,9.9-2.08,14.86c0.77,2.41,3.4,3.1,5.61,3.59c4.5801,0.88,9.0701,2.24,13.7001,2.92
c1.12-2.15,2.24-4.31,3.23-6.53c1.26-2.7,0.65-5.78,1.3099-8.62c1.28-0.25,2.61-0.22,3.9501-0.24
c1.64,6.12-4.28,10.67-4.1001,16.67c4.9801,2.27,10.3201,3.66,15.6101,5.04c2.75-2.46,3.6-6.34,3.6499-9.89
c0.02-1.68,1.67-2.95,3.3301-2.72c2.49-0.16,4.1,3.19,2.36,5c-2.01,2.62-3.3301,5.64-3.9301,8.87
c6.92,4.86,15.55,6.34,22.9401,10.4c1.09-1.33,2.0399-2.83,3.46-3.88c1.35,0.3,2.71,0.66,4.0701,1.09
c-0.16,1.9-0.88,3.67-1.7201,5.36c2.7201,2.21,5.7201,4.41,6.91,7.87c3.65,9.16,5.8199,19.04,5.74,28.92
c0.24,2.42,2.47,4,3.6901,5.97c-1,1.73-2.3401,3.28-3.0901,5.14c-0.59,4.29,0.48,8.63-0.1899,12.92
c-1.16,8.68-2.4301,17.67-6.73,25.43c-4.67,7.23-13.88,8.42-20.76,12.63c0.3099,2.16,1.1599,5.43-1.6901,6.26
c-2.34,0.53-3.48-1.79-4.77-3.21c-7.98,2.11-15.71,5.11-23.22,8.51c1.41,2.1,3.7001,3.76,4.28,6.34
c-0.23,2.67-3.6901,4.38-5.66,2.29c-0.7899-2.24-0.9299-4.63-1.38-6.94c-7.08-0.33-13.71,2.38-20.22,4.75
c1.12,1.97,2.5601,3.77,3.39,5.9c0.49,2.98-3.0601,4.57-5.41,3.23c-1.34-2.39-0.7-5.34-1.23-7.95c-6.65,0.04-13.14,1.68-19.52,3.34
c0.36,2.46,1.1901,4.93,0.85,7.45c-0.61,1.86-2.6599,1.38-4.11,1.15c-1.45-2.1-1.02-4.75-1.26-7.13
c-5.95-1.57-11.86,0.85-17.8099,1.11c0.2,1.6,0.51,3.21,0.5499,4.85c0.29,2.22-2.85,1.75-4.0299,2.51
c-0.65-2.07-0.8201-4.23-0.9401-6.37c-5.39-0.98-10.7999,0.26-16.1899,0.11c0.2799,2.4,2.0699,7.83-2.3101,7.05
c-3.08-0.8-2-4.43-1.8199-6.7c-5.79-1.18-11.6801-0.36-17.51-0.43c0.0499,2.49,0.26,4.98,0.22,7.48c-1.77,0.08-3.99,1.28-5.17-0.61
c-0.24-2.24,0.4701-4.45,0.6801-6.65c-5.6801-1.98-12-1.88-17.95-1.55c0.21,2.31,1.11,4.62,0.61,6.96
c-1.5601,1.28-3.8401,1.36-5.53,0.36c-0.3201-2.54,0.92-4.89,1.23-7.36c-1.59-1.79-4.09-2.02-6.28-2.44
c-4.87-0.66-9.6599-1.89-14.5699-2.04c-0.4,2.47-0.11,5.1-1,7.48c-1.0601,1.73-3.5701,1-4.98,0.18
c-1.3301-2.96,3.15-5.62,1.64-8.58c-3.24-2.55-7.62-2.47-11.4-3.67c-1.7101-0.33-3.36-1.45-5.11-1.07
c-3.66,1.7-0.0601,7.83-4.1001,9.17c-1.9299,1.35-3.99-0.87-3.48-2.82c0.8201-2.64,2.17-5.09,2.8201-7.8
c-8-3.68-16.67-5.66-24.55-9.62c-3.4399,2.09-6.3199,4.9-9.39,7.47c-0.62,1.35-0.49,3.56-2.36,3.85c-2.25,0.97-4.71-1.7-3.62-3.86
c0.38-1.57,2.23-1.64,3.4401-2.27c1.5299-2.61,3.1-5.21,4.23-8.02c-12.87-7.03-25.61-14.43-38.65-21.17
c-3.3-1.96-7.23-1.09-10.77-2.07c-5.1-1.45-10.4-0.2-15.5599,0.11c-23.8601,0.06-47.39,4.52-70.9701,7.55
c-29.62,3.97-59.5699,4.81-89.4199,4.42c-16.26-0.26-32.52-0.86-48.7101-2.39c-10.02-1.05-19.83-3.78-29.93-3.99
c-2.98,0-5.9-0.62-8.68-1.62c-2.42-0.81-5.33,0.41-7.35-1.49c-2.98-2.5-6.4-5.81-5.64-10.1c0.6801-7.01-0.41-14.01-0.23-21.03
c-0.05-4.34,0.49-8.66,0.49-13c-0.68-5.47,3.62-9.74,7.25-13.19c3.31-1.41,7.08-1.25,10.52-2.31c4.34-1.43,9.04-0.24,13.37-1.75
c7.57-2.29,15.5001-2.94,23.34-3.73c35.1801-3.58,70.63-4.52,105.9401-2.51c22.7999,0.94,45.35,4.65,68.01,7.09
c6.3099,0.64,12.64,1.32,19,1.26c1.71-0.08,3.34,0.56,4.96,1.1c8.63-1.94,17.73,1.77,26.13-1.55
c3.6801-1.24,7.6899-1.32,11.21-3.08c7.74-3.63,14.42-9.07,21.8101-13.3c-1.52-2.51-4.3201-3.92-5.79-6.4
c-0.89-2,1.34-3.29,2.67-4.25c2.51,1.78,3.71,4.68,5.63,6.99c1.6599,2,4.3199,0.18,6.21-0.54c5.5699-3.05,11.3-5.78,16.89-8.79
c-0.6801-3.46-2.39-6.5-4.5601-9.23c-1.7699-1.77,0.51-4.95,2.76-3.96c2.0601,0.3,2.65,2.42,2.86,4.18
c0.3,2.84,1.9801,5.22,3.63,7.45c6.9401-2.47,13.8401-5.08,20.8301-7.4c0.1799-5.44-2.22-10.55-2.0601-15.98
c1.66,0.07,3.3301,0.27,4.99,0.58c-0.6899,4.67-0.4099,9.46,1.41,13.86c5.34-0.98,10.9-1.67,15.6801-4.47
c-0.26-3.66,0.08-7.47-1.26-10.95c-0.5-1.57-1.4-3.22-0.62-4.86c1.4399-1.61,3.1699,0.01,4.74,0.54
c0.0399,4.26-0.37,9.1,2.45,12.67c3.5,3.53,8.7001,0.02,12.85-0.44c-0.02-3.3,0.12-6.61-0.0699-9.91
c-0.21-3.21-1.99-6.12-1.87-9.38c1.49,0.2,3.99-0.95,4.9299,0.81c1.1801,1.36,0.27,3.1,0.13,4.66
c-0.9399,4.43,1.02,8.74,2.2001,12.93c2.1799-1.01,4.38-3.14,6.89-1.66c2.88,1.46,6.0399,0.77,9.0499,0.12
c1.13-5.48,0.98-11.13,0.0701-16.63c-0.62-1.44,1.12-2.07,1.7999-3.02c0.9301,0.66,1.87,1.31,2.8301,1.97
c0.4299,6.01-1.39,12.45,1.3999,18.09c1.8101-0.77,3.4601-1.91,5.3-2.65c3.0601,0.35,5.87,1.98,9.05,1.86
C1422.6179,272.1071,1419.3679,265.6871,1420.7179,259.5871z"/>
<path stroke="#000000" stroke-width="0.0938" d="M1037.7379,448.7771c14.63-2.47,29.48-0.18,44.2-0.07
c24.6801,0.09,49.36,0.01,74.04,0.04c29.97-0.12,59.96-0.3,89.9099,0.99c12.54,0.51,25.2001-1.55,37.65,0.77
c12.65,2.24,24.8201,6.59,37.48,8.83c9.8301,1.92,19.9,2.02,29.89,2.12c30.12,0.27,59.98-4.3,90-5.89
c22.7101-1.07,45.6801-1,68.1001,3.21c7.1799,1.55,14.5399,3.32,20.7999,7.33c9.96,6.42,10.6901,23.6,0.34,29.99
c-7.6499,4.5-16.6,5.93-25.24,7.26c-25.1699,3.2-50.6799,2.35-75.85-0.42c-28.64-2.99-57.26-7.19-86.12-7.14
c-15.33,0.28-30.95,1.6-45.33,7.31c-2.51,5.84-6.5601,11.09-11.98,14.49c-5.2101,3.41-11.28,5.12-17.3201,6.31
c-1.37,6.55-0.6,13.26-0.99,19.89c-1.26,9.11-3.83,18.55-10.37,25.37c-1.02-1.08-2.46-2.02-2.45-3.65
c-0.4-5.65-1.24-11.45-3.87-16.53c-2.25,6.89-1.6101,14.32-3.7001,21.25c-5.3099-8.12-6.26-18.18-7.9399-27.52
c-0.86,9.16,0.37,18.54-2.05,27.51c-1.1-1.04-2.34-1.99-2.99-3.36c-3.58-7.5-3.66-16.07-6.62-23.76
c-2.02,8.98,1.6,18.31-1.0699,27.2c-6.55-5.41-5.63-14.91-9.1001-22.03c-1.5399,7.58,0.8401,15.4-1.08,22.93
c-5.73-7.11-4.45-16.95-8.22-24.92c-2.48,7.58,0.5299,15.91-2.28,23.38c-1.15,2.29-2.88-0.68-3.23-2
c-1.48-7.17-3.79-14.12-6.2101-21.01c-3.11,7.94,2.01,16.53-1.23,24.44c-1.34-1.09-2.7999-2.27-3.0599-4.09
c-1.14-4.92-2.1-9.9-3.74-14.68c-1.24-0.95-1.29,1.11-1.7201,1.78c-1.6,5.56,0.9501,11.5-1.23,17.02
c-6.45-6.34-3.46-16.39-6.7799-24.1c-1.63-0.44-1.64,1.41-2.02,2.47c-1.75,7.11,1.7999,15.1-2.38,21.67
c-4.35-8.13-5.05-17.49-5.8401-26.49c-4.22,8.27-0.47,18.02-3.8199,26.47c-6.99-5.69-1.88-16.56-8.4399-22.48
c-2.8,7.28,2.1499,15.94-2.77,22.51c-5.2001-7.15-2.3-16.84-6.5601-24.23c-4.8199,7.35,1.5,16.94-3.59,24.21
c-5.3201-7.35-1.9301-17.31-6.46-25.02c-2.64,8.09,0.6599,17.1-3.12,24.93c-6.7101-7.08-2.4-17.74-6.41-25.95
c-4.64,7.98,0.29,18.0099-4.59,25.9c-5.4901-6.48-1.4801-15.66-4.4801-23.01c-0.5399-1-1.0299-2.56-2.4399-1.94
c-2.54,8.13,2.3,17.92-3.48,25.05c-5.63-7.96-1.5701-18.27-4.72-26.9901c-6.26,7.34-0.6201,17.82-4.4501,26.1201
c-1.71-0.95-3.5699-2.1201-3.79-4.25c-1.5699-7.22,0.0801-14.78-2.0199-21.94c-6.5701,7.58-0.3501,18.65-5.3401,26.92
c-2.71-2.19-3.6499-5.63-3.6499-8.99c-0.4501-5.95,0.6699-12.28-2.16-17.8c-3.3201,8.59-1.63,18.03-3.8301,26.86
c-3.7699-2.45-4.47-7.03-4.47-11.17c-0.22-5.0099,0.5-10.17-0.99-15.04c-1.85-0.12-2.79,1.78-3.25,3.29
c-1.88,7.22,1.64,15.3-2.42,22.05c-6.7899-7.34-1.7599-18.15-4.87-26.8c-6.75,7.05,0.37,18.45-5.75,25.8701
c-6.5299-7.09-0.21-18.1-5.58-25.46c-3.17,8.16-0.92,17.21-3.59,25.49c-1.52-1.22-3.51-2.37-3.62-4.54
c-0.29-13.62-1.9401-27.21-3.8101-40.71c-4.99-0.13-10.1699-0.06-14.84-2.03c-4.1-8.78-7.7801-17.82-11.0801-26.95
c-3.35-10.74-2.62-22.84,2.53-32.89C1023.7478,455.4071,1030.1179,450.0171,1037.7379,448.7771z"/>
<path stroke="#000000" stroke-width="0.0938" d="M1064.0979,626.1671c6.76-1.98,14.97-4.08,21.1699,0.47
c5.3601,4.11,5.88,11.38,8.9801,16.96c2.23,4.9,6.4399,10.03,12.4399,9.3c2.21,9.37,4.2,18.78,6.3201,28.17
c-3.9401,2.02-7.64,5.19-8.51,9.76c-1.53,7.82,1.1,16.18-2.04,23.74c-1.0701,2.64-3.75,4.09-6.42,4.6201
c-24.01,5.84-48.6599,8.1299-73.04,11.89c-21.67,3.64-43.3,7.51-65.01,10.92c-62.94,9.89-125.54,21.7599-188.08,33.86
c-14.35,3-28.96,4.95-43.02,9.24c-6.2,1.67-12.51,3.53-18.99,3.47c-4.73-0.47-6.94-5.36-9.93-8.39
c-9.05,2.59-18.57,5.56-28.04,3.79c-4.43-0.84-5.61-5.57-7.24-9.06c-1.05-2.39-3.83-3.24-6.23-2.67
c-8.9,1.49-17.69,3.51-26.46,5.62c-0.32,4.29,2.15,9.35-1.04,13.01c-0.42-0.04-1.25-0.12-1.67-0.16
c-1.6801-3.07-1.7-6.71-3.22-9.82c-1.77-2.55-5.09-0.77-7.48-0.37c-0.08,4.55,3.03,11.45-2.56,13.87
c-1.12-3.93-1.29-8.37-3.88-11.69c-1.84-2.35-4.7-0.44-6.59,0.78c-0.18,4.45,2.45,9.95-1.72,13.31c-2.9-2.87-2.6-7.12-4.02-10.66
c-1.22-2.74-5.08-1.7599-6.86-0.18c-1.77,2.64-0.28,6.01-0.37,8.96c0.35,1.95-1.03,4.7-3.33,3.78c-1.24-3.08-1.16-6.53-2.46-9.57
c-1.48-3.38-7.66-1.88-7.69,1.71c-0.18,3.96,1.86,9.33-2.81,11.38c-1.49-3.42-1.42-7.3-3.1-10.62c-1.42-2.39-4.95-1.76-6.76-0.19
c-1.96,2.51,0.02,5.74,0.03,8.56c0.57,2.34-1.43,4.63-3.79,4.5c-1.29-3.24-1-6.88-2.38-10.07c-1.37-2.7-6.87-3.12-7.24,0.49
c-0.66,4.21,1.51,9.9-3.23,12.41c-2.09-4.76-2.8-10.87-7.61-13.8c-3.62,3.31-2.43,8.21-2.52,12.55c0.1,1.87-1.77,2.86-2.86,4.07
c-2.43-4.03-2.09-9.56-5.83-12.76c-1.96-0.34-3.58,1.01-5.26,1.74c0.48,4.59,3.21,10.95-2.06,13.76
c-2.24-3.74-2.38-8.36-4.81-11.98c-1.81-2.7401-6.89-0.14-6.01,2.93c0.34,4.06,1.95,9.73-2.92,11.75c-1.94-3.84-2.01-8.49-4.55-12
c-1.84-2.17-4.44,0.26-6.3,1.18c0.98,4.49,3.15,11.31-2.51,13.54c-1.61-3.7-1.36-8.07-3.64-11.47c-1.91-1.54-4.7-0.62-6.3,0.92
c-1.24,2.97,1.16,6.11,0.36,9.13c-0.39,1.31-1.48,2.96-3.09,2.59c-2.07-3-2.29-6.9901-4.83-9.6801
c-1.65-1.75-5.16-1.13-5.85,1.2401c-0.52,3.18,0.84,6.36,0.3,9.55c-0.28,1.82-2.33,2.3-3.63,3.21c-1.69-3.43-1.76-7.35-3.15-10.85
c-1.16-2.61-4.54-1.08-6.65-0.88c0.18,3.62,1.09,7.31,0.19,10.9c-0.34,1.96-2.41,2.55-3.92,3.37c-0.88-3.44-0.81-7.13-2.31-10.38
c-1.28-3.35-6.63-2.35-7.35,0.87c-0.19,3.31,1.59,6.67,0.37,9.91c-1.03,0.8-2.12,1.52-3.28,2.14c-2.28-2.82-2.3-6.5-3.02-9.86
c-0.53-2.63-3.84-2.4-5.85-1.96c-8.55,1.59-17.37,1.63-25.73,4.19c-8.86,2.31-18.13,3.81-27.28,2.73
c-4.62-0.57-10.16-2.76-11.11-7.9c-0.94-5.14-1.85-11.26,1.62-15.67c2.84-2.84,6.96-3.72,10.57-5.17
c15.67-5.13,31.8-8.71,47.8-12.61c3.39-0.68,1.24-4.52,1.05-6.72c-1.08-2.93,0.21-6.33,3.52-6.88c1.84,3.14,1.8,6.92,3.24,10.21
c1.41,2.92,6.47,1.65,6.91-1.34c0.15-2.66-0.72-5.29-0.45-7.93c0.12-1.85,2.17-2.22,3.45-3.06c1.79,3.4,2.22,7.2599,3.3,10.91
c1.94-0.21,4.12,0.12,5.85-0.98c1.49-1.65,0.62-4,0.73-5.96c-0.18-2.4,0.56-6,3.54-6.07c1.83,3.15,1.81,7.13,4.16,10.01
c1.42,1.61,4.08,1.11,5.54-0.2c1.87-3.42,1.26-7.51,1.72-11.24c2.59,2.94,4.04,6.74,6.78,9.55c1.26,1.62,2.84-0.27,3.28-1.53
c1.83-4.25,1.95-9.11,4.46-13.09c2,3.76,2.36,8.34,5.14,11.66c1.84,1.9,4.26-0.25,6.05-1.11c-0.3-3.2-1.22-6.41-0.73-9.62
c0.19-1.91,2.35-2.17,3.7-2.96c1.01,3.08,1.25,6.35,2.2,9.45c0.84,3.23,5.18,1.9,7.1,0.47c1.35-3.27-0.4-6.86,0.29-10.25
c0.88-0.93,2.09-1.41,3.19-2.02c1.53,2.88,1.94,6.15,2.94,9.22c0.88,2.03,3.71,2.14,5.39,1.1c1.81-4.18,2.27-8.9,4.82-12.78
c1.93,3.81,2.58,8.6,6.12,11.37c2.1,1.76,4.1-1.15,4.58-2.98c0.25-4.04-2.59-9.68,2.29-11.95c1.75,3.64,2.33,7.85,4.69,11.19
c1.38,2.35,4.37,1.0099,5.8-0.58c1.04-3.32-0.74-6.76-0.03-10.12c0.43-1.47,2.14-1.56,3.33-2.09c1.36,2.88,1.84,6.04,2.93,9.02
c1.24,2.64,5.09,2.03,6.79,0.23c2.37-3.25-1.13-7.65,1.02-10.91c0.6-0.32,1.81-0.95,2.42-1.26c1.6201,2.99,1.76,6.43,2.8101,9.6
c2.06,2.15,5.97,1.58,8.04-0.28c1.2-3.08-1-7.03,2.1-9.47c1.52,1.08,3.14,2.29,3.46,4.29c0.76,1.45,0.43,4.41,2.71,4.23
c1.85-0.09,3.52-1.03,5.24-1.61c-0.11-4.26-3.24-10.27,1.75-12.91c2.06,3.09,2,6.95,3.53,10.25c1.45,2.18,4.55,1.85,6.64,0.85
c2.5-2.55,0.31-6.33,0.41-9.39c-0.41-2.08,1.38-3.34,2.83-4.38c1.62,3.15,1.77,6.76,2.9,10.07c1.51,2.44,4.95,1.63,7.16,0.72
c2.69-1.5699,0.63-4.97,0.6-7.36c-0.6801-2.03,0.52-3.8,1.68-5.32c1.73,2.68,2.75,5.7,3.77,8.71c0.42,1.92,2.7,2.22,4.34,2.27
c6.1-0.14,11.79-2.8,17.86-3.29c3.65-0.69,8.33-0.95,10.47-4.48c0.49-3.77-0.65-7.9,1.34-11.37c1.65-1.72,3.86-2.77,5.81-4.13
c6.81-4.92,16.01-1.94,23.23-5.79c1.86-1.44,3.63-2.9901,5.58-4.31c0.05-2.54,0.25-5.08,0.94-7.53c8.13-1.59,16.41-1.96,24.68-2.06
c17.42-1.42,33.92-7.73,51.01-10.97c53.67-10.78,107.23-22.17,161.13-31.8
C973.7678,649.4471,1019.7878,640.9071,1064.0979,626.1671z"/>
<path stroke="#000000" stroke-width="0.0938" d="M1262.7778,646.9071c6.2101-3.03,13.4-2.85,20.14-2.37
c14.23,1.34,28.0701,5.13,41.89,8.63c12.52,3.13,25.09,6.79,38.1,6.96c7.9601,0.42,16.24-0.8799,23.92,1.88
c3.5,1.19,6.3099,3.72,8.66,6.51c51.4199,2.9,102.98,4.79,154.47,2.39c26.85-1.34,53.72-3.75,80.16-8.76
c31.5-6.26,62.5399-15.96,94.84-17.28c11.4399-0.21,23.27-1.01,34.28,2.75c8.71,2.93,17.84,4.18,26.77,6.24
c9.85,2.14,19.6499,4.58,29.22,7.75c13.12,4.24,25.4199,10.56,38,16.12c15.1,7.26,30.88,14.96,41.61,28.28
c9.23,12.51,13.16,28.45,12.66,43.86c-0.5,12.14-3.9301,24.45-11.3201,34.25c-3.9399,5.5-9.96,8.9-15.52,12.52
c-14.49,8.77-29.4199,17.11-45.5699,22.43c-21.0601,7.07-43.22,9.7-65.12,12.75c-4.64,4.9901-8.09,11.31-8.48,18.22
c-0.76,10.72,3.5499,20.91,7.7899,30.51c4.65,9.82,8.62,19.94,13.25,29.77c7.8201,17.01,15.87,34.13,19.9701,52.5
c8.22,35.17,5.7899,71.81,0.22,107.19c-1.48,10.91-5.98,21.15-7.51,32.05c-0.8101,4.26,1.29,8.41,4.25,11.37
c6.5,6.77,15.8199,11.16,19.87,20.0599c5.02,14.2001,2.02,31.24-8.5699,42.2001c-8.7101,9.35-21.02,14.65-33.5,16.58
c-1.63,10.7001-2.75,21.5601-6.05,31.91c-2.01,6-4.88,12.0499-9.8201,16.1899c-1.73,0.8201-3.98,0.76-5.61-0.23
c-2.9099-2.95-1.84-7.5-1.9299-11.21c0.48-3.05-1.99-5.34-2.7101-8.12c-2.8099-9.01-1.8799-18.62-1.3099-27.88
c0.95-11.99,2.77-23.97,2.29-36.01c-0.12-5.79-3.7101-10.58-5.25-15.97c-0.87-3.12,1.71-5.89,1.6-8.9501
c-0.53-2.1-1.66-3.96-2.3-5.99c0.9-1.1899,1.9501-2.24,3.01-3.2999c-2.16-1.37-6.22-1.38-6.08-4.6901
c0.2999-2.25,2.23-3.72,3.5599-5.38c-2.8999-4.66-7.6799-8.22-8.9399-13.79c-5.34-19.5699-5.2001-40.0499-8.74-59.9199
c-2.17-12.4-5.6-24.87-12.4501-35.56c-4.59-7.22-9.7899-14.15-12.89-22.19c-2.8799-7.69-4.7999-16.22-2.47-24.31
c1.99-7.18,0-14.62-2.87-21.25c-3.41-7.6-6.49-15.34-10.1699-22.81c-2.27-5-4.9701-10.36-3.8601-16.02
c1.42-7.26,7.3301-13.31,6.79-20.98c-0.97-8.4301-9.54-13.04-11.71-20.9301c-1.1801-4.74,1.78-8.99,4.5399-12.52
c-5.4099-12.52-15.59-22.52-27.5399-28.86c-17.51-9.3701-37.04-13.78-56-19.2c-48.5601-13.37-98.23-22.88-148.39-27.61
c-35.22-3.19-70.73-4.09-105.97-0.84c-22.36,2.28-44.11,8.62-66.53,10.36c-9.85,0.73-19.85,0.38-29.5-1.83
c-4.4401-21.89,1.74-43.87,3.75-65.66c1.73-16.31,1.8099-32.83,4.97-48.97
C1259.6779,655.3771,1260.5879,650.8571,1262.7778,646.9071 M1789.8779,1122.1571c-4.62,9.88-9.5,19.83-11.6001,30.62
c-1.7999,8.86-1.34,18.1,0.8301,26.85c5.25,0.79,10.83,0.5901,15.63-1.9399c8.6599-4.3401,13.8199-13.6,15.5399-22.86
c1.42-8.5601,0.5701-18.1801-5.08-25.13C1801.5378,1124.9771,1795.6979,1122.6171,1789.8779,1122.1571z"/>
<path stroke="#000000" stroke-width="0.0938" d="M267.0778,698.3471c8.45-0.59,16.97-1.7,25.43-0.84c3.12,0.26,4.12,3.82,6.67,5.1
c2.61,0.22,5.16-0.72,7.77-0.5c1.77,0.83,3.24,2.18,5.01,3.04c2.95,0.69,6.01,0.17,9,0.05c5.99-0.54,12.01-0.34,18.02-0.53
c12.03-0.31,24.07-0.85,36.1-0.35c3.43,5.1801,4.08,11.57,4.22,17.63c0,5.97,0.11,12.06-1.34,17.9c-0.62,2.29-1.75,5.04-4.32,5.64
c-5.18,1.11-10.5,0.24-15.74,0.34c-12.64,0.24-25.28,0.63-37.92,0.51c-4.44-0.09-9.06,0.57-12.67,3.35c-2.47-0.01-4.95-0.33-7.41,0
c-3.18,0.8199-4.28,5.11-7.87,5.0699c-12.65,1.47-25.36-0.43-38.02-0.92c-27.03-0.85-54.07,0.19-81.11,0.38
c-27.33-0.14-54.67,0.73-81.99-0.15c-3.43-0.17-6.92,0-10.29-0.69c-0.74-1.1-1.29-2.28-1.89-3.43c-1.64-0.96-3.98-1.74-3.3-4.14
c1.28-2.85,4.94-2.26,7.5-2.37c8.39,0.55,16.66-1.2,24.93-2.32c3.13-0.4901,6.81-0.87,8.6-3.88c-1.95-1.29-4.09-2.37-6.48-2.41
c-6.37-0.33-12.53-2.43-18.94-2.32c-3.16-0.02-6.63,0.31-9.38-1.6c-0.09-0.73-0.27-2.18-0.36-2.9c1.33-0.79,2.66-1.56,4-2.3199
c-4.12-0.2-8.68,0.14-12.04-2.73c1.58-4.63,6.84-3.32,10.58-3.46c10.72-0.6,21.36-2.53,31.75-5.15
c-12.16-3.99-25.15-0.92-37.61-2.28c-1.81-1.0099-1.31-3.73,0.44-4.5c2.04-1.09,4.11-2.62,6.56-2.25
c11.72,0.41,23.36-1.6,35.07-1.3c3.41-0.42,6.39-2.49,9.86-2.66c9.01-0.77,18.06-0.09,27.08,0.16c24.32,0.34,48.6-1.39,72.92-1.8
C242.2978,699.5071,254.7278,699.5871,267.0778,698.3471z"/>
<path stroke="#000000" stroke-width="0.0938" d="M1041.0879,779.8171c-0.34-1.45,1.29-2.7599,2.52-1.65
c3.74,1.4,2.6699,6.11,3.86,9.15c0.5499,2.66,4.01,1.22,5.95,1.33c-0.8099-3.8-1.27-7.76,0.22-11.46
c4.3501,1.92,4.6001,7.04,7.3101,10.34c5.71,0.89,11.34-0.97,16.9399-1.83c8.64-1.34,17.39-1.63,26.1101-2.14
c6.3999-0.38,12.88-0.5,19.1899,0.84c3.9301,9.68,4.99,20.41,2.97,30.68c-10.61,4.13-22.14,3.97-33.24,5.69
c-9.27,1.35-18.6,2.42-27.96,2.85c-5.01,0.36-1.52,6.21-2.4301,9.27c-0.46,2.4-3.25,1.03-4.5,0.01
c-2.2799-2.62-1.96-7.44-6.2999-7.87c-2.5,3.6-1.9501,8.15-2.77,12.26c-6.15-0.65-2.9301-9.35-8.1801-11.15
c-4.0599,3.37-0.6,8.97-1.74,13.37c-4.97-2.93-4.11-10.66-10.24-12.33c-3.03,3.88-0.75,8.78-1.27,13.19
c-5.78-1.38-6.02-8.29-9.52-12.09c-4.72,1.89-2,7.51-3.54,11.26c-6.01-0.07-3.32-9.1-8.44-9.58c-4.58,1.99-1.92,8.15-2.71,11.98
c-1.56-0.84-3.67-1.13-4.47-2.89c-1.41-2.6-1.09-6.54-4.16-7.93c-1.67-0.19-3.25,1.16-3.28,2.84c-0.22,2.92,0.27,5.86-0.06,8.79
c-4.65-1.58-4.85-6.86-7.26-10.39c-0.8,0.08-2.41,0.24-3.21,0.31c-0.34,0.53-1.01,1.57-1.34,2.09c0.22,3.15,0.75,6.38-0.2401,9.48
c-4.04-1.97-4.36-6.74-6.53-10.13c-1.29-1.84-3.52-0.38-5.15,0c0.48,3.43,0.8,6.92,0.23,10.37c-1.33-0.49-2.82-0.64-3.92-1.53
c-1.49-2.74-1.58-5.95-2.33-8.9c-1.8,0.03-3.59,0.07-5.36,0.19c-0.71,3.56,1.04,7.88-2.09,10.63c-3.46-1.94-3.37-6.17-5.22-9.23
c-1.69-0.57-4.06-0.42-4.84,1.45c-0.19,2.93,0.35,5.88-0.08,8.82c-4.84-0.62-5.01-5.91-6.86-9.34c-1.67-0.71-4.52-0.12-4.8,1.92
c-0.71,3.36,0.39,6.77,0.19,10.17c-4.81-1.5-4.66-7.13-6.7-10.88c-1.1-0.01-3.32-0.02-4.43-0.03
c-1.37,3.5099-0.39,7.23-0.6,10.8799c-4.38-0.48-4.4-5.35-6.22-8.34c-1.19-2.27-4.98-1.88-5.76,0.52
c-0.47,2.75,1.08,5.83-0.79,8.27c-4.19-0.86-3.97-5.53-5-8.75c-8.3-0.64-16.6201,0.19-24.83,1.34c-1.11,4.72-0.33,11.64-5.83,13.77
c-10.17,3.04-20.98,1.92-31.44,2.97c-12.65,1.22-25.34,0.06-38,0.69c-59.05,1.54-117.63,9.83-175.97,18.54
c-6.88,0.83-13.97,2.67-20.86,1.04c-6.52-2.59-1.99-13.05-8.9-15.1c-1.15-8.45-2.19-16.9-3.45-25.32
c1.51-0.75,3.03-1.49,4.54-2.2599c0.61-4.41-2.44-9.8,1.41-13.33c4.52-2.74,10.1-2.3,15.16-3.02c35.54-2.16,71.12-3.76,106.58-6.93
c39.81-3.23,79.03-10.95,118.4-17.37c8.94-1.43,18.06-3.11,27.13-1.93c6.08,1.03,6.16,9.53,12.03,10.95
c4.33,0.93,8.61-1.15,12.97-0.7c2.83,0.05,7.05,0.64,8.31-2.67c0.18-3.32-0.84-6.59-0.51-9.91c5.38,1.57,3.74,8.71,7.95,11.55
c1.36-0.86,2.9399-1.51,4.03-2.75c0.28-3.7-0.91-7.4,0.03-11.06c1.18,0.86,2.73,1.38,3.54,2.7c0.94,2.6-0.03,5.53,1.05,8.11
c1.31,2,5.33,2.79,6.2-0.04c1.17-3.73,0.31-7.77,1.57-11.49c3.44,2.62,3.84,7.13,5.86,10.66c1.46,2.23,4.43,0.67,5.88-0.81
c-0.32-3.86-1.31-7.73-0.38-11.58c4.74,2.39,4.1,8.3,6.65,12.2401c1.99,0.94,3.69-0.81,5.39-1.6c-0.22-3.81-1.4-7.66,0-11.39
c1.44,0.97,3.57,1.4901,4.06,3.4c0.81,2.36,0.56,5.09,1.97,7.25c0.82,1.75,3.17,0.89,4.68,1.22c1.81-4.36-0.77-8.95,0.67-13.39
c1.57,0.86,3.75,1.47,4.22,3.49c0.7,2.79,0.79,5.74,1.93,8.43c1.17,0.03,3.5,0.08,4.66,0.11c1.9901-4.24-0.38-8.8,0.83-13.17
c6.42,0.93,3.83,9.16,8,12.49c1.29-0.43,2.55-0.93,3.78-1.51c0.67-4.14-2.16-8.85,1.41-12.24c3.69,2.65,3.49,7.46,5.22,11.24
c1.11,2.42,3.81,0.6,5.59,0.12c0.24-4.05-0.98-8.12,0.16-12.11c1.12,0.55,2.3,1.04,3.34,1.79c2.09,2.81,0.59,6.75,2.43,9.69
c1.42,1.71,5.71,1.3199,5.32-1.47c0.29-3.26-1.55-6.86,0.58-9.79c2.08-0.1,4.22,1.37,4.34,3.57c0.36,2.94,0.69,6.31,3.89,7.54
c0.69-0.35,2.07-1.04,2.77-1.38c0.19-3.78-0.63-7.53-0.13-11.3c1.37,0.48,3.17,0.49,4.02,1.91c1.75,3.06,1.17,7.66,4.72,9.52
c5.4601-1.45,2.1901-8.34,3.3601-12.29c1.36,0.44,3.1799,0.34,4.0299,1.7599c1.6801,2.69,1.4701,6.12,3.12,8.84
c1.3101,1.76,3.4,0.2,5.0801-0.05C1041.6979,786.1171,1040.8579,782.9871,1041.0879,779.8171z"/>
<path stroke="#000000" stroke-width="0.0938" d="M277.0078,792.8871c1.1-3.48,0.74-8.69,4.8-10.18c3.28-0.93,4.01,3.91,7.01,3.71
c13.81,0.11,27.62-0.12,41.42-0.45c0.5-1.1,1-2.19,1.51-3.26c4.43,0.06,8.87-0.18,13.29,0.09c1.28,2.02,3.19,3.31,5.45,4.03
c2.7,5.24,2.76,11.3,2.98,17.06c0.01,6.02-0.24,12.16-1.94,17.97c-0.83,3.29-4.29,4.72-6.44,7.04c-5.07,0.32-11.35,1.92-15.25-2.35
c-13.71-0.25-27.4,0.69-41.1,0.5c-3.13-0.08-3.35,5.55-6.92,3.99c-3.44-1.95-3.41-6.58-4.76-9.89c-7.8,0.47-15.76-2.03-23.38,0.48
c-0.14,3.17,0.74,9.3101-4.1,8.98c-1.44-3.05-0.42-6.56-1.25-9.77c-1.6,0.18-3.2,0.39-4.79,0.62c-0.49,2.47-0.84,4.96-1.31,7.45
c-3.17-1.17-4-4.45-4.74-7.36c-1.75-0.02-3.5,0.02-5.24,0.13c-0.35,2.83-0.07,5.78-1.02,8.52c-0.89,0.35-1.8,0.4901-2.76,0.4
c-1.2-2.11-0.73-4.61-0.89-6.91c-1.82-1.05-3.8-1.77-5.83-2.3101c-0.69,2.96-0.37,6.11-1.47,8.97c-0.88,0.31-1.77,0.33-2.66,0.05
c-0.86-2.85-0.61-5.89-0.96-8.81c-2.05-0.03-4.17-0.13-6.13,0.58c-1.02,2.69,0.87,8.56-3.38,8.46c-1.45-2.65-0.22-5.87-1.4-8.59
c-1.92-0.84-4.05-0.62-6.05-0.28c-0.75,2.45-0.25,5.1-0.93,7.59c-4,0.38-2.96-4.46-3.53-6.98c-1.95-0.88-4.32-0.25-6.43-0.37
c-0.57,3.27,1.04,8.02-2.9,9.62c-0.91-3.1-1.18-6.33-1.56-9.52c-1.55-0.04-3.42-0.96-4.65,0.39c-1.91,2.83-1.69,6.57-3.69,9.39
c-2.54-2.62-1.41-6.4-2.45-9.56c-1.95-1.0099-4.06-0.05-6.01,0.42c-0.5,2.88,0.74,7.26-2.62,8.71c-2.97-2.15-1.01-6.24-2.27-9.18
c-1.96-0.73-4.02-0.1-5.98,0.22c-0.51,3.13,0.34,6.64-1.56,9.41c-4-1.5-2.37-6.64-3.67-9.86c-1.73-0.04-3.49-0.18-5.18,0.28
c-1.97,2.64,0.57,7.5-2.36,9.14c-3.62-1.42-2.47-6.1-2.96-9.11c-1.84-0.29-3.7-0.34-5.55-0.17c-0.98,3.02,0.31,7.12-2.43,9.29
c-3.9-1.59-1.97-6.57-2.78-9.84c-1.9,0.27-3.79,0.63-5.6,1.28c-0.28,2.77-0.47,5.56-0.79,8.34c-0.8-0.05-2.39-0.16-3.19-0.21
c-0.9-2.99-0.85-6.15-1.55-9.16c-1.49-0.33-3.2-0.3-4.33,0.88c-1.31,2.94-1.11,6.29-2.16,9.33c-4.53-0.96-3.84-6.08-3.86-9.6
c-1.73-0.06-3.47-0.08-5.2-0.06c-0.43,2.97-0.54,5.98-0.88,8.97c-0.98-0.08-2.93-0.25-3.91-0.34c-0.82-2.9-0.92-5.91-1.01-8.89
c-6.81-1.66-13.81-0.06-20.69-0.82c-10.43-0.94-20.94-1.41-31.24-3.32c-2.21,0.01-2.26-2.51-2.82-4.07
c-0.99-4.64-1.4-9.84,0.81-14.2c0.7-1.88,2.98-1.71,4.59-2.2c12.4-2.14,25.04-2.32,37.59-2.64c3.94-0.19,7.94-0.37,11.74-1.53
c0.15-3.25-0.02-6.53,0.86-9.7c4.88,1.11,4.13,6.8,4.94,10.6c1.67-0.04,3.34-0.09,5.01-0.15c0.53-3.34-0.19-6.83,0.97-10.06
c5.17,0.06,3.03,6.9,4.89,10.16c1.6-0.05,3.2-0.11,4.8-0.19c0.47-3.45,0.09-6.96,0.67-10.39c5.08,0.81,4.31,6.5,4.5,10.34
c1.74,0.11,3.49,0.18,5.24,0.24c0.78-3.53,0.49-7.24,1.77-10.66c4.28,1.73,2.54,7,3.28,10.59c2.04,0.05,4.08-0.01,6.12-0.17
c0.57-3.4901-0.04-7.15,1.23-10.51c4.34,1.4,2.81,7.03,3.52,10.51c2.01,0.1299,4.22,0.69,6.06-0.4301
c1.52-3.3199-0.76-7.55,1.96-10.4c2.84,2.68,2.63,6.68,3.03,10.26c1.93,0.22,3.86,0.31,5.8,0.26c0.52-3.54,0.59-7.15,1.58-10.6
c4.02,2.11,1.46,7.23,3.32,10.41c1.97,0.56,4.03,0.16,6.03-0.06c0.48-3.38,0.43-6.82,1.29-10.13c4.04,1.56,2.09,6.66,3.02,9.97
c2.01,0.23,4.15,1.09,6.11,0.2c2.72-2.86-1.16-8.57,3.26-10.14c0.98,3.53,1.01,7.21,1.55,10.82c2.05-0.12,4.1-0.34,6.13-0.68
c0.67-3.34,0.59-6.81,1.81-10.01c3.57,2.11,1.59,6.74,3.03,10.02c2.03,0.24,4.09,0.24,6.14,0.1c0.37-2.8,0.21-5.66,0.82-8.41
c0.27-1.18,2.13-1.64,2.64-0.31c1.14,2.52,0.26,5.52,1.14,8.17c1.92,1.01,4.18,0.89,6.19,0.18c0.58-3.44-0.88-8.42,3.37-9.94
c1.19,3.24,0.65,6.82,1.79,10.06c1.69,0.47,3.45,0.3,5.18,0.28c0.98-3.23-0.66-7.57,2.16-9.98c4.65,0.43,1.72,6.7,3.88,9.48
c1.45,0.14,2.91,0.2,4.37,0.2c1.22-3.5699-0.67-9.27,4.26-10.27c0.64,2.97,0.57,6.05,1.25,9.02c1.07,1.33,2.9,1.22,4.44,1.34
c2.84-2.99-0.64-9.75,5.04-10.27c0.61,3.33,0.85,6.72,1.24,10.09C261.2578,793.1071,269.1578,793.7771,277.0078,792.8871z"/>
<path stroke="#000000" stroke-width="0.0938" d="M1442.0879,812.6071c13.84-2.81,27.62-6.42,41.7999-7.01
c34.7101-1.84,70.04,1.9,102.92,13.54c7.98,2.76,16.3101,4.33,24.67,5.46c4.76,0.9,9.71,1.51,14.1599,3.51
c2.2101,2.48,1.9801,6.15,2.6901,9.24c2.77,1.34,6.66,1.72,7.96,4.97c1.3301,4.08-0.87,8.73,1.4301,12.63
c1.75,2.76,4.73,4.46,6.59,7.18c-3.6,7.78-2.17,17.5,3.41,23.9901c-4.29,7.03-3.25,16.14,0.36,23.24
c-1.67,2.75-4.61,4.57-5.85,7.58c-0.79,3.6899,1,7.33,0.7999,11.05c-0.24,3.88-6.2999,3.19-6.75,6.99
c-0.5599,2.49-1.35,5.21-3.6599,6.64c-5.13,3.41-11.67,3.17-17.1001,5.9c-5.6,2.76-10.1,7.24-15.46,10.39
c-8.61,5.13-17.91,8.94-27.01,13.08c-7.53,3.43-15.6799,5.65-22.59,10.3c-2.61,1.58-3.4301,4.85-3.15,7.72
c0.4,4.65,2.61,8.86,4.3201,13.15c2.22,5.29,3.35,10.99,5.7899,16.2c2.0601,5.08,8.89,6.65,9.51,12.54
c3.54,21.64,9.8301,42.74,14.5701,64.13c-1.02,3.88-2.0701,7.86-1.5901,11.92c2.91,30.0499,6.7101,60.5599,18.3201,88.6799
c3.24,8.36,9.23,15.3301,12.2899,23.78c2.2401,6.0601,2.64,12.84,0.8301,19.0699c-1.59,4.1001-6.27,5.52-8.78,8.87
c-1.36,1.55,0.11,3.41,1.34,4.5c4.54,3.79,10.2201,5.78,15.23,8.8601c7.53,4.58,14.5801,9.9199,21.3,15.62
c7,6.24,13.73,13.6499,15.96,23.0299c1.8401,8.38-0.34,18.0901-6.9299,23.92c-3.42,3.02-6.85,6.08-9.54,9.8
c0.4501,1,0.9301,2.0199,1.4301,3.0599c-7.91,3.89-15.8401,7.72-23.75,11.6c-16.5-29.83-33.9401-59.13-51.1801-88.5399
c-9.3199,0.1799-17.83-5.14-22.8199-12.8101c-11.17-16.9399-21.2201-34.72-28.74-53.59c-6.7101-17.17-11.8-35.3101-11.7201-53.88
c0.0701-22.1801-5.08-43.97-11.0699-65.2c-4.0699-13.9801-8.9401-27.7001-13.97-41.3501c-3.37-2.2899-8.35-2.39-10.5-6.2
c-3.35-6.72,2.0299-14.23-0.8201-21.05c-2.11-4.69-7.26-6.83-11.9099-8.08c-10.13-2.51-20.63-2.49-30.9801-2.96
c-48.36-2.67-96.3999-11.55-144.96-9.82c-8.79,0.36-18.02,0.37-26.05,4.4301c-12.21,6.15-22.45,15.61-34.97,21.2
c-7.49,3.43-15.72,5.15-23.95,5.17c-5.78-11.9301-6.37-25.36-8.55-38.21c-5.88-32.83-12.7999-65.47-20-98.04
c-1.58-7.67-1.97-15.64-0.5699-23.37c9.62-2.09,19.73-1.9301,29.23,0.73c10.6,2.99,21.1,6.4,31.45,10.18
c6.2001,2.24,12.92,2.82,19.39,1.45c24.4-3.9,48.5-9.5,72.17-16.59C1358.9078,838.8471,1399.3479,821.8171,1442.0879,812.6071
M1611.2079,1267.8771c-2.84,2.54-7.3101,3.8301-7.97,8.12c2.6699-0.4399,4.9399-2.0599,7.5499-2.72
c1.78,0.23,3.54,1.67,2.2201,3.5601c-2.25,2.09-5.65,3.5299-5.4801,7.21c3.39-0.64,6.79-2.8,10.27-1.28
c-1.02,4.17-7.88,4.88-6.27,9.8c3.0801-0.3301,6.6801-4.24,9.25-0.92c-1.5,3.05-5.23,4.6901-5.4099,8.39
c2.8999-0.22,5.84-2.28,8.74-1.1901c2.0499,4.13-4.61,5.1101-5.03,8.92c2.67,0.09,5.2-0.86,7.8199-1.28
c3.2201,1.4601,0.38,4.7301-1.6899,5.7301c-1.92,0.7899-2.11,2.7699-2.26,4.58c2.71-0.35,5.2-2.26,8.01-1.6801
c2.28,1.29,2.16,5.0601,4.92,5.79c5.4199-1.12,8-6.52,11.2899-10.36c0.12-5.49,0.0601-11.3-2.62-16.23
c-2.49-4.3301-6.22-7.75-9.88-11.04C1627.5378,1277.1871,1619.8779,1271.5371,1611.2079,1267.8771z"/>
<path stroke="#000000" stroke-width="0.0938" d="M119.7678,892.2071c2.11-0.12,4.23-0.25,6.32,0.18
c7.85,1.51,15.91,2.67,23.17,6.22c11.77,5.92,21.04,16.09,33.54,20.68c9.68,3.36,20.1,2.47,30.16,3.28
c11.97,0.88,24,0.2401,35.96,1.25c8,0.95,16.06,0.47,24.09,1.1201c14,0.06,27.97,1.2,41.97,1.2599
c14.36-0.07,28.71,0.02,43.06,0.56c2.06,0.03,4.26,0.95,4.83,3.13c-1.61,2.09-4.43,2.31-6.86,2.52
c-45.99,3.14-91.96,6.67-137.96,9.65c-11.96,1.36-24.51,0.36-35.83,5.12c-10.81,4.94-19.2,13.76-29.62,19.38
c-8.78,4.91-18.68,7.74-28.67,8.66c-2.34,0.38-3.36-2.02-4.53-3.5c-11.55-0.68-23.05,0.71-34.51,1.87
c-1.96,0.31-4.63-0.32-4.81-2.68c-0.96-7.29-0.31-14.69-1.1-21.99c-0.43-3.64-0.48-7.3-0.38-10.96
c0.26-11.71-0.61-23.48,0.53-35.16c0.02-4.45,5.24-5.31,8.7-5.61c10.44-0.34,20.71-3.46,31.19-2.35
C119.2078,894.1771,119.5878,892.8671,119.7678,892.2071z"/>
<path stroke="#000000" stroke-width="0.0938" d="M480.1578,909.0971c3.53-3.8,8.69-5.78,13.86-5.37c21.07,0.19,41.5,5.83,62.1,9.59
c24.74,4.53,49.17,10.63,73.96,14.91c47.98,7.91,96.7,9.73,144.8,16.8c46.55,6.49,92.84,15.3,138.13,27.94
c26.88,7.6,53.45,16.52,78.98,27.89c3.28,1.15,4.09,4.99,4.3,8.06c0.3799,3.48-0.38,7.07,0.28,10.51c4,4.53,11.18,2.5,15.69,6.22
c1.93,1.46,1.5,4.1,1.59,6.23c-0.19,17.5601,1.06,35.41-3.09,52.65c-50.26,7.9-101.36,4.53-151.8,0.3101
c-28.98-2.4501-57.97-4.9901-87.05-6.14c-47.66-1.49-95.33,0.6499-142.95,2.5299c-29.99,1.25-59.98,2.51-89.99,3.3501
c-13.67,0.4299-27.32,1.72-41.01,1.59c-6.76-0.25-13.8-0.38-20.1-3.12c-5.52-2.35-7.77-8.52-9.23-13.88
c-1.84-7.84-2.15-16.61,1.68-23.91c2.9-5.73,9.68-7.34,15.4-8.71c15.87-3.15,32.15-3,48.27-3.27c42-0.41,84.0099-1.02,125.97-3.05
c17.65-1.0399,35.31,0.7301,52.96,0.77c6.46-0.4099,13.27,0.0601,19.29-2.74c6.04-2.72,12.06-5.92,18.78-6.53
c15.6-1.91,31.45-1.36,47.04,0.41c7.71,0.74,14.57,5.53,22.45,5.05c0.29-1.66,1.2-3.4501,0.21-5.03c-1.66-3-4.92-4.54-7.58-6.48
c-1.97-1.2-3.62-3.11-5.9901-3.45c-68.58-13.82-137.53-25.68-206.3799-38.05c-26.64-4.54-53.07-10.34-79.92-13.61
c-18.62-2.54-37.87-5.99-53.8-16.61C467.8178,931.4671,471.3678,918.3871,480.1578,909.0971z"/>
<path stroke="#000000" stroke-width="0.0938" d="M356.4278,1014.2671c3.64-4.94,12.48-3.43,14.83,2.04
c3.39,15.36,5.96,30.91,9.06,46.35c0.99,5.4399,4.38,11.0601,1.97,16.61c-2.26,4.21-6.06,7.27-9.17,10.8101
c-3.4,3.5399-6.33,7.71-10.57,10.34c-5.5,2.55-12.65,2.29-17.43-1.7c-2.06-1.64-1.95-4.4901-2.23-6.8301
c-0.54-7.73-1.97-15.35-2.99-23.01c-0.19-3.4099-2.84-5.84-3.93-8.9099c-2.73-8.9401-10.4-15.4901-18.63-19.3601
c-13.04-5.6799-28.78-2.62-39.96,5.78c-2.37,1.61-4.43,3.99-7.37,4.54c-25.12,2.66-50.15,6.26-75.23,9.35
c-48.87,6.17-97.69,12.8199-146.66,18.12c-9.4,0.97-18.79,3.73-28.29,2.36c-2.95-0.36-6.07-2.35-6.07-5.63
c-0.35-6.6799-2.91-13.9299,0.3-20.25c2.97-4.11,8.06-5.9299,12.82-7.03c27.84-6.3199,55.95-11.46,84.13-15.99
c48.05-7.9299,96.37-14.3699,144.94-18.0599c5.98-0.52,11.99-0.51,17.98-0.08c10.68,0.89,21.57-0.18,32.08,2.36
c9.5,2.25,18.67,5.65,27.9,8.77c3.27,1.3401,4.83-3.4799,8.12-2.64c2.74-0.33,4.06,1.93,4.89,4.17c2.62-1.01,5.13-2.4099,6.92-4.62
C355.8078,1019.7471,354.6478,1016.4171,356.4278,1014.2671z"/>
<path stroke="#000000" stroke-width="0.0938" d="M1364.3479,1084.2771c2.76-5.23,7.12-9.64,12.6-11.98
c-0.12,5.29-2.25,10.1799-5.02,14.59c-3.27,5.0701-3.72,11.6901-1.15,17.15c3.63,8.23,11.7001,13.11,16.63,20.42
c4.0601,5.88,3.64,13.76,1.42,20.26c-4.46,11.36-15.53,17.96-22.17,27.85c-1.36,2.26-3.51,4.46-3.24,7.2899
c0.4501,28.6801,1.15,57.4301,4.8,85.92c2.5599,19.23,6.52,38.38,13.35,56.58c6.76,16.9801,18.23,31.4801,26.23,47.8201
c15.39,29.41,30.28,59.0699,45.23,88.7c4.51,9.27,10.6801,17.64,14.9501,27.04c3.28,6.92,5.1599,14.54,4.8199,22.23
c-13.62-11.24-24.1799-25.61-33.83-40.26c-12.9301-19.72-24.6901-40.45-41-57.6699c-1.3,21.1699,4.1,41.9399,8.24,62.5299
c3.79,18.55,7.25,37.55,5.15,56.54c-10.05-13.77-15.52-30.1901-20.0701-46.4401c-4.08-14.75-7.4099-29.7-11.6699-44.3999
c-5.52-18.01-9.7201-36.38-14.77-54.52c-5.27-19.17-8.15-39.2001-16.79-57.29c-9.35-19.6899-22.37-37.27-34.49-55.28
c-9.39-14.12-18.62-28.4299-29.6801-41.3199c-6.24-7.13-13.0299-14-21.2699-18.79c-13.27-8.0599-29.8-7.2999-43.14-15.09
c-9.04-5.48-15.38-15.58-15.41-26.26c-0.45-13.89,8.3101-27.35,20.86-33.11c9.5801-4.49,21.12-3.96,30.5701,0.64
c14.1799,6.83,23.24,22.85,22.0199,38.51c-0.4399,7.46-1.9099,15.0399-0.21,22.45c3.52,16.5801,13.5,30.9401,25.04,43
c13.71,14.42,29.85,26.17,45.62,38.1801c7.76-27.79,7.4-57.0701,4.99-85.5901c-0.8-6.63-0.5-13.6-3.38-19.7799
c-4.8199-10.7001-13.87-19.03-17.6901-30.24c-2.3099-6.51-1.6299-14.0601,2.25-19.8301c5.0601-8.08,13.8701-12.36,21.51-17.48
C1358.5679,1099.2072,1360.4078,1091.2971,1364.3479,1084.2771 M1357.2979,1117.6371c-5.02,0.98-9.9,3.38-13.0599,7.5
c-5.9501,7.53-7.24,18.65-2.6801,27.1801c5.15,9.73,18.78,11.84,28.1,7.35c10.54-5.33,15.48-18.74,12.42-29.89
c-1.4301-5.13-5.12-9.75-10.2-11.61C1367.2479,1116.2771,1362.0879,1116.5471,1357.2979,1117.6371 M1232.4279,1142.6971
c-6.03,1.2899-12.09,3.72-16.38,8.2899c-4.49,4.7201-6.13,11.7101-4.89,18.03c1.4701,8.22,5.9301,15.98,12.4701,21.21
c7.46,5.4901,17.2,8.4901,26.4199,6.4701c7.59-1.5801,14.38-6.5601,18.1901-13.3101c5.95-10.4299,4.8099-25.1899-4.3-33.48
C1255.5178,1142.3671,1243.2379,1140.4971,1232.4279,1142.6971z"/>
<path stroke="#000000" stroke-width="0.0938" d="M179.1478,1097.0071c-0.16-1.62,1.44-2.5399,2.84-2.71
c2.95-0.54,5.94,0.09,8.91,0.1799c10.7,0.3301,21.41,0.2201,32.11,0.3601c13.15,0.7,26.31-0.9601,39.45-0.17
c0.54,3.0599-0.62,5.85-2.04,8.49c2.62,0.5699,5.29,0.89,7.93,1.35c0.23,7.14-0.22,14.29,0.36,21.4301
c0.04,2.12,0.41,4.78-1.45,6.3099c-2.2,0.4701-4.48,0.3101-6.71,0.5701c0.57,2.75,3.19,5.47,1.64,8.33c-1,1.24-2.65,1.63-4.17,1.59
c-13.68-0.1599-27.36-0.2999-41.04-0.4199c-11.78-0.05-23.59,0.73-35.34,0.01c-4.37-1.11-1.63-6.4401-0.7-9.25
c-2.76-0.91-6.07,0.0699-8.36-2.0901c-0.38-8.21-0.22-16.48-0.08-24.6899c1.07-3.34,5.56-1.9,8.19-2.8
C182.0478,1101.2871,178.8478,1099.3372,179.1478,1097.0071 M255.9778,1116.5271c-2.83-1.0699-4-4.8199-7.02-5.1899
c-2.16,1.6499-3.92,3.7699-6.16,5.33c-1.21-1.88-2.1-3.92-3.09-5.9c-0.98,1.64-1.54,3.5701-2.81,5.04
c-4.05,0.4199-8.76,1.0699-12.18-1.67c-1.93-1.62-4.8-2.2-6.74-0.23c-3.56,3.6899-9.02,2.46-13.56,1.97
c-0.6-1.71-0.82-3.62-2.16-4.9299c-1.13,1.86-2.05,3.86-3.22,5.71c-2.38-1.41-3.98-3.6899-6.02-5.47
c-3.61-0.38-4.3,6.45-8.17,4.6599c-0.75-1.6399-1.15-3.4099-1.86-5.0299c-2.25,0.64-1.9,3.33-2.2,5.14
c0.06,3.2899-0.69,7.33,2.09,9.7899c1.2-1.75,0.85-6.39,4.01-5.13c1.74,1.53,3.17,3.41,4.98,4.89c2.54-1.46,4.56-3.65,7.1-5.1
c2.08,0.5,1.82,2.91,2.56,4.49c2.35,1.65,2.19-2.72,3.38-3.96c2.62-0.5,5.33-0.5901,8-0.4301c3.08,0.05,4.82,3.7101,8,3.39
c2.37-0.1,4-2.0699,6.05-3c3.31-0.26,6.68-0.47,9.99-0.0699c1.52,1.1499,1.69,3.38,2.61,5c1.04-1.78,1.82-3.75,3.34-5.1901
c2.58,0.5801,3.78,3.3,5.95,4.62c3.51-0.01,4.5-5.1899,8.16-4.98c0.79,1.75,1.3,3.62,1.98,5.4401c3.64-3.92,2.62-10.26,1.01-14.9
C257.5078,1111.8171,258.2778,1115.2971,255.9778,1116.5271z"/>
<path stroke="#000000" stroke-width="0.0938" d="M694.4978,1129.6671c22.13-3.39,44.25-6.89,66.34-10.54
c14.99-2.0599,32.56-0.3199,43.14,11.76c-1.69,6.92-5.97,13.0601-11.85,17.1c-9.87,6.8201-21.74,9.66-33.17,12.6901
c-18.59,4.4299-36.3,11.73-54.36,17.85c-21.4901,7.61-43.01,15.15-64.6801,22.23c-33.09,10.97-66.81,19.84-100.15,30.01
c-11.23,3.5-22.91,6.1801-34.75,5.6c-8.08-0.1499-15.98-2.25-24.07-1.99c-4.63,0.13-9.56-1.7-11.54-6.1899
c1.27-2.73,2.8-5.73,5.83-6.79c7.02-2.53,14.65,0.77,21.72-1.51c6.91-2.27,12.87-6.6,19.58-9.34c9.86-4.05,19.92-7.84,30.45-9.73
c15.2401-2.8,30.85-3.03,45.9901-6.42c19.71-4.45,38.55-11.89,57.47-18.84c17.15-6.48,34.63-12.04,51.94-18.0701
c17.01-5.83,34.05-11.5499,51.2-16.9299c-23.54-0.36-46.59,5.08-69.61,9.27c-24.3,4.51-49.11,6.4399-73.03,12.9299
c-17.74,4.73-33,16.1801-51.16,19.6c-6.8701,1.3401-13.81,2.2101-20.71,3.3101c-7.62,1.05-15.37,0.99-22.93,2.45
c-11.29,2.2001-19.81,11.49-31.32,13.04c-4.81,0.76-9.63-0.67-13.77-3.09c-0.36-6.87,5.7-11.2001,10.93-14.3401
c9.67-5.48,17.46-14.1699,28.26-17.6c16.91-5.72,34.79-7.5399,52.08-11.74
C605.8278,1143.4271,650.2278,1136.6671,694.4978,1129.6671z"/>
<path stroke="#000000" stroke-width="0.0938" d="M970.6678,1134.6471c2.89-1.95,5.79-4.1,9.27-4.87c2.99-1.1899,4.11,2.58,5.61,4.4
c-0.03,3.5-0.02,7.01-0.03,10.52c-6.96,4.83-12.66,11.1799-18.29,17.45c-28.03,30.61-58.51,58.83-87.75,88.26
c-10.98,10.87-21.55,22.6801-35.48,29.86c-20.98,11.1-43.83,18.13-65.01,28.8101c-5.06,2.8099-10.3,6.3099-16.4,5.5599
c-0.15-4.37,3.25-7.22,6.45-9.54c8.2-6.2999,17.15-11.61,24.92-18.47c1.39,0.35,2.79,0.73,4.2,1.13
c18.42-9.6899,35.95-21.49,50.59-36.37c-2.18-1.86-4.75-3.16-7.25-4.48c-1.28-3.14-0.53-7.15,2.76-8.6801
c4.91-2.7599,9.17,4.9601,13.93,2.02c2.48-1.6-0.05-3.98-0.9-5.74c-1.96-2.83,1.27-5.51,3.47-6.88
c3.2-1.48,5.94,1.4501,8.72,2.5701c2.43,1.26,4.91-0.51,6.79-1.9501c5.65-4.6799,9.91-10.75,15.33-15.6699
c14.56-14.1001,30.39-26.88,44.25-41.6901c-28.73,13.7001-57.1801,27.99-85.41,42.7001c1.67,3.1499,4.24,6.36,3.31,10.1699
c-1.56,2.01-4.3,3.25-6.81,2.5c-3.76-1.11-6.27-4.2999-9.11-6.77c-3.09,1.9701-3.46,5.9301-5.85,8.4401
c-2.83,2.1799-6.36,0.28-9.36-0.41c-15.39,7.03-30.07,15.5701-44.09,25.03c-3.73,2.52-7.79,4.66-10.91,7.95
c-2.43,2.53-2.47,6.6801-5.52,8.73c-4.71,3.53-10.28,5.62-15.29,8.66c-5.43,3.23-10.87,6.75-17.18,8
c-0.03-2.3199-0.04-4.61-0.02-6.9c3.46-1.5299,5.84-4.5399,8.81-6.7699c6.11-4.8101,12.63-9.16,18.11-14.7201
c7.89-7.8199,14.07-17.1899,22.19-24.7899c10.83-10.89,23.51-19.8,37.26-26.62c18.23-9.16,37.23-16.6801,55.59-25.5801
c29.35-13.74,58.73-27.4299,88.49-40.27C963.6878,1138.5671,967.3578,1136.9171,970.6678,1134.6471z"/>
<path stroke="#000000" stroke-width="0.0938" d="M69.3678,1193.2971c2.55-2.4301,6.09-3.67,9.6-3.37
c23.05,2.1899,46.06,5,69.15,6.8099c51.37,4.03,103.01,6.0601,153.94,14.38c5.04,0.6801,9.85,2.7201,14.96,2.89
c6.86-1.09,11.75-7.34,18.81-7.7999c4.62-0.49,9.6,1.9299,11.42,6.34c2.04,4.21,1.06,8.98-0.15,13.28
c7.92,3.6699,17.05,5.0399,25.58,2.87c5.07-1.3101,9.05-5.36,14.3-6.0801c2.5-0.2799,5.84,1.42,4.84,4.42
c-1.02,4.24-5.51,6.16-9.16,7.7c-10.08,3.79-21.11,3.4601-31.71,3.3c-6.2-0.04-13.06-2.58-18.67,1.16
c-20.3,12.6599-39.6,26.9299-60.61,38.4399c-39.16,22.3201-80.24,41.12-122.1,57.76c-8.94,3.71-18.09,6.9-27.32,9.8
c-7.92,2.3999-15.35,6.14-23.26,8.59c-8.08,2.92-16.68,3.83-25.1,5.3099c-5.6,0.55-11.8,1.5701-16.94-1.2799
c-5.57-4.36-7.95-11.9501-7.51-18.8301c0.84-6.73,6.69-11.23,12.1-14.5c14.64-8.51,31.4-12.0299,47.14-17.85
c42.37-15.41,84.33-31.99,125.44-50.51c16.82-7.53,33.54-15.45,49.16-25.27c-10.64-2.3099-21.5-3.23-32.29-4.51
c-3.66-0.3999-7.37-2.0299-11.04-1.0199c-3.36,1.47-4.01,5.62-6.66,7.89c-5.49,4.9199-13.25,5.6799-20.3,5.95
c-10.05,0.11-20.04-1.1901-30.04-2.04c-29.69-2.6599-59.38-5.36-89.07-8.0499c-7.96-0.9601-16.1-0.89-23.93-2.79
c-5.07-1.23-7.77-6.5699-8.19-11.4C61.0478,1207.097,63.5778,1198.7172,69.3678,1193.2971z"/>
<path stroke="#000000" stroke-width="0.0938" d="M1107.7579,1300.7172c3.6299-9.3201,12.1799-16.6201,22.0499-18.4701
c8.92-1.87,18.5,0.6,25.74,6.04c5,3.75,6.6801,10.64,12.26,13.77c7.72,3.9199,16.88,0.8199,24.79,4.12
c7.33,3.04,14.1899,7.77,18.74,14.38c3.41,4.5499,6.6799,10.1899,12.63,11.62c6.03,1.16,11.46-2.7001,15.61-6.61
c4.39-3.86,6.53-10.9,13.25-11.35c-1.6801,9.2599-8.4,16.45-15.36,22.2999c-10.99,8.9301-22.9,17.52-36.9,20.87
c-4.76,1.1801-9.64,1.74-14.52,2.02c0.89,2.75,1.7101,5.5601,1.72,8.51c2.28,0.95,5.0601,1.36,6.6801,3.4399
c3.08,3.9,3.87,9.03,3.64,13.88c-7.8101-0.59-11.21-9.14-18.4401-11.01c-8.5199-2.46-17.9199-0.75-25.6599,3.3401
c0.6499,1.9,1.6799,3.73,3.2999,5c7.27,6.0499,13.12,13.5399,19.48,20.5c2.13,2.38,4.7401,5.4099,3.37,8.86
c-2.6899,7.1-8.85,12.08-14.08,17.2999c-6.09,5.9601-14.66,9.15-23.16,8.38c-15.4399-0.37-28.8199-13.58-30.83-28.63
c-1.16-7.5399,1.71-15.49,7.24-20.7c6.55-6.3099,15.37-9.21,23.39-13.11c-5.72-4.9-12.78-7.75-19.73-10.38
c-11.72-4.33-23.98-6.96-35.62-11.49c-8.4-3.3101-17.61-2.98-26.48-3.21c-17.64-0.05-35.2301,1.6799-52.8701,1.58
c-32.05,0.04-64.1,0.76-96.13-0.49c-6.09-0.3101-12.48,0.1799-18.14-2.5c-0.1-4.5,4.03-7.14,8.0699-7.52
c34.87-5.35,70.03-8.5699,105.17-11.5c12.13,0.1899,23.86-3.61,35.98-3.63c12.35,0.52,24.58-1.75,36.87-2.5599
c7.1901-0.8301,15.15-0.9901,21.15-5.5701C1106.1478,1313.7072,1105.8479,1306.5171,1107.7579,1300.7172 M1127.4279,1290.5872
c-2.98,0.6-6.1,1.25-8.52,3.1899c-8.47,6.78-8.7799,21.52-0.34,28.45c5.5,4.3301,12.47,6.53,19.39,7.0801
c10.8199,1.09,20.88-8.16,22.51-18.54c0.4-7.28-4.1801-14.59-10.76-17.67
C1142.8379,1289.7971,1134.8479,1289.0171,1127.4279,1290.5872 M1172.3479,1311.5171c-9.09,3.14-15.85,12.64-14.9501,22.35
c0.4601,5.4701,4,10.23,8.4301,13.27c8.39,5.75,19.17,7.6,29.1,5.64c4.4501-0.86,9.01-2.39,12.3301-5.6
c3.9199-4.02,4.2599-10.34,2.85-15.49c-2.75-8.48-10.23-14.49-18.11-18.03
C1185.8878,1311.0371,1178.8379,1309.2671,1172.3479,1311.5171 M1081.8978,1334.2371c6.38,8.27,16.62,11.8501,25.91,15.74
c11.9,4.9801,24.09,9.25,36.58,12.4701c0.14-3.5,0.92-6.9,2.03-10.1901c4.4601,0.42,9.54,0.03,13.0901,3.3201
c-0.4401,3.22-1.25,6.37-2.0601,9.5199c5.5699,1.29,11.28,1.6901,16.9399,2.4301c0.2001-3.3099,1.1001-6.61,3.76-8.78
c-10.0299-0.76-17.62-7.99-24.1499-14.9299c-5.5601-6.0901-13.79-8.4301-21.55-10.25c-11.67-2.63-23.41-6.17-35.51-5.53
C1091.3779,1328.2371,1085.8179,1330.1771,1081.8978,1334.2371 M1136.4078,1386.6771c-6.89,1.28-13.73,5.04-17.09,11.41
c-4.1,7.87-2.63,18.3899,3.71,24.6799c5.7201,5.8,13.8,9.1801,21.9401,9.38c7.15,0.01,14.13-3.03,19.4199-7.78
c3.5-3.1599,6.01-7.59,6.14-12.38c0.67-7.5399-3.5399-14.7699-9.5499-19.0699
C1153.9679,1387.9271,1145.0079,1384.9271,1136.4078,1386.6771z"/>
<path stroke="#000000" stroke-width="0.0938" d="M584.9378,1305.2671c33.05,0.55,66.01-2.54,98.97-4.48
c5.88-0.53,10.49,4.02,13.8,8.3199c4.38,6.0801,8.02,13.1901,8.28,20.8201c-0.6,6.33-6.09,10.5-10.63,14.27
c-3.45,2.4099-6.29,5.5299-9.37,8.35c-14.3,1.38-28.7,0.62-43.05,1.13c-10.64,0.53-21.29,0.5499-31.92,1.16
c-9.75,0.6799-19.73,1.2999-28.83,5.1799c-9.25,3.91-19.32,5.08-29.23,5.98c-15.15,1.3201-30.38,1.14-45.55,2.0801
c-14.51,0.8199-29.03,1.2799-43.53,2.12c-12.99,0.71-25.88,4.36-38.94,2.8099c-5.17-0.4-8.97-4.6699-14.06-5.35
c-8.96-1.4301-17.97,0.66-26.96,0.45c-11.67-0.2699-23.31-1.36-34.99-1.0299c-16.1,0.0699-32.64,0.97-48.2-3.9801
c10.48-5.72,22.91-2.75,34.27-3.12c51.17-2.37,101.92-9.7899,152.88-14.6699c32.5-3.1901,65.15-5.17,97.83-4.78
c0.3-6-2.31-11.85-0.79-17.83c-50.9,3.8199-101.99,4.46-153,3.27c-24.99-0.76-49.96-2.4601-74.96-2.64
c-22.4,0.2699-44.89,3.7999-67.23,0.76c5.99-6.4701,15.35-5.17,23.29-5.4701c23.92-2.3999,47.84-4.88,71.78-7.08
c15.13-1.27,30-4.49,45.09-6.0699c34.29-3.1001,68.76-2.04,103.13-2.6901
C550.3678,1302.4672,567.6078,1304.8971,584.9378,1305.2671z"/>
<path stroke="#000000" stroke-width="0.0938" d="M1592.4279,1417.9572c2.1901-9.1001,7.41-17.39,14.46-23.51
c37.77,3.11,75.0801,11.5299,110.4701,25.1c19.4199,7.37,38.4099,15.85,57.12,24.86c14.0599,7.04,27.9199,14.6801,40.4099,24.3101
c10.66,8.1599,20.42,17.98,32.92,23.35c9.9401,4.2899,20.9401-0.16,31.11,2.8099c3.4401,0.92,6.02,3.49,8.29,6.12
c-2.96,4.3201-7.52,7.4301-12.67,8.4401c-14.09,2.83-28.46-2.5-42.5299,0.5399c-8.7301,1.9501-17.3101,5.17-24.6001,10.41
c-3.64,2.65-7.08,6.0701-8.2999,10.54c-1.66,5.87-0.74,12.1,0.73,17.9199c2.71,10.54,7.25,20.5,10,31.03
c2.25,8.42,2.73,17.23,2.35,25.92c-0.26,5.6899-2.27,11.0499-4.25,16.33c28.12,34.5,50.99,73.24,68.71,114.0701
c10.88,25.25,19.6001,51.5499,24.4,78.6599c3.29,18.4401,4.24,37.3401,2.25,55.9801c-1.03,10.88-6.53,21.5199-15.61,27.7999
c-8.6799,6.05-19.3099,8.3201-29.63,9.66c-26.6,3.0599-53.4,2.14-80.12,2.26c-39.58,0-79.15,0.01-118.73,0
c-10.21-9.0801-21.87-17.3-28.4301-29.64c-8.5599-15.48-10.2899-33.72-9.22-51.09c1.8101-27.63,8.41-54.77,17.71-80.79
c14.1001-38.97,33.8401-75.9401,58.4801-109.27c4.62-6.37,11.85-10.6799,15.24-17.9299c2.83-8.8601-0.7201-17.9701-1.61-26.8401
c-1.3501-10.1799,3.1499-19.77,6.6599-29.0399c4.78-11.8501,9.12-24.8101,6.03-37.6801c-10.6899-2.4399-21.67-3.99-31.84-8.22
c-15.5601,3.62-23.2001,20.16-38.0901,25.1c-3.75,1.4399-7.7999,1.49-11.6899,2.21c-10.4,14.12-22.8,26.6001-35.08,39.0701
c-9.86,9.46-17.0801,21.52-28.16,29.73c-5.23,3.96-11.6801,6.17-18.24,6.24c14.6799-30.27,31.9399-59.26,45.46-90.11
c9.88-22.23,17.67-45.4401,22.46-69.3101c0.4701-2.85,1.91-6.25-0.61-8.5699c-8.6899-10.05-24.6699-8.5601-33.22-18.85
C1591.2379,1430.6071,1591.0378,1423.8271,1592.4279,1417.9572 M1794.0579,1500.9971c3.8,5.1801,10.42,9.54,17.0601,7.6
c5.49-1.59,8.75-6.75,11.0699-11.61c-3.05-5.23-6.35-10.4099-10.8199-14.5399c-5.01-4.8101-11.65-7.62-18.4801-8.53
C1787.5779,1482.0872,1788.1578,1493.2771,1794.0579,1500.9971z"/>
<path stroke="#000000" stroke-width="0.0938" d="M497.3978,1438.5271c9.62-1.37,19.75-1.48,28.97,1.98
c3.11,1.25,6.27,2.87,8.39,5.55c1.94,2.4,2.28,6.39-0.14,8.6c-2.52,2.0699-6,1.58-9.03,1.71c-0.89,6.3,0.15,12.63,0.25,18.9501
c3.82,0.2999,7.71-0.38,11.48,0.4099c1.53,1.6901,1.31,4.15,1.66,6.27c0.8799,11.4301,1.77,22.87,2.42,34.3201
c-1.65,0.74-3.36,1.4-4.87,2.4399c0.28,2.37,2.91,2.28,4.64,3.0701c0.29,5.6599,3.96,10.35,8.66,13.21
c16.37,9.42,25.9,28.3099,26.27,46.9c0.72,25.0499-0.94,50.11-2.98,75.08c-2.31,28.7001-10.25,56.53-13.79,85.0601
c-2.67,19.8199-2.29,39.88-1.56,59.8199c0.74,16.83,4.26,33.35,7.43,49.84c1.01,5.7001,2.59,11.9701-0.01,17.5
c-2.27,4.1901-6.89,6.28-11.15,7.9c-9.35,3.1801-19.26,4.23-29.07,4.9c-17.02,0.91-34.2-0.15-50.93-3.48
c-6.27-1.4-13.56-4.2001-15.7-10.89c-1.81-8.39,1.79-16.65,3.02-24.87c4.2-25.72,5.16-51.9301,3.55-77.92
c-1.27-23.71-6.54-46.9199-11.48-70.0699c-7.09-33.5-9.82-67.73-11.23-101.89c-0.25-9.83,0.02-19.9301,3.47-29.25
c2.92-7.98,7.2-15.74,13.67-21.38c4.18-3.7,9.68-5.65,13.57-9.6801c1.6-2.95,2.39-6.26,2.85-9.5499
c2.09-0.9401,5.02-1.34,5.07-4.17c-1.58-0.58-3.17-1.13-4.74-1.64c0.14-11.8099,0.35-23.64,1.37-35.4099
c0.16-1.88,0.63-3.7101,1.07-5.52c3.72-0.64,7.5-0.61,11.25-0.9601c0.65-6.34,0.7-12.72,0.49-19.0699
c-2.75,0.14-5.49,0.65-8.25,0.47c-2.82-2.03-4.04-6.59-1.46-9.2899C484.8378,1442.597,490.9878,1439.4171,497.3978,1438.5271z"/>
<path stroke="#000000" stroke-width="0.0938" d="M1184.3779,1462.3971c5.59-5.29,10.59-11.26,16.7999-15.87
c3.37,0.92,8.34,4.0699,6.6901,8.27c-2.51,3.41-6.9301,4.48-10.3101,6.79c-4.73,3.0299-8.6,7.1599-13.0699,10.5299
c-0.5,3.98,0.38,7.91,0.6799,11.87c0.2101,8.89-3.4099,17.9801-10.26,23.79c-6.26,5.41-14.77,7.78-22.9399,7.3199
c-10.3301-0.4299-19.77-5.3999-30.03-6.23c-15.0699-1.21-30.4399,3.4401-42.54,12.4701c-3.4399,2.46-6.6499,5.22-9.7899,8.0399
c5.45,6.1901,12.77,10.3,20.24,13.5601c10.84,4.65,22.27,7.71,33.7,10.48c8.37,1.91,17.6,3.54,25.73-0.1901
c3-1.25,4.12-4.5699,6.2201-6.7999c1.5599-1.62,5.1399-1.0801,5.5399,1.37c0.4401,2.12,0.51,4.41,1.75,6.2999
c4.0801,6.9901,6.8301,14.8,7.5601,22.88c0.9299,10.1801-2.89,20.89-10.73,27.6001c-6.17,5.39-14.5701,7.74-22.67,7.22
c-14.75-0.08-28.3101-14.12-26.63-29.03c0.26-6.3099,6.1801-10.5599,6.67-16.8099c0.52-2.99-1.2201-5.78-3.6001-7.42
c-5.0599-3.63-11.1499-5.34-17.0099-7.14c-12.7001-3.78-26.0601-6.22-39.3301-4.73c-10.45,1.11-21.26,1.25-31.13,5.27
c-4.16,1.9099-7.61-2.86-11.79-1.79c-5.74,0.92-10.9,3.78-16.37,5.6c-36.1,11.9701-72.72,22.3101-109.62,31.48
c-5.72,1.3201-11.32,3.4601-17.23,3.66c-1.83,0.02-4.47-0.62-4.7401-2.75c1.91-3.85,6.6801-4.1899,10.15-5.89
c18.48-8.27,37.11-16.1799,55.7-24.1599c6.95-2.8301,14.18-4.9901,20.84-8.5c-26.94,0.2999-53.87,2.5099-80.83,1.48
c-3.99-0.25-8.09,0.58-11.92-0.88c1.01-3.12,3.47-5.64,6.76-6.22c33.57-5.3701,67.17-10.8,100.96-14.75
c13.02-1.4301,25.92-3.8101,38.97-4.9501c6.85-0.79,14.01,1.04,20.56-1.76c11.67-4.66,24.17-6.36,36.4301-8.72
c7.36-1.5601,15.03-2.62,21.7001-6.3c2.58-1.2799,4.88-3.09,7.52-4.25c6.1899-2.14,12.71,1.63,18.8999-0.4099
c6.9401-2.4601,12.5-8.41,14.39-15.54c1.91-6.89,4.54-14.03,10.35-18.61c7.7001-6.62,18.3601-9.5601,28.37-7.87
c4.26,0.8199,7.6901,3.9199,11.9901,4.66C1179.8079,1465.8871,1182.3579,1464.1671,1184.3779,1462.3971 M1151.3878,1468.6571
c-11.71,2.27-21.96,14.6-18.0599,26.73c5.74,14.38,27.7,18.3,38.29,7.13c4.6899-5.26,7.47-12.41,6.84-19.49
c-0.49-5.71-4.53-10.64-9.62-13.02C1163.4379,1467.4271,1157.1378,1467.1671,1151.3878,1468.6571 M1131.3878,1564.6471
c-5.9099,1.8201-11.35,5.91-13.9199,11.64c-2.8201,6.89-2,15.48,3.08,21.14c9.75,10.7999,29.29,11.61,38.79,0.04
c9.34-9.1201,5.42-26.8-6.27-31.9901C1146.2878,1562.4371,1138.4279,1562.7771,1131.3878,1564.6471z"/>
<path stroke="#000000" stroke-width="0.0938" d="M664.7078,1456.4271c4.99-2.62,10.82-1.97,16.25-2.41
c6.47,0.0701,13.78-0.62,19.3,3.39c1.51,16.98,0.71,34.11,2.33,51.11c2.05,0.97,6.12,0.29,6,3.48
c1.22,11.27,0.06,22.6901,1.69,33.9401c-2.2,0.1599-4.39,0.3199-6.57,0.53c1.89,0.95,4.54,0.8899,5.67,2.9199
c9.79,15.23,19.61,30.4401,29.55,45.5701c0.93,1.4399,1.5,3.11,1.41,4.88c-3.21,51.0099-5.1,102.09-7.63,153.13
c-1.42,29.97-2.87,59.9299-4.33,89.8899c-0.58,8.3301-0.5,16.7101-1.43,25.01c-0.6,6.17-5.9,10.4501-11.26,12.7001
c-10.01,4.24-21.05,5.11-31.79,5.61c-13.48,0.1699-28.11-0.77-39.44-8.89c-4.76-3.1901-6.42-8.98-6.49-14.42
c-2.69-53.3099-5.19-106.63-7.77-159.9399c-1.77-34.36-3.76-68.73-5.12-103.1c0.19-5.1001,4.71-8.5901,6.87-12.9301
c7.81-12.76,16.22-25.13,24.26-37.74c1.24-1.63,3.48-1.83,5.22-2.7c-2.11-0.24-4.22-0.4401-6.31-0.64
c0.81-11.01,0.33-22.0801,1.03-33.0701c-0.03-3,3.42-3.3099,5.52-4.25C664.4078,1491.2671,662.9278,1473.7371,664.7078,1456.4271z"
/>
<path stroke="#000000" stroke-width="0.0938" d="M303.8678,1462.7971c5.88-1.84,12.12-0.89,18.17-1.01
c3.61,1.45,7.61,1.27,11.31,2.47c6.75,1.97,13.81,4.22,19.07,9.11c4.4,4.1001,5.63,10.9401,3.38,16.4401
c-1.51,3.13-4.11,5.5399-6.27,8.22c5.15,1.84,11.09,2.9301,14.84,7.27c2.4,2.72,1.35,6.59,0.52,9.75
c-0.95,3.75-3.16,7.26-6.53,9.2999c-4.65,2.9-10.37,2.6101-15.46,4.2301c3.37,4.45,7.6,8.37,9.75,13.6499
c3.56,8.76,6.14,18.12,5.78,27.6801c0.18,10.49-2.71,20.67-3.27,31.1c-1.2,12.98-5.12,25.78-3.97,38.9
c-0.12,12-0.1,24.03-1.01,36.02c0.3,5.3099,0.3,10.63,0.41,15.95c1.38,12.3301,2.23,24.7101,4.02,36.99
c3.45,24.1001,8,48.03,11.38,72.14c1.53,12.52,2.43,25.25,1.06,37.84c-0.92,9.1001-5.05,18.14-12.43,23.77
c-8.51,6.4701-20.01,7.3501-30.23,5.61c-12.51-2.21-22.28-11.5599-29.15-21.74c-10.96-15.95-17.84-34.2999-23.13-52.7999
c-6.82-25.9601-13.19-52.13-16.21-78.8401c-2.26-21.21-4.47-42.5699-3.23-63.9199c0.36-13.34,1.28-26.66,1.17-40.01
c0.1-11.11-0.34-22.4-3.57-33.1c-1.16-4.03-3.28-7.6801-4.7-11.6c-3.35-8.8601-9.95-16.14-12.59-25.3
c-1.38-5.04-1.28-10.8101,1.68-15.27c4.01-6.15,10.3-10.53,17.18-12.9c2.56-0.7799,4.93-3.35,3.56-6.12
c-5.52-2.9299-11.61-4.8199-16.81-8.39c-5.41-3.64-11.36-8.38-11.93-15.39c-0.44-4.34-0.5-10.0299,3.84-12.46
c7.24-4.09,16.07-3.1,23.93-1.79c8.95,2.01,18.04,4.1801,26.17,8.5801c2.23,1.16,4.85,1.6699,7.3,0.91
c1-3.0801,0.8-6.63,3.01-9.2201C293.9978,1464.8971,299.2878,1463.9871,303.8678,1462.7971z"/>
<path stroke="#000000" stroke-width="0.0938" d="M82.6178,1493.5271c3.73-0.89,7.61-0.21,11.4-0.13
c25.63,0.33,51.27,0.95,76.91,0.83c4.07,0.0601,8.31-0.83,12.26,0.4801c2.27,0.7699,2.43,3.37,2.88,5.36
c1.12,0.15,2.24,0.3099,3.36,0.49c4.4,15.33,6.5,31.4199,4.94,47.34c-0.61,2.75,1.77,4.2,3.32,6c0.24,2.62,0.2,5.3201-0.35,7.9301
c-0.72,2.63-3.7,4.11-3.98,6.9199c-1.42,10.8301-5.87,20.91-9.56,31.11c-4.52,11.64-7.19,23.87-9.88,36.04
c-1.32,10.27-2.18,20.65-1.53,31.01c0.86,14.88,2.98,29.65,4.88,44.42c3.84,24.5299,2.93,49.64-1.09,74.09
c-2.91,16.51-7.06,32.89-13.58,48.38c-4.27,10.25-10.14,19.87-17.7,28.0499c-4.58,4.8601-11.45,7.38-18.07,7.15
c-7.93-0.46-14.25-6.23-18.51-12.49c-11.86-17.4299-17.3-38.1699-21.44-58.5699c-4.87-21.9501-6.25-44.5801-4.84-66.99
c0.98-24.0901,4.68-48,5.23-72.11c0.58-21.1801-5.14-41.8301-11.54-61.8301c-2.67-9.3099-6.35-18.4299-7.21-28.15
c-0.36-4.12-2.91-7.8099-2.46-12.0199c0.06-2.4801,1.75-4.51,2.09-6.91c1.22-17.48,2.6-35.27,8.6-51.87
c0.74,0.0599,2.23,0.1899,2.97,0.25C80.4978,1496.6771,80.4878,1494.0271,82.6178,1493.5271z"/>
<path stroke="#000000" stroke-width="0.0938" d="M1233.3679,1622.5571c1.76-0.6901,4.0599-1.13,5.5599,0.37
c1.59,2.13,1.04,5.2999-0.79,7.12c-3.6,3.65-8.5099,5.5499-12.6,8.5499c-15.45,10.51-31.58,19.9401-47.6,29.53
c-31.89,19.2001-63.78,38.41-96.3199,56.47c-14.4,8.13-29.3,15.55-42.5901,25.4801c-4.6,3.3099-9.71,6.1499-13.17,10.7799
c-4.46,5.78-8.16,12.54-14.74,16.24c-10.84,6.26-23.12,12.3201-29.24,23.8301c-1.58,6.73-2.18,13.72-4.56,20.28
c-2.95,8.96-7.98,17.58-15.85,23.0499c-9.18,6.37-20.33,9.97-31.5,10.12c-7.01,0.12-14.36-2.9099-21.04,0.4601
c-9.02,4.48-17.79,10.1799-24.15,18.12c-2.75,3.24-4.01,7.61-7.31,10.4199c-3.1,2.3401-7.43,1.39-10.47-0.5599
c-4.83-3.05-8.62-8.1801-9.4-13.89c-0.41-2.09,1.12-3.86,3.08-4.26c12.43-3.04,22.86-11.4,31.32-20.6901
c1.47-1.72,4.17-4.08,2.25-6.4199c-4.48-6.5601-7.27-14.5601-6.44-22.5601c0.68-7.4099,4.07-14.25,8.26-20.2799
c-3.12-1.38-5.66-3.6901-8.59-5.3501c-3.0601-1.8199-5.01-5.96-3.63-9.37c1.75-3.13,5.41-4.1699,8.41-5.6799
c9.89-4.7001,20.24-9.17,28.19-16.92c6.34-6.6,12.15-13.99,15.37-22.65c-9.25-1.6899-18.44-4.12-27.9-4.1799
c-6.97,0.09-13.96-1.0701-20.55-3.3201c-5.48-1.99-8.76-7.63-9.33-13.23c-1.21-10.79,2.78-21.98,10.3199-29.76
c10.1801-10.6799,25.09-15.9199,39.63-16.27c10.23-0.14,21.05,2.03,29.11,8.6901c6.71,5.45,10.29,14.64,8.46,23.1799
c-1.14,6.17-5.38,11-8.52,16.2301c-1.35,1.88-0.73,4.2799-0.8701,6.46c18.17-1.17,35.46-8.3101,53.75-8.4301
c7.17-0.1,14.8001,0.4701,21.4201-2.84c4.1899-1.98,5.97-6.84,10.1799-8.8099c17.8101-8.91,36.2401-16.4901,54.4801-24.4701
C1141.1879,1658.0872,1186.8179,1639.0771,1233.3679,1622.5571 M922.4678,1680.597c-8.07,1.55-16.17,4.78-21.78,11
c-5.08,5.39-9.22,12.7001-7.99,20.3601c0.2,2.22,2.18,3.63,4.15,4.2999c11.23,3.8101,23.5,4.24,35.05,1.64
c8.61-2,17.06-6.37,22.3-13.6899c2.82-3.9,4.68-9.38,2.26-13.89c-2.82-3.6801-7.23-5.6-11.3-7.51
C938.1678,1679.3171,929.9978,1679.1971,922.4678,1680.597 M977.7478,1733.6971c-6.83,1.61-10.89,8.01-17.27,10.49
c-4.8,2.0599-9.14,5.02-13.16,8.3199c-3.29,2.5701-7.82,2.74-11.04,5.39c-2.54,2.8201-4.78,6.15-5.45,9.96
c-0.72,3.6801-3.53,6.3401-5.86,9.0801c8.12-2.3401,16.66-2.39,25.04-2c10.36-0.1,20.91-0.4501,30.85-3.67
c16.06-5.1899,30.16-15.84,40.25-29.29c2.32-2.7899,4.8501-5.58,5.7001-9.22c-4.0601-0.8199-8.2001-1.0499-12.27-1.63
C1002.2478,1729.4672,989.7378,1730.847,977.7478,1733.6971 M935.4278,1790.7271c-10.75,3.54-21.91,8.6101-28.72,18.05
c-3.28,5.0699-6.22,11.02-5.45,17.24c0.86,5.4401,5.55,9.34,10.47,11.24c12.91,5.1,27.84,2.9601,39.74-3.7999
c9.99-5.4601,18.48-14.99,19.9-26.6101c0.83-5.09-0.84-11.1399-5.79-13.5099
C956.2978,1788.8771,945.3378,1788.1671,935.4278,1790.7271z"/>
<path stroke="#000000" stroke-width="0.0938" d="M1183.3179,1713.9171c2.54-2.42,6.0601-3.38,9.49-2.45
c11.48,2.7999,23.1901,4.5199,34.74,7.0499c27.47,5.8101,54.87,11.96,82.28,18.03c7.38,1.78,14.95-0.91,22.35,0.7
c9.15,1.6801,17.85,5.13,26.84,7.49c17.29,4.53,35.04,7.01,52.79,8.86c10.42,1.2001,20.9301,1.9501,31.16,4.41
c6.4,1.09,13.3199,3.01,19.65,0.64c7.5699-4.26,8.9299-14.28,16.24-18.87c15.9399-10.84,39.2899-6.87,51.88,7.37
c2.9199,3.63,3.4299,8.75,7.02,11.9401c4.5699,4.9299,11.7699,5.8999,18.1499,5.2c5.4701-0.6801,11.0701-1.34,16.1901-3.53
c2.24,1.77,4.6899,3.99,4.4399,7.17c-0.27,4.03-2.5699,8.61-6.75,9.7c-8.9299,1.51-16.99-5.35-25.9099-3.51
c-6.38,1.7201-9.1901,8.28-12.4401,13.37c-3.16,5.3301-8.95,8.64-14.96,9.64c-4.7001,0.73-9.42,1.51-13.8401,3.3301
c3.7001,6.7999,11.5601,9.63,15.8,15.99c3.99,5.6499,6.76,12.46,6.37,19.49c-0.26,6.9099-3.62,13.45-8.49,18.26
c-12.02,11.9399-31.89,15.13-46.9399,7.27c-7.4501-3.89-13.54-10.1901-17.4701-17.5901c-3.37-7.36-0.84-16.11-4.61-23.36
c-2.45-4.21-6.75-6.87-10.97-9c-8.49-4.26-17.74-6.71-26.3199-10.74c-9.8101-4.4301-19.25-9.6801-29.25-13.6899
c-18.6901-7.1901-38.0701-12.38-56.92-19.1101c-13.89-5.13-27.59-10.7799-41.67-15.35c-22.35-7.5399-45-14.11-67.4-21.48
C1203.5979,1727.2172,1189.7179,1725.1571,1183.3179,1713.9171 M1491.4979,1745.5071c-7.51,1.6801-14.5801,7.15-16.3301,14.9
c-1.6799,6.85,1.86,13.88,6.9601,18.34c5.0599,4.73,12.0699,6.4401,18.7699,7.27c8.0601,0.78,17.03-0.27,23.3601-5.78
c4.3099-3.95,7.5399-10.61,4.62-16.2699c-3.1101-5.8101-8.66-9.7401-13.87-13.5
C1508.2678,1745.6871,1499.6179,1743.2371,1491.4979,1745.5071 M1386.2979,1768.5671c16.75,9.12,33.9301,17.4299,50.8101,26.3199
c5.33,2.73,10.0299,6.77,15.8199,8.59c5.8101,1.5801,10.72-2.6,15.74-4.72c5.38-2.49,11.48-0.23,16.98-2.25
c-5.24-6.21-13.09-9.71-17.6499-16.5699c-2.12-3.12-4.29-7.04-8.51-7.35c-16.73-2.4-33.6801-1.4701-50.52-1.9301
C1401.2878,1770.847,1393.9479,1765.8871,1386.2979,1768.5671 M1476.5079,1808.6271c-6.52,1.62-13.54,4.7001-16.7301,11
c-2.98,6.54,0.1901,13.88,4.3101,19.15c6.79,8.48,16.89,14.9,27.91,15.62c6.59,0.01,13.7999-2.0699,18-7.47
c4.0399-5.3101,3.5199-12.84,0.63-18.55c-3.2401-6.77-9.42-11.36-15.28-15.71
C1490.0278,1808.7072,1483.0079,1806.6171,1476.5079,1808.6271z"/>
</g>
</svg>

BIN
jm2l/static/img/2020/Handicap-Symbol-300x300.jpg View File

Before After
Width: 300  |  Height: 300  |  Size: 7.1 KiB

BIN
jm2l/static/img/2020/Spaceport_2006.otf View File


BIN
jm2l/static/img/2020/Web-Marketing.jpg View File

Before After
Width: 460  |  Height: 275  |  Size: 26 KiB

+ 1863
- 0
jm2l/static/img/2020/bandeau_2020.svg
File diff suppressed because it is too large
View File


+ 1864
- 0
jm2l/static/img/2020/bandeau_2020.svg.2020_08_10_10_04_17.0.svg
File diff suppressed because it is too large
View File


+ 1751
- 0
jm2l/static/img/2020/bandeau_2020_v1.svg
File diff suppressed because it is too large
View File


BIN
jm2l/static/img/2020/biens-communs.jpg View File

Before After
Width: 584  |  Height: 214  |  Size: 59 KiB

+ 44
- 0
jm2l/static/img/2020/caddy.svg View File

@@ -0,0 +1,44 @@
<?xml version="1.0"?>
<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:svg="http://www.w3.org/2000/svg" id="svg2" height="297mm" width="210mm" version="1.1">
<title id="title3885">shopping cart</title>
<g id="layer1">
<path id="path3847" style="block-progression:tb;color:#000000;text-transform:none;text-indent:0" d="m579.07 41.891c-0.5602 0.008-1.1368 0.0575-1.6876 0.15625-0.01 0.002-0.021-0.002-0.031 0l-55.625 9.5c-3.5377 0.60697-6.5035 3.0328-7.8125 6.375a2.529 2.529 0 0 0 0 0.0312l-25.812 66.187-251.91 6.2812c-2.897 0.0724-5.6164 1.3809-7.5 3.5625-1.8833 2.1817-2.7899 5.0829-2.4376 7.9688l13.906 115.03c0.5737 4.8261 4.561 8.6532 9.4063 9.0312l179.59 14.281 35.594 28a2.529 2.529 0 0 0 0.125 0.0937c0.038 0.0264 0.086 0.0365 0.125 0.0625 0.044 0.0291 0.081 0.0652 0.125 0.0937 6.4957 4.8485 8.1056 11.454 7.1876 15.125-0.5231 2.0918-1.3217 3.6286-3.2188 4.8125-1.8971 1.1838-5.1742 2.0406-10.781 1.7188a2.529 2.529 0 0 0 -0.063 0c-0.1801-0.006-0.3823-0.004-0.5624 0-0.03 0.00069-0.064-0.00096-0.094 0l-214.19 0.625h-0.031c-5.6288-0.0359-10.366 4.6852-10.344 10.312 0.022 5.6278 4.7779 10.331 10.406 10.25 0.011-0.00015 0.021 0.00019 0.031 0l15.656-0.0312c-5.8172 3.7083-9.7187 10.195-9.7187 17.562 0 11.459 9.3852 20.844 20.844 20.844s20.844-9.385 20.844-20.844c0-7.4072-3.9118-13.958-9.7812-17.656l176.38-0.5c-6.3545 3.5825-10.688 10.384-10.688 18.156 0 11.459 9.385 20.844 20.844 20.844s20.844-9.385 20.844-20.844c0-9.9515-7.0696-18.341-16.438-20.375 8.8575-3.1334 15.662-9.5946 19.875-19.469a2.529 2.529 0 0 0 0.1563 -0.375c3.23-12.916-2.4989-26.959-14.312-36.094a2.529 2.529 0 0 0 -0.094 -0.0937c-0.029-0.0222-0.034-0.0716-0.062-0.0937a2.529 2.529 0 0 0 -0.3438 -0.34375l-25.219-19.781 78.656-201.47 49.906-8.5c0.01-0.002 0.021 0.002 0.031 0 5.2427-0.84286 9.0768-5.7292 8.625-11.031-0.4525-5.3122-5.0811-9.4786-10.406-9.4062zm-98.563 98.125-14.5 37.188h-18.906v-36.344l33.406-0.84375zm-40.625 1.0312v36.156h-34.906v-35.281l34.906-0.875zm-42.125 1.0312v35.125h-34.906v-34.25l34.906-0.875zm-42.125 1.0625v34.062h-34.906v-33.188l34.906-0.875zm-42.125 1.0625v33h-34.906v-32.125l34.906-0.875zm-42.125 1.0312v31.969h-25.594l-3.7813-31.219 29.375-0.75zm-24.719 39.156h24.719v32.656h-20.781l-3.9375-32.656zm31.938 0h34.906v32.656h-34.906v-32.656zm42.125 0h34.906v32.656h-34.906v-32.656zm42.125 0h34.906v32.656h-34.906v-32.656zm42.125 0h34.906v32.656h-34.906v-32.656zm42.125 0h16.125l-12.75 32.656h-3.375v-32.656zm-195.62 39.844h19.906v23.438l-17.25-1.375-2.6562-22.062zm27.125 0h34.906v26.781l-34.906-2.7812v-24zm42.125 0h34.906v30.125l-34.906-2.75v-27.375zm42.125 0h34.906v33.5l-34.906-2.7812v-30.719zm42.125 0h34.906v19.875l-6.625 16.969c-0.86-0.41667-1.7975-0.6724-2.75-0.75l-25.531-2.0312v-34.062zm42.125 0h0.5312l-0.5312 1.4688v-1.4688zm-176.84 132.44c6.8111 0 12.25 5.439 12.25 12.25s-5.4389 12.219-12.25 12.219c-6.8107 0-12.25-5.4078-12.25-12.219 0-6.811 5.4393-12.25 12.25-12.25zm197.59 0c6.8109 0 12.25 5.439 12.25 12.25s-5.4391 12.219-12.25 12.219c-6.811 0-12.25-5.4078-12.25-12.219 0-6.811 5.439-12.25 12.25-12.25zm-197.59 5.8125c-3.7001 0-6.6562 2.9561-6.6562 6.6562 0 3.7002 2.9561 6.625 6.6562 6.625 3.7003 0 6.6563-2.9248 6.6563-6.625s-2.956-6.6562-6.6563-6.6562zm197.59 0c-3.7002 0-6.6562 2.9561-6.6562 6.6562 0 3.7002 2.956 6.625 6.6562 6.625 3.7001 0 6.6562-2.9248 6.6562-6.625s-2.9561-6.6562-6.6562-6.6562z"/>
</g>
<metadata>
<rdf:RDF>
<cc:Work>
<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/publicdomain/"/>
<dc:publisher>
<cc:Agent rdf:about="http://openclipart.org/">
<dc:title>Openclipart</dc:title>
</cc:Agent>
</dc:publisher>
<dc:title>shopping cart</dc:title>
<dc:date>2010-05-13T14:39:42</dc:date>
<dc:description>shopping carg</dc:description>
<dc:source>http://openclipart.org/detail/60139/shopping-cart-by-voyeg3r</dc:source>
<dc:creator>
<cc:Agent>
<dc:title>voyeg3r</dc:title>
</cc:Agent>
</dc:creator>
<dc:subject>
<rdf:Bag>
<rdf:li>cart</rdf:li>
<rdf:li>clip art</rdf:li>
<rdf:li>clipart</rdf:li>
<rdf:li>shopping</rdf:li>
<rdf:li>supermarket</rdf:li>
</rdf:Bag>
</dc:subject>
</cc:Work>
<cc:License rdf:about="http://creativecommons.org/licenses/publicdomain/">
<cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction"/>
<cc:permits rdf:resource="http://creativecommons.org/ns#Distribution"/>
<cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks"/>
</cc:License>
</rdf:RDF>
</metadata>
</svg>

+ 99
- 0
jm2l/static/img/2020/disabled-man-icon.svg View File

@@ -0,0 +1,99 @@
<?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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg2"
sodipodi:docname="disabled-man-icon.svg"
viewBox="0 0 700 800"
version="1.1"
inkscape:version="0.92.1 r15371"
width="746.66669"
height="853.33331">
<defs
id="defs8" />
<sodipodi:namedview
id="base"
bordercolor="#666666"
inkscape:pageshadow="2"
inkscape:window-y="7"
fit-margin-left="0"
pagecolor="#ffffff"
fit-margin-top="0"
inkscape:window-maximized="1"
inkscape:zoom="0.5"
inkscape:window-x="-4"
inkscape:window-height="1000"
showgrid="false"
borderopacity="1.0"
inkscape:current-layer="layer1"
inkscape:cx="477"
inkscape:cy="242"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="1280"
inkscape:pageopacity="0.0"
inkscape:document-units="px" />
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer"
transform="translate(-533.54,-111.5)">
<path
id="path3005"
sodipodi:nodetypes="cssssscscccccccccccccccccccscccccsccccssscc"
style="fill:#333333;fill-rule:evenodd"
inkscape:connector-curvature="0"
d="m 810.21,273.78 c -12.232,12.232 -27.039,18.348 -44.421,18.348 -17.318,0 -32.124,-6.1159 -44.356,-18.348 -12.296,-12.296 -18.412,-27.103 -18.412,-44.421 0,-17.318 6.1159,-32.124 18.412,-44.421 12.232,-12.232 27.039,-18.348 44.356,-18.348 17.382,0 32.189,6.1159 44.421,18.348 12.232,12.296 18.348,27.103 18.348,44.421 0,17.318 -6.1159,32.124 -18.348,44.421 z m 13.133,139.76 h 105.32 l 24.785,56.974 h -125.79 l 2.897,39.657 h 182.06 l 91.545,210.52 61.803,-26.91 17.575,40.3 -114.08,49.7 -94.249,-216.57 h -225.9 l -19.056,-255.19 85.107,-6.309 z m -101.85,75.579 -4.8927,-65.536 c -24.27,11.009 -46.545,26.652 -66.824,46.931 -44.163,44.099 -66.245,97.403 -66.245,159.85 v 0.57941 l 0.0643,5.8584 c 1.4807,59.614 23.498,110.73 66.18,153.35 42.747,42.811 94.056,64.893 153.99,66.245 h 6.4378 c 62.124,-0.12875 115.17,-22.21 159.21,-66.245 21.245,-21.245 37.403,-44.614 48.412,-70.043 l -42.682,-97.983 c 0.13001,6.9817 0.2195,14.187 -0.1931,20.665 -2.6395,40.687 -18.734,75.837 -48.219,105.39 -32.446,32.382 -71.652,48.541 -117.55,48.541 -45.901,0 -85.043,-16.159 -117.42,-48.541 -32.446,-32.446 -48.67,-71.652 -48.67,-117.55 0,-45.901 16.223,-85.043 48.67,-117.42 9.3348,-9.3348 19.249,-17.382 29.742,-24.077" />
</g>
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work>
<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/publicdomain/" />
<dc:publisher>
<cc:Agent
rdf:about="http://openclipart.org/">
<dc:title>Openclipart</dc:title>
</cc:Agent>
</dc:publisher>
<dc:title>The Symbol of Disabled Man</dc:title>
<dc:date>2011-09-26T14:12:52</dc:date>
<dc:description>Simple clear icon with minimum nodes</dc:description>
<dc:source>https://openclipart.org/detail/162061/the-symbol-of-disabled-man-by-vlodco_zotov</dc:source>
<dc:creator>
<cc:Agent>
<dc:title>vlodco_zotov</dc:title>
</cc:Agent>
</dc:creator>
<dc:subject>
<rdf:Bag>
<rdf:li>disabled</rdf:li>
<rdf:li>icon</rdf:li>
<rdf:li>man</rdf:li>
<rdf:li>symbol</rdf:li>
</rdf:Bag>
</dc:subject>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/publicdomain/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
</cc:License>
</rdf:RDF>
</metadata>
</svg>

BIN
jm2l/static/img/2020/handicap_Bored.png View File

Before After
Width: 531  |  Height: 400  |  Size: 16 KiB

BIN
jm2l/static/img/2020/logo.png View File

Before After
Width: 958  |  Height: 213  |  Size: 221 KiB

BIN
jm2l/static/img/2020/rdptcoluche.jpg View File

Before After
Width: 507  |  Height: 380  |  Size: 48 KiB

+ 1
- 0
jm2l/static/img/2020/sapins.svg
File diff suppressed because it is too large
View File


+ 120
- 0
jm2l/static/img/2020/simple-Gear.svg View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:ns1="http://sozi.baierouge.fr"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
id="svg2319"
sodipodi:modified="true"
sodipodi:docname="simple_Gear.svg"
viewBox="0 0 121 121"
sodipodi:version="0.32"
version="1.0"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
inkscape:version="0.48.4 r9939"
>
<title
id="title2822"
>Gear</title
>
<sodipodi:namedview
id="base"
inkscape:snap-center="true"
inkscape:showpageshadow="false"
inkscape:zoom="1.6644983"
borderopacity="1.0"
inkscape:current-layer="Capa_x0020_1"
inkscape:cx="73.944172"
inkscape:cy="40.809784"
inkscape:window-maximized="1"
showgrid="false"
inkscape:guide-bbox="true"
showguides="true"
bordercolor="#666666"
inkscape:window-x="65"
guidetolerance="10"
objecttolerance="10"
inkscape:window-y="24"
inkscape:window-width="1855"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
pagecolor="#ffffff"
gridtolerance="10000"
inkscape:document-units="px"
inkscape:window-height="1056"
/>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer"
transform="translate(-153.03 -268.95)"
>
<g
id="Capa_x0020_1"
style="fill-rule:evenodd"
transform="matrix(39.803 0 0 39.803 63.558 116.51)"
>
<path
id="path83"
style="stroke:#dededd;stroke-width:.057358;fill:#c2c1c1"
d="m74.031 0.0625l-7.625 13.376c-1.948-0.254-3.952-0.376-5.968-0.376-2.281 0-4.528 0.147-6.719 0.469l-8.469-13.062c-4.32 1.1292-8.454 2.7376-12.344 4.7498l2.656 15.187c-3.574 2.316-6.813 5.12-9.624 8.313l-14.813-4.5c-2.5493 3.609-4.7344 7.491-6.4688 11.625l11.688 9.906c-1.241 4.003-1.94 8.239-2.063 12.625l-14.218 6.187c0.35094 4.527 1.1952 8.929 2.4682 13.126l15.25-0.032c1.644 3.984 3.823 7.697 6.438 11.032l-6.938 13.972c3.091 3.17 6.508 6 10.219 8.43l11.688-9.9c3.713 1.95 7.719 3.4 11.937 4.28l3.563 15.19c1.898 0.18 3.804 0.28 5.75 0.28 2.519 0 4.999-0.17 7.437-0.47l2.656-15.19c4.199-0.94 8.162-2.45 11.844-4.47l12.406 9.35c3.641-2.54 6.999-5.46 9.999-8.72l-7.655-13.378c2.559-3.376 4.705-7.111 6.285-11.124l15.43-0.876c1.16-4.227 1.87-8.646 2.1-13.187l-14.35-5.281c-0.19-4.379-1-8.579-2.31-12.563l11.28-10.719c-1.84-4.079-4.13-7.929-6.78-11.468l-14.342 5.281c-2.863-3.143-6.136-5.869-9.75-8.125l1.812-15.531c-3.941-1.9002-8.114-3.3986-12.469-4.4065zm-13.531 52.626c4.313 0 7.812 3.499 7.812 7.812s-3.499 7.812-7.812 7.812-7.812-3.499-7.812-7.812 3.499-7.812 7.812-7.812z"
transform="matrix(.025123 0 0 .025123 2.248 3.8298)"
/>
</g
>
</g
>
<metadata
>
<rdf:RDF
>
<cc:Work
>
<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/publicdomain/"
/>
<dc:publisher
>
<cc:Agent
rdf:about="http://openclipart.org/"
>
<dc:title
>Openclipart</dc:title
>
</cc:Agent
>
</dc:publisher
>
</cc:Work
>
<cc:License
rdf:about="http://creativecommons.org/licenses/publicdomain/"
>
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction"
/>
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution"
/>
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks"
/>
</cc:License
>
</rdf:RDF
>
</metadata
>
</svg
>

+ 60
- 0
jm2l/static/img/2020/wifil.svg View File

@@ -0,0 +1,60 @@
<?xml version="1.0"?>
<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://web.resource.org/cc/" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:svg="http://www.w3.org/2000/svg" id="svg2" viewBox="0 0 524.41 744.09" version="1.0">
<g id="layer1">
<g id="g6728" transform="matrix(4.9859 0 0 4.9859 -1552.8 -1873.1)">
<g id="g5114" transform="translate(14.508 -2.7766)">
<path id="path5112" stroke-linejoin="round" d="m335.97 451.57c-9.22-4.99-15.48-14.75-15.48-25.96 0-10.86 5.87-20.35 14.61-25.47" stroke-dashoffset="5" stroke="#000" stroke-linecap="round" stroke-width=".98361" fill="none"/>
<path id="path5107" stroke-linejoin="round" d="m365.47 400.48c8.42 5.2 14.04 14.51 14.04 25.13v0c0 10.97-6 20.56-14.9 25.64" stroke-dashoffset="5" stroke="#000" stroke-linecap="round" stroke-width=".98361" fill="none"/>
</g>
<use id="use5733" xlink:href="#g5114" transform="matrix(1.32 0 0 1.32 -116.64 -135.38)" height="1052.3622" width="744.09448" y="0" x="0"/>
<use id="use5735" xlink:href="#g5114" transform="matrix(1.6479 0 0 1.6479 -236.17 -274.12)" height="1052.3622" width="744.09448" y="0" x="0"/>
<path id="path5737" d="m365 422.36v80" stroke="#000" stroke-linecap="round" stroke-width="5" fill="none"/>
<path id="path5739" d="m380 429.86a7.5 7.5 0 1 1 -15 0 7.5 7.5 0 1 1 15 0z" transform="translate(-7.5 -7.5)" fill-rule="evenodd"/>
</g>
</g>
<metadata>
<rdf:RDF>
<cc:Work>
<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/publicdomain/"/>
<dc:publisher>
<cc:Agent rdf:about="http://openclipart.org/">
<dc:title>Openclipart</dc:title>
</cc:Agent>
</dc:publisher>
<dc:title>Wireless/WiFi symbol</dc:title>
<dc:date>2008-03-08T19:15:09</dc:date>
<dc:description>Wireless symobol for creating network schmatic</dc:description>
<dc:source>http://openclipart.org/detail/15561/wireless/wifi-symbol-by-ispyisail</dc:source>
<dc:creator>
<cc:Agent>
<dc:title>ispyisail</dc:title>
</cc:Agent>
</dc:creator>
<dc:subject>
<rdf:Bag>
<rdf:li>access point</rdf:li>
<rdf:li>clip art</rdf:li>
<rdf:li>clipart</rdf:li>
<rdf:li>icon</rdf:li>
<rdf:li>image</rdf:li>
<rdf:li>media</rdf:li>
<rdf:li>network</rdf:li>
<rdf:li>png</rdf:li>
<rdf:li>public domain</rdf:li>
<rdf:li>router</rdf:li>
<rdf:li>svg</rdf:li>
<rdf:li>wifi</rdf:li>
<rdf:li>wireless</rdf:li>
</rdf:Bag>
</dc:subject>
</cc:Work>
<cc:License rdf:about="http://creativecommons.org/licenses/publicdomain/">
<cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction"/>
<cc:permits rdf:resource="http://creativecommons.org/ns#Distribution"/>
<cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks"/>
</cc:License>
</rdf:RDF>
</metadata>
</svg>

+ 1
- 1
jm2l/templates/Errors/403.mako View File

@@ -58,7 +58,7 @@
% if reason: % if reason:
<p>${reason}</p> <p>${reason}</p>
% else: % else:
<p>Vous n'êtes pas authentifi&eacute;, ou n'avez pas les authorisations n&eacute;cessaires.</p>
<p>Vous n'êtes pas authentifié, ou n'avez pas les authorisations nécessaires.</p>
% endif % endif
</body> </body>
</html> </html>


+ 1
- 1
jm2l/templates/Errors/404.mako View File

@@ -54,7 +54,7 @@
</head> </head>
<body> <body>
<img src="/img/error404.png" width="200px" /> <img src="/img/error404.png" width="200px" />
<h1>Page non trouv&eacute;e</h1>
<h1>Page non trouvée</h1>
% if reason: % if reason:
<p>${reason}</p> <p>${reason}</p>
% else: % else:


+ 12
- 12
jm2l/templates/Interventions/Interventions.mako View File

@@ -10,7 +10,7 @@
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td>Conf&eacute;rences</td> <td style="text-align:center">
<td>Conférences</td> <td style="text-align:center">
% if len( request.user.year_events('Conference') ): % if len( request.user.year_events('Conference') ):
% for evt in request.user.year_events('Conference'): % for evt in request.user.year_events('Conference'):
% endfor % endfor
@@ -106,11 +106,11 @@ elif Type=='T':
%> %>
% if Type!='O': % if Type!='O':
<fieldset> <fieldset>
<legend class="lowshadow">Vos ${CurTitles} programm&eacute;s pour ${CurrentYear}</legend>
<legend class="lowshadow">Vos ${CurTitles} programmés pour ${CurrentYear}</legend>
<% <%
Selection = filter(lambda x:(x.event_type==CurEventType and x.for_year==CurrentYear), uprofil.events)
Selection = list(filter(lambda x:(x.event_type==CurEventType and x.for_year==CurrentYear), uprofil.events))
HeadHistTitle = u"L'historique de vos %s ( %d ) " % ( CurTitles, len(Selection) ) HeadHistTitle = u"L'historique de vos %s ( %d ) " % ( CurTitles, len(Selection) )
NothingTitle = u"Vous n'avez pas sollicit&eacute; d'intervention %s." % CurEvent
NothingTitle = u"Vous n'avez pas sollicité d'intervention %s." % CurEvent
%> %>
${helpers.show_Interventions(Selection, "Sujet", NothingTitle )} ${helpers.show_Interventions(Selection, "Sujet", NothingTitle )}
</fieldset> </fieldset>
@@ -118,21 +118,21 @@ NothingTitle = u"Vous n'avez pas sollicit&eacute; d'intervention %s." % CurEvent


% if Type=='C': % if Type=='C':
<p> <p>
<strong>Proposer une conf&eacute;rence / un lighting talk</strong><br/>
<strong>Proposer une conférence / un lighting talk</strong><br/>
<ul> <ul>
<li>Si vous avez une exp&eacute;rience particulière avec les logiciels libres
<li>Si vous avez une expérience particulière avec les logiciels libres
que vous souhaitez partager.</li> que vous souhaitez partager.</li>
<li>Si vous êtes acteur d’un des sujets actuels qui menacent ou qui <li>Si vous êtes acteur d’un des sujets actuels qui menacent ou qui
promeuvent le logiciel libre.</li> promeuvent le logiciel libre.</li>
<li>Si vous voulez pr&eacute;senter un logiciel libre dont vous êtes l’auteur.</li>
<li>Si vous voulez présenter un logiciel libre dont vous êtes l’auteur.</li>
</ul> </ul>
Nous serons heureux de vous &eacute;couter.
Nous serons heureux de vous écouter.
<br> <br>
Nous souhaitons proposer des conf&eacute;rences pour un public d&eacute;butant
Nous souhaitons proposer des conférences pour un public débutant
autant que pour des visiteurs avertis. Les sujets ne doivent pas autant que pour des visiteurs avertis. Les sujets ne doivent pas
forc&eacute;ment être techniques, mais aussi d’ordre g&eacute;n&eacute;ral avec la seule
forcément être techniques, mais aussi d’ordre général avec la seule
contrainte de traiter de près ou de loin des logiciels libres, de la contrainte de traiter de près ou de loin des logiciels libres, de la
communaut&eacute; ou de vos propres exp&eacute;riences d’utilisateur quotidien. <br>
communauté ou de vos propres exp&eacute;riences d’utilisateur quotidien. <br>
Le but de ces conf&eacute;rences est double : Le but de ces conf&eacute;rences est double :
<ul> <ul>
<li>donner confiance aux futurs utilisateurs de logiciels libres</li> <li>donner confiance aux futurs utilisateurs de logiciels libres</li>
@@ -205,7 +205,7 @@ NothingTitle = u"Vous n'avez pas sollicit&eacute; d'intervention %s." % CurEvent
<fieldset> <fieldset>
<legend class="lowshadow">Historique</legend> <legend class="lowshadow">Historique</legend>
<% <%
Selection = filter(lambda x:(x.event_type==CurEventType and x.for_year!=CurrentYear), uprofil.events)
Selection = list(filter(lambda x:(x.event_type==CurEventType and x.for_year!=CurrentYear), uprofil.events))
HeadHistTitle = u"L'historique de vos %s ( %d ) " % ( CurTitles, len(Selection) ) HeadHistTitle = u"L'historique de vos %s ( %d ) " % ( CurTitles, len(Selection) )
NothingTitle = u"D&eacute;sol&eacute;, Il n'y a rien dans l'historique vous concernant." NothingTitle = u"D&eacute;sol&eacute;, Il n'y a rien dans l'historique vous concernant."
%> %>


+ 1
- 1
jm2l/templates/Logistique/Dialog_Covoit.mako View File

@@ -30,7 +30,7 @@
</tbody> </tbody>
</table> </table>
<div class="center"> <div class="center">
Pour un co-voiturage le <u>${Exch.start_time.strftime("%a %d %b").decode('utf-8')}</u>
Pour un co-voiturage le <u>${Exch.start_time.strftime("%a %d %b")}</u>
vers <strong>${Exch.start_time.strftime("%H:%M")}</strong> vers <strong>${Exch.start_time.strftime("%H:%M")}</strong>
</div> </div>
Temps de voyage estimé à <span id="summary"></span> Temps de voyage estimé à <span id="summary"></span>


+ 1
- 1
jm2l/templates/Logistique/Dialog_Heberg.mako View File

@@ -12,7 +12,7 @@
<dd>Un hébergement</dd> <dd>Un hébergement</dd>
% endif % endif
<dt>Quand </dt> <dt>Quand </dt>
<dd>La nuit du ${Exch.start_time.strftime('%A %d %b %Y').decode('utf-8')} jusqu'au lendemain</dd>
<dd>La nuit du ${Exch.start_time.strftime('%A %d %b %Y')} jusqu'au lendemain</dd>
% if Exch.description: % if Exch.description:
<dt>Détails </dt> <dt>Détails </dt>
<dd>${Exch.description}</dd> <dd>${Exch.description}</dd>


+ 2
- 2
jm2l/templates/Logistique/Dialog_Matos.mako View File

@@ -8,8 +8,8 @@
<dt>Catégorie</dt> <dt>Catégorie</dt>
<dd>${Exch.Category.exch_subtype}</dd> <dd>${Exch.Category.exch_subtype}</dd>
<dt>Quand </dt> <dt>Quand </dt>
<dd>de ${Exch.start_time.strftime('%A %d %b %Y').decode('utf-8')} vers ${Exch.start_time.strftime('%Hh%M')}
à ${Exch.end_time.strftime('%A %d %b %Y').decode('utf-8')} vers ${Exch.end_time.strftime('%Hh%M')}
<dd>de ${Exch.start_time.strftime('%A %d %b %Y')} vers ${Exch.start_time.strftime('%Hh%M')}
à ${Exch.end_time.strftime('%A %d %b %Y')} vers ${Exch.end_time.strftime('%Hh%M')}
</dd> </dd>
<dt>Détails </dt> <dt>Détails </dt>
<dd>${Exch.description}</dd> <dd>${Exch.description}</dd>


+ 17
- 17
jm2l/templates/Logistique/Logistique.mako View File

@@ -8,11 +8,11 @@ DicExch = Exchanges.get_overview( request.user.uid )
<div class="tabbable tabs-left" id="Intendance_tab"> <div class="tabbable tabs-left" id="Intendance_tab">
<ul class="nav nav-tabs navbar" style="margin-bottom:0;background-color: #f7f7f7;"> <ul class="nav nav-tabs navbar" style="margin-bottom:0;background-color: #f7f7f7;">
<li class="active"> <a href="#ResumeInt" data-toggle="tab">Resum&eacute;</a> </li>
<li class="active"> <a href="#ResumeInt" data-toggle="tab">Resumé</a> </li>
<li> <a href="#Miam" data-toggle="tab"><span style="font-size:1.8em;">&#127869;</span> Miam</a> </li> <li> <a href="#Miam" data-toggle="tab"><span style="font-size:1.8em;">&#127869;</span> Miam</a> </li>
<li> <a href="#Covoiturage" data-toggle="tab"><span style="font-size:1.8em;">&#128664;</span> Covoiturage</a> </li> <li> <a href="#Covoiturage" data-toggle="tab"><span style="font-size:1.8em;">&#128664;</span> Covoiturage</a> </li>
<li> <a href="#Hebergement" data-toggle="tab"><span style="font-size:1.8em;">&#127962;</span> H&eacute;bergement</a> </li>
<li> <a href="#Materiel" data-toggle="tab"><span style="font-size:1.8em;">&#128722;</span> Mat&eacute;riel</a> </li>
<li> <a href="#Hebergement" data-toggle="tab"><span style="font-size:1.8em;">&#127962;</span> Hébergement</a> </li>
<li> <a href="#Materiel" data-toggle="tab"><span style="font-size:1.8em;">&#128722;</span> Matériel</a> </li>
</ul> </ul>
<div class="tab-content"> <div class="tab-content">
@@ -30,7 +30,7 @@ DicExch = Exchanges.get_overview( request.user.uid )
${tables.DoTable(Type, 'Ask', DicExch)} ${tables.DoTable(Type, 'Ask', DicExch)}
${tables.DoTable(Type, 'Proposal', DicExch)} ${tables.DoTable(Type, 'Proposal', DicExch)}
<fieldset> <fieldset>
<legend>Tous les &eacute;changes</legend>
<legend>Tous les échanges</legend>
${Missing(Type, DicExch['Missing'])} ${Missing(Type, DicExch['Missing'])}
</fieldset> </fieldset>
</%def> </%def>
@@ -59,23 +59,23 @@ DicForm = {
</td> </td>
<td> <td>
<p> <p>
Compl&eacute;tez dès à pr&eacute;sent votre partie repas afin que l'on puisse faire les r&eacute;servations n&eacute;cessaires !
Complétez dès à présent votre partie repas afin que l'on puisse faire les réservations nécessaires !
</p> </p>


<u>Vendredi soir :</u> <u>Vendredi soir :</u>
<p> <p>
Certains conf&eacute;renciers viennent de très loin et seront pr&eacute;sent d&eacute;s le vendredi.<br />
Nous vous proposons de nous retrouver à proximit&eacute;, à la CASA.<br />
Certains conférenciers viennent de très loin et seront présent dés le vendredi.<br />
Nous vous proposons de nous retrouver à proximité, à la CASA.<br />
<a href="http://groupelacasa.com/la-carte-et-les-menus-1-2-75"> La carte CASA </a> <a href="http://groupelacasa.com/la-carte-et-les-menus-1-2-75"> La carte CASA </a>
le vendredi soir autour d'un verre et d'un bon repas ! le vendredi soir autour d'un verre et d'un bon repas !
</p> </p>
<u>Samedi Midi :</u> <u>Samedi Midi :</u>
<p> <p>
&Agrave; la pause du midi, nous vous proposons un repas avec le food-truck 'les frères toqu&eacute;s' qui sera pr&eacute;sent sur le parking de PolyTech<br />
&Agrave; la pause du midi, nous vous proposons un repas avec le food-truck 'les frères toqués' qui sera présent sur le parking de PolyTech<br />
</p> </p>
<u>Samedi Soir :</u> <u>Samedi Soir :</u>
<p> <p>
Pour conclure la journ&eacute;e nous avons l'habitude de nous retrouver au repas de cloture.<br />
Pour conclure la journée nous avons l'habitude de nous retrouver au repas de cloture.<br />
Nous vous proposons de nous retrouver à Antibes au restaurant Les Tonnelles<br /> Nous vous proposons de nous retrouver à Antibes au restaurant Les Tonnelles<br />
<a href="https://fr-fr.facebook.com/lestonnellesantibes/?_fb_noscript=1"> Les Tonnelles </a> <a href="https://fr-fr.facebook.com/lestonnellesantibes/?_fb_noscript=1"> Les Tonnelles </a>
</p> </p>
@@ -100,7 +100,7 @@ elif Type=='M':
<thead> <thead>
<tr> <tr>
<th colspan="5"> <th colspan="5">
Les &eacute;changes ${CurTitle}
Les échanges ${CurTitle}
% if 0: % if 0:
<span style="float:right;"> <span style="float:right;">
<a data-original-title="Afficher les demandes" data-toggle="tooltip" id="${Type}_Demande"> <a data-original-title="Afficher les demandes" data-toggle="tooltip" id="${Type}_Demande">
@@ -124,7 +124,7 @@ elif Type=='M':
<tr> <tr>
<th style="width:1em;"></th> <th style="width:1em;"></th>
<th>D&eacute;tails</th>
<th>Détails</th>
<th style="width:1em;"></th> <th style="width:1em;"></th>
<tr> <tr>
</thead> </thead>
@@ -132,7 +132,7 @@ elif Type=='M':
% if len(Selection)==0: % if len(Selection)==0:
<tr> <tr>
<td colspan="5" style="text-align:center;"> <td colspan="5" style="text-align:center;">
<i>Il n'y a aucun &eacute;change ${CurTitle} propos&eacute; actuellement...</i>
<i>Il n'y a aucun échange ${CurTitle} proposé actuellement...</i>
</td> </td>
</tr> </tr>
% else: % else:
@@ -155,7 +155,7 @@ elif Type=='M':
<a href="/user/${item.provider.slug}"> ${item.provider.prenom} ${item.provider.nom} </a> offre <a href="/user/${item.provider.slug}"> ${item.provider.prenom} ${item.provider.nom} </a> offre
% endif % endif
% if item.exch_type=="C": % if item.exch_type=="C":
un co-voiturage le ${item.start_time.strftime('%a %d %b vers %Hh%M').decode('utf-8')}
un co-voiturage le ${item.start_time.strftime('%a %d %b vers %Hh%M')}
de <a href="javascript:DoGetLieu('/${CurrentYear}/modal/Place/${item.Itin.start.place_id}')">${item.Itin.start.display_name}</a> de <a href="javascript:DoGetLieu('/${CurrentYear}/modal/Place/${item.Itin.start.place_id}')">${item.Itin.start.display_name}</a>
à <a href="javascript:DoGetLieu('/${CurrentYear}/modal/Place/${item.Itin.arrival.place_id}')">${item.Itin.arrival.display_name}</a> à <a href="javascript:DoGetLieu('/${CurrentYear}/modal/Place/${item.Itin.arrival.place_id}')">${item.Itin.arrival.display_name}</a>
% elif item.exch_type=="M": % elif item.exch_type=="M":
@@ -165,8 +165,8 @@ elif Type=='M':
% if item.description: % if item.description:
${item.description[:30]} ${item.description[:30]}
% endif % endif
de ${item.start_time.strftime('%a %d %b %Hh%M').decode('utf-8')}
à ${item.end_time.strftime('%a %d %b %Hh%M').decode('utf-8')}
de ${item.start_time.strftime('%a %d %b %Hh%M')}
à ${item.end_time.strftime('%a %d %b %Hh%M')}
% else: % else:
% if item.Category: % if item.Category:
<i>${item.Category.exch_subtype}</i> <i>${item.Category.exch_subtype}</i>
@@ -174,7 +174,7 @@ elif Type=='M':
% if item.description: % if item.description:
${item.description[:30]} ${item.description[:30]}
% endif % endif
${item.start_time.strftime('%a %d %b').decode('utf-8')} soir
${item.start_time.strftime('%a %d %b')} soir
% endif % endif
</p> </p>
</td> </td>
@@ -284,7 +284,7 @@ ListWrap = ["Co-voiturage",u"Hébergement","Matos"]
</div> </div>
<div class="accordion-group"> <div class="accordion-group">
<div class="accordion-heading"> <div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#AccordionCounter" href="#collapseAll">Les compteurs de l´&eacute;v&eacute;nement</a>
<a class="accordion-toggle" data-toggle="collapse" data-parent="#AccordionCounter" href="#collapseAll">Les compteurs de l´év&eacute;nement</a>
</div> </div>
<div id="collapseAll" class="accordion-body collapse"> <div id="collapseAll" class="accordion-body collapse">
<div class="accordion-inner"> <div class="accordion-inner">


+ 4
- 4
jm2l/templates/Logistique/Tables.mako View File

@@ -97,17 +97,17 @@ elif Type=='M':
</td> </td>
<td> <td>
%if Type=='C': %if Type=='C':
${item.start_time.strftime('%A %d %b %Y').decode('utf-8')} vers ${item.start_time.strftime('%Hh%M')}
${item.start_time.strftime('%A %d %b %Y')} vers ${item.start_time.strftime('%Hh%M')}
de <a href="javascript:DoGetLieu('/${CurrentYear}/modal/Place/${item.Itin.start.place_id}')">${item.Itin.start.display_name}</a> de <a href="javascript:DoGetLieu('/${CurrentYear}/modal/Place/${item.Itin.start.place_id}')">${item.Itin.start.display_name}</a>
à <a href="javascript:DoGetLieu('/${CurrentYear}/modal/Place/${item.Itin.arrival.place_id}')">${item.Itin.arrival.display_name}</a> à <a href="javascript:DoGetLieu('/${CurrentYear}/modal/Place/${item.Itin.arrival.place_id}')">${item.Itin.arrival.display_name}</a>
%elif Type=='H': %elif Type=='H':
% if item.Category: % if item.Category:
<i>${item.Category.exch_subtype}</i>, <i>${item.Category.exch_subtype}</i>,
% endif % endif
La nuit du ${item.start_time.strftime('%A %d %b %Y').decode('utf-8')}<br>
La nuit du ${item.start_time.strftime('%A %d %b %Y')}<br>
%elif Type=='M': %elif Type=='M':
de ${item.start_time.strftime('%A %d %b %Y').decode('utf-8')} vers ${item.start_time.strftime('%Hh%M')}
à ${item.end_time.strftime('%A %d %b %Y').decode('utf-8')} vers ${item.end_time.strftime('%Hh%M')}<br>
de ${item.start_time.strftime('%A %d %b %Y')} vers ${item.start_time.strftime('%Hh%M')}
à ${item.end_time.strftime('%A %d %b %Y')} vers ${item.end_time.strftime('%Hh%M')}<br>
${item.Category.exch_subtype} ${item.Category.exch_subtype}
%endif %endif
%if item.description: %if item.description:


+ 1
- 1
jm2l/templates/NewIndex.mako View File

@@ -1,6 +1,6 @@
<%inherit file="jm2l:templates/layout.mako"/> <%inherit file="jm2l:templates/layout.mako"/>
<%def name="jsAddOn()"> <%def name="jsAddOn()">
<script src="/vendor/timeline/js/timeline-src.js"></script>
<script src="/vendor/timeline/js/timeline-min.js"></script>
<script> <script>
var timeline = new VMM.Timeline("timeline", '95%', '600px'); var timeline = new VMM.Timeline("timeline", '95%', '600px');
var c = {language:{ lang:"fr",api:{wikipedia:"fr"},date:{month:["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"],month_abbr:["janv.","févr.","mars","avril","mai","juin","juil.","août","sept.","oct.","nov.","dec."],day:["Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"],day_abbr:["Dim.","Lu.","Ma.","Me.","Jeu.","Vend.","Sam."]},dateformats:{year:"yyyy",month_short:"mmm",month:"mmmm yyyy",full_short:"d mmm",full:"d mmmm yyyy",time_short:"HH:MM:SS",time_no_seconds_short:"HH:MM",time_no_seconds_small_date:"HH:MM'<br/><small>'d mmmm yyyy'</small>'",full_long:"dddd',' d mmm yyyy 'à' HH:MM",full_long_small_date:"HH:MM'<br/><small>'dddd',' d mmm yyyy'</small>'"},messages:{loading_timeline:"Chargement de la frise en cours... ",return_to_title:"Retour à la page d'accueil",expand_timeline:"Elargir la frise",contract_timeline:"Réduire la frise",wikipedia:"Extrait de Wikipedia, l'encyclopédie libre",loading_content:"Chargement",loading:"Chargement",swipe_nav:"Swipe to Navigate"}}}; var c = {language:{ lang:"fr",api:{wikipedia:"fr"},date:{month:["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"],month_abbr:["janv.","févr.","mars","avril","mai","juin","juil.","août","sept.","oct.","nov.","dec."],day:["Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"],day_abbr:["Dim.","Lu.","Ma.","Me.","Jeu.","Vend.","Sam."]},dateformats:{year:"yyyy",month_short:"mmm",month:"mmmm yyyy",full_short:"d mmm",full:"d mmmm yyyy",time_short:"HH:MM:SS",time_no_seconds_short:"HH:MM",time_no_seconds_small_date:"HH:MM'<br/><small>'d mmmm yyyy'</small>'",full_long:"dddd',' d mmm yyyy 'à' HH:MM",full_long_small_date:"HH:MM'<br/><small>'dddd',' d mmm yyyy'</small>'"},messages:{loading_timeline:"Chargement de la frise en cours... ",return_to_title:"Retour à la page d'accueil",expand_timeline:"Elargir la frise",contract_timeline:"Réduire la frise",wikipedia:"Extrait de Wikipedia, l'encyclopédie libre",loading_content:"Chargement",loading:"Chargement",swipe_nav:"Swipe to Navigate"}}};


+ 4
- 4
jm2l/templates/Profil/Profil.mako View File

@@ -23,12 +23,12 @@
<% <%
DicFormA = { DicFormA = {
'nom': {'PlaceHolder':u"Mon Nom", 'ContainerClass':"span6", 'next':False}, 'nom': {'PlaceHolder':u"Mon Nom", 'ContainerClass':"span6", 'next':False},
'prenom': {'PlaceHolder':u"Mon Pr&eacute;nom", 'ContainerClass':"span6", 'next':True},
'prenom': {'PlaceHolder':u"Mon Prénom", 'ContainerClass':"span6", 'next':True},
'pseudo': {'PlaceHolder':u"Mon Pseudo", 'ContainerClass':"span6", 'next':False}, 'pseudo': {'PlaceHolder':u"Mon Pseudo", 'ContainerClass':"span6", 'next':False},
'mail': {'PlaceHolder':u"mon.mail@fqdn.tld", 'ContainerClass':"span6", 'next':True}, 'mail': {'PlaceHolder':u"mon.mail@fqdn.tld", 'ContainerClass':"span6", 'next':True},
'phone': {'PlaceHolder':u"0612345678", 'ContainerClass':"span6", 'next':False}, 'phone': {'PlaceHolder':u"0612345678", 'ContainerClass':"span6", 'next':False},
'website': {'PlaceHolder':u"http://ma-page-web.moi",'ContainerClass':"span6", 'next':True}, 'website': {'PlaceHolder':u"http://ma-page-web.moi",'ContainerClass':"span6", 'next':True},
'gpg_key': {'PlaceHolder':u"Ma cl&eacute; gpg", 'ContainerClass':"span6", 'next':False},
'gpg_key': {'PlaceHolder':u"Ma clé gpg", 'ContainerClass':"span6", 'next':False},
'soc_link':{'PlaceHolder':u"#jm2l sur irc.freenode.org",'ContainerClass':"span6", 'next':True}, 'soc_link':{'PlaceHolder':u"#jm2l sur irc.freenode.org",'ContainerClass':"span6", 'next':True},
'bio': {'Ignore':True}, 'bio': {'Ignore':True},
'tiersship': {'Ignore':True}, 'tiersship': {'Ignore':True},
@@ -52,12 +52,12 @@ DicFormB = {


DicForm2 = { DicForm2 = {
'nom': {'PlaceHolder':u"Mon Nom", "FieldStyle":"width:16em;", 'ContainerStyle':"float:left;"}, 'nom': {'PlaceHolder':u"Mon Nom", "FieldStyle":"width:16em;", 'ContainerStyle':"float:left;"},
'prenom': {'PlaceHolder':u"Mon Pr&eacute;nom", "FieldStyle":"width:16em;"},
'prenom': {'PlaceHolder':u"Mon Prénom", "FieldStyle":"width:16em;"},
'pseudo': {'PlaceHolder':u"Mon Pseudo", "FieldStyle":"width:16em;", 'ContainerStyle':"float:left;"}, 'pseudo': {'PlaceHolder':u"Mon Pseudo", "FieldStyle":"width:16em;", 'ContainerStyle':"float:left;"},
'mail': {'PlaceHolder':u"mon.mail@fqdn.tld", "FieldStyle":"width:16em;"}, 'mail': {'PlaceHolder':u"mon.mail@fqdn.tld", "FieldStyle":"width:16em;"},
'phone': {'PlaceHolder':u"0612345678", "FieldStyle":"width:16em;", 'ContainerStyle':"float:left;"}, 'phone': {'PlaceHolder':u"0612345678", "FieldStyle":"width:16em;", 'ContainerStyle':"float:left;"},
'website': {'PlaceHolder':u"http://ma-page-web.moi","FieldStyle":"width:16em;"}, 'website': {'PlaceHolder':u"http://ma-page-web.moi","FieldStyle":"width:16em;"},
'gpg_key': {'PlaceHolder':u"Ma cl&eacute; gpg", "FieldStyle":"width:90%;"},
'gpg_key': {'PlaceHolder':u"Ma clé gpg", "FieldStyle":"width:90%;"},
'soc_link':{'PlaceHolder':u"#jm2l sur irc.freenode.org","FieldStyle":"width:90%;"}, 'soc_link':{'PlaceHolder':u"#jm2l sur irc.freenode.org","FieldStyle":"width:90%;"},
'bio': {'PlaceHolder':u"Ma Bilibiographie", "FieldStyle":"width:95%;min-height:150px;", "fieldset":True, "ckeditor":1 }, 'bio': {'PlaceHolder':u"Ma Bilibiographie", "FieldStyle":"width:95%;min-height:150px;", "fieldset":True, "ckeditor":1 },
'tiersship': {'Ignore':True} 'tiersship': {'Ignore':True}


+ 13
- 13
jm2l/templates/Profil/Sejour.mako View File

@@ -14,14 +14,14 @@ fieldset:disabled {
% else: % else:
<legend class="lowshadow"> <legend class="lowshadow">
<img style="max-height:50px;" src="/img/warn.png" alt="Attention !"> <img style="max-height:50px;" src="/img/warn.png" alt="Attention !">
Vous n'avez pas confirm&eacute; votre venue aux JM2L ${CurrentYear}
Vous n'avez pas confirmé votre venue aux JM2L ${CurrentYear}
</legend> </legend>
<h4 class="lowshadow">Compl&eacute;tez et validez vite ce formulaire !</h4>
<h4 class="lowshadow">Complétez et validez vite ce formulaire !</h4>
% endif % endif


<form id="ProfilForm" action="/MonSejour" method="POST"> <form id="ProfilForm" action="/MonSejour" method="POST">
<fieldset class="ComeToJM2L"> <fieldset class="ComeToJM2L">
<legend>Arriv&eacute;e</legend>
<legend>Arrivée</legend>
<div class="form-inline"> <div class="form-inline">
J'arrive J'arrive
<select style="width:12em;" id="Arrival:Place" name="Arrival:Place" title="Lieu"> <select style="width:12em;" id="Arrival:Place" name="Arrival:Place" title="Lieu">
@@ -63,16 +63,16 @@ fieldset:disabled {
<ul style="list-style-type: none;"> <ul style="list-style-type: none;">
<li><label class="checkbox"> <li><label class="checkbox">
<input id="PMR" ${mytrip.IsCheck("Arrival:PMR")|n} name="Arrival:PMR" title="Assistance Personne à mobilit&eacute; r&eacute;duite (PMR)" type="checkbox">
d'assistance : Personne à mobilit&eacute; r&eacute;duite (PMR)</input></label>
<input id="PMR" ${mytrip.IsCheck("Arrival:PMR")|n} name="Arrival:PMR" title="Assistance Personne à mobilité réduite (PMR)" type="checkbox">
d'assistance : Personne à mobilité réduite (PMR)</input></label>
</li> </li>
<li><label class="checkbox"> <li><label class="checkbox">
<input id="Cov" ${mytrip.IsCheck("Arrival:Cov")|n} name="Arrival:Cov" title="Covoiturage" type="checkbox"> <input id="Cov" ${mytrip.IsCheck("Arrival:Cov")|n} name="Arrival:Cov" title="Covoiturage" type="checkbox">
d'un covoiturage, d'un h&eacute;bergement...<br>(j'ai rempli/je vais remplir la section Logistique).</input></label>
d'un covoiturage, d'un hébergement...<br>(j'ai rempli/je vais remplir la section Logistique).</input></label>
</li> </li>
<li><label class="checkbox"> <li><label class="checkbox">
<input id="Bras" ${mytrip.IsCheck("Arrival:Bras")|n} name="Arrival:Bras" title="Bras" type="checkbox"> <input id="Bras" ${mytrip.IsCheck("Arrival:Bras")|n} name="Arrival:Bras" title="Bras" type="checkbox">
de bras, car je rapporte plein de mat&eacute;riel. <br>(Je transporte ma maison, mon garage ...)</input></label>
de bras, car je rapporte plein de matériel. <br>(Je transporte ma maison, mon garage ...)</input></label>
</li> </li>
<li> <li>
<div class="form-inline"> <div class="form-inline">
@@ -81,7 +81,7 @@ fieldset:disabled {
Autres Autres
</input></label> </input></label>
<input type="text" style="width:20em;" name="Arrival:Comment" <input type="text" style="width:20em;" name="Arrival:Comment"
placeholder="Pr&eacute;cisions à propos de mon arriv&eacute;e…" />
placeholder="Précisions à propos de mon arrivée…" />
</div> </div>
</li> </li>
</ul> </ul>
@@ -90,7 +90,7 @@ fieldset:disabled {
</fieldset> </fieldset>
<fieldset class="ComeToJM2L"> <fieldset class="ComeToJM2L">
<legend>D&eacute;part</legend>
<legend>Départ</legend>
<div class="form-inline"> <div class="form-inline">
Je repars Je repars
<select style="width:12em;" id="Departure:Place" class="formforform-field" name="Departure:Place" title="Alors, j'arrive"> <select style="width:12em;" id="Departure:Place" class="formforform-field" name="Departure:Place" title="Alors, j'arrive">
@@ -130,8 +130,8 @@ fieldset:disabled {
Je vais avoir besoin: &nbsp;&nbsp;<small style="color: #aaa;">(Cochez les cases correspondantes)</small> Je vais avoir besoin: &nbsp;&nbsp;<small style="color: #aaa;">(Cochez les cases correspondantes)</small>
<ul style="list-style-type: none;"> <ul style="list-style-type: none;">
<li><label class="checkbox"> <li><label class="checkbox">
<input id="PMR" ${mytrip.IsCheck("Departure:PMR")|n} name="Departure:PMR" title="d'Assistance : Personne à mobilit&eacute; r&eacute;duite (PMR)" type="checkbox">
d'assistance : Personne à mobilit&eacute; r&eacute;duite (PMR)</input>
<input id="PMR" ${mytrip.IsCheck("Departure:PMR")|n} name="Departure:PMR" title="d'Assistance : Personne à mobilité réduite (PMR)" type="checkbox">
d'assistance : Personne à mobilité réduite (PMR)</input>
</label> </label>
</li> </li>
<li><label class="checkbox"> <li><label class="checkbox">
@@ -141,7 +141,7 @@ fieldset:disabled {
</li> </li>
<li><label class="checkbox"> <li><label class="checkbox">
<input id="Bras" ${mytrip.IsCheck("Departure:Bras")|n} name="Departure:Bras" title="de bras" type="checkbox"> <input id="Bras" ${mytrip.IsCheck("Departure:Bras")|n} name="Departure:Bras" title="de bras" type="checkbox">
de bras, car j'ai en stock plein de mat&eacute;riel (Ma maison).</input>
de bras, car j'ai en stock plein de matériel (Ma maison).</input>
</label> </label>
</li> </li>
<li> <li>
@@ -151,7 +151,7 @@ fieldset:disabled {
Autres Autres
</input></label> </input></label>
<input type="text" style="width:20em;" name="Departure:Comment" <input type="text" style="width:20em;" name="Departure:Comment"
placeholder="Pr&eacute;cisions à propos de mon d&eacute;part…" />
placeholder="Précisions à propos de mon départ…" />
</div> </div>
</li> </li>
</ul> </ul>


+ 2
- 2
jm2l/templates/Public/Programme.mako View File

@@ -111,7 +111,7 @@ if Counter==0:
vid = event.video.first() vid = event.video.first()
pres = event.presentation.first() pres = event.presentation.first()
%> %>
${event.start_time.strftime("%a %d %b").decode('utf-8')}<br>
${event.start_time.strftime("%a %d %b")}<br>
${event.start_time.strftime("%H:%M")} - ${event.end_time.strftime("%H:%M")} ${event.start_time.strftime("%H:%M")} - ${event.end_time.strftime("%H:%M")}
</td> </td>
<td style="position: relative;"> <td style="position: relative;">
@@ -132,7 +132,7 @@ if Counter==0:
</span> </span>
<br/> <br/>
avec avec
% for num, inter in enumerate(event.intervenants.all()):
% for num, inter in enumerate(event.intervenants):
%if num>0: %if num>0:
, ,
%endif %endif


+ 2
- 2
jm2l/templates/Salles/list_phy.mako View File

@@ -24,7 +24,7 @@ from slugify import slugify
% if len(DicSallePhy)==0: % if len(DicSallePhy)==0:
<tr> <tr>
<td style="text-align:center;"> <td style="text-align:center;">
<i>Il n'y a pas de salle d&eacute;finie pour le moment.</i>
<i>Il n'y a pas de salle définie pour le moment.</i>
</td> </td>
</tr> </tr>
% endif % endif
@@ -43,7 +43,7 @@ from slugify import slugify
% if SallePhy.uid: % if SallePhy.uid:
[ ${SallePhy.nb_places} places ] [ ${SallePhy.nb_places} places ]
% else: % else:
[ <a href="/PhySalles">Cr&eacute;er</a> ]
[ <a href="/PhySalles">Créer</a> ]
% endif % endif
</div> </div>




+ 2
- 2
jm2l/templates/Salles/salle.mako View File

@@ -29,9 +29,9 @@
%endif %endif
<% <%
DicForm = { DicForm = {
'year_uid': {'PlaceHolder':u"Ann&eacute;e", "FieldStyle":"width:7em;", "ContainerStyle":"float:left;" },
'year_uid': {'PlaceHolder':u"Année", "FieldStyle":"width:7em;", "ContainerStyle":"float:left;" },
'phy_salle_id': {'PlaceHolder':u"Salle Physique", "FieldStyle":"width:20em;", "ContainerStyle":"float:left;" }, 'phy_salle_id': {'PlaceHolder':u"Salle Physique", "FieldStyle":"width:20em;", "ContainerStyle":"float:left;" },
'place_type': {'PlaceHolder':u"Type d'&eacute;vènement","FieldStyle":"width:15em;" },
'place_type': {'PlaceHolder':u"Type d'évènement","FieldStyle":"width:15em;" },
'name': {'PlaceHolder':u"Nom de la salle", "FieldStyle":"width:90%;" }, 'name': {'PlaceHolder':u"Nom de la salle", "FieldStyle":"width:90%;" },
'description': {'PlaceHolder':u"Description", "ContainerStyle":"width:95%;min-height:150px;padding-top: 12px;", "ckeditor":"1" }, 'description': {'PlaceHolder':u"Description", "ContainerStyle":"width:95%;min-height:150px;padding-top: 12px;", "ckeditor":"1" },
} }


+ 1
- 1
jm2l/templates/Staff/compta.mako View File

@@ -46,7 +46,7 @@
</td> </td>
</tr> </tr>
% endif % endif
% for item, one_dic in found.iteritems():
% for item, one_dic in found.items():
<tr> <tr>
<td> <td>
<a href="/user/${item}"> <a href="/user/${item}">


+ 1
- 1
jm2l/templates/Staff/list.mako View File

@@ -63,7 +63,7 @@ from slugify import slugify
</a> </a>
<span style="float:right;"> <span style="float:right;">
- <a href="/user/${task.assignee.slug}">${task.assignee.pseudo or ' '.join([task.assignee.prenom, task.assignee.nom]) }</a> - <a href="/user/${task.assignee.slug}">${task.assignee.pseudo or ' '.join([task.assignee.prenom, task.assignee.nom]) }</a>
- ${task.due_date.strftime("%d %b").decode("utf-8")}
- ${task.due_date.strftime("%d %b")}
</span> </span>
% endif % endif
</td> </td>


+ 5
- 5
jm2l/templates/edit_event.mako View File

@@ -30,7 +30,7 @@
%endif %endif
% if 'uid' in form._fields: % if 'uid' in form._fields:
<div class="borderboxtime"> <div class="borderboxtime">
${event.start_time.strftime('%d %b %Y').decode('utf-8')} -
${event.start_time.strftime('%d %b %Y')} -
${event.start_time.strftime('%H:%M')} à ${event.end_time.strftime('%H:%M')} ${event.start_time.strftime('%H:%M')} à ${event.end_time.strftime('%H:%M')}
%if event.Salle: %if event.Salle:
- <strong>Salle</strong>: ${event.Salle.name} - <strong>Salle</strong>: ${event.Salle.name}
@@ -43,7 +43,7 @@
<div class="borderbox"> <div class="borderbox">
Intervenants programmés: Intervenants programmés:
<ul> <ul>
% if event.intervenants.count()==0:
% if len(event.intervenants)==0:
<i><b>Aucun</b></i> <i><b>Aucun</b></i>
% else: % else:
% for num, iterv in enumerate(event.intervenants): % for num, iterv in enumerate(event.intervenants):
@@ -160,7 +160,7 @@ DicForm = {
<td> <td>
<u>Les Intervenants:</u> <u>Les Intervenants:</u>
<ul> <ul>
% if event.intervenants.count()==0:
% if len(event.intervenants)==0:
<i><b>Aucun</b></i> <i><b>Aucun</b></i>
% else: % else:
% for num, iterv in enumerate(event.intervenants): % for num, iterv in enumerate(event.intervenants):
@@ -184,10 +184,10 @@ DicForm = {


</fieldset> </fieldset>
<div class="clearfix">&nbsp;</div> <div class="clearfix">&nbsp;</div>
<p style="float:right;">Créé le ${event.created.strftime('%d %b %Y').decode('utf-8')}</p>
<p style="float:right;">Créé le ${event.created.strftime('%d %b %Y')}</p>
%else: %else:
<p style="float:right;">Créé le <p style="float:right;">Créé le
${datetime.now().strftime('%d %b %Y').decode('utf-8')}
${datetime.now().strftime('%d %b %Y')}
</p> </p>
% endif % endif
<br/> <br/>


+ 17
- 17
jm2l/templates/helpers.mako View File

@@ -7,7 +7,7 @@ TabJs = {'select':[], 'desc':[]}
%> %>
<div class="row-fluid"> <div class="row-fluid">
% for FieldName, Field in form._fields.items(): % for FieldName, Field in form._fields.items():
% if DicFormat.has_key(Field.name) and DicFormat[Field.name].get("Ignore"):
% if Field.name in DicFormat and DicFormat[Field.name].get("Ignore"):
<% continue %> <% continue %>
% endif % endif
% if Field.type in ['HiddenField', 'CSRFTokenField']: % if Field.type in ['HiddenField', 'CSRFTokenField']:
@@ -27,7 +27,7 @@ TabJs = {'select':[], 'desc':[]}
</a> </a>
% endif % endif
</label> </label>
% if DicFormat.has_key(Field.name):
% if Field.name in DicFormat:
<% <%
PlaceHolder = DicFormat[Field.name].get("PlaceHolder") PlaceHolder = DicFormat[Field.name].get("PlaceHolder")
Class = [False,"ckeditor"][ "ckeditor" in DicFormat[Field.name] ] Class = [False,"ckeditor"][ "ckeditor" in DicFormat[Field.name] ]
@@ -49,7 +49,7 @@ TabJs = {'select':[], 'desc':[]}
% endfor % endfor
</div> </div>


% if DicFormat.has_key(Field.name) and DicFormat[Field.name].get("next")==True:
% if Field.name in DicFormat and DicFormat[Field.name].get("next")==True:
</div> </div>
<div class="row-fluid"> <div class="row-fluid">
% endif % endif
@@ -72,7 +72,7 @@ TabJs = {'select':[], 'desc':[]}
TabJs = {'select':[], 'desc':[]} TabJs = {'select':[], 'desc':[]}
%> %>
% for FieldName, Field in form._fields.items(): % for FieldName, Field in form._fields.items():
% if DicFormat.has_key(Field.name) and DicFormat[Field.name].get("Ignore"):
% if Field.name in DicFormat and DicFormat[Field.name].get("Ignore"):
<% continue %> <% continue %>
% endif % endif
% if Field.type in ['HiddenField', 'CSRFTokenField']: % if Field.type in ['HiddenField', 'CSRFTokenField']:
@@ -81,11 +81,11 @@ TabJs = {'select':[], 'desc':[]}
% elif Field.type=="SelectField": % elif Field.type=="SelectField":
<% TabJs['select'].append(Field.label.field_id) %> <% TabJs['select'].append(Field.label.field_id) %>
% endif % endif
% if DicFormat.has_key(Field.name) and DicFormat[Field.name].get("fieldset"):
% if Field.name in DicFormat and DicFormat[Field.name].get("fieldset"):
<fieldset> <fieldset>
<legend>${Field.label.text}</legend> <legend>${Field.label.text}</legend>
% else: % else:
% if DicFormat.has_key(Field.name) and DicFormat[Field.name].get("ContainerStyle"):
% if Field.name in DicFormat and DicFormat[Field.name].get("ContainerStyle"):
<div style="padding-right:5px;${DicFormat[Field.name].get("ContainerStyle")}"> <div style="padding-right:5px;${DicFormat[Field.name].get("ContainerStyle")}">
% else: % else:
<div style="padding-right:5px;"> <div style="padding-right:5px;">
@@ -101,11 +101,11 @@ TabJs = {'select':[], 'desc':[]}
% endif % endif
</label> </label>
% endif % endif
% if DicFormat.has_key(Field.name):
% if Field.name in DicFormat:
<% <%
PlaceHolder = DicFormat[Field.name].get("PlaceHolder") PlaceHolder = DicFormat[Field.name].get("PlaceHolder")
FieldStyle = DicFormat[Field.name].get("FieldStyle") FieldStyle = DicFormat[Field.name].get("FieldStyle")
Class = [False,"ckeditor"][ "ckeditor" in DicFormat[Field.name] ]
Class = [False, "ckeditor"][ "ckeditor" in DicFormat[Field.name] ]
%> %>
% if Field.type == "date": % if Field.type == "date":
${Field(placeholder=PlaceHolder or False, style=FieldStyle, class_="datepicker" )} ${Field(placeholder=PlaceHolder or False, style=FieldStyle, class_="datepicker" )}
@@ -122,7 +122,7 @@ TabJs = {'select':[], 'desc':[]}
${ error } ${ error }
</div> </div>
% endfor % endfor
% if DicFormat.has_key(Field.name) and DicFormat[Field.name].get("fieldset"):
% if Field.name in DicFormat and DicFormat[Field.name].get("fieldset"):
</fieldset> </fieldset>
% else: % else:
</div> </div>
@@ -142,7 +142,7 @@ TabJs = {'select':[], 'desc':[]}
<%def name="sejour_wrapper(Places)"> <%def name="sejour_wrapper(Places)">


<div class="form-inline"> <div class="form-inline">
D&eacute;part :
Départ :
<select style="width:12em;" id="Arrival:Place" name="Arrival:Place" title="Lieu"> <select style="width:12em;" id="Arrival:Place" name="Arrival:Place" title="Lieu">
% for place in Places: % for place in Places:
<option value="${place.place_id}">${place.display_name}</option> <option value="${place.place_id}">${place.display_name}</option>
@@ -151,7 +151,7 @@ TabJs = {'select':[], 'desc':[]}
</div> </div>
<br /> <br />
<div class="form-inline"> <div class="form-inline">
Arriv&eacute;e :
Arrivée :
<select style="width:12em;" id="Arrival:Place" name="Arrival:Place" title="Lieu"> <select style="width:12em;" id="Arrival:Place" name="Arrival:Place" title="Lieu">
% for place in Places: % for place in Places:
<option value="${place.place_id}">${place.display_name}</option> <option value="${place.place_id}">${place.display_name}</option>
@@ -184,7 +184,7 @@ TabJs = {'select':[], 'desc':[]}
${itin_form.arrival_place(style='width:17em;')} ${itin_form.arrival_place(style='width:17em;')}
</div> </div>
<div style="padding:5px;"> <div style="padding:5px;">
<small style="color:#999">Si je n´ai pas trouv&eacute; le lieu dont j´ai besoin dans ces listes...</small>
<small style="color:#999">Si je n´ai pas trouvé le lieu dont j´ai besoin dans ces listes...</small>
<br /> <br />
<small style="color:#999">Je peux </small> <small style="color:#999">Je peux </small>
<a class="btn btn-mini btn-info" role="button" href="javascript:DoGetLieu('/${CurrentYear}/modal/Place/0');"> <a class="btn btn-mini btn-info" role="button" href="javascript:DoGetLieu('/${CurrentYear}/modal/Place/0');">
@@ -350,9 +350,9 @@ TabJs = {'select':[], 'desc':[]}
<tr> <tr>
<td style="text-align:center;" colspan="2"> <td style="text-align:center;" colspan="2">
% if NotFoundTitle: % if NotFoundTitle:
<i>${NotFoundTitle}</i>
<i>${NotFoundTitle | h}</i>
% else: % else:
<i>D&eacute;sol&eacute;, Il n'y a rien dans l'historique.</i>
<i>Désolé;, Il n'y a rien dans l'historique.</i>
% endif % endif
</td> </td>
</tr> </tr>
@@ -366,7 +366,7 @@ TabJs = {'select':[], 'desc':[]}
vid = event.video.first() vid = event.video.first()
pres = event.presentation.first() pres = event.presentation.first()
%> %>
${event.start_time.strftime('%d %b %Y').decode('utf-8')}
${event.start_time.strftime('%d %b %Y')}
${start.hour}:${"%.2d" % start.minute}-${end.hour}:${"%.2d" % end.minute} ${start.hour}:${"%.2d" % start.minute}-${end.hour}:${"%.2d" % end.minute}
</td> </td>
<td style="position: relative;">${event.event_type}: <td style="position: relative;">${event.event_type}:
@@ -391,9 +391,9 @@ TabJs = {'select':[], 'desc':[]}
</div> </div>
% endif % endif
<br/> <br/>
% if event.intervenants.count()>1:
% if len(event.intervenants)>1:
avec avec
% for num, inter in enumerate(event.intervenants.all()):
% for num, inter in enumerate(event.intervenants):
<% <%
if inter==uprofil: if inter==uprofil:
continue continue


+ 7
- 7
jm2l/templates/jm2l.mako View File

@@ -61,7 +61,7 @@
<div class="tabbable" id="main_tab"> <div class="tabbable" id="main_tab">
<ul class="nav nav-tabs nav-pills" style="margin-bottom: 5px;"> <ul class="nav nav-tabs nav-pills" style="margin-bottom: 5px;">
<li class="active"><a href="#Profil" id="Map_Profil" data-toggle="tab">Mon Profil</a></li> <li class="active"><a href="#Profil" id="Map_Profil" data-toggle="tab">Mon Profil</a></li>
<li><a href="#Sejour" id="Map_Sejour" data-toggle="tab">Mon S&eacute;jour</a></li>
<li><a href="#Sejour" id="Map_Sejour" data-toggle="tab">Mon Séjour</a></li>
<li><a href="#Logistique" id="Map_Logistique" data-toggle="tab">Logistique</a></li> <li><a href="#Logistique" id="Map_Logistique" data-toggle="tab">Logistique</a></li>
<li><a href="#Interventions" id="Map_Interventions" data-toggle="tab">Mes Interventions</a></li> <li><a href="#Interventions" id="Map_Interventions" data-toggle="tab">Mes Interventions</a></li>
<li><a href="#Frais" id="Map_Frais" data-toggle="tab">Mes Frais</a></li> <li><a href="#Frais" id="Map_Frais" data-toggle="tab">Mes Frais</a></li>
@@ -79,8 +79,8 @@
<div class="tabbable tabs-left" id="Interventions_tab"> <div class="tabbable tabs-left" id="Interventions_tab">
<ul class="nav nav-tabs navbar" style="margin-bottom:0;"> <ul class="nav nav-tabs navbar" style="margin-bottom:0;">
<li class="active"> <a href="#ResumePart" data-toggle="tab">Resum&eacute;</a> </li>
<li> <a href="#Conference" data-toggle="tab">Conf&eacute;rence</a> </li>
<li class="active"> <a href="#ResumePart" data-toggle="tab">Resumé</a> </li>
<li> <a href="#Conference" data-toggle="tab">Conférence</a> </li>
<li> <a href="#Stand" data-toggle="tab">Stand</a> </li> <li> <a href="#Stand" data-toggle="tab">Stand</a> </li>
<li> <a href="#Atelier" data-toggle="tab">Atelier</a> </li> <li> <a href="#Atelier" data-toggle="tab">Atelier</a> </li>
<li> <a href="#TableRonde" data-toggle="tab">Table Ronde</a> </li> <li> <a href="#TableRonde" data-toggle="tab">Table Ronde</a> </li>
@@ -118,12 +118,12 @@
<div class="tab-pane fade" id="Frais"> <div class="tab-pane fade" id="Frais">
<fieldset> <fieldset>
<legend class="lowshadow">Une participation à mes frais ?</legend> <legend class="lowshadow">Une participation à mes frais ?</legend>
L'&eacute;quipe des JM2L participe aux <u>frais de transport</u> des intervenants !<br /><br />
L'équipe des JM2L participe aux <u>frais de transport</u> des intervenants !<br /><br />
Et bien oui, mais cette participation ne sera effective que si vous remplissez <u>toutes les conditions</u> suivantes: Et bien oui, mais cette participation ne sera effective que si vous remplissez <u>toutes les conditions</u> suivantes:
<ul style="list-style:circle;"> <ul style="list-style:circle;">
<li>Vous animez <strong>un atelier, une conf&eacute;rence ou une table ronde</strong> aux JM2L ${CurrentYear}.</li>
<li>Votre fiche est renseign&eacute;e avec <strong>votre RIB</strong>.</li>
<li>Votre fiche est renseign&eacute;e avec <strong>les preuves</strong> de vos achats.</li>
<li>Vous animez <strong>un atelier, une conférence ou une table ronde</strong> aux JM2L ${CurrentYear}.</li>
<li>Votre fiche est renseignée avec <strong>votre RIB</strong>.</li>
<li>Votre fiche est renseignée avec <strong>les preuves</strong> de vos achats.</li>
<li>Vous <strong>présentez l'original de vos tickets</strong> à l'accueil pendant l'évènement.</li> <li>Vous <strong>présentez l'original de vos tickets</strong> à l'accueil pendant l'évènement.</li>
<li>Tous vos documents sont conformes.</li> <li>Tous vos documents sont conformes.</li>
</ul> </ul>


+ 17
- 33
jm2l/templates/layout.mako View File

@@ -3,7 +3,7 @@
<%namespace name="helpers" file="jm2l:templates/helpers.mako"/> <%namespace name="helpers" file="jm2l:templates/helpers.mako"/>
<% <%
context._kwargs['postpone_js']=[] context._kwargs['postpone_js']=[]
DisplayYear = request.session.get('year', 2018)
DisplayYear = request.session.get('year', 2020)
%> %>
<head> <head>
<title>JM2L ${DisplayYear}</title> <title>JM2L ${DisplayYear}</title>
@@ -68,12 +68,12 @@ ${helpers.uploader_js()}
% if request.user and request.user.vote_logo not in [1,2,3]: % if request.user and request.user.vote_logo not in [1,2,3]:
<div class="item active"> <div class="item active">
<div class="align-center"> <div class="align-center">
<H1>JM2L 2017</H1>
<h3>Choisissez ici votre logo pr&eacute;f&eacute;r&eacute; !</h3>
<H1>JM2L 2020</H1>
<h3>Choisissez ici votre logo préféré !</h3>
<p>Utilisez les flèches pour choisir et voter !<br> <p>Utilisez les flèches pour choisir et voter !<br>
Vous pouvez changer à tout moment, mais vous n'aurez droit qu'a un seul choix, le vôtre ;)</p> Vous pouvez changer à tout moment, mais vous n'aurez droit qu'a un seul choix, le vôtre ;)</p>
<p>Vous souhaitez proposer le vôtre ? <br> <p>Vous souhaitez proposer le vôtre ? <br>
N'h&eacute;sitez pas à envoyer vos propositions par mail à l'&eacute;quipe !</p>
N'hésitez pas à envoyer vos propositions par mail à l'équipe !</p>
</div> </div>
</div> </div>
% endif % endif
@@ -105,10 +105,10 @@ ${helpers.uploader_js()}
<a class="btn dropdown-toggle" data-toggle="dropdown" href="#"> <a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
Édition&nbsp;<span class="caret"></span></a> Édition&nbsp;<span class="caret"></span></a>
<ul class="dropdown-menu pull-right" style="min-width:0"> <ul class="dropdown-menu pull-right" style="min-width:0">
% for tmpyear in range(2018, 2005, -1):
% for tmpyear in range(2020, 2005, -1):
% if tmpyear==DisplayYear: % if tmpyear==DisplayYear:
<li><a style="font-weight: bold;" href="/year/${tmpyear}">${tmpyear}</a></li> <li><a style="font-weight: bold;" href="/year/${tmpyear}">${tmpyear}</a></li>
% elif tmpyear!=2014 and tmpyear!=2016:
% elif tmpyear not in [2014, 2016, 2018, 2019]:
<li><a href="/year/${tmpyear}">${tmpyear}</a></li> <li><a href="/year/${tmpyear}">${tmpyear}</a></li>
% endif % endif
% endfor % endfor
@@ -128,17 +128,17 @@ ${helpers.uploader_js()}
% if request.user: % if request.user:
% if request.user.Staff: % if request.user.Staff:
<li><a href="/${DisplayYear}/Staff">Partie Staff</a></li> <li><a href="/${DisplayYear}/Staff">Partie Staff</a></li>
<li><a href="/${DisplayYear}/ListParticipant">G&eacute;rer les intervenants</a></li>
<li><a href="/ListSalles">G&eacute;rer les salles</a></li>
<li><a href="/entities">G&eacute;rer les entit&eacute;s</a></li>
<li><a href="/${DisplayYear}/ListParticipant">Gérer les intervenants</a></li>
<li><a href="/ListSalles">Gérer les salles</a></li>
<li><a href="/entities">Gérer les entités</a></li>
<li><a href="/${DisplayYear}/ListOrga">Participations &agrave; l'orga</a></li> <li><a href="/${DisplayYear}/ListOrga">Participations &agrave; l'orga</a></li>
<li><a href="/${DisplayYear}/Staff/compta">Comptabilit&eacute;</a></li>
<li><a href="/${DisplayYear}/Staff/compta">Comptabilité</a></li>
<li><a href="/ListSallesPhy">Les salles &agrave; Poly'tech</a></li> <li><a href="/ListSallesPhy">Les salles &agrave; Poly'tech</a></li>
<li role="separator" class="divider"></li> <li role="separator" class="divider"></li>
% endif % endif
<li><a href="/MesJM2L">Mon profil</a></li> <li><a href="/MesJM2L">Mon profil</a></li>
<li><a href="/user/${request.user.slug}">Mon profil public</a></li> <li><a href="/user/${request.user.slug}">Mon profil public</a></li>
<li><a href="/sign/out">Me d&eacute;connecter</a></li>
<li><a href="/sign/out">Me déconnecter</a></li>
% else: % else:
<li><a href="/participer-l-evenement#inscription">Je m'inscris</a></li> <li><a href="/participer-l-evenement#inscription">Je m'inscris</a></li>
<li><a href="/sign/login">Je m'identifie</a></li> <li><a href="/sign/login">Je m'identifie</a></li>
@@ -186,20 +186,20 @@ ${helpers.uploader_js()}


<footer class="footer"> <footer class="footer">
<div class="container"> <div class="container">
<h4>JM2L 2005-2018</h4>
<h4>JM2L 2005-2020</h4>
<p> <p>
Concoct&eacute; par <a href="http://www.linux-azur.org/">Linux Azur</a> ~
Concocté par <a href="https://www.linux-azur.org/">Linux Azur</a> ~
<a href="http://creativecommons.org/licenses/by-sa/4.0/">CopyFriendly</a> <a href="http://creativecommons.org/licenses/by-sa/4.0/">CopyFriendly</a>
</p> </p>
<p> <p>
+33 6 52 42 31 37 ~ contact at jm2l.linux-azur dot org +33 6 52 42 31 37 ~ contact at jm2l.linux-azur dot org
</p> </p>
<p> <p>
Conception et construction en <a href="http://git.linux-azur.org/JM2L/jm2l/src/master">DIY</a> ~
H&eacute;berg&eacute; par <a href="http://www.heberg-24.com/"> Heberg24 </a>
Conception et construction en <a href="https://git.linux-azur.org/tr4ck3ur/jm2l/src/branch/feature/python-3-migration">DIY</a> ~
Hébergé par <a href="http://www.heberg-24.com/"> Heberg24 </a>
</p> </p>
<p> <p>
Vous avez trouv&eacute; un bug ? <a href="http://git.linux-azur.org/JM2L/jm2l/issues">Reportez-le ici</a>
Vous avez trouvé un bug ? <a href="https://git.linux-azur.org/tr4ck3ur/jm2l/issues/new">Reportez-le ici</a>
</p> </p>
</div> </div>
</footer> </footer>
@@ -222,22 +222,6 @@ ${jsitem | n}
HandleControls(); HandleControls();
</script> </script>


<!-- Piwik -->
<script type="text/javascript">
var _paq = _paq || [];
_paq.push(["setDocumentTitle", document.domain + "/" + document.title]);
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="//stats.style-python.fr/";
_paq.push(['setTrackerUrl', u+'piwik.php']);
_paq.push(['setSiteId', 4]);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<noscript><p><img src="//stats.style-python.fr/piwik.php?idsite=4" style="border:0;" alt="" /></p></noscript>
<!-- End Piwik Code -->
% if request.user: % if request.user:
<script> <script>
function handlevote() { function handlevote() {
@@ -245,7 +229,7 @@ function handlevote() {
$('.carousel-vote a').attr('href', "/vote_logo/" + currentIndex ) $('.carousel-vote a').attr('href', "/vote_logo/" + currentIndex )
if (currentIndex==${request.user.vote_logo or 0}) { if (currentIndex==${request.user.vote_logo or 0}) {
$('.carousel-vote a').removeClass('btn-primary').addClass('btn-success') $('.carousel-vote a').removeClass('btn-primary').addClass('btn-success')
$('.carousel-vote a').html("<i class='icon-ok icon-white'></i> Mon pr&eacute;f&eacute;r&eacute; ! ");
$('.carousel-vote a').html("<i class='icon-ok icon-white'></i> Mon préféré ! ");
} else { } else {
$('.carousel-vote a').removeClass('btn-success').addClass('btn-primary'); $('.carousel-vote a').removeClass('btn-success').addClass('btn-primary');
$('.carousel-vote a').html("<i class='icon-star icon-white'></i> Je vote pour ce logo ! "); $('.carousel-vote a').html("<i class='icon-star icon-white'></i> Je vote pour ce logo ! ");


+ 3
- 3
jm2l/templates/mail_html.mako View File

@@ -96,7 +96,7 @@ Voici ce qu'il y'a dans la liste des tâches qui te sont assignées:
% for t in sorted(User.task_assoc, key=lambda k:k.due_date): % for t in sorted(User.task_assoc, key=lambda k:k.due_date):
% if not t.closed: % if not t.closed:
<tr> <tr>
<td>${t.due_date.strftime('%d %B %Y').decode('utf-8', 'xmlcharrefreplace')}</td><td>${t.area.name}</td>
<td>${t.due_date.strftime('%d %B %Y')}</td><td>${t.area.name}</td>
<td><a href="http://jm2l.linux-azur.org/2017/Staff/tasks/${t.uid}">${t.name}</a> <td><a href="http://jm2l.linux-azur.org/2017/Staff/tasks/${t.uid}">${t.name}</a>
% endif % endif
% endfor % endfor
@@ -107,7 +107,7 @@ Voici ce qu'il y'a dans la liste des tâches qui te sont assignées:
% for t in sorted(Contact.task_assoc, key=lambda k:k.due_date): % for t in sorted(Contact.task_assoc, key=lambda k:k.due_date):
% if not t.closed: % if not t.closed:
<tr> <tr>
<td>${t.due_date.strftime('%d %B %Y').decode('utf-8', 'xmlcharrefreplace')}</td><td>${t.area.name}</td>
<td>${t.due_date.strftime('%d %B %Y')}</td><td>${t.area.name}</td>
<td><a href="http://jm2l.linux-azur.org/2017/Staff/tasks/${t.uid}">${t.name}</a> <td><a href="http://jm2l.linux-azur.org/2017/Staff/tasks/${t.uid}">${t.name}</a>
% endif % endif
% endfor % endfor
@@ -116,7 +116,7 @@ Voici ce qu'il y'a dans la liste des tâches qui te sont assignées:
Pour accéder à ton espace sur le site, il te suffit de cliquer sur le <a href="${request.route_url('bymail', hash=User.my_hash)}">lien suivant.</a> Pour accéder à ton espace sur le site, il te suffit de cliquer sur le <a href="${request.route_url('bymail', hash=User.my_hash)}">lien suivant.</a>
<br/><br/> <br/><br/>
% for t in filter(lambda k:k.uid==51, Contact.task_assoc): % for t in filter(lambda k:k.uid==51, Contact.task_assoc):
Nous avons fixé la prochaine réunion JM2L au ${t.due_date.strftime('%d %B').decode('utf-8', 'xmlcharrefreplace')} à 19h30.
Nous avons fixé la prochaine réunion JM2L au ${t.due_date.strftime('%d %B')} à 19h30.
% endfor % endfor
<p> <p>
Bon courage ! Bon courage !


+ 3
- 3
jm2l/templates/mail_plain.mako View File

@@ -65,7 +65,7 @@ Voici ce qu'il y'a dans la liste des tâches qui te sont assignées:


% for t in sorted(User.task_assoc, key=lambda k:k.due_date): % for t in sorted(User.task_assoc, key=lambda k:k.due_date):
% if not t.closed: % if not t.closed:
- Pour le ${t.due_date.strftime('%d %B %Y').decode('utf-8', 'xmlcharrefreplace')} - ${t.area.name} tâche ${t.uid}
- Pour le ${t.due_date.strftime('%d %B %Y')} - ${t.area.name} tâche ${t.uid}
=> ${t.name} => ${t.name}
% endif % endif
@@ -75,7 +75,7 @@ Et il y'a aussi des tâches communes !


% for t in sorted(Contact.task_assoc, key=lambda k:k.due_date): % for t in sorted(Contact.task_assoc, key=lambda k:k.due_date):
% if not t.closed and t.uid!=51: % if not t.closed and t.uid!=51:
- Pour le ${t.due_date.strftime('%d %B %Y').decode('utf-8', 'xmlcharrefreplace')} - ${t.area.name} tâche ${t.uid}
- Pour le ${t.due_date.strftime('%d %B %Y')} - ${t.area.name} tâche ${t.uid}
=> ${t.name} => ${t.name}
% endif % endif
@@ -85,7 +85,7 @@ Pour accéder à ton espace il te suffit de cliquer sur le lien suivant :
${request.route_url('bymail', hash=User.my_hash)}. ${request.route_url('bymail', hash=User.my_hash)}.


% for t in filter(lambda k:k.uid==51, Contact.task_assoc): % for t in filter(lambda k:k.uid==51, Contact.task_assoc):
Nous avons fixé la prochaine réunion JM2L au ${t.due_date.strftime('%d %B').decode('utf-8', 'xmlcharrefreplace')} à 19h30.
Nous avons fixé la prochaine réunion JM2L au ${t.due_date.strftime('%d %B')} à 19h30.
% endfor % endfor




+ 1
- 1
jm2l/templates/show_user.mako View File

@@ -52,7 +52,7 @@
</div> </div>
<br/> <br/>
<hr/> <hr/>
<p style="float:right;">Créé le ${DispUser.created.strftime('%d %b %Y').decode('utf-8')}</p>
<p style="float:right;">Créé le ${DispUser.created.strftime('%d %b %Y')}</p>


</div> </div>
</div> </div>

+ 2
- 2
jm2l/templates/view_event.mako View File

@@ -13,7 +13,7 @@
</div> </div>
<strong>${event.event_type}</strong>: <strong>${event.event_type}</strong>:
<div class="borderboxtime"> <div class="borderboxtime">
${event.start_time.strftime('%d %b %Y').decode('utf-8')} -
${event.start_time.strftime('%d %b %Y')} -
${event.start_time.strftime('%H:%M')} à ${event.end_time.strftime('%H:%M')} ${event.start_time.strftime('%H:%M')} à ${event.end_time.strftime('%H:%M')}
</div> </div>
% if event.for_year==CurrentYear and request.user and (request.user.Staff or request.user in event.intervenants): % if event.for_year==CurrentYear and request.user and (request.user.Staff or request.user in event.intervenants):
@@ -116,7 +116,7 @@
</p> </p>
% endfor % endfor
<div class="clearfix">&nbsp;</div> <div class="clearfix">&nbsp;</div>
<p style="float:right;">Créé le ${event.created.strftime('%d %b %Y').decode('utf-8')}</p>
<p style="float:right;">Créé le ${event.created.strftime('%d %b %Y')}</p>
<br/> <br/>
<hr/> <hr/>
</div> </div>


+ 1
- 1
jm2l/templates/view_tiers.mako View File

@@ -103,7 +103,7 @@ ${The_entity_type.entity_subtype}
</p> </p>
% endfor % endfor
<br/><br/> <br/><br/>
<p style="float:right;">Créé le ${entity.created.strftime('%d %b %Y').decode('utf-8')}</p>
<p style="float:right;">Créé le ${entity.created.strftime('%d %b %Y')}</p>
<br/> <br/>
<hr/> <hr/>




+ 1
- 1
jm2l/templates/view_user.mako View File

@@ -47,7 +47,7 @@
<h4>Ses interventions :</h4> <h4>Ses interventions :</h4>
${helpers.show_Interventions(DispUser.events)} ${helpers.show_Interventions(DispUser.events)}
% endif % endif
<p style="float:right;">Créé le ${DispUser.created.strftime('%d %b %Y').decode('utf-8')}</p>
<p style="float:right;">Créé le ${DispUser.created.strftime('%d %b %Y')}</p>


</div> </div>
</div> </div>

+ 97
- 97
jm2l/to_print.py View File

@@ -1,6 +1,6 @@
# -*- coding: utf8 -*- # -*- coding: utf8 -*-
import io
from pyramid.response import Response from pyramid.response import Response
import cStringIO as StringIO
from pyramid.view import view_config from pyramid.view import view_config
from .models import DBSession, Event, Salles from .models import DBSession, Event, Salles
from reportlab.pdfgen import canvas from reportlab.pdfgen import canvas
@@ -11,174 +11,174 @@ from .upload import MediaPath
from jm2l.const import CurrentYear from jm2l.const import CurrentYear


# Create PDF container # Create PDF container
EXPIRATION_TIME = 300 # seconds
EXPIRATION_TIME = 300 # seconds
WIDTH = 210 * mm WIDTH = 210 * mm
HEIGHT = 297 * mm HEIGHT = 297 * mm
ICONSIZE = 10 * mm ICONSIZE = 10 * mm




def JM2L_large_Logo(canvas, Offset=(0,0)):
def JM2L_large_Logo(canvas, Offset=(0, 0)):
OffX, OffY = Offset OffX, OffY = Offset
canvas.setFont('Logo', 110) canvas.setFont('Logo', 110)
canvas.setFillColorRGB(.83,0,.33)
canvas.drawCentredString(WIDTH/2-OffY, HEIGHT-100-OffX, "JM2L")
canvas.setFillColorRGB(.83, 0, .33)
canvas.drawCentredString(WIDTH / 2 - OffY, HEIGHT - 100 - OffX, "JM2L")


canvas.setFont("Helvetica-Bold", 30) canvas.setFont("Helvetica-Bold", 30)
yearobject = canvas.beginText()
yearobject.setFillColorRGB(1,1,1)
yearobject.setTextRenderMode(0)
yearobject.setTextOrigin(WIDTH/2-OffY-120, HEIGHT-36-OffX)
yearobject.setWordSpace(48)
yearobject.textLines("2 0 1 5")
yearobject.setWordSpace(1)
canvas.drawText(yearobject)
year_object = canvas.beginText()
year_object.setFillColorRGB(1, 1, 1)
year_object.setTextRenderMode(0)
year_object.setTextOrigin(WIDTH / 2 - OffY - 120, HEIGHT - 36 - OffX)
year_object.setWordSpace(48)
year_object.textLines("2 0 1 5")
year_object.setWordSpace(1)
canvas.drawText(year_object)



def one_time_step(canvas, str, hour, max_size, offset): def one_time_step(canvas, str, hour, max_size, offset):
max_x, max_y = max_size max_x, max_y = max_size
off_x, off_y = offset off_x, off_y = offset
step_y = max_y/9
half_step = step_y/2
canvas.drawCentredString(off_x-30, max_y-step_y*hour+off_y-3, str)
hour_place = step_y*hour+off_y
canvas.line(off_x-5, hour_place, off_x, hour_place)
if hour<9:
canvas.line(off_x-2, hour_place+half_step, off_x, hour_place+half_step)
step_y = max_y / 9
half_step = step_y / 2
canvas.drawCentredString(off_x - 30, max_y - step_y * hour + off_y - 3, str)
hour_place = step_y * hour + off_y
canvas.line(off_x - 5, hour_place, off_x, hour_place)
if hour < 9:
canvas.line(off_x - 2, hour_place + half_step, off_x, hour_place + half_step)




@view_config(route_name='stand_print', http_cache = (EXPIRATION_TIME, {'public':True}))
@view_config(route_name='stand_print', http_cache=(EXPIRATION_TIME, {'public': True}))
def stand_print(request): def stand_print(request):
# Ok let's generate a print for place schedule # Ok let's generate a print for place schedule
# Register LiberationMono font # Register LiberationMono font
ttfFile = "jm2l/static/fonts/LiberationMono-Regular.ttf"
pdfmetrics.registerFont(TTFont("Liberation", ttfFile))
# Import font
ttfFile_Logo = "jm2l/static/fonts/PWTinselLetters.ttf"
pdfmetrics.registerFont(TTFont("Logo", ttfFile_Logo))
pdf = StringIO.StringIO()
c = canvas.Canvas( pdf, pagesize=(HEIGHT, WIDTH) )
ttf_file = "jm2l/static/fonts/LiberationMono-Regular.ttf"
pdfmetrics.registerFont(TTFont("Liberation", ttf_file))
#  Import font
ttf_file_logo = "jm2l/static/fonts/PWTinselLetters.ttf"
pdfmetrics.registerFont(TTFont("Logo", ttf_file_logo))
pdf = io.BytesIO()
c = canvas.Canvas(pdf, pagesize=(HEIGHT, WIDTH))
c.translate(mm, mm) c.translate(mm, mm)
# Feed some metadata # Feed some metadata
c.setCreator("linux-azur.org") c.setCreator("linux-azur.org")
c.setTitle("Affiches stand") c.setTitle("Affiches stand")


c.saveState() c.saveState()
year = int(request.matchdict.get('year', CurrentYear)) year = int(request.matchdict.get('year', CurrentYear))


Events = DBSession.query(Event)\
.filter(Event.for_year == year)\
Events = DBSession.query(Event) \
.filter(Event.for_year == year) \
.filter(Event.event_type == "Stand") .filter(Event.event_type == "Stand")


for ev in Events: for ev in Events:
c.setFont('Logo', 50) c.setFont('Logo', 50)
c.setFillColorRGB(.5,.5,.5)
c.drawString(HEIGHT-150, 30, "JM2L")
c.setFillColorRGB(.5, .5, .5)
c.drawString(HEIGHT - 150, 30, "JM2L")
c.setFont('Logo', 100) c.setFont('Logo', 100)
c.setFillColorRGB(0.5,0.5,0.5)
c.drawCentredString(HEIGHT/2, WIDTH-90, "STAND", 0)
c.setFillColorRGB(0,0,0)
c.setFillColorRGB(0.5, 0.5, 0.5)
c.drawCentredString(HEIGHT / 2, WIDTH - 90, "STAND", 0)
c.setFillColorRGB(0, 0, 0)
c.setFont('Helvetica', 42) c.setFont('Helvetica', 42)
c.drawCentredString(HEIGHT/2, WIDTH/2, ev.name, 0)
c.drawCentredString(HEIGHT / 2, WIDTH / 2, ev.name, 0)
c.showPage() c.showPage()


c.save() c.save()
pdf.seek(0) pdf.seek(0)


return Response(app_iter=pdf, content_type = 'application/pdf' )

return Response(app_iter=pdf, content_type='application/pdf')




@view_config(route_name='place_print', http_cache = (EXPIRATION_TIME, {'public':True}))
@view_config(route_name='place_print', http_cache=(EXPIRATION_TIME, {'public': True}))
def place_print(request): def place_print(request):
# Ok let's generate a print for place schedule # Ok let's generate a print for place schedule
# Register LiberationMono font # Register LiberationMono font
ttfFile = "jm2l/static/fonts/LiberationMono-Regular.ttf"
pdfmetrics.registerFont(TTFont("Liberation", ttfFile))
# Import font
ttfFile_Logo = "jm2l/static/fonts/PWTinselLetters.ttf"
pdfmetrics.registerFont(TTFont("Logo", ttfFile_Logo))
pdf = StringIO.StringIO()
c = canvas.Canvas( pdf, pagesize=(WIDTH, HEIGHT) )
ttf_file = "jm2l/static/fonts/LiberationMono-Regular.ttf"
pdfmetrics.registerFont(TTFont("Liberation", ttf_file))
#  Import font
ttf_file_logo = "jm2l/static/fonts/PWTinselLetters.ttf"
pdfmetrics.registerFont(TTFont("Logo", ttf_file_logo))
pdf = io.BytesIO()
c = canvas.Canvas(pdf, pagesize=(WIDTH, HEIGHT))
c.translate(mm, mm) c.translate(mm, mm)
# Feed some metadata # Feed some metadata
c.setCreator("linux-azur.org") c.setCreator("linux-azur.org")
c.setTitle("Planning Salle") c.setTitle("Planning Salle")


c.saveState() c.saveState()
year = int(request.matchdict.get('year', CurrentYear)) year = int(request.matchdict.get('year', CurrentYear))
# Initialization # Initialization
# Compute days used by all events matching the specified input year # Compute days used by all events matching the specified input year
place_used = DBSession.query(Event.salle_uid)\
.filter(Event.for_year == year)\
.filter(Event.event_type != 'Stand')\
.group_by(Event.salle_uid)
place_used = DBSession.query(Event.salle_uid) \
.filter(Event.for_year == year) \
.filter(Event.event_type != 'Stand') \
.group_by(Event.salle_uid)
for place in place_used: for place in place_used:
place_uid = place[0]
place_uid = place[0]
place_obj = Salles.by_id(place_uid) place_obj = Salles.by_id(place_uid)
# Logo on Top # Logo on Top
JM2L_large_Logo(c) JM2L_large_Logo(c)
max_size = (WIDTH-110, HEIGHT-300)
max_size = (WIDTH - 110, HEIGHT - 300)
offset = (70, 90) offset = (70, 90)
c.setFillColorRGB(.5,.5,.5)
c.setFillColorRGB(.5, .5, .5)
c.setFont('Liberation', 40) c.setFont('Liberation', 40)
c.drawCentredString(WIDTH/2, HEIGHT-190, place_obj.name, 1)
c.drawCentredString(WIDTH / 2, HEIGHT - 190, place_obj.name, 1)
c.setFont('Liberation', 35) c.setFont('Liberation', 35)
c.drawCentredString(WIDTH/2, HEIGHT-145, place_obj.place_type, 0 )
c.setFont('Helvetica', 20)
c.drawCentredString(WIDTH/2, 55, place_obj.phy.name, 0)
c.drawCentredString(WIDTH / 2, HEIGHT - 145, place_obj.place_type, 0)
c.setFont('Helvetica', 20)
c.drawCentredString(WIDTH / 2, 55, place_obj.phy.name, 0)
# Timetable container # Timetable container
c.setLineWidth(.1) c.setLineWidth(.1)
c.setLineCap(2) c.setLineCap(2)
#c.setFillColorRGB(0,0,1)
# c.setFillColorRGB(0,0,1)
c.rect(offset[0], offset[1], max_size[0], max_size[1], fill=0, stroke=1) c.rect(offset[0], offset[1], max_size[0], max_size[1], fill=0, stroke=1)
c.setLineWidth(.5)
c.setLineWidth(.5)
# create time mark # create time mark
c.setFillColorRGB(0,0,0)
c.setFillColorRGB(0, 0, 0)
c.setFont('Helvetica', 10) c.setFont('Helvetica', 10)
for i in range(0,10):
one_time_step(c, "%.2dh00" % (i+10), i, max_size, offset)
#c.setFont('Helvetica', 12)
Events = DBSession.query(Event)\
.filter(Event.for_year == year)\
.filter(Event.salle_uid == place_uid)\
.order_by(Event.start_time)
for i in range(0, 10):
one_time_step(c, "%.2dh00" % (i + 10), i, max_size, offset)
# c.setFont('Helvetica', 12)
Events = DBSession.query(Event) \
.filter(Event.for_year == year) \
.filter(Event.salle_uid == place_uid) \
.order_by(Event.start_time)
for ev in Events: for ev in Events:
place_time(c, ev, max_size, offset) place_time(c, ev, max_size, offset)
#c.rect(70, 50, WIDTH-100, HEIGHT-250, fill=0, stroke=1)
# c.rect(70, 50, WIDTH-100, HEIGHT-250, fill=0, stroke=1)
c.showPage() c.showPage()


c.save() c.save()
pdf.seek(0) pdf.seek(0)


return Response(app_iter=pdf, content_type = 'application/pdf' )
return Response(app_iter=pdf, content_type='application/pdf')



def place_time(c, ev, max_size, offset): def place_time(c, ev, max_size, offset):
max_x, max_y = max_size max_x, max_y = max_size
off_x, off_y = offset off_x, off_y = offset
minute = max_y/(9*60)
start_pos_y = ((int( ev.start_time.strftime('%H') )-10)*60 + int( ev.start_time.strftime('%M') )) * minute
stop_pos_y = ((int( ev.end_time.strftime('%H') )-10)*60 + int( ev.end_time.strftime('%M') )) * minute

c.setFillColorRGB(0.98,0.98,0.98)
c.rect(offset[0], max_y + off_y - start_pos_y, max_size[0], start_pos_y-stop_pos_y, fill=1, stroke=1)
c.setFillColorRGB(0,0,0)
#c.drawString(off_x+5, max_y + off_y - 15 - start_pos_y, ev.start_time.strftime('%H:%M'), 0)
c.setFont('Helvetica', 12)
c.drawCentredString(WIDTH/2, max_y + off_y - 35 - start_pos_y, ev.name, 0)
intervs = ', '.join( [x.slug for x in ev.intervenants] )
c.setFont('Helvetica', 10)
c.drawCentredString(WIDTH/2, max_y + off_y - 55 - start_pos_y, intervs, 0)
minute = max_y / (9 * 60)
start_pos_y = ((int(ev.start_time.strftime('%H')) - 10) * 60 + int(ev.start_time.strftime('%M'))) * minute
stop_pos_y = ((int(ev.end_time.strftime('%H')) - 10) * 60 + int(ev.end_time.strftime('%M'))) * minute

c.setFillColorRGB(0.98, 0.98, 0.98)
c.rect(offset[0], max_y + off_y - start_pos_y, max_size[0], start_pos_y - stop_pos_y, fill=1, stroke=1)
c.setFillColorRGB(0, 0, 0)
# c.drawString(off_x+5, max_y + off_y - 15 - start_pos_y, ev.start_time.strftime('%H:%M'), 0)
c.setFont('Helvetica', 12)
c.drawCentredString(WIDTH / 2, max_y + off_y - 35 - start_pos_y, ev.name, 0)
intervs = ', '.join([x.slug for x in ev.intervenants])
c.setFont('Helvetica', 10)
c.drawCentredString(WIDTH / 2, max_y + off_y - 55 - start_pos_y, intervs, 0)

+ 180
- 174
jm2l/upload.py View File

@@ -9,113 +9,114 @@ from os import path
import mimetypes import mimetypes
import magic import magic
import subprocess import subprocess
import cStringIO as StringIO
try:
from StringIO import StringIO
except ImportError:
from io import StringIO
# Database access imports # Database access imports
from .models import User, Place, Tiers, Event, SallePhy from .models import User, Place, Tiers, Event, SallePhy
from .blenderthumbnailer import blend_extract_thumb, write_png from .blenderthumbnailer import blend_extract_thumb, write_png
from jm2l.const import CurrentYear from jm2l.const import CurrentYear
from slugify import slugify from slugify import slugify


MIN_FILE_SIZE = 1 # bytes
MAX_FILE_SIZE = 500000000 # bytes
MIN_FILE_SIZE = 1 # bytes
MAX_FILE_SIZE = 500000000 # bytes
IMAGE_TYPES = re.compile('image/(gif|p?jpeg|(x-)?png)') IMAGE_TYPES = re.compile('image/(gif|p?jpeg|(x-)?png)')
ACCEPTED_MIMES = ['application/pdf', ACCEPTED_MIMES = ['application/pdf',
'application/vnd.oasis.opendocument.text',
'application/vnd.oasis.opendocument.text-template',
'application/vnd.oasis.opendocument.graphics',
'application/vnd.oasis.opendocument.graphics-template',
'application/vnd.oasis.opendocument.presentation',
'application/vnd.oasis.opendocument.presentation-template',
'application/vnd.oasis.opendocument.spreadsheet',
'application/vnd.oasis.opendocument.spreadsheet-template',
'image/svg+xml',
'application/x-blender'
]

'application/vnd.oasis.opendocument.text',
'application/vnd.oasis.opendocument.text-template',
'application/vnd.oasis.opendocument.graphics',
'application/vnd.oasis.opendocument.graphics-template',
'application/vnd.oasis.opendocument.presentation',
'application/vnd.oasis.opendocument.presentation-template',
'application/vnd.oasis.opendocument.spreadsheet',
'application/vnd.oasis.opendocument.spreadsheet-template',
'image/svg+xml',
'application/x-blender'
]


ACCEPT_FILE_TYPES = IMAGE_TYPES ACCEPT_FILE_TYPES = IMAGE_TYPES
THUMBNAIL_SIZE = 80 THUMBNAIL_SIZE = 80
EXPIRATION_TIME = 300 # seconds
IMAGEPATH = [ 'images' ]
DOCPATH = [ 'document' ]
THUMBNAILPATH = [ 'images', 'thumbnails' ]
EXPIRATION_TIME = 300 # seconds
IMAGEPATH = ['images']
DOCPATH = ['document']
THUMBNAILPATH = ['images', 'thumbnails']
# change the following to POST if DELETE isn't supported by the webserver # change the following to POST if DELETE isn't supported by the webserver
DELETEMETHOD="DELETE"
DELETEMETHOD = "DELETE"


mimetypes.init() mimetypes.init()


class MediaPath():

class MediaPath():


def get_all(self, media_table, linked_id, MediaType=None): def get_all(self, media_table, linked_id, MediaType=None):
filelist = list() filelist = list()
curpath = self.get_mediapath(media_table, linked_id, None) curpath = self.get_mediapath(media_table, linked_id, None)
thumbpath = os.path.join( curpath, 'thumbnails')
thumbpath = os.path.join(curpath, 'thumbnails')
if not os.path.isdir(curpath) or not os.path.isdir(thumbpath): if not os.path.isdir(curpath) or not os.path.isdir(thumbpath):
return list() return list()
for f in os.listdir(curpath): for f in os.listdir(curpath):
filename, ext = os.path.splitext( f )
if os.path.isdir(os.path.join(curpath,f)):
filename, ext = os.path.splitext(f)
if os.path.isdir(os.path.join(curpath, f)):
continue continue
if f.endswith('.type'): if f.endswith('.type'):
continue continue
if f: if f:
ress_url = '/image/%s/%d/%s' % (media_table, linked_id, f.replace(" ", "%20")) ress_url = '/image/%s/%d/%s' % (media_table, linked_id, f.replace(" ", "%20"))
thumb_url = '/image/%s/%d/thumbnails/%s' % (media_table, linked_id, f.replace(" ","%20"))
thumb_url = '/image/%s/%d/thumbnails/%s' % (media_table, linked_id, f.replace(" ", "%20"))
if MediaType is None: if MediaType is None:
if os.path.exists(os.path.join(thumbpath, f +".jpg")):
filelist.append((ress_url, thumb_url +".jpg"))
if os.path.exists(os.path.join(thumbpath, f + ".jpg")):
filelist.append((ress_url, thumb_url + ".jpg"))
else: else:
filelist.append((ress_url, thumb_url)) filelist.append((ress_url, thumb_url))
elif MediaType=='Image' and len( os.path.splitext(filename)[1] )==0:
elif MediaType == 'Image' and len(os.path.splitext(filename)[1]) == 0:
filelist.append((ress_url, thumb_url)) filelist.append((ress_url, thumb_url))
elif MediaType=='Other' and len( os.path.splitext(filename)[1] ):
elif MediaType == 'Other' and len(os.path.splitext(filename)[1]):
filelist.append((ress_url, thumb_url)) filelist.append((ress_url, thumb_url))
return filelist return filelist



def get_list(self, media_table, linked_id, MediaType=None): def get_list(self, media_table, linked_id, MediaType=None):
filelist = list() filelist = list()
curpath = self.get_mediapath(media_table, linked_id, None) curpath = self.get_mediapath(media_table, linked_id, None)
if not os.path.isdir(curpath): if not os.path.isdir(curpath):
return list() return list()
for f in os.listdir(curpath): for f in os.listdir(curpath):
if os.path.isdir(os.path.join(curpath,f)):
if os.path.isdir(os.path.join(curpath, f)):
continue continue
if f.endswith('.type'): if f.endswith('.type'):
continue continue
if f: if f:
filename, ext = os.path.splitext( f )
tmpurl = '/image/%s/%d/%s' % (media_table, linked_id, f.replace(" ","%20"))
filename, ext = os.path.splitext(f)
tmpurl = '/image/%s/%d/%s' % (media_table, linked_id, f.replace(" ", "%20"))
if MediaType is None: if MediaType is None:
filelist.append(tmpurl) filelist.append(tmpurl)
elif MediaType=='Image' and ext.lower() in ['.gif','.jpg','.png','.svg','.jpeg']:
elif MediaType == 'Image' and ext.lower() in ['.gif', '.jpg', '.png', '.svg', '.jpeg']:
filelist.append(tmpurl) filelist.append(tmpurl)
elif MediaType=='Other' and ext.lower() not in ['.gif','.jpg','.png','.svg','.jpeg']:
elif MediaType == 'Other' and ext.lower() not in ['.gif', '.jpg', '.png', '.svg', '.jpeg']:
filelist.append(tmpurl) filelist.append(tmpurl)
return filelist return filelist
def get_thumb(self, media_table, linked_id, MediaType=None): def get_thumb(self, media_table, linked_id, MediaType=None):
filelist = list() filelist = list()
curpath = self.get_mediapath(media_table, linked_id, None) curpath = self.get_mediapath(media_table, linked_id, None)
curpath = os.path.join( curpath, 'thumbnails')
curpath = os.path.join(curpath, 'thumbnails')
if not os.path.isdir(curpath): if not os.path.isdir(curpath):
return list() return list()
for f in os.listdir(curpath): for f in os.listdir(curpath):
filename, ext = os.path.splitext( f )
if os.path.isdir(os.path.join(curpath,f)):
filename, ext = os.path.splitext(f)
if os.path.isdir(os.path.join(curpath, f)):
continue continue
if f.endswith('.type'): if f.endswith('.type'):
continue continue
if f: if f:
tmpurl = '/image/%s/%d/thumbnails/%s' % (media_table, linked_id, f.replace(" ","%20"))
tmpurl = '/image/%s/%d/thumbnails/%s' % (media_table, linked_id, f.replace(" ", "%20"))
if MediaType is None: if MediaType is None:
filelist.append(tmpurl) filelist.append(tmpurl)
elif MediaType=='Image' and len( os.path.splitext(filename)[1] )==0:
elif MediaType == 'Image' and len(os.path.splitext(filename)[1]) == 0:
filelist.append(tmpurl) filelist.append(tmpurl)
elif MediaType=='Other' and len( os.path.splitext(filename)[1] ):
elif MediaType == 'Other' and len(os.path.splitext(filename)[1]):
filelist.append(tmpurl) filelist.append(tmpurl)
return filelist
return filelist


def move_mediapath(self, media_table, from_id, to_id): def move_mediapath(self, media_table, from_id, to_id):
""" """
@@ -126,8 +127,8 @@ class MediaPath():
:return: Error if any :return: Error if any
""" """
if media_table in ['tiers', 'place', 'salle', 'users']: if media_table in ['tiers', 'place', 'salle', 'users']:
src = IMAGEPATH + [ media_table, from_id ]
dst = IMAGEPATH + [ media_table, to_id ]
src = IMAGEPATH + [media_table, from_id]
dst = IMAGEPATH + [media_table, to_id]
else: else:
raise RuntimeError("Sorry, Media '%s' not supported yet for move." % media_table) raise RuntimeError("Sorry, Media '%s' not supported yet for move." % media_table)


@@ -153,51 +154,51 @@ class MediaPath():
linked_id = str(linked_id) linked_id = str(linked_id)
if media_table in ['tiers', 'place', 'salle']: if media_table in ['tiers', 'place', 'salle']:
# Retrieve Slug # Retrieve Slug
if media_table=='tiers':
if media_table == 'tiers':
slug = Tiers.by_id(linked_id).slug slug = Tiers.by_id(linked_id).slug
if media_table=='place':
if media_table == 'place':
slug = Place.by_id(linked_id).slug or slugify(Place.by_id(linked_id).name) slug = Place.by_id(linked_id).slug or slugify(Place.by_id(linked_id).name)
if media_table=='salle':
if media_table == 'salle':
slug = SallePhy.by_id(linked_id).slug slug = SallePhy.by_id(linked_id).slug
p = IMAGEPATH + [ media_table, slug ]
elif media_table=='presse':
p = IMAGEPATH + [media_table, slug]
elif media_table == 'presse':
# Use Year in linked_id # Use Year in linked_id
p = IMAGEPATH + [ media_table, linked_id ]
elif media_table=='tasks':
p = IMAGEPATH + [media_table, linked_id]
elif media_table == 'tasks':
# Use Current Year # Use Current Year
p = IMAGEPATH + [ str(CurrentYear), media_table, linked_id ]
elif media_table=='poles':
p = IMAGEPATH + [str(CurrentYear), media_table, linked_id]
elif media_table == 'poles':
# Use Current Year # Use Current Year
p = IMAGEPATH + [ str(CurrentYear), media_table, linked_id ]
p = IMAGEPATH + [str(CurrentYear), media_table, linked_id]
elif media_table in ['RIB', 'Justif']: elif media_table in ['RIB', 'Justif']:
slug = User.by_id(linked_id).slug slug = User.by_id(linked_id).slug
p = IMAGEPATH + ['users', slug , media_table ]
p = IMAGEPATH + ['users', slug, media_table]
elif media_table in ['users', 'badge']: elif media_table in ['users', 'badge']:
user = User.by_id(linked_id) user = User.by_id(linked_id)
if not user: if not user:
raise HTTPNotFound() raise HTTPNotFound()
else: else:
slug = user.slug slug = user.slug
p = IMAGEPATH + [media_table, slug ]
elif media_table=='event':
p = IMAGEPATH + [media_table, slug]
elif media_table == 'event':
ev = Event.by_id(linked_id) ev = Event.by_id(linked_id)
slug = ev.slug slug = ev.slug
year = ev.for_year year = ev.for_year
p = IMAGEPATH + ['event', str(year), slug ]
p = IMAGEPATH + ['event', str(year), slug]


if name: if name:
p += [ name ]
p += [name]
TargetPath = os.path.join('jm2l/upload', *p) TargetPath = os.path.join('jm2l/upload', *p)
if not os.path.isdir(os.path.dirname(TargetPath)): if not os.path.isdir(os.path.dirname(TargetPath)):
try: try:
os.makedirs(os.path.dirname(TargetPath)) os.makedirs(os.path.dirname(TargetPath))
except OSError, e:
except OSError as e:
if e.errno != 17: if e.errno != 17:
raise e raise e
return os.path.join('jm2l/upload', *p)
return os.path.join('jm2l/upload', *p)


def ExtMimeIcon(self, mime): def ExtMimeIcon(self, mime):
if mime=='application/pdf':
if mime == 'application/pdf':
return "/img/PDF.png" return "/img/PDF.png"


def check_blend_file(self, fileobj): def check_blend_file(self, fileobj):
@@ -217,12 +218,12 @@ class MediaPath():
fileobj.seek(0) fileobj.seek(0)


# Check if the binary file is a blender file # Check if the binary file is a blender file
if ( mimetype == "application/octet-stream" or mimetype == "application/x-gzip" ) and self.check_blend_file(fileobj):
if (mimetype == "application/octet-stream" or mimetype == "application/x-gzip") and self.check_blend_file(
fileobj):
return "application/x-blender", True return "application/x-blender", True
else: else:
return mimetype, False return mimetype, False



def get_mimetype(self, name): def get_mimetype(self, name):
""" This function return the mime-type based on .type file """ """ This function return the mime-type based on .type file """
try: try:
@@ -232,6 +233,7 @@ class MediaPath():
except IOError: except IOError:
return None return None



@view_defaults(route_name='media_upload') @view_defaults(route_name='media_upload')
class MediaUpload(MediaPath): class MediaUpload(MediaPath):


@@ -256,17 +258,17 @@ class MediaUpload(MediaPath):
# Try to determine mime type from content uploaded # Try to determine mime type from content uploaded
found_mime = magic.from_buffer(filecontent.read(1024), mime=True) found_mime = magic.from_buffer(filecontent.read(1024), mime=True)
filecontent.seek(0) filecontent.seek(0)
# Do a special statement for specific detected mime type # Do a special statement for specific detected mime type
if found_mime in ["application/octet-stream", "application/x-gzip"]: if found_mime in ["application/octet-stream", "application/x-gzip"]:
# Lets see if it's a bender file # Lets see if it's a bender file
if self.check_blend_file(filecontent): if self.check_blend_file(filecontent):
found_mime = "application/x-blender" found_mime = "application/x-blender"
# MonKey Patch of content type # MonKey Patch of content type
result['type'] = found_mime
# Reject mime type that don't match
if found_mime!=result['type']:
result['type'] = found_mime
# Reject mime type that don't match
if found_mime != result['type']:
result['error'] = 'L\'extension du fichier ne correspond pas à son contenu - ' result['error'] = 'L\'extension du fichier ne correspond pas à son contenu - '
result['error'] += "( %s vs %s )" % (found_mime, result['type']) result['error'] += "( %s vs %s )" % (found_mime, result['type'])
return False return False
@@ -281,7 +283,7 @@ class MediaUpload(MediaPath):
result['error'] = 'le fichier est trop petit' result['error'] = 'le fichier est trop petit'
elif result['size'] > MAX_FILE_SIZE: elif result['size'] > MAX_FILE_SIZE:
result['error'] = 'le fichier est trop voluminueux' result['error'] = 'le fichier est trop voluminueux'
#elif not ACCEPT_FILE_TYPES.match(file['type']):
# elif not ACCEPT_FILE_TYPES.match(file['type']):
# file['error'] = u'les type de fichiers acceptés sont png, jpg et gif' # file['error'] = u'les type de fichiers acceptés sont png, jpg et gif'
else: else:
return True return True
@@ -289,80 +291,82 @@ class MediaUpload(MediaPath):
return False return False


def get_file_size(self, fileobj): def get_file_size(self, fileobj):
fileobj.seek(0, 2) # Seek to the end of the file
size = fileobj.tell() # Get the position of EOF
fileobj.seek(0) # Reset the file position to the beginning
fileobj.seek(0, 2) # Seek to the end of the file
size = fileobj.tell() # Get the position of EOF
fileobj.seek(0) # Reset the file position to the beginning
return size return size


def thumbnailurl(self,name):
return self.request.route_url('media_view',name='thumbnails',
media_table=self.media_table,
uid=self.linked_id) + '/' + name
def thumbnailurl(self, name):
return self.request.route_url('media_view', name='thumbnails',
media_table=self.media_table,
uid=self.linked_id) + '/' + name


def thumbnailpath(self,name):
def thumbnailpath(self, name):
origin = self.mediapath(name) origin = self.mediapath(name)
TargetPath = os.path.join( os.path.dirname(origin), 'thumbnails', name)
TargetPath = os.path.join(os.path.dirname(origin), 'thumbnails', name)
if not os.path.isdir(os.path.dirname(TargetPath)): if not os.path.isdir(os.path.dirname(TargetPath)):
os.makedirs(os.path.dirname(TargetPath))
os.makedirs(os.path.dirname(TargetPath))
return TargetPath return TargetPath


def createthumbnail(self, filename): def createthumbnail(self, filename):
image = Image.open( self.mediapath(filename) )
image = Image.open(self.mediapath(filename))
image.thumbnail((THUMBNAIL_SIZE, THUMBNAIL_SIZE), Image.ANTIALIAS) image.thumbnail((THUMBNAIL_SIZE, THUMBNAIL_SIZE), Image.ANTIALIAS)
timage = Image.new('RGBA', (THUMBNAIL_SIZE, THUMBNAIL_SIZE), (255, 255, 255, 0)) timage = Image.new('RGBA', (THUMBNAIL_SIZE, THUMBNAIL_SIZE), (255, 255, 255, 0))
timage.paste( timage.paste(
image, image,
((THUMBNAIL_SIZE - image.size[0]) / 2, (THUMBNAIL_SIZE - image.size[1]) / 2))
(int((THUMBNAIL_SIZE - image.size[0]) / 2), int((THUMBNAIL_SIZE - image.size[1]) / 2)))
TargetFileName = self.thumbnailpath(filename) TargetFileName = self.thumbnailpath(filename)
timage.save( TargetFileName )
return self.thumbnailurl( os.path.basename(TargetFileName) )
if not TargetFileName.endswith('png'):
timage = timage.convert('RGB')
timage.save(TargetFileName)
return self.thumbnailurl(os.path.basename(TargetFileName))


def pdfthumbnail(self, filename): def pdfthumbnail(self, filename):
TargetFileName = self.thumbnailpath(filename) TargetFileName = self.thumbnailpath(filename)
Command = ["convert","./%s[0]" % self.mediapath(filename),"./%s_.jpg" % TargetFileName]
Command = ["convert", "./%s[0]" % self.mediapath(filename), "./%s_.jpg" % TargetFileName]
Result = subprocess.call(Command) Result = subprocess.call(Command)
if Result==0:
image = Image.open( TargetFileName+"_.jpg" )
pdf_indicator = Image.open( "jm2l/static/img/PDF_Thumb_Stamp.png" )
if Result == 0:
image = Image.open(TargetFileName + "_.jpg")
pdf_indicator = Image.open("jm2l/static/img/PDF_Thumb_Stamp.png")
image.thumbnail((THUMBNAIL_SIZE, THUMBNAIL_SIZE), Image.ANTIALIAS) image.thumbnail((THUMBNAIL_SIZE, THUMBNAIL_SIZE), Image.ANTIALIAS)
timage = Image.new('RGBA', (THUMBNAIL_SIZE, THUMBNAIL_SIZE), (255, 255, 255, 0)) timage = Image.new('RGBA', (THUMBNAIL_SIZE, THUMBNAIL_SIZE), (255, 255, 255, 0))
# Add thumbnail # Add thumbnail
timage.paste( timage.paste(
image,
((THUMBNAIL_SIZE - image.size[0]) / 2, (THUMBNAIL_SIZE - image.size[1]) / 2))
image,
(int((THUMBNAIL_SIZE - image.size[0]) / 2), int((THUMBNAIL_SIZE - image.size[1]) / 2)))
# Stamp with PDF file type # Stamp with PDF file type
timage.paste( timage.paste(
pdf_indicator, pdf_indicator,
(timage.size[0]-30, timage.size[1]-30),
(timage.size[0] - 30, timage.size[1] - 30),
pdf_indicator, pdf_indicator,
)
timage.convert('RGB').save( TargetFileName+".jpg", 'JPEG')
os.unlink(TargetFileName+"_.jpg")
return self.thumbnailurl( os.path.basename(TargetFileName+".jpg") )
)
timage.convert('RGB').save(TargetFileName + ".jpg", 'JPEG')
os.unlink(TargetFileName + "_.jpg")
return self.thumbnailurl(os.path.basename(TargetFileName + ".jpg"))
return self.ExtMimeIcon('application/pdf') return self.ExtMimeIcon('application/pdf')


def svgthumbnail(self, filename): def svgthumbnail(self, filename):
TargetFileName = self.thumbnailpath(filename) TargetFileName = self.thumbnailpath(filename)
Command = ["convert","./%s[0]" % self.mediapath(filename),"./%s_.jpg" % TargetFileName]
Command = ["convert", "./%s[0]" % self.mediapath(filename), "./%s_.jpg" % TargetFileName]
Result = subprocess.call(Command) Result = subprocess.call(Command)
if Result==0:
image = Image.open( TargetFileName+"_.jpg" )
pdf_indicator = Image.open( "jm2l/static/img/svg-icon.png" )
if Result == 0:
image = Image.open(TargetFileName + "_.jpg")
pdf_indicator = Image.open("jm2l/static/img/svg-icon.png")
image.thumbnail((THUMBNAIL_SIZE, THUMBNAIL_SIZE), Image.ANTIALIAS) image.thumbnail((THUMBNAIL_SIZE, THUMBNAIL_SIZE), Image.ANTIALIAS)
timage = Image.new('RGBA', (THUMBNAIL_SIZE, THUMBNAIL_SIZE), (255, 255, 255, 0)) timage = Image.new('RGBA', (THUMBNAIL_SIZE, THUMBNAIL_SIZE), (255, 255, 255, 0))
# Add thumbnail # Add thumbnail
timage.paste( timage.paste(
image,
((THUMBNAIL_SIZE - image.size[0]) / 2, (THUMBNAIL_SIZE - image.size[1]) / 2))
image,
(int((THUMBNAIL_SIZE - image.size[0]) / 2), int((THUMBNAIL_SIZE - image.size[1]) / 2)))
# Stamp with PDF file type # Stamp with PDF file type
timage.paste( timage.paste(
pdf_indicator, pdf_indicator,
(timage.size[0]-30, timage.size[1]-30),
(timage.size[0] - 30, timage.size[1] - 30),
pdf_indicator, pdf_indicator,
)
timage.convert('RGB').save( TargetFileName+".jpg", 'JPEG')
os.unlink(TargetFileName+"_.jpg")
return self.thumbnailurl( os.path.basename(TargetFileName+".jpg") )
)
timage.convert('RGB').save(TargetFileName + ".jpg", 'JPEG')
os.unlink(TargetFileName + "_.jpg")
return self.thumbnailurl(os.path.basename(TargetFileName + ".jpg"))
return self.ExtMimeIcon('image/svg+xml') return self.ExtMimeIcon('image/svg+xml')


def docthumbnail(self, filename): def docthumbnail(self, filename):
@@ -370,29 +374,30 @@ class MediaUpload(MediaPath):
# let's take the thumbnail generated inside the document # let's take the thumbnail generated inside the document
Command = ["unzip", "-p", self.mediapath(filename), "Thumbnails/thumbnail.png"] Command = ["unzip", "-p", self.mediapath(filename), "Thumbnails/thumbnail.png"]
ThumbBytes = subprocess.check_output(Command) ThumbBytes = subprocess.check_output(Command)
image = Image.open( StringIO.StringIO(ThumbBytes) )
image = Image.open(StringIO.StringIO(ThumbBytes))
image.thumbnail((THUMBNAIL_SIZE, THUMBNAIL_SIZE), Image.ANTIALIAS) image.thumbnail((THUMBNAIL_SIZE, THUMBNAIL_SIZE), Image.ANTIALIAS)
# Use the correct stamp # Use the correct stamp
f, ext = os.path.splitext( filename )
istamp = [ ('Writer','odt'),
('Impress','odp'),
('Calc','ods'),
('Draw','odg')]
stampfilename = filter(lambda (x,y): ext.endswith(y), istamp)
stamp = Image.open( "jm2l/static/img/%s-icon.png" % stampfilename[0][0])
f, ext = os.path.splitext(filename)
istamp = [('Writer', 'odt'),
('Impress', 'odp'),
('Calc', 'ods'),
('Draw', 'odg')]
stampfilename = filter(lambda x, y: ext.endswith(y), istamp)
stamp = Image.open("jm2l/static/img/%s-icon.png" % stampfilename[0][0])

timage = Image.new('RGBA', (THUMBNAIL_SIZE, THUMBNAIL_SIZE), (255, 255, 255, 0)) timage = Image.new('RGBA', (THUMBNAIL_SIZE, THUMBNAIL_SIZE), (255, 255, 255, 0))
# Add thumbnail # Add thumbnail
timage.paste( timage.paste(
image,
((THUMBNAIL_SIZE - image.size[0]) / 2, (THUMBNAIL_SIZE - image.size[1]) / 2))
image,
(int((THUMBNAIL_SIZE - image.size[0]) / 2), int((THUMBNAIL_SIZE - image.size[1]) / 2)))
# Stamp with PDF file type # Stamp with PDF file type
timage.paste( timage.paste(
stamp, stamp,
(timage.size[0]-30, timage.size[1]-30),
(timage.size[0] - 30, timage.size[1] - 30),
stamp, stamp,
)
timage.convert('RGB').save( TargetFileName+".jpg", 'JPEG')
return self.thumbnailurl( os.path.basename(TargetFileName+".jpg") )
)
timage.convert('RGB').save(TargetFileName + ".jpg", 'JPEG')
return self.thumbnailurl(os.path.basename(TargetFileName + ".jpg"))


def blendthumbnail(self, filename): def blendthumbnail(self, filename):
blendfile = self.mediapath(filename) blendfile = self.mediapath(filename)
@@ -400,45 +405,45 @@ class MediaUpload(MediaPath):
if 0: if 0:
head = fileobj.read(12) head = fileobj.read(12)
fileobj.seek(0) fileobj.seek(0)
if head[:2] == b'\x1f\x8b': # gzip magic if head[:2] == b'\x1f\x8b': # gzip magic
import zlib import zlib
head = zlib.decompress(fileobj.read(), 31)[:12] head = zlib.decompress(fileobj.read(), 31)[:12]
fileobj.seek(0)
fileobj.seek(0)
buf, width, height = blend_extract_thumb(blendfile) buf, width, height = blend_extract_thumb(blendfile)
if buf: if buf:
png = write_png(buf, width, height) png = write_png(buf, width, height)
TargetFileName = self.thumbnailpath(filename) TargetFileName = self.thumbnailpath(filename)
image = Image.open(StringIO.StringIO(png)) image = Image.open(StringIO.StringIO(png))
blender_indicator = Image.open( "jm2l/static/img/Blender_Thumb_Stamp.png" )
blender_indicator = Image.open("jm2l/static/img/Blender_Thumb_Stamp.png")
image.thumbnail((THUMBNAIL_SIZE, THUMBNAIL_SIZE), Image.ANTIALIAS) image.thumbnail((THUMBNAIL_SIZE, THUMBNAIL_SIZE), Image.ANTIALIAS)
timage = Image.new('RGBA', (THUMBNAIL_SIZE, THUMBNAIL_SIZE), (255, 255, 255, 0)) timage = Image.new('RGBA', (THUMBNAIL_SIZE, THUMBNAIL_SIZE), (255, 255, 255, 0))
# Add thumbnail # Add thumbnail
timage.paste( timage.paste(
image, image,
((THUMBNAIL_SIZE - image.size[0]) / 2, (THUMBNAIL_SIZE - image.size[1]) / 2))
(int((THUMBNAIL_SIZE - image.size[0]) / 2), int((THUMBNAIL_SIZE - image.size[1]) / 2)))
# Stamp with Blender file type # Stamp with Blender file type
timage.paste( timage.paste(
blender_indicator, blender_indicator,
(timage.size[0]-30, timage.size[1]-30),
(timage.size[0] - 30, timage.size[1] - 30),
blender_indicator, blender_indicator,
)
timage.save( TargetFileName+".png")
return self.thumbnailurl( os.path.basename(TargetFileName+".png") )
)
timage.save(TargetFileName + ".png")
return self.thumbnailurl(os.path.basename(TargetFileName + ".png"))
return self.ExtMimeIcon('application/x-blender') return self.ExtMimeIcon('application/x-blender')


def fileinfo(self,name):
filename = self.mediapath(name)
def fileinfo(self, name):
filename = self.mediapath(name)
f, ext = os.path.splitext(name) f, ext = os.path.splitext(name)
if ext!='.type' and os.path.isfile(filename):
if ext != '.type' and os.path.isfile(filename):
info = {} info = {}
info['name'] = name info['name'] = name
info['size'] = os.path.getsize(filename) info['size'] = os.path.getsize(filename)
info['url'] = self.request.route_url('media_view', info['url'] = self.request.route_url('media_view',
name=name,
media_table=self.media_table,
uid=self.linked_id)
name=name,
media_table=self.media_table,
uid=self.linked_id)


mime = self.get_mimetype(name) mime = self.get_mimetype(name)
if IMAGE_TYPES.match(mime): if IMAGE_TYPES.match(mime):
@@ -448,8 +453,8 @@ class MediaUpload(MediaPath):
thumbext = ".jpg" thumbext = ".jpg"
if mime == "application/x-blender": if mime == "application/x-blender":
thumbext = ".png" thumbext = ".png"
if os.path.exists( thumb + thumbext ):
info['thumbnailUrl'] = self.thumbnailurl(name)+thumbext
if os.path.exists(thumb + thumbext):
info['thumbnailUrl'] = self.thumbnailurl(name) + thumbext
else: else:
info['thumbnailUrl'] = self.ExtMimeIcon(mime) info['thumbnailUrl'] = self.ExtMimeIcon(mime)
else: else:
@@ -457,10 +462,10 @@ class MediaUpload(MediaPath):
if not self.display_only: if not self.display_only:
info['deleteType'] = DELETEMETHOD info['deleteType'] = DELETEMETHOD
info['deleteUrl'] = self.request.route_url('media_upload', info['deleteUrl'] = self.request.route_url('media_upload',
sep='',
name='',
media_table=self.media_table,
uid=self.linked_id) + '/' + name
sep='',
name='',
media_table=self.media_table,
uid=self.linked_id) + '/' + name
if DELETEMETHOD != 'DELETE': if DELETEMETHOD != 'DELETE':
info['deleteUrl'] += '&_method=DELETE' info['deleteUrl'] += '&_method=DELETE'
return info return info
@@ -488,7 +493,7 @@ class MediaUpload(MediaPath):
n = self.fileinfo(f) n = self.fileinfo(f)
if n: if n:
filelist.append(n) filelist.append(n)
return { "files":filelist }
return {"files": filelist}


@view_config(request_method='DELETE', xhr=True, accept="application/json", renderer='json') @view_config(request_method='DELETE', xhr=True, accept="application/json", renderer='json')
def delete(self): def delete(self):
@@ -498,96 +503,97 @@ class MediaUpload(MediaPath):
except IOError: except IOError:
pass pass
except OSError: except OSError:
pass
pass
try: try:
os.remove(self.thumbnailpath(filename)) os.remove(self.thumbnailpath(filename))
except IOError: except IOError:
pass pass
except OSError:
except OSError:
pass pass
try: try:
os.remove(self.thumbnailpath(filename+".jpg"))
os.remove(self.thumbnailpath(filename + ".jpg"))
except IOError: except IOError:
pass pass
except OSError:
pass
except OSError:
pass
try: try:
os.remove(self.mediapath(filename)) os.remove(self.mediapath(filename))
except IOError: except IOError:
return False return False
return True return True
@view_config(request_method='POST', xhr=True, accept="application/json", renderer='json') @view_config(request_method='POST', xhr=True, accept="application/json", renderer='json')
def post(self): def post(self):
if self.request.matchdict.get('_method') == "DELETE": if self.request.matchdict.get('_method') == "DELETE":
return self.delete() return self.delete()
results = [] results = []
for name, fieldStorage in self.request.POST.items(): for name, fieldStorage in self.request.POST.items():
if isinstance(fieldStorage,unicode):
continue
# if isinstance(fieldStorage, unicode):
# continue
result = {} result = {}
result['name'] = os.path.basename(fieldStorage.filename) result['name'] = os.path.basename(fieldStorage.filename)
result['type'] = fieldStorage.type result['type'] = fieldStorage.type
result['size'] = self.get_file_size(fieldStorage.file) result['size'] = self.get_file_size(fieldStorage.file)


if self.validate(result, fieldStorage.file): if self.validate(result, fieldStorage.file):
filename, file_extension = os.path.splitext( result['name'] )
local_filename = slugify( filename ) + file_extension
filename, file_extension = os.path.splitext(result['name'])
local_filename = slugify(filename) + file_extension
# Keep mime-type in .type file # Keep mime-type in .type file
with open( self.mediapath( local_filename ) + '.type', 'w') as f:
with open(self.mediapath(local_filename) + '.type', 'w') as f:
f.write(result['type']) f.write(result['type'])
# Store uploaded file # Store uploaded file
fieldStorage.file.seek(0) fieldStorage.file.seek(0)
with open( self.mediapath( local_filename ), 'wb') as f:
shutil.copyfileobj( fieldStorage.file , f)
with open(self.mediapath(local_filename), 'wb') as f:
shutil.copyfileobj(fieldStorage.file, f)


if re.match(IMAGE_TYPES, result['type']): if re.match(IMAGE_TYPES, result['type']):
result['thumbnailUrl'] = self.createthumbnail(local_filename) result['thumbnailUrl'] = self.createthumbnail(local_filename)
elif result['type']=='application/pdf':
elif result['type'] == 'application/pdf':
result['thumbnailUrl'] = self.pdfthumbnail(local_filename) result['thumbnailUrl'] = self.pdfthumbnail(local_filename)
elif result['type']=='image/svg+xml':
elif result['type'] == 'image/svg+xml':
result['thumbnailUrl'] = self.svgthumbnail(local_filename) result['thumbnailUrl'] = self.svgthumbnail(local_filename)
elif result['type'].startswith('application/vnd'): elif result['type'].startswith('application/vnd'):
result['thumbnailUrl'] = self.docthumbnail(local_filename) result['thumbnailUrl'] = self.docthumbnail(local_filename)
elif result['type']=='application/x-blender':
elif result['type'] == 'application/x-blender':
result['thumbnailUrl'] = self.blendthumbnail(local_filename) result['thumbnailUrl'] = self.blendthumbnail(local_filename)
else: else:
result['thumbnailUrl'] = self.ExtMimeIcon(result['type']) result['thumbnailUrl'] = self.ExtMimeIcon(result['type'])


result['deleteType'] = DELETEMETHOD result['deleteType'] = DELETEMETHOD
result['deleteUrl'] = self.request.route_url('media_upload', result['deleteUrl'] = self.request.route_url('media_upload',
sep='',
name='',
media_table=self.media_table,
uid=self.linked_id) + '/' + local_filename
sep='',
name='',
media_table=self.media_table,
uid=self.linked_id) + '/' + local_filename
result['url'] = self.request.route_url('media_view', result['url'] = self.request.route_url('media_view',
media_table=self.media_table,
uid=self.linked_id,
name=local_filename)
media_table=self.media_table,
uid=self.linked_id,
name=local_filename)
if DELETEMETHOD != 'DELETE': if DELETEMETHOD != 'DELETE':
result['deleteUrl'] += '&_method=DELETE' result['deleteUrl'] += '&_method=DELETE'
results.append(result) results.append(result)
return {"files":results}
return {"files": results}



@view_defaults(route_name='media_view') @view_defaults(route_name='media_view')
class MediaView(MediaPath): class MediaView(MediaPath):


def __init__(self,request):
def __init__(self, request):
self.request = request self.request = request
self.media_table = self.request.matchdict.get('media_table') self.media_table = self.request.matchdict.get('media_table')
self.linked_id = self.request.matchdict.get('uid') self.linked_id = self.request.matchdict.get('uid')


def mediapath(self,name):
def mediapath(self, name):
return self.get_mediapath(self.media_table, self.linked_id, name) return self.get_mediapath(self.media_table, self.linked_id, name)
@view_config(request_method='GET', http_cache = (EXPIRATION_TIME, {'public':True}))
@view_config(request_method='GET', http_cache=(EXPIRATION_TIME, {'public': True}))
def get(self): def get(self):
name = self.request.matchdict.get('name') name = self.request.matchdict.get('name')
self.request.response.content_type = self.get_mimetype(name) self.request.response.content_type = self.get_mimetype(name)


try: try:
self.request.response.body_file = open( self.mediapath(name), 'rb', 10000)
self.request.response.body_file = open(self.mediapath(name), 'rb', 10000)
except IOError: except IOError:
raise NotFound raise NotFound
return self.request.response return self.request.response


+ 862
- 781
jm2l/views.py
File diff suppressed because it is too large
View File


+ 8
- 3
setup.py View File

@@ -11,6 +11,7 @@ with open(os.path.join(here, 'CHANGES.txt')) as f:
## Do not forget to run for lxml dependencies ## Do not forget to run for lxml dependencies
## apt-get install libxml2-dev libxslt1-dev ## apt-get install libxml2-dev libxslt1-dev



requires = [ requires = [
'pyramid', 'pyramid',
'pyramid_chameleon', 'pyramid_chameleon',
@@ -28,15 +29,19 @@ requires = [
'python-magic', 'python-magic',
'Pillow', 'Pillow',
'pyramid_exclog', 'pyramid_exclog',
'repoze.sendmail==4.1',
'repoze.sendmail',
'pyramid_mailer', 'pyramid_mailer',
'apscheduler', 'apscheduler',
'qrcode', 'qrcode',
'reportlab', 'reportlab',
'passlib', 'passlib',
'argon2_cffi'
'argon2_cffi',
'paginate',
'markupsafe',
'webhelpers2',
'email_validator',
'pyramid-scheduler'
] ]

setup(name='JM2L', setup(name='JM2L',
version='0.1', version='0.1',
description='JM2L', description='JM2L',


+ 6
- 9
wsgi.py View File

@@ -1,9 +1,6 @@
APP_CONFIG = "prod.ini"

#Setup logging
import logging.config
logging.config.fileConfig(APP_CONFIG)

#Load the application
from paste.deploy import loadapp
application = loadapp('config:%s' % APP_CONFIG)
import sys
sys.path.append("/srv/.venv_jm2l/lib/python3.7/site-packages")
ini_path = "/srv/jm2l.linux-azur.org/jm2l/production.ini"
from pyramid.paster import get_app, setup_logging
setup_logging(ini_path)
application = get_app(ini_path, 'main')

Loading…
Cancel
Save