浏览代码

Merge branch 'dev'

Denis K 9 年之前
父节点
当前提交
6e0d2e77dd
共有 55 个文件被更改,包括 3802 次插入252 次删除
  1. 10 0
      CHANGELOG.rst
  2. 46 0
      README.rst
  3. 2 2
      docs/config_file.rst
  4. 1 0
      docs/getting_started.rst
  5. 1 4
      docs/index.rst
  6. 5 0
      docs/install.rst
  7. 45 0
      docs/install_dashboard.rst
  8. 1 1
      jet/__init__.py
  9. 0 8
      jet/dashboard/dashboard.py
  10. 2 2
      jet/dashboard/dashboard_modules/google_analytics.py
  11. 2 2
      jet/dashboard/dashboard_modules/yandex_metrika.py
  12. 28 0
      jet/dashboard/forms.py
  13. 8 0
      jet/dashboard/templates/jet.dashboard/dashboard_tools.html
  14. 6 2
      jet/dashboard/templatetags/jet_dashboard_tags.py
  15. 1 1
      jet/dashboard/urls.py
  16. 11 8
      jet/dashboard/views.py
  17. 二进制
      jet/locale/en/LC_MESSAGES/django.mo
  18. 60 51
      jet/locale/en/LC_MESSAGES/django.po
  19. 二进制
      jet/locale/en/LC_MESSAGES/djangojs.mo
  20. 16 9
      jet/locale/en/LC_MESSAGES/djangojs.po
  21. 二进制
      jet/locale/ru/LC_MESSAGES/django.mo
  22. 60 51
      jet/locale/ru/LC_MESSAGES/django.po
  23. 二进制
      jet/locale/ru/LC_MESSAGES/djangojs.mo
  24. 16 9
      jet/locale/ru/LC_MESSAGES/djangojs.po
  25. 2 0
      jet/static/jet/css/_changelist.scss
  26. 21 1
      jet/static/jet/css/_content.scss
  27. 6 0
      jet/static/jet/css/_forms.scss
  28. 26 2
      jet/static/jet/css/_sidebar.scss
  29. 0 20
      jet/static/jet/css/_table.scss
  30. 1 0
      jet/static/jet/css/icons/_variables.scss
  31. 二进制
      jet/static/jet/css/icons/fonts/jet-icons.eot
  32. 1 0
      jet/static/jet/css/icons/fonts/jet-icons.svg
  33. 二进制
      jet/static/jet/css/icons/fonts/jet-icons.ttf
  34. 二进制
      jet/static/jet/css/icons/fonts/jet-icons.woff
  35. 8 5
      jet/static/jet/css/icons/style.css
  36. 50 26
      jet/static/jet/css/themes/default/base.css
  37. 0 0
      jet/static/jet/css/themes/default/base.css.map
  38. 0 0
      jet/static/jet/css/themes/default/jquery-ui.theme.css.map
  39. 0 0
      jet/static/jet/css/themes/default/select2.theme.css.map
  40. 50 26
      jet/static/jet/css/themes/green/base.css
  41. 0 0
      jet/static/jet/css/themes/green/base.css.map
  42. 0 0
      jet/static/jet/css/themes/green/jquery-ui.theme.css.map
  43. 0 0
      jet/static/jet/css/themes/green/select2.theme.css.map
  44. 43 0
      jet/static/jet/js/main.js
  45. 0 0
      jet/static/jet/js/main.min.js
  46. 108 0
      jet/static/jet/vendor/perfect-scrollbar/css/perfect-scrollbar.css
  47. 7 0
      jet/static/jet/vendor/perfect-scrollbar/css/perfect-scrollbar.css.map
  48. 149 0
      jet/static/jet/vendor/perfect-scrollbar/css/perfect-scrollbar.scss
  49. 1492 0
      jet/static/jet/vendor/perfect-scrollbar/js/perfect-scrollbar.jquery.js
  50. 1 0
      jet/static/jet/vendor/perfect-scrollbar/js/perfect-scrollbar.jquery.min.js
  51. 1463 0
      jet/static/jet/vendor/perfect-scrollbar/js/perfect-scrollbar.js
  52. 1 0
      jet/static/jet/vendor/perfect-scrollbar/js/perfect-scrollbar.min.js
  53. 34 20
      jet/templates/admin/base.html
  54. 2 2
      jet/templates/admin/search_form.html
  55. 16 0
      jet/tests/test_views.py

+ 10 - 0
CHANGELOG.rst

@@ -1,6 +1,16 @@
 Changelog
 Changelog
 =========
 =========
 
 
+0.0.9
+-----
+* [Feature] Replace sidemenu scrollbars with Mac-like ones
+* [Feature] Added dashboard reset button
+* [Feature] Updated sidebar links ui
+* [Fix] Fixed filter submit block text alignment
+* [Fix] Made boolean field icon style global
+* [Fix] Fixed metrics requests timezone to be TIME_ZONE from settings
+
+
 0.0.8
 0.0.8
 -----
 -----
 * Change license to GPLv2
 * Change license to GPLv2

+ 46 - 0
README.rst

@@ -111,3 +111,49 @@ Installation
         
         
 * Clear your browser cache
 * Clear your browser cache
 
 
+Dashboard installation
+======================
+
+.. note:: Dashboard is located into a separate application. So after a typical JET installation it won't be active.
+          To enable dashboard application follow these steps:
+
+* Add 'jet.dashboard' application to the INSTALLED_APPS setting of your Django project settings.py file (note it should be before 'jet'):
+
+.. code:: python
+
+    INSTALLED_APPS = (
+        ...
+        'jet.dashboard',
+        'jet',
+        'django.contrib.admin',
+        ...
+    )
+
+* Add URL-pattern to the urlpatterns of your Django project urls.py file (they are needed for related–lookups and autocompletes):
+
+.. code:: python
+
+    urlpatterns = patterns(
+        '',
+        url(r'^jet/', include('jet.urls', 'jet')),  # Django JET URLS
+        url(r'^jet/dashboard/', include('jet.dashboard.urls', 'jet-dashboard')),  # Django JET dashboard URLS
+        url(r'^admin/', include(admin.site.urls)),
+        ...
+    )
+
+* Create database tables:
+
+.. code:: python
+
+    python manage.py migrate dashboard
+    # or
+    python manage.py syncdb
+
+* Collect static if you are in production environment:
+
+.. code:: python
+
+        python manage.py collectstatic
+
+
+

+ 2 - 2
docs/config_file.rst

@@ -34,8 +34,8 @@ to start using your own theme.
 JET_INDEX_DASHBOARD
 JET_INDEX_DASHBOARD
 -------------------
 -------------------
 
 
-Sets which dashboard class will be used for rending admin index dashboard. Allows you to create
-your own dashboard with custom modules with pre-installed layout.
+Sets which dashboard class will be used for rendering admin index dashboard. Allows you to create
+your own dashboard with custom modules and pre-installed layout.
 
 
 .. code:: python
 .. code:: python
 
 

+ 1 - 0
docs/getting_started.rst

@@ -8,3 +8,4 @@ Contents:
    :maxdepth: 2
    :maxdepth: 2
 
 
    install
    install
+   install_dashboard

+ 1 - 4
docs/index.rst

@@ -83,8 +83,5 @@ Changeform + sidemenu
 License
 License
 =======
 =======
 Django JET is licensed under a
 Django JET is licensed under a
-Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Public License
-
-See online version of this license here:
-https://creativecommons.org/licenses/by-nc-sa/4.0/
+The GNU General Public License, Version 2
 
 

+ 5 - 0
docs/install.rst

@@ -2,6 +2,10 @@
 Installation
 Installation
 ============
 ============
 
 
+.. note:: After following this instruction Django JET dashboard won't be active (as it is located into
+          a separate application). If you want to make it work, you will have to enable dashboard application
+          by following :doc:`install_dashboard` steps too.
+
 * Download and install latest version of Django JET:
 * Download and install latest version of Django JET:
 
 
 .. code:: python
 .. code:: python
@@ -18,6 +22,7 @@ Installation
         ...
         ...
         'jet',
         'jet',
         'django.contrib.admin',
         'django.contrib.admin',
+        ...
     )
     )
 
 
 * Make sure 'django.core.context_processors.request' context processor is enabled in settings.py:
 * Make sure 'django.core.context_processors.request' context processor is enabled in settings.py:

+ 45 - 0
docs/install_dashboard.rst

@@ -0,0 +1,45 @@
+======================
+Dashboard installation
+======================
+
+.. note:: Dashboard is located into a separate application. So after a typical JET installation it won't be active.
+          To enable dashboard application follow these steps:
+
+* Add 'jet.dashboard' application to the INSTALLED_APPS setting of your Django project settings.py file (note it should be before 'jet'):
+
+.. code:: python
+
+    INSTALLED_APPS = (
+        ...
+        'jet.dashboard',
+        'jet',
+        'django.contrib.admin',
+        ...
+    )
+
+* Add URL-pattern to the urlpatterns of your Django project urls.py file (they are needed for related–lookups and autocompletes):
+
+.. code:: python
+
+    urlpatterns = patterns(
+        '',
+        url(r'^jet/', include('jet.urls', 'jet')),  # Django JET URLS
+        url(r'^jet/dashboard/', include('jet.dashboard.urls', 'jet-dashboard')),  # Django JET dashboard URLS
+        url(r'^admin/', include(admin.site.urls)),
+        ...
+    )
+
+* Create database tables:
+
+.. code:: python
+
+    python manage.py migrate dashboard
+    # or
+    python manage.py syncdb
+
+* Collect static if you are in production environment:
+
+.. code:: python
+
+        python manage.py collectstatic
+

+ 1 - 1
jet/__init__.py

@@ -1 +1 @@
-VERSION = '0.0.8'
+VERSION = '0.0.9'

+ 0 - 8
jet/dashboard/dashboard.py

@@ -31,7 +31,6 @@ class Dashboard(object):
 
 
     def set_context(self, context):
     def set_context(self, context):
         self.context = context
         self.context = context
-        self.update_app_label()
         self.init_with_context(context)
         self.init_with_context(context)
         self.load_modules()
         self.load_modules()
 
 
@@ -45,9 +44,6 @@ class Dashboard(object):
 
 
         return module
         return module
 
 
-    def update_app_label(self):
-        pass
-
     def create_initial_module_models(self, user):
     def create_initial_module_models(self, user):
         module_models = []
         module_models = []
 
 
@@ -135,10 +131,6 @@ class Dashboard(object):
 
 
 
 
 class AppIndexDashboard(Dashboard):
 class AppIndexDashboard(Dashboard):
-    def update_app_label(self):
-        resolver = resolve(self.context['request'].path)
-        self.app_label = resolver.kwargs.get('app_label')
-
     def get_app_content_types(self):
     def get_app_content_types(self):
         return self.app_label + '.*',
         return self.app_label + '.*',
 
 

+ 2 - 2
jet/dashboard/dashboard_modules/google_analytics.py

@@ -282,8 +282,8 @@ class GoogleAnalyticsBase(DashboardModule):
 
 
     def api_ga(self, group=None):
     def api_ga(self, group=None):
         if self.counter_attached():
         if self.counter_attached():
-            date1 = datetime.datetime.utcnow() - datetime.timedelta(days=self.period)
-            date2 = datetime.datetime.utcnow()
+            date1 = datetime.datetime.now() - datetime.timedelta(days=self.period)
+            date2 = datetime.datetime.now()
 
 
             try:
             try:
                 client = GoogleAnalyticsClient(self.storage)
                 client = GoogleAnalyticsClient(self.storage)

+ 2 - 2
jet/dashboard/dashboard_modules/yandex_metrika.py

@@ -224,8 +224,8 @@ class YandexMetrikaBase(DashboardModule):
 
 
     def api_stat_traffic_summary(self, group=None):
     def api_stat_traffic_summary(self, group=None):
         if self.counter_attached():
         if self.counter_attached():
-            date1 = datetime.datetime.utcnow() - datetime.timedelta(days=self.period)
-            date2 = datetime.datetime.utcnow()
+            date1 = datetime.datetime.now() - datetime.timedelta(days=self.period)
+            date2 = datetime.datetime.now()
 
 
             client = YandexMetrikaClient(self.access_token)
             client = YandexMetrikaClient(self.access_token)
             result, exception = client.api_stat_traffic_summary(self.counter, date1, date2, group)
             result, exception = client.api_stat_traffic_summary(self.counter, date1, date2, group)

+ 28 - 0
jet/dashboard/forms.py

@@ -130,3 +130,31 @@ class RemoveDashboardModuleForm(forms.ModelForm):
     def save(self, commit=True):
     def save(self, commit=True):
         if commit:
         if commit:
             self.instance.delete()
             self.instance.delete()
+
+
+class ResetDashboardForm(forms.Form):
+    app_label = forms.CharField(required=False)
+
+    def __init__(self, request, *args, **kwargs):
+        self.request = request
+        super(ResetDashboardForm, self).__init__(*args, **kwargs)
+
+    class Meta:
+        model = UserDashboardModule
+        fields = []
+
+    def clean(self):
+        data = super(ResetDashboardForm, self).clean()
+        data['app_label'] = data['app_label'] if data['app_label'] else None
+
+        if not self.request.user.is_authenticated():
+            raise ValidationError('error')
+
+        return data
+
+    def save(self, commit=True):
+        if commit:
+            UserDashboardModule.objects.filter(
+                user=self.request.user.pk,
+                app_label=self.cleaned_data['app_label']
+            ).delete()

+ 8 - 0
jet/dashboard/templates/jet.dashboard/dashboard_tools.html

@@ -18,6 +18,14 @@
         </select><a href="#" class="button button-secondary add-dashboard-link" title="{% trans "Add" %}"><span class="icon-add"></span></a>
         </select><a href="#" class="button button-secondary add-dashboard-link" title="{% trans "Add" %}"><span class="icon-add"></span></a>
         <input type="hidden" name="app_label" value="{% if app_label %}{{ app_label }}{% endif %}">
         <input type="hidden" name="app_label" value="{% if app_label %}{{ app_label }}{% endif %}">
         <input type="hidden" name="type" value="">
         <input type="hidden" name="type" value="">
+        <a href="#" class="button button-transparent reset-dashboard-link" title="{% trans "Reset widgets" %}"><span class="icon-reset"></span></a>
     </form>
     </form>
+    <form action="{% url "jet-dashboard:reset_dashboard" %}" method="POST" id="reset-dashboard-form">
+        {% csrf_token %}
+        <input type="hidden" name="app_label" value="{% if app_label %}{{ app_label }}{% endif %}">
+    </form>
+    <div class="dialog-confirm" id="reset-dashboard-dialog" title="{% trans "Reset widgets" %}">
+        <p>{% trans "Are you sure want to reset widgets?" %}</p>
+    </div>
 </div>
 </div>
 
 

+ 6 - 2
jet/dashboard/templatetags/jet_dashboard_tags.py

@@ -1,5 +1,6 @@
 from __future__ import unicode_literals
 from __future__ import unicode_literals
 from django import template
 from django import template
+from django.core.urlresolvers import resolve
 from jet.dashboard.utils import get_current_dashboard
 from jet.dashboard.utils import get_current_dashboard
 
 
 register = template.Library()
 register = template.Library()
@@ -8,5 +9,8 @@ register = template.Library()
 @register.assignment_tag(takes_context=True)
 @register.assignment_tag(takes_context=True)
 def get_dashboard(context, location):
 def get_dashboard(context, location):
     dashboard_cls = get_current_dashboard(location)
     dashboard_cls = get_current_dashboard(location)
-    dashboard = dashboard_cls(context)
-    return dashboard
+
+    resolver = resolve(context['request'].path)
+    app_label = resolver.kwargs.get('app_label')
+
+    return dashboard_cls(context, app_label=app_label)

+ 1 - 1
jet/dashboard/urls.py

@@ -38,7 +38,7 @@ urlpatterns = patterns(
         name='load_dashboard_module'
         name='load_dashboard_module'
     ),
     ),
     url(
     url(
-        r'^reset_dashboard/((?P<app_label>[^/]+)/)?$',
+        r'^reset_dashboard/$',
         reset_dashboard_view,
         reset_dashboard_view,
         name='reset_dashboard'
         name='reset_dashboard'
     ),
     ),

+ 11 - 8
jet/dashboard/views.py

@@ -1,10 +1,9 @@
 from django.contrib import messages
 from django.contrib import messages
 from django.core.urlresolvers import reverse
 from django.core.urlresolvers import reverse
 from django.forms.formsets import formset_factory
 from django.forms.formsets import formset_factory
-from django.shortcuts import redirect
 from django.views.decorators.http import require_POST, require_GET
 from django.views.decorators.http import require_POST, require_GET
 from jet.dashboard.forms import UpdateDashboardModulesForm, AddUserDashboardModuleForm, \
 from jet.dashboard.forms import UpdateDashboardModulesForm, AddUserDashboardModuleForm, \
-    UpdateDashboardModuleCollapseForm, RemoveDashboardModuleForm
+    UpdateDashboardModuleCollapseForm, RemoveDashboardModuleForm, ResetDashboardForm
 from jet.dashboard.models import UserDashboardModule
 from jet.dashboard.models import UserDashboardModule
 from jet.utils import JsonResponse, get_app_list, SuccessMessageMixin
 from jet.utils import JsonResponse, get_app_list, SuccessMessageMixin
 from django.views.generic import UpdateView
 from django.views.generic import UpdateView
@@ -214,10 +213,14 @@ def load_dashboard_module_view(request, pk):
     return JsonResponse(result)
     return JsonResponse(result)
 
 
 
 
-def reset_dashboard_view(request, app_label=None):
-    UserDashboardModule.objects.filter(user=request.user.pk, app_label=app_label).delete()
-    if app_label:
-        url = reverse('admin:app_list', kwargs={'app_label': app_label})
+@require_POST
+def reset_dashboard_view(request):
+    result = {'error': False}
+    form = ResetDashboardForm(request, request.POST)
+
+    if form.is_valid():
+        form.save()
     else:
     else:
-        url = reverse('admin:index')
-    return redirect(url)
+        result['error'] = True
+
+    return JsonResponse(result)

二进制
jet/locale/en/LC_MESSAGES/django.mo


+ 60 - 51
jet/locale/en/LC_MESSAGES/django.po

@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-09-07 13:42+0000\n"
+"POT-Creation-Date: 2015-09-11 12:45+0000\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -23,16 +23,16 @@ msgstr ""
 msgid "Return to site"
 msgid "Return to site"
 msgstr ""
 msgstr ""
 
 
-#: dashboard/dashboard.py:166 templates/admin/base.html:77
+#: dashboard/dashboard.py:166 templates/admin/base.html:80
 msgid "Change password"
 msgid "Change password"
 msgstr ""
 msgstr ""
 
 
-#: dashboard/dashboard.py:168 templates/admin/base.html:81
+#: dashboard/dashboard.py:168 templates/admin/base.html:84
 msgid "Log out"
 msgid "Log out"
 msgstr ""
 msgstr ""
 
 
 #: dashboard/dashboard.py:176 dashboard/modules.py:160
 #: dashboard/dashboard.py:176 dashboard/modules.py:160
-#: templates/admin/base.html:157 templates/admin/index.html:14
+#: templates/admin/base.html:160 templates/admin/index.html:14
 msgid "Applications"
 msgid "Applications"
 msgstr ""
 msgstr ""
 
 
@@ -80,62 +80,62 @@ msgid "Grant access"
 msgstr ""
 msgstr ""
 
 
 #: dashboard/dashboard_modules/google_analytics.py:161
 #: dashboard/dashboard_modules/google_analytics.py:161
-#: dashboard/dashboard_modules/yandex_metrika.py:113
+#: dashboard/dashboard_modules/yandex_metrika.py:116
 msgid "Access"
 msgid "Access"
 msgstr ""
 msgstr ""
 
 
 #: dashboard/dashboard_modules/google_analytics.py:162
 #: dashboard/dashboard_modules/google_analytics.py:162
-#: dashboard/dashboard_modules/yandex_metrika.py:114
+#: dashboard/dashboard_modules/yandex_metrika.py:117
 msgid "Counter"
 msgid "Counter"
 msgstr ""
 msgstr ""
 
 
 #: dashboard/dashboard_modules/google_analytics.py:163
 #: dashboard/dashboard_modules/google_analytics.py:163
-#: dashboard/dashboard_modules/yandex_metrika.py:115
+#: dashboard/dashboard_modules/yandex_metrika.py:118
 msgid "Statistics period"
 msgid "Statistics period"
 msgstr ""
 msgstr ""
 
 
 #: dashboard/dashboard_modules/google_analytics.py:164
 #: dashboard/dashboard_modules/google_analytics.py:164
-#: dashboard/dashboard_modules/yandex_metrika.py:116
+#: dashboard/dashboard_modules/yandex_metrika.py:119
 msgid "Today"
 msgid "Today"
 msgstr ""
 msgstr ""
 
 
 #: dashboard/dashboard_modules/google_analytics.py:165
 #: dashboard/dashboard_modules/google_analytics.py:165
-#: dashboard/dashboard_modules/yandex_metrika.py:117
+#: dashboard/dashboard_modules/yandex_metrika.py:120
 msgid "Last week"
 msgid "Last week"
 msgstr ""
 msgstr ""
 
 
 #: dashboard/dashboard_modules/google_analytics.py:166
 #: dashboard/dashboard_modules/google_analytics.py:166
-#: dashboard/dashboard_modules/yandex_metrika.py:118
+#: dashboard/dashboard_modules/yandex_metrika.py:121
 msgid "Last month"
 msgid "Last month"
 msgstr ""
 msgstr ""
 
 
 #: dashboard/dashboard_modules/google_analytics.py:167
 #: dashboard/dashboard_modules/google_analytics.py:167
-#: dashboard/dashboard_modules/yandex_metrika.py:119
+#: dashboard/dashboard_modules/yandex_metrika.py:122
 msgid "Last quarter"
 msgid "Last quarter"
 msgstr ""
 msgstr ""
 
 
 #: dashboard/dashboard_modules/google_analytics.py:168
 #: dashboard/dashboard_modules/google_analytics.py:168
-#: dashboard/dashboard_modules/yandex_metrika.py:120
+#: dashboard/dashboard_modules/yandex_metrika.py:123
 msgid "Last year"
 msgid "Last year"
 msgstr ""
 msgstr ""
 
 
 #: dashboard/dashboard_modules/google_analytics.py:178
 #: dashboard/dashboard_modules/google_analytics.py:178
-#: dashboard/dashboard_modules/yandex_metrika.py:130
+#: dashboard/dashboard_modules/yandex_metrika.py:133
 msgid "none"
 msgid "none"
 msgstr ""
 msgstr ""
 
 
 #: dashboard/dashboard_modules/google_analytics.py:181
 #: dashboard/dashboard_modules/google_analytics.py:181
-#: dashboard/dashboard_modules/yandex_metrika.py:133
+#: dashboard/dashboard_modules/yandex_metrika.py:136
 msgid "grant access first"
 msgid "grant access first"
 msgstr ""
 msgstr ""
 
 
 #: dashboard/dashboard_modules/google_analytics.py:181
 #: dashboard/dashboard_modules/google_analytics.py:181
-#: dashboard/dashboard_modules/yandex_metrika.py:133
+#: dashboard/dashboard_modules/yandex_metrika.py:136
 msgid "counters loading failed"
 msgid "counters loading failed"
 msgstr ""
 msgstr ""
 
 
 #: dashboard/dashboard_modules/google_analytics.py:186
 #: dashboard/dashboard_modules/google_analytics.py:186
-#: dashboard/dashboard_modules/yandex_metrika.py:138
+#: dashboard/dashboard_modules/yandex_metrika.py:141
 msgid "Show"
 msgid "Show"
 msgstr ""
 msgstr ""
 
 
@@ -150,7 +150,7 @@ msgid "Sessions"
 msgstr ""
 msgstr ""
 
 
 #: dashboard/dashboard_modules/google_analytics.py:189
 #: dashboard/dashboard_modules/google_analytics.py:189
-#: dashboard/dashboard_modules/yandex_metrika.py:141
+#: dashboard/dashboard_modules/yandex_metrika.py:144
 #: dashboard/templates/jet.dashboard/modules/google_analytics_period_visitors.html:17
 #: dashboard/templates/jet.dashboard/modules/google_analytics_period_visitors.html:17
 #: dashboard/templates/jet.dashboard/modules/yandex_metrika_period_visitors.html:17
 #: dashboard/templates/jet.dashboard/modules/yandex_metrika_period_visitors.html:17
 msgid "Views"
 msgid "Views"
@@ -158,29 +158,29 @@ msgstr ""
 
 
 #: dashboard/dashboard_modules/google_analytics.py:191
 #: dashboard/dashboard_modules/google_analytics.py:191
 #: dashboard/dashboard_modules/google_analytics.py:199
 #: dashboard/dashboard_modules/google_analytics.py:199
-#: dashboard/dashboard_modules/yandex_metrika.py:143
-#: dashboard/dashboard_modules/yandex_metrika.py:151
+#: dashboard/dashboard_modules/yandex_metrika.py:146
+#: dashboard/dashboard_modules/yandex_metrika.py:154
 msgid "Group"
 msgid "Group"
 msgstr ""
 msgstr ""
 
 
 #: dashboard/dashboard_modules/google_analytics.py:192
 #: dashboard/dashboard_modules/google_analytics.py:192
 #: dashboard/dashboard_modules/google_analytics.py:200
 #: dashboard/dashboard_modules/google_analytics.py:200
-#: dashboard/dashboard_modules/yandex_metrika.py:144
-#: dashboard/dashboard_modules/yandex_metrika.py:152
+#: dashboard/dashboard_modules/yandex_metrika.py:147
+#: dashboard/dashboard_modules/yandex_metrika.py:155
 msgid "By day"
 msgid "By day"
 msgstr ""
 msgstr ""
 
 
 #: dashboard/dashboard_modules/google_analytics.py:193
 #: dashboard/dashboard_modules/google_analytics.py:193
 #: dashboard/dashboard_modules/google_analytics.py:201
 #: dashboard/dashboard_modules/google_analytics.py:201
-#: dashboard/dashboard_modules/yandex_metrika.py:145
-#: dashboard/dashboard_modules/yandex_metrika.py:153
+#: dashboard/dashboard_modules/yandex_metrika.py:148
+#: dashboard/dashboard_modules/yandex_metrika.py:156
 msgid "By week"
 msgid "By week"
 msgstr ""
 msgstr ""
 
 
 #: dashboard/dashboard_modules/google_analytics.py:194
 #: dashboard/dashboard_modules/google_analytics.py:194
 #: dashboard/dashboard_modules/google_analytics.py:202
 #: dashboard/dashboard_modules/google_analytics.py:202
-#: dashboard/dashboard_modules/yandex_metrika.py:146
-#: dashboard/dashboard_modules/yandex_metrika.py:154
+#: dashboard/dashboard_modules/yandex_metrika.py:149
+#: dashboard/dashboard_modules/yandex_metrika.py:157
 msgid "By month"
 msgid "By month"
 msgstr ""
 msgstr ""
 
 
@@ -200,13 +200,13 @@ msgstr ""
 
 
 #: dashboard/dashboard_modules/google_analytics.py:297
 #: dashboard/dashboard_modules/google_analytics.py:297
 #: dashboard/dashboard_modules/google_analytics_views.py:42
 #: dashboard/dashboard_modules/google_analytics_views.py:42
-#: dashboard/dashboard_modules/yandex_metrika.py:231
+#: dashboard/dashboard_modules/yandex_metrika.py:234
 #: dashboard/dashboard_modules/yandex_metrika_views.py:37
 #: dashboard/dashboard_modules/yandex_metrika_views.py:37
 msgid "API request failed."
 msgid "API request failed."
 msgstr ""
 msgstr ""
 
 
 #: dashboard/dashboard_modules/google_analytics.py:299
 #: dashboard/dashboard_modules/google_analytics.py:299
