summaryrefslogtreecommitdiffstats
path: root/web/_static/tablesorter/css
diff options
context:
space:
mode:
Diffstat (limited to 'web/_static/tablesorter/css')
-rw-r--r--web/_static/tablesorter/css/dragtable.mod.min.css1
-rw-r--r--web/_static/tablesorter/css/filter.formatter.min.css1
-rw-r--r--web/_static/tablesorter/css/highlights.min.css1
-rw-r--r--web/_static/tablesorter/css/images/black-asc.gifbin0 -> 48 bytes
-rw-r--r--web/_static/tablesorter/css/images/black-desc.gifbin0 -> 49 bytes
-rw-r--r--web/_static/tablesorter/css/images/black-unsorted.gifbin0 -> 54 bytes
-rw-r--r--web/_static/tablesorter/css/images/bootstrap-black-unsorted.pngbin0 -> 276 bytes
-rw-r--r--web/_static/tablesorter/css/images/bootstrap-white-unsorted.pngbin0 -> 180 bytes
-rw-r--r--web/_static/tablesorter/css/images/dragtable-handle.pngbin0 -> 75 bytes
-rw-r--r--web/_static/tablesorter/css/images/dragtable-handle.svg7
-rw-r--r--web/_static/tablesorter/css/images/dropbox-asc-hovered.pngbin0 -> 200 bytes
-rw-r--r--web/_static/tablesorter/css/images/dropbox-asc.pngbin0 -> 204 bytes
-rw-r--r--web/_static/tablesorter/css/images/dropbox-desc-hovered.pngbin0 -> 195 bytes
-rw-r--r--web/_static/tablesorter/css/images/dropbox-desc.pngbin0 -> 206 bytes
-rw-r--r--web/_static/tablesorter/css/images/first.pngbin0 -> 642 bytes
-rw-r--r--web/_static/tablesorter/css/images/green-asc.gifbin0 -> 283 bytes
-rw-r--r--web/_static/tablesorter/css/images/green-desc.gifbin0 -> 283 bytes
-rw-r--r--web/_static/tablesorter/css/images/green-header.gifbin0 -> 513 bytes
-rw-r--r--web/_static/tablesorter/css/images/green-unsorted.gifbin0 -> 520 bytes
-rw-r--r--web/_static/tablesorter/css/images/ice-asc.gifbin0 -> 285 bytes
-rw-r--r--web/_static/tablesorter/css/images/ice-desc.gifbin0 -> 285 bytes
-rw-r--r--web/_static/tablesorter/css/images/ice-unsorted.gifbin0 -> 180 bytes
-rw-r--r--web/_static/tablesorter/css/images/last.pngbin0 -> 661 bytes
-rw-r--r--web/_static/tablesorter/css/images/loading.gifbin0 -> 416 bytes
-rw-r--r--web/_static/tablesorter/css/images/metro-black-asc.pngbin0 -> 158 bytes
-rw-r--r--web/_static/tablesorter/css/images/metro-black-desc.pngbin0 -> 171 bytes
-rw-r--r--web/_static/tablesorter/css/images/metro-loading.gifbin0 -> 673 bytes
-rw-r--r--web/_static/tablesorter/css/images/metro-unsorted.pngbin0 -> 151 bytes
-rw-r--r--web/_static/tablesorter/css/images/metro-white-asc.pngbin0 -> 165 bytes
-rw-r--r--web/_static/tablesorter/css/images/metro-white-desc.pngbin0 -> 178 bytes
-rw-r--r--web/_static/tablesorter/css/images/next.pngbin0 -> 658 bytes
-rw-r--r--web/_static/tablesorter/css/images/prev.pngbin0 -> 663 bytes
-rw-r--r--web/_static/tablesorter/css/images/white-asc.gifbin0 -> 48 bytes
-rw-r--r--web/_static/tablesorter/css/images/white-desc.gifbin0 -> 49 bytes
-rw-r--r--web/_static/tablesorter/css/images/white-unsorted.gifbin0 -> 54 bytes
-rw-r--r--web/_static/tablesorter/css/jquery.tablesorter.pager.min.css1
-rw-r--r--web/_static/tablesorter/css/less/bootstrap.less328
-rw-r--r--web/_static/tablesorter/css/less/metro.less357
-rw-r--r--web/_static/tablesorter/css/less/theme.less330
-rw-r--r--web/_static/tablesorter/css/scss/theme.scss327
-rw-r--r--web/_static/tablesorter/css/theme.blackice.min.css1
-rw-r--r--web/_static/tablesorter/css/theme.blue.css229
-rw-r--r--web/_static/tablesorter/css/theme.blue.min.css1
-rw-r--r--web/_static/tablesorter/css/theme.bootstrap.min.css1
-rw-r--r--web/_static/tablesorter/css/theme.bootstrap_2.min.css1
-rw-r--r--web/_static/tablesorter/css/theme.bootstrap_3.min.css1
-rw-r--r--web/_static/tablesorter/css/theme.bootstrap_4.min.css1
-rw-r--r--web/_static/tablesorter/css/theme.dark.min.css1
-rw-r--r--web/_static/tablesorter/css/theme.default.min.css1
-rw-r--r--web/_static/tablesorter/css/theme.dropbox.min.css1
-rw-r--r--web/_static/tablesorter/css/theme.green.min.css1
-rw-r--r--web/_static/tablesorter/css/theme.grey.min.css1
-rw-r--r--web/_static/tablesorter/css/theme.ice.min.css1
-rw-r--r--web/_static/tablesorter/css/theme.jui.min.css1
-rw-r--r--web/_static/tablesorter/css/theme.materialize.min.css1
-rw-r--r--web/_static/tablesorter/css/theme.metro-dark.min.css1
-rw-r--r--web/_static/tablesorter/css/widget.grouping.min.css1
57 files changed, 1598 insertions, 0 deletions
diff --git a/web/_static/tablesorter/css/dragtable.mod.min.css b/web/_static/tablesorter/css/dragtable.mod.min.css
new file mode 100644
index 0000000..bcd580d
--- /dev/null
+++ b/web/_static/tablesorter/css/dragtable.mod.min.css
@@ -0,0 +1 @@
+.dragtable-sortable{list-style-type:none;margin:0;padding:0;-moz-user-select:none;z-index:10}.dragtable-sortable li{margin:0;padding:0;float:left;font-size:1em}.dragtable-sortable table{margin-top:0}.dragtable-sortable td,.dragtable-sortable th{border-left:0}.dragtable-sortable li:first-child td,.dragtable-sortable li:first-child th{border-left:1px solid #ccc}.ui-sortable-helper{opacity:.7}.ui-sortable-placeholder{-moz-box-shadow:4px 5px 4px rgba(0,0,0,.2) inset;-webkit-box-shadow:4px 5px 4px rgba(0,0,0,.2) inset;box-shadow:4px 5px 4px rgba(0,0,0,.2) inset;border-bottom:1px solid rgba(0,0,0,.2);border-top:1px solid rgba(0,0,0,.2);visibility:visible!important;background:#efefef}.ui-sortable-placeholder *{opacity:0;visibility:hidden}.table-handle,.table-handle-disabled{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyIiBoZWlnaHQ9IjEzIj48cmVjdCBzdHlsZT0iZmlsbDojMzMzO2ZpbGwtb3BhY2l0eTouODsiIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHg9IjEiIHk9IjIiLz4JPHJlY3Qgc3R5bGU9ImZpbGw6IzMzMztmaWxsLW9wYWNpdHk6Ljg7IiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4PSIxIiB5PSI0Ii8+CTxyZWN0IHN0eWxlPSJmaWxsOiMzMzM7ZmlsbC1vcGFjaXR5Oi44OyIgd2lkdGg9IjEiIGhlaWdodD0iMSIgeD0iMSIgeT0iNiIvPjxyZWN0IHN0eWxlPSJmaWxsOiMzMzM7ZmlsbC1vcGFjaXR5Oi44OyIgd2lkdGg9IjEiIGhlaWdodD0iMSIgeD0iMSIgeT0iOCIvPjxyZWN0IHN0eWxlPSJmaWxsOiMzMzM7ZmlsbC1vcGFjaXR5Oi44OyIgd2lkdGg9IjEiIGhlaWdodD0iMSIgeD0iMSIgeT0iMTAiLz48L3N2Zz4=);background-repeat:repeat-x;height:13px;margin:0 1px;cursor:move}.table-handle-disabled{opacity:0;cursor:not-allowed}.dragtable-sortable table{margin-bottom:0} \ No newline at end of file
diff --git a/web/_static/tablesorter/css/filter.formatter.min.css b/web/_static/tablesorter/css/filter.formatter.min.css
new file mode 100644
index 0000000..42ab375
--- /dev/null
+++ b/web/_static/tablesorter/css/filter.formatter.min.css
@@ -0,0 +1 @@
+.tablesorter .tablesorter-filter-row td{text-align:center;font-size:.9em;font-weight:400}.tablesorter .ui-slider,.tablesorter input.range{width:90%;margin:2px auto 2px auto;font-size:.8em}.tablesorter .ui-slider{top:12px}.tablesorter .ui-slider .ui-slider-handle{width:.9em;height:.9em}.tablesorter .ui-datepicker{font-size:.8em}.tablesorter .ui-slider-horizontal{height:.5em}.tablesorter .value-popup:after{content:attr(data-value);position:absolute;bottom:14px;left:-7px;min-width:18px;height:12px;background-color:#444;background-image:-webkit-gradient(linear,left top,left bottom,from(#444),to(#999));background-image:-webkit-linear-gradient(top,#444,#999);background-image:-moz-linear-gradient(top,#444,#999);background-image:-o-linear-gradient(top,#444,#999);background-image:linear-gradient(to bottom,#444,#999);-webkit-border-radius:3px;border-radius:3px;-webkit-background-clip:padding-box;background-clip:padding-box;-webkit-box-shadow:0 0 4px 0 #777;box-shadow:0 0 4px 0 #777;border:#444 1px solid;color:#fff;font:1em/1.1em Arial,Sans-Serif;padding:1px;text-align:center}.tablesorter .value-popup:before{content:"";position:absolute;width:0;height:0;border-top:8px solid #777;border-left:8px solid transparent;border-right:8px solid transparent;top:-8px;left:50%;margin-left:-8px;margin-top:-1px}.tablesorter .dateFrom,.tablesorter .dateTo{width:80px;margin:2px 5px}.tablesorter .button{width:14px;height:14px;background:#fcfff4;background:-webkit-linear-gradient(top,#fcfff4 0,#dfe5d7 40%,#b3bead 100%);background:-moz-linear-gradient(top,#fcfff4 0,#dfe5d7 40%,#b3bead 100%);background:-o-linear-gradient(top,#fcfff4 0,#dfe5d7 40%,#b3bead 100%);background:-ms-linear-gradient(top,#fcfff4 0,#dfe5d7 40%,#b3bead 100%);background:linear-gradient(top,#fcfff4 0,#dfe5d7 40%,#b3bead 100%);margin:1px 5px 1px 1px;-webkit-border-radius:25px;-moz-border-radius:25px;border-radius:25px;-webkit-box-shadow:inset 0 1px 1px #fff,0 1px 3px rgba(0,0,0,.5);-moz-box-shadow:inset 0 1px 1px #fff,0 1px 3px rgba(0,0,0,.5);box-shadow:inset 0 1px 1px #fff,0 1px 3px rgba(0,0,0,.5);position:relative;top:3px;display:inline-block}.tablesorter .button label{cursor:pointer;position:absolute;width:10px;height:10px;-webkit-border-radius:25px;-moz-border-radius:25px;border-radius:25px;left:2px;top:2px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.5),0 1px 0 rgba(255,255,255,1);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,.5),0 1px 0 rgba(255,255,255,1);box-shadow:inset 0 1px 1px rgba(0,0,0,.5),0 1px 0 rgba(255,255,255,1);background:#45484d;background:-webkit-linear-gradient(top,#222 0,#45484d 100%);background:-moz-linear-gradient(top,#222 0,#45484d 100%);background:-o-linear-gradient(top,#222 0,#45484d 100%);background:-ms-linear-gradient(top,#222 0,#45484d 100%);background:linear-gradient(top,#222 0,#45484d 100%)}.tablesorter .button label:after{opacity:0;content:'';position:absolute;width:8px;height:8px;background:#55f;background:-webkit-linear-gradient(top,#aaf 0,#55f 100%);background:-moz-linear-gradient(top,#aaf 0,#55f 100%);background:-o-linear-gradient(top,#aaf 0,#55f 100%);background:-ms-linear-gradient(top,#aaf 0,#55f 100%);background:linear-gradient(top,#aaf 0,#55f 100%);-webkit-border-radius:25px;-moz-border-radius:25px;border-radius:25px;top:1px;left:1px;-webkit-box-shadow:inset 0 1px 1px #fff,0 1px 3px rgba(0,0,0,.5);-moz-box-shadow:inset 0 1px 1px #fff,0 1px 3px rgba(0,0,0,.5);box-shadow:inset 0 1px 1px #fff,0 1px 3px rgba(0,0,0,.5)}.tablesorter .button label:hover::after{opacity:.3}.tablesorter .button input[type=checkbox]{visibility:hidden}.tablesorter .button input[type=checkbox]:checked+label:after{opacity:1}.tablesorter .colorpicker{width:30px;height:18px}.tablesorter .ui-spinner-input{width:100px;height:18px}.tablesorter .currentColor,.tablesorter .ui-spinner{position:relative}.tablesorter input.number{position:relative}.tablesorter .tablesorter-filter-row.hideme td *{height:1px;min-height:0;border:0;padding:0;margin:0;opacity:0} \ No newline at end of file
diff --git a/web/_static/tablesorter/css/highlights.min.css b/web/_static/tablesorter/css/highlights.min.css
new file mode 100644
index 0000000..6db668a
--- /dev/null
+++ b/web/_static/tablesorter/css/highlights.min.css
@@ -0,0 +1 @@
+table.focus-highlight td:before,table.hover-highlight td:before{background:#fff}.focus-highlight .odd td:before,.focus-highlight .odd th:before,.hover-highlight .odd td:before,.hover-highlight .odd th:before{background:#ebf2fa}.focus-highlight .even td:before,.focus-highlight .even th:before,.hover-highlight .even td:before,.hover-highlight .even th:before{background-color:#fff}.focus-highlight td:focus::before,.focus-highlight th:focus::before{background-color:#add8e6}.focus-highlight td:focus::after,.focus-highlight th:focus::after{background-color:#add8e6}.focus-highlight .even td:focus,.focus-highlight .even th:focus,.focus-highlight .odd td:focus,.focus-highlight .odd th:focus,.focus-highlight td:focus,.focus-highlight th:focus{background-color:#d9d9d9;color:#333}table.hover-highlight tbody>tr.even:hover>td,table.hover-highlight tbody>tr.odd:hover>td,table.hover-highlight tbody>tr:hover>td{background-color:#ffa}.hover-highlight tbody tr td:hover::after,.hover-highlight tbody tr th:hover::after{background-color:#ffa}.focus-highlight td:focus::after,.focus-highlight th:focus::after,.hover-highlight td:hover::after,.hover-highlight th:hover::after{content:'';position:absolute;width:100%;height:999em;left:0;top:-555em;z-index:-1}.focus-highlight td:focus::before,.focus-highlight th:focus::before{content:'';position:absolute;width:999em;height:100%;left:-555em;top:0;z-index:-2}.focus-highlight,.hover-highlight{overflow:hidden}.focus-highlight td,.focus-highlight th,.hover-highlight td,.hover-highlight th{position:relative;outline:0}table.focus-highlight,table.focus-highlight tbody tr.even>td,table.focus-highlight tbody tr.even>th,table.focus-highlight tbody tr.odd>td,table.focus-highlight tbody tr.odd>th,table.focus-highlight tbody>tr>td,table.hover-highlight,table.hover-highlight tbody tr.even>td,table.hover-highlight tbody tr.even>th,table.hover-highlight tbody tr.odd>td,table.hover-highlight tbody tr.odd>th,table.hover-highlight tbody>tr>td{background:0 0}table.focus-highlight td:before,table.hover-highlight td:before{content:'';position:absolute;width:100%;height:100%;left:0;top:0;z-index:-3} \ No newline at end of file
diff --git a/web/_static/tablesorter/css/images/black-asc.gif b/web/_static/tablesorter/css/images/black-asc.gif
new file mode 100644
index 0000000..730533f
--- /dev/null
+++ b/web/_static/tablesorter/css/images/black-asc.gif
Binary files differ
diff --git a/web/_static/tablesorter/css/images/black-desc.gif b/web/_static/tablesorter/css/images/black-desc.gif
new file mode 100644
index 0000000..4c3b610
--- /dev/null
+++ b/web/_static/tablesorter/css/images/black-desc.gif
Binary files differ
diff --git a/web/_static/tablesorter/css/images/black-unsorted.gif b/web/_static/tablesorter/css/images/black-unsorted.gif
new file mode 100644
index 0000000..5647f65
--- /dev/null
+++ b/web/_static/tablesorter/css/images/black-unsorted.gif
Binary files differ
diff --git a/web/_static/tablesorter/css/images/bootstrap-black-unsorted.png b/web/_static/tablesorter/css/images/bootstrap-black-unsorted.png
new file mode 100644
index 0000000..3190f29
--- /dev/null
+++ b/web/_static/tablesorter/css/images/bootstrap-black-unsorted.png
Binary files differ
diff --git a/web/_static/tablesorter/css/images/bootstrap-white-unsorted.png b/web/_static/tablesorter/css/images/bootstrap-white-unsorted.png
new file mode 100644
index 0000000..368c66d
--- /dev/null
+++ b/web/_static/tablesorter/css/images/bootstrap-white-unsorted.png
Binary files differ
diff --git a/web/_static/tablesorter/css/images/dragtable-handle.png b/web/_static/tablesorter/css/images/dragtable-handle.png
new file mode 100644
index 0000000..52a1a56
--- /dev/null
+++ b/web/_static/tablesorter/css/images/dragtable-handle.png
Binary files differ
diff --git a/web/_static/tablesorter/css/images/dragtable-handle.svg b/web/_static/tablesorter/css/images/dragtable-handle.svg
new file mode 100644
index 0000000..041ec1d
--- /dev/null
+++ b/web/_static/tablesorter/css/images/dragtable-handle.svg
@@ -0,0 +1,7 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="2" height="13">
+ <rect style="fill:#333;fill-opacity:.8;" width="1" height="1" x="1" y="2"/>
+ <rect style="fill:#333;fill-opacity:.8;" width="1" height="1" x="1" y="4"/>
+ <rect style="fill:#333;fill-opacity:.8;" width="1" height="1" x="1" y="6"/>
+ <rect style="fill:#333;fill-opacity:.8;" width="1" height="1" x="1" y="8"/>
+ <rect style="fill:#333;fill-opacity:.8;" width="1" height="1" x="1" y="10"/>
+</svg> \ No newline at end of file
diff --git a/web/_static/tablesorter/css/images/dropbox-asc-hovered.png b/web/_static/tablesorter/css/images/dropbox-asc-hovered.png
new file mode 100644
index 0000000..4e625e0
--- /dev/null
+++ b/web/_static/tablesorter/css/images/dropbox-asc-hovered.png
Binary files differ
diff --git a/web/_static/tablesorter/css/images/dropbox-asc.png b/web/_static/tablesorter/css/images/dropbox-asc.png
new file mode 100644
index 0000000..7b6615b
--- /dev/null
+++ b/web/_static/tablesorter/css/images/dropbox-asc.png
Binary files differ
diff --git a/web/_static/tablesorter/css/images/dropbox-desc-hovered.png b/web/_static/tablesorter/css/images/dropbox-desc-hovered.png
new file mode 100644
index 0000000..806707d
--- /dev/null
+++ b/web/_static/tablesorter/css/images/dropbox-desc-hovered.png
Binary files differ
diff --git a/web/_static/tablesorter/css/images/dropbox-desc.png b/web/_static/tablesorter/css/images/dropbox-desc.png
new file mode 100644
index 0000000..868a37c
--- /dev/null
+++ b/web/_static/tablesorter/css/images/dropbox-desc.png
Binary files differ
diff --git a/web/_static/tablesorter/css/images/first.png b/web/_static/tablesorter/css/images/first.png
new file mode 100644
index 0000000..7e505d6
--- /dev/null
+++ b/web/_static/tablesorter/css/images/first.png
Binary files differ
diff --git a/web/_static/tablesorter/css/images/green-asc.gif b/web/_static/tablesorter/css/images/green-asc.gif
new file mode 100644
index 0000000..4cfba09
--- /dev/null
+++ b/web/_static/tablesorter/css/images/green-asc.gif
Binary files differ
diff --git a/web/_static/tablesorter/css/images/green-desc.gif b/web/_static/tablesorter/css/images/green-desc.gif
new file mode 100644
index 0000000..4f88176
--- /dev/null
+++ b/web/_static/tablesorter/css/images/green-desc.gif
Binary files differ
diff --git a/web/_static/tablesorter/css/images/green-header.gif b/web/_static/tablesorter/css/images/green-header.gif
new file mode 100644
index 0000000..cc746b7
--- /dev/null
+++ b/web/_static/tablesorter/css/images/green-header.gif
Binary files differ
diff --git a/web/_static/tablesorter/css/images/green-unsorted.gif b/web/_static/tablesorter/css/images/green-unsorted.gif
new file mode 100644
index 0000000..0afe2c0
--- /dev/null
+++ b/web/_static/tablesorter/css/images/green-unsorted.gif
Binary files differ
diff --git a/web/_static/tablesorter/css/images/ice-asc.gif b/web/_static/tablesorter/css/images/ice-asc.gif
new file mode 100644
index 0000000..0961d9a
--- /dev/null
+++ b/web/_static/tablesorter/css/images/ice-asc.gif
Binary files differ
diff --git a/web/_static/tablesorter/css/images/ice-desc.gif b/web/_static/tablesorter/css/images/ice-desc.gif
new file mode 100644
index 0000000..0330fcc
--- /dev/null
+++ b/web/_static/tablesorter/css/images/ice-desc.gif
Binary files differ
diff --git a/web/_static/tablesorter/css/images/ice-unsorted.gif b/web/_static/tablesorter/css/images/ice-unsorted.gif
new file mode 100644
index 0000000..c1afde5
--- /dev/null
+++ b/web/_static/tablesorter/css/images/ice-unsorted.gif
Binary files differ
diff --git a/web/_static/tablesorter/css/images/last.png b/web/_static/tablesorter/css/images/last.png
new file mode 100644
index 0000000..41e248c
--- /dev/null
+++ b/web/_static/tablesorter/css/images/last.png
Binary files differ
diff --git a/web/_static/tablesorter/css/images/loading.gif b/web/_static/tablesorter/css/images/loading.gif
new file mode 100644
index 0000000..7205471
--- /dev/null
+++ b/web/_static/tablesorter/css/images/loading.gif
Binary files differ
diff --git a/web/_static/tablesorter/css/images/metro-black-asc.png b/web/_static/tablesorter/css/images/metro-black-asc.png
new file mode 100644
index 0000000..61c4f80
--- /dev/null
+++ b/web/_static/tablesorter/css/images/metro-black-asc.png
Binary files differ
diff --git a/web/_static/tablesorter/css/images/metro-black-desc.png b/web/_static/tablesorter/css/images/metro-black-desc.png
new file mode 100644
index 0000000..fc2188c
--- /dev/null
+++ b/web/_static/tablesorter/css/images/metro-black-desc.png
Binary files differ
diff --git a/web/_static/tablesorter/css/images/metro-loading.gif b/web/_static/tablesorter/css/images/metro-loading.gif
new file mode 100644
index 0000000..ae274c6
--- /dev/null
+++ b/web/_static/tablesorter/css/images/metro-loading.gif
Binary files differ
diff --git a/web/_static/tablesorter/css/images/metro-unsorted.png b/web/_static/tablesorter/css/images/metro-unsorted.png
new file mode 100644
index 0000000..e67ab2a
--- /dev/null
+++ b/web/_static/tablesorter/css/images/metro-unsorted.png
Binary files differ
diff --git a/web/_static/tablesorter/css/images/metro-white-asc.png b/web/_static/tablesorter/css/images/metro-white-asc.png
new file mode 100644
index 0000000..a850fbf
--- /dev/null
+++ b/web/_static/tablesorter/css/images/metro-white-asc.png
Binary files differ
diff --git a/web/_static/tablesorter/css/images/metro-white-desc.png b/web/_static/tablesorter/css/images/metro-white-desc.png
new file mode 100644
index 0000000..fc05607
--- /dev/null
+++ b/web/_static/tablesorter/css/images/metro-white-desc.png
Binary files differ
diff --git a/web/_static/tablesorter/css/images/next.png b/web/_static/tablesorter/css/images/next.png
new file mode 100644
index 0000000..aebf14d
--- /dev/null
+++ b/web/_static/tablesorter/css/images/next.png
Binary files differ
diff --git a/web/_static/tablesorter/css/images/prev.png b/web/_static/tablesorter/css/images/prev.png
new file mode 100644
index 0000000..7d1d049
--- /dev/null
+++ b/web/_static/tablesorter/css/images/prev.png
Binary files differ
diff --git a/web/_static/tablesorter/css/images/white-asc.gif b/web/_static/tablesorter/css/images/white-asc.gif
new file mode 100644
index 0000000..2173b0a
--- /dev/null
+++ b/web/_static/tablesorter/css/images/white-asc.gif
Binary files differ
diff --git a/web/_static/tablesorter/css/images/white-desc.gif b/web/_static/tablesorter/css/images/white-desc.gif
new file mode 100644
index 0000000..7109c3e
--- /dev/null
+++ b/web/_static/tablesorter/css/images/white-desc.gif
Binary files differ
diff --git a/web/_static/tablesorter/css/images/white-unsorted.gif b/web/_static/tablesorter/css/images/white-unsorted.gif
new file mode 100644
index 0000000..9bfc345
--- /dev/null
+++ b/web/_static/tablesorter/css/images/white-unsorted.gif
Binary files differ
diff --git a/web/_static/tablesorter/css/jquery.tablesorter.pager.min.css b/web/_static/tablesorter/css/jquery.tablesorter.pager.min.css
new file mode 100644
index 0000000..17bc885
--- /dev/null
+++ b/web/_static/tablesorter/css/jquery.tablesorter.pager.min.css
@@ -0,0 +1 @@
+.tablesorter-pager{padding:5px}td.tablesorter-pager{background-color:#e6eeee;margin:0}.tablesorter-pager img{vertical-align:middle;margin-right:2px;cursor:pointer}.tablesorter-pager .pagedisplay{padding:0 5px 0 5px;width:auto;white-space:nowrap;text-align:center}.tablesorter-pager select{margin:0;padding:0}.tablesorter-pager.disabled{display:none}.tablesorter-pager .disabled{opacity:.5;cursor:default} \ No newline at end of file
diff --git a/web/_static/tablesorter/css/less/bootstrap.less b/web/_static/tablesorter/css/less/bootstrap.less
new file mode 100644
index 0000000..d71e220
--- /dev/null
+++ b/web/_static/tablesorter/css/less/bootstrap.less
@@ -0,0 +1,328 @@
+/* Tablesorter Custom Bootstrap v3 LESS Theme by Rob Garrison
+
+To create your own theme, modify the code below and run it through
+a LESS compiler, like this one: http://leafo.net/lessphp/editor.html
+or download less.js from http://lesscss.org/
+
+Test out these customization files live
+ Basic LESS Theme : http://codepen.io/Mottie/pen/eqBbn
+ Bootstrap LESS : http://codepen.io/Mottie/pen/Ltzpi
+ Metro LESS Style : http://codepen.io/Mottie/pen/gCslk
+ Basic SCSS : http://codepen.io/Mottie/pen/LbXdNR
+
+*/
+
+/*** theme ***/
+@theme : tablesorter-bootstrap;
+
+/*** fonts ***/
+@tableHeaderFont : 14px bold Arial, Sans-serif;
+@tableBodyFont : 14px "Helvetica Neue", Helvetica, Arial, sans-serif;
+
+/*** color definitions ***/
+/* for best results, only change the hue (240),
+ leave the saturation (60%) and luminosity (80%) alone
+ pick the color from here: http://hslpicker.com/#99E699 */
+@headerBackground : hsl(240, 60%, 80%);
+@borderAndBackground : #cdcdcd;
+@overallBorder : @borderAndBackground 1px solid;
+@headerTextColor : #000;
+
+@bodyBackground : #fff;
+@bodyTextColor : #000;
+
+@headerAsc : darken(spin(@headerBackground, 5), 10%); /* darken(@headerBackground, 10%); */
+@headerDesc : lighten(spin(@headerBackground, -5), 10%); /* desaturate(@headerAsc, 5%); */
+
+@captionBackground : #fff; /* it might be best to match the document body background color here */
+@errorBackground : #e6bf99; /* ajax error message (added to thead) */
+
+@filterCellBackground : #eee;
+@filterElementTextColor: #333;
+@filterElementBkgd : #fff;
+@filterElementBorder : 1px solid #bbb;
+@filterTransitionTime : 0.1s;
+@filterRowHiddenHeight : 4px; /* becomes height using padding (so it's divided by 2) */
+
+@overallPadding : 4px;
+/* 20px should be slightly wider than the icon width to avoid overlap */
+@headerPadding : 4px 20px 4px 4px;
+@headerMargin : 0 0 18px;
+
+/* url(icons/loading.gif); */
+@processingIcon : url('data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=');
+
+/* zebra striping */
+.allRows {
+ background-color: @bodyBackground;
+ color: @bodyTextColor;
+}
+.evenRows {
+ background-color: lighten(@headerBackground, 35%);
+}
+.oddRows {
+ background-color: lighten(@headerBackground, 18%);
+}
+
+/* hovered rows */
+.oddHovered {
+ background-color: desaturate(@headerBackground, 60%);
+}
+.evenHovered {
+ background-color: lighten( desaturate(@headerBackground, 60%), 10% );
+}
+
+/* Columns widget */
+@primaryOdd : spin(@headerBackground, 10); /* saturate( darken( desaturate(@headerBackground, 10%), 10% ), 30%); */
+@primaryEven : lighten( @primaryOdd, 10% );
+@secondaryOdd : @primaryEven;
+@secondaryEven : lighten( @primaryEven, 5% );
+@tertiaryOdd : @secondaryEven;
+@tertiaryEven : lighten( @secondaryEven, 5% );
+
+/* Filter widget transition */
+.filterWidgetTransition {
+ -webkit-transition: line-height @filterTransitionTime ease;
+ -moz-transition: line-height @filterTransitionTime ease;
+ -o-transition: line-height @filterTransitionTime ease;
+ transition: line-height @filterTransitionTime ease;
+}
+
+/*** icon block ***/
+.iconPosition {
+ font-size: 11px;
+ position: absolute;
+ right: 2px;
+ top: 50%;
+ margin-top: -7px; /* half the icon height; older IE doesn't like this */
+ width: 14px;
+ height: 14px;
+ background-repeat: no-repeat;
+ line-height: 14px;
+}
+
+/* black */
+@unsortedBlack : url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOCAYAAAD5YeaVAAAA20lEQVR4AWJABpKSkoxALCstLb0aUAsZaCAMhVEY6B0amx8YZWDDEDSBa2AGe7XeIiAAClYwVGBvsAcIllsf/mvcC9DgOOd8h90fxWvngVEUbZIkuWRZZlE8eQjcisgZMM9zi+LJ6ZfwegmWZflZDugdHMfxTcGqql7TNBlUB/QObtv2VBSFrev6OY7jngzFk9OT/fn73fWYpqnlXNyXDMWT0zuYx/Bvel9ej+LJ6R08DMOu67q7DkTkrSA5vYPneV71fX/QASdTkJwezhs0TfMARn0wMDDGXEPgF4oijqwM5YjNAAAAAElFTkSuQmCC);
+
+/* white */
+@unsortedWhite : url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOCAYAAAD5YeaVAAAAe0lEQVR4AbXQoRWDMBiF0Sh2QLAAQ8SxJGugWSA6A2STW1PxTsnB9cnkfuYvv8OGC1t5G3Y0QMP+Bm857keAdQIzWBP3+Bw4MADQE18B6/etRnCV/w9nnGuLezfAmXhABGtAGIkruvk6auIFRwQJDywllsEAjCecB20GP59BQQ+gtlRLAAAAAElFTkSuQmCC);
+
+/* automatically choose the correct arrow/text color */
+.headerText (@a) when (lightness(@a) >= 50%) {
+ color: @headerTextColor;
+}
+.headerText (@a) when (lightness(@a) < 50%) {
+ color: lighten(@headerTextColor, 90%);
+}
+.unsorted (@a) when (lightness(@a) >= 50%) {
+ background-image: @unsortedBlack;
+ color: @headerTextColor;
+}
+.unsorted (@a) when (lightness(@a) < 50%) {
+ background-image: @unsortedWhite;
+ color: lighten(@headerTextColor, 90%);
+}
+
+/* variable theme name - requires less.js 1.3+;
+ or just replace (!".@{theme}") with the contents of @theme
+*/
+.@{theme} {
+ font: @tableBodyFont;
+ background-color: @borderAndBackground;
+ width: 100%;
+
+ /* style th's outside of the thead */
+ th, thead td {
+ font: @tableHeaderFont;
+ font-weight: bold;
+ background-color: @headerBackground;
+ .headerText(@headerBackground);
+ border-collapse: collapse;
+ margin: @headerMargin;
+ padding: @overallPadding;
+ }
+
+ tbody td, tfoot th, tfoot td {
+ padding: @overallPadding;
+ vertical-align: top;
+ }
+
+ /* style header */
+ .tablesorter-header {
+ cursor: pointer;
+ }
+
+ .tablesorter-header-inner {
+ position: relative;
+ padding: @headerPadding;
+ }
+
+ /* bootstrap uses <i> for icons */
+ .tablesorter-header-inner i.tablesorter-icon {
+ .iconPosition
+ }
+
+ .tablesorter-header.sorter-false {
+ cursor: default;
+
+ i.tablesorter-icon {
+ display: none;
+ }
+ .tablesorter-header-inner {
+ padding: @overallPadding;
+ }
+ }
+
+ .tablesorter-headerAsc {
+ background-color: @headerAsc;
+ }
+
+ .tablesorter-headerDesc {
+ background-color: @headerDesc;
+ }
+
+ .bootstrap-icon-unsorted {
+ .unsorted(@headerBackground);
+ }
+
+
+ /* tfoot */
+ tfoot .tablesorter-headerAsc,
+ tfoot .tablesorter-headerDesc {
+ /* remove sort arrows from footer */
+ background-image: none;
+ }
+
+ /* optional disabled input styling */
+ .disabled {
+ opacity: 0.5;
+ filter: alpha(opacity=50);
+ cursor: not-allowed;
+ }
+
+ /* body */
+ tbody {
+
+ td {
+ .allRows;
+ padding: @overallPadding;
+ vertical-align: top;
+ }
+
+ /* Zebra Widget - row alternating colors */
+ tr.odd > td {
+ .oddRows;
+ }
+ tr.even > td {
+ .evenRows;
+ }
+
+ }
+
+ /* hovered row colors
+ you'll need to add additional lines for
+ rows with more than 2 child rows
+ */
+ tbody > tr.hover > td,
+ tbody > tr:hover > td,
+ tbody > tr:hover + tr.tablesorter-childRow > td,
+ tbody > tr:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td,
+ tbody > tr.even.hover > td,
+ tbody > tr.even:hover > td,
+ tbody > tr.even:hover + tr.tablesorter-childRow > td,
+ tbody > tr.even:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td {
+ .evenHovered;
+ }
+ tbody > tr.odd.hover > td,
+ tbody > tr.odd:hover > td,
+ tbody > tr.odd:hover + tr.tablesorter-childRow > td,
+ tbody > tr.odd:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td {
+ .oddHovered;
+ }
+
+ /* table processing indicator - indeterminate spinner */
+ .tablesorter-processing {
+ background-image: @processingIcon;
+ background-position: center center;
+ background-repeat: no-repeat;
+ }
+
+ /* Column Widget - column sort colors */
+ tr.odd td.primary {
+ background-color: @primaryOdd;
+ }
+ td.primary, tr.even td.primary {
+ background-color: @primaryEven;
+ }
+ tr.odd td.secondary {
+ background-color: @secondaryOdd;
+ }
+ td.secondary, tr.even td.secondary {
+ background-color: @secondaryEven;
+ }
+ tr.odd td.tertiary {
+ background-color: @tertiaryOdd;
+ }
+ td.tertiary, tr.even td.tertiary {
+ background-color: @tertiaryEven;
+ }
+
+ /* caption (non-theme matching) */
+ caption {
+ background-color: @captionBackground ;
+ }
+
+ /* filter widget */
+ .tablesorter-filter-row input,
+ .tablesorter-filter-row select{
+ width: 98%;
+ margin: 0;
+ padding: @overallPadding;
+ color: @filterElementTextColor;
+ background-color: @filterElementBkgd;
+ border: @filterElementBorder;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ .filterWidgetTransition;
+ }
+ .tablesorter-filter-row {
+ background-color: @filterCellBackground;
+ }
+ .tablesorter-filter-row td {
+ text-align: center;
+ background-color: @filterCellBackground;
+ line-height: normal;
+ text-align: center; /* center the input */
+ .filterWidgetTransition;
+ }
+ /* hidden filter row */
+ .tablesorter-filter-row.hideme td {
+ padding: @filterRowHiddenHeight / 2;
+ margin: 0;
+ line-height: 0;
+ cursor: pointer;
+ }
+ .tablesorter-filter-row.hideme * {
+ height: 1px;
+ min-height: 0;
+ border: 0;
+ padding: 0;
+ margin: 0;
+ /* don't use visibility: hidden because it disables tabbing */
+ opacity: 0;
+ filter: alpha(opacity=0);
+ }
+ /* rows hidden by filtering (needed for child rows) */
+ .filtered {
+ display: none;
+ }
+
+ /* ajax error row */
+ .tablesorter-errorRow td {
+ text-align: center;
+ cursor: pointer;
+ background-color: @errorBackground;
+ }
+
+}
diff --git a/web/_static/tablesorter/css/less/metro.less b/web/_static/tablesorter/css/less/metro.less
new file mode 100644
index 0000000..5fd989f
--- /dev/null
+++ b/web/_static/tablesorter/css/less/metro.less
@@ -0,0 +1,357 @@
+/* Tablesorter Custom Metro LESS Theme by Rob Garrison
+
+To create your own theme, modify the code below and run it through
+a LESS compiler, like this one: http://leafo.net/lessphp/editor.html
+or download less.js from http://lesscss.org/
+
+Test out these customization files live
+ Basic LESS Theme : http://codepen.io/Mottie/pen/eqBbn
+ Bootstrap LESS : http://codepen.io/Mottie/pen/Ltzpi
+ Metro LESS Style : http://codepen.io/Mottie/pen/gCslk
+ Basic SCSS : http://codepen.io/Mottie/pen/LbXdNR
+
+*/
+
+/*** theme ***/
+@theme : tablesorter-metro;
+
+/*** fonts ***/
+@tableHeaderFont : 14px 'Segoe UI Semilight', 'Open Sans', Verdana, Arial, Helvetica, sans-serif;
+@tableBodyFont : 14px 'Segoe UI Semilight', 'Open Sans', Verdana, Arial, Helvetica, sans-serif;
+
+/*** color definitions ***/
+/* for best results, only change the hue (120),
+ leave the saturation (60%) and luminosity (75%) alone
+ pick the color from here: http://hslpicker.com/#825a2b
+
+ Inspired by http://www.jtable.org/ metro themes:
+ Blue: hsl(212, 86%, 35%)
+ Brown hsl(32, 50%, 30%)
+ Crimson hsl(0, 100%, 38%)
+ Dark Grey hsl(0, 0%, 27%)
+ Dark Orange hsl(13, 70%, 51%)
+ Green hsl(120, 100%, 32%)
+ Light Gray hsl(0, 0%, 44%)
+ Pink hsl(297, 100%, 33%)
+ Purple hsl(257, 51%, 48%)
+ Red hsl(5, 100%, 40%)
+*/
+@headerBackground : hsl(32, 50%, 30%);
+@borderAndBackground : #cdcdcd;
+@headerTextColor : #eee;
+
+@bodyBackground : #fff;
+@bodyTextColor : #000;
+
+@captionBackground : #fff; /* it might be best to match the document body background color here */
+@errorBackground : #e6bf99; /* ajax error message (added to thead) */
+
+@filterCellBackground : #eee;
+@filterElementTextColor: #333;
+@filterElementBkgd : #fff;
+@filterElementBorder : 1px solid #bbb;
+@filterTransitionTime : 0.1s;
+@filterRowHiddenHeight : 4px; /* becomes height using padding (so it's divided by 2) */
+
+@overallPadding : 4px;
+/* 20px should be slightly wider than the icon width to avoid overlap */
+@headerPadding : 4px 20px 4px 4px;
+
+/* url(icons/loading.gif); */
+@processingIcon : url('data:image/gif;base64,R0lGODlhEAAQAPIAAP///1VVVdbW1oCAgFVVVZaWlqurq7a2tiH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAADMwi63P4wyklrE2MIOggZnAdOmGYJRbExwroUmcG2LmDEwnHQLVsYOd2mBzkYDAdKa+dIAAAh+QQJCgAAACwAAAAAEAAQAAADNAi63P5OjCEgG4QMu7DmikRxQlFUYDEZIGBMRVsaqHwctXXf7WEYB4Ag1xjihkMZsiUkKhIAIfkECQoAAAAsAAAAABAAEAAAAzYIujIjK8pByJDMlFYvBoVjHA70GU7xSUJhmKtwHPAKzLO9HMaoKwJZ7Rf8AYPDDzKpZBqfvwQAIfkECQoAAAAsAAAAABAAEAAAAzMIumIlK8oyhpHsnFZfhYumCYUhDAQxRIdhHBGqRoKw0R8DYlJd8z0fMDgsGo/IpHI5TAAAIfkECQoAAAAsAAAAABAAEAAAAzIIunInK0rnZBTwGPNMgQwmdsNgXGJUlIWEuR5oWUIpz8pAEAMe6TwfwyYsGo/IpFKSAAAh+QQJCgAAACwAAAAAEAAQAAADMwi6IMKQORfjdOe82p4wGccc4CEuQradylesojEMBgsUc2G7sDX3lQGBMLAJibufbSlKAAAh+QQJCgAAACwAAAAAEAAQAAADMgi63P7wCRHZnFVdmgHu2nFwlWCI3WGc3TSWhUFGxTAUkGCbtgENBMJAEJsxgMLWzpEAACH5BAkKAAAALAAAAAAQABAAAAMyCLrc/jDKSatlQtScKdceCAjDII7HcQ4EMTCpyrCuUBjCYRgHVtqlAiB1YhiCnlsRkAAAOwAAAAAAAAAAAA==');
+
+/* zebra striping */
+.allRows {
+ background-color: @bodyBackground;
+ color: @bodyTextColor;
+}
+.evenRows {
+ background-color: lighten( desaturate(@headerBackground, 80%), 70%);
+ color: @bodyTextColor;
+}
+.oddRows {
+ background-color: lighten( desaturate(@headerBackground, 80%), 50%);
+}
+
+/* hovered rows */
+.oddHovered {
+ background-color: lighten( desaturate(@headerBackground, 50%), 40%);
+ color: @bodyTextColor;
+}
+.evenHovered {
+ background-color: lighten( desaturate(@headerBackground, 50%), 30%);
+ color: @bodyTextColor;
+}
+
+/* Columns widget */
+@primaryOdd : lighten( spin(@headerBackground, 10), 40%);
+@primaryEven : lighten( @primaryOdd, 8% );
+@secondaryOdd : @primaryEven;
+@secondaryEven : lighten( @primaryEven, 8% );
+@tertiaryOdd : @secondaryEven;
+@tertiaryEven : lighten( @secondaryEven, 8% );
+
+/* Filter widget transition */
+.filterWidgetTransition {
+ -webkit-transition: line-height @filterTransitionTime ease;
+ -moz-transition: line-height @filterTransitionTime ease;
+ -o-transition: line-height @filterTransitionTime ease;
+ transition: line-height @filterTransitionTime ease;
+}
+
+/*** Arrows ***/
+@arrowPosition : right 5px center;
+
+/* black */
+@unsortedBlack : url(data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAQBAMAAADQT4M0AAAAIVBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABt0UjBAAAACnRSTlMAMwsqXt+gIBUGxGoDMAAAAFlJREFUCNctzC0SQAAUReEzGNQ3AlHRiSRZFCVZYgeswRL8hLdK7834wj3tAlGP6y7fYHpKS6w6WwbVG0I1NZVnZPG8/DYxOYlnhUYkA06R1s9ESsxR4NIdPhkPFDFYuEnMAAAAAElFTkSuQmCC);
+@sortAscBlack : url(data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAQBAMAAADQT4M0AAAAIVBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABt0UjBAAAACnRSTlMAMwsqXt+gIBUGxGoDMAAAAFlJREFUCNctzC0SQAAUReEzGNQ3AlHRiSRZFCVZYgeswRL8hLdK7834wj3tAlGP6y7fYHpKS6w6WwbVG0I1NZVnZPG8/DYxOYlnhUYkA06R1s9ESsxR4NIdPhkPFDFYuEnMAAAAAElFTkSuQmCC);
+@sortDescBlack : url(data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAQBAMAAADQT4M0AAAALVBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADBoCg+AAAADnRSTlMAMiweCQITTvDctZZqaTlM310AAABcSURBVAjXY2BgYEtgAAFHERDJqigUAKSYBQUNgFSioKAYAwOLIBA4MASBKFUGQxAlzAAF+94BwWuGKBC1lIFl3rt3Lx0YGCzevWsGSjK9e6cAUlT3HKyW9wADAwDRrBiDy6bKzwAAAABJRU5ErkJggg==);
+
+/* white */
+@unsortedWhite : url(data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAQBAMAAADQT4M0AAAAElBMVEUAAADu7u7u7u7u7u7u7u7u7u7yb344AAAABnRSTlMAMhIHKyAHBrhHAAAATElEQVQI12NgYGBSYAABQ2Ew5SgCIlkFBQOAlKKgoBADA7MgEBgwsIAoB4ZAECXKAAFQHkg9WIejoCBIv4mgoDOQYgZpAxkDNARqEQBTkAYuMZEHPgAAAABJRU5ErkJggg==);
+@sortAscWhite : url(data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAQBAMAAADQT4M0AAAAHlBMVEUAAADu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u4+jEeEAAAACXRSTlMAMwkqFV7roCD4hW+/AAAAWUlEQVQI1y3MrQ5AABSG4Xd+Rj0jiDabjKZxB6qqaarGNRh27tY5myd8b/uAeML1l2+wPqUlUd0ss+oNoZqG2rOwe15+p5iC1HNAK5IBlUjnZyIlZsxx0QAfzokSZgp96u4AAAAASUVORK5CYII=);
+@sortDescWhite : url(data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAQBAMAAADQT4M0AAAAJ1BMVEUAAADu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u4RJgHSAAAADHRSTlMAMiweCQITaU7olrlu2HdvAAAAXElEQVQI12NgYGBLYAABRxEQyaooFACkmAUFDYBUoqCgGAMDiyAQODAEgShVBkMQJcwABWvOAMEphmgQtZWBZc6ZMycdGBhszpw5DJRkOnNGAaSo5wRYLXsBAwMAi4YWQHRX4F0AAAAASUVORK5CYII=);
+
+/* automatically choose the correct arrow/text color */
+.headerText (@a) when (lightness(@a) >= 50%) {
+ color: @headerTextColor;
+}
+.headerText (@a) when (lightness(@a) < 50%) {
+ color: lighten(@headerTextColor, 90%);
+}
+.unsorted (@a) when (lightness(@a) >= 50%) {
+ background-image: @unsortedBlack;
+}
+.unsorted (@a) when (lightness(@a) < 50%) {
+ background-image: @unsortedWhite;
+}
+.sortAsc (@a) when (lightness(@a) >= 50%) {
+ background-image: @sortAscBlack;
+}
+.sortAsc (@a) when (lightness(@a) < 50%) {
+ background-image: @sortAscWhite;
+}
+.sortDesc (@a) when (lightness(@a) >= 50%) {
+ background-image: @sortDescBlack;
+}
+.sortDesc (@a) when (lightness(@a) < 50%) {
+ background-image: @sortDescWhite;
+}
+
+/* variable theme name - requires less.js 1.3+;
+ or just replace (!".@{theme}") with the contents of @theme
+*/
+.@{theme} {
+ font: @tableBodyFont;
+ background-color: @borderAndBackground;
+ margin: 10px 0 15px;
+ width: 100%;
+ text-align: left;
+ border-spacing: 0;
+ border: 0;
+
+ th, td {
+ border: 0;
+ }
+
+ /* style th's outside of the thead */
+ th, thead td {
+ font: @tableHeaderFont;
+ font-weight: bold;
+ background-color: @headerBackground;
+ color: @headerTextColor;
+ .headerText(@headerBackground);
+ border-collapse: collapse;
+ padding: @overallPadding;
+ }
+
+ .dark-row th, .dark-row td, caption.dark-row {
+ background-color: darken( @headerBackground, 10% );
+ }
+
+ tbody td, tfoot th, tfoot td {
+ padding: @overallPadding;
+ vertical-align: top;
+ }
+
+ /* style header */
+ .tablesorter-header {
+ .unsorted(@headerBackground);
+ background-repeat: no-repeat;
+ background-position: @arrowPosition;
+ cursor: pointer;
+ white-space: normal;
+ }
+
+ .tablesorter-header-inner {
+ padding: @headerPadding;
+ }
+
+ .tablesorter-header.sorter-false {
+ background-image: none;
+ cursor: default;
+ padding: @overallPadding;
+ }
+
+ .tablesorter-headerAsc {
+ .sortAsc(@headerBackground);
+ }
+
+ .tablesorter-headerDesc {
+ .sortDesc(@headerBackground);
+ }
+
+ /* tfoot */
+ tfoot .tablesorter-headerAsc,
+ tfoot .tablesorter-headerDesc {
+ /* remove sort arrows from footer */
+ background-image: none;
+ }
+
+ /* optional disabled input styling */
+ .disabled {
+ opacity: 0.5;
+ filter: alpha(opacity=50);
+ cursor: not-allowed;
+ }
+
+ /* body */
+ tbody {
+
+ td {
+ .allRows;
+ padding: @overallPadding;
+ vertical-align: top;
+ }
+
+ /* Zebra Widget - row alternating colors */
+ tr.odd > td {
+ .oddRows;
+ }
+ tr.even > td {
+ .evenRows;
+ }
+
+ }
+
+ /* hovered row colors
+ you'll need to add additional lines for
+ rows with more than 2 child rows
+ */
+ tbody > tr.hover > td,
+ tbody > tr:hover > td,
+ tbody > tr:hover + tr.tablesorter-childRow > td,
+ tbody > tr:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td,
+ tbody > tr.even.hover > td,
+ tbody > tr.even:hover > td,
+ tbody > tr.even:hover + tr.tablesorter-childRow > td,
+ tbody > tr.even:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td {
+ .evenHovered;
+ }
+ tbody > tr.odd.hover > td,
+ tbody > tr.odd:hover > td,
+ tbody > tr.odd:hover + tr.tablesorter-childRow > td,
+ tbody > tr.odd:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td {
+ .oddHovered;
+ }
+
+ /* table processing indicator - indeterminate spinner */
+ .tablesorter-processing {
+ background-image: @processingIcon;
+ background-position: center center;
+ background-repeat: no-repeat;
+ }
+
+ /* pager */
+ div.tablesorter-pager {
+ button {
+ background-color: lighten( @headerBackground, 7% );
+ color: @headerTextColor;
+ border: lighten( @headerBackground, 15% ) 1px solid;
+ cursor: pointer;
+ }
+ button:hover {
+ background-color: lighten( @headerBackground, 15% );
+ }
+ }
+
+ /* Column Widget - column sort colors */
+ tr.odd td.primary {
+ background-color: @primaryOdd;
+ }
+ td.primary, tr.even td.primary {
+ background-color: @primaryEven;
+ }
+ tr.odd td.secondary {
+ background-color: @secondaryOdd;
+ }
+ td.secondary, tr.even td.secondary {
+ background-color: @secondaryEven;
+ }
+ tr.odd td.tertiary {
+ background-color: @tertiaryOdd;
+ }
+ td.tertiary, tr.even td.tertiary {
+ background-color: @tertiaryEven;
+ }
+
+ /* caption (non-theme matching) */
+ caption {
+ background-color: @captionBackground ;
+ }
+
+ /* filter widget */
+ .tablesorter-filter-row input,
+ .tablesorter-filter-row select{
+ width: 98%;
+ height: auto;
+ margin: 0;
+ padding: @overallPadding;
+ color: @filterElementTextColor;
+ background-color: @filterElementBkgd;
+ border: @filterElementBorder;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ .filterWidgetTransition;
+ }
+ .tablesorter-filter-row {
+ background-color: @filterCellBackground;
+ }
+ .tablesorter-filter-row td {
+ text-align: center;
+ background-color: @filterCellBackground;
+ line-height: normal;
+ text-align: center; /* center the input */
+ .filterWidgetTransition;
+ }
+ /* hidden filter row */
+ .tablesorter-filter-row.hideme td {
+ padding: @filterRowHiddenHeight / 2;
+ margin: 0;
+ line-height: 0;
+ cursor: pointer;
+ }
+ .tablesorter-filter-row.hideme * {
+ height: 1px;
+ min-height: 0;
+ border: 0;
+ padding: 0;
+ margin: 0;
+ /* don't use visibility: hidden because it disables tabbing */
+ opacity: 0;
+ filter: alpha(opacity=0);
+ }
+ /* rows hidden by filtering (needed for child rows) */
+ .filtered {
+ display: none;
+ }
+
+ /* ajax error row */
+ .tablesorter-errorRow td {
+ text-align: center;
+ cursor: pointer;
+ background-color: @errorBackground;
+ }
+
+}
diff --git a/web/_static/tablesorter/css/less/theme.less b/web/_static/tablesorter/css/less/theme.less
new file mode 100644
index 0000000..e645227
--- /dev/null
+++ b/web/_static/tablesorter/css/less/theme.less
@@ -0,0 +1,330 @@
+/* Tablesorter Custom LESS Theme by Rob Garrison
+
+ To create your own theme, modify the code below and run it through
+ a LESS compiler, like this one: http://leafo.net/lessphp/editor.html
+ or download less.js from http://lesscss.org/
+
+Test out these custom less files live
+ Basic Theme : http://codepen.io/Mottie/pen/eqBbn
+ Bootstrap : http://codepen.io/Mottie/pen/Ltzpi
+ Metro Style : http://codepen.io/Mottie/pen/gCslk
+ Basic SCSS : http://codepen.io/Mottie/pen/LbXdNR
+
+ */
+
+/*** theme ***/
+@theme : tablesorter-custom;
+
+/*** fonts ***/
+@tableHeaderFont : 11px 'trebuchet ms', verdana, arial;
+@tableBodyFont : 11px 'trebuchet ms', verdana, arial;
+
+/*** color definitions ***/
+/* for best results, only change the hue (120),
+ leave the saturation (60%) and luminosity (75%) alone
+ pick the color from here: http://hslpicker.com/#99E699 */
+@headerBackground : hsl(120, 60%, 75%);
+@borderAndBackground : #cdcdcd;
+@overallBorder : @borderAndBackground 1px solid;
+@headerTextColor : #000;
+
+@bodyBackground : #fff;
+@bodyTextColor : #000;
+
+@headerAsc : darken(spin(@headerBackground, 5), 10%); /* darken(@headerBackground, 10%); */
+@headerDesc : lighten(spin(@headerBackground, -5), 10%); /* desaturate(@headerAsc, 5%); */
+
+@captionBackground : #fff; /* it might be best to match the document body background color here */
+@errorBackground : #e6bf99; /* ajax error message (added to thead) */
+
+@filterCellBackground : #eee;
+@filterElementTextColor: #333;
+@filterElementBkgd : #fff;
+@filterElementBorder : 1px solid #bbb;
+@filterTransitionTime : 0.1s;
+@filterRowHiddenHeight : 4px; /* becomes height using padding (so it's divided by 2) */
+
+@overallPadding : 4px;
+/* 20px should be slightly wider than the icon width to avoid overlap */
+@headerPadding : 4px 20px 4px 4px;
+
+/* url(icons/loading.gif); */
+@processingIcon : url('data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=');
+
+/* zebra striping */
+.allRows {
+ background-color: @bodyBackground;
+ color: @bodyTextColor;
+}
+.evenRows {
+ background-color: lighten(@headerBackground, 40%);
+ color: @bodyTextColor;
+}
+.oddRows {
+ background-color: lighten(@headerBackground, 20%);
+}
+
+/* hovered rows */
+.oddHovered {
+ background-color: desaturate(@headerBackground, 60%);
+ color: @bodyTextColor;
+}
+.evenHovered {
+ background-color: lighten( desaturate(@headerBackground, 60%), 10% );
+ color: @bodyTextColor;
+}
+
+/* Columns widget */
+@primaryOdd : spin(@headerBackground, 10); /* saturate( darken( desaturate(@headerBackground, 10%), 10% ), 30%); */
+@primaryEven : lighten( @primaryOdd, 10% );
+@secondaryOdd : @primaryEven;
+@secondaryEven : lighten( @primaryEven, 5% );
+@tertiaryOdd : @secondaryEven;
+@tertiaryEven : lighten( @secondaryEven, 5% );
+
+/* Filter widget transition */
+.filterWidgetTransition {
+ -webkit-transition: line-height @filterTransitionTime ease;
+ -moz-transition: line-height @filterTransitionTime ease;
+ -o-transition: line-height @filterTransitionTime ease;
+ transition: line-height @filterTransitionTime ease;
+}
+
+/*** Arrows ***/
+@arrowPosition : right 5px center;
+
+/* black */
+@unsortedBlack : url(data:image/gif;base64,R0lGODlhFQAJAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==);
+@sortAscBlack : url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7);
+@sortDescBlack : url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7);
+
+/* white */
+@unsortedWhite : url(data:image/gif;base64,R0lGODlhFQAJAIAAAP///////yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==);
+@sortAscWhite : url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7);
+@sortDescWhite : url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7);
+
+/* automatically choose the correct arrow/text color */
+.headerText (@a) when (lightness(@a) >= 50%) {
+ color: @headerTextColor;
+}
+.headerText (@a) when (lightness(@a) < 50%) {
+ color: lighten(@headerTextColor, 90%);
+}
+.unsorted (@a) when (lightness(@a) >= 50%) {
+ background-image: @unsortedBlack;
+}
+.unsorted (@a) when (lightness(@a) < 50%) {
+ background-image: @unsortedWhite;
+}
+.sortAsc (@a) when (lightness(@a) >= 50%) {
+ background-image: @sortAscBlack;
+}
+.sortAsc (@a) when (lightness(@a) < 50%) {
+ background-image: @sortAscWhite;
+}
+.sortDesc (@a) when (lightness(@a) >= 50%) {
+ background-image: @sortDescBlack;
+}
+.sortDesc (@a) when (lightness(@a) < 50%) {
+ background-image: @sortDescWhite;
+}
+
+/* variable theme name - requires less.js 1.3+;
+ or just replace (!".@{theme}") with the contents of @theme
+ */
+.@{theme} {
+ font: @tableBodyFont;
+ background-color: @borderAndBackground;
+ margin: 10px 0 15px;
+ width: 100%;
+ text-align: left;
+ border-spacing: 0;
+ border: @overallBorder;
+ border-width: 1px 0 0 1px;
+
+ th, td {
+ border: @overallBorder;
+ border-width: 0 1px 1px 0;
+ }
+
+ /* style th's outside of the thead */
+ th, thead td {
+ font: @tableHeaderFont;
+ font-weight: bold;
+ background-color: @headerBackground;
+ .headerText(@headerBackground);
+ border-collapse: collapse;
+ padding: @overallPadding;
+ }
+
+ tbody td, tfoot th, tfoot td {
+ padding: @overallPadding;
+ vertical-align: top;
+ }
+
+ /* style header */
+ .tablesorter-header {
+ .unsorted(@headerBackground);
+ background-repeat: no-repeat;
+ background-position: @arrowPosition;
+ padding: @headerPadding;
+ cursor: pointer;
+ }
+
+ .tablesorter-header.sorter-false {
+ background-image: none;
+ cursor: default;
+ padding: @overallPadding;
+ }
+
+ .tablesorter-headerAsc {
+ background-color: @headerAsc;
+ .sortAsc(@headerBackground);
+ }
+
+ .tablesorter-headerDesc {
+ background-color: @headerDesc;
+ .sortDesc(@headerBackground);
+ }
+
+ /* tfoot */
+ tfoot .tablesorter-headerAsc,
+ tfoot .tablesorter-headerDesc {
+ /* remove sort arrows from footer */
+ background-image: none;
+ }
+
+ /* optional disabled input styling */
+ .disabled {
+ opacity: 0.5;
+ filter: alpha(opacity=50);
+ cursor: not-allowed;
+ }
+
+ /* body */
+ tbody {
+
+ td {
+ .allRows;
+ padding: @overallPadding;
+ vertical-align: top;
+ }
+
+ /* Zebra Widget - row alternating colors */
+ tr.odd > td {
+ .oddRows;
+ }
+ tr.even > td {
+ .evenRows;
+ }
+
+ }
+
+ /* hovered row colors
+ you'll need to add additional lines for
+ rows with more than 2 child rows
+ */
+ tbody > tr.hover td,
+ tbody > tr:hover td,
+ tbody > tr:hover + tr.tablesorter-childRow > td,
+ tbody > tr:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td,
+ tbody > tr.even.hover > td,
+ tbody > tr.even:hover > td,
+ tbody > tr.even:hover + tr.tablesorter-childRow > td,
+ tbody > tr.even:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td {
+ .evenHovered;
+ }
+ tbody > tr.odd.hover > td,
+ tbody > tr.odd:hover > td,
+ tbody > tr.odd:hover + tr.tablesorter-childRow > td,
+ tbody > tr.odd:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td {
+ .oddHovered;
+ }
+
+ /* table processing indicator - indeterminate spinner */
+ .tablesorter-processing {
+ background-image: @processingIcon;
+ background-position: center center;
+ background-repeat: no-repeat;
+ }
+
+ /* Column Widget - column sort colors */
+ tr.odd td.primary {
+ background-color: @primaryOdd;
+ }
+ td.primary, tr.even td.primary {
+ background-color: @primaryEven;
+ }
+ tr.odd td.secondary {
+ background-color: @secondaryOdd;
+ }
+ td.secondary, tr.even td.secondary {
+ background-color: @secondaryEven;
+ }
+ tr.odd td.tertiary {
+ background-color: @tertiaryOdd;
+ }
+ td.tertiary, tr.even td.tertiary {
+ background-color: @tertiaryEven;
+ }
+
+ /* caption (non-theme matching) */
+ caption {
+ background-color: @captionBackground ;
+ }
+
+ /* filter widget */
+ .tablesorter-filter-row input,
+ .tablesorter-filter-row select {
+ width: 98%;
+ height: auto;
+ margin: 0;
+ padding: @overallPadding;
+ color: @filterElementTextColor;
+ background-color: @filterElementBkgd;
+ border: @filterElementBorder;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ .filterWidgetTransition;
+ }
+ .tablesorter-filter-row {
+ background-color: @filterCellBackground;
+ }
+ .tablesorter-filter-row td {
+ text-align: center;
+ background-color: @filterCellBackground;
+ line-height: normal;
+ text-align: center; /* center the input */
+ .filterWidgetTransition;
+ }
+ /* hidden filter row */
+ .tablesorter-filter-row.hideme td {
+ padding: @filterRowHiddenHeight / 2;
+ margin: 0;
+ line-height: 0;
+ cursor: pointer;
+ }
+ .tablesorter-filter-row.hideme * {
+ height: 1px;
+ min-height: 0;
+ border: 0;
+ padding: 0;
+ margin: 0;
+ /* don't use visibility: hidden because it disables tabbing */
+ opacity: 0;
+ filter: alpha(opacity=0);
+ }
+ /* rows hidden by filtering (needed for child rows) */
+ .filtered {
+ display: none;
+ }
+
+ /* ajax error row */
+ .tablesorter-errorRow td {
+ text-align: center;
+ cursor: pointer;
+ background-color: @errorBackground;
+ }
+
+}
diff --git a/web/_static/tablesorter/css/scss/theme.scss b/web/_static/tablesorter/css/scss/theme.scss
new file mode 100644
index 0000000..f8a940c
--- /dev/null
+++ b/web/_static/tablesorter/css/scss/theme.scss
@@ -0,0 +1,327 @@
+/* Tablesorter Custom SCSS Theme by Dan Feidt (https://github.com/HongPong)
+ Converted from Custom LESS Theme by Rob Garrison
+
+ To create your own theme, modify the code below and run it through
+ a SCSS compiler, like this one: http://beautifytools.com/scss-compiler.php
+ or download sass.js from https://github.com/medialize/sass.js
+
+Test out these customization files live
+ Basic LESS Theme : http://codepen.io/Mottie/pen/eqBbn
+ Bootstrap LESS : http://codepen.io/Mottie/pen/Ltzpi
+ Metro LESS Style : http://codepen.io/Mottie/pen/gCslk
+ Basic SCSS : http://codepen.io/Mottie/pen/LbXdNR
+
+ */
+
+/*** theme ***/
+$theme : tablesorter-custom;
+
+/*** fonts ***/
+$tableHeaderFont : 11px 'trebuchet ms', verdana, arial;
+$tableBodyFont : 11px 'trebuchet ms', verdana, arial;
+
+/*** color definitions ***/
+/* for best results, only change the hue (120),
+ leave the saturation (60%) and luminosity (75%) alone
+ pick the color from here: http://hslpicker.com/#99E699 */
+$headerBackground : hsl(0, 60%, 75%);
+$borderAndBackground : #cdcdcd;
+$overallBorder : $borderAndBackground 1px solid;
+$headerTextColor : #000;
+
+$bodyBackground : #fff;
+$bodyTextColor : #000;
+
+$headerAsc : darken(adjust-hue($headerBackground, 5), 10%); /* darken($headerBackground, 10%); */
+$headerDesc : lighten(adjust-hue($headerBackground, -5), 10%); /* desaturate($headerAsc, 5%); */
+
+$captionBackground : #fff; /* it might be best to match the document body background color here */
+$errorBackground : #e6bf99; /* ajax error message (added to thead) */
+
+$filterCellBackground : #eee;
+$filterElementTextColor: #333;
+$filterElementBkgd : #fff;
+$filterElementBorder : 1px solid #bbb;
+$filterTransitionTime : 0.1s;
+$filterRowHiddenHeight : 4px; /* becomes height using padding (so it's divided by 2) */
+
+$overallPadding : 4px;
+/* 20px should be slightly wider than the icon width to avoid overlap */
+$headerPadding : 4px 20px 4px 4px;
+
+/* url(icons/loading.gif); */
+$processingIcon : url('data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=');
+
+/* zebra striping */
+@mixin allRows {
+ background-color: $bodyBackground;
+ color: $bodyTextColor;
+}
+@mixin evenRows {
+ background-color: lighten($headerBackground, 40%);
+ color: $bodyTextColor;
+}
+@mixin oddRows {
+ background-color: lighten($headerBackground, 20%);
+}
+
+/* hovered rows */
+@mixin oddHovered {
+ background-color: desaturate($headerBackground, 60%);
+ color: $bodyTextColor;
+}
+@mixin evenHovered {
+ background-color: lighten( desaturate($headerBackground, 60%), 10% );
+ color: $bodyTextColor;
+}
+
+/* Columns widget */
+$primaryOdd : adjust-hue($headerBackground, 10); /* saturate( darken( desaturate($headerBackground, 10%), 10% ), 30%); */
+$primaryEven : lighten( $primaryOdd, 10% );
+$secondaryOdd : $primaryEven;
+$secondaryEven : lighten( $primaryEven, 5% );
+$tertiaryOdd : $secondaryEven;
+$tertiaryEven : lighten( $secondaryEven, 5% );
+
+/* Filter widget transition */
+@mixin filterWidgetTransition {
+ -webkit-transition: line-height $filterTransitionTime ease;
+ -moz-transition: line-height $filterTransitionTime ease;
+ -o-transition: line-height $filterTransitionTime ease;
+ transition: line-height $filterTransitionTime ease;
+}
+
+/*** Arrows ***/
+$arrowPosition : right 5px center;
+
+/* black */
+$unsortedBlack : url(data:image/gif;base64,R0lGODlhFQAJAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==);
+$sortAscBlack : url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7);
+$sortDescBlack : url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7);
+
+/* white */
+$unsortedWhite : url(data:image/gif;base64,R0lGODlhFQAJAIAAAP///////yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==);
+$sortAscWhite : url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7);
+$sortDescWhite : url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7);
+
+/* automatically choose the correct arrow/text color */
+@function set-lightness($a, $b) {
+ @if (lightness($headerBackground) >= 50) {
+ @return $a;
+ } @else {
+ @return $b;
+ }
+}
+@mixin headerText {
+ color: set-lightness($headerTextColor, lighten($headerTextColor, 90%));
+}
+
+@mixin unsorted {
+ background-image: set-lightness($unsortedBlack, $unsortedWhite);
+}
+@mixin sortAsc {
+ background-image: set-lightness($sortAscBlack, $sortAscWhite);
+}
+@mixin sortDesc {
+ background-image: set-lightness($sortDescBlack, $sortDescWhite);
+}
+
+/* variable theme name - requires less.js 1.3+;
+ or just replace (!".#{$theme}") with the contents of $theme
+ */
+.#{$theme} {
+ font: $tableBodyFont;
+ background-color: $borderAndBackground;
+ margin: 10px 0 15px;
+ width: 100%;
+ text-align: left;
+ border-spacing: 0;
+ border: $overallBorder;
+ border-width: 1px 0 0 1px;
+
+ th, td {
+ border: $overallBorder;
+ border-width: 0 1px 1px 0;
+ }
+
+ /* style th's outside of the thead */
+ th, thead td {
+ font: $tableHeaderFont;
+ font-weight: bold;
+ background-color: $headerBackground;
+ @include headerText;
+ border-collapse: collapse;
+ padding: $overallPadding;
+ }
+
+ tbody td, tfoot th, tfoot td {
+ padding: $overallPadding;
+ vertical-align: top;
+ }
+
+ /* style header */
+ .tablesorter-header {
+ @include unsorted;
+ background-repeat: no-repeat;
+ background-position: $arrowPosition;
+ padding: $headerPadding;
+ cursor: pointer;
+ }
+
+ .tablesorter-header.sorter-false {
+ background-image: none;
+ cursor: default;
+ padding: $overallPadding;
+ }
+
+ .tablesorter-headerAsc {
+ background-color: $headerAsc;
+ @include sortAsc;
+ }
+
+ .tablesorter-headerDesc {
+ background-color: $headerDesc;
+ @include sortDesc;
+ }
+
+ /* tfoot */
+ tfoot .tablesorter-headerAsc,
+ tfoot .tablesorter-headerDesc {
+ /* remove sort arrows from footer */
+ background-image: none;
+ }
+
+ /* optional disabled input styling */
+ .disabled {
+ opacity: 0.5;
+ filter: alpha(opacity=50);
+ cursor: not-allowed;
+ }
+
+ /* body */
+ tbody {
+
+ td {
+ @include allRows;
+ padding: $overallPadding;
+ vertical-align: top;
+ }
+
+ /* Zebra Widget - row alternating colors */
+ tr.odd > td {
+ @include oddRows;
+ }
+ tr.even > td {
+ @include evenRows;
+ }
+
+ }
+
+ /* hovered row colors
+ you'll need to add additional lines for
+ rows with more than 2 child rows
+ */
+ tbody > tr.hover td,
+ tbody > tr:hover td,
+ tbody > tr:hover + tr.tablesorter-childRow > td,
+ tbody > tr:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td,
+ tbody > tr.even.hover > td,
+ tbody > tr.even:hover > td,
+ tbody > tr.even:hover + tr.tablesorter-childRow > td,
+ tbody > tr.even:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td {
+ @include evenHovered;
+ }
+ tbody > tr.odd.hover > td,
+ tbody > tr.odd:hover > td,
+ tbody > tr.odd:hover + tr.tablesorter-childRow > td,
+ tbody > tr.odd:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td {
+ @include oddHovered;
+ }
+
+ /* table processing indicator - indeterminate spinner */
+ .tablesorter-processing {
+ background-image: $processingIcon;
+ background-position: center center;
+ background-repeat: no-repeat;
+ }
+
+ /* Column Widget - column sort colors */
+ tr.odd td.primary {
+ background-color: $primaryOdd;
+ }
+ td.primary, tr.even td.primary {
+ background-color: $primaryEven;
+ }
+ tr.odd td.secondary {
+ background-color: $secondaryOdd;
+ }
+ td.secondary, tr.even td.secondary {
+ background-color: $secondaryEven;
+ }
+ tr.odd td.tertiary {
+ background-color: $tertiaryOdd;
+ }
+ td.tertiary, tr.even td.tertiary {
+ background-color: $tertiaryEven;
+ }
+
+ /* caption (non-theme matching) */
+ caption {
+ background-color: $captionBackground ;
+ }
+
+ /* filter widget */
+ .tablesorter-filter-row input,
+ .tablesorter-filter-row select {
+ width: 98%;
+ height: auto;
+ margin: 0;
+ padding: $overallPadding;
+ color: $filterElementTextColor;
+ background-color: $filterElementBkgd;
+ border: $filterElementBorder;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ @include filterWidgetTransition;
+ }
+ .tablesorter-filter-row {
+ background-color: $filterCellBackground;
+ }
+ .tablesorter-filter-row td {
+ text-align: center;
+ background-color: $filterCellBackground;
+ line-height: normal;
+ text-align: center; /* center the input */
+ @include filterWidgetTransition;
+ }
+ /* hidden filter row */
+ .tablesorter-filter-row.hideme td {
+ padding: $filterRowHiddenHeight / 2;
+ margin: 0;
+ line-height: 0;
+ cursor: pointer;
+ }
+ .tablesorter-filter-row.hideme * {
+ height: 1px;
+ min-height: 0;
+ border: 0;
+ padding: 0;
+ margin: 0;
+ /* don't use visibility: hidden because it disables tabbing */
+ opacity: 0;
+ filter: alpha(opacity=0);
+ }
+ /* rows hidden by filtering (needed for child rows) */
+ .filtered {
+ display: none;
+ }
+
+ /* ajax error row */
+ .tablesorter-errorRow td {
+ text-align: center;
+ cursor: pointer;
+ background-color: $errorBackground;
+ }
+
+}
diff --git a/web/_static/tablesorter/css/theme.blackice.min.css b/web/_static/tablesorter/css/theme.blackice.min.css
new file mode 100644
index 0000000..b2d7b6b
--- /dev/null
+++ b/web/_static/tablesorter/css/theme.blackice.min.css
@@ -0,0 +1 @@
+.tablesorter-blackice{width:100%;margin-right:auto;margin-left:auto;font:11px/18px Arial,Sans-serif;text-align:left;background-color:#000;border-collapse:collapse;border-spacing:0}.tablesorter-blackice th,.tablesorter-blackice thead td{padding:4px;font:13px/20px Arial,Sans-serif;font-weight:700;color:#e5e5e5;text-align:left;text-shadow:0 1px 0 rgba(0,0,0,.7);background-color:#111;border:1px solid #232323}.tablesorter-blackice .header,.tablesorter-blackice .tablesorter-header{padding:4px 20px 4px 4px;cursor:pointer;background-image:url(data:image/gif;base64,R0lGODlhFQAJAIAAAP///////yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==);background-position:center right;background-repeat:no-repeat}.tablesorter-blackice .headerSortUp,.tablesorter-blackice .tablesorter-headerAsc,.tablesorter-blackice .tablesorter-headerSortUp{background-image:url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7);color:#fff}.tablesorter-blackice .headerSortDown,.tablesorter-blackice .tablesorter-headerDesc,.tablesorter-blackice .tablesorter-headerSortDown{color:#fff;background-image:url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7)}.tablesorter-blackice thead .sorter-false{background-image:none;cursor:default;padding:4px}.tablesorter-blackice tfoot .tablesorter-headerAsc,.tablesorter-blackice tfoot .tablesorter-headerDesc,.tablesorter-blackice tfoot .tablesorter-headerSortDown,.tablesorter-blackice tfoot .tablesorter-headerSortUp{background-image:none}.tablesorter-blackice td{padding:4px;color:#ccc;vertical-align:top;background-color:#333;border:1px solid #232323}.tablesorter-blackice tbody>tr.even:hover>td,.tablesorter-blackice tbody>tr.hover>td,.tablesorter-blackice tbody>tr.odd:hover>td,.tablesorter-blackice tbody>tr:hover>td{background-color:#000}.tablesorter-blackice .tablesorter-processing{background-position:center center!important;background-repeat:no-repeat!important;background-image:url(data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=)!important}.tablesorter-blackice tr.odd>td{background-color:#333}.tablesorter-blackice tr.even>td{background-color:#393939}.tablesorter-blackice td.primary,.tablesorter-blackice tr.odd td.primary{background-color:#2f3a40}.tablesorter-blackice tr.even td.primary{background-color:#3f4a50}.tablesorter-blackice td.secondary,.tablesorter-blackice tr.odd td.secondary{background-color:#3f4a50}.tablesorter-blackice tr.even td.secondary{background-color:#4f5a60}.tablesorter-blackice td.tertiary,.tablesorter-blackice tr.odd td.tertiary{background-color:#4f5a60}.tablesorter-blackice tr.even td.tertiary{background-color:#5a646b}.tablesorter-blackice>caption{background-color:#fff}.tablesorter-blackice .tablesorter-filter-row{background-color:#222}.tablesorter-blackice .tablesorter-filter-row td{background-color:#222;line-height:normal;text-align:center;-webkit-transition:line-height .1s ease;-moz-transition:line-height .1s ease;-o-transition:line-height .1s ease;transition:line-height .1s ease}.tablesorter-blackice .tablesorter-filter-row .disabled{opacity:.5;cursor:not-allowed}.tablesorter-blackice .tablesorter-filter-row.hideme td{padding:2px;margin:0;line-height:0;cursor:pointer}.tablesorter-blackice .tablesorter-filter-row.hideme *{height:1px;min-height:0;border:0;padding:0;margin:0;opacity:0}.tablesorter-blackice input.tablesorter-filter,.tablesorter-blackice select.tablesorter-filter{width:98%;height:auto;margin:0;padding:4px;background-color:#fff;border:1px solid #bbb;color:#333;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:height .1s ease;-moz-transition:height .1s ease;-o-transition:height .1s ease;transition:height .1s ease}.tablesorter .filtered{display:none}.tablesorter .tablesorter-errorRow td{text-align:center;cursor:pointer;background-color:#e6bf99} \ No newline at end of file
diff --git a/web/_static/tablesorter/css/theme.blue.css b/web/_static/tablesorter/css/theme.blue.css
new file mode 100644
index 0000000..da90a81
--- /dev/null
+++ b/web/_static/tablesorter/css/theme.blue.css
@@ -0,0 +1,229 @@
+/*************
+ Blue Theme
+ *************/
+/* overall */
+.tablesorter-blue {
+ width: 100%;
+ background-color: #fff;
+ margin: 10px 0 15px;
+ text-align: left;
+ border-spacing: 0;
+ border: #cdcdcd 1px solid;
+ border-width: 1px 0 0 1px;
+}
+.tablesorter-blue th,
+.tablesorter-blue td {
+ border: #cdcdcd 1px solid;
+ border-width: 0 1px 1px 0;
+}
+
+/* header */
+.tablesorter-blue th,
+.tablesorter-blue thead td {
+ font: 12px/18px Arial, Sans-serif;
+ font-weight: bold;
+ color: #000;
+ background-color: #99bfe6;
+ border-collapse: collapse;
+ padding: 4px;
+ text-shadow: 0 1px 0 rgba(204, 204, 204, 0.7);
+}
+.tablesorter-blue tbody td,
+.tablesorter-blue tfoot th,
+.tablesorter-blue tfoot td {
+ padding: 4px;
+ vertical-align: top;
+}
+.tablesorter-blue .header,
+.tablesorter-blue .tablesorter-header {
+ /* black (unsorted) double arrow */
+ background-image: url(data:image/gif;base64,R0lGODlhFQAJAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==);
+ /* white (unsorted) double arrow */
+ /* background-image: url(data:image/gif;base64,R0lGODlhFQAJAIAAAP///////yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==); */
+ /* image */
+ /* background-image: url(images/black-unsorted.gif); */
+ background-repeat: no-repeat;
+ background-position: center right;
+ padding: 4px 18px 4px 4px;
+ white-space: normal;
+ cursor: pointer;
+}
+.tablesorter-blue .headerSortUp,
+.tablesorter-blue .tablesorter-headerSortUp,
+.tablesorter-blue .tablesorter-headerAsc {
+ background-color: #9fbfdf;
+ /* black asc arrow */
+ background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7);
+ /* white asc arrow */
+ /* background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7); */
+ /* image */
+ /* background-image: url(images/black-asc.gif); */
+}
+.tablesorter-blue .headerSortDown,
+.tablesorter-blue .tablesorter-headerSortDown,
+.tablesorter-blue .tablesorter-headerDesc {
+ background-color: #8cb3d9;
+ /* black desc arrow */
+ background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7);
+ /* white desc arrow */
+ /* background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7); */
+ /* image */
+ /* background-image: url(images/black-desc.gif); */
+}
+.tablesorter-blue thead .sorter-false {
+ background-image: none;
+ cursor: default;
+ padding: 4px;
+}
+
+/* tfoot */
+.tablesorter-blue tfoot .tablesorter-headerSortUp,
+.tablesorter-blue tfoot .tablesorter-headerSortDown,
+.tablesorter-blue tfoot .tablesorter-headerAsc,
+.tablesorter-blue tfoot .tablesorter-headerDesc {
+ /* remove sort arrows from footer */
+ background-image: none;
+}
+
+/* tbody */
+.tablesorter-blue td {
+ color: #3d3d3d;
+ background-color: #fff;
+ padding: 4px;
+ vertical-align: top;
+}
+
+/* hovered row colors
+ you'll need to add additional lines for
+ rows with more than 2 child rows
+ */
+.tablesorter-blue tbody > tr.hover > td,
+.tablesorter-blue tbody > tr:hover > td,
+.tablesorter-blue tbody > tr:hover + tr.tablesorter-childRow > td,
+.tablesorter-blue tbody > tr:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td,
+.tablesorter-blue tbody > tr.even.hover > td,
+.tablesorter-blue tbody > tr.even:hover > td,
+.tablesorter-blue tbody > tr.even:hover + tr.tablesorter-childRow > td,
+.tablesorter-blue tbody > tr.even:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td {
+ background-color: #d9d9d9;
+}
+.tablesorter-blue tbody > tr.odd.hover > td,
+.tablesorter-blue tbody > tr.odd:hover > td,
+.tablesorter-blue tbody > tr.odd:hover + tr.tablesorter-childRow > td,
+.tablesorter-blue tbody > tr.odd:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td {
+ background-color: #bfbfbf;
+}
+
+/* table processing indicator */
+.tablesorter-blue .tablesorter-processing {
+ background-position: center center !important;
+ background-repeat: no-repeat !important;
+ /* background-image: url(images/loading.gif) !important; */
+ background-image: url('data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=') !important;
+}
+
+/* Zebra Widget - row alternating colors */
+.tablesorter-blue tbody tr.odd > td {
+ background-color: #ebf2fa;
+}
+.tablesorter-blue tbody tr.even > td {
+ background-color: #fff;
+}
+
+/* Column Widget - column sort colors */
+.tablesorter-blue td.primary,
+.tablesorter-blue tr.odd td.primary {
+ background-color: #99b3e6;
+}
+.tablesorter-blue tr.even td.primary {
+ background-color: #c2d1f0;
+}
+.tablesorter-blue td.secondary,
+.tablesorter-blue tr.odd td.secondary {
+ background-color: #c2d1f0;
+}
+.tablesorter-blue tr.even td.secondary {
+ background-color: #d6e0f5;
+}
+.tablesorter-blue td.tertiary,
+.tablesorter-blue tr.odd td.tertiary {
+ background-color: #d6e0f5;
+}
+.tablesorter-blue tr.even td.tertiary {
+ background-color: #ebf0fa;
+}
+
+/* caption */
+.tablesorter-blue > caption {
+ background-color: #fff;
+}
+
+/* filter widget */
+.tablesorter-blue .tablesorter-filter-row {
+ background-color: #eee;
+}
+.tablesorter-blue .tablesorter-filter-row td {
+ background-color: #eee;
+ line-height: normal;
+ text-align: center; /* center the input */
+ -webkit-transition: line-height 0.1s ease;
+ -moz-transition: line-height 0.1s ease;
+ -o-transition: line-height 0.1s ease;
+ transition: line-height 0.1s ease;
+}
+/* optional disabled input styling */
+.tablesorter-blue .tablesorter-filter-row .disabled {
+ opacity: 0.5;
+ filter: alpha(opacity=50);
+ cursor: not-allowed;
+}
+/* hidden filter row */
+.tablesorter-blue .tablesorter-filter-row.hideme td {
+ /*** *********************************************** ***/
+ /*** change this padding to modify the thickness ***/
+ /*** of the closed filter row (height = padding x 2) ***/
+ padding: 2px;
+ /*** *********************************************** ***/
+ margin: 0;
+ line-height: 0;
+ cursor: pointer;
+}
+.tablesorter-blue .tablesorter-filter-row.hideme * {
+ height: 1px;
+ min-height: 0;
+ border: 0;
+ padding: 0;
+ margin: 0;
+ /* don't use visibility: hidden because it disables tabbing */
+ opacity: 0;
+ filter: alpha(opacity=0);
+}
+/* filters */
+.tablesorter-blue input.tablesorter-filter,
+.tablesorter-blue select.tablesorter-filter {
+ width: 98%;
+ height: auto;
+ margin: 0;
+ padding: 4px;
+ background-color: #fff;
+ border: 1px solid #bbb;
+ color: #333;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ -webkit-transition: height 0.1s ease;
+ -moz-transition: height 0.1s ease;
+ -o-transition: height 0.1s ease;
+ transition: height 0.1s ease;
+}
+/* rows hidden by filtering (needed for child rows) */
+.tablesorter .filtered {
+ display: none;
+}
+
+/* ajax error row */
+.tablesorter .tablesorter-errorRow td {
+ text-align: center;
+ cursor: pointer;
+ background-color: #e6bf99;
+}
diff --git a/web/_static/tablesorter/css/theme.blue.min.css b/web/_static/tablesorter/css/theme.blue.min.css
new file mode 100644
index 0000000..e4043d5
--- /dev/null
+++ b/web/_static/tablesorter/css/theme.blue.min.css
@@ -0,0 +1 @@
+.tablesorter-blue{width:100%;background-color:#fff;margin:10px 0 15px;text-align:left;border-spacing:0;border:#cdcdcd 1px solid;border-width:1px 0 0 1px}.tablesorter-blue td,.tablesorter-blue th{border:#cdcdcd 1px solid;border-width:0 1px 1px 0}.tablesorter-blue th,.tablesorter-blue thead td{font:12px/18px Arial,Sans-serif;font-weight:700;color:#000;background-color:#99bfe6;border-collapse:collapse;padding:4px;text-shadow:0 1px 0 rgba(204,204,204,.7)}.tablesorter-blue tbody td,.tablesorter-blue tfoot td,.tablesorter-blue tfoot th{padding:4px;vertical-align:top}.tablesorter-blue .header,.tablesorter-blue .tablesorter-header{background-image:url(data:image/gif;base64,R0lGODlhFQAJAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==);background-repeat:no-repeat;background-position:center right;padding:4px 18px 4px 4px;white-space:normal;cursor:pointer}.tablesorter-blue .headerSortUp,.tablesorter-blue .tablesorter-headerAsc,.tablesorter-blue .tablesorter-headerSortUp{background-color:#9fbfdf;background-image:url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7)}.tablesorter-blue .headerSortDown,.tablesorter-blue .tablesorter-headerDesc,.tablesorter-blue .tablesorter-headerSortDown{background-color:#8cb3d9;background-image:url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7)}.tablesorter-blue thead .sorter-false{background-image:none;cursor:default;padding:4px}.tablesorter-blue tfoot .tablesorter-headerAsc,.tablesorter-blue tfoot .tablesorter-headerDesc,.tablesorter-blue tfoot .tablesorter-headerSortDown,.tablesorter-blue tfoot .tablesorter-headerSortUp{background-image:none}.tablesorter-blue td{color:#3d3d3d;background-color:#fff;padding:4px;vertical-align:top}.tablesorter-blue tbody>tr.even.hover>td,.tablesorter-blue tbody>tr.even:hover+tr.tablesorter-childRow+tr.tablesorter-childRow>td,.tablesorter-blue tbody>tr.even:hover+tr.tablesorter-childRow>td,.tablesorter-blue tbody>tr.even:hover>td,.tablesorter-blue tbody>tr.hover>td,.tablesorter-blue tbody>tr:hover+tr.tablesorter-childRow+tr.tablesorter-childRow>td,.tablesorter-blue tbody>tr:hover+tr.tablesorter-childRow>td,.tablesorter-blue tbody>tr:hover>td{background-color:#d9d9d9}.tablesorter-blue tbody>tr.odd.hover>td,.tablesorter-blue tbody>tr.odd:hover+tr.tablesorter-childRow+tr.tablesorter-childRow>td,.tablesorter-blue tbody>tr.odd:hover+tr.tablesorter-childRow>td,.tablesorter-blue tbody>tr.odd:hover>td{background-color:#bfbfbf}.tablesorter-blue .tablesorter-processing{background-position:center center!important;background-repeat:no-repeat!important;background-image:url(data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=)!important}.tablesorter-blue tbody tr.odd>td{background-color:#ebf2fa}.tablesorter-blue tbody tr.even>td{background-color:#fff}.tablesorter-blue td.primary,.tablesorter-blue tr.odd td.primary{background-color:#99b3e6}.tablesorter-blue tr.even td.primary{background-color:#c2d1f0}.tablesorter-blue td.secondary,.tablesorter-blue tr.odd td.secondary{background-color:#c2d1f0}.tablesorter-blue tr.even td.secondary{background-color:#d6e0f5}.tablesorter-blue td.tertiary,.tablesorter-blue tr.odd td.tertiary{background-color:#d6e0f5}.tablesorter-blue tr.even td.tertiary{background-color:#ebf0fa}.tablesorter-blue>caption{background-color:#fff}.tablesorter-blue .tablesorter-filter-row{background-color:#eee}.tablesorter-blue .tablesorter-filter-row td{background-color:#eee;line-height:normal;text-align:center;-webkit-transition:line-height .1s ease;-moz-transition:line-height .1s ease;-o-transition:line-height .1s ease;transition:line-height .1s ease}.tablesorter-blue .tablesorter-filter-row .disabled{opacity:.5;cursor:not-allowed}.tablesorter-blue .tablesorter-filter-row.hideme td{padding:2px;margin:0;line-height:0;cursor:pointer}.tablesorter-blue .tablesorter-filter-row.hideme *{height:1px;min-height:0;border:0;padding:0;margin:0;opacity:0}.tablesorter-blue input.tablesorter-filter,.tablesorter-blue select.tablesorter-filter{width:98%;height:auto;margin:0;padding:4px;background-color:#fff;border:1px solid #bbb;color:#333;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:height .1s ease;-moz-transition:height .1s ease;-o-transition:height .1s ease;transition:height .1s ease}.tablesorter .filtered{display:none}.tablesorter .tablesorter-errorRow td{text-align:center;cursor:pointer;background-color:#e6bf99} \ No newline at end of file
diff --git a/web/_static/tablesorter/css/theme.bootstrap.min.css b/web/_static/tablesorter/css/theme.bootstrap.min.css
new file mode 100644
index 0000000..12734bd
--- /dev/null
+++ b/web/_static/tablesorter/css/theme.bootstrap.min.css
@@ -0,0 +1 @@
+.tablesorter-bootstrap{width:100%}.tablesorter-bootstrap tfoot td,.tablesorter-bootstrap tfoot th,.tablesorter-bootstrap thead td,.tablesorter-bootstrap thead th{font:14px/20px Arial,Sans-serif;font-weight:700;padding:4px;margin:0 0 18px;background-color:#eee}.tablesorter-bootstrap .tablesorter-header{cursor:pointer}.tablesorter-bootstrap .sorter-false{cursor:default}.tablesorter-bootstrap .tablesorter-header.sorter-false i.tablesorter-icon{display:none}.tablesorter-bootstrap .tablesorter-header-inner{position:relative;padding:4px 18px 4px 4px}.tablesorter-bootstrap .sorter-false .tablesorter-header-inner{padding:4px}.tablesorter-bootstrap .tablesorter-header i.tablesorter-icon{font-size:11px;position:absolute;right:2px;top:50%;margin-top:-7px;width:14px;height:14px;background-repeat:no-repeat;line-height:14px;display:inline-block}.tablesorter-bootstrap .bootstrap-icon-unsorted{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOCAYAAAD5YeaVAAAA20lEQVR4AWJABpKSkoxALCstLb0aUAsZaCAMhVEY6B0amx8YZWDDEDSBa2AGe7XeIiAAClYwVGBvsAcIllsf/mvcC9DgOOd8h90fxWvngVEUbZIkuWRZZlE8eQjcisgZMM9zi+LJ6ZfwegmWZflZDugdHMfxTcGqql7TNBlUB/QObtv2VBSFrev6OY7jngzFk9OT/fn73fWYpqnlXNyXDMWT0zuYx/Bvel9ej+LJ6R08DMOu67q7DkTkrSA5vYPneV71fX/QASdTkJwezhs0TfMARn0wMDDGXEPgF4oijqwM5YjNAAAAAElFTkSuQmCC)}.tablesorter-bootstrap .bootstrap-icon-white.bootstrap-icon-unsorted{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOCAYAAAD5YeaVAAAAe0lEQVR4AbXQoRWDMBiF0Sh2QLAAQ8SxJGugWSA6A2STW1PxTsnB9cnkfuYvv8OGC1t5G3Y0QMP+Bm857keAdQIzWBP3+Bw4MADQE18B6/etRnCV/w9nnGuLezfAmXhABGtAGIkruvk6auIFRwQJDywllsEAjCecB20GP59BQQ+gtlRLAAAAAElFTkSuQmCC)}.tablesorter-bootstrap>tbody>tr.odd>td,.tablesorter-bootstrap>tbody>tr.tablesorter-hasChildRow.odd:hover~tr.tablesorter-hasChildRow.odd~.tablesorter-childRow.odd>td{background-color:#f9f9f9}.tablesorter-bootstrap>tbody>tr.even:hover>td,.tablesorter-bootstrap>tbody>tr.hover>td,.tablesorter-bootstrap>tbody>tr.odd:hover>td,.tablesorter-bootstrap>tbody>tr.tablesorter-hasChildRow.even:hover~.tablesorter-childRow.even>td,.tablesorter-bootstrap>tbody>tr.tablesorter-hasChildRow.odd:hover~.tablesorter-childRow.odd>td{background-color:#f5f5f5}.tablesorter-bootstrap>tbody>tr.even>td,.tablesorter-bootstrap>tbody>tr.tablesorter-hasChildRow.even:hover~tr.tablesorter-hasChildRow.even~.tablesorter-childRow.even>td{background-color:#fff}.tablesorter-bootstrap .tablesorter-processing{background-image:url(data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=);background-position:center center!important;background-repeat:no-repeat!important}.tablesorter-bootstrap>tbody>tr.odd td.primary{background-color:#bfbfbf}.tablesorter-bootstrap>tbody>tr td.primary,.tablesorter-bootstrap>tbody>tr.even td.primary{background-color:#d9d9d9}.tablesorter-bootstrap>tbody>tr.odd td.secondary{background-color:#d9d9d9}.tablesorter-bootstrap>tbody>tr td.secondary,.tablesorter-bootstrap>tbody>tr.even td.secondary{background-color:#e6e6e6}.tablesorter-bootstrap>tbody>tr.odd td.tertiary{background-color:#e6e6e6}.tablesorter-bootstrap>tbody>tr td.tertiary,.tablesorter-bootstrap>tbody>tr.even td.tertiary{background-color:#f2f2f2}.tablesorter-bootstrap>.caption{background-color:#fff}.tablesorter-bootstrap .tablesorter-filter-row input.tablesorter-filter,.tablesorter-bootstrap .tablesorter-filter-row select.tablesorter-filter{width:98%;margin:0;padding:4px 6px;color:#333;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:height .1s ease;-moz-transition:height .1s ease;-o-transition:height .1s ease;transition:height .1s ease}.tablesorter-bootstrap .tablesorter-filter-row .tablesorter-filter.disabled{background-color:#eee;color:#555;cursor:not-allowed;border:1px solid #ccc;border-radius:4px;box-shadow:0 1px 1px rgba(0,0,0,.075) inset;box-sizing:border-box;transition:height .1s ease}.tablesorter-bootstrap .tablesorter-filter-row{background-color:#efefef}.tablesorter-bootstrap .tablesorter-filter-row td{background-color:#efefef;line-height:normal;text-align:center;padding:4px 6px;vertical-align:middle;-webkit-transition:line-height .1s ease;-moz-transition:line-height .1s ease;-o-transition:line-height .1s ease;transition:line-height .1s ease}.tablesorter-bootstrap .tablesorter-filter-row.hideme td{padding:2px;margin:0;line-height:0}.tablesorter-bootstrap .tablesorter-filter-row.hideme *{height:1px;min-height:0;border:0;padding:0;margin:0;opacity:0}.tablesorter .filtered{display:none}.tablesorter-bootstrap .tablesorter-pager select{padding:4px 6px}.tablesorter-bootstrap .tablesorter-pager .pagedisplay{border:0}.tablesorter-bootstrap tfoot i{font-size:11px}.tablesorter .tablesorter-errorRow td{text-align:center;cursor:pointer;background-color:#e6bf99} \ No newline at end of file
diff --git a/web/_static/tablesorter/css/theme.bootstrap_2.min.css b/web/_static/tablesorter/css/theme.bootstrap_2.min.css
new file mode 100644
index 0000000..073d37f
--- /dev/null
+++ b/web/_static/tablesorter/css/theme.bootstrap_2.min.css
@@ -0,0 +1 @@
+.tablesorter-bootstrap{width:100%}.tablesorter-bootstrap .tablesorter-header,.tablesorter-bootstrap tfoot td,.tablesorter-bootstrap tfoot th{font:14px/20px Arial,Sans-serif;font-weight:700;position:relative;padding:8px;margin:0 0 18px;list-style:none;background-color:#fbfbfb;background-image:-moz-linear-gradient(top,#fff,#efefef);background-image:-ms-linear-gradient(top,#fff,#efefef);background-image:-webkit-gradient(linear,0 0,0 100%,from(white),to(#efefef));background-image:-webkit-linear-gradient(top,#fff,#efefef);background-image:-o-linear-gradient(top,#fff,#efefef);background-image:linear-gradient(to bottom,#fff,#efefef);background-repeat:repeat-x;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.tablesorter-bootstrap .tablesorter-header{cursor:pointer}.tablesorter-bootstrap .sorter-false{cursor:default}.tablesorter-bootstrap .tablesorter-header.sorter-false i.tablesorter-icon{display:none}.tablesorter-bootstrap .tablesorter-header-inner{position:relative;padding:4px 18px 4px 4px}.tablesorter-bootstrap .sorter-false .tablesorter-header-inner{padding:4px}.tablesorter-bootstrap .tablesorter-header i.tablesorter-icon{position:absolute;right:2px;top:50%;margin-top:-7px;width:14px;height:14px;background-repeat:no-repeat;line-height:14px;display:inline-block}.tablesorter-bootstrap .bootstrap-icon-unsorted{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOCAYAAAD5YeaVAAABGUlEQVR4AZWQAUfEYBzGC07fILfrbnfgqG1jmxliDitmYIaxb9Y3CEIEVHDaUGMfYF8gIyBqbd7eH7wWofB6/J7nN+x/IIRQbz6fH8p3slgsrkl4uv8QNU071XX9wTAMQcLTD6bi2WazubUsq3ddV5AwPftU1tbr9Z0UPhGDIHgjYXp2JS+Xy71t2wNCFEV113UxCdOzKznLshvf9z+SJHlp23ZHR8L07Er+6/u/LO96td1u3zmX/BmdjoTp2ZUchmHted4o/16sVqt7KR6TMD27kpumOc/z/EkOvWmaQp7rlYTp2ZU8juOsqqqLoij2UvhyHEeQMD27knl93x+VZXmZpukz9yVh+l+vMQzDrK7rXRzHjyQ83b8BlglBGLw1Kb4AAAAASUVORK5CYII=)}.tablesorter-bootstrap .icon-white.bootstrap-icon-unsorted{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOCAYAAAD5YeaVAAAAe0lEQVR4AbXQoRWDMBiF0Sh2QLAAQ8SxJGugWSA6A2STW1PxTsnB9cnkfuYvv8OGC1t5G3Y0QMP+Bm857keAdQIzWBP3+Bw4MADQE18B6/etRnCV/w9nnGuLezfAmXhABGtAGIkruvk6auIFRwQJDywllsEAjCecB20GP59BQQ+gtlRLAAAAAElFTkSuQmCC)}.tablesorter-bootstrap tr.odd>td{background-color:#f9f9f9}.tablesorter-bootstrap tbody>.even:hover>td,.tablesorter-bootstrap tbody>.odd:hover>td,.tablesorter-bootstrap tbody>tr.hover>td{background-color:#f5f5f5}.tablesorter-bootstrap tbody>tr.even>td{background-color:#fff}.tablesorter-bootstrap .tablesorter-processing{background-image:url(data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=);position:absolute;z-index:1000}.tablesorter-bootstrap>tbody>tr.odd td.primary{background-color:#bfbfbf}.tablesorter-bootstrap>tbody>tr td.primary,.tablesorter-bootstrap>tbody>tr.even td.primary{background-color:#d9d9d9}.tablesorter-bootstrap>tbody>tr.odd td.secondary{background-color:#d9d9d9}.tablesorter-bootstrap>tbody>tr td.secondary,.tablesorter-bootstrap>tbody>tr.even td.secondary{background-color:#e6e6e6}.tablesorter-bootstrap>tbody>tr.odd td.tertiary{background-color:#e6e6e6}.tablesorter-bootstrap>tbody>tr td.tertiary,.tablesorter-bootstrap>tbody>tr.even td.tertiary{background-color:#f2f2f2}.tablesorter-bootstrap>caption{background-color:#fff}.tablesorter-bootstrap .tablesorter-filter-row input.tablesorter-filter,.tablesorter-bootstrap .tablesorter-filter-row select.tablesorter-filter{height:28px;width:98%;margin:0;padding:4px 6px;background-color:#fff;color:#333;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:height .1s ease;-moz-transition:height .1s ease;-o-transition:height .1s ease;transition:height .1s ease}.tablesorter-bootstrap .tablesorter-filter-row .tablesorter-filter.disabled{background-color:#eee;cursor:not-allowed}.tablesorter-bootstrap .tablesorter-filter-row{background-color:#ddd}.tablesorter-bootstrap .tablesorter-filter-row td{background-color:#eee;line-height:normal;text-align:center;padding:4px 6px;vertical-align:middle;-webkit-transition:line-height .1s ease;-moz-transition:line-height .1s ease;-o-transition:line-height .1s ease;transition:line-height .1s ease}.tablesorter-bootstrap tr.tablesorter-filter-row.hideme td{padding:2px;margin:0;line-height:0}.tablesorter-bootstrap tr.tablesorter-filter-row.hideme *{height:1px;min-height:0;border:0;padding:0;margin:0;opacity:0}.tablesorter .filtered{display:none}.tablesorter-bootstrap .tablesorter-pager select{padding:4px 6px}.tablesorter-bootstrap .tablesorter-pager .pagedisplay{border:0}.tablesorter .tablesorter-errorRow td{text-align:center;cursor:pointer;background-color:#e6bf99} \ No newline at end of file
diff --git a/web/_static/tablesorter/css/theme.bootstrap_3.min.css b/web/_static/tablesorter/css/theme.bootstrap_3.min.css
new file mode 100644
index 0000000..12734bd
--- /dev/null
+++ b/web/_static/tablesorter/css/theme.bootstrap_3.min.css
@@ -0,0 +1 @@
+.tablesorter-bootstrap{width:100%}.tablesorter-bootstrap tfoot td,.tablesorter-bootstrap tfoot th,.tablesorter-bootstrap thead td,.tablesorter-bootstrap thead th{font:14px/20px Arial,Sans-serif;font-weight:700;padding:4px;margin:0 0 18px;background-color:#eee}.tablesorter-bootstrap .tablesorter-header{cursor:pointer}.tablesorter-bootstrap .sorter-false{cursor:default}.tablesorter-bootstrap .tablesorter-header.sorter-false i.tablesorter-icon{display:none}.tablesorter-bootstrap .tablesorter-header-inner{position:relative;padding:4px 18px 4px 4px}.tablesorter-bootstrap .sorter-false .tablesorter-header-inner{padding:4px}.tablesorter-bootstrap .tablesorter-header i.tablesorter-icon{font-size:11px;position:absolute;right:2px;top:50%;margin-top:-7px;width:14px;height:14px;background-repeat:no-repeat;line-height:14px;display:inline-block}.tablesorter-bootstrap .bootstrap-icon-unsorted{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOCAYAAAD5YeaVAAAA20lEQVR4AWJABpKSkoxALCstLb0aUAsZaCAMhVEY6B0amx8YZWDDEDSBa2AGe7XeIiAAClYwVGBvsAcIllsf/mvcC9DgOOd8h90fxWvngVEUbZIkuWRZZlE8eQjcisgZMM9zi+LJ6ZfwegmWZflZDugdHMfxTcGqql7TNBlUB/QObtv2VBSFrev6OY7jngzFk9OT/fn73fWYpqnlXNyXDMWT0zuYx/Bvel9ej+LJ6R08DMOu67q7DkTkrSA5vYPneV71fX/QASdTkJwezhs0TfMARn0wMDDGXEPgF4oijqwM5YjNAAAAAElFTkSuQmCC)}.tablesorter-bootstrap .bootstrap-icon-white.bootstrap-icon-unsorted{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOCAYAAAD5YeaVAAAAe0lEQVR4AbXQoRWDMBiF0Sh2QLAAQ8SxJGugWSA6A2STW1PxTsnB9cnkfuYvv8OGC1t5G3Y0QMP+Bm857keAdQIzWBP3+Bw4MADQE18B6/etRnCV/w9nnGuLezfAmXhABGtAGIkruvk6auIFRwQJDywllsEAjCecB20GP59BQQ+gtlRLAAAAAElFTkSuQmCC)}.tablesorter-bootstrap>tbody>tr.odd>td,.tablesorter-bootstrap>tbody>tr.tablesorter-hasChildRow.odd:hover~tr.tablesorter-hasChildRow.odd~.tablesorter-childRow.odd>td{background-color:#f9f9f9}.tablesorter-bootstrap>tbody>tr.even:hover>td,.tablesorter-bootstrap>tbody>tr.hover>td,.tablesorter-bootstrap>tbody>tr.odd:hover>td,.tablesorter-bootstrap>tbody>tr.tablesorter-hasChildRow.even:hover~.tablesorter-childRow.even>td,.tablesorter-bootstrap>tbody>tr.tablesorter-hasChildRow.odd:hover~.tablesorter-childRow.odd>td{background-color:#f5f5f5}.tablesorter-bootstrap>tbody>tr.even>td,.tablesorter-bootstrap>tbody>tr.tablesorter-hasChildRow.even:hover~tr.tablesorter-hasChildRow.even~.tablesorter-childRow.even>td{background-color:#fff}.tablesorter-bootstrap .tablesorter-processing{background-image:url(data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=);background-position:center center!important;background-repeat:no-repeat!important}.tablesorter-bootstrap>tbody>tr.odd td.primary{background-color:#bfbfbf}.tablesorter-bootstrap>tbody>tr td.primary,.tablesorter-bootstrap>tbody>tr.even td.primary{background-color:#d9d9d9}.tablesorter-bootstrap>tbody>tr.odd td.secondary{background-color:#d9d9d9}.tablesorter-bootstrap>tbody>tr td.secondary,.tablesorter-bootstrap>tbody>tr.even td.secondary{background-color:#e6e6e6}.tablesorter-bootstrap>tbody>tr.odd td.tertiary{background-color:#e6e6e6}.tablesorter-bootstrap>tbody>tr td.tertiary,.tablesorter-bootstrap>tbody>tr.even td.tertiary{background-color:#f2f2f2}.tablesorter-bootstrap>.caption{background-color:#fff}.tablesorter-bootstrap .tablesorter-filter-row input.tablesorter-filter,.tablesorter-bootstrap .tablesorter-filter-row select.tablesorter-filter{width:98%;margin:0;padding:4px 6px;color:#333;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:height .1s ease;-moz-transition:height .1s ease;-o-transition:height .1s ease;transition:height .1s ease}.tablesorter-bootstrap .tablesorter-filter-row .tablesorter-filter.disabled{background-color:#eee;color:#555;cursor:not-allowed;border:1px solid #ccc;border-radius:4px;box-shadow:0 1px 1px rgba(0,0,0,.075) inset;box-sizing:border-box;transition:height .1s ease}.tablesorter-bootstrap .tablesorter-filter-row{background-color:#efefef}.tablesorter-bootstrap .tablesorter-filter-row td{background-color:#efefef;line-height:normal;text-align:center;padding:4px 6px;vertical-align:middle;-webkit-transition:line-height .1s ease;-moz-transition:line-height .1s ease;-o-transition:line-height .1s ease;transition:line-height .1s ease}.tablesorter-bootstrap .tablesorter-filter-row.hideme td{padding:2px;margin:0;line-height:0}.tablesorter-bootstrap .tablesorter-filter-row.hideme *{height:1px;min-height:0;border:0;padding:0;margin:0;opacity:0}.tablesorter .filtered{display:none}.tablesorter-bootstrap .tablesorter-pager select{padding:4px 6px}.tablesorter-bootstrap .tablesorter-pager .pagedisplay{border:0}.tablesorter-bootstrap tfoot i{font-size:11px}.tablesorter .tablesorter-errorRow td{text-align:center;cursor:pointer;background-color:#e6bf99} \ No newline at end of file
diff --git a/web/_static/tablesorter/css/theme.bootstrap_4.min.css b/web/_static/tablesorter/css/theme.bootstrap_4.min.css
new file mode 100644
index 0000000..3b91e8d
--- /dev/null
+++ b/web/_static/tablesorter/css/theme.bootstrap_4.min.css
@@ -0,0 +1 @@
+.tablesorter-bootstrap{width:100%}.tablesorter-bootstrap tfoot td,.tablesorter-bootstrap tfoot th,.tablesorter-bootstrap thead td,.tablesorter-bootstrap thead th{font:14px/20px Arial,Sans-serif;font-weight:700;padding:4px;margin:0 0 18px}.tablesorter-bootstrap thead .tablesorter-header{background-position:right 5px center;background-repeat:no-repeat;cursor:pointer;white-space:normal}.tablesorter-bootstrap:not(.table-dark) tfoot td,.tablesorter-bootstrap:not(.table-dark) tfoot th,.tablesorter-bootstrap:not(.table-dark) thead:not(.thead-dark) .tablesorter-header{background-color:#eee}.tablesorter-bootstrap thead .sorter-false{cursor:default;background-image:none}.tablesorter-bootstrap .tablesorter-header-inner{position:relative;padding:4px 18px 4px 4px}.tablesorter-bootstrap .sorter-false .tablesorter-header-inner{padding:4px}.tablesorter-bootstrap thead .tablesorter-headerUnSorted:not(.sorter-false){background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMiIgaGVpZ2h0PSIxNiIgdmlld0JveD0iMCAwIDE0IDIwIj48cGF0aCBkPSJNMTQgMTNsLTIuNS0yLjVMNyAxNWwtNC41LTQuNUwwIDEzbDcgN3pNMTQgNy41TDExLjUgMTAgNyA1LjUgMi41IDEwIDAgNy41bDctN3oiLz48L3N2Zz4=)}.tablesorter-bootstrap thead .tablesorter-headerAsc{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMiIgaGVpZ2h0PSIxMiIgdmlld0JveD0iMCAwIDE0IDE0Ij48cGF0aCBkPSJNMTQgOS41TDExLjUgMTIgNyA3LjUgMi41IDEyIDAgOS41bDctN3oiLz48L3N2Zz4=)}.tablesorter-bootstrap thead .tablesorter-headerDesc{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMiIgaGVpZ2h0PSIxMiIgdmlld0JveD0iMCAwIDE0IDE0Ij48cGF0aCBkPSJNMTQgNWwtMi41LTIuNS00LjUgNC41LTQuNS00LjVMMCA1IDcgMTJ6Ii8+PC9zdmc+)}.tablesorter-bootstrap thead.thead-dark .tablesorter-headerUnSorted:not(.sorter-false),.tablesorter-bootstrap.table-dark thead .tablesorter-headerUnSorted:not(.sorter-false){background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMiIgaGVpZ2h0PSIxNiIgdmlld0JveD0iMCAwIDE0IDIwIj48cGF0aCBmaWxsPSIjZmZmIiBkPSJNMTQgMTNsLTIuNS0yLjVMNyAxNWwtNC41LTQuNUwwIDEzbDcgN3pNMTQgNy41TDExLjUgMTAgNyA1LjUgMi41IDEwIDAgNy41bDctN3oiLz48L3N2Zz4=)}.tablesorter-bootstrap thead.thead-dark .tablesorter-headerAsc,.tablesorter-bootstrap.table-dark thead .tablesorter-headerAsc{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMiIgaGVpZ2h0PSIxMiIgdmlld0JveD0iMCAwIDE0IDE0Ij48cGF0aCBmaWxsPSIjZmZmIiBkPSJNMTQgOS41TDExLjUgMTIgNyA3LjUgMi41IDEyIDAgOS41bDctN3oiLz48L3N2Zz4=)}.tablesorter-bootstrap thead.thead-dark .tablesorter-headerDesc,.tablesorter-bootstrap.table-dark thead .tablesorter-headerDesc{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMiIgaGVpZ2h0PSIxMiIgdmlld0JveD0iMCAwIDE0IDE0Ij48cGF0aCBmaWxsPSIjZmZmIiBkPSJNMTQgNWwtMi41LTIuNS00LjUgNC41LTQuNS00LjVMMCA1IDcgMTJ6Ii8+PC9zdmc+)}.tablesorter-bootstrap:not(.table-dark)>tbody>tr.odd>td,.tablesorter-bootstrap:not(.table-dark)>tbody>tr.tablesorter-hasChildRow.odd:hover~tr.tablesorter-hasChildRow.odd~.tablesorter-childRow.odd>td{background-color:#f9f9f9}.tablesorter-bootstrap:not(.table-dark)>tbody>tr.even:hover>td,.tablesorter-bootstrap:not(.table-dark)>tbody>tr.hover>td,.tablesorter-bootstrap:not(.table-dark)>tbody>tr.odd:hover>td,.tablesorter-bootstrap:not(.table-dark)>tbody>tr.tablesorter-hasChildRow.even:hover~.tablesorter-childRow.even>td,.tablesorter-bootstrap:not(.table-dark)>tbody>tr.tablesorter-hasChildRow.odd:hover~.tablesorter-childRow.odd>td{background-color:#f5f5f5}.tablesorter-bootstrap:not(.table-dark)>tbody>tr.even>td,.tablesorter-bootstrap:not(.table-dark)>tbody>tr.tablesorter-hasChildRow.even:hover~tr.tablesorter-hasChildRow.even~.tablesorter-childRow.even>td{background-color:#fff}.tablesorter-bootstrap .tablesorter-processing{background-image:url(data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=);background-position:center center!important;background-repeat:no-repeat!important}.tablesorter-bootstrap:not(.table-dark)>tbody>tr.odd td.primary{background-color:#bfbfbf}.tablesorter-bootstrap:not(.table-dark)>tbody>tr td.primary,.tablesorter-bootstrap:not(.table-dark)>tbody>tr.even td.primary{background-color:#d9d9d9}.tablesorter-bootstrap:not(.table-dark)>tbody>tr.odd td.secondary{background-color:#d9d9d9}.tablesorter-bootstrap:not(.table-dark)>tbody>tr td.secondary,.tablesorter-bootstrap:not(.table-dark)>tbody>tr.even td.secondary{background-color:#e6e6e6}.tablesorter-bootstrap:not(.table-dark)>tbody>tr.odd td.tertiary{background-color:#e6e6e6}.tablesorter-bootstrap:not(.table-dark)>tbody>tr td.tertiary,.tablesorter-bootstrap:not(.table-dark)>tbody>tr.even td.tertiary{background-color:#f2f2f2}.tablesorter-bootstrap:not(.table-dark)>.caption{background-color:#fff}.tablesorter-bootstrap .tablesorter-filter-row input.tablesorter-filter,.tablesorter-bootstrap .tablesorter-filter-row select.tablesorter-filter{width:98%;margin:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:height .1s ease;-moz-transition:height .1s ease;-o-transition:height .1s ease;transition:height .1s ease}.tablesorter-bootstrap:not(.table-dark) .tablesorter-filter-row{background-color:#efefef}.tablesorter-bootstrap:not(.table-dark) .tablesorter-filter-row input.tablesorter-filter,.tablesorter-bootstrap:not(.table-dark) .tablesorter-filter-row select.tablesorter-filter{color:#333}.tablesorter-bootstrap .tablesorter-filter-row .tablesorter-filter.disabled{cursor:not-allowed;box-shadow:0 1px 1px rgba(0,0,0,.075) inset;box-sizing:border-box;transition:height .1s ease}.tablesorter-bootstrap:not(.table-dark) .tablesorter-filter-row td{line-height:normal;text-align:center;padding:4px 6px;vertical-align:middle;-webkit-transition:line-height .1s ease;-moz-transition:line-height .1s ease;-o-transition:line-height .1s ease;transition:line-height .1s ease}.tablesorter-bootstrap .tablesorter-filter-row.hideme td{padding:2px;margin:0;line-height:0}.tablesorter-bootstrap .tablesorter-filter-row.hideme *{height:1px;min-height:0;border:0;padding:0;margin:0;opacity:0}.tablesorter .filtered{display:none}.tablesorter-bootstrap .tablesorter-pager .pagedisplay{border:0}.tablesorter:not(.table-dark) .tablesorter-errorRow td{text-align:center;cursor:pointer;background-color:#e6bf99} \ No newline at end of file
diff --git a/web/_static/tablesorter/css/theme.dark.min.css b/web/_static/tablesorter/css/theme.dark.min.css
new file mode 100644
index 0000000..c065878
--- /dev/null
+++ b/web/_static/tablesorter/css/theme.dark.min.css
@@ -0,0 +1 @@
+.tablesorter-dark{width:100%;font:11px/18px Arial,Sans-serif;color:#ccc;text-align:left;background-color:#000;border-spacing:0}.tablesorter-dark th,.tablesorter-dark thead td{padding:4px;font:12px/20px Arial,Sans-serif;font-weight:700;color:#fff;background-color:#000;border-collapse:collapse}.tablesorter-dark thead th{border-bottom:#333 2px solid}.tablesorter-dark .header,.tablesorter-dark .tablesorter-header{padding:4px 20px 4px 4px;cursor:pointer;background-image:url(data:image/gif;base64,R0lGODlhFQAJAIAAAP///////yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==);background-position:center right;background-repeat:no-repeat}.tablesorter-dark thead .headerSortUp,.tablesorter-dark thead .tablesorter-headerAsc,.tablesorter-dark thead .tablesorter-headerSortUp{background-image:url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7);border-bottom:#888 1px solid}.tablesorter-dark thead .headerSortDown,.tablesorter-dark thead .tablesorter-headerDesc,.tablesorter-dark thead .tablesorter-headerSortDown{background-image:url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7);border-bottom:#888 1px solid}.tablesorter-dark thead .sorter-false{background-image:none;cursor:default;padding:4px}.tablesorter-dark tfoot .tablesorter-headerAsc,.tablesorter-dark tfoot .tablesorter-headerDesc,.tablesorter-dark tfoot .tablesorter-headerSortDown,.tablesorter-dark tfoot .tablesorter-headerSortUp{border-top:#888 1px solid;background-image:none}.tablesorter-dark td{padding:4px;background-color:#000;border-bottom:#333 1px solid;color:#ccc}.tablesorter-dark tbody>tr.even:hover>td,.tablesorter-dark tbody>tr.hover>td,.tablesorter-dark tbody>tr.odd:hover>td,.tablesorter-dark tbody>tr:hover>td{background-color:#000}.tablesorter-dark .tablesorter-processing{background-position:center center!important;background-repeat:no-repeat!important;background-image:url(data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=)!important}.tablesorter-dark tr.odd>td{background-color:#202020}.tablesorter-dark tr.even>td{background-color:#101010}.tablesorter-dark td.primary,.tablesorter-dark tr.odd td.primary{background-color:#0a0a0a}.tablesorter-dark tr.even td.primary{background-color:#050505}.tablesorter-dark td.secondary,.tablesorter-dark tr.odd td.secondary{background-color:#0f0f0f}.tablesorter-dark tr.even td.secondary{background-color:#0a0a0a}.tablesorter-dark td.tertiary,.tablesorter-dark tr.odd td.tertiary{background-color:#191919}.tablesorter-dark tr.even td.tertiary{background-color:#0f0f0f}.tablesorter-dark>caption{background-color:#202020}.tablesorter-dark .tablesorter-filter-row{background-color:#202020}.tablesorter-dark .tablesorter-filter-row td{background-color:#202020;line-height:normal;text-align:center;-webkit-transition:line-height .1s ease;-moz-transition:line-height .1s ease;-o-transition:line-height .1s ease;transition:line-height .1s ease}.tablesorter-dark .tablesorter-filter-row .disabled{opacity:.5;cursor:not-allowed}.tablesorter-dark .tablesorter-filter-row.hideme td{padding:2px;margin:0;line-height:0;cursor:pointer}.tablesorter-dark .tablesorter-filter-row.hideme *{height:1px;min-height:0;border:0;padding:0;margin:0;opacity:0}.tablesorter-dark input.tablesorter-filter,.tablesorter-dark select.tablesorter-filter{width:98%;height:auto;margin:0;padding:4px;background-color:#111;border:1px solid #222;color:#ddd;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:height .1s ease;-moz-transition:height .1s ease;-o-transition:height .1s ease;transition:height .1s ease}.tablesorter .filtered{display:none}.tablesorter .tablesorter-errorRow td{text-align:center;cursor:pointer;background-color:#e6bf99} \ No newline at end of file
diff --git a/web/_static/tablesorter/css/theme.default.min.css b/web/_static/tablesorter/css/theme.default.min.css
new file mode 100644
index 0000000..78f2f73
--- /dev/null
+++ b/web/_static/tablesorter/css/theme.default.min.css
@@ -0,0 +1 @@
+.tablesorter-default{width:100%;font:12px/18px Arial,Sans-serif;color:#333;background-color:#fff;border-spacing:0;margin:10px 0 15px;text-align:left}.tablesorter-default th,.tablesorter-default thead td{font-weight:700;color:#000;background-color:#fff;border-collapse:collapse;border-bottom:#ccc 2px solid;padding:0}.tablesorter-default tfoot td,.tablesorter-default tfoot th{border:0}.tablesorter-default .header,.tablesorter-default .tablesorter-header{background-image:url(data:image/gif;base64,R0lGODlhFQAJAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==);background-position:center right;background-repeat:no-repeat;cursor:pointer;white-space:normal;padding:4px 20px 4px 4px}.tablesorter-default thead .headerSortUp,.tablesorter-default thead .tablesorter-headerAsc,.tablesorter-default thead .tablesorter-headerSortUp{background-image:url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7);border-bottom:#000 2px solid}.tablesorter-default thead .headerSortDown,.tablesorter-default thead .tablesorter-headerDesc,.tablesorter-default thead .tablesorter-headerSortDown{background-image:url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7);border-bottom:#000 2px solid}.tablesorter-default thead .sorter-false{background-image:none;cursor:default;padding:4px}.tablesorter-default tfoot .tablesorter-headerAsc,.tablesorter-default tfoot .tablesorter-headerDesc,.tablesorter-default tfoot .tablesorter-headerSortDown,.tablesorter-default tfoot .tablesorter-headerSortUp{border-top:#000 2px solid}.tablesorter-default td{background-color:#fff;border-bottom:#ccc 1px solid;padding:4px;vertical-align:top}.tablesorter-default tbody>tr.even:hover>td,.tablesorter-default tbody>tr.hover>td,.tablesorter-default tbody>tr.odd:hover>td,.tablesorter-default tbody>tr:hover>td{background-color:#fff;color:#000}.tablesorter-default .tablesorter-processing{background-position:center center!important;background-repeat:no-repeat!important;background-image:url(data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=)!important}.tablesorter-default tr.odd>td{background-color:#dfdfdf}.tablesorter-default tr.even>td{background-color:#efefef}.tablesorter-default tr.odd td.primary{background-color:#bfbfbf}.tablesorter-default td.primary,.tablesorter-default tr.even td.primary{background-color:#d9d9d9}.tablesorter-default tr.odd td.secondary{background-color:#d9d9d9}.tablesorter-default td.secondary,.tablesorter-default tr.even td.secondary{background-color:#e6e6e6}.tablesorter-default tr.odd td.tertiary{background-color:#e6e6e6}.tablesorter-default td.tertiary,.tablesorter-default tr.even td.tertiary{background-color:#f2f2f2}.tablesorter-default>caption{background-color:#fff}.tablesorter-default .tablesorter-filter-row{background-color:#eee}.tablesorter-default .tablesorter-filter-row td{background-color:#eee;border-bottom:#ccc 1px solid;line-height:normal;text-align:center;-webkit-transition:line-height .1s ease;-moz-transition:line-height .1s ease;-o-transition:line-height .1s ease;transition:line-height .1s ease}.tablesorter-default .tablesorter-filter-row .disabled{opacity:.5;cursor:not-allowed}.tablesorter-default .tablesorter-filter-row.hideme td{padding:2px;margin:0;line-height:0;cursor:pointer}.tablesorter-default .tablesorter-filter-row.hideme *{height:1px;min-height:0;border:0;padding:0;margin:0;opacity:0}.tablesorter-default input.tablesorter-filter,.tablesorter-default select.tablesorter-filter{width:95%;height:auto;margin:4px auto;padding:4px;background-color:#fff;border:1px solid #bbb;color:#333;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:height .1s ease;-moz-transition:height .1s ease;-o-transition:height .1s ease;transition:height .1s ease}.tablesorter .filtered{display:none}.tablesorter .tablesorter-errorRow td{text-align:center;cursor:pointer;background-color:#e6bf99} \ No newline at end of file
diff --git a/web/_static/tablesorter/css/theme.dropbox.min.css b/web/_static/tablesorter/css/theme.dropbox.min.css
new file mode 100644
index 0000000..04e05fe
--- /dev/null
+++ b/web/_static/tablesorter/css/theme.dropbox.min.css
@@ -0,0 +1 @@
+.tablesorter-dropbox{width:100%;font:13px/32px "Open Sans","lucida grande","Segoe UI",arial,verdana,"lucida sans unicode",tahoma,sans-serif;color:#555;text-align:left;background-color:#fff;border-collapse:collapse;border-top:1px solid #82cffa;border-spacing:0}.tablesorter-dropbox tfoot td,.tablesorter-dropbox tfoot th,.tablesorter-dropbox th,.tablesorter-dropbox thead td{background-color:#f0f9ff;border-color:#82cffa #e7f2fb #96c4ea;border-style:solid;border-width:1px;padding:3px 6px;font-size:13px;font-weight:400;line-height:29px;color:#2281cf;text-align:left}.tablesorter-dropbox .header,.tablesorter-dropbox .tablesorter-headerRow,.tablesorter-dropbox thead tr{background-color:#f0f9ff;border-bottom:1px solid #96c4ea;box-shadow:0 1px 1px rgba(0,0,0,.12),0 0 0 #000 inset;white-space:normal}.tablesorter-dropbox .tablesorter-headerAsc,.tablesorter-dropbox .tablesorter-headerDesc,.tablesorter-dropbox .tablesorter-headerSortDown,.tablesorter-dropbox .tablesorter-headerSortUp{font-weight:600}.tablesorter-dropbox .tablesorter-header{cursor:pointer}.tablesorter-dropbox .tablesorter-header i.tablesorter-icon{width:9px;height:9px;padding:0 10px 0 4px;display:inline-block;background-position:center right;background-repeat:no-repeat;content:""}.tablesorter-dropbox .tablesorter-headerAsc i.tablesorter-icon,.tablesorter-dropbox .tablesorter-headerSortUp i.tablesorter-icon{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAALhJREFUeNpi/P//PwMhwILMiexYx8bIxNTy/9+/muUVQb9g4kzIitg4edI4+YRLQTSyOCPMupjerUI8whK3OXgEhH58+fDuy9sXqkuKvd+hmMTOxdvCxS8sxMUvxACiQXwU6+Im7DDg5BNKY+fiY2BmYWMA0SA+SByuiJ2bbzIHrwAzMxsb0AGMDCAaxAeJg+SZ7wtaqfAISfQAdTIwMUM8ywhUyMTEzPD/71+5FXvPLWUkJpwAAgwAZqYvvHStbD4AAAAASUVORK5CYII=)}.tablesorter-dropbox .tablesorter-headerAsc:hover i.tablesorter-icon,.tablesorter-dropbox .tablesorter-headerSortUp:hover i.tablesorter-icon{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAALVJREFUeNpi/P//PwMhwILMCc+qZGNkYmr5/+9fzcpp7b9g4kzIitjYOdM4uXlLQTSyOCPMuqi8OiEefsHbHFzcQj++fX335eN71WWTmt6hmMTOwdXCycMnBDSJAUSD+CjWxRQ0GHBw86Sxc3AyMDOzMIBoEB8kDlfEzsk1mYOLByjPCnQAIwOIBvFB4iB55rsfmVS4+QV7QNYwMTNDHApUyMTExPDv/z+5Feu3L2UkJpwAAgwA244u+I9CleAAAAAASUVORK5CYII=)}.tablesorter-dropbox .tablesorter-headerDesc i.tablesorter-icon,.tablesorter-dropbox .tablesorter-headerSortDown i.tablesorter-icon{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAALdJREFUeNpi/P//PwMhwBLdtVGFhZ3zNhMzC4bkv79/GP78/K7KCDIpZ9mVw+xcfDaMTExwBf///WP4+e3TkSlROrZg7UxMLLns3HxnmFnZmGGK/v7+9ff3j2+5YHkQMSlC48Kv719m/f//D2IKkAbxQeJwRSDw4/OHmr+/fr0DqmAA0SA+TA6uaEq0zjugG+r//vkFcks9iA/3HbJvvn18O+vf379yP758mMXAoAAXZyQmnAACDADX316BiTFbMQAAAABJRU5ErkJggg==)}.tablesorter-dropbox .tablesorter-headerDesc:hover i.tablesorter-icon,.tablesorter-dropbox .tablesorter-headerSortDown:hover i.tablesorter-icon{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAALNJREFUeNpi/P//PwMhwBJf3uP879e3PUzMzBiS//7+ZWBi43JhBJmU2z7nIzMzEx8jIyNcAUj8799/nyZXpvCzgARYuXjTWBkZVjCzIEz7++cvw+//DGkgNiPMTWVT1l5hZvynDTINbMp/pqtdOcE6IDkmmM5fv3/5//v37z9QBQOIBvFhcnBFEwoj7/5jZFnz9+8fBhAN4sN9h+ybH9++JrGxscr/+vE1CVmckZhwAggwANvlUyq5Dd1wAAAAAElFTkSuQmCC)}.tablesorter-dropbox thead .sorter-false{cursor:default}.tablesorter-dropbox thead .sorter-false i.tablesorter-icon{display:none}.tablesorter-dropbox td{padding:5px 6px;line-height:32px;color:#555;text-align:left;border-top:1px solid #edf1f5;border-bottom:1px solid #edf1f5}.tablesorter-dropbox tbody>tr.even:hover>td,.tablesorter-dropbox tbody>tr.hover>td,.tablesorter-dropbox tbody>tr.odd:hover>td,.tablesorter-dropbox tbody>tr:hover>td{background-color:rgba(230,245,255,.3);border-right:0;border-left:0;border-color:#c6d8e4;border-style:double}.tablesorter-dropbox .tablesorter-processing{background-position:center center!important;background-repeat:no-repeat!important;background-image:url(data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=)!important}.tablesorter-dropbox>caption{background-color:#fff}.tablesorter-dropbox .tablesorter-filter-row{background-color:#fff}.tablesorter-dropbox .tablesorter-filter-row td{background-color:#fff;line-height:normal;text-align:center;-webkit-transition:line-height .1s ease;-moz-transition:line-height .1s ease;-o-transition:line-height .1s ease;transition:line-height .1s ease}.tablesorter-dropbox .tablesorter-filter-row .disabled{opacity:.5;cursor:not-allowed}.tablesorter-dropbox .tablesorter-filter-row.hideme td{padding:2px;margin:0;line-height:0;cursor:pointer}.tablesorter-dropbox .tablesorter-filter-row.hideme *{height:1px;min-height:0;border:0;padding:0;margin:0;opacity:0}.tablesorter-dropbox input.tablesorter-filter,.tablesorter-dropbox select.tablesorter-filter{width:98%;height:auto;margin:0;background-color:#fff;border:1px solid #bbb;color:#333;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:height .1s ease;-moz-transition:height .1s ease;-o-transition:height .1s ease;transition:height .1s ease}.tablesorter .filtered{display:none}.tablesorter .tablesorter-errorRow td{text-align:center;cursor:pointer;background-color:#e6bf99} \ No newline at end of file
diff --git a/web/_static/tablesorter/css/theme.green.min.css b/web/_static/tablesorter/css/theme.green.min.css
new file mode 100644
index 0000000..b5d17ea
--- /dev/null
+++ b/web/_static/tablesorter/css/theme.green.min.css
@@ -0,0 +1 @@
+.tablesorter-green{width:100%;text-align:left;border-spacing:0;border:#cdcdcd 1px solid;border-width:1px 0 0 1px}.tablesorter-green td,.tablesorter-green th{font:12px/18px Arial,Sans-serif;border:#cdcdcd 1px solid;border-width:0 1px 1px 0}.tablesorter-green tfoot tr,.tablesorter-green thead tr .tablesorter-header{background-position:center center;background-repeat:repeat-x;background-image:url(data:image/gif;base64,R0lGODlhAQBkAOYAAN/e39XU1fX19tTU1eXm5uTl5ePk5OLj4+Hi4vX29fT19PP08/Lz8vHy8fDx8O/w7+7v7uzt7Orr6ufo5/T08/Pz8ufn5uLi4eDg39/f3t3d3Nzc29HR0NDQz8/Pzuvq6urp6eno6Ojn5+fm5tfW1tbV1dTT09PS0tLR0dHQ0NDPz/f39/b29vX19fT09PPz8/Ly8vHx8e/v7+7u7u3t7ezs7Ovr6+rq6unp6ejo6Ofn5+bm5uXl5eTk5OPj4+Li4uHh4eDg4N/f397e3t3d3dzc3Nvb29ra2tnZ2djY2NfX19XV1dPT09LS0tHR0dDQ0M/Pz8rKysXFxf///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAFMALAAAAAABAGQAAAdegCsrLC0tLi+ILi6FCSwsCS0KkhQVDA0OMjM0NTYfICEiIzw9P0AYGUQaG0ZHSEoDTU9Qs08pTk1MSyRJR0VDQT8+PTw7Ojg3NTMyMTAvi4WOhC0vMTI1OT9GTlFSgQA7)}.tablesorter-green th,.tablesorter-green thead td{font-weight:700;border-right:#cdcdcd 1px solid;border-collapse:collapse;padding:6px}.tablesorter-green .header,.tablesorter-green .tablesorter-header-inner{background-position:5px center;background-repeat:no-repeat;background-image:url(data:image/gif;base64,R0lGODlhEAAQAOYAAA5NDBBYDlWWUzRUM5DVjp7inJ/fnQ1ECiCsGhyYFxqKFRFdDhBXDQxCCiO8HSK2HCCqGh2aGByUFxuPFhqNFhmHFRZ2EhVvERRpEBBVDSS8HiGyHB+mGh6fGRuTFxiAFBd5Eww/Cgs5CRp7Fiu+JRx8GCy/JjHAKyynKCuhJzXCMDbCMDnDMyNuHz3EODy9N0LFPSl7JkvIRjycOFDKS1LKTVPLT1XLUFTCT17OWTBkLmbQYnDTbHXVcXnWdoXago/djGmUZ112XCJEIEdjRf///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAEUALAAAAAAQABAAAAdlgEWCg4SFhoIvh4cVLECKhCMeJjwFj0UlEwgaMD4Gii0WFAkRHQ47BIY6IQAZDAwBCyAPOJa1toRBGBAwNTY3OT0/AoZCDQoOKi4yNDOKRCIfGycrKZYDBxIkKLZDFxy3RTHgloEAOw==);border-collapse:collapse;white-space:normal;cursor:pointer}.tablesorter-green thead .headerSortUp .tablesorter-header-inner,.tablesorter-green thead .tablesorter-headerAsc .tablesorter-header-inner,.tablesorter-green thead .tablesorter-headerSortUp .tablesorter-header-inner{background-image:url(data:image/gif;base64,R0lGODlhEAAQANUAAA5NDBBYDpDVjp7inJ/fnSCsGhyYFxFdDhBXDSO8HSK2HB2aGBuPFhqNFhmHFRZ2EhBVDSS8Hh6fGRuTFxd5Eww/Chp7Fhx8GCy/JjnDMyNuHzy9N0LFPVTCTzBkLmbQYnDTbHnWdo/djP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAACMALAAAAAAQABAAAAY4wJFwSCwaj8ikcslMbpojR0bEtEwwoIHywihEOCECUvNoGBaSxEdg9FQAEAQicKAoOtC8fs8fBgEAOw==)}.tablesorter-green thead .headerSortDown .tablesorter-header-inner,.tablesorter-green thead .tablesorter-headerDesc .tablesorter-header-inner,.tablesorter-green thead .tablesorter-headerSortDown .tablesorter-header-inner{background-image:url(data:image/gif;base64,R0lGODlhEAAQANUAAFWWUzRUMw1EChqKFQxCCiO8HSCqGhyUFxVvERRpECGyHB+mGhiAFAs5CSu+JTHAKyynKCuhJzXCMDbCMD3EOELFPSl7JkvIRjycOFDKS1LKTVPLT1XLUF7OWXXVcYXagmmUZ112XCJEIEdjRf///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAACQALAAAAAAQABAAAAY4QJJwSCwaj8ikcskkghKGimbD6Xg+AGOIMChIKJcMBjlqMBSPSUQZEBwcEKYIsWiSLPa8fs9HBgEAOw==)}.tablesorter-green td.tablesorter-header .tablesorter-header-inner,.tablesorter-green th.tablesorter-header .tablesorter-header-inner{padding-left:23px}.tablesorter-green thead .tablesorter-header.sorter-false .tablesorter-header-inner{background-image:none;cursor:default;padding-left:6px}.tablesorter-green tbody td,.tablesorter-green tfoot th{padding:6px;vertical-align:top}.tablesorter-green td{color:#3d3d3d;padding:6px}.tablesorter-green tbody>tr.even.hover>td,.tablesorter-green tbody>tr.even:hover+tr.tablesorter-childRow+tr.tablesorter-childRow>td,.tablesorter-green tbody>tr.even:hover+tr.tablesorter-childRow>td,.tablesorter-green tbody>tr.even:hover>td,.tablesorter-green tbody>tr.hover>td,.tablesorter-green tbody>tr:hover+tr.tablesorter-childRow+tr.tablesorter-childRow>td,.tablesorter-green tbody>tr:hover+tr.tablesorter-childRow>td,.tablesorter-green tbody>tr:hover>td{background-color:#d9d9d9}.tablesorter-green tbody>tr.odd.hover>td,.tablesorter-green tbody>tr.odd:hover+tr.tablesorter-childRow+tr.tablesorter-childRow>td,.tablesorter-green tbody>tr.odd:hover+tr.tablesorter-childRow>td,.tablesorter-green tbody>tr.odd:hover>td{background-color:#bfbfbf}.tablesorter-green .tablesorter-processing{background-position:center center!important;background-repeat:no-repeat!important;background-image:url(data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=)!important}.tablesorter-green tr.odd>td{background-color:#ebfaeb}.tablesorter-green tr.even>td{background-color:#fff}.tablesorter-green td.primary,.tablesorter-green tr.odd td.primary{background-color:#99e6a6}.tablesorter-green tr.even td.primary{background-color:#c2f0c9}.tablesorter-green td.secondary,.tablesorter-green tr.odd td.secondary{background-color:#c2f0c9}.tablesorter-green tr.even td.secondary{background-color:#d6f5db}.tablesorter-green td.tertiary,.tablesorter-green tr.odd td.tertiary{background-color:#d6f5db}.tablesorter-green tr.even td.tertiary{background-color:#ebfaed}.tablesorter-green>caption{background-color:#fff}.tablesorter-green .tablesorter-filter-row{background-color:#eee}.tablesorter-green .tablesorter-filter-row td{background-color:#eee;line-height:normal;text-align:center;-webkit-transition:line-height .1s ease;-moz-transition:line-height .1s ease;-o-transition:line-height .1s ease;transition:line-height .1s ease}.tablesorter-green .tablesorter-filter-row .disabled{opacity:.5;cursor:not-allowed}.tablesorter-green .tablesorter-filter-row.hideme td{padding:2px;margin:0;line-height:0;cursor:pointer}.tablesorter-green .tablesorter-filter-row.hideme *{height:1px;min-height:0;border:0;padding:0;margin:0;opacity:0}.tablesorter-green input.tablesorter-filter,.tablesorter-green select.tablesorter-filter{width:98%;height:auto;margin:0;padding:4px;background-color:#fff;border:1px solid #bbb;color:#333;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:height .1s ease;-moz-transition:height .1s ease;-o-transition:height .1s ease;transition:height .1s ease}.tablesorter .filtered{display:none}.tablesorter .tablesorter-errorRow td{text-align:center;cursor:pointer;background-color:#e6bf99} \ No newline at end of file
diff --git a/web/_static/tablesorter/css/theme.grey.min.css b/web/_static/tablesorter/css/theme.grey.min.css
new file mode 100644
index 0000000..18ec538
--- /dev/null
+++ b/web/_static/tablesorter/css/theme.grey.min.css
@@ -0,0 +1 @@
+.tablesorter-grey{width:100%;margin:10px 0 15px;text-align:left;border-spacing:0;border-left:#555 1px solid}.tablesorter-grey th,.tablesorter-grey thead td{font:bold 12px/18px Arial,Sans-serif;color:#c8c8c8;background-color:#3c3c3c;background-image:-moz-linear-gradient(top,#555,#3c3c3c);background-image:-ms-linear-gradient(top,#555,#3c3c3c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#555),to(#3c3c3c));background-image:-webkit-linear-gradient(top,#555,#3c3c3c);background-image:-o-linear-gradient(top,#555,#3c3c3c);background-image:linear-gradient(to bottom,#555,#3c3c3c);background-repeat:repeat-x;border-right:#555 1px solid;text-shadow:0 1px 0 rgba(128,128,128,.7);-webkit-box-shadow:inset 0 1px 0 #222;-moz-box-shadow:inset 0 1px 0 #222;box-shadow:inset 0 1px 0 #222;padding:4px}.tablesorter-grey .tablesorter-header-inner{position:relative;padding:4px 15px 4px 4px}.tablesorter-grey .header,.tablesorter-grey .tablesorter-header{cursor:pointer}.tablesorter-grey .header i,.tablesorter-grey .tablesorter-header i.tablesorter-icon{width:18px;height:10px;position:absolute;right:2px;top:50%;margin-top:-10px;background-image:url(data:image/gif;base64,R0lGODlhFQAJAIAAAP///////yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==);background-repeat:no-repeat;background-position:center right;padding:4px;white-space:normal}.tablesorter-grey th.headerSortDown,.tablesorter-grey th.headerSortUp,.tablesorter-grey th.tablesorter-headerSortDown,.tablesorter-grey th.tablesorter-headerSortUp{color:#ddd;background-color:#135185;background-image:-moz-linear-gradient(top,#195c93,#0e4776);background-image:-ms-linear-gradient(top,#195c93,#0e4776);background-image:-webkit-gradient(linear,0 0,0 100%,from(#195c93),to(#0e4776));background-image:-webkit-linear-gradient(top,#195c93,#0e4776);background-image:-o-linear-gradient(top,#195c93,#0e4776);background-image:linear-gradient(to bottom,#195c93,#0e4776)}.tablesorter-grey .headerSortUp i.tablesorter-icon,.tablesorter-grey .tablesorter-headerAsc i.tablesorter-icon,.tablesorter-grey .tablesorter-headerSortUp i.tablesorter-icon{background-image:url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7)}.tablesorter-grey .headerSortDown i.tablesorter-icon,.tablesorter-grey .tablesorter-headerDesc i.tablesorter-icon,.tablesorter-grey .tablesorter-headerSortDown i.tablesorter-icon{background-image:url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7)}.tablesorter-grey thead .sorter-false{cursor:default}.tablesorter-grey thead .sorter-false i.tablesorter-icon{display:none}.tablesorter-grey tbody td,.tablesorter-grey tfoot td,.tablesorter-grey tfoot th{padding:4px;vertical-align:top;border-right:#555 1px solid}.tablesorter-grey tfoot td,.tablesorter-grey tfoot th{padding:8px}.tablesorter-grey td{color:#eee;background-color:#6d6d6d;padding:4px;vertical-align:top}.tablesorter-grey tbody>tr.even.hover>td,.tablesorter-grey tbody>tr.even:hover+tr.tablesorter-childRow+tr.tablesorter-childRow>td,.tablesorter-grey tbody>tr.even:hover+tr.tablesorter-childRow>td,.tablesorter-grey tbody>tr.even:hover>td,.tablesorter-grey tbody>tr.hover>td,.tablesorter-grey tbody>tr:hover+tr.tablesorter-childRow+tr.tablesorter-childRow>td,.tablesorter-grey tbody>tr:hover+tr.tablesorter-childRow>td,.tablesorter-grey tbody>tr:hover>td{background-color:#134b78}.tablesorter-grey tbody>tr.odd.hover>td,.tablesorter-grey tbody>tr.odd:hover+tr.tablesorter-childRow+tr.tablesorter-childRow>td,.tablesorter-grey tbody>tr.odd:hover+tr.tablesorter-childRow>td,.tablesorter-grey tbody>tr.odd:hover>td{background-color:#134b78}.tablesorter-grey .tablesorter-processing{background-position:center center!important;background-repeat:no-repeat!important;background-image:url(data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=)!important}.tablesorter-grey tbody tr.odd>td{background-color:#5e5e5e}.tablesorter-grey tbody tr.even>td{background-color:#6d6d6d}.tablesorter-grey td.primary,.tablesorter-grey tr.odd td.primary{color:#ddd;background-color:#165388}.tablesorter-grey tr.even td.primary{color:#ddd;background-color:#195c93}.tablesorter-grey td.secondary,.tablesorter-grey tr.odd td.secondary{color:#ddd;background-color:#185c9a}.tablesorter-grey tr.even td.secondary{color:#ddd;background-color:#1d67a5}.tablesorter-grey td.tertiary,.tablesorter-grey tr.odd td.tertiary{color:#ddd;background-color:#1b67ad}.tablesorter-grey tr.even td.tertiary{color:#ddd;background-color:#2073b7}.tablesorter-grey>caption{background-color:#fff}.tablesorter-grey .tablesorter-filter-row{background-color:#3c3c3c}.tablesorter-grey .tablesorter-filter-row td{background-color:#3c3c3c;line-height:normal;text-align:center;-webkit-transition:line-height .1s ease;-moz-transition:line-height .1s ease;-o-transition:line-height .1s ease;transition:line-height .1s ease}.tablesorter-grey .tablesorter-filter-row .disabled{opacity:.5;cursor:not-allowed}.tablesorter-grey .tablesorter-filter-row.hideme td{padding:2px;margin:0;line-height:0;cursor:pointer}.tablesorter-grey .tablesorter-filter-row.hideme *{height:1px;min-height:0;border:0;padding:0;margin:0;opacity:0}.tablesorter-grey input.tablesorter-filter,.tablesorter-grey select.tablesorter-filter{width:98%;height:auto;margin:0;padding:4px;background-color:#6d6d6d;border:1px solid #555;color:#ddd;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:height .1s ease;-moz-transition:height .1s ease;-o-transition:height .1s ease;transition:height .1s ease}.tablesorter .filtered{display:none}.tablesorter .tablesorter-errorRow td{text-align:center;cursor:pointer;background-color:#e6bf99} \ No newline at end of file
diff --git a/web/_static/tablesorter/css/theme.ice.min.css b/web/_static/tablesorter/css/theme.ice.min.css
new file mode 100644
index 0000000..490ad25
--- /dev/null
+++ b/web/_static/tablesorter/css/theme.ice.min.css
@@ -0,0 +1 @@
+.tablesorter-ice{width:100%;background-color:#fff;margin:10px 0 15px;text-align:left;border-spacing:0;border:#ccc 1px solid;border-width:1px 0 0 1px}.tablesorter-ice td,.tablesorter-ice th{border:#ccc 1px solid;border-width:0 1px 1px 0}.tablesorter-ice th,.tablesorter-ice thead td{font:12px/18px Arial,Sans-serif;color:#555;background-color:#f6f8f9;border-collapse:collapse;padding:4px;text-shadow:0 1px 0 rgba(255,255,255,.7)}.tablesorter-ice tbody td,.tablesorter-ice tfoot td,.tablesorter-ice tfoot th{padding:4px;vertical-align:top}.tablesorter-ice .header,.tablesorter-ice .tablesorter-header{background-color:#f6f8f9;background-position:center right;background-repeat:no-repeat;background-image:url(data:image/gif;base64,R0lGODlhDAAMAMQAAAJEjAJCiwJBigJAiANFjgNGjgNEjQRIkQRHkANIkAVMlAVQmAZWnQZUnAdYoAhdpAhZoAlhqQlepQliqQppsApmrQxutgtutQtutAxwtwxwtg1yug1zugxtsw1yuP8A/yH5BAEAAB8ALAAAAAAMAAwAAAUx4Cd+3GiOW4ado2d9VMVm1xg9ptadTsP+QNZEcjoQTBDGCAFgLRSfQgCYMAiCn8EvBAA7);padding:4px 20px 4px 4px;white-space:normal;cursor:pointer}.tablesorter-ice .headerSortUp,.tablesorter-ice .tablesorter-headerAsc,.tablesorter-ice .tablesorter-headerSortUp{color:#333;background-color:#ebedee;background-position:center right;background-repeat:no-repeat;background-image:url(data:image/gif;base64,R0lGODlhDAAMANUAAAJCiwNHkANFjgNEjQRIkQNJkQRMlARKkwRKkgVPlwZSmgdaogdYnwhfpghcowlhqgliqglgqAlgpwljqwporwpmrQplrAtsswtqsgtrsgtqsQxttAtvtQtttAxyuQxwtwxxtwxvtg10uw1zuQ1xuP8A/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAACUALAAAAAAMAAwAAAY6wJKwJBoahyNQ6Dj0fDoZCpPEuWgqk4jxs8FQLI+Gg8Esm5kQydFQMC7IwkOAqUiUCAIzIjA4lwBlQQA7)}.tablesorter-ice .headerSortDown,.tablesorter-ice .tablesorter-headerDesc,.tablesorter-ice .tablesorter-headerSortDown{color:#333;background-color:#ebedee;background-position:center right;background-repeat:no-repeat;background-image:url(data:image/gif;base64,R0lGODlhDAAMANUAAAE/iAJBigNFjgNEjQNFjQNDiwRHkQRHjwNHjwROlgRMlQRMlARJkgRKkgZQmAVPlgZWnQZSmgZRmAdXoAdXnwdUnAdbogdZoQhbowlhqAlepglkrAliqQtstAtqsQxyugxyuQxwuAxxuAxxtwxwtgxvtQ10vA12vA10u/8A/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAACkALAAAAAAMAAwAAAY6wJQwdRoah6bP6DhEiVIdDxNEGm4yxlDpiJkwv2AmR2OhVCSJBsJ4gUQeCwOB6VAwBAXwYRAIpwBfQQA7)}.tablesorter-ice thead .sorter-false{background-image:none;cursor:default;padding:4px}.tablesorter-ice tfoot .tablesorter-headerAsc,.tablesorter-ice tfoot .tablesorter-headerDesc,.tablesorter-ice tfoot .tablesorter-headerSortDown,.tablesorter-ice tfoot .tablesorter-headerSortUp{background-color:#ebedee}.tablesorter-ice td{color:#333}.tablesorter-ice tbody>tr.even:hover>td,.tablesorter-ice tbody>tr.hover>td,.tablesorter-ice tbody>tr.odd:hover>td,.tablesorter-ice tbody>tr:hover>td{background-color:#ebf2fa}.tablesorter-ice .tablesorter-processing{background-position:center center!important;background-repeat:no-repeat!important;background-image:url(data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=)!important}.tablesorter-ice tr.odd>td{background-color:#dfdfdf}.tablesorter-ice tr.even>td{background-color:#efefef}.tablesorter-ice td.primary,.tablesorter-ice tr.odd td.primary{background-color:#9ae5e5}.tablesorter-ice tr.even td.primary{background-color:#c2f0f0}.tablesorter-ice td.secondary,.tablesorter-ice tr.odd td.secondary{background-color:#c2f0f0}.tablesorter-ice tr.even td.secondary{background-color:#d5f5f5}.tablesorter-ice td.tertiary,.tablesorter-ice tr.odd td.tertiary{background-color:#d5f5f5}.tablesorter-ice tr.even td.tertiary{background-color:#ebfafa}.tablesorter-ice.containsStickyHeaders thead tr:nth-child(1) td,.tablesorter-ice.containsStickyHeaders thead tr:nth-child(1) th{border-top:#ccc 1px solid}.tablesorter-ice>caption{background-color:#fff}.tablesorter-ice .tablesorter-filter-row{background-color:#eee}.tablesorter-ice .tablesorter-filter-row td{background-color:#eee;line-height:normal;text-align:center;-webkit-transition:line-height .1s ease;-moz-transition:line-height .1s ease;-o-transition:line-height .1s ease;transition:line-height .1s ease}.tablesorter-ice .tablesorter-filter-row .disabled{opacity:.5;cursor:not-allowed}.tablesorter-ice .tablesorter-filter-row.hideme td{padding:2px;margin:0;line-height:0;cursor:pointer}.tablesorter-ice .tablesorter-filter-row.hideme *{height:1px;min-height:0;border:0;padding:0;margin:0;opacity:0}.tablesorter-ice input.tablesorter-filter,.tablesorter-ice select.tablesorter-filter{width:98%;height:auto;margin:0;padding:4px;background-color:#fff;border:1px solid #bbb;color:#333;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:height .1s ease;-moz-transition:height .1s ease;-o-transition:height .1s ease;transition:height .1s ease}.tablesorter .filtered{display:none}.tablesorter .tablesorter-errorRow td{text-align:center;cursor:pointer;background-color:#e6bf99} \ No newline at end of file
diff --git a/web/_static/tablesorter/css/theme.jui.min.css b/web/_static/tablesorter/css/theme.jui.min.css
new file mode 100644
index 0000000..4b67422
--- /dev/null
+++ b/web/_static/tablesorter/css/theme.jui.min.css
@@ -0,0 +1 @@
+.tablesorter-jui{width:100%;border-collapse:separate;border-spacing:2px;margin:10px 0 15px;padding:5px;font-size:.8em}.tablesorter-jui tfoot td,.tablesorter-jui tfoot th,.tablesorter-jui thead td,.tablesorter-jui thead th{position:relative;background-repeat:no-repeat;background-position:right center;font-weight:700!important;border-width:1px!important;text-align:left;padding:8px}.tablesorter-jui .header,.tablesorter-jui .tablesorter-header{cursor:pointer;white-space:normal}.tablesorter-jui .tablesorter-header-inner{padding-right:20px}.tablesorter-jui thead tr th .ui-icon{position:absolute;right:3px;top:50%;margin-top:-8px}.tablesorter-jui thead .sorter-false{cursor:default}.tablesorter-jui thead tr .sorter-false .ui-icon{display:none}.tablesorter-jui tfoot td,.tablesorter-jui tfoot th{font-weight:400!important;font-size:.9em;padding:2px}.tablesorter-jui td{padding:4px;vertical-align:top}.tablesorter-jui tbody>tr.hover>td,.tablesorter-jui tbody>tr:hover>td{opacity:.7}.tablesorter-jui .tablesorter-processing .tablesorter-header-inner{background-position:center center!important;background-repeat:no-repeat!important;background-image:url(data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=)!important}.tablesorter-jui tr.ui-state-default{background-image:none;font-weight:400}.tablesorter-jui .tablesorter-processing{background-color:#ddd;background-color:rgba(255,255,255,.8)}.tablesorter-jui>caption{border:0}.tablesorter-jui .tablesorter-filter-row{background-color:transparent}.tablesorter-jui .tablesorter-filter-row td{background-color:transparent;line-height:normal;text-align:center;-webkit-transition:line-height .1s ease;-moz-transition:line-height .1s ease;-o-transition:line-height .1s ease;transition:line-height .1s ease}.tablesorter-jui .tablesorter-filter-row .disabled{opacity:.5;cursor:not-allowed}.tablesorter-jui .tablesorter-filter-row.hideme td{padding:2px;margin:0;line-height:0;cursor:pointer}.tablesorter-jui .tablesorter-filter-row.hideme *{height:1px;min-height:0;border:0;padding:0;margin:0;opacity:0}.tablesorter-jui input.tablesorter-filter,.tablesorter-jui select.tablesorter-filter{width:98%;height:auto;margin:0;padding:4px;background-color:#fff;border:1px solid #bbb;color:#333;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:height .1s ease;-moz-transition:height .1s ease;-o-transition:height .1s ease;transition:height .1s ease}.tablesorter .filtered{display:none}.tablesorter .tablesorter-errorRow td{text-align:center;cursor:pointer;background-color:#e6bf99} \ No newline at end of file
diff --git a/web/_static/tablesorter/css/theme.materialize.min.css b/web/_static/tablesorter/css/theme.materialize.min.css
new file mode 100644
index 0000000..ba3488b
--- /dev/null
+++ b/web/_static/tablesorter/css/theme.materialize.min.css
@@ -0,0 +1 @@
+.tablesorter-materialize{width:100%}.tablesorter-materialize tfoot td,.tablesorter-materialize tfoot th,.tablesorter-materialize thead td,.tablesorter-materialize thead th{font:14px/20px Arial,Sans-serif;font-weight:700;padding:4px;margin:0 0 18px;background-color:#eee}.tablesorter-materialize .tablesorter-header{cursor:pointer}.tablesorter-materialize .sorter-false{cursor:default}.tablesorter-materialize .tablesorter-header-inner{position:relative;padding:4px 18px 4px 4px}.tablesorter-materialize thead .tablesorter-header{background-repeat:no-repeat;background-position:center right;padding:4px 18px 4px 4px;white-space:normal;cursor:pointer}.tablesorter-materialize thead .tablesorter-headerUnSorted{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxOCIgaGVpZ2h0PSIxMiIgdmlld0JveD0iMCAwIDI0IDE2Ij48cGF0aCBkPSJNMTUgOCAxIDggOCAwek0xNSA5IDEgOSA4IDE2eiIgZmlsbD0iIzIyMiIvPjwvc3ZnPg==)}.tablesorter-materialize thead .tablesorter-headerAsc{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxOCIgaGVpZ2h0PSIxMiIgdmlld0JveD0iMCAwIDI0IDE2Ij48cGF0aCBkPSJNMTUgMTEgMSAxMSA4IDN6IiBmaWxsPSIjMjIyIi8+PC9zdmc+)}.tablesorter-materialize thead .tablesorter-headerDesc{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxOCIgaGVpZ2h0PSIxMiIgdmlld0JveD0iMCAwIDI0IDE2Ij48cGF0aCBkPSJNMTUgNiAxIDYgOCAxM3oiIGZpbGw9IiMyMjIiLz48L3N2Zz4=)}.tablesorter-materialize-dark thead .tablesorter-headerUnSorted{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxOCIgaGVpZ2h0PSIxMiIgdmlld0JveD0iMCAwIDI0IDE2Ij48cGF0aCBkPSJNMTUgOCAxIDggOCAwek0xNSA5IDEgOSA4IDE2eiIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg==)}.tablesorter-materialize-dark thead .tablesorter-headerAsc{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxOCIgaGVpZ2h0PSIxMiIgdmlld0JveD0iMCAwIDI0IDE2Ij48cGF0aCBkPSJNMTUgMTEgMSAxMSA4IDN6IiBmaWxsPSIjZmZmIi8+PC9zdmc+)}.tablesorter-materialize-dark thead .tablesorter-headerDesc{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxOCIgaGVpZ2h0PSIxMiIgdmlld0JveD0iMCAwIDI0IDE2Ij48cGF0aCBkPSJNMTUgNiAxIDYgOCAxM3oiIGZpbGw9IiNmZmYiLz48L3N2Zz4=)}.tablesorter-materialize>tbody>tr.odd>td,.tablesorter-materialize>tbody>tr.tablesorter-hasChildRow.odd:hover~tr.tablesorter-hasChildRow.odd~.tablesorter-childRow.odd>td{background-color:#f9f9f9}.tablesorter-materialize>tbody>tr.even:hover>td,.tablesorter-materialize>tbody>tr.hover>td,.tablesorter-materialize>tbody>tr.odd:hover>td,.tablesorter-materialize>tbody>tr.tablesorter-hasChildRow.even:hover~.tablesorter-childRow.even>td,.tablesorter-materialize>tbody>tr.tablesorter-hasChildRow.odd:hover~.tablesorter-childRow.odd>td{background-color:#f5f5f5}.tablesorter-materialize>tbody>tr.even>td,.tablesorter-materialize>tbody>tr.tablesorter-hasChildRow.even:hover~tr.tablesorter-hasChildRow.even~.tablesorter-childRow.even>td{background-color:#fff}.tablesorter-materialize .tablesorter-processing{background-image:url(data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=);background-position:center center!important;background-repeat:no-repeat!important}.tablesorter-materialize>.caption{background-color:#fff}.tablesorter-materialize .tablesorter-filter-row input.tablesorter-filter,.tablesorter-materialize .tablesorter-filter-row select.tablesorter-filter{width:98%;margin:0;padding:4px 6px;color:#333;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:height .1s ease;-moz-transition:height .1s ease;-o-transition:height .1s ease;transition:height .1s ease}.tablesorter-materialize .tablesorter-filter-row .tablesorter-filter.disabled{background-color:#eee;color:#555;cursor:not-allowed;border:1px solid #ccc;border-radius:4px;box-shadow:0 1px 1px rgba(0,0,0,.075) inset;box-sizing:border-box;transition:height .1s ease}.tablesorter-materialize .tablesorter-filter-row{background-color:#efefef}.tablesorter-materialize .tablesorter-filter-row td{background-color:#efefef;line-height:normal;text-align:center;padding:4px 6px;vertical-align:middle;-webkit-transition:line-height .1s ease;-moz-transition:line-height .1s ease;-o-transition:line-height .1s ease;transition:line-height .1s ease}.tablesorter-materialize .tablesorter-filter-row.hideme td{padding:2px;margin:0;line-height:0}.tablesorter-materialize .tablesorter-filter-row.hideme *{height:1px;min-height:0;border:0;padding:0;margin:0;opacity:0}.tablesorter .filtered{display:none}.tablesorter-materialize .tablesorter-pager select{padding:4px 6px;display:inline-block;width:auto}.tablesorter-materialize .tablesorter-pager .pagedisplay{border:0}.tablesorter .tablesorter-errorRow td{text-align:center;cursor:pointer;background-color:#e6bf99} \ No newline at end of file
diff --git a/web/_static/tablesorter/css/theme.metro-dark.min.css b/web/_static/tablesorter/css/theme.metro-dark.min.css
new file mode 100644
index 0000000..f406edb
--- /dev/null
+++ b/web/_static/tablesorter/css/theme.metro-dark.min.css
@@ -0,0 +1 @@
+.tablesorter-metro-dark{width:100%;font:12px/18px 'Segoe UI Semilight','Open Sans',Verdana,Arial,Helvetica,sans-serif;color:#000;background-color:#333;border-spacing:0;margin:10px 0 15px;text-align:left}.tablesorter-metro-dark caption.dark-row,.tablesorter-metro-dark tr.dark-row td,.tablesorter-metro-dark tr.dark-row th{background-color:#222;color:#fff;padding:2px;text-align:left;font-size:14px}.tablesorter-metro-dark caption,.tablesorter-metro-dark tfoot td,.tablesorter-metro-dark tfoot th,.tablesorter-metro-dark th,.tablesorter-metro-dark thead td{font-weight:300;font-size:15px;color:#ddd;background-color:#333;padding:4px}.tablesorter-metro-dark .header,.tablesorter-metro-dark .tablesorter-header{background-image:url(data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAQBAMAAADQT4M0AAAAGFBMVEUAAADu7u7u7u7u7u7u7u7u7u7u7u7u7u5jNePWAAAACHRSTlMAMxIHKwEgMWD59H4AAABSSURBVAjXY2BgYFJgAAHzYhDJ6igSAKTYBAUTgJSioKAQAwNzoaCguAFDiCAQuDIkgigxBgiA8cJAVCpQt6AgSL+JoKAzA0gjUBsQqBcBCYhFAAE/CV4zeSzxAAAAAElFTkSuQmCC);background-position:right 5px center;background-repeat:no-repeat;cursor:pointer;white-space:normal}.tablesorter-metro-dark .tablesorter-header-inner{padding:0 18px 0 4px}.tablesorter-metro-dark thead .headerSortUp,.tablesorter-metro-dark thead .tablesorter-headerAsc,.tablesorter-metro-dark thead .tablesorter-headerSortUp{background-image:url(data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAQBAMAAADQT4M0AAAAIVBMVEUAAADu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u5meJAOAAAACnRSTlMAMwsqXt+gIBUGxGoDMAAAAFlJREFUCNctzC0SQAAUReEzGNQ3AlHRiSRZFCVZYgeswRL8hLdK7834wj3tAlGP6y7fYHpKS6w6WwbVG0I1NZVnZPG8/DYxOYlnhUYkA06R1s9ESsxR4NIdPhkPFDFYuEnMAAAAAElFTkSuQmCC)}.tablesorter-metro-dark thead .headerSortDown,.tablesorter-metro-dark thead .tablesorter-headerDesc,.tablesorter-metro-dark thead .tablesorter-headerSortDown{background-image:url(data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAQBAMAAADQT4M0AAAALVBMVEUAAADu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7i0NViAAAADnRSTlMAMiweCQITTvDctZZqaTlM310AAABcSURBVAjXY2BgYEtgAAFHERDJqigUAKSYBQUNgFSioKAYAwOLIBA4MASBKFUGQxAlzAAF+94BwWuGKBC1lIFl3rt3Lx0YGCzevWsGSjK9e6cAUlT3HKyW9wADAwDRrBiDy6bKzwAAAABJRU5ErkJggg==)}.tablesorter-metro-dark thead .sorter-false{background-image:none;cursor:default;padding:4px}.tablesorter-metro-dark td{background-color:#fff;padding:4px;vertical-align:top}.tablesorter-metro-dark tbody>tr.even:hover>td,.tablesorter-metro-dark tbody>tr.hover>td,.tablesorter-metro-dark tbody>tr.odd:hover>td,.tablesorter-metro-dark tbody>tr:hover>td{background-color:#bbb;color:#000}.tablesorter-metro-dark .tablesorter-processing{background-position:center center!important;background-repeat:no-repeat!important;background-image:url(data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=)!important}.tablesorter-metro-dark .tablesorter-pager button{background-color:#444;color:#eee;border:#555 1px solid;cursor:pointer}.tablesorter-metro-dark .tablesorter-pager button:hover{background-color:#555}.tablesorter-metro-dark tr.odd>td{background-color:#eee}.tablesorter-metro-dark tr.even>td{background-color:#fff}.tablesorter-metro-dark tr.odd td.primary{background-color:#bfbfbf}.tablesorter-metro-dark td.primary,.tablesorter-metro-dark tr.even td.primary{background-color:#d9d9d9}.tablesorter-metro-dark tr.odd td.secondary{background-color:#d9d9d9}.tablesorter-metro-dark td.secondary,.tablesorter-metro-dark tr.even td.secondary{background-color:#e6e6e6}.tablesorter-metro-dark tr.odd td.tertiary{background-color:#e6e6e6}.tablesorter-metro-dark td.tertiary,.tablesorter-metro-dark tr.even td.tertiary{background-color:#f2f2f2}.tablesorter-metro-dark .tablesorter-filter-row{background-color:#eee}.tablesorter-metro-dark .tablesorter-filter-row td{background-color:#eee;line-height:normal;text-align:center;-webkit-transition:line-height .1s ease;-moz-transition:line-height .1s ease;-o-transition:line-height .1s ease;transition:line-height .1s ease}.tablesorter-metro-dark .tablesorter-filter-row .disabled{opacity:.5;cursor:not-allowed}.tablesorter-metro-dark .tablesorter-filter-row.hideme td{padding:2px;margin:0;line-height:0;cursor:pointer}.tablesorter-metro-dark .tablesorter-filter-row.hideme *{height:1px;min-height:0;border:0;padding:0;margin:0;opacity:0}.tablesorter-metro-dark input.tablesorter-filter,.tablesorter-metro-dark select.tablesorter-filter{width:95%;height:auto;margin:0;padding:4px;background-color:#fff;border:1px solid #bbb;color:#333;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:height .1s ease;-moz-transition:height .1s ease;-o-transition:height .1s ease;transition:height .1s ease}.tablesorter .filtered{display:none}.tablesorter .tablesorter-errorRow td{text-align:center;cursor:pointer;background-color:#e6bf99} \ No newline at end of file
diff --git a/web/_static/tablesorter/css/widget.grouping.min.css b/web/_static/tablesorter/css/widget.grouping.min.css
new file mode 100644
index 0000000..0beb435
--- /dev/null
+++ b/web/_static/tablesorter/css/widget.grouping.min.css
@@ -0,0 +1 @@
+tr.group-header td{background:#eee}.group-name{text-transform:uppercase;font-weight:700}.group-count{color:#999}.group-hidden{display:none!important}.group-header,.group-header td{user-select:none;-moz-user-select:none}tr.group-header td i{display:inline-block;width:0;height:0;border-top:4px solid transparent;border-bottom:4px solid #888;border-right:4px solid #888;border-left:4px solid transparent;margin-right:7px;user-select:none;-moz-user-select:none}tr.group-header.collapsed td i{border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid #888;border-right:0;margin-right:10px} \ No newline at end of file