You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuscany.apache.org by js...@apache.org on 2013/01/03 08:41:56 UTC

svn commit: r1428193 [7/8] - in /tuscany/sca-cpp/trunk: etc/ hosting/server/ hosting/server/data/apps/me360/ hosting/server/data/apps/nearme/ hosting/server/data/apps/nearme2/ hosting/server/data/apps/new/ hosting/server/data/apps/ourphotos/ hosting/se...

Modified: tuscany/sca-cpp/trunk/modules/js/htdocs/component.js
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/js/htdocs/component.js?rev=1428193&r1=1428192&r2=1428193&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/js/htdocs/component.js (original)
+++ tuscany/sca-cpp/trunk/modules/js/htdocs/component.js Thu Jan  3 07:41:53 2013
@@ -38,11 +38,11 @@ var JSONClient = {};
  */
 JSONClient.escapeJSONChar = function(c) {
     if(c == "\"" || c == "\\") return "\\" + c;
-    if (c == "\b") return "\\b";
-    if (c == "\f") return "\\f";
-    if (c == "\n") return "\\n";
-    if (c == "\r") return "\\r";
-    if (c == "\t") return "\\t";
+    if(c == "\b") return "\\b";
+    if(c == "\f") return "\\f";
+    if(c == "\n") return "\\n";
+    if(c == "\r") return "\\r";
+    if(c == "\t") return "\\t";
     var hex = c.charCodeAt(0).toString(16);
     if(hex.length == 1) return "\\u000" + hex;
     if(hex.length == 2) return "\\u00" + hex;
@@ -110,11 +110,6 @@ function HTTPBindingClient(name, uri, do
 }
 
 /**
- * JSON-RPC request counter.
- */
-HTTPBindingClient.jsonrpcID = 1;
-
-/**
  * HTTPBindingClient implementation
  */
 
@@ -129,7 +124,7 @@ HTTPBindingClient.prototype.createApplyM
             args.push(arguments[i]);
 
         var cb = null;
-        if (typeof args[args.length - 1] == "function")
+        if(typeof args[args.length - 1] == "function")
             cb = args.pop();
 
         var req = HTTPBindingClient.makeJSONRequest(methodName, args, cb);
@@ -140,12 +135,17 @@ HTTPBindingClient.prototype.createApplyM
 };
 
 /**
+ * JSON-RPC request counter.
+ */
+HTTPBindingClient.jsonrpcID = 1;
+
+/**
  * Make a JSON-RPC request.
  */
 HTTPBindingClient.makeJSONRequest = function(methodName, args, cb) {
     var req = {};
     req.id = HTTPBindingClient.jsonrpcID++;
-    if (cb)
+    if(cb)
         req.cb = cb;
     var obj = {};
     obj.id = req.id;
@@ -164,8 +164,8 @@ HTTPBindingClient.jsonResult = function(
         try {
             var contentType = http.getResponseHeader("Content-Type");
             var parts = contentType.split(/\s*;\s*/);
-            for (var i = 0; i < parts.length; i++) {
-                if (parts[i].substring(0, 8) == "charset=")
+            for(var i = 0; i < parts.length; i++) {
+                if(parts[i].substring(0, 8) == "charset=")
                     return parts[i].substring(8, parts[i].length);
             }
         } catch (e) {}
@@ -184,48 +184,203 @@ HTTPBindingClient.jsonResult = function(
 };
 
 /**
+ * Schedule async requests, and limit to 4 concurrent running requests.
+ */
+HTTPBindingClient.queuedRequests = new Array();
+HTTPBindingClient.runningRequests = 0;
+HTTPBindingClient.scheduleAsyncRequest = function(f) {
+    // Queue the request function
+    HTTPBindingClient.queuedRequests.push(f);
+
+    // Execute requests in the queue
+    (function runAsyncRequests() {
+        // Stop now if we already have enough requests running or there's no request in the queue
+        //debug('runAsyncRequests', 'running', HTTPBindingClient.runningRequests, 'queued', HTTPBindingClient.queuedRequests.length);
+        if(HTTPBindingClient.runningRequests >= 4 || HTTPBindingClient.queuedRequests.length == 0)
+            return true;
+
+        // Run the first request in the queue
+        var req = HTTPBindingClient.queuedRequests.shift();
+        HTTPBindingClient.runningRequests++;
+        setTimeout(function runAsyncRequest() {
+            try {
+                return req(function asyncRequestDone() {
+                    // Execute any requests left in the queue
+                    HTTPBindingClient.runningRequests--;
+                    runAsyncRequests();
+                    return true;
+                });
+            } catch(e) {
+                // Execute any requests left in the queue
+                HTTPBindingClient.runningRequests--;
+                runAsyncRequests();
+            }
+        }, 0);
+
+        // Execute any requests left in the queue
+        runAsyncRequests();
+    })();
+    return true;
+};
+
+/**
+ * Get a cache item from local storage.
+ */
+HTTPBindingClient.getCacheItem = function(k) {
+    var ls = lstorage || localStorage;
+    return ls.getItem('cache.d.' + k);
+};
+
+/**
+ * Set a cache item in local storage.
+ */
+HTTPBindingClient.setCacheItem = function(k, v) {
+    HTTPBindingClient.collectCacheItems();
+    var ls = lstorage || localStorage;
+    try {
+        var s = ls.getItem('cache.size');
+        var size = parseInt(s);
+        var ov = ls.getItem('cache.d.' + k);
+        var nsize = size - (ov != null? ov.length : 0) + (v != null? v.length : 0);
+        if (nsize != size)
+            ls.setItem('cache.size', nsize.toString());
+    } catch(e) {}
+    return ls.setItem('cache.d.' + k, v);
+};
+
+/**
+* Remove a cache item from local storage.
+*/
+HTTPBindingClient.removeCacheItem = function(k) {
+    var ls = lstorage || localStorage;
+    try {
+        var s = ls.getItem('cache.size');
+        var size = parseInt(s);
+        var ov = ls.getItem('cache.d' + k);
+        if (ov != null) {
+            var nsize = size - ov.length;
+            ls.setItem('cache.size', nsize.toString());
+        }
+    } catch(e) {}
+    return ls.removeItem('cache.d.' + k);
+};
+
+/**
+ * Keep local storage cache entries under 2MB.
+ */
+HTTPBindingClient.maxCacheSize = /* 20000; */ 2097152;
+HTTPBindingClient.collectCacheSize = /* 10000; */ 1048576;
+HTTPBindingClient.collectCacheItems = function() {
+    var ls = window.lstorage || localStorage;
+    var nkeys = window.lstorage? function() { return ls.length(); } : function() { return ls.length; };
+    try {
+        // Get the current cache size
+        var size = 0;
+        var s = ls.getItem('cache.size');
+        if(s == null) {
+            // Calculate and store initial cache size
+            //debug('calculating cache size');
+            var n = nkeys();
+            for(var i = 0; i < n; i++) {
+                var k = ls.key(i);
+                if(k == null || k.substr(0, 8) != 'cache.d.')
+                    continue;
+                var v = ls.getItem(k);
+                if(v == null)
+                    continue;
+                size += v.length;
+            }
+            ls.setItem('cache.size', size.toString());
+        } else
+            size = parseInt(s);
+
+        // Nothing to do if it's below the max size
+        //debug('cache.size', size);
+        if (size <= HTTPBindingClient.maxCacheSize)
+            return false;
+
+        // Collect random cache entries until we reach our min size
+        //debug('collecting cache items');
+        var keys = new Array();
+        var n = nkeys();
+        for(var i = 0; i < n; i++) {
+            var k = ls.key(i);
+            if(k == null || k.substr(0, 8) != 'cache.d.')
+                continue;
+            keys.push(k);
+        }
+        while (keys.length != 0 && size >= HTTPBindingClient.collectCacheSize) {
+            var r = Math.floor(keys.length * Math.random());
+            if (r == keys.length)
+                continue;
+            var k = keys[r];
+            var v = ls.getItem(k);
+            //debug('collect cache item', k);
+            ls.removeItem(k);
+            keys.splice(r, 1);
+            if (v != null)
+                size = size - v.length;
+        }
+
+        // Store the new cache size
+        //debug('updated cache.size', size);
+        ls.setItem('cache.size', size.toString());
+        return true;
+    } catch(e) {}
+    return false;
+};
+
+/**
  * Apply a function remotely using JSON-RPC.
  */
 HTTPBindingClient.prototype.jsonApply = function(req) {
-    // Connect to the service
-    var http = HTTPBindingClient.getHTTPRequest();
     var hascb = req.cb? true : false;
-    http.open("POST", this.uri, hascb);
-    http.setRequestHeader("Accept", "*/*");
-    http.setRequestHeader("Content-Type", "application/json-rpc");
 
-    // Construct call back if we have one
+    // Call asynchronously with a callback
     if(hascb) {
-        http.onreadystatechange = function() {
-            if(http.readyState == 4) {
-                // Pass the result or exception
-                if(http.status == 200) {
-                    var res = null;
-                    try {
-                        res = HTTPBindingClient.jsonResult(http);
+        var u = this.uri;
+        return HTTPBindingClient.scheduleAsyncRequest(function jsonApplyRequest(done) {
+            var http = new XMLHttpRequest();
+            http.open("POST", u, true);
+            http.setRequestHeader("Accept", "*/*");
+            http.setRequestHeader("Content-Type", "application/json-rpc");
+            http.onreadystatechange = function() {
+                if(http.readyState == 4) {
+                    // Pass the result or exception
+                    if(http.status == 200) {
+                        var res = null;
                         try {
-                            req.cb(res);
-                        } catch(cbe) {}
-                    } catch(e) {
+                            res = HTTPBindingClient.jsonResult(http);
+                            try {
+                                req.cb(res);
+                            } catch(cbe) {}
+                        } catch(e) {
+                            try {
+                                req.cb(null, e);
+                            } catch(cbe) {}
+                        }
+                    } else {
                         try {
-                            req.cb(null, e);
+                            req.cb(null, HTTPBindingClient.Exception(http.status, http.statusText));
                         } catch(cbe) {}
                     }
-                } else
-                    try {
-                        req.cb(null, HTTPBindingClient.Exception(http.status, http.statusText));
-                    } catch(cbe) {}
-            }
-        };
+                    return done();
+                }
+            };
 
-        // Send the request
-        http.send(req.data);
-        return req.id;
+            // Send the request
+            http.send(req.data);
+            return req.id;
+        });
     }
 
-    // Send the request and return the result or exception
+    // Call synchronously and return the result or exception
+    var http = new XMLHttpRequest();
+    http.open("POST", this.uri, false);
+    http.setRequestHeader("Accept", "*/*");
+    http.setRequestHeader("Content-Type", "application/json-rpc");
     http.send(req.data);
-    if (http.status == 200)
+    if(http.status == 200)
         return HTTPBindingClient.jsonResult(http);
     throw new HTTPBindingClient.Exception(http.status, http.statusText);
 };
@@ -234,95 +389,104 @@ HTTPBindingClient.prototype.jsonApply = 
 /**
  * REST GET method.
  */
-HTTPBindingClient.prototype.get = function(id, cb) {
+HTTPBindingClient.prototype.get = function(id, cb, mode) {
     var u = id? (this.uri? this.uri + '/' + id : id) : this.uri;
     var hascb = cb? true : false;
 
     // Get from local storage first
-    var ls = window.lstorage || localStorage;
     var item = null;
-    try { item = ls.getItem(u); } catch(e) {}
-    //log('localStorage.getItem', u, item);
-    if (item != null && item != '') {
-        if (!hascb)
-            return item;
-
-        // Pass local result to callback
-        try {
-            cb(item);
-        } catch (cbe) {}
+    if(mode != 'remote') {
+        item = HTTPBindingClient.getCacheItem(u);
+        if(item != null && item != '') {
+            if(!hascb)
+                return item;
+
+            // Pass local result to callback
+            try {
+                cb(item);
+            } catch (cbe) {}
+        }
     }
 
-    // Connect to the service
-    var http = HTTPBindingClient.getHTTPRequest();
-    http.open("GET", u, hascb);
-    http.setRequestHeader("Accept", "*/*");
-
-    // Construct call back if we have one
-    if (hascb) {
-        http.onreadystatechange = function() {
-            //log('readystate', http.readyState, 'status', http.status, 'headers', http.getAllResponseHeaders());
-            if (http.readyState == 4) {
-                // Pass result if different from local result
-                if (http.status == 200) {
-
-                    if (http.getResponseHeader("X-Login") != null) { 
-                        // Detect redirect to a login page
-                        try {
-                            var le = new HTTPBindingClient.Exception(403, 'X-Login');
-                            if (window.onloginredirect)
-                                window.onloginredirect(le);
-                            return cb(null, le);
-                        } catch(cbe) {}
+    // Call asynchronously with a callback
+    if(hascb) {
+        return HTTPBindingClient.scheduleAsyncRequest(function getRequest(done) {
+            var http = new XMLHttpRequest();
+            http.open("GET", u, true);
+            http.setRequestHeader("Accept", "*/*");
+            http.onreadystatechange = function() {
+                //debug('readystate', http.readyState, 'status', http.status, 'headers', http.getAllResponseHeaders());
+                if(http.readyState == 4) {
+                    // Pass result if different from local result
+                    if(http.status == 200) {
+                        var xl = http.getResponseHeader("X-Login");
+                        if(xl != null && xl != '') {
+                            // Detect redirect to a login page
+                            try {
+                                var le = new HTTPBindingClient.Exception(403, 'X-Login');
+                                if(window.onloginredirect)
+                                    window.onloginredirect(le);
+                                cb(null, le);
+                                return done();
+                            } catch(cbe) {}
 
-                    } else if (http.responseText == '' || http.getResponseHeader("Content-Type") == null) {
-                        // Report empty response
-                        try {
-                            return cb(null, new HTTPBindingClient.Exception(403, 'No-Content'));
-                        } catch(cbe) {}
+                        }
+                        var ct = http.getResponseHeader("Content-Type");
+                        if(http.responseText == '' || ct == null || ct == '') {
+                            // Report empty response
+                            try {
+                                cb(null, new HTTPBindingClient.Exception(403, 'No-Content'));
+                                return done();
+                            } catch(cbe) {}
 
-                    } else {
-                        if (item == null || http.responseText != item) {
-                            // Store retrieved entry in local storage
-                            if (http.responseText != null) {
-                                //log('localStorage.setItem', u, http.responseText);
-                                try { ls.setItem(u, http.responseText); } catch(e) {}
+                        } else {
+                            if(item == null || http.responseText != item) {
+                                // Store retrieved entry in local storage
+                                if(http.responseText != null)
+                                    HTTPBindingClient.setCacheItem(u, http.responseText);
+                                try {
+                                    cb(http.responseText);
+                                    return done();
+                                } catch(cbe) {}
                             }
+                        }
+                    }
+                    else {
+                        // Pass exception if we didn't have a local result
+                        if(item == null) {
                             try {
-                                return cb(http.responseText);
+                                cb(null, new HTTPBindingClient.Exception(http.status, http.statusText));
+                                return done();
                             } catch(cbe) {}
                         }
                     }
+                    return done();
                 }
-                else {
-                    // Pass exception if we didn't have a local result
-                    if (item == null) {
-                        try {
-                            return cb(null, new HTTPBindingClient.Exception(http.status, http.statusText));
-                        } catch(cbe) {}
-                    }
-                }
-            }
-        };
+            };
 
-        // Send the request
-        http.send(null);
-        return true;
+            // Send the request
+            http.send(null);
+            return true;
+        });
     }
 
-    // Send the request and return the result or exception
+    // Call synchronously and return the result or exception
+    var http = new XMLHttpRequest();
+    http.open("GET", u, false);
+    http.setRequestHeader("Accept", "*/*");
     http.send(null);
-    if (http.status == 200) {
-        if (http.getResponseHeader("X-Login") != null) {
-
+    if(http.status == 200) {
+        var xl = http.getResponseHeader("X-Login");
+        if(xl != null && xl != '') {
             // Detect redirect to a login page
             var le = new HTTPBindingClient.Exception(403, 'X-Login');
-            if (window.onloginredirect)
+            if(window.onloginredirect)
                 window.onloginredirect(le);
             throw le;
 
-        } else if (http.responseText == '' || http.getResponseHeader("Content-Type") == null) {
-
+        }
+        var ct = http.getResponseHeader("Content-Type");
+        if(http.responseText == '' || ct == null || ct == '') {
             // Report empty response
             throw new HTTPBindingClient.Exception(403, 'No-Content');
         }
@@ -332,207 +496,187 @@ HTTPBindingClient.prototype.get = functi
 };
 
 /**
- * REST GET method, does not use the local cache.
+ * REST POST method.
  */
-HTTPBindingClient.prototype.getnocache = function(id, cb) {
-    var u = id? (this.uri? this.uri + '/' + id : id) : this.uri;
+HTTPBindingClient.prototype.post = function (entry, cb) {
     var hascb = cb? true : false;
 
-    // Connect to the service
-    var http = HTTPBindingClient.getHTTPRequest();
-    http.open("GET", u, hascb);
-    http.setRequestHeader("Accept", "*/*");
-
-    // Construct call back if we have one
-    if (hascb) {
-        http.onreadystatechange = function() {
-            if (http.readyState == 4) {
-                if (http.status == 200) {
-
-                    if (http.getResponseHeader("X-Login") != null) {
-                        // Detect redirect to a login page
-                        try {
-                            var le = new HTTPBindingClient.Exception(403, 'X-Login');
-                            if (window.onloginredirect)
-                                window.onloginredirect(le);
-                            return cb(null, le);
-                        } catch(cbe) {}
-
-                    } else if (http.responseText == '' || http.getResponseHeader("Content-Type") == null) {
-                        // Report empty response
+    // Call asynchronously with a callback
+    if(hascb) {
+        var u = this.uri;
+        return HTTPBindingClient.scheduleAsyncRequest(function postRequest(done) {
+            var http = new XMLHttpRequest();
+            http.open("POST", u, true);
+            http.setRequestHeader("Accept", "*/*");
+            http.setRequestHeader("Content-Type", "application/atom+xml");
+            http.onreadystatechange = function() {
+                if(http.readyState == 4) {
+                    if(http.status == 201) {
+                        // Successful result
                         try {
-                            return cb(null, new HTTPBindingClient.Exception(403, 'No-Content'));
+                            cb(http.responseText);
                         } catch(cbe) {}
-
-                    } else {
+                    }
+                    else {
+                        // Report status code as an exception
                         try {
-                            return cb(http.responseText);
+                            cb(null, new HTTPBindingClient.Exception(http.status, http.statusText));
                         } catch(cbe) {}
                     }
-                } else {
-                    try {
-                        return cb(null, new HTTPBindingClient.Exception(http.status, http.statusText));
-                    } catch(cbe) {}
+                    return done();
                 }
-            }
-        };
-
-        // Send the request
-        http.send(null);
-        return true;
-    }
-
-    // Send the request and return the result or exception
-    http.send(null);
-    if (http.status == 200) {
-        if (http.getResponseHeader("X-Login") != null) {
-
-            // Detect redirect to a login page
-            var le = new HTTPBindingClient.Exception(403, 'X-Login');
-            if (window.onloginredirect)
-                window.onloginredirect(le);
-            throw le;
-
-        } else if (http.responseText == '' || http.getResponseHeader("Content-Type") == null) {
-
-            // Report empty response
-            throw new HTTPBindingClient.Exception(403, 'No-Content');
-        }
-        return http.responseText;
+            };
+            // Send the request
+            http.send(entry);
+            return true;
+        });
     }
-    throw new HTTPBindingClient.Exception(http.status, http.statusText);
-};
 
-/**
- * REST POST method.
- */
-HTTPBindingClient.prototype.post = function (entry, cb) {
-
-    // Connect to the service
-    var http = HTTPBindingClient.getHTTPRequest();
+    // Call synchronously
+    var http = new XMLHttpRequest();
     var hascb = cb? true : false;
-    http.open("POST", this.uri, hascb);
+    http.open("POST", this.uri, false);
     http.setRequestHeader("Accept", "*/*");
     http.setRequestHeader("Content-Type", "application/atom+xml");
-
-    // Construct call back if we have one
-    if (hascb) {
-        http.onreadystatechange = function() {
-            // Pass the result or exception
-            if (http.readyState == 4) {
-                if (http.status == 201) {
-                    try {
-                        cb(http.responseText);
-                    } catch(cbe) {}
-                }
-                else {
-                    try {
-                        cb(null, new HTTPBindingClient.Exception(http.status, http.statusText));
-                    } catch(cbe) {}
-                }
-            }
-        };
-        // Send the request
-        http.send(entry);
-        return true;
-    }
-
-    // Send the request and return the result or exception
     http.send(entry);
-    if (http.status == 201)
+    if(http.status == 201)
         return http.responseText;
+
+    // Return status code as an exception
     throw new HTTPBindingClient.Exception(http.status, http.statusText);
 };
 
 /**
  * REST PUT method.
  */
-HTTPBindingClient.prototype.put = function (id, entry, cb) {
-    var u = this.uri + '/' + id;
+HTTPBindingClient.prototype.put = function(id, entry, cb, mode) {
+    var u = id? (this.uri? this.uri + '/' + id : id) : this.uri;
+    var hascb = cb? true : false;
 
     // Update local storage
-    var ls = window.lstorage || localStorage;
-    try { ls.setItem(u, entry); } catch(e) {}
-    //log('localStorage.setItem', u, entry);
+    var oentry = null;
+    if(mode != 'remote') {
+        oentry = HTTPBindingClient.getCacheItem(u);
+        HTTPBindingClient.setCacheItem(u, entry);
+    }
 
-    // Connect to the service
-    var http = HTTPBindingClient.getHTTPRequest();
-    var hascb = cb? true : false;
-    http.open("PUT", u, hascb);
-    http.setRequestHeader("Accept", "*/*");
-    http.setRequestHeader("Content-Type", "application/atom+xml");
+    // Call asynchronously with a callback
+    if(hascb) {
+        return HTTPBindingClient.scheduleAsyncRequest(function putRequest(done) {
+            var http = new XMLHttpRequest();
+            http.open("PUT", u, true);
+            http.setRequestHeader("Accept", "*/*");
+            http.setRequestHeader("Content-Type", "application/atom+xml");
+            http.onreadystatechange = function() {
+                if(http.readyState == 4) {
+                    if(http.status == 200) {
+                        // Successful result
+                        try {
+                            cb();
+                        } catch(cbe) {}
+                    } else {
+                        if(http.status == 404) {
+                            // Undo local storage update
+                            if(mode != 'remote') {
+                                try {
+                                    if(oentry != null)
+                                        HTTPBindingClient.setCacheItem(u, oentry);
+                                    else
+                                        HTTPBindingClient.removeCacheItem(u);
+                                } catch(e) {}
+                            }
+                        }
 
-    // Construct call back if we have one
-    if (hascb) {
-        http.onreadystatechange = function() {
-            if (http.readyState == 4) {
-                // Pass any exception
-                if (http.status == 200) {
-                    try {
-                        cb();
-                    } catch(cbe) {}
-                } else {
-                    try {
-                        cb(new HTTPBindingClient.Exception(http.status, http.statusText));
-                    } catch(cbe) {}
+                        // Report status code as an exception
+                        try {
+                            cb(new HTTPBindingClient.Exception(http.status, http.statusText));
+                        } catch(cbe) {}
+                    }
+                    return done();
                 }
-            }
-        };
-        // Send the request
-        http.send(entry);
-        return true;
+            };
+
+            // Send the request
+            http.send(entry);
+            return true;
+        });
     }
 
-    // Send the request and return any exception
+    // Call synchronously
+    var http = new XMLHttpRequest();
+    http.open("PUT", u, false);
+    http.setRequestHeader("Accept", "*/*");
+    http.setRequestHeader("Content-Type", "application/atom+xml");
     http.send(entry);
-    if (http.status == 200)
+    if(http.status == 200)
         return true;
+    if(http.status == 404) {
+        // Undo local storage update
+        if(mode != 'remote') {
+            try {
+                if(oentry != null)
+                    HTTPBindingClient.setCacheItem(u, oentry);
+                else
+                    HTTPBindingClient.removeCacheItem(u);
+            } catch(e) {}
+        }
+    }
+
+    // Return status code as an exception
     throw new HTTPBindingClient.Exception(http.status, http.statusText);
 };
 
 /**
  * REST DELETE method.
  */
-HTTPBindingClient.prototype.del = function (id, cb) {       
-    var u = this.uri + '/' + id;
+HTTPBindingClient.prototype.del = function(id, cb, mode) {
+    var u = id? (this.uri? this.uri + '/' + id : id) : this.uri;
+    var hascb = cb? true : false;
 
     // Update local storage
     var ls = window.lstorage || localStorage;
-    try { ls.removeItem(u); } catch(e) {}
-    //log('localStorage.removeItem', u);
-
-    // Connect to the service
-    var http = HTTPBindingClient.getHTTPRequest();
-    var hascb = cb? true : false;
-    http.open("DELETE", u, hascb);        
-    http.setRequestHeader("Accept", "*/*");
+    if(mode != 'remote')
+        HTTPBindingClient.removeCacheItem(u);
 
-    // Construct call back if we have one
-    if (cb) {
-        http.onreadystatechange = function() {
-            if (http.readyState == 4) {
-                // Pass any exception
-                if (http.status == 200) {
-                    try {
-                        cb();
-                    } catch(cbe) {}
-                }
-                else {
-                    try {
-                        cb(new HTTPBindingClient.Exception(http.status, http.statusText));
-                    } catch(cbe) {}
+    // Call asynchronously with a callback
+    if(hascb) {
+        return HTTPBindingClient.scheduleAsyncRequest(function delRequest(done) {
+            var http = new XMLHttpRequest();
+            http.open("DELETE", u, true);        
+            http.setRequestHeader("Accept", "*/*");
+            http.onreadystatechange = function() {
+                if(http.readyState == 4) {
+                    if(http.status == 200) {
+                        // Successful result
+                        try {
+                            cb();
+                        } catch(cbe) {}
+                    }
+                    else {
+                        // Report status code as an exception
+                        try {
+                            cb(new HTTPBindingClient.Exception(http.status, http.statusText));
+                        } catch(cbe) {}
+                    }
+                    return done();
                 }
-            }
-        };
-        // Send the request
-        http.send(null);
-        return true;
+            };
+
+            // Send the request
+            http.send(null);
+            return true;
+        });
     }
 
-    // Send the request and return any exception
+    // Call synchronously
+    var http = new XMLHttpRequest();
+    http.open("DELETE", u, false);        
+    http.setRequestHeader("Accept", "*/*");
     http.send(null);
-    if (http.status == 200)
+    if(http.status == 200)
         return true;
+
+    // Report status code as an exception
     throw new HTTPBindingClient.Exception(http.status, http.statusText);
 };
 
@@ -552,38 +696,6 @@ HTTPBindingClient.Exception.prototype.to
 };
 
 /**
- * XMLHttpRequest wrapper.
- */
-HTTPBindingClient.msxmlNames = [ "MSXML2.XMLHTTP.5.0", "MSXML2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP" ];
-
-HTTPBindingClient.getHTTPRequest = function() {
-    if (HTTPBindingClient.httpFactory)
-        return HTTPBindingClient.httpFactory();
-
-    // Mozilla XMLHttpRequest
-    try {
-        HTTPBindingClient.httpFactory = function() {
-            return new XMLHttpRequest();
-        };
-        return HTTPBindingClient.httpFactory();
-    } catch(e) {}
-
-    // Microsoft MSXML ActiveX
-    for (var i = 0; i < HTTPBindingClient.msxmlNames.length; i++) {
-        try {
-            HTTPBindingClient.httpFactory = function() {
-                return new ActiveXObject(HTTPBindingClient.msxmlNames[i]);
-            };
-            return HTTPBindingClient.httpFactory();
-        } catch (e) {}
-    }
-
-    // Can't create XMLHttpRequest
-    HTTPBindingClient.httpFactory = null;
-    throw new HTTPBindingClient.Exception(0, "Can't create XMLHttpRequest object");
-};
-
-/**
  * Public API.
  */
 
@@ -600,7 +712,7 @@ sca.httpclient = function(name, uri, dom
  * Return a component proxy.
  */
 sca.component = function(name, domain) {
-    if (!domain)
+    if(!domain)
         return new HTTPBindingClient(name, '/c/' + name, domain);
     return new HTTPBindingClient(name, '/' + domain + '/c/' + name, domain);
 };
@@ -609,7 +721,7 @@ sca.component = function(name, domain) {
  * Return a reference proxy.
  */
 sca.reference = function(comp, rname) {
-    if (!comp.domain)
+    if(!comp.domain)
         return new HTTPBindingClient(comp.name + '/' + rname, '/r/' + comp.name + '/' + rname, comp.domain);
     return new HTTPBindingClient(comp.name + '/' + rname, '/' + comp.domain + '/r/' + comp.name + '/' + rname, comp.domain);
 };
@@ -622,13 +734,13 @@ sca.defun = function(ref) {
         return function() {
             var args = new Array();
             args[0] = name;
-            for (i = 0, n = arguments.length; i < n; i++)
+            for(i = 0, n = arguments.length; i < n; i++)
                 args[i + 1] = arguments[i];
             return this.apply.apply(this, args);
         };
     }
 
-    for (f = 1; f < arguments.length; f++) {
+    for(f = 1; f < arguments.length; f++) {
         var fn = arguments[f];
         ref[fn]= defapply(fn);
     }

Modified: tuscany/sca-cpp/trunk/modules/js/htdocs/ui.css
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/js/htdocs/ui.css?rev=1428193&r1=1428192&r2=1428193&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/js/htdocs/ui.css (original)
+++ tuscany/sca-cpp/trunk/modules/js/htdocs/ui.css Thu Jan  3 07:41:53 2013
@@ -17,10 +17,14 @@
  * under the License.
  */
 
-body {
+/**
+ * Main body.
+ */
+body, .body {
 margin-top: 0px; margin-bottom: 2px; margin-left: 2px; margin-right: 2px;
-font-family: Arial; font-style: normal; font-variant: normal; font-size: 14px;
+font-family: "Lucida Grande", Helvetica, Arial; font-style: normal; font-variant: normal; font-size: 14px;
 background-color: #ffffff; opacity: 1;
+-webkit-font-smoothing: subpixel-antialiased;
 -webkit-text-size-adjust: none;
 -webkit-touch-callout: none;
 -webkit-tap-highlight-color: rgba(0,0,0,0);
@@ -30,35 +34,33 @@ cursor: default;
 }
 
 .delayed {
-visibility: hidden;
-}
-
-.fixed {
-position: fixed;
+display: none;
 }
 
-.devicewidth {
-position: absolute; top: 0px; left: 0px; width: 100%; height: 5000px; overflow: hidden;
+.installer {
+position: relative; width: 0px; height: 0px; display: none; visibility: hidden; background: transparent;
 }
 
-.mainbody {
-position: absolute; top: 0px; left: 0px; width: 100%; height: 5000px; overflow: visible;
--webkit-backface-visibility: hidden;
+.filler {
+position: relative; left: 0px; top: 0px; width: 1px; background: transparent; z-index: -20;
 }
 
+/**
+ * Main view.
+ */
 .viewcontainer3dm {
-position: absolute; left: 0px; top: 35px; width: 100%;
+position: fixed; left: 0px; top: 70px; right: 0px; bottom: 25px; padding-top: 2px; padding-bottom: 2px;
 -webkit-backface-visibility: hidden;
 }
 
 .viewcontainer3d {
-position: absolute; left: 0px; top: 35px; width: 100%;
+position: fixed; left: 0px; top: 70px; right: 0px; bottom: 25px; padding-top: 2px; padding-bottom: 2px;
 -webkit-backface-visibility: hidden;
 }
 
 .leftviewloading3dm {
-position: absolute; top: 0px; left: 0px; width: 100%; height: 5000px; overflow: hidden;
-z-index: -10; background-color: #ffffff;
+position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px;
+z-index: -5; background-color: #ffffff;
 -webkit-transform: translate(100%, 0px);
 -moz-transform: translate(100%, 0px);
 -ms-transform: translate(100%, 0px);
@@ -68,8 +70,8 @@ transform: translate(100%, 0px);
 }
 
 .rightviewloading3dm {
-position: absolute; top: 0px; left: 0px; width: 100%; height: 5000px; overflow: hidden;
-z-index: -10; background-color: #ffffff;
+position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px;
+z-index: -5; background-color: #ffffff;
 -webkit-transform: translate(-100%, 0px);
 -moz-transform: translate(-100%, 0px);
 -ms-transform: translate(-100%, 0px);
@@ -79,8 +81,8 @@ transform: translate(-100%, 0px);
 }
 
 .viewloading3d {
-position: absolute; top: 0px; left: 0px; width: 100%; height: 5000px; overflow: hidden;
-visibility: hidden; z-index: -10; background-color: #ffffff;
+position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px;
+z-index: -5; background-color: #ffffff;
 -webkit-transform: translate(100%, 0px);
 -moz-transform: translate(100%, 0px);
 -ms-transform: translate(100%, 0px);
@@ -90,7 +92,7 @@ transform: translate(100%, 0px);
 }
 
 .viewloaded3dm {
-position: absolute; top: 0px; left: 0px; width: 100%; height: 5000px; overflow: visible;
+position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px;
 z-index: 0; background-color: #ffffff;
 -webkit-transition: -webkit-transform 0.4s ease-in-out;
 -moz-transition: -moz-transform 0.4s ease-in-out;
@@ -106,7 +108,7 @@ transform: translate(0px, 0px);
 }
 
 .viewloaded3d {
-position: absolute; top: 0px; left: 0px; width: 100%; height: 5000px; overflow: visible;
+position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px;
 z-index: 0; background-color: #ffffff;
 -webkit-transform: translate(0px, 0px);
 -moz-transform: translate(0px, 0px);
@@ -117,8 +119,8 @@ transform: translate(0px, 0px);
 }
 
 .viewunloading3dm {
-position: absolute; top: 0px; left: 0px; width: 100%; height: 5000px; overflow: hidden;
-z-index: 0; background-color: #ffffff;
+position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px;
+z-index: -10; background-color: #ffffff;
 -webkit-transform: translate(0px, 0px);
 -moz-transform: translate(0px, 0px);
 -ms-transform: translate(0px, 0px);
@@ -128,7 +130,7 @@ transform: translate(0px, 0px);
 }
 
 .leftviewunloaded3dm {
-position: absolute; top: 0px; left: 0px; width: 100%; height: 5000px; overflow: hidden;
+position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px;
 z-index: -10; background-color: #ffffff;
 -webkit-transition: -webkit-transform 0.4s ease-in-out;
 -moz-transition: -moz-transform 0.4s ease-in-out;
@@ -144,7 +146,7 @@ transform: translate(-100%, 0px);
 }
 
 .rightviewunloaded3dm {
-position: absolute; top: 0px; left: 0px; width: 100%; height: 5000px; overflow: hidden;
+position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px;
 z-index: -10; background-color: #ffffff;
 -webkit-transition: -webkit-transform 0.4s ease-in-out;
 -moz-transition: -moz-transform 0.4s ease-in-out;
@@ -159,44 +161,109 @@ transform: translate(100%, 0px);
 -webkit-backface-visibility: hidden;
 }
 
-.body {
-width: 100%; height: 5000px; overflow: visible;
+.viewunloaded3d {
+position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px;
+z-index: -10; background-color: #ffffff;
+-webkit-transform: translate(-100%, 0px);
+-moz-transform: translate(-100%, 0px);
+-ms-transform: translate(-100%, 0px);
+-o-transform: translate(-100%, 0px);
+transform: translate(-100%, 0px);
 -webkit-backface-visibility: hidden;
 }
 
-.viewhead {
-position: absolute; left: 0px; top: 35px; height: 35px; line-height: 35px; width: 100%; z-index: 8;
-font-size: 110%; font-weight: bold; background-color: #f1f1f1; color: #000000;
-border-top: 1px; border-bottom: 1px; border-left: 0px; border-right: 0px;
-border-style: solid; border-top-color: #e5e5e5; border-bottom-color: #e5e5e5;
-overflow: hidden;
+.viewcontent {
+position: absolute; left: 0px; top: 2px; right: 0px; bottom: 0px;
+overflow-x: hidden; overflow-y: scroll; -webkit-overflow-scrolling: touch;
 -webkit-backface-visibility: hidden;
 }
 
-.viewheadbackground {
-position: absolute; left: 0px; top: 35px; height: 35px; line-height: 35px; width: 2500px; z-index: 7;
-background-color: #f1f1f1;
+.viewform {
+position: absolute; left: 0px; top: 2px; right: 0px; bottom: 0px;
+overflow-x: hidden; overflow-y: scroll; -webkit-overflow-scrolling: touch;
+-webkit-backface-visibility: hidden;
+}
+
+/**
+ * View header and footer.
+ */
+.viewhead {
+position: fixed; left: 0px; top: 35px; height: 35px; line-height: 35px; width: 100%; z-index: 8;
+font-size: 15px; font-weight: bold; background-color: #f5f5f5; color: #000000;
 border-top: 1px; border-bottom: 1px; border-left: 0px; border-right: 0px;
 border-style: solid; border-top-color: #e5e5e5; border-bottom-color: #e5e5e5;
-overflow: hidden;
 -webkit-backface-visibility: hidden;
 }
 
 .viewfoot {
-position: absolute; left: 0px; bottom: 0px; height: 25px; line-height: 25px; width: 100%; z-index: 8;
+position: fixed; left: 0px; bottom: 0px; height: 25px; line-height: 25px; width: 100%; z-index: 8;
 font-size: 12px; background-color: #ffffff; color: #404040;
 border-top: 1px; border-bottom: 1px; border-left: 0px; border-right: 0px;
 border-style: solid; border-top-color: #e5e5e5; border-bottom-color: #ffffff;
-overflow: hidden;
 -webkit-backface-visibility: hidden;
 }
 
-.status {
-position: absolute; left: 0px; bottom: 0px; height: 35px; line-height: 35px; width: 100%; z-index: 9;
-font-size: 12px; background-color: #ffffff; color: #404040;
+.note {
+font-size: 12px; color: #808080;
+text-transform: none;
+}
+
+/**
+ * Menu toolbar.
+ */
+.tbarmenu {
+position: fixed; top: 0px; left: 0px; z-index: 10; width: 100%; margin: 0px; padding: 0px; border-collapse: separate;
+height: 35px; line-height: 35px; background-color: #2c2c2c;
+border-top: 1px; border-bottom: 1px; border-left: 0px; border-right: 0px; border-style: solid; border-top-color: #2c2c2c; border-bottom-color: #2c2c2c;
+-webkit-backface-visibility: hidden;
+}
+
+.tbarleft {
+padding-left: 2px; padding-right: 6px; white-space: nowrap; float: left;
+text-transform: uppercase;
+}
+
+.tbarright {
+padding-left: 6px; padding-right: 2px; white-space: nowrap; float: right;
+}
+
+.tbaramenu {
+font-size: 15px; color: #cccccc; text-decoration: none; white-space: nowrap;
+}
+
+.tbarsmenu {
+font-size: 15px; font-weight: bold; color: #ffffff; text-decoration: none; white-space: nowrap;
+}
+
+.amenu {
+padding-left: 2px; padding-right: 6px; white-space: nowrap; color: #808080; text-decoration: none; float: left;
+}
+
+.smenu {
+padding-left: 2px; padding-right: 6px; white-space: nowrap; color: #000000; text-decoration: none; float: left;
+}
+
+.cmenu {
+font-size: 15px; padding-left: 6px; padding-right: 6px; white-space: nowrap; color: #000000; text-decoration: none; float: left;
+padding-left: 45px;
+}
+
+.bcmenu {
+font-size: 22px; padding-left: 2px; padding-right: 6px; white-space: nowrap; color: #000000; text-decoration: none;
+}
+
+.rmenu {
+padding-left: 2px; padding-right: 2px; white-space: nowrap; white-space: nowrap; float: right;
+}
+
+/**
+ * Status bar.
+ */
+.status3d {
+position: absolute; left: 0px; bottom: 0px; height: 25px; line-height: 25px; width: 100%; z-index: 9;
+background-color: #ffffff; color: #404040;
 border-top: 0px; border-bottom: 0px; border-left: 0px; border-right: 0px;
 border-style: solid; border-top-color: #e5e5e5; border-bottom-color: #ffffff;
-overflow: hidden;
 -webkit-transform: translate(0px, 0px);
 -moz-transform: translate(0px, 0px);
 -ms-transform: translate(0px, 0px);
@@ -205,232 +272,244 @@ transform: translate(0px, 0px);
 -webkit-backface-visibility: hidden;
 }
 
-.statusout3 {
-position: absolute; left: 0px; bottom: 0px; height: 35px; line-height: 35px; width: 100%; z-index: 9;
-font-size: 12px; background-color: #ffffff; color: #404040;
+.statusout3d {
+position: absolute; left: 0px; bottom: 0px; height: 25px; line-height: 25px; width: 100%; z-index: 9;
+background-color: #ffffff; color: #404040;
 border-top: 0px; border-bottom: 0px; border-left: 0px; border-right: 0px;
 border-style: solid; border-top-color: #e5e5e5; border-bottom-color: #ffffff;
-overflow: hidden;
--webkit-transition: -webkit-transform 0.4s ease-in-out 3s;
--moz-transition: -moz-transform 0.4s ease-in-out 3s;
--ms-transition: -ms-transform 0.4s ease-in-out 3s;
--o-transition: -o-transform 0.4s ease-in-out 3s;
-transition: transform 0.4s ease-in-out 3s;
--webkit-transform: translate(0px, 35px);
--moz-transform: translate(0px, 35px);
--ms-transform: translate(0px, 35px);
--o-transform: translate(0px, 35px);
-transform: translate(0px, 35px);
+-webkit-transition: -webkit-transform 0.4s ease-in-out;
+-moz-transition: -moz-transform 0.4s ease-in-out;
+-ms-transition: -ms-transform 0.4s ease-in-out;
+-o-transition: -o-transform 0.4s ease-in-out;
+transition: transform 0.4s ease-in-out;
+-webkit-transform: translate(0px, 25px);
+-moz-transform: translate(0px, 25px);
+-ms-transform: translate(0px, 25px);
+-o-transform: translate(0px, 25px);
+transform: translate(0px, 25px);
 -webkit-backface-visibility: hidden;
 }
 
-.statusout1 {
-position: absolute; left: 0px; bottom: 0px; height: 35px; line-height: 35px; width: 100%; z-index: 9;
-font-size: 12px; background-color: #ffffff; color: #404040;
+.status3dm {
+position: absolute; left: 0px; bottom: 0px; height: 25px; line-height: 25px; width: 100%; z-index: 9;
+background-color: #ffffff; color: #404040;
 border-top: 0px; border-bottom: 0px; border-left: 0px; border-right: 0px;
 border-style: solid; border-top-color: #e5e5e5; border-bottom-color: #ffffff;
-overflow: hidden;
--webkit-transition: -webkit-transform 0.4s ease-in-out 1s;
--moz-transition: -moz-transform 0.4s ease-in-out 1s;
--ms-transition: -ms-transform 0.4s ease-in-out 1s;
--o-transition: -o-transform 0.4s ease-in-out 1s;
-transition: transform 0.4s ease-in-out 1s;
--webkit-transform: translate(0px, 35px);
--moz-transform: translate(0px, 35px);
--ms-transform: translate(0px, 35px);
--o-transform: translate(0px, 35px);
-transform: translate(0px, 35px);
+-webkit-transform: translate(0px, 0px);
+-moz-transform: translate(0px, 0px);
+-ms-transform: translate(0px, 0px);
+-o-transform: translate(0px, 0px);
+transform: translate(0px, 0px);
+-webkit-backface-visibility: hidden;
+}
+
+.statusout3dm {
+position: absolute; left: 0px; bottom: 0px; height: 25px; line-height: 25px; width: 100%; z-index: 9;
+background-color: #ffffff; color: #404040;
+border-top: 0px; border-bottom: 0px; border-left: 0px; border-right: 0px;
+border-style: solid; border-top-color: #e5e5e5; border-bottom-color: #ffffff;
+-webkit-transition: -webkit-transform 0.4s ease-in-out;
+-moz-transition: -moz-transform 0.4s ease-in-out;
+-ms-transition: -ms-transform 0.4s ease-in-out;
+-o-transition: -o-transform 0.4s ease-in-out;
+transition: transform 0.4s ease-in-out;
+-webkit-transform: translate(0px, 25px);
+-moz-transform: translate(0px, 25px);
+-ms-transform: translate(0px, 25px);
+-o-transform: translate(0px, 25px);
+transform: translate(0px, 25px);
 -webkit-backface-visibility: hidden;
 }
 
 .okstatus {
-font-size: 110%; font-weight: bold; padding-left: 6px; padding-right: 6px; white-space: nowrap; text-decoration: none;
-background-color: #f1f1f1; color: #000000;
+font-size: 14px; padding-left: 6px; padding-right: 6px; white-space: nowrap; text-decoration: none;
+background-color: #f5f5f5; color: #000000;
 width: 100%; margin-left: auto; margin-right: auto; text-align: center; float: right;
 }
 
 .errorstatus {
-font-size: 110%; font-weight: bold; padding-left: 6px; padding-right: 6px; white-space: nowrap; text-decoration: none;
+font-size: 14px; padding-left: 6px; padding-right: 6px; white-space: nowrap; text-decoration: none;
 background-color: #d14836; color: #ffffff;
 width: 100%; margin-left: auto; margin-right: auto; text-align: center; float: right;
 }
 
-.viewfootbackground {
-position: absolute; left: 0px; bottom: 0px; height: 25px; line-height: 25px; width: 2500px; z-index: 7;
-background-color: #ffffff;
-border-top: 1px; border-bottom: 1px; border-left: 0px; border-right: 0px;
-border-style: solid; border-top-color: #e5e5e5; border-bottom-color: #ffffff;
-overflow: hidden;
--webkit-backface-visibility: hidden;
+/**
+ * Working status animation.
+ */
+.working {
+position: fixed; z-index: 15; display: none; width: 60px; height: 60px; left: 50%; top: 50%; border-bottom-color: transparent;
+margin: -50px 0 0 -50px; border: 20px solid #c0c0c0; border-right-color: transparent;
+border-radius: 50%; -webkit-border-radius: 50%; -moz-border-radius: 50%;
+-webkit-box-shadow: 0 0 45px 5px #f5f5f5; -moz-box-shadow: 0 0 45px 5px #f5f5f5; -ms-box-shadow: 0 0 45px 5px #f5f5f5;
+-o-box-shadow: 0 0 45px 5px #f5f5f5; box-shadow: 0 0 45px 5px #f5f5f5;
+-webkit-animation: spin 1s linear infinite;
+-moz-animation: spin 1s linear infinite;
+-ms-animation: spin 1s linear infinite;
+-o-animation: spin 1s linear infinite;
+animation: spin 1s linear infinite;
 }
 
-.viewcontent {
-position: absolute; left: 0px; top: 38px; width: 100%;
--webkit-backface-visibility: hidden;
+@-webkit-keyframes spin {
+from { -webkit-transform: rotate(0deg); opacity: 0.4; }
+50% { -webkit-transform: rotate(180deg); opacity: 1; }
+to { -webkit-transform: rotate(360deg); opacity: 0.4; }
 }
 
-.viewform {
-position: absolute; left: 0px; top: 40px; width: 100%;
+@-moz-keyframes spin {
+from { -moz-transform: rotate(0deg); opacity: 0.4; }
+50% { -moz-transform: rotate(180deg); opacity: 1; }
+to { -moz-transform: rotate(360deg); opacity: 0.4; }
 }
 
-table {
-border: 0px; border-collapse: collapse; border-color: #a2bae7; border-style: solid;
-font-family: Arial; font-style: normal; font-variant: normal; font-size: 14px;
-overflow: visible;
+@-ms-keyframes spin {
+from { -ms-transform: rotate(0deg); opacity: 0.4; }
+50% { -ms-transform: rotate(180deg); opacity: 1; }
+to { -ms-transform: rotate(360deg); opacity: 0.4; }
 }
 
-.trb {
-border-bottom: 1px; border-bottom-style: solid; border-color: #dcdcdc;
+@-o-keyframes spin {
+from { -o-transform: rotate(0deg); opacity: 0.4; }
+50% { -o-transform: rotate(180deg); opacity: 1; }
+to { -o-transform: rotate(360deg); opacity: 0.4; }
 }
 
-th {
-font-size: 110%; font-weight: bold; background-color: #f1f1f1; color: #000000;
-text-align: left; padding-left: 2px; padding-right: 8px; padding-top: 0px; padding-bottom: 0px; vertical-align: middle; white-space: nowrap;
-border-top: 1px; border-bottom: 1px; border-left: 1px; border-right: 1px; border-style: solid; border-top-color: #e5e5e5; border-bottom-color: #e5e5e5; border-left-color: #e5e5e5; border-right-color: #e5e5e5;
-overflow: hidden;
+@keyframes spin {
+from { transform: rotate(0deg); opacity: 0.4; }
+50% { transform: rotate(180deg); opacity: 1; }
+to { transform: rotate(360deg); opacity: 0.4; }
 }
 
-.section {
-font-size: 110%; font-weight: bold; background-color: #f1f1f1; color: #000000; height: 30px; line-height: 30px;
-text-align: left; padding-top: 0px; padding-bottom: 0px; padding-left: 2px; padding-right: 2px; white-space: nowrap;
-border-top: 1px; border-bottom: 1px; border-left: 0px; border-right: 0px; border-style: solid; border-top-color: #e5e5e5; border-bottom-color: #e5e5e5; border-left-color: #e5e5e5; border-right-color: #e5e5e5;
-overflow: hidden;
+/**
+ * Refreshing status animation.
+ */
+.refreshing {
+z-index: 14; display: none; width: 10px; height: 10px; border-bottom-color: transparent; vertical-align: top;
+border: 5px solid #c0c0c0; border-right-color: transparent;
+border-radius: 50%; -webkit-border-radius: 50%; -moz-border-radius: 50%;
+-webkit-box-shadow: 0 0 10px 5px #f5f5f5; -moz-box-shadow: 0 0 10px 5px #f5f5f5; -ms-box-shadow: 0 0 10px 5px #f5f5f5;
+-o-box-shadow: 0 0 10px 5px #f5f5f5; box-shadow: 0 0 10px 5px #f5f5f5;
+-webkit-animation: spin 1s linear infinite;
+-moz-animation: spin 1s linear infinite;
+-ms-animation: spin 1s linear infinite;
+-o-animation: spin 1s linear infinite;
+animation: spin 1s linear infinite;
 }
 
-.hsection {
-width: 100%; height: 0px; visibility: hidden;
-border-top: 0px; border-bottom: 0px; border-left: 0px; border-right: 0px; border-style: solid; border-bottom-color: #000000; background-color: #ffffff;
-padding-left: 2px; padding-right: 2px; padding-top: 0px; padding-bottom: 0px; margin-bottom: 0px; margin-left: auto; margin-right: auto; text-align: center;
+/**
+ * Scrollbars.
+ */
+.flatscrollbars::-webkit-scrollbar{
+width: 10px; height: 10px; background-color: #ffffff;
+box-shadow: inset 1px 1px 0 rgba(0,0,0,.1), inset -1px -1px 0 rgba(0,0,0,.07);
 }
 
-.fsection{
-width: 100%; height: 0px; visibility: hidden;
-border-top: 0px; border-bottom: 0px; border-left: 0px; border-right: 0px; border-style: solid; border-top-color: #a2bae7;
-padding: 0px; margin-top: 0px; margin-left: auto; margin-right: auto; text-align: center;
+.flatscrollbars::-webkit-scrollbar:hover{
+background-color: #eeeeee;
 }
 
-.bluetext {
-color: #4787ed;
+.flatscrollbars::-webkit-resizer{
+-webkit-border-radius: 4px;
+background-color: #666666;
 }
 
-.redtext {
-color: #d14836;
+.flatscrollbars::-webkit-scrollbar-thumb{
+min-height: 0.8em; min-width: 0.8em; background-color: rgba(0, 0, 0, .2);
+box-shadow: inset 1px 1px 0 rgba(0,0,0,.1), inset -1px -1px 0 rgba(0,0,0,.07);
 }
 
-.mirror {
-display: inline-block;
--webkit-transform: scaleX(-1);
--moz-transform: scaleX(-1);
--ms-transform: scaleX(-1);
--o-transform: scaleX(-1);
-transform: scaleX(-1);
+.flatscrollbars::-webkit-scrollbar-thumb:hover{
+background-color: #bbbbbb;
 }
 
-.greentext {
-color: #009900;
+.flatscrollbars::-webkit-scrollbar-thumb:active{
+background-color: #888888;
 }
 
+/**
+ * Base HTML elements.
+ */
 .text {
 padding-top: 3px; padding-bottom: 4px; vertical-align: middle; white-space: nowrap;
 }
 
-.link {
-padding-top: 3px; padding-bottom: 4px; vertical-align: middle; white-space: nowrap;
-}
-
-.checkbox {
-padding-top: 3px; padding-bottom: 4px; vertical-align: middle; white-space: nowrap;
-}
-
-.thl {
-border-left: 0px;
-}
-
-.thr {
-border-right: 0px;
+.bluetext {
+color: #4787ed;
 }
 
-.ths {
-padding: 0px;
+.redtext {
+color: #d14836;
 }
 
-td {
-padding-left: 2px; padding-top: 2px; padding-right: 8px; white-space: nowrap; vertical-align: middle; border: 0px;
+.greentext {
+color: #3d9400;
 }
 
-.tdl {
-border-right: 1px; border-style: solid; border-color: #a2bae7; width: 10px;
+h1 {
+font-size: 20px; font-weight: bold; vertical-align: middle; margin-top: 5px; margin-bottom: 5px; margin-left: 2px; margin-right: 2px; white-space: nowrap;
 }
 
-.tdr {
-border-left: 1px; border-style: solid; border-color: #a2bae7;
+h2 {
+font-size: 18px; font-weight: bold; vertical-align: middle; margin-top: 5px; margin-bottom: 5px; margin-left: 2px; margin-right: 2px; white-space: nowrap;
 }
 
-.tdw {
-padding-left: 2px; padding-top: 2px; padding-right: 8px; white-space: normal; vertical-align: middle;
+.hw1 {
+font-size: 20px; font-weight: bold; vertical-align: middle; margin-top: 5px; margin-bottom: 5px; margin-left: 2px; margin-right: 2px; white-space: normal;
 }
 
-.datatd {
-border-top: 1px; border-bottom: 1px; border-style: solid; border-color: #dcdcdc; width: 10px; vertical-align: middle;
+.hw2 {
+font-size: 18px; font-weight: bold; vertical-align: middle; margin-top: 5px; margin-bottom: 5px; margin-left: 2px; margin-right: 2px; white-space: normal;
 }
 
-.datatdl {
-border-right: 1px; border-top: 1px; border-bottom: 1px; border-style: solid; border-color: #dcdcdc; width: 10px; vertical-align: middle;
+.hd1 {
+font-size: 20px; font-weight: bold; white-space: nowrap; padding-top: 3px; padding-bottom: 4px; vertical-align: middle;
 }
 
-.datatdltop {
-border-right: 1px; border-top: 1px; border-bottom: 1px; border-style: solid; border-color: #dcdcdc; width: 10px; vertical-align: top;
+.hd2 {
+font-size: 18px; font-weight: bold; white-space: nowrap; padding-top: 3px; padding-bottom: 4px; vertical-align: middle;
 }
 
-.datatdr {
-border-left: 1px; border-top: 1px; border-bottom: 1px; border-style: solid; border-color: #dcdcdc; vertical-align: middle;
+.section {
+font-size: 15px; font-weight: bold; background-color: #f5f5f5; color: #000000; height: 30px; line-height: 30px; width: 100%; display: block;
+text-align: left; padding-top: 0px; padding-bottom: 0px; padding-left: 2px; padding-right: 2px; white-space: nowrap;
+border-top: 1px; border-bottom: 1px; border-left: 0px; border-right: 0px; border-style: solid; border-top-color: #e5e5e5; border-bottom-color: #e5e5e5; border-left-color: #e5e5e5; border-right-color: #e5e5e5;
 }
 
-.datatable {
-border-top: 1px; border-bottom: 1px; border-style: solid; border-color: #dcdcdc;
-overflow: visible;
+.link {
+padding-top: 3px; padding-bottom: 4px; vertical-align: middle; white-space: nowrap;
 }
 
-.databg {
-opacity: .6;  
--ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)";
-filter: alpha(opacity=60);
+a:link {
+color: #357ae8; text-decoration: none; white-space: nowrap; cursor: pointer;
 }
 
-.guide {
-border: 1px; border-style: solid; border-color: #c0c0c0;
+a:visited {
+color: #357ae8; text-decoration: none; white-space: nowrap; cursor: pointer;
 }
 
-iframe {
-border: 0px; margin: 0px; padding: 0px;
+.label{
+font-weight: bold; padding-top: 6px;
 }
 
-.fakeframe {
-padding: 3px; background-color: #dcdcdc; color: #000000;
+.lightlabel{
+font-weight: normal; color: #808080; padding-top: 6px;
 }
 
 input {
+font-family: "Lucida Grande", Helvetica, Arial; font-style: normal; font-variant: normal; font-size: 15px;
 vertical-align: middle;
-font-family: Arial; font-style: normal; font-variant: normal; font-size: 15px;
-outline: none;
--webkit-text-size-adjust: 100%;
-}
-
-button {
-vertical-align: middle;
-font-family: Arial; font-style: normal; font-variant: normal; font-size: 15px;
 outline: none;
 -webkit-text-size-adjust: 100%;
 }
 
 textarea {
-font-family: Arial; font-style: normal; font-variant: normal; font-size: 15px;
+font-family: "Lucida Grande", Helvetica, Arial; font-style: normal; font-variant: normal; font-size: 15px;
 outline: none;
 overflow: auto; resize: none;
 }
 
 .flatentry {
-font-family: Arial; font-style: normal; font-variant: normal; font-size: 15px;
+font-family: "Lucida Grande", Helvetica, Arial; font-style: normal; font-variant: normal; font-size: 15px;
+vertical-align: middle;
 -webkit-appearance: none; appearance: none;
 border: 1px solid #d9d9d9!important; border-top: 1px solid silver!important;
 box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box;
@@ -438,13 +517,29 @@ border-radius: 1px; -webkit-border-radiu
 margin: 1px!important; padding: 3px 1px 3px 3px;
 }
 
-.graphentry {
-font-family: Arial; font-style: normal; font-variant: normal; font-size: 13px;
+.readentry {
+font-family: "Lucida Grande", Helvetica, Arial; font-style: normal; font-variant: normal; font-size: 15px;
+vertical-align: middle; color: #808080;
 -webkit-appearance: none; appearance: none;
+border: 0px;
+box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box;
+border-radius: 1px; -webkit-border-radius: 1px; -moz-border-radius: 1px;
+margin: 1px!important; padding: 3px 1px 3px 3px;
+overflow: hidden; text-overflow: ellipsis;
+}
+
+.searchentry {
+font-family: "Lucida Grande", Helvetica, Arial; font-style: normal; font-variant: normal; font-size: 15px;
+vertical-align: middle;
+-webkit-appearance: searchfield; -moz-appearance: searchfield; -ms-appearance: searchfield; appearance: searchfield;
 border: 1px solid #d9d9d9!important; border-top: 1px solid silver!important;
 box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box;
 border-radius: 1px; -webkit-border-radius: 1px; -moz-border-radius: 1px;
-margin: 0px; padding: 0px;
+margin: 1px!important; padding: 3px 1px 3px 3px;
+}
+
+.checkbox {
+padding-top: 3px; padding-bottom: 4px; vertical-align: middle; white-space: nowrap;
 }
 
 .flatcheckbox {
@@ -459,117 +554,117 @@ outline: none; -moz-outline-style: none;
 outline: none; -moz-outline-style: none;
 }
 
-.editablesvg {
-background-color: transparent;
-font-family: inherit; font-style: inherit; font-variant: inherit; font-size: inherit; font-weight: inherit;
-padding: 0px; margin: 0px;
-overflow: auto; resize: none;
-outline: none; -moz-outline-style: none;
--webkit-appearance: none; -webkit-text-size-adjust: 100%;
+iframe {
+border: 0px; margin: 0px; padding: 0px;
+}
+
+img {
 border: 0px;
 }
 
-a:link {
-color: #357ae8; text-decoration: none; white-space: nowrap; cursor: pointer;
+/**
+ * Tables.
+ */
+table {
+border: 0px; border-collapse: collapse; border-color: #a2bae7; border-style: solid;
+font-family: "Lucida Grande", Helvetica, Arial; font-style: normal; font-variant: normal; font-size: 14px;
 }
 
-a:visited {
-color: #357ae8; text-decoration: none; white-space: nowrap; cursor: pointer;
+.table {
+width: 100%;
 }
 
-.tbarmenu {
-position: absolute; top: 0px; left: 0px; z-index: 10; width: 100%; margin: 0px; padding: 0px; border-collapse: separate;
-height: 35px; line-height: 35px; background-color: #2c2c2c;
-border-top: 1px; border-bottom: 1px; border-left: 0px; border-right: 0px; border-style: solid; border-top-color: #2c2c2c; border-bottom-color: #2c2c2c;
--webkit-backface-visibility: hidden;
+th {
+font-size: 15px; font-weight: bold; background-color: #f5f5f5; color: #000000;
+text-align: left; padding-left: 2px; padding-right: 8px; padding-top: 0px; padding-bottom: 0px; vertical-align: middle; white-space: nowrap;
+border-top: 1px; border-bottom: 1px; border-left: 1px; border-right: 1px; border-style: solid; border-top-color: #e5e5e5; border-bottom-color: #e5e5e5; border-left-color: #e5e5e5; border-right-color: #e5e5e5;
 }
 
-.tbarbackground {
-position: absolute; top: 0px; left: 0px; z-index: 9; width: 2500px; margin: 0px; padding: 0px; border-collapse: separate;
-height: 35px; line-height: 35px; background-color: #2c2c2c;
-border-top: 1px; border-bottom: 1px; border-left: 0px; border-right: 0px; border-style: solid; border-top-color: #2c2c2c; border-bottom-color: #2c2c2c;
-overflow: hidden;
--webkit-backface-visibility: hidden;
+.thl {
+border-left: 0px;
 }
 
-.tbarleft {
-padding-left: 2px; padding-right: 6px; white-space: nowrap; float: left;
+.thr {
+border-right: 0px;
 }
 
-.tbarright {
-padding-left: 6px; padding-right: 2px; white-space: nowrap; float: right;
+.ths {
+padding: 0px;
 }
 
-.tbaramenu {
-font-size: 110%; color: #cccccc; text-decoration: none; white-space: nowrap;
+td {
+padding-left: 2px; padding-top: 2px; padding-right: 8px; white-space: nowrap; vertical-align: middle; border: 0px;
 }
 
-.tbarsmenu {
-font-size: 110%; font-weight: bold; color: #ffffff; text-decoration: none; white-space: nowrap;
+.tdl {
+border-right: 1px; border-style: solid; border-color: #a2bae7; width: 10px;
 }
 
-.amenu {
-padding-left: 2px; padding-right: 6px; white-space: nowrap; color: #808080; text-decoration: none; float: left;
+.tdr {
+border-left: 1px; border-style: solid; border-color: #a2bae7;
 }
 
-.smenu {
-padding-left: 2px; padding-right: 6px; white-space: nowrap; color: #000000; text-decoration: none; float: left;
+.tdw {
+padding-left: 2px; padding-top: 2px; padding-right: 8px; white-space: normal; vertical-align: middle;
 }
 
-.cmenu {
-font-size: 18px; padding-left: 6px; padding-right: 6px; white-space: nowrap; color: #000000; text-decoration: none;
-width: 100%; margin-left: auto; margin-right: auto; text-align: center; float: right;
+.datatd {
+border-top: 1px; border-bottom: 1px; border-style: solid; border-color: #dcdcdc; width: 10px; vertical-align: middle;
 }
 
-.bcmenu {
-font-size: 22px; padding-left: 2px; padding-right: 6px; white-space: nowrap; color: #000000; text-decoration: none;
+.datatdl {
+border-right: 1px; border-top: 1px; border-bottom: 1px; border-style: solid; border-color: #dcdcdc; width: 10px; vertical-align: middle;
 }
 
-.rmenu {
-padding-left: 2px; padding-right: 2px; white-space: nowrap; white-space: nowrap; float: right;
+.datatdltop {
+border-right: 1px; border-top: 1px; border-bottom: 1px; border-style: solid; border-color: #dcdcdc; width: 10px; vertical-align: top;
 }
 
-h1 {
-font-size: 150%; font-weight: bold; vertical-align: middle; margin-top: 5px; margin-bottom: 5px; margin-left: 2px; margin-right: 2px; white-space: nowrap;
+.datatdr {
+border-left: 1px; border-top: 1px; border-bottom: 1px; border-style: solid; border-color: #dcdcdc; vertical-align: middle;
 }
 
-h2 {
-font-size: 120%; font-weight: bold; vertical-align: middle; margin-top: 5px; margin-bottom: 5px; margin-left: 2px; margin-right: 2px; white-space: nowrap;
+.list {
+width: 100%;
 }
 
-.hd1 {
-font-size: 150%; font-weight: bold; white-space: nowrap;
+.datatable {
+border-top: 1px; border-bottom: 1px; border-style: solid; border-color: #dcdcdc; width: 100%;
 }
 
-.hd2 {
-font-size: 120%; font-weight: bold; white-space: nowrap;
+.databg {
+opacity: .6;  
+-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)";
+filter: alpha(opacity=60);
 }
 
-img {
-border: 0px;
+/**
+ * Buttons.
+ */
+button {
+vertical-align: middle;
+font-family: "Lucida Grande", Helvetica, Arial; font-style: normal; font-variant: normal; font-size: 15px;
+outline: none;
+-webkit-text-size-adjust: 100%;
 }
 
 .plusminus {
 font-size: 18px; font-family: "Courier New";
 }
 
-.imgbutton {
-width: 142px; height: 64px; margin-left: 20px; margin-right: 20px; padding: 0px; border: 1px; cursor: pointer;
-}
-
 .graybutton {
-display: inline-block; text-align: center; color: #444; font-weight: bold;
-padding-top: 0px; padding-bottom: 0px; padding-left: 4px; padding-right: 4px;
+display: inline-block; text-align: center; color: #444; font-weight: bold; font-size: 14px; text-transform: uppercase;
+padding-top: 0px; padding-bottom: 0px; padding-left: 4px; padding-right: 4px; margin-left: 2px; margin-right: 2px;
 height: 28px; line-height: 28px; min-width: 30px;
 -webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px;
-border: 1px solid gainsboro; background-color: whiteSmoke;
-background-image: -webkit-gradient(linear,left top,left bottom,from(whiteSmoke),to(#f1f1f1));
-background-image: -webkit-linear-gradient(top,whiteSmoke,#f1f1f1);
-background-image: -moz-linear-gradient(top,whiteSmoke,#f1f1f1);
-background-image: -ms-linear-gradient(top,whiteSmoke,#f1f1f1);
-background-image: -o-linear-gradient(top,whiteSmoke,#f1f1f1);
-background-image: linear-gradient(top,whiteSmoke,#f1f1f1);
 cursor: default;
+border: 1px solid gainsboro; background-color: #f5f5f5;
+background-image: -webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#f1f1f1));
+background-image: -webkit-linear-gradient(top,#f5f5f5,#f1f1f1);
+background-image: -moz-linear-gradient(top,#f5f5f5,#f1f1f1);
+background-image: -ms-linear-gradient(top,#f5f5f5,#f1f1f1);
+background-image: -o-linear-gradient(top,#f5f5f5,#f1f1f1);
+background-image: linear-gradient(top,#f5f5f5,#f1f1f1);
 }
 
 .graybutton:hover {
@@ -583,22 +678,63 @@ background-image: linear-gradient(top,#f
 }
 
 .graybutton:active {
-background-color: #f6f6f6;
-background-image: -webkit-gradient(linear,left top,left bottom,from(#f6f6f6),to(#f1f1f1));
-background-image: -webkit-linear-gradient(top,#f6f6f6,#f1f1f1);
-background-image: -moz-linear-gradient(top,#f6f6f6,#f1f1f1);
-background-image: -ms-linear-gradient(top,#f6f6f6,#f1f1f1);
-background-image: -o-linear-gradient(top,#f6f6f6,#f1f1f1);
-background-image: linear-gradient(top,#f6f6f6,#f1f1f1);
--webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
+-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -ms-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
+-o-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
 }
 
 .graybutton:disabled {
 color: #c0c0c0;
 }
 
+.graybutton:hover:disabled {
+color: #c0c0c0;
+}
+
+.lightbutton {
+display: inline-block; text-align: center; color: #444; font-weight: normal; font-size: 14px;
+padding-top: 0px; padding-bottom: 0px; padding-left: 4px; padding-right: 4px; margin-left: 2px; margin-right: 2px;
+height: 28px; line-height: 28px; min-width: 30px;
+-webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px;
+cursor: default;
+border: 1px solid gainsboro; background-color: #f5f5f5;
+background-image: -webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#f1f1f1));
+background-image: -webkit-linear-gradient(top,#f5f5f5,#f1f1f1);
+background-image: -moz-linear-gradient(top,#f5f5f5,#f1f1f1);
+background-image: -ms-linear-gradient(top,#f5f5f5,#f1f1f1);
+background-image: -o-linear-gradient(top,#f5f5f5,#f1f1f1);
+background-image: linear-gradient(top,#f5f5f5,#f1f1f1);
+}
+
+.lightbutton:hover {
+border: 1px solid #c6c6c6; color: #333; text-shadow: 0 1px rgba(0, 0, 0, 0.3); background-color: #f8f8f8;
+background-image: -webkit-gradient(linear,left top,left bottom,from(#f8f8f8),to(#f1f1f1));
+background-image: -webkit-linear-gradient(top,#f8f8f8,#f1f1f1);
+background-image: -moz-linear-gradient(top,#f8f8f8,#f1f1f1);
+background-image: -ms-linear-gradient(top,#f8f8f8,#f1f1f1);
+background-image: -o-linear-gradient(top,#f8f8f8,#f1f1f1);
+background-image: linear-gradient(top,#f8f8f8,#f1f1f1);
+}
+
+.lightbutton:active {
+-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -ms-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
+-o-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
+}
+
+.lightbutton:disabled {
+color: #c0c0c0;
+}
+
+.lightbutton:hover:disabled {
+color: #c0c0c0;
+}
+
 .bluebutton {
-border: 1px solid #3079ed; color: white; text-shadow: 0 1px rgba(0, 0, 0, 0.1); background-color: #4d90fe;
+display: inline-block; text-align: center; font-weight: bold; font-size: 14px; text-transform: uppercase;
+padding-top: 0px; padding-bottom: 0px; padding-left: 4px; padding-right: 4px; margin-left: 2px; margin-right: 2px;
+height: 28px; line-height: 28px; min-width: 30px;
+-webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px;
+cursor: default;
+border: 1px solid #3079ed; color: #ffffff; text-shadow: 0 1px rgba(0, 0, 0, 0.1); background-color: #4d90fe;
 background-image: -webkit-gradient(linear,left top,left bottom,from(#4d90fe),to(#4787ed));
 background-image: -webkit-linear-gradient(top,#4d90fe,#4787ed);
 background-image: -moz-linear-gradient(top,#4d90fe,#4787ed);
@@ -607,12 +743,8 @@ background-image: -o-linear-gradient(top
 background-image: linear-gradient(top,#4d90fe,#4787ed);
 }
 
-.bluebutton:disabled {
-color: #c0c0c0;
-}
-
 .bluebutton:hover {
-border: 1px solid #2f5bb7; color: white; text-shadow: 0 1px rgba(0, 0, 0, 0.3); background-color: #357ae8;
+border: 1px solid #2f5bb7; color: #ffffff; text-shadow: 0 1px rgba(0, 0, 0, 0.3); background-color: #357ae8;
 background-image: -webkit-gradient(linear,left top,left bottom,from(#4d90fe),to(#357ae8));
 background-image: -webkit-linear-gradient(top,#4d90fe,#357ae8);
 background-image: -moz-linear-gradient(top,#4d90fe,#357ae8);
@@ -621,89 +753,306 @@ background-image: -o-linear-gradient(top
 background-image: linear-gradient(top,#4d90fe,#357ae8);
 }
 
+.bluebutton:active {
+-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -ms-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
+-o-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
+}
+
+.bluebutton:disabled {
+color: #c0c0c0;
+}
+
 .bluebutton:hover:disabled {
 color: #c0c0c0;
 }
 
+.greenbutton {
+display: inline-block; text-align: center; font-weight: bold; font-size: 14px; text-transform: uppercase;
+padding-top: 0px; padding-bottom: 0px; padding-left: 4px; padding-right: 4px; margin-left: 2px; margin-right: 2px;
+height: 28px; line-height: 28px; min-width: 30px;
+-webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px;
+cursor: default;
+border: 1px solid #29691d; color: #ffffff; text-shadow: 0 1px rgba(0, 0, 0, 0.1); background-color: #3d9400;
+background-image: -webkit-gradient(linear,left top,left bottom,from(#3d9400),to(#398a00));
+background-image: -webkit-linear-gradient(top,#3d9400,#398a00);
+background-image: -moz-linear-gradient(top,#3d9400,#398a00);
+background-image: -ms-linear-gradient(top,#3d9400,#398a00);
+background-image: -o-linear-gradient(top,#3d9400,#398a00);
+background-image: linear-gradient(top,#3d9400,#398a00);
+}
+
+.greenbutton:hover {
+border: 1px solid #2d6200; color: #ffffff; text-shadow: 0 1px rgba(0, 0, 0, 0.3); background-color: #097b24;
+background-image: -webkit-gradient(linear,left top,left bottom,from(#3d9400),to(#097b24));
+background-image: -webkit-linear-gradient(top,#3d9400,#097b24);
+background-image: -moz-linear-gradient(top,#3d9400,#097b24);
+background-image: -ms-linear-gradient(top,#3d9400,#097b24);
+background-image: -o-linear-gradient(top,#3d9400,#097b24);
+background-image: linear-gradient(top,#3d9400,#097b24);
+}
+
+.greenbutton:active {
+-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -ms-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
+-o-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
+}
+
+.greenbutton:disabled {
+color: #c0c0c0;
+}
+
+.greenbutton:hover:disabled {
+color: #c0c0c0;
+}
+
 .redbutton {
-border: 1px solid transparent; color: white; text-shadow: 0 1px rgba(0, 0, 0, 0.1); background-color: #d14836;
+display: inline-block; text-align: center; font-weight: bold; font-size: 14px; text-transform: uppercase;
+padding-top: 0px; padding-bottom: 0px; padding-left: 4px; padding-right: 4px; margin-left: 2px; margin-right: 2px;
+height: 28px; line-height: 28px; min-width: 30px;
+-webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px;
+cursor: default;
+border: 1px solid transparent; color: #ffffff; text-shadow: 0 1px rgba(0, 0, 0, 0.1); background-color: #d14836;
 background-image: -webkit-gradient(linear,left top,left bottom,from(#dd4b39),to(#d14836));
 background-image: -webkit-linear-gradient(top,#dd4b39,#d14836);
 background-image: -moz-linear-gradient(top,#dd4b39,#d14836);
 background-image: -ms-linear-gradient(top,#dd4b39,#d14836);
 background-image: -o-linear-gradient(top,#dd4b39,#d14836);
 background-image: linear-gradient(top,#dd4b39,#d14836);
--webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3); -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3); -ms-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3);
--o-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3);
-}
-
-.redbutton:disabled {
-color: #c0c0c0;
 }
 
 .redbutton:hover {
-border: 1px solid #b0281a; border-bottom-color: #af301f; color: white; background-color: #c53727;
+border: 1px solid #b0281a; border-bottom-color: #af301f; color: #ffffff; text-shadow: 0 1px rgba(0, 0, 0, 0.3); background-color: #c53727;
+background-image: -webkit-gradient(linear,left top,left bottom,from(#dd4b39),to(#c53727));
 background-image: -webkit-linear-gradient(top,#dd4b39,#c53727);
 background-image: -moz-linear-gradient(top,#dd4b39,#c53727);
 background-image: -ms-linear-gradient(top,#dd4b39,#c53727);
 background-image: -o-linear-gradient(top,#dd4b39,#c53727);
 background-image: linear-gradient(top,#dd4b39,#c53727);
--webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); -moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); -ms-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
--o-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
+}
+
+.redbutton:active {
+-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -ms-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
+-o-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
+}
+
+.redbutton:disabled {
+color: #c0c0c0;
 }
 
 .redbutton:hover:disabled {
 color: #c0c0c0;
 }
 
+/**
+ * Store.
+ */
+.imgbutton {
+width: 142px; height: 64px; margin-left: 20px; margin-right: 20px; padding: 0px; border: 1px; cursor: pointer;
+}
+
 .box {
-width: 150px; display: inline-block;
+width: 148px; display: inline-block; overflow: hidden; text-overflow: ellipsis;
 border: 1px; border-style: solid; border-color: #dcdcdc; border-collapse: collapse;
 white-space: nowrap; margin: 2px; padding: 2px; vertical-align: top;
 }
 
 .appicon {
-float: left;
-height: 50px; width: 50px; vertical-align: top; margin: 0px; padding: 0px;
+float: left; width: 50px; vertical-align: top; padding-right: 4px; padding-top: 2px; padding-bottom: 4px;
+overflow: hidden; text-overflow: ellipsis;
 }
 
-.apptitle {
-font-weight: bold;
+.appdetails {
+font-size: 13px; color: #808080; overflow: hidden; text-overflow: ellipsis;
 }
 
-.note {
-font-size: 12px; color: #808080;
+.apptitle {
+font-size: 14px; font-weight: bold; overflow: hidden; text-overflow: ellipsis;
 }
 
+/**
+ * Editor.
+ */
 .pagediv {
-position: absolute; display: block; overflow: visible;
+position: absolute; left: 0px; top: 0px; width: 1024px; height: 1024px;
+z-index: 2; overflow: hidden;
+}
+
+.playdiv {
+position: absolute; left: 0px; top: 0px; width: 1024px; height: 1024px;
+z-index: 1; overflow: hidden;
+}
+
+.guide {
+border: 1px; border-style: solid; border-color: #fcff00;
+}
+
+.draggable3d {
+position: absolute;
+-webkit-transition: -webkit-transform 0.016s linear;
+-moz-transition: -moz-transform 0.016s linear;
+-ms-transition: -ms-transform 0.016s linear;
+-o-transition: -o-transform 0.016s linear;
+transition: transform 0.016s linear;
+-webkit-backface-visibility: hidden;
+}
+
+.draggable3dm {
+position: absolute;
+-webkit-transition: -webkit-transform 0.016s linear;
+-moz-transition: -moz-transform 0.016s linear;
+-ms-transition: -ms-transform 0.016s linear;
+-o-transition: -o-transform 0.016s linear;
+transition: transform 0.016s linear;
+-webkit-backface-visibility: hidden;
+}
+
+/**
+ * Palette.
+ */
+.palettecontainer3dm {
+position: absolute; left: 0px; top: 0px; width: 0px; bottom: 0px; padding-top: 2px; padding-bottom: 2px;
+-webkit-backface-visibility: hidden;
+}
+
+.palettecontainer3d {
+position: absolute; left: 0px; top: 0px; width: 0px; bottom: 0px; padding-top: 2px; padding-bottom: 2px;
+-webkit-backface-visibility: hidden;
+}
+
+.paletteloading3d {
+position: absolute; left: 0px; top: 0px; bottom: 0px;
+z-index: 6; background-color: #ffffff;
+-webkit-transform: translate(-150px, 0px);
+-moz-transform: translate(-150px, 0px);
+-ms-transform: translate(-150px, 0px);
+-o-transform: translate(-150px, 0px);
+transform: translate(-150px, 0px);
+-webkit-backface-visibility: hidden;
+}
+
+.paletteloading3dm {
+position: absolute; left: 0px; top: 0px; bottom: 0px;
+z-index: 6; background-color: #ffffff;
+-webkit-transform: translate(-150px, 0px);
+-moz-transform: translate(-150px, 0px);
+-ms-transform: translate(-150px, 0px);
+-o-transform: translate(-150px, 0px);
+transform: translate(-150px, 0px);
+-webkit-backface-visibility: hidden;
+}
+
+.paletteloaded3d {
+position: absolute; left: 0px; top: 0px; bottom: 0px;
+z-index: 6; background-color: #ffffff;
+-webkit-transform: translate(0px, 0px);
+-moz-transform: translate(0px, 0px);
+-ms-transform: translate(0px, 0px);
+-o-transform: translate(0px, 0px);
+transform: translate(0px, 0px);
 -webkit-backface-visibility: hidden;
 }
 
-.graphdiv {
-position: absolute; display: block; overflow: visible;
+.paletteloaded3dm {
+position: absolute; left: 0px; top: 0px; bottom: 0px;
+z-index: 6; background-color: #ffffff;
+-webkit-transition: -webkit-transform 0.4s ease-in-out;
+-moz-transition: -moz-transform 0.4s ease-in-out;
+-ms-transition: -ms-transform 0.4s ease-in-out;
+-o-transition: -o-transform 0.4s ease-in-out;
+transition: transform 0.4s ease-in-out;
+-webkit-transform: translate(0px, 0px);
+-moz-transform: translate(0px, 0px);
+-ms-transform: translate(0px, 0px);
+-o-transform: translate(0px, 0px);
+transform: translate(0px, 0px);
+-webkit-backface-visibility: hidden;
+}
+
+.paletteunloading3dm {
+position: absolute; left: 0px; top: 0px; bottom: 0px;
+z-index: 6; background-color: #ffffff;
+-webkit-transform: translate(0px, 0px);
+-moz-transform: translate(0px, 0px);
+-ms-transform: translate(0px, 0px);
+-o-transform: translate(0px, 0px);
+transform: translate(0px, 0px);
 -webkit-backface-visibility: hidden;
 }
 
+.paletteunloaded3dm {
+position: absolute; left: 0px; top: 0px; bottom: 0px;
+z-index: 6; background-color: #ffffff;
+-webkit-transition: -webkit-transform 0.4s ease-in-out;
+-moz-transition: -moz-transform 0.4s ease-in-out;
+-ms-transition: -ms-transform 0.4s ease-in-out;
+-o-transition: -o-transform 0.4s ease-in-out;
+transition: transform 0.4s ease-in-out;
+-webkit-transform: translate(-150px, 0px);
+-moz-transform: translate(-150px, 0px);
+-ms-transform: translate(-150px, 0px);
+-o-transform: translate(-150px, 0px);
+transform: translate(-150px, 0px);
+-webkit-backface-visibility: hidden;
+}
+
+.paletteunloaded {
+position: absolute; left: 0px; top: 0px; bottom: 0px;
+z-index: 6; background-color: #ffffff;
+-webkit-transform: translate(-150px, 0px);
+-moz-transform: translate(-150px, 0px);
+-ms-transform: translate(-150px, 0px);
+-o-transform: translate(-150px, 0px);
+transform: translate(-150px, 0px);
+-webkit-backface-visibility: hidden;
+}
+
+.palettecontent {
+position: absolute; left: 0px; top: 0px; bottom: 0px; width: 150px;
+padding-right: 4px; padding-top: 4px; padding-bottom: 6px; z-index: 6;
+border-top: 0px; border-bottom: 0px; border-left: 0px; border-right: 1px;
+background-color: #ffffff; border-style: solid; border-color: #e5e5e5;
+overflow-y: scroll; overflow-x: hidden; -webkit-overflow-scrolling: touch;
+}
+
+.palettetable {
+border-top: 1px; border-bottom: 1px; border-left: 1px; border-right: 1px; border-style: solid; border-color: #dcdcdc;
+background-color: #ffffff; width: 100%;
+}
+
+.palettetd {
+border-top: 1px; border-bottom: 1px; border-left: 1px; border-right: 1px; border-style: solid; border-color: #dcdcdc; vertical-align: middle;
+height: 25px; padding-bottom: 6px; padding-top: 4px;
+}
+
+/**
+ * Graph.
+ */
 .g {
-position: absolute; display: block; overflow: visible;
+position: absolute; display: block;
 -webkit-backface-visibility: hidden;
 }
 
 .path {
-position: absolute; background: transparent; display: block; overflow: visible;
-visibility: visible;
+position: absolute; background: transparent; display: block;
 -webkit-backface-visibility: hidden;
 }
 
 .gtitle {
 position: absolute;
 margin: 4px; padding: 0px; line-height: 15px; vertical-align: middle; white-space: nowrap;
-font-family: Arial; font-style: normal; font-variant: normal; font-size: 13px; cursor: default;
-background: transparent; display: block; overflow: visible;
+font-family: "Lucida Grande", Helvetica, Arial; font-style: normal; font-variant: normal; font-size: 14px; cursor: default;
+background: transparent; display: block;
 -webkit-text-size-adjust: none;
 -webkit-touch-callout: none;
 -webkit-tap-highlight-color: rgba(0,0,0,0);
 -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none;
 }
 
+.graphentry {
+font-family: "Lucida Grande", Helvetica, Arial; font-style: normal; font-variant: normal; font-size: 14px;
+-webkit-appearance: none; appearance: none;
+border: 1px solid #d9d9d9!important; border-top: 1px solid silver!important;
+box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box;
+border-radius: 1px; -webkit-border-radius: 1px; -moz-border-radius: 1px;
+margin: 0px; padding: 0px;
+}
+