-#: dashboard/dashboard_modules/yandex_metrika.py:233
+#: dashboard/dashboard_modules/yandex_metrika.py:236
 #, python-format
 #, python-format
 msgid " Try to <a href=\"%s\">revoke and grant access</a> again"
 msgid " Try to <a href=\"%s\">revoke and grant access</a> again"
 msgstr ""
 msgstr ""
@@ -224,16 +224,16 @@ msgid "sessions"
 msgstr ""
 msgstr ""
 
 
 #: dashboard/dashboard_modules/google_analytics.py:318
 #: dashboard/dashboard_modules/google_analytics.py:318
-#: dashboard/dashboard_modules/yandex_metrika.py:254
+#: dashboard/dashboard_modules/yandex_metrika.py:257
 msgid "views"
 msgid "views"
 msgstr ""
 msgstr ""
 
 
 #: dashboard/dashboard_modules/google_analytics.py:320
 #: dashboard/dashboard_modules/google_analytics.py:320
 #: dashboard/dashboard_modules/google_analytics.py:365
 #: dashboard/dashboard_modules/google_analytics.py:365
 #: dashboard/dashboard_modules/google_analytics.py:404
 #: dashboard/dashboard_modules/google_analytics.py:404
-#: dashboard/dashboard_modules/yandex_metrika.py:256
-#: dashboard/dashboard_modules/yandex_metrika.py:295
-#: dashboard/dashboard_modules/yandex_metrika.py:328
+#: dashboard/dashboard_modules/yandex_metrika.py:259
+#: dashboard/dashboard_modules/yandex_metrika.py:298
+#: dashboard/dashboard_modules/yandex_metrika.py:331
 msgid "Bad server response"
 msgid "Bad server response"
 msgstr ""
 msgstr ""
 
 
@@ -257,51 +257,51 @@ msgstr ""
 msgid "Bad arguments"
 msgid "Bad arguments"
 msgstr ""
 msgstr ""
 
 
-#: dashboard/dashboard_modules/yandex_metrika.py:139
+#: dashboard/dashboard_modules/yandex_metrika.py:142
 #: dashboard/templates/jet.dashboard/modules/yandex_metrika_period_visitors.html:15
 #: dashboard/templates/jet.dashboard/modules/yandex_metrika_period_visitors.html:15
 msgid "Visitors"
 msgid "Visitors"
 msgstr ""
 msgstr ""
 
 
-#: dashboard/dashboard_modules/yandex_metrika.py:140
+#: dashboard/dashboard_modules/yandex_metrika.py:143
 #: dashboard/templates/jet.dashboard/modules/yandex_metrika_period_visitors.html:16
 #: dashboard/templates/jet.dashboard/modules/yandex_metrika_period_visitors.html:16
 msgid "Visits"
 msgid "Visits"
 msgstr ""
 msgstr ""
 
 
-#: dashboard/dashboard_modules/yandex_metrika.py:214
+#: dashboard/dashboard_modules/yandex_metrika.py:217
 #, python-format
 #, python-format
 msgid ""
 msgid ""
 "Please <a href=\"%s\">attach Yandex account and choose Yandex Metrika "
 "Please <a href=\"%s\">attach Yandex account and choose Yandex Metrika "
 "counter</a> to start using widget"
 "counter</a> to start using widget"
 msgstr ""
 msgstr ""
 
 
-#: dashboard/dashboard_modules/yandex_metrika.py:217
+#: dashboard/dashboard_modules/yandex_metrika.py:220
 #, python-format
 #, python-format
 msgid ""
 msgid ""
 "Please <a href=\"%s\">select Yandex Metrika counter</a> to start using widget"
 "Please <a href=\"%s\">select Yandex Metrika counter</a> to start using widget"
 msgstr ""
 msgstr ""
 
 
-#: dashboard/dashboard_modules/yandex_metrika.py:240
+#: dashboard/dashboard_modules/yandex_metrika.py:243
 msgid "Yandex Metrika visitors totals"
 msgid "Yandex Metrika visitors totals"
 msgstr ""
 msgstr ""
 
 
-#: dashboard/dashboard_modules/yandex_metrika.py:252
+#: dashboard/dashboard_modules/yandex_metrika.py:255
 msgid "visitors"
 msgid "visitors"
 msgstr ""
 msgstr ""
 
 
-#: dashboard/dashboard_modules/yandex_metrika.py:253
+#: dashboard/dashboard_modules/yandex_metrika.py:256
 msgid "visits"
 msgid "visits"
 msgstr ""
 msgstr ""
 
 
-#: dashboard/dashboard_modules/yandex_metrika.py:260
+#: dashboard/dashboard_modules/yandex_metrika.py:263
 msgid "Yandex Metrika visitors chart"
 msgid "Yandex Metrika visitors chart"
 msgstr ""
 msgstr ""
 
 
-#: dashboard/dashboard_modules/yandex_metrika.py:299
+#: dashboard/dashboard_modules/yandex_metrika.py:302
 msgid "Yandex Metrika period visitors"
 msgid "Yandex Metrika period visitors"
 msgstr ""
 msgstr ""
 
 
 #: dashboard/models.py:11 dashboard/modules.py:116
 #: dashboard/models.py:11 dashboard/modules.py:116
-#: templates/admin/base.html:189
+#: templates/admin/base.html:192
 msgid "Title"
 msgid "Title"
 msgstr ""
 msgstr ""
 
 
@@ -345,7 +345,7 @@ msgstr ""
 msgid "user dashboard modules"
 msgid "user dashboard modules"
 msgstr ""
 msgstr ""
 
 
-#: dashboard/modules.py:115 models.py:12 templates/admin/base.html:191
+#: dashboard/modules.py:115 models.py:12 templates/admin/base.html:194
 msgid "URL"
 msgid "URL"
 msgstr ""
 msgstr ""
 
 
@@ -399,7 +399,7 @@ msgstr ""
 
 
 #: dashboard/templates/admin/app_index.html:32
 #: dashboard/templates/admin/app_index.html:32
 #: dashboard/templates/jet.dashboard/update_module.html:14
 #: dashboard/templates/jet.dashboard/update_module.html:14
-#: templates/admin/base.html:92 templates/admin/base.html.py:141
+#: templates/admin/base.html:95 templates/admin/base.html.py:144
 #: templates/admin/change_form.html:17 templates/admin/change_list.html:33
 #: templates/admin/change_form.html:17 templates/admin/change_list.html:33
 #: templates/admin/delete_confirmation.html:8
 #: templates/admin/delete_confirmation.html:8
 #: templates/admin/delete_selected_confirmation.html:8
 #: templates/admin/delete_selected_confirmation.html:8
@@ -437,6 +437,15 @@ msgstr ""
 msgid "Add"
 msgid "Add"
 msgstr ""
 msgstr ""
 
 
+#: dashboard/templates/jet.dashboard/dashboard_tools.html:21
+#: dashboard/templates/jet.dashboard/dashboard_tools.html:27
+msgid "Reset widgets"
+msgstr ""
+
+#: dashboard/templates/jet.dashboard/dashboard_tools.html:28
+msgid "Are you sure want to reset widgets?"
+msgstr ""
+
 #: dashboard/templates/jet.dashboard/module.html:19
 #: dashboard/templates/jet.dashboard/module.html:19
 #: dashboard/templates/jet.dashboard/modules/app_list.html:24
 #: dashboard/templates/jet.dashboard/modules/app_list.html:24
 #: dashboard/templates/jet.dashboard/modules/model_list.html:14
 #: dashboard/templates/jet.dashboard/modules/model_list.html:14
@@ -500,7 +509,7 @@ msgid "Please correct the errors below."
 msgstr ""
 msgstr ""
 
 
 #: dashboard/templates/jet.dashboard/update_module.html:126
 #: dashboard/templates/jet.dashboard/update_module.html:126
-#: templates/admin/base.html:211 templates/admin/base.html.py:218
+#: templates/admin/base.html:214 templates/admin/base.html.py:221
 #: templates/admin/edit_inline/stacked.html:21
 #: templates/admin/edit_inline/stacked.html:21
 #: templates/admin/edit_inline/stacked.html:75
 #: templates/admin/edit_inline/stacked.html:75
 #: templates/admin/edit_inline/tabular.html:100
 #: templates/admin/edit_inline/tabular.html:100
@@ -543,7 +552,7 @@ msgstr ""
 msgid "bookmark"
 msgid "bookmark"
 msgstr ""
 msgstr ""
 
 
-#: models.py:19 templates/admin/base.html:204
+#: models.py:19 templates/admin/base.html:207
 msgid "bookmarks"
 msgid "bookmarks"
 msgstr ""
 msgstr ""
 
 
@@ -576,27 +585,27 @@ msgstr ""
 msgid "Clear selection"
 msgid "Clear selection"
 msgstr ""
 msgstr ""
 
 
-#: templates/admin/base.html:146
+#: templates/admin/base.html:149
 msgid "View site"
 msgid "View site"
 msgstr ""
 msgstr ""
 
 
-#: templates/admin/base.html:186 templates/admin/base.html.py:203
+#: templates/admin/base.html:189 templates/admin/base.html.py:206
 msgid "Add bookmark"
 msgid "Add bookmark"
 msgstr ""
 msgstr ""
 
 
-#: templates/admin/base.html:199
+#: templates/admin/base.html:202
 msgid "Delete bookmark"
 msgid "Delete bookmark"
 msgstr ""
 msgstr ""
 
 
-#: templates/admin/base.html:200
+#: templates/admin/base.html:203
 msgid "Are you sure want to delete this bookmark?"
 msgid "Are you sure want to delete this bookmark?"
 msgstr ""
 msgstr ""
 
 
-#: templates/admin/base.html:226
+#: templates/admin/base.html:229
 msgid "Documentation"
 msgid "Documentation"
 msgstr ""
 msgstr ""
 
 
-#: templates/admin/base.html:249
+#: templates/admin/base.html:252
 msgid "Application page"
 msgid "Application page"
 msgstr ""
 msgstr ""
 
 

二进制
jet/locale/en/LC_MESSAGES/djangojs.mo


+ 16 - 9
jet/locale/en/LC_MESSAGES/djangojs.po

@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-08-07 13:32+0000\n"
+"POT-Creation-Date: 2015-09-11 12:44+0000\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -15,36 +15,43 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Content-Transfer-Encoding: 8bit\n"
 
 
-#: static/jet/js/main.js:266
+#: static/jet/js/main.js:266 static/jet/js/main.min.js:1
 msgid "Add"
 msgid "Add"
 msgstr ""
 msgstr ""
 
 
 #: static/jet/js/main.js:271 static/jet/js/main.js:315
 #: static/jet/js/main.js:271 static/jet/js/main.js:315
-#: static/jet/js/main.js:721
+#: static/jet/js/main.js:766 static/jet/js/main.js:862
+#: static/jet/js/main.min.js:1 static/jet/js/main.min.js:2
+#: static/jet/js/main.min.js:3
 msgid "Cancel"
 msgid "Cancel"
 msgstr ""
 msgstr ""
 
 
-#: static/jet/js/main.js:310 static/jet/js/main.js:716
+#: static/jet/js/main.js:310 static/jet/js/main.js:761
+#: static/jet/js/main.min.js:1 static/jet/js/main.min.js:2
 msgid "Delete"
 msgid "Delete"
 msgstr ""
 msgstr ""
 
 
-#: static/jet/js/main.js:336
+#: static/jet/js/main.js:336 static/jet/js/main.min.js:1
 msgid "Hide applications"
 msgid "Hide applications"
 msgstr ""
 msgstr ""
 
 
-#: static/jet/js/main.js:338
+#: static/jet/js/main.js:338 static/jet/js/main.min.js:1
 msgid "Show hidden"
 msgid "Show hidden"
 msgstr ""
 msgstr ""
 
 
-#: static/jet/js/main.js:792
+#: static/jet/js/main.js:857 static/jet/js/main.min.js:3
+msgid "Yes"
+msgstr ""
+
+#: static/jet/js/main.js:884 static/jet/js/main.min.js:3
 msgid "Warning: you have unsaved changes"
 msgid "Warning: you have unsaved changes"
 msgstr ""
 msgstr ""
 
 
-#: static/jet/js/select2.jet.js:108
+#: static/jet/js/select2.jet.js:108 static/jet/js/select2.jet.min.js:1
 msgid "select all"
 msgid "select all"
 msgstr ""
 msgstr ""
 
 
-#: static/jet/js/select2.jet.js:111
+#: static/jet/js/select2.jet.js:111 static/jet/js/select2.jet.min.js:1
 msgid "deselect all"
 msgid "deselect all"
 msgstr ""
 msgstr ""
 
 

二进制
jet/locale/ru/LC_MESSAGES/django.mo


+ 60 - 51
jet/locale/ru/LC_MESSAGES/django.po

@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-09-07 13:42+0000\n"
+"POT-Creation-Date: 2015-09-11 12:45+0000\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -25,16 +25,16 @@ msgstr "Быстрые ссылки"
 msgid "Return to site"
 msgid "Return to site"
 msgstr "Вернуться на сайт"
 msgstr "Вернуться на сайт"
 
 
-#: dashboard/dashboard.py:166 templates/admin/base.html:77
+#: dashboard/dashboard.py:166 templates/admin/base.html:80
 msgid "Change password"
 msgid "Change password"
 msgstr ""
 msgstr ""
 
 
-#: dashboard/dashboard.py:168 templates/admin/base.html:81
+#: dashboard/dashboard.py:168 templates/admin/base.html:84
 msgid "Log out"
 msgid "Log out"
 msgstr ""
 msgstr ""
 
 
 #: dashboard/dashboard.py:176 dashboard/modules.py:160
 #: dashboard/dashboard.py:176 dashboard/modules.py:160
-#: templates/admin/base.html:157 templates/admin/index.html:14
+#: templates/admin/base.html:160 templates/admin/index.html:14
 msgid "Applications"
 msgid "Applications"
 msgstr "Приложения"
 msgstr "Приложения"
 
 
@@ -82,62 +82,62 @@ msgid "Grant access"
 msgstr "Предоставить доступ"
 msgstr "Предоставить доступ"
 
 
 #: dashboard/dashboard_modules/google_analytics.py:161
 #: dashboard/dashboard_modules/google_analytics.py:161
-#: dashboard/dashboard_modules/yandex_metrika.py:113
+#: dashboard/dashboard_modules/yandex_metrika.py:116
 msgid "Access"
 msgid "Access"
 msgstr "Доступ"
 msgstr "Доступ"
 
 
 #: dashboard/dashboard_modules/google_analytics.py:162
 #: dashboard/dashboard_modules/google_analytics.py:162
-#: dashboard/dashboard_modules/yandex_metrika.py:114
+#: dashboard/dashboard_modules/yandex_metrika.py:117
 msgid "Counter"
 msgid "Counter"
 msgstr "Счетчик"
 msgstr "Счетчик"
 
 
 #: dashboard/dashboard_modules/google_analytics.py:163
 #: dashboard/dashboard_modules/google_analytics.py:163
-#: dashboard/dashboard_modules/yandex_metrika.py:115
+#: dashboard/dashboard_modules/yandex_metrika.py:118
 msgid "Statistics period"
 msgid "Statistics period"
 msgstr "Статистика за период"
 msgstr "Статистика за период"
 
 
 #: dashboard/dashboard_modules/google_analytics.py:164
 #: dashboard/dashboard_modules/google_analytics.py:164
-#: dashboard/dashboard_modules/yandex_metrika.py:116
+#: dashboard/dashboard_modules/yandex_metrika.py:119
 msgid "Today"
 msgid "Today"
 msgstr "Сегодня"
 msgstr "Сегодня"
 
 
 #: dashboard/dashboard_modules/google_analytics.py:165
 #: dashboard/dashboard_modules/google_analytics.py:165
-#: dashboard/dashboard_modules/yandex_metrika.py:117
+#: dashboard/dashboard_modules/yandex_metrika.py:120
 msgid "Last week"
 msgid "Last week"
 msgstr "Последняя неделя"
 msgstr "Последняя неделя"
 
 
 #: dashboard/dashboard_modules/google_analytics.py:166
 #: dashboard/dashboard_modules/google_analytics.py:166
-#: dashboard/dashboard_modules/yandex_metrika.py:118
+#: dashboard/dashboard_modules/yandex_metrika.py:121
 msgid "Last month"
 msgid "Last month"
 msgstr "Последний месяц"
 msgstr "Последний месяц"
 
 
 #: dashboard/dashboard_modules/google_analytics.py:167
 #: dashboard/dashboard_modules/google_analytics.py:167
-#: dashboard/dashboard_modules/yandex_metrika.py:119
+#: dashboard/dashboard_modules/yandex_metrika.py:122
 msgid "Last quarter"
 msgid "Last quarter"
 msgstr "Последний квартал"
 msgstr "Последний квартал"
 
 
 #: dashboard/dashboard_modules/google_analytics.py:168
 #: dashboard/dashboard_modules/google_analytics.py:168
-#: dashboard/dashboard_modules/yandex_metrika.py:120
+#: dashboard/dashboard_modules/yandex_metrika.py:123
 msgid "Last year"
 msgid "Last year"
 msgstr "Последний год"
 msgstr "Последний год"
 
 
 #: dashboard/dashboard_modules/google_analytics.py:178
 #: dashboard/dashboard_modules/google_analytics.py:178
-#: dashboard/dashboard_modules/yandex_metrika.py:130
+#: dashboard/dashboard_modules/yandex_metrika.py:133
 msgid "none"
 msgid "none"
 msgstr "не указано"
 msgstr "не указано"
 
 
 #: dashboard/dashboard_modules/google_analytics.py:181
 #: dashboard/dashboard_modules/google_analytics.py:181
-#: dashboard/dashboard_modules/yandex_metrika.py:133
+#: dashboard/dashboard_modules/yandex_metrika.py:136
 msgid "grant access first"
 msgid "grant access first"
 msgstr "сначала предоставьте доступ"
 msgstr "сначала предоставьте доступ"
 
 
 #: dashboard/dashboard_modules/google_analytics.py:181
 #: dashboard/dashboard_modules/google_analytics.py:181
-#: dashboard/dashboard_modules/yandex_metrika.py:133
+#: dashboard/dashboard_modules/yandex_metrika.py:136
 msgid "counters loading failed"
 msgid "counters loading failed"
 msgstr "не удалось загрузить счетчики"
 msgstr "не удалось загрузить счетчики"
 
 
 #: dashboard/dashboard_modules/google_analytics.py:186
 #: dashboard/dashboard_modules/google_analytics.py:186
-#: dashboard/dashboard_modules/yandex_metrika.py:138
+#: dashboard/dashboard_modules/yandex_metrika.py:141
 msgid "Show"
 msgid "Show"
 msgstr "Показывать"
 msgstr "Показывать"
 
 
@@ -152,7 +152,7 @@ msgid "Sessions"
 msgstr "Сессии"
 msgstr "Сессии"
 
 
 #: dashboard/dashboard_modules/google_analytics.py:189
 #: dashboard/dashboard_modules/google_analytics.py:189
-#: dashboard/dashboard_modules/yandex_metrika.py:141
+#: dashboard/dashboard_modules/yandex_metrika.py:144
 #: dashboard/templates/jet.dashboard/modules/google_analytics_period_visitors.html:17
 #: dashboard/templates/jet.dashboard/modules/google_analytics_period_visitors.html:17
 #: dashboard/templates/jet.dashboard/modules/yandex_metrika_period_visitors.html:17
 #: dashboard/templates/jet.dashboard/modules/yandex_metrika_period_visitors.html:17
 msgid "Views"
 msgid "Views"
@@ -160,29 +160,29 @@ msgstr "Просмотры"
 
 
 #: dashboard/dashboard_modules/google_analytics.py:191
 #: dashboard/dashboard_modules/google_analytics.py:191
 #: dashboard/dashboard_modules/google_analytics.py:199
 #: dashboard/dashboard_modules/google_analytics.py:199
-#: dashboard/dashboard_modules/yandex_metrika.py:143
-#: dashboard/dashboard_modules/yandex_metrika.py:151
+#: dashboard/dashboard_modules/yandex_metrika.py:146
+#: dashboard/dashboard_modules/yandex_metrika.py:154
 msgid "Group"
 msgid "Group"
 msgstr "Группировать"
 msgstr "Группировать"
 
 
 #: dashboard/dashboard_modules/google_analytics.py:192
 #: dashboard/dashboard_modules/google_analytics.py:192
 #: dashboard/dashboard_modules/google_analytics.py:200
 #: dashboard/dashboard_modules/google_analytics.py:200
-#: dashboard/dashboard_modules/yandex_metrika.py:144
-#: dashboard/dashboard_modules/yandex_metrika.py:152
+#: dashboard/dashboard_modules/yandex_metrika.py:147
+#: dashboard/dashboard_modules/yandex_metrika.py:155
 msgid "By day"
 msgid "By day"
 msgstr "По дням"
 msgstr "По дням"
 
 
 #: dashboard/dashboard_modules/google_analytics.py:193
 #: dashboard/dashboard_modules/google_analytics.py:193
 #: dashboard/dashboard_modules/google_analytics.py:201
 #: dashboard/dashboard_modules/google_analytics.py:201
-#: dashboard/dashboard_modules/yandex_metrika.py:145
-#: dashboard/dashboard_modules/yandex_metrika.py:153
+#: dashboard/dashboard_modules/yandex_metrika.py:148
+#: dashboard/dashboard_modules/yandex_metrika.py:156
 msgid "By week"
 msgid "By week"
 msgstr "По неделям"
 msgstr "По неделям"
 
 
 #: dashboard/dashboard_modules/google_analytics.py:194
 #: dashboard/dashboard_modules/google_analytics.py:194
 #: dashboard/dashboard_modules/google_analytics.py:202
 #: dashboard/dashboard_modules/google_analytics.py:202
-#: dashboard/dashboard_modules/yandex_metrika.py:146
-#: dashboard/dashboard_modules/yandex_metrika.py:154
+#: dashboard/dashboard_modules/yandex_metrika.py:149
+#: dashboard/dashboard_modules/yandex_metrika.py:157
 msgid "By month"
 msgid "By month"
 msgstr "По месяцам"
 msgstr "По месяцам"
 
 
@@ -205,13 +205,13 @@ msgstr ""
 
 
 #: dashboard/dashboard_modules/google_analytics.py:297
 #: dashboard/dashboard_modules/google_analytics.py:297
 #: dashboard/dashboard_modules/google_analytics_views.py:42
 #: dashboard/dashboard_modules/google_analytics_views.py:42
-#: dashboard/dashboard_modules/yandex_metrika.py:231
+#: dashboard/dashboard_modules/yandex_metrika.py:234
 #: dashboard/dashboard_modules/yandex_metrika_views.py:37
 #: dashboard/dashboard_modules/yandex_metrika_views.py:37
 msgid "API request failed."
 msgid "API request failed."
 msgstr "Ошибка запроса к API."
 msgstr "Ошибка запроса к API."
 
 
 #: dashboard/dashboard_modules/google_analytics.py:299
 #: dashboard/dashboard_modules/google_analytics.py:299
-#: dashboard/dashboard_modules/yandex_metrika.py:233
+#: dashboard/dashboard_modules/yandex_metrika.py:236
 #, python-format
 #, python-format
 msgid " Try to <a href=\"%s\">revoke and grant access</a> again"
 msgid " Try to <a href=\"%s\">revoke and grant access</a> again"
 msgstr " Попробуйте <a href=\"%s\">убрать и предоставить доступ</a> заново"
 msgstr " Попробуйте <a href=\"%s\">убрать и предоставить доступ</a> заново"
@@ -229,16 +229,16 @@ msgid "sessions"
 msgstr "сессии"
 msgstr "сессии"
 
 
 #: dashboard/dashboard_modules/google_analytics.py:318
 #: dashboard/dashboard_modules/google_analytics.py:318
-#: dashboard/dashboard_modules/yandex_metrika.py:254
+#: dashboard/dashboard_modules/yandex_metrika.py:257
 msgid "views"
 msgid "views"
 msgstr "просмотры"
 msgstr "просмотры"
 
 
 #: dashboard/dashboard_modules/google_analytics.py:320
 #: dashboard/dashboard_modules/google_analytics.py:320
 #: dashboard/dashboard_modules/google_analytics.py:365
 #: dashboard/dashboard_modules/google_analytics.py:365
 #: dashboard/dashboard_modules/google_analytics.py:404
 #: dashboard/dashboard_modules/google_analytics.py:404
-#: dashboard/dashboard_modules/yandex_metrika.py:256
-#: dashboard/dashboard_modules/yandex_metrika.py:295
-#: dashboard/dashboard_modules/yandex_metrika.py:328
+#: dashboard/dashboard_modules/yandex_metrika.py:259
+#: dashboard/dashboard_modules/yandex_metrika.py:298
+#: dashboard/dashboard_modules/yandex_metrika.py:331
 msgid "Bad server response"
 msgid "Bad server response"
 msgstr "Некорректный ответ сервера"
 msgstr "Некорректный ответ сервера"
 
 
@@ -262,17 +262,17 @@ msgstr "Модуль не найден"
 msgid "Bad arguments"
 msgid "Bad arguments"
 msgstr "Некорректные аргументы"
 msgstr "Некорректные аргументы"
 
 
-#: dashboard/dashboard_modules/yandex_metrika.py:139
+#: dashboard/dashboard_modules/yandex_metrika.py:142
 #: dashboard/templates/jet.dashboard/modules/yandex_metrika_period_visitors.html:15
 #: dashboard/templates/jet.dashboard/modules/yandex_metrika_period_visitors.html:15
 msgid "Visitors"
 msgid "Visitors"
 msgstr "Посетители"
 msgstr "Посетители"
 
 
-#: dashboard/dashboard_modules/yandex_metrika.py:140
+#: dashboard/dashboard_modules/yandex_metrika.py:143
 #: dashboard/templates/jet.dashboard/modules/yandex_metrika_period_visitors.html:16
 #: dashboard/templates/jet.dashboard/modules/yandex_metrika_period_visitors.html:16
 msgid "Visits"
 msgid "Visits"
 msgstr "Визиты"
 msgstr "Визиты"
 
 
-#: dashboard/dashboard_modules/yandex_metrika.py:214
+#: dashboard/dashboard_modules/yandex_metrika.py:217
 #, python-format
 #, python-format
 msgid ""
 msgid ""
 "Please <a href=\"%s\">attach Yandex account and choose Yandex Metrika "
 "Please <a href=\"%s\">attach Yandex account and choose Yandex Metrika "
@@ -281,35 +281,35 @@ msgstr ""
 "Пожалуйста <a href=\"%s\">прикрепите аккаунт Яндекс и выберите счетчик "
 "Пожалуйста <a href=\"%s\">прикрепите аккаунт Яндекс и выберите счетчик "
 "Яндекс Метрики</a> для виджета"
 "Яндекс Метрики</a> для виджета"
 
 
-#: dashboard/dashboard_modules/yandex_metrika.py:217
+#: dashboard/dashboard_modules/yandex_metrika.py:220
 #, python-format
 #, python-format
 msgid ""
 msgid ""
 "Please <a href=\"%s\">select Yandex Metrika counter</a> to start using widget"
 "Please <a href=\"%s\">select Yandex Metrika counter</a> to start using widget"
 msgstr ""
 msgstr ""
 "Пожалуйста <a href=\"%s\">выберите счетчик Яндекс Метрики</a> для виджета"
 "Пожалуйста <a href=\"%s\">выберите счетчик Яндекс Метрики</a> для виджета"
 
 
-#: dashboard/dashboard_modules/yandex_metrika.py:240
+#: dashboard/dashboard_modules/yandex_metrika.py:243
 msgid "Yandex Metrika visitors totals"
 msgid "Yandex Metrika visitors totals"
 msgstr "Данные о посещениях Яндекс Метрики"
 msgstr "Данные о посещениях Яндекс Метрики"
 
 
-#: dashboard/dashboard_modules/yandex_metrika.py:252
+#: dashboard/dashboard_modules/yandex_metrika.py:255
 msgid "visitors"
 msgid "visitors"
 msgstr "посетители"
 msgstr "посетители"
 
 
