diff --git a/.gitignore b/.gitignore
index 65d6949..289210e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
 .vagrant
 venv
+venv2
 .vscode
 .idea
 .DS_*
diff --git a/.travis.yml b/.travis.yml
index 747a498..e012921 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,8 +1,8 @@
 language: python
 python:
-  - "2.7"
+  - "3.6"
 env:
-  - DJANGO=1.11.26
+  - DJANGO=2.2.10
 install:
   - pip install -r dev/requirements.txt
 script:
diff --git a/Dockerfile b/Dockerfile
index 0c04c68..c3b122f 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -6,21 +6,21 @@ RUN echo 'APT::Get::Clean=always;' >> /etc/apt/apt.conf.d/99AutomaticClean
 RUN apt-get update -qqy
 RUN DEBIAN_FRONTEND=noninteractive apt-get -qyy install \
 	-o APT::Install-Suggests=false \
-	git python-virtualenv python-dev python-lxml libvirt-dev zlib1g-dev nginx libsasl2-modules
+	git python3-virtualenv python3-dev python3-lxml virtualenv libvirt-dev zlib1g-dev nginx libsasl2-modules
 
 ADD . /srv/webvirtcloud
 RUN chown -R www-data:www-data /srv/webvirtcloud
 
 # Setup webvirtcloud
 RUN cd /srv/webvirtcloud && \
-	virtualenv venv && \
+	virtualenv --python=python3 venv && \
 	. venv/bin/activate && \
-	pip install -U pip && \
-	pip install -r conf/requirements.txt && \
+	pip3 install -U pip && \
+	pip3 install -r conf/requirements.txt && \
 	chown -R www-data:www-data /srv/webvirtcloud
 
 RUN cd /srv/webvirtcloud && . venv/bin/activate && \
-	python manage.py migrate && \
+	python3 manage.py migrate && \
 	chown -R www-data:www-data /srv/webvirtcloud
 
 # Setup Nginx
diff --git a/README.md b/README.md
index 6d810b5..1b2fcb2 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
 ## WebVirtCloud
-
+###### Python3 & Django 2.11
 
 ## Features
 * QEMU/KVM Hypervisor Management
@@ -38,10 +38,10 @@ haystack = string.ascii_letters + string.digits + string.punctuation
 print(''.join([random.SystemRandom().choice(haystack) for _ in range(50)]))
 ```
 
-### Install WebVirtCloud panel (Ubuntu)
+### Install WebVirtCloud panel (Ubuntu 18.04+ LTS)
 
 ```bash
-sudo apt-get -y install git virtualenv python-virtualenv python-dev python-lxml libvirt-dev zlib1g-dev libxslt1-dev nginx supervisor libsasl2-modules gcc pkg-config python-guestfs
+sudo apt-get -y install git virtualenv python3-virtualenv python3-dev python3-lxml libvirt-dev zlib1g-dev libxslt1-dev nginx supervisor libsasl2-modules gcc pkg-config python3-guestfs
 git clone https://github.com/retspen/webvirtcloud
 cd webvirtcloud
 cp webvirtcloud/settings.py.template webvirtcloud/settings.py
@@ -52,7 +52,7 @@ cd ..
 sudo mv webvirtcloud /srv
 sudo chown -R www-data:www-data /srv/webvirtcloud
 cd /srv/webvirtcloud
-virtualenv venv
+virtualenv -p python3 venv
 source venv/bin/activate
 pip install -r conf/requirements.txt
 python manage.py migrate
@@ -76,11 +76,11 @@ Done!!
 
 Go to http://serverip and you should see the login screen.
 
-
-### Install WebVirtCloud panel (CentOS)
+### Install WebVirtCloud panel (CentOS8/OEL8)
 
 ```bash
-sudo yum -y install python-virtualenv python-devel libvirt-devel glibc gcc nginx supervisor python-lxml git python-libguestfs iproute-tc
+sudo yum -y install epel-release
+sudo yum -y install python3-virtualenv python3-devel libvirt-devel glibc gcc nginx supervisor python3-lxml git python3-libguestfs iproute-tc cyrus-sasl-md5 python3-libguestfs
 ```
 
 #### Creating directories and cloning repo
@@ -90,15 +90,17 @@ sudo mkdir /srv && cd /srv
 sudo git clone https://github.com/retspen/webvirtcloud && cd webvirtcloud
 cp webvirtcloud/settings.py.template webvirtcloud/settings.py
 # now put secret key to webvirtcloud/settings.py
+# create secret key manually or use that command
+sudo sed -r "s/SECRET_KEY = ''/SECRET_KEY = '"`python3 /srv/webvirtcloud/conf/runit/secret_generator.py`"'/" -i /srv/webvirtcloud/webvirtcloud/settings.py
 ```
 
 #### Start installation webvirtcloud
 ```
-sudo virtualenv venv
-sudo source venv/bin/activate
-sudo venv/bin/pip install -r conf/requirements.txt
-sudo cp conf/nginx/webvirtcloud.conf /etc/nginx/conf.d/
-sudo venv/bin/python manage.py migrate
+virtualenv-3 venv
+source venv/bin/activate
+pip3 install -r conf/requirements.txt
+cp conf/nginx/webvirtcloud.conf /etc/nginx/conf.d/
+python3 manage.py migrate
 ```
 
 #### Configure the supervisor for CentOS
@@ -115,7 +117,7 @@ autorestart=true
 redirect_stderr=true
 
 [program:novncd]
-command=/srv/webvirtcloud/venv/bin/python /srv/webvirtcloud/console/novncd
+command=/srv/webvirtcloud/venv/bin/python3 /srv/webvirtcloud/console/novncd
 directory=/srv/webvirtcloud
 user=nginx
 autostart=true
@@ -191,11 +193,20 @@ Change permission for selinux:
 
 ```bash
 sudo semanage fcontext -a -t httpd_sys_content_t "/srv/webvirtcloud(/.*)"
+sudo setsebool -P httpd_can_network_connect on -P
 ```
 
-Add required user to the kvm group:
+Add required user to the kvm group(if you not install with root):
 ```bash
-sudo usermod -G kvm -a webvirtmgr
+sudo usermod -G kvm -a <username>
+```
+
+Allow http ports on firewall:
+```bash
+sudo firewall-cmd --add-service=http
+sudo firewall-cmd --add-service=http --permanent
+sudo firewall-cmd --add-port=6080/tcp
+sudo firewall-cmd --add-port=6080/tcp --permanent
 ```
 
 Let's restart nginx and the supervisord services:
@@ -226,7 +237,7 @@ Done!!
 
 Go to http://serverip and you should see the login screen.
 
-### Alternative running novncd via runit
+### Alternative running novncd via runit(Debian)
 Alternative to running nonvcd via supervisor is runit.
 
 On Debian systems install runit and configure novncd service
@@ -272,11 +283,12 @@ datasource:
 
 ### How To Update
 ```bash
-cd <installation-directory>
-sudo source venv/bin/activate
+# Go to Installation Directory
+cd /srv/webvirtcloud
+source venv/bin/activate
 git pull
-pip install -U -r conf/requirements.txt 
-python manage.py migrate
+pip3 install -U -r conf/requirements.txt 
+python3 manage.py migrate
 sudo service supervisor restart
 ```
 ### Screenshots
diff --git a/Vagrantfile b/Vagrantfile
index 21819f3..d92377c 100644
--- a/Vagrantfile
+++ b/Vagrantfile
@@ -12,10 +12,10 @@ Vagrant.configure(2) do |config|
      sudo sed -i 's/auth_tcp = \"sasl\"/auth_tcp = \"none\"/g' /etc/libvirt/libvirtd.conf
      sudo service libvirt-bin restart
      sudo adduser vagrant libvirtd
-     sudo apt-get -y install python-virtualenv python-dev python-lxml libvirt-dev zlib1g-dev
-     virtualenv /vagrant/venv
+     sudo apt-get -y install python3-virtualenv virtualenv python3-pip python3-dev python3-lxml libvirt-dev zlib1g-dev python3-guestfs
+     virtualenv -p python3 /vagrant/venv
      source /vagrant/venv/bin/activate
-     pip install -r /vagrant/dev/requirements.txt
+     pip3 install -r /vagrant/dev/requirements.txt
     SHELL
   end
   # To start this machine run "vagrant up prod"
@@ -24,6 +24,7 @@ Vagrant.configure(2) do |config|
     prod.vm.box = "ubuntu/bionic64"
     prod.vm.hostname = "webvirtcloud"
     prod.vm.network "private_network", ip: "192.168.33.11"
+    prod.vm.network "forwarded_port", guest: 80, host: 8081
     #prod.vm.synced_folder ".", "/srv/webvirtcloud"
     prod.vm.provision "shell", inline: <<-SHELL
      sudo mkdir /srv/webvirtcloud
@@ -33,15 +34,15 @@ Vagrant.configure(2) do |config|
      sudo service libvirt-bin restart
      sudo adduser vagrant libvirtd
      sudo chown -R vagrant:vagrant /srv/webvirtcloud
-     sudo apt-get -y install python-virtualenv python-dev python-lxml python-pip libvirt-dev zlib1g-dev libxslt1-dev nginx supervisor libsasl2-modules gcc pkg-config python-guestfs
-     virtualenv /srv/webvirtcloud/venv
+     sudo apt-get -y install python3-virtualenv python3-dev python3-lxml python3-pip virtualenv libvirt-dev zlib1g-dev libxslt1-dev nginx supervisor libsasl2-modules gcc pkg-config python3-guestfs
+     virtualenv -p python3 /srv/webvirtcloud/venv
      source /srv/webvirtcloud/venv/bin/activate
-     pip install -r /srv/webvirtcloud/dev/requirements.txt
+     pip3 install -r /srv/webvirtcloud/requirements.txt
      sudo cp /srv/webvirtcloud/conf/supervisor/webvirtcloud.conf /etc/supervisor/conf.d
      sudo cp /srv/webvirtcloud/conf/nginx/webvirtcloud.conf /etc/nginx/conf.d
      sudo cp /srv/webvirtcloud/webvirtcloud/settings.py.template /srv/webvirtcloud/webvirtcloud/settings.py
-     sudo sed "s/SECRET_KEY = ''/SECRET_KEY = '"`python /srv/webvirtcloud/conf/runit/secret_generator.py`"'/" -i /srv/webvirtcloud/webvirtcloud/settings.py
-     python /srv/webvirtcloud/manage.py migrate
+     sudo sed "s/SECRET_KEY = ''/SECRET_KEY = '"`python3 /srv/webvirtcloud/conf/runit/secret_generator.py`"'/" -i /srv/webvirtcloud/webvirtcloud/settings.py
+     python3 /srv/webvirtcloud/manage.py migrate
      sudo rm /etc/nginx/sites-enabled/default
      sudo chown -R www-data:www-data /srv/webvirtcloud
      sudo service nginx restart
diff --git a/accounts/forms.py b/accounts/forms.py
index 4127ac4..db53ed5 100644
--- a/accounts/forms.py
+++ b/accounts/forms.py
@@ -9,7 +9,8 @@ class UserAddForm(forms.Form):
     name = forms.CharField(label="Name",
                            error_messages={'required': _('No User name has been entered')},
                            max_length=20)
-    password = forms.CharField(required=not settings.ALLOW_EMPTY_PASSWORD, error_messages={'required': _('No password has been entered')},)
+    password = forms.CharField(required=not settings.ALLOW_EMPTY_PASSWORD,
+                               error_messages={'required': _('No password has been entered')},)
 
     def clean_name(self):
         name = self.cleaned_data['name']
diff --git a/accounts/migrations/0001_initial.py b/accounts/migrations/0001_initial.py
index 3989532..1990eeb 100644
--- a/accounts/migrations/0001_initial.py
+++ b/accounts/migrations/0001_initial.py
@@ -1,29 +1,51 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
+# Generated by Django 2.2.10 on 2020-01-28 07:01
 
-from django.db import models, migrations
 from django.conf import settings
+import django.core.validators
+from django.db import migrations, models
+import django.db.models.deletion
 
 
 class Migration(migrations.Migration):
 
+    initial = True
+
     dependencies = [
-        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
         ('instances', '0001_initial'),
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
     ]
 
     operations = [
+        migrations.CreateModel(
+            name='UserSSHKey',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('keyname', models.CharField(max_length=25)),
+                ('keypublic', models.CharField(max_length=500)),
+                ('user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL)),
+            ],
+        ),
         migrations.CreateModel(
             name='UserInstance',
             fields=[
-                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                 ('is_change', models.BooleanField(default=False)),
                 ('is_delete', models.BooleanField(default=False)),
-                ('instance', models.ForeignKey(to='instances.Instance')),
-                ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
+                ('is_vnc', models.BooleanField(default=False)),
+                ('instance', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='instances.Instance')),
+                ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
+            ],
+        ),
+        migrations.CreateModel(
+            name='UserAttributes',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('can_clone_instances', models.BooleanField(default=True)),
+                ('max_instances', models.IntegerField(default=1, help_text='-1 for unlimited. Any integer value', validators=[django.core.validators.MinValueValidator(-1)])),
+                ('max_cpus', models.IntegerField(default=1, help_text='-1 for unlimited. Any integer value', validators=[django.core.validators.MinValueValidator(-1)])),
+                ('max_memory', models.IntegerField(default=2048, help_text='-1 for unlimited. Any integer value', validators=[django.core.validators.MinValueValidator(-1)])),
+                ('max_disk_size', models.IntegerField(default=20, help_text='-1 for unlimited. Any integer value', validators=[django.core.validators.MinValueValidator(-1)])),
+                ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
             ],
-            options={
-            },
-            bases=(models.Model,),
         ),
     ]
diff --git a/accounts/migrations/0002_auto_20150325_0846.py b/accounts/migrations/0002_auto_20150325_0846.py
deleted file mode 100644
index 8780f97..0000000
--- a/accounts/migrations/0002_auto_20150325_0846.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import migrations
-
-
-def add_useradmin(apps, schema_editor):
-    from django.utils import timezone
-    from django.contrib.auth.models import User
-
-    User.objects.create_superuser('admin', None, 'admin',
-                                  last_login=timezone.now()
-                                  )
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('accounts', '0001_initial'),
-    ]
-
-    operations = [
-        migrations.RunPython(add_useradmin),
-    ]
diff --git a/accounts/migrations/0003_usersshkey.py b/accounts/migrations/0003_usersshkey.py
deleted file mode 100644
index b00bc62..0000000
--- a/accounts/migrations/0003_usersshkey.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import models, migrations
-from django.conf import settings
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
-        ('accounts', '0002_auto_20150325_0846'),
-    ]
-
-    operations = [
-        migrations.CreateModel(
-            name='UserSSHKey',
-            fields=[
-                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
-                ('keyname', models.CharField(max_length=25)),
-                ('keypublic', models.CharField(max_length=500)),
-                ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
-            ],
-        ),
-    ]
diff --git a/accounts/migrations/0004_userattributes.py b/accounts/migrations/0004_userattributes.py
deleted file mode 100644
index fb32539..0000000
--- a/accounts/migrations/0004_userattributes.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import models, migrations
-from django.conf import settings
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
-        ('accounts', '0003_usersshkey'),
-    ]
-
-    operations = [
-        migrations.CreateModel(
-            name='UserAttributes',
-            fields=[
-                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
-                ('max_instances', models.IntegerField(default=0)),
-                ('max_cpus', models.IntegerField(default=0)),
-                ('max_memory', models.IntegerField(default=0)),
-                ('user', models.OneToOneField(to=settings.AUTH_USER_MODEL)),
-            ],
-        ),
-    ]
diff --git a/accounts/migrations/0004_userinstance_is_vnc.py b/accounts/migrations/0004_userinstance_is_vnc.py
deleted file mode 100644
index 9c1c9b8..0000000
--- a/accounts/migrations/0004_userinstance_is_vnc.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('accounts', '0003_usersshkey'),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name='userinstance',
-            name='is_vnc',
-            field=models.BooleanField(default=False),
-        ),
-    ]
diff --git a/accounts/migrations/0005_userattributes_can_clone_instances.py b/accounts/migrations/0005_userattributes_can_clone_instances.py
deleted file mode 100644
index 4539657..0000000
--- a/accounts/migrations/0005_userattributes_can_clone_instances.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import models, migrations
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('accounts', '0004_userattributes'),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name='userattributes',
-            name='can_clone_instances',
-            field=models.BooleanField(default=False),
-        ),
-    ]
diff --git a/accounts/migrations/0006_userattributes_max_disk_size.py b/accounts/migrations/0006_userattributes_max_disk_size.py
deleted file mode 100644
index 3d21f5f..0000000
--- a/accounts/migrations/0006_userattributes_max_disk_size.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import models, migrations
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('accounts', '0005_userattributes_can_clone_instances'),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name='userattributes',
-            name='max_disk_size',
-            field=models.IntegerField(default=0),
-        ),
-    ]
diff --git a/accounts/migrations/0007_auto_20160426_0635.py b/accounts/migrations/0007_auto_20160426_0635.py
deleted file mode 100644
index 2f92aba..0000000
--- a/accounts/migrations/0007_auto_20160426_0635.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('accounts', '0006_userattributes_max_disk_size'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='userattributes',
-            name='max_cpus',
-            field=models.IntegerField(default=1),
-        ),
-        migrations.AlterField(
-            model_name='userattributes',
-            name='max_disk_size',
-            field=models.IntegerField(default=20),
-        ),
-        migrations.AlterField(
-            model_name='userattributes',
-            name='max_instances',
-            field=models.IntegerField(default=1),
-        ),
-        migrations.AlterField(
-            model_name='userattributes',
-            name='max_memory',
-            field=models.IntegerField(default=2048),
-        ),
-    ]
diff --git a/accounts/migrations/0008_merge.py b/accounts/migrations/0008_merge.py
deleted file mode 100644
index 8edf672..0000000
--- a/accounts/migrations/0008_merge.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('accounts', '0004_userinstance_is_vnc'),
-        ('accounts', '0007_auto_20160426_0635'),
-    ]
-
-    operations = [
-    ]
diff --git a/accounts/migrations/0009_auto_20171026_0805.py b/accounts/migrations/0009_auto_20171026_0805.py
deleted file mode 100644
index 7d035c7..0000000
--- a/accounts/migrations/0009_auto_20171026_0805.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('accounts', '0008_merge'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='userattributes',
-            name='can_clone_instances',
-            field=models.BooleanField(default=True),
-        ),
-    ]
diff --git a/accounts/migrations/0010_auto_20180625_1236.py b/accounts/migrations/0010_auto_20180625_1236.py
deleted file mode 100644
index 23e1548..0000000
--- a/accounts/migrations/0010_auto_20180625_1236.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.13 on 2018-06-25 12:36
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('accounts', '0009_auto_20171026_0805'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='userattributes',
-            name='max_cpus',
-            field=models.IntegerField(default=1, help_text=b'-1 for unlimited. Any integer value'),
-        ),
-        migrations.AlterField(
-            model_name='userattributes',
-            name='max_disk_size',
-            field=models.IntegerField(default=20, help_text=b'-1 for unlimited. Any integer value'),
-        ),
-        migrations.AlterField(
-            model_name='userattributes',
-            name='max_instances',
-            field=models.IntegerField(default=1, help_text=b'-1 for unlimited. Any integer value'),
-        ),
-        migrations.AlterField(
-            model_name='userattributes',
-            name='max_memory',
-            field=models.IntegerField(default=2048, help_text=b'-1 for unlimited. Any integer value'),
-        ),
-    ]
diff --git a/accounts/migrations/0011_auto_20180625_1313.py b/accounts/migrations/0011_auto_20180625_1313.py
deleted file mode 100644
index 1ee194b..0000000
--- a/accounts/migrations/0011_auto_20180625_1313.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.13 on 2018-06-25 13:13
-from __future__ import unicode_literals
-
-import django.core.validators
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('accounts', '0010_auto_20180625_1236'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='userattributes',
-            name='max_cpus',
-            field=models.IntegerField(default=1, help_text=b'-1 for unlimited. Any integer value', validators=[django.core.validators.MinValueValidator(-1)]),
-        ),
-        migrations.AlterField(
-            model_name='userattributes',
-            name='max_disk_size',
-            field=models.IntegerField(default=20, help_text=b'-1 for unlimited. Any integer value', validators=[django.core.validators.MinValueValidator(-1)]),
-        ),
-        migrations.AlterField(
-            model_name='userattributes',
-            name='max_instances',
-            field=models.IntegerField(default=1, help_text=b'-1 for unlimited. Any integer value', validators=[django.core.validators.MinValueValidator(-1)]),
-        ),
-        migrations.AlterField(
-            model_name='userattributes',
-            name='max_memory',
-            field=models.IntegerField(default=2048, help_text=b'-1 for unlimited. Any integer value', validators=[django.core.validators.MinValueValidator(-1)]),
-        ),
-    ]
diff --git a/accounts/migrations/0012_auto_20180625_1331.py b/accounts/migrations/0012_auto_20180625_1331.py
deleted file mode 100644
index 827599e..0000000
--- a/accounts/migrations/0012_auto_20180625_1331.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.13 on 2018-06-25 13:31
-from __future__ import unicode_literals
-
-import django.core.validators
-from django.db import migrations, models
-import re
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('accounts', '0011_auto_20180625_1313'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='userattributes',
-            name='max_cpus',
-            field=models.IntegerField(default=1, help_text=b'-1 for unlimited. Any integer value', validators=[django.core.validators.RegexValidator(re.compile('^-?\\d+\\Z'), code='invalid', message='Enter a valid integer.')]),
-        ),
-        migrations.AlterField(
-            model_name='userattributes',
-            name='max_disk_size',
-            field=models.IntegerField(default=20, help_text=b'-1 for unlimited. Any integer value', validators=[django.core.validators.RegexValidator(re.compile('^-?\\d+\\Z'), code='invalid', message='Enter a valid integer.')]),
-        ),
-        migrations.AlterField(
-            model_name='userattributes',
-            name='max_instances',
-            field=models.IntegerField(default=1, help_text=b'-1 for unlimited. Any integer value', validators=[django.core.validators.RegexValidator(re.compile('^-?\\d+\\Z'), code='invalid', message='Enter a valid integer.')]),
-        ),
-        migrations.AlterField(
-            model_name='userattributes',
-            name='max_memory',
-            field=models.IntegerField(default=2048, help_text=b'-1 for unlimited. Any integer value', validators=[django.core.validators.RegexValidator(re.compile('^-?\\d+\\Z'), code='invalid', message='Enter a valid integer.')]),
-        ),
-    ]
diff --git a/accounts/migrations/0013_auto_20180625_1358.py b/accounts/migrations/0013_auto_20180625_1358.py
deleted file mode 100644
index 1fdec50..0000000
--- a/accounts/migrations/0013_auto_20180625_1358.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.13 on 2018-06-25 13:58
-from __future__ import unicode_literals
-
-import django.core.validators
-from django.db import migrations, models
-import re
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('accounts', '0012_auto_20180625_1331'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='userattributes',
-            name='max_cpus',
-            field=models.IntegerField(default=1, help_text=b'-1 for unlimited. Any integer value', validators=[django.core.validators.RegexValidator(re.compile('^-?\\d+\\Z'), code='invalid', message='Enter a valid integer.'), django.core.validators.MinValueValidator(-1)]),
-        ),
-        migrations.AlterField(
-            model_name='userattributes',
-            name='max_disk_size',
-            field=models.IntegerField(default=20, help_text=b'-1 for unlimited. Any integer value', validators=[django.core.validators.RegexValidator(re.compile('^-?\\d+\\Z'), code='invalid', message='Enter a valid integer.'), django.core.validators.MinValueValidator(-1)]),
-        ),
-        migrations.AlterField(
-            model_name='userattributes',
-            name='max_instances',
-            field=models.IntegerField(default=1, help_text=b'-1 for unlimited. Any integer value', validators=[django.core.validators.RegexValidator(re.compile('^-?\\d+\\Z'), code='invalid', message='Enter a valid integer.'), django.core.validators.MinValueValidator(-1)]),
-        ),
-        migrations.AlterField(
-            model_name='userattributes',
-            name='max_memory',
-            field=models.IntegerField(default=2048, help_text=b'-1 for unlimited. Any integer value', validators=[django.core.validators.RegexValidator(re.compile('^-?\\d+\\Z'), code='invalid', message='Enter a valid integer.'), django.core.validators.MinValueValidator(-1)]),
-        ),
-    ]
diff --git a/accounts/migrations/0014_auto_20180808_1436.py b/accounts/migrations/0014_auto_20180808_1436.py
deleted file mode 100644
index a4f3c78..0000000
--- a/accounts/migrations/0014_auto_20180808_1436.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.13 on 2018-08-08 11:36
-from __future__ import unicode_literals
-
-import django.core.validators
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('accounts', '0013_auto_20180625_1358'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='userattributes',
-            name='max_cpus',
-            field=models.IntegerField(default=1, help_text=b'-1 for unlimited. Any integer value', validators=[django.core.validators.MinValueValidator(-1)]),
-        ),
-        migrations.AlterField(
-            model_name='userattributes',
-            name='max_disk_size',
-            field=models.IntegerField(default=20, help_text=b'-1 for unlimited. Any integer value', validators=[django.core.validators.MinValueValidator(-1)]),
-        ),
-        migrations.AlterField(
-            model_name='userattributes',
-            name='max_instances',
-            field=models.IntegerField(default=1, help_text=b'-1 for unlimited. Any integer value', validators=[django.core.validators.MinValueValidator(-1)]),
-        ),
-        migrations.AlterField(
-            model_name='userattributes',
-            name='max_memory',
-            field=models.IntegerField(default=2048, help_text=b'-1 for unlimited. Any integer value', validators=[django.core.validators.MinValueValidator(-1)]),
-        ),
-    ]
diff --git a/accounts/migrations/0015_auto_20180808_1449.py b/accounts/migrations/0015_auto_20180808_1449.py
deleted file mode 100644
index d94905a..0000000
--- a/accounts/migrations/0015_auto_20180808_1449.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.13 on 2018-08-08 11:49
-from __future__ import unicode_literals
-
-from django.conf import settings
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('accounts', '0014_auto_20180808_1436'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='usersshkey',
-            name='user',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL),
-        ),
-    ]
diff --git a/accounts/models.py b/accounts/models.py
index 42c8051..77cf81a 100644
--- a/accounts/models.py
+++ b/accounts/models.py
@@ -1,36 +1,39 @@
-from django.db import models
+from django.db.models import Model, BooleanField, IntegerField, CharField
+from django.db.models import ForeignKey, OneToOneField
+from django.db.models import CASCADE, DO_NOTHING
 from django.contrib.auth.models import User
 from django.conf import settings
 from instances.models import Instance
 from django.core.validators import MinValueValidator
 
 
-class UserInstance(models.Model):
-    user = models.ForeignKey(User, on_delete=models.CASCADE)
-    instance = models.ForeignKey(Instance, on_delete=models.CASCADE)
-    is_change = models.BooleanField(default=False)
-    is_delete = models.BooleanField(default=False)
-    is_vnc = models.BooleanField(default=False)
+class UserInstance(Model):
+    user = ForeignKey(User, on_delete=CASCADE)
+    instance = ForeignKey(Instance, on_delete=CASCADE)
+    is_change = BooleanField(default=False)
+    is_delete = BooleanField(default=False)
+    is_vnc = BooleanField(default=False)
 
     def __unicode__(self):
         return self.instance.name
 
 
-class UserSSHKey(models.Model):
-    user = models.ForeignKey(User, on_delete=models.DO_NOTHING)
-    keyname = models.CharField(max_length=25)
-    keypublic = models.CharField(max_length=500)
+class UserSSHKey(Model):
+    user = ForeignKey(User, on_delete=DO_NOTHING)
+    keyname = CharField(max_length=25)
+    keypublic = CharField(max_length=500)
 
     def __unicode__(self):
         return self.keyname
 
-class UserAttributes(models.Model):
-    user = models.OneToOneField(User, on_delete=models.CASCADE)
-    can_clone_instances = models.BooleanField(default=True)
-    max_instances = models.IntegerField(default=1, help_text="-1 for unlimited. Any integer value", validators=[MinValueValidator(-1),])
-    max_cpus = models.IntegerField(default=1, help_text="-1 for unlimited. Any integer value", validators=[MinValueValidator(-1)])
-    max_memory = models.IntegerField(default=2048, help_text="-1 for unlimited. Any integer value", validators=[MinValueValidator(-1)])
-    max_disk_size = models.IntegerField(default=20, help_text="-1 for unlimited. Any integer value", validators=[MinValueValidator(-1)])
+
+class UserAttributes(Model):
+    user = OneToOneField(User, on_delete=CASCADE)
+    can_clone_instances = BooleanField(default=True)
+    max_instances = IntegerField(default=1, help_text="-1 for unlimited. Any integer value", validators=[MinValueValidator(-1), ])
+    max_cpus = IntegerField(default=1, help_text="-1 for unlimited. Any integer value", validators=[MinValueValidator(-1)])
+    max_memory = IntegerField(default=2048, help_text="-1 for unlimited. Any integer value", validators=[MinValueValidator(-1)])
+    max_disk_size = IntegerField(default=20, help_text="-1 for unlimited. Any integer value", validators=[MinValueValidator(-1)])
 
     @staticmethod
     def create_missing_userattributes(user):
diff --git a/accounts/templates/account.html b/accounts/templates/account.html
index 56f91b8..0f9bbb7 100644
--- a/accounts/templates/account.html
+++ b/accounts/templates/account.html
@@ -87,8 +87,8 @@
                                                             <div class="form-group">
                                                                 <label class="col-sm-4 control-label">{% trans "VNC" %}</label>
                                                                 <div class="col-sm-6">
-                                                                    <select type="text" class="form-control" name="inst_vnc">
-                                                                        <option value="">False</option>
+                                                                    <select class="form-control" name="inst_vnc">
+                                                                        <option value="">{% trans 'False' %}</option>
                                                                         <option value="1" {% if inst.is_vnc %}selected{% endif %}>True</option>
                                                                     </select>
                                                                 </div>
@@ -96,8 +96,8 @@
                                                             <div class="form-group">
                                                                 <label class="col-sm-4 control-label">{% trans "Resize" %}</label>
                                                                 <div class="col-sm-6">
-                                                                    <select type="text" class="form-control" name="inst_change">
-                                                                        <option value="">False</option>
+                                                                    <select class="form-control" name="inst_change">
+                                                                        <option value="">{% trans 'False' %}</option>
                                                                         <option value="1" {% if inst.is_change %}selected{% endif %}>True</option>
                                                                     </select>
                                                                 </div>
@@ -105,8 +105,8 @@
                                                             <div class="form-group">
                                                                 <label class="col-sm-4 control-label">{% trans "Delete" %}</label>
                                                                 <div class="col-sm-6">
-                                                                    <select type="text" class="form-control" name="inst_delete">
-                                                                        <option value="">False</option>
+                                                                    <select class="form-control" name="inst_delete">
+                                                                        <option value="">{% trans 'False' %}</option>
                                                                         <option value="1" {% if inst.is_delete %}selected{% endif %}>True</option>
                                                                     </select>
                                                                 </div>
@@ -124,7 +124,7 @@
                                     <td style="width:5px;">
                                         <form action="" method="post" role="form">{% csrf_token %}
                                             <input type="hidden" name="user_inst" value="{{ inst.id }}">
-                                            <button type="submit" class="btn btn-xs btn-default" name="delete" tittle="{% trans "Delete" %}" onclick="return confirm('{% trans "Are you sure?" %}')">
+                                            <button type="submit" class="btn btn-xs btn-default" name="delete" title="{% trans "Delete" %}" onclick="return confirm('{% trans "Are you sure?" %}')">
                                                 <span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
                                             </button>
                                         </form>
diff --git a/accounts/urls.py b/accounts/urls.py
index c0ea4f1..6b49b70 100644
--- a/accounts/urls.py
+++ b/accounts/urls.py
@@ -1,10 +1,10 @@
-from django.conf.urls import url
+from django.urls import path, re_path
 from django.contrib.auth import views as auth_views
 from . import views
 
 urlpatterns = [
-    url(r'^login/$', auth_views.LoginView.as_view(template_name='login.html'), name='login'),
-    url(r'^logout/$', auth_views.LogoutView.as_view(template_name='logout.html'), name='logout'),
-    url(r'^profile/$', views.profile, name='profile'), url(r'^$', views.accounts, name='accounts'),
-    url(r'^profile/(?P<user_id>[0-9]+)/$', views.account, name='account'),
+    path('login/', auth_views.LoginView.as_view(template_name='login.html'), name='login'),
+    path('logout/', auth_views.LogoutView.as_view(template_name='logout.html'), name='logout'),
+    path('profile/', views.profile, name='profile'), path('', views.accounts, name='accounts'),
+    re_path(r'^profile/(?P<user_id>[0-9]+)/$', views.account, name='account'),
 ]
diff --git a/computes/forms.py b/computes/forms.py
index 5389708..bbde4d4 100644
--- a/computes/forms.py
+++ b/computes/forms.py
@@ -151,10 +151,8 @@ class ComputeEditHostForm(forms.Form):
 
 
 class ComputeAddSocketForm(forms.Form):
-    name = forms.CharField(error_messages={'required': _('No hostname has been entered')},
-                           max_length=64)
-    details = forms.CharField(error_messages={'required': _('No details has been entred')},
-                           max_length=50)
+    name = forms.CharField(error_messages={'required': _('No hostname has been entered')}, max_length=64)
+    details = forms.CharField(error_messages={'required': _('No details has been entred')}, max_length=50)
 
     def clean_name(self):
         name = self.cleaned_data['name']
diff --git a/computes/migrations/0001_initial.py b/computes/migrations/0001_initial.py
index e8d6139..c8f9183 100644
--- a/computes/migrations/0001_initial.py
+++ b/computes/migrations/0001_initial.py
@@ -1,11 +1,12 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
+# Generated by Django 2.2.10 on 2020-01-28 07:01
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
+    initial = True
+
     dependencies = [
     ]
 
@@ -13,15 +14,13 @@ class Migration(migrations.Migration):
         migrations.CreateModel(
             name='Compute',
             fields=[
-                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
-                ('name', models.CharField(max_length=20)),
-                ('hostname', models.CharField(max_length=20)),
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('name', models.CharField(max_length=64)),
+                ('hostname', models.CharField(max_length=64)),
                 ('login', models.CharField(max_length=20)),
-                ('password', models.CharField(max_length=14, null=True, blank=True)),
+                ('password', models.CharField(blank=True, max_length=14, null=True)),
+                ('details', models.CharField(blank=True, max_length=64, null=True)),
                 ('type', models.IntegerField()),
             ],
-            options={
-            },
-            bases=(models.Model,),
         ),
     ]
diff --git a/computes/migrations/0002_compute_details.py b/computes/migrations/0002_compute_details.py
deleted file mode 100644
index 1e0fdf5..0000000
--- a/computes/migrations/0002_compute_details.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import models, migrations
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('computes', '0001_initial'),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name='Compute',
-            name='details',
-            field=models.CharField(max_length=50, null=True, blank=True),
-        ),
-    ]
diff --git a/computes/migrations/0003_auto_20200121_1523.py b/computes/migrations/0003_auto_20200121_1523.py
deleted file mode 100644
index 361cbc1..0000000
--- a/computes/migrations/0003_auto_20200121_1523.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.26 on 2020-01-21 12:23
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('computes', '0002_compute_details'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='compute',
-            name='details',
-            field=models.CharField(blank=True, max_length=64, null=True),
-        ),
-        migrations.AlterField(
-            model_name='compute',
-            name='hostname',
-            field=models.CharField(max_length=64),
-        ),
-        migrations.AlterField(
-            model_name='compute',
-            name='name',
-            field=models.CharField(max_length=64),
-        ),
-    ]
diff --git a/computes/models.py b/computes/models.py
index 1a83e59..db224a3 100644
--- a/computes/models.py
+++ b/computes/models.py
@@ -1,13 +1,13 @@
-from django.db import models
+from django.db.models import Model, CharField, IntegerField
 
 
-class Compute(models.Model):
-    name = models.CharField(max_length=64)
-    hostname = models.CharField(max_length=64)
-    login = models.CharField(max_length=20)
-    password = models.CharField(max_length=14, blank=True, null=True)
-    details = models.CharField(max_length=64, null=True, blank=True)
-    type = models.IntegerField()
+class Compute(Model):
+    name = CharField(max_length=64)
+    hostname = CharField(max_length=64)
+    login = CharField(max_length=20)
+    password = CharField(max_length=14, blank=True, null=True)
+    details = CharField(max_length=64, null=True, blank=True)
+    type = IntegerField()
 
     def __unicode__(self):
         return self.hostname
diff --git a/computes/urls.py b/computes/urls.py
index 350fc00..be5f09b 100644
--- a/computes/urls.py
+++ b/computes/urls.py
@@ -1,4 +1,4 @@
-from django.conf.urls import url
+from django.urls import path, re_path
 from storages.views import storages, storage, get_volumes
 from networks.views import networks, network
 from secrets.views import secrets
@@ -9,23 +9,24 @@ from instances.views import instances
 from nwfilters.views import nwfilter, nwfilters
 
 urlpatterns = [
-    url(r'^$', computes, name='computes'),
-    url(r'^(?P<compute_id>[0-9]+)/$', overview, name='overview'),
-    url(r'^(?P<compute_id>[0-9]+)/statistics$', compute_graph, name='compute_graph'),
-    url(r'^(?P<compute_id>[0-9]+)/instances/$', instances, name='instances'),
-    url(r'^(?P<compute_id>[0-9]+)/storages/$', storages, name='storages'),
-    url(r'^(?P<compute_id>[0-9]+)/storage/(?P<pool>[\w\-\.\/]+)/volumes$', get_volumes, name='volumes'),
-    url(r'^(?P<compute_id>[0-9]+)/storage/(?P<pool>[\w\-\.\/]+)/$', storage, name='storage'),
-    url(r'^(?P<compute_id>[0-9]+)/networks/$', networks, name='networks'),
-    url(r'^(?P<compute_id>[0-9]+)/network/(?P<pool>[\w\-\.]+)/$', network, name='network'),
-    url(r'^(?P<compute_id>[0-9]+)/interfaces/$', interfaces, name='interfaces'),
-    url(r'^(?P<compute_id>[0-9]+)/interface/(?P<iface>[\w\-\.\:]+)/$', interface, name='interface'),
-    url(r'^(?P<compute_id>[0-9]+)/nwfilters/$', nwfilters, name='nwfilters'),
-    url(r'^(?P<compute_id>[0-9]+)/nwfilter/(?P<nwfltr>[\w\-\.\:]+)/$', nwfilter, name='nwfilter'),
-    url(r'^(?P<compute_id>[0-9]+)/secrets/$', secrets, name='secrets'),
-    url(r'^(?P<compute_id>[0-9]+)/create/$', create_instance_select_type, name='create_instance_select_type'),
-    url(r'^(?P<compute_id>[0-9]+)/create/archs/(?P<arch>[\w\-\.\/]+)/machines/(?P<machine>[\w\-\.\/]+)$', create_instance, name='create_instance'),
-    url(r'^(?P<compute_id>[0-9]+)/archs/(?P<arch>[\w\-\.\/]+)/machines$', get_compute_machine_types, name='machines'),
-    url(r'^(?P<compute_id>[0-9]+)/archs/(?P<arch>[\w\-\.\/]+)/machines/(?P<machine>[\w\-\.\/]+)/disks/(?P<disk>[\w\-\.\/]+)/buses$', get_compute_disk_buses, name='buses'),
-    url(r'^(?P<compute_id>[0-9]+)/archs/(?P<arch>[\w\-\.\/]+)/machines/(?P<machine>[\w\-\.\/]+)/capabilities$', get_dom_capabilities, name='domcaps'),
+    path('', computes, name='computes'),
+    re_path(r'^(?P<compute_id>[0-9]+)/$', overview, name='overview'),
+    re_path(r'^(?P<compute_id>[0-9]+)/statistics$', compute_graph, name='compute_graph'),
+    re_path(r'^(?P<compute_id>[0-9]+)/instances/$', instances, name='instances'),
+    re_path(r'^(?P<compute_id>[0-9]+)/storages/$', storages, name='storages'),
+    re_path(r'^(?P<compute_id>[0-9]+)/storage/(?P<pool>[\w\-\.\/]+)/volumes$', get_volumes, name='volumes'),
+    re_path(r'^(?P<compute_id>[0-9]+)/storage/(?P<pool>[\w\-\.\/]+)/$', storage, name='storage'),
+    re_path(r'^(?P<compute_id>[0-9]+)/networks/$', networks, name='networks'),
+    re_path(r'^(?P<compute_id>[0-9]+)/network/(?P<pool>[\w\-\.]+)/$', network, name='network'),
+    re_path(r'^(?P<compute_id>[0-9]+)/interfaces/$', interfaces, name='interfaces'),
+    re_path(r'^(?P<compute_id>[0-9]+)/interface/(?P<iface>[\w\-\.\:]+)/$', interface, name='interface'),
+    re_path(r'^(?P<compute_id>[0-9]+)/nwfilters/$', nwfilters, name='nwfilters'),
+    re_path(r'^(?P<compute_id>[0-9]+)/nwfilter/(?P<nwfltr>[\w\-\.\:]+)/$', nwfilter, name='nwfilter'),
+    re_path(r'^(?P<compute_id>[0-9]+)/secrets/$', secrets, name='secrets'),
+    re_path(r'^(?P<compute_id>[0-9]+)/create/$', create_instance_select_type, name='create_instance_select_type'),
+    re_path(r'^(?P<compute_id>[0-9]+)/create/archs/(?P<arch>[\w\-\.\/]+)/machines/(?P<machine>[\w\-\.\/]+)$', create_instance, name='create_instance'),
+    re_path(r'^(?P<compute_id>[0-9]+)/archs/(?P<arch>[\w\-\.\/]+)/machines$', get_compute_machine_types, name='machines'),
+    re_path(r'^(?P<compute_id>[0-9]+)/archs/(?P<arch>[\w\-\.\/]+)/machines/(?P<machine>[\w\-\.\/]+)/disks/(?P<disk>[\w\-\.\/]+)/buses$', get_compute_disk_buses, name='buses'),
+    re_path(r'^(?P<compute_id>[0-9]+)/archs/(?P<arch>[\w\-\.\/]+)/machines/(?P<machine>[\w\-\.\/]+)/capabilities$', get_dom_capabilities, name='domcaps'),
 ]
+
diff --git a/conf/daemon/gstfsd b/conf/daemon/gstfsd
index 1851770..589cf8b 100644
--- a/conf/daemon/gstfsd
+++ b/conf/daemon/gstfsd
@@ -3,7 +3,7 @@
 # gstfsd - WebVirtCloud daemon for managing VM's filesystem
 #
 
-import SocketServer
+import socketserver
 import json
 import guestfs
 import re
@@ -13,11 +13,11 @@ PORT = 16510
 ADDRESS = "0.0.0.0"
 
 
-class MyTCPServer(SocketServer.ThreadingTCPServer):
+class MyTCPServer(socketserver.ThreadingTCPServer):
     allow_reuse_address = True
 
 
-class MyTCPServerHandler(SocketServer.BaseRequestHandler):
+class MyTCPServerHandler(socketserver.BaseRequestHandler):
     def handle(self):
         # recive data
         data = json.loads(self.request.recv(1024).strip())
@@ -42,9 +42,9 @@ class MyTCPServerHandler(SocketServer.BaseRequestHandler):
                         if data['action'] == 'publickey':
                             if not gfs.is_dir('/root/.ssh'):
                                 gfs.mkdir('/root/.ssh')
-                                gfs.chmod(0700, "/root/.ssh")
+                                gfs.chmod(700, "/root/.ssh")
                             gfs.write('/root/.ssh/authorized_keys', data['key'])
-                            gfs.chmod(0600, '/root/.ssh/authorized_keys')
+                            gfs.chmod(600, '/root/.ssh/authorized_keys')
                             self.request.sendall(json.dumps({'return': 'success'}))
                     gfs.umount(part)
                 except RuntimeError:
@@ -52,7 +52,7 @@ class MyTCPServerHandler(SocketServer.BaseRequestHandler):
             gfs.shutdown()
             gfs.close()
         except RuntimeError as err:
-            self.request.sendall(json.dumps({'return': 'error', 'message': err.message}))
+            self.request.sendall(json.dumps({'return': 'error', 'message': err}))
 
 
 server = MyTCPServer((ADDRESS, PORT), MyTCPServerHandler)
diff --git a/conf/requirements.txt b/conf/requirements.txt
index fc57c17..11adabb 100644
--- a/conf/requirements.txt
+++ b/conf/requirements.txt
@@ -1,7 +1,8 @@
-Django==1.11.26
+Django==2.2.10
 websockify==0.9.0
-gunicorn==19.9.0
-lxml==4.4.2
-libvirt-python==5.10.0
+gunicorn==20.0.4
+lxml==4.5.0
+libvirt-python==6.1.0
+six
 pytz
 rwlock
diff --git a/conf/runit/secret_generator.py b/conf/runit/secret_generator.py
index 830ba9d..2a5a8dc 100644
--- a/conf/runit/secret_generator.py
+++ b/conf/runit/secret_generator.py
@@ -1,4 +1,4 @@
 import random, string
 
 haystack = string.ascii_letters + string.digits + string.punctuation
-print(''.join([random.SystemRandom().choice(haystack.replace('/','').replace('\'', '').replace('\"','')) for _ in range(50)]))
\ No newline at end of file
+print(''.join([random.SystemRandom().choice(haystack.replace('/', '').replace('\'', '').replace('\"', '')) for _ in range(50)]))
diff --git a/conf/supervisor/gstfsd.conf b/conf/supervisor/gstfsd.conf
index 2834b30..094f41c 100644
--- a/conf/supervisor/gstfsd.conf
+++ b/conf/supervisor/gstfsd.conf
@@ -1,5 +1,5 @@
 [program:gstfsd]
-command=/usr/bin/python /usr/local/bin/gstfsd
+command=/srv/webvirtcloud/venv/bin/python3 /usr/local/bin/gstfsd
 directory=/usr/local/bin
 user=root
 autostart=true
diff --git a/conf/supervisor/webvirtcloud.conf b/conf/supervisor/webvirtcloud.conf
index 2994bc9..692fe8a 100644
--- a/conf/supervisor/webvirtcloud.conf
+++ b/conf/supervisor/webvirtcloud.conf
@@ -7,7 +7,7 @@ autorestart=true
 redirect_stderr=true
 
 [program:novncd]
-command=/srv/webvirtcloud/venv/bin/python /srv/webvirtcloud/console/novncd
+command=/srv/webvirtcloud/venv/bin/python3 /srv/webvirtcloud/console/novncd
 directory=/srv/webvirtcloud
 user=www-data
 autostart=true
diff --git a/console/novncd b/console/novncd
index 0f205a0..15ac905 100755
--- a/console/novncd
+++ b/console/novncd
@@ -7,7 +7,7 @@ import django
 
 DIR_PATH = os.path.dirname(os.path.abspath(__file__))
 ROOT_PATH = os.path.abspath(os.path.join(DIR_PATH, '..', ''))
-os.environ.setdefault("DJANGO_SETTINGS_MODULE", "webvirtcloud.settings")
+os.environ["DJANGO_SETTINGS_MODULE"] = "webvirtcloud.settings"
 CERT = DIR_PATH + '/cert.pem'
 
 if ROOT_PATH not in sys.path:
@@ -15,16 +15,16 @@ if ROOT_PATH not in sys.path:
 
 django.setup()
 
-# VENV_PATH = ROOT_PATH + '/venv/lib/python2.7/site-packages'
+# VENV_PATH = ROOT_PATH + '/venv/lib/python3.6/site-packages'
 # if VENV_PATH not in sys.path:
 #     sys.path.append(VENV_PATH)
 
 import re
-import Cookie
 import socket
+from six.moves import http_cookies as Cookie
 from webvirtcloud.settings import WS_PORT, WS_HOST, WS_CERT
 from vrtManager.connection import CONN_SSH, CONN_SOCKET
-from tunnel import Tunnel
+from console.tunnel import Tunnel
 from optparse import OptionParser
 
 parser = OptionParser()
@@ -127,12 +127,30 @@ def get_connection_infos(token):
 
 class CompatibilityMixIn(object):
     def _new_client(self, daemon, socket_factory):
-        cookie = Cookie.SimpleCookie()
-        cookie.load(self.headers.getheader('cookie'))
-        if 'token' not in cookie:
-            self.msg('No token cookie found !')
-            return False
-        token = cookie['token'].value
+        # NoVNC uses it's own convention that forward token
+        # from the request to a cookie header, we should check
+        # also for this behavior
+        hcookie = self.headers.get('cookie')
+        if hcookie:
+            cookie = Cookie.SimpleCookie()
+            for hcookie_part in hcookie.split(';'):
+                hcookie_part = hcookie_part.lstrip()
+                try:
+                    cookie.load(hcookie_part)
+                except Cookie.CookieError:
+                    # NOTE(stgleb): Do not print out cookie content
+                    # for security reasons.
+                    self.msg('Found malformed cookie')
+                else:
+                    if 'token' in cookie:
+                        token = cookie['token'].value
+
+        # cookie = Cookie.SimpleCookie()
+        # cookie.load(self.headers.getheader('cookie'))
+        # if 'token' not in cookie:
+        #     self.msg('No token cookie found !')
+        #     return False
+        # token = cookie['token'].value
 
         (connhost, connport, connuser, conntype, console_host, console_port,
          console_socket) = get_connection_infos(token)
diff --git a/console/templates/console-base.html b/console/templates/console-base.html
index e5c7ffe..5a79a01 100644
--- a/console/templates/console-base.html
+++ b/console/templates/console-base.html
@@ -35,7 +35,6 @@
             margin-left: auto;
             margin-right: auto;
             display: block;
-            margin: auto;
         }
        
         #status {
diff --git a/console/templates/console-spice-full.html b/console/templates/console-spice-full.html
index 08ef3ee..aac780d 100644
--- a/console/templates/console-spice-full.html
+++ b/console/templates/console-spice-full.html
@@ -25,65 +25,28 @@
 {% extends "console-base.html" %}
 {% load i18n %}
 {% load staticfiles %}
+
 {% block head %}
     <title>WebVirtCloud - Spice Client - Full</title>
-    <script src="{% static "js/spice-html5/spicearraybuffer.js" %}"></script>
-    <script src="{% static "js/spice-html5/enums.js" %}"></script>
-    <script src="{% static "js/spice-html5/atKeynames.js" %}"></script>
-    <script src="{% static "js/spice-html5/utils.js" %}"></script>
-    <script src="{% static "js/spice-html5/png.js" %}"></script>
-    <script src="{% static "js/spice-html5/lz.js" %}"></script>
-    <script src="{% static "js/spice-html5/quic.js" %}"></script>
-    <script src="{% static "js/spice-html5/bitmap.js" %}"></script>
-    <script src="{% static "js/spice-html5/spicedataview.js" %}"></script>
-    <script src="{% static "js/spice-html5/spicetype.js" %}"></script>
-    <script src="{% static "js/spice-html5/spicemsg.js" %}"></script>
-    <script src="{% static "js/spice-html5/wire.js" %}"></script>
-    <script src="{% static "js/spice-html5/spiceconn.js" %}"></script>
-    <script src="{% static "js/spice-html5/display.js" %}"></script>
-    <script src="{% static "js/spice-html5/port.js" %}"></script>
-    <script src="{% static "js/spice-html5/main.js" %}"></script>
-    <script src="{% static "js/spice-html5/inputs.js" %}"></script>
-    <script src="{% static "js/spice-html5/webm.js" %}"></script>
-    <script src="{% static "js/spice-html5/playback.js" %}"></script>
-    <script src="{% static "js/spice-html5/simulatecursor.js" %}"></script>
-    <script src="{% static "js/spice-html5/cursor.js" %}"></script>
-    <script src="{% static "js/spice-html5/thirdparty/jsbn.js" %}"></script>
-    <script src="{% static "js/spice-html5/thirdparty/rsa.js" %}"></script>
-    <script src="{% static "js/spice-html5/thirdparty/prng4.js" %}"></script>
-    <script src="{% static "js/spice-html5/thirdparty/rng.js" %}"></script>
-    <script src="{% static "js/spice-html5/thirdparty/sha1.js" %}"></script>
-    <script src="{% static "js/spice-html5/ticket.js" %}"></script>
-    <script src="{% static "js/spice-html5/resize.js" %}"></script>
-    <script src="{% static "js/spice-html5/filexfer.js" %}"></script>
     <link rel="stylesheet" type="text/css" href="{% static "js/spice-html5/spice.css" %}" />
-{% endblock %}
-
-{% block content %}
-
-    <div id="login" hidden>
-        <span class="logo">SPICE</span>
-        <label for="host">{% trans 'Host' %}:</label> <input type='text' id='host' value='{{ ws_host }}'> <!-- localhost -->
-        <label for="port">{% trans 'Port' %}:</label> <input type='text' id='port' value='{{ ws_port }}'>
-        <label for="password">{% trans 'Password' %}:</label> <input type='password' id='password' value='{{ console_passwd }}'>
-        <label for="show_console">{% trans 'Show console' %}</label><input type="checkbox" id="show_console" value="1" onchange="toggle_console()" checked>
-        <button id="connectButton" onclick="connect();">{% trans 'Start' %}</button>
-    </div>
-
-    <div id="spice-area">
-        <div id="spice-screen" class="spice-screen"></div>
-        <div id="message-div" class="spice-message"></div>
-    </div>
-
-    <div id="debug-div">
-    <!-- If DUMPXXX is turned on, dumped images will go here -->
-    </div>
-
-{% endblock %}
-
-{% block foot %}
 
+    <!-- ES2015/ES6 modules polyfill -->
+    <script type="module">
+        window._spice_has_module_support = true;
+    </script>
     <script>
+        window.addEventListener("load", function() {
+            if (window._spice_has_module_support) return;
+            var loader = document.createElement("script");
+            loader.src = '{% static "thirdparty/browser-es-module-loader/dist/browser-es-module-loader.js" %}';
+            document.head.appendChild(loader);
+        });
+    </script>
+
+    <script type="module" crossorigin="anonymous">
+
+        import * as SpiceHtml5 from '{% static "js/spice-html5/main.js" %}';
+
         var host = null, port = null;
         var sc;
 
@@ -96,9 +59,6 @@
 
             host = document.getElementById("host").value;
             port = document.getElementById("port").value;
-            if (window.location.protocol == 'https:') {
-                scheme = "wss://";
-            }
             password = document.getElementById("password").value;
 
             if ((!host) || (!port)) {
@@ -116,11 +76,10 @@
             document.getElementById('connectButton').onclick = disconnect;
 
             try {
-                sc = new SpiceMainConn({uri: uri, screen_id: "spice-screen", dump_id: "debug-div",
+                sc = new SpiceHtml5.SpiceMainConn({uri: uri, screen_id: "spice-screen", dump_id: "debug-div",
                             message_id: "message-div", password: password, onerror: spice_error, onagent: agent_connected });
             }
-            catch (e)
-            {
+            catch (e) {
                 alert(e.toString());
                 disconnect();
             }
@@ -135,25 +94,27 @@
             document.getElementById('connectButton').onclick = connect;
             if (window.File && window.FileReader && window.FileList && window.Blob) {
                 var spice_xfer_area = document.getElementById('spice-xfer-area');
-                document.getElementById('spice-area').removeChild(spice_xfer_area);
-                document.getElementById('spice-area').removeEventListener('dragover', handle_file_dragover, false);
-                document.getElementById('spice-area').removeEventListener('drop', handle_file_drop, false);
+                if (spice_xfer_area != null) {
+                  document.getElementById('spice-area').removeChild(spice_xfer_area);
+                }
+                document.getElementById('spice-area').removeEventListener('dragover', SpiceHtml5.handle_file_dragover, false);
+                document.getElementById('spice-area').removeEventListener('drop', SpiceHtml5.handle_file_drop, false);
             }
             console.log("<< disconnect");
         }
 
         function agent_connected(sc) {
-            window.addEventListener('resize', handle_resize);
+            window.addEventListener('resize', SpiceHtml5.handle_resize);
             window.spice_connection = this;
 
-            resize_helper(this);
+            SpiceHtml5.resize_helper(this);
 
             if (window.File && window.FileReader && window.FileList && window.Blob) {
                 var spice_xfer_area = document.createElement("div");
                 spice_xfer_area.setAttribute('id', 'spice-xfer-area');
                 document.getElementById('spice-area').appendChild(spice_xfer_area);
-                document.getElementById('spice-area').addEventListener('dragover', handle_file_dragover, false);
-                document.getElementById('spice-area').addEventListener('drop', handle_file_drop, false);
+                document.getElementById('spice-area').addEventListener('dragover', SpiceHtml5.handle_file_dragover, false);
+                document.getElementById('spice-area').addEventListener('drop', SpiceHtml5.handle_file_drop, false);
             }
             else {
                 console.log("File API is not supported");
@@ -171,20 +132,9 @@
                 m.style.display = 'none';
             }
 
-            window.addEventListener('resize', handle_resize);
-            resize_helper(sc);
-        }
-
-        function fullscreen() {
-            var screen=document.getElementById('spice-screen');
-            if(screen.requestFullscreen) {
-                screen.requestFullscreen();
-            } else if(screen.mozRequestFullScreen) {
-                screen.mozRequestFullScreen();
-            } else if(screen.webkitRequestFullscreen) {
-                screen.webkitRequestFullscreen();
-            } else if(screen.msRequestFullscreen) {
-                screen.msRequestFullscreen();
+            window.addEventListener('resize', SpiceHtml5.handle_resize);
+            if (sc) {
+                SpiceHtml5.resize_helper(sc);
             }
         }
         /* SPICE port event listeners
@@ -198,20 +148,72 @@
             DEBUG > 0 && console.log('SPICE port', event.detail.channel.portName, 'event data:', event.detail.spiceEvent);
         });
         */
-        document.getElementById("fullscreen_button").addEventListener('click', fullscreen);
-        document.getElementById('ctrlaltdel').addEventListener('click', sendCtrlAltDel);
-        document.getElementById('ctrlaltf1').addEventListener('click', function(){sendCtrlAltFN(0);});
-        document.getElementById('ctrlaltf2').addEventListener('click', function(){sendCtrlAltFN(1);});
-        document.getElementById('ctrlaltf3').addEventListener('click', function(){sendCtrlAltFN(2);});
-        document.getElementById('ctrlaltf4').addEventListener('click', function(){sendCtrlAltFN(3);});
-        document.getElementById('ctrlaltf5').addEventListener('click', function(){sendCtrlAltFN(4);});
-        document.getElementById('ctrlaltf6').addEventListener('click', function(){sendCtrlAltFN(5);});
-        document.getElementById('ctrlaltf7').addEventListener('click', function(){sendCtrlAltFN(6);});
-        document.getElementById('ctrlaltf8').addEventListener('click', function(){sendCtrlAltFN(7);});
-        document.getElementById('ctrlaltf9').addEventListener('click', function(){sendCtrlAltFN(8);});
-        document.getElementById('ctrlaltf10').addEventListener('click', function(){sendCtrlAltFN(9);});
-        document.getElementById('ctrlaltf11').addEventListener('click', function(){sendCtrlAltFN(10);});
-        document.getElementById('ctrlaltf12').addEventListener('click', function(){sendCtrlAltFN(11);});
-        connect();
-    </script>
+
+        function fullscreen() {
+        var screen=document.getElementById('spice-screen');
+        if(screen.requestFullscreen) {
+            screen.requestFullscreen();
+        } else if(screen.mozRequestFullScreen) {
+            screen.mozRequestFullScreen();
+        } else if(screen.webkitRequestFullscreen) {
+            screen.webkitRequestFullscreen();
+        } else if(screen.msRequestFullscreen) {
+            screen.msRequestFullscreen();
+        }
+    }
+    /* SPICE port event listeners
+    window.addEventListener('spice-port-data', function(event) {
+        // Here we convert data to text, but really we can obtain binary data also
+        var msg_text = arraybuffer_to_str(new Uint8Array(event.detail.data));
+        DEBUG > 0 && console.log('SPICE port', event.detail.channel.portName, 'message text:', msg_text);
+    });
+
+    window.addEventListener('spice-port-event', function(event) {
+        DEBUG > 0 && console.log('SPICE port', event.detail.channel.portName, 'event data:', event.detail.spiceEvent);
+    });
+    */
+    document.getElementById("fullscreen_button").addEventListener('click', fullscreen);
+    document.getElementById('ctrlaltdel').addEventListener('click', function(){sendCtrlAltDel(sc);});
+    document.getElementById('ctrlaltf1').addEventListener('click', function(){sendCtrlAltFN(0);});
+    document.getElementById('ctrlaltf2').addEventListener('click', function(){sendCtrlAltFN(1);});
+    document.getElementById('ctrlaltf3').addEventListener('click', function(){sendCtrlAltFN(2);});
+    document.getElementById('ctrlaltf4').addEventListener('click', function(){sendCtrlAltFN(3);});
+    document.getElementById('ctrlaltf5').addEventListener('click', function(){sendCtrlAltFN(4);});
+    document.getElementById('ctrlaltf6').addEventListener('click', function(){sendCtrlAltFN(5);});
+    document.getElementById('ctrlaltf7').addEventListener('click', function(){sendCtrlAltFN(6);});
+    document.getElementById('ctrlaltf8').addEventListener('click', function(){sendCtrlAltFN(7);});
+    document.getElementById('ctrlaltf9').addEventListener('click', function(){sendCtrlAltFN(8);});
+    document.getElementById('ctrlaltf10').addEventListener('click', function(){sendCtrlAltFN(9);});
+    document.getElementById('ctrlaltf11').addEventListener('click', function(){sendCtrlAltFN(10);});
+    document.getElementById('ctrlaltf12').addEventListener('click', function(){sendCtrlAltFN(11);});
+
+    document.getElementById('connectButton').onclick = connect;
+    document.getElementById('show_console').onchange = toggle_console;
+</script>
+{% endblock %}
+
+{% block content %}
+    <div id="login">
+        <span class="logo">SPICE</span>
+        <label for="host">{% trans 'Host' %}:</label> <input type='text' id='host' value='{{ ws_host }}'> <!-- localhost -->
+        <label for="port">{% trans 'Port' %}:</label> <input type='text' id='port' value='{{ ws_port }}'>
+        <label for="password">{% trans 'Password' %}:</label> <input type='password' id='password' value='{{ console_passwd }}'>
+        <label for="show_console">{% trans 'Show console' %}</label><input type="checkbox" id="show_console" value="1" onchange="toggle_console()" checked>
+        <button id="connectButton">{% trans 'Start' %}</button>
+    </div>
+
+    <div id="spice-area">
+        <div id="spice-screen" class="spice-screen"></div>
+    </div>
+
+    <div id="message-div" class="spice-message"></div>
+
+    <div id="debug-div">
+    <!-- If DUMPXXX is turned on, dumped images will go here -->
+    </div>
+
+{% endblock %}
+
+{% block foot %}
+
 {% endblock %}
diff --git a/console/templates/console-spice-lite.html b/console/templates/console-spice-lite.html
index f1e272c..d498f0f 100644
--- a/console/templates/console-spice-lite.html
+++ b/console/templates/console-spice-lite.html
@@ -25,56 +25,27 @@
 {% extends "console-base.html" %}
 {% load i18n %}
 {% load staticfiles %}
+
 {% block head %}
-
     <title>WebVirtCloud - Spice - Lite</title>
-    <script src="{% static "js/spice-html5/spicearraybuffer.js" %}"></script>
-    <script src="{% static "js/spice-html5/enums.js" %}"></script>
-    <script src="{% static "js/spice-html5/atKeynames.js" %}"></script>
-    <script src="{% static "js/spice-html5/utils.js" %}"></script>
-    <script src="{% static "js/spice-html5/png.js" %}"></script>
-    <script src="{% static "js/spice-html5/lz.js" %}"></script>
-    <script src="{% static "js/spice-html5/quic.js" %}"></script>
-    <script src="{% static "js/spice-html5/bitmap.js" %}"></script>
-    <script src="{% static "js/spice-html5/spicedataview.js" %}"></script>
-    <script src="{% static "js/spice-html5/spicetype.js" %}"></script>
-    <script src="{% static "js/spice-html5/spicemsg.js" %}"></script>
-    <script src="{% static "js/spice-html5/wire.js" %}"></script>
-    <script src="{% static "js/spice-html5/spiceconn.js" %}"></script>
-    <script src="{% static "js/spice-html5/display.js" %}"></script>
-    <script src="{% static "js/spice-html5/main.js" %}"></script>
-    <script src="{% static "js/spice-html5/inputs.js" %}"></script>
-    <script src="{% static "js/spice-html5/webm.js" %}"></script>
-    <script src="{% static "js/spice-html5/playback.js" %}"></script>
-    <script src="{% static "js/spice-html5/simulatecursor.js" %}"></script>
-    <script src="{% static "js/spice-html5/cursor.js" %}"></script>
-    <script src="{% static "js/spice-html5/thirdparty/jsbn.js" %}"></script>
-    <script src="{% static "js/spice-html5/thirdparty/rsa.js" %}"></script>
-    <script src="{% static "js/spice-html5/thirdparty/prng4.js" %}"></script>
-    <script src="{% static "js/spice-html5/thirdparty/rng.js" %}"></script>
-    <script src="{% static "js/spice-html5/thirdparty/sha1.js" %}"></script>
-    <script src="{% static "js/spice-html5/ticket.js" %}"></script>
-    <script src="{% static "js/spice-html5/resize.js" %}"></script>
-    <script src="{% static "js/spice-html5/filexfer.js" %}"></script>
-    <script src="{% static "js/spice-html5/port.js" %}"></script>
-
     <link rel="stylesheet" type="text/css" href="{% static "js/spice-html5/spice.css" %}" />
 
-{% endblock %}
-
-{% block content %}
-    <div id="spice-area">
-        <div id="spice-screen" class="spice-screen"></div>
-        <div id="message-div" class="spice-message"></div>
-    </div>
-
-    <div id="debug-div">
-    <!-- If DUMPXXX is turned on, dumped images will go here -->
-    </div>
-{% endblock %}
-
-{% block foot %}
+    <!-- ES2015/ES6 modules polyfill -->
+    <script type="module">
+        window._spice_has_module_support = true;
+    </script>
     <script>
+        window.addEventListener("load", function() {
+            if (window._spice_has_module_support) return;
+            var loader = document.createElement("script");
+            loader.src = '{% static "thirdparty/browser-es-module-loader/dist/browser-es-module-loader.js" %}';
+            document.head.appendChild(loader);
+        });
+    </script>
+
+    <script type="module" crossorigin="anonymous">
+        import * as SpiceHtml5 from '{% static "js/spice-html5/main.js" %}';
+
         var host = null, port = null;
         var sc;
 
@@ -92,21 +63,18 @@
         }
 
         function spice_error(e) {
-            console.log(e);
             disconnect();
-            if (e.message !== undefined) {
-                log_error(e.message);
-            }
-            else {
-                log_error('Unknown error');
+            if (e !== undefined && e.message === "Permission denied.") {
+              var pass = prompt("Password");
+              connect(pass);
             }
         }
 
-        function connect() {
-            var host, port, password, scheme = "ws://", uri;
-            console.log('>> connect');
+        function connect(password) {
+            var host, port, scheme = "ws://", uri;
+
             // By default, use the host and port of server that served this file
-            //host = spice_query_var('host', window.location.hostname);
+            // host = spice_query_var('host', window.location.hostname);
             host = '{{ ws_host| safe }}';
 
             // Note that using the web server port only makes sense
@@ -129,16 +97,18 @@
 
             // If a token variable is passed in, set the parameter in a cookie.
             // This is used by nova-spiceproxy.
-            token = spice_query_var('token', null);
+            var token = spice_query_var('token', null);
             if (token) {
                 spice_set_cookie('token', token, 1)
             }
 
-            //password = spice_query_var('password', '');
-            password = '{{ console_passwd | safe }}';
+            if (password === undefined) {
+                password = spice_query_var('password', '');
+                password = '{{ console_passwd | safe }}';
+            }
             if (password === 'None') password = '';
 
-            path = spice_query_var('path', 'websockify');
+            var path = spice_query_var('path', 'websockify');
 
             if ((!host) || (!port)) {
                 console.log("must specify host and port in URL");
@@ -156,43 +126,44 @@
             }
 
             try {
-                sc = new SpiceMainConn({uri: uri, screen_id: "spice-screen", dump_id: "debug-div",
+                sc = new SpiceHtml5.SpiceMainConn({uri: uri, screen_id: "spice-screen", dump_id: "debug-div",
                             message_id: "message-div", password: password, onerror: spice_error, onagent: agent_connected });
             }
             catch (e) {
                 alert(e.toString());
                 disconnect();
             }
-            console.log('<< connect')
+
         }
 
-        function disconnect()
-        {
+        function disconnect() {
             console.log(">> disconnect");
             if (sc) {
                 sc.stop();
             }
             if (window.File && window.FileReader && window.FileList && window.Blob) {
                 var spice_xfer_area = document.getElementById('spice-xfer-area');
-                document.getElementById('spice-area').removeChild(spice_xfer_area);
-                document.getElementById('spice-area').removeEventListener('dragover', handle_file_dragover, false);
-                document.getElementById('spice-area').removeEventListener('drop', handle_file_drop, false);
+                if (spice_xfer_area != null) {
+                  document.getElementById('spice-area').removeChild(spice_xfer_area);
+                }
+                document.getElementById('spice-area').removeEventListener('dragover', SpiceHtml5.handle_file_dragover, false);
+                document.getElementById('spice-area').removeEventListener('drop', SpiceHtml5.handle_file_drop, false);
             }
             console.log("<< disconnect");
         }
 
         function agent_connected(sc) {
-            window.addEventListener('resize', handle_resize);
+            window.addEventListener('resize', SpiceHtml5.handle_resize);
             window.spice_connection = this;
 
-            resize_helper(this);
+            SpiceHtml5.resize_helper(this);
 
             if (window.File && window.FileReader && window.FileList && window.Blob) {
                 var spice_xfer_area = document.createElement("div");
                 spice_xfer_area.setAttribute('id', 'spice-xfer-area');
                 document.getElementById('spice-area').appendChild(spice_xfer_area);
-                document.getElementById('spice-area').addEventListener('dragover', handle_file_dragover, false);
-                document.getElementById('spice-area').addEventListener('drop', handle_file_drop, false);
+                document.getElementById('spice-area').addEventListener('dragover', SpiceHtml5.handle_file_dragover, false);
+                document.getElementById('spice-area').addEventListener('drop', SpiceHtml5.handle_file_drop, false);
             }
             else {
                 console.log("File API is not supported");
@@ -224,7 +195,7 @@
         });
         */
         document.getElementById("fullscreen_button").addEventListener('click', fullscreen);
-        document.getElementById('ctrlaltdel').addEventListener('click', sendCtrlAltDel);
+        document.getElementById('ctrlaltdel').addEventListener('click', function(){sendCtrlAltDel(sc);});
         document.getElementById('ctrlaltf1').addEventListener('click', function(){sendCtrlAltFN(0);});
         document.getElementById('ctrlaltf2').addEventListener('click', function(){sendCtrlAltFN(1);});
         document.getElementById('ctrlaltf3').addEventListener('click', function(){sendCtrlAltFN(2);});
@@ -237,6 +208,22 @@
         document.getElementById('ctrlaltf10').addEventListener('click', function(){sendCtrlAltFN(9);});
         document.getElementById('ctrlaltf11').addEventListener('click', function(){sendCtrlAltFN(10);});
         document.getElementById('ctrlaltf12').addEventListener('click', function(){sendCtrlAltFN(11);});
-        connect();
+        connect(undefined);
     </script>
 {% endblock %}
+{% block content %}
+        <div id="login">
+            <span class="logo">SPICE</span>
+        </div>
+
+        <div id="spice-area">
+            <div id="spice-screen" class="spice-screen"></div>
+        </div>
+
+        <div id="message-div" class="spice-message"></div>
+
+        <div id="debug-div">
+        <!-- If DUMPXXX is turned on, dumped images will go here -->
+        </div>
+{% endblock %}
+
diff --git a/console/tunnel.py b/console/tunnel.py
index a6ba2c8..c7c19d6 100644
--- a/console/tunnel.py
+++ b/console/tunnel.py
@@ -27,6 +27,7 @@ import os
 import socket
 import signal
 import logging
+from functools import reduce
 
 
 class Tunnel(object):
@@ -103,7 +104,7 @@ class Tunnel(object):
 
         logging.debug("Tunnel PID=%d OUTFD=%d ERRFD=%d",
                       pid, fds[0].fileno(), errorfds[0].fileno())
-        errorfds[0].setblocking(0)
+        errorfds[0].setblocking(False)
 
         self.outfd = fds[0]
         self.errfd = errorfds[0]
diff --git a/console/views.py b/console/views.py
index 85b0a27..a27a562 100644
--- a/console/views.py
+++ b/console/views.py
@@ -33,7 +33,7 @@ def console(request):
         console_type = conn.get_console_type()
         console_websocket_port = conn.get_console_websocket_port()
         console_passwd = conn.get_console_passwd()
-    except libvirtError as lib_err:
+    except libvirtError:
         console_type = None
         console_websocket_port = None
         console_passwd = None
diff --git a/create/forms.py b/create/forms.py
index a869ca4..21695e2 100644
--- a/create/forms.py
+++ b/create/forms.py
@@ -62,4 +62,3 @@ class NewVMForm(forms.Form):
         elif len(name) > 64:
             raise forms.ValidationError(_('The name of the virtual machine must not exceed 20 characters'))
         return name
-
diff --git a/create/migrations/0001_initial.py b/create/migrations/0001_initial.py
index 030ee30..102bc96 100644
--- a/create/migrations/0001_initial.py
+++ b/create/migrations/0001_initial.py
@@ -1,11 +1,12 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
+# Generated by Django 2.2.10 on 2020-01-28 07:01
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
+    initial = True
+
     dependencies = [
     ]
 
@@ -13,14 +14,11 @@ class Migration(migrations.Migration):
         migrations.CreateModel(
             name='Flavor',
             fields=[
-                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                 ('label', models.CharField(max_length=12)),
                 ('memory', models.IntegerField()),
                 ('vcpu', models.IntegerField()),
                 ('disk', models.IntegerField()),
             ],
-            options={
-            },
-            bases=(models.Model,),
         ),
     ]
diff --git a/create/migrations/0002_auto_20150325_0921.py b/create/migrations/0002_addFlavors.py
similarity index 92%
rename from create/migrations/0002_auto_20150325_0921.py
rename to create/migrations/0002_addFlavors.py
index 5594060..f3ea4b3 100644
--- a/create/migrations/0002_auto_20150325_0921.py
+++ b/create/migrations/0002_addFlavors.py
@@ -1,5 +1,4 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
+# Generated by Django 2.2.10 on 2020-01-28 07:01
 
 from django.db import migrations
 
@@ -28,4 +27,4 @@ class Migration(migrations.Migration):
 
     operations = [
         migrations.RunPython(add_favors),
-    ]
+    ]
\ No newline at end of file
diff --git a/create/models.py b/create/models.py
index 0572fdd..80bf9f3 100644
--- a/create/models.py
+++ b/create/models.py
@@ -1,11 +1,11 @@
-from django.db import models
+from django.db.models import Model, CharField, IntegerField
 
 
-class Flavor(models.Model):
-    label = models.CharField(max_length=12)
-    memory = models.IntegerField()
-    vcpu = models.IntegerField()
-    disk = models.IntegerField()
+class Flavor(Model):
+    label = CharField(max_length=12)
+    memory = IntegerField()
+    vcpu = IntegerField()
+    disk = IntegerField()
 
     def __unicode__(self):
         return self.name
diff --git a/create/templates/create_instance_w1.html b/create/templates/create_instance_w1.html
index e4a5f2c..a75a0b2 100644
--- a/create/templates/create_instance_w1.html
+++ b/create/templates/create_instance_w1.html
@@ -94,7 +94,7 @@
                                 </button>
                             </form>
                         </div>
-                        <div class="clearfix"/>
+                        <div class="clearfix"></div>
                     </div>
                 </div>
             </div>
diff --git a/create/templates/create_instance_w2.html b/create/templates/create_instance_w2.html
index 09a9484..9e00d7c 100644
--- a/create/templates/create_instance_w2.html
+++ b/create/templates/create_instance_w2.html
@@ -120,7 +120,7 @@
                                                                     <div class="col-sm-6">
                                                                         <select class="form-control" id="select_firmware" name="firmware">
                                                                             {% for frm in firmwares %}
-                                                                            <option value="{{ frm }}" {% if frm == default_firmware %}selected{% endif %}>{{ frm }}</option>
+                                                                            <option value="{{ frm }}" {% if frm in default_firmware %}selected{% endif %}>{{ frm }}</option>
                                                                             {% endfor %}
                                                                         </select>
                                                                     </div>
@@ -792,7 +792,7 @@
                     $.each(input_value.split(','), function (index, value) {
                         let li = '<li>eth' + counter +
                                 ' -> ' + value + ' ' +
-                                '<a class="btn-link pull-right" onclick="javascript:$(\'#network-control\').multiselect(\'deselect\', \'' + value + '\', true)"><i class="fa fa-remove"></i></a></a></li>';
+                                '<a class="btn-link pull-right" onclick="$(\'#network-control\').multiselect(\'deselect\', \'' + value + '\', true)"><i class="fa fa-remove"></i></a></a></li>';
                         selected_list_html += li;
                         counter++;
                     });
diff --git a/create/views.py b/create/views.py
index c66484f..e2e81fb 100644
--- a/create/views.py
+++ b/create/views.py
@@ -19,9 +19,13 @@ from webvirtcloud.settings import QEMU_CONSOLE_DEFAULT_TYPE
 from webvirtcloud.settings import INSTANCE_VOLUME_DEFAULT_IO
 from webvirtcloud.settings import INSTANCE_VOLUME_DEFAULT_DETECT_ZEROES
 from webvirtcloud.settings import INSTANCE_VOLUME_DEFAULT_DISCARD
+from webvirtcloud.settings import INSTANCE_ARCH_DEFAULT_TYPE
+from webvirtcloud.settings import INSTANCE_FIRMWARE_DEFAULT_TYPE
+
 from django.contrib import messages
 from logs.views import addlogmsg
 
+
 @login_required
 def create_instance_select_type(request, compute_id):
 
@@ -45,8 +49,9 @@ def create_instance_select_type(request, compute_id):
         all_hypervisors = conn.get_hypervisors_machines()
         # Supported hypervisors by webvirtcloud: i686, x86_64(for now)
         supported_arch = ["x86_64", "i686", "aarch64", "armv7l", "ppc64", "ppc64le", "s390x"]
-        hypervisors = [hpv for hpv in all_hypervisors.keys() if hpv in supported_arch ]
+        hypervisors = [hpv for hpv in all_hypervisors.keys() if hpv in supported_arch]
         default_machine = INSTANCE_MACHINE_DEFAULT_TYPE
+        default_arch = INSTANCE_ARCH_DEFAULT_TYPE
 
         if request.method == 'POST':
             if 'create_xml' in request.POST:
@@ -63,18 +68,21 @@ def create_instance_select_type(request, compute_id):
                         conn._defineXML(xml)
                         return HttpResponseRedirect(reverse('instance', args=[compute_id, name]))
                     except libvirtError as lib_err:
-                        error_messages.append(lib_err.message)
+                        error_messages.append(lib_err)
 
     except libvirtError as lib_err:
         error_messages.append(lib_err)
 
     return render(request, 'create_instance_w1.html', locals())
 
+
 @login_required
 def create_instance(request, compute_id, arch, machine):
     """
     :param request:
     :param compute_id:
+    :param arch:
+    :param machine:
     :return:
     """
     if not request.user.is_superuser:
@@ -96,6 +104,7 @@ def create_instance(request, compute_id, arch, machine):
                          compute.password,
                          compute.type)
 
+        default_firmware = INSTANCE_FIRMWARE_DEFAULT_TYPE
         default_cpu_mode = INSTANCE_CPU_DEFAULT_MODE
         instances = conn.get_instances()
         videos = conn.get_video_models(arch, machine)
@@ -189,7 +198,7 @@ def create_instance(request, compute_id, arch, machine):
                                     volume_list.append(volume)
                                     is_disk_created = True
                                 except libvirtError as lib_err:
-                                    error_messages.append(lib_err.message)
+                                    error_messages.append(lib_err)
                         elif data['template']:
                             templ_path = conn.get_volume_path(data['template'])
                             dest_vol = conn.get_volume_path(data["name"] + ".img", data['storage'])
@@ -221,7 +230,7 @@ def create_instance(request, compute_id, arch, machine):
                                         volume['bus'] = request.POST.get('bus' + str(idx), '')
                                         volume_list.append(volume)
                                     except libvirtError as lib_err:
-                                        error_messages.append(lib_err.message)
+                                        error_messages.append(lib_err)
                         if data['cache_mode'] not in conn.get_cache_modes():
                             error_msg = _("Invalid cache mode")
                             error_messages.append(error_msg)
diff --git a/dev/requirements.txt b/dev/requirements.txt
index e88d0b2..d56ba0a 100644
--- a/dev/requirements.txt
+++ b/dev/requirements.txt
@@ -1,4 +1,4 @@
 -r ../conf/requirements.txt
-pep8==1.7.1
+pycodestyle
 pyflakes==2.1.1
-pylint==1.9.4
+pylint==2.4.4
diff --git a/gunicorn.conf.py b/gunicorn.conf.py
index 8c07259..90bd54e 100644
--- a/gunicorn.conf.py
+++ b/gunicorn.conf.py
@@ -20,7 +20,7 @@ import os
 #       range.
 #
 
-#bind = 'unix:/srv/webvirtcloud/venv/wvcloud.socket'
+# bind = 'unix:/srv/webvirtcloud/venv/wvcloud.socket'
 bind = '127.0.0.1:8000'
 backlog = 2048
 
diff --git a/instances/migrations/0001_initial.py b/instances/migrations/0001_initial.py
index fe3c00f..e27f7aa 100644
--- a/instances/migrations/0001_initial.py
+++ b/instances/migrations/0001_initial.py
@@ -1,11 +1,13 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
+# Generated by Django 2.2.10 on 2020-01-28 07:01
 
-from django.db import models, migrations
+from django.db import migrations, models
+import django.db.models.deletion
 
 
 class Migration(migrations.Migration):
 
+    initial = True
+
     dependencies = [
         ('computes', '0001_initial'),
     ]
@@ -14,13 +16,12 @@ class Migration(migrations.Migration):
         migrations.CreateModel(
             name='Instance',
             fields=[
-                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
-                ('name', models.CharField(max_length=20)),
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('name', models.CharField(max_length=120)),
                 ('uuid', models.CharField(max_length=36)),
-                ('compute', models.ForeignKey(to='computes.Compute')),
+                ('is_template', models.BooleanField(default=False)),
+                ('created', models.DateField(auto_now_add=True)),
+                ('compute', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='computes.Compute')),
             ],
-            options={
-            },
-            bases=(models.Model,),
         ),
     ]
diff --git a/instances/migrations/0002_instance_is_template.py b/instances/migrations/0002_instance_is_template.py
deleted file mode 100644
index cbf2cdd..0000000
--- a/instances/migrations/0002_instance_is_template.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import models, migrations
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('instances', '0001_initial'),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name='instance',
-            name='is_template',
-            field=models.BooleanField(default=False),
-        ),
-    ]
diff --git a/instances/migrations/0003_instance_created.py b/instances/migrations/0003_instance_created.py
deleted file mode 100644
index 32d4ac9..0000000
--- a/instances/migrations/0003_instance_created.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-import datetime
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('instances', '0002_instance_is_template'),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name='instance',
-            name='created',
-            field=models.DateField(default=datetime.datetime(2017, 10, 26, 8, 5, 55, 797326), auto_now_add=True),
-            preserve_default=False,
-        ),
-    ]
diff --git a/instances/migrations/0004_auto_20180724_1136.py b/instances/migrations/0004_auto_20180724_1136.py
deleted file mode 100644
index 82480cd..0000000
--- a/instances/migrations/0004_auto_20180724_1136.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.13 on 2018-07-24 11:36
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('instances', '0003_instance_created'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='instance',
-            name='name',
-            field=models.CharField(max_length=120),
-        ),
-    ]
diff --git a/instances/models.py b/instances/models.py
index b11c860..436ab41 100644
--- a/instances/models.py
+++ b/instances/models.py
@@ -1,13 +1,13 @@
-from django.db import models
+from django.db.models import Model, ForeignKey, CharField, BooleanField, DateField, CASCADE
 from computes.models import Compute
 
 
-class Instance(models.Model):
-    compute = models.ForeignKey(Compute, on_delete=models.CASCADE)
-    name = models.CharField(max_length=120)
-    uuid = models.CharField(max_length=36)
-    is_template = models.BooleanField(default=False)
-    created = models.DateField(auto_now_add=True)
+class Instance(Model):
+    compute = ForeignKey(Compute, on_delete=CASCADE)
+    name = CharField(max_length=120)
+    uuid = CharField(max_length=36)
+    is_template = BooleanField(default=False)
+    created = DateField(auto_now_add=True)
 
     def __unicode__(self):
         return self.name
diff --git a/instances/templates/edit_instance_volume.html b/instances/templates/edit_instance_volume.html
index e0b5fd9..5b023e5 100644
--- a/instances/templates/edit_instance_volume.html
+++ b/instances/templates/edit_instance_volume.html
@@ -48,7 +48,7 @@
                                 <div class="form-group">
                                     <label class="col-sm-4 control-label">{% trans 'Bus' %}</label>
                                     <div class="col-sm-8">
-                                        <select class="form-control" name="vol_bus">
+                                        <select class="form-control" name="vol_bus" {% if status != 5 %} disabled {% endif %}>
                                         {% for bus in bus_host %}
                                             <option value="{{ bus }}" {% if bus == disk.bus %}selected{% endif %}>{{ bus }}</option>
                                         {% endfor %}
@@ -110,6 +110,7 @@
                                         </select>
                                     </div>
                                 </div>
+                                <input class="form-control" name="vol_bus_old" value="{{ disk.bus }}"/>
                             </div><!-- /.tabpane-content -->
                         </div><!-- /.tab-content -->
                 </div> <!-- /.modal-body -->
diff --git a/instances/templates/instance.html b/instances/templates/instance.html
index c3cb9c6..c3307c1 100644
--- a/instances/templates/instance.html
+++ b/instances/templates/instance.html
@@ -510,7 +510,7 @@
                             <div role="tabpanel" class="tab-pane tab-pane-bordered" id="resizevm_disk">
                                 {% if request.user.is_superuser or request.user.is_staff or userinstance.is_change %}
                                     <form class="form-horizontal" method="post" role="form">{% csrf_token %}
-                                        <p style="font-weight:bold;">{% trans "Disk allocation (B):" %}</p>
+                                        <p style="font-weight:bold;">{% trans "Disk allocation (GB):" %}</p>
                                         {% for disk in disks %}
                                         <div class="form-group">
                                             <label class="col-sm-4 control-label" style="font-weight:normal;">{% trans "Current allocation" %} ({{ disk.dev }})</label>
@@ -704,25 +704,25 @@
                                             </div>
                                         </form>
                                         <p style="font-weight:bold;">{% trans 'Boot Order' %}</p>
-                                            <form class="form-horizontal" action="" method="post" role="form">{% csrf_token %}
-                                                <div class="form-group">
-                                                    <div class="col-sm-12 col-sm-offset-2">
-                                                    {% ifequal status 5 %}
-                                                        <p>{% trans "Enable Boot Menu for your instance when it starts up " %}
-                                                        {% ifequal bootmenu 0 %}
-                                                            <input type="submit" class="btn btn-success" name="set_bootmenu" title="Show boot menu" value="{% trans "Enable" %}">
-                                                        {% else %}
-                                                            <input type="submit" class="btn btn-danger" name="unset_bootmenu" title="Hide boot menu" value="{% trans "Disable" %}">
-                                                        {% endifequal %}
+                                        <form class="form-horizontal" action="" method="post" role="form">{% csrf_token %}
+                                            <div class="form-group">
+                                                <div class="col-sm-12 col-sm-offset-2">
+                                                {% ifequal status 5 %}
+                                                    <p>{% trans "Enable Boot Menu for your instance when it starts up " %}
+                                                    {% ifequal bootmenu 0 %}
+                                                        <input type="submit" class="btn btn-success" name="set_bootmenu" title="Show boot menu" value="{% trans "Enable" %}">
                                                     {% else %}
-                                                        {% ifequal bootmenu 0  %}
-                                                            <p>{% trans "**** Please shutdown instance to modify boot menu ****" %}</p>
-                                                        {% endifequal %}
+                                                        <input type="submit" class="btn btn-danger" name="unset_bootmenu" title="Hide boot menu" value="{% trans "Disable" %}">
                                                     {% endifequal %}
-                                                    </div>
+                                                {% else %}
+                                                    {% ifequal bootmenu 0  %}
+                                                        <p>{% trans "**** Please shutdown instance to modify boot menu ****" %}</p>
+                                                    {% endifequal %}
+                                                {% endifequal %}
                                                 </div>
-                                            </form>
-                                        </p>
+                                            </div>
+                                        </form>
+
                                         {% ifequal bootmenu 1  %}
                                             <div class="col-sm-6 col-sm-offset-2">
                                             <div class="well">
@@ -841,12 +841,14 @@
                                         <div class="col-xs-12 col-sm-12">
                                         <table class="table table-hover">
                                             <thead>
-                                                <th>{% trans "Device" %}</th>
-                                                <th>{% trans "Used" %}</th>
-                                                <th>{% trans "Capacity" %}</th>
-                                                <th>{% trans "Storage" %}</th>
-                                                <th>{% trans "Source" %}</th>
-                                                <th>{% trans "Action" %}</th>
+                                                <tr>
+                                                    <th>{% trans "Device" %}</th>
+                                                    <th>{% trans "Used" %}</th>
+                                                    <th>{% trans "Capacity" %}</th>
+                                                    <th>{% trans "Storage" %}</th>
+                                                    <th>{% trans "Source" %}</th>
+                                                    <th>{% trans "Action" %}</th>
+                                                </tr>
                                             </thead>
                                             <tbody>
                                             {% for disk in disks %}
@@ -1169,7 +1171,7 @@
                                     <button class="btn btn-lg btn-success pull-right disabled">{% trans "Migrate" %}</button>
                                 {% endif %}
                             </form>
-                            <div class="clearfix"></div></p>
+                            <div class="clearfix"></div>
                         </div>
                         <div role="tabpanel" class="tab-pane tab-pane-bordered" id="xmledit">
                             <p>{% trans "If you need to edit xml please Power Off the instance" %}</p>
@@ -1354,7 +1356,7 @@
                                         </div>
                                     {% else %}
                                         <div class="col-sm-4">
-                                            <select id="select_clone_name" class="form-control" name="name" size="1"/>
+                                            <select id="select_clone_name" class="form-control" name="name" size="1">
                                             {% for name in clone_free_names %}
                                                 <option value="{{ name }}">{{ name }}</option>
                                             {% endfor %}
@@ -1730,7 +1732,7 @@
         $.getJSON('{% url 'random_mac_address' %}', function (data) {
             $('input[name="' + net + '"]').val(data['mac']);
         });
-    };
+    }
 </script>
 <script>
     function show_console() {
@@ -1765,13 +1767,13 @@
         vname = '{{ vname }}';
         {% for disk in disks %}
             disk_name = '{{ disk.image }}';
-            disk_dot = disk_name.split('.')
+            disk_dot = disk_name.split('.');
             disk_dot_suffix = disk_dot[disk_dot.length-1];
             if (disk_name.startsWith(vname)) {
                 image = disk_name.replace(vname, new_vname);
             } else if (disk_name.lastIndexOf('.') > -1 && disk_dot_suffix.length <= 7) {
                 disk_dot.pop();
-                disk_name_only = disk_dot.join('-')
+                disk_name_only = disk_dot.join('-');
                 image = new_vname + "-" + disk_name_only + "." + disk_dot_suffix
             } else if (new_vname != disk_name) {
                 image = new_vname
@@ -1811,28 +1813,28 @@
     });
     $(document).ready(function () {
         // set current console keymap or fall back to default
-        var keymap = "{{ console_keymap }}"
+        var keymap = "{{ console_keymap }}";
         if (keymap != '') {
             $("#console_select_keymap option[value='" + keymap + "']").prop('selected', true);
         }
     });
     $(document).ready(function () {
         // set current console type or fall back to default
-        var console_type = "{{ console_type }}"
+        var console_type = "{{ console_type }}";
         if (console_type != '') {
             $("#console_select_type option[value='" + console_type + "']").prop('selected', true);
         }
     });
     $(document).ready(function () {
         // set current console listen address or fall back to default
-        var console_listen_address = "{{ console_listen_address }}"
+        var console_listen_address = "{{ console_listen_address }}";
         if (console_listen_address != '') {
             $("#console_select_listen_address option[value='" + console_listen_address + "']").prop('selected', true);
         }
     });
     $(document).ready(function () {
         // get video model or fall back to default
-        let video_model = "{{ video_model }}"
+        let video_model = "{{ video_model }}";
         if (video_model != '') {
             $("#video_model_select option[value='" + video_model + "']").prop('selected', true);
         }
@@ -2103,7 +2105,7 @@
         var netChart = {};
         {% for net in networks %}
             var net_ctx_{{ forloop.counter0 }} = $("#netEth{{ forloop.counter0 }}Chart").get(0).getContext("2d");
-            netChart['{{ forloop.counter0 }}'] = new Chart(net_ctx_{{ forloop.counter0 }}, {
+            netChart[{{ forloop.counter0 }}] = new Chart(net_ctx_{{ forloop.counter0 }}, {
                 type: 'line',
                 data: {
                    datasets : [
@@ -2182,8 +2184,8 @@
                 for (let j = 0; j < data.blkdata.length; j++) {
                     diskChart[data.blkdata[j].dev].data.labels.push(data.timeline);
 
-                    diskChart[data.blkdata[j].dev].data.datasets[0].data.push(data.blkdata[0].data[0]);
-                    diskChart[data.blkdata[j].dev].data.datasets[1].data.push(data.blkdata[0].data[1]);
+                    diskChart[data.blkdata[j].dev].data.datasets[0].data.push(data.blkdata[j].data[0]);
+                    diskChart[data.blkdata[j].dev].data.datasets[1].data.push(data.blkdata[j].data[1]);
                     if (diskChart[data.blkdata[j].dev].data.datasets[0].data.length > 10){
                         diskChart[data.blkdata[j].dev].data.labels.shift();
                         diskChart[data.blkdata[j].dev].data.datasets[0].data.shift();
@@ -2195,8 +2197,8 @@
                 for (let j = 0; j < data.netdata.length; j++) {
                     netChart[data.netdata[j].dev].data.labels.push(data.timeline);
 
-                    netChart[data.netdata[j].dev].data.datasets[0].data.push(data.netdata[0].data[0]);
-                    netChart[data.netdata[j].dev].data.datasets[1].data.push(data.netdata[0].data[1]);
+                    netChart[data.netdata[j].dev].data.datasets[0].data.push(data.netdata[j].data[0]);
+                    netChart[data.netdata[j].dev].data.datasets[1].data.push(data.netdata[j].data[1]);
                     if (netChart[data.netdata[j].dev].data.datasets[0].data.length > 10){
                         netChart[data.netdata[j].dev].data.labels.shift();
                         netChart[data.netdata[j].dev].data.datasets[0].data.shift();
@@ -2211,7 +2213,7 @@
 <script>
      backgroundJobRunning = false;
      window.setInterval(function get_status() {
-         var status = {{ status }};
+         var status = {{ status|lower }};
          $.getJSON('{% url 'inst_status' compute_id vname %}', function (data) {
              if (data['status'] != status && !backgroundJobRunning) {
                  window.location.reload()
diff --git a/instances/urls.py b/instances/urls.py
index 1054ed1..32922a2 100644
--- a/instances/urls.py
+++ b/instances/urls.py
@@ -1,14 +1,14 @@
-from django.conf.urls import url
+from django.urls import path, re_path
 from . import views
 
 urlpatterns = [
-    url(r'^$', views.allinstances, name='allinstances'),
-    url(r'^(?P<compute_id>[0-9]+)/(?P<vname>[\w\-\.]+)/$',  views.instance, name='instance'),
-    url(r'^statistics/(?P<compute_id>[0-9]+)/(?P<vname>[\w\-\.]+)/$', views.inst_graph, name='inst_graph'),
-    url(r'^status/(?P<compute_id>[0-9]+)/(?P<vname>[\w\-\.]+)/$', views.inst_status, name='inst_status'),
-    url(r'^guess_mac_address/(?P<vname>[\w\-\.]+)/$', views.guess_mac_address, name='guess_mac_address'),
-    url(r'^guess_clone_name/$', views.guess_clone_name, name='guess_clone_name'),
-    url(r'^random_mac_address/$', views.random_mac_address, name='random_mac_address'),
-    url(r'^check_instance/(?P<vname>[\w\-\.]+)/$', views.check_instance, name='check_instance'),
-    url(r'^sshkeys/(?P<vname>[\w\-\.]+)/$', views.sshkeys, name='sshkeys'),
+    path('', views.allinstances, name='allinstances'),
+    re_path(r'^(?P<compute_id>[0-9]+)/(?P<vname>[\w\-\.]+)/$',  views.instance, name='instance'),
+    re_path(r'^statistics/(?P<compute_id>[0-9]+)/(?P<vname>[\w\-\.]+)/$', views.inst_graph, name='inst_graph'),
+    re_path(r'^status/(?P<compute_id>[0-9]+)/(?P<vname>[\w\-\.]+)/$', views.inst_status, name='inst_status'),
+    re_path(r'^guess_mac_address/(?P<vname>[\w\-\.]+)/$', views.guess_mac_address, name='guess_mac_address'),
+    re_path(r'^guess_clone_name/$', views.guess_clone_name, name='guess_clone_name'),
+    re_path(r'^random_mac_address/$', views.random_mac_address, name='random_mac_address'),
+    re_path(r'^check_instance/(?P<vname>[\w\-\.]+)/$', views.check_instance, name='check_instance'),
+    re_path(r'^sshkeys/(?P<vname>[\w\-\.]+)/$', views.sshkeys, name='sshkeys'),
 ]
diff --git a/instances/views.py b/instances/views.py
index 20d4616..7b9c51a 100644
--- a/instances/views.py
+++ b/instances/views.py
@@ -63,7 +63,7 @@ def allinstances(request):
             return instances_actions(request)
         except libvirtError as lib_err:
             error_messages.append(lib_err)
-            addlogmsg(request.user.username, request.POST.get("name", "instance"), lib_err.message)
+            addlogmsg(request.user.username, request.POST.get("name", "instance"), lib_err)
 
     view_style = settings.VIEW_INSTANCES_LIST_STYLE
 
@@ -94,7 +94,7 @@ def instances(request, compute_id):
             return instances_actions(request)
         except libvirtError as lib_err:
             error_messages.append(lib_err)
-            addlogmsg(request.user.username, request.POST.get("name", "instance"), lib_err.message)
+            addlogmsg(request.user.username, request.POST.get("name", "instance"), lib_err)
 
     return render(request, 'instances.html', locals())
 
@@ -131,19 +131,19 @@ def instance(request, compute_id, vname):
     def filesizefstr(size_str):
         if size_str == '':
             return 0
-        size_str = size_str.encode('ascii', 'ignore').upper().translate(None, " B")
+        size_str = size_str.upper().replace("B", "")
         if 'K' == size_str[-1]:
-            return long(float(size_str[:-1])) << 10
+            return int(float(size_str[:-1])) << 10
         elif 'M' == size_str[-1]:
-            return long(float(size_str[:-1])) << 20
+            return int(float(size_str[:-1])) << 20
         elif 'G' == size_str[-1]:
-            return long(float(size_str[:-1])) << 30
+            return int(float(size_str[:-1])) << 30
         elif 'T' == size_str[-1]:
-            return long(float(size_str[:-1])) << 40
+            return int(float(size_str[:-1])) << 40
         elif 'P' == size_str[-1]:
-            return long(float(size_str[:-1])) << 50
+            return int(float(size_str[:-1])) << 50
         else:
-            return long(float(size_str))
+            return int(float(size_str))
 
     def get_clone_free_names(size=10):
         prefix = settings.CLONE_INSTANCE_DEFAULT_PREFIX
@@ -217,8 +217,8 @@ def instance(request, compute_id, vname):
         if media:
             existing_media_devs = [m['dev'] for m in media]
 
-        for l in string.lowercase:
-            dev = dev_base + l
+        for al in string.ascii_lowercase:
+            dev = dev_base + al
             if dev not in existing_disk_devs and dev not in existing_media_devs:
                 return dev
         raise Exception(_('None available device name'))
@@ -576,7 +576,7 @@ def instance(request, compute_id, vname):
                 target_dev = get_new_disk_dev(media, disks, bus)
 
                 source = conn_create.create_volume(storage, name, size, format, meta_prealloc, default_owner)
-                conn.attach_disk(source, target_dev, target_bus=bus, driver_type=format, cache_mode=cache)
+                conn.attach_disk(target_dev, source, target_bus=bus, driver_type=format, cache_mode=cache)
                 msg = _('Attach new disk {} ({})'.format(name, format))
                 addlogmsg(request.user.username, instance.name, msg)
                 return HttpResponseRedirect(request.get_full_path() + '#disks')
@@ -598,7 +598,7 @@ def instance(request, compute_id, vname):
                 target_dev = get_new_disk_dev(media, disks, bus)
                 source = path + "/" + name
 
-                conn.attach_disk(source, target_dev, target_bus=bus, driver_type=driver_type, cache_mode=cache)
+                conn.attach_disk(target_dev, source, target_bus=bus, driver_type=driver_type, cache_mode=cache)
                 msg = _('Attach Existing disk: ' + target_dev)
                 addlogmsg(request.user.username, instance.name, msg)
                 return HttpResponseRedirect(request.get_full_path() + '#disks')
@@ -609,16 +609,26 @@ def instance(request, compute_id, vname):
                 new_path = request.POST.get('vol_path', '')
                 shareable = bool(request.POST.get('vol_shareable', False))
                 readonly = bool(request.POST.get('vol_readonly', False))
-                bus = request.POST.get('vol_bus', '')
+                disk_type = request.POST.get('vol_type', '')
+                new_bus = request.POST.get('vol_bus', '')
+                bus = request.POST.get('vol_bus_old', '')
                 serial = request.POST.get('vol_serial', '')
                 format = request.POST.get('vol_format', '')
                 cache = request.POST.get('vol_cache', default_cache)
                 io = request.POST.get('vol_io_mode', default_io)
                 discard = request.POST.get('vol_discard_mode', default_discard)
                 zeroes = request.POST.get('vol_detect_zeroes', default_zeroes)
+                new_target_dev = get_new_disk_dev(media, disks, new_bus)
 
-                conn.edit_disk(target_dev, new_path, readonly, shareable, bus, serial, format,
-                               cache, io, discard, zeroes)
+                if new_bus != bus:
+                    conn.detach_disk(target_dev)
+                    conn.attach_disk(new_target_dev, new_path, target_bus=new_bus,
+                                 driver_type=format, cache_mode=cache,
+                                 readonly=readonly, shareable=shareable, serial=serial,
+                                 io_mode=io, discard_mode=discard, detect_zeroes_mode=zeroes)
+                else:
+                    conn.edit_disk(target_dev, new_path, readonly, shareable, new_bus, serial, format,
+                                   cache, io, discard, zeroes)
 
                 if not conn.get_status() == 5:
                     messages.success(request, _("Disk changes changes are applied. " +
@@ -646,7 +656,7 @@ def instance(request, compute_id, vname):
                 try:
                     conn_delete.del_volume(name)
                 except libvirtError as err:
-                    msg = _('The disk: ' + dev + ' is detached but not deleted. ' + err.message)
+                    msg = _('The disk: ' + dev + ' is detached but not deleted. ' + err)
                     messages.warning(request, msg)
 
                 addlogmsg(request.user.username, instance.name, msg)
@@ -663,7 +673,7 @@ def instance(request, compute_id, vname):
             if 'add_cdrom' in request.POST and allow_admin_or_not_template:
                 bus = request.POST.get('bus', 'ide' if machine == 'pc' else 'sata')
                 target = get_new_disk_dev(media, disks, bus)
-                conn.attach_disk("", target, disk_device='cdrom', cache_mode='none', target_bus=bus, readonly=True)
+                conn.attach_disk(target, "",  disk_device='cdrom', cache_mode='none', target_bus=bus, readonly=True)
                 msg = _('Add CD-ROM: ' + target)
                 addlogmsg(request.user.username, instance.name, msg)
                 return HttpResponseRedirect(request.get_full_path() + '#disks')
@@ -746,7 +756,7 @@ def instance(request, compute_id, vname):
                     try:
                         conn.set_vcpu_hotplug(eval(status))
                     except libvirtError as lib_err:
-                        messages.error(request, lib_err.message)
+                        messages.error(request, lib_err)
                     messages.success(request, msg)
                     addlogmsg(request.user.username, instance.name, msg)
                     return HttpResponseRedirect(request.get_full_path() + '#resize')
@@ -951,7 +961,7 @@ def instance(request, compute_id, vname):
                                              "Stop and start network to activate new config")
 
                     except libvirtError as le:
-                        messages.error(request, le.message)
+                        messages.error(request, le)
                     return HttpResponseRedirect(request.get_full_path() + '#network')
                 if 'unset_qos' in request.POST:
                     qos_dir = request.POST.get('qos_direction', '')
@@ -1028,13 +1038,13 @@ def instance(request, compute_id, vname):
                         error_messages.append(msg)
                     else:
                         new_instance = Instance(compute_id=compute_id, name=clone_data['name'])
-                        #new_instance.save()
+                        # new_instance.save()
                         try:
                             new_uuid = conn.clone_instance(clone_data)
                             new_instance.uuid = new_uuid
                             new_instance.save()
                         except Exception as e:
-                            #new_instance.delete()
+                            # new_instance.delete()
                             raise e
 
                         user_instance = UserInstance(instance_id=new_instance.id, user_id=request.user.id, is_delete=True)
@@ -1064,8 +1074,8 @@ def instance(request, compute_id, vname):
         conn.close()
 
     except libvirtError as lib_err:
-        error_messages.append(lib_err.message)
-        addlogmsg(request.user.username, vname, lib_err.message)
+        error_messages.append(lib_err)
+        addlogmsg(request.user.username, vname, lib_err)
 
     return render(request, 'instance.html', locals())
 
@@ -1152,7 +1162,7 @@ def get_host_instances(request, comp):
     status = connection_manager.host_is_up(comp.type, comp.hostname)
 
     if status is True:
-        conn = wvmHostDetails(comp, comp.login, comp.password, comp.type)
+        conn = wvmHostDetails(comp.hostname, comp.login, comp.password, comp.type)
         comp_node_info = conn.get_node_info()
         comp_mem = conn.get_memory_usage()
         comp_instances = conn.get_host_instances(True)
diff --git a/logs/migrations/0001_initial.py b/logs/migrations/0001_initial.py
index 9acc8bf..21e66a8 100644
--- a/logs/migrations/0001_initial.py
+++ b/logs/migrations/0001_initial.py
@@ -1,29 +1,24 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
+# Generated by Django 2.2.10 on 2020-01-28 07:01
 
-from django.db import models, migrations
-from django.conf import settings
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
+    initial = True
+
     dependencies = [
-        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
-        ('instances', '0001_initial'),
     ]
 
     operations = [
         migrations.CreateModel(
             name='Logs',
             fields=[
-                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('user', models.CharField(max_length=50)),
+                ('instance', models.CharField(max_length=50)),
                 ('message', models.CharField(max_length=255)),
                 ('date', models.DateTimeField(auto_now=True)),
-                ('instance', models.ForeignKey(to='instances.Instance')),
-                ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
             ],
-            options={
-            },
-            bases=(models.Model,),
         ),
     ]
diff --git a/logs/migrations/0002_auto_20150316_1420.py b/logs/migrations/0002_auto_20150316_1420.py
deleted file mode 100644
index 9b742d8..0000000
--- a/logs/migrations/0002_auto_20150316_1420.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import models, migrations
-from django.conf import settings
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
-        ('logs', '0001_initial'),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name='logs',
-            name='user',
-            field=models.ForeignKey(to=settings.AUTH_USER_MODEL),
-            preserve_default=False,
-        ),
-        migrations.AlterField(
-            model_name='logs',
-            name='date',
-            field=models.DateTimeField(auto_now=True),
-            preserve_default=True,
-        ),
-    ]
diff --git a/logs/migrations/0003_auto_20150518_1855.py b/logs/migrations/0003_auto_20150518_1855.py
deleted file mode 100644
index 4fb709c..0000000
--- a/logs/migrations/0003_auto_20150518_1855.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import models, migrations
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('logs', '0002_auto_20150316_1420'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='logs',
-            name='instance',
-            field=models.CharField(max_length=50),
-        ),
-        migrations.AlterField(
-            model_name='logs',
-            name='user',
-            field=models.CharField(max_length=50),
-        ),
-    ]
diff --git a/logs/models.py b/logs/models.py
index 57aa0a7..9125a62 100644
--- a/logs/models.py
+++ b/logs/models.py
@@ -1,11 +1,11 @@
-from django.db import models
+from django.db.models import Model, CharField, DateTimeField
 
 
-class Logs(models.Model):
-    user = models.CharField(max_length=50)
-    instance = models.CharField(max_length=50)
-    message = models.CharField(max_length=255)
-    date = models.DateTimeField(auto_now=True)
+class Logs(Model):
+    user = CharField(max_length=50)
+    instance = CharField(max_length=50)
+    message = CharField(max_length=255)
+    date = DateTimeField(auto_now=True)
 
     def __unicode__(self):
         return self.instance
diff --git a/logs/templates/paging.html b/logs/templates/paging.html
index dc72a8c..9901dff 100644
--- a/logs/templates/paging.html
+++ b/logs/templates/paging.html
@@ -1,4 +1,4 @@
-<center>
+<div class="center-block">
     {% if page > 1 %}
         <a href="{% url 'showlogspage' page|add:"-1" %}">&larr;</a>
     {% else %}
@@ -9,4 +9,4 @@
     {% else %}
         &nbsp;
     {% endif %}
-</center>
+</div>
diff --git a/logs/urls.py b/logs/urls.py
index 574405c..fb8fb0b 100644
--- a/logs/urls.py
+++ b/logs/urls.py
@@ -1,8 +1,8 @@
-from django.conf.urls import url
+from django.urls import path, re_path
 from . import views
 
 urlpatterns = [
-    url(r'^$', views.showlogs, name='showlogs'),
-    url(r'^(?P<page>[0-9]+)/$', views.showlogs, name='showlogspage'),
-    url(r'^vm_logs/(?P<vname>[\w\-\.]+)/$', views.vm_logs, name='vm_logs'),
+    path('', views.showlogs, name='showlogs'),
+    re_path(r'^(?P<page>[0-9]+)/$', views.showlogs, name='showlogspage'),
+    re_path(r'^vm_logs/(?P<vname>[\w\-\.]+)/$', views.vm_logs, name='vm_logs'),
 ]
diff --git a/networks/forms.py b/networks/forms.py
index 7c3b07d..fbf08bb 100644
--- a/networks/forms.py
+++ b/networks/forms.py
@@ -9,7 +9,7 @@ class AddNetPool(forms.Form):
     subnet = forms.CharField(error_messages={'required': _('No IPv4 subnet has been entered')},
                              max_length=20, required=False)
     subnet6 = forms.CharField(error_messages={'required': _('No IPv6 subnet has been entered')},
-                             max_length=42, required=False)
+                              max_length=42, required=False)
     forward = forms.CharField(max_length=100)
     dhcp4 = forms.BooleanField(required=False)
     dhcp6 = forms.BooleanField(required=False)
diff --git a/networks/templates/network.html b/networks/templates/network.html
index 45aba51..5ebdd3f 100644
--- a/networks/templates/network.html
+++ b/networks/templates/network.html
@@ -191,6 +191,7 @@
                                     <tbody style="text-align: center">
                                     {% for fix4 in ipv4_fixed_address %}
                                         <tr>
+                                            <td>
                                             <form method="post" role="form">{% csrf_token %}
                                                 <td><input class="form-control" value="{{ fix4.mac }}" name="mac" readonly/></td>
                                                 <td><input class="form-control" value="{{ fix4.ip }}" name="address" /></td>
@@ -209,6 +210,7 @@
                                                     </button>
                                                 </td>
                                             </form>
+                                            </td>
                                         </tr>
                                     {% endfor %}
                                     </tbody>
diff --git a/networks/views.py b/networks/views.py
index acde835..a883be8 100644
--- a/networks/views.py
+++ b/networks/views.py
@@ -126,31 +126,31 @@ def network(request, compute_id, pool):
                 conn.start()
                 return HttpResponseRedirect(request.get_full_path())
             except libvirtError as lib_err:
-                error_messages.append(lib_err.message)
+                error_messages.append(lib_err)
         if 'stop' in request.POST:
             try:
                 conn.stop()
                 return HttpResponseRedirect(request.get_full_path())
             except libvirtError as lib_err:
-                error_messages.append(lib_err.message)
+                error_messages.append(lib_err)
         if 'delete' in request.POST:
             try:
                 conn.delete()
                 return HttpResponseRedirect(reverse('networks', args=[compute_id]))
             except libvirtError as lib_err:
-                error_messages.append(lib_err.message)
+                error_messages.append(lib_err)
         if 'set_autostart' in request.POST:
             try:
                 conn.set_autostart(1)
                 return HttpResponseRedirect(request.get_full_path())
             except libvirtError as lib_err:
-                error_messages.append(lib_err.message)
+                error_messages.append(lib_err)
         if 'unset_autostart' in request.POST:
             try:
                 conn.set_autostart(0)
                 return HttpResponseRedirect(request.get_full_path())
             except libvirtError as lib_err:
-                error_messages.append(lib_err.message)
+                error_messages.append(lib_err)
         if 'modify_fixed_address' in request.POST:
             name = request.POST.get('name', '')
             address = request.POST.get('address', '')
@@ -166,9 +166,9 @@ def network(request, compute_id, pool):
                 messages.success(request, _("{} Fixed Address Operation Completed.").format(family.upper()))
                 return HttpResponseRedirect(request.get_full_path())
             except libvirtError as lib_err:
-                error_messages.append(lib_err.message)
+                error_messages.append(lib_err)
             except ValueError as val_err:
-                error_messages.append(val_err.message)
+                error_messages.append(val_err)
         if 'delete_fixed_address' in request.POST:
             ip = request.POST.get('address', '')
             family = request.POST.get('family', 'ipv4')
@@ -184,7 +184,7 @@ def network(request, compute_id, pool):
                 messages.success(request, _("{} DHCP Range is Changed.").format(family.upper()))
                 return HttpResponseRedirect(request.get_full_path())
             except libvirtError as lib_err:
-                error_messages.append(lib_err.message)
+                error_messages.append(lib_err)
         if 'edit_network' in request.POST:
             edit_xml = request.POST.get('edit_xml', '')
             if edit_xml:
@@ -208,8 +208,8 @@ def network(request, compute_id, pool):
                                      _("Stop and start network to activate new config"))
                 else:
                     messages.success(request, _("{} Qos is set").format(qos_dir.capitalize()))
-            except libvirtError as le:
-                messages.error(request, le.message)
+            except libvirtError as lib_err:
+                messages.error(request, lib_err)
             return HttpResponseRedirect(request.get_full_path())
         if 'unset_qos' in request.POST:
             qos_dir = request.POST.get('qos_direction', '')
diff --git a/nwfilters/templates/nwfilter.html b/nwfilters/templates/nwfilter.html
index 18e04c6..fd46691 100644
--- a/nwfilters/templates/nwfilter.html
+++ b/nwfilters/templates/nwfilter.html
@@ -95,9 +95,11 @@
     <div class="col-xs-12 col-sm-12">
         <table class="table table-hover">
             <thead>
-                <th style="width: 45px;">#</th>
-                <th>{% trans "Reference" %}</th>
-                <th>{% trans "Action" %}</th>
+                <tr>
+                    <th style="width: 45px;">#</th>
+                    <th>{% trans "Reference" %}</th>
+                    <th>{% trans "Action" %}</th>
+                </tr>
             </thead>
             <tbody>
             {% for ref in refs %}
@@ -125,6 +127,7 @@
     <div class="col-xs-12 col-sm-12">
         <table class="table table-hover">
             <thead>
+            <tr>
                 <th style="width:45px;">{% trans "Rule" %}</th>
                 <th>{% trans "ActionType" %}</th>
                 <th>{% trans "Direction" %}</th>
@@ -132,6 +135,7 @@
                 <th>{% trans "Statematch" %}</th>
                 <th>{% trans "Directives" %}</th>
                 <th style="width:100px;">{% trans "Action" %}</th>
+            </tr>
             </thead>
             <tbody>
             {% for rule in rules %}
diff --git a/nwfilters/views.py b/nwfilters/views.py
index c8e35e8..3ee9163 100644
--- a/nwfilters/views.py
+++ b/nwfilters/views.py
@@ -59,8 +59,8 @@ def nwfilters(request, compute_id):
                             conn.create_nwfilter(xml)
                             addlogmsg(request.user.username, compute.hostname, msg)
                         except libvirtError as lib_err:
-                            error_messages.append(lib_err.message)
-                            addlogmsg(request.user.username, compute.hostname, lib_err.message)
+                            error_messages.append(lib_err)
+                            addlogmsg(request.user.username, compute.hostname, lib_err)
 
             if 'del_nwfilter' in request.POST:
                 name = request.POST.get('nwfiltername', '')
diff --git a/secrets/views.py b/secrets/views.py
index a21ffd8..d519ad9 100644
--- a/secrets/views.py
+++ b/secrets/views.py
@@ -22,13 +22,13 @@ def secrets(request, compute_id):
     secrets_all = []
     error_messages = []
     compute = get_object_or_404(Compute, pk=compute_id)
-
     try:
         conn = wvmSecrets(compute.hostname,
                           compute.login,
                           compute.password,
                           compute.type)
         secrets = conn.get_secrets()
+
         for uuid in secrets:
             secrt = conn.get_secret(uuid)
             try:
diff --git a/static/js/bootstrap-multiselect.js b/static/js/bootstrap-multiselect.js
index ab1e2d6..e59b175 100644
--- a/static/js/bootstrap-multiselect.js
+++ b/static/js/bootstrap-multiselect.js
@@ -813,7 +813,7 @@
                         }
 
                         $options.push(this.getOptionByValue(value));
-                    }, this))
+                    }, this));
 
                     // Cannot use select or deselect here because it would call updateOptGroups again.
 
@@ -1608,7 +1608,7 @@
          * Update opt groups.
          */
         updateOptGroups: function() {
-            var $groups = $('li.multiselect-group', this.$ul)
+            var $groups = $('li.multiselect-group', this.$ul);
             var selectedClass = this.options.selectedClass;
 
             $groups.each(function() {
diff --git a/static/js/novnc/app/styles/base.css b/static/js/novnc/app/styles/base.css
index 2b31916..21e775e 100755
--- a/static/js/novnc/app/styles/base.css
+++ b/static/js/novnc/app/styles/base.css
@@ -22,7 +22,7 @@
 body {
   margin:0;
   padding:0;
-  font-family: Helvetica;
+  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
   /*Background image with light grey curve.*/
   background-color:#494949;
   background-repeat:no-repeat;
diff --git a/static/js/novnc/vendor/browser-es-module-loader/dist/babel-worker.js b/static/js/novnc/vendor/browser-es-module-loader/dist/babel-worker.js
index 3f9d7e0..9ccd019 100755
--- a/static/js/novnc/vendor/browser-es-module-loader/dist/babel-worker.js
+++ b/static/js/novnc/vendor/browser-es-module-loader/dist/babel-worker.js
@@ -6843,7 +6843,7 @@ var Printer = function () {
 
     var i = void 0;
     for (i = 0; i < str.length && str[i] === " "; i++) {
-      continue;
+
     }if (i === str.length) return;
 
     var cha = str[i];
@@ -8008,9 +8008,9 @@ var ReplaceSupers = function () {
     var superRef = this.superRef || t.identifier("Function");
 
     if (parent.property === id) {
-      return;
+
     } else if (t.isCallExpression(parent, { callee: id })) {
-      return;
+
     } else if (t.isMemberExpression(parent) && !methodNode.static) {
       return t.memberExpression(superRef, t.identifier("prototype"));
     } else {
@@ -14914,7 +14914,7 @@ function evaluate() {
         return existing.value;
       } else {
         deopt(path);
-        return;
+
       }
     } else {
       var item = { resolved: false };
@@ -15762,7 +15762,7 @@ var _loop = function _loop(type) {
 for (var type in virtualTypes) {
   var _ret = _loop(type);
 
-  if (_ret === "continue") continue;
+  if (_ret === "continue")
 }
 module.exports = exports["default"];
 },{"../cache":115,"../index":118,"../scope":137,"./ancestry":119,"./comments":120,"./context":121,"./conversion":122,"./evaluation":123,"./family":124,"./inference":126,"./introspection":129,"./lib/virtual-types":132,"./modification":133,"./removal":134,"./replacement":135,"babel-runtime/core-js/get-iterator":95,"babel-runtime/helpers/classCallCheck":109,"babel-types":151,"debug":279,"invariant":292,"lodash/assign":463}],126:[function(require,module,exports){
@@ -16144,7 +16144,7 @@ function VariableDeclarator() {
   if (id.isIdentifier()) {
     return this.get("init").getTypeAnnotation();
   } else {
-    return;
+
   }
 }
 
@@ -19257,7 +19257,7 @@ function wrapWithStateOrWrapper(oldVisitor, state, wrapper) {
   for (var key in oldVisitor) {
     var _ret = _loop(key);
 
-    if (_ret === "continue") continue;
+    if (_ret === "continue")
   }
 
   return newVisitor;
@@ -30370,27 +30370,27 @@ function range(a, b, str) {
 }
 
 },{}],157:[function(require,module,exports){
-'use strict'
+'use strict';
 
-exports.byteLength = byteLength
-exports.toByteArray = toByteArray
-exports.fromByteArray = fromByteArray
+exports.byteLength = byteLength;
+exports.toByteArray = toByteArray;
+exports.fromByteArray = fromByteArray;
 
-var lookup = []
-var revLookup = []
-var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array
+var lookup = [];
+var revLookup = [];
+var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array;
 
-var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
+var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
 for (var i = 0, len = code.length; i < len; ++i) {
-  lookup[i] = code[i]
+  lookup[i] = code[i];
   revLookup[code.charCodeAt(i)] = i
 }
 
-revLookup['-'.charCodeAt(0)] = 62
-revLookup['_'.charCodeAt(0)] = 63
+revLookup['-'.charCodeAt(0)] = 62;
+revLookup['_'.charCodeAt(0)] = 63;
 
 function placeHoldersCount (b64) {
-  var len = b64.length
+  var len = b64.length;
   if (len % 4 > 0) {
     throw new Error('Invalid string. Length must be a multiple of 4')
   }
@@ -30409,30 +30409,30 @@ function byteLength (b64) {
 }
 
 function toByteArray (b64) {
-  var i, l, tmp, placeHolders, arr
-  var len = b64.length
-  placeHolders = placeHoldersCount(b64)
+  var i, l, tmp, placeHolders, arr;
+  var len = b64.length;
+  placeHolders = placeHoldersCount(b64);
 
-  arr = new Arr((len * 3 / 4) - placeHolders)
+  arr = new Arr((len * 3 / 4) - placeHolders);
 
   // if there are placeholders, only get up to the last complete 4 chars
-  l = placeHolders > 0 ? len - 4 : len
+  l = placeHolders > 0 ? len - 4 : len;
 
-  var L = 0
+  var L = 0;
 
   for (i = 0; i < l; i += 4) {
-    tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]
-    arr[L++] = (tmp >> 16) & 0xFF
-    arr[L++] = (tmp >> 8) & 0xFF
+    tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)];
+    arr[L++] = (tmp >> 16) & 0xFF;
+    arr[L++] = (tmp >> 8) & 0xFF;
     arr[L++] = tmp & 0xFF
   }
 
   if (placeHolders === 2) {
-    tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4)
+    tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4);
     arr[L++] = tmp & 0xFF
   } else if (placeHolders === 1) {
-    tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2)
-    arr[L++] = (tmp >> 8) & 0xFF
+    tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2);
+    arr[L++] = (tmp >> 8) & 0xFF;
     arr[L++] = tmp & 0xFF
   }
 
@@ -30444,22 +30444,22 @@ function tripletToBase64 (num) {
 }
 
 function encodeChunk (uint8, start, end) {
-  var tmp
-  var output = []
+  var tmp;
+  var output = [];
   for (var i = start; i < end; i += 3) {
-    tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
+    tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]);
     output.push(tripletToBase64(tmp))
   }
   return output.join('')
 }
 
 function fromByteArray (uint8) {
-  var tmp
-  var len = uint8.length
-  var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
-  var output = ''
-  var parts = []
-  var maxChunkLength = 16383 // must be multiple of 3
+  var tmp;
+  var len = uint8.length;
+  var extraBytes = len % 3; // if we have 1 byte left, pad 2 bytes
+  var output = '';
+  var parts = [];
+  var maxChunkLength = 16383; // must be multiple of 3
 
   // go through the array every three bytes, we'll deal with trailing stuff later
   for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
@@ -30468,19 +30468,19 @@ function fromByteArray (uint8) {
 
   // pad the end with zeros, but make sure to not forget the extra bytes
   if (extraBytes === 1) {
-    tmp = uint8[len - 1]
-    output += lookup[tmp >> 2]
-    output += lookup[(tmp << 4) & 0x3F]
+    tmp = uint8[len - 1];
+    output += lookup[tmp >> 2];
+    output += lookup[(tmp << 4) & 0x3F];
     output += '=='
   } else if (extraBytes === 2) {
-    tmp = (uint8[len - 2] << 8) + (uint8[len - 1])
-    output += lookup[tmp >> 10]
-    output += lookup[(tmp >> 4) & 0x3F]
-    output += lookup[(tmp << 2) & 0x3F]
+    tmp = (uint8[len - 2] << 8) + (uint8[len - 1]);
+    output += lookup[tmp >> 10];
+    output += lookup[(tmp >> 4) & 0x3F];
+    output += lookup[(tmp << 2) & 0x3F];
     output += '='
   }
 
-  parts.push(output)
+  parts.push(output);
 
   return parts.join('')
 }
@@ -30637,7 +30637,7 @@ function expand(str, isTop) {
   if (isSequence) {
     var x = numeric(n[0]);
     var y = numeric(n[1]);
-    var width = Math.max(n[0].length, n[1].length)
+    var width = Math.max(n[0].length, n[1].length);
     var incr = n.length == 3
       ? Math.abs(numeric(n[2]))
       : 1;
@@ -30700,15 +30700,15 @@ function expand(str, isTop) {
  */
 /* eslint-disable no-proto */
 
-'use strict'
+'use strict';
 
-var base64 = require('base64-js')
-var ieee754 = require('ieee754')
-var isArray = require('isarray')
+var base64 = require('base64-js');
+var ieee754 = require('ieee754');
+var isArray = require('isarray');
 
-exports.Buffer = Buffer
-exports.SlowBuffer = SlowBuffer
-exports.INSPECT_MAX_BYTES = 50
+exports.Buffer = Buffer;
+exports.SlowBuffer = SlowBuffer;
+exports.INSPECT_MAX_BYTES = 50;
 
 /**
  * If `Buffer.TYPED_ARRAY_SUPPORT`:
@@ -30736,17 +30736,17 @@ exports.INSPECT_MAX_BYTES = 50
  */
 Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined
   ? global.TYPED_ARRAY_SUPPORT
-  : typedArraySupport()
+  : typedArraySupport();
 
 /*
  * Export kMaxLength after typed array support is determined.
  */
-exports.kMaxLength = kMaxLength()
+exports.kMaxLength = kMaxLength();
 
 function typedArraySupport () {
   try {
-    var arr = new Uint8Array(1)
-    arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}
+    var arr = new Uint8Array(1);
+    arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }};
     return arr.foo() === 42 && // typed array instances can be augmented
         typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`
         arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`
@@ -30767,7 +30767,7 @@ function createBuffer (that, length) {
   }
   if (Buffer.TYPED_ARRAY_SUPPORT) {
     // Return an augmented `Uint8Array` instance, for best performance
-    that = new Uint8Array(length)
+    that = new Uint8Array(length);
     that.__proto__ = Buffer.prototype
   } else {
     // Fallback: Return an object instance of the Buffer class
@@ -30807,13 +30807,13 @@ function Buffer (arg, encodingOrOffset, length) {
   return from(this, arg, encodingOrOffset, length)
 }
 
-Buffer.poolSize = 8192 // not used by this implementation
+Buffer.poolSize = 8192; // not used by this implementation
 
 // TODO: Legacy, not needed anymore. Remove in next major version.
 Buffer._augment = function (arr) {
-  arr.__proto__ = Buffer.prototype
+  arr.__proto__ = Buffer.prototype;
   return arr
-}
+};
 
 function from (that, value, encodingOrOffset, length) {
   if (typeof value === 'number') {
@@ -30841,11 +30841,11 @@ function from (that, value, encodingOrOffset, length) {
  **/
 Buffer.from = function (value, encodingOrOffset, length) {
   return from(null, value, encodingOrOffset, length)
-}
+};
 
 if (Buffer.TYPED_ARRAY_SUPPORT) {
-  Buffer.prototype.__proto__ = Uint8Array.prototype
-  Buffer.__proto__ = Uint8Array
+  Buffer.prototype.__proto__ = Uint8Array.prototype;
+  Buffer.__proto__ = Uint8Array;
   if (typeof Symbol !== 'undefined' && Symbol.species &&
       Buffer[Symbol.species] === Buffer) {
     // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
@@ -30865,7 +30865,7 @@ function assertSize (size) {
 }
 
 function alloc (that, size, fill, encoding) {
-  assertSize(size)
+  assertSize(size);
   if (size <= 0) {
     return createBuffer(that, size)
   }
@@ -30886,11 +30886,11 @@ function alloc (that, size, fill, encoding) {
  **/
 Buffer.alloc = function (size, fill, encoding) {
   return alloc(null, size, fill, encoding)
-}
+};
 
 function allocUnsafe (that, size) {
-  assertSize(size)
-  that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)
+  assertSize(size);
+  that = createBuffer(that, size < 0 ? 0 : checked(size) | 0);
   if (!Buffer.TYPED_ARRAY_SUPPORT) {
     for (var i = 0; i < size; ++i) {
       that[i] = 0
@@ -30904,13 +30904,13 @@ function allocUnsafe (that, size) {
  * */
 Buffer.allocUnsafe = function (size) {
   return allocUnsafe(null, size)
-}
+};
 /**
  * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.
  */
 Buffer.allocUnsafeSlow = function (size) {
   return allocUnsafe(null, size)
-}
+};
 
 function fromString (that, string, encoding) {
   if (typeof encoding !== 'string' || encoding === '') {
@@ -30921,10 +30921,10 @@ function fromString (that, string, encoding) {
     throw new TypeError('"encoding" must be a valid string encoding')
   }
 
-  var length = byteLength(string, encoding) | 0
-  that = createBuffer(that, length)
+  var length = byteLength(string, encoding) | 0;
+  that = createBuffer(that, length);
 
-  var actual = that.write(string, encoding)
+  var actual = that.write(string, encoding);
 
   if (actual !== length) {
     // Writing a hex string, for example, that contains invalid characters will
@@ -30937,8 +30937,8 @@ function fromString (that, string, encoding) {
 }
 
 function fromArrayLike (that, array) {
-  var length = array.length < 0 ? 0 : checked(array.length) | 0
-  that = createBuffer(that, length)
+  var length = array.length < 0 ? 0 : checked(array.length) | 0;
+  that = createBuffer(that, length);
   for (var i = 0; i < length; i += 1) {
     that[i] = array[i] & 255
   }
@@ -30946,7 +30946,7 @@ function fromArrayLike (that, array) {
 }
 
 function fromArrayBuffer (that, array, byteOffset, length) {
-  array.byteLength // this throws if `array` is not a valid ArrayBuffer
+  array.byteLength; // this throws if `array` is not a valid ArrayBuffer
 
   if (byteOffset < 0 || array.byteLength < byteOffset) {
     throw new RangeError('\'offset\' is out of bounds')
@@ -30966,7 +30966,7 @@ function fromArrayBuffer (that, array, byteOffset, length) {
 
   if (Buffer.TYPED_ARRAY_SUPPORT) {
     // Return an augmented `Uint8Array` instance, for best performance
-    that = array
+    that = array;
     that.__proto__ = Buffer.prototype
   } else {
     // Fallback: Return an object instance of the Buffer class
@@ -30977,14 +30977,14 @@ function fromArrayBuffer (that, array, byteOffset, length) {
 
 function fromObject (that, obj) {
   if (Buffer.isBuffer(obj)) {
-    var len = checked(obj.length) | 0
-    that = createBuffer(that, len)
+    var len = checked(obj.length) | 0;
+    that = createBuffer(that, len);
 
     if (that.length === 0) {
       return that
     }
 
-    obj.copy(that, 0, 0, len)
+    obj.copy(that, 0, 0, len);
     return that
   }
 
@@ -31024,30 +31024,30 @@ function SlowBuffer (length) {
 
 Buffer.isBuffer = function isBuffer (b) {
   return !!(b != null && b._isBuffer)
-}
+};
 
 Buffer.compare = function compare (a, b) {
   if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
     throw new TypeError('Arguments must be Buffers')
   }
 
-  if (a === b) return 0
+  if (a === b) return 0;
 
-  var x = a.length
-  var y = b.length
+  var x = a.length;
+  var y = b.length;
 
   for (var i = 0, len = Math.min(x, y); i < len; ++i) {
     if (a[i] !== b[i]) {
-      x = a[i]
-      y = b[i]
+      x = a[i];
+      y = b[i];
       break
     }
   }
 
-  if (x < y) return -1
-  if (y < x) return 1
+  if (x < y) return -1;
+  if (y < x) return 1;
   return 0
-}
+};
 
 Buffer.isEncoding = function isEncoding (encoding) {
   switch (String(encoding).toLowerCase()) {
@@ -31062,11 +31062,11 @@ Buffer.isEncoding = function isEncoding (encoding) {
     case 'ucs-2':
     case 'utf16le':
     case 'utf-16le':
-      return true
+      return true;
     default:
       return false
   }
-}
+};
 
 Buffer.concat = function concat (list, length) {
   if (!isArray(list)) {
@@ -31077,26 +31077,26 @@ Buffer.concat = function concat (list, length) {
     return Buffer.alloc(0)
   }
 
-  var i
+  var i;
   if (length === undefined) {
-    length = 0
+    length = 0;
     for (i = 0; i < list.length; ++i) {
       length += list[i].length
     }
   }
 
-  var buffer = Buffer.allocUnsafe(length)
-  var pos = 0
+  var buffer = Buffer.allocUnsafe(length);
+  var pos = 0;
   for (i = 0; i < list.length; ++i) {
-    var buf = list[i]
+    var buf = list[i];
     if (!Buffer.isBuffer(buf)) {
       throw new TypeError('"list" argument must be an Array of Buffers')
     }
-    buf.copy(buffer, pos)
+    buf.copy(buffer, pos);
     pos += buf.length
   }
   return buffer
-}
+};
 
 function byteLength (string, encoding) {
   if (Buffer.isBuffer(string)) {
@@ -31110,41 +31110,41 @@ function byteLength (string, encoding) {
     string = '' + string
   }
 
-  var len = string.length
-  if (len === 0) return 0
+  var len = string.length;
+  if (len === 0) return 0;
 
   // Use a for loop to avoid recursion
-  var loweredCase = false
+  var loweredCase = false;
   for (;;) {
     switch (encoding) {
       case 'ascii':
       case 'latin1':
       case 'binary':
-        return len
+        return len;
       case 'utf8':
       case 'utf-8':
       case undefined:
-        return utf8ToBytes(string).length
+        return utf8ToBytes(string).length;
       case 'ucs2':
       case 'ucs-2':
       case 'utf16le':
       case 'utf-16le':
-        return len * 2
+        return len * 2;
       case 'hex':
-        return len >>> 1
+        return len >>> 1;
       case 'base64':
-        return base64ToBytes(string).length
+        return base64ToBytes(string).length;
       default:
-        if (loweredCase) return utf8ToBytes(string).length // assume utf8
-        encoding = ('' + encoding).toLowerCase()
+        if (loweredCase) return utf8ToBytes(string).length; // assume utf8
+        encoding = ('' + encoding).toLowerCase();
         loweredCase = true
     }
   }
 }
-Buffer.byteLength = byteLength
+Buffer.byteLength = byteLength;
 
 function slowToString (encoding, start, end) {
-  var loweredCase = false
+  var loweredCase = false;
 
   // No need to verify that "this.length <= MAX_UINT32" since it's a read-only
   // property of a typed array.
@@ -31171,43 +31171,43 @@ function slowToString (encoding, start, end) {
   }
 
   // Force coersion to uint32. This will also coerce falsey/NaN values to 0.
-  end >>>= 0
-  start >>>= 0
+  end >>>= 0;
+  start >>>= 0;
 
   if (end <= start) {
     return ''
   }
 
-  if (!encoding) encoding = 'utf8'
+  if (!encoding) encoding = 'utf8';
 
   while (true) {
     switch (encoding) {
       case 'hex':
-        return hexSlice(this, start, end)
+        return hexSlice(this, start, end);
 
       case 'utf8':
       case 'utf-8':
-        return utf8Slice(this, start, end)
+        return utf8Slice(this, start, end);
 
       case 'ascii':
-        return asciiSlice(this, start, end)
+        return asciiSlice(this, start, end);
 
       case 'latin1':
       case 'binary':
-        return latin1Slice(this, start, end)
+        return latin1Slice(this, start, end);
 
       case 'base64':
-        return base64Slice(this, start, end)
+        return base64Slice(this, start, end);
 
       case 'ucs2':
       case 'ucs-2':
       case 'utf16le':
       case 'utf-16le':
-        return utf16leSlice(this, start, end)
+        return utf16leSlice(this, start, end);
 
       default:
-        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
-        encoding = (encoding + '').toLowerCase()
+        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding);
+        encoding = (encoding + '').toLowerCase();
         loweredCase = true
     }
   }
@@ -31215,16 +31215,16 @@ function slowToString (encoding, start, end) {
 
 // The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect
 // Buffer instances.
-Buffer.prototype._isBuffer = true
+Buffer.prototype._isBuffer = true;
 
 function swap (b, n, m) {
-  var i = b[n]
-  b[n] = b[m]
+  var i = b[n];
+  b[n] = b[m];
   b[m] = i
 }
 
 Buffer.prototype.swap16 = function swap16 () {
-  var len = this.length
+  var len = this.length;
   if (len % 2 !== 0) {
     throw new RangeError('Buffer size must be a multiple of 16-bits')
   }
@@ -31232,56 +31232,56 @@ Buffer.prototype.swap16 = function swap16 () {
     swap(this, i, i + 1)
   }
   return this
-}
+};
 
 Buffer.prototype.swap32 = function swap32 () {
-  var len = this.length
+  var len = this.length;
   if (len % 4 !== 0) {
     throw new RangeError('Buffer size must be a multiple of 32-bits')
   }
   for (var i = 0; i < len; i += 4) {
-    swap(this, i, i + 3)
+    swap(this, i, i + 3);
     swap(this, i + 1, i + 2)
   }
   return this
-}
+};
 
 Buffer.prototype.swap64 = function swap64 () {
-  var len = this.length
+  var len = this.length;
   if (len % 8 !== 0) {
     throw new RangeError('Buffer size must be a multiple of 64-bits')
   }
   for (var i = 0; i < len; i += 8) {
-    swap(this, i, i + 7)
-    swap(this, i + 1, i + 6)
-    swap(this, i + 2, i + 5)
+    swap(this, i, i + 7);
+    swap(this, i + 1, i + 6);
+    swap(this, i + 2, i + 5);
     swap(this, i + 3, i + 4)
   }
   return this
-}
+};
 
 Buffer.prototype.toString = function toString () {
-  var length = this.length | 0
-  if (length === 0) return ''
-  if (arguments.length === 0) return utf8Slice(this, 0, length)
+  var length = this.length | 0;
+  if (length === 0) return '';
+  if (arguments.length === 0) return utf8Slice(this, 0, length);
   return slowToString.apply(this, arguments)
-}
+};
 
 Buffer.prototype.equals = function equals (b) {
-  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
-  if (this === b) return true
+  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer');
+  if (this === b) return true;
   return Buffer.compare(this, b) === 0
-}
+};
 
 Buffer.prototype.inspect = function inspect () {
-  var str = ''
-  var max = exports.INSPECT_MAX_BYTES
+  var str = '';
+  var max = exports.INSPECT_MAX_BYTES;
   if (this.length > 0) {
-    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')
+    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ');
     if (this.length > max) str += ' ... '
   }
   return '<Buffer ' + str + '>'
-}
+};
 
 Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {
   if (!Buffer.isBuffer(target)) {
@@ -31315,32 +31315,32 @@ Buffer.prototype.compare = function compare (target, start, end, thisStart, this
     return 1
   }
 
-  start >>>= 0
-  end >>>= 0
-  thisStart >>>= 0
-  thisEnd >>>= 0
+  start >>>= 0;
+  end >>>= 0;
+  thisStart >>>= 0;
+  thisEnd >>>= 0;
 
-  if (this === target) return 0
+  if (this === target) return 0;
 
-  var x = thisEnd - thisStart
-  var y = end - start
-  var len = Math.min(x, y)
+  var x = thisEnd - thisStart;
+  var y = end - start;
+  var len = Math.min(x, y);
 
-  var thisCopy = this.slice(thisStart, thisEnd)
-  var targetCopy = target.slice(start, end)
+  var thisCopy = this.slice(thisStart, thisEnd);
+  var targetCopy = target.slice(start, end);
 
   for (var i = 0; i < len; ++i) {
     if (thisCopy[i] !== targetCopy[i]) {
-      x = thisCopy[i]
-      y = targetCopy[i]
+      x = thisCopy[i];
+      y = targetCopy[i];
       break
     }
   }
 
-  if (x < y) return -1
-  if (y < x) return 1
+  if (x < y) return -1;
+  if (y < x) return 1;
   return 0
-}
+};
 
 // Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
 // OR the last index of `val` in `buffer` at offset <= `byteOffset`.
@@ -31353,30 +31353,30 @@ Buffer.prototype.compare = function compare (target, start, end, thisStart, this
 // - dir - true for indexOf, false for lastIndexOf
 function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
   // Empty buffer means no match
-  if (buffer.length === 0) return -1
+  if (buffer.length === 0) return -1;
 
   // Normalize byteOffset
   if (typeof byteOffset === 'string') {
-    encoding = byteOffset
+    encoding = byteOffset;
     byteOffset = 0
   } else if (byteOffset > 0x7fffffff) {
     byteOffset = 0x7fffffff
   } else if (byteOffset < -0x80000000) {
     byteOffset = -0x80000000
   }
-  byteOffset = +byteOffset  // Coerce to Number.
+  byteOffset = +byteOffset;  // Coerce to Number.
   if (isNaN(byteOffset)) {
     // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer
     byteOffset = dir ? 0 : (buffer.length - 1)
   }
 
   // Normalize byteOffset: negative offsets start from the end of the buffer
-  if (byteOffset < 0) byteOffset = buffer.length + byteOffset
+  if (byteOffset < 0) byteOffset = buffer.length + byteOffset;
   if (byteOffset >= buffer.length) {
-    if (dir) return -1
+    if (dir) return -1;
     else byteOffset = buffer.length - 1
   } else if (byteOffset < 0) {
-    if (dir) byteOffset = 0
+    if (dir) byteOffset = 0;
     else return -1
   }
 
@@ -31393,7 +31393,7 @@ function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
     }
     return arrayIndexOf(buffer, val, byteOffset, encoding, dir)
   } else if (typeof val === 'number') {
-    val = val & 0xFF // Search for a byte value [0-255]
+    val = val & 0xFF; // Search for a byte value [0-255]
     if (Buffer.TYPED_ARRAY_SUPPORT &&
         typeof Uint8Array.prototype.indexOf === 'function') {
       if (dir) {
@@ -31409,20 +31409,20 @@ function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
 }
 
 function arrayIndexOf (arr, val, byteOffset, encoding, dir) {
-  var indexSize = 1
-  var arrLength = arr.length
-  var valLength = val.length
+  var indexSize = 1;
+  var arrLength = arr.length;
+  var valLength = val.length;
 
   if (encoding !== undefined) {
-    encoding = String(encoding).toLowerCase()
+    encoding = String(encoding).toLowerCase();
     if (encoding === 'ucs2' || encoding === 'ucs-2' ||
         encoding === 'utf16le' || encoding === 'utf-16le') {
       if (arr.length < 2 || val.length < 2) {
         return -1
       }
-      indexSize = 2
-      arrLength /= 2
-      valLength /= 2
+      indexSize = 2;
+      arrLength /= 2;
+      valLength /= 2;
       byteOffset /= 2
     }
   }
@@ -31435,25 +31435,25 @@ function arrayIndexOf (arr, val, byteOffset, encoding, dir) {
     }
   }
 
-  var i
+  var i;
   if (dir) {
-    var foundIndex = -1
+    var foundIndex = -1;
     for (i = byteOffset; i < arrLength; i++) {
       if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
-        if (foundIndex === -1) foundIndex = i
+        if (foundIndex === -1) foundIndex = i;
         if (i - foundIndex + 1 === valLength) return foundIndex * indexSize
       } else {
-        if (foundIndex !== -1) i -= i - foundIndex
+        if (foundIndex !== -1) i -= i - foundIndex;
         foundIndex = -1
       }
     }
   } else {
-    if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength
+    if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength;
     for (i = byteOffset; i >= 0; i--) {
-      var found = true
+      var found = true;
       for (var j = 0; j < valLength; j++) {
         if (read(arr, i + j) !== read(val, j)) {
-          found = false
+          found = false;
           break
         }
       }
@@ -31466,38 +31466,38 @@ function arrayIndexOf (arr, val, byteOffset, encoding, dir) {
 
 Buffer.prototype.includes = function includes (val, byteOffset, encoding) {
   return this.indexOf(val, byteOffset, encoding) !== -1
-}
+};
 
 Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {
   return bidirectionalIndexOf(this, val, byteOffset, encoding, true)
-}
+};
 
 Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {
   return bidirectionalIndexOf(this, val, byteOffset, encoding, false)
-}
+};
 
 function hexWrite (buf, string, offset, length) {
-  offset = Number(offset) || 0
-  var remaining = buf.length - offset
+  offset = Number(offset) || 0;
+  var remaining = buf.length - offset;
   if (!length) {
     length = remaining
   } else {
-    length = Number(length)
+    length = Number(length);
     if (length > remaining) {
       length = remaining
     }
   }
 
   // must be an even number of digits
-  var strLen = string.length
-  if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')
+  var strLen = string.length;
+  if (strLen % 2 !== 0) throw new TypeError('Invalid hex string');
 
   if (length > strLen / 2) {
     length = strLen / 2
   }
   for (var i = 0; i < length; ++i) {
-    var parsed = parseInt(string.substr(i * 2, 2), 16)
-    if (isNaN(parsed)) return i
+    var parsed = parseInt(string.substr(i * 2, 2), 16);
+    if (isNaN(parsed)) return i;
     buf[offset + i] = parsed
   }
   return i
@@ -31526,22 +31526,22 @@ function ucs2Write (buf, string, offset, length) {
 Buffer.prototype.write = function write (string, offset, length, encoding) {
   // Buffer#write(string)
   if (offset === undefined) {
-    encoding = 'utf8'
-    length = this.length
+    encoding = 'utf8';
+    length = this.length;
     offset = 0
   // Buffer#write(string, encoding)
   } else if (length === undefined && typeof offset === 'string') {
-    encoding = offset
-    length = this.length
+    encoding = offset;
+    length = this.length;
     offset = 0
   // Buffer#write(string, offset[, length][, encoding])
   } else if (isFinite(offset)) {
-    offset = offset | 0
+    offset = offset | 0;
     if (isFinite(length)) {
-      length = length | 0
+      length = length | 0;
       if (encoding === undefined) encoding = 'utf8'
     } else {
-      encoding = length
+      encoding = length;
       length = undefined
     }
   // legacy write(string, encoding, offset, length) - remove in v0.13
@@ -31551,56 +31551,56 @@ Buffer.prototype.write = function write (string, offset, length, encoding) {
     )
   }
 
-  var remaining = this.length - offset
-  if (length === undefined || length > remaining) length = remaining
+  var remaining = this.length - offset;
+  if (length === undefined || length > remaining) length = remaining;
 
   if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
     throw new RangeError('Attempt to write outside buffer bounds')
   }
 
-  if (!encoding) encoding = 'utf8'
+  if (!encoding) encoding = 'utf8';
 
-  var loweredCase = false
+  var loweredCase = false;
   for (;;) {
     switch (encoding) {
       case 'hex':
-        return hexWrite(this, string, offset, length)
+        return hexWrite(this, string, offset, length);
 
       case 'utf8':
       case 'utf-8':
-        return utf8Write(this, string, offset, length)
+        return utf8Write(this, string, offset, length);
 
       case 'ascii':
-        return asciiWrite(this, string, offset, length)
+        return asciiWrite(this, string, offset, length);
 
       case 'latin1':
       case 'binary':
-        return latin1Write(this, string, offset, length)
+        return latin1Write(this, string, offset, length);
 
       case 'base64':
         // Warning: maxLength not taken into account in base64Write
-        return base64Write(this, string, offset, length)
+        return base64Write(this, string, offset, length);
 
       case 'ucs2':
       case 'ucs-2':
       case 'utf16le':
       case 'utf-16le':
-        return ucs2Write(this, string, offset, length)
+        return ucs2Write(this, string, offset, length);
 
       default:
-        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
-        encoding = ('' + encoding).toLowerCase()
+        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding);
+        encoding = ('' + encoding).toLowerCase();
         loweredCase = true
     }
   }
-}
+};
 
 Buffer.prototype.toJSON = function toJSON () {
   return {
     type: 'Buffer',
     data: Array.prototype.slice.call(this._arr || this, 0)
   }
-}
+};
 
 function base64Slice (buf, start, end) {
   if (start === 0 && end === buf.length) {
@@ -31611,52 +31611,52 @@ function base64Slice (buf, start, end) {
 }
 
 function utf8Slice (buf, start, end) {
-  end = Math.min(buf.length, end)
-  var res = []
+  end = Math.min(buf.length, end);
+  var res = [];
 
-  var i = start
+  var i = start;
   while (i < end) {
-    var firstByte = buf[i]
-    var codePoint = null
+    var firstByte = buf[i];
+    var codePoint = null;
     var bytesPerSequence = (firstByte > 0xEF) ? 4
       : (firstByte > 0xDF) ? 3
       : (firstByte > 0xBF) ? 2
-      : 1
+      : 1;
 
     if (i + bytesPerSequence <= end) {
-      var secondByte, thirdByte, fourthByte, tempCodePoint
+      var secondByte, thirdByte, fourthByte, tempCodePoint;
 
       switch (bytesPerSequence) {
         case 1:
           if (firstByte < 0x80) {
             codePoint = firstByte
           }
-          break
+          break;
         case 2:
-          secondByte = buf[i + 1]
+          secondByte = buf[i + 1];
           if ((secondByte & 0xC0) === 0x80) {
-            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
+            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F);
             if (tempCodePoint > 0x7F) {
               codePoint = tempCodePoint
             }
           }
-          break
+          break;
         case 3:
-          secondByte = buf[i + 1]
-          thirdByte = buf[i + 2]
+          secondByte = buf[i + 1];
+          thirdByte = buf[i + 2];
           if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
-            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
+            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F);
             if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
               codePoint = tempCodePoint
             }
           }
-          break
+          break;
         case 4:
-          secondByte = buf[i + 1]
-          thirdByte = buf[i + 2]
-          fourthByte = buf[i + 3]
+          secondByte = buf[i + 1];
+          thirdByte = buf[i + 2];
+          fourthByte = buf[i + 3];
           if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
-            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
+            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F);
             if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
               codePoint = tempCodePoint
             }
@@ -31667,16 +31667,16 @@ function utf8Slice (buf, start, end) {
     if (codePoint === null) {
       // we did not generate a valid codePoint so insert a
       // replacement char (U+FFFD) and advance only 1 byte
-      codePoint = 0xFFFD
+      codePoint = 0xFFFD;
       bytesPerSequence = 1
     } else if (codePoint > 0xFFFF) {
       // encode to utf16 (surrogate pair dance)
-      codePoint -= 0x10000
-      res.push(codePoint >>> 10 & 0x3FF | 0xD800)
+      codePoint -= 0x10000;
+      res.push(codePoint >>> 10 & 0x3FF | 0xD800);
       codePoint = 0xDC00 | codePoint & 0x3FF
     }
 
-    res.push(codePoint)
+    res.push(codePoint);
     i += bytesPerSequence
   }
 
@@ -31686,17 +31686,17 @@ function utf8Slice (buf, start, end) {
 // Based on http://stackoverflow.com/a/22747272/680742, the browser with
 // the lowest limit is Chrome, with 0x10000 args.
 // We go 1 magnitude less, for safety
-var MAX_ARGUMENTS_LENGTH = 0x1000
+var MAX_ARGUMENTS_LENGTH = 0x1000;
 
 function decodeCodePointsArray (codePoints) {
-  var len = codePoints.length
+  var len = codePoints.length;
   if (len <= MAX_ARGUMENTS_LENGTH) {
     return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
   }
 
   // Decode in chunks to avoid "call stack size exceeded".
-  var res = ''
-  var i = 0
+  var res = '';
+  var i = 0;
   while (i < len) {
     res += String.fromCharCode.apply(
       String,
@@ -31707,8 +31707,8 @@ function decodeCodePointsArray (codePoints) {
 }
 
 function asciiSlice (buf, start, end) {
-  var ret = ''
-  end = Math.min(buf.length, end)
+  var ret = '';
+  end = Math.min(buf.length, end);
 
   for (var i = start; i < end; ++i) {
     ret += String.fromCharCode(buf[i] & 0x7F)
@@ -31717,8 +31717,8 @@ function asciiSlice (buf, start, end) {
 }
 
 function latin1Slice (buf, start, end) {
-  var ret = ''
-  end = Math.min(buf.length, end)
+  var ret = '';
+  end = Math.min(buf.length, end);
 
   for (var i = start; i < end; ++i) {
     ret += String.fromCharCode(buf[i])
@@ -31727,12 +31727,12 @@ function latin1Slice (buf, start, end) {
 }
 
 function hexSlice (buf, start, end) {
-  var len = buf.length
+  var len = buf.length;
 
-  if (!start || start < 0) start = 0
-  if (!end || end < 0 || end > len) end = len
+  if (!start || start < 0) start = 0;
+  if (!end || end < 0 || end > len) end = len;
 
-  var out = ''
+  var out = '';
   for (var i = start; i < end; ++i) {
     out += toHex(buf[i])
   }
@@ -31740,8 +31740,8 @@ function hexSlice (buf, start, end) {
 }
 
 function utf16leSlice (buf, start, end) {
-  var bytes = buf.slice(start, end)
-  var res = ''
+  var bytes = buf.slice(start, end);
+  var res = '';
   for (var i = 0; i < bytes.length; i += 2) {
     res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)
   }
@@ -31749,260 +31749,260 @@ function utf16leSlice (buf, start, end) {
 }
 
 Buffer.prototype.slice = function slice (start, end) {
-  var len = this.length
-  start = ~~start
-  end = end === undefined ? len : ~~end
+  var len = this.length;
+  start = ~~start;
+  end = end === undefined ? len : ~~end;
 
   if (start < 0) {
-    start += len
+    start += len;
     if (start < 0) start = 0
   } else if (start > len) {
     start = len
   }
 
   if (end < 0) {
-    end += len
+    end += len;
     if (end < 0) end = 0
   } else if (end > len) {
     end = len
   }
 
-  if (end < start) end = start
+  if (end < start) end = start;
 
-  var newBuf
+  var newBuf;
   if (Buffer.TYPED_ARRAY_SUPPORT) {
-    newBuf = this.subarray(start, end)
+    newBuf = this.subarray(start, end);
     newBuf.__proto__ = Buffer.prototype
   } else {
-    var sliceLen = end - start
-    newBuf = new Buffer(sliceLen, undefined)
+    var sliceLen = end - start;
+    newBuf = new Buffer(sliceLen, undefined);
     for (var i = 0; i < sliceLen; ++i) {
       newBuf[i] = this[i + start]
     }
   }
 
   return newBuf
-}
+};
 
 /*
  * Need to make sure that buffer isn't trying to write out of bounds.
  */
 function checkOffset (offset, ext, length) {
-  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
+  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint');
   if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
 }
 
 Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
-  offset = offset | 0
-  byteLength = byteLength | 0
-  if (!noAssert) checkOffset(offset, byteLength, this.length)
+  offset = offset | 0;
+  byteLength = byteLength | 0;
+  if (!noAssert) checkOffset(offset, byteLength, this.length);
 
-  var val = this[offset]
-  var mul = 1
-  var i = 0
+  var val = this[offset];
+  var mul = 1;
+  var i = 0;
   while (++i < byteLength && (mul *= 0x100)) {
     val += this[offset + i] * mul
   }
 
   return val
-}
+};
 
 Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
-  offset = offset | 0
-  byteLength = byteLength | 0
+  offset = offset | 0;
+  byteLength = byteLength | 0;
   if (!noAssert) {
     checkOffset(offset, byteLength, this.length)
   }
 
-  var val = this[offset + --byteLength]
-  var mul = 1
+  var val = this[offset + --byteLength];
+  var mul = 1;
   while (byteLength > 0 && (mul *= 0x100)) {
     val += this[offset + --byteLength] * mul
   }
 
   return val
-}
+};
 
 Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
-  if (!noAssert) checkOffset(offset, 1, this.length)
+  if (!noAssert) checkOffset(offset, 1, this.length);
   return this[offset]
-}
+};
 
 Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
-  if (!noAssert) checkOffset(offset, 2, this.length)
+  if (!noAssert) checkOffset(offset, 2, this.length);
   return this[offset] | (this[offset + 1] << 8)
-}
+};
 
 Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
-  if (!noAssert) checkOffset(offset, 2, this.length)
+  if (!noAssert) checkOffset(offset, 2, this.length);
   return (this[offset] << 8) | this[offset + 1]
-}
+};
 
 Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
-  if (!noAssert) checkOffset(offset, 4, this.length)
+  if (!noAssert) checkOffset(offset, 4, this.length);
 
   return ((this[offset]) |
       (this[offset + 1] << 8) |
       (this[offset + 2] << 16)) +
       (this[offset + 3] * 0x1000000)
-}
+};
 
 Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
-  if (!noAssert) checkOffset(offset, 4, this.length)
+  if (!noAssert) checkOffset(offset, 4, this.length);
 
   return (this[offset] * 0x1000000) +
     ((this[offset + 1] << 16) |
     (this[offset + 2] << 8) |
     this[offset + 3])
-}
+};
 
 Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
-  offset = offset | 0
-  byteLength = byteLength | 0
-  if (!noAssert) checkOffset(offset, byteLength, this.length)
+  offset = offset | 0;
+  byteLength = byteLength | 0;
+  if (!noAssert) checkOffset(offset, byteLength, this.length);
 
-  var val = this[offset]
-  var mul = 1
-  var i = 0
+  var val = this[offset];
+  var mul = 1;
+  var i = 0;
   while (++i < byteLength && (mul *= 0x100)) {
     val += this[offset + i] * mul
   }
-  mul *= 0x80
+  mul *= 0x80;
 
-  if (val >= mul) val -= Math.pow(2, 8 * byteLength)
+  if (val >= mul) val -= Math.pow(2, 8 * byteLength);
 
   return val
-}
+};
 
 Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
-  offset = offset | 0
-  byteLength = byteLength | 0
-  if (!noAssert) checkOffset(offset, byteLength, this.length)
+  offset = offset | 0;
+  byteLength = byteLength | 0;
+  if (!noAssert) checkOffset(offset, byteLength, this.length);
 
-  var i = byteLength
-  var mul = 1
-  var val = this[offset + --i]
+  var i = byteLength;
+  var mul = 1;
+  var val = this[offset + --i];
   while (i > 0 && (mul *= 0x100)) {
     val += this[offset + --i] * mul
   }
-  mul *= 0x80
+  mul *= 0x80;
 
-  if (val >= mul) val -= Math.pow(2, 8 * byteLength)
+  if (val >= mul) val -= Math.pow(2, 8 * byteLength);
 
   return val
-}
+};
 
 Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
-  if (!noAssert) checkOffset(offset, 1, this.length)
-  if (!(this[offset] & 0x80)) return (this[offset])
+  if (!noAssert) checkOffset(offset, 1, this.length);
+  if (!(this[offset] & 0x80)) return (this[offset]);
   return ((0xff - this[offset] + 1) * -1)
-}
+};
 
 Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
-  if (!noAssert) checkOffset(offset, 2, this.length)
-  var val = this[offset] | (this[offset + 1] << 8)
+  if (!noAssert) checkOffset(offset, 2, this.length);
+  var val = this[offset] | (this[offset + 1] << 8);
   return (val & 0x8000) ? val | 0xFFFF0000 : val
-}
+};
 
 Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
-  if (!noAssert) checkOffset(offset, 2, this.length)
-  var val = this[offset + 1] | (this[offset] << 8)
+  if (!noAssert) checkOffset(offset, 2, this.length);
+  var val = this[offset + 1] | (this[offset] << 8);
   return (val & 0x8000) ? val | 0xFFFF0000 : val
-}
+};
 
 Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
-  if (!noAssert) checkOffset(offset, 4, this.length)
+  if (!noAssert) checkOffset(offset, 4, this.length);
 
   return (this[offset]) |
     (this[offset + 1] << 8) |
     (this[offset + 2] << 16) |
     (this[offset + 3] << 24)
-}
+};
 
 Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
-  if (!noAssert) checkOffset(offset, 4, this.length)
+  if (!noAssert) checkOffset(offset, 4, this.length);
 
   return (this[offset] << 24) |
     (this[offset + 1] << 16) |
     (this[offset + 2] << 8) |
     (this[offset + 3])
-}
+};
 
 Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
-  if (!noAssert) checkOffset(offset, 4, this.length)
+  if (!noAssert) checkOffset(offset, 4, this.length);
   return ieee754.read(this, offset, true, 23, 4)
-}
+};
 
 Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
-  if (!noAssert) checkOffset(offset, 4, this.length)
+  if (!noAssert) checkOffset(offset, 4, this.length);
   return ieee754.read(this, offset, false, 23, 4)
-}
+};
 
 Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
-  if (!noAssert) checkOffset(offset, 8, this.length)
+  if (!noAssert) checkOffset(offset, 8, this.length);
   return ieee754.read(this, offset, true, 52, 8)
-}
+};
 
 Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
-  if (!noAssert) checkOffset(offset, 8, this.length)
+  if (!noAssert) checkOffset(offset, 8, this.length);
   return ieee754.read(this, offset, false, 52, 8)
-}
+};
 
 function checkInt (buf, value, offset, ext, max, min) {
-  if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance')
-  if (value > max || value < min) throw new RangeError('"value" argument is out of bounds')
+  if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance');
+  if (value > max || value < min) throw new RangeError('"value" argument is out of bounds');
   if (offset + ext > buf.length) throw new RangeError('Index out of range')
 }
 
 Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
-  value = +value
-  offset = offset | 0
-  byteLength = byteLength | 0
+  value = +value;
+  offset = offset | 0;
+  byteLength = byteLength | 0;
   if (!noAssert) {
-    var maxBytes = Math.pow(2, 8 * byteLength) - 1
+    var maxBytes = Math.pow(2, 8 * byteLength) - 1;
     checkInt(this, value, offset, byteLength, maxBytes, 0)
   }
 
-  var mul = 1
-  var i = 0
-  this[offset] = value & 0xFF
+  var mul = 1;
+  var i = 0;
+  this[offset] = value & 0xFF;
   while (++i < byteLength && (mul *= 0x100)) {
     this[offset + i] = (value / mul) & 0xFF
   }
 
   return offset + byteLength
-}
+};
 
 Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
-  value = +value
-  offset = offset | 0
-  byteLength = byteLength | 0
+  value = +value;
+  offset = offset | 0;
+  byteLength = byteLength | 0;
   if (!noAssert) {
-    var maxBytes = Math.pow(2, 8 * byteLength) - 1
+    var maxBytes = Math.pow(2, 8 * byteLength) - 1;
     checkInt(this, value, offset, byteLength, maxBytes, 0)
   }
 
-  var i = byteLength - 1
-  var mul = 1
-  this[offset + i] = value & 0xFF
+  var i = byteLength - 1;
+  var mul = 1;
+  this[offset + i] = value & 0xFF;
   while (--i >= 0 && (mul *= 0x100)) {
     this[offset + i] = (value / mul) & 0xFF
   }
 
   return offset + byteLength
-}
+};
 
 Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
-  value = +value
-  offset = offset | 0
-  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
-  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
-  this[offset] = (value & 0xff)
+  value = +value;
+  offset = offset | 0;
+  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0);
+  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value);
+  this[offset] = (value & 0xff);
   return offset + 1
-}
+};
 
 function objectWriteUInt16 (buf, value, offset, littleEndian) {
-  if (value < 0) value = 0xffff + value + 1
+  if (value < 0) value = 0xffff + value + 1;
   for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {
     buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
       (littleEndian ? i : 1 - i) * 8
@@ -32010,81 +32010,81 @@ function objectWriteUInt16 (buf, value, offset, littleEndian) {
 }
 
 Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
-  value = +value
-  offset = offset | 0
-  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
+  value = +value;
+  offset = offset | 0;
+  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0);
   if (Buffer.TYPED_ARRAY_SUPPORT) {
-    this[offset] = (value & 0xff)
+    this[offset] = (value & 0xff);
     this[offset + 1] = (value >>> 8)
   } else {
     objectWriteUInt16(this, value, offset, true)
   }
   return offset + 2
-}
+};
 
 Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
-  value = +value
-  offset = offset | 0
-  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
+  value = +value;
+  offset = offset | 0;
+  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0);
   if (Buffer.TYPED_ARRAY_SUPPORT) {
-    this[offset] = (value >>> 8)
+    this[offset] = (value >>> 8);
     this[offset + 1] = (value & 0xff)
   } else {
     objectWriteUInt16(this, value, offset, false)
   }
   return offset + 2
-}
+};
 
 function objectWriteUInt32 (buf, value, offset, littleEndian) {
-  if (value < 0) value = 0xffffffff + value + 1
+  if (value < 0) value = 0xffffffff + value + 1;
   for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {
     buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
   }
 }
 
 Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
-  value = +value
-  offset = offset | 0
-  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
+  value = +value;
+  offset = offset | 0;
+  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0);
   if (Buffer.TYPED_ARRAY_SUPPORT) {
-    this[offset + 3] = (value >>> 24)
-    this[offset + 2] = (value >>> 16)
-    this[offset + 1] = (value >>> 8)
+    this[offset + 3] = (value >>> 24);
+    this[offset + 2] = (value >>> 16);
+    this[offset + 1] = (value >>> 8);
     this[offset] = (value & 0xff)
   } else {
     objectWriteUInt32(this, value, offset, true)
   }
   return offset + 4
-}
+};
 
 Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
-  value = +value
-  offset = offset | 0
-  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
+  value = +value;
+  offset = offset | 0;
+  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0);
   if (Buffer.TYPED_ARRAY_SUPPORT) {
-    this[offset] = (value >>> 24)
-    this[offset + 1] = (value >>> 16)
-    this[offset + 2] = (value >>> 8)
+    this[offset] = (value >>> 24);
+    this[offset + 1] = (value >>> 16);
+    this[offset + 2] = (value >>> 8);
     this[offset + 3] = (value & 0xff)
   } else {
     objectWriteUInt32(this, value, offset, false)
   }
   return offset + 4
-}
+};
 
 Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
-  value = +value
-  offset = offset | 0
+  value = +value;
+  offset = offset | 0;
   if (!noAssert) {
-    var limit = Math.pow(2, 8 * byteLength - 1)
+    var limit = Math.pow(2, 8 * byteLength - 1);
 
     checkInt(this, value, offset, byteLength, limit - 1, -limit)
   }
 
-  var i = 0
-  var mul = 1
-  var sub = 0
-  this[offset] = value & 0xFF
+  var i = 0;
+  var mul = 1;
+  var sub = 0;
+  this[offset] = value & 0xFF;
   while (++i < byteLength && (mul *= 0x100)) {
     if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {
       sub = 1
@@ -32093,21 +32093,21 @@ Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, no
   }
 
   return offset + byteLength
-}
+};
 
 Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
-  value = +value
-  offset = offset | 0
+  value = +value;
+  offset = offset | 0;
   if (!noAssert) {
-    var limit = Math.pow(2, 8 * byteLength - 1)
+    var limit = Math.pow(2, 8 * byteLength - 1);
 
     checkInt(this, value, offset, byteLength, limit - 1, -limit)
   }
 
-  var i = byteLength - 1
-  var mul = 1
-  var sub = 0
-  this[offset + i] = value & 0xFF
+  var i = byteLength - 1;
+  var mul = 1;
+  var sub = 0;
+  this[offset + i] = value & 0xFF;
   while (--i >= 0 && (mul *= 0x100)) {
     if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {
       sub = 1
@@ -32116,77 +32116,77 @@ Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, no
   }
 
   return offset + byteLength
-}
+};
 
 Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
-  value = +value
-  offset = offset | 0
-  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
-  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
-  if (value < 0) value = 0xff + value + 1
-  this[offset] = (value & 0xff)
+  value = +value;
+  offset = offset | 0;
+  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80);
+  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value);
+  if (value < 0) value = 0xff + value + 1;
+  this[offset] = (value & 0xff);
   return offset + 1
-}
+};
 
 Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
-  value = +value
-  offset = offset | 0
-  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
+  value = +value;
+  offset = offset | 0;
+  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000);
   if (Buffer.TYPED_ARRAY_SUPPORT) {
-    this[offset] = (value & 0xff)
+    this[offset] = (value & 0xff);
     this[offset + 1] = (value >>> 8)
   } else {
     objectWriteUInt16(this, value, offset, true)
   }
   return offset + 2
-}
+};
 
 Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
-  value = +value
-  offset = offset | 0
-  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
+  value = +value;
+  offset = offset | 0;
+  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000);
   if (Buffer.TYPED_ARRAY_SUPPORT) {
-    this[offset] = (value >>> 8)
+    this[offset] = (value >>> 8);
     this[offset + 1] = (value & 0xff)
   } else {
     objectWriteUInt16(this, value, offset, false)
   }
   return offset + 2
-}
+};
 
 Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
-  value = +value
-  offset = offset | 0
-  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
+  value = +value;
+  offset = offset | 0;
+  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000);
   if (Buffer.TYPED_ARRAY_SUPPORT) {
-    this[offset] = (value & 0xff)
-    this[offset + 1] = (value >>> 8)
-    this[offset + 2] = (value >>> 16)
+    this[offset] = (value & 0xff);
+    this[offset + 1] = (value >>> 8);
+    this[offset + 2] = (value >>> 16);
     this[offset + 3] = (value >>> 24)
   } else {
     objectWriteUInt32(this, value, offset, true)
   }
   return offset + 4
-}
+};
 
 Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
-  value = +value
-  offset = offset | 0
-  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
-  if (value < 0) value = 0xffffffff + value + 1
+  value = +value;
+  offset = offset | 0;
+  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000);
+  if (value < 0) value = 0xffffffff + value + 1;
   if (Buffer.TYPED_ARRAY_SUPPORT) {
-    this[offset] = (value >>> 24)
-    this[offset + 1] = (value >>> 16)
-    this[offset + 2] = (value >>> 8)
+    this[offset] = (value >>> 24);
+    this[offset + 1] = (value >>> 16);
+    this[offset + 2] = (value >>> 8);
     this[offset + 3] = (value & 0xff)
   } else {
     objectWriteUInt32(this, value, offset, false)
   }
   return offset + 4
-}
+};
 
 function checkIEEE754 (buf, value, offset, ext, max, min) {
-  if (offset + ext > buf.length) throw new RangeError('Index out of range')
+  if (offset + ext > buf.length) throw new RangeError('Index out of range');
   if (offset < 0) throw new RangeError('Index out of range')
 }
 
@@ -32194,61 +32194,61 @@ function writeFloat (buf, value, offset, littleEndian, noAssert) {
   if (!noAssert) {
     checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
   }
-  ieee754.write(buf, value, offset, littleEndian, 23, 4)
+  ieee754.write(buf, value, offset, littleEndian, 23, 4);
   return offset + 4
 }
 
 Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
   return writeFloat(this, value, offset, true, noAssert)
-}
+};
 
 Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
   return writeFloat(this, value, offset, false, noAssert)
-}
+};
 
 function writeDouble (buf, value, offset, littleEndian, noAssert) {
   if (!noAssert) {
     checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
   }
-  ieee754.write(buf, value, offset, littleEndian, 52, 8)
+  ieee754.write(buf, value, offset, littleEndian, 52, 8);
   return offset + 8
 }
 
 Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
   return writeDouble(this, value, offset, true, noAssert)
-}
+};
 
 Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
   return writeDouble(this, value, offset, false, noAssert)
-}
+};
 
 // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
 Buffer.prototype.copy = function copy (target, targetStart, start, end) {
-  if (!start) start = 0
-  if (!end && end !== 0) end = this.length
-  if (targetStart >= target.length) targetStart = target.length
-  if (!targetStart) targetStart = 0
-  if (end > 0 && end < start) end = start
+  if (!start) start = 0;
+  if (!end && end !== 0) end = this.length;
+  if (targetStart >= target.length) targetStart = target.length;
+  if (!targetStart) targetStart = 0;
+  if (end > 0 && end < start) end = start;
 
   // Copy 0 bytes; we're done
-  if (end === start) return 0
-  if (target.length === 0 || this.length === 0) return 0
+  if (end === start) return 0;
+  if (target.length === 0 || this.length === 0) return 0;
 
   // Fatal error conditions
   if (targetStart < 0) {
     throw new RangeError('targetStart out of bounds')
   }
-  if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')
-  if (end < 0) throw new RangeError('sourceEnd out of bounds')
+  if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds');
+  if (end < 0) throw new RangeError('sourceEnd out of bounds');
 
   // Are we oob?
-  if (end > this.length) end = this.length
+  if (end > this.length) end = this.length;
   if (target.length - targetStart < end - start) {
     end = target.length - targetStart + start
   }
 
-  var len = end - start
-  var i
+  var len = end - start;
+  var i;
 
   if (this === target && start < targetStart && targetStart < end) {
     // descending copy from end
@@ -32269,7 +32269,7 @@ Buffer.prototype.copy = function copy (target, targetStart, start, end) {
   }
 
   return len
-}
+};
 
 // Usage:
 //    buffer.fill(number[, offset[, end]])
@@ -32279,15 +32279,15 @@ Buffer.prototype.fill = function fill (val, start, end, encoding) {
   // Handle string cases:
   if (typeof val === 'string') {
     if (typeof start === 'string') {
-      encoding = start
-      start = 0
+      encoding = start;
+      start = 0;
       end = this.length
     } else if (typeof end === 'string') {
-      encoding = end
+      encoding = end;
       end = this.length
     }
     if (val.length === 1) {
-      var code = val.charCodeAt(0)
+      var code = val.charCodeAt(0);
       if (code < 256) {
         val = code
       }
@@ -32311,12 +32311,12 @@ Buffer.prototype.fill = function fill (val, start, end, encoding) {
     return this
   }
 
-  start = start >>> 0
-  end = end === undefined ? this.length : end >>> 0
+  start = start >>> 0;
+  end = end === undefined ? this.length : end >>> 0;
 
-  if (!val) val = 0
+  if (!val) val = 0;
 
-  var i
+  var i;
   if (typeof val === 'number') {
     for (i = start; i < end; ++i) {
       this[i] = val
@@ -32324,26 +32324,26 @@ Buffer.prototype.fill = function fill (val, start, end, encoding) {
   } else {
     var bytes = Buffer.isBuffer(val)
       ? val
-      : utf8ToBytes(new Buffer(val, encoding).toString())
-    var len = bytes.length
+      : utf8ToBytes(new Buffer(val, encoding).toString());
+    var len = bytes.length;
     for (i = 0; i < end - start; ++i) {
       this[i + start] = bytes[i % len]
     }
   }
 
   return this
-}
+};
 
 // HELPER FUNCTIONS
 // ================
 
-var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g
+var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g;
 
 function base64clean (str) {
   // Node strips out invalid characters like \n and \t from the string, base64-js does not
-  str = stringtrim(str).replace(INVALID_BASE64_RE, '')
+  str = stringtrim(str).replace(INVALID_BASE64_RE, '');
   // Node converts strings with length < 2 to ''
-  if (str.length < 2) return ''
+  if (str.length < 2) return '';
   // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
   while (str.length % 4 !== 0) {
     str = str + '='
@@ -32352,24 +32352,24 @@ function base64clean (str) {
 }
 
 function stringtrim (str) {
-  if (str.trim) return str.trim()
+  if (str.trim) return str.trim();
   return str.replace(/^\s+|\s+$/g, '')
 }
 
 function toHex (n) {
-  if (n < 16) return '0' + n.toString(16)
+  if (n < 16) return '0' + n.toString(16);
   return n.toString(16)
 }
 
 function utf8ToBytes (string, units) {
-  units = units || Infinity
-  var codePoint
-  var length = string.length
-  var leadSurrogate = null
-  var bytes = []
+  units = units || Infinity;
+  var codePoint;
+  var length = string.length;
+  var leadSurrogate = null;
+  var bytes = [];
 
   for (var i = 0; i < length; ++i) {
-    codePoint = string.charCodeAt(i)
+    codePoint = string.charCodeAt(i);
 
     // is surrogate component
     if (codePoint > 0xD7FF && codePoint < 0xE000) {
@@ -32378,24 +32378,24 @@ function utf8ToBytes (string, units) {
         // no lead yet
         if (codePoint > 0xDBFF) {
           // unexpected trail
-          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD);
           continue
         } else if (i + 1 === length) {
           // unpaired lead
-          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD);
           continue
         }
 
         // valid lead
-        leadSurrogate = codePoint
+        leadSurrogate = codePoint;
 
         continue
       }
 
       // 2 leads in a row
       if (codePoint < 0xDC00) {
-        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
-        leadSurrogate = codePoint
+        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD);
+        leadSurrogate = codePoint;
         continue
       }
 
@@ -32406,27 +32406,27 @@ function utf8ToBytes (string, units) {
       if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
     }
 
-    leadSurrogate = null
+    leadSurrogate = null;
 
     // encode utf8
     if (codePoint < 0x80) {
-      if ((units -= 1) < 0) break
+      if ((units -= 1) < 0) break;
       bytes.push(codePoint)
     } else if (codePoint < 0x800) {
-      if ((units -= 2) < 0) break
+      if ((units -= 2) < 0) break;
       bytes.push(
         codePoint >> 0x6 | 0xC0,
         codePoint & 0x3F | 0x80
       )
     } else if (codePoint < 0x10000) {
-      if ((units -= 3) < 0) break
+      if ((units -= 3) < 0) break;
       bytes.push(
         codePoint >> 0xC | 0xE0,
         codePoint >> 0x6 & 0x3F | 0x80,
         codePoint & 0x3F | 0x80
       )
     } else if (codePoint < 0x110000) {
-      if ((units -= 4) < 0) break
+      if ((units -= 4) < 0) break;
       bytes.push(
         codePoint >> 0x12 | 0xF0,
         codePoint >> 0xC & 0x3F | 0x80,
@@ -32442,7 +32442,7 @@ function utf8ToBytes (string, units) {
 }
 
 function asciiToBytes (str) {
-  var byteArray = []
+  var byteArray = [];
   for (var i = 0; i < str.length; ++i) {
     // Node's code seems to be doing this and not & 0x7F..
     byteArray.push(str.charCodeAt(i) & 0xFF)
@@ -32451,15 +32451,15 @@ function asciiToBytes (str) {
 }
 
 function utf16leToBytes (str, units) {
-  var c, hi, lo
-  var byteArray = []
+  var c, hi, lo;
+  var byteArray = [];
   for (var i = 0; i < str.length; ++i) {
-    if ((units -= 2) < 0) break
+    if ((units -= 2) < 0) break;
 
-    c = str.charCodeAt(i)
-    hi = c >> 8
-    lo = c % 256
-    byteArray.push(lo)
+    c = str.charCodeAt(i);
+    hi = c >> 8;
+    lo = c % 256;
+    byteArray.push(lo);
     byteArray.push(hi)
   }
 
@@ -32472,7 +32472,7 @@ function base64ToBytes (str) {
 
 function blitBuffer (src, dst, offset, length) {
   for (var i = 0; i < length; ++i) {
-    if ((i + offset >= dst.length) || (i >= src.length)) break
+    if ((i + offset >= dst.length) || (i >= src.length)) break;
     dst[i + offset] = src[i]
   }
   return i
@@ -34767,7 +34767,7 @@ function formatArgs(args) {
   if (!useColors) return;
 
   var c = 'color: ' + this.color;
-  args.splice(1, 0, c, 'color: inherit')
+  args.splice(1, 0, c, 'color: inherit');
 
   // the final "%c" is somewhat tricky, because there could be other
   // arguments passed either before or after the %c, so we need to
@@ -37247,25 +37247,25 @@ module.exports = re.test.bind(re);
 
 },{"ansi-regex":1}],291:[function(require,module,exports){
 exports.read = function (buffer, offset, isLE, mLen, nBytes) {
-  var e, m
-  var eLen = nBytes * 8 - mLen - 1
-  var eMax = (1 << eLen) - 1
-  var eBias = eMax >> 1
-  var nBits = -7
-  var i = isLE ? (nBytes - 1) : 0
-  var d = isLE ? -1 : 1
-  var s = buffer[offset + i]
+  var e, m;
+  var eLen = nBytes * 8 - mLen - 1;
+  var eMax = (1 << eLen) - 1;
+  var eBias = eMax >> 1;
+  var nBits = -7;
+  var i = isLE ? (nBytes - 1) : 0;
+  var d = isLE ? -1 : 1;
+  var s = buffer[offset + i];
 
-  i += d
+  i += d;
 
-  e = s & ((1 << (-nBits)) - 1)
-  s >>= (-nBits)
-  nBits += eLen
+  e = s & ((1 << (-nBits)) - 1);
+  s >>= (-nBits);
+  nBits += eLen;
   for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}
 
-  m = e & ((1 << (-nBits)) - 1)
-  e >>= (-nBits)
-  nBits += mLen
+  m = e & ((1 << (-nBits)) - 1);
+  e >>= (-nBits);
+  nBits += mLen;
   for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}
 
   if (e === 0) {
@@ -37273,31 +37273,31 @@ exports.read = function (buffer, offset, isLE, mLen, nBytes) {
   } else if (e === eMax) {
     return m ? NaN : ((s ? -1 : 1) * Infinity)
   } else {
-    m = m + Math.pow(2, mLen)
+    m = m + Math.pow(2, mLen);
     e = e - eBias
   }
   return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
-}
+};
 
 exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
-  var e, m, c
-  var eLen = nBytes * 8 - mLen - 1
-  var eMax = (1 << eLen) - 1
-  var eBias = eMax >> 1
-  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
-  var i = isLE ? 0 : (nBytes - 1)
-  var d = isLE ? 1 : -1
-  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
+  var e, m, c;
+  var eLen = nBytes * 8 - mLen - 1;
+  var eMax = (1 << eLen) - 1;
+  var eBias = eMax >> 1;
+  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0);
+  var i = isLE ? 0 : (nBytes - 1);
+  var d = isLE ? 1 : -1;
+  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0;
 
-  value = Math.abs(value)
+  value = Math.abs(value);
 
   if (isNaN(value) || value === Infinity) {
-    m = isNaN(value) ? 1 : 0
+    m = isNaN(value) ? 1 : 0;
     e = eMax
   } else {
-    e = Math.floor(Math.log(value) / Math.LN2)
+    e = Math.floor(Math.log(value) / Math.LN2);
     if (value * (c = Math.pow(2, -e)) < 1) {
-      e--
+      e--;
       c *= 2
     }
     if (e + eBias >= 1) {
@@ -37306,26 +37306,26 @@ exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
       value += rt * Math.pow(2, 1 - eBias)
     }
     if (value * c >= 2) {
-      e++
+      e++;
       c /= 2
     }
 
     if (e + eBias >= eMax) {
-      m = 0
+      m = 0;
       e = eMax
     } else if (e + eBias >= 1) {
-      m = (value * c - 1) * Math.pow(2, mLen)
+      m = (value * c - 1) * Math.pow(2, mLen);
       e = e + eBias
     } else {
-      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
+      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);
       e = 0
     }
   }
 
   for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
 
-  e = (e << mLen) | m
-  eLen += mLen
+  e = (e << mLen) | m;
+  eLen += mLen;
   for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
 
   buffer[offset + i - d] |= s * 128
@@ -37407,22 +37407,22 @@ module.exports = Array.isArray || function (arr) {
 
 Object.defineProperty(exports, "__esModule", {
   value: true
-})
+});
 
 // This regex comes from regex.coffee, and is inserted here by generate-index.js
 // (run `npm run build`).
-exports.default = /((['"])(?:(?!\2|\\).|\\(?:\r\n|[\s\S]))*(\2)?|`(?:[^`\\$]|\\[\s\S]|\$(?!\{)|\$\{(?:[^{}]|\{[^}]*\}?)*\}?)*(`)?)|(\/\/.*)|(\/\*(?:[^*]|\*(?!\/))*(\*\/)?)|(\/(?!\*)(?:\[(?:(?![\]\\]).|\\.)*\]|(?![\/\]\\]).|\\.)+\/(?:(?!\s*(?:\b|[\u0080-\uFFFF$\\'"~({]|[+\-!](?!=)|\.?\d))|[gmiyu]{1,5}\b(?![\u0080-\uFFFF$\\]|\s*(?:[+\-*%&|^<>!=?({]|\/(?![\/*])))))|(0[xX][\da-fA-F]+|0[oO][0-7]+|0[bB][01]+|(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?)|((?!\d)(?:(?!\s)[$\w\u0080-\uFFFF]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+)|(--|\+\+|&&|\|\||=>|\.{3}|(?:[+\-\/%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2})=?|[?~.,:;[\](){}])|(\s+)|(^$|[\s\S])/g
+exports.default = /((['"])(?:(?!\2|\\).|\\(?:\r\n|[\s\S]))*(\2)?|`(?:[^`\\$]|\\[\s\S]|\$(?!\{)|\$\{(?:[^{}]|\{[^}]*\}?)*\}?)*(`)?)|(\/\/.*)|(\/\*(?:[^*]|\*(?!\/))*(\*\/)?)|(\/(?!\*)(?:\[(?:(?![\]\\]).|\\.)*\]|(?![\/\]\\]).|\\.)+\/(?:(?!\s*(?:\b|[\u0080-\uFFFF$\\'"~({]|[+\-!](?!=)|\.?\d))|[gmiyu]{1,5}\b(?![\u0080-\uFFFF$\\]|\s*(?:[+\-*%&|^<>!=?({]|\/(?![\/*])))))|(0[xX][\da-fA-F]+|0[oO][0-7]+|0[bB][01]+|(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?)|((?!\d)(?:(?!\s)[$\w\u0080-\uFFFF]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+)|(--|\+\+|&&|\|\||=>|\.{3}|(?:[+\-\/%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2})=?|[?~.,:;[\](){}])|(\s+)|(^$|[\s\S])/g;
 
 exports.matchToToken = function(match) {
-  var token = {type: "invalid", value: match[0]}
-       if (match[ 1]) token.type = "string" , token.closed = !!(match[3] || match[4])
-  else if (match[ 5]) token.type = "comment"
-  else if (match[ 6]) token.type = "comment", token.closed = !!match[7]
-  else if (match[ 8]) token.type = "regex"
-  else if (match[ 9]) token.type = "number"
-  else if (match[10]) token.type = "name"
-  else if (match[11]) token.type = "punctuator"
-  else if (match[12]) token.type = "whitespace"
+  var token = {type: "invalid", value: match[0]};
+       if (match[ 1]) token.type = "string" , token.closed = !!(match[3] || match[4]);
+  else if (match[ 5]) token.type = "comment";
+  else if (match[ 6]) token.type = "comment", token.closed = !!match[7];
+  else if (match[ 8]) token.type = "regex";
+  else if (match[ 9]) token.type = "number";
+  else if (match[10]) token.type = "name";
+  else if (match[11]) token.type = "punctuator";
+  else if (match[12]) token.type = "whitespace";
   return token
 }
 
@@ -37736,7 +37736,7 @@ exports.matchToToken = function(match) {
 			var escaped = '\\' + (longhand ? 'u' : 'x') +
 				('0000' + hexadecimal).slice(longhand ? -4 : -2);
 			result += escaped;
-			continue;
+
 		}
 		if (options.wrap) {
 			result = quote + result + quote;
@@ -45311,16 +45311,16 @@ function values(object) {
 module.exports = values;
 
 },{"./_baseValues":371,"./keys":498}],519:[function(require,module,exports){
-module.exports = minimatch
-minimatch.Minimatch = Minimatch
+module.exports = minimatch;
+minimatch.Minimatch = Minimatch;
 
-var path = { sep: '/' }
+var path = { sep: '/' };
 try {
   path = require('path')
 } catch (er) {}
 
-var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}
-var expand = require('brace-expansion')
+var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {};
+var expand = require('brace-expansion');
 
 var plTypes = {
   '!': { open: '(?:(?!(?:', close: '))[^/]*?)'},
@@ -45328,86 +45328,86 @@ var plTypes = {
   '+': { open: '(?:', close: ')+' },
   '*': { open: '(?:', close: ')*' },
   '@': { open: '(?:', close: ')' }
-}
+};
 
 // any single thing other than /
 // don't need to escape / when using new RegExp()
-var qmark = '[^/]'
+var qmark = '[^/]';
 
 // * => any number of characters
-var star = qmark + '*?'
+var star = qmark + '*?';
 
 // ** when dots are allowed.  Anything goes, except .. and .
 // not (^ or / followed by one or two dots followed by $ or /),
 // followed by anything, any number of times.
-var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?'
+var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?';
 
 // not a ^ or / followed by a dot,
 // followed by anything, any number of times.
-var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?'
+var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?';
 
 // characters that need to be escaped in RegExp.
-var reSpecials = charSet('().*{}+?[]^$\\!')
+var reSpecials = charSet('().*{}+?[]^$\\!');
 
 // "abc" -> { a:true, b:true, c:true }
 function charSet (s) {
   return s.split('').reduce(function (set, c) {
-    set[c] = true
+    set[c] = true;
     return set
   }, {})
 }
 
 // normalizes slashes.
-var slashSplit = /\/+/
+var slashSplit = /\/+/;
 
-minimatch.filter = filter
+minimatch.filter = filter;
 function filter (pattern, options) {
-  options = options || {}
+  options = options || {};
   return function (p, i, list) {
     return minimatch(p, pattern, options)
   }
 }
 
 function ext (a, b) {
-  a = a || {}
-  b = b || {}
-  var t = {}
+  a = a || {};
+  b = b || {};
+  var t = {};
   Object.keys(b).forEach(function (k) {
     t[k] = b[k]
-  })
+  });
   Object.keys(a).forEach(function (k) {
     t[k] = a[k]
-  })
+  });
   return t
 }
 
 minimatch.defaults = function (def) {
-  if (!def || !Object.keys(def).length) return minimatch
+  if (!def || !Object.keys(def).length) return minimatch;
 
-  var orig = minimatch
+  var orig = minimatch;
 
   var m = function minimatch (p, pattern, options) {
     return orig.minimatch(p, pattern, ext(def, options))
-  }
+  };
 
   m.Minimatch = function Minimatch (pattern, options) {
     return new orig.Minimatch(pattern, ext(def, options))
-  }
+  };
 
   return m
-}
+};
 
 Minimatch.defaults = function (def) {
-  if (!def || !Object.keys(def).length) return Minimatch
+  if (!def || !Object.keys(def).length) return Minimatch;
   return minimatch.defaults(def).Minimatch
-}
+};
 
 function minimatch (p, pattern, options) {
   if (typeof pattern !== 'string') {
     throw new TypeError('glob pattern string required')
   }
 
-  if (!options) options = {}
+  if (!options) options = {};
 
   // shortcut: comments match nothing.
   if (!options.nocomment && pattern.charAt(0) === '#') {
@@ -45415,7 +45415,7 @@ function minimatch (p, pattern, options) {
   }
 
   // "" only matches ""
-  if (pattern.trim() === '') return p === ''
+  if (pattern.trim() === '') return p === '';
 
   return new Minimatch(pattern, options).match(p)
 }
@@ -45429,55 +45429,55 @@ function Minimatch (pattern, options) {
     throw new TypeError('glob pattern string required')
   }
 
-  if (!options) options = {}
-  pattern = pattern.trim()
+  if (!options) options = {};
+  pattern = pattern.trim();
 
   // windows support: need to use /, not \
   if (path.sep !== '/') {
     pattern = pattern.split(path.sep).join('/')
   }
 
-  this.options = options
-  this.set = []
-  this.pattern = pattern
-  this.regexp = null
-  this.negate = false
-  this.comment = false
-  this.empty = false
+  this.options = options;
+  this.set = [];
+  this.pattern = pattern;
+  this.regexp = null;
+  this.negate = false;
+  this.comment = false;
+  this.empty = false;
 
   // make the set of regexps etc.
   this.make()
 }
 
-Minimatch.prototype.debug = function () {}
+Minimatch.prototype.debug = function () {};
 
-Minimatch.prototype.make = make
+Minimatch.prototype.make = make;
 function make () {
   // don't do it more than once.
-  if (this._made) return
+  if (this._made) return;
 
-  var pattern = this.pattern
-  var options = this.options
+  var pattern = this.pattern;
+  var options = this.options;
 
   // empty patterns and comments match nothing.
   if (!options.nocomment && pattern.charAt(0) === '#') {
-    this.comment = true
+    this.comment = true;
     return
   }
   if (!pattern) {
-    this.empty = true
+    this.empty = true;
     return
   }
 
   // step 1: figure out negation, etc.
-  this.parseNegate()
+  this.parseNegate();
 
   // step 2: expand braces
-  var set = this.globSet = this.braceExpand()
+  var set = this.globSet = this.braceExpand();
 
-  if (options.debug) this.debug = console.error
+  if (options.debug) this.debug = console.error;
 
-  this.debug(this.pattern, set)
+  this.debug(this.pattern, set);
 
   // step 3: now we have a set, so turn each one into a series of path-portion
   // matching patterns.
@@ -45486,44 +45486,44 @@ function make () {
   // and will not contain any / characters
   set = this.globParts = set.map(function (s) {
     return s.split(slashSplit)
-  })
+  });
 
-  this.debug(this.pattern, set)
+  this.debug(this.pattern, set);
 
   // glob --> regexps
   set = set.map(function (s, si, set) {
     return s.map(this.parse, this)
-  }, this)
+  }, this);
 
-  this.debug(this.pattern, set)
+  this.debug(this.pattern, set);
 
   // filter out everything that didn't compile properly.
   set = set.filter(function (s) {
     return s.indexOf(false) === -1
-  })
+  });
 
-  this.debug(this.pattern, set)
+  this.debug(this.pattern, set);
 
   this.set = set
 }
 
-Minimatch.prototype.parseNegate = parseNegate
+Minimatch.prototype.parseNegate = parseNegate;
 function parseNegate () {
-  var pattern = this.pattern
-  var negate = false
-  var options = this.options
-  var negateOffset = 0
+  var pattern = this.pattern;
+  var negate = false;
+  var options = this.options;
+  var negateOffset = 0;
 
-  if (options.nonegate) return
+  if (options.nonegate) return;
 
   for (var i = 0, l = pattern.length
     ; i < l && pattern.charAt(i) === '!'
     ; i++) {
-    negate = !negate
+    negate = !negate;
     negateOffset++
   }
 
-  if (negateOffset) this.pattern = pattern.substr(negateOffset)
+  if (negateOffset) this.pattern = pattern.substr(negateOffset);
   this.negate = negate
 }
 
@@ -45539,9 +45539,9 @@ function parseNegate () {
 // a{b}c -> a{b}c
 minimatch.braceExpand = function (pattern, options) {
   return braceExpand(pattern, options)
-}
+};
 
-Minimatch.prototype.braceExpand = braceExpand
+Minimatch.prototype.braceExpand = braceExpand;
 
 function braceExpand (pattern, options) {
   if (!options) {
@@ -45553,7 +45553,7 @@ function braceExpand (pattern, options) {
   }
 
   pattern = typeof pattern === 'undefined'
-    ? this.pattern : pattern
+    ? this.pattern : pattern;
 
   if (typeof pattern === 'undefined') {
     throw new TypeError('undefined pattern')
@@ -45579,36 +45579,36 @@ function braceExpand (pattern, options) {
 // when it is the *only* thing in a path portion.  Otherwise, any series
 // of * is equivalent to a single *.  Globstar behavior is enabled by
 // default, and can be disabled by setting options.noglobstar.
-Minimatch.prototype.parse = parse
-var SUBPARSE = {}
+Minimatch.prototype.parse = parse;
+var SUBPARSE = {};
 function parse (pattern, isSub) {
   if (pattern.length > 1024 * 64) {
     throw new TypeError('pattern is too long')
   }
 
-  var options = this.options
+  var options = this.options;
 
   // shortcuts
-  if (!options.noglobstar && pattern === '**') return GLOBSTAR
-  if (pattern === '') return ''
+  if (!options.noglobstar && pattern === '**') return GLOBSTAR;
+  if (pattern === '') return '';
 
-  var re = ''
-  var hasMagic = !!options.nocase
-  var escaping = false
+  var re = '';
+  var hasMagic = !!options.nocase;
+  var escaping = false;
   // ? => one single character
-  var patternListStack = []
-  var negativeLists = []
-  var stateChar
-  var inClass = false
-  var reClassStart = -1
-  var classStart = -1
+  var patternListStack = [];
+  var negativeLists = [];
+  var stateChar;
+  var inClass = false;
+  var reClassStart = -1;
+  var classStart = -1;
   // . and .. never match anything that doesn't start with .,
   // even when options.dot is set.
   var patternStart = pattern.charAt(0) === '.' ? '' // anything
   // not (start or / followed by . or .. followed by / or end)
   : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))'
-  : '(?!\\.)'
-  var self = this
+  : '(?!\\.)';
+  var self = this;
 
   function clearStateChar () {
     if (stateChar) {
@@ -45616,18 +45616,18 @@ function parse (pattern, isSub) {
       // that wasn't consumed by this pass.
       switch (stateChar) {
         case '*':
-          re += star
-          hasMagic = true
-        break
+          re += star;
+          hasMagic = true;
+        break;
         case '?':
-          re += qmark
-          hasMagic = true
-        break
+          re += qmark;
+          hasMagic = true;
+        break;
         default:
-          re += '\\' + stateChar
+          re += '\\' + stateChar;
         break
       }
-      self.debug('clearStateChar %j %j', stateChar, re)
+      self.debug('clearStateChar %j %j', stateChar, re);
       stateChar = false
     }
   }
@@ -45635,12 +45635,12 @@ function parse (pattern, isSub) {
   for (var i = 0, len = pattern.length, c
     ; (i < len) && (c = pattern.charAt(i))
     ; i++) {
-    this.debug('%s\t%s %s %j', pattern, i, re, c)
+    this.debug('%s\t%s %s %j', pattern, i, re, c);
 
     // skip over any that are escaped.
     if (escaping && reSpecials[c]) {
-      re += '\\' + c
-      escaping = false
+      re += '\\' + c;
+      escaping = false;
       continue
     }
 
@@ -45648,12 +45648,12 @@ function parse (pattern, isSub) {
       case '/':
         // completely not allowed, even escaped.
         // Should already be path-split by now.
-        return false
+        return false;
 
       case '\\':
-        clearStateChar()
-        escaping = true
-      continue
+        clearStateChar();
+        escaping = true;
+      continue;
 
       // the various stateChar values
       // for the "extglob" stuff.
@@ -45662,37 +45662,37 @@ function parse (pattern, isSub) {
       case '+':
       case '@':
       case '!':
-        this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c)
+        this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c);
 
         // all of those are literals inside a class, except that
         // the glob [!a] means [^a] in regexp
         if (inClass) {
-          this.debug('  in class')
-          if (c === '!' && i === classStart + 1) c = '^'
-          re += c
+          this.debug('  in class');
+          if (c === '!' && i === classStart + 1) c = '^';
+          re += c;
           continue
         }
 
         // if we already have a stateChar, then it means
         // that there was something like ** or +? in there.
         // Handle the stateChar, then proceed with this one.
-        self.debug('call clearStateChar %j', stateChar)
-        clearStateChar()
-        stateChar = c
+        self.debug('call clearStateChar %j', stateChar);
+        clearStateChar();
+        stateChar = c;
         // if extglob is disabled, then +(asdf|foo) isn't a thing.
         // just clear the statechar *now*, rather than even diving into
         // the patternList stuff.
-        if (options.noext) clearStateChar()
-      continue
+        if (options.noext) clearStateChar();
+      continue;
 
       case '(':
         if (inClass) {
-          re += '('
+          re += '(';
           continue
         }
 
         if (!stateChar) {
-          re += '\\('
+          re += '\\(';
           continue
         }
 
@@ -45702,57 +45702,57 @@ function parse (pattern, isSub) {
           reStart: re.length,
           open: plTypes[stateChar].open,
           close: plTypes[stateChar].close
-        })
+        });
         // negation is (?:(?!js)[^/]*)
-        re += stateChar === '!' ? '(?:(?!(?:' : '(?:'
-        this.debug('plType %j %j', stateChar, re)
-        stateChar = false
-      continue
+        re += stateChar === '!' ? '(?:(?!(?:' : '(?:';
+        this.debug('plType %j %j', stateChar, re);
+        stateChar = false;
+      continue;
 
       case ')':
         if (inClass || !patternListStack.length) {
-          re += '\\)'
+          re += '\\)';
           continue
         }
 
-        clearStateChar()
-        hasMagic = true
-        var pl = patternListStack.pop()
+        clearStateChar();
+        hasMagic = true;
+        var pl = patternListStack.pop();
         // negation is (?:(?!js)[^/]*)
         // The others are (?:<pattern>)<type>
-        re += pl.close
+        re += pl.close;
         if (pl.type === '!') {
           negativeLists.push(pl)
         }
-        pl.reEnd = re.length
-      continue
+        pl.reEnd = re.length;
+      continue;
 
       case '|':
         if (inClass || !patternListStack.length || escaping) {
-          re += '\\|'
-          escaping = false
+          re += '\\|';
+          escaping = false;
           continue
         }
 
-        clearStateChar()
-        re += '|'
-      continue
+        clearStateChar();
+        re += '|';
+      continue;
 
       // these are mostly the same in regexp and glob
       case '[':
         // swallow any state-tracking char before the [
-        clearStateChar()
+        clearStateChar();
 
         if (inClass) {
-          re += '\\' + c
+          re += '\\' + c;
           continue
         }
 
-        inClass = true
-        classStart = i
-        reClassStart = re.length
-        re += c
-      continue
+        inClass = true;
+        classStart = i;
+        reClassStart = re.length;
+        re += c;
+      continue;
 
       case ']':
         //  a right bracket shall lose its special
@@ -45760,8 +45760,8 @@ function parse (pattern, isSub) {
         //  a bracket expression if it occurs
         //  first in the list.  -- POSIX.2 2.8.3.2
         if (i === classStart + 1 || !inClass) {
-          re += '\\' + c
-          escaping = false
+          re += '\\' + c;
+          escaping = false;
           continue
         }
 
@@ -45775,28 +45775,28 @@ function parse (pattern, isSub) {
           // TODO: It would probably be faster to determine this
           // without a try/catch and a new RegExp, but it's tricky
           // to do safely.  For now, this is safe and works.
-          var cs = pattern.substring(classStart + 1, i)
+          var cs = pattern.substring(classStart + 1, i);
           try {
             RegExp('[' + cs + ']')
           } catch (er) {
             // not a valid class!
-            var sp = this.parse(cs, SUBPARSE)
-            re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]'
-            hasMagic = hasMagic || sp[1]
-            inClass = false
+            var sp = this.parse(cs, SUBPARSE);
+            re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]';
+            hasMagic = hasMagic || sp[1];
+            inClass = false;
             continue
           }
         }
 
         // finish up the class.
-        hasMagic = true
-        inClass = false
-        re += c
-      continue
+        hasMagic = true;
+        inClass = false;
+        re += c;
+      continue;
 
       default:
         // swallow any state char that wasn't consumed
-        clearStateChar()
+        clearStateChar();
 
         if (escaping) {
           // no need
@@ -45818,9 +45818,9 @@ function parse (pattern, isSub) {
     // this is a huge pita.  We now have to re-walk
     // the contents of the would-be class to re-translate
     // any characters that were passed through as-is
-    cs = pattern.substr(classStart + 1)
-    sp = this.parse(cs, SUBPARSE)
-    re = re.substr(0, reClassStart) + '\\[' + sp[0]
+    cs = pattern.substr(classStart + 1);
+    sp = this.parse(cs, SUBPARSE);
+    re = re.substr(0, reClassStart) + '\\[' + sp[0];
     hasMagic = hasMagic || sp[1]
   }
 
@@ -45831,8 +45831,8 @@ function parse (pattern, isSub) {
   // Go through and escape them, taking care not to double-escape any
   // | chars that were already escaped.
   for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) {
-    var tail = re.slice(pl.reStart + pl.open.length)
-    this.debug('setting tail', re, pl)
+    var tail = re.slice(pl.reStart + pl.open.length);
+    this.debug('setting tail', re, pl);
     // maybe some even number of \, then maybe 1 \, followed by a |
     tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) {
       if (!$2) {
@@ -45847,19 +45847,19 @@ function parse (pattern, isSub) {
       //
       // I am sorry that you have to see this.
       return $1 + $1 + $2 + '|'
-    })
+    });
 
-    this.debug('tail=%j\n   %s', tail, tail, pl, re)
+    this.debug('tail=%j\n   %s', tail, tail, pl, re);
     var t = pl.type === '*' ? star
       : pl.type === '?' ? qmark
-      : '\\' + pl.type
+      : '\\' + pl.type;
 
-    hasMagic = true
+    hasMagic = true;
     re = re.slice(0, pl.reStart) + t + '\\(' + tail
   }
 
   // handle trailing things that only matter at the very end.
-  clearStateChar()
+  clearStateChar();
   if (escaping) {
     // trailing \\
     re += '\\\\'
@@ -45867,7 +45867,7 @@ function parse (pattern, isSub) {
 
   // only need to apply the nodot start if the re starts with
   // something that could conceivably capture a dot
-  var addPatternStart = false
+  var addPatternStart = false;
   switch (re.charAt(0)) {
     case '.':
     case '[':
@@ -45880,30 +45880,30 @@ function parse (pattern, isSub) {
   // lookahead, has to look ALL the way ahead, to the end of
   // the pattern.
   for (var n = negativeLists.length - 1; n > -1; n--) {
-    var nl = negativeLists[n]
+    var nl = negativeLists[n];
 
-    var nlBefore = re.slice(0, nl.reStart)
-    var nlFirst = re.slice(nl.reStart, nl.reEnd - 8)
-    var nlLast = re.slice(nl.reEnd - 8, nl.reEnd)
-    var nlAfter = re.slice(nl.reEnd)
+    var nlBefore = re.slice(0, nl.reStart);
+    var nlFirst = re.slice(nl.reStart, nl.reEnd - 8);
+    var nlLast = re.slice(nl.reEnd - 8, nl.reEnd);
+    var nlAfter = re.slice(nl.reEnd);
 
-    nlLast += nlAfter
+    nlLast += nlAfter;
 
     // Handle nested stuff like *(*.js|!(*.json)), where open parens
     // mean that we should *not* include the ) in the bit that is considered
     // "after" the negated section.
-    var openParensBefore = nlBefore.split('(').length - 1
-    var cleanAfter = nlAfter
+    var openParensBefore = nlBefore.split('(').length - 1;
+    var cleanAfter = nlAfter;
     for (i = 0; i < openParensBefore; i++) {
       cleanAfter = cleanAfter.replace(/\)[+*?]?/, '')
     }
-    nlAfter = cleanAfter
+    nlAfter = cleanAfter;
 
-    var dollar = ''
+    var dollar = '';
     if (nlAfter === '' && isSub !== SUBPARSE) {
       dollar = '$'
     }
-    var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast
+    var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast;
     re = newRe
   }
 
@@ -45930,7 +45930,7 @@ function parse (pattern, isSub) {
     return globUnescape(pattern)
   }
 
-  var flags = options.nocase ? 'i' : ''
+  var flags = options.nocase ? 'i' : '';
   try {
     var regExp = new RegExp('^' + re + '$', flags)
   } catch (er) {
@@ -45941,19 +45941,19 @@ function parse (pattern, isSub) {
     return new RegExp('$.')
   }
 
-  regExp._glob = pattern
-  regExp._src = re
+  regExp._glob = pattern;
+  regExp._src = re;
 
   return regExp
 }
 
 minimatch.makeRe = function (pattern, options) {
   return new Minimatch(pattern, options || {}).makeRe()
-}
+};
 
-Minimatch.prototype.makeRe = makeRe
+Minimatch.prototype.makeRe = makeRe;
 function makeRe () {
-  if (this.regexp || this.regexp === false) return this.regexp
+  if (this.regexp || this.regexp === false) return this.regexp;
 
   // at this point, this.set is a 2d array of partial
   // pattern strings, or "**".
@@ -45961,18 +45961,18 @@ function makeRe () {
   // It's better to use .match().  This function shouldn't
   // be used, really, but it's pretty convenient sometimes,
   // when you just want to work with a regex.
-  var set = this.set
+  var set = this.set;
 
   if (!set.length) {
-    this.regexp = false
+    this.regexp = false;
     return this.regexp
   }
-  var options = this.options
+  var options = this.options;
 
   var twoStar = options.noglobstar ? star
     : options.dot ? twoStarDot
-    : twoStarNoDot
-  var flags = options.nocase ? 'i' : ''
+    : twoStarNoDot;
+  var flags = options.nocase ? 'i' : '';
 
   var re = set.map(function (pattern) {
     return pattern.map(function (p) {
@@ -45980,14 +45980,14 @@ function makeRe () {
       : (typeof p === 'string') ? regExpEscape(p)
       : p._src
     }).join('\\\/')
-  }).join('|')
+  }).join('|');
 
   // must match entire pattern
   // ending in a * or ** will make it less strict.
-  re = '^(?:' + re + ')$'
+  re = '^(?:' + re + ')$';
 
   // can match anything, as long as it's not this.
-  if (this.negate) re = '^(?!' + re + ').*$'
+  if (this.negate) re = '^(?!' + re + ').*$';
 
   try {
     this.regexp = new RegExp(re, flags)
@@ -45998,28 +45998,28 @@ function makeRe () {
 }
 
 minimatch.match = function (list, pattern, options) {
-  options = options || {}
-  var mm = new Minimatch(pattern, options)
+  options = options || {};
+  var mm = new Minimatch(pattern, options);
   list = list.filter(function (f) {
     return mm.match(f)
-  })
+  });
   if (mm.options.nonull && !list.length) {
     list.push(pattern)
   }
   return list
-}
+};
 
-Minimatch.prototype.match = match
+Minimatch.prototype.match = match;
 function match (f, partial) {
-  this.debug('match', f, this.pattern)
+  this.debug('match', f, this.pattern);
   // short-circuit in the case of busted things.
   // comments, etc.
-  if (this.comment) return false
-  if (this.empty) return f === ''
+  if (this.comment) return false;
+  if (this.empty) return f === '';
 
-  if (f === '/' && partial) return true
+  if (f === '/' && partial) return true;
 
-  var options = this.options
+  var options = this.options;
 
   // windows: need to use /, not \
   if (path.sep !== '/') {
@@ -46027,41 +46027,41 @@ function match (f, partial) {
   }
 
   // treat the test path as a set of pathparts.
-  f = f.split(slashSplit)
-  this.debug(this.pattern, 'split', f)
+  f = f.split(slashSplit);
+  this.debug(this.pattern, 'split', f);
 
   // just ONE of the pattern sets in this.set needs to match
   // in order for it to be valid.  If negating, then just one
   // match means that we have failed.
   // Either way, return on the first hit.
 
-  var set = this.set
-  this.debug(this.pattern, 'set', set)
+  var set = this.set;
+  this.debug(this.pattern, 'set', set);
 
   // Find the basename of the path by looking for the last non-empty segment
-  var filename
-  var i
+  var filename;
+  var i;
   for (i = f.length - 1; i >= 0; i--) {
-    filename = f[i]
+    filename = f[i];
     if (filename) break
   }
 
   for (i = 0; i < set.length; i++) {
-    var pattern = set[i]
-    var file = f
+    var pattern = set[i];
+    var file = f;
     if (options.matchBase && pattern.length === 1) {
       file = [filename]
     }
-    var hit = this.matchOne(file, pattern, partial)
+    var hit = this.matchOne(file, pattern, partial);
     if (hit) {
-      if (options.flipNegate) return true
+      if (options.flipNegate) return true;
       return !this.negate
     }
   }
 
   // didn't get any hits.  this is success if it's a negative
   // pattern, failure otherwise.
-  if (options.flipNegate) return false
+  if (options.flipNegate) return false;
   return this.negate
 }
 
@@ -46071,12 +46071,12 @@ function match (f, partial) {
 // out of pattern, then that's fine, as long as all
 // the parts match.
 Minimatch.prototype.matchOne = function (file, pattern, partial) {
-  var options = this.options
+  var options = this.options;
 
   this.debug('matchOne',
-    { 'this': this, file: file, pattern: pattern })
+    { 'this': this, file: file, pattern: pattern });
 
-  this.debug('matchOne', file.length, pattern.length)
+  this.debug('matchOne', file.length, pattern.length);
 
   for (var fi = 0,
       pi = 0,
@@ -46084,18 +46084,18 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
       pl = pattern.length
       ; (fi < fl) && (pi < pl)
       ; fi++, pi++) {
-    this.debug('matchOne loop')
-    var p = pattern[pi]
-    var f = file[fi]
+    this.debug('matchOne loop');
+    var p = pattern[pi];
+    var f = file[fi];
 
-    this.debug(pattern, p, f)
+    this.debug(pattern, p, f);
 
     // should be impossible.
     // some invalid regexp stuff in the set.
-    if (p === false) return false
+    if (p === false) return false;
 
     if (p === GLOBSTAR) {
-      this.debug('GLOBSTAR', [pattern, p, f])
+      this.debug('GLOBSTAR', [pattern, p, f]);
 
       // "**"
       // a/**/b/**/c would match the following:
@@ -46119,10 +46119,10 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
       //       - matchOne(y/z/c, c) -> no
       //       - matchOne(z/c, c) -> no
       //       - matchOne(c, c) yes, hit
-      var fr = fi
-      var pr = pi + 1
+      var fr = fi;
+      var pr = pi + 1;
       if (pr === pl) {
-        this.debug('** at the end')
+        this.debug('** at the end');
         // a ** at the end will just swallow the rest.
         // We have found a match.
         // however, it will not swallow /.x, unless
@@ -46138,13 +46138,13 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
 
       // ok, let's see if we can swallow whatever we can.
       while (fr < fl) {
-        var swallowee = file[fr]
+        var swallowee = file[fr];
 
-        this.debug('\nglobstar while', file, fr, pattern, pr, swallowee)
+        this.debug('\nglobstar while', file, fr, pattern, pr, swallowee);
 
         // XXX remove this slice.  Just pass the start index.
         if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
-          this.debug('globstar found match!', fr, fl, swallowee)
+          this.debug('globstar found match!', fr, fl, swallowee);
           // found a match.
           return true
         } else {
@@ -46152,12 +46152,12 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
           // can only swallow ".foo" when explicitly asked.
           if (swallowee === '.' || swallowee === '..' ||
             (!options.dot && swallowee.charAt(0) === '.')) {
-            this.debug('dot detected!', file, fr, pattern, pr)
+            this.debug('dot detected!', file, fr, pattern, pr);
             break
           }
 
           // ** swallows a segment, and continue.
-          this.debug('globstar swallow a segment, and continue')
+          this.debug('globstar swallow a segment, and continue');
           fr++
         }
       }
@@ -46167,7 +46167,7 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
       // If there's more *pattern* left, then
       if (partial) {
         // ran out of file
-        this.debug('\n>>> no match, partial?', file, fr, pattern, pr)
+        this.debug('\n>>> no match, partial?', file, fr, pattern, pr);
         if (fr === fl) return true
       }
       return false
@@ -46176,7 +46176,7 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
     // something other than **
     // non-magic patterns just have to match exactly
     // patterns with magic have been turned into regexps.
-    var hit
+    var hit;
     if (typeof p === 'string') {
       if (options.nocase) {
         hit = f.toLowerCase() === p.toLowerCase()
@@ -46185,7 +46185,7 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
       }
       this.debug('string match', p, f, hit)
     } else {
-      hit = f.match(p)
+      hit = f.match(p);
       this.debug('pattern match', p, f, hit)
     }
 
@@ -46218,13 +46218,13 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
     // this is only acceptable if we're on the very last
     // empty segment of a file with a trailing slash.
     // a/* should match a/b/
-    var emptyFileEnd = (fi === fl - 1) && (file[fi] === '')
+    var emptyFileEnd = (fi === fl - 1) && (file[fi] === '');
     return emptyFileEnd
   }
 
   // should be unreachable.
   throw new Error('wtf?')
-}
+};
 
 // replace stuff like \* with *
 function globUnescape (s) {
@@ -46815,7 +46815,7 @@ function defaultClearTimeout () {
     } catch (e) {
         cachedClearTimeout = defaultClearTimeout;
     }
-} ())
+} ());
 function runTimeout(fun) {
     if (cachedSetTimeout === setTimeout) {
         //normal enviroments in sane situations
@@ -46952,7 +46952,7 @@ process.emit = noop;
 process.prependListener = noop;
 process.prependOnceListener = noop;
 
-process.listeners = function (name) { return [] }
+process.listeners = function (name) { return [] };
 
 process.binding = function (name) {
     throw new Error('process.binding is not supported');
@@ -47067,7 +47067,7 @@ process.umask = function() { return 0; };
 				if (tmp == previous + 1) {
 					if (index != max) {
 						previous = tmp;
-						continue;
+
 					} else {
 						isStart = true;
 						result.push(tmp + 1);
@@ -50632,7 +50632,7 @@ function processTerm(item) {
 			throw Error('Unknown term type: ' + item.type);
 	}
 	return item;
-};
+}
 
 module.exports = function(pattern, flags) {
 	var tree = parse(pattern, flags);
@@ -50928,7 +50928,7 @@ module.exports = function(pattern, flags) {
       case null:
         switch (min) {
           case 0:
-            quantifier = '*'
+            quantifier = '*';
             break;
           case 1:
             quantifier = '+';
@@ -52728,7 +52728,7 @@ function SourceMapConsumer(aSourceMap) {
 
 SourceMapConsumer.fromSourceMap = function(aSourceMap) {
   return BasicSourceMapConsumer.fromSourceMap(aSourceMap);
-}
+};
 
 /**
  * The version of the source mapping spec that we are consuming.
@@ -54063,7 +54063,7 @@ SourceMapGenerator.prototype._validateMapping =
         && aGenerated.line > 0 && aGenerated.column >= 0
         && !aOriginal && !aSource && !aName) {
       // Case 1.
-      return;
+
     }
     else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
              && aOriginal && 'line' in aOriginal && 'column' in aOriginal
@@ -54071,7 +54071,7 @@ SourceMapGenerator.prototype._validateMapping =
              && aOriginal.line > 0 && aOriginal.column >= 0
              && aSource) {
       // Cases 2 and 3.
-      return;
+
     }
     else {
       throw new Error('Invalid mapping: ' + JSON.stringify({
@@ -54104,7 +54104,7 @@ SourceMapGenerator.prototype._serializeMappings =
     var mappings = this._mappings.toArray();
     for (var i = 0, len = mappings.length; i < len; i++) {
       mapping = mappings[i];
-      next = ''
+      next = '';
 
       if (mapping.generatedLine !== previousGeneratedLine) {
         previousGeneratedColumn = 0;
@@ -55151,7 +55151,7 @@ exports.WriteStream = WriteStream;
 if (typeof Object.create === 'function') {
   // implementation from standard node.js 'util' module
   module.exports = function inherits(ctor, superCtor) {
-    ctor.super_ = superCtor
+    ctor.super_ = superCtor;
     ctor.prototype = Object.create(superCtor.prototype, {
       constructor: {
         value: ctor,
@@ -55164,10 +55164,10 @@ if (typeof Object.create === 'function') {
 } else {
   // old school shim for old browsers
   module.exports = function inherits(ctor, superCtor) {
-    ctor.super_ = superCtor
-    var TempCtor = function () {}
-    TempCtor.prototype = superCtor.prototype
-    ctor.prototype = new TempCtor()
+    ctor.super_ = superCtor;
+    var TempCtor = function () {};
+    TempCtor.prototype = superCtor.prototype;
+    ctor.prototype = new TempCtor();
     ctor.prototype.constructor = ctor
   }
 }
diff --git a/static/js/novnc/vendor/browser-es-module-loader/src/browser-es-module-loader.js b/static/js/novnc/vendor/browser-es-module-loader/src/browser-es-module-loader.js
index efae617..319caef 100755
--- a/static/js/novnc/vendor/browser-es-module-loader/src/browser-es-module-loader.js
+++ b/static/js/novnc/vendor/browser-es-module-loader/src/browser-es-module-loader.js
@@ -35,7 +35,7 @@ if (typeof document != 'undefined' && document.getElementsByTagName) {
 
     // throw so it still shows up in the console
     throw err;
-  }
+  };
 
   var ready = function() {
     document.removeEventListener('DOMContentLoaded', ready, false );
@@ -63,7 +63,7 @@ if (typeof document != 'undefined' && document.getElementsByTagName) {
         }
       }
     }
-  }
+  };
 
   // simple DOM ready
   if (document.readyState !== 'loading')
@@ -105,10 +105,10 @@ function xhrFetch(url, resolve, reject) {
   var xhr = new XMLHttpRequest();
   var load = function(source) {
     resolve(xhr.responseText);
-  }
+  };
   var error = function() {
     reject(new Error('XHR error' + (xhr.status ? ' (' + xhr.status + (xhr.statusText ? ' ' + xhr.statusText  : '') + ')' : '') + ' loading ' + url));
-  }
+  };
 
   xhr.onreadystatechange = function () {
     if (xhr.readyState === 4) {
@@ -235,7 +235,7 @@ BrowserESModuleLoader.prototype[RegisterLoader.instantiate] = function(key, proc
   return new Promise(function(resolve, reject) {
     // anonymous module
     if (anonSources[key]) {
-      resolve(anonSources[key])
+      resolve(anonSources[key]);
       anonSources[key] = undefined;
     }
     // otherwise we fetch
diff --git a/static/js/novnc/vendor/pako/lib/utils/common.js b/static/js/novnc/vendor/pako/lib/utils/common.js
index 576fd59..8959d9e 100755
--- a/static/js/novnc/vendor/pako/lib/utils/common.js
+++ b/static/js/novnc/vendor/pako/lib/utils/common.js
@@ -4,7 +4,7 @@ export function shrinkBuf (buf, size) {
   if (buf.subarray) { return buf.subarray(0, size); }
   buf.length = size;
   return buf;
-};
+}
 
 
 export function arraySet (dest, src, src_offs, len, dest_offs) {
diff --git a/static/js/novnc/vendor/pako/lib/zlib/inffast.js b/static/js/novnc/vendor/pako/lib/zlib/inffast.js
index 889dcc7..b2b788a 100755
--- a/static/js/novnc/vendor/pako/lib/zlib/inffast.js
+++ b/static/js/novnc/vendor/pako/lib/zlib/inffast.js
@@ -277,7 +277,7 @@ export default function inflate_fast(strm, start) {
           }
           else if ((op & 64) === 0) {          /* 2nd level distance code */
             here = dcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))];
-            continue dodist;
+            continue;
           }
           else {
             strm.msg = 'invalid distance code';
@@ -290,7 +290,7 @@ export default function inflate_fast(strm, start) {
       }
       else if ((op & 64) === 0) {              /* 2nd level length code */
         here = lcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))];
-        continue dolen;
+        continue;
       }
       else if (op & 32) {                     /* end-of-block */
         //Tracevv((stderr, "inflate:         end of block\n"));
@@ -320,5 +320,5 @@ export default function inflate_fast(strm, start) {
   strm.avail_out = (_out < end ? 257 + (end - _out) : 257 - (_out - end));
   state.hold = hold;
   state.bits = bits;
-  return;
+
 };
diff --git a/static/js/plugins/flot/excanvas.min.js b/static/js/plugins/flot/excanvas.min.js
deleted file mode 100755
index 12c74f7..0000000
--- a/static/js/plugins/flot/excanvas.min.js
+++ /dev/null
@@ -1 +0,0 @@
-if(!document.createElement("canvas").getContext){(function(){var z=Math;var K=z.round;var J=z.sin;var U=z.cos;var b=z.abs;var k=z.sqrt;var D=10;var F=D/2;function T(){return this.context_||(this.context_=new W(this))}var O=Array.prototype.slice;function G(i,j,m){var Z=O.call(arguments,2);return function(){return i.apply(j,Z.concat(O.call(arguments)))}}function AD(Z){return String(Z).replace(/&/g,"&amp;").replace(/"/g,"&quot;")}function r(i){if(!i.namespaces.g_vml_){i.namespaces.add("g_vml_","urn:schemas-microsoft-com:vml","#default#VML")}if(!i.namespaces.g_o_){i.namespaces.add("g_o_","urn:schemas-microsoft-com:office:office","#default#VML")}if(!i.styleSheets.ex_canvas_){var Z=i.createStyleSheet();Z.owningElement.id="ex_canvas_";Z.cssText="canvas{display:inline-block;overflow:hidden;text-align:left;width:300px;height:150px}"}}r(document);var E={init:function(Z){if(/MSIE/.test(navigator.userAgent)&&!window.opera){var i=Z||document;i.createElement("canvas");i.attachEvent("onreadystatechange",G(this.init_,this,i))}},init_:function(m){var j=m.getElementsByTagName("canvas");for(var Z=0;Z<j.length;Z++){this.initElement(j[Z])}},initElement:function(i){if(!i.getContext){i.getContext=T;r(i.ownerDocument);i.innerHTML="";i.attachEvent("onpropertychange",S);i.attachEvent("onresize",w);var Z=i.attributes;if(Z.width&&Z.width.specified){i.style.width=Z.width.nodeValue+"px"}else{i.width=i.clientWidth}if(Z.height&&Z.height.specified){i.style.height=Z.height.nodeValue+"px"}else{i.height=i.clientHeight}}return i}};function S(i){var Z=i.srcElement;switch(i.propertyName){case"width":Z.getContext().clearRect();Z.style.width=Z.attributes.width.nodeValue+"px";Z.firstChild.style.width=Z.clientWidth+"px";break;case"height":Z.getContext().clearRect();Z.style.height=Z.attributes.height.nodeValue+"px";Z.firstChild.style.height=Z.clientHeight+"px";break}}function w(i){var Z=i.srcElement;if(Z.firstChild){Z.firstChild.style.width=Z.clientWidth+"px";Z.firstChild.style.height=Z.clientHeight+"px"}}E.init();var I=[];for(var AC=0;AC<16;AC++){for(var AB=0;AB<16;AB++){I[AC*16+AB]=AC.toString(16)+AB.toString(16)}}function V(){return[[1,0,0],[0,1,0],[0,0,1]]}function d(m,j){var i=V();for(var Z=0;Z<3;Z++){for(var AF=0;AF<3;AF++){var p=0;for(var AE=0;AE<3;AE++){p+=m[Z][AE]*j[AE][AF]}i[Z][AF]=p}}return i}function Q(i,Z){Z.fillStyle=i.fillStyle;Z.lineCap=i.lineCap;Z.lineJoin=i.lineJoin;Z.lineWidth=i.lineWidth;Z.miterLimit=i.miterLimit;Z.shadowBlur=i.shadowBlur;Z.shadowColor=i.shadowColor;Z.shadowOffsetX=i.shadowOffsetX;Z.shadowOffsetY=i.shadowOffsetY;Z.strokeStyle=i.strokeStyle;Z.globalAlpha=i.globalAlpha;Z.font=i.font;Z.textAlign=i.textAlign;Z.textBaseline=i.textBaseline;Z.arcScaleX_=i.arcScaleX_;Z.arcScaleY_=i.arcScaleY_;Z.lineScale_=i.lineScale_}var B={aliceblue:"#F0F8FF",antiquewhite:"#FAEBD7",aquamarine:"#7FFFD4",azure:"#F0FFFF",beige:"#F5F5DC",bisque:"#FFE4C4",black:"#000000",blanchedalmond:"#FFEBCD",blueviolet:"#8A2BE2",brown:"#A52A2A",burlywood:"#DEB887",cadetblue:"#5F9EA0",chartreuse:"#7FFF00",chocolate:"#D2691E",coral:"#FF7F50",cornflowerblue:"#6495ED",cornsilk:"#FFF8DC",crimson:"#DC143C",cyan:"#00FFFF",darkblue:"#00008B",darkcyan:"#008B8B",darkgoldenrod:"#B8860B",darkgray:"#A9A9A9",darkgreen:"#006400",darkgrey:"#A9A9A9",darkkhaki:"#BDB76B",darkmagenta:"#8B008B",darkolivegreen:"#556B2F",darkorange:"#FF8C00",darkorchid:"#9932CC",darkred:"#8B0000",darksalmon:"#E9967A",darkseagreen:"#8FBC8F",darkslateblue:"#483D8B",darkslategray:"#2F4F4F",darkslategrey:"#2F4F4F",darkturquoise:"#00CED1",darkviolet:"#9400D3",deeppink:"#FF1493",deepskyblue:"#00BFFF",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1E90FF",firebrick:"#B22222",floralwhite:"#FFFAF0",forestgreen:"#228B22",gainsboro:"#DCDCDC",ghostwhite:"#F8F8FF",gold:"#FFD700",goldenrod:"#DAA520",grey:"#808080",greenyellow:"#ADFF2F",honeydew:"#F0FFF0",hotpink:"#FF69B4",indianred:"#CD5C5C",indigo:"#4B0082",ivory:"#FFFFF0",khaki:"#F0E68C",lavender:"#E6E6FA",lavenderblush:"#FFF0F5",lawngreen:"#7CFC00",lemonchiffon:"#FFFACD",lightblue:"#ADD8E6",lightcoral:"#F08080",lightcyan:"#E0FFFF",lightgoldenrodyellow:"#FAFAD2",lightgreen:"#90EE90",lightgrey:"#D3D3D3",lightpink:"#FFB6C1",lightsalmon:"#FFA07A",lightseagreen:"#20B2AA",lightskyblue:"#87CEFA",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#B0C4DE",lightyellow:"#FFFFE0",limegreen:"#32CD32",linen:"#FAF0E6",magenta:"#FF00FF",mediumaquamarine:"#66CDAA",mediumblue:"#0000CD",mediumorchid:"#BA55D3",mediumpurple:"#9370DB",mediumseagreen:"#3CB371",mediumslateblue:"#7B68EE",mediumspringgreen:"#00FA9A",mediumturquoise:"#48D1CC",mediumvioletred:"#C71585",midnightblue:"#191970",mintcream:"#F5FFFA",mistyrose:"#FFE4E1",moccasin:"#FFE4B5",navajowhite:"#FFDEAD",oldlace:"#FDF5E6",olivedrab:"#6B8E23",orange:"#FFA500",orangered:"#FF4500",orchid:"#DA70D6",palegoldenrod:"#EEE8AA",palegreen:"#98FB98",paleturquoise:"#AFEEEE",palevioletred:"#DB7093",papayawhip:"#FFEFD5",peachpuff:"#FFDAB9",peru:"#CD853F",pink:"#FFC0CB",plum:"#DDA0DD",powderblue:"#B0E0E6",rosybrown:"#BC8F8F",royalblue:"#4169E1",saddlebrown:"#8B4513",salmon:"#FA8072",sandybrown:"#F4A460",seagreen:"#2E8B57",seashell:"#FFF5EE",sienna:"#A0522D",skyblue:"#87CEEB",slateblue:"#6A5ACD",slategray:"#708090",slategrey:"#708090",snow:"#FFFAFA",springgreen:"#00FF7F",steelblue:"#4682B4",tan:"#D2B48C",thistle:"#D8BFD8",tomato:"#FF6347",turquoise:"#40E0D0",violet:"#EE82EE",wheat:"#F5DEB3",whitesmoke:"#F5F5F5",yellowgreen:"#9ACD32"};function g(i){var m=i.indexOf("(",3);var Z=i.indexOf(")",m+1);var j=i.substring(m+1,Z).split(",");if(j.length==4&&i.substr(3,1)=="a"){alpha=Number(j[3])}else{j[3]=1}return j}function C(Z){return parseFloat(Z)/100}function N(i,j,Z){return Math.min(Z,Math.max(j,i))}function c(AF){var j,i,Z;h=parseFloat(AF[0])/360%360;if(h<0){h++}s=N(C(AF[1]),0,1);l=N(C(AF[2]),0,1);if(s==0){j=i=Z=l}else{var m=l<0.5?l*(1+s):l+s-l*s;var AE=2*l-m;j=A(AE,m,h+1/3);i=A(AE,m,h);Z=A(AE,m,h-1/3)}return"#"+I[Math.floor(j*255)]+I[Math.floor(i*255)]+I[Math.floor(Z*255)]}function A(i,Z,j){if(j<0){j++}if(j>1){j--}if(6*j<1){return i+(Z-i)*6*j}else{if(2*j<1){return Z}else{if(3*j<2){return i+(Z-i)*(2/3-j)*6}else{return i}}}}function Y(Z){var AE,p=1;Z=String(Z);if(Z.charAt(0)=="#"){AE=Z}else{if(/^rgb/.test(Z)){var m=g(Z);var AE="#",AF;for(var j=0;j<3;j++){if(m[j].indexOf("%")!=-1){AF=Math.floor(C(m[j])*255)}else{AF=Number(m[j])}AE+=I[N(AF,0,255)]}p=m[3]}else{if(/^hsl/.test(Z)){var m=g(Z);AE=c(m);p=m[3]}else{AE=B[Z]||Z}}}return{color:AE,alpha:p}}var L={style:"normal",variant:"normal",weight:"normal",size:10,family:"sans-serif"};var f={};function X(Z){if(f[Z]){return f[Z]}var m=document.createElement("div");var j=m.style;try{j.font=Z}catch(i){}return f[Z]={style:j.fontStyle||L.style,variant:j.fontVariant||L.variant,weight:j.fontWeight||L.weight,size:j.fontSize||L.size,family:j.fontFamily||L.family}}function P(j,i){var Z={};for(var AF in j){Z[AF]=j[AF]}var AE=parseFloat(i.currentStyle.fontSize),m=parseFloat(j.size);if(typeof j.size=="number"){Z.size=j.size}else{if(j.size.indexOf("px")!=-1){Z.size=m}else{if(j.size.indexOf("em")!=-1){Z.size=AE*m}else{if(j.size.indexOf("%")!=-1){Z.size=(AE/100)*m}else{if(j.size.indexOf("pt")!=-1){Z.size=m/0.75}else{Z.size=AE}}}}}Z.size*=0.981;return Z}function AA(Z){return Z.style+" "+Z.variant+" "+Z.weight+" "+Z.size+"px "+Z.family}function t(Z){switch(Z){case"butt":return"flat";case"round":return"round";case"square":default:return"square"}}function W(i){this.m_=V();this.mStack_=[];this.aStack_=[];this.currentPath_=[];this.strokeStyle="#000";this.fillStyle="#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=D*1;this.globalAlpha=1;this.font="10px sans-serif";this.textAlign="left";this.textBaseline="alphabetic";this.canvas=i;var Z=i.ownerDocument.createElement("div");Z.style.width=i.clientWidth+"px";Z.style.height=i.clientHeight+"px";Z.style.overflow="hidden";Z.style.position="absolute";i.appendChild(Z);this.element_=Z;this.arcScaleX_=1;this.arcScaleY_=1;this.lineScale_=1}var M=W.prototype;M.clearRect=function(){if(this.textMeasureEl_){this.textMeasureEl_.removeNode(true);this.textMeasureEl_=null}this.element_.innerHTML=""};M.beginPath=function(){this.currentPath_=[]};M.moveTo=function(i,Z){var j=this.getCoords_(i,Z);this.currentPath_.push({type:"moveTo",x:j.x,y:j.y});this.currentX_=j.x;this.currentY_=j.y};M.lineTo=function(i,Z){var j=this.getCoords_(i,Z);this.currentPath_.push({type:"lineTo",x:j.x,y:j.y});this.currentX_=j.x;this.currentY_=j.y};M.bezierCurveTo=function(j,i,AI,AH,AG,AE){var Z=this.getCoords_(AG,AE);var AF=this.getCoords_(j,i);var m=this.getCoords_(AI,AH);e(this,AF,m,Z)};function e(Z,m,j,i){Z.currentPath_.push({type:"bezierCurveTo",cp1x:m.x,cp1y:m.y,cp2x:j.x,cp2y:j.y,x:i.x,y:i.y});Z.currentX_=i.x;Z.currentY_=i.y}M.quadraticCurveTo=function(AG,j,i,Z){var AF=this.getCoords_(AG,j);var AE=this.getCoords_(i,Z);var AH={x:this.currentX_+2/3*(AF.x-this.currentX_),y:this.currentY_+2/3*(AF.y-this.currentY_)};var m={x:AH.x+(AE.x-this.currentX_)/3,y:AH.y+(AE.y-this.currentY_)/3};e(this,AH,m,AE)};M.arc=function(AJ,AH,AI,AE,i,j){AI*=D;var AN=j?"at":"wa";var AK=AJ+U(AE)*AI-F;var AM=AH+J(AE)*AI-F;var Z=AJ+U(i)*AI-F;var AL=AH+J(i)*AI-F;if(AK==Z&&!j){AK+=0.125}var m=this.getCoords_(AJ,AH);var AG=this.getCoords_(AK,AM);var AF=this.getCoords_(Z,AL);this.currentPath_.push({type:AN,x:m.x,y:m.y,radius:AI,xStart:AG.x,yStart:AG.y,xEnd:AF.x,yEnd:AF.y})};M.rect=function(j,i,Z,m){this.moveTo(j,i);this.lineTo(j+Z,i);this.lineTo(j+Z,i+m);this.lineTo(j,i+m);this.closePath()};M.strokeRect=function(j,i,Z,m){var p=this.currentPath_;this.beginPath();this.moveTo(j,i);this.lineTo(j+Z,i);this.lineTo(j+Z,i+m);this.lineTo(j,i+m);this.closePath();this.stroke();this.currentPath_=p};M.fillRect=function(j,i,Z,m){var p=this.currentPath_;this.beginPath();this.moveTo(j,i);this.lineTo(j+Z,i);this.lineTo(j+Z,i+m);this.lineTo(j,i+m);this.closePath();this.fill();this.currentPath_=p};M.createLinearGradient=function(i,m,Z,j){var p=new v("gradient");p.x0_=i;p.y0_=m;p.x1_=Z;p.y1_=j;return p};M.createRadialGradient=function(m,AE,j,i,p,Z){var AF=new v("gradientradial");AF.x0_=m;AF.y0_=AE;AF.r0_=j;AF.x1_=i;AF.y1_=p;AF.r1_=Z;return AF};M.drawImage=function(AO,j){var AH,AF,AJ,AV,AM,AK,AQ,AX;var AI=AO.runtimeStyle.width;var AN=AO.runtimeStyle.height;AO.runtimeStyle.width="auto";AO.runtimeStyle.height="auto";var AG=AO.width;var AT=AO.height;AO.runtimeStyle.width=AI;AO.runtimeStyle.height=AN;if(arguments.length==3){AH=arguments[1];AF=arguments[2];AM=AK=0;AQ=AJ=AG;AX=AV=AT}else{if(arguments.length==5){AH=arguments[1];AF=arguments[2];AJ=arguments[3];AV=arguments[4];AM=AK=0;AQ=AG;AX=AT}else{if(arguments.length==9){AM=arguments[1];AK=arguments[2];AQ=arguments[3];AX=arguments[4];AH=arguments[5];AF=arguments[6];AJ=arguments[7];AV=arguments[8]}else{throw Error("Invalid number of arguments")}}}var AW=this.getCoords_(AH,AF);var m=AQ/2;var i=AX/2;var AU=[];var Z=10;var AE=10;AU.push(" <g_vml_:group",' coordsize="',D*Z,",",D*AE,'"',' coordorigin="0,0"',' style="width:',Z,"px;height:",AE,"px;position:absolute;");if(this.m_[0][0]!=1||this.m_[0][1]||this.m_[1][1]!=1||this.m_[1][0]){var p=[];p.push("M11=",this.m_[0][0],",","M12=",this.m_[1][0],",","M21=",this.m_[0][1],",","M22=",this.m_[1][1],",","Dx=",K(AW.x/D),",","Dy=",K(AW.y/D),"");var AS=AW;var AR=this.getCoords_(AH+AJ,AF);var AP=this.getCoords_(AH,AF+AV);var AL=this.getCoords_(AH+AJ,AF+AV);AS.x=z.max(AS.x,AR.x,AP.x,AL.x);AS.y=z.max(AS.y,AR.y,AP.y,AL.y);AU.push("padding:0 ",K(AS.x/D),"px ",K(AS.y/D),"px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",p.join(""),", sizingmethod='clip');")}else{AU.push("top:",K(AW.y/D),"px;left:",K(AW.x/D),"px;")}AU.push(' ">','<g_vml_:image src="',AO.src,'"',' style="width:',D*AJ,"px;"," height:",D*AV,'px"',' cropleft="',AM/AG,'"',' croptop="',AK/AT,'"',' cropright="',(AG-AM-AQ)/AG,'"',' cropbottom="',(AT-AK-AX)/AT,'"'," />","</g_vml_:group>");this.element_.insertAdjacentHTML("BeforeEnd",AU.join(""))};M.stroke=function(AM){var m=10;var AN=10;var AE=5000;var AG={x:null,y:null};var AL={x:null,y:null};for(var AH=0;AH<this.currentPath_.length;AH+=AE){var AK=[];var AF=false;AK.push("<g_vml_:shape",' filled="',!!AM,'"',' style="position:absolute;width:',m,"px;height:",AN,'px;"',' coordorigin="0,0"',' coordsize="',D*m,",",D*AN,'"',' stroked="',!AM,'"',' path="');var AO=false;for(var AI=AH;AI<Math.min(AH+AE,this.currentPath_.length);AI++){if(AI%AE==0&&AI>0){AK.push(" m ",K(this.currentPath_[AI-1].x),",",K(this.currentPath_[AI-1].y))}var Z=this.currentPath_[AI];var AJ;switch(Z.type){case"moveTo":AJ=Z;AK.push(" m ",K(Z.x),",",K(Z.y));break;case"lineTo":AK.push(" l ",K(Z.x),",",K(Z.y));break;case"close":AK.push(" x ");Z=null;break;case"bezierCurveTo":AK.push(" c ",K(Z.cp1x),",",K(Z.cp1y),",",K(Z.cp2x),",",K(Z.cp2y),",",K(Z.x),",",K(Z.y));break;case"at":case"wa":AK.push(" ",Z.type," ",K(Z.x-this.arcScaleX_*Z.radius),",",K(Z.y-this.arcScaleY_*Z.radius)," ",K(Z.x+this.arcScaleX_*Z.radius),",",K(Z.y+this.arcScaleY_*Z.radius)," ",K(Z.xStart),",",K(Z.yStart)," ",K(Z.xEnd),",",K(Z.yEnd));break}if(Z){if(AG.x==null||Z.x<AG.x){AG.x=Z.x}if(AL.x==null||Z.x>AL.x){AL.x=Z.x}if(AG.y==null||Z.y<AG.y){AG.y=Z.y}if(AL.y==null||Z.y>AL.y){AL.y=Z.y}}}AK.push(' ">');if(!AM){R(this,AK)}else{a(this,AK,AG,AL)}AK.push("</g_vml_:shape>");this.element_.insertAdjacentHTML("beforeEnd",AK.join(""))}};function R(j,AE){var i=Y(j.strokeStyle);var m=i.color;var p=i.alpha*j.globalAlpha;var Z=j.lineScale_*j.lineWidth;if(Z<1){p*=Z}AE.push("<g_vml_:stroke",' opacity="',p,'"',' joinstyle="',j.lineJoin,'"',' miterlimit="',j.miterLimit,'"',' endcap="',t(j.lineCap),'"',' weight="',Z,'px"',' color="',m,'" />')}function a(AO,AG,Ah,AP){var AH=AO.fillStyle;var AY=AO.arcScaleX_;var AX=AO.arcScaleY_;var Z=AP.x-Ah.x;var m=AP.y-Ah.y;if(AH instanceof v){var AL=0;var Ac={x:0,y:0};var AU=0;var AK=1;if(AH.type_=="gradient"){var AJ=AH.x0_/AY;var j=AH.y0_/AX;var AI=AH.x1_/AY;var Aj=AH.y1_/AX;var Ag=AO.getCoords_(AJ,j);var Af=AO.getCoords_(AI,Aj);var AE=Af.x-Ag.x;var p=Af.y-Ag.y;AL=Math.atan2(AE,p)*180/Math.PI;if(AL<0){AL+=360}if(AL<0.000001){AL=0}}else{var Ag=AO.getCoords_(AH.x0_,AH.y0_);Ac={x:(Ag.x-Ah.x)/Z,y:(Ag.y-Ah.y)/m};Z/=AY*D;m/=AX*D;var Aa=z.max(Z,m);AU=2*AH.r0_/Aa;AK=2*AH.r1_/Aa-AU}var AS=AH.colors_;AS.sort(function(Ak,i){return Ak.offset-i.offset});var AN=AS.length;var AR=AS[0].color;var AQ=AS[AN-1].color;var AW=AS[0].alpha*AO.globalAlpha;var AV=AS[AN-1].alpha*AO.globalAlpha;var Ab=[];for(var Ae=0;Ae<AN;Ae++){var AM=AS[Ae];Ab.push(AM.offset*AK+AU+" "+AM.color)}AG.push('<g_vml_:fill type="',AH.type_,'"',' method="none" focus="100%"',' color="',AR,'"',' color2="',AQ,'"',' colors="',Ab.join(","),'"',' opacity="',AV,'"',' g_o_:opacity2="',AW,'"',' angle="',AL,'"',' focusposition="',Ac.x,",",Ac.y,'" />')}else{if(AH instanceof u){if(Z&&m){var AF=-Ah.x;var AZ=-Ah.y;AG.push("<g_vml_:fill",' position="',AF/Z*AY*AY,",",AZ/m*AX*AX,'"',' type="tile"',' src="',AH.src_,'" />')}}else{var Ai=Y(AO.fillStyle);var AT=Ai.color;var Ad=Ai.alpha*AO.globalAlpha;AG.push('<g_vml_:fill color="',AT,'" opacity="',Ad,'" />')}}}M.fill=function(){this.stroke(true)};M.closePath=function(){this.currentPath_.push({type:"close"})};M.getCoords_=function(j,i){var Z=this.m_;return{x:D*(j*Z[0][0]+i*Z[1][0]+Z[2][0])-F,y:D*(j*Z[0][1]+i*Z[1][1]+Z[2][1])-F}};M.save=function(){var Z={};Q(this,Z);this.aStack_.push(Z);this.mStack_.push(this.m_);this.m_=d(V(),this.m_)};M.restore=function(){if(this.aStack_.length){Q(this.aStack_.pop(),this);this.m_=this.mStack_.pop()}};function H(Z){return isFinite(Z[0][0])&&isFinite(Z[0][1])&&isFinite(Z[1][0])&&isFinite(Z[1][1])&&isFinite(Z[2][0])&&isFinite(Z[2][1])}function y(i,Z,j){if(!H(Z)){return }i.m_=Z;if(j){var p=Z[0][0]*Z[1][1]-Z[0][1]*Z[1][0];i.lineScale_=k(b(p))}}M.translate=function(j,i){var Z=[[1,0,0],[0,1,0],[j,i,1]];y(this,d(Z,this.m_),false)};M.rotate=function(i){var m=U(i);var j=J(i);var Z=[[m,j,0],[-j,m,0],[0,0,1]];y(this,d(Z,this.m_),false)};M.scale=function(j,i){this.arcScaleX_*=j;this.arcScaleY_*=i;var Z=[[j,0,0],[0,i,0],[0,0,1]];y(this,d(Z,this.m_),true)};M.transform=function(p,m,AF,AE,i,Z){var j=[[p,m,0],[AF,AE,0],[i,Z,1]];y(this,d(j,this.m_),true)};M.setTransform=function(AE,p,AG,AF,j,i){var Z=[[AE,p,0],[AG,AF,0],[j,i,1]];y(this,Z,true)};M.drawText_=function(AK,AI,AH,AN,AG){var AM=this.m_,AQ=1000,i=0,AP=AQ,AF={x:0,y:0},AE=[];var Z=P(X(this.font),this.element_);var j=AA(Z);var AR=this.element_.currentStyle;var p=this.textAlign.toLowerCase();switch(p){case"left":case"center":case"right":break;case"end":p=AR.direction=="ltr"?"right":"left";break;case"start":p=AR.direction=="rtl"?"right":"left";break;default:p="left"}switch(this.textBaseline){case"hanging":case"top":AF.y=Z.size/1.75;break;case"middle":break;default:case null:case"alphabetic":case"ideographic":case"bottom":AF.y=-Z.size/2.25;break}switch(p){case"right":i=AQ;AP=0.05;break;case"center":i=AP=AQ/2;break}var AO=this.getCoords_(AI+AF.x,AH+AF.y);AE.push('<g_vml_:line from="',-i,' 0" to="',AP,' 0.05" ',' coordsize="100 100" coordorigin="0 0"',' filled="',!AG,'" stroked="',!!AG,'" style="position:absolute;width:1px;height:1px;">');if(AG){R(this,AE)}else{a(this,AE,{x:-i,y:0},{x:AP,y:Z.size})}var AL=AM[0][0].toFixed(3)+","+AM[1][0].toFixed(3)+","+AM[0][1].toFixed(3)+","+AM[1][1].toFixed(3)+",0,0";var AJ=K(AO.x/D)+","+K(AO.y/D);AE.push('<g_vml_:skew on="t" matrix="',AL,'" ',' offset="',AJ,'" origin="',i,' 0" />','<g_vml_:path textpathok="true" />','<g_vml_:textpath on="true" string="',AD(AK),'" style="v-text-align:',p,";font:",AD(j),'" /></g_vml_:line>');this.element_.insertAdjacentHTML("beforeEnd",AE.join(""))};M.fillText=function(j,Z,m,i){this.drawText_(j,Z,m,i,false)};M.strokeText=function(j,Z,m,i){this.drawText_(j,Z,m,i,true)};M.measureText=function(j){if(!this.textMeasureEl_){var Z='<span style="position:absolute;top:-20000px;left:0;padding:0;margin:0;border:none;white-space:pre;"></span>';this.element_.insertAdjacentHTML("beforeEnd",Z);this.textMeasureEl_=this.element_.lastChild}var i=this.element_.ownerDocument;this.textMeasureEl_.innerHTML="";this.textMeasureEl_.style.font=this.font;this.textMeasureEl_.appendChild(i.createTextNode(j));return{width:this.textMeasureEl_.offsetWidth}};M.clip=function(){};M.arcTo=function(){};M.createPattern=function(i,Z){return new u(i,Z)};function v(Z){this.type_=Z;this.x0_=0;this.y0_=0;this.r0_=0;this.x1_=0;this.y1_=0;this.r1_=0;this.colors_=[]}v.prototype.addColorStop=function(i,Z){Z=Y(Z);this.colors_.push({offset:i,color:Z.color,alpha:Z.alpha})};function u(i,Z){q(i);switch(Z){case"repeat":case null:case"":this.repetition_="repeat";break;case"repeat-x":case"repeat-y":case"no-repeat":this.repetition_=Z;break;default:n("SYNTAX_ERR")}this.src_=i.src;this.width_=i.width;this.height_=i.height}function n(Z){throw new o(Z)}function q(Z){if(!Z||Z.nodeType!=1||Z.tagName!="IMG"){n("TYPE_MISMATCH_ERR")}if(Z.readyState!="complete"){n("INVALID_STATE_ERR")}}function o(Z){this.code=this[Z];this.message=Z+": DOM Exception "+this.code}var x=o.prototype=new Error;x.INDEX_SIZE_ERR=1;x.DOMSTRING_SIZE_ERR=2;x.HIERARCHY_REQUEST_ERR=3;x.WRONG_DOCUMENT_ERR=4;x.INVALID_CHARACTER_ERR=5;x.NO_DATA_ALLOWED_ERR=6;x.NO_MODIFICATION_ALLOWED_ERR=7;x.NOT_FOUND_ERR=8;x.NOT_SUPPORTED_ERR=9;x.INUSE_ATTRIBUTE_ERR=10;x.INVALID_STATE_ERR=11;x.SYNTAX_ERR=12;x.INVALID_MODIFICATION_ERR=13;x.NAMESPACE_ERR=14;x.INVALID_ACCESS_ERR=15;x.VALIDATION_ERR=16;x.TYPE_MISMATCH_ERR=17;G_vmlCanvasManager=E;CanvasRenderingContext2D=W;CanvasGradient=v;CanvasPattern=u;DOMException=o})()};
\ No newline at end of file
diff --git a/static/js/plugins/flot/flot-data.js b/static/js/plugins/flot/flot-data.js
deleted file mode 100755
index b6d68fc..0000000
--- a/static/js/plugins/flot/flot-data.js
+++ /dev/null
@@ -1,1244 +0,0 @@
-// Flot Charts sample data for SB Admin template
-
-// Flot Line Chart with Tooltips
-$(document).ready(function() {
-    console.log("document ready");
-    var offset = 0;
-    plot();
-
-    function plot() {
-        var sin = [],
-            cos = [];
-        for (var i = 0; i < 12; i += 0.2) {
-            sin.push([i, Math.sin(i + offset)]);
-            cos.push([i, Math.cos(i + offset)]);
-        }
-
-        var options = {
-            series: {
-                lines: {
-                    show: true
-                },
-                points: {
-                    show: true
-                }
-            },
-            grid: {
-                hoverable: true //IMPORTANT! this is needed for tooltip to work
-            },
-            yaxis: {
-                min: -1.2,
-                max: 1.2
-            },
-            tooltip: true,
-            tooltipOpts: {
-                content: "'%s' of %x.1 is %y.4",
-                shifts: {
-                    x: -60,
-                    y: 25
-                }
-            }
-        };
-
-        var plotObj = $.plot($("#flot-line-chart"), [{
-                data: sin,
-                label: "sin(x)"
-            }, {
-                data: cos,
-                label: "cos(x)"
-            }],
-            options);
-    }
-});
-
-// Flot Pie Chart with Tooltips
-$(function() {
-
-    var data = [{
-        label: "Series 0",
-        data: 1
-    }, {
-        label: "Series 1",
-        data: 3
-    }, {
-        label: "Series 2",
-        data: 9
-    }, {
-        label: "Series 3",
-        data: 20
-    }];
-
-    var plotObj = $.plot($("#flot-pie-chart"), data, {
-        series: {
-            pie: {
-                show: true
-            }
-        },
-        grid: {
-            hoverable: true
-        },
-        tooltip: true,
-        tooltipOpts: {
-            content: "%p.0%, %s", // show percentages, rounding to 2 decimal places
-            shifts: {
-                x: 20,
-                y: 0
-            },
-            defaultTheme: false
-        }
-    });
-
-});
-
-// Flot Line Charts - Multiple Axes - With Data
-$(function() {
-    var oilprices = [
-        [1167692400000, 61.05],
-        [1167778800000, 58.32],
-        [1167865200000, 57.35],
-        [1167951600000, 56.31],
-        [1168210800000, 55.55],
-        [1168297200000, 55.64],
-        [1168383600000, 54.02],
-        [1168470000000, 51.88],
-        [1168556400000, 52.99],
-        [1168815600000, 52.99],
-        [1168902000000, 51.21],
-        [1168988400000, 52.24],
-        [1169074800000, 50.48],
-        [1169161200000, 51.99],
-        [1169420400000, 51.13],
-        [1169506800000, 55.04],
-        [1169593200000, 55.37],
-        [1169679600000, 54.23],
-        [1169766000000, 55.42],
-        [1170025200000, 54.01],
-        [1170111600000, 56.97],
-        [1170198000000, 58.14],
-        [1170284400000, 58.14],
-        [1170370800000, 59.02],
-        [1170630000000, 58.74],
-        [1170716400000, 58.88],
-        [1170802800000, 57.71],
-        [1170889200000, 59.71],
-        [1170975600000, 59.89],
-        [1171234800000, 57.81],
-        [1171321200000, 59.06],
-        [1171407600000, 58.00],
-        [1171494000000, 57.99],
-        [1171580400000, 59.39],
-        [1171839600000, 59.39],
-        [1171926000000, 58.07],
-        [1172012400000, 60.07],
-        [1172098800000, 61.14],
-        [1172444400000, 61.39],
-        [1172530800000, 61.46],
-        [1172617200000, 61.79],
-        [1172703600000, 62.00],
-        [1172790000000, 60.07],
-        [1173135600000, 60.69],
-        [1173222000000, 61.82],
-        [1173308400000, 60.05],
-        [1173654000000, 58.91],
-        [1173740400000, 57.93],
-        [1173826800000, 58.16],
-        [1173913200000, 57.55],
-        [1173999600000, 57.11],
-        [1174258800000, 56.59],
-        [1174345200000, 59.61],
-        [1174518000000, 61.69],
-        [1174604400000, 62.28],
-        [1174860000000, 62.91],
-        [1174946400000, 62.93],
-        [1175032800000, 64.03],
-        [1175119200000, 66.03],
-        [1175205600000, 65.87],
-        [1175464800000, 64.64],
-        [1175637600000, 64.38],
-        [1175724000000, 64.28],
-        [1175810400000, 64.28],
-        [1176069600000, 61.51],
-        [1176156000000, 61.89],
-        [1176242400000, 62.01],
-        [1176328800000, 63.85],
-        [1176415200000, 63.63],
-        [1176674400000, 63.61],
-        [1176760800000, 63.10],
-        [1176847200000, 63.13],
-        [1176933600000, 61.83],
-        [1177020000000, 63.38],
-        [1177279200000, 64.58],
-        [1177452000000, 65.84],
-        [1177538400000, 65.06],
-        [1177624800000, 66.46],
-        [1177884000000, 64.40],
-        [1178056800000, 63.68],
-        [1178143200000, 63.19],
-        [1178229600000, 61.93],
-        [1178488800000, 61.47],
-        [1178575200000, 61.55],
-        [1178748000000, 61.81],
-        [1178834400000, 62.37],
-        [1179093600000, 62.46],
-        [1179180000000, 63.17],
-        [1179266400000, 62.55],
-        [1179352800000, 64.94],
-        [1179698400000, 66.27],
-        [1179784800000, 65.50],
-        [1179871200000, 65.77],
-        [1179957600000, 64.18],
-        [1180044000000, 65.20],
-        [1180389600000, 63.15],
-        [1180476000000, 63.49],
-        [1180562400000, 65.08],
-        [1180908000000, 66.30],
-        [1180994400000, 65.96],
-        [1181167200000, 66.93],
-        [1181253600000, 65.98],
-        [1181599200000, 65.35],
-        [1181685600000, 66.26],
-        [1181858400000, 68.00],
-        [1182117600000, 69.09],
-        [1182204000000, 69.10],
-        [1182290400000, 68.19],
-        [1182376800000, 68.19],
-        [1182463200000, 69.14],
-        [1182722400000, 68.19],
-        [1182808800000, 67.77],
-        [1182895200000, 68.97],
-        [1182981600000, 69.57],
-        [1183068000000, 70.68],
-        [1183327200000, 71.09],
-        [1183413600000, 70.92],
-        [1183586400000, 71.81],
-        [1183672800000, 72.81],
-        [1183932000000, 72.19],
-        [1184018400000, 72.56],
-        [1184191200000, 72.50],
-        [1184277600000, 74.15],
-        [1184623200000, 75.05],
-        [1184796000000, 75.92],
-        [1184882400000, 75.57],
-        [1185141600000, 74.89],
-        [1185228000000, 73.56],
-        [1185314400000, 75.57],
-        [1185400800000, 74.95],
-        [1185487200000, 76.83],
-        [1185832800000, 78.21],
-        [1185919200000, 76.53],
-        [1186005600000, 76.86],
-        [1186092000000, 76.00],
-        [1186437600000, 71.59],
-        [1186696800000, 71.47],
-        [1186956000000, 71.62],
-        [1187042400000, 71.00],
-        [1187301600000, 71.98],
-        [1187560800000, 71.12],
-        [1187647200000, 69.47],
-        [1187733600000, 69.26],
-        [1187820000000, 69.83],
-        [1187906400000, 71.09],
-        [1188165600000, 71.73],
-        [1188338400000, 73.36],
-        [1188511200000, 74.04],
-        [1188856800000, 76.30],
-        [1189116000000, 77.49],
-        [1189461600000, 78.23],
-        [1189548000000, 79.91],
-        [1189634400000, 80.09],
-        [1189720800000, 79.10],
-        [1189980000000, 80.57],
-        [1190066400000, 81.93],
-        [1190239200000, 83.32],
-        [1190325600000, 81.62],
-        [1190584800000, 80.95],
-        [1190671200000, 79.53],
-        [1190757600000, 80.30],
-        [1190844000000, 82.88],
-        [1190930400000, 81.66],
-        [1191189600000, 80.24],
-        [1191276000000, 80.05],
-        [1191362400000, 79.94],
-        [1191448800000, 81.44],
-        [1191535200000, 81.22],
-        [1191794400000, 79.02],
-        [1191880800000, 80.26],
-        [1191967200000, 80.30],
-        [1192053600000, 83.08],
-        [1192140000000, 83.69],
-        [1192399200000, 86.13],
-        [1192485600000, 87.61],
-        [1192572000000, 87.40],
-        [1192658400000, 89.47],
-        [1192744800000, 88.60],
-        [1193004000000, 87.56],
-        [1193090400000, 87.56],
-        [1193176800000, 87.10],
-        [1193263200000, 91.86],
-        [1193612400000, 93.53],
-        [1193698800000, 94.53],
-        [1193871600000, 95.93],
-        [1194217200000, 93.98],
-        [1194303600000, 96.37],
-        [1194476400000, 95.46],
-        [1194562800000, 96.32],
-        [1195081200000, 93.43],
-        [1195167600000, 95.10],
-        [1195426800000, 94.64],
-        [1195513200000, 95.10],
-        [1196031600000, 97.70],
-        [1196118000000, 94.42],
-        [1196204400000, 90.62],
-        [1196290800000, 91.01],
-        [1196377200000, 88.71],
-        [1196636400000, 88.32],
-        [1196809200000, 90.23],
-        [1196982000000, 88.28],
-        [1197241200000, 87.86],
-        [1197327600000, 90.02],
-        [1197414000000, 92.25],
-        [1197586800000, 90.63],
-        [1197846000000, 90.63],
-        [1197932400000, 90.49],
-        [1198018800000, 91.24],
-        [1198105200000, 91.06],
-        [1198191600000, 90.49],
-        [1198710000000, 96.62],
-        [1198796400000, 96.00],
-        [1199142000000, 99.62],
-        [1199314800000, 99.18],
-        [1199401200000, 95.09],
-        [1199660400000, 96.33],
-        [1199833200000, 95.67],
-        [1200351600000, 91.90],
-        [1200438000000, 90.84],
-        [1200524400000, 90.13],
-        [1200610800000, 90.57],
-        [1200956400000, 89.21],
-        [1201042800000, 86.99],
-        [1201129200000, 89.85],
-        [1201474800000, 90.99],
-        [1201561200000, 91.64],
-        [1201647600000, 92.33],
-        [1201734000000, 91.75],
-        [1202079600000, 90.02],
-        [1202166000000, 88.41],
-        [1202252400000, 87.14],
-        [1202338800000, 88.11],
-        [1202425200000, 91.77],
-        [1202770800000, 92.78],
-        [1202857200000, 93.27],
-        [1202943600000, 95.46],
-        [1203030000000, 95.46],
-        [1203289200000, 101.74],
-        [1203462000000, 98.81],
-        [1203894000000, 100.88],
-        [1204066800000, 99.64],
-        [1204153200000, 102.59],
-        [1204239600000, 101.84],
-        [1204498800000, 99.52],
-        [1204585200000, 99.52],
-        [1204671600000, 104.52],
-        [1204758000000, 105.47],
-        [1204844400000, 105.15],
-        [1205103600000, 108.75],
-        [1205276400000, 109.92],
-        [1205362800000, 110.33],
-        [1205449200000, 110.21],
-        [1205708400000, 105.68],
-        [1205967600000, 101.84],
-        [1206313200000, 100.86],
-        [1206399600000, 101.22],
-        [1206486000000, 105.90],
-        [1206572400000, 107.58],
-        [1206658800000, 105.62],
-        [1206914400000, 101.58],
-        [1207000800000, 100.98],
-        [1207173600000, 103.83],
-        [1207260000000, 106.23],
-        [1207605600000, 108.50],
-        [1207778400000, 110.11],
-        [1207864800000, 110.14],
-        [1208210400000, 113.79],
-        [1208296800000, 114.93],
-        [1208383200000, 114.86],
-        [1208728800000, 117.48],
-        [1208815200000, 118.30],
-        [1208988000000, 116.06],
-        [1209074400000, 118.52],
-        [1209333600000, 118.75],
-        [1209420000000, 113.46],
-        [1209592800000, 112.52],
-        [1210024800000, 121.84],
-        [1210111200000, 123.53],
-        [1210197600000, 123.69],
-        [1210543200000, 124.23],
-        [1210629600000, 125.80],
-        [1210716000000, 126.29],
-        [1211148000000, 127.05],
-        [1211320800000, 129.07],
-        [1211493600000, 132.19],
-        [1211839200000, 128.85],
-        [1212357600000, 127.76],
-        [1212703200000, 138.54],
-        [1212962400000, 136.80],
-        [1213135200000, 136.38],
-        [1213308000000, 134.86],
-        [1213653600000, 134.01],
-        [1213740000000, 136.68],
-        [1213912800000, 135.65],
-        [1214172000000, 134.62],
-        [1214258400000, 134.62],
-        [1214344800000, 134.62],
-        [1214431200000, 139.64],
-        [1214517600000, 140.21],
-        [1214776800000, 140.00],
-        [1214863200000, 140.97],
-        [1214949600000, 143.57],
-        [1215036000000, 145.29],
-        [1215381600000, 141.37],
-        [1215468000000, 136.04],
-        [1215727200000, 146.40],
-        [1215986400000, 145.18],
-        [1216072800000, 138.74],
-        [1216159200000, 134.60],
-        [1216245600000, 129.29],
-        [1216332000000, 130.65],
-        [1216677600000, 127.95],
-        [1216850400000, 127.95],
-        [1217282400000, 122.19],
-        [1217455200000, 124.08],
-        [1217541600000, 125.10],
-        [1217800800000, 121.41],
-        [1217887200000, 119.17],
-        [1217973600000, 118.58],
-        [1218060000000, 120.02],
-        [1218405600000, 114.45],
-        [1218492000000, 113.01],
-        [1218578400000, 116.00],
-        [1218751200000, 113.77],
-        [1219010400000, 112.87],
-        [1219096800000, 114.53],
-        [1219269600000, 114.98],
-        [1219356000000, 114.98],
-        [1219701600000, 116.27],
-        [1219788000000, 118.15],
-        [1219874400000, 115.59],
-        [1219960800000, 115.46],
-        [1220306400000, 109.71],
-        [1220392800000, 109.35],
-        [1220565600000, 106.23],
-        [1220824800000, 106.34]
-    ];
-    var exchangerates = [
-        [1167606000000, 0.7580],
-        [1167692400000, 0.7580],
-        [1167778800000, 0.75470],
-        [1167865200000, 0.75490],
-        [1167951600000, 0.76130],
-        [1168038000000, 0.76550],
-        [1168124400000, 0.76930],
-        [1168210800000, 0.76940],
-        [1168297200000, 0.76880],
-        [1168383600000, 0.76780],
-        [1168470000000, 0.77080],
-        [1168556400000, 0.77270],
-        [1168642800000, 0.77490],
-        [1168729200000, 0.77410],
-        [1168815600000, 0.77410],
-        [1168902000000, 0.77320],
-        [1168988400000, 0.77270],
-        [1169074800000, 0.77370],
-        [1169161200000, 0.77240],
-        [1169247600000, 0.77120],
-        [1169334000000, 0.7720],
-        [1169420400000, 0.77210],
-        [1169506800000, 0.77170],
-        [1169593200000, 0.77040],
-        [1169679600000, 0.7690],
-        [1169766000000, 0.77110],
-        [1169852400000, 0.7740],
-        [1169938800000, 0.77450],
-        [1170025200000, 0.77450],
-        [1170111600000, 0.7740],
-        [1170198000000, 0.77160],
-        [1170284400000, 0.77130],
-        [1170370800000, 0.76780],
-        [1170457200000, 0.76880],
-        [1170543600000, 0.77180],
-        [1170630000000, 0.77180],
-        [1170716400000, 0.77280],
-        [1170802800000, 0.77290],
-        [1170889200000, 0.76980],
-        [1170975600000, 0.76850],
-        [1171062000000, 0.76810],
-        [1171148400000, 0.7690],
-        [1171234800000, 0.7690],
-        [1171321200000, 0.76980],
-        [1171407600000, 0.76990],
-        [1171494000000, 0.76510],
-        [1171580400000, 0.76130],
-        [1171666800000, 0.76160],
-        [1171753200000, 0.76140],
-        [1171839600000, 0.76140],
-        [1171926000000, 0.76070],
-        [1172012400000, 0.76020],
-        [1172098800000, 0.76110],
-        [1172185200000, 0.76220],
-        [1172271600000, 0.76150],
-        [1172358000000, 0.75980],
-        [1172444400000, 0.75980],
-        [1172530800000, 0.75920],
-        [1172617200000, 0.75730],
-        [1172703600000, 0.75660],
-        [1172790000000, 0.75670],
-        [1172876400000, 0.75910],
-        [1172962800000, 0.75820],
-        [1173049200000, 0.75850],
-        [1173135600000, 0.76130],
-        [1173222000000, 0.76310],
-        [1173308400000, 0.76150],
-        [1173394800000, 0.760],
-        [1173481200000, 0.76130],
-        [1173567600000, 0.76270],
-        [1173654000000, 0.76270],
-        [1173740400000, 0.76080],
-        [1173826800000, 0.75830],
-        [1173913200000, 0.75750],
-        [1173999600000, 0.75620],
-        [1174086000000, 0.7520],
-        [1174172400000, 0.75120],
-        [1174258800000, 0.75120],
-        [1174345200000, 0.75170],
-        [1174431600000, 0.7520],
-        [1174518000000, 0.75110],
-        [1174604400000, 0.7480],
-        [1174690800000, 0.75090],
-        [1174777200000, 0.75310],
-        [1174860000000, 0.75310],
-        [1174946400000, 0.75270],
-        [1175032800000, 0.74980],
-        [1175119200000, 0.74930],
-        [1175205600000, 0.75040],
-        [1175292000000, 0.750],
-        [1175378400000, 0.74910],
-        [1175464800000, 0.74910],
-        [1175551200000, 0.74850],
-        [1175637600000, 0.74840],
-        [1175724000000, 0.74920],
-        [1175810400000, 0.74710],
-        [1175896800000, 0.74590],
-        [1175983200000, 0.74770],
-        [1176069600000, 0.74770],
-        [1176156000000, 0.74830],
-        [1176242400000, 0.74580],
-        [1176328800000, 0.74480],
-        [1176415200000, 0.7430],
-        [1176501600000, 0.73990],
-        [1176588000000, 0.73950],
-        [1176674400000, 0.73950],
-        [1176760800000, 0.73780],
-        [1176847200000, 0.73820],
-        [1176933600000, 0.73620],
-        [1177020000000, 0.73550],
-        [1177106400000, 0.73480],
-        [1177192800000, 0.73610],
-        [1177279200000, 0.73610],
-        [1177365600000, 0.73650],
-        [1177452000000, 0.73620],
-        [1177538400000, 0.73310],
-        [1177624800000, 0.73390],
-        [1177711200000, 0.73440],
-        [1177797600000, 0.73270],
-        [1177884000000, 0.73270],
-        [1177970400000, 0.73360],
-        [1178056800000, 0.73330],
-        [1178143200000, 0.73590],
-        [1178229600000, 0.73590],
-        [1178316000000, 0.73720],
-        [1178402400000, 0.7360],
-        [1178488800000, 0.7360],
-        [1178575200000, 0.7350],
-        [1178661600000, 0.73650],
-        [1178748000000, 0.73840],
-        [1178834400000, 0.73950],
-        [1178920800000, 0.74130],
-        [1179007200000, 0.73970],
-        [1179093600000, 0.73960],
-        [1179180000000, 0.73850],
-        [1179266400000, 0.73780],
-        [1179352800000, 0.73660],
-        [1179439200000, 0.740],
-        [1179525600000, 0.74110],
-        [1179612000000, 0.74060],
-        [1179698400000, 0.74050],
-        [1179784800000, 0.74140],
-        [1179871200000, 0.74310],
-        [1179957600000, 0.74310],
-        [1180044000000, 0.74380],
-        [1180130400000, 0.74430],
-        [1180216800000, 0.74430],
-        [1180303200000, 0.74430],
-        [1180389600000, 0.74340],
-        [1180476000000, 0.74290],
-        [1180562400000, 0.74420],
-        [1180648800000, 0.7440],
-        [1180735200000, 0.74390],
-        [1180821600000, 0.74370],
-        [1180908000000, 0.74370],
-        [1180994400000, 0.74290],
-        [1181080800000, 0.74030],
-        [1181167200000, 0.73990],
-        [1181253600000, 0.74180],
-        [1181340000000, 0.74680],
-        [1181426400000, 0.7480],
-        [1181512800000, 0.7480],
-        [1181599200000, 0.7490],
-        [1181685600000, 0.74940],
-        [1181772000000, 0.75220],
-        [1181858400000, 0.75150],
-        [1181944800000, 0.75020],
-        [1182031200000, 0.74720],
-        [1182117600000, 0.74720],
-        [1182204000000, 0.74620],
-        [1182290400000, 0.74550],
-        [1182376800000, 0.74490],
-        [1182463200000, 0.74670],
-        [1182549600000, 0.74580],
-        [1182636000000, 0.74270],
-        [1182722400000, 0.74270],
-        [1182808800000, 0.7430],
-        [1182895200000, 0.74290],
-        [1182981600000, 0.7440],
-        [1183068000000, 0.7430],
-        [1183154400000, 0.74220],
-        [1183240800000, 0.73880],
-        [1183327200000, 0.73880],
-        [1183413600000, 0.73690],
-        [1183500000000, 0.73450],
-        [1183586400000, 0.73450],
-        [1183672800000, 0.73450],
-        [1183759200000, 0.73520],
-        [1183845600000, 0.73410],
-        [1183932000000, 0.73410],
-        [1184018400000, 0.7340],
-        [1184104800000, 0.73240],
-        [1184191200000, 0.72720],
-        [1184277600000, 0.72640],
-        [1184364000000, 0.72550],
-        [1184450400000, 0.72580],
-        [1184536800000, 0.72580],
-        [1184623200000, 0.72560],
-        [1184709600000, 0.72570],
-        [1184796000000, 0.72470],
-        [1184882400000, 0.72430],
-        [1184968800000, 0.72440],
-        [1185055200000, 0.72350],
-        [1185141600000, 0.72350],
-        [1185228000000, 0.72350],
-        [1185314400000, 0.72350],
-        [1185400800000, 0.72620],
-        [1185487200000, 0.72880],
-        [1185573600000, 0.73010],
-        [1185660000000, 0.73370],
-        [1185746400000, 0.73370],
-        [1185832800000, 0.73240],
-        [1185919200000, 0.72970],
-        [1186005600000, 0.73170],
-        [1186092000000, 0.73150],
-        [1186178400000, 0.72880],
-        [1186264800000, 0.72630],
-        [1186351200000, 0.72630],
-        [1186437600000, 0.72420],
-        [1186524000000, 0.72530],
-        [1186610400000, 0.72640],
-        [1186696800000, 0.7270],
-        [1186783200000, 0.73120],
-        [1186869600000, 0.73050],
-        [1186956000000, 0.73050],
-        [1187042400000, 0.73180],
-        [1187128800000, 0.73580],
-        [1187215200000, 0.74090],
-        [1187301600000, 0.74540],
-        [1187388000000, 0.74370],
-        [1187474400000, 0.74240],
-        [1187560800000, 0.74240],
-        [1187647200000, 0.74150],
-        [1187733600000, 0.74190],
-        [1187820000000, 0.74140],
-        [1187906400000, 0.73770],
-        [1187992800000, 0.73550],
-        [1188079200000, 0.73150],
-        [1188165600000, 0.73150],
-        [1188252000000, 0.7320],
-        [1188338400000, 0.73320],
-        [1188424800000, 0.73460],
-        [1188511200000, 0.73280],
-        [1188597600000, 0.73230],
-        [1188684000000, 0.7340],
-        [1188770400000, 0.7340],
-        [1188856800000, 0.73360],
-        [1188943200000, 0.73510],
-        [1189029600000, 0.73460],
-        [1189116000000, 0.73210],
-        [1189202400000, 0.72940],
-        [1189288800000, 0.72660],
-        [1189375200000, 0.72660],
-        [1189461600000, 0.72540],
-        [1189548000000, 0.72420],
-        [1189634400000, 0.72130],
-        [1189720800000, 0.71970],
-        [1189807200000, 0.72090],
-        [1189893600000, 0.7210],
-        [1189980000000, 0.7210],
-        [1190066400000, 0.7210],
-        [1190152800000, 0.72090],
-        [1190239200000, 0.71590],
-        [1190325600000, 0.71330],
-        [1190412000000, 0.71050],
-        [1190498400000, 0.70990],
-        [1190584800000, 0.70990],
-        [1190671200000, 0.70930],
-        [1190757600000, 0.70930],
-        [1190844000000, 0.70760],
-        [1190930400000, 0.7070],
-        [1191016800000, 0.70490],
-        [1191103200000, 0.70120],
-        [1191189600000, 0.70110],
-        [1191276000000, 0.70190],
-        [1191362400000, 0.70460],
-        [1191448800000, 0.70630],
-        [1191535200000, 0.70890],
-        [1191621600000, 0.70770],
-        [1191708000000, 0.70770],
-        [1191794400000, 0.70770],
-        [1191880800000, 0.70910],
-        [1191967200000, 0.71180],
-        [1192053600000, 0.70790],
-        [1192140000000, 0.70530],
-        [1192226400000, 0.7050],
-        [1192312800000, 0.70550],
-        [1192399200000, 0.70550],
-        [1192485600000, 0.70450],
-        [1192572000000, 0.70510],
-        [1192658400000, 0.70510],
-        [1192744800000, 0.70170],
-        [1192831200000, 0.70],
-        [1192917600000, 0.69950],
-        [1193004000000, 0.69940],
-        [1193090400000, 0.70140],
-        [1193176800000, 0.70360],
-        [1193263200000, 0.70210],
-        [1193349600000, 0.70020],
-        [1193436000000, 0.69670],
-        [1193522400000, 0.6950],
-        [1193612400000, 0.6950],
-        [1193698800000, 0.69390],
-        [1193785200000, 0.6940],
-        [1193871600000, 0.69220],
-        [1193958000000, 0.69190],
-        [1194044400000, 0.69140],
-        [1194130800000, 0.68940],
-        [1194217200000, 0.68910],
-        [1194303600000, 0.69040],
-        [1194390000000, 0.6890],
-        [1194476400000, 0.68340],
-        [1194562800000, 0.68230],
-        [1194649200000, 0.68070],
-        [1194735600000, 0.68150],
-        [1194822000000, 0.68150],
-        [1194908400000, 0.68470],
-        [1194994800000, 0.68590],
-        [1195081200000, 0.68220],
-        [1195167600000, 0.68270],
-        [1195254000000, 0.68370],
-        [1195340400000, 0.68230],
-        [1195426800000, 0.68220],
-        [1195513200000, 0.68220],
-        [1195599600000, 0.67920],
-        [1195686000000, 0.67460],
-        [1195772400000, 0.67350],
-        [1195858800000, 0.67310],
-        [1195945200000, 0.67420],
-        [1196031600000, 0.67440],
-        [1196118000000, 0.67390],
-        [1196204400000, 0.67310],
-        [1196290800000, 0.67610],
-        [1196377200000, 0.67610],
-        [1196463600000, 0.67850],
-        [1196550000000, 0.68180],
-        [1196636400000, 0.68360],
-        [1196722800000, 0.68230],
-        [1196809200000, 0.68050],
-        [1196895600000, 0.67930],
-        [1196982000000, 0.68490],
-        [1197068400000, 0.68330],
-        [1197154800000, 0.68250],
-        [1197241200000, 0.68250],
-        [1197327600000, 0.68160],
-        [1197414000000, 0.67990],
-        [1197500400000, 0.68130],
-        [1197586800000, 0.68090],
-        [1197673200000, 0.68680],
-        [1197759600000, 0.69330],
-        [1197846000000, 0.69330],
-        [1197932400000, 0.69450],
-        [1198018800000, 0.69440],
-        [1198105200000, 0.69460],
-        [1198191600000, 0.69640],
-        [1198278000000, 0.69650],
-        [1198364400000, 0.69560],
-        [1198450800000, 0.69560],
-        [1198537200000, 0.6950],
-        [1198623600000, 0.69480],
-        [1198710000000, 0.69280],
-        [1198796400000, 0.68870],
-        [1198882800000, 0.68240],
-        [1198969200000, 0.67940],
-        [1199055600000, 0.67940],
-        [1199142000000, 0.68030],
-        [1199228400000, 0.68550],
-        [1199314800000, 0.68240],
-        [1199401200000, 0.67910],
-        [1199487600000, 0.67830],
-        [1199574000000, 0.67850],
-        [1199660400000, 0.67850],
-        [1199746800000, 0.67970],
-        [1199833200000, 0.680],
-        [1199919600000, 0.68030],
-        [1200006000000, 0.68050],
-        [1200092400000, 0.6760],
-        [1200178800000, 0.6770],
-        [1200265200000, 0.6770],
-        [1200351600000, 0.67360],
-        [1200438000000, 0.67260],
-        [1200524400000, 0.67640],
-        [1200610800000, 0.68210],
-        [1200697200000, 0.68310],
-        [1200783600000, 0.68420],
-        [1200870000000, 0.68420],
-        [1200956400000, 0.68870],
-        [1201042800000, 0.69030],
-        [1201129200000, 0.68480],
-        [1201215600000, 0.68240],
-        [1201302000000, 0.67880],
-        [1201388400000, 0.68140],
-        [1201474800000, 0.68140],
-        [1201561200000, 0.67970],
-        [1201647600000, 0.67690],
-        [1201734000000, 0.67650],
-        [1201820400000, 0.67330],
-        [1201906800000, 0.67290],
-        [1201993200000, 0.67580],
-        [1202079600000, 0.67580],
-        [1202166000000, 0.6750],
-        [1202252400000, 0.6780],
-        [1202338800000, 0.68330],
-        [1202425200000, 0.68560],
-        [1202511600000, 0.69030],
-        [1202598000000, 0.68960],
-        [1202684400000, 0.68960],
-        [1202770800000, 0.68820],
-        [1202857200000, 0.68790],
-        [1202943600000, 0.68620],
-        [1203030000000, 0.68520],
-        [1203116400000, 0.68230],
-        [1203202800000, 0.68130],
-        [1203289200000, 0.68130],
-        [1203375600000, 0.68220],
-        [1203462000000, 0.68020],
-        [1203548400000, 0.68020],
-        [1203634800000, 0.67840],
-        [1203721200000, 0.67480],
-        [1203807600000, 0.67470],
-        [1203894000000, 0.67470],
-        [1203980400000, 0.67480],
-        [1204066800000, 0.67330],
-        [1204153200000, 0.6650],
-        [1204239600000, 0.66110],
-        [1204326000000, 0.65830],
-        [1204412400000, 0.6590],
-        [1204498800000, 0.6590],
-        [1204585200000, 0.65810],
-        [1204671600000, 0.65780],
-        [1204758000000, 0.65740],
-        [1204844400000, 0.65320],
-        [1204930800000, 0.65020],
-        [1205017200000, 0.65140],
-        [1205103600000, 0.65140],
-        [1205190000000, 0.65070],
-        [1205276400000, 0.6510],
-        [1205362800000, 0.64890],
-        [1205449200000, 0.64240],
-        [1205535600000, 0.64060],
-        [1205622000000, 0.63820],
-        [1205708400000, 0.63820],
-        [1205794800000, 0.63410],
-        [1205881200000, 0.63440],
-        [1205967600000, 0.63780],
-        [1206054000000, 0.64390],
-        [1206140400000, 0.64780],
-        [1206226800000, 0.64810],
-        [1206313200000, 0.64810],
-        [1206399600000, 0.64940],
-        [1206486000000, 0.64380],
-        [1206572400000, 0.63770],
-        [1206658800000, 0.63290],
-        [1206745200000, 0.63360],
-        [1206831600000, 0.63330],
-        [1206914400000, 0.63330],
-        [1207000800000, 0.6330],
-        [1207087200000, 0.63710],
-        [1207173600000, 0.64030],
-        [1207260000000, 0.63960],
-        [1207346400000, 0.63640],
-        [1207432800000, 0.63560],
-        [1207519200000, 0.63560],
-        [1207605600000, 0.63680],
-        [1207692000000, 0.63570],
-        [1207778400000, 0.63540],
-        [1207864800000, 0.6320],
-        [1207951200000, 0.63320],
-        [1208037600000, 0.63280],
-        [1208124000000, 0.63310],
-        [1208210400000, 0.63420],
-        [1208296800000, 0.63210],
-        [1208383200000, 0.63020],
-        [1208469600000, 0.62780],
-        [1208556000000, 0.63080],
-        [1208642400000, 0.63240],
-        [1208728800000, 0.63240],
-        [1208815200000, 0.63070],
-        [1208901600000, 0.62770],
-        [1208988000000, 0.62690],
-        [1209074400000, 0.63350],
-        [1209160800000, 0.63920],
-        [1209247200000, 0.640],
-        [1209333600000, 0.64010],
-        [1209420000000, 0.63960],
-        [1209506400000, 0.64070],
-        [1209592800000, 0.64230],
-        [1209679200000, 0.64290],
-        [1209765600000, 0.64720],
-        [1209852000000, 0.64850],
-        [1209938400000, 0.64860],
-        [1210024800000, 0.64670],
-        [1210111200000, 0.64440],
-        [1210197600000, 0.64670],
-        [1210284000000, 0.65090],
-        [1210370400000, 0.64780],
-        [1210456800000, 0.64610],
-        [1210543200000, 0.64610],
-        [1210629600000, 0.64680],
-        [1210716000000, 0.64490],
-        [1210802400000, 0.6470],
-        [1210888800000, 0.64610],
-        [1210975200000, 0.64520],
-        [1211061600000, 0.64220],
-        [1211148000000, 0.64220],
-        [1211234400000, 0.64250],
-        [1211320800000, 0.64140],
-        [1211407200000, 0.63660],
-        [1211493600000, 0.63460],
-        [1211580000000, 0.6350],
-        [1211666400000, 0.63460],
-        [1211752800000, 0.63460],
-        [1211839200000, 0.63430],
-        [1211925600000, 0.63460],
-        [1212012000000, 0.63790],
-        [1212098400000, 0.64160],
-        [1212184800000, 0.64420],
-        [1212271200000, 0.64310],
-        [1212357600000, 0.64310],
-        [1212444000000, 0.64350],
-        [1212530400000, 0.6440],
-        [1212616800000, 0.64730],
-        [1212703200000, 0.64690],
-        [1212789600000, 0.63860],
-        [1212876000000, 0.63560],
-        [1212962400000, 0.6340],
-        [1213048800000, 0.63460],
-        [1213135200000, 0.6430],
-        [1213221600000, 0.64520],
-        [1213308000000, 0.64670],
-        [1213394400000, 0.65060],
-        [1213480800000, 0.65040],
-        [1213567200000, 0.65030],
-        [1213653600000, 0.64810],
-        [1213740000000, 0.64510],
-        [1213826400000, 0.6450],
-        [1213912800000, 0.64410],
-        [1213999200000, 0.64140],
-        [1214085600000, 0.64090],
-        [1214172000000, 0.64090],
-        [1214258400000, 0.64280],
-        [1214344800000, 0.64310],
-        [1214431200000, 0.64180],
-        [1214517600000, 0.63710],
-        [1214604000000, 0.63490],
-        [1214690400000, 0.63330],
-        [1214776800000, 0.63340],
-        [1214863200000, 0.63380],
-        [1214949600000, 0.63420],
-        [1215036000000, 0.6320],
-        [1215122400000, 0.63180],
-        [1215208800000, 0.6370],
-        [1215295200000, 0.63680],
-        [1215381600000, 0.63680],
-        [1215468000000, 0.63830],
-        [1215554400000, 0.63710],
-        [1215640800000, 0.63710],
-        [1215727200000, 0.63550],
-        [1215813600000, 0.6320],
-        [1215900000000, 0.62770],
-        [1215986400000, 0.62760],
-        [1216072800000, 0.62910],
-        [1216159200000, 0.62740],
-        [1216245600000, 0.62930],
-        [1216332000000, 0.63110],
-        [1216418400000, 0.6310],
-        [1216504800000, 0.63120],
-        [1216591200000, 0.63120],
-        [1216677600000, 0.63040],
-        [1216764000000, 0.62940],
-        [1216850400000, 0.63480],
-        [1216936800000, 0.63780],
-        [1217023200000, 0.63680],
-        [1217109600000, 0.63680],
-        [1217196000000, 0.63680],
-        [1217282400000, 0.6360],
-        [1217368800000, 0.6370],
-        [1217455200000, 0.64180],
-        [1217541600000, 0.64110],
-        [1217628000000, 0.64350],
-        [1217714400000, 0.64270],
-        [1217800800000, 0.64270],
-        [1217887200000, 0.64190],
-        [1217973600000, 0.64460],
-        [1218060000000, 0.64680],
-        [1218146400000, 0.64870],
-        [1218232800000, 0.65940],
-        [1218319200000, 0.66660],
-        [1218405600000, 0.66660],
-        [1218492000000, 0.66780],
-        [1218578400000, 0.67120],
-        [1218664800000, 0.67050],
-        [1218751200000, 0.67180],
-        [1218837600000, 0.67840],
-        [1218924000000, 0.68110],
-        [1219010400000, 0.68110],
-        [1219096800000, 0.67940],
-        [1219183200000, 0.68040],
-        [1219269600000, 0.67810],
-        [1219356000000, 0.67560],
-        [1219442400000, 0.67350],
-        [1219528800000, 0.67630],
-        [1219615200000, 0.67620],
-        [1219701600000, 0.67770],
-        [1219788000000, 0.68150],
-        [1219874400000, 0.68020],
-        [1219960800000, 0.6780],
-        [1220047200000, 0.67960],
-        [1220133600000, 0.68170],
-        [1220220000000, 0.68170],
-        [1220306400000, 0.68320],
-        [1220392800000, 0.68770],
-        [1220479200000, 0.69120],
-        [1220565600000, 0.69140],
-        [1220652000000, 0.70090],
-        [1220738400000, 0.70120],
-        [1220824800000, 0.7010],
-        [1220911200000, 0.70050]
-    ];
-
-    function euroFormatter(v, axis) {
-        return v.toFixed(axis.tickDecimals) + "€";
-    }
-
-    function doPlot(position) {
-        $.plot($("#flot-multiple-axes-chart"), [{
-            data: oilprices,
-            label: "Oil price ($)"
-        }, {
-            data: exchangerates,
-            label: "USD/EUR exchange rate",
-            yaxis: 2
-        }], {
-            xaxes: [{
-                mode: 'time'
-            }],
-            yaxes: [{
-                min: 0
-            }, {
-                // align if we are to the right
-                alignTicksWithAxis: position == "right" ? 1 : null,
-                position: position,
-                tickFormatter: euroFormatter
-            }],
-            legend: {
-                position: 'sw'
-            },
-            grid: {
-                hoverable: true //IMPORTANT! this is needed for tooltip to work
-            },
-            tooltip: true,
-            tooltipOpts: {
-                content: "%s for %x was %y",
-                xDateFormat: "%y-%0m-%0d",
-
-                onHover: function(flotItem, $tooltipEl) {
-                    // console.log(flotItem, $tooltipEl);
-                }
-            }
-
-        });
-    }
-
-    doPlot("right");
-
-    $("button").click(function() {
-        doPlot($(this).text());
-    });
-});
-
-// Flot Chart Dynamic Chart
-
-$(function() {
-
-    var container = $("#flot-moving-line-chart");
-
-    // Determine how many data points to keep based on the placeholder's initial size;
-    // this gives us a nice high-res plot while avoiding more than one point per pixel.
-
-    var maximum = container.outerWidth() / 2 || 300;
-
-    //
-
-    var data = [];
-
-    function getRandomData() {
-
-        if (data.length) {
-            data = data.slice(1);
-        }
-
-        while (data.length < maximum) {
-            var previous = data.length ? data[data.length - 1] : 50;
-            var y = previous + Math.random() * 10 - 5;
-            data.push(y < 0 ? 0 : y > 100 ? 100 : y);
-        }
-
-        // zip the generated y values with the x values
-
-        var res = [];
-        for (var i = 0; i < data.length; ++i) {
-            res.push([i, data[i]])
-        }
-
-        return res;
-    }
-
-    //
-
-    series = [{
-        data: getRandomData(),
-        lines: {
-            fill: true
-        }
-    }];
-
-    //
-
-    var plot = $.plot(container, series, {
-        grid: {
-            borderWidth: 1,
-            minBorderMargin: 20,
-            labelMargin: 10,
-            backgroundColor: {
-                colors: ["#fff", "#e4f4f4"]
-            },
-            margin: {
-                top: 8,
-                bottom: 20,
-                left: 20
-            },
-            markings: function(axes) {
-                var markings = [];
-                var xaxis = axes.xaxis;
-                for (var x = Math.floor(xaxis.min); x < xaxis.max; x += xaxis.tickSize * 2) {
-                    markings.push({
-                        xaxis: {
-                            from: x,
-                            to: x + xaxis.tickSize
-                        },
-                        color: "rgba(232, 232, 255, 0.2)"
-                    });
-                }
-                return markings;
-            }
-        },
-        xaxis: {
-            tickFormatter: function() {
-                return "";
-            }
-        },
-        yaxis: {
-            min: 0,
-            max: 110
-        },
-        legend: {
-            show: true
-        }
-    });
-
-    // Update the random dataset at 25FPS for a smoothly-animating chart
-
-    setInterval(function updateRandom() {
-        series[0].data = getRandomData();
-        plot.setData(series);
-        plot.draw();
-    }, 40);
-
-});
-
-// Flot Chart Bar Graph
-
-$(function() {
-
-    var barOptions = {
-        series: {
-            bars: {
-                show: true,
-                barWidth: 43200000
-            }
-        },
-        xaxis: {
-            mode: "time",
-            timeformat: "%m/%d",
-            minTickSize: [1, "day"]
-        },
-        grid: {
-            hoverable: true
-        },
-        legend: {
-            show: false
-        },
-        tooltip: true,
-        tooltipOpts: {
-            content: "x: %x, y: %y"
-        }
-    };
-    var barData = {
-        label: "bar",
-        data: [
-            [1354521600000, 1000],
-            [1355040000000, 2000],
-            [1355223600000, 3000],
-            [1355306400000, 4000],
-            [1355487300000, 5000],
-            [1355571900000, 6000]
-        ]
-    };
-    $.plot($("#flot-bar-chart"), [barData], barOptions);
-
-});
diff --git a/static/js/plugins/flot/jquery.flot.js b/static/js/plugins/flot/jquery.flot.js
deleted file mode 100755
index aabc544..0000000
--- a/static/js/plugins/flot/jquery.flot.js
+++ /dev/null
@@ -1,2599 +0,0 @@
-/*! Javascript plotting library for jQuery, v. 0.7.
- *
- * Released under the MIT license by IOLA, December 2007.
- *
- */
-
-// first an inline dependency, jquery.colorhelpers.js, we inline it here
-// for convenience
-
-/* Plugin for jQuery for working with colors.
- * 
- * Version 1.1.
- * 
- * Inspiration from jQuery color animation plugin by John Resig.
- *
- * Released under the MIT license by Ole Laursen, October 2009.
- *
- * Examples:
- *
- *   $.color.parse("#fff").scale('rgb', 0.25).add('a', -0.5).toString()
- *   var c = $.color.extract($("#mydiv"), 'background-color');
- *   console.log(c.r, c.g, c.b, c.a);
- *   $.color.make(100, 50, 25, 0.4).toString() // returns "rgba(100,50,25,0.4)"
- *
- * Note that .scale() and .add() return the same modified object
- * instead of making a new one.
- *
- * V. 1.1: Fix error handling so e.g. parsing an empty string does
- * produce a color rather than just crashing.
- */ 
-(function(B){B.color={};B.color.make=function(F,E,C,D){var G={};G.r=F||0;G.g=E||0;G.b=C||0;G.a=D!=null?D:1;G.add=function(J,I){for(var H=0;H<J.length;++H){G[J.charAt(H)]+=I}return G.normalize()};G.scale=function(J,I){for(var H=0;H<J.length;++H){G[J.charAt(H)]*=I}return G.normalize()};G.toString=function(){if(G.a>=1){return"rgb("+[G.r,G.g,G.b].join(",")+")"}else{return"rgba("+[G.r,G.g,G.b,G.a].join(",")+")"}};G.normalize=function(){function H(J,K,I){return K<J?J:(K>I?I:K)}G.r=H(0,parseInt(G.r),255);G.g=H(0,parseInt(G.g),255);G.b=H(0,parseInt(G.b),255);G.a=H(0,G.a,1);return G};G.clone=function(){return B.color.make(G.r,G.b,G.g,G.a)};return G.normalize()};B.color.extract=function(D,C){var E;do{E=D.css(C).toLowerCase();if(E!=""&&E!="transparent"){break}D=D.parent()}while(!B.nodeName(D.get(0),"body"));if(E=="rgba(0, 0, 0, 0)"){E="transparent"}return B.color.parse(E)};B.color.parse=function(F){var E,C=B.color.make;if(E=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(F)){return C(parseInt(E[1],10),parseInt(E[2],10),parseInt(E[3],10))}if(E=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(F)){return C(parseInt(E[1],10),parseInt(E[2],10),parseInt(E[3],10),parseFloat(E[4]))}if(E=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(F)){return C(parseFloat(E[1])*2.55,parseFloat(E[2])*2.55,parseFloat(E[3])*2.55)}if(E=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(F)){return C(parseFloat(E[1])*2.55,parseFloat(E[2])*2.55,parseFloat(E[3])*2.55,parseFloat(E[4]))}if(E=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(F)){return C(parseInt(E[1],16),parseInt(E[2],16),parseInt(E[3],16))}if(E=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(F)){return C(parseInt(E[1]+E[1],16),parseInt(E[2]+E[2],16),parseInt(E[3]+E[3],16))}var D=B.trim(F).toLowerCase();if(D=="transparent"){return C(255,255,255,0)}else{E=A[D]||[0,0,0];return C(E[0],E[1],E[2])}};var A={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(jQuery);
-
-// the actual Flot code
-(function($) {
-    function Plot(placeholder, data_, options_, plugins) {
-        // data is on the form:
-        //   [ series1, series2 ... ]
-        // where series is either just the data as [ [x1, y1], [x2, y2], ... ]
-        // or { data: [ [x1, y1], [x2, y2], ... ], label: "some label", ... }
-        
-        var series = [],
-            options = {
-                // the color theme used for graphs
-                colors: ["#edc240", "#afd8f8", "#cb4b4b", "#4da74d", "#9440ed"],
-                legend: {
-                    show: true,
-                    noColumns: 1, // number of colums in legend table
-                    labelFormatter: null, // fn: string -> string
-                    labelBoxBorderColor: "#ccc", // border color for the little label boxes
-                    container: null, // container (as jQuery object) to put legend in, null means default on top of graph
-                    position: "ne", // position of default legend container within plot
-                    margin: 5, // distance from grid edge to default legend container within plot
-                    backgroundColor: null, // null means auto-detect
-                    backgroundOpacity: 0.85 // set to 0 to avoid background
-                },
-                xaxis: {
-                    show: null, // null = auto-detect, true = always, false = never
-                    position: "bottom", // or "top"
-                    mode: null, // null or "time"
-                    color: null, // base color, labels, ticks
-                    tickColor: null, // possibly different color of ticks, e.g. "rgba(0,0,0,0.15)"
-                    transform: null, // null or f: number -> number to transform axis
-                    inverseTransform: null, // if transform is set, this should be the inverse function
-                    min: null, // min. value to show, null means set automatically
-                    max: null, // max. value to show, null means set automatically
-                    autoscaleMargin: null, // margin in % to add if auto-setting min/max
-                    ticks: null, // either [1, 3] or [[1, "a"], 3] or (fn: axis info -> ticks) or app. number of ticks for auto-ticks
-                    tickFormatter: null, // fn: number -> string
-                    labelWidth: null, // size of tick labels in pixels
-                    labelHeight: null,
-                    reserveSpace: null, // whether to reserve space even if axis isn't shown
-                    tickLength: null, // size in pixels of ticks, or "full" for whole line
-                    alignTicksWithAxis: null, // axis number or null for no sync
-                    
-                    // mode specific options
-                    tickDecimals: null, // no. of decimals, null means auto
-                    tickSize: null, // number or [number, "unit"]
-                    minTickSize: null, // number or [number, "unit"]
-                    monthNames: null, // list of names of months
-                    timeformat: null, // format string to use
-                    twelveHourClock: false // 12 or 24 time in time mode
-                },
-                yaxis: {
-                    autoscaleMargin: 0.02,
-                    position: "left" // or "right"
-                },
-                xaxes: [],
-                yaxes: [],
-                series: {
-                    points: {
-                        show: false,
-                        radius: 3,
-                        lineWidth: 2, // in pixels
-                        fill: true,
-                        fillColor: "#ffffff",
-                        symbol: "circle" // or callback
-                    },
-                    lines: {
-                        // we don't put in show: false so we can see
-                        // whether lines were actively disabled 
-                        lineWidth: 2, // in pixels
-                        fill: false,
-                        fillColor: null,
-                        steps: false
-                    },
-                    bars: {
-                        show: false,
-                        lineWidth: 2, // in pixels
-                        barWidth: 1, // in units of the x axis
-                        fill: true,
-                        fillColor: null,
-                        align: "left", // or "center" 
-                        horizontal: false
-                    },
-                    shadowSize: 3
-                },
-                grid: {
-                    show: true,
-                    aboveData: false,
-                    color: "#545454", // primary color used for outline and labels
-                    backgroundColor: null, // null for transparent, else color
-                    borderColor: null, // set if different from the grid color
-                    tickColor: null, // color for the ticks, e.g. "rgba(0,0,0,0.15)"
-                    labelMargin: 5, // in pixels
-                    axisMargin: 8, // in pixels
-                    borderWidth: 2, // in pixels
-                    minBorderMargin: null, // in pixels, null means taken from points radius
-                    markings: null, // array of ranges or fn: axes -> array of ranges
-                    markingsColor: "#f4f4f4",
-                    markingsLineWidth: 2,
-                    // interactive stuff
-                    clickable: false,
-                    hoverable: false,
-                    autoHighlight: true, // highlight in case mouse is near
-                    mouseActiveRadius: 10 // how far the mouse can be away to activate an item
-                },
-                hooks: {}
-            },
-        canvas = null,      // the canvas for the plot itself
-        overlay = null,     // canvas for interactive stuff on top of plot
-        eventHolder = null, // jQuery object that events should be bound to
-        ctx = null, octx = null,
-        xaxes = [], yaxes = [],
-        plotOffset = { left: 0, right: 0, top: 0, bottom: 0},
-        canvasWidth = 0, canvasHeight = 0,
-        plotWidth = 0, plotHeight = 0,
-        hooks = {
-            processOptions: [],
-            processRawData: [],
-            processDatapoints: [],
-            drawSeries: [],
-            draw: [],
-            bindEvents: [],
-            drawOverlay: [],
-            shutdown: []
-        },
-        plot = this;
-
-        // public functions
-        plot.setData = setData;
-        plot.setupGrid = setupGrid;
-        plot.draw = draw;
-        plot.getPlaceholder = function() { return placeholder; };
-        plot.getCanvas = function() { return canvas; };
-        plot.getPlotOffset = function() { return plotOffset; };
-        plot.width = function () { return plotWidth; };
-        plot.height = function () { return plotHeight; };
-        plot.offset = function () {
-            var o = eventHolder.offset();
-            o.left += plotOffset.left;
-            o.top += plotOffset.top;
-            return o;
-        };
-        plot.getData = function () { return series; };
-        plot.getAxes = function () {
-            var res = {}, i;
-            $.each(xaxes.concat(yaxes), function (_, axis) {
-                if (axis)
-                    res[axis.direction + (axis.n != 1 ? axis.n : "") + "axis"] = axis;
-            });
-            return res;
-        };
-        plot.getXAxes = function () { return xaxes; };
-        plot.getYAxes = function () { return yaxes; };
-        plot.c2p = canvasToAxisCoords;
-        plot.p2c = axisToCanvasCoords;
-        plot.getOptions = function () { return options; };
-        plot.highlight = highlight;
-        plot.unhighlight = unhighlight;
-        plot.triggerRedrawOverlay = triggerRedrawOverlay;
-        plot.pointOffset = function(point) {
-            return {
-                left: parseInt(xaxes[axisNumber(point, "x") - 1].p2c(+point.x) + plotOffset.left),
-                top: parseInt(yaxes[axisNumber(point, "y") - 1].p2c(+point.y) + plotOffset.top)
-            };
-        };
-        plot.shutdown = shutdown;
-        plot.resize = function () {
-            getCanvasDimensions();
-            resizeCanvas(canvas);
-            resizeCanvas(overlay);
-        };
-
-        // public attributes
-        plot.hooks = hooks;
-        
-        // initialize
-        initPlugins(plot);
-        parseOptions(options_);
-        setupCanvases();
-        setData(data_);
-        setupGrid();
-        draw();
-        bindEvents();
-
-
-        function executeHooks(hook, args) {
-            args = [plot].concat(args);
-            for (var i = 0; i < hook.length; ++i)
-                hook[i].apply(this, args);
-        }
-
-        function initPlugins() {
-            for (var i = 0; i < plugins.length; ++i) {
-                var p = plugins[i];
-                p.init(plot);
-                if (p.options)
-                    $.extend(true, options, p.options);
-            }
-        }
-        
-        function parseOptions(opts) {
-            var i;
-            
-            $.extend(true, options, opts);
-            
-            if (options.xaxis.color == null)
-                options.xaxis.color = options.grid.color;
-            if (options.yaxis.color == null)
-                options.yaxis.color = options.grid.color;
-            
-            if (options.xaxis.tickColor == null) // backwards-compatibility
-                options.xaxis.tickColor = options.grid.tickColor;
-            if (options.yaxis.tickColor == null) // backwards-compatibility
-                options.yaxis.tickColor = options.grid.tickColor;
-
-            if (options.grid.borderColor == null)
-                options.grid.borderColor = options.grid.color;
-            if (options.grid.tickColor == null)
-                options.grid.tickColor = $.color.parse(options.grid.color).scale('a', 0.22).toString();
-            
-            // fill in defaults in axes, copy at least always the
-            // first as the rest of the code assumes it'll be there
-            for (i = 0; i < Math.max(1, options.xaxes.length); ++i)
-                options.xaxes[i] = $.extend(true, {}, options.xaxis, options.xaxes[i]);
-            for (i = 0; i < Math.max(1, options.yaxes.length); ++i)
-                options.yaxes[i] = $.extend(true, {}, options.yaxis, options.yaxes[i]);
-
-            // backwards compatibility, to be removed in future
-            if (options.xaxis.noTicks && options.xaxis.ticks == null)
-                options.xaxis.ticks = options.xaxis.noTicks;
-            if (options.yaxis.noTicks && options.yaxis.ticks == null)
-                options.yaxis.ticks = options.yaxis.noTicks;
-            if (options.x2axis) {
-                options.xaxes[1] = $.extend(true, {}, options.xaxis, options.x2axis);
-                options.xaxes[1].position = "top";
-            }
-            if (options.y2axis) {
-                options.yaxes[1] = $.extend(true, {}, options.yaxis, options.y2axis);
-                options.yaxes[1].position = "right";
-            }
-            if (options.grid.coloredAreas)
-                options.grid.markings = options.grid.coloredAreas;
-            if (options.grid.coloredAreasColor)
-                options.grid.markingsColor = options.grid.coloredAreasColor;
-            if (options.lines)
-                $.extend(true, options.series.lines, options.lines);
-            if (options.points)
-                $.extend(true, options.series.points, options.points);
-            if (options.bars)
-                $.extend(true, options.series.bars, options.bars);
-            if (options.shadowSize != null)
-                options.series.shadowSize = options.shadowSize;
-
-            // save options on axes for future reference
-            for (i = 0; i < options.xaxes.length; ++i)
-                getOrCreateAxis(xaxes, i + 1).options = options.xaxes[i];
-            for (i = 0; i < options.yaxes.length; ++i)
-                getOrCreateAxis(yaxes, i + 1).options = options.yaxes[i];
-
-            // add hooks from options
-            for (var n in hooks)
-                if (options.hooks[n] && options.hooks[n].length)
-                    hooks[n] = hooks[n].concat(options.hooks[n]);
-
-            executeHooks(hooks.processOptions, [options]);
-        }
-
-        function setData(d) {
-            series = parseData(d);
-            fillInSeriesOptions();
-            processData();
-        }
-        
-        function parseData(d) {
-            var res = [];
-            for (var i = 0; i < d.length; ++i) {
-                var s = $.extend(true, {}, options.series);
-
-                if (d[i].data != null) {
-                    s.data = d[i].data; // move the data instead of deep-copy
-                    delete d[i].data;
-
-                    $.extend(true, s, d[i]);
-
-                    d[i].data = s.data;
-                }
-                else
-                    s.data = d[i];
-                res.push(s);
-            }
-
-            return res;
-        }
-        
-        function axisNumber(obj, coord) {
-            var a = obj[coord + "axis"];
-            if (typeof a == "object") // if we got a real axis, extract number
-                a = a.n;
-            if (typeof a != "number")
-                a = 1; // default to first axis
-            return a;
-        }
-
-        function allAxes() {
-            // return flat array without annoying null entries
-            return $.grep(xaxes.concat(yaxes), function (a) { return a; });
-        }
-        
-        function canvasToAxisCoords(pos) {
-            // return an object with x/y corresponding to all used axes 
-            var res = {}, i, axis;
-            for (i = 0; i < xaxes.length; ++i) {
-                axis = xaxes[i];
-                if (axis && axis.used)
-                    res["x" + axis.n] = axis.c2p(pos.left);
-            }
-
-            for (i = 0; i < yaxes.length; ++i) {
-                axis = yaxes[i];
-                if (axis && axis.used)
-                    res["y" + axis.n] = axis.c2p(pos.top);
-            }
-            
-            if (res.x1 !== undefined)
-                res.x = res.x1;
-            if (res.y1 !== undefined)
-                res.y = res.y1;
-
-            return res;
-        }
-        
-        function axisToCanvasCoords(pos) {
-            // get canvas coords from the first pair of x/y found in pos
-            var res = {}, i, axis, key;
-
-            for (i = 0; i < xaxes.length; ++i) {
-                axis = xaxes[i];
-                if (axis && axis.used) {
-                    key = "x" + axis.n;
-                    if (pos[key] == null && axis.n == 1)
-                        key = "x";
-
-                    if (pos[key] != null) {
-                        res.left = axis.p2c(pos[key]);
-                        break;
-                    }
-                }
-            }
-            
-            for (i = 0; i < yaxes.length; ++i) {
-                axis = yaxes[i];
-                if (axis && axis.used) {
-                    key = "y" + axis.n;
-                    if (pos[key] == null && axis.n == 1)
-                        key = "y";
-
-                    if (pos[key] != null) {
-                        res.top = axis.p2c(pos[key]);
-                        break;
-                    }
-                }
-            }
-            
-            return res;
-        }
-        
-        function getOrCreateAxis(axes, number) {
-            if (!axes[number - 1])
-                axes[number - 1] = {
-                    n: number, // save the number for future reference
-                    direction: axes == xaxes ? "x" : "y",
-                    options: $.extend(true, {}, axes == xaxes ? options.xaxis : options.yaxis)
-                };
-                
-            return axes[number - 1];
-        }
-
-        function fillInSeriesOptions() {
-            var i;
-            
-            // collect what we already got of colors
-            var neededColors = series.length,
-                usedColors = [],
-                assignedColors = [];
-            for (i = 0; i < series.length; ++i) {
-                var sc = series[i].color;
-                if (sc != null) {
-                    --neededColors;
-                    if (typeof sc == "number")
-                        assignedColors.push(sc);
-                    else
-                        usedColors.push($.color.parse(series[i].color));
-                }
-            }
-            
-            // we might need to generate more colors if higher indices
-            // are assigned
-            for (i = 0; i < assignedColors.length; ++i) {
-                neededColors = Math.max(neededColors, assignedColors[i] + 1);
-            }
-
-            // produce colors as needed
-            var colors = [], variation = 0;
-            i = 0;
-            while (colors.length < neededColors) {
-                var c;
-                if (options.colors.length == i) // check degenerate case
-                    c = $.color.make(100, 100, 100);
-                else
-                    c = $.color.parse(options.colors[i]);
-
-                // vary color if needed
-                var sign = variation % 2 == 1 ? -1 : 1;
-                c.scale('rgb', 1 + sign * Math.ceil(variation / 2) * 0.2)
-
-                // FIXME: if we're getting to close to something else,
-                // we should probably skip this one
-                colors.push(c);
-                
-                ++i;
-                if (i >= options.colors.length) {
-                    i = 0;
-                    ++variation;
-                }
-            }
-
-            // fill in the options
-            var colori = 0, s;
-            for (i = 0; i < series.length; ++i) {
-                s = series[i];
-                
-                // assign colors
-                if (s.color == null) {
-                    s.color = colors[colori].toString();
-                    ++colori;
-                }
-                else if (typeof s.color == "number")
-                    s.color = colors[s.color].toString();
-
-                // turn on lines automatically in case nothing is set
-                if (s.lines.show == null) {
-                    var v, show = true;
-                    for (v in s)
-                        if (s[v] && s[v].show) {
-                            show = false;
-                            break;
-                        }
-                    if (show)
-                        s.lines.show = true;
-                }
-
-                // setup axes
-                s.xaxis = getOrCreateAxis(xaxes, axisNumber(s, "x"));
-                s.yaxis = getOrCreateAxis(yaxes, axisNumber(s, "y"));
-            }
-        }
-        
-        function processData() {
-            var topSentry = Number.POSITIVE_INFINITY,
-                bottomSentry = Number.NEGATIVE_INFINITY,
-                fakeInfinity = Number.MAX_VALUE,
-                i, j, k, m, length,
-                s, points, ps, x, y, axis, val, f, p;
-
-            function updateAxis(axis, min, max) {
-                if (min < axis.datamin && min != -fakeInfinity)
-                    axis.datamin = min;
-                if (max > axis.datamax && max != fakeInfinity)
-                    axis.datamax = max;
-            }
-
-            $.each(allAxes(), function (_, axis) {
-                // init axis
-                axis.datamin = topSentry;
-                axis.datamax = bottomSentry;
-                axis.used = false;
-            });
-            
-            for (i = 0; i < series.length; ++i) {
-                s = series[i];
-                s.datapoints = { points: [] };
-                
-                executeHooks(hooks.processRawData, [ s, s.data, s.datapoints ]);
-            }
-            
-            // first pass: clean and copy data
-            for (i = 0; i < series.length; ++i) {
-                s = series[i];
-
-                var data = s.data, format = s.datapoints.format;
-
-                if (!format) {
-                    format = [];
-                    // find out how to copy
-                    format.push({ x: true, number: true, required: true });
-                    format.push({ y: true, number: true, required: true });
-
-                    if (s.bars.show || (s.lines.show && s.lines.fill)) {
-                        format.push({ y: true, number: true, required: false, defaultValue: 0 });
-                        if (s.bars.horizontal) {
-                            delete format[format.length - 1].y;
-                            format[format.length - 1].x = true;
-                        }
-                    }
-                    
-                    s.datapoints.format = format;
-                }
-
-                if (s.datapoints.pointsize != null)
-                    continue; // already filled in
-
-                s.datapoints.pointsize = format.length;
-                
-                ps = s.datapoints.pointsize;
-                points = s.datapoints.points;
-
-                insertSteps = s.lines.show && s.lines.steps;
-                s.xaxis.used = s.yaxis.used = true;
-                
-                for (j = k = 0; j < data.length; ++j, k += ps) {
-                    p = data[j];
-
-                    var nullify = p == null;
-                    if (!nullify) {
-                        for (m = 0; m < ps; ++m) {
-                            val = p[m];
-                            f = format[m];
-
-                            if (f) {
-                                if (f.number && val != null) {
-                                    val = +val; // convert to number
-                                    if (isNaN(val))
-                                        val = null;
-                                    else if (val == Infinity)
-                                        val = fakeInfinity;
-                                    else if (val == -Infinity)
-                                        val = -fakeInfinity;
-                                }
-
-                                if (val == null) {
-                                    if (f.required)
-                                        nullify = true;
-                                    
-                                    if (f.defaultValue != null)
-                                        val = f.defaultValue;
-                                }
-                            }
-                            
-                            points[k + m] = val;
-                        }
-                    }
-                    
-                    if (nullify) {
-                        for (m = 0; m < ps; ++m) {
-                            val = points[k + m];
-                            if (val != null) {
-                                f = format[m];
-                                // extract min/max info
-                                if (f.x)
-                                    updateAxis(s.xaxis, val, val);
-                                if (f.y)
-                                    updateAxis(s.yaxis, val, val);
-                            }
-                            points[k + m] = null;
-                        }
-                    }
-                    else {
-                        // a little bit of line specific stuff that
-                        // perhaps shouldn't be here, but lacking
-                        // better means...
-                        if (insertSteps && k > 0
-                            && points[k - ps] != null
-                            && points[k - ps] != points[k]
-                            && points[k - ps + 1] != points[k + 1]) {
-                            // copy the point to make room for a middle point
-                            for (m = 0; m < ps; ++m)
-                                points[k + ps + m] = points[k + m];
-
-                            // middle point has same y
-                            points[k + 1] = points[k - ps + 1];
-
-                            // we've added a point, better reflect that
-                            k += ps;
-                        }
-                    }
-                }
-            }
-
-            // give the hooks a chance to run
-            for (i = 0; i < series.length; ++i) {
-                s = series[i];
-                
-                executeHooks(hooks.processDatapoints, [ s, s.datapoints]);
-            }
-
-            // second pass: find datamax/datamin for auto-scaling
-            for (i = 0; i < series.length; ++i) {
-                s = series[i];
-                points = s.datapoints.points,
-                ps = s.datapoints.pointsize;
-
-                var xmin = topSentry, ymin = topSentry,
-                    xmax = bottomSentry, ymax = bottomSentry;
-                
-                for (j = 0; j < points.length; j += ps) {
-                    if (points[j] == null)
-                        continue;
-
-                    for (m = 0; m < ps; ++m) {
-                        val = points[j + m];
-                        f = format[m];
-                        if (!f || val == fakeInfinity || val == -fakeInfinity)
-                            continue;
-                        
-                        if (f.x) {
-                            if (val < xmin)
-                                xmin = val;
-                            if (val > xmax)
-                                xmax = val;
-                        }
-                        if (f.y) {
-                            if (val < ymin)
-                                ymin = val;
-                            if (val > ymax)
-                                ymax = val;
-                        }
-                    }
-                }
-                
-                if (s.bars.show) {
-                    // make sure we got room for the bar on the dancing floor
-                    var delta = s.bars.align == "left" ? 0 : -s.bars.barWidth/2;
-                    if (s.bars.horizontal) {
-                        ymin += delta;
-                        ymax += delta + s.bars.barWidth;
-                    }
-                    else {
-                        xmin += delta;
-                        xmax += delta + s.bars.barWidth;
-                    }
-                }
-                
-                updateAxis(s.xaxis, xmin, xmax);
-                updateAxis(s.yaxis, ymin, ymax);
-            }
-
-            $.each(allAxes(), function (_, axis) {
-                if (axis.datamin == topSentry)
-                    axis.datamin = null;
-                if (axis.datamax == bottomSentry)
-                    axis.datamax = null;
-            });
-        }
-
-        function makeCanvas(skipPositioning, cls) {
-            var c = document.createElement('canvas');
-            c.className = cls;
-            c.width = canvasWidth;
-            c.height = canvasHeight;
-                    
-            if (!skipPositioning)
-                $(c).css({ position: 'absolute', left: 0, top: 0 });
-                
-            $(c).appendTo(placeholder);
-                
-            if (!c.getContext) // excanvas hack
-                c = window.G_vmlCanvasManager.initElement(c);
-
-            // used for resetting in case we get replotted
-            c.getContext("2d").save();
-            
-            return c;
-        }
-
-        function getCanvasDimensions() {
-            canvasWidth = placeholder.width();
-            canvasHeight = placeholder.height();
-            
-            if (canvasWidth <= 0 || canvasHeight <= 0)
-                throw "Invalid dimensions for plot, width = " + canvasWidth + ", height = " + canvasHeight;
-        }
-
-        function resizeCanvas(c) {
-            // resizing should reset the state (excanvas seems to be
-            // buggy though)
-            if (c.width != canvasWidth)
-                c.width = canvasWidth;
-
-            if (c.height != canvasHeight)
-                c.height = canvasHeight;
-
-            // so try to get back to the initial state (even if it's
-            // gone now, this should be safe according to the spec)
-            var cctx = c.getContext("2d");
-            cctx.restore();
-
-            // and save again
-            cctx.save();
-        }
-        
-        function setupCanvases() {
-            var reused,
-                existingCanvas = placeholder.children("canvas.base"),
-                existingOverlay = placeholder.children("canvas.overlay");
-
-            if (existingCanvas.length == 0 || existingOverlay == 0) {
-                // init everything
-                
-                placeholder.html(""); // make sure placeholder is clear
-            
-                placeholder.css({ padding: 0 }); // padding messes up the positioning
-                
-                if (placeholder.css("position") == 'static')
-                    placeholder.css("position", "relative"); // for positioning labels and overlay
-
-                getCanvasDimensions();
-                
-                canvas = makeCanvas(true, "base");
-                overlay = makeCanvas(false, "overlay"); // overlay canvas for interactive features
-
-                reused = false;
-            }
-            else {
-                // reuse existing elements
-
-                canvas = existingCanvas.get(0);
-                overlay = existingOverlay.get(0);
-
-                reused = true;
-            }
-
-            ctx = canvas.getContext("2d");
-            octx = overlay.getContext("2d");
-
-            // we include the canvas in the event holder too, because IE 7
-            // sometimes has trouble with the stacking order
-            eventHolder = $([overlay, canvas]);
-
-            if (reused) {
-                // run shutdown in the old plot object
-                placeholder.data("plot").shutdown();
-
-                // reset reused canvases
-                plot.resize();
-                
-                // make sure overlay pixels are cleared (canvas is cleared when we redraw)
-                octx.clearRect(0, 0, canvasWidth, canvasHeight);
-                
-                // then whack any remaining obvious garbage left
-                eventHolder.unbind();
-                placeholder.children().not([canvas, overlay]).remove();
-            }
-
-            // save in case we get replotted
-            placeholder.data("plot", plot);
-        }
-
-        function bindEvents() {
-            // bind events
-            if (options.grid.hoverable) {
-                eventHolder.mousemove(onMouseMove);
-                eventHolder.mouseleave(onMouseLeave);
-            }
-
-            if (options.grid.clickable)
-                eventHolder.click(onClick);
-
-            executeHooks(hooks.bindEvents, [eventHolder]);
-        }
-
-        function shutdown() {
-            if (redrawTimeout)
-                clearTimeout(redrawTimeout);
-            
-            eventHolder.unbind("mousemove", onMouseMove);
-            eventHolder.unbind("mouseleave", onMouseLeave);
-            eventHolder.unbind("click", onClick);
-            
-            executeHooks(hooks.shutdown, [eventHolder]);
-        }
-
-        function setTransformationHelpers(axis) {
-            // set helper functions on the axis, assumes plot area
-            // has been computed already
-            
-            function identity(x) { return x; }
-            
-            var s, m, t = axis.options.transform || identity,
-                it = axis.options.inverseTransform;
-            
-            // precompute how much the axis is scaling a point
-            // in canvas space
-            if (axis.direction == "x") {
-                s = axis.scale = plotWidth / Math.abs(t(axis.max) - t(axis.min));
-                m = Math.min(t(axis.max), t(axis.min));
-            }
-            else {
-                s = axis.scale = plotHeight / Math.abs(t(axis.max) - t(axis.min));
-                s = -s;
-                m = Math.max(t(axis.max), t(axis.min));
-            }
-
-            // data point to canvas coordinate
-            if (t == identity) // slight optimization
-                axis.p2c = function (p) { return (p - m) * s; };
-            else
-                axis.p2c = function (p) { return (t(p) - m) * s; };
-            // canvas coordinate to data point
-            if (!it)
-                axis.c2p = function (c) { return m + c / s; };
-            else
-                axis.c2p = function (c) { return it(m + c / s); };
-        }
-
-        function measureTickLabels(axis) {
-            var opts = axis.options, i, ticks = axis.ticks || [], labels = [],
-                l, w = opts.labelWidth, h = opts.labelHeight, dummyDiv;
-
-            function makeDummyDiv(labels, width) {
-                return $('<div style="position:absolute;top:-10000px;' + width + 'font-size:smaller">' +
-                         '<div class="' + axis.direction + 'Axis ' + axis.direction + axis.n + 'Axis">'
-                         + labels.join("") + '</div></div>')
-                    .appendTo(placeholder);
-            }
-            
-            if (axis.direction == "x") {
-                // to avoid measuring the widths of the labels (it's slow), we
-                // construct fixed-size boxes and put the labels inside
-                // them, we don't need the exact figures and the
-                // fixed-size box content is easy to center
-                if (w == null)
-                    w = Math.floor(canvasWidth / (ticks.length > 0 ? ticks.length : 1));
-
-                // measure x label heights
-                if (h == null) {
-                    labels = [];
-                    for (i = 0; i < ticks.length; ++i) {
-                        l = ticks[i].label;
-                        if (l)
-                            labels.push('<div class="tickLabel" style="float:left;width:' + w + 'px">' + l + '</div>');
-                    }
-
-                    if (labels.length > 0) {
-                        // stick them all in the same div and measure
-                        // collective height
-                        labels.push('<div style="clear:left"></div>');
-                        dummyDiv = makeDummyDiv(labels, "width:10000px;");
-                        h = dummyDiv.height();
-                        dummyDiv.remove();
-                    }
-                }
-            }
-            else if (w == null || h == null) {
-                // calculate y label dimensions
-                for (i = 0; i < ticks.length; ++i) {
-                    l = ticks[i].label;
-                    if (l)
-                        labels.push('<div class="tickLabel">' + l + '</div>');
-                }
-                
-                if (labels.length > 0) {
-                    dummyDiv = makeDummyDiv(labels, "");
-                    if (w == null)
-                        w = dummyDiv.children().width();
-                    if (h == null)
-                        h = dummyDiv.find("div.tickLabel").height();
-                    dummyDiv.remove();
-                }
-            }
-
-            if (w == null)
-                w = 0;
-            if (h == null)
-                h = 0;
-
-            axis.labelWidth = w;
-            axis.labelHeight = h;
-        }
-
-        function allocateAxisBoxFirstPhase(axis) {
-            // find the bounding box of the axis by looking at label
-            // widths/heights and ticks, make room by diminishing the
-            // plotOffset
-
-            var lw = axis.labelWidth,
-                lh = axis.labelHeight,
-                pos = axis.options.position,
-                tickLength = axis.options.tickLength,
-                axismargin = options.grid.axisMargin,
-                padding = options.grid.labelMargin,
-                all = axis.direction == "x" ? xaxes : yaxes,
-                index;
-
-            // determine axis margin
-            var samePosition = $.grep(all, function (a) {
-                return a && a.options.position == pos && a.reserveSpace;
-            });
-            if ($.inArray(axis, samePosition) == samePosition.length - 1)
-                axismargin = 0; // outermost
-
-            // determine tick length - if we're innermost, we can use "full"
-            if (tickLength == null)
-                tickLength = "full";
-
-            var sameDirection = $.grep(all, function (a) {
-                return a && a.reserveSpace;
-            });
-
-            var innermost = $.inArray(axis, sameDirection) == 0;
-            if (!innermost && tickLength == "full")
-                tickLength = 5;
-                
-            if (!isNaN(+tickLength))
-                padding += +tickLength;
-
-            // compute box
-            if (axis.direction == "x") {
-                lh += padding;
-                
-                if (pos == "bottom") {
-                    plotOffset.bottom += lh + axismargin;
-                    axis.box = { top: canvasHeight - plotOffset.bottom, height: lh };
-                }
-                else {
-                    axis.box = { top: plotOffset.top + axismargin, height: lh };
-                    plotOffset.top += lh + axismargin;
-                }
-            }
-            else {
-                lw += padding;
-                
-                if (pos == "left") {
-                    axis.box = { left: plotOffset.left + axismargin, width: lw };
-                    plotOffset.left += lw + axismargin;
-                }
-                else {
-                    plotOffset.right += lw + axismargin;
-                    axis.box = { left: canvasWidth - plotOffset.right, width: lw };
-                }
-            }
-
-             // save for future reference
-            axis.position = pos;
-            axis.tickLength = tickLength;
-            axis.box.padding = padding;
-            axis.innermost = innermost;
-        }
-
-        function allocateAxisBoxSecondPhase(axis) {
-            // set remaining bounding box coordinates
-            if (axis.direction == "x") {
-                axis.box.left = plotOffset.left;
-                axis.box.width = plotWidth;
-            }
-            else {
-                axis.box.top = plotOffset.top;
-                axis.box.height = plotHeight;
-            }
-        }
-        
-        function setupGrid() {
-            var i, axes = allAxes();
-
-            // first calculate the plot and axis box dimensions
-
-            $.each(axes, function (_, axis) {
-                axis.show = axis.options.show;
-                if (axis.show == null)
-                    axis.show = axis.used; // by default an axis is visible if it's got data
-                
-                axis.reserveSpace = axis.show || axis.options.reserveSpace;
-
-                setRange(axis);
-            });
-
-            allocatedAxes = $.grep(axes, function (axis) { return axis.reserveSpace; });
-
-            plotOffset.left = plotOffset.right = plotOffset.top = plotOffset.bottom = 0;
-            if (options.grid.show) {
-                $.each(allocatedAxes, function (_, axis) {
-                    // make the ticks
-                    setupTickGeneration(axis);
-                    setTicks(axis);
-                    snapRangeToTicks(axis, axis.ticks);
-
-                    // find labelWidth/Height for axis
-                    measureTickLabels(axis);
-                });
-
-                // with all dimensions in house, we can compute the
-                // axis boxes, start from the outside (reverse order)
-                for (i = allocatedAxes.length - 1; i >= 0; --i)
-                    allocateAxisBoxFirstPhase(allocatedAxes[i]);
-
-                // make sure we've got enough space for things that
-                // might stick out
-                var minMargin = options.grid.minBorderMargin;
-                if (minMargin == null) {
-                    minMargin = 0;
-                    for (i = 0; i < series.length; ++i)
-                        minMargin = Math.max(minMargin, series[i].points.radius + series[i].points.lineWidth/2);
-                }
-                    
-                for (var a in plotOffset) {
-                    plotOffset[a] += options.grid.borderWidth;
-                    plotOffset[a] = Math.max(minMargin, plotOffset[a]);
-                }
-            }
-            
-            plotWidth = canvasWidth - plotOffset.left - plotOffset.right;
-            plotHeight = canvasHeight - plotOffset.bottom - plotOffset.top;
-
-            // now we got the proper plotWidth/Height, we can compute the scaling
-            $.each(axes, function (_, axis) {
-                setTransformationHelpers(axis);
-            });
-
-            if (options.grid.show) {
-                $.each(allocatedAxes, function (_, axis) {
-                    allocateAxisBoxSecondPhase(axis);
-                });
-
-                insertAxisLabels();
-            }
-            
-            insertLegend();
-        }
-        
-        function setRange(axis) {
-            var opts = axis.options,
-                min = +(opts.min != null ? opts.min : axis.datamin),
-                max = +(opts.max != null ? opts.max : axis.datamax),
-                delta = max - min;
-
-            if (delta == 0.0) {
-                // degenerate case
-                var widen = max == 0 ? 1 : 0.01;
-
-                if (opts.min == null)
-                    min -= widen;
-                // always widen max if we couldn't widen min to ensure we
-                // don't fall into min == max which doesn't work
-                if (opts.max == null || opts.min != null)
-                    max += widen;
-            }
-            else {
-                // consider autoscaling
-                var margin = opts.autoscaleMargin;
-                if (margin != null) {
-                    if (opts.min == null) {
-                        min -= delta * margin;
-                        // make sure we don't go below zero if all values
-                        // are positive
-                        if (min < 0 && axis.datamin != null && axis.datamin >= 0)
-                            min = 0;
-                    }
-                    if (opts.max == null) {
-                        max += delta * margin;
-                        if (max > 0 && axis.datamax != null && axis.datamax <= 0)
-                            max = 0;
-                    }
-                }
-            }
-            axis.min = min;
-            axis.max = max;
-        }
-
-        function setupTickGeneration(axis) {
-            var opts = axis.options;
-                
-            // estimate number of ticks
-            var noTicks;
-            if (typeof opts.ticks == "number" && opts.ticks > 0)
-                noTicks = opts.ticks;
-            else
-                // heuristic based on the model a*sqrt(x) fitted to
-                // some data points that seemed reasonable
-                noTicks = 0.3 * Math.sqrt(axis.direction == "x" ? canvasWidth : canvasHeight);
-
-            var delta = (axis.max - axis.min) / noTicks,
-                size, generator, unit, formatter, i, magn, norm;
-
-            if (opts.mode == "time") {
-                // pretty handling of time
-                
-                // map of app. size of time units in milliseconds
-                var timeUnitSize = {
-                    "second": 1000,
-                    "minute": 60 * 1000,
-                    "hour": 60 * 60 * 1000,
-                    "day": 24 * 60 * 60 * 1000,
-                    "month": 30 * 24 * 60 * 60 * 1000,
-                    "year": 365.2425 * 24 * 60 * 60 * 1000
-                };
-
-
-                // the allowed tick sizes, after 1 year we use
-                // an integer algorithm
-                var spec = [
-                    [1, "second"], [2, "second"], [5, "second"], [10, "second"],
-                    [30, "second"], 
-                    [1, "minute"], [2, "minute"], [5, "minute"], [10, "minute"],
-                    [30, "minute"], 
-                    [1, "hour"], [2, "hour"], [4, "hour"],
-                    [8, "hour"], [12, "hour"],
-                    [1, "day"], [2, "day"], [3, "day"],
-                    [0.25, "month"], [0.5, "month"], [1, "month"],
-                    [2, "month"], [3, "month"], [6, "month"],
-                    [1, "year"]
-                ];
-
-                var minSize = 0;
-                if (opts.minTickSize != null) {
-                    if (typeof opts.tickSize == "number")
-                        minSize = opts.tickSize;
-                    else
-                        minSize = opts.minTickSize[0] * timeUnitSize[opts.minTickSize[1]];
-                }
-
-                for (var i = 0; i < spec.length - 1; ++i)
-                    if (delta < (spec[i][0] * timeUnitSize[spec[i][1]]
-                                 + spec[i + 1][0] * timeUnitSize[spec[i + 1][1]]) / 2
-                       && spec[i][0] * timeUnitSize[spec[i][1]] >= minSize)
-                        break;
-                size = spec[i][0];
-                unit = spec[i][1];
-                
-                // special-case the possibility of several years
-                if (unit == "year") {
-                    magn = Math.pow(10, Math.floor(Math.log(delta / timeUnitSize.year) / Math.LN10));
-                    norm = (delta / timeUnitSize.year) / magn;
-                    if (norm < 1.5)
-                        size = 1;
-                    else if (norm < 3)
-                        size = 2;
-                    else if (norm < 7.5)
-                        size = 5;
-                    else
-                        size = 10;
-
-                    size *= magn;
-                }
-
-                axis.tickSize = opts.tickSize || [size, unit];
-                
-                generator = function(axis) {
-                    var ticks = [],
-                        tickSize = axis.tickSize[0], unit = axis.tickSize[1],
-                        d = new Date(axis.min);
-                    
-                    var step = tickSize * timeUnitSize[unit];
-
-                    if (unit == "second")
-                        d.setUTCSeconds(floorInBase(d.getUTCSeconds(), tickSize));
-                    if (unit == "minute")
-                        d.setUTCMinutes(floorInBase(d.getUTCMinutes(), tickSize));
-                    if (unit == "hour")
-                        d.setUTCHours(floorInBase(d.getUTCHours(), tickSize));
-                    if (unit == "month")
-                        d.setUTCMonth(floorInBase(d.getUTCMonth(), tickSize));
-                    if (unit == "year")
-                        d.setUTCFullYear(floorInBase(d.getUTCFullYear(), tickSize));
-                    
-                    // reset smaller components
-                    d.setUTCMilliseconds(0);
-                    if (step >= timeUnitSize.minute)
-                        d.setUTCSeconds(0);
-                    if (step >= timeUnitSize.hour)
-                        d.setUTCMinutes(0);
-                    if (step >= timeUnitSize.day)
-                        d.setUTCHours(0);
-                    if (step >= timeUnitSize.day * 4)
-                        d.setUTCDate(1);
-                    if (step >= timeUnitSize.year)
-                        d.setUTCMonth(0);
-
-
-                    var carry = 0, v = Number.NaN, prev;
-                    do {
-                        prev = v;
-                        v = d.getTime();
-                        ticks.push(v);
-                        if (unit == "month") {
-                            if (tickSize < 1) {
-                                // a bit complicated - we'll divide the month
-                                // up but we need to take care of fractions
-                                // so we don't end up in the middle of a day
-                                d.setUTCDate(1);
-                                var start = d.getTime();
-                                d.setUTCMonth(d.getUTCMonth() + 1);
-                                var end = d.getTime();
-                                d.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize);
-                                carry = d.getUTCHours();
-                                d.setUTCHours(0);
-                            }
-                            else
-                                d.setUTCMonth(d.getUTCMonth() + tickSize);
-                        }
-                        else if (unit == "year") {
-                            d.setUTCFullYear(d.getUTCFullYear() + tickSize);
-                        }
-                        else
-                            d.setTime(v + step);
-                    } while (v < axis.max && v != prev);
-
-                    return ticks;
-                };
-
-                formatter = function (v, axis) {
-                    var d = new Date(v);
-
-                    // first check global format
-                    if (opts.timeformat != null)
-                        return $.plot.formatDate(d, opts.timeformat, opts.monthNames);
-                    
-                    var t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]];
-                    var span = axis.max - axis.min;
-                    var suffix = (opts.twelveHourClock) ? " %p" : "";
-                    
-                    if (t < timeUnitSize.minute)
-                        fmt = "%h:%M:%S" + suffix;
-                    else if (t < timeUnitSize.day) {
-                        if (span < 2 * timeUnitSize.day)
-                            fmt = "%h:%M" + suffix;
-                        else
-                            fmt = "%b %d %h:%M" + suffix;
-                    }
-                    else if (t < timeUnitSize.month)
-                        fmt = "%b %d";
-                    else if (t < timeUnitSize.year) {
-                        if (span < timeUnitSize.year)
-                            fmt = "%b";
-                        else
-                            fmt = "%b %y";
-                    }
-                    else
-                        fmt = "%y";
-                    
-                    return $.plot.formatDate(d, fmt, opts.monthNames);
-                };
-            }
-            else {
-                // pretty rounding of base-10 numbers
-                var maxDec = opts.tickDecimals;
-                var dec = -Math.floor(Math.log(delta) / Math.LN10);
-                if (maxDec != null && dec > maxDec)
-                    dec = maxDec;
-
-                magn = Math.pow(10, -dec);
-                norm = delta / magn; // norm is between 1.0 and 10.0
-                
-                if (norm < 1.5)
-                    size = 1;
-                else if (norm < 3) {
-                    size = 2;
-                    // special case for 2.5, requires an extra decimal
-                    if (norm > 2.25 && (maxDec == null || dec + 1 <= maxDec)) {
-                        size = 2.5;
-                        ++dec;
-                    }
-                }
-                else if (norm < 7.5)
-                    size = 5;
-                else
-                    size = 10;
-
-                size *= magn;
-                
-                if (opts.minTickSize != null && size < opts.minTickSize)
-                    size = opts.minTickSize;
-
-                axis.tickDecimals = Math.max(0, maxDec != null ? maxDec : dec);
-                axis.tickSize = opts.tickSize || size;
-
-                generator = function (axis) {
-                    var ticks = [];
-
-                    // spew out all possible ticks
-                    var start = floorInBase(axis.min, axis.tickSize),
-                        i = 0, v = Number.NaN, prev;
-                    do {
-                        prev = v;
-                        v = start + i * axis.tickSize;
-                        ticks.push(v);
-                        ++i;
-                    } while (v < axis.max && v != prev);
-                    return ticks;
-                };
-
-                formatter = function (v, axis) {
-                    return v.toFixed(axis.tickDecimals);
-                };
-            }
-
-            if (opts.alignTicksWithAxis != null) {
-                var otherAxis = (axis.direction == "x" ? xaxes : yaxes)[opts.alignTicksWithAxis - 1];
-                if (otherAxis && otherAxis.used && otherAxis != axis) {
-                    // consider snapping min/max to outermost nice ticks
-                    var niceTicks = generator(axis);
-                    if (niceTicks.length > 0) {
-                        if (opts.min == null)
-                            axis.min = Math.min(axis.min, niceTicks[0]);
-                        if (opts.max == null && niceTicks.length > 1)
-                            axis.max = Math.max(axis.max, niceTicks[niceTicks.length - 1]);
-                    }
-                    
-                    generator = function (axis) {
-                        // copy ticks, scaled to this axis
-                        var ticks = [], v, i;
-                        for (i = 0; i < otherAxis.ticks.length; ++i) {
-                            v = (otherAxis.ticks[i].v - otherAxis.min) / (otherAxis.max - otherAxis.min);
-                            v = axis.min + v * (axis.max - axis.min);
-                            ticks.push(v);
-                        }
-                        return ticks;
-                    };
-                    
-                    // we might need an extra decimal since forced
-                    // ticks don't necessarily fit naturally
-                    if (axis.mode != "time" && opts.tickDecimals == null) {
-                        var extraDec = Math.max(0, -Math.floor(Math.log(delta) / Math.LN10) + 1),
-                            ts = generator(axis);
-
-                        // only proceed if the tick interval rounded
-                        // with an extra decimal doesn't give us a
-                        // zero at end
-                        if (!(ts.length > 1 && /\..*0$/.test((ts[1] - ts[0]).toFixed(extraDec))))
-                            axis.tickDecimals = extraDec;
-                    }
-                }
-            }
-
-            axis.tickGenerator = generator;
-            if ($.isFunction(opts.tickFormatter))
-                axis.tickFormatter = function (v, axis) { return "" + opts.tickFormatter(v, axis); };
-            else
-                axis.tickFormatter = formatter;
-        }
-        
-        function setTicks(axis) {
-            var oticks = axis.options.ticks, ticks = [];
-            if (oticks == null || (typeof oticks == "number" && oticks > 0))
-                ticks = axis.tickGenerator(axis);
-            else if (oticks) {
-                if ($.isFunction(oticks))
-                    // generate the ticks
-                    ticks = oticks({ min: axis.min, max: axis.max });
-                else
-                    ticks = oticks;
-            }
-
-            // clean up/labelify the supplied ticks, copy them over
-            var i, v;
-            axis.ticks = [];
-            for (i = 0; i < ticks.length; ++i) {
-                var label = null;
-                var t = ticks[i];
-                if (typeof t == "object") {
-                    v = +t[0];
-                    if (t.length > 1)
-                        label = t[1];
-                }
-                else
-                    v = +t;
-                if (label == null)
-                    label = axis.tickFormatter(v, axis);
-                if (!isNaN(v))
-                    axis.ticks.push({ v: v, label: label });
-            }
-        }
-
-        function snapRangeToTicks(axis, ticks) {
-            if (axis.options.autoscaleMargin && ticks.length > 0) {
-                // snap to ticks
-                if (axis.options.min == null)
-                    axis.min = Math.min(axis.min, ticks[0].v);
-                if (axis.options.max == null && ticks.length > 1)
-                    axis.max = Math.max(axis.max, ticks[ticks.length - 1].v);
-            }
-        }
-      
-        function draw() {
-            ctx.clearRect(0, 0, canvasWidth, canvasHeight);
-
-            var grid = options.grid;
-
-            // draw background, if any
-            if (grid.show && grid.backgroundColor)
-                drawBackground();
-            
-            if (grid.show && !grid.aboveData)
-                drawGrid();
-
-            for (var i = 0; i < series.length; ++i) {
-                executeHooks(hooks.drawSeries, [ctx, series[i]]);
-                drawSeries(series[i]);
-            }
-
-            executeHooks(hooks.draw, [ctx]);
-            
-            if (grid.show && grid.aboveData)
-                drawGrid();
-        }
-
-        function extractRange(ranges, coord) {
-            var axis, from, to, key, axes = allAxes();
-
-            for (i = 0; i < axes.length; ++i) {
-                axis = axes[i];
-                if (axis.direction == coord) {
-                    key = coord + axis.n + "axis";
-                    if (!ranges[key] && axis.n == 1)
-                        key = coord + "axis"; // support x1axis as xaxis
-                    if (ranges[key]) {
-                        from = ranges[key].from;
-                        to = ranges[key].to;
-                        break;
-                    }
-                }
-            }
-
-            // backwards-compat stuff - to be removed in future
-            if (!ranges[key]) {
-                axis = coord == "x" ? xaxes[0] : yaxes[0];
-                from = ranges[coord + "1"];
-                to = ranges[coord + "2"];
-            }
-
-            // auto-reverse as an added bonus
-            if (from != null && to != null && from > to) {
-                var tmp = from;
-                from = to;
-                to = tmp;
-            }
-            
-            return { from: from, to: to, axis: axis };
-        }
-        
-        function drawBackground() {
-            ctx.save();
-            ctx.translate(plotOffset.left, plotOffset.top);
-
-            ctx.fillStyle = getColorOrGradient(options.grid.backgroundColor, plotHeight, 0, "rgba(255, 255, 255, 0)");
-            ctx.fillRect(0, 0, plotWidth, plotHeight);
-            ctx.restore();
-        }
-
-        function drawGrid() {
-            var i;
-            
-            ctx.save();
-            ctx.translate(plotOffset.left, plotOffset.top);
-
-            // draw markings
-            var markings = options.grid.markings;
-            if (markings) {
-                if ($.isFunction(markings)) {
-                    var axes = plot.getAxes();
-                    // xmin etc. is backwards compatibility, to be
-                    // removed in the future
-                    axes.xmin = axes.xaxis.min;
-                    axes.xmax = axes.xaxis.max;
-                    axes.ymin = axes.yaxis.min;
-                    axes.ymax = axes.yaxis.max;
-                    
-                    markings = markings(axes);
-                }
-
-                for (i = 0; i < markings.length; ++i) {
-                    var m = markings[i],
-                        xrange = extractRange(m, "x"),
-                        yrange = extractRange(m, "y");
-
-                    // fill in missing
-                    if (xrange.from == null)
-                        xrange.from = xrange.axis.min;
-                    if (xrange.to == null)
-                        xrange.to = xrange.axis.max;
-                    if (yrange.from == null)
-                        yrange.from = yrange.axis.min;
-                    if (yrange.to == null)
-                        yrange.to = yrange.axis.max;
-
-                    // clip
-                    if (xrange.to < xrange.axis.min || xrange.from > xrange.axis.max ||
-                        yrange.to < yrange.axis.min || yrange.from > yrange.axis.max)
-                        continue;
-
-                    xrange.from = Math.max(xrange.from, xrange.axis.min);
-                    xrange.to = Math.min(xrange.to, xrange.axis.max);
-                    yrange.from = Math.max(yrange.from, yrange.axis.min);
-                    yrange.to = Math.min(yrange.to, yrange.axis.max);
-
-                    if (xrange.from == xrange.to && yrange.from == yrange.to)
-                        continue;
-
-                    // then draw
-                    xrange.from = xrange.axis.p2c(xrange.from);
-                    xrange.to = xrange.axis.p2c(xrange.to);
-                    yrange.from = yrange.axis.p2c(yrange.from);
-                    yrange.to = yrange.axis.p2c(yrange.to);
-                    
-                    if (xrange.from == xrange.to || yrange.from == yrange.to) {
-                        // draw line
-                        ctx.beginPath();
-                        ctx.strokeStyle = m.color || options.grid.markingsColor;
-                        ctx.lineWidth = m.lineWidth || options.grid.markingsLineWidth;
-                        ctx.moveTo(xrange.from, yrange.from);
-                        ctx.lineTo(xrange.to, yrange.to);
-                        ctx.stroke();
-                    }
-                    else {
-                        // fill area
-                        ctx.fillStyle = m.color || options.grid.markingsColor;
-                        ctx.fillRect(xrange.from, yrange.to,
-                                     xrange.to - xrange.from,
-                                     yrange.from - yrange.to);
-                    }
-                }
-            }
-            
-            // draw the ticks
-            var axes = allAxes(), bw = options.grid.borderWidth;
-
-            for (var j = 0; j < axes.length; ++j) {
-                var axis = axes[j], box = axis.box,
-                    t = axis.tickLength, x, y, xoff, yoff;
-                if (!axis.show || axis.ticks.length == 0)
-                    continue
-                
-                ctx.strokeStyle = axis.options.tickColor || $.color.parse(axis.options.color).scale('a', 0.22).toString();
-                ctx.lineWidth = 1;
-
-                // find the edges
-                if (axis.direction == "x") {
-                    x = 0;
-                    if (t == "full")
-                        y = (axis.position == "top" ? 0 : plotHeight);
-                    else
-                        y = box.top - plotOffset.top + (axis.position == "top" ? box.height : 0);
-                }
-                else {
-                    y = 0;
-                    if (t == "full")
-                        x = (axis.position == "left" ? 0 : plotWidth);
-                    else
-                        x = box.left - plotOffset.left + (axis.position == "left" ? box.width : 0);
-                }
-                
-                // draw tick bar
-                if (!axis.innermost) {
-                    ctx.beginPath();
-                    xoff = yoff = 0;
-                    if (axis.direction == "x")
-                        xoff = plotWidth;
-                    else
-                        yoff = plotHeight;
-                    
-                    if (ctx.lineWidth == 1) {
-                        x = Math.floor(x) + 0.5;
-                        y = Math.floor(y) + 0.5;
-                    }
-
-                    ctx.moveTo(x, y);
-                    ctx.lineTo(x + xoff, y + yoff);
-                    ctx.stroke();
-                }
-
-                // draw ticks
-                ctx.beginPath();
-                for (i = 0; i < axis.ticks.length; ++i) {
-                    var v = axis.ticks[i].v;
-                    
-                    xoff = yoff = 0;
-
-                    if (v < axis.min || v > axis.max
-                        // skip those lying on the axes if we got a border
-                        || (t == "full" && bw > 0
-                            && (v == axis.min || v == axis.max)))
-                        continue;
-
-                    if (axis.direction == "x") {
-                        x = axis.p2c(v);
-                        yoff = t == "full" ? -plotHeight : t;
-                        
-                        if (axis.position == "top")
-                            yoff = -yoff;
-                    }
-                    else {
-                        y = axis.p2c(v);
-                        xoff = t == "full" ? -plotWidth : t;
-                        
-                        if (axis.position == "left")
-                            xoff = -xoff;
-                    }
-
-                    if (ctx.lineWidth == 1) {
-                        if (axis.direction == "x")
-                            x = Math.floor(x) + 0.5;
-                        else
-                            y = Math.floor(y) + 0.5;
-                    }
-
-                    ctx.moveTo(x, y);
-                    ctx.lineTo(x + xoff, y + yoff);
-                }
-                
-                ctx.stroke();
-            }
-            
-            
-            // draw border
-            if (bw) {
-                ctx.lineWidth = bw;
-                ctx.strokeStyle = options.grid.borderColor;
-                ctx.strokeRect(-bw/2, -bw/2, plotWidth + bw, plotHeight + bw);
-            }
-
-            ctx.restore();
-        }
-
-        function insertAxisLabels() {
-            placeholder.find(".tickLabels").remove();
-            
-            var html = ['<div class="tickLabels" style="font-size:smaller">'];
-
-            var axes = allAxes();
-            for (var j = 0; j < axes.length; ++j) {
-                var axis = axes[j], box = axis.box;
-                if (!axis.show)
-                    continue;
-                //debug: html.push('<div style="position:absolute;opacity:0.10;background-color:red;left:' + box.left + 'px;top:' + box.top + 'px;width:' + box.width +  'px;height:' + box.height + 'px"></div>')
-                html.push('<div class="' + axis.direction + 'Axis ' + axis.direction + axis.n + 'Axis" style="color:' + axis.options.color + '">');
-                for (var i = 0; i < axis.ticks.length; ++i) {
-                    var tick = axis.ticks[i];
-                    if (!tick.label || tick.v < axis.min || tick.v > axis.max)
-                        continue;
-
-                    var pos = {}, align;
-                    
-                    if (axis.direction == "x") {
-                        align = "center";
-                        pos.left = Math.round(plotOffset.left + axis.p2c(tick.v) - axis.labelWidth/2);
-                        if (axis.position == "bottom")
-                            pos.top = box.top + box.padding;
-                        else
-                            pos.bottom = canvasHeight - (box.top + box.height - box.padding);
-                    }
-                    else {
-                        pos.top = Math.round(plotOffset.top + axis.p2c(tick.v) - axis.labelHeight/2);
-                        if (axis.position == "left") {
-                            pos.right = canvasWidth - (box.left + box.width - box.padding)
-                            align = "right";
-                        }
-                        else {
-                            pos.left = box.left + box.padding;
-                            align = "left";
-                        }
-                    }
-
-                    pos.width = axis.labelWidth;
-
-                    var style = ["position:absolute", "text-align:" + align ];
-                    for (var a in pos)
-                        style.push(a + ":" + pos[a] + "px")
-                    
-                    html.push('<div class="tickLabel" style="' + style.join(';') + '">' + tick.label + '</div>');
-                }
-                html.push('</div>');
-            }
-
-            html.push('</div>');
-
-            placeholder.append(html.join(""));
-        }
-
-        function drawSeries(series) {
-            if (series.lines.show)
-                drawSeriesLines(series);
-            if (series.bars.show)
-                drawSeriesBars(series);
-            if (series.points.show)
-                drawSeriesPoints(series);
-        }
-        
-        function drawSeriesLines(series) {
-            function plotLine(datapoints, xoffset, yoffset, axisx, axisy) {
-                var points = datapoints.points,
-                    ps = datapoints.pointsize,
-                    prevx = null, prevy = null;
-                
-                ctx.beginPath();
-                for (var i = ps; i < points.length; i += ps) {
-                    var x1 = points[i - ps], y1 = points[i - ps + 1],
-                        x2 = points[i], y2 = points[i + 1];
-                    
-                    if (x1 == null || x2 == null)
-                        continue;
-
-                    // clip with ymin
-                    if (y1 <= y2 && y1 < axisy.min) {
-                        if (y2 < axisy.min)
-                            continue;   // line segment is outside
-                        // compute new intersection point
-                        x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
-                        y1 = axisy.min;
-                    }
-                    else if (y2 <= y1 && y2 < axisy.min) {
-                        if (y1 < axisy.min)
-                            continue;
-                        x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
-                        y2 = axisy.min;
-                    }
-
-                    // clip with ymax
-                    if (y1 >= y2 && y1 > axisy.max) {
-                        if (y2 > axisy.max)
-                            continue;
-                        x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
-                        y1 = axisy.max;
-                    }
-                    else if (y2 >= y1 && y2 > axisy.max) {
-                        if (y1 > axisy.max)
-                            continue;
-                        x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
-                        y2 = axisy.max;
-                    }
-
-                    // clip with xmin
-                    if (x1 <= x2 && x1 < axisx.min) {
-                        if (x2 < axisx.min)
-                            continue;
-                        y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
-                        x1 = axisx.min;
-                    }
-                    else if (x2 <= x1 && x2 < axisx.min) {
-                        if (x1 < axisx.min)
-                            continue;
-                        y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
-                        x2 = axisx.min;
-                    }
-
-                    // clip with xmax
-                    if (x1 >= x2 && x1 > axisx.max) {
-                        if (x2 > axisx.max)
-                            continue;
-                        y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
-                        x1 = axisx.max;
-                    }
-                    else if (x2 >= x1 && x2 > axisx.max) {
-                        if (x1 > axisx.max)
-                            continue;
-                        y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
-                        x2 = axisx.max;
-                    }
-
-                    if (x1 != prevx || y1 != prevy)
-                        ctx.moveTo(axisx.p2c(x1) + xoffset, axisy.p2c(y1) + yoffset);
-                    
-                    prevx = x2;
-                    prevy = y2;
-                    ctx.lineTo(axisx.p2c(x2) + xoffset, axisy.p2c(y2) + yoffset);
-                }
-                ctx.stroke();
-            }
-
-            function plotLineArea(datapoints, axisx, axisy) {
-                var points = datapoints.points,
-                    ps = datapoints.pointsize,
-                    bottom = Math.min(Math.max(0, axisy.min), axisy.max),
-                    i = 0, top, areaOpen = false,
-                    ypos = 1, segmentStart = 0, segmentEnd = 0;
-
-                // we process each segment in two turns, first forward
-                // direction to sketch out top, then once we hit the
-                // end we go backwards to sketch the bottom
-                while (true) {
-                    if (ps > 0 && i > points.length + ps)
-                        break;
-
-                    i += ps; // ps is negative if going backwards
-
-                    var x1 = points[i - ps],
-                        y1 = points[i - ps + ypos],
-                        x2 = points[i], y2 = points[i + ypos];
-
-                    if (areaOpen) {
-                        if (ps > 0 && x1 != null && x2 == null) {
-                            // at turning point
-                            segmentEnd = i;
-                            ps = -ps;
-                            ypos = 2;
-                            continue;
-                        }
-
-                        if (ps < 0 && i == segmentStart + ps) {
-                            // done with the reverse sweep
-                            ctx.fill();
-                            areaOpen = false;
-                            ps = -ps;
-                            ypos = 1;
-                            i = segmentStart = segmentEnd + ps;
-                            continue;
-                        }
-                    }
-
-                    if (x1 == null || x2 == null)
-                        continue;
-
-                    // clip x values
-                    
-                    // clip with xmin
-                    if (x1 <= x2 && x1 < axisx.min) {
-                        if (x2 < axisx.min)
-                            continue;
-                        y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
-                        x1 = axisx.min;
-                    }
-                    else if (x2 <= x1 && x2 < axisx.min) {
-                        if (x1 < axisx.min)
-                            continue;
-                        y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
-                        x2 = axisx.min;
-                    }
-
-                    // clip with xmax
-                    if (x1 >= x2 && x1 > axisx.max) {
-                        if (x2 > axisx.max)
-                            continue;
-                        y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
-                        x1 = axisx.max;
-                    }
-                    else if (x2 >= x1 && x2 > axisx.max) {
-                        if (x1 > axisx.max)
-                            continue;
-                        y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
-                        x2 = axisx.max;
-                    }
-
-                    if (!areaOpen) {
-                        // open area
-                        ctx.beginPath();
-                        ctx.moveTo(axisx.p2c(x1), axisy.p2c(bottom));
-                        areaOpen = true;
-                    }
-                    
-                    // now first check the case where both is outside
-                    if (y1 >= axisy.max && y2 >= axisy.max) {
-                        ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.max));
-                        ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.max));
-                        continue;
-                    }
-                    else if (y1 <= axisy.min && y2 <= axisy.min) {
-                        ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.min));
-                        ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.min));
-                        continue;
-                    }
-                    
-                    // else it's a bit more complicated, there might
-                    // be a flat maxed out rectangle first, then a
-                    // triangular cutout or reverse; to find these
-                    // keep track of the current x values
-                    var x1old = x1, x2old = x2;
-
-                    // clip the y values, without shortcutting, we
-                    // go through all cases in turn
-                    
-                    // clip with ymin
-                    if (y1 <= y2 && y1 < axisy.min && y2 >= axisy.min) {
-                        x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
-                        y1 = axisy.min;
-                    }
-                    else if (y2 <= y1 && y2 < axisy.min && y1 >= axisy.min) {
-                        x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
-                        y2 = axisy.min;
-                    }
-
-                    // clip with ymax
-                    if (y1 >= y2 && y1 > axisy.max && y2 <= axisy.max) {
-                        x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
-                        y1 = axisy.max;
-                    }
-                    else if (y2 >= y1 && y2 > axisy.max && y1 <= axisy.max) {
-                        x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
-                        y2 = axisy.max;
-                    }
-
-                    // if the x value was changed we got a rectangle
-                    // to fill
-                    if (x1 != x1old) {
-                        ctx.lineTo(axisx.p2c(x1old), axisy.p2c(y1));
-                        // it goes to (x1, y1), but we fill that below
-                    }
-                    
-                    // fill triangular section, this sometimes result
-                    // in redundant points if (x1, y1) hasn't changed
-                    // from previous line to, but we just ignore that
-                    ctx.lineTo(axisx.p2c(x1), axisy.p2c(y1));
-                    ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));
-
-                    // fill the other rectangle if it's there
-                    if (x2 != x2old) {
-                        ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));
-                        ctx.lineTo(axisx.p2c(x2old), axisy.p2c(y2));
-                    }
-                }
-            }
-
-            ctx.save();
-            ctx.translate(plotOffset.left, plotOffset.top);
-            ctx.lineJoin = "round";
-
-            var lw = series.lines.lineWidth,
-                sw = series.shadowSize;
-            // FIXME: consider another form of shadow when filling is turned on
-            if (lw > 0 && sw > 0) {
-                // draw shadow as a thick and thin line with transparency
-                ctx.lineWidth = sw;
-                ctx.strokeStyle = "rgba(0,0,0,0.1)";
-                // position shadow at angle from the mid of line
-                var angle = Math.PI/18;
-                plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/2), Math.cos(angle) * (lw/2 + sw/2), series.xaxis, series.yaxis);
-                ctx.lineWidth = sw/2;
-                plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/4), Math.cos(angle) * (lw/2 + sw/4), series.xaxis, series.yaxis);
-            }
-
-            ctx.lineWidth = lw;
-            ctx.strokeStyle = series.color;
-            var fillStyle = getFillStyle(series.lines, series.color, 0, plotHeight);
-            if (fillStyle) {
-                ctx.fillStyle = fillStyle;
-                plotLineArea(series.datapoints, series.xaxis, series.yaxis);
-            }
-
-            if (lw > 0)
-                plotLine(series.datapoints, 0, 0, series.xaxis, series.yaxis);
-            ctx.restore();
-        }
-
-        function drawSeriesPoints(series) {
-            function plotPoints(datapoints, radius, fillStyle, offset, shadow, axisx, axisy, symbol) {
-                var points = datapoints.points, ps = datapoints.pointsize;
-
-                for (var i = 0; i < points.length; i += ps) {
-                    var x = points[i], y = points[i + 1];
-                    if (x == null || x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)
-                        continue;
-                    
-                    ctx.beginPath();
-                    x = axisx.p2c(x);
-                    y = axisy.p2c(y) + offset;
-                    if (symbol == "circle")
-                        ctx.arc(x, y, radius, 0, shadow ? Math.PI : Math.PI * 2, false);
-                    else
-                        symbol(ctx, x, y, radius, shadow);
-                    ctx.closePath();
-                    
-                    if (fillStyle) {
-                        ctx.fillStyle = fillStyle;
-                        ctx.fill();
-                    }
-                    ctx.stroke();
-                }
-            }
-            
-            ctx.save();
-            ctx.translate(plotOffset.left, plotOffset.top);
-
-            var lw = series.points.lineWidth,
-                sw = series.shadowSize,
-                radius = series.points.radius,
-                symbol = series.points.symbol;
-            if (lw > 0 && sw > 0) {
-                // draw shadow in two steps
-                var w = sw / 2;
-                ctx.lineWidth = w;
-                ctx.strokeStyle = "rgba(0,0,0,0.1)";
-                plotPoints(series.datapoints, radius, null, w + w/2, true,
-                           series.xaxis, series.yaxis, symbol);
-
-                ctx.strokeStyle = "rgba(0,0,0,0.2)";
-                plotPoints(series.datapoints, radius, null, w/2, true,
-                           series.xaxis, series.yaxis, symbol);
-            }
-
-            ctx.lineWidth = lw;
-            ctx.strokeStyle = series.color;
-            plotPoints(series.datapoints, radius,
-                       getFillStyle(series.points, series.color), 0, false,
-                       series.xaxis, series.yaxis, symbol);
-            ctx.restore();
-        }
-
-        function drawBar(x, y, b, barLeft, barRight, offset, fillStyleCallback, axisx, axisy, c, horizontal, lineWidth) {
-            var left, right, bottom, top,
-                drawLeft, drawRight, drawTop, drawBottom,
-                tmp;
-
-            // in horizontal mode, we start the bar from the left
-            // instead of from the bottom so it appears to be
-            // horizontal rather than vertical
-            if (horizontal) {
-                drawBottom = drawRight = drawTop = true;
-                drawLeft = false;
-                left = b;
-                right = x;
-                top = y + barLeft;
-                bottom = y + barRight;
-
-                // account for negative bars
-                if (right < left) {
-                    tmp = right;
-                    right = left;
-                    left = tmp;
-                    drawLeft = true;
-                    drawRight = false;
-                }
-            }
-            else {
-                drawLeft = drawRight = drawTop = true;
-                drawBottom = false;
-                left = x + barLeft;
-                right = x + barRight;
-                bottom = b;
-                top = y;
-
-                // account for negative bars
-                if (top < bottom) {
-                    tmp = top;
-                    top = bottom;
-                    bottom = tmp;
-                    drawBottom = true;
-                    drawTop = false;
-                }
-            }
-           
-            // clip
-            if (right < axisx.min || left > axisx.max ||
-                top < axisy.min || bottom > axisy.max)
-                return;
-            
-            if (left < axisx.min) {
-                left = axisx.min;
-                drawLeft = false;
-            }
-
-            if (right > axisx.max) {
-                right = axisx.max;
-                drawRight = false;
-            }
-
-            if (bottom < axisy.min) {
-                bottom = axisy.min;
-                drawBottom = false;
-            }
-            
-            if (top > axisy.max) {
-                top = axisy.max;
-                drawTop = false;
-            }
-
-            left = axisx.p2c(left);
-            bottom = axisy.p2c(bottom);
-            right = axisx.p2c(right);
-            top = axisy.p2c(top);
-            
-            // fill the bar
-            if (fillStyleCallback) {
-                c.beginPath();
-                c.moveTo(left, bottom);
-                c.lineTo(left, top);
-                c.lineTo(right, top);
-                c.lineTo(right, bottom);
-                c.fillStyle = fillStyleCallback(bottom, top);
-                c.fill();
-            }
-
-            // draw outline
-            if (lineWidth > 0 && (drawLeft || drawRight || drawTop || drawBottom)) {
-                c.beginPath();
-
-                // FIXME: inline moveTo is buggy with excanvas
-                c.moveTo(left, bottom + offset);
-                if (drawLeft)
-                    c.lineTo(left, top + offset);
-                else
-                    c.moveTo(left, top + offset);
-                if (drawTop)
-                    c.lineTo(right, top + offset);
-                else
-                    c.moveTo(right, top + offset);
-                if (drawRight)
-                    c.lineTo(right, bottom + offset);
-                else
-                    c.moveTo(right, bottom + offset);
-                if (drawBottom)
-                    c.lineTo(left, bottom + offset);
-                else
-                    c.moveTo(left, bottom + offset);
-                c.stroke();
-            }
-        }
-        
-        function drawSeriesBars(series) {
-            function plotBars(datapoints, barLeft, barRight, offset, fillStyleCallback, axisx, axisy) {
-                var points = datapoints.points, ps = datapoints.pointsize;
-                
-                for (var i = 0; i < points.length; i += ps) {
-                    if (points[i] == null)
-                        continue;
-                    drawBar(points[i], points[i + 1], points[i + 2], barLeft, barRight, offset, fillStyleCallback, axisx, axisy, ctx, series.bars.horizontal, series.bars.lineWidth);
-                }
-            }
-
-            ctx.save();
-            ctx.translate(plotOffset.left, plotOffset.top);
-
-            // FIXME: figure out a way to add shadows (for instance along the right edge)
-            ctx.lineWidth = series.bars.lineWidth;
-            ctx.strokeStyle = series.color;
-            var barLeft = series.bars.align == "left" ? 0 : -series.bars.barWidth/2;
-            var fillStyleCallback = series.bars.fill ? function (bottom, top) { return getFillStyle(series.bars, series.color, bottom, top); } : null;
-            plotBars(series.datapoints, barLeft, barLeft + series.bars.barWidth, 0, fillStyleCallback, series.xaxis, series.yaxis);
-            ctx.restore();
-        }
-
-        function getFillStyle(filloptions, seriesColor, bottom, top) {
-            var fill = filloptions.fill;
-            if (!fill)
-                return null;
-
-            if (filloptions.fillColor)
-                return getColorOrGradient(filloptions.fillColor, bottom, top, seriesColor);
-            
-            var c = $.color.parse(seriesColor);
-            c.a = typeof fill == "number" ? fill : 0.4;
-            c.normalize();
-            return c.toString();
-        }
-        
-        function insertLegend() {
-            placeholder.find(".legend").remove();
-
-            if (!options.legend.show)
-                return;
-            
-            var fragments = [], rowStarted = false,
-                lf = options.legend.labelFormatter, s, label;
-            for (var i = 0; i < series.length; ++i) {
-                s = series[i];
-                label = s.label;
-                if (!label)
-                    continue;
-                
-                if (i % options.legend.noColumns == 0) {
-                    if (rowStarted)
-                        fragments.push('</tr>');
-                    fragments.push('<tr>');
-                    rowStarted = true;
-                }
-
-                if (lf)
-                    label = lf(label, s);
-                
-                fragments.push(
-                    '<td class="legendColorBox"><div style="border:1px solid ' + options.legend.labelBoxBorderColor + ';padding:1px"><div style="width:4px;height:0;border:5px solid ' + s.color + ';overflow:hidden"></div></div></td>' +
-                    '<td class="legendLabel">' + label + '</td>');
-            }
-            if (rowStarted)
-                fragments.push('</tr>');
-            
-            if (fragments.length == 0)
-                return;
-
-            var table = '<table style="font-size:smaller;color:' + options.grid.color + '">' + fragments.join("") + '</table>';
-            if (options.legend.container != null)
-                $(options.legend.container).html(table);
-            else {
-                var pos = "",
-                    p = options.legend.position,
-                    m = options.legend.margin;
-                if (m[0] == null)
-                    m = [m, m];
-                if (p.charAt(0) == "n")
-                    pos += 'top:' + (m[1] + plotOffset.top) + 'px;';
-                else if (p.charAt(0) == "s")
-                    pos += 'bottom:' + (m[1] + plotOffset.bottom) + 'px;';
-                if (p.charAt(1) == "e")
-                    pos += 'right:' + (m[0] + plotOffset.right) + 'px;';
-                else if (p.charAt(1) == "w")
-                    pos += 'left:' + (m[0] + plotOffset.left) + 'px;';
-                var legend = $('<div class="legend">' + table.replace('style="', 'style="position:absolute;' + pos +';') + '</div>').appendTo(placeholder);
-                if (options.legend.backgroundOpacity != 0.0) {
-                    // put in the transparent background
-                    // separately to avoid blended labels and
-                    // label boxes
-                    var c = options.legend.backgroundColor;
-                    if (c == null) {
-                        c = options.grid.backgroundColor;
-                        if (c && typeof c == "string")
-                            c = $.color.parse(c);
-                        else
-                            c = $.color.extract(legend, 'background-color');
-                        c.a = 1;
-                        c = c.toString();
-                    }
-                    var div = legend.children();
-                    $('<div style="position:absolute;width:' + div.width() + 'px;height:' + div.height() + 'px;' + pos +'background-color:' + c + ';"> </div>').prependTo(legend).css('opacity', options.legend.backgroundOpacity);
-                }
-            }
-        }
-
-
-        // interactive features
-        
-        var highlights = [],
-            redrawTimeout = null;
-        
-        // returns the data item the mouse is over, or null if none is found
-        function findNearbyItem(mouseX, mouseY, seriesFilter) {
-            var maxDistance = options.grid.mouseActiveRadius,
-                smallestDistance = maxDistance * maxDistance + 1,
-                item = null, foundPoint = false, i, j;
-
-            for (i = series.length - 1; i >= 0; --i) {
-                if (!seriesFilter(series[i]))
-                    continue;
-                
-                var s = series[i],
-                    axisx = s.xaxis,
-                    axisy = s.yaxis,
-                    points = s.datapoints.points,
-                    ps = s.datapoints.pointsize,
-                    mx = axisx.c2p(mouseX), // precompute some stuff to make the loop faster
-                    my = axisy.c2p(mouseY),
-                    maxx = maxDistance / axisx.scale,
-                    maxy = maxDistance / axisy.scale;
-
-                // with inverse transforms, we can't use the maxx/maxy
-                // optimization, sadly
-                if (axisx.options.inverseTransform)
-                    maxx = Number.MAX_VALUE;
-                if (axisy.options.inverseTransform)
-                    maxy = Number.MAX_VALUE;
-                
-                if (s.lines.show || s.points.show) {
-                    for (j = 0; j < points.length; j += ps) {
-                        var x = points[j], y = points[j + 1];
-                        if (x == null)
-                            continue;
-                        
-                        // For points and lines, the cursor must be within a
-                        // certain distance to the data point
-                        if (x - mx > maxx || x - mx < -maxx ||
-                            y - my > maxy || y - my < -maxy)
-                            continue;
-
-                        // We have to calculate distances in pixels, not in
-                        // data units, because the scales of the axes may be different
-                        var dx = Math.abs(axisx.p2c(x) - mouseX),
-                            dy = Math.abs(axisy.p2c(y) - mouseY),
-                            dist = dx * dx + dy * dy; // we save the sqrt
-
-                        // use <= to ensure last point takes precedence
-                        // (last generally means on top of)
-                        if (dist < smallestDistance) {
-                            smallestDistance = dist;
-                            item = [i, j / ps];
-                        }
-                    }
-                }
-                    
-                if (s.bars.show && !item) { // no other point can be nearby
-                    var barLeft = s.bars.align == "left" ? 0 : -s.bars.barWidth/2,
-                        barRight = barLeft + s.bars.barWidth;
-                    
-                    for (j = 0; j < points.length; j += ps) {
-                        var x = points[j], y = points[j + 1], b = points[j + 2];
-                        if (x == null)
-                            continue;
-  
-                        // for a bar graph, the cursor must be inside the bar
-                        if (series[i].bars.horizontal ? 
-                            (mx <= Math.max(b, x) && mx >= Math.min(b, x) && 
-                             my >= y + barLeft && my <= y + barRight) :
-                            (mx >= x + barLeft && mx <= x + barRight &&
-                             my >= Math.min(b, y) && my <= Math.max(b, y)))
-                                item = [i, j / ps];
-                    }
-                }
-            }
-
-            if (item) {
-                i = item[0];
-                j = item[1];
-                ps = series[i].datapoints.pointsize;
-                
-                return { datapoint: series[i].datapoints.points.slice(j * ps, (j + 1) * ps),
-                         dataIndex: j,
-                         series: series[i],
-                         seriesIndex: i };
-            }
-            
-            return null;
-        }
-
-        function onMouseMove(e) {
-            if (options.grid.hoverable)
-                triggerClickHoverEvent("plothover", e,
-                                       function (s) { return s["hoverable"] != false; });
-        }
-
-        function onMouseLeave(e) {
-            if (options.grid.hoverable)
-                triggerClickHoverEvent("plothover", e,
-                                       function (s) { return false; });
-        }
-
-        function onClick(e) {
-            triggerClickHoverEvent("plotclick", e,
-                                   function (s) { return s["clickable"] != false; });
-        }
-
-        // trigger click or hover event (they send the same parameters
-        // so we share their code)
-        function triggerClickHoverEvent(eventname, event, seriesFilter) {
-            var offset = eventHolder.offset(),
-                canvasX = event.pageX - offset.left - plotOffset.left,
-                canvasY = event.pageY - offset.top - plotOffset.top,
-            pos = canvasToAxisCoords({ left: canvasX, top: canvasY });
-
-            pos.pageX = event.pageX;
-            pos.pageY = event.pageY;
-
-            var item = findNearbyItem(canvasX, canvasY, seriesFilter);
-
-            if (item) {
-                // fill in mouse pos for any listeners out there
-                item.pageX = parseInt(item.series.xaxis.p2c(item.datapoint[0]) + offset.left + plotOffset.left);
-                item.pageY = parseInt(item.series.yaxis.p2c(item.datapoint[1]) + offset.top + plotOffset.top);
-            }
-
-            if (options.grid.autoHighlight) {
-                // clear auto-highlights
-                for (var i = 0; i < highlights.length; ++i) {
-                    var h = highlights[i];
-                    if (h.auto == eventname &&
-                        !(item && h.series == item.series &&
-                          h.point[0] == item.datapoint[0] &&
-                          h.point[1] == item.datapoint[1]))
-                        unhighlight(h.series, h.point);
-                }
-                
-                if (item)
-                    highlight(item.series, item.datapoint, eventname);
-            }
-            
-            placeholder.trigger(eventname, [ pos, item ]);
-        }
-
-        function triggerRedrawOverlay() {
-            if (!redrawTimeout)
-                redrawTimeout = setTimeout(drawOverlay, 30);
-        }
-
-        function drawOverlay() {
-            redrawTimeout = null;
-
-            // draw highlights
-            octx.save();
-            octx.clearRect(0, 0, canvasWidth, canvasHeight);
-            octx.translate(plotOffset.left, plotOffset.top);
-            
-            var i, hi;
-            for (i = 0; i < highlights.length; ++i) {
-                hi = highlights[i];
-
-                if (hi.series.bars.show)
-                    drawBarHighlight(hi.series, hi.point);
-                else
-                    drawPointHighlight(hi.series, hi.point);
-            }
-            octx.restore();
-            
-            executeHooks(hooks.drawOverlay, [octx]);
-        }
-        
-        function highlight(s, point, auto) {
-            if (typeof s == "number")
-                s = series[s];
-
-            if (typeof point == "number") {
-                var ps = s.datapoints.pointsize;
-                point = s.datapoints.points.slice(ps * point, ps * (point + 1));
-            }
-
-            var i = indexOfHighlight(s, point);
-            if (i == -1) {
-                highlights.push({ series: s, point: point, auto: auto });
-
-                triggerRedrawOverlay();
-            }
-            else if (!auto)
-                highlights[i].auto = false;
-        }
-            
-        function unhighlight(s, point) {
-            if (s == null && point == null) {
-                highlights = [];
-                triggerRedrawOverlay();
-            }
-            
-            if (typeof s == "number")
-                s = series[s];
-
-            if (typeof point == "number")
-                point = s.data[point];
-
-            var i = indexOfHighlight(s, point);
-            if (i != -1) {
-                highlights.splice(i, 1);
-
-                triggerRedrawOverlay();
-            }
-        }
-        
-        function indexOfHighlight(s, p) {
-            for (var i = 0; i < highlights.length; ++i) {
-                var h = highlights[i];
-                if (h.series == s && h.point[0] == p[0]
-                    && h.point[1] == p[1])
-                    return i;
-            }
-            return -1;
-        }
-        
-        function drawPointHighlight(series, point) {
-            var x = point[0], y = point[1],
-                axisx = series.xaxis, axisy = series.yaxis;
-            
-            if (x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)
-                return;
-            
-            var pointRadius = series.points.radius + series.points.lineWidth / 2;
-            octx.lineWidth = pointRadius;
-            octx.strokeStyle = $.color.parse(series.color).scale('a', 0.5).toString();
-            var radius = 1.5 * pointRadius,
-                x = axisx.p2c(x),
-                y = axisy.p2c(y);
-            
-            octx.beginPath();
-            if (series.points.symbol == "circle")
-                octx.arc(x, y, radius, 0, 2 * Math.PI, false);
-            else
-                series.points.symbol(octx, x, y, radius, false);
-            octx.closePath();
-            octx.stroke();
-        }
-
-        function drawBarHighlight(series, point) {
-            octx.lineWidth = series.bars.lineWidth;
-            octx.strokeStyle = $.color.parse(series.color).scale('a', 0.5).toString();
-            var fillStyle = $.color.parse(series.color).scale('a', 0.5).toString();
-            var barLeft = series.bars.align == "left" ? 0 : -series.bars.barWidth/2;
-            drawBar(point[0], point[1], point[2] || 0, barLeft, barLeft + series.bars.barWidth,
-                    0, function () { return fillStyle; }, series.xaxis, series.yaxis, octx, series.bars.horizontal, series.bars.lineWidth);
-        }
-
-        function getColorOrGradient(spec, bottom, top, defaultColor) {
-            if (typeof spec == "string")
-                return spec;
-            else {
-                // assume this is a gradient spec; IE currently only
-                // supports a simple vertical gradient properly, so that's
-                // what we support too
-                var gradient = ctx.createLinearGradient(0, top, 0, bottom);
-                
-                for (var i = 0, l = spec.colors.length; i < l; ++i) {
-                    var c = spec.colors[i];
-                    if (typeof c != "string") {
-                        var co = $.color.parse(defaultColor);
-                        if (c.brightness != null)
-                            co = co.scale('rgb', c.brightness)
-                        if (c.opacity != null)
-                            co.a *= c.opacity;
-                        c = co.toString();
-                    }
-                    gradient.addColorStop(i / (l - 1), c);
-                }
-                
-                return gradient;
-            }
-        }
-    }
-
-    $.plot = function(placeholder, data, options) {
-        //var t0 = new Date();
-        var plot = new Plot($(placeholder), data, options, $.plot.plugins);
-        //(window.console ? console.log : alert)("time used (msecs): " + ((new Date()).getTime() - t0.getTime()));
-        return plot;
-    };
-
-    $.plot.version = "0.7";
-    
-    $.plot.plugins = [];
-
-    // returns a string with the date d formatted according to fmt
-    $.plot.formatDate = function(d, fmt, monthNames) {
-        var leftPad = function(n) {
-            n = "" + n;
-            return n.length == 1 ? "0" + n : n;
-        };
-        
-        var r = [];
-        var escape = false, padNext = false;
-        var hours = d.getUTCHours();
-        var isAM = hours < 12;
-        if (monthNames == null)
-            monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
-
-        if (fmt.search(/%p|%P/) != -1) {
-            if (hours > 12) {
-                hours = hours - 12;
-            } else if (hours == 0) {
-                hours = 12;
-            }
-        }
-        for (var i = 0; i < fmt.length; ++i) {
-            var c = fmt.charAt(i);
-            
-            if (escape) {
-                switch (c) {
-                case 'h': c = "" + hours; break;
-                case 'H': c = leftPad(hours); break;
-                case 'M': c = leftPad(d.getUTCMinutes()); break;
-                case 'S': c = leftPad(d.getUTCSeconds()); break;
-                case 'd': c = "" + d.getUTCDate(); break;
-                case 'm': c = "" + (d.getUTCMonth() + 1); break;
-                case 'y': c = "" + d.getUTCFullYear(); break;
-                case 'b': c = "" + monthNames[d.getUTCMonth()]; break;
-                case 'p': c = (isAM) ? ("" + "am") : ("" + "pm"); break;
-                case 'P': c = (isAM) ? ("" + "AM") : ("" + "PM"); break;
-                case '0': c = ""; padNext = true; break;
-                }
-                if (c && padNext) {
-                    c = leftPad(c);
-                    padNext = false;
-                }
-                r.push(c);
-                if (!padNext)
-                    escape = false;
-            }
-            else {
-                if (c == "%")
-                    escape = true;
-                else
-                    r.push(c);
-            }
-        }
-        return r.join("");
-    };
-    
-    // round to nearby lower multiple of base
-    function floorInBase(n, base) {
-        return base * Math.floor(n / base);
-    }
-    
-})(jQuery);
diff --git a/static/js/plugins/flot/jquery.flot.pie.js b/static/js/plugins/flot/jquery.flot.pie.js
deleted file mode 100755
index b46c03c..0000000
--- a/static/js/plugins/flot/jquery.flot.pie.js
+++ /dev/null
@@ -1,750 +0,0 @@
-/*
-Flot plugin for rendering pie charts. The plugin assumes the data is 
-coming is as a single data value for each series, and each of those 
-values is a positive value or zero (negative numbers don't make 
-any sense and will cause strange effects). The data values do 
-NOT need to be passed in as percentage values because it 
-internally calculates the total and percentages.
-
-* Created by Brian Medendorp, June 2009
-* Updated November 2009 with contributions from: btburnett3, Anthony Aragues and Xavi Ivars
-
-* Changes:
-	2009-10-22: lineJoin set to round
-	2009-10-23: IE full circle fix, donut
-	2009-11-11: Added basic hover from btburnett3 - does not work in IE, and center is off in Chrome and Opera
-	2009-11-17: Added IE hover capability submitted by Anthony Aragues
-	2009-11-18: Added bug fix submitted by Xavi Ivars (issues with arrays when other JS libraries are included as well)
-		
-
-Available options are:
-series: {
-	pie: {
-		show: true/false
-		radius: 0-1 for percentage of fullsize, or a specified pixel length, or 'auto'
-		innerRadius: 0-1 for percentage of fullsize or a specified pixel length, for creating a donut effect
-		startAngle: 0-2 factor of PI used for starting angle (in radians) i.e 3/2 starts at the top, 0 and 2 have the same result
-		tilt: 0-1 for percentage to tilt the pie, where 1 is no tilt, and 0 is completely flat (nothing will show)
-		offset: {
-			top: integer value to move the pie up or down
-			left: integer value to move the pie left or right, or 'auto'
-		},
-		stroke: {
-			color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#FFF')
-			width: integer pixel width of the stroke
-		},
-		label: {
-			show: true/false, or 'auto'
-			formatter:  a user-defined function that modifies the text/style of the label text
-			radius: 0-1 for percentage of fullsize, or a specified pixel length
-			background: {
-				color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#000')
-				opacity: 0-1
-			},
-			threshold: 0-1 for the percentage value at which to hide labels (if they're too small)
-		},
-		combine: {
-			threshold: 0-1 for the percentage value at which to combine slices (if they're too small)
-			color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#CCC'), if null, the plugin will automatically use the color of the first slice to be combined
-			label: any text value of what the combined slice should be labeled
-		}
-		highlight: {
-			opacity: 0-1
-		}
-	}
-}
-
-More detail and specific examples can be found in the included HTML file.
-
-*/
-
-(function ($) 
-{
-	function init(plot) // this is the "body" of the plugin
-	{
-		var canvas = null;
-		var target = null;
-		var maxRadius = null;
-		var centerLeft = null;
-		var centerTop = null;
-		var total = 0;
-		var redraw = true;
-		var redrawAttempts = 10;
-		var shrink = 0.95;
-		var legendWidth = 0;
-		var processed = false;
-		var raw = false;
-		
-		// interactive variables	
-		var highlights = [];	
-	
-		// add hook to determine if pie plugin in enabled, and then perform necessary operations
-		plot.hooks.processOptions.push(checkPieEnabled);
-		plot.hooks.bindEvents.push(bindEvents);	
-
-		// check to see if the pie plugin is enabled
-		function checkPieEnabled(plot, options)
-		{
-			if (options.series.pie.show)
-			{
-				//disable grid
-				options.grid.show = false;
-				
-				// set labels.show
-				if (options.series.pie.label.show=='auto')
-					if (options.legend.show)
-						options.series.pie.label.show = false;
-					else
-						options.series.pie.label.show = true;
-				
-				// set radius
-				if (options.series.pie.radius=='auto')
-					if (options.series.pie.label.show)
-						options.series.pie.radius = 3/4;
-					else
-						options.series.pie.radius = 1;
-						
-				// ensure sane tilt
-				if (options.series.pie.tilt>1)
-					options.series.pie.tilt=1;
-				if (options.series.pie.tilt<0)
-					options.series.pie.tilt=0;
-			
-				// add processData hook to do transformations on the data
-				plot.hooks.processDatapoints.push(processDatapoints);
-				plot.hooks.drawOverlay.push(drawOverlay);	
-				
-				// add draw hook
-				plot.hooks.draw.push(draw);
-			}
-		}
-	
-		// bind hoverable events
-		function bindEvents(plot, eventHolder) 		
-		{		
-			var options = plot.getOptions();
-			
-			if (options.series.pie.show && options.grid.hoverable)
-				eventHolder.unbind('mousemove').mousemove(onMouseMove);
-				
-			if (options.series.pie.show && options.grid.clickable)
-				eventHolder.unbind('click').click(onClick);
-		}	
-		
-
-		// debugging function that prints out an object
-		function alertObject(obj)
-		{
-			var msg = '';
-			function traverse(obj, depth)
-			{
-				if (!depth)
-					depth = 0;
-				for (var i = 0; i < obj.length; ++i)
-				{
-					for (var j=0; j<depth; j++)
-						msg += '\t';
-				
-					if( typeof obj[i] == "object")
-					{	// its an object
-						msg += ''+i+':\n';
-						traverse(obj[i], depth+1);
-					}
-					else
-					{	// its a value
-						msg += ''+i+': '+obj[i]+'\n';
-					}
-				}
-			}
-			traverse(obj);
-			alert(msg);
-		}
-		
-		function calcTotal(data)
-		{
-			for (var i = 0; i < data.length; ++i)
-			{
-				var item = parseFloat(data[i].data[0][1]);
-				if (item)
-					total += item;
-			}
-		}	
-		
-		function processDatapoints(plot, series, data, datapoints) 
-		{	
-			if (!processed)
-			{
-				processed = true;
-			
-				canvas = plot.getCanvas();
-				target = $(canvas).parent();
-				options = plot.getOptions();
-			
-				plot.setData(combine(plot.getData()));
-			}
-		}
-		
-		function setupPie()
-		{
-			legendWidth = target.children().filter('.legend').children().width();
-		
-			// calculate maximum radius and center point
-			maxRadius =  Math.min(canvas.width,(canvas.height/options.series.pie.tilt))/2;
-			centerTop = (canvas.height/2)+options.series.pie.offset.top;
-			centerLeft = (canvas.width/2);
-			
-			if (options.series.pie.offset.left=='auto')
-				if (options.legend.position.match('w'))
-					centerLeft += legendWidth/2;
-				else
-					centerLeft -= legendWidth/2;
-			else
-				centerLeft += options.series.pie.offset.left;
-					
-			if (centerLeft<maxRadius)
-				centerLeft = maxRadius;
-			else if (centerLeft>canvas.width-maxRadius)
-				centerLeft = canvas.width-maxRadius;
-		}
-		
-		function fixData(data)
-		{
-			for (var i = 0; i < data.length; ++i)
-			{
-				if (typeof(data[i].data)=='number')
-					data[i].data = [[1,data[i].data]];
-				else if (typeof(data[i].data)=='undefined' || typeof(data[i].data[0])=='undefined')
-				{
-					if (typeof(data[i].data)!='undefined' && typeof(data[i].data.label)!='undefined')
-						data[i].label = data[i].data.label; // fix weirdness coming from flot
-					data[i].data = [[1,0]];
-					
-				}
-			}
-			return data;
-		}
-		
-		function combine(data)
-		{
-			data = fixData(data);
-			calcTotal(data);
-			var combined = 0;
-			var numCombined = 0;
-			var color = options.series.pie.combine.color;
-			
-			var newdata = [];
-			for (var i = 0; i < data.length; ++i)
-			{
-				// make sure its a number
-				data[i].data[0][1] = parseFloat(data[i].data[0][1]);
-				if (!data[i].data[0][1])
-					data[i].data[0][1] = 0;
-					
-				if (data[i].data[0][1]/total<=options.series.pie.combine.threshold)
-				{
-					combined += data[i].data[0][1];
-					numCombined++;
-					if (!color)
-						color = data[i].color;
-				}				
-				else
-				{
-					newdata.push({
-						data: [[1,data[i].data[0][1]]], 
-						color: data[i].color, 
-						label: data[i].label,
-						angle: (data[i].data[0][1]*(Math.PI*2))/total,
-						percent: (data[i].data[0][1]/total*100)
-					});
-				}
-			}
-			if (numCombined>0)
-				newdata.push({
-					data: [[1,combined]], 
-					color: color, 
-					label: options.series.pie.combine.label,
-					angle: (combined*(Math.PI*2))/total,
-					percent: (combined/total*100)
-				});
-			return newdata;
-		}		
-		
-		function draw(plot, newCtx)
-		{
-			if (!target) return; // if no series were passed
-			ctx = newCtx;
-		
-			setupPie();
-			var slices = plot.getData();
-		
-			var attempts = 0;
-			while (redraw && attempts<redrawAttempts)
-			{
-				redraw = false;
-				if (attempts>0)
-					maxRadius *= shrink;
-				attempts += 1;
-				clear();
-				if (options.series.pie.tilt<=0.8)
-					drawShadow();
-				drawPie();
-			}
-			if (attempts >= redrawAttempts) {
-				clear();
-				target.prepend('<div class="error">Could not draw pie with labels contained inside canvas</div>');
-			}
-			
-			if ( plot.setSeries && plot.insertLegend )
-			{
-				plot.setSeries(slices);
-				plot.insertLegend();
-			}
-			
-			// we're actually done at this point, just defining internal functions at this point
-			
-			function clear()
-			{
-				ctx.clearRect(0,0,canvas.width,canvas.height);
-				target.children().filter('.pieLabel, .pieLabelBackground').remove();
-			}
-			
-			function drawShadow()
-			{
-				var shadowLeft = 5;
-				var shadowTop = 15;
-				var edge = 10;
-				var alpha = 0.02;
-			
-				// set radius
-				if (options.series.pie.radius>1)
-					var radius = options.series.pie.radius;
-				else
-					var radius = maxRadius * options.series.pie.radius;
-					
-				if (radius>=(canvas.width/2)-shadowLeft || radius*options.series.pie.tilt>=(canvas.height/2)-shadowTop || radius<=edge)
-					return;	// shadow would be outside canvas, so don't draw it
-			
-				ctx.save();
-				ctx.translate(shadowLeft,shadowTop);
-				ctx.globalAlpha = alpha;
-				ctx.fillStyle = '#000';
-
-				// center and rotate to starting position
-				ctx.translate(centerLeft,centerTop);
-				ctx.scale(1, options.series.pie.tilt);
-				
-				//radius -= edge;
-				for (var i=1; i<=edge; i++)
-				{
-					ctx.beginPath();
-					ctx.arc(0,0,radius,0,Math.PI*2,false);
-					ctx.fill();
-					radius -= i;
-				}	
-				
-				ctx.restore();
-			}
-			
-			function drawPie()
-			{
-				startAngle = Math.PI*options.series.pie.startAngle;
-				
-				// set radius
-				if (options.series.pie.radius>1)
-					var radius = options.series.pie.radius;
-				else
-					var radius = maxRadius * options.series.pie.radius;
-				
-				// center and rotate to starting position
-				ctx.save();
-				ctx.translate(centerLeft,centerTop);
-				ctx.scale(1, options.series.pie.tilt);
-				//ctx.rotate(startAngle); // start at top; -- This doesn't work properly in Opera
-				
-				// draw slices
-				ctx.save();
-				var currentAngle = startAngle;
-				for (var i = 0; i < slices.length; ++i)
-				{
-					slices[i].startAngle = currentAngle;
-					drawSlice(slices[i].angle, slices[i].color, true);
-				}
-				ctx.restore();
-				
-				// draw slice outlines
-				ctx.save();
-				ctx.lineWidth = options.series.pie.stroke.width;
-				currentAngle = startAngle;
-				for (var i = 0; i < slices.length; ++i)
-					drawSlice(slices[i].angle, options.series.pie.stroke.color, false);
-				ctx.restore();
-					
-				// draw donut hole
-				drawDonutHole(ctx);
-				
-				// draw labels
-				if (options.series.pie.label.show)
-					drawLabels();
-				
-				// restore to original state
-				ctx.restore();
-				
-				function drawSlice(angle, color, fill)
-				{	
-					if (angle<=0)
-						return;
-				
-					if (fill)
-						ctx.fillStyle = color;
-					else
-					{
-						ctx.strokeStyle = color;
-						ctx.lineJoin = 'round';
-					}
-						
-					ctx.beginPath();
-					if (Math.abs(angle - Math.PI*2) > 0.000000001)
-						ctx.moveTo(0,0); // Center of the pie
-					else if ($.browser.msie)
-						angle -= 0.0001;
-					//ctx.arc(0,0,radius,0,angle,false); // This doesn't work properly in Opera
-					ctx.arc(0,0,radius,currentAngle,currentAngle+angle,false);
-					ctx.closePath();
-					//ctx.rotate(angle); // This doesn't work properly in Opera
-					currentAngle += angle;
-					
-					if (fill)
-						ctx.fill();
-					else
-						ctx.stroke();
-				}
-				
-				function drawLabels()
-				{
-					var currentAngle = startAngle;
-					
-					// set radius
-					if (options.series.pie.label.radius>1)
-						var radius = options.series.pie.label.radius;
-					else
-						var radius = maxRadius * options.series.pie.label.radius;
-					
-					for (var i = 0; i < slices.length; ++i)
-					{
-						if (slices[i].percent >= options.series.pie.label.threshold*100)
-							drawLabel(slices[i], currentAngle, i);
-						currentAngle += slices[i].angle;
-					}
-					
-					function drawLabel(slice, startAngle, index)
-					{
-						if (slice.data[0][1]==0)
-							return;
-							
-						// format label text
-						var lf = options.legend.labelFormatter, text, plf = options.series.pie.label.formatter;
-						if (lf)
-							text = lf(slice.label, slice);
-						else
-							text = slice.label;
-						if (plf)
-							text = plf(text, slice);
-							
-						var halfAngle = ((startAngle+slice.angle) + startAngle)/2;
-						var x = centerLeft + Math.round(Math.cos(halfAngle) * radius);
-						var y = centerTop + Math.round(Math.sin(halfAngle) * radius) * options.series.pie.tilt;
-						
-						var html = '<span class="pieLabel" id="pieLabel'+index+'" style="position:absolute;top:' + y + 'px;left:' + x + 'px;">' + text + "</span>";
-						target.append(html);
-						var label = target.children('#pieLabel'+index);
-						var labelTop = (y - label.height()/2);
-						var labelLeft = (x - label.width()/2);
-						label.css('top', labelTop);
-						label.css('left', labelLeft);
-						
-						// check to make sure that the label is not outside the canvas
-						if (0-labelTop>0 || 0-labelLeft>0 || canvas.height-(labelTop+label.height())<0 || canvas.width-(labelLeft+label.width())<0)
-							redraw = true;
-						
-						if (options.series.pie.label.background.opacity != 0) {
-							// put in the transparent background separately to avoid blended labels and label boxes
-							var c = options.series.pie.label.background.color;
-							if (c == null) {
-								c = slice.color;
-							}
-							var pos = 'top:'+labelTop+'px;left:'+labelLeft+'px;';
-							$('<div class="pieLabelBackground" style="position:absolute;width:' + label.width() + 'px;height:' + label.height() + 'px;' + pos +'background-color:' + c + ';"> </div>').insertBefore(label).css('opacity', options.series.pie.label.background.opacity);
-						}
-					} // end individual label function
-				} // end drawLabels function
-			} // end drawPie function
-		} // end draw function
-		
-		// Placed here because it needs to be accessed from multiple locations 
-		function drawDonutHole(layer)
-		{
-			// draw donut hole
-			if(options.series.pie.innerRadius > 0)
-			{
-				// subtract the center
-				layer.save();
-				innerRadius = options.series.pie.innerRadius > 1 ? options.series.pie.innerRadius : maxRadius * options.series.pie.innerRadius;
-				layer.globalCompositeOperation = 'destination-out'; // this does not work with excanvas, but it will fall back to using the stroke color
-				layer.beginPath();
-				layer.fillStyle = options.series.pie.stroke.color;
-				layer.arc(0,0,innerRadius,0,Math.PI*2,false);
-				layer.fill();
-				layer.closePath();
-				layer.restore();
-				
-				// add inner stroke
-				layer.save();
-				layer.beginPath();
-				layer.strokeStyle = options.series.pie.stroke.color;
-				layer.arc(0,0,innerRadius,0,Math.PI*2,false);
-				layer.stroke();
-				layer.closePath();
-				layer.restore();
-				// TODO: add extra shadow inside hole (with a mask) if the pie is tilted.
-			}
-		}
-		
-		//-- Additional Interactive related functions --
-		
-		function isPointInPoly(poly, pt)
-		{
-			for(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)
-				((poly[i][1] <= pt[1] && pt[1] < poly[j][1]) || (poly[j][1] <= pt[1] && pt[1]< poly[i][1]))
-				&& (pt[0] < (poly[j][0] - poly[i][0]) * (pt[1] - poly[i][1]) / (poly[j][1] - poly[i][1]) + poly[i][0])
-				&& (c = !c);
-			return c;
-		}
-		
-		function findNearbySlice(mouseX, mouseY)
-		{
-			var slices = plot.getData(),
-				options = plot.getOptions(),
-				radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
-			
-			for (var i = 0; i < slices.length; ++i) 
-			{
-				var s = slices[i];	
-				
-				if(s.pie.show)
-				{
-					ctx.save();
-					ctx.beginPath();
-					ctx.moveTo(0,0); // Center of the pie
-					//ctx.scale(1, options.series.pie.tilt);	// this actually seems to break everything when here.
-					ctx.arc(0,0,radius,s.startAngle,s.startAngle+s.angle,false);
-					ctx.closePath();
-					x = mouseX-centerLeft;
-					y = mouseY-centerTop;
-					if(ctx.isPointInPath)
-					{
-						if (ctx.isPointInPath(mouseX-centerLeft, mouseY-centerTop))
-						{
-							//alert('found slice!');
-							ctx.restore();
-							return {datapoint: [s.percent, s.data], dataIndex: 0, series: s, seriesIndex: i};
-						}
-					}
-					else
-					{
-						// excanvas for IE doesn;t support isPointInPath, this is a workaround. 
-						p1X = (radius * Math.cos(s.startAngle));
-						p1Y = (radius * Math.sin(s.startAngle));
-						p2X = (radius * Math.cos(s.startAngle+(s.angle/4)));
-						p2Y = (radius * Math.sin(s.startAngle+(s.angle/4)));
-						p3X = (radius * Math.cos(s.startAngle+(s.angle/2)));
-						p3Y = (radius * Math.sin(s.startAngle+(s.angle/2)));
-						p4X = (radius * Math.cos(s.startAngle+(s.angle/1.5)));
-						p4Y = (radius * Math.sin(s.startAngle+(s.angle/1.5)));
-						p5X = (radius * Math.cos(s.startAngle+s.angle));
-						p5Y = (radius * Math.sin(s.startAngle+s.angle));
-						arrPoly = [[0,0],[p1X,p1Y],[p2X,p2Y],[p3X,p3Y],[p4X,p4Y],[p5X,p5Y]];
-						arrPoint = [x,y];
-						// TODO: perhaps do some mathmatical trickery here with the Y-coordinate to compensate for pie tilt?
-						if(isPointInPoly(arrPoly, arrPoint))
-						{
-							ctx.restore();
-							return {datapoint: [s.percent, s.data], dataIndex: 0, series: s, seriesIndex: i};
-						}			
-					}
-					ctx.restore();
-				}
-			}
-			
-			return null;
-		}
-
-		function onMouseMove(e) 
-		{
-			triggerClickHoverEvent('plothover', e);
-		}
-		
-        function onClick(e) 
-		{
-			triggerClickHoverEvent('plotclick', e);
-        }
-
-		// trigger click or hover event (they send the same parameters so we share their code)
-		function triggerClickHoverEvent(eventname, e) 
-		{
-			var offset = plot.offset(),
-				canvasX = parseInt(e.pageX - offset.left),
-				canvasY =  parseInt(e.pageY - offset.top),
-				item = findNearbySlice(canvasX, canvasY);
-			
-			if (options.grid.autoHighlight) 
-			{
-				// clear auto-highlights
-				for (var i = 0; i < highlights.length; ++i) 
-				{
-					var h = highlights[i];
-					if (h.auto == eventname && !(item && h.series == item.series))
-						unhighlight(h.series);
-				}
-			}
-			
-			// highlight the slice
-			if (item) 
-			    highlight(item.series, eventname);
-				
-			// trigger any hover bind events
-			var pos = { pageX: e.pageX, pageY: e.pageY };
-			target.trigger(eventname, [ pos, item ]);	
-		}
-
-		function highlight(s, auto) 
-		{
-			if (typeof s == "number")
-				s = series[s];
-
-			var i = indexOfHighlight(s);
-			if (i == -1) 
-			{
-				highlights.push({ series: s, auto: auto });
-				plot.triggerRedrawOverlay();
-			}
-			else if (!auto)
-				highlights[i].auto = false;
-		}
-
-		function unhighlight(s) 
-		{
-			if (s == null) 
-			{
-				highlights = [];
-				plot.triggerRedrawOverlay();
-			}
-			
-			if (typeof s == "number")
-				s = series[s];
-
-			var i = indexOfHighlight(s);
-			if (i != -1) 
-			{
-				highlights.splice(i, 1);
-				plot.triggerRedrawOverlay();
-			}
-		}
-
-		function indexOfHighlight(s) 
-		{
-			for (var i = 0; i < highlights.length; ++i) 
-			{
-				var h = highlights[i];
-				if (h.series == s)
-					return i;
-			}
-			return -1;
-		}
-
-		function drawOverlay(plot, octx) 
-		{
-			//alert(options.series.pie.radius);
-			var options = plot.getOptions();
-			//alert(options.series.pie.radius);
-			
-			var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
-
-			octx.save();
-			octx.translate(centerLeft, centerTop);
-			octx.scale(1, options.series.pie.tilt);
-			
-			for (i = 0; i < highlights.length; ++i) 
-				drawHighlight(highlights[i].series);
-			
-			drawDonutHole(octx);
-
-			octx.restore();
-
-			function drawHighlight(series) 
-			{
-				if (series.angle < 0) return;
-				
-				//octx.fillStyle = parseColor(options.series.pie.highlight.color).scale(null, null, null, options.series.pie.highlight.opacity).toString();
-				octx.fillStyle = "rgba(255, 255, 255, "+options.series.pie.highlight.opacity+")"; // this is temporary until we have access to parseColor
-				
-				octx.beginPath();
-				if (Math.abs(series.angle - Math.PI*2) > 0.000000001)
-					octx.moveTo(0,0); // Center of the pie
-				octx.arc(0,0,radius,series.startAngle,series.startAngle+series.angle,false);
-				octx.closePath();
-				octx.fill();
-			}
-			
-		}	
-		
-	} // end init (plugin body)
-	
-	// define pie specific options and their default values
-	var options = {
-		series: {
-			pie: {
-				show: false,
-				radius: 'auto',	// actual radius of the visible pie (based on full calculated radius if <=1, or hard pixel value)
-				innerRadius:0, /* for donut */
-				startAngle: 3/2,
-				tilt: 1,
-				offset: {
-					top: 0,
-					left: 'auto'
-				},
-				stroke: {
-					color: '#FFF',
-					width: 1
-				},
-				label: {
-					show: 'auto',
-					formatter: function(label, slice){
-						return '<div style="font-size:x-small;text-align:center;padding:2px;color:'+slice.color+';">'+label+'<br/>'+Math.round(slice.percent)+'%</div>';
-					},	// formatter function
-					radius: 1,	// radius at which to place the labels (based on full calculated radius if <=1, or hard pixel value)
-					background: {
-						color: null,
-						opacity: 0
-					},
-					threshold: 0	// percentage at which to hide the label (i.e. the slice is too narrow)
-				},
-				combine: {
-					threshold: -1,	// percentage at which to combine little slices into one larger slice
-					color: null,	// color to give the new slice (auto-generated if null)
-					label: 'Other'	// label to give the new slice
-				},
-				highlight: {
-					//color: '#FFF',		// will add this functionality once parseColor is available
-					opacity: 0.5
-				}
-			}
-		}
-	};
-    
-	$.plot.plugins.push({
-		init: init,
-		options: options,
-		name: "pie",
-		version: "1.0"
-	});
-})(jQuery);
diff --git a/static/js/plugins/flot/jquery.flot.resize.js b/static/js/plugins/flot/jquery.flot.resize.js
deleted file mode 100755
index 1178425..0000000
--- a/static/js/plugins/flot/jquery.flot.resize.js
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Flot plugin for automatically redrawing plots as the placeholder resizes.
-
-Copyright (c) 2007-2013 IOLA and Ole Laursen.
-Licensed under the MIT license.
-
-It works by listening for changes on the placeholder div (through the jQuery
-resize event plugin) - if the size changes, it will redraw the plot.
-
-There are no options. If you need to disable the plugin for some plots, you
-can just fix the size of their placeholders.
-
-*/
-
-/* Inline dependency:
- * jQuery resize event - v1.1 - 3/14/2010
- * http://benalman.com/projects/jquery-resize-plugin/
- *
- * Copyright (c) 2010 "Cowboy" Ben Alman
- * Dual licensed under the MIT and GPL licenses.
- * http://benalman.com/about/license/
- */
-
-(function($,h,c){var a=$([]),e=$.resize=$.extend($.resize,{}),i,k="setTimeout",j="resize",d=j+"-special-event",b="delay",f="throttleWindow";e[b]=250;e[f]=true;$.event.special[j]={setup:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.add(l);$.data(this,d,{w:l.width(),h:l.height()});if(a.length===1){g()}},teardown:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.not(l);l.removeData(d);if(!a.length){clearTimeout(i)}},add:function(l){if(!e[f]&&this[k]){return false}var n;function m(s,o,p){var q=$(this),r=$.data(this,d);r.w=o!==c?o:q.width();r.h=p!==c?p:q.height();n.apply(this,arguments)}if($.isFunction(l)){n=l;return m}else{n=l.handler;l.handler=m}}};function g(){i=h[k](function(){a.each(function(){var n=$(this),m=n.width(),l=n.height(),o=$.data(this,d);if(m!==o.w||l!==o.h){n.trigger(j,[o.w=m,o.h=l])}});g()},e[b])}})(jQuery,this);
-
-(function ($) {
-    var options = { }; // no options
-
-    function init(plot) {
-        function onResize() {
-            var placeholder = plot.getPlaceholder();
-
-            // somebody might have hidden us and we can't plot
-            // when we don't have the dimensions
-            if (placeholder.width() == 0 || placeholder.height() == 0)
-                return;
-
-            plot.resize();
-            plot.setupGrid();
-            plot.draw();
-        }
-        
-        function bindEvents(plot, eventHolder) {
-            plot.getPlaceholder().resize(onResize);
-        }
-
-        function shutdown(plot, eventHolder) {
-            plot.getPlaceholder().unbind("resize", onResize);
-        }
-        
-        plot.hooks.bindEvents.push(bindEvents);
-        plot.hooks.shutdown.push(shutdown);
-    }
-    
-    $.plot.plugins.push({
-        init: init,
-        options: options,
-        name: 'resize',
-        version: '1.0'
-    });
-})(jQuery);
\ No newline at end of file
diff --git a/static/js/plugins/flot/jquery.flot.tooltip.min.js b/static/js/plugins/flot/jquery.flot.tooltip.min.js
deleted file mode 100755
index 09e3bbf..0000000
--- a/static/js/plugins/flot/jquery.flot.tooltip.min.js
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * jquery.flot.tooltip
- * 
- * description: easy-to-use tooltips for Flot charts
- * version: 0.6.2
- * author: Krzysztof Urbas @krzysu [myviews.pl]
- * website: https://github.com/krzysu/flot.tooltip
- * 
- * build on 2013-09-30
- * released under MIT License, 2012
-*/ 
-(function(t){var o={tooltip:!1,tooltipOpts:{content:"%s | X: %x | Y: %y",xDateFormat:null,yDateFormat:null,shifts:{x:10,y:20},defaultTheme:!0,onHover:function(){}}},i=function(t){this.tipPosition={x:0,y:0},this.init(t)};i.prototype.init=function(o){function i(t){var o={};o.x=t.pageX,o.y=t.pageY,s.updateTooltipPosition(o)}function e(t,o,i){var e=s.getDomElement();if(i){var n;n=s.stringFormat(s.tooltipOptions.content,i),e.html(n),s.updateTooltipPosition({x:o.pageX,y:o.pageY}),e.css({left:s.tipPosition.x+s.tooltipOptions.shifts.x,top:s.tipPosition.y+s.tooltipOptions.shifts.y}).show(),"function"==typeof s.tooltipOptions.onHover&&s.tooltipOptions.onHover(i,e)}else e.hide().html("")}var s=this;o.hooks.bindEvents.push(function(o,n){s.plotOptions=o.getOptions(),s.plotOptions.tooltip!==!1&&void 0!==s.plotOptions.tooltip&&(s.tooltipOptions=s.plotOptions.tooltipOpts,s.getDomElement(),t(o.getPlaceholder()).bind("plothover",e),t(n).bind("mousemove",i))}),o.hooks.shutdown.push(function(o,s){t(o.getPlaceholder()).unbind("plothover",e),t(s).unbind("mousemove",i)})},i.prototype.getDomElement=function(){var o;return t("#flotTip").length>0?o=t("#flotTip"):(o=t("<div />").attr("id","flotTip"),o.appendTo("body").hide().css({position:"absolute"}),this.tooltipOptions.defaultTheme&&o.css({background:"#fff","z-index":"100",padding:"0.4em 0.6em","border-radius":"0.5em","font-size":"0.8em",border:"1px solid #111",display:"none","white-space":"nowrap"})),o},i.prototype.updateTooltipPosition=function(o){var i=t("#flotTip").outerWidth()+this.tooltipOptions.shifts.x,e=t("#flotTip").outerHeight()+this.tooltipOptions.shifts.y;o.x-t(window).scrollLeft()>t(window).innerWidth()-i&&(o.x-=i),o.y-t(window).scrollTop()>t(window).innerHeight()-e&&(o.y-=e),this.tipPosition.x=o.x,this.tipPosition.y=o.y},i.prototype.stringFormat=function(t,o){var i=/%p\.{0,1}(\d{0,})/,e=/%s/,s=/%x\.{0,1}(?:\d{0,})/,n=/%y\.{0,1}(?:\d{0,})/;return"function"==typeof t&&(t=t(o.series.label,o.series.data[o.dataIndex][0],o.series.data[o.dataIndex][1],o)),o.series.percent!==void 0&&(t=this.adjustValPrecision(i,t,o.series.percent)),o.series.label!==void 0&&(t=t.replace(e,o.series.label)),this.isTimeMode("xaxis",o)&&this.isXDateFormat(o)&&(t=t.replace(s,this.timestampToDate(o.series.data[o.dataIndex][0],this.tooltipOptions.xDateFormat))),this.isTimeMode("yaxis",o)&&this.isYDateFormat(o)&&(t=t.replace(n,this.timestampToDate(o.series.data[o.dataIndex][1],this.tooltipOptions.yDateFormat))),"number"==typeof o.series.data[o.dataIndex][0]&&(t=this.adjustValPrecision(s,t,o.series.data[o.dataIndex][0])),"number"==typeof o.series.data[o.dataIndex][1]&&(t=this.adjustValPrecision(n,t,o.series.data[o.dataIndex][1])),o.series.xaxis.tickFormatter!==void 0&&(t=t.replace(s,o.series.xaxis.tickFormatter(o.series.data[o.dataIndex][0],o.series.xaxis))),o.series.yaxis.tickFormatter!==void 0&&(t=t.replace(n,o.series.yaxis.tickFormatter(o.series.data[o.dataIndex][1],o.series.yaxis))),t},i.prototype.isTimeMode=function(t,o){return o.series[t].options.mode!==void 0&&"time"===o.series[t].options.mode},i.prototype.isXDateFormat=function(){return this.tooltipOptions.xDateFormat!==void 0&&null!==this.tooltipOptions.xDateFormat},i.prototype.isYDateFormat=function(){return this.tooltipOptions.yDateFormat!==void 0&&null!==this.tooltipOptions.yDateFormat},i.prototype.timestampToDate=function(o,i){var e=new Date(o);return t.plot.formatDate(e,i)},i.prototype.adjustValPrecision=function(t,o,i){var e,s=o.match(t);return null!==s&&""!==RegExp.$1&&(e=RegExp.$1,i=i.toFixed(e),o=o.replace(t,i)),o};var e=function(t){new i(t)};t.plot.plugins.push({init:e,options:o,name:"tooltip",version:"0.6.1"})})(jQuery);
\ No newline at end of file
diff --git a/static/js/spice-html5/spice.css b/static/js/spice-html5/spice.css
index 23b7e51..968ba16 100755
--- a/static/js/spice-html5/spice.css
+++ b/static/js/spice-html5/spice.css
@@ -36,7 +36,6 @@ body
 #login input
 {
     padding: 5px;
-    background-color: #fAfAfA;
     border: 1px inset #999999;
     outline: none;
     -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px;
@@ -81,7 +80,7 @@ body
 {
     min-height: 600px;
     height: 100%;
-    margin: 62px 10px 10px 10px;
+    margin: 10px;
     padding: 0;
     background-color: #333333;
 }
@@ -104,6 +103,8 @@ body
     -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
     -moz-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
     box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
+    /* We default the message box to hidden. */
+    display: none;
 }
 .spice-message p {
     margin-bottom: 0em;
diff --git a/storages/views.py b/storages/views.py
index d57e979..b7f6c25 100644
--- a/storages/views.py
+++ b/storages/views.py
@@ -105,7 +105,7 @@ def storage(request, compute_id, pool):
         size, free = conn.get_size()
         used = (size - free)
         if state:
-            percent = (used * 100) / size
+            percent = (used * 100) // size
         else:
             percent = 0
         status = conn.get_status()
@@ -127,31 +127,31 @@ def storage(request, compute_id, pool):
                 conn.start()
                 return HttpResponseRedirect(request.get_full_path())
             except libvirtError as lib_err:
-                error_messages.append(lib_err.message)
+                error_messages.append(lib_err)
         if 'stop' in request.POST:
             try:
                 conn.stop()
                 return HttpResponseRedirect(request.get_full_path())
             except libvirtError as lib_err:
-                error_messages.append(lib_err.message)
+                error_messages.append(lib_err)
         if 'delete' in request.POST:
             try:
                 conn.delete()
                 return HttpResponseRedirect(reverse('storages', args=[compute_id]))
             except libvirtError as lib_err:
-                error_messages.append(lib_err.message)
+                error_messages.append(lib_err)
         if 'set_autostart' in request.POST:
             try:
                 conn.set_autostart(1)
                 return HttpResponseRedirect(request.get_full_path())
             except libvirtError as lib_err:
-                error_messages.append(lib_err.message)
+                error_messages.append(lib_err)
         if 'unset_autostart' in request.POST:
             try:
                 conn.set_autostart(0)
                 return HttpResponseRedirect(request.get_full_path())
             except libvirtError as lib_err:
-                error_messages.append(lib_err.message)
+                error_messages.append(lib_err)
         if 'add_volume' in request.POST:
             form = AddImage(request.POST)
             if form.is_valid():
@@ -175,7 +175,7 @@ def storage(request, compute_id, pool):
                 messages.success(request, _('Volume: {} is deleted.'.format(volname)))
                 return HttpResponseRedirect(request.get_full_path())
             except libvirtError as lib_err:
-                error_messages.append(lib_err.message)
+                error_messages.append(lib_err)
         if 'iso_upload' in request.POST:
             if str(request.FILES['file']) in conn.update_volumes():
                 error_msg = _("ISO image already exist")
diff --git a/vrtManager/connection.py b/vrtManager/connection.py
index f0b8eb3..9639909 100644
--- a/vrtManager/connection.py
+++ b/vrtManager/connection.py
@@ -80,7 +80,7 @@ class wvmConnection(object):
                 elif self.type == CONN_SOCKET:
                     self.__connect_socket()
                 else:
-                    raise ValueError('"{type}" is not a valid connection type'.format(type=self.type))
+                    raise ValueError(f'"{self.type}" is not a valid connection type')
 
                 if self.connected:
                     # do some preprocessing of the connection:
@@ -135,14 +135,14 @@ class wvmConnection(object):
     def __connect_tcp(self):
         flags = [libvirt.VIR_CRED_AUTHNAME, libvirt.VIR_CRED_PASSPHRASE]
         auth = [flags, self.__libvirt_auth_credentials_callback, None]
-        uri = 'qemu+tcp://%s/system' % self.host
+        uri = f'qemu+tcp://{self.host}/system'
 
         try:
             self.connection = libvirt.openAuth(uri, auth, 0)
             self.last_error = None
 
         except libvirtError as e:
-            self.last_error = 'Connection Failed: ' + str(e)
+            self.last_error = f'Connection Failed: {str(e)}'
             self.connection = None
 
     def __connect_ssh(self):
@@ -153,7 +153,7 @@ class wvmConnection(object):
             self.last_error = None
 
         except libvirtError as e:
-            self.last_error = 'Connection Failed: ' + str(e) + ' --- ' + repr(libvirt.virGetLastError())
+            self.last_error = f'Connection Failed: {str(e)} --- ' + repr(libvirt.virGetLastError())
             self.connection = None
 
     def __connect_tls(self):
@@ -166,7 +166,7 @@ class wvmConnection(object):
             self.last_error = None
 
         except libvirtError as e:
-            self.last_error = 'Connection Failed: ' + str(e)
+            self.last_error = f'Connection Failed: {str(e)}'
             self.connection = None
 
     def __connect_socket(self):
@@ -177,7 +177,7 @@ class wvmConnection(object):
             self.last_error = None
 
         except libvirtError as e:
-            self.last_error = 'Connection Failed: ' + str(e)
+            self.last_error = f'Connection Failed: {str(e)}'
             self.connection = None
 
     def close(self):
@@ -208,18 +208,18 @@ class wvmConnection(object):
 
     def __unicode__(self):
         if self.type == CONN_TCP:
-            type_str = u'tcp'
+            type_str = 'tcp'
         elif self.type == CONN_SSH:
-            type_str = u'ssh'
+            type_str = 'ssh'
         elif self.type == CONN_TLS:
-            type_str = u'tls'
+            type_str = 'tls'
         else:
-            type_str = u'invalid_type'
+            type_str = 'invalid_type'
 
-        return u'qemu+{type}://{user}@{host}/system'.format(type=type_str, user=self.login, host=self.host)
+        return f'qemu+{type_str}://{self.login}@{self.host}/system'
 
     def __repr__(self):
-        return '<wvmConnection {connection_str}>'.format(connection_str=unicode(self))
+        return f'<wvmConnection {str(self)}>'
 
 
 class wvmConnectionManager(object):
@@ -264,9 +264,9 @@ class wvmConnectionManager(object):
         raises libvirtError if (re)connecting fails
         """
         # force all string values to unicode
-        host = unicode(host)
-        login = unicode(login)
-        passwd = unicode(passwd) if passwd is not None else None
+        host = str(host)
+        login = str(login)
+        passwd = str(passwd) if passwd is not None else None
 
         connection = self._search_connection(host, login, passwd, conn)
 
@@ -432,21 +432,21 @@ class wvmConnect(object):
 
     def get_version(self):
         ver = self.wvm.getVersion()
-        major = ver / 1000000
+        major = ver // 1000000
         ver = ver % 1000000
-        minor = ver / 1000
+        minor = ver // 1000
         ver = ver % 1000
         release = ver
-        return "%s.%s.%s" % (major, minor, release)
+        return f"{major}.{minor}.{release}"
 
     def get_lib_version(self):
         ver = self.wvm.getLibVersion()
-        major = ver / 1000000
+        major = ver // 1000000
         ver %= 1000000
-        minor = ver / 1000
+        minor = ver // 1000
         ver %= 1000
         release = ver
-        return "%s.%s.%s" % (major,minor,release)
+        return f"{major}.{minor}.{release}"
 
     def is_kvm_supported(self):
         """Return KVM capabilities."""
diff --git a/vrtManager/create.py b/vrtManager/create.py
index 4d0d14e..f4e0faf 100644
--- a/vrtManager/create.py
+++ b/vrtManager/create.py
@@ -6,9 +6,6 @@ from webvirtcloud.settings import INSTANCE_VOLUME_DEFAULT_FORMAT
 from webvirtcloud.settings import INSTANCE_VOLUME_DEFAULT_SCSI_CONTROLLER
 
 
-
-
-
 def get_rbd_storage_data(stg):
     xml = stg.XMLDesc(0)
     ceph_user = util.get_xml_path(xml, "/pool/source/auth/@username")
@@ -236,10 +233,10 @@ class wvmCreate(wvmConnect):
                 """
         xml += """<devices>"""
 
-        vd_disk_letters = list(string.lowercase)
-        fd_disk_letters = list(string.lowercase)
-        hd_disk_letters = list(string.lowercase)
-        sd_disk_letters = list(string.lowercase)
+        vd_disk_letters = list(string.ascii_lowercase)
+        fd_disk_letters = list(string.ascii_lowercase)
+        hd_disk_letters = list(string.ascii_lowercase)
+        sd_disk_letters = list(string.ascii_lowercase)
         add_cd = True
 
         disk_opts = ''
diff --git a/vrtManager/hostdetails.py b/vrtManager/hostdetails.py
index 6a036e1..9a88853 100644
--- a/vrtManager/hostdetails.py
+++ b/vrtManager/hostdetails.py
@@ -19,10 +19,10 @@ class wvmHostDetails(wvmConnect):
         all_mem = self.wvm.getInfo()[1] * 1048576
         freemem = self.wvm.getMemoryStats(-1, 0)
         if type(freemem) == dict:
-            free = (freemem.values()[0] +
-                    freemem.values()[2] +
-                    freemem.values()[3]) * 1024
-            percent = (100 - ((free * 100) / all_mem))
+            free = (freemem['buffers'] +
+                    freemem['free'] +
+                    freemem['cached']) * 1024
+            percent = abs(100 - ((free * 100) // all_mem))
             usage = (all_mem - free)
             mem_usage = {'total': all_mem, 'usage': usage, 'percent': percent}
         else:
@@ -38,7 +38,7 @@ class wvmHostDetails(wvmConnect):
         cpu = self.wvm.getCPUStats(-1, 0)
         if type(cpu) == dict:
             for num in range(2):
-                idle = self.wvm.getCPUStats(-1, 0).values()[1]
+                idle = self.wvm.getCPUStats(-1, 0)['idle']
                 total = sum(self.wvm.getCPUStats(-1, 0).values())
                 diff_idle = idle - prev_idle
                 diff_total = total - prev_total
diff --git a/vrtManager/instance.py b/vrtManager/instance.py
index 275363e..869d577 100644
--- a/vrtManager/instance.py
+++ b/vrtManager/instance.py
@@ -275,7 +275,7 @@ class wvmInstance(wvmConnect):
         """Get number of physical CPUs."""
         hostinfo = self.wvm.getInfo()
         pcpus = hostinfo[4] * hostinfo[5] * hostinfo[6] * hostinfo[7]
-        range_pcpus = xrange(1, int(pcpus + 1))
+        range_pcpus = range(1, int(pcpus + 1))
         return range_pcpus
 
     def get_interface_addresses(self, iface_mac):
@@ -322,11 +322,11 @@ class wvmInstance(wvmConnect):
         return None, None
 
     def _get_interface_addresses(self, source):
-        #("Calling interfaceAddresses source=%s", source)
+        # ("Calling interfaceAddresses source=%s", source)
         try:
             return self.instance.interfaceAddresses(source)
         except Exception as e:
-            #log.debug("interfaceAddresses failed: %s", str(e))
+            # log.debug("interfaceAddresses failed: %s", str(e))
             pass
         return {}
 
@@ -340,7 +340,7 @@ class wvmInstance(wvmConnect):
             self._ip_cache["qemuga"] = self._get_interface_addresses(
                 VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT)
 
-        arp_flag = 3 # libvirt."VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_ARP"
+        arp_flag = 3  # libvirt."VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_ARP"
         self._ip_cache["arp"] = self._get_interface_addresses(arp_flag)
 
     def get_net_devices(self):
@@ -501,7 +501,7 @@ class wvmInstance(wvmConnect):
         else:
             raise Exception('Unknown boot menu option, please choose one of 0:disable, 1:enable, -1:remove')
 
-        xmldom = ElementTree.tostring(tree)
+        xmldom = ElementTree.tostring(tree).decode()
         self._defineXML(xmldom)
 
     def get_bootorder(self):
@@ -592,7 +592,7 @@ class wvmInstance(wvmConnect):
                         d.append(order)
             else:
                 raise Exception('Invalid Device Type for boot order')
-        self._defineXML(ElementTree.tostring(tree))
+        self._defineXML(ElementTree.tostring(tree).decode())
 
     def mount_iso(self, dev, image):
         def attach_iso(dev, disk, vol):
@@ -618,11 +618,11 @@ class wvmInstance(wvmConnect):
             if attach_iso(dev, disk, vol):
                 break
         if self.get_status() == 1:
-            xml = ElementTree.tostring(disk)
+            xml = ElementTree.tostring(disk).decode()
             self.instance.attachDevice(xml)
             xmldom = self._XMLDesc(VIR_DOMAIN_XML_SECURE)
         if self.get_status() == 5:
-            xmldom = ElementTree.tostring(tree)
+            xmldom = ElementTree.tostring(tree).decode()
         self._defineXML(xmldom)
 
     def umount_iso(self, dev, image):
@@ -637,14 +637,14 @@ class wvmInstance(wvmConnect):
                         if elm.get('dev') == dev:
                             disk.remove(src_media)
         if self.get_status() == 1:
-            xml_disk = ElementTree.tostring(disk)
+            xml_disk = ElementTree.tostring(disk).decode()
             self.instance.attachDevice(xml_disk)
             xmldom = self._XMLDesc(VIR_DOMAIN_XML_SECURE)
         if self.get_status() == 5:
-            xmldom = ElementTree.tostring(tree)
+            xmldom = ElementTree.tostring(tree).decode()
         self._defineXML(xmldom)
 
-    def attach_disk(self, source, target_dev, target_bus='ide', disk_type='file',
+    def attach_disk(self, target_dev, source,  target_bus='ide', disk_type='file',
                     disk_device='disk', driver_name='qemu', driver_type='raw',
                     readonly=False, shareable=False, serial=None,
                     cache_mode=None, io_mode=None, discard_mode=None, detect_zeroes_mode=None):
@@ -683,7 +683,7 @@ class wvmInstance(wvmConnect):
         tree = etree.fromstring(self._XMLDesc(0))
 
         disk_el = tree.xpath("./devices/disk/target[@dev='{}']".format(target_dev))[0].getparent()
-        xml_disk = etree.tostring(disk_el)
+        xml_disk = etree.tostring(disk_el).decode()
         devices = tree.find('devices')
         devices.remove(disk_el)
 
@@ -699,6 +699,7 @@ class wvmInstance(wvmConnect):
         old_disk_type = disk_el.get('type')
         old_disk_device = disk_el.get('device')
         old_driver_name = disk_el.xpath('driver/@name')[0]
+        old_target_bus = disk_el.xpath('target/@bus')[0]
 
         additionals = ''
         if cache_mode is not None and cache_mode != 'default':
@@ -715,6 +716,7 @@ class wvmInstance(wvmConnect):
             xml_disk += "<driver name='%s' type='%s'/>" % (old_driver_name, format)
         elif old_disk_device == 'disk':
             xml_disk += "<driver name='%s' type='%s' %s/>" % (old_driver_name, format, additionals)
+
         xml_disk += """<source file='%s'/>
           <target dev='%s' bus='%s'/>""" % (source, target_dev, target_bus)
         if readonly:
@@ -735,7 +737,7 @@ class wvmInstance(wvmConnect):
             time.sleep(1)
             cpu_use_now = self.instance.info()[4]
             diff_usage = cpu_use_now - cpu_use_ago
-            cpu_usage['cpu'] = 100 * diff_usage / (1 * nbcore * 10 ** 9L)
+            cpu_usage['cpu'] = 100 * diff_usage / (1 * nbcore * 10 ** 9)
         else:
             cpu_usage['cpu'] = 0
         return cpu_usage
@@ -746,7 +748,7 @@ class wvmInstance(wvmConnect):
     def set_vcpu_hotplug(self, status, vcpus_hotplug=0):
         """ vcpus_hotplug = 0 make all vpus hotpluggable """
         vcpus_hotplug = int(self.get_vcpu()) if vcpus_hotplug == 0 else vcpus_hotplug
-        if self.get_status() == 5: # shutoff
+        if self.get_status() == 5:  # shutoff
             if status:
                 xml = """ <vcpus>"""
                 xml += """<vcpu id='0' enabled='yes' hotpluggable='no' order='1'/>"""
@@ -758,14 +760,14 @@ class wvmInstance(wvmConnect):
                 vcpus = tree.xpath("/domain/vcpus")
                 if not vcpus:
                     tree.append(etree.fromstring(xml))
-                    self._defineXML(etree.tostring(tree))
+                    self._defineXML(etree.tostring(tree).decode())
             else:
                 tree = etree.fromstring(self._XMLDesc(0))
                 vcpus = tree.xpath("/domain/vcpus")
                 for vcpu in vcpus:
                     parent = vcpu.getparent()
                     parent.remove(vcpu)
-                    self._defineXML(etree.tostring(tree))
+                    self._defineXML(etree.tostring(tree).decode())
         else:
             raise libvirtError("Please shutdown the instance then try to enable vCPU hotplug")
 
@@ -892,7 +894,7 @@ class wvmInstance(wvmConnect):
                 listen.attrib.pop("address")
             except:
                 pass
-        newxml = ElementTree.tostring(root)
+        newxml = ElementTree.tostring(root).decode()
         return self._defineXML(newxml)
     
     def get_console_socket(self):
@@ -917,7 +919,7 @@ class wvmInstance(wvmConnect):
             # Little fix for old version ElementTree
             graphic = root.find("devices/graphics")
         graphic.set('type', console_type)
-        newxml = ElementTree.tostring(root)
+        newxml = ElementTree.tostring(root).decode()
         self._defineXML(newxml)
 
     def get_console_port(self, console_type=None):
@@ -953,7 +955,7 @@ class wvmInstance(wvmConnect):
                 graphic.attrib.pop('passwd')
             except:
                 pass
-        newxml = ElementTree.tostring(root)
+        newxml = ElementTree.tostring(root).decode()
         return self._defineXML(newxml)
 
     def set_console_keymap(self, keymap):
@@ -972,7 +974,7 @@ class wvmInstance(wvmConnect):
                 graphic.attrib.pop('keymap')
             except:
                 pass
-        newxml = ElementTree.tostring(root)
+        newxml = ElementTree.tostring(root).decode()
         self._defineXML(newxml)
 
     def get_console_keymap(self):
@@ -998,7 +1000,7 @@ class wvmInstance(wvmConnect):
                 parent = model.getparent()
                 parent.remove(model)
                 parent.append(etree.fromstring(video_xml))
-                self._defineXML(etree.tostring(tree))
+                self._defineXML(etree.tostring(tree).decode())
 
     def resize_cpu(self, cur_vcpu, vcpu):
         """
@@ -1011,11 +1013,11 @@ class wvmInstance(wvmConnect):
         xml = self._XMLDesc(VIR_DOMAIN_XML_SECURE)
         tree = etree.fromstring(xml)
 
-        set_vcpu = tree.find('vcpu')
-        set_vcpu.text = vcpu
-        set_vcpu.set('current', cur_vcpu)
+        vcpu_elem = tree.find('vcpu')
+        vcpu_elem.text = vcpu
+        vcpu_elem.set('current', cur_vcpu)
 
-        new_xml = etree.tostring(tree)
+        new_xml = etree.tostring(tree).decode()
         self._defineXML(new_xml)
 
         if is_vcpus_enabled:
@@ -1034,14 +1036,14 @@ class wvmInstance(wvmConnect):
             return
 
         xml = self._XMLDesc(VIR_DOMAIN_XML_SECURE)
-        tree = ElementTree.fromstring(xml)
+        tree = etree.fromstring(xml)
 
-        set_mem = tree.find('memory')
-        set_mem.text = str(memory)
-        set_cur_mem = tree.find('currentMemory')
-        set_cur_mem.text = str(cur_memory)
+        mem_elem = tree.find('memory')
+        mem_elem.text = str(memory)
+        cur_mem_elem = tree.find('currentMemory')
+        cur_mem_elem.text = str(cur_memory)
 
-        new_xml = ElementTree.tostring(tree)
+        new_xml = etree.tostring(tree).decode()
         self._defineXML(new_xml)
 
     def resize_disk(self, disks):
@@ -1049,14 +1051,14 @@ class wvmInstance(wvmConnect):
         Function change disks on vds.
         """
         xml = self._XMLDesc(VIR_DOMAIN_XML_SECURE)
-        tree = ElementTree.fromstring(xml)
+        tree = etree.fromstring(xml)
 
         for disk in disks:
             source_dev = disk['path']
             vol = self.get_volume_by_path(source_dev)
             vol.resize(disk['size_new'])
 
-        new_xml = ElementTree.tostring(tree)
+        new_xml = etree.tostring(tree).decode()
         self._defineXML(new_xml)
 
     def get_iso_media(self):
@@ -1250,7 +1252,7 @@ class wvmInstance(wvmConnect):
             'description': clone_data.get('clone-description', ''),
         }
         self._set_options(tree, options)
-        self._defineXML(ElementTree.tostring(tree))
+        self._defineXML(ElementTree.tostring(tree).decode())
 
         return self.get_instance(clone_data['name']).UUIDString()
 
@@ -1297,7 +1299,7 @@ class wvmInstance(wvmConnect):
         for interface in tree.findall('devices/interface'):
             source = interface.find('mac')
             if source.get('address', '') == mac_address:
-                new_xml = ElementTree.tostring(interface)
+                new_xml = ElementTree.tostring(interface).decode()
 
                 if self.get_status() == 1:
                     self.instance.detachDeviceFlags(new_xml, VIR_DOMAIN_AFFECT_LIVE)
@@ -1359,7 +1361,7 @@ class wvmInstance(wvmConnect):
                 else:
                     if source is not None: interface.remove(source)
 
-        new_xml = ElementTree.tostring(tree)
+        new_xml = ElementTree.tostring(tree).decode()
         self._defineXML(new_xml)
 
     def set_link_state(self, mac_address, state):
@@ -1373,7 +1375,7 @@ class wvmInstance(wvmConnect):
                 link_el = etree.Element("link")
                 link_el.attrib["state"] = state
                 interface.append(link_el)
-                new_xml = etree.tostring(interface)
+                new_xml = etree.tostring(interface).decode()
                 if self.get_status() == 1:
                     self.instance.updateDeviceFlags(new_xml, VIR_DOMAIN_AFFECT_LIVE)
                     self.instance.updateDeviceFlags(new_xml, VIR_DOMAIN_AFFECT_CONFIG)
@@ -1400,7 +1402,7 @@ class wvmInstance(wvmConnect):
         tree = ElementTree.fromstring(xml)
 
         self._set_options(tree, options)
-        new_xml = ElementTree.tostring(tree)
+        new_xml = ElementTree.tostring(tree).decode()
         self._defineXML(new_xml)
 
     def set_memory(self, size, flags=0):
@@ -1460,7 +1462,7 @@ class wvmInstance(wvmConnect):
                         parent.append(etree.fromstring(xml))
                     else:
                         band.append(etree.fromstring(xml))
-        new_xml = etree.tostring(tree)
+        new_xml = etree.tostring(tree).decode()
         self.wvm.defineXML(new_xml)
 
     def unset_qos(self, mac, direction):
@@ -1472,7 +1474,7 @@ class wvmInstance(wvmConnect):
             if parent_mac[0] == mac:
                 band_el.remove(direct)
 
-        self.wvm.defineXML(etree.tostring(tree))
+        self.wvm.defineXML(etree.tostring(tree).decode())
 
     def add_guest_agent(self):
         channel_xml = """
@@ -1490,7 +1492,7 @@ class wvmInstance(wvmConnect):
         tree = etree.fromstring(self._XMLDesc(0))
         for target in tree.xpath("/domain/devices/channel[@type='unix']/target[@name='org.qemu.guest_agent.0']"):
             parent = target.getparent()
-            channel_xml = etree.tostring(parent)
+            channel_xml = etree.tostring(parent).decode()
             if self.get_status() == 1:
                 self.instance.detachDeviceFlags(channel_xml, VIR_DOMAIN_AFFECT_LIVE)
                 self.instance.detachDeviceFlags(channel_xml, VIR_DOMAIN_AFFECT_CONFIG)
diff --git a/vrtManager/network.py b/vrtManager/network.py
index 560bd42..dafc1e4 100644
--- a/vrtManager/network.py
+++ b/vrtManager/network.py
@@ -213,7 +213,7 @@ class wvmNetwork(wvmConnect):
                     for host in hosts:
                         ip = host.get('ip')
                         mac = host.get('mac')
-                        name = host.get('name','')
+                        name = host.get('name', '')
                         result.append({'ip': ip, 'mac': mac, 'name': name})
                     return result
                 else:
@@ -223,7 +223,7 @@ class wvmNetwork(wvmConnect):
                 for host in hosts:
                     ip = host.get('ip')
                     id = host.get('id')
-                    name = host.get('name','')
+                    name = host.get('name', '')
                     result.append({'ip': ip, 'id': id, 'name': name})
                 return result
 
@@ -236,7 +236,7 @@ class wvmNetwork(wvmConnect):
                 range = tree.xpath("./ip[@family='ipv6']/dhcp/range")
             range[0].set('start', range_start)
             range[0].set('end', range_end)
-            self.wvm.networkDefineXML(etree.tostring(tree))
+            self.wvm.networkDefineXML(etree.tostring(tree).decode())
 
     def delete_fixed_address(self, ip, family='ipv4'):
         tree = etree.fromstring(self._XMLDesc(0))
@@ -335,7 +335,7 @@ class wvmNetwork(wvmConnect):
                 parent.append(etree.fromstring(xml))
             else:
                 band[0].append(etree.fromstring(xml))
-        new_xml = etree.tostring(tree)
+        new_xml = etree.tostring(tree).decode()
         self.wvm.networkDefineXML(new_xml)
 
     def unset_qos(self, direction):
@@ -344,7 +344,7 @@ class wvmNetwork(wvmConnect):
             parent = direct.getparent()
             parent.remove(direct)
 
-        self.wvm.networkDefineXML(etree.tostring(tree))
+        self.wvm.networkDefineXML(etree.tostring(tree).decode())
 
     def edit_network(self, new_xml):
         self.wvm.networkDefineXML(new_xml)
@@ -354,7 +354,7 @@ class wvmNetwork(wvmConnect):
             self.leases = self.net.DHCPLeases()
         except Exception as e:
             self.leases = []
-            raise "Error getting %s DHCP leases: %s" % self, str(e)
+            raise "Error getting %s DHCP leases: %s" % (self, e)
 
     def get_dhcp_leases(self):
         if self.leases is None:
diff --git a/vrtManager/nwfilters.py b/vrtManager/nwfilters.py
index aeb7e4f..901aa6f 100644
--- a/vrtManager/nwfilters.py
+++ b/vrtManager/nwfilters.py
@@ -19,7 +19,7 @@ class wvmNWFilters(wvmConnect):
             tree.set('name', cln_name)
             uuid = tree.find('uuid')
             tree.remove(uuid)
-            self.create_nwfilter(ElementTree.tostring(tree))
+            self.create_nwfilter(ElementTree.tostring(tree).decode())
 
 
 class wvmNWFilter(wvmConnect):
@@ -43,7 +43,7 @@ class wvmNWFilter(wvmConnect):
         tree = ElementTree.fromstring(self._XMLDesc(0))
         uuid = tree.find('uuid')
         tree.remove(uuid)
-        return ElementTree.tostring(tree)
+        return ElementTree.tostring(tree).decode()
 
     def get_filter_refs(self):
         refs = []
@@ -64,7 +64,7 @@ class wvmNWFilter(wvmConnect):
 
             rule_directives = r.find("./")
             if rule_directives is not None:
-                rule_directives = ElementTree.tostring(rule_directives)
+                rule_directives = ElementTree.tostring(rule_directives).decode()
 
             rule_info = {
                 "action": rule_action,
@@ -84,7 +84,7 @@ class wvmNWFilter(wvmConnect):
             if name == ref.get('filter'):
                 tree.remove(ref)
                 break
-        return ElementTree.tostring(tree)
+        return ElementTree.tostring(tree).decode()
 
     def delete_rule(self, action, direction, priority):
         tree = ElementTree.fromstring(self._XMLDesc(0))
@@ -93,14 +93,14 @@ class wvmNWFilter(wvmConnect):
         if rule_tree:
             tree.remove(rule_tree[0])
 
-        return ElementTree.tostring(tree)
+        return ElementTree.tostring(tree).decode()
 
     def add_ref(self, name):
         tree = ElementTree.fromstring(self._XMLDesc(0))
         element = ElementTree.Element("filterref")
         element.attrib['filter'] = name
         tree.append(element)
-        return ElementTree.tostring(tree)
+        return ElementTree.tostring(tree).decode()
 
     def add_rule(self, xml):
         tree = ElementTree.fromstring(self._XMLDesc(0))
@@ -122,4 +122,4 @@ class wvmNWFilter(wvmConnect):
             element.append(rule_directives)
             tree.append(element)
 
-        return ElementTree.tostring(tree)
+        return ElementTree.tostring(tree).decode()
diff --git a/vrtManager/storage.py b/vrtManager/storage.py
index bd51b1d..84a5c13 100644
--- a/vrtManager/storage.py
+++ b/vrtManager/storage.py
@@ -147,13 +147,13 @@ class wvmStorage(wvmConnect):
         return util.get_xml_path(self._XMLDesc(0), "/pool/target/path")
 
     def get_allocation(self):
-        return long(util.get_xml_path(self._XMLDesc(0), "/pool/allocation"))
+        return int(util.get_xml_path(self._XMLDesc(0), "/pool/allocation"))
 
     def get_available(self):
-        return long(util.get_xml_path(self._XMLDesc(0), "/pool/available"))
+        return int(util.get_xml_path(self._XMLDesc(0), "/pool/available"))
 
     def get_capacity(self):
-        return long(util.get_xml_path(self._XMLDesc(0), "/pool/capacity"))
+        return int(util.get_xml_path(self._XMLDesc(0), "/pool/capacity"))
 
     def get_pretty_allocation(self):
         return util.pretty_bytes(self.get_allocation())
diff --git a/vrtManager/util.py b/vrtManager/util.py
index 626269b..ea59881 100644
--- a/vrtManager/util.py
+++ b/vrtManager/util.py
@@ -34,9 +34,9 @@ def randomUUID():
                      "%02x" * 6]) % tuple(u)
 
 
-def randomPasswd(length=12, alphabet=string.letters + string.digits):
+def randomPasswd(length=12, alphabet=string.ascii_letters + string.digits):
     """Generate a random password"""
-    return ''.join([random.choice(alphabet) for i in xrange(length)])
+    return ''.join([random.choice(alphabet) for i in range(length)])
 
 
 def get_max_vcpus(conn, type=None):
@@ -75,7 +75,7 @@ def compareMAC(p, q):
         else:
             return -1
 
-    for i in xrange(len(pa)):
+    for i in range(len(pa)):
         n = int(pa[i], 0x10) - int(qa[i], 0x10)
         if n > 0:
             return 1
@@ -160,12 +160,12 @@ def validate_macaddr(val):
     if val is None:
         return
 
-    if not (isinstance(val, str) or isinstance(val, basestring)):
+    if not (isinstance(val, str) or isinstance(val, str)):
         raise ValueError("MAC address must be a string.")
 
     form = re.match("^([0-9a-fA-F]{1,2}:){5}[0-9a-fA-F]{1,2}$", val)
     if form is None:
-        raise ValueError("MAC address must be of the format AA:BB:CC:DD:EE:FF, was '%s'" % val)
+        raise ValueError(f"MAC address must be of the format AA:BB:CC:DD:EE:FF, was {val}")
 
 
 # Mapping of UEFI binary names to their associated architectures. We
@@ -189,4 +189,4 @@ uefi_arch_patterns = {
     "armv7l": [
         r".*arm/QEMU_EFI.*",  # fedora, gerd's firmware repo
     ],
-}
\ No newline at end of file
+}
diff --git a/webvirtcloud/settings.py.template b/webvirtcloud/settings.py.template
index 291c0a3..72871e4 100644
--- a/webvirtcloud/settings.py.template
+++ b/webvirtcloud/settings.py.template
@@ -4,7 +4,9 @@ Django settings for webvirtcloud project.
 """
 
 import os
-BASE_DIR = os.path.dirname(os.path.dirname(__file__))
+
+# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 
 SECRET_KEY = ''
 
@@ -12,73 +14,44 @@ DEBUG = True
 
 ALLOWED_HOSTS = ['*']
 
-INSTALLED_APPS = (
+
+# Application definition
+
+INSTALLED_APPS = [
     'django.contrib.admin',
     'django.contrib.auth',
     'django.contrib.contenttypes',
     'django.contrib.sessions',
     'django.contrib.messages',
     'django.contrib.staticfiles',
+    'accounts',
     'computes',
     'console',
-    'networks',
-    'storages',
-    'interfaces',
-    'nwfilters',
-    'instances',
-    'secrets',
-    'logs',
-    'accounts',
     'create',
     'datasource',
-)
+    'networks',
+    'instances',
+    'interfaces',
+    'nwfilters',
+    'storages',
+    'secrets',
+    'logs',
+]
 
-MIDDLEWARE_CLASSES = (
+MIDDLEWARE = [
+    'django.middleware.security.SecurityMiddleware',
     'django.contrib.sessions.middleware.SessionMiddleware',
     'django.middleware.common.CommonMiddleware',
     'django.middleware.csrf.CsrfViewMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
     'django.contrib.auth.middleware.RemoteUserMiddleware',
-    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
     'django.middleware.clickjacking.XFrameOptionsMiddleware',
-)
-
-AUTHENTICATION_BACKENDS = (
-    'django.contrib.auth.backends.ModelBackend',
-    #'django.contrib.auth.backends.RemoteUserBackend',
-    #'accounts.backends.MyRemoteUserBackend',
-)
-
-LOGIN_URL = '/accounts/login'
+    'django.middleware.locale.LocaleMiddleware',
+]
 
 ROOT_URLCONF = 'webvirtcloud.urls'
 
-WSGI_APPLICATION = 'webvirtcloud.wsgi.application'
-
-DATABASES = {
-    'default': {
-        'ENGINE': 'django.db.backends.sqlite3',
-        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
-    }
-}
-
-LANGUAGE_CODE = 'en-us'
-
-TIME_ZONE = 'UTC'
-
-USE_I18N = True
-
-USE_L10N = True
-
-USE_TZ = True
-
-STATIC_URL = '/static/'
-
-STATICFILES_DIRS = (
-    os.path.join(BASE_DIR, "static"),
-)
-
 TEMPLATES = [
     {
         'BACKEND': 'django.template.backends.django.DjangoTemplates',
@@ -95,9 +68,57 @@ TEMPLATES = [
     },
 ]
 
-## WebVirtCloud settings
+WSGI_APPLICATION = 'webvirtcloud.wsgi.application'
 
-# Wobsock port
+
+# Database
+# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
+
+DATABASES = {
+    'default': {
+        'ENGINE': 'django.db.backends.sqlite3',
+        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
+    }
+}
+
+AUTHENTICATION_BACKENDS = [
+    'django.contrib.auth.backends.ModelBackend',
+    #'django.contrib.auth.backends.RemoteUserBackend',
+    #'accounts.backends.MyRemoteUserBackend',
+]
+
+LOGIN_URL = '/accounts/login'
+
+LANGUAGE_CODE = 'en-us'
+
+TIME_ZONE = 'UTC'
+
+USE_I18N = True
+
+USE_L10N = True
+
+USE_TZ = True
+
+STATIC_URL = '/static/'
+
+STATICFILES_DIRS = [
+    os.path.join(BASE_DIR, "static"),
+]
+
+LOGGING = {
+    "version": 1,
+    "disable_existing_loggers": False,
+    "handlers": {"mail_admins": {"level": "ERROR", "class": "django.utils.log.AdminEmailHandler"}},
+    "loggers": {
+        "django.request": {"handlers": ["mail_admins"], "level": "ERROR", "propagate": True}
+    },
+}
+
+#
+## WebVirtCloud settings
+#
+
+# Websock port
 WS_PORT = 6080
 
 # Websock host
@@ -112,19 +133,19 @@ WS_PUBLIC_HOST = None
 # Websock SSL connection
 WS_CERT = None
 
-# list of console types
+# List of console types
 QEMU_CONSOLE_TYPES = ['vnc', 'spice']
 
-# default console type
+# Default console type
 QEMU_CONSOLE_DEFAULT_TYPE = 'vnc'
 
-# list of console listen addresses
+# List of console listen addresses
 QEMU_CONSOLE_LISTEN_ADDRESSES = (
     ('127.0.0.1', 'Localhost'),
     ('0.0.0.0', 'All interfaces'),
 )
 
-# list taken from http://qemu.weilnetz.de/qemu-doc.html#sec_005finvocation
+# List taken from http://qemu.weilnetz.de/qemu-doc.html#sec_005finvocation
 QEMU_KEYMAPS = ['ar', 'da', 'de', 'de-ch', 'en-gb', 'en-us', 'es', 'et', 'fi',
                 'fo', 'fr', 'fr-be', 'fr-ca', 'fr-ch', 'hr', 'hu', 'is', 'it',
                 'ja', 'lt', 'lv', 'mk', 'nl', 'nl-be', 'no', 'pl', 'pt',
@@ -181,3 +202,9 @@ INSTANCE_CPU_DEFAULT_MODE = 'host-model'
 
 # Chipset/Machine: pc or q35 for x86_64
 INSTANCE_MACHINE_DEFAULT_TYPE = 'q35'
+
+# Firmware: BIOS or UEFI for x86_64
+INSTANCE_FIRMWARE_DEFAULT_TYPE = 'BIOS'
+
+# Architecture: x86_64, i686, etc
+INSTANCE_ARCH_DEFAULT_TYPE = 'x86_64'
\ No newline at end of file
diff --git a/webvirtcloud/urls.py b/webvirtcloud/urls.py
index 4924a68..6c21817 100644
--- a/webvirtcloud/urls.py
+++ b/webvirtcloud/urls.py
@@ -1,17 +1,17 @@
-from django.conf.urls import include, url
+from django.urls import include, path
 
 from instances.views import index
 from console.views import console
 # from django.contrib import admin
 
 urlpatterns = [
-    url(r'^$', index, name='index'),
+    path('', index, name='index'),
 
-    url(r'^instances/', include('instances.urls')),
-    url(r'^accounts/', include('accounts.urls')),
-    url(r'^computes/', include('computes.urls')),
-    url(r'^logs/', include('logs.urls')),
-    url(r'^datasource/', include('datasource.urls')),
-    url(r'^console/$', console, name='console'),
-    #url(r'^admin/', include(admin.site.urls)),
+    path('instances/', include('instances.urls')),
+    path('accounts/', include('accounts.urls')),
+    path('computes/', include('computes.urls')),
+    path('logs/', include('logs.urls')),
+    path('datasource/', include('datasource.urls')),
+    path('console/', console, name='console'),
+    # url(r'^admin/', include(admin.site.urls)),
 ]
diff --git a/webvirtcloud/wsgi.py b/webvirtcloud/wsgi.py
index 912df99..aafa04f 100644
--- a/webvirtcloud/wsgi.py
+++ b/webvirtcloud/wsgi.py
@@ -4,11 +4,11 @@ WSGI config for webvirtcloud project.
 It exposes the WSGI callable as a module-level variable named ``application``.
 
 For more information on this file, see
-https://docs.djangoproject.com/en/1.11/howto/deployment/wsgi/
+https://docs.djangoproject.com/en/2.0/howto/deployment/wsgi/
 """
 
 import os
-os.environ.setdefault("DJANGO_SETTINGS_MODULE", "webvirtcloud.settings")
+os.environ["DJANGO_SETTINGS_MODULE"] = "webvirtcloud.settings"
 
 from django.core.wsgi import get_wsgi_application
 application = get_wsgi_application()
diff --git a/webvirtcloud/wsgi_custom.py b/webvirtcloud/wsgi_custom.py
index a9bf44c..0abf5da 100644
--- a/webvirtcloud/wsgi_custom.py
+++ b/webvirtcloud/wsgi_custom.py
@@ -4,14 +4,17 @@ WSGI config for webvirtcloud project.
 It exposes the WSGI callable as a module-level variable named ``application``.
 
 For more information on this file, see
-https://docs.djangoproject.com/en/1.7/howto/deployment/wsgi/
+https://docs.djangoproject.com/en/2.0/howto/deployment/wsgi/
 """
-
-execfile('/srv/webvirtcloud/venv/bin/activate_this.py', dict(__file__='/srv/webvirtcloud/venv/bin/activate_this.py'))
-
 import os, sys
-sys.path.append('/srv/webvirtcloud')
-os.environ.setdefault("DJANGO_SETTINGS_MODULE", "webvirtcloud.settings")
-
 from django.core.wsgi import get_wsgi_application
+
+# execfile('/srv/webvirtcloud/venv/bin/activate_this.py', dict(__file__='/srv/webvvirtcloud/venv/bin/activate_this.py'))
+exec(compile(open('/srv/webvirtcloud/venv/bin/activate_this.py', "rb").read(),
+             '/srv/webvirtcloud/venv/bin/activate_this.py', 'exec'))
+
+sys.path.append('/srv/webvirtcloud')
+os.environ["DJANGO_SETTINGS_MODULE"] = "webvirtcloud.settings"
+
+
 application = get_wsgi_application()