diff --git a/apps/assets/migrations/0001_initial.py b/apps/assets/migrations/0001_initial.py
deleted file mode 100644
index d07b2ce0f..000000000
--- a/apps/assets/migrations/0001_initial.py
+++ /dev/null
@@ -1,191 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10 on 2016-09-11 09:22
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
- initial = True
-
- dependencies = [
- ]
-
- operations = [
- migrations.CreateModel(
- name='AdminUser',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('name', models.CharField(max_length=128, unique=True, verbose_name='Name')),
- ('username', models.CharField(max_length=16, verbose_name='Username')),
- ('_password', models.CharField(blank=True, max_length=256, verbose_name='Password')),
- ('_private_key', models.CharField(blank=True, max_length=4096, verbose_name='SSH private key')),
- ('_public_key', models.CharField(blank=True, max_length=4096, verbose_name='SSH public key')),
- ('as_default', models.BooleanField(default=False, verbose_name='As default')),
- ('comment', models.TextField(blank=True, verbose_name='Comment')),
- ('date_created', models.DateTimeField(auto_now=True, null=True)),
- ('created_by', models.CharField(max_length=32, null=True, verbose_name='Created by')),
- ],
- options={
- 'db_table': 'admin_user',
- },
- ),
- migrations.CreateModel(
- name='Asset',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('ip', models.CharField(blank=True, max_length=32, null=True, verbose_name='IP')),
- ('other_ip', models.CharField(blank=True, max_length=255, null=True, verbose_name='Other IP')),
- ('remote_card_ip', models.CharField(blank=True, max_length=16, null=True, verbose_name='Remote card IP')),
- ('hostname', models.CharField(blank=True, max_length=128, null=True, unique=True, verbose_name='Hostname')),
- ('port', models.IntegerField(blank=True, null=True, verbose_name='Port')),
- ('username', models.CharField(blank=True, max_length=16, null=True, verbose_name='Admin user')),
- ('password', models.CharField(blank=True, max_length=256, null=True, verbose_name='Admin password')),
- ('mac_address', models.CharField(blank=True, max_length=20, null=True, verbose_name='Mac address')),
- ('brand', models.CharField(blank=True, max_length=64, null=True, verbose_name='Brand')),
- ('cpu', models.CharField(blank=True, max_length=64, null=True, verbose_name='CPU')),
- ('memory', models.CharField(blank=True, max_length=128, null=True, verbose_name='Memory')),
- ('disk', models.CharField(blank=True, max_length=1024, null=True, verbose_name='Disk')),
- ('os', models.CharField(blank=True, max_length=128, null=True, verbose_name='OS')),
- ('cabinet_no', models.CharField(blank=True, max_length=32, null=True, verbose_name='Cabinet number')),
- ('cabinet_pos', models.IntegerField(blank=True, null=True, verbose_name='Cabinet position')),
- ('number', models.CharField(blank=True, max_length=32, null=True, unique=True, verbose_name='Asset number')),
- ('sn', models.CharField(blank=True, max_length=128, null=True, unique=True, verbose_name='Serial number')),
- ('created_by', models.CharField(blank=True, max_length=32, null=True, verbose_name='Created by')),
- ('is_active', models.BooleanField(default=True, verbose_name='Is active')),
- ('date_created', models.DateTimeField(auto_now=True, null=True, verbose_name='Date added')),
- ('comment', models.CharField(blank=True, max_length=128, null=True, verbose_name='Comment')),
- ('admin_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='assets', to='assets.AdminUser', verbose_name='Admin user')),
- ],
- options={
- 'db_table': 'asset',
- },
- ),
- migrations.CreateModel(
- name='AssetExtend',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('key', models.CharField(blank=True, max_length=64, null=True, verbose_name='KEY')),
- ('value', models.CharField(blank=True, max_length=64, null=True, verbose_name='VALUE')),
- ('created_by', models.CharField(blank=True, max_length=32, verbose_name='Created by')),
- ('date_created', models.DateTimeField(auto_now=True, null=True)),
- ('comment', models.TextField(blank=True, verbose_name='Comment')),
- ],
- options={
- 'db_table': 'asset_extend',
- },
- ),
- migrations.CreateModel(
- name='AssetGroup',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('name', models.CharField(max_length=64, unique=True, verbose_name='Name')),
- ('created_by', models.CharField(blank=True, max_length=32, verbose_name='Created by')),
- ('date_created', models.DateTimeField(auto_now=True, null=True, verbose_name='Date added')),
- ('comment', models.TextField(blank=True, verbose_name='Comment')),
- ],
- options={
- 'db_table': 'asset_group',
- },
- ),
- migrations.CreateModel(
- name='IDC',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('name', models.CharField(max_length=32, verbose_name='Name')),
- ('bandwidth', models.CharField(blank=True, max_length=32, verbose_name='Bandwidth')),
- ('contact', models.CharField(blank=True, max_length=16, verbose_name='Contact')),
- ('phone', models.CharField(blank=True, max_length=32, verbose_name='Phone')),
- ('address', models.CharField(blank=True, max_length=128, verbose_name='Address')),
- ('network', models.TextField(blank=True, verbose_name='Network')),
- ('date_created', models.DateTimeField(auto_now=True, null=True, verbose_name='Date added')),
- ('operator', models.CharField(blank=True, max_length=32, verbose_name='Operator')),
- ('created_by', models.CharField(blank=True, max_length=32, verbose_name='Created by')),
- ('comment', models.TextField(blank=True, verbose_name='Comment')),
- ],
- options={
- 'db_table': 'idc',
- },
- ),
- migrations.CreateModel(
- name='Label',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('key', models.CharField(blank=True, max_length=64, null=True, verbose_name='KEY')),
- ('value', models.CharField(blank=True, max_length=64, null=True, verbose_name='VALUE')),
- ('created_by', models.CharField(blank=True, max_length=32, verbose_name='Created by')),
- ('date_created', models.DateTimeField(auto_now=True, null=True)),
- ('comment', models.CharField(blank=True, max_length=128, verbose_name='Comment')),
- ('asset', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='assets.Asset', verbose_name='Asset')),
- ],
- options={
- 'db_table': 'label',
- },
- ),
- migrations.CreateModel(
- name='SystemUser',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('name', models.CharField(max_length=128, unique=True, verbose_name='Name')),
- ('username', models.CharField(max_length=16, verbose_name='Username')),
- ('_password', models.CharField(blank=True, max_length=256, verbose_name='Password')),
- ('protocol', models.CharField(choices=[('ssh', 'ssh')], default='ssh', max_length=16, verbose_name='Protocol')),
- ('_private_key', models.CharField(blank=True, max_length=4096, verbose_name='SSH private key')),
- ('_public_key', models.CharField(blank=True, max_length=4096, verbose_name='SSH public key')),
- ('as_default', models.BooleanField(default=False, verbose_name='As default')),
- ('auto_push', models.BooleanField(default=True, verbose_name='Auto push')),
- ('auto_update', models.BooleanField(default=True, verbose_name='Auto update pass/key')),
- ('sudo', models.TextField(default='/user/bin/whoami', max_length=4096, verbose_name='Sudo')),
- ('shell', models.CharField(default='/bin/bash', max_length=64, verbose_name='Shell')),
- ('home', models.CharField(blank=True, max_length=64, verbose_name='Home')),
- ('uid', models.IntegerField(blank=True, null=True, verbose_name='Uid')),
- ('date_created', models.DateTimeField(auto_now=True)),
- ('created_by', models.CharField(blank=True, max_length=32, verbose_name='Created by')),
- ('comment', models.TextField(blank=True, max_length=128, verbose_name='Comment')),
- ],
- options={
- 'db_table': 'system_user',
- },
- ),
- migrations.AddField(
- model_name='assetgroup',
- name='system_users',
- field=models.ManyToManyField(blank=True, related_name='asset_groups', to='assets.SystemUser'),
- ),
- migrations.AddField(
- model_name='asset',
- name='env',
- field=models.ManyToManyField(related_name='asset_env_extend', to='assets.AssetExtend', verbose_name='Asset environment'),
- ),
- migrations.AddField(
- model_name='asset',
- name='groups',
- field=models.ManyToManyField(related_name='assets', to='assets.AssetGroup', verbose_name='Asset groups'),
- ),
- migrations.AddField(
- model_name='asset',
- name='idc',
- field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='assets', to='assets.IDC', verbose_name='IDC'),
- ),
- migrations.AddField(
- model_name='asset',
- name='status',
- field=models.ManyToManyField(related_name='asset_status_extend', to='assets.AssetExtend', verbose_name='Asset status'),
- ),
- migrations.AddField(
- model_name='asset',
- name='system_user',
- field=models.ManyToManyField(blank=True, related_name='assets', to='assets.SystemUser', verbose_name='System User'),
- ),
- migrations.AddField(
- model_name='asset',
- name='type',
- field=models.ManyToManyField(related_name='asset_type_extend', to='assets.AssetExtend', verbose_name='Asset type'),
- ),
- migrations.AlterIndexTogether(
- name='asset',
- index_together=set([('ip', 'port')]),
- ),
- ]
diff --git a/apps/assets/templates/assets/admin_user_list.html b/apps/assets/templates/assets/admin_user_list.html
index eeb4587bd..2031dfa49 100644
--- a/apps/assets/templates/assets/admin_user_list.html
+++ b/apps/assets/templates/assets/admin_user_list.html
@@ -34,7 +34,7 @@
{% trans 'Refresh' %}
{% trans 'Update' %}
- {% trans 'Delete' %}
+ {% trans 'Delete' %}
{% endfor %}
diff --git a/apps/assets/templates/assets/asset_group_list.html b/apps/assets/templates/assets/asset_group_list.html
index c5a4380ba..c945127cd 100644
--- a/apps/assets/templates/assets/asset_group_list.html
+++ b/apps/assets/templates/assets/asset_group_list.html
@@ -30,7 +30,7 @@
{{ asset_group.comment|truncatewords:8 }} |
{% trans 'Update' %}
- {% trans 'Delete' %}
+ {% trans 'Delete' %}
|
{% endfor %}
diff --git a/apps/assets/templates/assets/idc_list.html b/apps/assets/templates/assets/idc_list.html
index 4012331fc..ca8bd157b 100644
--- a/apps/assets/templates/assets/idc_list.html
+++ b/apps/assets/templates/assets/idc_list.html
@@ -28,8 +28,43 @@
{{ idc.address }} |
{% trans 'Update' %}
- {% trans 'Delete' %}
+ {% trans 'Delete' %}
|
{% endfor %}
{% endblock %}
+{% block custom_foot_js %}
+
+{% endblock %}
diff --git a/apps/assets/templates/assets/system_user_list.html b/apps/assets/templates/assets/system_user_list.html
index 37be0c3fc..ac8672347 100644
--- a/apps/assets/templates/assets/system_user_list.html
+++ b/apps/assets/templates/assets/system_user_list.html
@@ -36,7 +36,7 @@
{% trans 'Refresh' %}
{% trans 'Update' %}
- {% trans 'Delete' %}
+ {% trans 'Delete' %}
{% endfor %}
diff --git a/apps/assets/views.py b/apps/assets/views.py
index 04f4ae053..5b752d8ec 100644
--- a/apps/assets/views.py
+++ b/apps/assets/views.py
@@ -186,16 +186,25 @@ class IDCCreateView(AdminUserRequiredMixin, CreateView):
class IDCUpdateView(AdminUserRequiredMixin, UpdateView):
- pass
-
+ model = IDC
+ form_class = IDCForm
+ template_name = 'assets/idc_create.html'
+ context_object_name = 'IDC'
+ success_url = reverse_lazy('assets:idc-list')
+ def form_valid(self, form):
+ IDC = form.save(commit=False)
+ IDC.save()
+ return super(IDCUpdateView, self).form_valid(form)
class IDCDetailView(AdminUserRequiredMixin, DetailView):
pass
-class IDCDeleteView(AdminUserRequiredMixin, DeleteView):
- pass
+class IDCDeleteView(AdminUserRequiredMixin, DeleteView):
+ model = IDC
+ template_name = 'assets/delete_confirm.html'
+ success_url = reverse_lazy('assets:idc-list')
class AdminUserListView(AdminUserRequiredMixin, ListView):
model = AdminUser
@@ -293,7 +302,7 @@ class AdminUserDetailView(AdminUserRequiredMixin, SingleObjectMixin, ListView):
class AdminUserDeleteView(AdminUserRequiredMixin, DeleteView):
model = AdminUser
template_name = 'assets/delete_confirm.html'
- success_url = 'assets:admin-user-list'
+ success_url = reverse_lazy('assets:admin-user-list')
class SystemUserListView(AdminUserRequiredMixin, ListView):
@@ -384,7 +393,7 @@ class SystemUserDetailView(AdminUserRequiredMixin, DetailView):
class SystemUserDeleteView(AdminUserRequiredMixin, DeleteView):
model = SystemUser
template_name = 'assets/delete_confirm.html'
- success_url = 'assets:system-user-list'
+ success_url = reverse_lazy('assets:system-user-list')
class SystemUserAssetView(AdminUserRequiredMixin, SingleObjectMixin, ListView):
diff --git a/apps/fixtures/init.json b/apps/fixtures/init.json
index a9b504052..96cb0535a 100644
--- a/apps/fixtures/init.json
+++ b/apps/fixtures/init.json
@@ -1 +1 @@
-[{"model": "users.usergroup", "pk": 1, "fields": {"name": "Default", "comment": "Default user group for all user", "date_added": "2016-09-05T11:39:25.770Z", "created_by": "System"}}, {"model": "users.user", "pk": 1, "fields": {"password": "pbkdf2_sha256$30000$5ReHkQOQA2Hk$DIW0b5U/uK+U0xqjA3QpYvBcODNhm2MPCm7YWbQys3I=", "last_login": null, "first_name": "", "last_name": "", "is_active": true, "date_joined": "2016-09-05T11:39:25.771Z", "username": "admin", "name": "Administrator", "email": "admin@jumpserver.org", "role": "Admin", "avatar": "", "wechat": "", "phone": "", "enable_otp": false, "secret_key_otp": "", "private_key": "", "public_key": "", "comment": "Administrator is the super user of system", "is_first_login": false, "date_expired": "2086-08-19T11:39:25.771Z", "created_by": "System", "user_permissions": [], "groups": [1]}}]
\ No newline at end of file
+[{"model": "users.usergroup", "pk": 1, "fields": {"name": "Default", "comment": "Default user group for all user", "date_created": "2016-09-05T11:39:25.770Z", "created_by": "System"}}, {"model": "users.user", "pk": 1, "fields": {"password": "pbkdf2_sha256$30000$5ReHkQOQA2Hk$DIW0b5U/uK+U0xqjA3QpYvBcODNhm2MPCm7YWbQys3I=", "last_login": null, "first_name": "", "last_name": "", "is_active": true, "date_joined": "2016-09-05T11:39:25.771Z", "username": "admin", "name": "Administrator", "email": "admin@jumpserver.org", "role": "Admin", "avatar": "", "wechat": "", "phone": "", "enable_otp": false, "secret_key_otp": "", "private_key": "", "public_key": "", "comment": "Administrator is the super user of system", "is_first_login": false, "date_expired": "2086-08-19T11:39:25.771Z", "created_by": "System", "user_permissions": [], "groups": [1]}}]
\ No newline at end of file
diff --git a/apps/fixtures/users.json b/apps/fixtures/users.json
index a9b504052..dc4c209f0 100644
--- a/apps/fixtures/users.json
+++ b/apps/fixtures/users.json
@@ -1 +1 @@
-[{"model": "users.usergroup", "pk": 1, "fields": {"name": "Default", "comment": "Default user group for all user", "date_added": "2016-09-05T11:39:25.770Z", "created_by": "System"}}, {"model": "users.user", "pk": 1, "fields": {"password": "pbkdf2_sha256$30000$5ReHkQOQA2Hk$DIW0b5U/uK+U0xqjA3QpYvBcODNhm2MPCm7YWbQys3I=", "last_login": null, "first_name": "", "last_name": "", "is_active": true, "date_joined": "2016-09-05T11:39:25.771Z", "username": "admin", "name": "Administrator", "email": "admin@jumpserver.org", "role": "Admin", "avatar": "", "wechat": "", "phone": "", "enable_otp": false, "secret_key_otp": "", "private_key": "", "public_key": "", "comment": "Administrator is the super user of system", "is_first_login": false, "date_expired": "2086-08-19T11:39:25.771Z", "created_by": "System", "user_permissions": [], "groups": [1]}}]
\ No newline at end of file
+[{"model": "users.usergroup", "pk": 1, "fields": {"name": "Default", "comment": "Default user group for all user", "date_created": "2016-09-05T11:39:25.770Z", "created_by": "System"}}, {"model": "users.user", "pk": 1, "fields": {"password": "pbkdf2_sha256$30000$5ReHkQOQA2Hk$DIW0b5U/uK+U0xqjA3QpYvBcODNhm2MPCm7YWbQys3I=", "last_login": null, "first_name": "", "last_name": "", "is_active": true, "date_joined": "2016-09-05T11:39:25.771Z", "username": "admin", "name": "Administrator", "email": "admin@jumpserver.org", "role": "Admin", "avatar": "", "wechat": "", "phone": "", "enable_otp": false, "secret_key_otp": "", "_private_key": "", "_public_key": "", "comment": "Administrator is the super user of system", "is_first_login": false, "date_expired": "2086-08-19T11:39:25.771Z", "created_by": "System", "user_permissions": [], "groups": [1]}}]
\ No newline at end of file
diff --git a/apps/jumpserver/settings.py b/apps/jumpserver/settings.py
index 409cc2d03..8bbaf14bb 100644
--- a/apps/jumpserver/settings.py
+++ b/apps/jumpserver/settings.py
@@ -314,3 +314,4 @@ CAPTCHA_IMAGE_SIZE = (75, 33)
CAPTCHA_FOREGROUND_COLOR = '#001100'
#
+
diff --git a/apps/static/css/images/jbox-button1.png b/apps/static/css/images/jbox-button1.png
new file mode 100644
index 000000000..7d8a6a4b2
Binary files /dev/null and b/apps/static/css/images/jbox-button1.png differ
diff --git a/apps/static/css/images/jbox-close.gif b/apps/static/css/images/jbox-close.gif
new file mode 100644
index 000000000..83ffe0b6c
Binary files /dev/null and b/apps/static/css/images/jbox-close.gif differ
diff --git a/apps/static/css/images/jbox-icons.png b/apps/static/css/images/jbox-icons.png
new file mode 100644
index 000000000..c35abcffc
Binary files /dev/null and b/apps/static/css/images/jbox-icons.png differ
diff --git a/apps/static/css/plugins/sweetalert/sweetalert.css b/apps/static/css/plugins/sweetalert/sweetalert.css
new file mode 100644
index 000000000..4469aea6b
--- /dev/null
+++ b/apps/static/css/plugins/sweetalert/sweetalert.css
@@ -0,0 +1,715 @@
+body.stop-scrolling {
+ height: 100%;
+ overflow: hidden; }
+
+.sweet-overlay {
+ background-color: black;
+ /* IE8 */
+ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)";
+ /* IE8 */
+ background-color: rgba(0, 0, 0, 0.4);
+ position: fixed;
+ left: 0;
+ right: 0;
+ top: 0;
+ bottom: 0;
+ display: none;
+ z-index: 10000; }
+
+.sweet-alert {
+ background-color: white;
+ font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
+ width: 478px;
+ padding: 17px;
+ border-radius: 5px;
+ text-align: center;
+ position: fixed;
+ left: 50%;
+ top: 50%;
+ margin-left: -256px;
+ margin-top: -200px;
+ overflow: hidden;
+ display: none;
+ z-index: 99999; }
+ @media all and (max-width: 540px) {
+ .sweet-alert {
+ width: auto;
+ margin-left: 0;
+ margin-right: 0;
+ left: 15px;
+ right: 15px; } }
+ .sweet-alert h2 {
+ color: #575757;
+ font-size: 30px;
+ text-align: center;
+ font-weight: 600;
+ text-transform: none;
+ position: relative;
+ margin: 25px 0;
+ padding: 0;
+ line-height: 40px;
+ display: block; }
+ .sweet-alert p {
+ color: #797979;
+ font-size: 16px;
+ text-align: center;
+ font-weight: 300;
+ position: relative;
+ text-align: inherit;
+ float: none;
+ margin: 0;
+ padding: 0;
+ line-height: normal; }
+ .sweet-alert fieldset {
+ border: none;
+ position: relative; }
+ .sweet-alert .sa-error-container {
+ background-color: #f1f1f1;
+ margin-left: -17px;
+ margin-right: -17px;
+ overflow: hidden;
+ padding: 0 10px;
+ max-height: 0;
+ webkit-transition: padding 0.15s, max-height 0.15s;
+ transition: padding 0.15s, max-height 0.15s; }
+ .sweet-alert .sa-error-container.show {
+ padding: 10px 0;
+ max-height: 100px;
+ webkit-transition: padding 0.2s, max-height 0.2s;
+ transition: padding 0.25s, max-height 0.25s; }
+ .sweet-alert .sa-error-container .icon {
+ display: inline-block;
+ width: 24px;
+ height: 24px;
+ border-radius: 50%;
+ background-color: #ea7d7d;
+ color: white;
+ line-height: 24px;
+ text-align: center;
+ margin-right: 3px; }
+ .sweet-alert .sa-error-container p {
+ display: inline-block; }
+ .sweet-alert .sa-input-error {
+ position: absolute;
+ top: 29px;
+ right: 26px;
+ width: 20px;
+ height: 20px;
+ opacity: 0;
+ -webkit-transform: scale(0.5);
+ transform: scale(0.5);
+ -webkit-transform-origin: 50% 50%;
+ transform-origin: 50% 50%;
+ -webkit-transition: all 0.1s;
+ transition: all 0.1s; }
+ .sweet-alert .sa-input-error::before, .sweet-alert .sa-input-error::after {
+ content: "";
+ width: 20px;
+ height: 6px;
+ background-color: #f06e57;
+ border-radius: 3px;
+ position: absolute;
+ top: 50%;
+ margin-top: -4px;
+ left: 50%;
+ margin-left: -9px; }
+ .sweet-alert .sa-input-error::before {
+ -webkit-transform: rotate(-45deg);
+ transform: rotate(-45deg); }
+ .sweet-alert .sa-input-error::after {
+ -webkit-transform: rotate(45deg);
+ transform: rotate(45deg); }
+ .sweet-alert .sa-input-error.show {
+ opacity: 1;
+ -webkit-transform: scale(1);
+ transform: scale(1); }
+ .sweet-alert input {
+ width: 100%;
+ box-sizing: border-box;
+ border-radius: 3px;
+ border: 1px solid #d7d7d7;
+ height: 43px;
+ margin-top: 10px;
+ margin-bottom: 17px;
+ font-size: 18px;
+ box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.06);
+ padding: 0 12px;
+ display: none;
+ -webkit-transition: all 0.3s;
+ transition: all 0.3s; }
+ .sweet-alert input:focus {
+ outline: none;
+ box-shadow: 0px 0px 3px #c4e6f5;
+ border: 1px solid #b4dbed; }
+ .sweet-alert input:focus::-moz-placeholder {
+ transition: opacity 0.3s 0.03s ease;
+ opacity: 0.5; }
+ .sweet-alert input:focus:-ms-input-placeholder {
+ transition: opacity 0.3s 0.03s ease;
+ opacity: 0.5; }
+ .sweet-alert input:focus::-webkit-input-placeholder {
+ transition: opacity 0.3s 0.03s ease;
+ opacity: 0.5; }
+ .sweet-alert input::-moz-placeholder {
+ color: #bdbdbd; }
+ .sweet-alert input:-ms-input-placeholder {
+ color: #bdbdbd; }
+ .sweet-alert input::-webkit-input-placeholder {
+ color: #bdbdbd; }
+ .sweet-alert.show-input input {
+ display: block; }
+ .sweet-alert button {
+ background-color: #AEDEF4;
+ color: white;
+ border: none;
+ box-shadow: none;
+ font-size: 17px;
+ font-weight: 500;
+ -webkit-border-radius: 4px;
+ border-radius: 5px;
+ padding: 10px 32px;
+ margin: 26px 5px 0 5px;
+ cursor: pointer; }
+ .sweet-alert button:focus {
+ outline: none;
+ box-shadow: 0 0 2px rgba(128, 179, 235, 0.5), inset 0 0 0 1px rgba(0, 0, 0, 0.05); }
+ .sweet-alert button:hover {
+ background-color: #a1d9f2; }
+ .sweet-alert button:active {
+ background-color: #81ccee; }
+ .sweet-alert button.cancel {
+ background-color: #D0D0D0; }
+ .sweet-alert button.cancel:hover {
+ background-color: #c8c8c8; }
+ .sweet-alert button.cancel:active {
+ background-color: #b6b6b6; }
+ .sweet-alert button.cancel:focus {
+ box-shadow: rgba(197, 205, 211, 0.8) 0px 0px 2px, rgba(0, 0, 0, 0.0470588) 0px 0px 0px 1px inset !important; }
+ .sweet-alert button::-moz-focus-inner {
+ border: 0; }
+ .sweet-alert[data-has-cancel-button=false] button {
+ box-shadow: none !important; }
+ .sweet-alert[data-has-confirm-button=false][data-has-cancel-button=false] {
+ padding-bottom: 40px; }
+ .sweet-alert .sa-icon {
+ width: 80px;
+ height: 80px;
+ border: 4px solid gray;
+ -webkit-border-radius: 40px;
+ border-radius: 40px;
+ border-radius: 50%;
+ margin: 20px auto;
+ padding: 0;
+ position: relative;
+ box-sizing: content-box; }
+ .sweet-alert .sa-icon.sa-error {
+ border-color: #F27474; }
+ .sweet-alert .sa-icon.sa-error .sa-x-mark {
+ position: relative;
+ display: block; }
+ .sweet-alert .sa-icon.sa-error .sa-line {
+ position: absolute;
+ height: 5px;
+ width: 47px;
+ background-color: #F27474;
+ display: block;
+ top: 37px;
+ border-radius: 2px; }
+ .sweet-alert .sa-icon.sa-error .sa-line.sa-left {
+ -webkit-transform: rotate(45deg);
+ transform: rotate(45deg);
+ left: 17px; }
+ .sweet-alert .sa-icon.sa-error .sa-line.sa-right {
+ -webkit-transform: rotate(-45deg);
+ transform: rotate(-45deg);
+ right: 16px; }
+ .sweet-alert .sa-icon.sa-warning {
+ border-color: #F8BB86; }
+ .sweet-alert .sa-icon.sa-warning .sa-body {
+ position: absolute;
+ width: 5px;
+ height: 47px;
+ left: 50%;
+ top: 10px;
+ -webkit-border-radius: 2px;
+ border-radius: 2px;
+ margin-left: -2px;
+ background-color: #F8BB86; }
+ .sweet-alert .sa-icon.sa-warning .sa-dot {
+ position: absolute;
+ width: 7px;
+ height: 7px;
+ -webkit-border-radius: 50%;
+ border-radius: 50%;
+ margin-left: -3px;
+ left: 50%;
+ bottom: 10px;
+ background-color: #F8BB86; }
+ .sweet-alert .sa-icon.sa-info {
+ border-color: #C9DAE1; }
+ .sweet-alert .sa-icon.sa-info::before {
+ content: "";
+ position: absolute;
+ width: 5px;
+ height: 29px;
+ left: 50%;
+ bottom: 17px;
+ border-radius: 2px;
+ margin-left: -2px;
+ background-color: #C9DAE1; }
+ .sweet-alert .sa-icon.sa-info::after {
+ content: "";
+ position: absolute;
+ width: 7px;
+ height: 7px;
+ border-radius: 50%;
+ margin-left: -3px;
+ top: 19px;
+ background-color: #C9DAE1; }
+ .sweet-alert .sa-icon.sa-success {
+ border-color: #A5DC86; }
+ .sweet-alert .sa-icon.sa-success::before, .sweet-alert .sa-icon.sa-success::after {
+ content: '';
+ -webkit-border-radius: 40px;
+ border-radius: 40px;
+ border-radius: 50%;
+ position: absolute;
+ width: 60px;
+ height: 120px;
+ background: white;
+ -webkit-transform: rotate(45deg);
+ transform: rotate(45deg); }
+ .sweet-alert .sa-icon.sa-success::before {
+ -webkit-border-radius: 120px 0 0 120px;
+ border-radius: 120px 0 0 120px;
+ top: -7px;
+ left: -33px;
+ -webkit-transform: rotate(-45deg);
+ transform: rotate(-45deg);
+ -webkit-transform-origin: 60px 60px;
+ transform-origin: 60px 60px; }
+ .sweet-alert .sa-icon.sa-success::after {
+ -webkit-border-radius: 0 120px 120px 0;
+ border-radius: 0 120px 120px 0;
+ top: -11px;
+ left: 30px;
+ -webkit-transform: rotate(-45deg);
+ transform: rotate(-45deg);
+ -webkit-transform-origin: 0px 60px;
+ transform-origin: 0px 60px; }
+ .sweet-alert .sa-icon.sa-success .sa-placeholder {
+ width: 80px;
+ height: 80px;
+ border: 4px solid rgba(165, 220, 134, 0.2);
+ -webkit-border-radius: 40px;
+ border-radius: 40px;
+ border-radius: 50%;
+ box-sizing: content-box;
+ position: absolute;
+ left: -4px;
+ top: -4px;
+ z-index: 2; }
+ .sweet-alert .sa-icon.sa-success .sa-fix {
+ width: 5px;
+ height: 90px;
+ background-color: white;
+ position: absolute;
+ left: 28px;
+ top: 8px;
+ z-index: 1;
+ -webkit-transform: rotate(-45deg);
+ transform: rotate(-45deg); }
+ .sweet-alert .sa-icon.sa-success .sa-line {
+ height: 5px;
+ background-color: #A5DC86;
+ display: block;
+ border-radius: 2px;
+ position: absolute;
+ z-index: 2; }
+ .sweet-alert .sa-icon.sa-success .sa-line.sa-tip {
+ width: 25px;
+ left: 14px;
+ top: 46px;
+ -webkit-transform: rotate(45deg);
+ transform: rotate(45deg); }
+ .sweet-alert .sa-icon.sa-success .sa-line.sa-long {
+ width: 47px;
+ right: 8px;
+ top: 38px;
+ -webkit-transform: rotate(-45deg);
+ transform: rotate(-45deg); }
+ .sweet-alert .sa-icon.sa-custom {
+ background-size: contain;
+ border-radius: 0;
+ border: none;
+ background-position: center center;
+ background-repeat: no-repeat; }
+
+/*
+ * Animations
+ */
+@-webkit-keyframes showSweetAlert {
+ 0% {
+ transform: scale(0.7);
+ -webkit-transform: scale(0.7); }
+ 45% {
+ transform: scale(1.05);
+ -webkit-transform: scale(1.05); }
+ 80% {
+ transform: scale(0.95);
+ -webkit-transform: scale(0.95); }
+ 100% {
+ transform: scale(1);
+ -webkit-transform: scale(1); } }
+
+@keyframes showSweetAlert {
+ 0% {
+ transform: scale(0.7);
+ -webkit-transform: scale(0.7); }
+ 45% {
+ transform: scale(1.05);
+ -webkit-transform: scale(1.05); }
+ 80% {
+ transform: scale(0.95);
+ -webkit-transform: scale(0.95); }
+ 100% {
+ transform: scale(1);
+ -webkit-transform: scale(1); } }
+
+@-webkit-keyframes hideSweetAlert {
+ 0% {
+ transform: scale(1);
+ -webkit-transform: scale(1); }
+ 100% {
+ transform: scale(0.5);
+ -webkit-transform: scale(0.5); } }
+
+@keyframes hideSweetAlert {
+ 0% {
+ transform: scale(1);
+ -webkit-transform: scale(1); }
+ 100% {
+ transform: scale(0.5);
+ -webkit-transform: scale(0.5); } }
+
+@-webkit-keyframes slideFromTop {
+ 0% {
+ top: 0%; }
+ 100% {
+ top: 50%; } }
+
+@keyframes slideFromTop {
+ 0% {
+ top: 0%; }
+ 100% {
+ top: 50%; } }
+
+@-webkit-keyframes slideToTop {
+ 0% {
+ top: 50%; }
+ 100% {
+ top: 0%; } }
+
+@keyframes slideToTop {
+ 0% {
+ top: 50%; }
+ 100% {
+ top: 0%; } }
+
+@-webkit-keyframes slideFromBottom {
+ 0% {
+ top: 70%; }
+ 100% {
+ top: 50%; } }
+
+@keyframes slideFromBottom {
+ 0% {
+ top: 70%; }
+ 100% {
+ top: 50%; } }
+
+@-webkit-keyframes slideToBottom {
+ 0% {
+ top: 50%; }
+ 100% {
+ top: 70%; } }
+
+@keyframes slideToBottom {
+ 0% {
+ top: 50%; }
+ 100% {
+ top: 70%; } }
+
+.showSweetAlert[data-animation=pop] {
+ -webkit-animation: showSweetAlert 0.3s;
+ animation: showSweetAlert 0.3s; }
+
+.showSweetAlert[data-animation=none] {
+ -webkit-animation: none;
+ animation: none; }
+
+.showSweetAlert[data-animation=slide-from-top] {
+ -webkit-animation: slideFromTop 0.3s;
+ animation: slideFromTop 0.3s; }
+
+.showSweetAlert[data-animation=slide-from-bottom] {
+ -webkit-animation: slideFromBottom 0.3s;
+ animation: slideFromBottom 0.3s; }
+
+.hideSweetAlert[data-animation=pop] {
+ -webkit-animation: hideSweetAlert 0.2s;
+ animation: hideSweetAlert 0.2s; }
+
+.hideSweetAlert[data-animation=none] {
+ -webkit-animation: none;
+ animation: none; }
+
+.hideSweetAlert[data-animation=slide-from-top] {
+ -webkit-animation: slideToTop 0.4s;
+ animation: slideToTop 0.4s; }
+
+.hideSweetAlert[data-animation=slide-from-bottom] {
+ -webkit-animation: slideToBottom 0.3s;
+ animation: slideToBottom 0.3s; }
+
+@-webkit-keyframes animateSuccessTip {
+ 0% {
+ width: 0;
+ left: 1px;
+ top: 19px; }
+ 54% {
+ width: 0;
+ left: 1px;
+ top: 19px; }
+ 70% {
+ width: 50px;
+ left: -8px;
+ top: 37px; }
+ 84% {
+ width: 17px;
+ left: 21px;
+ top: 48px; }
+ 100% {
+ width: 25px;
+ left: 14px;
+ top: 45px; } }
+
+@keyframes animateSuccessTip {
+ 0% {
+ width: 0;
+ left: 1px;
+ top: 19px; }
+ 54% {
+ width: 0;
+ left: 1px;
+ top: 19px; }
+ 70% {
+ width: 50px;
+ left: -8px;
+ top: 37px; }
+ 84% {
+ width: 17px;
+ left: 21px;
+ top: 48px; }
+ 100% {
+ width: 25px;
+ left: 14px;
+ top: 45px; } }
+
+@-webkit-keyframes animateSuccessLong {
+ 0% {
+ width: 0;
+ right: 46px;
+ top: 54px; }
+ 65% {
+ width: 0;
+ right: 46px;
+ top: 54px; }
+ 84% {
+ width: 55px;
+ right: 0px;
+ top: 35px; }
+ 100% {
+ width: 47px;
+ right: 8px;
+ top: 38px; } }
+
+@keyframes animateSuccessLong {
+ 0% {
+ width: 0;
+ right: 46px;
+ top: 54px; }
+ 65% {
+ width: 0;
+ right: 46px;
+ top: 54px; }
+ 84% {
+ width: 55px;
+ right: 0px;
+ top: 35px; }
+ 100% {
+ width: 47px;
+ right: 8px;
+ top: 38px; } }
+
+@-webkit-keyframes rotatePlaceholder {
+ 0% {
+ transform: rotate(-45deg);
+ -webkit-transform: rotate(-45deg); }
+ 5% {
+ transform: rotate(-45deg);
+ -webkit-transform: rotate(-45deg); }
+ 12% {
+ transform: rotate(-405deg);
+ -webkit-transform: rotate(-405deg); }
+ 100% {
+ transform: rotate(-405deg);
+ -webkit-transform: rotate(-405deg); } }
+
+@keyframes rotatePlaceholder {
+ 0% {
+ transform: rotate(-45deg);
+ -webkit-transform: rotate(-45deg); }
+ 5% {
+ transform: rotate(-45deg);
+ -webkit-transform: rotate(-45deg); }
+ 12% {
+ transform: rotate(-405deg);
+ -webkit-transform: rotate(-405deg); }
+ 100% {
+ transform: rotate(-405deg);
+ -webkit-transform: rotate(-405deg); } }
+
+.animateSuccessTip {
+ -webkit-animation: animateSuccessTip 0.75s;
+ animation: animateSuccessTip 0.75s; }
+
+.animateSuccessLong {
+ -webkit-animation: animateSuccessLong 0.75s;
+ animation: animateSuccessLong 0.75s; }
+
+.sa-icon.sa-success.animate::after {
+ -webkit-animation: rotatePlaceholder 4.25s ease-in;
+ animation: rotatePlaceholder 4.25s ease-in; }
+
+@-webkit-keyframes animateErrorIcon {
+ 0% {
+ transform: rotateX(100deg);
+ -webkit-transform: rotateX(100deg);
+ opacity: 0; }
+ 100% {
+ transform: rotateX(0deg);
+ -webkit-transform: rotateX(0deg);
+ opacity: 1; } }
+
+@keyframes animateErrorIcon {
+ 0% {
+ transform: rotateX(100deg);
+ -webkit-transform: rotateX(100deg);
+ opacity: 0; }
+ 100% {
+ transform: rotateX(0deg);
+ -webkit-transform: rotateX(0deg);
+ opacity: 1; } }
+
+.animateErrorIcon {
+ -webkit-animation: animateErrorIcon 0.5s;
+ animation: animateErrorIcon 0.5s; }
+
+@-webkit-keyframes animateXMark {
+ 0% {
+ transform: scale(0.4);
+ -webkit-transform: scale(0.4);
+ margin-top: 26px;
+ opacity: 0; }
+ 50% {
+ transform: scale(0.4);
+ -webkit-transform: scale(0.4);
+ margin-top: 26px;
+ opacity: 0; }
+ 80% {
+ transform: scale(1.15);
+ -webkit-transform: scale(1.15);
+ margin-top: -6px; }
+ 100% {
+ transform: scale(1);
+ -webkit-transform: scale(1);
+ margin-top: 0;
+ opacity: 1; } }
+
+@keyframes animateXMark {
+ 0% {
+ transform: scale(0.4);
+ -webkit-transform: scale(0.4);
+ margin-top: 26px;
+ opacity: 0; }
+ 50% {
+ transform: scale(0.4);
+ -webkit-transform: scale(0.4);
+ margin-top: 26px;
+ opacity: 0; }
+ 80% {
+ transform: scale(1.15);
+ -webkit-transform: scale(1.15);
+ margin-top: -6px; }
+ 100% {
+ transform: scale(1);
+ -webkit-transform: scale(1);
+ margin-top: 0;
+ opacity: 1; } }
+
+.animateXMark {
+ -webkit-animation: animateXMark 0.5s;
+ animation: animateXMark 0.5s; }
+
+@-webkit-keyframes pulseWarning {
+ 0% {
+ border-color: #F8D486; }
+ 100% {
+ border-color: #F8BB86; } }
+
+@keyframes pulseWarning {
+ 0% {
+ border-color: #F8D486; }
+ 100% {
+ border-color: #F8BB86; } }
+
+.pulseWarning {
+ -webkit-animation: pulseWarning 0.75s infinite alternate;
+ animation: pulseWarning 0.75s infinite alternate; }
+
+@-webkit-keyframes pulseWarningIns {
+ 0% {
+ background-color: #F8D486; }
+ 100% {
+ background-color: #F8BB86; } }
+
+@keyframes pulseWarningIns {
+ 0% {
+ background-color: #F8D486; }
+ 100% {
+ background-color: #F8BB86; } }
+
+.pulseWarningIns {
+ -webkit-animation: pulseWarningIns 0.75s infinite alternate;
+ animation: pulseWarningIns 0.75s infinite alternate; }
+
+/* Internet Explorer 9 has some special quirks that are fixed here */
+/* The icons are not animated. */
+/* This file is automatically merged into sweet-alert.min.js through Gulp */
+/* Error icon */
+.sweet-alert .sa-icon.sa-error .sa-line.sa-left {
+ -ms-transform: rotate(45deg) \9; }
+
+.sweet-alert .sa-icon.sa-error .sa-line.sa-right {
+ -ms-transform: rotate(-45deg) \9; }
+
+/* Success icon */
+.sweet-alert .sa-icon.sa-success {
+ border-color: transparent\9; }
+
+.sweet-alert .sa-icon.sa-success .sa-line.sa-tip {
+ -ms-transform: rotate(45deg) \9; }
+
+.sweet-alert .sa-icon.sa-success .sa-line.sa-long {
+ -ms-transform: rotate(-45deg) \9; }
diff --git a/apps/static/jbox/Skins/jumpserver/Desktop.ini b/apps/static/jbox/Skins/jumpserver/Desktop.ini
new file mode 100644
index 000000000..09485b11b
--- /dev/null
+++ b/apps/static/jbox/Skins/jumpserver/Desktop.ini
@@ -0,0 +1,3 @@
+[.ShellClassInfo]
+IconFile=%SystemRoot%\system32\SHELL32.dll
+IconIndex=161
diff --git a/apps/static/jbox/Skins/jumpserver/images/Thumbs.db b/apps/static/jbox/Skins/jumpserver/images/Thumbs.db
new file mode 100644
index 000000000..37d2c8e06
Binary files /dev/null and b/apps/static/jbox/Skins/jumpserver/images/Thumbs.db differ
diff --git a/apps/static/jbox/Skins/jumpserver/images/jbox-button1.png b/apps/static/jbox/Skins/jumpserver/images/jbox-button1.png
new file mode 100644
index 000000000..7d8a6a4b2
Binary files /dev/null and b/apps/static/jbox/Skins/jumpserver/images/jbox-button1.png differ
diff --git a/apps/static/jbox/Skins/jumpserver/images/jbox-button2.png b/apps/static/jbox/Skins/jumpserver/images/jbox-button2.png
new file mode 100644
index 000000000..456a48100
Binary files /dev/null and b/apps/static/jbox/Skins/jumpserver/images/jbox-button2.png differ
diff --git a/apps/static/jbox/Skins/jumpserver/images/jbox-close1.gif b/apps/static/jbox/Skins/jumpserver/images/jbox-close1.gif
new file mode 100644
index 000000000..a87057e89
Binary files /dev/null and b/apps/static/jbox/Skins/jumpserver/images/jbox-close1.gif differ
diff --git a/apps/static/jbox/Skins/jumpserver/images/jbox-close2.gif b/apps/static/jbox/Skins/jumpserver/images/jbox-close2.gif
new file mode 100644
index 000000000..dd2dde900
Binary files /dev/null and b/apps/static/jbox/Skins/jumpserver/images/jbox-close2.gif differ
diff --git a/apps/static/jbox/Skins/jumpserver/images/jbox-content-loading.gif b/apps/static/jbox/Skins/jumpserver/images/jbox-content-loading.gif
new file mode 100644
index 000000000..f3e165009
Binary files /dev/null and b/apps/static/jbox/Skins/jumpserver/images/jbox-content-loading.gif differ
diff --git a/apps/static/jbox/Skins/jumpserver/images/jbox-icons-ie6.gif b/apps/static/jbox/Skins/jumpserver/images/jbox-icons-ie6.gif
new file mode 100644
index 000000000..201b912e0
Binary files /dev/null and b/apps/static/jbox/Skins/jumpserver/images/jbox-icons-ie6.gif differ
diff --git a/apps/static/jbox/Skins/jumpserver/images/jbox-icons.png b/apps/static/jbox/Skins/jumpserver/images/jbox-icons.png
new file mode 100644
index 000000000..c35abcffc
Binary files /dev/null and b/apps/static/jbox/Skins/jumpserver/images/jbox-icons.png differ
diff --git a/apps/static/jbox/Skins/jumpserver/images/jbox-loading1.gif b/apps/static/jbox/Skins/jumpserver/images/jbox-loading1.gif
new file mode 100644
index 000000000..684c59dbe
Binary files /dev/null and b/apps/static/jbox/Skins/jumpserver/images/jbox-loading1.gif differ
diff --git a/apps/static/jbox/Skins/jumpserver/images/jbox-loading2.gif b/apps/static/jbox/Skins/jumpserver/images/jbox-loading2.gif
new file mode 100644
index 000000000..60f007036
Binary files /dev/null and b/apps/static/jbox/Skins/jumpserver/images/jbox-loading2.gif differ
diff --git a/apps/static/jbox/Skins/jumpserver/images/jbox-loading3.gif b/apps/static/jbox/Skins/jumpserver/images/jbox-loading3.gif
new file mode 100644
index 000000000..5e0e6c17b
Binary files /dev/null and b/apps/static/jbox/Skins/jumpserver/images/jbox-loading3.gif differ
diff --git a/apps/static/jbox/Skins/jumpserver/images/jbox-title-icon.gif b/apps/static/jbox/Skins/jumpserver/images/jbox-title-icon.gif
new file mode 100644
index 000000000..b9c772fb5
Binary files /dev/null and b/apps/static/jbox/Skins/jumpserver/images/jbox-title-icon.gif differ
diff --git a/apps/static/jbox/Skins/jumpserver/jbox.css b/apps/static/jbox/Skins/jumpserver/jbox.css
new file mode 100644
index 000000000..e34a7b3d8
--- /dev/null
+++ b/apps/static/jbox/Skins/jumpserver/jbox.css
@@ -0,0 +1,43 @@
+@charset "utf-8";
+/*
+ ʾCSS ʽֻɫԣͼƬĵַͼƬСҪĬϵһ£border:dotted solid double dashed
+*/
+*:focus {outline: none;}
+/* fade */
+.jbox-fade{background-color:#000000;}
+/* drag */
+.jbox-drag{border:1px dashed #003870;}
+/* jbox */
+div.jbox {padding:0px;border:none;font-size:12px;}
+/* border */
+div.jbox .jbox-border{background: none repeat scroll 0 0 #000000;filter:alpha(opacity=20);-moz-opacity:0.2;opacity:0.2;}
+/* container */
+div.jbox .jbox-container{background-color:#ffffff;border:1px solid #999999;}
+/* title-panel */
+div.jbox .jbox-title-panel{background:#2f4050;border-bottom:1px solid #CCCCCC;}
+div.jbox .jbox-title{font-weight:bold;color:#ffffff;}
+div.jbox .jbox-title-icon{background:url(images/jbox-title-icon.gif) no-repeat scroll 3px 5px transparent;}
+div.jbox .jbox-close,div.jbox .jbox-close-hover{background:url(images/jbox-close1.gif) no-repeat scroll 0px 0px transparent;}
+div.jbox .jbox-close-hover{background-position:-16px 0;}
+/* content */
+div.jbox .jbox-content{min-height:24px;line-height:18px;color:#444444;}
+div.jbox .jbox-content-loading{background-color:#E6E6E6;}
+div.jbox .jbox-content-loading-image{background:url(images/jbox-content-loading.gif) no-repeat bottom center;}
+/* button-panel */
+div.jbox .jbox-button-panel{border-top:1px solid #CCCCCC;background-color: #EEEEEE;}
+div.jbox .jbox-bottom-text{text-indent:10px;color:#444444;}
+div.jbox .jbox-button{background:url(images/jbox-button2.png) repeat-x transparent;border:#AAAAAA 1px solid;color:#888888;border-radius:3px 3px 3px 3px;margin:1px 7px 0px 0px;height:22px;cursor:default;}
+div.jbox .jbox-button-hover{background-position:0px -20px;color:#666666;}
+div.jbox .jbox-button-active{background-position:0px -40px;}
+div.jbox-warning .jbox .jbox-button-panel{background-color: #FFFFFF;}
+/* tip-color */
+div.jbox .jbox-tip-color{background-color:#003870;border-color:#003870;border-radius:3px 3px 3px 3px;color:#ffffff;}
+/* icons */
+div.jbox span.jbox-icon{background:url(images/jbox-icons.png) no-repeat scroll 0 0 transparent;_background:url(images/jbox-icons-ie6.gif) no-repeat scroll 0 0 transparent;}
+div.jbox span.jbox-icon-info {background-position:0 0;}
+div.jbox span.jbox-icon-question {background-position:-36px 0;}
+div.jbox span.jbox-icon-success {background-position:-72px 0;}
+div.jbox span.jbox-icon-warning {background-position:-108px 0;}
+div.jbox span.jbox-icon-error {background-position:-144px 0;}
+div.jbox span.jbox-icon-none {display: none; overflow:hidden;}
+div.jbox span.jbox-icon-loading {background:url(images/jbox-loading1.gif) no-repeat scroll 0 0 transparent;}
\ No newline at end of file
diff --git a/apps/static/jbox/Skins2/jumpserver/Desktop.ini b/apps/static/jbox/Skins2/jumpserver/Desktop.ini
new file mode 100644
index 000000000..09485b11b
--- /dev/null
+++ b/apps/static/jbox/Skins2/jumpserver/Desktop.ini
@@ -0,0 +1,3 @@
+[.ShellClassInfo]
+IconFile=%SystemRoot%\system32\SHELL32.dll
+IconIndex=161
diff --git a/apps/static/jbox/Skins2/jumpserver/images/Thumbs.db b/apps/static/jbox/Skins2/jumpserver/images/Thumbs.db
new file mode 100644
index 000000000..c9e4ec7f9
Binary files /dev/null and b/apps/static/jbox/Skins2/jumpserver/images/Thumbs.db differ
diff --git a/apps/static/jbox/Skins2/jumpserver/images/jbox-close1.gif b/apps/static/jbox/Skins2/jumpserver/images/jbox-close1.gif
new file mode 100644
index 000000000..a87057e89
Binary files /dev/null and b/apps/static/jbox/Skins2/jumpserver/images/jbox-close1.gif differ
diff --git a/apps/static/jbox/Skins2/jumpserver/images/jbox-close2.gif b/apps/static/jbox/Skins2/jumpserver/images/jbox-close2.gif
new file mode 100644
index 000000000..dd2dde900
Binary files /dev/null and b/apps/static/jbox/Skins2/jumpserver/images/jbox-close2.gif differ
diff --git a/apps/static/jbox/Skins2/jumpserver/images/jbox-content-loading.gif b/apps/static/jbox/Skins2/jumpserver/images/jbox-content-loading.gif
new file mode 100644
index 000000000..f04301a94
Binary files /dev/null and b/apps/static/jbox/Skins2/jumpserver/images/jbox-content-loading.gif differ
diff --git a/apps/static/jbox/Skins2/jumpserver/images/jbox-icons-ie6.gif b/apps/static/jbox/Skins2/jumpserver/images/jbox-icons-ie6.gif
new file mode 100644
index 000000000..201b912e0
Binary files /dev/null and b/apps/static/jbox/Skins2/jumpserver/images/jbox-icons-ie6.gif differ
diff --git a/apps/static/jbox/Skins2/jumpserver/images/jbox-icons.png b/apps/static/jbox/Skins2/jumpserver/images/jbox-icons.png
new file mode 100644
index 000000000..f72f29240
Binary files /dev/null and b/apps/static/jbox/Skins2/jumpserver/images/jbox-icons.png differ
diff --git a/apps/static/jbox/Skins2/jumpserver/images/jbox-loading1.gif b/apps/static/jbox/Skins2/jumpserver/images/jbox-loading1.gif
new file mode 100644
index 000000000..5e0834f1d
Binary files /dev/null and b/apps/static/jbox/Skins2/jumpserver/images/jbox-loading1.gif differ
diff --git a/apps/static/jbox/Skins2/jumpserver/images/jbox-loading2.gif b/apps/static/jbox/Skins2/jumpserver/images/jbox-loading2.gif
new file mode 100644
index 000000000..209124ab6
Binary files /dev/null and b/apps/static/jbox/Skins2/jumpserver/images/jbox-loading2.gif differ
diff --git a/apps/static/jbox/Skins2/jumpserver/images/jbox-loading3.gif b/apps/static/jbox/Skins2/jumpserver/images/jbox-loading3.gif
new file mode 100644
index 000000000..770540141
Binary files /dev/null and b/apps/static/jbox/Skins2/jumpserver/images/jbox-loading3.gif differ
diff --git a/apps/static/jbox/Skins2/jumpserver/images/jbox-title-icon.gif b/apps/static/jbox/Skins2/jumpserver/images/jbox-title-icon.gif
new file mode 100644
index 000000000..b9c772fb5
Binary files /dev/null and b/apps/static/jbox/Skins2/jumpserver/images/jbox-title-icon.gif differ
diff --git a/apps/static/jbox/Skins2/jumpserver/jbox.css b/apps/static/jbox/Skins2/jumpserver/jbox.css
new file mode 100644
index 000000000..81ba8cc10
--- /dev/null
+++ b/apps/static/jbox/Skins2/jumpserver/jbox.css
@@ -0,0 +1,41 @@
+@charset "utf-8";
+
+*:focus {outline: none;}
+/* fade */
+.jbox-fade{background-color:#000000;}
+/* drag */
+.jbox-drag{border:1px dashed #0097d4;}
+/* jbox */
+div.jbox {padding:0px;border:none;font-size:12px;}
+/* border */
+div.jbox .jbox-border{background: none repeat scroll 0 0 #000000;filter:alpha(opacity=20);-moz-opacity:0.2;opacity:0.2;}
+/* container */
+div.jbox .jbox-container{background-color:#ffffff;border:1px solid #999999;}
+/* title-panel */
+div.jbox .jbox-title-panel{background: #2f4050;background: -webkit-gradient(linear, left top, left bottom, from(#2f4050), to(#2f4050));background: -moz-linear-gradient(top, #2f4050, #2f4050);filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#2f4050', endColorstr='#2f4050');border-bottom:1px solid #999999;}
+div.jbox .jbox-title{font-weight:bold;color:#ffffff;}
+div.jbox .jbox-title-icon{background:url(images/jbox-title-icon.gif) no-repeat scroll 3px 5px transparent;}
+div.jbox .jbox-close,div.jbox .jbox-close-hover{background:url(images/jbox-close1.gif) no-repeat scroll 0px 0px transparent;}
+div.jbox .jbox-close-hover{background-position:-16px 0;}
+/* content */
+div.jbox .jbox-content{min-height:24px;line-height:18px;color:#444444;}
+div.jbox .jbox-content-loading{background-color:#E6E6E6;}
+div.jbox .jbox-content-loading-image{background:url(images/jbox-content-loading.gif) no-repeat bottom center;}
+/* button-panel */
+div.jbox .jbox-button-panel{border-top:1px solid #CCCCCC;background-color: #EEEEEE;}
+div.jbox .jbox-bottom-text{text-indent:10px;color:#444444;}
+div.jbox .jbox-button{background: #0097d4;background: -webkit-gradient(linear, left top, left bottom, from(#2f4050), to(#2f4050));background: -moz-linear-gradient(top, #2f4050, #2f4050);filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#2f4050', endColorstr='#2f4050');border:#004b6a 1px solid;color:#fff;border-radius:3px 3px 3px 3px;margin:1px 7px 0px 0px;height:22px;cursor:default;}
+div.jbox .jbox-button-hover{background: #0097d4;background: -webkit-gradient(linear, left top, left bottom, from(#0097d4), to(#005b7f));background: -moz-linear-gradient(top, #0097d4, #005b7f);filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0097d4', endColorstr='#005b7f');}
+div.jbox .jbox-button-active{background: -webkit-gradient(linear, left top, left bottom, from(#005b7f), to(#0097d4));background: -moz-linear-gradient(top, #005b7f, #0097d4);filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#005b7f', endColorstr='#0097d4');}
+div.jbox-warning .jbox .jbox-button-panel{background-color: #FFFFFF;}
+/* tip-color */
+div.jbox .jbox-tip-color{background: #0097d4;background: -webkit-gradient(linear, left top, left bottom, from(#0097d4), to(#005b7f));background: -moz-linear-gradient(top, #0097d4, #005b7f);filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0097d4', endColorstr='#005b7f');border-color:#004b6a;border-radius:3px 3px 3px 3px;color:#fff;}
+/* icons */
+div.jbox span.jbox-icon{background:url(images/jbox-icons.png) no-repeat scroll 0 0 transparent;_background:url(images/jbox-icons-ie6.gif) no-repeat scroll 0 0 transparent;}
+div.jbox span.jbox-icon-info {background-position:0 0;}
+div.jbox span.jbox-icon-question {background-position:-36px 0;}
+div.jbox span.jbox-icon-success {background-position:-72px 0;}
+div.jbox span.jbox-icon-warning {background-position:-108px 0;}
+div.jbox span.jbox-icon-error {background-position:-144px 0;}
+div.jbox span.jbox-icon-none {display: none; overflow:hidden;}
+div.jbox span.jbox-icon-loading {background:url(images/jbox-loading1.gif) no-repeat scroll 0 0 transparent;}
\ No newline at end of file
diff --git a/apps/static/jbox/i18n/jquery.jBox-zh-CN.js b/apps/static/jbox/i18n/jquery.jBox-zh-CN.js
new file mode 100644
index 000000000..7783f954a
--- /dev/null
+++ b/apps/static/jbox/i18n/jquery.jBox-zh-CN.js
@@ -0,0 +1,77 @@
+
+/* jBox 全局设置 */
+var jBoxConfig = {};
+
+jBoxConfig.defaults = {
+ id: null, /* 在页面中的唯一id,如果为null则自动生成随机id,一个id只会显示一个jBox */
+ top: '15%', /* 窗口离顶部的距离,可以是百分比或像素(如 '100px') */
+ border: 5, /* 窗口的外边框像素大小,必须是0以上的整数 */
+ opacity: 0.1, /* 窗口隔离层的透明度,如果设置为0,则不显示隔离层 */
+ timeout: 0, /* 窗口显示多少毫秒后自动关闭,如果设置为0,则不自动关闭 */
+ showType: 'fade', /* 窗口显示的类型,可选值有:show、fade、slide */
+ showSpeed: 'fast', /* 窗口显示的速度,可选值有:'slow'、'fast'、表示毫秒的整数 */
+ showIcon: true, /* 是否显示窗口标题的图标,true显示,false不显示,或自定义的CSS样式类名(以为图标为背景) */
+ showClose: true, /* 是否显示窗口右上角的关闭按钮 */
+ draggable: true, /* 是否可以拖动窗口 */
+ dragLimit: true, /* 在可以拖动窗口的情况下,是否限制在可视范围 */
+ dragClone: false, /* 在可以拖动窗口的情况下,鼠标按下时窗口是否克隆窗口 */
+ persistent: true, /* 在显示隔离层的情况下,点击隔离层时,是否坚持窗口不关闭 */
+ showScrolling: true, /* 是否显示浏览的滚动条 */
+ ajaxData: {}, /* 在窗口内容使用get:或post:前缀标识的情况下,ajax post的数据,例如:{ id: 1 } 或 "id=1" */
+ iframeScrolling: 'auto', /* 在窗口内容使用iframe:前缀标识的情况下,iframe的scrolling属性值,可选值有:'auto'、'yes'、'no' */
+
+ title: 'jBox', /* 窗口的标题 */
+ width: 350, /* 窗口的宽度,值为'auto'或表示像素的整数 */
+ height: 'auto', /* 窗口的高度,值为'auto'或表示像素的整数 */
+ bottomText: '', /* 窗口的按钮左边的内容,当没有按钮时此设置无效 */
+ buttons: { '确定': 'ok' }, /* 窗口的按钮 */
+ buttonsFocus: 0, /* 表示第几个按钮为默认按钮,索引从0开始 */
+ loaded: function (h) { }, /* 窗口加载完成后执行的函数,需要注意的是,如果是ajax或iframe也是要等加载完http请求才算窗口加载完成,参数h表示窗口内容的jQuery对象 */
+ submit: function (v, h, f) { return true; }, /* 点击窗口按钮后的回调函数,返回true时表示关闭窗口,参数有三个,v表示所点的按钮的返回值,h表示窗口内容的jQuery对象,f表示窗口内容里的form表单键值 */
+ closed: function () { } /* 窗口关闭后执行的函数 */
+};
+
+jBoxConfig.stateDefaults = {
+ content: '', /* 状态的内容,不支持前缀标识 */
+ buttons: { '确定': 'ok' }, /* 状态的按钮 */
+ buttonsFocus: 0, /* 表示第几个按钮为默认按钮,索引从0开始 */
+ submit: function (v, h, f) { return true; } /* 点击状态按钮后的回调函数,返回true时表示关闭窗口,参数有三个,v表示所点的按钮的返回值,h表示窗口内容的jQuery对象,f表示窗口内容里的form表单键值 */
+};
+
+jBoxConfig.tipDefaults = {
+ content: '', /* 提示的内容,不支持前缀标识 */
+ icon: 'info', /* 提示的图标,可选值有'info'、'success'、'warning'、'error'、'loading',默认值为'info',当为'loading'时,timeout值会被设置为0,表示不会自动关闭。 */
+ top: '40%', /* 提示离顶部的距离,可以是百分比或像素(如 '100px') */
+ width: 'auto', /* 提示的高度,值为'auto'或表示像素的整数 */
+ height: 'auto', /* 提示的高度,值为'auto'或表示像素的整数 */
+ opacity: 0, /* 窗口隔离层的透明度,如果设置为0,则不显示隔离层 */
+ timeout: 3000, /* 提示显示多少毫秒后自动关闭,必须是大于0的整数 */
+ closed: function () { } /* 提示关闭后执行的函数 */
+};
+
+jBoxConfig.messagerDefaults = {
+ content: '', /* 信息的内容,不支持前缀标识 */
+ title: 'jBox', /* 信息的标题 */
+ icon: 'none', /* 信息图标,值为'none'时为不显示图标,可选值有'none'、'info'、'question'、'success'、'warning'、'error' */
+ width: 350, /* 信息的高度,值为'auto'或表示像素的整数 */
+ height: 'auto', /* 信息的高度,值为'auto'或表示像素的整数 */
+ timeout: 3000, /* 信息显示多少毫秒后自动关闭,如果设置为0,则不自动关闭 */
+ showType: 'slide', /* 信息显示的类型,可选值有:show、fade、slide */
+ showSpeed: 600, /* 信息显示的速度,可选值有:'slow'、'fast'、表示毫秒的整数 */
+ border: 0, /* 信息的外边框像素大小,必须是0以上的整数 */
+ buttons: {}, /* 信息的按钮 */
+ buttonsFocus: 0, /* 表示第几个按钮为默认按钮,索引从0开始 */
+ loaded: function (h) { }, /* 窗口加载完成后执行的函数,参数h表示窗口内容的jQuery对象 */
+ submit: function (v, h, f) { return true; }, /* 点击信息按钮后的回调函数,返回true时表示关闭窗口,参数有三个,v表示所点的按钮的返回值,h表示窗口内容的jQuery对象,f表示窗口内容里的form表单键值 */
+ closed: function () { } /* 信息关闭后执行的函数 */
+};
+
+jBoxConfig.languageDefaults = {
+ close: '关闭', /* 窗口右上角关闭按钮提示 */
+ ok: '确定', /* $.jBox.prompt() 系列方法的“确定”按钮文字 */
+ yes: '是', /* $.jBox.warning() 方法的“是”按钮文字 */
+ no: '否', /* $.jBox.warning() 方法的“否”按钮文字 */
+ cancel: '取消' /* $.jBox.confirm() 和 $.jBox.warning() 方法的“取消”按钮文字 */
+};
+
+$.jBox.setDefaults(jBoxConfig);
diff --git a/apps/static/jbox/jquery-migrate-1.1.1.min.js b/apps/static/jbox/jquery-migrate-1.1.1.min.js
new file mode 100644
index 000000000..7aa623713
--- /dev/null
+++ b/apps/static/jbox/jquery-migrate-1.1.1.min.js
@@ -0,0 +1,9 @@
+/*!
+ * jQuery Migrate - v1.1.1 - 2013-02-16
+ * https://github.com/jquery/jquery-migrate
+ * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors; Licensed MIT
+ */
+(function(s,p,i){var D={};s.migrateWarnings=[];if(!s.migrateMute&&p.console&&console.log){console.log("JQMIGRATE: Logging is active")}if(s.migrateTrace===i){s.migrateTrace=true}s.migrateReset=function(){D={};s.migrateWarnings.length=0};function h(G){if(!D[G]){D[G]=true;s.migrateWarnings.push(G);if(p.console&&console.warn&&!s.migrateMute){console.warn("JQMIGRATE: "+G);if(s.migrateTrace&&console.trace){console.trace()}}}}function a(I,K,H,J){if(Object.defineProperty){try{Object.defineProperty(I,K,{configurable:true,enumerable:true,get:function(){h(J);return H},set:function(L){h(J);H=L}});return}catch(G){}}s._definePropertyBroken=true;I[K]=H}if(document.compatMode==="BackCompat"){h("jQuery is not compatible with Quirks Mode")}var f=s("",{size:1}).attr("size")&&s.attrFn,x=s.attr,w=s.attrHooks.value&&s.attrHooks.value.get||function(){return null},j=s.attrHooks.value&&s.attrHooks.value.set||function(){return i},t=/^(?:input|button)$/i,y=/^[238]$/,B=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,k=/^(?:checked|selected)$/i;a(s,"attrFn",f||{},"jQuery.attrFn is deprecated");s.attr=function(K,I,L,J){var H=I.toLowerCase(),G=K&&K.nodeType;if(J){if(x.length<4){h("jQuery.fn.attr( props, pass ) is deprecated")}if(K&&!y.test(G)&&(f?I in f:s.isFunction(s.fn[I]))){return s(K)[I](L)}}if(I==="type"&&L!==i&&t.test(K.nodeName)&&K.parentNode){h("Can't change the 'type' of an input or button in IE 6/7/8")}if(!s.attrHooks[H]&&B.test(H)){s.attrHooks[H]={get:function(N,M){var P,O=s.prop(N,M);return O===true||typeof O!=="boolean"&&(P=N.getAttributeNode(M))&&P.nodeValue!==false?M.toLowerCase():i},set:function(N,P,M){var O;if(P===false){s.removeAttr(N,M)}else{O=s.propFix[M]||M;if(O in N){N[O]=true}N.setAttribute(M,M.toLowerCase())}return M}};if(k.test(H)){h("jQuery.fn.attr('"+H+"') may use property instead of attribute")
+}}return x.call(s,K,I,L)};s.attrHooks.value={get:function(H,G){var I=(H.nodeName||"").toLowerCase();if(I==="button"){return w.apply(this,arguments)}if(I!=="input"&&I!=="option"){h("jQuery.fn.attr('value') no longer gets properties")}return G in H?H.value:null},set:function(G,H){var I=(G.nodeName||"").toLowerCase();if(I==="button"){return j.apply(this,arguments)}if(I!=="input"&&I!=="option"){h("jQuery.fn.attr('value', val) no longer sets properties")}G.value=H}};var q,E,z=s.fn.init,A=s.parseJSON,v=/^(?:[^<]*(<[\w\W]+>)[^>]*|#([\w\-]*))$/;s.fn.init=function(G,J,I){var H;if(G&&typeof G==="string"&&!s.isPlainObject(J)&&(H=v.exec(G))&&H[1]){if(G.charAt(0)!=="<"){h("$(html) HTML strings must start with '<' character")}if(J&&J.context){J=J.context}if(s.parseHTML){return z.call(this,s.parseHTML(s.trim(G),J,true),J,I)}}return z.apply(this,arguments)};s.fn.init.prototype=s.fn;s.parseJSON=function(G){if(!G&&G!==null){h("jQuery.parseJSON requires a valid JSON string");return null}return A.apply(this,arguments)};s.uaMatch=function(H){H=H.toLowerCase();var G=/(chrome)[ \/]([\w.]+)/.exec(H)||/(webkit)[ \/]([\w.]+)/.exec(H)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(H)||/(msie) ([\w.]+)/.exec(H)||H.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(H)||[];return{browser:G[1]||"",version:G[2]||"0"}};if(!s.browser){q=s.uaMatch(navigator.userAgent);E={};if(q.browser){E[q.browser]=true;E.version=q.version}if(E.chrome){E.webkit=true}else{if(E.webkit){E.safari=true}}s.browser=E}a(s,"browser",s.browser,"jQuery.browser is deprecated");s.sub=function(){function G(J,K){return new G.fn.init(J,K)}s.extend(true,G,this);G.superclass=this;G.fn=G.prototype=this();G.fn.constructor=G;G.sub=this.sub;G.fn.init=function I(J,K){if(K&&K instanceof s&&!(K instanceof G)){K=G(K)}return s.fn.init.call(this,J,K,H)};G.fn.init.prototype=G.fn;var H=G(document);h("jQuery.sub() is deprecated");return G};s.ajaxSetup({converters:{"text json":s.parseJSON}});var n=s.fn.data;s.fn.data=function(I){var H,G,J=this[0];if(J&&I==="events"&&arguments.length===1){H=s.data(J,I);
+G=s._data(J,I);if((H===i||H===G)&&G!==i){h("Use of jQuery.fn.data('events') is deprecated");return G}}return n.apply(this,arguments)};var o=/\/(java|ecma)script/i,u=s.fn.andSelf||s.fn.addBack;s.fn.andSelf=function(){h("jQuery.fn.andSelf() replaced by jQuery.fn.addBack()");return u.apply(this,arguments)};if(!s.clean){s.clean=function(G,H,N,J){H=H||document;H=!H.nodeType&&H[0]||H;H=H.ownerDocument||H;h("jQuery.clean() is deprecated");var K,I,L,O,M=[];s.merge(M,s.buildFragment(G,H).childNodes);if(N){L=function(P){if(!P.type||o.test(P.type)){return J?J.push(P.parentNode?P.parentNode.removeChild(P):P):N.appendChild(P)}};for(K=0;(I=M[K])!=null;K++){if(!(s.nodeName(I,"script")&&L(I))){N.appendChild(I);if(typeof I.getElementsByTagName!=="undefined"){O=s.grep(s.merge([],I.getElementsByTagName("script")),L);M.splice.apply(M,[K+1,0].concat(O));K+=O.length}}}}return M}}var c=s.event.add,b=s.event.remove,g=s.event.trigger,r=s.fn.toggle,d=s.fn.live,m=s.fn.die,C="ajaxStart|ajaxStop|ajaxSend|ajaxComplete|ajaxError|ajaxSuccess",e=new RegExp("\\b(?:"+C+")\\b"),F=/(?:^|\s)hover(\.\S+|)\b/,l=function(G){if(typeof(G)!=="string"||s.event.special.hover){return G}if(F.test(G)){h("'hover' pseudo-event is deprecated, use 'mouseenter mouseleave'")}return G&&G.replace(F,"mouseenter$1 mouseleave$1")};if(s.event.props&&s.event.props[0]!=="attrChange"){s.event.props.unshift("attrChange","attrName","relatedNode","srcElement")}if(s.event.dispatch){a(s.event,"handle",s.event.dispatch,"jQuery.event.handle is undocumented and deprecated")}s.event.add=function(J,H,I,K,G){if(J!==document&&e.test(H)){h("AJAX events should be attached to document: "+H)}c.call(this,J,l(H||""),I,K,G)};s.event.remove=function(K,I,J,G,H){b.call(this,K,l(I)||"",J,G,H)};s.fn.error=function(){var G=Array.prototype.slice.call(arguments,0);h("jQuery.fn.error() is deprecated");G.splice(0,0,"error");if(arguments.length){return this.bind.apply(this,G)}this.triggerHandler.apply(this,G);return this};s.fn.toggle=function(K,I){if(!s.isFunction(K)||!s.isFunction(I)){return r.apply(this,arguments)
+}h("jQuery.fn.toggle(handler, handler...) is deprecated");var H=arguments,G=K.guid||s.guid++,J=0,L=function(M){var N=(s._data(this,"lastToggle"+K.guid)||0)%J;s._data(this,"lastToggle"+K.guid,N+1);M.preventDefault();return H[N].apply(this,arguments)||false};L.guid=G;while(J35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1;};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p;}('(8(a){a.7=8(b,c){c=a.1n({},a.7.17,c);c.1M=c.1V>9;c.1p=c.1p||1q;c.1A=c.1A||1q;5(b==1y){b=\'\'};5(c.W<9){c.W=9};5(c.1t==1y){c.1t=\'51\'+2U.52(2U.3i()*4Z)};6 d=(a.1U.2e&&3u(a.1U.3a)<3r);6 e=a(\'#\'+c.1t);5(e.1I>9){c.1k=a.7.17.1k++;e.16({1k:c.1k});e.10(\'#4\').16({1k:c.1k+1h});1j e};6 f={2g:\'\',1x:\'\',1e:\'\',2j:b.50==53};5(!f.2j){b=b+\'\';6 N=b.56();5(N.1X(\'1t:\')==9)f.1x=\'4t\';1b 5(N.1X(\'4C:\')==9)f.1x=\'35\';1b 5(N.1X(\'57:\')==9)f.1x=\'30\';1b 5(N.1X(\'1F:\')==9)f.1x=\'2w\';1b 5(N.1X(\'1e:\')==9)f.1x=\'3h\';1b{b=\'1e:\'+b;f.1x=\'3h\'};b=b.54(b.1X(":")+1h,b.1I)};5(!c.1p&&!c.1A&&!c.4s){a(a.1U.2e?\'1e\':\'1z\').3c(\'11\',\'2a:2l;1f-27:55;\')};6 g=!c.1p&&!(c.1o==1y);6 h=f.1x==\'35\'||f.1x==\'30\'||f.1x==\'2w\';6 i=1L c.14==\'36\'?(c.14-4Y)+\'19\':"4R%";6 j=[];j.X(\'\');5(c.1M){5((d&&a(\'1F\').1I>9)||a(\'4S, 4P\').1I>9){j.X(\'<1F 1t="4-24" 1a="4-24" 3y="3M:3X" 11="1D:2R;1s:1B;z-3t:-1;">1F>\')}1b{5(d){a(\'3Z\').16(\'3L\',\'2l\')};j.X(\'\')}};j.X(\'\');5(c.1Y){j.X(\'\')};j.X(\'\');j.X(\'\');j.X(\'\');j.X(\'<4p W="0" 4X="0" 4U="0" 11="1E:1c;1f:1c;W:1d;">\');5(c.W>9){j.X(\'<2n>\');j.X(\'<1u 1a="4-W" 11="1E:1c;1f:1c;W:1d;W-3d:\'+c.W+\'19 0 0 0;14:\'+c.W+\'19;Y:\'+c.W+\'19;">1u>\');j.X(\'<1u 1a="4-W" 11="1E:1c;1f:1c;W:1d;Y:\'+c.W+\'19;2a: 2l;">1u>\');j.X(\'<1u 1a="4-W" 11="1E:1c;1f:1c;W:1d;W-3d:0 \'+c.W+\'19 0 0;14:\'+c.W+\'19;Y:\'+c.W+\'19;">1u>\');j.X(\'2n>\')};j.X(\'<2n>\');j.X(\'<1u 1a="4-W" 11="1E:1c;1f:1c;W:1d;">1u>\');j.X(\'<1u 4V="18" 11="1E:1c;1f:1c;W:1d;">\');j.X(\'\');j.X(\'\');5(g){j.X(\'\');j.X(\'\'+(c.1o==\'\'?\'&5p;\':c.1o)+\'\');j.X(\'\')};j.X(\'\');j.X(\'\');j.X(\'1u>\');j.X(\'<1u 1a="4-W" 11="1E:1c;1f:1c;W:1d;">1u>\');j.X(\'2n>\');5(c.W>9){j.X(\'<2n>\');j.X(\'<1u 1a="4-W" 11="1E:1c;1f:1c;W:1d;W-3d:0 0 0 \'+c.W+\'19; 14:\'+c.W+\'19; Y:\'+c.W+\'19;">1u>\');j.X(\'<1u 1a="4-W" 11="1E:1c;1f:1c;W:1d;Y:\'+c.W+\'19;2a: 2l;">1u>\');j.X(\'<1u 1a="4-W" 11="1E:1c;1f:1c;W:1d;W-3d:0 0 \'+c.W+\'19 0; 14:\'+c.W+\'19; Y:\'+c.W+\'19;">1u>\');j.X(\'2n>\')};j.X(\'4p>\');j.X(\'\');j.X(\'\');6 k=\'<1F 2h="4-1F" 1t="4-1F" 14="2v%" Y="2v%" 5i="0" 5b="0" 5c="0" 59="\'+c.4r+\'">1F>\';6 l=a(2f);6 m=a(1H.1z);6 n=a(j.2m(\'\')).5a(m);6 o=n.2r(\'#4\');6 p=n.2r(\'#4-24\');6 q=n.2r(\'#4-3m\');5(!f.2j){3H(f.1x){1R"4t":f.1e=a(\'#\'+b).1e();1K;1R"35":1R"30":f.1e=\'\';f.2g=b;1K;1R"3h":f.1e=b;1K;1R"2w":f.1e=k;5(b.1X(\'#\')==-1h){f.2g=b+(b.1X(\'?\')==-1h?\'?39\':\'&39\')+2U.3i()}1b{6 N=b.5d(\'#\');f.2g=N[9]+(N[9].1X(\'?\')==-1h?\'?39\':\'&39\')+2U.3i()+\'#\'+N[1h]};1K};b={5g:{13:f.1e,1C:c.1C,2o:c.2o,1W:c.1W}}};6 r=[];6 s=o.10(\'.4-2W-1o\').3N(1i);6 t=o.10(\'.4-2W-1l\').3N(1i);6 u=a.1U.2e?\'3j-Y:3V;1f:1c 3O 1c 3O;\':\'1f:1c 2N 1c 2N;\';a.2C(b,8(N,O){5(f.2j){O=a.1n({},a.7.2O,O)};b[N]=O;5(O.1C==1y){O.1C={}};6 P=1q;a.2C(O.1C,8(T,U){P=1i});6 Q=\'1m\';5(1L c.Y==\'36\'){Q=c.Y;5(g){Q=Q-s};5(P){Q=Q-t};Q=(Q-1h)+\'19\'};6 R=\'\';6 S=\'2s\';5(!f.2j&&h){6 T=c.Y;5(1L c.Y==\'36\'){5(g){T=T-s};5(P){T=T-t};S=((T/2X)*1N)+\'19\';T=(T-1h)+\'19\'};R=[\'\',\'\',\'\'].2m(\'\')};r.X(\'\');r.X(\'\'+R+\'\'+O.13+\'\');r.X(\'\');5(!c.1p){r.X(\'<26 1a="4-29-1T" 11="3W:1g;1D:2R;3j-Y:2s;">26>\')};a.2C(O.1C,8(T,U){r.X(\'<1l 1a="4-1l" 31="\'+U+\'" 11="\'+u+\'">\'+T+\'1l>\')});r.X(\'\')});o.10(\'#4-2T\').1e(r.2m(\'\')).2r(\'.4-1G:3k\').16(\'1D\',\'2R\');5(h){6 N=o.10(\'#4-13\').16({1s:(d)?"1B":"32",1g:-4H})};a.2C(b,8(N,O){6 P=o.10(\'#4-1G-\'+N);P.2r(\'.4-1l-23\').2r(\'1l\').2c(8(){6 Q=P.10(\'#4-13\');6 R=O.1C[a(21).1T()];6 S={};a.2C(o.10(\'#4-2T :4h\').4M(),8(U,V){5(S[V.2h]===1y){S[V.2h]=V.31}1b 5(1L S[V.2h]==4L){S[V.2h].X(V.31)}1b{S[V.2h]=[S[V.2h],V.31]}});6 T=O.1W(R,Q,S);5(T===1y||T){I()}}).1P(\'2t\',8(){a(21).2x(\'4-1l-3x\')}).1P(\'4A\',8(){a(21).2I(\'4-1l-3x\')}).1P(\'4G\',8(){a(21).2x(\'4-1l-2E\')}).1P(\'4O\',8(){a(21).2I(\'4-1l-3x\').2I(\'4-1l-2E\')});P.10(\'.4-1l-23 1l:2V(\'+O.2o+\')\').2x(\'4-1l-1O\')});6 v=8(){n.16({18:l.3e()});5(c.1A){o.16({1s:(d)?"1B":"32",27:1h,29:1h})}};6 w=8(){6 N=l.14();1j 1H.1z.3I1h){4I(O);n.2I(\'4-25\')}},4N)}1b{I()}};6 z=8(N){5(c.1p||c.1A){1j 1q};6 O=(2f.4f)?4f.4g:N.4g;5(O==4F){I()};5(O==5Z){6 P=a(\':4h:5Y:2p\',n);6 Q=!N.4e&&N.1r==P[P.1I-1h];6 R=N.4e&&N.1r==P[9];5(Q||R){38(8(){5(!P)1j;6 S=P[R===1i?P.1I-1h:9];5(S)S.1O()},2G);1j 1q}}};6 A=8(){5(c.1M){p.16({1s:"1B",Y:c.1p?x():l.Y(),14:d?l.14():"2v%",18:9,1g:9,27:9,29:9})}};6 B=8(){5(c.1A){o.16({1s:(d)?"1B":"32",27:1h,29:1h})}1b{q.16({18:c.18});o.16({1s:"1B",18:q.3f().18+(c.1p?l.3e():9),1g:((l.14()-o.3S())/1N)})};5((c.1M&&!c.1p)||(!c.1M&&!c.1p&&!c.1A)){n.16({1s:(d)?"1B":"32",Y:c.1M?l.Y():9,14:"2v%",18:(d)?l.3e():9,1g:9,27:9,29:9})};A()};6 C=8(){c.1k=a.7.17.1k++;n.16({1k:c.1k});o.16({1k:c.1k+1h})};6 D=8(){c.1k=a.7.17.1k++;n.16({1k:c.1k});o.16({1D:"1d",1k:c.1k+1h});5(c.1M){p.16({1D:"1d",1k:c.1k,1V:c.1V})}};6 E=8(N){6 O=N.1w;O.1r.10(\'1F\').2K();5(c.22){O.1r.2u().16({1g:O.1r.16(\'1g\'),18:O.1r.16(\'18\'),61:-1N,60:-1N,14:O.1r.14()+1N,Y:O.1r.Y()+1N}).1Z()};1j 1q};6 F=8(N){6 O=N.1w;6 P=O.49+N.4c-O.43;6 Q=O.4y+N.48-O.4a;5(c.4o){6 R=1h;6 S=1H.46.3C-N.1w.1r.Y()-1h;6 T=1h;6 U=1H.46.3I-N.1w.1r.14()-1h;5(QS)Q=S-(c.22?1N:9);5(PU)P=U-(c.22?1N:9)};5(c.22){O.1r.2u().16({1g:P,18:Q})}1b{O.1r.16({1g:P,18:Q})};1j 1q};6 G=8(N){a(1H).2i(\'.1Y\');5(c.22){6 O=N.1w.1r.2u().2K();N.1w.1r.16({1g:O.16(\'1g\'),18:O.16(\'18\')}).10(\'1F\').1Z()}1b{N.1w.1r.10(\'1F\').1Z()};1j 1q};6 H=8(N){6 O=N.1w.1r.1s();6 P={1r:N.1w.1r,43:N.4c,4a:N.48,49:O.1g,4y:O.18};a(1H).1P(\'2t.1Y\',P,E).1P(\'5V.1Y\',P,F).1P(\'4A.1Y\',P,G)};6 I=8(){5(!c.1p&&!c.1A){5(a(\'.4-1z\').1I==1h){a(a.1U.2e?\'1e\':\'1z\').5U(\'11\')};J()}1b{5(c.1p){6 1v=a(1H.1z).1w(\'1v\');5(1v&&1v.2F==1i){q.16(\'18\',1v.33.18);6 N=q.3f().18+l.3e();5(N==o.3f().18){J()}1b{o.10(\'#4-13\').1e(1v.33.13.5X(2X)).5W().16({1g:((l.14()-o.3S())/1N)}).41({18:N,1V:0.1},3J,J)}}1b{o.41({18:\'-=62\',1V:9},3J,J)}}1b{3H(c.2J){1R\'3D\':o.4b(c.20,J);1K;1R\'24\':o.3P(c.20,J);1K;1R\'1Z\':3R:o.2K(c.20,J);1K}}}};6 J=8(){l.2i(\'3U\',A);5(c.1Y&&!c.1p&&!c.1A){o.10(\'.4-1o-23\').2i(\'2t\',H)};5(f.1x!=\'2w\'){o.10(\'#4-1F\').3c({\'3y\':\'3M:3X\'})};o.1e(\'\').3F();5(d&&!c.1p){m.2i(\'3T\',v)};5(c.1M){p.3P(\'37\',8(){p.2i(\'2c\',y).2i(\'2t\',C).1e(\'\').3F()})};n.2i(\'3Y 3K\',z).1e(\'\').3F();5(d&&c.1M){a(\'3Z\').16(\'3L\',\'2p\')};5(1L c.2H==\'8\'){c.2H()}};6 K=8(){5(c.1Q>9){o.1w(\'3B\',2f.38(I,c.1Q));5(c.1A){o.2E(8(){2f.63(o.1w(\'3B\'))},8(){o.1w(\'3B\',2f.38(I,c.1Q))})}}};6 L=8(){5(1L c.2Y==\'8\'){c.2Y(o.10(\'.4-1G:2p\').10(\'.4-13\'))}};5(!f.2j){3H(f.1x){1R"35":1R"30":a.64({1x:f.1x,2g:f.2g,1w:c.3g==1y?{}:c.3g,5B:\'1e\',5A:1q,2y:8(N,O){o.10(\'#4-13\').16({1s:"3Q"}).1e(N).1Z().2u().2K();L()},2z:8(){o.10(\'#4-13-2B\').1e(\'5z 5C.\')}});1K;1R"2w":o.10(\'#4-1F\').3c({\'3y\':f.2g}).1P("5F",8(N){a(21).5E().16({1s:"3Q"}).1Z().2u().2K();o.10(\'#4-2T .4-1G:3k .4-1l-1O\').1O();L()});1K;3R:o.10(\'#4-13\').1Z();1K}};B();D();5(d&&!c.1p){l.3T(v)};5(c.1M){p.2c(y)};l.3U(A);n.1P(\'3Y 3K\',z);o.10(\'.4-1J\').2c(I);5(c.1M){p.4u(\'37\')};6 M=\'1Z\';5(c.2J==\'3D\'){M=\'44\'}1b 5(c.2J==\'24\'){M=\'4u\'};5(c.1A){o[M](c.20,K)}1b{6 1v=a(1H.1z).1w(\'1v\');5(1v&&1v.2F==1i){a(1H.1z).1w(\'1v\',{2F:1q,33:{}});o.16(\'1D\',\'\')}1b{5(!f.2j&&h){o[M](c.20)}1b{o[M](c.20,L);}}};5(!c.1p){o.10(\'.4-29-1T\').1e(c.4E)}1b{o.10(\'.4-4v,.4-13\').2x(\'4-1v-4x\')};5(f.1x!=\'2w\'){o.10(\'#4-2T .4-1G:3k .4-1l-1O\').1O()}1b{o.1O()};5(!c.1A){K()};n.1P(\'2t\',C);5(c.1Y&&!c.1p&&!c.1A){o.10(\'.4-1o-23\').1P(\'2t\',{1r:o},H).16(\'4w\',\'5D\')};1j n};a.7.3a=2.3;a.7.17={1t:3A,18:"15%",1k:5u,W:2X,1V:0.1,1Q:9,2J:\'24\',20:\'37\',2L:1i,34:1i,1Y:1i,4o:1i,22:1q,4q:1i,4s:1i,3g:{},4r:\'1m\',1o:\'7\',14:3p,Y:\'1m\',4E:\'\',1C:{\'3z\':\'2b\'},2o:9,2Y:8(b){},1W:8(b,c,d){1j 1i},2H:8(){}};a.7.2O={13:\'\',1C:{\'3z\':\'2b\'},2o:9,1W:8(b,c,d){1j 1i}};a.7.2Q={13:\'\',12:\'28\',18:\'40%\',14:\'1m\',Y:\'1m\',1V:9,1Q:4B,2H:8(){}};a.7.2A={13:\'\',1o:\'7\',12:\'1d\',14:3p,Y:\'1m\',1Q:4B,2J:\'3D\',20:5t,W:9,1C:{},2o:9,2Y:8(){},1W:8(b,c,d){1j 1i},2H:8(){}};a.7.1S={1J:\'5s\',2b:\'3z\',3n:\'5v\',3q:\'5y\',2S:\'5x\'};a.7.5w=8(b){a.7.17=a.1n({},a.7.17,b.17);a.7.2O=a.1n({},a.7.2O,b.2O);a.7.2Q=a.1n({},a.7.2Q,b.2Q);a.7.2A=a.1n({},a.7.2A,b.2A);a.7.1S=a.1n({},a.7.1S,b.1S)};a.7.2D=8(){1j a(\'.4-1z\').2V(a(\'.4-1z\').1I-1h)};a.7.5P=8(b){6 c=(1L b==\'3v\')?a(\'#\'+b):a.7.2D();1j c.10(\'#4-1F\').4C(9)};a.7.5O=8(){1j a.7.3b().10(\'.4-13\').1e()};a.7.5N=8(b){1j a.7.3b().10(\'.4-13\').1e(b)};a.7.3b=8(b){5(b==1y){1j a.7.2D().10(\'.4-1G:2p\')}1b{1j a.7.2D().10(\'#4-1G-\'+b)}};a.7.5Q=8(){1j a.7.3b().3c(\'1t\').5T(\'4-1G-\',\'\')};a.7.3w=8(b,c){6 d=a.7.2D();5(d!=1y&&d!=3A){6 e;b=b||1q;d.10(\'.4-1G\').4b(\'37\');5(1L b==\'3v\'){e=d.10(\'#4-1G-\'+b)}1b{e=b?d.10(\'.4-1G:2p\').2F():d.10(\'.4-1G:2p\').2u()};e.44(3p,8(){2f.38(8(){e.10(\'.4-1l-1O\').1O();5(c!=1y){e.10(\'.4-13\').1e(c)}},5S)})}};a.7.5R=8(b){a.7.3w(1i,b)};a.7.5I=8(b){a.7.3w(1q,b)};a.7.1J=8(b,c){b=b||1q;c=c||\'1z\';5(1L b==\'3v\'){a(\'#\'+b).10(\'.4-1J\').2c()}1b{6 d=a(\'.4-\'+c);5(b){5H(6 e=9,l=d.1I;e9){d.2V(d.1I-1h).10(\'.4-1J\').2c()}}}};a.7.5G=8(b,c,d,e,f){6 17={13:b,1o:c,14:d,Y:e};f=a.1n({},17,f);f=a.1n({},a.7.17,f);a.7(f.13,f)};a.7.2d=8(b,c,d,e){6 17={13:b,1o:c,12:d,1C:3s(\'({ "\'+a.7.1S.2b+\'": "2b" })\')};e=a.1n({},17,e);e=a.1n({},a.7.17,e);5(e.W<9){e.W=9};5(e.12!=\'28\'&&e.12!=\'25\'&&e.12!=\'2y\'&&e.12!=\'2z\'&&e.12!=\'3G\'){1f=\'\';e.12=\'1d\'};6 f=e.1o==1y?2G:4j;6 g=e.12==\'1d\'?\'Y:1m;\':\'2P-Y:2M;\'+((a.1U.2e&&3u(a.1U.3a)<3r)?\'Y:1m !4l;Y:2v%;4n:2M;\':\'Y:1m;\');6 h=[];h.X(\'1e:\');h.X(\'\');h.X(\'<26 1a="4-12 4-12-\'+e.12+\'" 11="1s:1B; 18:\'+(f+e.W)+\'19;1g:\'+(2G+e.W)+\'19; 14:2q; Y:2q;">26>\');h.X(e.13);h.X(\'\');e.13=h.2m(\'\');a.7(e.13,e)};a.7.5J=8(b,c,d){a.7.2d(b,c,\'1d\',d)};a.7.28=8(b,c,d){a.7.2d(b,c,\'28\',d)};a.7.2y=8(b,c,d){a.7.2d(b,c,\'2y\',d)};a.7.2z=8(b,c,d){a.7.2d(b,c,\'2z\',d)};a.7.5M=8(b,c,d,e){6 17={1C:3s(\'({ "\'+a.7.1S.2b+\'": "2b", "\'+a.7.1S.2S+\'": "2S" })\')};5(d!=1y&&1L d==\'8\'){17.1W=d}1b{17.1W=8(f,g,h){1j 1i}};e=a.1n({},17,e);a.7.2d(b,c,\'3G\',e)};a.7.25=8(b,c,d,e){6 17={1C:3s(\'({ "\'+a.7.1S.3n+\'": "3n", "\'+a.7.1S.3q+\'": "3q", "\'+a.7.1S.2S+\'": "2S" })\')};5(d!=1y&&1L d==\'8\'){17.1W=d}1b{17.1W=8(f,g,h){1j 1i}};e=a.1n({},17,e);a.7.2d(b,c,\'25\',e)};a.7.1v=8(b,c,d){6 17={13:b,12:c,1V:9,W:9,34:1q,1C:{},1p:1i};5(17.12==\'2B\'){17.1Q=9;17.1V=0.1};d=a.1n({},17,d);d=a.1n({},a.7.2Q,d);d=a.1n({},a.7.17,d);5(d.1Q<9){d.1Q=9};5(d.W<9){d.W=9};5(d.12!=\'28\'&&d.12!=\'25\'&&d.12!=\'2y\'&&d.12!=\'2z\'&&d.12!=\'2B\'){d.12=\'28\'};6 e=[];e.X(\'1e:\');e.X(\'\');e.X(\'<26 1a="4-12 4-12-\'+d.12+\'" 11="1s:1B;18:\'+(4d+d.W)+\'19;1g:\'+(4d+d.W)+\'19; 14:2q; Y:2q;">26>\');e.X(d.13);e.X(\'\');d.13=e.2m(\'\');5(a(\'.4-1v\').1I>9){a(1H.1z).1w(\'1v\',{2F:1i,33:d});a.7.4k()};5(d.3E!=1y){a(\'#\'+d.3E).1O();18.$(\'#\'+d.3E).1O()};a.7(d.13,d)};a.7.4k=8(){a.7.1J(1q,\'1v\')};a.7.3l=8(b,c,d,e){a.7.4i();6 17={13:b,1o:c,1Q:(d==1y?a.7.2A.1Q:d),1V:9,34:1i,1Y:1q,1A:1i};e=a.1n({},17,e);e=a.1n({},a.7.2A,e);6 f=a.1n({},a.7.17,{});f.1o=3A;e=a.1n({},f,e);5(e.W<9){e.W=9};5(e.12!=\'28\'&&e.12!=\'25\'&&e.12!=\'2y\'&&e.12!=\'2z\'&&e.12!=\'3G\'){1f=\'\';e.12=\'1d\'};6 g=e.1o==1y?2G:4j;6 h=e.12==\'1d\'?\'Y:1m;\':\'2P-Y:2M;\'+((a.1U.2e&&3u(a.1U.3a)<3r)?\'Y:1m !4l;Y:2v%;4n:2M;\':\'Y:1m;\');6 i=[];i.X(\'1e:\');i.X(\'\');i.X(\'<26 1a="4-12 4-12-\'+e.12+\'" 11="1s:1B; 18:\'+(g+e.W)+\'19;1g:\'+(2G+e.W)+\'19; 14:2q; Y:2q;">26>\');i.X(e.13);i.X(\'\');e.13=i.2m(\'\');a.7(e.13,e)};a.7.4i=8(){a.7.1J(1q,\'3l\')};2f.7=a.7})(5K);',62,377,'||||jbox|if|var|jBox|function|0x0|||||||||||||||||||||||||||||||||||||||||||||||||border|push|height|div|find|style|icon|content|width||css|defaults|top|px|class|else|0px|none|html|padding|left|0x1|true|return|zIndex|button|auto|extend|title|isTip|false|target|position|id|td|tip|data|type|undefined|body|isMessager|absolute|buttons|display|margin|iframe|state|document|length|close|break|typeof|showFade|0x2|focus|bind|timeout|case|languageDefaults|text|browser|opacity|submit|indexOf|draggable|show|showSpeed|this|dragClone|panel|fade|warning|span|right|info|bottom|overflow|ok|click|prompt|msie|window|url|name|unbind|isObject|align|hidden|join|tr|buttonsFocus|visible|32px|children|25px|mousedown|prev|100|IFRAME|addClass|success|error|messagerDefaults|loading|each|getBox|hover|next|0xa|closed|removeClass|showType|hide|showIcon|30px|10px|stateDefaults|min|tipDefaults|block|cancel|states|Math|eq|help|0x5|loaded|5px|POST|value|fixed|options|showClose|GET|number|fast|setTimeout|___t|version|getState|attr|radius|scrollTop|offset|ajaxData|HTML|random|line|first|messager|temp|yes|50px|0x15e|no|0x7|eval|index|parseInt|string|goToState|active|src|确定|null|autoClosing|clientHeight|slide|focusId|remove|question|switch|clientWidth|0x1f4|keypress|visibility|about|outerHeight|6px|fadeOut|static|default|outerWidth|scroll|resize|19px|float|blank|keydown|select||animate|center|startX|slideDown|1984|documentElement|drag|pageY|startLeft|startY|slideUp|pageX|0x4|shiftKey|event|keyCode|input|closeMessager|0x23|closeTip|important|0x28|_height|dragLimit|table|persistent|iframeScrolling|showScrolling|ID|fadeIn|container|cursor|color|startTop|15px|mouseup|0xbb8|get|0x6|bottomText|0x1b|mouseover|0x2710|clearInterval|toggleClass|setInterval|Array|serializeArray|0x64|mouseout|applet|background|90|object|ff3300|cellspacing|valign|fdisplay|cellpadding|0x32|0xf4240|constructor|jBox_|floor|Object|substring|17px|toLowerCase|post|onmouseover|scrolling|appendTo|marginwidth|frameborder|split|image|220px|state0|70px|marginheight|0x19|0x18|onmouseout|pointer|0x12|all|nbsp|ellipsis|word|关闭|0x258|0x7c0|是|setDefaults|取消|否|Loading|cache|dataType|Error|move|parent|load|open|for|prevState|alert|jQuery|18px|confirm|setContent|getContent|getIframe|getStateName|nextState|0x14|replace|removeAttr|mousemove|end|substr|enabled|0x9|marginTop|marginLeft|200|clearTimeout|ajax'.split('|'),0,{}));
\ No newline at end of file
diff --git a/apps/static/js/jumpserver.js b/apps/static/js/jumpserver.js
index 5b7452b6b..20e62736f 100644
--- a/apps/static/js/jumpserver.js
+++ b/apps/static/js/jumpserver.js
@@ -4,10 +4,10 @@
var checked=false;
function check_all(form) {
var checkboxes = document.getElementById(form);
- if (checked == false) {
- checked = true
+ if (checked === false) {
+ checked = true;
} else {
- checked = false
+ checked = false;
}
for (var i = 0; i < checkboxes.elements.length; i++) {
if (checkboxes.elements[i].type == "checkbox") {
@@ -51,13 +51,13 @@ function GetRowData(row){
//此函数用于在多选提交时至少要选择一行
function GetTableDataBox() {
var tabProduct = document.getElementById("editable");
- var tableData = new Array();
- var returnData = new Array();
+ var tableData = [];
+ var returnData = [];
var checkboxes = document.getElementById("contents_form");
- var id_list = new Array();
+ var id_list = [];
len = checkboxes.elements.length;
for (var i=0; i < len; i++) {
- if (checkboxes.elements[i].type == "checkbox" && checkboxes.elements[i].checked == true && checkboxes.elements[i].value != "checkall") {
+ if (checkboxes.elements[i].type == "checkbox" && checkboxes.elements[i].checked === true && checkboxes.elements[i].value != "checkall") {
id_list.push(i);
}
}
@@ -67,7 +67,7 @@ function GetTableDataBox() {
tableData.push(GetRowData(tabProduct.rows[id_list[i]]));
}
- if (id_list.length == 0){
+ if (id_list.length === 0){
alert('请至少选择一行!');
}
returnData.push(tableData);
@@ -77,7 +77,7 @@ function GetTableDataBox() {
function move(from, to, from_o, to_o) {
$("#" + from + " option").each(function () {
- if ($(this).prop("selected") == true) {
+ if ($(this).prop("selected") === true) {
$("#" + to).append(this);
if( typeof from_o !== 'undefined'){
$("#"+to_o).append($("#"+from_o +" option[value='"+this.value+"']"));
@@ -88,7 +88,7 @@ function move(from, to, from_o, to_o) {
function move_left(from, to, from_o, to_o) {
$("#" + from + " option").each(function () {
- if ($(this).prop("selected") == true) {
+ if ($(this).prop("selected") === true) {
$("#" + to).append(this);
if( typeof from_o !== 'undefined'){
$("#"+to_o).append($("#"+from_o +" option[value='"+this.value+"']"));
@@ -126,8 +126,8 @@ function move_left(from, to, from_o, to_o) {
function selectAll(){
// 选择该页面所有option
$('option').each(function(){
- $(this).attr('selected', true)
- })
+ $(this).attr('selected', true);
+ });
}
@@ -156,6 +156,8 @@ function getIDall() {
function APIUpdateAttr(props) {
// props = {url: .., body: , success: , error: , method: ,}
props = props || {};
+ success_message = props.success_message || 'Update Successfully!';
+ fail_message = props.fail_message || 'Error occurred while updating.';
$.ajax({
url: props.url,
type: props.method || "PATCH",
@@ -164,18 +166,18 @@ function APIUpdateAttr(props) {
dataType: props.data_type || "json",
}).done(function(data, textStatue, jqXHR) {
if (typeof props.success === 'function') {
- return props.success(data)
+ return props.success(data);
} else {
- toastr.success('Update Success!')
+ toastr.success(success_message);
}
}).fail(function(jqXHR, textStatue, errorThrown) {
if (typeof props.error === 'function') {
- return props.error(errorThrown)
+ return props.error(errorThrown);
} else {
- toastr.error('Error occurred while updating.')
+ toastr.error(fail_message);
}
- })
+ });
return true;
}
-var jumpserver = new Object();
+var jumpserver = {};
diff --git a/apps/static/js/plugins/sweetalert/sweetalert.min.js b/apps/static/js/plugins/sweetalert/sweetalert.min.js
new file mode 100644
index 000000000..3e4e7ff4c
--- /dev/null
+++ b/apps/static/js/plugins/sweetalert/sweetalert.min.js
@@ -0,0 +1 @@
+!function(e,t,n){"use strict";!function o(e,t,n){function a(s,l){if(!t[s]){if(!e[s]){var i="function"==typeof require&&require;if(!l&&i)return i(s,!0);if(r)return r(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=t[s]={exports:{}};e[s][0].call(c.exports,function(t){var n=e[s][1][t];return a(n?n:t)},c,c.exports,o,e,t,n)}return t[s].exports}for(var r="function"==typeof require&&require,s=0;s=0;)n=n.replace(" "+t+" "," ");e.className=n.replace(/^\s+|\s+$/g,"")}},i=function(e){var n=t.createElement("div");return n.appendChild(t.createTextNode(e)),n.innerHTML},u=function(e){e.style.opacity="",e.style.display="block"},c=function(e){if(e&&!e.length)return u(e);for(var t=0;t0?setTimeout(o,t):e.style.display="none"});o()},h=function(n){if("function"==typeof MouseEvent){var o=new MouseEvent("click",{view:e,bubbles:!1,cancelable:!0});n.dispatchEvent(o)}else if(t.createEvent){var a=t.createEvent("MouseEvents");a.initEvent("click",!1,!1),n.dispatchEvent(a)}else t.createEventObject?n.fireEvent("onclick"):"function"==typeof n.onclick&&n.onclick()},g=function(t){"function"==typeof t.stopPropagation?(t.stopPropagation(),t.preventDefault()):e.event&&e.event.hasOwnProperty("cancelBubble")&&(e.event.cancelBubble=!0)};a.hasClass=r,a.addClass=s,a.removeClass=l,a.escapeHtml=i,a._show=u,a.show=c,a._hide=d,a.hide=f,a.isDescendant=p,a.getTopMargin=m,a.fadeIn=v,a.fadeOut=y,a.fireClick=h,a.stopEventPropagation=g},{}],5:[function(t,o,a){Object.defineProperty(a,"__esModule",{value:!0});var r=t("./handle-dom"),s=t("./handle-swal-dom"),l=function(t,o,a){var l=t||e.event,i=l.keyCode||l.which,u=a.querySelector("button.confirm"),c=a.querySelector("button.cancel"),d=a.querySelectorAll("button[tabindex]");if(-1!==[9,13,32,27].indexOf(i)){for(var f=l.target||l.srcElement,p=-1,m=0;m"),i.innerHTML=e.html?e.text:s.escapeHtml(e.text||"").split("\n").join("
"),e.text&&s.show(i),e.customClass)s.addClass(t,e.customClass),t.setAttribute("data-custom-class",e.customClass);else{var d=t.getAttribute("data-custom-class");s.removeClass(t,d),t.setAttribute("data-custom-class","")}if(s.hide(t.querySelectorAll(".sa-icon")),e.type&&!a.isIE8()){var f=function(){for(var o=!1,a=0;ao;o++)n=parseInt(e.substr(2*o,2),16),n=Math.round(Math.min(Math.max(0,n+n*t),255)).toString(16),a+=("00"+n).substr(n.length);return a};o.extend=a,o.hexToRgb=r,o.isIE8=s,o.logStr=l,o.colorLuminance=i},{}]},{},[1]),"function"==typeof define&&define.amd?define(function(){return sweetAlert}):"undefined"!=typeof module&&module.exports&&(module.exports=sweetAlert)}(window,document);
\ No newline at end of file
diff --git a/apps/templates/_foot_js.html b/apps/templates/_foot_js.html
index 624d32a01..b9ca3b784 100644
--- a/apps/templates/_foot_js.html
+++ b/apps/templates/_foot_js.html
@@ -1,3 +1,4 @@
+{% load i18n %}
{% load static %}
@@ -52,5 +53,36 @@ $.ajaxSetup({
// textarea rows
$('textarea').attr('rows', 5)
+
+
+
+//Sweet Alert for Delete
+function obj_del(obj,name,url){
+ swal({
+ title: "{% trans 'Are you sure delete ??' %}",
+ //text: "You will not be able to recover this imaginary file!",
+ text: "【"+name+"】",
+ type: "warning",
+ showCancelButton: true,
+ cancelButtonText: "{% trans 'Cancel' %}",
+ confirmButtonColor: "#DD6B55",
+ confirmButtonText: "{% trans 'Yes, delete it!' %}",
+ closeOnConfirm: false
+ }, function () {
+ $.ajax({
+ type : "post",
+ url : url,
+ data : {
+ // idc_id : idc_id
+ },
+ success : function(data) {
+ swal("{% trans 'Deleted!' %}", "【"+name+"】"+"{% trans 'has been deleted.' %}", "success");
+ $(obj).parent().parent().remove();
+ },
+ dataType : "text"
+ });
+ });
+}
+
diff --git a/apps/templates/_head_css_js.html b/apps/templates/_head_css_js.html
index bc968ca90..53bfa683b 100644
--- a/apps/templates/_head_css_js.html
+++ b/apps/templates/_head_css_js.html
@@ -4,13 +4,25 @@
+
-
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/templates/_modal.html b/apps/templates/_modal.html
new file mode 100644
index 000000000..9d8b50c70
--- /dev/null
+++ b/apps/templates/_modal.html
@@ -0,0 +1,20 @@
+{% load i18n %}
+
+
+
+
+
+ {% block modal_body %}
+ {% endblock %}
+
+
+
+
+
diff --git a/apps/users/api.py b/apps/users/api.py
index ee7b5f233..bb995d0f8 100644
--- a/apps/users/api.py
+++ b/apps/users/api.py
@@ -6,6 +6,7 @@ import logging
from rest_framework import generics
from .serializers import UserSerializer, UserGroupSerializer, UserAttributeSerializer, UserGroupEditSerializer
+from .serializers import UserPKUpdateSerializer
from .models import User, UserGroup
@@ -49,3 +50,25 @@ class UserAttributeApi(generics.RetrieveUpdateDestroyAPIView):
class UserGroupEditApi(generics.RetrieveUpdateAPIView):
queryset = User.objects.all()
serializer_class = UserGroupEditSerializer
+
+
+class UserResetPasswordApi(generics.UpdateAPIView):
+ queryset = User.objects.all()
+ serializer_class = UserGroupEditSerializer
+
+ def perform_update(self, serializer):
+ # Note: we are not updating the user object here.
+ # We just do the reset-password staff.
+ user = self.get_object()
+ from .utils import send_reset_password_mail
+ send_reset_password_mail(user)
+
+
+class UserResetPKApi(generics.UpdateAPIView):
+ queryset = User.objects.all()
+ serializer_class = UserPKUpdateSerializer
+
+ def perform_update(self, serializer):
+ user = self.get_object()
+ user.private_key = serializer.validated_data['_private_key']
+ user.save()
diff --git a/apps/users/serializers.py b/apps/users/serializers.py
index 808bb7349..7e70049f8 100644
--- a/apps/users/serializers.py
+++ b/apps/users/serializers.py
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
#
+from django.utils.translation import ugettext_lazy as _
+
from rest_framework import serializers
from .models import User, UserGroup
@@ -38,3 +40,17 @@ class UserGroupEditSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['id', 'groups']
+
+
+class UserPKUpdateSerializer(serializers.ModelSerializer):
+
+ class Meta:
+ model = User
+ fields = ['id', '_private_key']
+
+ def validate__private_key(self, value):
+ from users.utils import validate_ssh_pk
+ checked, reason = validate_ssh_pk(value)
+ if not checked:
+ raise serializers.ValidationError(_('Not a valid ssh private key.'))
+ return value
diff --git a/apps/users/templates/users/_user_reset_pk_modal.html b/apps/users/templates/users/_user_reset_pk_modal.html
new file mode 100644
index 000000000..bd6b62715
--- /dev/null
+++ b/apps/users/templates/users/_user_reset_pk_modal.html
@@ -0,0 +1,8 @@
+{% extends '_modal.html' %}
+{% load i18n %}
+{% block modal_id %}user_reset_pk_modal{% endblock %}
+{% block modal_title%}{% trans 'Reset User SSH Private Key' %}{% endblock %}
+{% block modal_body %}
+
+{% endblock %}
+{% block modal_confirm_id %}btn_user_reset_pk{% endblock %}
diff --git a/apps/users/templates/users/user_detail.html b/apps/users/templates/users/user_detail.html
index a8500ac51..6073d5d13 100644
--- a/apps/users/templates/users/user_detail.html
+++ b/apps/users/templates/users/user_detail.html
@@ -6,7 +6,9 @@
{% block custom_head_css_js %}
+
+
{% endblock %}
{% block content %}
@@ -22,7 +24,7 @@
-
+
{{ user_object.name }}
@@ -104,14 +106,14 @@
- {% trans 'Quick update' %}
+ {% trans 'Quick modify' %}
- Active: |
-
+ | {% trans 'Active' %}: |
+
|
- 二次验证: |
-
+ | {% trans 'Enable OTP' %}: |
+
|
{% trans 'Reset ssh key' %}: |
-
-
+
+
|
@@ -187,7 +189,7 @@
{{ group.name }} |
-
+
|
{% endfor %}
@@ -201,12 +203,11 @@
-
-
+ {% include 'users/_user_reset_pk_modal.html' %}
{% endblock %}
{% block custom_foot_js %}
{% endblock %}
diff --git a/apps/users/templates/users/user_list.html b/apps/users/templates/users/user_list.html
index 74edf727c..d220a4a84 100644
--- a/apps/users/templates/users/user_list.html
+++ b/apps/users/templates/users/user_list.html
@@ -19,7 +19,7 @@
{% endblock %}
{% block table_body %}
- {% for user in user_list %}
+ {% for user in object_list %}
@@ -42,7 +42,8 @@
|
{% trans 'Update' %}
- {% trans 'Delete' %}
+
+ {% trans 'Delete' %}
|
{% endfor %}
diff --git a/apps/users/urls.py b/apps/users/urls.py
index 179827216..5a83c64b1 100644
--- a/apps/users/urls.py
+++ b/apps/users/urls.py
@@ -35,6 +35,8 @@ urlpatterns += [
api.UserDetailDeleteUpdateApi.as_view(), name='user-detail-api'),
url(r'^v1/users/(?P[0-9]+)/patch$',
api.UserAttributeApi.as_view(), name='user-patch-api'),
+ url(r'^v1/users/(?P\d+)/reset-password/$', api.UserResetPasswordApi.as_view(), name='user-reset-password-api'),
+ url(r'^v1/users/(?P\d+)/reset-pk/$', api.UserResetPKApi.as_view(), name='user-reset-pk-api'),
url(r'^v1/user-groups$', api.UserGroupListAddApi.as_view(), name='user-group-list-api'),
url(r'^v1/user-groups/(?P[0-9]+)$',
api.UserGroupDetailDeleteUpdateApi.as_view(), name='user-group-detail-api'),
diff --git a/apps/users/utils.py b/apps/users/utils.py
index 9e9a34321..13076a106 100644
--- a/apps/users/utils.py
+++ b/apps/users/utils.py
@@ -5,6 +5,7 @@ import logging
import os
import re
+from django.conf import settings
from django.contrib.auth.mixins import UserPassesTestMixin
from django.urls import reverse_lazy
from django.utils.translation import ugettext as _
@@ -121,6 +122,8 @@ def send_reset_password_mail(user):
'email': user.email,
'login_url': reverse('users:login', external=True),
}
+ if settings.DEBUG:
+ logger.debug(message)
send_mail_async.delay(subject, message, recipient_list, html_message=message)
diff --git a/apps/users/views.py b/apps/users/views.py
index a385b473c..18a9061c5 100644
--- a/apps/users/views.py
+++ b/apps/users/views.py
@@ -10,7 +10,7 @@ from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.messages.views import SuccessMessageMixin
from django.core.files.storage import default_storage
from django.db.models import Q
-from django.http import HttpResponseRedirect
+from django.http import HttpResponseRedirect,HttpResponse
from django.shortcuts import get_object_or_404, reverse, redirect
from django.utils.decorators import method_decorator
from django.utils.translation import ugettext as _
@@ -94,7 +94,6 @@ class UserListView(AdminUserRequiredMixin, ListView):
if keyword:
self.queryset = self.queryset.filter(Q(username__icontains=keyword) |
Q(name__icontains=keyword))
-
if sort:
self.queryset = self.queryset.order_by(sort)
return self.queryset
@@ -163,6 +162,19 @@ class UserDeleteView(AdminUserRequiredMixin, DeleteView):
success_url = reverse_lazy('users:user-list')
template_name = 'users/user_delete_confirm.html'
+ def delete(self, request, *args, **kwargs):
+ """
+ Calls the delete() method on the fetched object and then
+ redirects to the success URL.
+ """
+ self.object = self.get_object()
+ success_url = self.get_success_url()
+ if self.object.name == "admin" or self.object.id == request.session.get('_auth_user_id'):
+ pass
+ else:
+ self.object.delete()
+
+ return HttpResponseRedirect(success_url)
class UserDetailView(AdminUserRequiredMixin, DetailView):
model = User