-#: dashboard/dashboard_modules/yandex_metrika.py:253
+#: dashboard/dashboard_modules/yandex_metrika.py:256
 msgid "visits"
 msgid "visits"
 msgstr "визиты"
 msgstr "визиты"
 
 
-#: dashboard/dashboard_modules/yandex_metrika.py:260
+#: dashboard/dashboard_modules/yandex_metrika.py:263
 msgid "Yandex Metrika visitors chart"
 msgid "Yandex Metrika visitors chart"
 msgstr "График посещений Яндекс Метрики"
 msgstr "График посещений Яндекс Метрики"
 
 
-#: dashboard/dashboard_modules/yandex_metrika.py:299
+#: dashboard/dashboard_modules/yandex_metrika.py:302
 msgid "Yandex Metrika period visitors"
 msgid "Yandex Metrika period visitors"
 msgstr "Посещения Яндекс Метрики за период"
 msgstr "Посещения Яндекс Метрики за период"
 
 
 #: dashboard/models.py:11 dashboard/modules.py:116
 #: dashboard/models.py:11 dashboard/modules.py:116
-#: templates/admin/base.html:189
+#: templates/admin/base.html:192
 msgid "Title"
 msgid "Title"
 msgstr "Название"
 msgstr "Название"
 
 
@@ -353,7 +353,7 @@ msgstr ""
 msgid "user dashboard modules"
 msgid "user dashboard modules"
 msgstr ""
 msgstr ""
 
 
-#: dashboard/modules.py:115 models.py:12 templates/admin/base.html:191
+#: dashboard/modules.py:115 models.py:12 templates/admin/base.html:194
 msgid "URL"
 msgid "URL"
 msgstr "URL"
 msgstr "URL"
 
 
@@ -407,7 +407,7 @@ msgstr "Необходимо указать корректный URL поток
 
 
 #: dashboard/templates/admin/app_index.html:32
 #: dashboard/templates/admin/app_index.html:32
 #: dashboard/templates/jet.dashboard/update_module.html:14
 #: dashboard/templates/jet.dashboard/update_module.html:14
-#: templates/admin/base.html:92 templates/admin/base.html.py:141
+#: templates/admin/base.html:95 templates/admin/base.html.py:144
 #: templates/admin/change_form.html:17 templates/admin/change_list.html:33
 #: templates/admin/change_form.html:17 templates/admin/change_list.html:33
 #: templates/admin/delete_confirmation.html:8
 #: templates/admin/delete_confirmation.html:8
 #: templates/admin/delete_selected_confirmation.html:8
 #: templates/admin/delete_selected_confirmation.html:8
@@ -445,6 +445,15 @@ msgstr "изначальные"
 msgid "Add"
 msgid "Add"
 msgstr ""
 msgstr ""
 
 
+#: dashboard/templates/jet.dashboard/dashboard_tools.html:21
+#: dashboard/templates/jet.dashboard/dashboard_tools.html:27
+msgid "Reset widgets"
+msgstr "Сбросить виджеты"
+
+#: dashboard/templates/jet.dashboard/dashboard_tools.html:28
+msgid "Are you sure want to reset widgets?"
+msgstr "Вы точно хотите сбросить виджеты?"
+
 #: dashboard/templates/jet.dashboard/module.html:19
 #: dashboard/templates/jet.dashboard/module.html:19
 #: dashboard/templates/jet.dashboard/modules/app_list.html:24
 #: dashboard/templates/jet.dashboard/modules/app_list.html:24
 #: dashboard/templates/jet.dashboard/modules/model_list.html:14
 #: dashboard/templates/jet.dashboard/modules/model_list.html:14
@@ -508,7 +517,7 @@ msgid "Please correct the errors below."
 msgstr ""
 msgstr ""
 
 
 #: dashboard/templates/jet.dashboard/update_module.html:126
 #: dashboard/templates/jet.dashboard/update_module.html:126
-#: templates/admin/base.html:211 templates/admin/base.html.py:218
+#: templates/admin/base.html:214 templates/admin/base.html.py:221
 #: templates/admin/edit_inline/stacked.html:21
 #: templates/admin/edit_inline/stacked.html:21
 #: templates/admin/edit_inline/stacked.html:75
 #: templates/admin/edit_inline/stacked.html:75
 #: templates/admin/edit_inline/tabular.html:100
 #: templates/admin/edit_inline/tabular.html:100
@@ -551,7 +560,7 @@ msgstr ""
 msgid "bookmark"
 msgid "bookmark"
 msgstr ""
 msgstr ""
 
 
-#: models.py:19 templates/admin/base.html:204
+#: models.py:19 templates/admin/base.html:207
 msgid "bookmarks"
 msgid "bookmarks"
 msgstr "закладки"
 msgstr "закладки"
 
 
@@ -584,27 +593,27 @@ msgstr ""
 msgid "Clear selection"
 msgid "Clear selection"
 msgstr ""
 msgstr ""
 
 
-#: templates/admin/base.html:146
+#: templates/admin/base.html:149
 msgid "View site"
 msgid "View site"
 msgstr ""
 msgstr ""
 
 
-#: templates/admin/base.html:186 templates/admin/base.html.py:203
+#: templates/admin/base.html:189 templates/admin/base.html.py:206
 msgid "Add bookmark"
 msgid "Add bookmark"
 msgstr "Добавить закладку"
 msgstr "Добавить закладку"
 
 
-#: templates/admin/base.html:199
+#: templates/admin/base.html:202
 msgid "Delete bookmark"
 msgid "Delete bookmark"
 msgstr "Удалить закладку"
 msgstr "Удалить закладку"
 
 
-#: templates/admin/base.html:200
+#: templates/admin/base.html:203
 msgid "Are you sure want to delete this bookmark?"
 msgid "Are you sure want to delete this bookmark?"
 msgstr "Вы точно хотите удалить эту закладку?"
 msgstr "Вы точно хотите удалить эту закладку?"
 
 
-#: templates/admin/base.html:226
+#: templates/admin/base.html:229
 msgid "Documentation"
 msgid "Documentation"
 msgstr ""
 msgstr ""
 
 
-#: templates/admin/base.html:249
+#: templates/admin/base.html:252
 msgid "Application page"
 msgid "Application page"
 msgstr "Страница приложения"
 msgstr "Страница приложения"
 
 

二进制
jet/locale/ru/LC_MESSAGES/djangojs.mo


+ 16 - 9
jet/locale/ru/LC_MESSAGES/djangojs.po

@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-08-07 13:32+0000\n"
+"POT-Creation-Date: 2015-09-11 12:44+0000\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -15,36 +15,43 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Content-Transfer-Encoding: 8bit\n"
 
 
-#: static/jet/js/main.js:266
+#: static/jet/js/main.js:266 static/jet/js/main.min.js:1
 msgid "Add"
 msgid "Add"
 msgstr "Добавить"
 msgstr "Добавить"
 
 
 #: static/jet/js/main.js:271 static/jet/js/main.js:315
 #: static/jet/js/main.js:271 static/jet/js/main.js:315
-#: static/jet/js/main.js:721
+#: static/jet/js/main.js:766 static/jet/js/main.js:862
+#: static/jet/js/main.min.js:1 static/jet/js/main.min.js:2
+#: static/jet/js/main.min.js:3
 msgid "Cancel"
 msgid "Cancel"
 msgstr "Отмена"
 msgstr "Отмена"
 
 
-#: static/jet/js/main.js:310 static/jet/js/main.js:716
+#: static/jet/js/main.js:310 static/jet/js/main.js:761
+#: static/jet/js/main.min.js:1 static/jet/js/main.min.js:2
 msgid "Delete"
 msgid "Delete"
 msgstr "Удалить"
 msgstr "Удалить"
 
 
-#: static/jet/js/main.js:336
+#: static/jet/js/main.js:336 static/jet/js/main.min.js:1
 msgid "Hide applications"
 msgid "Hide applications"
 msgstr "Скрыть приложения"
 msgstr "Скрыть приложения"
 
 
-#: static/jet/js/main.js:338
+#: static/jet/js/main.js:338 static/jet/js/main.min.js:1
 msgid "Show hidden"
 msgid "Show hidden"
 msgstr "Показать скрытые"
 msgstr "Показать скрытые"
 
 
-#: static/jet/js/main.js:792
+#: static/jet/js/main.js:857 static/jet/js/main.min.js:3
+msgid "Yes"
+msgstr "Да"
+
+#: static/jet/js/main.js:884 static/jet/js/main.min.js:3
 msgid "Warning: you have unsaved changes"
 msgid "Warning: you have unsaved changes"
 msgstr "Внимание: у вас есть несохраненные изменения"
 msgstr "Внимание: у вас есть несохраненные изменения"
 
 
-#: static/jet/js/select2.jet.js:108
+#: static/jet/js/select2.jet.js:108 static/jet/js/select2.jet.min.js:1
 msgid "select all"
 msgid "select all"
 msgstr "выбрать все"
 msgstr "выбрать все"
 
 
-#: static/jet/js/select2.jet.js:111
+#: static/jet/js/select2.jet.js:111 static/jet/js/select2.jet.min.js:1
 msgid "deselect all"
 msgid "deselect all"
 msgstr "убрать все"
 msgstr "убрать все"
 
 

+ 2 - 0
jet/static/jet/css/_changelist.scss

@@ -11,6 +11,8 @@
 
 
     &-submit-block {
     &-submit-block {
       white-space: nowrap;
       white-space: nowrap;
+      line-height: 32px;
+      display: inline-block;
     }
     }
   }
   }
 
 

+ 21 - 1
jet/static/jet/css/_content.scss

@@ -108,4 +108,24 @@ ul.object-tools {
 }
 }
 @-moz-keyframes spin { 100% { -moz-transform: rotate(360deg); } }
 @-moz-keyframes spin { 100% { -moz-transform: rotate(360deg); } }
 @-webkit-keyframes spin { 100% { -webkit-transform: rotate(360deg); } }
 @-webkit-keyframes spin { 100% { -webkit-transform: rotate(360deg); } }
-@keyframes spin { 100% { -webkit-transform: rotate(360deg); transform:rotate(360deg); } }
+@keyframes spin { 100% { -webkit-transform: rotate(360deg); transform:rotate(360deg); } }
+
+img[src$="admin/img/icon-yes.gif"], img[src$="admin/img/icon-no.gif"], img[src$="admin/img/icon-unknown.gif"] {
+  @include font-icon;
+  content: "";
+  font-weight: bold;
+}
+
+img[src$="admin/img/icon-yes.gif"]:before {
+  content: $icon-tick;
+  color: $success-text-color;
+}
+
+img[src$="admin/img/icon-no.gif"]:before {
+  content: $icon-cross;
+  color: $warning-text-color;
+}
+
+img[src$="admin/img/icon-unknown.gif"]:before {
+  content: $icon-question;
+}

+ 6 - 0
jet/static/jet/css/_forms.scss

@@ -62,6 +62,12 @@
     color: $background-button-text-color;
     color: $background-button-text-color;
   }
   }
 
 
+  &.button-transparent {
+    background-color: transparent;
+    color: $text-color;
+    padding: 0 10px;
+  }
+
   &:hover {
   &:hover {
     background-color: $button-hover-background-color;
     background-color: $button-hover-background-color;
     color: $button-hover-text-color;
     color: $button-hover-text-color;

+ 26 - 2
jet/static/jet/css/_sidebar.scss

@@ -8,8 +8,9 @@
     margin-bottom: 32px !important;
     margin-bottom: 32px !important;
 
 
     &-wrapper {
     &-wrapper {
-      overflow-y: auto;
+      overflow: hidden;
       height: 100%;
       height: 100%;
+      position: relative;
     }
     }
 
 
     &-item {
     &-item {
@@ -95,7 +96,7 @@
       &-list {
       &-list {
         @extend .clear-list;
         @extend .clear-list;
 
 
-        &:not(:empty) {
+        .sidebar-menu-item-title + &:not(:empty) {
           margin-top: 10px !important;
           margin-top: 10px !important;
         }
         }
 
 
@@ -104,6 +105,17 @@
             display: none;
             display: none;
           }
           }
 
 
+          &-icon {
+            font-size: 18px;
+            vertical-align: middle;
+            margin-right: 6px;
+            color: $sidebar-icon-color;
+          }
+
+          &.compact &-icon {
+            font-size: 16px;
+          }
+
           &-link {
           &-link {
             &, &:visited, &:hover {
             &, &:visited, &:hover {
               display: block;
               display: block;
@@ -172,6 +184,18 @@
             margin-left: 4px;
             margin-left: 4px;
           }
           }
         }
         }
+
+        &.compact &-item-link {
+          &, &:visited, &:hover {
+            font-size: 11px;
+            padding: 6px 12px 6px 24px;
+            text-transform: uppercase;
+          }
+
+          &.padding-icon {
+            padding-left: 49px;
+          }
+        }
       }
       }
     }
     }
   }
   }

+ 0 - 20
jet/static/jet/css/_table.scss

@@ -127,26 +127,6 @@
         &.action-checkbox {
         &.action-checkbox {
           text-align: center;
           text-align: center;
         }
         }
-
-        img[src$="admin/img/icon-yes.gif"], img[src$="admin/img/icon-no.gif"], img[src$="admin/img/icon-unknown.gif"] {
-          @include font-icon;
-          content: "";
-          font-weight: bold;
-        }
-
-        img[src$="admin/img/icon-yes.gif"]:before {
-          content: $icon-tick;
-          color: $success-text-color;
-        }
-
-        img[src$="admin/img/icon-no.gif"]:before {
-          content: $icon-cross;
-          color: $warning-text-color;
-        }
-
-        img[src$="admin/img/icon-unknown.gif"]:before {
-          content: $icon-question;
-        }
       }
       }
     }
     }
 
 

+ 1 - 0
jet/static/jet/css/icons/_variables.scss

@@ -1,3 +1,4 @@
+$icon-reset: "\e61e";
 $icon-search: "\e61d";
 $icon-search: "\e61d";
 $icon-user: "\e61c";
 $icon-user: "\e61c";
 $icon-jet: "\e61b";
 $icon-jet: "\e61b";

二进制
jet/static/jet/css/icons/fonts/jet-icons.eot


+ 1 - 0
jet/static/jet/css/icons/fonts/jet-icons.svg

@@ -37,4 +37,5 @@
 <glyph unicode="&#xe61b;" glyph-name="jet" d="M136.192 156.16c0 0 54.886 51.2 74.547 28.058s-29.082-65.946-40.141-77.21c-11.264-11.264-79.053-23.962-91.136-73.114s-4.915 19.456 52.838 20.685c57.958 1.024 51.61-1.638 95.437 10.24s59.187 34.611 59.187 34.611 5.325-40.755-54.477-72.294c-59.802-31.539 37.069-3.482 76.186 17.818s62.464 70.246 62.464 70.246 3.072-26.214-36.454-91.75c0 0 159.744 91.341 101.786 235.315 0 0 1.843-72.499-48.538-131.277 0 0 9.216 56.934-6.758 63.693-11.469 4.915-36.659-88.064-77.21-92.774 0 0 29.082 41.574 18.432 56.525-15.155 21.299-87.45-38.707-87.45-38.707s3.686 53.043 79.462 98.714c0 0-29.491 7.782-61.645 1.024 0 0 56.115 46.899 123.699 41.37 0 0-36.864 24.166-71.475 18.842 0 0 14.336 28.877 87.245 26.419 0 0-107.52 55.296-211.149-40.55 0 0 58.778 28.672 93.389-4.506-0.205-0.205-119.194-9.011-138.24-101.376zM363.315 371.814l121.856-116.736c403.456 205.824 470.016 605.184 470.016 605.184s-303.923-45.67-591.872-488.448zM437.043 360.55l-26.624 21.504c283.648 371.712 460.8 409.6 460.8 409.6s-280.576-215.45-434.176-431.104zM508.723 107.827l-9.626 130.867c0 0 82.534 41.37 165.069 113.869zM214.835 397.619l131.072-14.336c0 0 27.853 48.333 119.808 159.744z" />
 <glyph unicode="&#xe61b;" glyph-name="jet" d="M136.192 156.16c0 0 54.886 51.2 74.547 28.058s-29.082-65.946-40.141-77.21c-11.264-11.264-79.053-23.962-91.136-73.114s-4.915 19.456 52.838 20.685c57.958 1.024 51.61-1.638 95.437 10.24s59.187 34.611 59.187 34.611 5.325-40.755-54.477-72.294c-59.802-31.539 37.069-3.482 76.186 17.818s62.464 70.246 62.464 70.246 3.072-26.214-36.454-91.75c0 0 159.744 91.341 101.786 235.315 0 0 1.843-72.499-48.538-131.277 0 0 9.216 56.934-6.758 63.693-11.469 4.915-36.659-88.064-77.21-92.774 0 0 29.082 41.574 18.432 56.525-15.155 21.299-87.45-38.707-87.45-38.707s3.686 53.043 79.462 98.714c0 0-29.491 7.782-61.645 1.024 0 0 56.115 46.899 123.699 41.37 0 0-36.864 24.166-71.475 18.842 0 0 14.336 28.877 87.245 26.419 0 0-107.52 55.296-211.149-40.55 0 0 58.778 28.672 93.389-4.506-0.205-0.205-119.194-9.011-138.24-101.376zM363.315 371.814l121.856-116.736c403.456 205.824 470.016 605.184 470.016 605.184s-303.923-45.67-591.872-488.448zM437.043 360.55l-26.624 21.504c283.648 371.712 460.8 409.6 460.8 409.6s-280.576-215.45-434.176-431.104zM508.723 107.827l-9.626 130.867c0 0 82.534 41.37 165.069 113.869zM214.835 397.619l131.072-14.336c0 0 27.853 48.333 119.808 159.744z" />
 <glyph unicode="&#xe61c;" glyph-name="user" d="M851.481 250.954c-39.072 50.987-86.335 84.097-154.057 102.883l-63.453-222.157c0-20.464-16.755-37.216-37.216-37.216-20.455 0-37.21 16.753-37.21 37.216v176.765c0 25.674-20.845 46.519-46.519 46.519s-46.516-20.847-46.516-46.519v-176.765c0-20.464-16.755-37.216-37.212-37.216-20.464 0-37.218 16.753-37.218 37.216l-63.453 222.157c-67.723-18.969-114.985-51.895-154.053-102.883-15.446-20.095-23.839-60.471-24.388-82.063 0.185-5.581 0-12.095 0-18.601v-74.435c0-41.12 33.309-74.425 74.43-74.425h576.815c41.12 0 74.435 33.305 74.435 74.425v74.435c0 6.505-0.182 13.019 0 18.601-0.563 21.591-8.946 61.97-24.383 82.063zM317.649 697.706c0-108.665 67.744-268.315 195.375-268.315 125.413 0 195.371 159.65 195.371 268.315 0 108.661-87.454 196.862-195.371 196.862s-195.375-88.201-195.375-196.862z" />
 <glyph unicode="&#xe61c;" glyph-name="user" d="M851.481 250.954c-39.072 50.987-86.335 84.097-154.057 102.883l-63.453-222.157c0-20.464-16.755-37.216-37.216-37.216-20.455 0-37.21 16.753-37.21 37.216v176.765c0 25.674-20.845 46.519-46.519 46.519s-46.516-20.847-46.516-46.519v-176.765c0-20.464-16.755-37.216-37.212-37.216-20.464 0-37.218 16.753-37.218 37.216l-63.453 222.157c-67.723-18.969-114.985-51.895-154.053-102.883-15.446-20.095-23.839-60.471-24.388-82.063 0.185-5.581 0-12.095 0-18.601v-74.435c0-41.12 33.309-74.425 74.43-74.425h576.815c41.12 0 74.435 33.305 74.435 74.425v74.435c0 6.505-0.182 13.019 0 18.601-0.563 21.591-8.946 61.97-24.383 82.063zM317.649 697.706c0-108.665 67.744-268.315 195.375-268.315 125.413 0 195.371 159.65 195.371 268.315 0 108.661-87.454 196.862-195.371 196.862s-195.375-88.201-195.375-196.862z" />
 <glyph unicode="&#xe61d;" glyph-name="search" d="M120.942 128.031l203.291 203.291c-38.651 53.090-61.716 118.249-61.716 188.955 0 177.713 144.047 321.759 321.759 321.759s321.759-144.047 321.759-321.759-144.047-321.759-321.759-321.759c-70.706 0-135.862 23.068-188.955 61.716l-203.291-203.291-71.089 71.089zM584.274 299.065c121.965 0 221.209 99.243 221.209 221.209s-99.243 221.209-221.209 221.209-221.209-99.243-221.209-221.209 99.243-221.209 221.209-221.209z" />
 <glyph unicode="&#xe61d;" glyph-name="search" d="M120.942 128.031l203.291 203.291c-38.651 53.090-61.716 118.249-61.716 188.955 0 177.713 144.047 321.759 321.759 321.759s321.759-144.047 321.759-321.759-144.047-321.759-321.759-321.759c-70.706 0-135.862 23.068-188.955 61.716l-203.291-203.291-71.089 71.089zM584.274 299.065c121.965 0 221.209 99.243 221.209 221.209s-99.243 221.209-221.209 221.209-221.209-99.243-221.209-221.209 99.243-221.209 221.209-221.209z" />
+<glyph unicode="&#xe61e;" glyph-name="reset" horiz-adv-x="1013" d="M1011.457 476.745c-56.408-0.485-112.778-0.784-169.149-1.269 9.482-97.062-22.511-197.371-96.838-271.586-131.966-131.929-345.801-131.929-477.692 0-131.929 131.817-131.929 345.689 0 477.618 112.554 112.591 284.652 128.607 414.714 49.016-44.088-43.566-95.942-95.158-95.942-95.158-37.331-39.646 0.635-65.927 25.759-66.077h329.562c12.618 0 22.772 10.191 22.809 22.809v326.874c1.531 30.798-32.292 59.432-65.554 26.132 0 0-55.81-55.213-94.56-93.664-198.080 144.771-477.244 128.345-656.174-50.547-197.856-197.856-197.856-518.645 0-716.464 197.819-197.782 518.608-197.782 716.427 0 107.664 107.589 156.195 251.614 146.638 392.316z" />
 </font></defs></svg>
 </font></defs></svg>

二进制
jet/static/jet/css/icons/fonts/jet-icons.ttf


二进制
jet/static/jet/css/icons/fonts/jet-icons.woff


+ 8 - 5
jet/static/jet/css/icons/style.css

@@ -1,10 +1,10 @@
 @font-face {
 @font-face {
 	font-family: 'jet-icons';
 	font-family: 'jet-icons';
-	src:url('fonts/jet-icons.eot?-7wlpt4');
-	src:url('fonts/jet-icons.eot?#iefix-7wlpt4') format('embedded-opentype'),
-		url('fonts/jet-icons.ttf?-7wlpt4') format('truetype'),
-		url('fonts/jet-icons.woff?-7wlpt4') format('woff'),
-		url('fonts/jet-icons.svg?-7wlpt4#jet-icons') format('svg');
+	src:url('fonts/jet-icons.eot?-lem1jo');
+	src:url('fonts/jet-icons.eot?#iefix-lem1jo') format('embedded-opentype'),
+		url('fonts/jet-icons.ttf?-lem1jo') format('truetype'),
+		url('fonts/jet-icons.woff?-lem1jo') format('woff'),
+		url('fonts/jet-icons.svg?-lem1jo#jet-icons') format('svg');
 	font-weight: normal;
 	font-weight: normal;
 	font-style: normal;
 	font-style: normal;
 }
 }
@@ -23,6 +23,9 @@
 	-moz-osx-font-smoothing: grayscale;
 	-moz-osx-font-smoothing: grayscale;
 }
 }
 
 
+.icon-reset:before {
+	content: "\e61e";
+}
 .icon-search:before {
 .icon-search:before {
 	content: "\e61d";
 	content: "\e61d";
 }
 }

+ 50 - 26
jet/static/jet/css/themes/default/base.css

@@ -729,28 +729,6 @@ a:hover {
       font-size: 13px; }
       font-size: 13px; }
       .table tbody tr th.action-checkbox, #changelist table tbody tr th.action-checkbox, table#change-history tbody tr th.action-checkbox, .table tbody tr td.action-checkbox, #changelist table tbody tr td.action-checkbox, table#change-history tbody tr td.action-checkbox {
       .table tbody tr th.action-checkbox, #changelist table tbody tr th.action-checkbox, table#change-history tbody tr th.action-checkbox, .table tbody tr td.action-checkbox, #changelist table tbody tr td.action-checkbox, table#change-history tbody tr td.action-checkbox {
         text-align: center; }
         text-align: center; }
-      .table tbody tr th img[src$="admin/img/icon-yes.gif"], #changelist table tbody tr th img[src$="admin/img/icon-yes.gif"], table#change-history tbody tr th img[src$="admin/img/icon-yes.gif"], .table tbody tr th img[src$="admin/img/icon-no.gif"], #changelist table tbody tr th img[src$="admin/img/icon-no.gif"], table#change-history tbody tr th img[src$="admin/img/icon-no.gif"], .table tbody tr th img[src$="admin/img/icon-unknown.gif"], #changelist table tbody tr th img[src$="admin/img/icon-unknown.gif"], table#change-history tbody tr th img[src$="admin/img/icon-unknown.gif"], .table tbody tr td img[src$="admin/img/icon-yes.gif"], #changelist table tbody tr td img[src$="admin/img/icon-yes.gif"], table#change-history tbody tr td img[src$="admin/img/icon-yes.gif"], .table tbody tr td img[src$="admin/img/icon-no.gif"], #changelist table tbody tr td img[src$="admin/img/icon-no.gif"], table#change-history tbody tr td img[src$="admin/img/icon-no.gif"], .table tbody tr td img[src$="admin/img/icon-unknown.gif"], #changelist table tbody tr td img[src$="admin/img/icon-unknown.gif"], table#change-history tbody tr td img[src$="admin/img/icon-unknown.gif"] {
-        font-family: 'jet-icons';
-        speak: none;
-        font-style: normal;
-        font-weight: normal;
-        font-variant: normal;
-        text-transform: none;
-        line-height: 1;
-        /* Better Font Rendering =========== */
-        -webkit-font-smoothing: antialiased;
-        -moz-osx-font-smoothing: grayscale;
-        display: inline-block;
-        content: "";
-        font-weight: bold; }
-      .table tbody tr th img[src$="admin/img/icon-yes.gif"]:before, #changelist table tbody tr th img[src$="admin/img/icon-yes.gif"]:before, table#change-history tbody tr th img[src$="admin/img/icon-yes.gif"]:before, .table tbody tr td img[src$="admin/img/icon-yes.gif"]:before, #changelist table tbody tr td img[src$="admin/img/icon-yes.gif"]:before, table#change-history tbody tr td img[src$="admin/img/icon-yes.gif"]:before {
-        content: "";
-        color: #8ecb8e; }
-      .table tbody tr th img[src$="admin/img/icon-no.gif"]:before, #changelist table tbody tr th img[src$="admin/img/icon-no.gif"]:before, table#change-history tbody tr th img[src$="admin/img/icon-no.gif"]:before, .table tbody tr td img[src$="admin/img/icon-no.gif"]:before, #changelist table tbody tr td img[src$="admin/img/icon-no.gif"]:before, table#change-history tbody tr td img[src$="admin/img/icon-no.gif"]:before {
-        content: "";
-        color: #dba4a4; }
-      .table tbody tr th img[src$="admin/img/icon-unknown.gif"]:before, #changelist table tbody tr th img[src$="admin/img/icon-unknown.gif"]:before, table#change-history tbody tr th img[src$="admin/img/icon-unknown.gif"]:before, .table tbody tr td img[src$="admin/img/icon-unknown.gif"]:before, #changelist table tbody tr td img[src$="admin/img/icon-unknown.gif"]:before, table#change-history tbody tr td img[src$="admin/img/icon-unknown.gif"]:before {
-        content: ""; }
   .table tbody tr.selected, #changelist table tbody tr.selected, table#change-history tbody tr.selected {
   .table tbody tr.selected, #changelist table tbody tr.selected, table#change-history tbody tr.selected {
     border-color: #e5e2a5; }
     border-color: #e5e2a5; }
     .table tbody tr.selected:last-child th:first-child, #changelist table tbody tr.selected:last-child th:first-child, table#change-history tbody tr.selected:last-child th:first-child, .table tbody tr.selected:last-child td:first-child, #changelist table tbody tr.selected:last-child td:first-child, table#change-history tbody tr.selected:last-child td:first-child {
     .table tbody tr.selected:last-child th:first-child, #changelist table tbody tr.selected:last-child th:first-child, table#change-history tbody tr.selected:last-child th:first-child, .table tbody tr.selected:last-child td:first-child, #changelist table tbody tr.selected:last-child td:first-child, table#change-history tbody tr.selected:last-child td:first-child {
