incremental
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 31f672b..9035ee7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -115,6 +115,13 @@
 
 set_source_files_properties(${GENERATED_SRC_FILES} PROPERTIES GENERATED TRUE)
 
+if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
+    if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
+        set_source_files_properties(${CMAKE_BINARY_DIR}/generated/webassets.cpp PROPERTIES COMPILE_FLAGS -Wno-narrowing)
+    endif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
+endif()
+
+
 set(SRC_FILES
     src/token_authorization_middleware.cpp
     src/base64.cpp
diff --git a/docs/profile.md b/docs/profile.md
index fffc400..3a2156e 100644
--- a/docs/profile.md
+++ b/docs/profile.md
@@ -1,4 +1,8 @@
 LD_LIBRARY_PATH=/tmp LD_PRELOAD=libprofiler.so CPUPROFILE=/tmp/profile ./bmcweb
 
 scp ed@hades.jf.intel.com:/home/ed/webserver/buildarm/bmcweb /tmp
-scp ed@hades.jf.intel.com:/home/ed/gperftools/.libs/libprofiler.so /tmp
\ No newline at end of file
+scp ed@hades.jf.intel.com:/home/ed/webserver/buildarm/getvideo /tmp -i /nv/.ssh/id_rsa
+scp ed@hades.jf.intel.com:/home/ed/gperftools/.libs/libprofiler.so /tmp
+
+echo 1 >> /sys/module/video_drv/parameters/debug
+echo 8 > /proc/sys/kernel/printk
\ No newline at end of file
diff --git a/include/token_authorization_middleware.hpp b/include/token_authorization_middleware.hpp
index 61c8385..1602656 100644
--- a/include/token_authorization_middleware.hpp
+++ b/include/token_authorization_middleware.hpp
@@ -4,7 +4,15 @@
 #include <crow/http_response.h>
 
 namespace crow {
+
+struct User {
+
+};
+
 struct TokenAuthorizationMiddleware {
+  // TODO(ed) auth_token shouldn't really be passed to the context
+  // it opens the possibility of exposure by and endpoint.
+  // instead we should only pass some kind of "user" struct
   struct context {
     std::string auth_token;
   };
diff --git a/include/web_kvm.hpp b/include/web_kvm.hpp
index cecd09f..24544fc 100644
--- a/include/web_kvm.hpp
+++ b/include/web_kvm.hpp
@@ -1,5 +1,13 @@
+#include <boost/endian/arithmetic.hpp>
+#include <string>
+
+#include "app_type.hpp"
+
+#include <video.h>
+
 namespace crow {
 namespace kvm {
+
 static const std::string rfb_3_3_version_string = "RFB 003.003\n";
 static const std::string rfb_3_7_version_string = "RFB 003.007\n";
 static const std::string rfb_3_8_version_string = "RFB 003.008\n";
@@ -26,14 +34,14 @@
   boost::endian::big_uint8_t pad3;
 };
 
-struct server_initialization_message {
+struct server_initialization_msg {
   boost::endian::big_uint16_t framebuffer_width;
   boost::endian::big_uint16_t framebuffer_height;
   pixel_format_struct pixel_format;
   boost::endian::big_uint32_t name_length;
 };
 
-enum class client_to_server_message_type : uint8_t {
+enum class client_to_server_msg_type : uint8_t {
   set_pixel_format = 0,
   fix_color_map_entries = 1,
   set_encodings = 2,
@@ -43,14 +51,14 @@
   client_cut_text = 6
 };
 
-struct set_pixel_format_message {
+struct set_pixel_format_msg {
   boost::endian::big_uint8_t pad1;
   boost::endian::big_uint8_t pad2;
   boost::endian::big_uint8_t pad3;
   pixel_format_struct pixel_format;
 };
 
-struct frame_buffer_update_request_message {
+struct frame_buffer_update_req {
   boost::endian::big_uint8_t incremental;
   boost::endian::big_uint16_t x_position;
   boost::endian::big_uint16_t y_position;
@@ -58,20 +66,20 @@
   boost::endian::big_uint16_t height;
 };
 
-struct key_event_message {
+struct key_event_msg {
   boost::endian::big_uint8_t down_flag;
   boost::endian::big_uint8_t pad1;
   boost::endian::big_uint8_t pad2;
   boost::endian::big_uint32_t key;
 };
 
-struct pointer_event_message {
+struct pointer_event_msg {
   boost::endian::big_uint8_t button_mask;
   boost::endian::big_uint16_t x_position;
   boost::endian::big_uint16_t y_position;
 };
 
-struct client_cut_text_message {
+struct client_cut_text_msg {
   std::vector<uint8_t> data;
 };
 
@@ -112,12 +120,12 @@
   std::vector<uint8_t> data;
 };
 
-struct framebuffer_update_message {
+struct framebuffer_update_msg {
   boost::endian::big_uint8_t message_type;
   std::vector<framebuffer_rectangle> rectangles;
 };
 
-std::string serialize(const framebuffer_update_message& msg) {
+std::string serialize(const framebuffer_update_msg& msg) {
   // calculate the size of the needed vector for serialization
   size_t vector_size = 4;
   for (const auto& rect : msg.rectangles) {
@@ -152,13 +160,13 @@
   UNSTARTED,
   AWAITING_CLIENT_VERSION,
   AWAITING_CLIENT_AUTH_METHOD,
-  AWAITING_CLIENT_INIT_MESSAGE,
+  AWAITING_CLIENT_INIT_msg,
   MAIN_LOOP
 };
 
 class connection_metadata {
  public:
-  connection_metadata(void) : vnc_state(VncState::AWAITING_CLIENT_VERSION){};
+  connection_metadata(void) : vnc_state(VncState::UNSTARTED){};
 
   VncState vnc_state;
 };
@@ -172,8 +180,13 @@
   CROW_ROUTE(app, "/kvmws")
       .websocket()
       .onopen([&](crow::websocket::connection& conn) {
-        meta.vnc_state = VncState::AWAITING_CLIENT_VERSION;
-        conn.send_binary(rfb_3_8_version_string);
+        if (meta.vnc_state == VncState::UNSTARTED) {
+          meta.vnc_state = VncState::AWAITING_CLIENT_VERSION;
+          conn.send_binary(rfb_3_8_version_string);
+        } else {
+          conn.close();
+        }
+
       })
       .onclose(
           [&](crow::websocket::connection& conn, const std::string& reason) {
@@ -203,7 +216,7 @@
           case VncState::AWAITING_CLIENT_AUTH_METHOD: {
             std::string security_result{{0, 0, 0, 0}};
             if (data[0] == (uint8_t)RfbAuthScheme::no_authentication) {
-              meta.vnc_state = VncState::AWAITING_CLIENT_INIT_MESSAGE;
+              meta.vnc_state = VncState::AWAITING_CLIENT_INIT_msg;
             } else {
               // Mark auth as failed
               security_result[3] = 1;
@@ -211,9 +224,9 @@
             }
             conn.send_binary(security_result);
           } break;
-          case VncState::AWAITING_CLIENT_INIT_MESSAGE: {
+          case VncState::AWAITING_CLIENT_INIT_msg: {
             // Now send the server initialization
-            server_initialization_message server_init_msg;
+            server_initialization_msg server_init_msg;
             server_init_msg.framebuffer_width = 640;
             server_init_msg.framebuffer_height = 480;
             server_init_msg.pixel_format.bits_per_pixel = 32;
@@ -237,30 +250,28 @@
             meta.vnc_state = VncState::MAIN_LOOP;
           } break;
           case VncState::MAIN_LOOP: {
-            if (data.size() >= sizeof(client_to_server_message_type)) {
-              auto type = static_cast<client_to_server_message_type>(data[0]);
-              LOG(DEBUG) << "Got type " << (uint32_t)type << "\n";
+            if (data.size() >= sizeof(client_to_server_msg_type)) {
+              auto type = static_cast<client_to_server_msg_type>(data[0]);
+              LOG(DEBUG) << "Received client message type " << (uint32_t)type
+                         << "\n";
               switch (type) {
-                case client_to_server_message_type::set_pixel_format: {
+                case client_to_server_msg_type::set_pixel_format: {
                 } break;
 
-                case client_to_server_message_type::fix_color_map_entries: {
+                case client_to_server_msg_type::fix_color_map_entries: {
                 } break;
-                case client_to_server_message_type::set_encodings: {
+                case client_to_server_msg_type::set_encodings: {
                 } break;
-                case client_to_server_message_type::
-                    framebuffer_update_request: {
+                case client_to_server_msg_type::framebuffer_update_request: {
                   // Make sure the buffer is long enough to handle what we're
                   // about to do
-                  if (data.size() >=
-                      sizeof(frame_buffer_update_request_message) +
-                          sizeof(client_to_server_message_type)) {
-                    auto msg = reinterpret_cast<
-                        const frame_buffer_update_request_message*>(
-                        data.data() + sizeof(client_to_server_message_type));
+                  if (data.size() >= sizeof(frame_buffer_update_req) +
+                                         sizeof(client_to_server_msg_type)) {
+                    auto msg = reinterpret_cast<const frame_buffer_update_req*>(
+                        data.data() + sizeof(client_to_server_msg_type));
 
                     if (!msg->incremental) {
-                      framebuffer_update_message buffer_update_message;
+                      framebuffer_update_msg buffer_update_msg;
 
                       // If the viewer is requesting a full update, force write
                       // of all pixels
@@ -291,9 +302,9 @@
                         }
                       }
 
-                      buffer_update_message.rectangles.push_back(
+                      buffer_update_msg.rectangles.push_back(
                           std::move(this_rect));
-                      auto serialized = serialize(buffer_update_message);
+                      auto serialized = serialize(buffer_update_msg);
 
                       conn.send_binary(serialized);
                     }
@@ -303,13 +314,13 @@
 
                 break;
 
-                case client_to_server_message_type::key_event: {
+                case client_to_server_msg_type::key_event: {
                 } break;
 
-                case client_to_server_message_type::pointer_event: {
+                case client_to_server_msg_type::pointer_event: {
                 } break;
 
-                case client_to_server_message_type::client_cut_text: {
+                case client_to_server_msg_type::client_cut_text: {
                 } break;
 
                 default:
diff --git a/include/webassets.hpp b/include/webassets.hpp
index 924b1d5..b5431bc 100644
--- a/include/webassets.hpp
+++ b/include/webassets.hpp
@@ -9,6 +9,7 @@
 #include <crow/routing.h>
 #include <app_type.hpp>
 
+
 namespace crow {
 namespace webassets {
 void request_routes(BmcAppType& app);
diff --git a/scripts/build_web_assets.py b/scripts/build_web_assets.py
index 58a9b94..8268787 100755
--- a/scripts/build_web_assets.py
+++ b/scripts/build_web_assets.py
@@ -30,8 +30,14 @@
 void crow::webassets::request_routes(BmcAppType& app){
 """
 
-CPP_MIDDLE_CACHING_HANDLER = """
-        res.add_header("Cache-Control", "public, max-age=31556926");
+CACHE_FOREVER_HEADER = """
+    res.add_header("Cache-Control", "public, max-age=31556926");
+"""
+
+CPP_MIDDLE_BUFFER = """
+    CROW_ROUTE(app, "{relative_path_sha1}")([](const crow::request& req, crow::response& res) {{
+        {CACHE_FOREVER_HEADER}
+
         res.add_header("ETag", "{sha1}");
         if (req.headers.count("If-None-Match") == 1) {{
             if (req.get_header_value("If-None-Match") == "{sha1}"){{
@@ -40,12 +46,7 @@
                 return;
             }}
         }}
-"""
 
-
-CPP_MIDDLE_BUFFER = """
-    CROW_ROUTE(app, "{relative_path_sha1}")([](const crow::request& req, crow::response& res) {{
-        {CPP_MIDDLE_CACHING_HANDLER}
         res.code = 200;
         // TODO, if you have a browser from the dark ages that doesn't support gzip,
         // unzip it before sending based on Accept-Encoding header
@@ -75,11 +76,12 @@
 def get_relative_path(full_filepath):
     pathsplit = full_filepath.split(os.path.sep)
     relative_path = os.path.sep.join(pathsplit[pathsplit.index("static") + 1:])
+
     relative_path_escaped = relative_path
     for character in ['/', '.', '-']:
         relative_path_escaped = relative_path_escaped.replace(character, "_")
 
-    relative_path = "/static/" + relative_path
+    relative_path = "static/" + relative_path
 
     return relative_path, relative_path_escaped
 
@@ -93,12 +95,60 @@
 def filter_html(sha1_list, file_content):
     string_content = file_content.decode()
     for key, value in sha1_list.items():
-        key = key.lstrip("/")
         replace_name = get_sha1_path_from_relative(key, value)
-        key = re.escape(key)
-        string_content = re.sub("((src|href)=[\"'])(" + key + ")([\"'])", "\\1" + replace_name + "\\4", string_content)
+        string_content_new = re.sub("((src|href)=[\"'])(" + re.escape(key) + ")([\"'])", "\\1" + replace_name + "\\4", string_content)
+        if string_content_new != string_content:
+            print("    Replaced {}".format(key))
+            print("    With {}".format(replace_name))
+            string_content = string_content_new
+
     return string_content.encode()
 
+def filter_js(sha1_list, file_content):
+
+    string_content = file_content.decode()
+    for key, value in sha1_list.items():
+        replace_name = get_sha1_path_from_relative(key, value)
+
+        string_content_new = re.sub(key, replace_name, string_content)
+        if string_content_new != string_content:
+            print("    Replaced {}".format(key))
+            print("    With {}".format(replace_name))
+            string_content = string_content_new
+    return string_content.encode()
+
+def compute_sha1_and_update_dict(sha1_list, file_content, relative_path):
+    sha = hashlib.sha1()
+    sha.update(file_content)
+    sha_bytes = sha.digest()
+
+    sha_text = "".join("{:02x}".format(x) for x in sha_bytes)
+    sha1_list[relative_path] = sha_text
+
+FILE_PRECIDENCE = ['.woff', '.png' ,'.css', '.js', '.html']
+def sort_order(full_filepath):
+    # sort list based on users
+    path, ext = os.path.splitext(full_filepath)
+    if ext in FILE_PRECIDENCE:
+        return FILE_PRECIDENCE.index(ext) + 1
+    else:
+        return 0
+
+
+def get_dependencies(dependency_list, full_filepath):
+    r = []
+    my_dependencies = dependency_list[full_filepath]
+    r.extend(my_dependencies)
+    sub_deps = []
+    for dependency in my_dependencies:
+        sub_deps += get_dependencies(dependency_list, dependency)
+    r.extend(sub_deps)
+    return r
+
+def remove_duplicates_preserve_order(seq):
+    seen = set()
+    seen_add = seen.add
+    return [x for x in seq if not (x in seen or seen_add(x))]
 
 def main():
     """ Main Function """
@@ -114,25 +164,44 @@
     file_list = [os.path.realpath(f) for f in file_list]
 
     sha1_list = {}
-    if not args.debug:
-        # TODO(ed) most html and woff cacheable
-        excluded_types = [".html", ".woff"]
-        # sha1 hash everthing
-        for full_filepath in file_list:
-            if os.path.splitext(full_filepath)[1] not in excluded_types:
-                with open(full_filepath, 'rb') as input_file:
-                    file_content = input_file.read()
-                sha = hashlib.sha1()
-                sha.update(file_content)
 
-                sha_text = "".join("{:02x}".format(x) for x in sha.digest())
-                relative_path, relative_path_escaped = get_relative_path(full_filepath)
-                sha1_list[relative_path] = sha_text
+    file_list.sort(key=sort_order)
+    from collections import defaultdict
+    depends_on = {}
+
+    for full_filepath in file_list:
+        relative_path, relative_path_escaped = get_relative_path(full_filepath)
+        text_file_types = ['.css', '.js', '.html']
+        ext = os.path.splitext(relative_path)[1]
+        depends_on[full_filepath] = []
+        if ext in text_file_types:
+            with open(full_filepath, 'r') as input_file:
+                file_content = input_file.read()
+            for full_replacename in file_list:
+                relative_replacename, _ = get_relative_path(full_replacename)
+                if ext == ".html":
+                    match = re.search("((src|href)=[\"'])(" + relative_replacename + ")([\"'])", file_content)
+                    if match:
+                        depends_on[full_filepath].append(full_replacename)
+
+                elif ext == ".js":
+                    match = re.search("([\"'])(" + relative_replacename + ")([\"'])", file_content)
+                    if match:
+                        depends_on[full_filepath].append(full_replacename)
+
+    dependency_ordered_file_list = []
+    for full_filepath in file_list:
+        relative_path, relative_path_escaped = get_relative_path(full_filepath)
+        deps = get_dependencies(depends_on, full_filepath)
+        dependency_ordered_file_list.extend(deps)
+        dependency_ordered_file_list.append(full_filepath)
+
+    dependency_ordered_file_list = remove_duplicates_preserve_order(dependency_ordered_file_list)
 
     with open(args.output, 'w') as cpp_output:
         cpp_output.write(CPP_BEGIN_BUFFER)
 
-        for full_filepath in file_list:
+        for full_filepath in dependency_ordered_file_list:
             # make sure none of the files are hidden
             with open(full_filepath, 'rb') as input_file:
                 file_content = input_file.read()
@@ -141,14 +210,20 @@
             print("Including {:<40} size {:>7}".format(relative_path, len(file_content)))
 
             if relative_path.endswith(".html") or relative_path == "/":
-                print("Fixing {}".format(relative_path))
-                file_content = filter_html(sha1_list, file_content)
+                new_file_content = filter_html(sha1_list, file_content)
+            elif relative_path.endswith(".js"):
+                new_file_content = filter_js(sha1_list, file_content)
+            else:
+                new_file_content = file_content
+
+            file_content = new_file_content
 
             if not args.debug:
                 file_content = gzip.compress(file_content)
                 #file_content = file_content[:10]
                 # compute the 2s complement.  If you don't, you get narrowing warnings from gcc/clang
-            
+
+            compute_sha1_and_update_dict(sha1_list, file_content, relative_path)
             array_binary_text = ', '.join(str(twos_comp(x, 8)) for x in file_content)
 
             cpp_output.write(
@@ -161,8 +236,7 @@
 
         cpp_output.write(ROUTE_DECLARATION)
 
-
-        for full_filepath in file_list:
+        for full_filepath in dependency_ordered_file_list:
             relative_path, relative_path_escaped = get_relative_path(full_filepath)
             sha1 = sha1_list.get(relative_path, '')
 
@@ -171,10 +245,15 @@
                 print("unknown content type for {}".format(relative_path))
 
             # handle the default routes
-            if relative_path == "/static/index.html":
+            if relative_path == "static/index.html":
                 relative_path = "/"
-
-            relative_path_sha1 = get_sha1_path_from_relative(relative_path, sha1)
+                relative_path_sha1 = "/"
+            # TODO(ed), handle woff files better.  They are referenced in CSS, which at this
+            # point isn't scrubbed with a find and replace algorithm
+            elif relative_path.endswith(".woff"):
+                relative_path_sha1 = relative_path
+            else:
+                relative_path_sha1 = "/" + get_sha1_path_from_relative(relative_path, sha1)
 
             content_encoding = 'none' if args.debug else 'gzip'
 
@@ -185,15 +264,14 @@
                 'sha1': sha1,
                 'sha1_short': sha1[:20],
                 'content_type': content_type,
-                'ENABLE_CACHING': str(ENABLE_CACHING).lower(),
-                'content_encoding': ''
+                'content_encoding': content_encoding
             }
-            if ENABLE_CACHING and sha1 != "":
-                environment["CPP_MIDDLE_CACHING_HANDLER"] = CPP_MIDDLE_CACHING_HANDLER.format(
-                    **environment
-                )
-            else:
-                environment["CPP_MIDDLE_CACHING_HANDLER"] = ""
+            environment["CACHE_FOREVER_HEADER"] = ""
+            if ENABLE_CACHING:
+                # if we have a valid sha1, and we have a unique path to the resource
+                # it can be safely cached forever
+                if sha1 != "" and relative_path != relative_path_sha1:
+                    environment["CACHE_FOREVER_HEADER"] = CACHE_FOREVER_HEADER      
 
             content = CPP_MIDDLE_BUFFER.format(
                 **environment
diff --git a/src/getvideo_main.cpp b/src/getvideo_main.cpp
index f73ee30..2259b8c 100644
--- a/src/getvideo_main.cpp
+++ b/src/getvideo_main.cpp
@@ -1,7 +1,14 @@
 #include <video.h>
-#include <fstream>
-#include <iostream>
+
 #include <iomanip>
+#include <iostream>
+#include <chrono>
+#include <thread>
+#include <vector>
+#include <fstream>
+#include <fcntl.h>
+#include <unistd.h>
+
 
 namespace AstVideo {
 class VideoPuller {
@@ -10,40 +17,91 @@
 
   void initialize() {
     std::cout << "Opening /dev/video\n";
-    file.open("/dev/video", std::ios::out | std::ios::in | std::ios::binary);
-    if (!file.is_open()) {
+    video_fd = open("/dev/video", O_RDWR);
+    if (!video_fd) {
       std::cout << "Failed to open /dev/video\n";
+    } else {
+      std::cout << "Opened successfully\n";
     }
+
+    std::vector<unsigned char> buffer(1024 * 1024, 0);
+
     IMAGE_INFO image_info{};
-
-    file.write(reinterpret_cast<char*>(&image_info), sizeof(image_info));
-
-    file.read(reinterpret_cast<char*>(&image_info), sizeof(image_info));
+    image_info.do_image_refresh = 1;  // full frame refresh
+    image_info.qc_valid = 0;          // quick cursor disabled
+    image_info.parameter.features.w = 800;
+    image_info.parameter.features.h = 600;
+    image_info.parameter.features.chrom_tbl = 0;  // level
+    image_info.parameter.features.lumin_tbl = 0;
+    image_info.parameter.features.jpg_fmt = 1;
+    image_info.parameter.features.buf = buffer.data();
+    image_info.crypttype = -1;
+    std::cout << "Writing\n";
     
-    if (file){
-        std::cout << "Read succeeded\n";
+    int status;
+    /*
+    status = write(video_fd, reinterpret_cast<char*>(&image_info),
+                        sizeof(image_info));
+    if (status != 0) {
+      std::cout << "Write failed.  Return: " << status <<"\n";
+      perror("perror output:");
     }
+    */
+    std::cout << "Write done\n";
+    //std::this_thread::sleep_for(std::chrono::milliseconds(2000));
     
+    std::cout << "Reading\n";
+    status = read(video_fd, reinterpret_cast<char*>(&image_info), sizeof(image_info));
+    std::cout << "Reading\n";
+
+    if (status != 0) {
+      std::cout << "Read failed with status " << status << "\n";
+    }
+
     auto pt = reinterpret_cast<char*>(&image_info);
 
-    for(int i=0; i<sizeof(image_info); i++){
-        std::cout << std::hex << std::setfill('0') << std::setw(2) << int(*(pt + i)) << " ";
+    for (int i = 0; i < sizeof(image_info); i++) {
+      std::cout << std::hex << std::setfill('0') << std::setw(2)
+                << int(*(pt + i)) << " ";
     }
+    std::cout << "\n";
+    /*
+    for(int i = 0; i < 1024; i++){
+        if (i % 16 == 0){
+          std::cout << "\n";
+        }
+        std::cout << std::hex << std::setfill('0') << std::setw(2)
+            << int(buffer[i]) << " ";
+    }
+    */
+    buffer.resize(image_info.len);
     
+    std::ofstream f("/tmp/screen.jpg",std::ios::out | std::ios::binary); 
+
+    f.write(reinterpret_cast<char*>(buffer.data()), buffer.size());
+
     std::cout << "\n";
 
     std::cout << "typedef struct _video_features {\n";
-    std::cout << "short jpg_fmt: " << image_info.parameter.features.jpg_fmt << "\n";
-    std::cout << "short lumin_tbl;" << image_info.parameter.features.lumin_tbl << "\n";
-    std::cout << "short chrom_tbl;" << image_info.parameter.features.chrom_tbl << "\n";
-    std::cout << "short tolerance_noise;" << image_info.parameter.features.tolerance_noise << "\n";
-    std::cout << "int w;" << image_info.parameter.features.w << "\n";
-    std::cout << "int h;" << image_info.parameter.features.h << "\n";
-    //std::cout << "unsigned char *buf;" << image_info.parameter.features.buf << "\n";
+    std::cout << "short jpg_fmt: " << image_info.parameter.features.jpg_fmt
+              << "\n";
+    std::cout << "short lumin_tbl;" << image_info.parameter.features.lumin_tbl
+              << "\n";
+    std::cout << "short chrom_tbl;" << image_info.parameter.features.chrom_tbl
+              << "\n";
+    std::cout << "short tolerance_noise;"
+              << image_info.parameter.features.tolerance_noise << "\n";
+    std::cout << "int w; 0X" << image_info.parameter.features.w << "\n";
+    std::cout << "int h; 0X" << image_info.parameter.features.h << "\n";
+
+    std::cout << "void* buf; 0X" << static_cast<void*>(image_info.parameter.features.buf) << "\n";
+    // std::cout << "unsigned char *buf;" << image_info.parameter.features.buf
+    // << "\n";
     std::cout << "} FEATURES_TAG;\n";
 
     std::cout << "typedef struct _image_info {";
-    std::cout << "short do_image_refresh;" << image_info.do_image_refresh << "\n";
+    std::cout << "short do_image_refresh;" << image_info.do_image_refresh
+              << "\n";
     std::cout << "char qc_valid;" << image_info.qc_valid << "\n";
     std::cout << "unsigned int len;" << image_info.len << "\n";
     std::cout << "int crypttype;" << image_info.crypttype << "\n";
@@ -54,8 +112,10 @@
     std::cout << "} parameter;\n";
     std::cout << "} IMAGE_INFO;\n";
     std::cout << std::endl;
+
+    close(video_fd);
   }
-  std::fstream file;
+  int video_fd;
 };
 }
 
diff --git a/src/webserver_main.cpp b/src/webserver_main.cpp
index 58483df..80354fb 100644
--- a/src/webserver_main.cpp
+++ b/src/webserver_main.cpp
@@ -1,3 +1,9 @@
+#include <webassets.hpp>
+#include <web_kvm.hpp>
+#include "ssl_key_handler.hpp"
+
+#include "app_type.hpp"
+
 #include "crow/app.h"
 #include "crow/ci_map.h"
 #include "crow/common.h"
@@ -20,25 +26,20 @@
 #include "crow/utility.h"
 #include "crow/websocket.h"
 
-#include "app_type.hpp"
 
 #include "color_cout_g3_sink.hpp"
 #include "token_authorization_middleware.hpp"
 #include "webassets.hpp"
 
+
+#include <boost/asio.hpp>
+#include <boost/endian/arithmetic.hpp>
+
+
 #include <iostream>
 #include <memory>
 #include <string>
-#include "ssl_key_handler.hpp"
-
-#include <boost/endian/arithmetic.hpp>
-
-#include <boost/asio.hpp>
-
 #include <unordered_set>
-#include <webassets.hpp>
-
-#include <web_kvm.hpp>
 
 int main(int argc, char** argv) {
   auto worker(g3::LogWorker::createLogWorker());
@@ -53,6 +54,7 @@
   ensuressl::ensure_openssl_key_present_and_valid(ssl_pem_file);
 
   BmcAppType app;
+
   crow::webassets::request_routes(app);
   crow::kvm::request_routes(app);
 
@@ -68,16 +70,19 @@
 
   CROW_ROUTE(app, "/login")
       .methods("POST"_method)([&](const crow::request& req) {
+        crow::json::wvalue x;
         auto auth_token =
             app.get_context<crow::TokenAuthorizationMiddleware>(req).auth_token;
-        crow::json::wvalue x;
+        
         x["token"] = auth_token;
 
         return x;
       });
 
   CROW_ROUTE(app, "/logout")
-      .methods("GET"_method, "POST"_method)([]() {
+      .methods("GET"_method, "POST"_method)([&](const crow::request& req) {
+
+        app.get_context<crow::TokenAuthorizationMiddleware>(req).auth_token = "";
         // Do nothing.  Credentials have already been cleared by middleware.
         return 200;
       });
diff --git a/static/index.html b/static/index.html
index 9f08b37..391bf93 100644
--- a/static/index.html
+++ b/static/index.html
@@ -13,43 +13,40 @@
 
     <link rel="icon" href="static/favicon.ico" type="image/x-icon" />
 
-    <script src="static/js/angular.js"></script>
-    <script src="static/js/angular-animate.js"></script>
-    <script src="static/js/angular-sanitize.js"></script>
-    <script src="static/js/angular-cookies.js"></script>
-    <script src="static/js/angular-resource.js"></script>
-    <script src="static/js/angular-ui-router.js"></script>
-    <script src="static/js/angular-websocket.js"></script>
-    <script src="static/js/lodash.core.js"></script>
+    <script type="text/javascript" src="static/js/angular.js"></script>
+    <script type="text/javascript" src="static/js/angular-animate.js"></script>
+    <script type="text/javascript" src="static/js/angular-sanitize.js"></script>
+    <script type="text/javascript" src="static/js/angular-cookies.js"></script>
+    <script type="text/javascript" src="static/js/angular-resource.js"></script>
+    <script type="text/javascript" src="static/js/angular-ui-router.js"></script>
+    <script type="text/javascript" src="static/js/angular-websocket.js"></script>
+    <script type="text/javascript" src="static/js/lodash.core.js"></script>
 
-    <script src="static/js/ui-bootstrap-tpls-2.1.3.js"></script>
+    <script type="text/javascript" src="static/js/ui-bootstrap-tpls-2.1.3.js"></script>
 
-    <script src="static/js/bmcApp.js"></script>
-    <script src="static/js/base64.js"></script>
-    <script src="static/js/versionController.js"></script>
-    <script src="static/js/selController.js"></script>
-    <script src="static/js/loginController.js"></script>
-    <script src="static/js/kvmController.js"></script>
-    <script src="static/js/ipmiController.js"></script>
+    <script type="text/javascript" src="static/js/bmcApp.js"></script>
+    <script type="text/javascript" src="static/js/base64.js"></script>
+    <script type="text/javascript" src="static/js/versionController.js"></script>
+    <script type="text/javascript" src="static/js/selController.js"></script>
+    <script type="text/javascript" src="static/js/loginController.js"></script>
+    <script type="text/javascript" src="static/js/kvmController.js"></script>
+    <script type="text/javascript" src="static/js/ipmiController.js"></script>
  
-    <script src="static/noVNC/core/util.js"></script>
-    <script src="static/noVNC/app/webutil.js"></script>  
+    <script type="text/javascript" src="static/noVNC/core/util.js"></script>
+    <script type="text/javascript" src="static/noVNC/app/webutil.js"></script>  
 
-    <script src="static/noVNC/core/base64.js"></script>
-    <script src="static/noVNC/core/websock.js"></script>
-    <script src="static/noVNC/core/des.js"></script>
-    <script src="static/noVNC/core/input/keysymdef.js"></script>
-    <script src="static/noVNC/core/input/xtscancodes.js"></script>
-    <script src="static/noVNC/core/input/util.js"></script>
-    <script src="static/noVNC/core/input/devices.js"></script>
-    <script src="static/noVNC/core/display.js"></script>
-    <script src="static/noVNC/core/inflator.js"></script>
-    <script src="static/noVNC/core/rfb.js"></script>
-    <script src="static/noVNC/core/input/keysym.js"></script> 
+    <script type="text/javascript" src="static/noVNC/core/base64.js"></script>
+    <script type="text/javascript" src="static/noVNC/core/websock.js"></script>
+    <script type="text/javascript" src="static/noVNC/core/des.js"></script>
+    <script type="text/javascript" src="static/noVNC/core/input/keysymdef.js"></script>
+    <script type="text/javascript" src="static/noVNC/core/input/xtscancodes.js"></script>
+    <script type="text/javascript" src="static/noVNC/core/input/util.js"></script>
+    <script type="text/javascript" src="static/noVNC/core/input/devices.js"></script>
+    <script type="text/javascript" src="static/noVNC/core/display.js"></script>
+    <script type="text/javascript" src="static/noVNC/core/inflator.js"></script>
+    <script type="text/javascript" src="static/noVNC/core/rfb.js"></script>
+    <script type="text/javascript" src="static/noVNC/core/input/keysym.js"></script> 
 
-    <script type="text/javascript">
-        var INCLUDE_URI= "static/noVNC/include/";
-    </script>
 </head>
 
 <body>
@@ -67,7 +64,7 @@
                     <span class="icon-bar"></span>
                     <span class="icon-bar"></span>
                     </button>
-                    <a class="navbar-brand" href="#"><img style="max-width:100%; max-height:100%" src="static/img/logo.png" /></a>
+                    <a class="navbar-brand" href="#"><img style="max-width:100%; max-height:100%; height:50; width:73" src="static/img/logo.png" /></a>
                 </div>
 
                 <!-- Collect the nav links, forms, and other content for toggling -->
diff --git a/static/js/bmcApp.js b/static/js/bmcApp.js
index d4282ba..7d31cc2 100644
--- a/static/js/bmcApp.js
+++ b/static/js/bmcApp.js
@@ -10,7 +10,6 @@
   'ngResource'
 ]);
 
-
 app.controller('MainCtrl', ['$scope', function($scope) {
 
 }]);
@@ -71,8 +70,8 @@
   }
 }]);
 
-app.run(['$rootScope', '$cookieStore', '$state', '$resource', 'AuthenticationService',
-  function($rootScope, $cookieStore, $state, $resource, AuthenticationService) {
+app.run(['$rootScope', '$cookieStore', '$state', '$resource', 'AuthenticationService', '$http', '$templateCache',
+  function($rootScope, $cookieStore, $state, $resource, AuthenticationService, $http, $templateCache) {
     if ($rootScope.globals == undefined){
         $rootScope.globals = {};
     }
@@ -91,6 +90,8 @@
             $state.go('login');
           }
         });
+  
+    $http.get('static/partial-kvm.html', { cache: $templateCache });
   }
 ]);
 
diff --git a/static/js/kvmController.js b/static/js/kvmController.js
index d10a223..e3dcb14 100644
--- a/static/js/kvmController.js
+++ b/static/js/kvmController.js
@@ -24,7 +24,8 @@
                         'onUpdateState':  updateState,
                         //'onXvpInit':    xvpInit,
                         'onFBUComplete': FBUComplete,
-                        'onDesktopName': updateDesktopName
+                        'onDesktopName': updateDesktopName,
+                        'foobar': 1
                         });
         rfb.connect(host, port, password, path);
     } catch (exc) {