@@ -1394,8 +1372,9 @@ a:hover {
   .sidebar-menu {
   .sidebar-menu {
     margin-bottom: 32px !important; }
     margin-bottom: 32px !important; }
     .sidebar-menu-wrapper {
     .sidebar-menu-wrapper {
-      overflow-y: auto;
-      height: 100%; }
+      overflow: hidden;
+      height: 100%;
+      position: relative; }
     .sidebar-menu-item {
     .sidebar-menu-item {
       padding: 20px 24px;
       padding: 20px 24px;
       border-bottom: 1px solid #2b3647; }
       border-bottom: 1px solid #2b3647; }
@@ -1458,10 +1437,17 @@ a:hover {
       .sidebar-menu-item-action:hover {
       .sidebar-menu-item-action:hover {
         color: #639af5;
         color: #639af5;
         background-color: #2b3647; }
         background-color: #2b3647; }
-      .sidebar-menu-item-list:not(:empty) {
+      .sidebar-menu-item-title + .sidebar-menu-item-list:not(:empty) {
         margin-top: 10px !important; }
         margin-top: 10px !important; }
       .sidebar-menu-item-list-item.empty {
       .sidebar-menu-item-list-item.empty {
         display: none; }
         display: none; }
+      .sidebar-menu-item-list-item-icon {
+        font-size: 18px;
+        vertical-align: middle;
+        margin-right: 6px;
+        color: #6f7e95; }
+      .sidebar-menu-item-list-item.compact .sidebar-menu-item-list-item-icon {
+        font-size: 16px; }
       .sidebar-menu-item-list-item-link, .sidebar-menu-item-list-item-link:visited, .sidebar-menu-item-list-item-link:hover {
       .sidebar-menu-item-list-item-link, .sidebar-menu-item-list-item-link:visited, .sidebar-menu-item-list-item-link:hover {
         display: block;
         display: block;
         color: #c0cad8;
         color: #c0cad8;
@@ -1513,6 +1499,12 @@ a:hover {
         font-size: 16px;
         font-size: 16px;
         font-weight: bold !important;
         font-weight: bold !important;
         margin-left: 4px; }
         margin-left: 4px; }
+      .sidebar-menu-item-list.compact .sidebar-menu-item-list-item-link, .sidebar-menu-item-list.compact .sidebar-menu-item-list-item-link:visited, .sidebar-menu-item-list.compact .sidebar-menu-item-list-item-link:hover {
+        font-size: 11px;
+        padding: 6px 12px 6px 24px;
+        text-transform: uppercase; }
+      .sidebar-menu-item-list.compact .sidebar-menu-item-list-item-link.padding-icon {
+        padding-left: 49px; }
   .sidebar-popup {
   .sidebar-popup {
     position: absolute;
     position: absolute;
     top: 0;
     top: 0;
@@ -2294,6 +2286,10 @@ a:hover {
 .button.button-background, input.button-background[type="submit"], input.button-background[type="button"] {
 .button.button-background, input.button-background[type="submit"], input.button-background[type="button"] {
   background-color: #fff;
   background-color: #fff;
   color: #6f7e95; }
   color: #6f7e95; }
+.button.button-transparent, input.button-transparent[type="submit"], input.button-transparent[type="button"] {
+  background-color: transparent;
+  color: #6f7e95;
+  padding: 0 10px; }
 .button:hover, input[type="submit"]:hover, input[type="button"]:hover {
 .button:hover, input[type="submit"]:hover, input[type="button"]:hover {
   background-color: #639af5;
   background-color: #639af5;
   color: #fff;
   color: #fff;
@@ -2985,7 +2981,9 @@ input[type=checkbox] {
   #changelist .changelist-filter * {
   #changelist .changelist-filter * {
     vertical-align: top; }
     vertical-align: top; }
   #changelist .changelist-filter-submit-block {
   #changelist .changelist-filter-submit-block {
-    white-space: nowrap; }
+    white-space: nowrap;
+    line-height: 32px;
+    display: inline-block; }
 #changelist .results {
 #changelist .results {
   overflow-x: auto; }
   overflow-x: auto; }
 #changelist table {
 #changelist table {
@@ -4684,6 +4682,32 @@ ul.object-tools {
   100% {
   100% {
     -webkit-transform: rotate(360deg);
     -webkit-transform: rotate(360deg);
     transform: rotate(360deg); } }
     transform: rotate(360deg); } }
+img[src$="admin/img/icon-yes.gif"], img[src$="admin/img/icon-no.gif"], img[src$="admin/img/icon-unknown.gif"] {
+  font-family: 'jet-icons';
+  speak: none;
+  font-style: normal;
+  font-weight: normal;
+  font-variant: normal;
+  text-transform: none;
+  line-height: 1;
+  /* Better Font Rendering =========== */
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+  display: inline-block;
+  content: "";
+  font-weight: bold; }
+
+img[src$="admin/img/icon-yes.gif"]:before {
+  content: "";
+  color: #8ecb8e; }
+
+img[src$="admin/img/icon-no.gif"]:before {
+  content: "";
+  color: #dba4a4; }
+
+img[src$="admin/img/icon-unknown.gif"]:before {
+  content: ""; }
+
 /*
 /*
  * General
  * General
  */
  */

文件差异内容过多而无法显示
+ 0 - 0
jet/static/jet/css/themes/default/base.css.map


文件差异内容过多而无法显示
+ 0 - 0
jet/static/jet/css/themes/default/jquery-ui.theme.css.map


文件差异内容过多而无法显示
+ 0 - 0
jet/static/jet/css/themes/default/select2.theme.css.map


+ 50 - 26
jet/static/jet/css/themes/green/base.css

@@ -760,28 +760,6 @@ a:hover {
       font-size: 13px; }
       font-size: 13px; }
       .table tbody tr th.action-checkbox, #changelist table tbody tr th.action-checkbox, table#change-history tbody tr th.action-checkbox, .table tbody tr td.action-checkbox, #changelist table tbody tr td.action-checkbox, table#change-history tbody tr td.action-checkbox {
       .table tbody tr th.action-checkbox, #changelist table tbody tr th.action-checkbox, table#change-history tbody tr th.action-checkbox, .table tbody tr td.action-checkbox, #changelist table tbody tr td.action-checkbox, table#change-history tbody tr td.action-checkbox {
         text-align: center; }
         text-align: center; }
-      .table tbody tr th img[src$="admin/img/icon-yes.gif"], #changelist table tbody tr th img[src$="admin/img/icon-yes.gif"], table#change-history tbody tr th img[src$="admin/img/icon-yes.gif"], .table tbody tr th img[src$="admin/img/icon-no.gif"], #changelist table tbody tr th img[src$="admin/img/icon-no.gif"], table#change-history tbody tr th img[src$="admin/img/icon-no.gif"], .table tbody tr th img[src$="admin/img/icon-unknown.gif"], #changelist table tbody tr th img[src$="admin/img/icon-unknown.gif"], table#change-history tbody tr th img[src$="admin/img/icon-unknown.gif"], .table tbody tr td img[src$="admin/img/icon-yes.gif"], #changelist table tbody tr td img[src$="admin/img/icon-yes.gif"], table#change-history tbody tr td img[src$="admin/img/icon-yes.gif"], .table tbody tr td img[src$="admin/img/icon-no.gif"], #changelist table tbody tr td img[src$="admin/img/icon-no.gif"], table#change-history tbody tr td img[src$="admin/img/icon-no.gif"], .table tbody tr td img[src$="admin/img/icon-unknown.gif"], #changelist table tbody tr td img[src$="admin/img/icon-unknown.gif"], table#change-history tbody tr td img[src$="admin/img/icon-unknown.gif"] {
-        font-family: 'jet-icons';
-        speak: none;
-        font-style: normal;
-        font-weight: normal;
-        font-variant: normal;
-        text-transform: none;
-        line-height: 1;
-        /* Better Font Rendering =========== */
-        -webkit-font-smoothing: antialiased;
-        -moz-osx-font-smoothing: grayscale;
-        display: inline-block;
-        content: "";
-        font-weight: bold; }
-      .table tbody tr th img[src$="admin/img/icon-yes.gif"]:before, #changelist table tbody tr th img[src$="admin/img/icon-yes.gif"]:before, table#change-history tbody tr th img[src$="admin/img/icon-yes.gif"]:before, .table tbody tr td img[src$="admin/img/icon-yes.gif"]:before, #changelist table tbody tr td img[src$="admin/img/icon-yes.gif"]:before, table#change-history tbody tr td img[src$="admin/img/icon-yes.gif"]:before {
-        content: "";
-        color: #bcd386; }
-      .table tbody tr th img[src$="admin/img/icon-no.gif"]:before, #changelist table tbody tr th img[src$="admin/img/icon-no.gif"]:before, table#change-history tbody tr th img[src$="admin/img/icon-no.gif"]:before, .table tbody tr td img[src$="admin/img/icon-no.gif"]:before, #changelist table tbody tr td img[src$="admin/img/icon-no.gif"]:before, table#change-history tbody tr td img[src$="admin/img/icon-no.gif"]:before {
-        content: "";
-        color: #dba4a4; }
-      .table tbody tr th img[src$="admin/img/icon-unknown.gif"]:before, #changelist table tbody tr th img[src$="admin/img/icon-unknown.gif"]:before, table#change-history tbody tr th img[src$="admin/img/icon-unknown.gif"]:before, .table tbody tr td img[src$="admin/img/icon-unknown.gif"]:before, #changelist table tbody tr td img[src$="admin/img/icon-unknown.gif"]:before, table#change-history tbody tr td img[src$="admin/img/icon-unknown.gif"]:before {
-        content: ""; }
   .table tbody tr.selected, #changelist table tbody tr.selected, table#change-history tbody tr.selected {
   .table tbody tr.selected, #changelist table tbody tr.selected, table#change-history tbody tr.selected {
     border-color: #e5e2a5; }
     border-color: #e5e2a5; }
     .table tbody tr.selected:last-child th:first-child, #changelist table tbody tr.selected:last-child th:first-child, table#change-history tbody tr.selected:last-child th:first-child, .table tbody tr.selected:last-child td:first-child, #changelist table tbody tr.selected:last-child td:first-child, table#change-history tbody tr.selected:last-child td:first-child {
     .table tbody tr.selected:last-child th:first-child, #changelist table tbody tr.selected:last-child th:first-child, table#change-history tbody tr.selected:last-child th:first-child, .table tbody tr.selected:last-child td:first-child, #changelist table tbody tr.selected:last-child td:first-child, table#change-history tbody tr.selected:last-child td:first-child {
@@ -1425,8 +1403,9 @@ a:hover {
   .sidebar-menu {
   .sidebar-menu {
     margin-bottom: 32px !important; }
     margin-bottom: 32px !important; }
     .sidebar-menu-wrapper {
     .sidebar-menu-wrapper {
-      overflow-y: auto;
-      height: 100%; }
+      overflow: hidden;
+      height: 100%;
+      position: relative; }
     .sidebar-menu-item {
     .sidebar-menu-item {
       padding: 20px 24px;
       padding: 20px 24px;
       border-bottom: 1px solid #254d49; }
       border-bottom: 1px solid #254d49; }
@@ -1489,10 +1468,17 @@ a:hover {
       .sidebar-menu-item-action:hover {
       .sidebar-menu-item-action:hover {
         color: #7FB1DC;
         color: #7FB1DC;
         background-color: #254d49; }
         background-color: #254d49; }
-      .sidebar-menu-item-list:not(:empty) {
+      .sidebar-menu-item-title + .sidebar-menu-item-list:not(:empty) {
         margin-top: 10px !important; }
         margin-top: 10px !important; }
       .sidebar-menu-item-list-item.empty {
       .sidebar-menu-item-list-item.empty {
         display: none; }
         display: none; }
+      .sidebar-menu-item-list-item-icon {
+        font-size: 18px;
+        vertical-align: middle;
+        margin-right: 6px;
+        color: #62a29c; }
+      .sidebar-menu-item-list-item.compact .sidebar-menu-item-list-item-icon {
+        font-size: 16px; }
       .sidebar-menu-item-list-item-link, .sidebar-menu-item-list-item-link:visited, .sidebar-menu-item-list-item-link:hover {
       .sidebar-menu-item-list-item-link, .sidebar-menu-item-list-item-link:visited, .sidebar-menu-item-list-item-link:hover {
         display: block;
         display: block;
         color: #bbddd9;
         color: #bbddd9;
@@ -1544,6 +1530,12 @@ a:hover {
         font-size: 16px;
         font-size: 16px;
         font-weight: bold !important;
         font-weight: bold !important;
         margin-left: 4px; }
         margin-left: 4px; }
+      .sidebar-menu-item-list.compact .sidebar-menu-item-list-item-link, .sidebar-menu-item-list.compact .sidebar-menu-item-list-item-link:visited, .sidebar-menu-item-list.compact .sidebar-menu-item-list-item-link:hover {
+        font-size: 11px;
+        padding: 6px 12px 6px 24px;
+        text-transform: uppercase; }
+      .sidebar-menu-item-list.compact .sidebar-menu-item-list-item-link.padding-icon {
+        padding-left: 49px; }
   .sidebar-popup {
   .sidebar-popup {
     position: absolute;
     position: absolute;
     top: 0;
     top: 0;
@@ -2325,6 +2317,10 @@ a:hover {
 .button.button-background, input.button-background[type="submit"], input.button-background[type="button"] {
 .button.button-background, input.button-background[type="submit"], input.button-background[type="button"] {
   background-color: white;
   background-color: white;
   color: #62a29c; }
   color: #62a29c; }
+.button.button-transparent, input.button-transparent[type="submit"], input.button-transparent[type="button"] {
+  background-color: transparent;
+  color: #62a29c;
+  padding: 0 10px; }
 .button:hover, input[type="submit"]:hover, input[type="button"]:hover {
 .button:hover, input[type="submit"]:hover, input[type="button"]:hover {
   background-color: #7FB1DC;
   background-color: #7FB1DC;
   color: white;
   color: white;
@@ -3016,7 +3012,9 @@ input[type=checkbox] {
   #changelist .changelist-filter * {
   #changelist .changelist-filter * {
     vertical-align: top; }
     vertical-align: top; }
   #changelist .changelist-filter-submit-block {
   #changelist .changelist-filter-submit-block {
-    white-space: nowrap; }
+    white-space: nowrap;
+    line-height: 32px;
+    display: inline-block; }
 #changelist .results {
 #changelist .results {
   overflow-x: auto; }
   overflow-x: auto; }
 #changelist table {
 #changelist table {
@@ -4715,6 +4713,32 @@ ul.object-tools {
   100% {
   100% {
     -webkit-transform: rotate(360deg);
     -webkit-transform: rotate(360deg);
     transform: rotate(360deg); } }
     transform: rotate(360deg); } }
+img[src$="admin/img/icon-yes.gif"], img[src$="admin/img/icon-no.gif"], img[src$="admin/img/icon-unknown.gif"] {
+  font-family: 'jet-icons';
+  speak: none;
+  font-style: normal;
+  font-weight: normal;
+  font-variant: normal;
+  text-transform: none;
+  line-height: 1;
+  /* Better Font Rendering =========== */
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+  display: inline-block;
+  content: "";
+  font-weight: bold; }
+
+img[src$="admin/img/icon-yes.gif"]:before {
+  content: "";
+  color: #bcd386; }
+
+img[src$="admin/img/icon-no.gif"]:before {
+  content: "";
+  color: #dba4a4; }
+
+img[src$="admin/img/icon-unknown.gif"]:before {
+  content: ""; }
+
 /*
 /*
  * General
  * General
  */
  */

文件差异内容过多而无法显示
+ 0 - 0
jet/static/jet/css/themes/green/base.css.map


文件差异内容过多而无法显示
+ 0 - 0
jet/static/jet/css/themes/green/jquery-ui.theme.css.map


文件差异内容过多而无法显示
+ 0 - 0
jet/static/jet/css/themes/green/select2.theme.css.map


+ 43 - 0
jet/static/jet/js/main.js

@@ -833,6 +833,44 @@
                     }
                     }
                 });
                 });
             });
             });
+
+            $('.reset-dashboard-link').on('click', function(e) {
+                var buttons = {};
+                var resetDashboard = function () {
+                    var $form = $('#reset-dashboard-form');
+
+                    $.ajax({
+                        url: $form.attr('action'),
+                        method: $form.attr('method'),
+                        dataType: 'json',
+                        data: $form.serialize(),
+                        success: function (result) {
+                            if (result.error) {
+                                return;
+                            }
+
+                            location.reload();
+                        }
+                    });
+                };
+
+                buttons[django.gettext('Yes')] = function() {
+                    resetDashboard();
+                    $(this).dialog('close');
+                };
+
+                buttons[django.gettext('Cancel')] = function() {
+                    $(this).dialog('close');
+                };
+
+                $('#reset-dashboard-dialog').dialog({
+                    resizable: false,
+                    modal: true,
+                    buttons: buttons
+                });
+
+                e.preventDefault();
+            });
         };
         };
 
 
         var initUnsavedChangesWarning = function() {
         var initUnsavedChangesWarning = function() {
@@ -864,6 +902,10 @@
             }
             }
         };
         };
 
 
+        var initScrollbars = function() {
+            $('.sidebar-menu-wrapper').perfectScrollbar();
+        };
+
         initjQueryCaseInsensitiveSelector();
         initjQueryCaseInsensitiveSelector();
         initjQuerySlideFadeToggle();
         initjQuerySlideFadeToggle();
         initFilters();
         initFilters();
@@ -878,5 +920,6 @@
         initTooltips();
         initTooltips();
         initDashboard();
         initDashboard();
         initUnsavedChangesWarning();
         initUnsavedChangesWarning();
+        initScrollbars();
     });
     });
 })(jet.jQuery);
 })(jet.jQuery);

文件差异内容过多而无法显示
+ 0 - 0
jet/static/jet/js/main.min.js


+ 108 - 0
jet/static/jet/vendor/perfect-scrollbar/css/perfect-scrollbar.css

@@ -0,0 +1,108 @@
+/* perfect-scrollbar v0.6.5 */
+.ps-container {
+  -ms-touch-action: none;
+  overflow: hidden !important; }
+  .ps-container.ps-active-x > .ps-scrollbar-x-rail, .ps-container.ps-active-y > .ps-scrollbar-y-rail {
+    display: block; }
+  .ps-container.ps-in-scrolling {
+    pointer-events: none; }
+    .ps-container.ps-in-scrolling.ps-x > .ps-scrollbar-x-rail {
+      background-color: #eee;
+      opacity: 0.9; }
+      .ps-container.ps-in-scrolling.ps-x > .ps-scrollbar-x-rail > .ps-scrollbar-x {
+        background-color: #999; }
+    .ps-container.ps-in-scrolling.ps-y > .ps-scrollbar-y-rail {
+      background-color: #eee;
+      opacity: 0.9; }
+      .ps-container.ps-in-scrolling.ps-y > .ps-scrollbar-y-rail > .ps-scrollbar-y {
+        background-color: #999; }
+  .ps-container > .ps-scrollbar-x-rail {
+    display: none;
+    position: absolute;
+    /* please don't change 'position' */
+    -webkit-border-radius: 4px;
+    -moz-border-radius: 4px;
+    -ms-border-radius: 4px;
+    border-radius: 4px;
+    opacity: 0;
+    -webkit-transition: background-color .2s linear, opacity .2s linear;
+    -moz-transition: background-color .2s linear, opacity .2s linear;
+    -o-transition: background-color .2s linear, opacity .2s linear;
+    transition: background-color .2s linear, opacity .2s linear;
+    bottom: 3px;
+    /* there must be 'bottom' for ps-scrollbar-x-rail */
+    height: 8px;
+    margin: 0 3px; }
+    .ps-container > .ps-scrollbar-x-rail > .ps-scrollbar-x {
+      position: absolute;
+      /* please don't change 'position' */
+      background-color: #aaa;
+      -webkit-border-radius: 4px;
+      -moz-border-radius: 4px;
+      -ms-border-radius: 4px;
+      border-radius: 4px;
+      -webkit-transition: background-color .2s linear;
+      -moz-transition: background-color .2s linear;
+      -o-transition: background-color .2s linear;
+      transition: background-color .2s linear;
+      bottom: 0;
+      /* there must be 'bottom' for ps-scrollbar-x */
+      height: 8px; }
+  .ps-container > .ps-scrollbar-y-rail {
+    display: none;
+    position: absolute;
+    /* please don't change 'position' */
+    -webkit-border-radius: 4px;
+    -moz-border-radius: 4px;
+    -ms-border-radius: 4px;
+    border-radius: 4px;
+    opacity: 0;
+    -webkit-transition: background-color .2s linear, opacity .2s linear;
+    -moz-transition: background-color .2s linear, opacity .2s linear;
+    -o-transition: background-color .2s linear, opacity .2s linear;
+    transition: background-color .2s linear, opacity .2s linear;
+    right: 3px;
+    /* there must be 'right' for ps-scrollbar-y-rail */
+    width: 8px;
+    margin: 3px 0; }
+    .ps-container > .ps-scrollbar-y-rail > .ps-scrollbar-y {
+      position: absolute;
+      /* please don't change 'position' */
+      background-color: #aaa;
+      -webkit-border-radius: 4px;
+      -moz-border-radius: 4px;
+      -ms-border-radius: 4px;
+      border-radius: 4px;
+      -webkit-transition: background-color .2s linear;
+      -moz-transition: background-color .2s linear;
+      -o-transition: background-color .2s linear;
+      transition: background-color .2s linear;
+      right: 0;
+      /* there must be 'right' for ps-scrollbar-y */
+      width: 8px; }
+  .ps-container:hover.ps-in-scrolling {
+    pointer-events: none; }
+    .ps-container:hover.ps-in-scrolling.ps-x > .ps-scrollbar-x-rail {
+      background-color: #eee;
+      opacity: 0.9; }
+      .ps-container:hover.ps-in-scrolling.ps-x > .ps-scrollbar-x-rail > .ps-scrollbar-x {
+        background-color: #999; }
+    .ps-container:hover.ps-in-scrolling.ps-y > .ps-scrollbar-y-rail {
+      background-color: #eee;
+      opacity: 0.9; }
+      .ps-container:hover.ps-in-scrolling.ps-y > .ps-scrollbar-y-rail > .ps-scrollbar-y {
+        background-color: #999; }
+  .ps-container:hover > .ps-scrollbar-x-rail, .ps-container:hover:hover > .ps-scrollbar-y-rail {
+    opacity: 0.6; }
+  .ps-container:hover > .ps-scrollbar-x-rail:hover {
+    background-color: #eee;
+    opacity: 0.9; }
+    .ps-container:hover > .ps-scrollbar-x-rail:hover > .ps-scrollbar-x {
+      background-color: #999; }
+  .ps-container:hover > .ps-scrollbar-y-rail:hover {
+    background-color: #eee;
+    opacity: 0.9; }
+    .ps-container:hover > .ps-scrollbar-y-rail:hover > .ps-scrollbar-y {
+      background-color: #999; }
+
+/*# sourceMappingURL=perfect-scrollbar.css.map */

+ 7 - 0
jet/static/jet/vendor/perfect-scrollbar/css/perfect-scrollbar.css.map

@@ -0,0 +1,7 @@
+{
+"version": 3,
+"mappings": ";AACA,aAAc;EACZ,gBAAgB,EAAE,IAAI;EACtB,QAAQ,EAAE,iBAAiB;EAE3B,kGAA2E;IACzE,OAAO,EAAE,KAAK;EAGhB,6BAAkB;IAChB,cAAc,EAAE,IAAI;IAEpB,yDAA8B;MAC5B,gBAAgB,EAAE,IAAI;MACtB,OAAO,EAAE,GAAG;MAEZ,2EAAoB;QAClB,gBAAgB,EAAE,IAAI;IAI1B,yDAA8B;MAC5B,gBAAgB,EAAE,IAAI;MACtB,OAAO,EAAE,GAAG;MAEZ,2EAAoB;QAClB,gBAAgB,EAAE,IAAI;EAK5B,oCAAyB;IACvB,OAAO,EAAE,IAAI;IACb,QAAQ,EAAE,QAAQ;;IAElB,qBAAqB,EAAE,GAAG;IAC1B,kBAAkB,EAAE,GAAG;IACvB,iBAAiB,EAAE,GAAG;IACtB,aAAa,EAAE,GAAG;IAClB,OAAO,EAAE,CAAC;IACV,kBAAkB,EAAE,+CAA+C;IACnE,eAAe,EAAE,+CAA+C;IAChE,aAAa,EAAE,+CAA+C;IAC9D,UAAU,EAAE,+CAA+C;IAC3D,MAAM,EAAE,GAAG;;IAEX,MAAM,EAAE,GAAG;IACX,MAAM,EAAE,KAAK;IAEb,sDAAoB;MAClB,QAAQ,EAAE,QAAQ;;MAElB,gBAAgB,EAAE,IAAI;MACtB,qBAAqB,EAAE,GAAG;MAC1B,kBAAkB,EAAE,GAAG;MACvB,iBAAiB,EAAE,GAAG;MACtB,aAAa,EAAE,GAAG;MAClB,kBAAkB,EAAE,2BAA2B;MAC/C,eAAe,EAAE,2BAA2B;MAC5C,aAAa,EAAE,2BAA2B;MAC1C,UAAU,EAAE,2BAA2B;MACvC,MAAM,EAAE,CAAC;;MAET,MAAM,EAAE,GAAG;EAIf,oCAAyB;IACvB,OAAO,EAAE,IAAI;IACb,QAAQ,EAAE,QAAQ;;IAElB,qBAAqB,EAAE,GAAG;IAC1B,kBAAkB,EAAE,GAAG;IACvB,iBAAiB,EAAE,GAAG;IACtB,aAAa,EAAE,GAAG;IAClB,OAAO,EAAE,CAAC;IACV,kBAAkB,EAAE,+CAA+C;IACnE,eAAe,EAAE,+CAA+C;IAChE,aAAa,EAAE,+CAA+C;IAC9D,UAAU,EAAE,+CAA+C;IAC3D,KAAK,EAAE,GAAG;;IAEV,KAAK,EAAE,GAAG;IACV,MAAM,EAAE,KAAK;IAEb,sDAAoB;MAClB,QAAQ,EAAE,QAAQ;;MAElB,gBAAgB,EAAE,IAAI;MACtB,qBAAqB,EAAE,GAAG;MAC1B,kBAAkB,EAAE,GAAG;MACvB,iBAAiB,EAAE,GAAG;MACtB,aAAa,EAAE,GAAG;MAClB,kBAAkB,EAAE,2BAA2B;MAC/C,eAAe,EAAE,2BAA2B;MAC5C,aAAa,EAAE,2BAA2B;MAC1C,UAAU,EAAE,2BAA2B;MACvC,KAAK,EAAE,CAAC;;MAER,KAAK,EAAE,GAAG;EAId,mCAAwB;IACtB,cAAc,EAAE,IAAI;IAEpB,+DAA8B;MAC5B,gBAAgB,EAAE,IAAI;MACtB,OAAO,EAAE,GAAG;MAEZ,iFAAoB;QAClB,gBAAgB,EAAE,IAAI;IAI1B,+DAA8B;MAC5B,gBAAgB,EAAE,IAAI;MACtB,OAAO,EAAE,GAAG;MAEZ,iFAAoB;QAClB,gBAAgB,EAAE,IAAI;EAM1B,4FAAyD;IACvD,OAAO,EAAE,GAAG;EAGd,gDAA+B;IAC7B,gBAAgB,EAAE,IAAI;IACtB,OAAO,EAAE,GAAG;IAEZ,kEAAoB;MAClB,gBAAgB,EAAE,IAAI;EAI1B,gDAA+B;IAC7B,gBAAgB,EAAE,IAAI;IACtB,OAAO,EAAE,GAAG;IAEZ,kEAAoB;MAClB,gBAAgB,EAAE,IAAI",
+"sources": ["perfect-scrollbar.scss"],
+"names": [],
+"file": "perfect-scrollbar.css"
+}

+ 149 - 0
jet/static/jet/vendor/perfect-scrollbar/css/perfect-scrollbar.scss

@@ -0,0 +1,149 @@
+/* perfect-scrollbar v0.6.5 */
+.ps-container {
+  -ms-touch-action: none;
+  overflow: hidden !important;
+
+  &.ps-active-x > .ps-scrollbar-x-rail, &.ps-active-y > .ps-scrollbar-y-rail {
+    display: block;
+  }
+
+  &.ps-in-scrolling {
+    pointer-events: none;
+
+    &.ps-x > .ps-scrollbar-x-rail {
+      background-color: #eee;
+      opacity: 0.9;
+
+      & > .ps-scrollbar-x {
+        background-color: #999;
+      }
+    }
+
+    &.ps-y > .ps-scrollbar-y-rail {
+      background-color: #eee;
+      opacity: 0.9;
+
+      & > .ps-scrollbar-y {
+        background-color: #999;
+      }
+    }
+  }
+
+  & > .ps-scrollbar-x-rail {
+    display: none;
+    position: absolute;
+    /* please don't change 'position' */
+    -webkit-border-radius: 4px;
+    -moz-border-radius: 4px;
+    -ms-border-radius: 4px;
+    border-radius: 4px;
+    opacity: 0;
+    -webkit-transition: background-color .2s linear, opacity .2s linear;
+    -moz-transition: background-color .2s linear, opacity .2s linear;
+    -o-transition: background-color .2s linear, opacity .2s linear;
+    transition: background-color .2s linear, opacity .2s linear;
+    bottom: 3px;
+    /* there must be 'bottom' for ps-scrollbar-x-rail */
+    height: 8px;
+    margin: 0 3px;
+
+    & > .ps-scrollbar-x {
+      position: absolute;
+      /* please don't change 'position' */
+      background-color: #aaa;
+      -webkit-border-radius: 4px;
+      -moz-border-radius: 4px;
+      -ms-border-radius: 4px;
+      border-radius: 4px;
+      -webkit-transition: background-color .2s linear;
+      -moz-transition: background-color .2s linear;
+      -o-transition: background-color .2s linear;
+      transition: background-color .2s linear;
+      bottom: 0;
+      /* there must be 'bottom' for ps-scrollbar-x */
+      height: 8px;
+    }
+  }
+
+  & > .ps-scrollbar-y-rail {
+    display: none;
+    position: absolute;
+    /* please don't change 'position' */
+    -webkit-border-radius: 4px;
+    -moz-border-radius: 4px;
+    -ms-border-radius: 4px;
+    border-radius: 4px;
+    opacity: 0;
+    -webkit-transition: background-color .2s linear, opacity .2s linear;
+    -moz-transition: background-color .2s linear, opacity .2s linear;
+    -o-transition: background-color .2s linear, opacity .2s linear;
+    transition: background-color .2s linear, opacity .2s linear;
+    right: 3px;
+    /* there must be 'right' for ps-scrollbar-y-rail */
+    width: 8px;
+    margin: 3px 0;
+
+    & > .ps-scrollbar-y {
+      position: absolute;
+      /* please don't change 'position' */
+      background-color: #aaa;
+      -webkit-border-radius: 4px;
+      -moz-border-radius: 4px;
+      -ms-border-radius: 4px;
+      border-radius: 4px;
+      -webkit-transition: background-color .2s linear;
+      -moz-transition: background-color .2s linear;
+      -o-transition: background-color .2s linear;
+      transition: background-color .2s linear;
+      right: 0;
+      /* there must be 'right' for ps-scrollbar-y */
+      width: 8px;
+    }
+  }
+
+  &:hover.ps-in-scrolling {
+    pointer-events: none;
+
+    &.ps-x > .ps-scrollbar-x-rail {
+      background-color: #eee;
+      opacity: 0.9;
+
+      & > .ps-scrollbar-x {
+        background-color: #999;
+      }
+    }
+
+    &.ps-y > .ps-scrollbar-y-rail {
+      background-color: #eee;
+      opacity: 0.9;
+
+      & > .ps-scrollbar-y {
+        background-color: #999;
+      }
+    }
+  }
+
+  &:hover {
+    & > .ps-scrollbar-x-rail, &:hover > .ps-scrollbar-y-rail {
+      opacity: 0.6;
+    }
+
+    & > .ps-scrollbar-x-rail:hover {
+      background-color: #eee;
+      opacity: 0.9;
+
+      & > .ps-scrollbar-x {
+        background-color: #999;
+      }
+    }
+
+    & > .ps-scrollbar-y-rail:hover {
+      background-color: #eee;
+      opacity: 0.9;
+
+      & > .ps-scrollbar-y {
+        background-color: #999;
+      }
+    }
+  }
+}

+ 1492 - 0
jet/static/jet/vendor/perfect-scrollbar/js/perfect-scrollbar.jquery.js

@@ -0,0 +1,1492 @@
+/* perfect-scrollbar v0.6.5 */
+(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var ps = require('../main')
+  , psInstances = require('../plugin/instances');
+
+function mountJQuery(jQuery) {
+  jQuery.fn.perfectScrollbar = function (settingOrCommand) {
+    return this.each(function () {
+      if (typeof settingOrCommand === 'object' ||
+          typeof settingOrCommand === 'undefined') {
+        // If it's an object or none, initialize.
+        var settings = settingOrCommand;
+
+        if (!psInstances.get(this)) {
+          ps.initialize(this, settings);
+        }
+      } else {
+        // Unless, it may be a command.
+        var command = settingOrCommand;
+
+        if (command === 'update') {
+          ps.update(this);
+        } else if (command === 'destroy') {
+          ps.destroy(this);
+        }
+      }
+
+      return jQuery(this);
+    });
+  };
+}
+
+if (typeof define === 'function' && define.amd) {
+  // AMD. Register as an anonymous module.
+  define(['jquery'], mountJQuery);
+} else {
+  var jq = window.jQuery ? window.jQuery : window.$;
+  if (typeof jq !== 'undefined') {
+    mountJQuery(jq);
+  }
+}
+
+module.exports = mountJQuery;
+
+},{"../main":7,"../plugin/instances":18}],2:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+function oldAdd(element, className) {
+  var classes = element.className.split(' ');
+  if (classes.indexOf(className) < 0) {
+    classes.push(className);
+  }
+  element.className = classes.join(' ');
+}
+
+function oldRemove(element, className) {
+  var classes = element.className.split(' ');
+  var idx = classes.indexOf(className);
+  if (idx >= 0) {
+    classes.splice(idx, 1);
+  }
+  element.className = classes.join(' ');
+}
+
+exports.add = function (element, className) {
+  if (element.classList) {
+    element.classList.add(className);
+  } else {
+    oldAdd(element, className);
+  }
+};
+
+exports.remove = function (element, className) {
+  if (element.classList) {
+    element.classList.remove(className);
+  } else {
+    oldRemove(element, className);
+  }
+};
+
+exports.list = function (element) {
+  if (element.classList) {
+    return element.classList;
+  } else {
+    return element.className.split(' ');
+  }
+};
+
+},{}],3:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var DOM = {};
+
+DOM.e = function (tagName, className) {
+  var element = document.createElement(tagName);
+  element.className = className;
+  return element;
+};
+
+DOM.appendTo = function (child, parent) {
+  parent.appendChild(child);
+  return child;
+};
+
+function cssGet(element, styleName) {
+  return window.getComputedStyle(element)[styleName];
+}
+
+function cssSet(element, styleName, styleValue) {
+  if (typeof styleValue === 'number') {
+    styleValue = styleValue.toString() + 'px';
+  }
+  element.style[styleName] = styleValue;
+  return element;
+}
+
+function cssMultiSet(element, obj) {
+  for (var key in obj) {
+    var val = obj[key];
+    if (typeof val === 'number') {
+      val = val.toString() + 'px';
+    }
+    element.style[key] = val;
+  }
+  return element;
+}
+
+DOM.css = function (element, styleNameOrObject, styleValue) {
+  if (typeof styleNameOrObject === 'object') {
+    // multiple set with object
+    return cssMultiSet(element, styleNameOrObject);
+  } else {
+    if (typeof styleValue === 'undefined') {
+      return cssGet(element, styleNameOrObject);
+    } else {
+      return cssSet(element, styleNameOrObject, styleValue);
+    }
+  }
+};
+
+DOM.matches = function (element, query) {
+  if (typeof element.matches !== 'undefined') {
+    return element.matches(query);
+  } else {
+    if (typeof element.matchesSelector !== 'undefined') {
+      return element.matchesSelector(query);
+    } else if (typeof element.webkitMatchesSelector !== 'undefined') {
+      return element.webkitMatchesSelector(query);
+    } else if (typeof element.mozMatchesSelector !== 'undefined') {
+      return element.mozMatchesSelector(query);
+    } else if (typeof element.msMatchesSelector !== 'undefined') {
+      return element.msMatchesSelector(query);
+    }
+  }
+};
+
+DOM.remove = function (element) {
+  if (typeof element.remove !== 'undefined') {
+    element.remove();
+  } else {
+    if (element.parentNode) {
+      element.parentNode.removeChild(element);
+    }
+  }
+};
+
+DOM.queryChildren = function (element, selector) {
+  return Array.prototype.filter.call(element.childNodes, function (child) {
+    return DOM.matches(child, selector);
+  });
+};
+
+module.exports = DOM;
+
+},{}],4:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var EventElement = function (element) {
+  this.element = element;
+  this.events = {};
+};
+
+EventElement.prototype.bind = function (eventName, handler) {
+  if (typeof this.events[eventName] === 'undefined') {
+    this.events[eventName] = [];
+  }
+  this.events[eventName].push(handler);
+  this.element.addEventListener(eventName, handler, false);
+};
+
+EventElement.prototype.unbind = function (eventName, handler) {
+  var isHandlerProvided = (typeof handler !== 'undefined');
+  this.events[eventName] = this.events[eventName].filter(function (hdlr) {
+    if (isHandlerProvided && hdlr !== handler) {
+      return true;
+    }
+    this.element.removeEventListener(eventName, hdlr, false);
+    return false;
+  }, this);
+};
+
+EventElement.prototype.unbindAll = function () {
+  for (var name in this.events) {
+    this.unbind(name);
+  }
+};
+
+var EventManager = function () {
+  this.eventElements = [];
+};
+
+EventManager.prototype.eventElement = function (element) {
+  var ee = this.eventElements.filter(function (eventElement) {
+    return eventElement.element === element;
+  })[0];
+  if (typeof ee === 'undefined') {
+    ee = new EventElement(element);
+    this.eventElements.push(ee);
+  }
+  return ee;
+};
+
+EventManager.prototype.bind = function (element, eventName, handler) {
+  this.eventElement(element).bind(eventName, handler);
+};
+
+EventManager.prototype.unbind = function (element, eventName, handler) {
+  this.eventElement(element).unbind(eventName, handler);
+};
+
+EventManager.prototype.unbindAll = function () {
+  for (var i = 0; i < this.eventElements.length; i++) {
+    this.eventElements[i].unbindAll();
+  }
+};
+
+EventManager.prototype.once = function (element, eventName, handler) {
+  var ee = this.eventElement(element);
+  var onceHandler = function (e) {
+    ee.unbind(eventName, onceHandler);
+    handler(e);
+  };
+  ee.bind(eventName, onceHandler);
+};
+
+module.exports = EventManager;
+
+},{}],5:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+module.exports = (function () {
+  function s4() {
+    return Math.floor((1 + Math.random()) * 0x10000)
+               .toString(16)
+               .substring(1);
+  }
+  return function () {
+    return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
+           s4() + '-' + s4() + s4() + s4();
+  };
+})();
+
+},{}],6:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var cls = require('./class')
+  , d = require('./dom');
+
+exports.toInt = function (x) {
+  return parseInt(x, 10) || 0;
+};
+
+exports.clone = function (obj) {
+  if (obj === null) {
+    return null;
+  } else if (typeof obj === 'object') {
+    var result = {};
+    for (var key in obj) {
+      result[key] = this.clone(obj[key]);
+    }
+    return result;
+  } else {
+    return obj;
+  }
+};
+
+exports.extend = function (original, source) {
+  var result = this.clone(original);
+  for (var key in source) {
+    result[key] = this.clone(source[key]);
+  }
+  return result;
+};
+
+exports.isEditable = function (el) {
+  return d.matches(el, "input,[contenteditable]") ||
+         d.matches(el, "select,[contenteditable]") ||
+         d.matches(el, "textarea,[contenteditable]") ||
+         d.matches(el, "button,[contenteditable]");
+};
+
+exports.removePsClasses = function (element) {
+  var clsList = cls.list(element);
+  for (var i = 0; i < clsList.length; i++) {
+    var className = clsList[i];
+    if (className.indexOf('ps-') === 0) {
+      cls.remove(element, className);
+    }
+  }
+};
+
+exports.outerWidth = function (element) {
+  return this.toInt(d.css(element, 'width')) +
+         this.toInt(d.css(element, 'paddingLeft')) +
+         this.toInt(d.css(element, 'paddingRight')) +
+         this.toInt(d.css(element, 'borderLeftWidth')) +
+         this.toInt(d.css(element, 'borderRightWidth'));
+};
+
+exports.startScrolling = function (element, axis) {
+  cls.add(element, 'ps-in-scrolling');
+  if (typeof axis !== 'undefined') {
+    cls.add(element, 'ps-' + axis);
+  } else {
+    cls.add(element, 'ps-x');
+    cls.add(element, 'ps-y');
+  }
+};
+
+exports.stopScrolling = function (element, axis) {
+  cls.remove(element, 'ps-in-scrolling');
+  if (typeof axis !== 'undefined') {
+    cls.remove(element, 'ps-' + axis);
+  } else {
+    cls.remove(element, 'ps-x');
+    cls.remove(element, 'ps-y');
+  }
+};
+
+exports.env = {
+  isWebKit: 'WebkitAppearance' in document.documentElement.style,
+  supportsTouch: (('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch),
+  supportsIePointer: window.navigator.msMaxTouchPoints !== null
+};
+
+},{"./class":2,"./dom":3}],7:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var destroy = require('./plugin/destroy')
+  , initialize = require('./plugin/initialize')
+  , update = require('./plugin/update');
+
+module.exports = {
+  initialize: initialize,
+  update: update,
+  destroy: destroy
+};
+
+},{"./plugin/destroy":9,"./plugin/initialize":17,"./plugin/update":20}],8:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+module.exports = {
+  wheelSpeed: 1,
+  wheelPropagation: false,
+  swipePropagation: true,
+  minScrollbarLength: null,
+  maxScrollbarLength: null,
+  useBothWheelAxes: false,
+  useKeyboard: true,
+  suppressScrollX: false,
+  suppressScrollY: false,
+  scrollXMarginOffset: 0,
+  scrollYMarginOffset: 0,
+  stopPropagationOnClick: true
+};
+
+},{}],9:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var d = require('../lib/dom')
+  , h = require('../lib/helper')
+  , instances = require('./instances');
+
+module.exports = function (element) {
+  var i = instances.get(element);
+
+  if (!i) {
+    return;
+  }
+
+  i.event.unbindAll();
+  d.remove(i.scrollbarX);
+  d.remove(i.scrollbarY);
+  d.remove(i.scrollbarXRail);
+  d.remove(i.scrollbarYRail);
+  h.removePsClasses(element);
+
+  instances.remove(element);
+};
+
+},{"../lib/dom":3,"../lib/helper":6,"./instances":18}],10:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var h = require('../../lib/helper')
+  , instances = require('../instances')
+  , updateGeometry = require('../update-geometry');
+
+function bindClickRailHandler(element, i) {
+  function pageOffset(el) {
+    return el.getBoundingClientRect();
+  }
+  var stopPropagation = window.Event.prototype.stopPropagation.bind;
+
+  if (i.settings.stopPropagationOnClick) {
+    i.event.bind(i.scrollbarY, 'click', stopPropagation);
+  }
+  i.event.bind(i.scrollbarYRail, 'click', function (e) {
+    var halfOfScrollbarLength = h.toInt(i.scrollbarYHeight / 2);
+    var positionTop = i.railYRatio * (e.pageY - window.scrollY - pageOffset(i.scrollbarYRail).top - halfOfScrollbarLength);
+    var maxPositionTop = i.railYRatio * (i.railYHeight - i.scrollbarYHeight);
+    var positionRatio = positionTop / maxPositionTop;
+
+    if (positionRatio < 0) {
+      positionRatio = 0;
+    } else if (positionRatio > 1) {
+      positionRatio = 1;
+    }
+
+    element.scrollTop = (i.contentHeight - i.containerHeight) * positionRatio;
+    updateGeometry(element);
+
+    e.stopPropagation();
+  });
+
+  if (i.settings.stopPropagationOnClick) {
+    i.event.bind(i.scrollbarX, 'click', stopPropagation);
+  }
+  i.event.bind(i.scrollbarXRail, 'click', function (e) {
+    var halfOfScrollbarLength = h.toInt(i.scrollbarXWidth / 2);
+    var positionLeft = i.railXRatio * (e.pageX - window.scrollX - pageOffset(i.scrollbarXRail).left - halfOfScrollbarLength);
+    var maxPositionLeft = i.railXRatio * (i.railXWidth - i.scrollbarXWidth);
+    var positionRatio = positionLeft / maxPositionLeft;
+
+    if (positionRatio < 0) {
+      positionRatio = 0;
+    } else if (positionRatio > 1) {
+      positionRatio = 1;
+    }
+
+    element.scrollLeft = ((i.contentWidth - i.containerWidth) * positionRatio) - i.negativeScrollAdjustment;
+    updateGeometry(element);
+
+    e.stopPropagation();
+  });
+}
+
+module.exports = function (element) {
+  var i = instances.get(element);
+  bindClickRailHandler(element, i);
+};
+
+},{"../../lib/helper":6,"../instances":18,"../update-geometry":19}],11:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var d = require('../../lib/dom')
+  , h = require('../../lib/helper')
+  , instances = require('../instances')
+  , updateGeometry = require('../update-geometry');
+
+function bindMouseScrollXHandler(element, i) {
+  var currentLeft = null;
+  var currentPageX = null;
+
+  function updateScrollLeft(deltaX) {
+    var newLeft = currentLeft + (deltaX * i.railXRatio);
+    var maxLeft = i.scrollbarXRail.getBoundingClientRect().left + (i.railXRatio * (i.railXWidth - i.scrollbarXWidth));
+
+    if (newLeft < 0) {
+      i.scrollbarXLeft = 0;
+    } else if (newLeft > maxLeft) {
+      i.scrollbarXLeft = maxLeft;
+    } else {
+      i.scrollbarXLeft = newLeft;
+    }
+
+    var scrollLeft = h.toInt(i.scrollbarXLeft * (i.contentWidth - i.containerWidth) / (i.containerWidth - (i.railXRatio * i.scrollbarXWidth))) - i.negativeScrollAdjustment;
+    element.scrollLeft = scrollLeft;
+  }
+
+  var mouseMoveHandler = function (e) {
+    updateScrollLeft(e.pageX - currentPageX);
+    updateGeometry(element);
+    e.stopPropagation();
+    e.preventDefault();
+  };
+
+  var mouseUpHandler = function () {
+    h.stopScrolling(element, 'x');
+    i.event.unbind(i.ownerDocument, 'mousemove', mouseMoveHandler);
+  };
+
+  i.event.bind(i.scrollbarX, 'mousedown', function (e) {
+    currentPageX = e.pageX;
+    currentLeft = h.toInt(d.css(i.scrollbarX, 'left')) * i.railXRatio;
+    h.startScrolling(element, 'x');
+
+    i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler);
+    i.event.once(i.ownerDocument, 'mouseup', mouseUpHandler);
+
+    e.stopPropagation();
+    e.preventDefault();
+  });
+}
+
+function bindMouseScrollYHandler(element, i) {
+  var currentTop = null;
+  var currentPageY = null;
+
+  function updateScrollTop(deltaY) {
+    var newTop = currentTop + (deltaY * i.railYRatio);
+    var maxTop = i.scrollbarYRail.getBoundingClientRect().top + (i.railYRatio * (i.railYHeight - i.scrollbarYHeight));
+
+    if (newTop < 0) {
+      i.scrollbarYTop = 0;
+    } else if (newTop > maxTop) {
+      i.scrollbarYTop = maxTop;
+    } else {
+      i.scrollbarYTop = newTop;
+    }
+
+    var scrollTop = h.toInt(i.scrollbarYTop * (i.contentHeight - i.containerHeight) / (i.containerHeight - (i.railYRatio * i.scrollbarYHeight)));
+    element.scrollTop = scrollTop;
+  }
+
+  var mouseMoveHandler = function (e) {
+    updateScrollTop(e.pageY - currentPageY);
+    updateGeometry(element);
+    e.stopPropagation();
+    e.preventDefault();
+  };
+
+  var mouseUpHandler = function () {
+    h.stopScrolling(element, 'y');
+    i.event.unbind(i.ownerDocument, 'mousemove', mouseMoveHandler);
+  };
+
+  i.event.bind(i.scrollbarY, 'mousedown', function (e) {
+    currentPageY = e.pageY;
+    currentTop = h.toInt(d.css(i.scrollbarY, 'top')) * i.railYRatio;
+    h.startScrolling(element, 'y');
+
+    i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler);
+    i.event.once(i.ownerDocument, 'mouseup', mouseUpHandler);
+
+    e.stopPropagation();
+    e.preventDefault();
+  });
+}
+
+module.exports = function (element) {
+  var i = instances.get(element);
+  bindMouseScrollXHandler(element, i);
+  bindMouseScrollYHandler(element, i);
+};
+
+},{"../../lib/dom":3,"../../lib/helper":6,"../instances":18,"../update-geometry":19}],12:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var h = require('../../lib/helper')
+  , instances = require('../instances')
+  , updateGeometry = require('../update-geometry');
+
+function bindKeyboardHandler(element, i) {
+  var hovered = false;
+  i.event.bind(element, 'mouseenter', function () {
+    hovered = true;
+  });
+  i.event.bind(element, 'mouseleave', function () {
+    hovered = false;
+  });
+
+  var shouldPrevent = false;
+  function shouldPreventDefault(deltaX, deltaY) {
+    var scrollTop = element.scrollTop;
+    if (deltaX === 0) {
+      if (!i.scrollbarYActive) {
+        return false;
+      }
+      if ((scrollTop === 0 && deltaY > 0) || (scrollTop >= i.contentHeight - i.containerHeight && deltaY < 0)) {
+        return !i.settings.wheelPropagation;
+      }
+    }
+
+    var scrollLeft = element.scrollLeft;
+    if (deltaY === 0) {
+      if (!i.scrollbarXActive) {
+        return false;
+      }
+      if ((scrollLeft === 0 && deltaX < 0) || (scrollLeft >= i.contentWidth - i.containerWidth && deltaX > 0)) {
+        return !i.settings.wheelPropagation;
+      }
+    }
+    return true;
+  }
+
+  i.event.bind(i.ownerDocument, 'keydown', function (e) {
+    if (e.isDefaultPrevented && e.isDefaultPrevented()) {
+      return;
+    }
+
+    if (!hovered) {
+      return;
+    }
+
+    var activeElement = document.activeElement ? document.activeElement : i.ownerDocument.activeElement;
+    if (activeElement) {
+      // go deeper if element is a webcomponent
+      while (activeElement.shadowRoot) {
+        activeElement = activeElement.shadowRoot.activeElement;
+      }
+      if (h.isEditable(activeElement)) {
+        return;
+      }
+    }
+
+    var deltaX = 0;
+    var deltaY = 0;
+
+    switch (e.which) {
+    case 37: // left
+      deltaX = -30;
+      break;
+    case 38: // up
+      deltaY = 30;
+      break;
+    case 39: // right
+      deltaX = 30;
+      break;
+    case 40: // down
+      deltaY = -30;
+      break;
+    case 33: // page up
+      deltaY = 90;
+      break;
+    case 32: // space bar
+      if (e.shiftKey) {
+        deltaY = 90;
+      } else {
+        deltaY = -90;
+      }
+      break;
+    case 34: // page down
+      deltaY = -90;
+      break;
+    case 35: // end
+      if (e.ctrlKey) {
+        deltaY = -i.contentHeight;
+      } else {
+        deltaY = -i.containerHeight;
+      }
+      break;
+    case 36: // home
+      if (e.ctrlKey) {
+        deltaY = element.scrollTop;
+      } else {
+        deltaY = i.containerHeight;
+      }
+      break;
+    default:
+      return;
+    }
+
+    element.scrollTop = element.scrollTop - deltaY;
+    element.scrollLeft = element.scrollLeft + deltaX;
+    updateGeometry(element);
+
+    shouldPrevent = shouldPreventDefault(deltaX, deltaY);
+    if (shouldPrevent) {
+      e.preventDefault();
+    }
+  });
+}
+
+module.exports = function (element) {
+  var i = instances.get(element);
+  bindKeyboardHandler(element, i);
+};
+
+},{"../../lib/helper":6,"../instances":18,"../update-geometry":19}],13:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var h = require('../../lib/helper')
+  , instances = require('../instances')
+  , updateGeometry = require('../update-geometry');
+
+function bindMouseWheelHandler(element, i) {
+  var shouldPrevent = false;
+
+  function shouldPreventDefault(deltaX, deltaY) {
+    var scrollTop = element.scrollTop;
+    if (deltaX === 0) {
+      if (!i.scrollbarYActive) {
+        return false;
+      }
+      if ((scrollTop === 0 && deltaY > 0) || (scrollTop >= i.contentHeight - i.containerHeight && deltaY < 0)) {
+        return !i.settings.wheelPropagation;
+      }
+    }
+
+    var scrollLeft = element.scrollLeft;
+    if (deltaY === 0) {
+      if (!i.scrollbarXActive) {
+        return false;
+      }
+      if ((scrollLeft === 0 && deltaX < 0) || (scrollLeft >= i.contentWidth - i.containerWidth && deltaX > 0)) {
+        return !i.settings.wheelPropagation;
+      }
+    }
+    return true;
+  }
+
+  function getDeltaFromEvent(e) {
+    var deltaX = e.deltaX;
+    var deltaY = -1 * e.deltaY;
+
+    if (typeof deltaX === "undefined" || typeof deltaY === "undefined") {
+      // OS X Safari
+      deltaX = -1 * e.wheelDeltaX / 6;
+      deltaY = e.wheelDeltaY / 6;
+    }
+
+    if (e.deltaMode && e.deltaMode === 1) {
+      // Firefox in deltaMode 1: Line scrolling
+      deltaX *= 10;
+      deltaY *= 10;
+    }
+
+    if (deltaX !== deltaX && deltaY !== deltaY/* NaN checks */) {
+      // IE in some mouse drivers
+      deltaX = 0;
+      deltaY = e.wheelDelta;
+    }
+
+    return [deltaX, deltaY];
+  }
+
+  function shouldBeConsumedByTextarea(deltaX, deltaY) {
+    var hoveredTextarea = element.querySelector('textarea:hover');
+    if (hoveredTextarea) {
+      var maxScrollTop = hoveredTextarea.scrollHeight - hoveredTextarea.clientHeight;
+      if (maxScrollTop > 0) {
+        if (!(hoveredTextarea.scrollTop === 0 && deltaY > 0) &&
+            !(hoveredTextarea.scrollTop === maxScrollTop && deltaY < 0)) {
+          return true;
+        }
+      }
+      var maxScrollLeft = hoveredTextarea.scrollLeft - hoveredTextarea.clientWidth;
+      if (maxScrollLeft > 0) {
+        if (!(hoveredTextarea.scrollLeft === 0 && deltaX < 0) &&
+            !(hoveredTextarea.scrollLeft === maxScrollLeft && deltaX > 0)) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  function mousewheelHandler(e) {
+    // FIXME: this is a quick fix for the select problem in FF and IE.
+    // If there comes an effective way to deal with the problem,
+    // this lines should be removed.
+    if (!h.env.isWebKit && element.querySelector('select:focus')) {
+      return;
+    }
+
+    var delta = getDeltaFromEvent(e);
+
+    var deltaX = delta[0];
+    var deltaY = delta[1];
+
+    if (shouldBeConsumedByTextarea(deltaX, deltaY)) {
+      return;
+    }
+
+    shouldPrevent = false;
+    if (!i.settings.useBothWheelAxes) {
+      // deltaX will only be used for horizontal scrolling and deltaY will
+      // only be used for vertical scrolling - this is the default
+      element.scrollTop = element.scrollTop - (deltaY * i.settings.wheelSpeed);
+      element.scrollLeft = element.scrollLeft + (deltaX * i.settings.wheelSpeed);
+    } else if (i.scrollbarYActive && !i.scrollbarXActive) {
+      // only vertical scrollbar is active and useBothWheelAxes option is
+      // active, so let's scroll vertical bar using both mouse wheel axes
+      if (deltaY) {
+        element.scrollTop = element.scrollTop - (deltaY * i.settings.wheelSpeed);
+      } else {
+        element.scrollTop = element.scrollTop + (deltaX * i.settings.wheelSpeed);
+      }
+      shouldPrevent = true;
+    } else if (i.scrollbarXActive && !i.scrollbarYActive) {
+      // useBothWheelAxes and only horizontal bar is active, so use both
+      // wheel axes for horizontal bar
+      if (deltaX) {
+        element.scrollLeft = element.scrollLeft + (deltaX * i.settings.wheelSpeed);
+      } else {
+        element.scrollLeft = element.scrollLeft - (deltaY * i.settings.wheelSpeed);
+      }
+      shouldPrevent = true;
+    }
+
+    updateGeometry(element);
+
+    shouldPrevent = (shouldPrevent || shouldPreventDefault(deltaX, deltaY));
+    if (shouldPrevent) {
+      e.stopPropagation();
+      e.preventDefault();
+    }
+  }
+
+  if (typeof window.onwheel !== "undefined") {
+    i.event.bind(element, 'wheel', mousewheelHandler);
+  } else if (typeof window.onmousewheel !== "undefined") {
+    i.event.bind(element, 'mousewheel', mousewheelHandler);
+  }
+}
+
+module.exports = function (element) {
+  var i = instances.get(element);
+  bindMouseWheelHandler(element, i);
+};
+
+},{"../../lib/helper":6,"../instances":18,"../update-geometry":19}],14:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var instances = require('../instances')
+  , updateGeometry = require('../update-geometry');
+
+function bindNativeScrollHandler(element, i) {
+  i.event.bind(element, 'scroll', function () {
+    updateGeometry(element);
+  });
+}
+
+module.exports = function (element) {
+  var i = instances.get(element);
+  bindNativeScrollHandler(element, i);
+};
+
+},{"../instances":18,"../update-geometry":19}],15:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var h = require('../../lib/helper')
+  , instances = require('../instances')
+  , updateGeometry = require('../update-geometry');
+
+function bindSelectionHandler(element, i) {
+  function getRangeNode() {
+    var selection = window.getSelection ? window.getSelection() :
+                    document.getSelection ? document.getSelection() : '';
+    if (selection.toString().length === 0) {
+      return null;
+    } else {
+      return selection.getRangeAt(0).commonAncestorContainer;
+    }
+  }
+
+  var scrollingLoop = null;
+  var scrollDiff = {top: 0, left: 0};
+  function startScrolling() {
+    if (!scrollingLoop) {
+      scrollingLoop = setInterval(function () {
+        if (!instances.get(element)) {
+          clearInterval(scrollingLoop);
+          return;
+        }
+
+        element.scrollTop = element.scrollTop + scrollDiff.top;
+        element.scrollLeft = element.scrollLeft + scrollDiff.left;
+        updateGeometry(element);
+      }, 50); // every .1 sec
+    }
+  }
+  function stopScrolling() {
+    if (scrollingLoop) {
+      clearInterval(scrollingLoop);
+      scrollingLoop = null;
+    }
+    h.stopScrolling(element);
+  }
+
+  var isSelected = false;
+  i.event.bind(i.ownerDocument, 'selectionchange', function () {
+    if (element.contains(getRangeNode())) {
+      isSelected = true;
+    } else {
+      isSelected = false;
+      stopScrolling();
+    }
+  });
+  i.event.bind(window, 'mouseup', function () {
+    if (isSelected) {
+      isSelected = false;
+      stopScrolling();
+    }
+  });
+
+  i.event.bind(window, 'mousemove', function (e) {
+    if (isSelected) {
+      var mousePosition = {x: e.pageX, y: e.pageY};
+      var containerGeometry = {
+        left: element.offsetLeft,
+        right: element.offsetLeft + element.offsetWidth,
+        top: element.offsetTop,
+        bottom: element.offsetTop + element.offsetHeight
+      };
+
+      if (mousePosition.x < containerGeometry.left + 3) {
+        scrollDiff.left = -5;
+        h.startScrolling(element, 'x');
+      } else if (mousePosition.x > containerGeometry.right - 3) {
+        scrollDiff.left = 5;
+        h.startScrolling(element, 'x');
+      } else {
+        scrollDiff.left = 0;
+      }
+
+      if (mousePosition.y < containerGeometry.top + 3) {
+        if (containerGeometry.top + 3 - mousePosition.y < 5) {
+          scrollDiff.top = -5;
+        } else {
+          scrollDiff.top = -20;
+        }
+        h.startScrolling(element, 'y');
+      } else if (mousePosition.y > containerGeometry.bottom - 3) {
+        if (mousePosition.y - containerGeometry.bottom + 3 < 5) {
+          scrollDiff.top = 5;
+        } else {
+          scrollDiff.top = 20;
+        }
+        h.startScrolling(element, 'y');
+      } else {
+        scrollDiff.top = 0;
+      }
+
+      if (scrollDiff.top === 0 && scrollDiff.left === 0) {
+        stopScrolling();
+      } else {
+        startScrolling();
+      }
+    }
+  });
+}
+
+module.exports = function (element) {
+  var i = instances.get(element);
+  bindSelectionHandler(element, i);
+};
+
+},{"../../lib/helper":6,"../instances":18,"../update-geometry":19}],16:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var instances = require('../instances')
+  , updateGeometry = require('../update-geometry');
+
+function bindTouchHandler(element, i, supportsTouch, supportsIePointer) {
+  function shouldPreventDefault(deltaX, deltaY) {
+    var scrollTop = element.scrollTop;
+    var scrollLeft = element.scrollLeft;
+    var magnitudeX = Math.abs(deltaX);
+    var magnitudeY = Math.abs(deltaY);
+
+    if (magnitudeY > magnitudeX) {
+      // user is perhaps trying to swipe up/down the page
+
+      if (((deltaY < 0) && (scrollTop === i.contentHeight - i.containerHeight)) ||
+          ((deltaY > 0) && (scrollTop === 0))) {
+        return !i.settings.swipePropagation;
+      }
+    } else if (magnitudeX > magnitudeY) {
+      // user is perhaps trying to swipe left/right across the page
+
+      if (((deltaX < 0) && (scrollLeft === i.contentWidth - i.containerWidth)) ||
+          ((deltaX > 0) && (scrollLeft === 0))) {
+        return !i.settings.swipePropagation;
+      }
+    }
+
+    return true;
+  }
+
+  function applyTouchMove(differenceX, differenceY) {
+    element.scrollTop = element.scrollTop - differenceY;
+    element.scrollLeft = element.scrollLeft - differenceX;
+
+    updateGeometry(element);
+  }
+
+  var startOffset = {};
+  var startTime = 0;
+  var speed = {};
+  var easingLoop = null;
+  var inGlobalTouch = false;
+  var inLocalTouch = false;
+
+  function globalTouchStart() {
+    inGlobalTouch = true;
+  }
+  function globalTouchEnd() {
+    inGlobalTouch = false;
+  }
+
+  function getTouch(e) {
+    if (e.targetTouches) {
+      return e.targetTouches[0];
+    } else {
+      // Maybe IE pointer
+      return e;
+    }
+  }
+  function shouldHandle(e) {
+    if (e.targetTouches && e.targetTouches.length === 1) {
+      return true;
+    }
+    if (e.pointerType && e.pointerType !== 'mouse' && e.pointerType !== e.MSPOINTER_TYPE_MOUSE) {
+      return true;
+    }
+    return false;
+  }
+  function touchStart(e) {
+    if (shouldHandle(e)) {
+      inLocalTouch = true;
+
+      var touch = getTouch(e);
+
+      startOffset.pageX = touch.pageX;
+      startOffset.pageY = touch.pageY;
+
+      startTime = (new Date()).getTime();
+
+      if (easingLoop !== null) {
+        clearInterval(easingLoop);
+      }
+
+      e.stopPropagation();
+    }
+  }
+  function touchMove(e) {
+    if (!inGlobalTouch && inLocalTouch && shouldHandle(e)) {
+      var touch = getTouch(e);
+
+      var currentOffset = {pageX: touch.pageX, pageY: touch.pageY};
+
+      var differenceX = currentOffset.pageX - startOffset.pageX;
+      var differenceY = currentOffset.pageY - startOffset.pageY;
+
+      applyTouchMove(differenceX, differenceY);
+      startOffset = currentOffset;
+
+      var currentTime = (new Date()).getTime();
+
+      var timeGap = currentTime - startTime;
+      if (timeGap > 0) {
+        speed.x = differenceX / timeGap;
+        speed.y = differenceY / timeGap;
+        startTime = currentTime;
+      }
+
+      if (shouldPreventDefault(differenceX, differenceY)) {
+        e.stopPropagation();
+        e.preventDefault();
+      }
+    }
+  }
+  function touchEnd() {
+    if (!inGlobalTouch && inLocalTouch) {
+      inLocalTouch = false;
+
+      clearInterval(easingLoop);
+      easingLoop = setInterval(function () {
+        if (!instances.get(element)) {
+          clearInterval(easingLoop);
+          return;
+        }
+
+        if (Math.abs(speed.x) < 0.01 && Math.abs(speed.y) < 0.01) {
+          clearInterval(easingLoop);
+          return;
+        }
+
+        applyTouchMove(speed.x * 30, speed.y * 30);
+
+        speed.x *= 0.8;
+        speed.y *= 0.8;
+      }, 10);
+    }
+  }
+
+  if (supportsTouch) {
+    i.event.bind(window, 'touchstart', globalTouchStart);
+    i.event.bind(window, 'touchend', globalTouchEnd);
+    i.event.bind(element, 'touchstart', touchStart);
+    i.event.bind(element, 'touchmove', touchMove);
+    i.event.bind(element, 'touchend', touchEnd);
+  }
+
+  if (supportsIePointer) {
+    if (window.PointerEvent) {
+      i.event.bind(window, 'pointerdown', globalTouchStart);
+      i.event.bind(window, 'pointerup', globalTouchEnd);
+      i.event.bind(element, 'pointerdown', touchStart);
+      i.event.bind(element, 'pointermove', touchMove);
+      i.event.bind(element, 'pointerup', touchEnd);
+    } else if (window.MSPointerEvent) {
+      i.event.bind(window, 'MSPointerDown', globalTouchStart);
+      i.event.bind(window, 'MSPointerUp', globalTouchEnd);
+      i.event.bind(element, 'MSPointerDown', touchStart);
+      i.event.bind(element, 'MSPointerMove', touchMove);
+      i.event.bind(element, 'MSPointerUp', touchEnd);
+    }
+  }
+}
+
+module.exports = function (element, supportsTouch, supportsIePointer) {
+  var i = instances.get(element);
+  bindTouchHandler(element, i, supportsTouch, supportsIePointer);
+};
+
+},{"../instances":18,"../update-geometry":19}],17:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var cls = require('../lib/class')
+  , h = require('../lib/helper')
+  , instances = require('./instances')
+  , updateGeometry = require('./update-geometry');
+
+// Handlers
+var clickRailHandler = require('./handler/click-rail')
+  , dragScrollbarHandler = require('./handler/drag-scrollbar')
+  , keyboardHandler = require('./handler/keyboard')
+  , mouseWheelHandler = require('./handler/mouse-wheel')
+  , nativeScrollHandler = require('./handler/native-scroll')
+  , selectionHandler = require('./handler/selection')
+  , touchHandler = require('./handler/touch');
+
+module.exports = function (element, userSettings) {
+  userSettings = typeof userSettings === 'object' ? userSettings : {};
+
+  cls.add(element, 'ps-container');
+
+  // Create a plugin instance.
+  var i = instances.add(element);
+
+  i.settings = h.extend(i.settings, userSettings);
+
+  clickRailHandler(element);
+  dragScrollbarHandler(element);
+  mouseWheelHandler(element);
+  nativeScrollHandler(element);
+  selectionHandler(element);
+
+  if (h.env.supportsTouch || h.env.supportsIePointer) {
+    touchHandler(element, h.env.supportsTouch, h.env.supportsIePointer);
+  }
+  if (i.settings.useKeyboard) {
+    keyboardHandler(element);
+  }
+
+  updateGeometry(element);
+};
+
+},{"../lib/class":2,"../lib/helper":6,"./handler/click-rail":10,"./handler/drag-scrollbar":11,"./handler/keyboard":12,"./handler/mouse-wheel":13,"./handler/native-scroll":14,"./handler/selection":15,"./handler/touch":16,"./instances":18,"./update-geometry":19}],18:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var d = require('../lib/dom')
+  , defaultSettings = require('./default-setting')
+  , EventManager = require('../lib/event-manager')
+  , guid = require('../lib/guid')
+  , h = require('../lib/helper');
+
+var instances = {};
+
+function Instance(element) {
+  var i = this;
+
+  i.settings = h.clone(defaultSettings);
+  i.containerWidth = null;
+  i.containerHeight = null;
+  i.contentWidth = null;
+  i.contentHeight = null;
+
+  i.isRtl = d.css(element, 'direction') === "rtl";
+  i.isNegativeScroll = (function () {
+    var originalScrollLeft = element.scrollLeft;
+    var result = null;
+    element.scrollLeft = -1;
+    result = element.scrollLeft < 0;
+    element.scrollLeft = originalScrollLeft;
+    return result;
+  })();
+  i.negativeScrollAdjustment = i.isNegativeScroll ? element.scrollWidth - element.clientWidth : 0;
+  i.event = new EventManager();
+  i.ownerDocument = element.ownerDocument || document;
+
+  i.scrollbarXRail = d.appendTo(d.e('div', 'ps-scrollbar-x-rail'), element);
+  i.scrollbarX = d.appendTo(d.e('div', 'ps-scrollbar-x'), i.scrollbarXRail);
+  i.scrollbarXActive = null;
+  i.scrollbarXWidth = null;
+  i.scrollbarXLeft = null;
+  i.scrollbarXBottom = h.toInt(d.css(i.scrollbarXRail, 'bottom'));
+  i.isScrollbarXUsingBottom = i.scrollbarXBottom === i.scrollbarXBottom; // !isNaN
+  i.scrollbarXTop = i.isScrollbarXUsingBottom ? null : h.toInt(d.css(i.scrollbarXRail, 'top'));
+  i.railBorderXWidth = h.toInt(d.css(i.scrollbarXRail, 'borderLeftWidth')) + h.toInt(d.css(i.scrollbarXRail, 'borderRightWidth'));
+  // Set rail to display:block to calculate margins
+  d.css(i.scrollbarXRail, 'display', 'block');
+  i.railXMarginWidth = h.toInt(d.css(i.scrollbarXRail, 'marginLeft')) + h.toInt(d.css(i.scrollbarXRail, 'marginRight'));
+  d.css(i.scrollbarXRail, 'display', '');
+  i.railXWidth = null;
+  i.railXRatio = null;
+
+  i.scrollbarYRail = d.appendTo(d.e('div', 'ps-scrollbar-y-rail'), element);
+  i.scrollbarY = d.appendTo(d.e('div', 'ps-scrollbar-y'), i.scrollbarYRail);
+  i.scrollbarYActive = null;
+  i.scrollbarYHeight = null;
+  i.scrollbarYTop = null;
+  i.scrollbarYRight = h.toInt(d.css(i.scrollbarYRail, 'right'));
+  i.isScrollbarYUsingRight = i.scrollbarYRight === i.scrollbarYRight; // !isNaN
+  i.scrollbarYLeft = i.isScrollbarYUsingRight ? null : h.toInt(d.css(i.scrollbarYRail, 'left'));
+  i.scrollbarYOuterWidth = i.isRtl ? h.outerWidth(i.scrollbarY) : null;
+  i.railBorderYWidth = h.toInt(d.css(i.scrollbarYRail, 'borderTopWidth')) + h.toInt(d.css(i.scrollbarYRail, 'borderBottomWidth'));
+  d.css(i.scrollbarYRail, 'display', 'block');
+  i.railYMarginHeight = h.toInt(d.css(i.scrollbarYRail, 'marginTop')) + h.toInt(d.css(i.scrollbarYRail, 'marginBottom'));
+  d.css(i.scrollbarYRail, 'display', '');
+  i.railYHeight = null;
+  i.railYRatio = null;
+}
+
+function getId(element) {
+  if (typeof element.dataset === 'undefined') {
+    return element.getAttribute('data-ps-id');
+  } else {
+    return element.dataset.psId;
+  }
+}
+
+function setId(element, id) {
+  if (typeof element.dataset === 'undefined') {
+    element.setAttribute('data-ps-id', id);
+  } else {
+    element.dataset.psId = id;
+  }
+}
+
+function removeId(element) {
+  if (typeof element.dataset === 'undefined') {
+    element.removeAttribute('data-ps-id');
+  } else {
+    delete element.dataset.psId;
+  }
+}
+
+exports.add = function (element) {
+  var newId = guid();
+  setId(element, newId);
+  instances[newId] = new Instance(element);
+  return instances[newId];
+};
+
+exports.remove = function (element) {
+  delete instances[getId(element)];
+  removeId(element);
+};
+
+exports.get = function (element) {
+  return instances[getId(element)];
+};
+
+},{"../lib/dom":3,"../lib/event-manager":4,"../lib/guid":5,"../lib/helper":6,"./default-setting":8}],19:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var cls = require('../lib/class')
+  , d = require('../lib/dom')
+  , h = require('../lib/helper')
+  , instances = require('./instances');
+
+function getThumbSize(i, thumbSize) {
+  if (i.settings.minScrollbarLength) {
+    thumbSize = Math.max(thumbSize, i.settings.minScrollbarLength);
+  }
+  if (i.settings.maxScrollbarLength) {
+    thumbSize = Math.min(thumbSize, i.settings.maxScrollbarLength);
+  }
+  return thumbSize;
+}
+
+function updateCss(element, i) {
+  var xRailOffset = {width: i.railXWidth};
+  if (i.isRtl) {
+    xRailOffset.left = i.negativeScrollAdjustment + element.scrollLeft + i.containerWidth - i.contentWidth;
+  } else {
+    xRailOffset.left = element.scrollLeft;
+  }
+  if (i.isScrollbarXUsingBottom) {
+    xRailOffset.bottom = i.scrollbarXBottom - element.scrollTop;
+  } else {
+    xRailOffset.top = i.scrollbarXTop + element.scrollTop;
+  }
+  d.css(i.scrollbarXRail, xRailOffset);
+
+  var yRailOffset = {top: element.scrollTop, height: i.railYHeight};
+  if (i.isScrollbarYUsingRight) {
+    if (i.isRtl) {
+      yRailOffset.right = i.contentWidth - (i.negativeScrollAdjustment + element.scrollLeft) - i.scrollbarYRight - i.scrollbarYOuterWidth;
+    } else {
+      yRailOffset.right = i.scrollbarYRight - element.scrollLeft;
+    }
+  } else {
+    if (i.isRtl) {
+      yRailOffset.left = i.negativeScrollAdjustment + element.scrollLeft + i.containerWidth * 2 - i.contentWidth - i.scrollbarYLeft - i.scrollbarYOuterWidth;
+    } else {
+      yRailOffset.left = i.scrollbarYLeft + element.scrollLeft;
+    }
+  }
+  d.css(i.scrollbarYRail, yRailOffset);
+
+  d.css(i.scrollbarX, {left: i.scrollbarXLeft, width: i.scrollbarXWidth - i.railBorderXWidth});
+  d.css(i.scrollbarY, {top: i.scrollbarYTop, height: i.scrollbarYHeight - i.railBorderYWidth});
+}
+
+module.exports = function (element) {
+  var i = instances.get(element);
+
+  i.containerWidth = element.clientWidth;
+  i.containerHeight = element.clientHeight;
+  i.contentWidth = element.scrollWidth;
+  i.contentHeight = element.scrollHeight;
+
+  var existingRails;
+  if (!element.contains(i.scrollbarXRail)) {
+    existingRails = d.queryChildren(element, '.ps-scrollbar-x-rail');
+    if (existingRails.length > 0) {
+      existingRails.forEach(function (rail) {
+        d.remove(rail);
+      });
+    }
+    d.appendTo(i.scrollbarXRail, element);
+  }
+  if (!element.contains(i.scrollbarYRail)) {
+    existingRails = d.queryChildren(element, '.ps-scrollbar-y-rail');
+    if (existingRails.length > 0) {
+      existingRails.forEach(function (rail) {
+        d.remove(rail);
+      });
+    }
+    d.appendTo(i.scrollbarYRail, element);
+  }
+
+  if (!i.settings.suppressScrollX && i.containerWidth + i.settings.scrollXMarginOffset < i.contentWidth) {
+    i.scrollbarXActive = true;
+    i.railXWidth = i.containerWidth - i.railXMarginWidth;
+    i.railXRatio = i.containerWidth / i.railXWidth;
+    i.scrollbarXWidth = getThumbSize(i, h.toInt(i.railXWidth * i.containerWidth / i.contentWidth));
+    i.scrollbarXLeft = h.toInt((i.negativeScrollAdjustment + element.scrollLeft) * (i.railXWidth - i.scrollbarXWidth) / (i.contentWidth - i.containerWidth));
+  } else {
+    i.scrollbarXActive = false;
+    i.scrollbarXWidth = 0;
+    i.scrollbarXLeft = 0;
+    element.scrollLeft = 0;
+  }
+
+  if (!i.settings.suppressScrollY && i.containerHeight + i.settings.scrollYMarginOffset < i.contentHeight) {
+    i.scrollbarYActive = true;
+    i.railYHeight = i.containerHeight - i.railYMarginHeight;
+    i.railYRatio = i.containerHeight / i.railYHeight;
+    i.scrollbarYHeight = getThumbSize(i, h.toInt(i.railYHeight * i.containerHeight / i.contentHeight));
+    i.scrollbarYTop = h.toInt(element.scrollTop * (i.railYHeight - i.scrollbarYHeight) / (i.contentHeight - i.containerHeight));
+  } else {
+    i.scrollbarYActive = false;
+    i.scrollbarYHeight = 0;
+    i.scrollbarYTop = 0;
+    element.scrollTop = 0;
+  }
+
+  if (i.scrollbarXLeft >= i.railXWidth - i.scrollbarXWidth) {
+    i.scrollbarXLeft = i.railXWidth - i.scrollbarXWidth;
+  }
+  if (i.scrollbarYTop >= i.railYHeight - i.scrollbarYHeight) {
+    i.scrollbarYTop = i.railYHeight - i.scrollbarYHeight;
+  }
+
+  updateCss(element, i);
+
+  cls[i.scrollbarXActive ? 'add' : 'remove'](element, 'ps-active-x');
+  cls[i.scrollbarYActive ? 'add' : 'remove'](element, 'ps-active-y');
+};
+
+},{"../lib/class":2,"../lib/dom":3,"../lib/helper":6,"./instances":18}],20:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var d = require('../lib/dom')
+  , h = require('../lib/helper')
+  , instances = require('./instances')
+  , updateGeometry = require('./update-geometry');
+
+module.exports = function (element) {
+  var i = instances.get(element);
+
+  if (!i) {
+    return;
+  }
+
+  // Recalcuate negative scrollLeft adjustment
+  i.negativeScrollAdjustment = i.isNegativeScroll ? element.scrollWidth - element.clientWidth : 0;
+
+  // Recalculate rail margins
+  d.css(i.scrollbarXRail, 'display', 'block');
+  d.css(i.scrollbarYRail, 'display', 'block');
+  i.railXMarginWidth = h.toInt(d.css(i.scrollbarXRail, 'marginLeft')) + h.toInt(d.css(i.scrollbarXRail, 'marginRight'));
+  i.railYMarginHeight = h.toInt(d.css(i.scrollbarYRail, 'marginTop')) + h.toInt(d.css(i.scrollbarYRail, 'marginBottom'));
+
+  // Hide scrollbars not to affect scrollWidth and scrollHeight
+  d.css(i.scrollbarXRail, 'display', 'none');
+  d.css(i.scrollbarYRail, 'display', 'none');
+
+  updateGeometry(element);
+
+  d.css(i.scrollbarXRail, 'display', '');
+  d.css(i.scrollbarYRail, 'display', '');
+};
+
+},{"../lib/dom":3,"../lib/helper":6,"./instances":18,"./update-geometry":19}]},{},[1]);

文件差异内容过多而无法显示
+ 1 - 0
jet/static/jet/vendor/perfect-scrollbar/js/perfect-scrollbar.jquery.min.js


+ 1463 - 0
jet/static/jet/vendor/perfect-scrollbar/js/perfect-scrollbar.js

@@ -0,0 +1,1463 @@
+/* perfect-scrollbar v0.6.5 */
+(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var ps = require('../main');
+
+if (typeof define === 'function' && define.amd) {
+  // AMD
+  define(ps);
+} else {
+  // Add to a global object.
+  window.PerfectScrollbar = ps;
+  if (typeof window.Ps === 'undefined') {
+    window.Ps = ps;
+  }
+}
+
+},{"../main":7}],2:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+function oldAdd(element, className) {
+  var classes = element.className.split(' ');
+  if (classes.indexOf(className) < 0) {
+    classes.push(className);
+  }
+  element.className = classes.join(' ');
+}
+
+function oldRemove(element, className) {
+  var classes = element.className.split(' ');
+  var idx = classes.indexOf(className);
+  if (idx >= 0) {
+    classes.splice(idx, 1);
+  }
+  element.className = classes.join(' ');
+}
+
+exports.add = function (element, className) {
+  if (element.classList) {
+    element.classList.add(className);
+  } else {
+    oldAdd(element, className);
+  }
+};
+
+exports.remove = function (element, className) {
+  if (element.classList) {
+    element.classList.remove(className);
+  } else {
+    oldRemove(element, className);
+  }
+};
+
+exports.list = function (element) {
+  if (element.classList) {
+    return element.classList;
+  } else {
+    return element.className.split(' ');
+  }
+};
+
+},{}],3:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var DOM = {};
+
+DOM.e = function (tagName, className) {
+  var element = document.createElement(tagName);
+  element.className = className;
+  return element;
+};
+
+DOM.appendTo = function (child, parent) {
+  parent.appendChild(child);
+  return child;
+};
+
+function cssGet(element, styleName) {
+  return window.getComputedStyle(element)[styleName];
+}
+
+function cssSet(element, styleName, styleValue) {
+  if (typeof styleValue === 'number') {
+    styleValue = styleValue.toString() + 'px';
+  }
+  element.style[styleName] = styleValue;
+  return element;
+}
+
+function cssMultiSet(element, obj) {
+  for (var key in obj) {
+    var val = obj[key];
+    if (typeof val === 'number') {
+      val = val.toString() + 'px';
+    }
+    element.style[key] = val;
+  }
+  return element;
+}
+
+DOM.css = function (element, styleNameOrObject, styleValue) {
+  if (typeof styleNameOrObject === 'object') {
+    // multiple set with object
+    return cssMultiSet(element, styleNameOrObject);
+  } else {
+    if (typeof styleValue === 'undefined') {
+      return cssGet(element, styleNameOrObject);
+    } else {
+      return cssSet(element, styleNameOrObject, styleValue);
+    }
+  }
+};
+
+DOM.matches = function (element, query) {
+  if (typeof element.matches !== 'undefined') {
+    return element.matches(query);
+  } else {
+    if (typeof element.matchesSelector !== 'undefined') {
+      return element.matchesSelector(query);
+    } else if (typeof element.webkitMatchesSelector !== 'undefined') {
+      return element.webkitMatchesSelector(query);
+    } else if (typeof element.mozMatchesSelector !== 'undefined') {
+      return element.mozMatchesSelector(query);
+    } else if (typeof element.msMatchesSelector !== 'undefined') {
+      return element.msMatchesSelector(query);
+    }
+  }
+};
+
+DOM.remove = function (element) {
+  if (typeof element.remove !== 'undefined') {
+    element.remove();
+  } else {
+    if (element.parentNode) {
+      element.parentNode.removeChild(element);
+    }
+  }
+};
+
+DOM.queryChildren = function (element, selector) {
+  return Array.prototype.filter.call(element.childNodes, function (child) {
+    return DOM.matches(child, selector);
+  });
+};
+
+module.exports = DOM;
+
+},{}],4:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var EventElement = function (element) {
+  this.element = element;
+  this.events = {};
+};
+
+EventElement.prototype.bind = function (eventName, handler) {
+  if (typeof this.events[eventName] === 'undefined') {
+    this.events[eventName] = [];
+  }
+  this.events[eventName].push(handler);
+  this.element.addEventListener(eventName, handler, false);
+};
+
+EventElement.prototype.unbind = function (eventName, handler) {
+  var isHandlerProvided = (typeof handler !== 'undefined');
+  this.events[eventName] = this.events[eventName].filter(function (hdlr) {
+    if (isHandlerProvided && hdlr !== handler) {
+      return true;
+    }
+    this.element.removeEventListener(eventName, hdlr, false);
+    return false;
+  }, this);
+};
+
+EventElement.prototype.unbindAll = function () {
+  for (var name in this.events) {
+    this.unbind(name);
+  }
+};
+
+var EventManager = function () {
+  this.eventElements = [];
+};
+
+EventManager.prototype.eventElement = function (element) {
+  var ee = this.eventElements.filter(function (eventElement) {
+    return eventElement.element === element;
+  })[0];
+  if (typeof ee === 'undefined') {
+    ee = new EventElement(element);
+    this.eventElements.push(ee);
+  }
+  return ee;
+};
+
+EventManager.prototype.bind = function (element, eventName, handler) {
+  this.eventElement(element).bind(eventName, handler);
+};
+
+EventManager.prototype.unbind = function (element, eventName, handler) {
+  this.eventElement(element).unbind(eventName, handler);
+};
+
+EventManager.prototype.unbindAll = function () {
+  for (var i = 0; i < this.eventElements.length; i++) {
+    this.eventElements[i].unbindAll();
+  }
+};
+
+EventManager.prototype.once = function (element, eventName, handler) {
+  var ee = this.eventElement(element);
+  var onceHandler = function (e) {
+    ee.unbind(eventName, onceHandler);
+    handler(e);
+  };
+  ee.bind(eventName, onceHandler);
+};
+
+module.exports = EventManager;
+
+},{}],5:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+module.exports = (function () {
+  function s4() {
+    return Math.floor((1 + Math.random()) * 0x10000)
+               .toString(16)
+               .substring(1);
+  }
+  return function () {
+    return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
+           s4() + '-' + s4() + s4() + s4();
+  };
+})();
+
+},{}],6:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var cls = require('./class')
+  , d = require('./dom');
+
+exports.toInt = function (x) {
+  return parseInt(x, 10) || 0;
+};
+
+exports.clone = function (obj) {
+  if (obj === null) {
+    return null;
+  } else if (typeof obj === 'object') {
+    var result = {};
+    for (var key in obj) {
+      result[key] = this.clone(obj[key]);
+    }
+    return result;
+  } else {
+    return obj;
+  }
+};
+
+exports.extend = function (original, source) {
+  var result = this.clone(original);
+  for (var key in source) {
+    result[key] = this.clone(source[key]);
+  }
+  return result;
+};
+
+exports.isEditable = function (el) {
+  return d.matches(el, "input,[contenteditable]") ||
+         d.matches(el, "select,[contenteditable]") ||
+         d.matches(el, "textarea,[contenteditable]") ||
+         d.matches(el, "button,[contenteditable]");
+};
+
+exports.removePsClasses = function (element) {
+  var clsList = cls.list(element);
+  for (var i = 0; i < clsList.length; i++) {
+    var className = clsList[i];
+    if (className.indexOf('ps-') === 0) {
+      cls.remove(element, className);
+    }
+  }
+};
+
+exports.outerWidth = function (element) {
+  return this.toInt(d.css(element, 'width')) +
+         this.toInt(d.css(element, 'paddingLeft')) +
+         this.toInt(d.css(element, 'paddingRight')) +
+         this.toInt(d.css(element, 'borderLeftWidth')) +
+         this.toInt(d.css(element, 'borderRightWidth'));
+};
+
+exports.startScrolling = function (element, axis) {
+  cls.add(element, 'ps-in-scrolling');
+  if (typeof axis !== 'undefined') {
+    cls.add(element, 'ps-' + axis);
+  } else {
+    cls.add(element, 'ps-x');
+    cls.add(element, 'ps-y');
+  }
+};
+
+exports.stopScrolling = function (element, axis) {
+  cls.remove(element, 'ps-in-scrolling');
+  if (typeof axis !== 'undefined') {
+    cls.remove(element, 'ps-' + axis);
+  } else {
+    cls.remove(element, 'ps-x');
+    cls.remove(element, 'ps-y');
+  }
+};
+
+exports.env = {
+  isWebKit: 'WebkitAppearance' in document.documentElement.style,
+  supportsTouch: (('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch),
+  supportsIePointer: window.navigator.msMaxTouchPoints !== null
+};
+
+},{"./class":2,"./dom":3}],7:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var destroy = require('./plugin/destroy')
+  , initialize = require('./plugin/initialize')
+  , update = require('./plugin/update');
+
+module.exports = {
+  initialize: initialize,
+  update: update,
+  destroy: destroy
+};
+
+},{"./plugin/destroy":9,"./plugin/initialize":17,"./plugin/update":20}],8:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+module.exports = {
+  wheelSpeed: 1,
+  wheelPropagation: false,
+  swipePropagation: true,
+  minScrollbarLength: null,
+  maxScrollbarLength: null,
+  useBothWheelAxes: false,
+  useKeyboard: true,
+  suppressScrollX: false,
+  suppressScrollY: false,
+  scrollXMarginOffset: 0,
+  scrollYMarginOffset: 0,
+  stopPropagationOnClick: true
+};
+
+},{}],9:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var d = require('../lib/dom')
+  , h = require('../lib/helper')
+  , instances = require('./instances');
+
+module.exports = function (element) {
+  var i = instances.get(element);
+
+  if (!i) {
+    return;
+  }
+
+  i.event.unbindAll();
+  d.remove(i.scrollbarX);
+  d.remove(i.scrollbarY);
+  d.remove(i.scrollbarXRail);
+  d.remove(i.scrollbarYRail);
+  h.removePsClasses(element);
+
+  instances.remove(element);
+};
+
+},{"../lib/dom":3,"../lib/helper":6,"./instances":18}],10:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var h = require('../../lib/helper')
+  , instances = require('../instances')
+  , updateGeometry = require('../update-geometry');
+
+function bindClickRailHandler(element, i) {
+  function pageOffset(el) {
+    return el.getBoundingClientRect();
+  }
+  var stopPropagation = window.Event.prototype.stopPropagation.bind;
+
+  if (i.settings.stopPropagationOnClick) {
+    i.event.bind(i.scrollbarY, 'click', stopPropagation);
+  }
+  i.event.bind(i.scrollbarYRail, 'click', function (e) {
+    var halfOfScrollbarLength = h.toInt(i.scrollbarYHeight / 2);
+    var positionTop = i.railYRatio * (e.pageY - window.scrollY - pageOffset(i.scrollbarYRail).top - halfOfScrollbarLength);
+    var maxPositionTop = i.railYRatio * (i.railYHeight - i.scrollbarYHeight);
+    var positionRatio = positionTop / maxPositionTop;
+
+    if (positionRatio < 0) {
+      positionRatio = 0;
+    } else if (positionRatio > 1) {
+      positionRatio = 1;
+    }
+
+    element.scrollTop = (i.contentHeight - i.containerHeight) * positionRatio;
+    updateGeometry(element);
+
+    e.stopPropagation();
+  });
+
+  if (i.settings.stopPropagationOnClick) {
+    i.event.bind(i.scrollbarX, 'click', stopPropagation);
+  }
+  i.event.bind(i.scrollbarXRail, 'click', function (e) {
+    var halfOfScrollbarLength = h.toInt(i.scrollbarXWidth / 2);
+    var positionLeft = i.railXRatio * (e.pageX - window.scrollX - pageOffset(i.scrollbarXRail).left - halfOfScrollbarLength);
+    var maxPositionLeft = i.railXRatio * (i.railXWidth - i.scrollbarXWidth);
+    var positionRatio = positionLeft / maxPositionLeft;
+
+    if (positionRatio < 0) {
+      positionRatio = 0;
+    } else if (positionRatio > 1) {
+      positionRatio = 1;
+    }
+
+    element.scrollLeft = ((i.contentWidth - i.containerWidth) * positionRatio) - i.negativeScrollAdjustment;
+    updateGeometry(element);
+
+    e.stopPropagation();
+  });
+}
+
+module.exports = function (element) {
+  var i = instances.get(element);
+  bindClickRailHandler(element, i);
+};
+
+},{"../../lib/helper":6,"../instances":18,"../update-geometry":19}],11:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var d = require('../../lib/dom')
+  , h = require('../../lib/helper')
+  , instances = require('../instances')
+  , updateGeometry = require('../update-geometry');
+
+function bindMouseScrollXHandler(element, i) {
+  var currentLeft = null;
+  var currentPageX = null;
+
+  function updateScrollLeft(deltaX) {
+    var newLeft = currentLeft + (deltaX * i.railXRatio);
+    var maxLeft = i.scrollbarXRail.getBoundingClientRect().left + (i.railXRatio * (i.railXWidth - i.scrollbarXWidth));
+
+    if (newLeft < 0) {
+      i.scrollbarXLeft = 0;
+    } else if (newLeft > maxLeft) {
+      i.scrollbarXLeft = maxLeft;
+    } else {
+      i.scrollbarXLeft = newLeft;
+    }
+
+    var scrollLeft = h.toInt(i.scrollbarXLeft * (i.contentWidth - i.containerWidth) / (i.containerWidth - (i.railXRatio * i.scrollbarXWidth))) - i.negativeScrollAdjustment;
+    element.scrollLeft = scrollLeft;
+  }
+
+  var mouseMoveHandler = function (e) {
+    updateScrollLeft(e.pageX - currentPageX);
+    updateGeometry(element);
+    e.stopPropagation();
+    e.preventDefault();
+  };
+
+  var mouseUpHandler = function () {
+    h.stopScrolling(element, 'x');
+    i.event.unbind(i.ownerDocument, 'mousemove', mouseMoveHandler);
+  };
+
+  i.event.bind(i.scrollbarX, 'mousedown', function (e) {
+    currentPageX = e.pageX;
+    currentLeft = h.toInt(d.css(i.scrollbarX, 'left')) * i.railXRatio;
+    h.startScrolling(element, 'x');
+
+    i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler);
+    i.event.once(i.ownerDocument, 'mouseup', mouseUpHandler);
+
+    e.stopPropagation();
+    e.preventDefault();
+  });
+}
+
+function bindMouseScrollYHandler(element, i) {
+  var currentTop = null;
+  var currentPageY = null;
+
+  function updateScrollTop(deltaY) {
+    var newTop = currentTop + (deltaY * i.railYRatio);
+    var maxTop = i.scrollbarYRail.getBoundingClientRect().top + (i.railYRatio * (i.railYHeight - i.scrollbarYHeight));
+
+    if (newTop < 0) {
+      i.scrollbarYTop = 0;
+    } else if (newTop > maxTop) {
+      i.scrollbarYTop = maxTop;
+    } else {
+      i.scrollbarYTop = newTop;
+    }
+
+    var scrollTop = h.toInt(i.scrollbarYTop * (i.contentHeight - i.containerHeight) / (i.containerHeight - (i.railYRatio * i.scrollbarYHeight)));
+    element.scrollTop = scrollTop;
+  }
+
+  var mouseMoveHandler = function (e) {
+    updateScrollTop(e.pageY - currentPageY);
+    updateGeometry(element);
+    e.stopPropagation();
+    e.preventDefault();
+  };
+
+  var mouseUpHandler = function () {
+    h.stopScrolling(element, 'y');
+    i.event.unbind(i.ownerDocument, 'mousemove', mouseMoveHandler);
+  };
+
+  i.event.bind(i.scrollbarY, 'mousedown', function (e) {
+    currentPageY = e.pageY;
+    currentTop = h.toInt(d.css(i.scrollbarY, 'top')) * i.railYRatio;
+    h.startScrolling(element, 'y');
+
+    i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler);
+    i.event.once(i.ownerDocument, 'mouseup', mouseUpHandler);
+
+    e.stopPropagation();
+    e.preventDefault();
+  });
+}
+
+module.exports = function (element) {
+  var i = instances.get(element);
+  bindMouseScrollXHandler(element, i);
+  bindMouseScrollYHandler(element, i);
+};
+
+},{"../../lib/dom":3,"../../lib/helper":6,"../instances":18,"../update-geometry":19}],12:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var h = require('../../lib/helper')
+  , instances = require('../instances')
+  , updateGeometry = require('../update-geometry');
+
+function bindKeyboardHandler(element, i) {
+  var hovered = false;
+  i.event.bind(element, 'mouseenter', function () {
+    hovered = true;
+  });
+  i.event.bind(element, 'mouseleave', function () {
+    hovered = false;
+  });
+
+  var shouldPrevent = false;
+  function shouldPreventDefault(deltaX, deltaY) {
+    var scrollTop = element.scrollTop;
+    if (deltaX === 0) {
+      if (!i.scrollbarYActive) {
+        return false;
+      }
+      if ((scrollTop === 0 && deltaY > 0) || (scrollTop >= i.contentHeight - i.containerHeight && deltaY < 0)) {
+        return !i.settings.wheelPropagation;
+      }
+    }
+
+    var scrollLeft = element.scrollLeft;
+    if (deltaY === 0) {
+      if (!i.scrollbarXActive) {
+        return false;
+      }
+      if ((scrollLeft === 0 && deltaX < 0) || (scrollLeft >= i.contentWidth - i.containerWidth && deltaX > 0)) {
+        return !i.settings.wheelPropagation;
+      }
+    }
+    return true;
+  }
+
+  i.event.bind(i.ownerDocument, 'keydown', function (e) {
+    if (e.isDefaultPrevented && e.isDefaultPrevented()) {
+      return;
+    }
+
+    if (!hovered) {
+      return;
+    }
+
+    var activeElement = document.activeElement ? document.activeElement : i.ownerDocument.activeElement;
+    if (activeElement) {
+      // go deeper if element is a webcomponent
+      while (activeElement.shadowRoot) {
+        activeElement = activeElement.shadowRoot.activeElement;
+      }
+      if (h.isEditable(activeElement)) {
+        return;
+      }
+    }
+
+    var deltaX = 0;
+    var deltaY = 0;
+
+    switch (e.which) {
+    case 37: // left
+      deltaX = -30;
+      break;
+    case 38: // up
+      deltaY = 30;
+      break;
+    case 39: // right
+      deltaX = 30;
+      break;
+    case 40: // down
+      deltaY = -30;
+      break;
+    case 33: // page up
+      deltaY = 90;
+      break;
+    case 32: // space bar
+      if (e.shiftKey) {
+        deltaY = 90;
+      } else {
+        deltaY = -90;
+      }
+      break;
+    case 34: // page down
+      deltaY = -90;
+      break;
+    case 35: // end
+      if (e.ctrlKey) {
+        deltaY = -i.contentHeight;
+      } else {
+        deltaY = -i.containerHeight;
+      }
+      break;
+    case 36: // home
+      if (e.ctrlKey) {
+        deltaY = element.scrollTop;
+      } else {
+        deltaY = i.containerHeight;
+      }
+      break;
+    default:
+      return;
+    }
+
+    element.scrollTop = element.scrollTop - deltaY;
+    element.scrollLeft = element.scrollLeft + deltaX;
+    updateGeometry(element);
+
+    shouldPrevent = shouldPreventDefault(deltaX, deltaY);
+    if (shouldPrevent) {
+      e.preventDefault();
+    }
+  });
+}
+
+module.exports = function (element) {
+  var i = instances.get(element);
+  bindKeyboardHandler(element, i);
+};
+
+},{"../../lib/helper":6,"../instances":18,"../update-geometry":19}],13:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var h = require('../../lib/helper')
+  , instances = require('../instances')
+  , updateGeometry = require('../update-geometry');
+
+function bindMouseWheelHandler(element, i) {
+  var shouldPrevent = false;
+
+  function shouldPreventDefault(deltaX, deltaY) {
+    var scrollTop = element.scrollTop;
+    if (deltaX === 0) {
+      if (!i.scrollbarYActive) {
+        return false;
+      }
+      if ((scrollTop === 0 && deltaY > 0) || (scrollTop >= i.contentHeight - i.containerHeight && deltaY < 0)) {
+        return !i.settings.wheelPropagation;
+      }
+    }
+
+    var scrollLeft = element.scrollLeft;
+    if (deltaY === 0) {
+      if (!i.scrollbarXActive) {
+        return false;
+      }
+      if ((scrollLeft === 0 && deltaX < 0) || (scrollLeft >= i.contentWidth - i.containerWidth && deltaX > 0)) {
+        return !i.settings.wheelPropagation;
+      }
+    }
+    return true;
+  }
+
+  function getDeltaFromEvent(e) {
+    var deltaX = e.deltaX;
+    var deltaY = -1 * e.deltaY;
+
+    if (typeof deltaX === "undefined" || typeof deltaY === "undefined") {
+      // OS X Safari
+      deltaX = -1 * e.wheelDeltaX / 6;
+      deltaY = e.wheelDeltaY / 6;
+    }
+
+    if (e.deltaMode && e.deltaMode === 1) {
+      // Firefox in deltaMode 1: Line scrolling
+      deltaX *= 10;
+      deltaY *= 10;
+    }
+
+    if (deltaX !== deltaX && deltaY !== deltaY/* NaN checks */) {
+      // IE in some mouse drivers
+      deltaX = 0;
+      deltaY = e.wheelDelta;
+    }
+
+    return [deltaX, deltaY];
+  }
+
+  function shouldBeConsumedByTextarea(deltaX, deltaY) {
+    var hoveredTextarea = element.querySelector('textarea:hover');
+    if (hoveredTextarea) {
+      var maxScrollTop = hoveredTextarea.scrollHeight - hoveredTextarea.clientHeight;
+      if (maxScrollTop > 0) {
+        if (!(hoveredTextarea.scrollTop === 0 && deltaY > 0) &&
+            !(hoveredTextarea.scrollTop === maxScrollTop && deltaY < 0)) {
+          return true;
+        }
+      }
+      var maxScrollLeft = hoveredTextarea.scrollLeft - hoveredTextarea.clientWidth;
+      if (maxScrollLeft > 0) {
+        if (!(hoveredTextarea.scrollLeft === 0 && deltaX < 0) &&
+            !(hoveredTextarea.scrollLeft === maxScrollLeft && deltaX > 0)) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  function mousewheelHandler(e) {
+    // FIXME: this is a quick fix for the select problem in FF and IE.
+    // If there comes an effective way to deal with the problem,
+    // this lines should be removed.
+    if (!h.env.isWebKit && element.querySelector('select:focus')) {
+      return;
+    }
+
+    var delta = getDeltaFromEvent(e);
+
+    var deltaX = delta[0];
+    var deltaY = delta[1];
+
+    if (shouldBeConsumedByTextarea(deltaX, deltaY)) {
+      return;
+    }
+
+    shouldPrevent = false;
+    if (!i.settings.useBothWheelAxes) {
+      // deltaX will only be used for horizontal scrolling and deltaY will
+      // only be used for vertical scrolling - this is the default
+      element.scrollTop = element.scrollTop - (deltaY * i.settings.wheelSpeed);
+      element.scrollLeft = element.scrollLeft + (deltaX * i.settings.wheelSpeed);
+    } else if (i.scrollbarYActive && !i.scrollbarXActive) {
+      // only vertical scrollbar is active and useBothWheelAxes option is
+      // active, so let's scroll vertical bar using both mouse wheel axes
+      if (deltaY) {
+        element.scrollTop = element.scrollTop - (deltaY * i.settings.wheelSpeed);
+      } else {
+        element.scrollTop = element.scrollTop + (deltaX * i.settings.wheelSpeed);
+      }
+      shouldPrevent = true;
+    } else if (i.scrollbarXActive && !i.scrollbarYActive) {
+      // useBothWheelAxes and only horizontal bar is active, so use both
+      // wheel axes for horizontal bar
+      if (deltaX) {
+        element.scrollLeft = element.scrollLeft + (deltaX * i.settings.wheelSpeed);
+      } else {
+        element.scrollLeft = element.scrollLeft - (deltaY * i.settings.wheelSpeed);
+      }
+      shouldPrevent = true;
+    }
+
+    updateGeometry(element);
+
+    shouldPrevent = (shouldPrevent || shouldPreventDefault(deltaX, deltaY));
+    if (shouldPrevent) {
+      e.stopPropagation();
+      e.preventDefault();
+    }
+  }
+
+  if (typeof window.onwheel !== "undefined") {
+    i.event.bind(element, 'wheel', mousewheelHandler);
+  } else if (typeof window.onmousewheel !== "undefined") {
+    i.event.bind(element, 'mousewheel', mousewheelHandler);
+  }
+}
+
+module.exports = function (element) {
+  var i = instances.get(element);
+  bindMouseWheelHandler(element, i);
+};
+
+},{"../../lib/helper":6,"../instances":18,"../update-geometry":19}],14:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var instances = require('../instances')
+  , updateGeometry = require('../update-geometry');
+
+function bindNativeScrollHandler(element, i) {
+  i.event.bind(element, 'scroll', function () {
+    updateGeometry(element);
+  });
+}
+
+module.exports = function (element) {
+  var i = instances.get(element);
+  bindNativeScrollHandler(element, i);
+};
+
+},{"../instances":18,"../update-geometry":19}],15:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var h = require('../../lib/helper')
+  , instances = require('../instances')
+  , updateGeometry = require('../update-geometry');
+
+function bindSelectionHandler(element, i) {
+  function getRangeNode() {
+    var selection = window.getSelection ? window.getSelection() :
+                    document.getSelection ? document.getSelection() : '';
+    if (selection.toString().length === 0) {
+      return null;
+    } else {
+      return selection.getRangeAt(0).commonAncestorContainer;
+    }
+  }
+
+  var scrollingLoop = null;
+  var scrollDiff = {top: 0, left: 0};
+  function startScrolling() {
+    if (!scrollingLoop) {
+      scrollingLoop = setInterval(function () {
+        if (!instances.get(element)) {
+          clearInterval(scrollingLoop);
+          return;
+        }
+
+        element.scrollTop = element.scrollTop + scrollDiff.top;
+        element.scrollLeft = element.scrollLeft + scrollDiff.left;
+        updateGeometry(element);
+      }, 50); // every .1 sec
+    }
+  }
+  function stopScrolling() {
+    if (scrollingLoop) {
+      clearInterval(scrollingLoop);
+      scrollingLoop = null;
+    }
+    h.stopScrolling(element);
+  }
+
+  var isSelected = false;
+  i.event.bind(i.ownerDocument, 'selectionchange', function () {
+    if (element.contains(getRangeNode())) {
+      isSelected = true;
+    } else {
+      isSelected = false;
+      stopScrolling();
+    }
+  });
+  i.event.bind(window, 'mouseup', function () {
+    if (isSelected) {
+      isSelected = false;
+      stopScrolling();
+    }
+  });
+
+  i.event.bind(window, 'mousemove', function (e) {
+    if (isSelected) {
+      var mousePosition = {x: e.pageX, y: e.pageY};
+      var containerGeometry = {
+        left: element.offsetLeft,
+        right: element.offsetLeft + element.offsetWidth,
+        top: element.offsetTop,
+        bottom: element.offsetTop + element.offsetHeight
+      };
+
+      if (mousePosition.x < containerGeometry.left + 3) {
+        scrollDiff.left = -5;
+        h.startScrolling(element, 'x');
+      } else if (mousePosition.x > containerGeometry.right - 3) {
+        scrollDiff.left = 5;
+        h.startScrolling(element, 'x');
+      } else {
+        scrollDiff.left = 0;
+      }
+
+      if (mousePosition.y < containerGeometry.top + 3) {
+        if (containerGeometry.top + 3 - mousePosition.y < 5) {
+          scrollDiff.top = -5;
+        } else {
+          scrollDiff.top = -20;
+        }
+        h.startScrolling(element, 'y');
+      } else if (mousePosition.y > containerGeometry.bottom - 3) {
+        if (mousePosition.y - containerGeometry.bottom + 3 < 5) {
+          scrollDiff.top = 5;
+        } else {
+          scrollDiff.top = 20;
+        }
+        h.startScrolling(element, 'y');
+      } else {
+        scrollDiff.top = 0;
+      }
+
+      if (scrollDiff.top === 0 && scrollDiff.left === 0) {
+        stopScrolling();
+      } else {
+        startScrolling();
+      }
+    }
+  });
+}
+
+module.exports = function (element) {
+  var i = instances.get(element);
+  bindSelectionHandler(element, i);
+};
+
+},{"../../lib/helper":6,"../instances":18,"../update-geometry":19}],16:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var instances = require('../instances')
+  , updateGeometry = require('../update-geometry');
+
+function bindTouchHandler(element, i, supportsTouch, supportsIePointer) {
+  function shouldPreventDefault(deltaX, deltaY) {
+    var scrollTop = element.scrollTop;
+    var scrollLeft = element.scrollLeft;
+    var magnitudeX = Math.abs(deltaX);
+    var magnitudeY = Math.abs(deltaY);
+
+    if (magnitudeY > magnitudeX) {
+      // user is perhaps trying to swipe up/down the page
+
+      if (((deltaY < 0) && (scrollTop === i.contentHeight - i.containerHeight)) ||
+          ((deltaY > 0) && (scrollTop === 0))) {
+        return !i.settings.swipePropagation;
+      }
+    } else if (magnitudeX > magnitudeY) {
+      // user is perhaps trying to swipe left/right across the page
+
+      if (((deltaX < 0) && (scrollLeft === i.contentWidth - i.containerWidth)) ||
+          ((deltaX > 0) && (scrollLeft === 0))) {
+        return !i.settings.swipePropagation;
+      }
+    }
+
+    return true;
+  }
+
+  function applyTouchMove(differenceX, differenceY) {
+    element.scrollTop = element.scrollTop - differenceY;
+    element.scrollLeft = element.scrollLeft - differenceX;
+
+    updateGeometry(element);
+  }
+
+  var startOffset = {};
+  var startTime = 0;
+  var speed = {};
+  var easingLoop = null;
+  var inGlobalTouch = false;
+  var inLocalTouch = false;
+
+  function globalTouchStart() {
+    inGlobalTouch = true;
+  }
+  function globalTouchEnd() {
+    inGlobalTouch = false;
+  }
+
+  function getTouch(e) {
+    if (e.targetTouches) {
+      return e.targetTouches[0];
+    } else {
+      // Maybe IE pointer
+      return e;
+    }
+  }
+  function shouldHandle(e) {
+    if (e.targetTouches && e.targetTouches.length === 1) {
+      return true;
+    }
+    if (e.pointerType && e.pointerType !== 'mouse' && e.pointerType !== e.MSPOINTER_TYPE_MOUSE) {
+      return true;
+    }
+    return false;
+  }
+  function touchStart(e) {
+    if (shouldHandle(e)) {
+      inLocalTouch = true;
+
+      var touch = getTouch(e);
+
+      startOffset.pageX = touch.pageX;
+      startOffset.pageY = touch.pageY;
+
+      startTime = (new Date()).getTime();
+
+      if (easingLoop !== null) {
+        clearInterval(easingLoop);
+      }
+
+      e.stopPropagation();
+    }
+  }
+  function touchMove(e) {
+    if (!inGlobalTouch && inLocalTouch && shouldHandle(e)) {
+      var touch = getTouch(e);
+
+      var currentOffset = {pageX: touch.pageX, pageY: touch.pageY};
+
+      var differenceX = currentOffset.pageX - startOffset.pageX;
+      var differenceY = currentOffset.pageY - startOffset.pageY;
+
+      applyTouchMove(differenceX, differenceY);
+      startOffset = currentOffset;
+
+      var currentTime = (new Date()).getTime();
+
+      var timeGap = currentTime - startTime;
+      if (timeGap > 0) {
+        speed.x = differenceX / timeGap;
+        speed.y = differenceY / timeGap;
+        startTime = currentTime;
+      }
+
+      if (shouldPreventDefault(differenceX, differenceY)) {
+        e.stopPropagation();
+        e.preventDefault();
+      }
+    }
+  }
+  function touchEnd() {
+    if (!inGlobalTouch && inLocalTouch) {
+      inLocalTouch = false;
+
+      clearInterval(easingLoop);
+      easingLoop = setInterval(function () {
+        if (!instances.get(element)) {
+          clearInterval(easingLoop);
+          return;
+        }
+
+        if (Math.abs(speed.x) < 0.01 && Math.abs(speed.y) < 0.01) {
+          clearInterval(easingLoop);
+          return;
+        }
+
+        applyTouchMove(speed.x * 30, speed.y * 30);
+
+        speed.x *= 0.8;
+        speed.y *= 0.8;
+      }, 10);
+    }
+  }
+
+  if (supportsTouch) {
+    i.event.bind(window, 'touchstart', globalTouchStart);
+    i.event.bind(window, 'touchend', globalTouchEnd);
+    i.event.bind(element, 'touchstart', touchStart);
+    i.event.bind(element, 'touchmove', touchMove);
+    i.event.bind(element, 'touchend', touchEnd);
+  }
+
+  if (supportsIePointer) {
+    if (window.PointerEvent) {
+      i.event.bind(window, 'pointerdown', globalTouchStart);
+      i.event.bind(window, 'pointerup', globalTouchEnd);
+      i.event.bind(element, 'pointerdown', touchStart);
+      i.event.bind(element, 'pointermove', touchMove);
+      i.event.bind(element, 'pointerup', touchEnd);
+    } else if (window.MSPointerEvent) {
+      i.event.bind(window, 'MSPointerDown', globalTouchStart);
+      i.event.bind(window, 'MSPointerUp', globalTouchEnd);
+      i.event.bind(element, 'MSPointerDown', touchStart);
+      i.event.bind(element, 'MSPointerMove', touchMove);
+      i.event.bind(element, 'MSPointerUp', touchEnd);
+    }
+  }
+}
+
+module.exports = function (element, supportsTouch, supportsIePointer) {
+  var i = instances.get(element);
+  bindTouchHandler(element, i, supportsTouch, supportsIePointer);
+};
+
+},{"../instances":18,"../update-geometry":19}],17:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var cls = require('../lib/class')
+  , h = require('../lib/helper')
+  , instances = require('./instances')
+  , updateGeometry = require('./update-geometry');
+
+// Handlers
+var clickRailHandler = require('./handler/click-rail')
+  , dragScrollbarHandler = require('./handler/drag-scrollbar')
+  , keyboardHandler = require('./handler/keyboard')
+  , mouseWheelHandler = require('./handler/mouse-wheel')
+  , nativeScrollHandler = require('./handler/native-scroll')
+  , selectionHandler = require('./handler/selection')
+  , touchHandler = require('./handler/touch');
+
+module.exports = function (element, userSettings) {
+  userSettings = typeof userSettings === 'object' ? userSettings : {};
+
+  cls.add(element, 'ps-container');
+
+  // Create a plugin instance.
+  var i = instances.add(element);
+
+  i.settings = h.extend(i.settings, userSettings);
+
+  clickRailHandler(element);
+  dragScrollbarHandler(element);
+  mouseWheelHandler(element);
+  nativeScrollHandler(element);
+  selectionHandler(element);
+
+  if (h.env.supportsTouch || h.env.supportsIePointer) {
+    touchHandler(element, h.env.supportsTouch, h.env.supportsIePointer);
+  }
+  if (i.settings.useKeyboard) {
+    keyboardHandler(element);
+  }
+
+  updateGeometry(element);
+};
+
+},{"../lib/class":2,"../lib/helper":6,"./handler/click-rail":10,"./handler/drag-scrollbar":11,"./handler/keyboard":12,"./handler/mouse-wheel":13,"./handler/native-scroll":14,"./handler/selection":15,"./handler/touch":16,"./instances":18,"./update-geometry":19}],18:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var d = require('../lib/dom')
+  , defaultSettings = require('./default-setting')
+  , EventManager = require('../lib/event-manager')
+  , guid = require('../lib/guid')
+  , h = require('../lib/helper');
+
+var instances = {};
+
+function Instance(element) {
+  var i = this;
+
+  i.settings = h.clone(defaultSettings);
+  i.containerWidth = null;
+  i.containerHeight = null;
+  i.contentWidth = null;
+  i.contentHeight = null;
+
+  i.isRtl = d.css(element, 'direction') === "rtl";
+  i.isNegativeScroll = (function () {
+    var originalScrollLeft = element.scrollLeft;
+    var result = null;
+    element.scrollLeft = -1;
+    result = element.scrollLeft < 0;
+    element.scrollLeft = originalScrollLeft;
+    return result;
+  })();
+  i.negativeScrollAdjustment = i.isNegativeScroll ? element.scrollWidth - element.clientWidth : 0;
+  i.event = new EventManager();
+  i.ownerDocument = element.ownerDocument || document;
+
+  i.scrollbarXRail = d.appendTo(d.e('div', 'ps-scrollbar-x-rail'), element);
+  i.scrollbarX = d.appendTo(d.e('div', 'ps-scrollbar-x'), i.scrollbarXRail);
+  i.scrollbarXActive = null;
+  i.scrollbarXWidth = null;
+  i.scrollbarXLeft = null;
+  i.scrollbarXBottom = h.toInt(d.css(i.scrollbarXRail, 'bottom'));
+  i.isScrollbarXUsingBottom = i.scrollbarXBottom === i.scrollbarXBottom; // !isNaN
+  i.scrollbarXTop = i.isScrollbarXUsingBottom ? null : h.toInt(d.css(i.scrollbarXRail, 'top'));
+  i.railBorderXWidth = h.toInt(d.css(i.scrollbarXRail, 'borderLeftWidth')) + h.toInt(d.css(i.scrollbarXRail, 'borderRightWidth'));
+  // Set rail to display:block to calculate margins
+  d.css(i.scrollbarXRail, 'display', 'block');
+  i.railXMarginWidth = h.toInt(d.css(i.scrollbarXRail, 'marginLeft')) + h.toInt(d.css(i.scrollbarXRail, 'marginRight'));
+  d.css(i.scrollbarXRail, 'display', '');
+  i.railXWidth = null;
+  i.railXRatio = null;
+
+  i.scrollbarYRail = d.appendTo(d.e('div', 'ps-scrollbar-y-rail'), element);
+  i.scrollbarY = d.appendTo(d.e('div', 'ps-scrollbar-y'), i.scrollbarYRail);
+  i.scrollbarYActive = null;
+  i.scrollbarYHeight = null;
+  i.scrollbarYTop = null;
+  i.scrollbarYRight = h.toInt(d.css(i.scrollbarYRail, 'right'));
+  i.isScrollbarYUsingRight = i.scrollbarYRight === i.scrollbarYRight; // !isNaN
+  i.scrollbarYLeft = i.isScrollbarYUsingRight ? null : h.toInt(d.css(i.scrollbarYRail, 'left'));
+  i.scrollbarYOuterWidth = i.isRtl ? h.outerWidth(i.scrollbarY) : null;
+  i.railBorderYWidth = h.toInt(d.css(i.scrollbarYRail, 'borderTopWidth')) + h.toInt(d.css(i.scrollbarYRail, 'borderBottomWidth'));
+  d.css(i.scrollbarYRail, 'display', 'block');
+  i.railYMarginHeight = h.toInt(d.css(i.scrollbarYRail, 'marginTop')) + h.toInt(d.css(i.scrollbarYRail, 'marginBottom'));
+  d.css(i.scrollbarYRail, 'display', '');
+  i.railYHeight = null;
+  i.railYRatio = null;
+}
+
+function getId(element) {
+  if (typeof element.dataset === 'undefined') {
+    return element.getAttribute('data-ps-id');
+  } else {
+    return element.dataset.psId;
+  }
+}
+
+function setId(element, id) {
+  if (typeof element.dataset === 'undefined') {
+    element.setAttribute('data-ps-id', id);
+  } else {
+    element.dataset.psId = id;
+  }
+}
+
+function removeId(element) {
+  if (typeof element.dataset === 'undefined') {
+    element.removeAttribute('data-ps-id');
+  } else {
+    delete element.dataset.psId;
+  }
+}
+
+exports.add = function (element) {
+  var newId = guid();
+  setId(element, newId);
+  instances[newId] = new Instance(element);
+  return instances[newId];
+};
+
+exports.remove = function (element) {
+  delete instances[getId(element)];
+  removeId(element);
+};
+
+exports.get = function (element) {
+  return instances[getId(element)];
+};
+
+},{"../lib/dom":3,"../lib/event-manager":4,"../lib/guid":5,"../lib/helper":6,"./default-setting":8}],19:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var cls = require('../lib/class')
+  , d = require('../lib/dom')
+  , h = require('../lib/helper')
+  , instances = require('./instances');
+
+function getThumbSize(i, thumbSize) {
+  if (i.settings.minScrollbarLength) {
+    thumbSize = Math.max(thumbSize, i.settings.minScrollbarLength);
+  }
+  if (i.settings.maxScrollbarLength) {
+    thumbSize = Math.min(thumbSize, i.settings.maxScrollbarLength);
+  }
+  return thumbSize;
+}
+
+function updateCss(element, i) {
+  var xRailOffset = {width: i.railXWidth};
+  if (i.isRtl) {
+    xRailOffset.left = i.negativeScrollAdjustment + element.scrollLeft + i.containerWidth - i.contentWidth;
+  } else {
+    xRailOffset.left = element.scrollLeft;
+  }
+  if (i.isScrollbarXUsingBottom) {
+    xRailOffset.bottom = i.scrollbarXBottom - element.scrollTop;
+  } else {
+    xRailOffset.top = i.scrollbarXTop + element.scrollTop;
+  }
+  d.css(i.scrollbarXRail, xRailOffset);
+
+  var yRailOffset = {top: element.scrollTop, height: i.railYHeight};
+  if (i.isScrollbarYUsingRight) {
+    if (i.isRtl) {
+      yRailOffset.right = i.contentWidth - (i.negativeScrollAdjustment + element.scrollLeft) - i.scrollbarYRight - i.scrollbarYOuterWidth;
+    } else {
+      yRailOffset.right = i.scrollbarYRight - element.scrollLeft;
+    }
+  } else {
+    if (i.isRtl) {
+      yRailOffset.left = i.negativeScrollAdjustment + element.scrollLeft + i.containerWidth * 2 - i.contentWidth - i.scrollbarYLeft - i.scrollbarYOuterWidth;
+    } else {
+      yRailOffset.left = i.scrollbarYLeft + element.scrollLeft;
+    }
+  }
+  d.css(i.scrollbarYRail, yRailOffset);
+
+  d.css(i.scrollbarX, {left: i.scrollbarXLeft, width: i.scrollbarXWidth - i.railBorderXWidth});
+  d.css(i.scrollbarY, {top: i.scrollbarYTop, height: i.scrollbarYHeight - i.railBorderYWidth});
+}
+
+module.exports = function (element) {
+  var i = instances.get(element);
+
+  i.containerWidth = element.clientWidth;
+  i.containerHeight = element.clientHeight;
+  i.contentWidth = element.scrollWidth;
+  i.contentHeight = element.scrollHeight;
+
+  var existingRails;
+  if (!element.contains(i.scrollbarXRail)) {
+    existingRails = d.queryChildren(element, '.ps-scrollbar-x-rail');
+    if (existingRails.length > 0) {
+      existingRails.forEach(function (rail) {
+        d.remove(rail);
+      });
+    }
+    d.appendTo(i.scrollbarXRail, element);
+  }
+  if (!element.contains(i.scrollbarYRail)) {
+    existingRails = d.queryChildren(element, '.ps-scrollbar-y-rail');
+    if (existingRails.length > 0) {
+      existingRails.forEach(function (rail) {
+        d.remove(rail);
+      });
+    }
+    d.appendTo(i.scrollbarYRail, element);
+  }
+
+  if (!i.settings.suppressScrollX && i.containerWidth + i.settings.scrollXMarginOffset < i.contentWidth) {
+    i.scrollbarXActive = true;
+    i.railXWidth = i.containerWidth - i.railXMarginWidth;
+    i.railXRatio = i.containerWidth / i.railXWidth;
+    i.scrollbarXWidth = getThumbSize(i, h.toInt(i.railXWidth * i.containerWidth / i.contentWidth));
+    i.scrollbarXLeft = h.toInt((i.negativeScrollAdjustment + element.scrollLeft) * (i.railXWidth - i.scrollbarXWidth) / (i.contentWidth - i.containerWidth));
+  } else {
+    i.scrollbarXActive = false;
+    i.scrollbarXWidth = 0;
+    i.scrollbarXLeft = 0;
+    element.scrollLeft = 0;
+  }
+
+  if (!i.settings.suppressScrollY && i.containerHeight + i.settings.scrollYMarginOffset < i.contentHeight) {
+    i.scrollbarYActive = true;
+    i.railYHeight = i.containerHeight - i.railYMarginHeight;
+    i.railYRatio = i.containerHeight / i.railYHeight;
+    i.scrollbarYHeight = getThumbSize(i, h.toInt(i.railYHeight * i.containerHeight / i.contentHeight));
+    i.scrollbarYTop = h.toInt(element.scrollTop * (i.railYHeight - i.scrollbarYHeight) / (i.contentHeight - i.containerHeight));
+  } else {
+    i.scrollbarYActive = false;
+    i.scrollbarYHeight = 0;
+    i.scrollbarYTop = 0;
+    element.scrollTop = 0;
+  }
+
+  if (i.scrollbarXLeft >= i.railXWidth - i.scrollbarXWidth) {
+    i.scrollbarXLeft = i.railXWidth - i.scrollbarXWidth;
+  }
+  if (i.scrollbarYTop >= i.railYHeight - i.scrollbarYHeight) {
+    i.scrollbarYTop = i.railYHeight - i.scrollbarYHeight;
+  }
+
+  updateCss(element, i);
+
+  cls[i.scrollbarXActive ? 'add' : 'remove'](element, 'ps-active-x');
+  cls[i.scrollbarYActive ? 'add' : 'remove'](element, 'ps-active-y');
+};
+
+},{"../lib/class":2,"../lib/dom":3,"../lib/helper":6,"./instances":18}],20:[function(require,module,exports){
+/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
+ * Licensed under the MIT License
+ */
+'use strict';
+
+var d = require('../lib/dom')
+  , h = require('../lib/helper')
+  , instances = require('./instances')
+  , updateGeometry = require('./update-geometry');
+
+module.exports = function (element) {
+  var i = instances.get(element);
+
+  if (!i) {
+    return;
+  }
+
+  // Recalcuate negative scrollLeft adjustment
+  i.negativeScrollAdjustment = i.isNegativeScroll ? element.scrollWidth - element.clientWidth : 0;
+
+  // Recalculate rail margins
+  d.css(i.scrollbarXRail, 'display', 'block');
+  d.css(i.scrollbarYRail, 'display', 'block');
+  i.railXMarginWidth = h.toInt(d.css(i.scrollbarXRail, 'marginLeft')) + h.toInt(d.css(i.scrollbarXRail, 'marginRight'));
+  i.railYMarginHeight = h.toInt(d.css(i.scrollbarYRail, 'marginTop')) + h.toInt(d.css(i.scrollbarYRail, 'marginBottom'));
+
+  // Hide scrollbars not to affect scrollWidth and scrollHeight
+  d.css(i.scrollbarXRail, 'display', 'none');
+  d.css(i.scrollbarYRail, 'display', 'none');
+
+  updateGeometry(element);
+
+  d.css(i.scrollbarXRail, 'display', '');
+  d.css(i.scrollbarYRail, 'display', '');
+};
+
+},{"../lib/dom":3,"../lib/helper":6,"./instances":18,"./update-geometry":19}]},{},[1]);

文件差异内容过多而无法显示
+ 1 - 0
jet/static/jet/vendor/perfect-scrollbar/js/perfect-scrollbar.min.js


+ 34 - 20
jet/templates/admin/base.html

@@ -10,6 +10,7 @@
     <link href="{% static "jet/vendor/select2/css/select2.min.css" %}" rel="stylesheet" />
     <link href="{% static "jet/vendor/select2/css/select2.min.css" %}" rel="stylesheet" />
     <link href="{% static "jet/vendor/jquery-ui/jquery-ui.min.css" %}" rel="stylesheet" />
     <link href="{% static "jet/vendor/jquery-ui/jquery-ui.min.css" %}" rel="stylesheet" />
     <link href="{% static "jet/vendor/jquery-ui-timepicker/jquery.ui.timepicker.css" %}" rel="stylesheet" />
     <link href="{% static "jet/vendor/jquery-ui-timepicker/jquery.ui.timepicker.css" %}" rel="stylesheet" />
+    <link href="{% static "jet/vendor/perfect-scrollbar/css/perfect-scrollbar.css" %}" rel="stylesheet" />
     <link href="{% static "jet/css/icons/style.css" %}" rel="stylesheet" />
     <link href="{% static "jet/css/icons/style.css" %}" rel="stylesheet" />
     <link href="{% static "jet/css/themes/"|add:THEME|add:"/base.css" %}" rel="stylesheet" />
     <link href="{% static "jet/css/themes/"|add:THEME|add:"/base.css" %}" rel="stylesheet" />
     <link href="{% static "jet/css/themes/"|add:THEME|add:"/select2.theme.css" %}" rel="stylesheet" />
     <link href="{% static "jet/css/themes/"|add:THEME|add:"/select2.theme.css" %}" rel="stylesheet" />
@@ -30,6 +31,8 @@
     <script src="{% static "jet/vendor/jquery-ui/jquery-ui.min.js" %}"></script>
     <script src="{% static "jet/vendor/jquery-ui/jquery-ui.min.js" %}"></script>
     <script src="{% static "jet/vendor/jquery-ui-timepicker/jquery.ui.timepicker.js" %}"></script>
     <script src="{% static "jet/vendor/jquery-ui-timepicker/jquery.ui.timepicker.js" %}"></script>
     <script src="{% static "jet/vendor/select2/js/select2.full.min.js" %}"></script>
     <script src="{% static "jet/vendor/select2/js/select2.full.min.js" %}"></script>
+    <script src="{% static "jet/vendor/perfect-scrollbar/js/perfect-scrollbar.min.js" %}"></script>
+    <script src="{% static "jet/vendor/perfect-scrollbar/js/perfect-scrollbar.jquery.min.js" %}"></script>
     {% if LANGUAGE_CODE|slice:":2" != 'en' %}
     {% if LANGUAGE_CODE|slice:":2" != 'en' %}
         {% with "jet/vendor/jquery-ui/i18n/datepicker-"|add:LANGUAGE_CODE|add:".js" as url %}
         {% with "jet/vendor/jquery-ui/i18n/datepicker-"|add:LANGUAGE_CODE|add:".js" as url %}
             <script src="{% static url %}"></script>
             <script src="{% static url %}"></script>
@@ -110,9 +113,9 @@
                     {% endif %}
                     {% endif %}
                 {% endblock messages %}
                 {% endblock messages %}
 
 
-            <div class="content-sidebar">
-                        {% block sidebar %}{% endblock %}
-                    </div>
+                <div class="content-sidebar">
+                    {% block sidebar %}{% endblock %}
+                </div>
 
 
                 <div id="content" class="cf {% block coltype %}colM{% endblock %}">
                 <div id="content" class="cf {% block coltype %}colM{% endblock %}">
                     {% block pretitle %}{% endblock %}
                     {% block pretitle %}{% endblock %}
@@ -136,16 +139,34 @@
                         {% block branding %}{% endblock %}
                         {% block branding %}{% endblock %}
                     </div>
                     </div>
                     <ul class="sidebar-menu">
                     <ul class="sidebar-menu">
-                        {% if user.is_active and user.is_staff %}
-                            <li class="sidebar-menu-item">
-                                <span class="sidebar-menu-item-icon icon-data"></span> <a href="{% url 'admin:index' %}" class="sidebar-menu-item-link">{% trans 'Home' %}</a>
-                            </li>
-                        {% endif %}
-                        {% if site_url %}
-                            <li class="sidebar-menu-item">
-                                <span class="sidebar-menu-item-icon icon-open-external"></span> <a href="{{ site_url }}" class="sidebar-menu-item-link">{% trans 'View site' %}</a>
-                            </li>
-                        {% endif %}
+                        <li class="sidebar-menu-item no-horizontal-padding">
+                            <ul class="sidebar-menu-item-list compact">
+                                {% if user.is_active and user.is_staff %}
+                                    <li class="sidebar-menu-item-list-item">
+                                        <a href="{% url 'admin:index' %}" class="sidebar-menu-item-list-item-link">
+                                            <span class="sidebar-menu-item-list-item-icon icon-data"></span> {% trans 'Home' %}
+                                        </a>
+                                    </li>
+                                {% endif %}
+                                {% if site_url %}
+                                    <li class="sidebar-menu-item-list-item">
+                                        <a href="{{ site_url }}" class="sidebar-menu-item-list-item-link">
+                                            <span class="sidebar-menu-item-list-item-icon icon-open-external"></span> {% trans 'View site' %}
+                                        </a>
+                                    </li>
+                                {% endif %}
+                                {% url 'django-admindocs-docroot' as docsroot %}
+                                {% if docsroot %}
+                                    <li class="sidebar-menu-item-list-item">
+                                        <a href="{{ docsroot }}" class="sidebar-menu-item-list-item-link">
+                                            <span class="sidebar-menu-item-list-item-icon icon-book"></span> {% trans 'Documentation' %}
+                                        </a>
+                                    </li>
+                                {% endif %}
+                                {% block nav-global %}{% endblock %}
+                            </ul>
+                        </li>
+
                         {% if user.is_active and user.is_staff %}
                         {% if user.is_active and user.is_staff %}
                             {% get_menu as app_list %}
                             {% get_menu as app_list %}
                             {% if app_list.apps or app_list.pinned_apps %}
                             {% if app_list.apps or app_list.pinned_apps %}
@@ -220,13 +241,6 @@
                                     </li>
                                     </li>
                                 </ul>
                                 </ul>
                             </li>
                             </li>
-                            {% url 'django-admindocs-docroot' as docsroot %}
-                            {% if docsroot %}
-                                <li class="sidebar-menu-item">
-                                    <span class="sidebar-menu-item-icon icon-book"></span> <a href="{{ docsroot }}" class="sidebar-menu-item-link">{% trans 'Documentation' %}</a>
-                                </li>
-                            {% endif %}
-                            {% block nav-global %}{% endblock %}
                         {% endif %}
                         {% endif %}
                     </ul>
                     </ul>
                 </div>
                 </div>

+ 2 - 2
jet/templates/admin/search_form.html

@@ -13,13 +13,13 @@
             {% endif %}
             {% endif %}
         {% endblock %}
         {% endblock %}
 
 
-        <span class="changelist-filter-submit-block">
+        <div class="changelist-filter-submit-block">
             <input type="submit" value="{% trans 'Search' %}" />
             <input type="submit" value="{% trans 'Search' %}" />
 
 
             {% if show_result_count %}
             {% if show_result_count %}
                 <span class="small quiet">{% blocktrans count counter=cl.result_count %}{{ counter }} result{% plural %}{{ counter }} results{% endblocktrans %} (<a href="?{% if cl.is_popup %}_popup=1{% endif %}">{% if cl.show_full_result_count %}{% blocktrans with full_result_count=cl.full_result_count %}{{ full_result_count }} total{% endblocktrans %}{% else %}{% trans "Show all" %}{% endif %}</a>)</span>
                 <span class="small quiet">{% blocktrans count counter=cl.result_count %}{{ counter }} result{% plural %}{{ counter }} results{% endblocktrans %} (<a href="?{% if cl.is_popup %}_popup=1{% endif %}">{% if cl.show_full_result_count %}{% blocktrans with full_result_count=cl.full_result_count %}{{ full_result_count }} total{% endblocktrans %}{% else %}{% trans "Show all" %}{% endif %}</a>)</span>
             {% endif %}
             {% endif %}
-        </span>
+        </div>
 
 
         {% for pair in cl.params.items %}
         {% for pair in cl.params.items %}
             {% ifnotequal pair.0 search_var %}<input type="hidden" name="{{ pair.0 }}" value="{{ pair.1 }}"/>{% endifnotequal %}
             {% ifnotequal pair.0 search_var %}<input type="hidden" name="{{ pair.0 }}" value="{{ pair.1 }}"/>{% endifnotequal %}

+ 16 - 0
jet/tests/test_views.py

@@ -165,6 +165,22 @@ class ViewsTestCase(TestCase):
         module = UserDashboardModule.objects.get(pk=response['id'])
         module = UserDashboardModule.objects.get(pk=response['id'])
         self.assertNotEqual(module, None)
         self.assertNotEqual(module, None)
 
 
+    def test_add_user_app_dashboard_module_view(self):
+        app_label = 'auth'
+        response = self.admin.post(reverse('jet-dashboard:add_user_dashboard_module'), {
+            'app_label': app_label,
+            'type': 'available_children',
+            'module': 0
+        })
+
+        self.assertEqual(response.status_code, 200)
+        response = json.loads(response.content.decode())
+        self.assertFalse(response['error'])
+        self.assertNotEqual(response['id'], None)
+        module = UserDashboardModule.objects.get(pk=response['id'])
+        self.assertNotEqual(module, None)
+        self.assertEqual(module.app_label, app_label)
+
     def test_update_dashboard_module_collapse_view(self):
     def test_update_dashboard_module_collapse_view(self):
         module = UserDashboardModule.objects.create(
         module = UserDashboardModule.objects.create(
             title='',
             title='',

部分文件因为文件数量过多而无法显示