diff --git a/src/sunstone/public/app/main.js b/src/sunstone/public/app/main.js
index 4469292ea47..b108036625d 100644
--- a/src/sunstone/public/app/main.js
+++ b/src/sunstone/public/app/main.js
@@ -71,6 +71,9 @@ require.config({
"flot.time": "../bower_components/flot/jquery.flot.time",
"flot.tooltip": "../bower_components/flot.tooltip/js/jquery.flot.tooltip",
+ /* WMKS */
+ "wmks" : "../bower_components/wmks/wmks.min",
+
/* VNC */
"vnc-rfb": "../bower_components/no-vnc/lib/rfb",
@@ -119,6 +122,8 @@ require.config({
deps: [
"foundation",
"jquery",
+ "jquery-ui",
+ "wmks",
"tabs/provision-tab",
"tabs/dashboard-tab",
"tabs/system-top-tab",
@@ -168,6 +173,16 @@ require.config({
deps: ["jquery"]
},
+ /* JQuery-UI */
+ "jquery-ui": {
+ deps: ["jquery"]
+ },
+
+ /* WMKS */
+ "wmks": {
+ deps: ["jquery", "jquery-ui"]
+ },
+
/* Foundation */
"foundation": {
deps: ["jquery"]
diff --git a/src/sunstone/public/app/opennebula/vm.js b/src/sunstone/public/app/opennebula/vm.js
index 50518570966..58330c450a0 100644
--- a/src/sunstone/public/app/opennebula/vm.js
+++ b/src/sunstone/public/app/opennebula/vm.js
@@ -525,6 +525,27 @@ define(function(require) {
}
});
},
+ "vmrc" : function(params, startstop) {
+ var callback = params.success;
+ var callback_error = params.error;
+ var id = params.data.id;
+ var resource = RESOURCE;
+
+ var method = startstop;
+ var request = OpenNebulaHelper.request(resource, method, params.data);
+ $.ajax({
+ url: "vm/" + id + "/startvnc",
+ type: "POST",
+ dataType: "json",
+ success: function(response) {
+ return callback ? callback(request, response) : null;
+ },
+ error: function(response) {
+ return callback_error ?
+ callback_error(request, OpenNebulaError(response)) : null;
+ }
+ });
+ },
"append": function(params) {
var action_obj = {"template_raw" : params.data.extra_param, append : true};
OpenNebulaAction.simple_action(params, RESOURCE, "update", action_obj);
diff --git a/src/sunstone/public/app/tabs/vms-tab.js b/src/sunstone/public/app/tabs/vms-tab.js
index 3d47c846835..3e328041eda 100644
--- a/src/sunstone/public/app/tabs/vms-tab.js
+++ b/src/sunstone/public/app/tabs/vms-tab.js
@@ -36,6 +36,7 @@ define(function(require) {
require("./vms-tab/dialogs/snapshot"),
require("./vms-tab/dialogs/revert"),
require("./vms-tab/dialogs/vnc"),
+ require("./vms-tab/dialogs/vmrc"),
require("./vms-tab/dialogs/spice"),
require("./vms-tab/dialogs/saveas-template")
];
diff --git a/src/sunstone/public/app/tabs/vms-tab/actions.js b/src/sunstone/public/app/tabs/vms-tab/actions.js
index 69b5cf50f37..f553ce8c23b 100644
--- a/src/sunstone/public/app/tabs/vms-tab/actions.js
+++ b/src/sunstone/public/app/tabs/vms-tab/actions.js
@@ -22,6 +22,7 @@ define(function(require) {
var OpenNebulaVM = require('opennebula/vm');
var CommonActions = require('utils/common-actions');
var Vnc = require('utils/vnc');
+ var Vmrc = require('utils/vmrc');
var Spice = require('utils/spice');
var Files = require('utils/files');
@@ -30,6 +31,7 @@ define(function(require) {
var DEPLOY_DIALOG_ID = require('./dialogs/deploy/dialogId');
var MIGRATE_DIALOG_ID = require('./dialogs/migrate/dialogId');
var VNC_DIALOG_ID = require('./dialogs/vnc/dialogId');
+ var VMRC_DIALOG_ID = require('./dialogs/vmrc/dialogId');
var SPICE_DIALOG_ID = require('./dialogs/spice/dialogId');
var SAVE_AS_TEMPLATE_DIALOG_ID = require('./dialogs/saveas-template/dialogId');
var UPDATECONF_FORM_ID = require('./form-panels/updateconf/formPanelId');
@@ -282,6 +284,34 @@ define(function(require) {
},
notify: true
},
+ "VM.startvmrc" : {
+ type: "custom",
+ call: function() {
+ $.each(Sunstone.getDataTable(TAB_ID).elements(), function(index, elem) {
+ if (!Vmrc.lockStatus()) {
+ Vmrc.lock();
+ Sunstone.runAction("VM.startvmrc_action", elem);
+ } else {
+ Notifier.notifyError(Locale.tr("VMRC Connection in progress"))
+ return false;
+ }
+ });
+ }
+ },
+ "VM.startvmrc_action" : {
+ type: "single",
+ call: OpenNebulaVM.vmrc,
+ callback: function(request, response) {
+ var dialog = Sunstone.getDialog(VMRC_DIALOG_ID);
+ dialog.setElement(response);
+ dialog.show();
+ },
+ error: function(req, resp) {
+ Notifier.onError(req, resp);
+ Vmrc.unlock();
+ },
+ notify: true
+ },
"VM.startspice" : {
type: "custom",
call: function() {
diff --git a/src/sunstone/public/app/tabs/vms-tab/buttons.js b/src/sunstone/public/app/tabs/vms-tab/buttons.js
index 1e7d2fa1581..58dd4c846ce 100644
--- a/src/sunstone/public/app/tabs/vms-tab/buttons.js
+++ b/src/sunstone/public/app/tabs/vms-tab/buttons.js
@@ -200,6 +200,12 @@ define(function(require) {
layout: "vmsremote_buttons",
custom_classes: "only-sunstone-info vnc-sunstone-info"
},
+ "VM.startvmrc" : {
+ type: "action",
+ text: Locale.tr("VMRC"),
+ layout: "vmsremote_buttons",
+ custom_classes: "only-sunstone-info vmrc-sunstone-info"
+ },
"VM.startspice" : {
type: "action",
text: Locale.tr("SPICE"),
diff --git a/src/sunstone/public/app/tabs/vms-tab/dialogs/vmrc.js b/src/sunstone/public/app/tabs/vms-tab/dialogs/vmrc.js
new file mode 100644
index 00000000000..6a9a572cad5
--- /dev/null
+++ b/src/sunstone/public/app/tabs/vms-tab/dialogs/vmrc.js
@@ -0,0 +1,95 @@
+/* -------------------------------------------------------------------------- */
+/* Copyright 2002-2020, OpenNebula Project, OpenNebula Systems */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
+/* not use this file except in compliance with the License. You may obtain */
+/* a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
+/* See the License for the specific language governing permissions and */
+/* limitations under the License. */
+/* -------------------------------------------------------------------------- */
+
+define(function(require) {
+ /*
+ DEPENDENCIES
+ */
+
+ var BaseDialog = require('utils/dialogs/dialog');
+ var TemplateHTML = require('hbs!./vmrc/html');
+ var Sunstone = require('sunstone');
+ var Vmrc = require('utils/vmrc');
+
+ /*
+ CONSTANTS
+ */
+
+ var DIALOG_ID = require('./vmrc/dialogId');
+ var TAB_ID = require('../tabId')
+
+ /*
+ CONSTRUCTOR
+ */
+
+ function Dialog() {
+ this.dialogId = DIALOG_ID;
+
+ BaseDialog.call(this);
+ };
+
+ Dialog.DIALOG_ID = DIALOG_ID;
+ Dialog.prototype = Object.create(BaseDialog.prototype);
+ Dialog.prototype.constructor = Dialog;
+ Dialog.prototype.html = _html;
+ Dialog.prototype.onShow = _onShow;
+ Dialog.prototype.onClose = _onClose;
+ Dialog.prototype.setup = _setup;
+ Dialog.prototype.setElement = _setElement;
+
+ return Dialog;
+
+ /*
+ FUNCTION DEFINITIONS
+ */
+
+ function _html() {
+ return TemplateHTML({
+ 'dialogId': this.dialogId
+ });
+ }
+
+ function _setup(context) {
+ var that = this;
+
+ $("#open_in_a_new_window", context).on("click", function() {
+ var dialog = Sunstone.getDialog(DIALOG_ID);
+ dialog.hide();
+ });
+
+ $('#sendCtrlAltDelButton', context).click(function() {
+ Vmrc.sendCtrlAltDel();
+ return false;
+ });
+
+ return false;
+ }
+
+ function _onShow(context) {
+ Vmrc.vmrcCallback(this.element);
+ return false;
+ }
+
+ function _onClose(context) {
+ Vmrc.disconnect();
+ Vmrc.unlock();
+ return false;
+ }
+
+ function _setElement(element) {
+ this.element = element
+ }
+});
diff --git a/src/sunstone/public/app/tabs/vms-tab/dialogs/vmrc/dialogId.js b/src/sunstone/public/app/tabs/vms-tab/dialogs/vmrc/dialogId.js
new file mode 100644
index 00000000000..a392271ea5c
--- /dev/null
+++ b/src/sunstone/public/app/tabs/vms-tab/dialogs/vmrc/dialogId.js
@@ -0,0 +1,19 @@
+/* -------------------------------------------------------------------------- */
+/* Copyright 2002-2020, OpenNebula Project, OpenNebula Systems */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
+/* not use this file except in compliance with the License. You may obtain */
+/* a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
+/* See the License for the specific language governing permissions and */
+/* limitations under the License. */
+/* -------------------------------------------------------------------------- */
+
+define(function(require) {
+ return 'vmrcVMDialog';
+});
diff --git a/src/sunstone/public/app/tabs/vms-tab/dialogs/vmrc/html.hbs b/src/sunstone/public/app/tabs/vms-tab/dialogs/vmrc/html.hbs
new file mode 100644
index 00000000000..a88426b0698
--- /dev/null
+++ b/src/sunstone/public/app/tabs/vms-tab/dialogs/vmrc/html.hbs
@@ -0,0 +1,40 @@
+{{! -------------------------------------------------------------------------- }}
+{{! Copyright 2002-2020, OpenNebula Project, OpenNebula Systems }}
+{{! }}
+{{! Licensed under the Apache License, Version 2.0 (the "License"); you may }}
+{{! not use this file except in compliance with the License. You may obtain }}
+{{! a copy of the License at }}
+{{! }}
+{{! http://www.apache.org/licenses/LICENSE-2.0 }}
+{{! }}
+{{! Unless required by applicable law or agreed to in writing, software }}
+{{! distributed under the License is distributed on an "AS IS" BASIS, }}
+{{! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }}
+{{! See the License for the specific language governing permissions and }}
+{{! limitations under the License. }}
+{{! -------------------------------------------------------------------------- }}
+
+
\ No newline at end of file
diff --git a/src/sunstone/public/app/utils/vmrc.js b/src/sunstone/public/app/utils/vmrc.js
new file mode 100644
index 00000000000..f29ec2354db
--- /dev/null
+++ b/src/sunstone/public/app/utils/vmrc.js
@@ -0,0 +1,130 @@
+/* -------------------------------------------------------------------------- */
+/* Copyright 2002-2020, OpenNebula Project, OpenNebula Systems */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
+/* not use this file except in compliance with the License. You may obtain */
+/* a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
+/* See the License for the specific language governing permissions and */
+/* limitations under the License. */
+/* -------------------------------------------------------------------------- */
+
+define(function(require) {
+ // var WMKS = requiere("wmks");
+ var Config = require("sunstone-config");
+ var _lock = false;
+ var _rfb;
+ var _wmks;
+ var _message = "";
+ var _status = "Loading";
+ var _is_encrypted = "";
+
+ return {
+ "lockStatus": lockStatus,
+ "lock": lock,
+ "unlock": unlock,
+ "vmrcCallback": vmrcCallback,
+ "disconnect": disconnect,
+ "sendCtrlAltDel": sendCtrlAltDel
+ };
+
+ function lockStatus() {
+ return _lock;
+ }
+
+ function lock() {
+ _lock = true;
+ }
+
+ function unlock() {
+ _lock = false;
+ }
+
+ function setStatus(message="", status=""){
+ _message = message;
+ _status = status;
+ $(".VMRC_message").text(_message);
+ $("#VMRC_status").text(_status);
+ }
+
+ function connected(){
+ setStatus(null, "VMRC " + _rfb._rfb_connection_state + " (" + _is_encrypted + ") to: " + _rfb._fb_name);
+ }
+
+ function disconnectedFromServer(e){
+ if (e.detail.clean) {
+ setStatus(null, "VMRC " + _rfb._rfb_connection_state + " (" + _is_encrypted + ") to: " + _rfb._fb_name);
+ } else {
+ setStatus("Something went wrong, connection is closed", "Failed");
+ }
+ }
+
+ function desktopNameChange(e) {
+ if (e.detail.name) {
+ setStatus(null, "VMRC " + _rfb._rfb_connection_state + " (" + _is_encrypted + ") to: " + e.detail.name);
+ }
+ }
+
+ function credentialsRequired(e) {
+ setStatus("Something went wrong, more credentials must be given to continue", "Failed");
+ }
+
+ function vmrcCallback(response) {
+ var URL = "";
+ var proxy_port = Config.vncProxyPort;
+ var pw = response["password"];
+ var token = response["token"];
+ var vm_name = response["vm_name"];
+ var protocol = window.location.protocol;
+ var hostname = window.location.hostname;
+ var port = window.location.port;
+
+ if (protocol === "https:") {
+ URL = "wss";
+ _is_encrypted ="encrypted";
+ } else {
+ URL = "ws";
+ _is_encrypted ="unencrypted";
+ }
+ URL += "://" + hostname;
+ URL += ":" + proxy_port;
+ URL += "/ticket/" + token;
+ // URL += "/?vm=" + vm_name;
+
+ // if (!Config.requestVNCPassword) {
+ // URL += "&password=" + pw;
+ // }
+ var re = new RegExp("^(ws|wss):\\/\\/[\\w\\D]*?\\?", "gi");
+ var link = URL.replace(re, protocol + "//" + hostname + ":" + port + "/vnc?");
+
+ try{
+ var wmks = WMKS.createWMKS("VMRC_canvas",{})
+ .register(WMKS.CONST.Events.CONNECTION_STATE_CHANGE,
+ function(event,data){
+ if(typeof cons !== 'undefined' && data.state == cons.ConnectionState.CONNECTED)
+ {
+ console.log("connection state change : connected");
+ }
+ });
+ wmks.connect(URL);
+ }catch(err){
+ setStatus("Something went wrong, connection is closed", "Failed");
+ console.log("error start VMRC ", err);
+ }
+
+ $("#open_in_a_new_window").attr("href", link);
+ }
+
+ function disconnect() {
+ if (_rfb) { _rfb.disconnect(); }
+ }
+
+ function sendCtrlAltDel() {
+ if (_rfb) { _rfb.sendCtrlAltDel(); }
+ }
+});
diff --git a/src/sunstone/public/app/utils/webmks/css/extended-keypad.css b/src/sunstone/public/app/utils/webmks/css/extended-keypad.css
new file mode 100644
index 00000000000..3dbc0824f88
--- /dev/null
+++ b/src/sunstone/public/app/utils/webmks/css/extended-keypad.css
@@ -0,0 +1,314 @@
+/******************************************************************************
+ * Copyright 2013 VMware, Inc. All rights reserved.
+ *****************************************************************************/
+
+/*
+ * extended-keypad.css
+ *
+ * Defines style for the virtual keys on the control pane.
+ */
+
+.ctrl-pane-wrapper {
+ width: 290px !important; /* Needed as the default is a bit larger than this */
+ border: 1px solid #333 !important;
+ -moz-border-radius: 6px; -webkit-border-radius: 6px; -khtml-border-radius: 6px; border-radius: 6px;
+ background: rgb(170,171,182); /* Old browsers */
+ background: -webkit-linear-gradient(top, rgba(170,171,182,.93) 0%,rgba(123,123,133,.93) 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, rgba(170,171,182,.93) 0%,rgba(123,123,133,.93) 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, rgba(170,171,182,.93) 0%,rgba(123,123,133,.93) 100%); /* IE10+ */
+ background: linear-gradient(top, rgba(170,171,182,.93) 0%,rgba(123,123,133,.93) 100%); /* W3C */
+}
+
+.fnKey-pane-wrapper {
+ width: 427px;
+ border: 1px solid #333;
+ -moz-border-radius: 6px; -webkit-border-radius: 6px; -khtml-border-radius: 6px; border-radius: 6px;
+ background: #c1c4d1; /* Old browsers */
+ background: -webkit-linear-gradient(top, #c1c4d1 0%,#b0b1bd 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #c1c4d1 0%,#b0b1bd 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, #c1c4d1 0%,#b0b1bd 100%); /* IE10+ */
+ background: linear-gradient(top, #c1c4d1 0%, #b0b1bd 100%); /* W3C */
+ position: absolute;
+ padding: 0;
+ -moz-box-shadow: 0px 5px 7px rgba(0,0,0,.5);
+ -webkit-box-shadow: 0px 5px 7px rgba(0,0,0,.5);
+ box-shadow: 0px 5px 7px rgba(0,0,0,.5);
+}
+
+.fnKey-pane-wrapper-down {
+ width: 427px;
+ border: 1px solid #333;
+ -moz-border-radius: 6px; -webkit-border-radius: 6px; -khtml-border-radius: 6px; border-radius: 6px;
+ background: #6e6e77; /* Old browsers */
+ background: -webkit-linear-gradient(top, #6e6e77 0%,#656565 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #6e6e77 0%,#656565 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, #6e6e77 0%,#656565 100%); /* IE10+ */
+ background: linear-gradient(top, #6e6e77 0%, #656565 100%); /* W3C */
+ position: absolute;
+ padding: 0;
+ -moz-box-shadow: 0px 5px 7px rgba(0,0,0,.5);
+ -webkit-box-shadow: 0px 5px 7px rgba(0,0,0,.5);
+ box-shadow: 0px 5px 7px rgba(0,0,0,.5);
+}
+
+/* Hide jquery ui title bar. */
+.ctrl-pane-wrapper .ui-dialog-titlebar {
+ border-top: 1px solid #ccc;
+ border-left: 1px solid #aaa;
+ border-right: 1px solid #aaa;
+ border-bottom: 0;
+ padding: .6em .8em 0 .8em;
+ background: none !important;
+ -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; -khtml-border-top-left-radius: 5px; border-top-left-radius: 5px;
+ -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px; -khtml-border-top-right-radius: 5px; border-top-right-radius: 5px;
+}
+
+/* Replace jquery ui title bar close icon. */
+.ctrl-pane-wrapper .ui-dialog-titlebar-close {
+ margin-top: -9px;
+ border: 0 !important;
+ background: none !important;
+}
+
+/* Background-image is defined along with touch-sprite in 1 place. */
+.ctrl-pane-wrapper .ui-dialog-titlebar-close .ui-icon {
+ background-position: -9px -239px;
+ background-repeat: no-repeat;
+}
+
+.ctrl-pane-wrapper .ui-dialog-titlebar-close .ui-icon:active {
+ background-position-x: -24px;
+ background-repeat: no-repeat;
+}
+
+/* The grabber icon indicating the dialog could be moved around */
+.ctrl-pane-wrapper .ui-dialog-titlebar .ui-dialog-title {
+ background-position: -10px -255px;
+ background-repeat: no-repeat;
+ width: 40px;
+ height: 14px;
+ margin: 0 0 0 42%;
+}
+
+.ctrl-pane-wrapper .ui-dialog-titlebar .ui-dialog-title:active {
+ background-position-x: -52px;
+}
+
+.ctrl-pane-wrapper .ui-dialog-content {
+ background: none !important;
+ padding: 0 0;
+ border-style: solid;
+ border-color: #aaaaaa;
+ border-width: 0 1px 1px 1px;
+ -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; -khtml-border-bottom-left-radius: 5px; border-bottom-left-radius: 5px;
+ -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px; -khtml-border-bottom-right-radius: 5px; border-bottom-right-radius: 5px;
+}
+
+.fnKey-inner-border-helper {
+ position: relative;
+ background: none !important;
+ border-style: solid;
+ border-color: #d5d5d5;
+ border-width: 1px;
+ -moz-border-radius: 5px; -webkit-border-radius: 5px; -khtml-border-radius: 5px; border-radius: 5px;
+ pointer-events:none;
+}
+
+.ctrl-pane-wrapper .ctrl-pane {
+ padding: 3px 0 3px 6px;
+ height: 140px;
+ width: 280px;
+}
+
+.ctrl-pane .baseKey {
+ float: left;
+ border: 0;
+ padding: 0;
+ width: 57px;
+ height: 57px;
+ margin: 6px;
+ -moz-border-radius: 6px; -webkit-border-radius: 6px; -khtml-border-radius: 6px; border-radius: 6px;
+ font-family: "HelveticaNeue", "Helvetica Neue", "HelveticaNeue", "Helvetica Neue", 'TeXGyreHeros', "Helvetica", "Tahoma", "Geneva", "Arial", sans-serif;
+ font-size: 18px;
+ text-shadow: 0 1px 1px #eeeeee;
+ -moz-box-shadow: 0px 1px 3px rgba(0, 0, 0, .7);
+ -webkit-box-shadow: 0px 1px 3px rgba(0,0,0,.7);
+ box-shadow: 0px 1px 3px rgba(0,0,0,.7);
+}
+
+.ctrl-pane .ctrl-key-top-row {
+ background: -webkit-linear-gradient(top, #fff 0%,#f3f5fb 2%,#d2d2d8 98%,#999 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #fff 0%,#f3f5fb 2%,#d2d2d8 98%,#999 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, #fff 0%,#f3f5fb 2%,#d2d2d8 98%,#999 100%); /* IE10+ */
+ background: linear-gradient(top, #fff 0%,#f3f5fb 2%,#d2d2d8 98%,#999 100%); /* W3C */
+}
+
+.ctrl-pane .ctrl-key-bottom-row {
+ background: -webkit-linear-gradient(top, #fff 0%,#e1e1e3 2%,#d1d1d4 50%,#bebec3 98%,#838387 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #fff 0%,#e1e1e3 2%,#d1d1d4 50%,#bebec3 98%,#838387 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, #fff 0%,#e1e1e3 2%,#d1d1d4 50%,#bebec3 98%,#838387 100%); /* IE10+ */
+ background: linear-gradient(top, #fff 0%,#e1e1e3 2%,#d1d1d4 50%,#bebec3 98%,#838387 100%); /* W3C */
+}
+
+.ctrl-pane .up-position .fn-key-top-row {
+ color:#333;
+ background: #ffffff; /* Old browsers */
+ background: -webkit-linear-gradient(top, #ffffff 0%,#f7f7f7 2%,#dcdde3 96%,#999999 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #ffffff 0%,#f7f7f7 2%,#dcdde3 96%,#999999 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, #ffffff 0%,#f7f7f7 2%,#dcdde3 96%,#999999 100%); /* IE10+ */
+ background: linear-gradient(top, #ffffff 0%,#f7f7f7 2%,#dcdde3 96%,#999999 100%); /* W3C */
+}
+
+.ctrl-pane .up-position .fn-key-bottom-row {
+ color:#333;
+ background: #ffffff; /* Old browsers */
+ background: -webkit-linear-gradient(top, #ffffff 0%,#f3f5fb 2%,#d2d2d8 98%,#999999 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #ffffff 0%,#f3f5fb 2%,#d2d2d8 98%,#999999 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, #ffffff 0%,#f3f5fb 2%,#d2d2d8 98%,#999999 100%); /* IE10+ */
+ background: linear-gradient(top, #ffffff 0%,#f3f5fb 2%,#d2d2d8 98%,#999999 100%); /* W3C */
+}
+
+.ctrl-pane .down-position .fn-key-top-row {
+ color:#333;
+ background: #ffffff; /* Old browsers */
+ background: -webkit-linear-gradient(top, #ffffff 0%,#e1e1e3 4%,#d1d1d4 45%,#b7b8bd 98%,#838387 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #ffffff 0%,#e1e1e3 4%,#d1d1d4 45%,#b7b8bd 98%,#838387 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, #ffffff 0%,#e1e1e3 4%,#d1d1d4 45%,#b7b8bd 98%,#838387 100%); /* IE10+ */
+ background: linear-gradient(top, #ffffff 0%,#e1e1e3 4%,#d1d1d4 45%,#b7b8bd 98%,#838387 100%); /* W3C */
+}
+
+.ctrl-pane .down-position .fn-key-bottom-row {
+ color:#333;
+ background: #ffffff; /* Old browsers */
+ background: -webkit-linear-gradient(top, #ffffff 0%,#d9dadd 4%,#c8c8cd 45%,#b0b0b7 98%,#838387 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #ffffff 0%,#d9dadd 4%,#c8c8cd 45%,#b0b0b7 98%,#838387 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, #ffffff 0%,#d9dadd 4%,#c8c8cd 45%,#b0b0b7 98%,#838387 100%); /* IE10+ */
+ background: linear-gradient(top, #ffffff 0%,#d9dadd 4%,#c8c8cd 45%,#b0b0b7 98%,#838387 100%); /* W3C */
+}
+
+.ctrl-pane .fn-key-top-row {
+ margin: 12px 6px 6px 6px;
+}
+
+.ctrl-pane .border-key-top-left .fn-key-top-row {
+ margin: 12px 6px 6px 12px;
+}
+
+.ctrl-pane .border-key-top-right .fn-key-top-row {
+ margin: 12px 12px 6px 6px;
+}
+
+.ctrl-pane .fn-key-bottom-row {
+ margin: 5px 6px 12px 6px;
+}
+
+.ctrl-pane .border-key-bottom-left .fn-key-bottom-row {
+ margin: 5px 6px 12px 12px;
+}
+
+.ctrl-pane .border-key-bottom-right .fn-key-bottom-row {
+ margin: 5px 12px 12px 6px;
+}
+
+.ctrl-pane .ctrl-key-top-row:active, .ctrl-pane .fn-key-top-row:active,
+.ctrl-pane .ctrl-key-bottom-row:active, .ctrl-pane .fn-key-bottom-row:active {
+ background: #bbbbbb;
+ background: -webkit-linear-gradient(bottom, #888888 25%, #CCCCCC 68%);
+ background: -ms-linear-gradient(bottom, #888888 25%, #CCCCCC 68%);
+ background: -o-linear-gradient(bottom, #888888 25%, #CCCCCC 68%);
+ background: linear-gradient(bottom, #888888 25%, #CCCCCC 68%);
+}
+
+.ctrl-pane .ctrl-key-top-row div, .ctrl-pane .ctrl-key-bottom-row div,
+.ctrl-pane .fn-key-top-row div, .ctrl-pane .fn-key-bottom-row div {
+ width: 100%;
+ text-align: center;
+ padding-top: 17px;
+ overflow-x: hidden;
+}
+
+/* Highlight selected modifier key */
+.ctrl-pane .ab-modifier-key-down {
+ color: #4D8DFF;
+}
+
+.ctrl-pane .baseKey img { /* use .touch-sprite for image */
+ background-repeat: no-repeat;
+ width: 57px;
+ height: 57px;
+ border: 0;
+ -moz-border-radius: 6px; -webkit-border-radius: 6px; -khtml-border-radius: 6px; border-radius: 6px;
+}
+
+.ctrl-pane .baseKey .right-arrow {
+ background-position: -242px -182px;
+}
+
+.ctrl-pane .baseKey .left-arrow {
+ background-position: -126px -182px;
+}
+
+.ctrl-pane .baseKey .up-arrow {
+ background-position: -299px -182px;
+}
+
+.ctrl-pane .baseKey .down-arrow {
+ background-position: -183px -182px;
+}
+
+.ctrl-pane .baseKey .more-keys {
+ background-position: -10px -182px;
+}
+
+/* Ctrl - pane flip transition. */
+.ctrl-pane.flip-container {
+ perspective: 1000;
+ -webkit-perspective: 1000;
+ -moz-perspective: 1000;
+ -ms-perspective: 1000;
+}
+
+ /* flip the ctrl-pane when this class toggles. */
+.flip-container.perform-flip .flipper {
+ transform: rotateY(180deg);
+ -webkit-transform: rotateY(180deg);
+ -moz-transform: rotateY(180deg);
+ -ms-transform: rotateY(180deg);
+}
+
+/* flip speed goes here */
+.flip-container .flipper {
+ transition: 0.6s;
+ transform-style: preserve-3d;
+ -webkit-transition: 0.6s;
+ -webkit-transform-style: preserve-3d;
+ -moz-transition: 0.6s;
+ -moz-transform-style: preserve-3d;
+ -ms-transition: 0.6s;
+ -ms-transform-style: preserve-3d;
+ position: relative;
+}
+
+/* hide back of pane during swap */
+.flip-container .front, .flip-container .back {
+ backface-visibility: hidden;
+ -webkit-backface-visibility: hidden;
+ -moz-backface-visibility: hidden;
+ -ms-backface-visibility: hidden;
+ position: absolute;
+ top: 0;
+ left: 0;
+}
+
+/* front pane, placed above back */
+.flip-container .front {
+ z-index: 200;
+}
+
+/* back, initially hidden pane */
+.flip-container .back {
+ transform: rotateY(180deg);
+ -webkit-transform: rotateY(180deg);
+ -moz-transform: rotateY(180deg);
+ -ms-transform: rotateY(180deg);
+}
diff --git a/src/sunstone/public/app/utils/webmks/css/main-ui.css b/src/sunstone/public/app/utils/webmks/css/main-ui.css
new file mode 100644
index 00000000000..772112a7d37
--- /dev/null
+++ b/src/sunstone/public/app/utils/webmks/css/main-ui.css
@@ -0,0 +1,155 @@
+/******************************************************************************
+ * Copyright 2013 VMware, Inc. All rights reserved.
+ *****************************************************************************/
+
+/*
+ * main-ui.css
+ *
+ * Defines style for the wmks ui widgets.
+ *
+ * Use CSS3 for touch devices as jquery effects break when browser handles
+ * orientation changes, or page bouncing.
+ *
+ * TODO: Need to handle Retina mode for iPad.
+ */
+
+/*
+ * jQuery UI Dialog 1.8.16
+ */
+.ui-dialog {
+ padding: 0;
+ box-shadow: 0px 5px 7px rgba(0,0,0,.5);
+}
+
+.ui-dialog .ui-dialog-titlebar {
+ padding: .8em .8em;
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0;
+}
+
+.ui-dialog .ui-dialog-titlebar-close {
+ right: .4em;
+ margin-top: -11px;
+}
+
+.ui-widget-content {
+ border: 0;
+ background: #ffffff;
+ color: #333333;
+}
+
+.ui-widget-header a {
+ color: #333333;
+}
+
+
+/* Touch feedback indicator */
+.ui-touch-feedback-icon {
+ background-image: url('../img/touch_sprite_feedback.png');
+ width: 300px;
+ height: 120px;
+ position: absolute;
+ left: -9999px;
+ top: -9999px;
+ z-index: 2;
+}
+
+.feedback-container {
+ z-index: 2;
+ position: absolute;
+ display: none;
+}
+
+.feedback-container.cursor-icon {
+ background: url('../img/touch_sprite_feedback.png') -260px -15px no-repeat;
+ width: 17px;
+ height: 23px;
+}
+
+.feedback-container.tap-icon {
+ background: url('../img/touch_sprite_feedback.png') -300px -15px no-repeat;
+ width: 36px;
+ height: 36px;
+}
+
+.feedback-container.drag-icon {
+ background: url('../img/touch_sprite_feedback.png') -10px -10px no-repeat;
+ width: 100px;
+ height: 100px;
+}
+
+.feedback-container.pulse-icon {
+ background: url('../img/touch_sprite_feedback.png') -111px -10px no-repeat;
+ width: 100px;
+ height: 100px;
+}
+
+.feedback-container.scroll-icon {
+ background: url('../img/touch_sprite_feedback.png') -212px -10px no-repeat;
+ width: 27px;
+ height: 100px;
+}
+
+/* CSS3 feedback indicator animation. Keep it simple (uses lower cpu cycles)
+ as there may be multiple animation requests made in quick successions. */
+.animate-feedback-indicator {
+ display: block;
+ opacity: 0;
+ animation-name: showfadeout;
+ animation-duration: 350ms;
+ -webkit-animation-name: showfadeout;
+ -webkit-animation-duration: 350ms;
+ -moz-animation-name: showfadeout;
+ -moz-animation-duration: 350ms;
+ -ms-animation-name: showfadeout;
+ -ms-animation-duration: 350ms;
+}
+
+@-webkit-keyframes showfadeout {
+ 0% { opacity: 1; }
+ 100% { opacity: 0; }
+}
+
+@-moz-keyframes showfadeout {
+ 0% { opacity: 1; }
+ 100% { opacity: 0; }
+}
+
+@-ms-keyframes showfadeout {
+ 0% { opacity: 1; }
+ 100% { opacity: 0; }
+}
+
+.animate-double-feedback-indicator {
+ display: block;
+ opacity: 0;
+ animation-name: showdoublefadeout;
+ animation-duration: 400ms;
+ -webkit-animation-name: showdoublefadeout;
+ -webkit-animation-duration: 400ms;
+ -moz-animation-name: showdoublefadeout;
+ -moz-animation-duration: 400ms;
+ -ms-animation-name: showdoublefadeout;
+ -ms-animation-duration: 400ms;
+}
+
+@-webkit-keyframes showdoublefadeout {
+ 0% { opacity: 1; }
+ 40% { opacity: 0; }
+ 70% { opacity: 1; }
+ 100% { opacity: 0; }
+}
+
+@-moz-keyframes showdoublefadeout {
+ 0% { opacity: 1; }
+ 40% { opacity: 0; }
+ 70% { opacity: 1; }
+ 100% { opacity: 0; }
+}
+
+@-ms-keyframes showdoublefadeout {
+ 0% { opacity: 1; }
+ 40% { opacity: 0; }
+ 70% { opacity: 1; }
+ 100% { opacity: 0; }
+}
diff --git a/src/sunstone/public/app/utils/webmks/css/trackpad.css b/src/sunstone/public/app/utils/webmks/css/trackpad.css
new file mode 100644
index 00000000000..efccae414ad
--- /dev/null
+++ b/src/sunstone/public/app/utils/webmks/css/trackpad.css
@@ -0,0 +1,192 @@
+/******************************************************************************
+ * Copyright 2013 VMware, Inc. All rights reserved.
+ *****************************************************************************/
+
+/*
+ * trackpad.css
+ *
+ * Defines style for the trackpad widget.
+ */
+
+/*
+ * jQuery UI Dialog 1.8.16
+ */
+.ui-dialog {
+ padding: 0;
+ box-shadow: 0px 5px 7px rgba(0,0,0,.5);
+}
+
+.ui-dialog .ui-dialog-titlebar {
+ padding: .8em .8em;
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0;
+}
+
+.ui-dialog .ui-dialog-titlebar-close {
+ right: .4em;
+ margin-top: -11px;
+}
+
+.ui-widget-content {
+ border: 0;
+ background: #ffffff;
+ color: #333333;
+}
+
+.ui-widget-header a {
+ color: #333333;
+}
+
+/*
+ * Touch sprite is loaded in a single class (as we have disabled caching images).
+ * We do this for the iOS case, due to extreme limitations in terms of image size.
+ * This form of grouped declaration forces all these definitions to load the same
+ * sprite. (This is also loaded upfront for the navbar so its always visible).
+ * For details see PR - 978390.
+ */
+.trackpad-wrapper .ui-dialog-titlebar-close .ui-icon,
+.trackpad-wrapper .ui-dialog-titlebar .ui-dialog-title,
+.touch-sprite {
+ background-image: url('../img/touch_sprite.png');
+}
+
+/* Replace jquery ui title bar close icon. */
+.trackpad-wrapper .ui-dialog-titlebar-close {
+ margin-top: -9px;
+ border: 0 !important;
+ background: none !important;
+}
+
+.trackpad-wrapper .ui-dialog-titlebar-close {
+ margin-top: -11px;
+}
+
+/* Background-image is defined along with touch-sprite in 1 place. */
+.trackpad-wrapper .ui-dialog-titlebar-close .ui-icon {
+ background-position: -9px -239px;
+ background-repeat: no-repeat;
+}
+
+.trackpad-wrapper .ui-dialog-titlebar-close .ui-icon:active {
+ background-position-x: -24px;
+ background-repeat: no-repeat;
+}
+
+/* The grabber icon indicating the dialog could be moved around */
+.trackpad-wrapper .ui-dialog-titlebar .ui-dialog-title {
+ background-position: -10px -255px;
+ background-repeat: no-repeat;
+ width: 40px;
+ height: 14px;
+ margin: 0 0 0 42%;
+}
+.trackpad-wrapper .ui-dialog-titlebar .ui-dialog-title:active {
+ background-position-x: -52px;
+}
+
+.trackpad-wrapper {
+ width: 289px !important; /* As this is less than the default value */
+ border: 1px solid #333 !important;
+ background: none !important;
+ border-radius: 6px;
+ box-shadow: 0px 4px 9px rgba(0,0,0,.6);
+}
+
+.trackpad-wrapper .ui-dialog-titlebar {
+ border-top: 1px solid #ccc;
+ border-left: 1px solid #aaa;
+ border-right: 1px solid #aaa;
+ border-bottom: 0;
+ padding: .5em .8em .4em .8em;
+ background: rgb(175,176,187); /* Old browsers */
+ background: -webkit-linear-gradient(top, rgba(175,176,187,.93) 0%,rgba(170,171,182,.93) 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, rgba(175,176,187,.93) 0%,rgba(170,171,182,.93) 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, rgba(175,176,187,.93) 0%,rgba(170,171,182,.93) 100%); /* IE10+ */
+ background: linear-gradient(top, rgba(175,176,187,.93) 0%,rgba(170,171,182,.93) 100%); /* W3C */
+ border-top-left-radius: 5px;
+ border-top-right-radius: 5px;
+}
+
+.trackpad-wrapper .trackpad-container {
+ padding: 0 !important;
+}
+
+.trackpad-wrapper .left-border {
+ background: rgb(170,171,182); /* Old browsers */
+ background: -webkit-linear-gradient(top, rgba(170,171,182,.93) 0%,rgba(123,123,133,.93) 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, rgba(170,171,182,.93) 0%,rgba(123,123,133,.93) 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, rgba(170,171,182,.93) 0%,rgba(123,123,133,.93) 100%); /* IE10+ */
+ background: linear-gradient(top, rgba(170,171,182,.93) 0%,rgba(123,123,133,.93) 100%); /* W3C */
+ margin-top: -1px;
+ float: left;
+ width: 12px;
+ height: 209px;
+ border: 0;
+}
+
+.trackpad-wrapper .touch-area {
+ background: rgba(255,255,255,0.8);
+ background: -webkit-linear-gradient(-70deg, rgba(255,255,255,0.8) 0%, rgba(238,238,240,0.8) 22%, rgba(210,210,216,0.8) 71%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(-70deg, rgba(255,255,255,0.8) 0%, rgba(238,238,240,0.8) 22%, rgba(210,210,216,0.8) 71%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(-70deg, rgba(255,255,255,0.8) 0%, rgba(238,238,240,0.8) 22%, rgba(210,210,216,0.8) 71%); /* IE10+ */
+ background: linear-gradient(110deg, rgba(255,255,255,0.8) 0%, rgba(238,238,240,0.8) 22%, rgba(210,210,216,0.8) 71%); /* W3C */
+ border: 1px solid #555;
+ box-shadow: 0 2px 6px 1px #888 inset;
+ float: left;
+ width: 263px;
+ height: 206px;
+}
+
+.trackpad-wrapper .right-border {
+ background: rgb(170,171,182); /* Old browsers */
+ background: -webkit-linear-gradient(top, rgba(170,171,182,.93) 0%,rgba(123,123,133,.93) 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, rgba(170,171,182,.93) 0%,rgba(123,123,133,.93) 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, rgba(170,171,182,.93) 0%,rgba(123,123,133,.93) 100%); /* IE10+ */
+ background: linear-gradient(top, rgba(170,171,182,.93) 0%,rgba(123,123,133,.93) 100%); /* W3C */
+ margin-top: -1px;
+ float: left;
+ width: 12px;
+ height: 209px;
+ border: 0;
+ }
+
+.trackpad-wrapper .bottom-border {
+ background: rgb(123,123,133); /* Old browsers */
+ background: -webkit-linear-gradient(top, rgba(123,123,133,.93) 0%,rgba(110,110,119,.93) 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, rgba(123,123,133,.93) 0%,rgba(110,110,119,.93) 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, rgba(123,123,133,.93) 0%,rgba(110,110,119,.93) 100%); /* IE10+ */
+ background: linear-gradient(top, rgba(123,123,133,.93) 0%,rgba(110,110,119,.93) 100%); /* W3C */
+ width: 289px;
+ height: 73px;
+ margin-top: 208px;
+ border: 0;
+}
+
+.trackpad-wrapper .button-left, .trackpad-wrapper .button-right {
+ background: rgb(255,255,255); /* Old browsers */
+ background: -webkit-linear-gradient(top, rgba(255,255,255,.7) 0%,rgba(225,225,227,.7) 3%,rgba(204,204,204,.7) 45%,rgba(190,190,195,.7) 96%,rgba(131,131,135,.7) 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, rgba(255,255,255,.7) 0%,rgba(225,225,227,.7) 3%,rgba(204,204,204,.7) 45%,rgba(190,190,195,.7) 96%,rgba(131,131,135,.7) 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, rgba(255,255,255,.7) 0%,rgba(225,225,227,.7) 3%,rgba(204,204,204,.7) 45%,rgba(190,190,195,.7) 96%,rgba(131,131,135,.7) 100%); /* IE10+ */
+ background: linear-gradient(top, rgba(255,255,255,.7) 0%,rgba(225,225,227,.7) 3%,rgba(204,204,204,.7) 45%,rgba(190,190,195,.7) 96%,rgba(131,131,135,.7) 100%); /* W3C */
+ border-radius: 6px;
+ box-shadow: 0 2px 5px #333;
+ float: left;
+ width: 126px;
+ height: 47px;
+}
+
+.trackpad-wrapper .button-left {
+ margin: 12px 0px auto 12px;
+}
+
+.trackpad-wrapper .button-right {
+ margin: 12px;
+}
+
+.trackpad-wrapper .button-left.button-highlight,
+.trackpad-wrapper .button-right.button-highlight {
+ background: -webkit-linear-gradient(top, rgba(170,171,182,.7) 0%,rgba(123,123,133,.7) 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, rgba(170,171,182,.7) 0%,rgba(123,123,133,.7) 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, rgba(170,171,182,.7) 0%,rgba(123,123,133,.7) 100%); /* IE10+ */
+ background: linear-gradient(top, rgba(170,171,182,.7) 0%,rgba(123,123,133,.7) 100%); /* W3C */
+}
diff --git a/src/sunstone/public/app/utils/webmks/css/wmks-all.css b/src/sunstone/public/app/utils/webmks/css/wmks-all.css
new file mode 100644
index 00000000000..b12feed8571
--- /dev/null
+++ b/src/sunstone/public/app/utils/webmks/css/wmks-all.css
@@ -0,0 +1,661 @@
+/******************************************************************************
+ * Copyright 2013 VMware, Inc. All rights reserved.
+ *****************************************************************************/
+
+/*
+ * main-ui.css
+ *
+ * Defines style for the wmks ui widgets.
+ *
+ * Use CSS3 for touch devices as jquery effects break when browser handles
+ * orientation changes, or page bouncing.
+ *
+ * TODO: Need to handle Retina mode for iPad.
+ */
+
+/*
+ * jQuery UI Dialog 1.8.16
+ */
+.ui-dialog {
+ padding: 0;
+ box-shadow: 0px 5px 7px rgba(0,0,0,.5);
+}
+
+.ui-dialog .ui-dialog-titlebar {
+ padding: .8em .8em;
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0;
+}
+
+.ui-dialog .ui-dialog-titlebar-close {
+ right: .4em;
+ margin-top: -11px;
+}
+
+.ui-widget-content {
+ border: 0;
+ background: #ffffff;
+ color: #333333;
+}
+
+.ui-widget-header a {
+ color: #333333;
+}
+
+
+/* Touch feedback indicator */
+.ui-touch-feedback-icon {
+ background-image: url('../img/touch_sprite_feedback.png');
+ width: 300px;
+ height: 120px;
+ position: absolute;
+ left: -9999px;
+ top: -9999px;
+ z-index: 2;
+}
+
+.feedback-container {
+ z-index: 2;
+ position: absolute;
+ display: none;
+}
+
+.feedback-container.cursor-icon {
+ background: url('../img/touch_sprite_feedback.png') -260px -15px no-repeat;
+ width: 17px;
+ height: 23px;
+}
+
+.feedback-container.tap-icon {
+ background: url('../img/touch_sprite_feedback.png') -300px -15px no-repeat;
+ width: 36px;
+ height: 36px;
+}
+
+.feedback-container.drag-icon {
+ background: url('../img/touch_sprite_feedback.png') -10px -10px no-repeat;
+ width: 100px;
+ height: 100px;
+}
+
+.feedback-container.pulse-icon {
+ background: url('../img/touch_sprite_feedback.png') -111px -10px no-repeat;
+ width: 100px;
+ height: 100px;
+}
+
+.feedback-container.scroll-icon {
+ background: url('../img/touch_sprite_feedback.png') -212px -10px no-repeat;
+ width: 27px;
+ height: 100px;
+}
+
+/* CSS3 feedback indicator animation. Keep it simple (uses lower cpu cycles)
+ as there may be multiple animation requests made in quick successions. */
+.animate-feedback-indicator {
+ display: block;
+ opacity: 0;
+ animation-name: showfadeout;
+ animation-duration: 350ms;
+ -webkit-animation-name: showfadeout;
+ -webkit-animation-duration: 350ms;
+ -moz-animation-name: showfadeout;
+ -moz-animation-duration: 350ms;
+ -ms-animation-name: showfadeout;
+ -ms-animation-duration: 350ms;
+}
+
+@-webkit-keyframes showfadeout {
+ 0% { opacity: 1; }
+ 100% { opacity: 0; }
+}
+
+@-moz-keyframes showfadeout {
+ 0% { opacity: 1; }
+ 100% { opacity: 0; }
+}
+
+@-ms-keyframes showfadeout {
+ 0% { opacity: 1; }
+ 100% { opacity: 0; }
+}
+
+.animate-double-feedback-indicator {
+ display: block;
+ opacity: 0;
+ animation-name: showdoublefadeout;
+ animation-duration: 400ms;
+ -webkit-animation-name: showdoublefadeout;
+ -webkit-animation-duration: 400ms;
+ -moz-animation-name: showdoublefadeout;
+ -moz-animation-duration: 400ms;
+ -ms-animation-name: showdoublefadeout;
+ -ms-animation-duration: 400ms;
+}
+
+@-webkit-keyframes showdoublefadeout {
+ 0% { opacity: 1; }
+ 40% { opacity: 0; }
+ 70% { opacity: 1; }
+ 100% { opacity: 0; }
+}
+
+@-moz-keyframes showdoublefadeout {
+ 0% { opacity: 1; }
+ 40% { opacity: 0; }
+ 70% { opacity: 1; }
+ 100% { opacity: 0; }
+}
+
+@-ms-keyframes showdoublefadeout {
+ 0% { opacity: 1; }
+ 40% { opacity: 0; }
+ 70% { opacity: 1; }
+ 100% { opacity: 0; }
+}
+/******************************************************************************
+ * Copyright 2013 VMware, Inc. All rights reserved.
+ *****************************************************************************/
+
+/*
+ * trackpad.css
+ *
+ * Defines style for the trackpad widget.
+ */
+
+/*
+ * jQuery UI Dialog 1.8.16
+ */
+.ui-dialog {
+ padding: 0;
+ box-shadow: 0px 5px 7px rgba(0,0,0,.5);
+}
+
+.ui-dialog .ui-dialog-titlebar {
+ padding: .8em .8em;
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0;
+}
+
+.ui-dialog .ui-dialog-titlebar-close {
+ right: .4em;
+ margin-top: -11px;
+}
+
+.ui-widget-content {
+ border: 0;
+ background: #ffffff;
+ color: #333333;
+}
+
+.ui-widget-header a {
+ color: #333333;
+}
+
+/*
+ * Touch sprite is loaded in a single class (as we have disabled caching images).
+ * We do this for the iOS case, due to extreme limitations in terms of image size.
+ * This form of grouped declaration forces all these definitions to load the same
+ * sprite. (This is also loaded upfront for the navbar so its always visible).
+ * For details see PR - 978390.
+ */
+.trackpad-wrapper .ui-dialog-titlebar-close .ui-icon,
+.trackpad-wrapper .ui-dialog-titlebar .ui-dialog-title,
+.touch-sprite {
+ background-image: url('../img/touch_sprite.png');
+}
+
+/* Replace jquery ui title bar close icon. */
+.trackpad-wrapper .ui-dialog-titlebar-close {
+ margin-top: -9px;
+ border: 0 !important;
+ background: none !important;
+}
+
+.trackpad-wrapper .ui-dialog-titlebar-close {
+ margin-top: -11px;
+}
+
+/* Background-image is defined along with touch-sprite in 1 place. */
+.trackpad-wrapper .ui-dialog-titlebar-close .ui-icon {
+ background-position: -9px -239px;
+ background-repeat: no-repeat;
+}
+
+.trackpad-wrapper .ui-dialog-titlebar-close .ui-icon:active {
+ background-position-x: -24px;
+ background-repeat: no-repeat;
+}
+
+/* The grabber icon indicating the dialog could be moved around */
+.trackpad-wrapper .ui-dialog-titlebar .ui-dialog-title {
+ background-position: -10px -255px;
+ background-repeat: no-repeat;
+ width: 40px;
+ height: 14px;
+ margin: 0 0 0 42%;
+}
+.trackpad-wrapper .ui-dialog-titlebar .ui-dialog-title:active {
+ background-position-x: -52px;
+}
+
+.trackpad-wrapper {
+ width: 289px !important; /* As this is less than the default value */
+ border: 1px solid #333 !important;
+ background: none !important;
+ border-radius: 6px;
+ box-shadow: 0px 4px 9px rgba(0,0,0,.6);
+}
+
+.trackpad-wrapper .ui-dialog-titlebar {
+ border-top: 1px solid #ccc;
+ border-left: 1px solid #aaa;
+ border-right: 1px solid #aaa;
+ border-bottom: 0;
+ padding: .5em .8em .4em .8em;
+ background: rgb(175,176,187); /* Old browsers */
+ background: -webkit-linear-gradient(top, rgba(175,176,187,.93) 0%,rgba(170,171,182,.93) 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, rgba(175,176,187,.93) 0%,rgba(170,171,182,.93) 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, rgba(175,176,187,.93) 0%,rgba(170,171,182,.93) 100%); /* IE10+ */
+ background: linear-gradient(top, rgba(175,176,187,.93) 0%,rgba(170,171,182,.93) 100%); /* W3C */
+ border-top-left-radius: 5px;
+ border-top-right-radius: 5px;
+}
+
+.trackpad-wrapper .trackpad-container {
+ padding: 0 !important;
+}
+
+.trackpad-wrapper .left-border {
+ background: rgb(170,171,182); /* Old browsers */
+ background: -webkit-linear-gradient(top, rgba(170,171,182,.93) 0%,rgba(123,123,133,.93) 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, rgba(170,171,182,.93) 0%,rgba(123,123,133,.93) 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, rgba(170,171,182,.93) 0%,rgba(123,123,133,.93) 100%); /* IE10+ */
+ background: linear-gradient(top, rgba(170,171,182,.93) 0%,rgba(123,123,133,.93) 100%); /* W3C */
+ margin-top: -1px;
+ float: left;
+ width: 12px;
+ height: 209px;
+ border: 0;
+}
+
+.trackpad-wrapper .touch-area {
+ background: rgba(255,255,255,0.8);
+ background: -webkit-linear-gradient(-70deg, rgba(255,255,255,0.8) 0%, rgba(238,238,240,0.8) 22%, rgba(210,210,216,0.8) 71%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(-70deg, rgba(255,255,255,0.8) 0%, rgba(238,238,240,0.8) 22%, rgba(210,210,216,0.8) 71%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(-70deg, rgba(255,255,255,0.8) 0%, rgba(238,238,240,0.8) 22%, rgba(210,210,216,0.8) 71%); /* IE10+ */
+ background: linear-gradient(110deg, rgba(255,255,255,0.8) 0%, rgba(238,238,240,0.8) 22%, rgba(210,210,216,0.8) 71%); /* W3C */
+ border: 1px solid #555;
+ box-shadow: 0 2px 6px 1px #888 inset;
+ float: left;
+ width: 263px;
+ height: 206px;
+}
+
+.trackpad-wrapper .right-border {
+ background: rgb(170,171,182); /* Old browsers */
+ background: -webkit-linear-gradient(top, rgba(170,171,182,.93) 0%,rgba(123,123,133,.93) 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, rgba(170,171,182,.93) 0%,rgba(123,123,133,.93) 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, rgba(170,171,182,.93) 0%,rgba(123,123,133,.93) 100%); /* IE10+ */
+ background: linear-gradient(top, rgba(170,171,182,.93) 0%,rgba(123,123,133,.93) 100%); /* W3C */
+ margin-top: -1px;
+ float: left;
+ width: 12px;
+ height: 209px;
+ border: 0;
+ }
+
+.trackpad-wrapper .bottom-border {
+ background: rgb(123,123,133); /* Old browsers */
+ background: -webkit-linear-gradient(top, rgba(123,123,133,.93) 0%,rgba(110,110,119,.93) 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, rgba(123,123,133,.93) 0%,rgba(110,110,119,.93) 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, rgba(123,123,133,.93) 0%,rgba(110,110,119,.93) 100%); /* IE10+ */
+ background: linear-gradient(top, rgba(123,123,133,.93) 0%,rgba(110,110,119,.93) 100%); /* W3C */
+ width: 289px;
+ height: 73px;
+ margin-top: 208px;
+ border: 0;
+}
+
+.trackpad-wrapper .button-left, .trackpad-wrapper .button-right {
+ background: rgb(255,255,255); /* Old browsers */
+ background: -webkit-linear-gradient(top, rgba(255,255,255,.7) 0%,rgba(225,225,227,.7) 3%,rgba(204,204,204,.7) 45%,rgba(190,190,195,.7) 96%,rgba(131,131,135,.7) 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, rgba(255,255,255,.7) 0%,rgba(225,225,227,.7) 3%,rgba(204,204,204,.7) 45%,rgba(190,190,195,.7) 96%,rgba(131,131,135,.7) 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, rgba(255,255,255,.7) 0%,rgba(225,225,227,.7) 3%,rgba(204,204,204,.7) 45%,rgba(190,190,195,.7) 96%,rgba(131,131,135,.7) 100%); /* IE10+ */
+ background: linear-gradient(top, rgba(255,255,255,.7) 0%,rgba(225,225,227,.7) 3%,rgba(204,204,204,.7) 45%,rgba(190,190,195,.7) 96%,rgba(131,131,135,.7) 100%); /* W3C */
+ border-radius: 6px;
+ box-shadow: 0 2px 5px #333;
+ float: left;
+ width: 126px;
+ height: 47px;
+}
+
+.trackpad-wrapper .button-left {
+ margin: 12px 0px auto 12px;
+}
+
+.trackpad-wrapper .button-right {
+ margin: 12px;
+}
+
+.trackpad-wrapper .button-left.button-highlight,
+.trackpad-wrapper .button-right.button-highlight {
+ background: -webkit-linear-gradient(top, rgba(170,171,182,.7) 0%,rgba(123,123,133,.7) 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, rgba(170,171,182,.7) 0%,rgba(123,123,133,.7) 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, rgba(170,171,182,.7) 0%,rgba(123,123,133,.7) 100%); /* IE10+ */
+ background: linear-gradient(top, rgba(170,171,182,.7) 0%,rgba(123,123,133,.7) 100%); /* W3C */
+}
+/******************************************************************************
+ * Copyright 2013 VMware, Inc. All rights reserved.
+ *****************************************************************************/
+
+/*
+ * extended-keypad.css
+ *
+ * Defines style for the virtual keys on the control pane.
+ */
+
+.ctrl-pane-wrapper {
+ width: 290px !important; /* Needed as the default is a bit larger than this */
+ border: 1px solid #333 !important;
+ -moz-border-radius: 6px; -webkit-border-radius: 6px; -khtml-border-radius: 6px; border-radius: 6px;
+ background: rgb(170,171,182); /* Old browsers */
+ background: -webkit-linear-gradient(top, rgba(170,171,182,.93) 0%,rgba(123,123,133,.93) 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, rgba(170,171,182,.93) 0%,rgba(123,123,133,.93) 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, rgba(170,171,182,.93) 0%,rgba(123,123,133,.93) 100%); /* IE10+ */
+ background: linear-gradient(top, rgba(170,171,182,.93) 0%,rgba(123,123,133,.93) 100%); /* W3C */
+}
+
+.fnKey-pane-wrapper {
+ width: 427px;
+ border: 1px solid #333;
+ -moz-border-radius: 6px; -webkit-border-radius: 6px; -khtml-border-radius: 6px; border-radius: 6px;
+ background: #c1c4d1; /* Old browsers */
+ background: -webkit-linear-gradient(top, #c1c4d1 0%,#b0b1bd 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #c1c4d1 0%,#b0b1bd 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, #c1c4d1 0%,#b0b1bd 100%); /* IE10+ */
+ background: linear-gradient(top, #c1c4d1 0%, #b0b1bd 100%); /* W3C */
+ position: absolute;
+ padding: 0;
+ -moz-box-shadow: 0px 5px 7px rgba(0,0,0,.5);
+ -webkit-box-shadow: 0px 5px 7px rgba(0,0,0,.5);
+ box-shadow: 0px 5px 7px rgba(0,0,0,.5);
+}
+
+.fnKey-pane-wrapper-down {
+ width: 427px;
+ border: 1px solid #333;
+ -moz-border-radius: 6px; -webkit-border-radius: 6px; -khtml-border-radius: 6px; border-radius: 6px;
+ background: #6e6e77; /* Old browsers */
+ background: -webkit-linear-gradient(top, #6e6e77 0%,#656565 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #6e6e77 0%,#656565 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, #6e6e77 0%,#656565 100%); /* IE10+ */
+ background: linear-gradient(top, #6e6e77 0%, #656565 100%); /* W3C */
+ position: absolute;
+ padding: 0;
+ -moz-box-shadow: 0px 5px 7px rgba(0,0,0,.5);
+ -webkit-box-shadow: 0px 5px 7px rgba(0,0,0,.5);
+ box-shadow: 0px 5px 7px rgba(0,0,0,.5);
+}
+
+/* Hide jquery ui title bar. */
+.ctrl-pane-wrapper .ui-dialog-titlebar {
+ border-top: 1px solid #ccc;
+ border-left: 1px solid #aaa;
+ border-right: 1px solid #aaa;
+ border-bottom: 0;
+ padding: .6em .8em 0 .8em;
+ background: none !important;
+ -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; -khtml-border-top-left-radius: 5px; border-top-left-radius: 5px;
+ -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px; -khtml-border-top-right-radius: 5px; border-top-right-radius: 5px;
+}
+
+/* Replace jquery ui title bar close icon. */
+.ctrl-pane-wrapper .ui-dialog-titlebar-close {
+ margin-top: -9px;
+ border: 0 !important;
+ background: none !important;
+}
+
+/* Background-image is defined along with touch-sprite in 1 place. */
+.ctrl-pane-wrapper .ui-dialog-titlebar-close .ui-icon {
+ background-position: -9px -239px;
+ background-repeat: no-repeat;
+}
+
+.ctrl-pane-wrapper .ui-dialog-titlebar-close .ui-icon:active {
+ background-position-x: -24px;
+ background-repeat: no-repeat;
+}
+
+/* The grabber icon indicating the dialog could be moved around */
+.ctrl-pane-wrapper .ui-dialog-titlebar .ui-dialog-title {
+ background-position: -10px -255px;
+ background-repeat: no-repeat;
+ width: 40px;
+ height: 14px;
+ margin: 0 0 0 42%;
+}
+
+.ctrl-pane-wrapper .ui-dialog-titlebar .ui-dialog-title:active {
+ background-position-x: -52px;
+}
+
+.ctrl-pane-wrapper .ui-dialog-content {
+ background: none !important;
+ padding: 0 0;
+ border-style: solid;
+ border-color: #aaaaaa;
+ border-width: 0 1px 1px 1px;
+ -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; -khtml-border-bottom-left-radius: 5px; border-bottom-left-radius: 5px;
+ -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px; -khtml-border-bottom-right-radius: 5px; border-bottom-right-radius: 5px;
+}
+
+.fnKey-inner-border-helper {
+ position: relative;
+ background: none !important;
+ border-style: solid;
+ border-color: #d5d5d5;
+ border-width: 1px;
+ -moz-border-radius: 5px; -webkit-border-radius: 5px; -khtml-border-radius: 5px; border-radius: 5px;
+ pointer-events:none;
+}
+
+.ctrl-pane-wrapper .ctrl-pane {
+ padding: 3px 0 3px 6px;
+ height: 140px;
+ width: 280px;
+}
+
+.ctrl-pane .baseKey {
+ float: left;
+ border: 0;
+ padding: 0;
+ width: 57px;
+ height: 57px;
+ margin: 6px;
+ -moz-border-radius: 6px; -webkit-border-radius: 6px; -khtml-border-radius: 6px; border-radius: 6px;
+ font-family: "HelveticaNeue", "Helvetica Neue", "HelveticaNeue", "Helvetica Neue", 'TeXGyreHeros', "Helvetica", "Tahoma", "Geneva", "Arial", sans-serif;
+ font-size: 18px;
+ text-shadow: 0 1px 1px #eeeeee;
+ -moz-box-shadow: 0px 1px 3px rgba(0, 0, 0, .7);
+ -webkit-box-shadow: 0px 1px 3px rgba(0,0,0,.7);
+ box-shadow: 0px 1px 3px rgba(0,0,0,.7);
+}
+
+.ctrl-pane .ctrl-key-top-row {
+ background: -webkit-linear-gradient(top, #fff 0%,#f3f5fb 2%,#d2d2d8 98%,#999 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #fff 0%,#f3f5fb 2%,#d2d2d8 98%,#999 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, #fff 0%,#f3f5fb 2%,#d2d2d8 98%,#999 100%); /* IE10+ */
+ background: linear-gradient(top, #fff 0%,#f3f5fb 2%,#d2d2d8 98%,#999 100%); /* W3C */
+}
+
+.ctrl-pane .ctrl-key-bottom-row {
+ background: -webkit-linear-gradient(top, #fff 0%,#e1e1e3 2%,#d1d1d4 50%,#bebec3 98%,#838387 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #fff 0%,#e1e1e3 2%,#d1d1d4 50%,#bebec3 98%,#838387 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, #fff 0%,#e1e1e3 2%,#d1d1d4 50%,#bebec3 98%,#838387 100%); /* IE10+ */
+ background: linear-gradient(top, #fff 0%,#e1e1e3 2%,#d1d1d4 50%,#bebec3 98%,#838387 100%); /* W3C */
+}
+
+.ctrl-pane .up-position .fn-key-top-row {
+ color:#333;
+ background: #ffffff; /* Old browsers */
+ background: -webkit-linear-gradient(top, #ffffff 0%,#f7f7f7 2%,#dcdde3 96%,#999999 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #ffffff 0%,#f7f7f7 2%,#dcdde3 96%,#999999 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, #ffffff 0%,#f7f7f7 2%,#dcdde3 96%,#999999 100%); /* IE10+ */
+ background: linear-gradient(top, #ffffff 0%,#f7f7f7 2%,#dcdde3 96%,#999999 100%); /* W3C */
+}
+
+.ctrl-pane .up-position .fn-key-bottom-row {
+ color:#333;
+ background: #ffffff; /* Old browsers */
+ background: -webkit-linear-gradient(top, #ffffff 0%,#f3f5fb 2%,#d2d2d8 98%,#999999 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #ffffff 0%,#f3f5fb 2%,#d2d2d8 98%,#999999 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, #ffffff 0%,#f3f5fb 2%,#d2d2d8 98%,#999999 100%); /* IE10+ */
+ background: linear-gradient(top, #ffffff 0%,#f3f5fb 2%,#d2d2d8 98%,#999999 100%); /* W3C */
+}
+
+.ctrl-pane .down-position .fn-key-top-row {
+ color:#333;
+ background: #ffffff; /* Old browsers */
+ background: -webkit-linear-gradient(top, #ffffff 0%,#e1e1e3 4%,#d1d1d4 45%,#b7b8bd 98%,#838387 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #ffffff 0%,#e1e1e3 4%,#d1d1d4 45%,#b7b8bd 98%,#838387 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, #ffffff 0%,#e1e1e3 4%,#d1d1d4 45%,#b7b8bd 98%,#838387 100%); /* IE10+ */
+ background: linear-gradient(top, #ffffff 0%,#e1e1e3 4%,#d1d1d4 45%,#b7b8bd 98%,#838387 100%); /* W3C */
+}
+
+.ctrl-pane .down-position .fn-key-bottom-row {
+ color:#333;
+ background: #ffffff; /* Old browsers */
+ background: -webkit-linear-gradient(top, #ffffff 0%,#d9dadd 4%,#c8c8cd 45%,#b0b0b7 98%,#838387 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #ffffff 0%,#d9dadd 4%,#c8c8cd 45%,#b0b0b7 98%,#838387 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, #ffffff 0%,#d9dadd 4%,#c8c8cd 45%,#b0b0b7 98%,#838387 100%); /* IE10+ */
+ background: linear-gradient(top, #ffffff 0%,#d9dadd 4%,#c8c8cd 45%,#b0b0b7 98%,#838387 100%); /* W3C */
+}
+
+.ctrl-pane .fn-key-top-row {
+ margin: 12px 6px 6px 6px;
+}
+
+.ctrl-pane .border-key-top-left .fn-key-top-row {
+ margin: 12px 6px 6px 12px;
+}
+
+.ctrl-pane .border-key-top-right .fn-key-top-row {
+ margin: 12px 12px 6px 6px;
+}
+
+.ctrl-pane .fn-key-bottom-row {
+ margin: 5px 6px 12px 6px;
+}
+
+.ctrl-pane .border-key-bottom-left .fn-key-bottom-row {
+ margin: 5px 6px 12px 12px;
+}
+
+.ctrl-pane .border-key-bottom-right .fn-key-bottom-row {
+ margin: 5px 12px 12px 6px;
+}
+
+.ctrl-pane .ctrl-key-top-row:active, .ctrl-pane .fn-key-top-row:active,
+.ctrl-pane .ctrl-key-bottom-row:active, .ctrl-pane .fn-key-bottom-row:active {
+ background: #bbbbbb;
+ background: -webkit-linear-gradient(bottom, #888888 25%, #CCCCCC 68%);
+ background: -ms-linear-gradient(bottom, #888888 25%, #CCCCCC 68%);
+ background: -o-linear-gradient(bottom, #888888 25%, #CCCCCC 68%);
+ background: linear-gradient(bottom, #888888 25%, #CCCCCC 68%);
+}
+
+.ctrl-pane .ctrl-key-top-row div, .ctrl-pane .ctrl-key-bottom-row div,
+.ctrl-pane .fn-key-top-row div, .ctrl-pane .fn-key-bottom-row div {
+ width: 100%;
+ text-align: center;
+ padding-top: 17px;
+ overflow-x: hidden;
+}
+
+/* Highlight selected modifier key */
+.ctrl-pane .ab-modifier-key-down {
+ color: #4D8DFF;
+}
+
+.ctrl-pane .baseKey img { /* use .touch-sprite for image */
+ background-repeat: no-repeat;
+ width: 57px;
+ height: 57px;
+ border: 0;
+ -moz-border-radius: 6px; -webkit-border-radius: 6px; -khtml-border-radius: 6px; border-radius: 6px;
+}
+
+.ctrl-pane .baseKey .right-arrow {
+ background-position: -242px -182px;
+}
+
+.ctrl-pane .baseKey .left-arrow {
+ background-position: -126px -182px;
+}
+
+.ctrl-pane .baseKey .up-arrow {
+ background-position: -299px -182px;
+}
+
+.ctrl-pane .baseKey .down-arrow {
+ background-position: -183px -182px;
+}
+
+.ctrl-pane .baseKey .more-keys {
+ background-position: -10px -182px;
+}
+
+/* Ctrl - pane flip transition. */
+.ctrl-pane.flip-container {
+ perspective: 1000;
+ -webkit-perspective: 1000;
+ -moz-perspective: 1000;
+ -ms-perspective: 1000;
+}
+
+ /* flip the ctrl-pane when this class toggles. */
+.flip-container.perform-flip .flipper {
+ transform: rotateY(180deg);
+ -webkit-transform: rotateY(180deg);
+ -moz-transform: rotateY(180deg);
+ -ms-transform: rotateY(180deg);
+}
+
+/* flip speed goes here */
+.flip-container .flipper {
+ transition: 0.6s;
+ transform-style: preserve-3d;
+ -webkit-transition: 0.6s;
+ -webkit-transform-style: preserve-3d;
+ -moz-transition: 0.6s;
+ -moz-transform-style: preserve-3d;
+ -ms-transition: 0.6s;
+ -ms-transform-style: preserve-3d;
+ position: relative;
+}
+
+/* hide back of pane during swap */
+.flip-container .front, .flip-container .back {
+ backface-visibility: hidden;
+ -webkit-backface-visibility: hidden;
+ -moz-backface-visibility: hidden;
+ -ms-backface-visibility: hidden;
+ position: absolute;
+ top: 0;
+ left: 0;
+}
+
+/* front pane, placed above back */
+.flip-container .front {
+ z-index: 200;
+}
+
+/* back, initially hidden pane */
+.flip-container .back {
+ transform: rotateY(180deg);
+ -webkit-transform: rotateY(180deg);
+ -moz-transform: rotateY(180deg);
+ -ms-transform: rotateY(180deg);
+}
diff --git a/src/sunstone/public/app/utils/webmks/img/touch_sprite.png b/src/sunstone/public/app/utils/webmks/img/touch_sprite.png
new file mode 100644
index 00000000000..9209d836cd3
Binary files /dev/null and b/src/sunstone/public/app/utils/webmks/img/touch_sprite.png differ
diff --git a/src/sunstone/public/app/utils/webmks/img/touch_sprite_feedback.png b/src/sunstone/public/app/utils/webmks/img/touch_sprite_feedback.png
new file mode 100644
index 00000000000..fbdb0a3fc5f
Binary files /dev/null and b/src/sunstone/public/app/utils/webmks/img/touch_sprite_feedback.png differ
diff --git a/src/sunstone/public/app/utils/webmks/wmks.min.js b/src/sunstone/public/app/utils/webmks/wmks.min.js
new file mode 100644
index 00000000000..7a1d74277bb
--- /dev/null
+++ b/src/sunstone/public/app/utils/webmks/wmks.min.js
@@ -0,0 +1,6 @@
+(function(){function a(a){var b=a.length,c=new Array(Math.ceil(b/8)),d,e;for(d=0,e=0;d0?d.shift():new Image},f=function(a){delete a[0],a[0]=null,a=null},g=function(a){a.onload=a.onerror=null;var e=[71,73,70,56,57,97,1,0,1,0,0,255,0,44,0,0,0,0,1,0,1,0,0,2,0,59];e.push32($.now()),a.src="data:image/gif;base64,"+c.encodeFromArray(e),d.length<=b?d.push(a):f([a])};this.getImage=function(){return e()},this.releaseImage=function(a){if(!a)return;g(a)}}function e(){this._mediaSource=null,this._sourceBuffer=null,this._tempQueue=[],this._mediaPlayer=null,this._isError=!1,this._isErrorDoneCalled=!1,this._sendRequest=0,this._doneRequest=0,this._decodeDoneCb=null,this._decodeErrorCb=null,e.instanceNumber++,this._name="MP4Decoder"+e.instanceNumber}function f(d){function g(a){WMKS.LOGGER.trace("uint8utf8: replacing functions"),a._originalFunctions=a._originalFunctions||{};for(var b in f)f.hasOwnProperty(b)&&(a._originalFunctions[b]||(a._originalFunctions[b]=a[b]),a[b]=f[b])}function h(a){WMKS.LOGGER.trace("restoreFunctions");if(!a._originalFunctions)return;for(var b in a._originalFunctions)a._originalFunctions.hasOwnProperty(b)&&(a[b]=a._originalFunctions[b])}"use strict",WMKS.LOGGER.debug("adding uint8utf8 support");var e=d;e.hasOwnProperty("_legacyReceiveQueue")||(e._legacyReceiveQueue="",e._legacyReceiveQueueIndex=""),e.useLegacy=!1;var f={};f._receiveQueueBytesUnread=function(){return this._legacyReceiveQueue.length-this._legacyReceiveQueueIndex},f._receiveQueueConsumeBytes=function(a){this._legacyReceiveQueueIndex+=a},f._receiveQueueReset=function(){this._legacyReceiveQueue="",this._legacyReceiveQueueIndex=0},f._readString=function(a){var b=this._legacyReceiveQueue.slice(this._legacyReceiveQueueIndex,this._legacyReceiveQueueIndex+a);return this._legacyReceiveQueueIndex+=a,b},f._readStringUTF8=function(a){var b,c,d,e,f=[],g=this._legacyReceiveQueueIndex;while(ge._legacyReceiveQueue.length)return e.fail("overflow receiveQueue");e._legacyReceiveQueueIndex===e._legacyReceiveQueue.length&&(e._legacyReceiveQueue="",e._legacyReceiveQueueIndex=0);if(typeof b.data!="string"){var c=new Uint8Array(b.data);e._legacyReceiveQueue=e._legacyReceiveQueue.concat(a(c))}else e._legacyReceiveQueue=e._legacyReceiveQueue.concat(b.data);e._processMessages()},e.protocolList.indexOf("uint8utf8")===-1&&e.protocolList.push("uint8utf8"),f._receiveQueueReset.call(e)}var c={decodeToArray:function(a,c){return b(window.atob(a),c)},decodeToString:function(a){return window.atob(a)},encodeFromArray:function(b){return window.btoa(a(b))},encodeFromString:function(a){return window.btoa(a)}};WMKS={},WMKS.LOGGER=new function(){"use strict",this.LEVEL={TRACE:0,DEBUG:1,INFO:2,WARN:3,ERROR:4};var a=this.LEVEL.INFO,b=[" [Trace] "," [Debug] "," [Info ] "," [Warn ] "," [Error] "];this.trace=function(a){this.log(a,this.LEVEL.TRACE)},this.debug=function(a){this.log(a,this.LEVEL.DEBUG)},this.info=function(a){this.log(a,this.LEVEL.INFO)},this.warn=function(a){this.log(a,this.LEVEL.WARN)},this.error=function(a){this.log(a,this.LEVEL.ERROR)},this.log=typeof console=="undefined"||typeof console.log=="undefined"?$.noop:function(c,d){d=d===undefined?this.LEVEL.INFO:d,d>=a&&c&&console.log((WMKS.BROWSER.isIE()?(new Date).toUTCString():(new Date).toISOString())+b[d]+c)},this.setLogLevel=function(c){typeof c=="number"&&c>=0&&c-1?c:d;var e=function(b,c){var d=a.match(b);return d&&d.length>c&&d[c]||""};this.version={full:""},this.isSafari()?this.version.full=e(/Version[ \/]([0-9\.]+)/i,1):this.isChrome()?this.version.full=e(/Chrome\/([0-9\.]+)/i,1):this.isFirefox()?this.version.full=e(/(?:Firefox|Iceweasel)[ \/]([0-9\.]+)/i,1):this.isOpera()?this.version.full=e(/Version[ \/]([0-9\.]+)/i,1)||e(/(?:opera|opr)[\s\/]([0-9\.]+)/i,1):this.isIE()&&(this.version.full=e(/(?:\b(MS)?IE\s+|\bTrident\/7\.0;.*\s+rv:|\bEdge\/)([0-9\.]+)/i,2));var f=this.version.full.split(".");this.version.major=parseInt(f.length>0?f[0]:0,10),this.version.minor=parseInt(f.length>1?f[1]:0,10),this.version.float=parseFloat(this.version.full),this.isCanvasSupported=function(){try{var a=document.createElement("canvas"),b=!!a.getContext;return a=null,b}catch(c){return!1}}},WMKS.CONST={CLICK:{left:1,middle:2,right:4},FORCE_RAW_KEY_CODE:{8:!0,9:!0,13:!0}},WMKS.UTIL={createCanvas:function(a){var b={};return a&&(b.position="absolute"),$("").css(b)},createVideo:function(a){var b={};return a&&(b.position="absolute"),$("").css(b)},getLineLength:function(a,b){return Math.sqrt(Math.pow(a,2)+Math.pow(b,2))},isHighResolutionSupported:function(){return window.devicePixelRatio&&window.devicePixelRatio>1},isFullscreenNow:function(){return document.fullscreenElement||document.mozFullScreenElement||document.msFullscreenElement||document.webkitFullscreenElement?!0:!1},isFullscreenEnabled:function(){return!WMKS.BROWSER.isSafari()&&(document.fullscreenEnabled||document.mozFullScreenEnabled||document.msFullscreenEnabled||document.webkitFullscreenEnabled)?!0:!1},toggleFullScreen:function(a,b){var c=WMKS.UTIL.isFullscreenNow(),d=b||document.documentElement;if(!WMKS.UTIL.isFullscreenEnabled()){WMKS.LOGGER.warn("This browser does not support fullScreen mode.");return}if(c===a)return;c?document.exitFullscreen?document.exitFullscreen():document.mozCancelFullScreen?document.mozCancelFullScreen():document.webkitCancelFullScreen?document.webkitCancelFullScreen():document.msExitFullscreen&&document.msExitFullscreen():d.requestFullscreen?d.requestFullscreen():d.mozRequestFullScreen?d.mozRequestFullScreen():d.webkitRequestFullscreen?d.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT):d.msRequestFullscreen&&d.msRequestFullscreen()}},WMKS.BitBuf=function(a,b){return"use strict",this._buf=a,this._size=b,this._readCount=0,this._overflow=!1,this._thisByte=0,this._thisByteBits=0,this},WMKS.BitBuf.prototype.readBits0=function(a,b){"use strict";var c;return this._bits>b),a<<=b,a|=(this._thisByte&c)>>8-b,this._thisByte<<=b,this._thisByte&=255,this._thisByteBits-=b,a)},WMKS.BitBuf.prototype.readBits=function(a){"use strict";var b=a,c=0;if(this._overflow)return 0;while(a>this._thisByteBits){a-=this._thisByteBits,c=this.readBits0(c,this._thisByteBits);if(this._readCount0)return this._overflow=!0,0}}return c=this.readBits0(c,a),c},WMKS.BitBuf.prototype.readEliasGamma=function(){"use strict";var a=0,b,c,d=this._readCount,e=this._thisByteBits;while(!this._overflow&&(c=this.readBits(1))==0)a++;return b=1<>8&255,a&255)},Array.prototype.push32=function(a){this.push(a>>24&255,a>>16&255,a>>8&255,a&255)},Array.prototype.push16le=function(a){this.push(a&255,a>>8&255)},Array.prototype.push32le=function(a){this.push(a&255,a>>8&255,a>>16&255,a>>24&255)},e.instanceNumber=0,e.byteStreamFormat='video/mp4; codecs="avc1.640030"',e.prototype.toString=function(){return this._name},e.prototype.init=function(a,b,c,d,e){var f=this,g=b||window.URL||window.webkitURL,h=c||window.MediaSource||window.WebKitMediaSource;this.reset(),this._decodeDoneCb=d,this._decodeErrorCb=e,this._mediaPlayer=a,this._mediaSource=new h,this._mediaPlayer.src=g.createObjectURL(this._mediaSource),this._mediaSource.addEventListener("sourceopen",function(a){return f._onMediaSourceOpen(a)},!1),this._mediaSource.addEventListener("webkitsourceopen",function(a){return f._onMediaSourceOpen(a)},!1)},e.prototype._onMediaSourceOpen=function(a){var b=this;WMKS.LOGGER.log(this+" media source status is changed to open.");if(this._mediaSource.readyState!=="open"){WMKS.LOGGER.log(this+" media source is not open yet.");return}this._sourceBuffer=this._mediaSource.addSourceBuffer(e.byteStreamFormat),this._sourceBuffer.addEventListener("updateend",function(){if(b._tempQueue.length===0)return;b._tempQueue[0].method==="add"&&b._decodeDoneCb&&(b._doneRequest++,WMKS.LOGGER.debug(b+" request track: send "+b._sendRequest+" done "+b._doneRequest),b._decodeDoneCb()),b._tempQueue.shift(),b._flushPayloads()}),this._sourceBuffer.addEventListener("error",function(a){WMKS.LOGGER.error(b+" error code is "+a)}),this._flushPayloads();return},e.prototype._flushPayloads=function(){var a=0,b=0,c=0;if(!this._sourceBuffer){WMKS.LOGGER.log(this+"source buffer is not ready yet.");return}if(this._tempQueue.length===0)return;if(this._mediaSource.readyState==="open"&&!this._sourceBuffer.updating)try{if(this._tempQueue[0].method==="add")this._sourceBuffer.appendBuffer(this._tempQueue[0].payload);else if(this._tempQueue[0].method==="remove"){a=this._sourceBuffer.buffered.start(0),b=this._sourceBuffer.buffered.end(0),c=this._mediaPlayer.currentTime-.5,WMKS.LOGGER.log(this+" status: start "+a+" end "+b+" with current time "+this._mediaPlayer.currentTime);if(c>a)WMKS.LOGGER.log(this+" start to remove from "+a+" to "+c),this._sourceBuffer.remove(a,c);else throw WMKS.LOGGER.log(this+" it is too close to clear buffer."),this._tempQueue.shift(),"close buffer"}}catch(d){if(d.name==="QuotaExceededError"){var e=this;WMKS.LOGGER.log(this+" browser is full."),setTimeout(function(){e._tempQueue.unshift({method:"remove"}),e._flushPayloads()},0)}else WMKS.LOGGER.error(this+" encounters a unrecoverable error. "+d),this._isError=!0,this._decodeDoneCb&&this._decodeDoneCb(),this._decodeErrorCb&&!this._isErrorDoneCalled&&(this._isErrorDoneCalled=!0,this._decodeErrorCb())}},e.prototype.reset=function(){WMKS.LOGGER.log(this+" is reset."),this._mediaSource&&(this._sourceBuffer&&(this._mediaSource.removeSourceBuffer(this._sourceBuffer),this._sourceBuffer=null),this._mediaSource.readyState==="open"&&this._mediaSource.endOfStream(),this._mediaSource=null),this._mediaPlayer&&(this._mediaPlayer.src="",this._mediaPlayer=null),this._sendRequest=0,this._doneRequest=0,this._decodeDoneCb=null,this._decodeErrorCb=null,this._isError=!1,this._isErrorDoneCalled=!1,this._tempQueue=[]},e.prototype.appendData=function(a){if(this._isError){WMKS.LOGGER.log(this+" is in error state."),this._decodeDoneCb&&this._decodeDoneCb();return}this._sendRequest++,this._tempQueue.push({method:"add",payload:a}),this._flushPayloads(),this._mediaPlayer&&this._mediaPlayer.paused&&this._mediaPlayer.play()},function(){function d(a){var b=0,c=0,d=$.event.dispatch||$.event.handle;"detail"in a&&(c=a.detail*-1),"wheelDelta"in a&&(c=a.wheelDelta),"wheelDeltaY"in a&&(c=a.wheelDeltaY),"wheelDeltaX"in a&&(b=a.wheelDeltaX*-1),"axis"in a&&a.axis===a.HORIZONTAL_AXIS&&(b=c*-1,c=0),"deltaY"in a&&(c=a.deltaY*-1),"deltaX"in a&&(b=a.deltaX);if(c===0&&b===0)return;return a=$.event.fix(a),a.type="mousewheel",delete a.wheelDelta,a.wheelDeltaX=b,a.wheelDeltaY=c,d.call(this,a)}var a="onwheel"in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"],b=["wheel","mousewheel","DOMMouseScroll","MozMousePixelScroll"];if($.event.fixHooks)for(var c=b.length;c;)$.event.fixHooks[b[--c]]=$.event.mouseHooks;$.event.special.mousewheel={setup:function(){if(this.addEventListener){var b;for(b=0;b0&&this._receiveQueue[0].data.byteLength<=this._receiveQueueIndex)this._receiveQueueLength-=this._receiveQueue[0].data.byteLength,this._receiveQueueIndex-=this._receiveQueue[0].data.byteLength,this._receiveQueue.shift()},WMKS.VNCDecoder.prototype._receiveQueueReset=function(){this._receiveQueue=[],this._receiveQueueLength=0,this._receiveQueueIndex=0},WMKS.VNCDecoder.prototype._readBytes=function(a){"use strict";if(this._receiveQueueIndex+a<=this._receiveQueue[0].data.byteLength){var b=new Uint8Array(this._receiveQueue[0].data,this._receiveQueueIndex,a);return this._receiveQueueConsumeBytes(a),b}var b=new Uint8Array(a),c=0;while(a>0){var d=Math.min(a,this._receiveQueue[0].data.byteLength-this._receiveQueueIndex),e=new Uint8Array(this._receiveQueue[0].data,this._receiveQueueIndex,d);b.set(e,c),c+=d,a-=d,this._receiveQueueConsumeBytes(d)}return b},WMKS.VNCDecoder.prototype._readByte=function(){"use strict";var a=this._readBytes(1);return a[0]},WMKS.VNCDecoder.prototype._skipBytes=function(a){"use strict",this._receiveQueueConsumeBytes(a)},WMKS.VNCDecoder.prototype._readString=function(b){"use strict";var c=this._readBytes(b);return a(c)},WMKS.VNCDecoder.prototype._readStringUTF8=function(a){"use strict";var b,c,d,e,f=[],g=0,h=this._readBytes(a);while(g=0;m-=1)for(l=0;l0&&(o=b[n]<0?h.push8(o):h.push8(a[n+3])}for(m=0;m0&&(d=this._readBytes(a.masklength)),a.pixelslength>0&&(e=this._readBytes(a.pixelslength));for(b=0;b0&&(e=this._readBytes(a.pixelslength),a.pixelslength==4&&e[3]==0&&(e[3]=1));this._changeCursor(e,f,a.x,a.y,a.width,a.height),this._nextRect()},WMKS.VNCDecoder.prototype._readVMWDefineCursor=function(a){a.cursorType=this._readByte(),this._skipBytes(1),a.pixelslength=4*a.width*a.height,a.cursorType===0?a.masklength=a.pixelslength:a.masklength=0,this._setReadCB(a.pixelslength+a.masklength,this._readVMWDefineCursorData,a)},WMKS.VNCDecoder.prototype._updateCanvasCursor=function(){var a,b;this._cursorVisible?WMKS.BROWSER.isIE()?a="default":a=this._currentCursorURI:WMKS.BROWSER.isFirefox()&&WMKS.BROWSER.isMacOS()?a="none, !important":a="none",b=this._mediaPlayer||this._canvas[0],b.style.cursor!==a&&(b.style.cursor=a)},WMKS.VNCDecoder.prototype._readVMWCursorState=function(a){var b=this._readInt16();this._cursorVisible=!!(b&1),this._updateCanvasCursor(),this.options.onCursorStateChanged(this._cursorVisible),this._nextRect()},WMKS.VNCDecoder.prototype._readVMWCursorPosition=function(a){WMKS.VNCDecoder.cursorPosition=a,this._nextRect()},WMKS.VNCDecoder.prototype._readTypematicInfo=function(a){this.typematicState=this._readInt16(),this.typematicPeriod=this._readInt32(),this.typematicDelay=this._readInt32(),this._nextRect()},WMKS.VNCDecoder.prototype._readLEDState=function(a){this._keyboardLEDs=this._readInt32(),this.options.onKeyboardLEDsChanged(this._keyboardLEDs),this._nextRect()},WMKS.VNCDecoder.prototype._readFrameStamp=function(a){this._frameTimestampLo=this._readInt32(),this._frameTimestampHi=this._readInt32(),this._nextRect()},WMKS.VNCDecoder.prototype._fillRectWithColor=function(a,b,c,d,e,f){var g;g="rgb("+f[0]+","+f[1]+","+f[2]+")",a.fillStyle=g,a.fillRect(b,c,d,e)},WMKS.VNCDecoder.prototype._blitImageString=function(a,b,c,d,e,f){var g,h,i;g=a.createImageData(d,e),i=g.data;for(h=0;h=50)?(a.image.onload=this.onDecodeObjectURLComplete,a.image.src=d.createObjectURL(new Blob([b],{type:f}))):(b=c.encodeFromArray(b),a.image.onload=this.onDecodeComplete,a.image.src="data:"+f+";base64,"+b)),this._nextRect()},WMKS.VNCDecoder.prototype._readTightPNG=function(a){a.subEncoding=this._readByte(),a.subEncoding&=this.subEncMask,this._mediaPlayer&&this.options.onEncodingChanged("TightPNG");if(a.subEncoding===this.subEncFill)a.color=[],a.color[0]=this._readByte(),a.color[1]=this._readByte(),a.color[2]=this._readByte(),a.color[3]=255,this.rectsDecoded++,this._nextRect();else{var b=1,c=this._readByte();c&128&&(b=2,c&=-129,c+=this._readByte()<<7,c&16384&&
+(b=3,c&=-16385,c+=this._readByte()<<14)),this._setReadCB(c,this._readTightData,a)}},WMKS.VNCDecoder.prototype._readH264MP4Rect=function(a){var b=this._readInt16(),c=this._readInt16(),d=this._readInt32();b===1&&(WMKS.LOGGER.log("MP4 encoding is selected and stream is reset."),this.options.onEncodingChanged("MP4"),this._mp4Decoder.init(this._mediaPlayer,undefined,undefined,this.onDecodeComplete,this.onDecodeMP4Error)),this._setReadCB(d,this._readH264MP4Data,a)},WMKS.VNCDecoder.prototype._readH264MP4Data=function(a){this._mp4Decoder.appendData(this._readBytes(this.nextBytes)),this._nextRect()},WMKS.VNCDecoder.prototype._readH264Rect=function(a){var b=this._readInt16(),c=this._readInt16(),d=this._readInt32();b===1&&(WMKS.LOGGER.log("Raw H264 encoding is selected and stream is reset."),this.options.onEncodingChanged("RawH264")),this._setReadCB(d,this._readH264Data,a)},WMKS.VNCDecoder.prototype._readH264Data=function(a){this._readBytes(this.nextBytes),this._nextRect()},WMKS.VNCDecoder.prototype._readCopyRect=function(a){a.srcX=this._readInt16(),a.srcY=this._readInt16(),this._nextRect()},WMKS.VNCDecoder.prototype._readRaw=function(a){a.imageString=this._readString(this.nextBytes),this._nextRect()},WMKS.VNCDecoder.prototype._readDesktopSize=function(a){this._FBWidth=a.width,this._FBHeight=a.height,this.options.onNewDesktopSize(this._FBWidth,this._FBHeight),this._nextRect()},WMKS.VNCDecoder.prototype._readRect=function(){var a=this.rectsRead;this.rect[a]={},this.rect[a].x=this._readInt16(),this.rect[a].y=this._readInt16(),this.rect[a].width=this._readInt16(),this.rect[a].height=this._readInt16(),this.rect[a].encoding=this._readInt32(),this.rect[a].encoding!==this.encTightPNG&&this.rect[a].encoding!==this.encH264MP4&&this.rectsDecoded++;switch(this.rect[a].encoding){case this.encRaw:this._setReadCB(this.rect[a].width*this.rect[a].height*this._FBBytesPerPixel,this._readRaw,this.rect[a]);break;case this.encCopyRect:this._setReadCB(4,this._readCopyRect,this.rect[a]);break;case this.encOffscreenCopyRect:this._setReadCB(6,this._readOffscreenCopyRect,this.rect[a]);break;case this.encUpdateCache:this._setReadCB(5,this._readUpdateCacheRect,this.rect[a]);break;case this.encH264RectEnc:this._setReadCB(8,this._readH264Rect,this.rect[a]);break;case this.encTightPNG:this._setReadCB(4,this._readTightPNG,this.rect[a]);break;case this.encH264MP4:this._setReadCB(8,this._readH264MP4Rect);break;case this.encDesktopSize:this._readDesktopSize(this.rect[a]);break;case this.encVMWDefineCursor:this._setReadCB(2,this._readVMWDefineCursor,this.rect[a]);break;case this.encVMWCursorState:this._assumeServerIsVMware(),this._setReadCB(2,this._readVMWCursorState,this.rect[a]);break;case this.encVMWCursorPosition:this._readVMWCursorPosition(this.rect[a]);break;case this.encVMWTypematicInfo:this._setReadCB(10,this._readTypematicInfo,this.rect[a]);break;case this.encVMWLEDState:this._setReadCB(4,this._readLEDState,this.rect[a]);break;case this.encVMWFrameStamp:this._setReadCB(8,this._readFrameStamp,this.rect[a]);break;default:return this.fail("Disconnected: unsupported encoding "+this.rect[a].encoding)}},WMKS.VNCDecoder.prototype._evictUpdateCacheEntry=function(a){"use strict",this.updateCache[a].image!==null&&this._releaseImage(this.updateCache[a].image),this.updateCache[a]={},this.updateCache[a].image=null},WMKS.VNCDecoder.prototype._executeUpdateCacheInit=function(a){"use strict";var b;for(b=0;bthis.options.cacheSizeEntries)return this.fail("Disconnected: requested cache too large");for(b=0;b=this.updateCacheEntries)return this.fail("Disconnected: requested cache slot too large");b=new WMKS.BitBuf(a.data,a.dataLength),c=!b.readBits(1),d=0,f=0;do{d=b.readEliasGamma(),c=!c;if(c)for(e=0;e=this.updateCacheEntries)return this.fail("Disconnected: requested cache slot invalid");b.mask=a.data,b.maskLength=a.dataLength,n=new WMKS.BitBuf(b.mask,b.maskLength),c=!n.readBits(1),d=0;do d==0&&(d=n.readEliasGamma(),c=!c),m=Math.min(k-i,g-e),m=Math.min(m,d),c&&(this._canvas[0].ctx.drawImage(b.image,i*16,j*16,m*16,16,e*16,f*16,m*16,16),i+=m,i==k&&(i=0,j++)),e+=m,e==g&&(e=0,f++),d-=m;while(f=this.updateCacheEntries)return this.fail("Disconnected: requested cache slot invalid");var b=0,c=0,d=Math.ceil(this._FBWidth/16),e=Math.ceil(this._FBHeight/16),f,g=this.updateCache[a.slot],h=0,i=0,j=g.imageWidth/16,k=g.imageHeight/16,l=new WMKS.BitBuf(a.data,a.dataLength),m=new WMKS.BitBuf(g.mask,g.maskLength),n=!m.readBits(1),o=0,p=!l.readBits(1),q=0;if(!this._updateCacheInitialized()||this._updateCacheInsideBeginEnd()||a.slot>=this.updateCacheEntries)return this.fail("");do o==0&&(o=m.readEliasGamma(),n=!n),q==0&&(q=l.readEliasGamma(),p=!p),f=d-b,f=Math.min(f,o),n&&(f=Math.min(f,j-h),f=Math.min(f,q),p&&this._canvas[0].ctx.drawImage(g.image,h*16,i*16,f*16,16,b*16,c*16,f*16,16),h+=f,h==j&&(h=0,i++),q-=f),b+=f,b==d&&(b=0,c++),o-=f;while(c0&&this.requestedHeight>0&&this.onRequestResolution(this.requestedWidth,this.requestedHeight),a&this.serverCapClientCaps&&this._sendClientCaps(),a&this.serverCapUpdateCacheInfo&&this._sendUpdateCacheInfo();if(a&this.serverCapDisablingCopyUI||a&this.serverCapDisablingPasteUI){var b=0,c=0;a&this.serverCapDisablingCopyUI&&(b=1),a&this.serverCapDisablingPasteUI&&(c=1),this.options.onUpdateCopyPasteUI(b,c)}this._getNextServerMessage()},WMKS.VNCDecoder.prototype._handleServerHeartbeatMsg=function(){var a=this._readInt16();this.options.onHeartbeat(a),this._getNextServerMessage()},WMKS.VNCDecoder.prototype._handleSessionCloseMsg=function(){var a=this._readInt32();this.options.onBeforeDisconnected(a),this._getNextServerMessage()},WMKS.VNCDecoder.prototype._handleAudioMixer=function(){var a=this._readInt32(),b=this._readInt32(),c=this._readInt32(),d=this._readInt32();a<2&&(b===0||b===1)?this.options.onAudioMixer({channelId:a,msgType:b,data:c,flags:d}):WMKS.LOGGER.warn("Ignoring audio mixer message for an unsupported channelId = "+a+" msgType = "+b+" data = "+c+" flags = "+d),this._getNextServerMessage()},WMKS.VNCDecoder.prototype._handleServerSetReconnectTokenMsg=function(a){var b=this._readString(a);this.options.onSetReconnectToken(b),this._getNextServerMessage()},WMKS.VNCDecoder.prototype._handleServerAudioMsg=function(){var a=this._readInt32(),b=this._readInt32(),c=this._readInt32(),d=this._readInt32(),e=this._readInt32(),f=this._readInt32(),g=this._readInt32(),h=this._readInt32(),i={sampleRate:b,numChannels:c,containerSize:e,sampleSize:d,length:a,audioTimestampLo:f,audioTimestampHi:g,frameTimestampLo:this._frameTimestampLo,frameTimestampHi:this._frameTimestampHi,flags:h,data:null};this._setReadCB(a,this._handleServerAudioMsgData,i)},WMKS.VNCDecoder.prototype._handleServerAudioMsgData=function(a){a.length>0?(a.data=this._readBytes(a.length),this.useVMWAudioAck&&(a.flags==0||a.flags&this.audioflagRequestAck)&&this._sendAudioAck(a.audioTimestampLo,a.audioTimestampHi),this.options.onAudio(a)):WMKS.LOGGER.info("Audio data length is 0."),this._getNextServerMessage()},WMKS.VNCDecoder.prototype._handleServerCutText=function(a){var b=this._readStringUTF8(a);this.options.onCopy(b),this._getNextServerMessage()},WMKS.VNCDecoder.prototype._handleServerMsg=function(){var a,b,c,d,e,f=this,g=this._readByte();switch(g){case this.msgFramebufferUpdate:this._setReadCB(3,this._framebufferUpdate);break;case this.msgSetColorMapEntries:var h=function(){f._skipBytes(3);var a=f._readInt16();f._setReadCB(6*a,f._gobble,f._getNextServerMessage)};this._setReadCB(5,h);break;case this.msgRingBell:this._getNextServerMessage();break;case this.msgServerCutText:var i=function(){f._readBytes(3),a=f._readInt32(),a>0?f._setReadCB(a,f._handleServerCutText,a):f._getNextServerMessage()};this._setReadCB(8,i);break;case this.msgVMWSrvMessage:var j=function(){var a=f._readByte(),b=f._readInt16();if(a===this.msgVMWSrvMessage_ServerCaps){if(b!==8)return f.options.onProtocolError(),f.fail("invalid length message for id: "+a+", len: "+b);f._setReadCB(b-4,f._handleServerCapsMsg)}else if(a===this.msgVMWSrvMessage_Heartbeat){if(b!==6)return f.options.onProtocolError(),f.fail("invalid length message for id: "+a+", len: "+b);f._setReadCB(b-4,f._handleServerHeartbeatMsg)}else if(a===this.msgVMWSrvMessage_SetReconnectToken)f._setReadCB(b-4,f._handleServerSetReconnectTokenMsg,b-4);else if(a===this.msgVMWSrvMessage_Audio){if(b!==36)return f.options.onProtocolError(),f.fail("invalid length message for id: "+a+", len: "+b);f._setReadCB(b-4,f._handleServerAudioMsg)}else if(a===this.msgVMWSrvMessage_SessionClose){if(b!==8)return f.options.onProtocolError(),f.fail("invalid length message for id: "+a+", len: "+b);f._setReadCB(b-4,f._handleSessionCloseMsg)}else if(a===this.msgVMWSrvMessage_AudioMixer){if(b!==20)return f.options.onProtocolError(),f.fail("invalid length message for id: "+a+", len: "+b);f._setReadCB(b-4,f._handleAudioMixer)}else{var c=b-4;c===0?f._getNextServerMessage():f._setReadCB(c,f._gobble,f._getNextServerMessage)}};this._setReadCB(3,j);break;default:return this.options.onProtocolError(),this.fail("Disconnected: illegal server message type "+g)}},WMKS.VNCDecoder.prototype._processMessages=function(){while(this._state===this.VNC_ACTIVE_STATE&&this._receiveQueueBytesUnread()>=this.nextBytes){var a=this.nextBytes,b=this._receiveQueueBytesUnread();this.nextFn(this.nextArg);var c=this._receiveQueueBytesUnread();if(a0&&(WMKS.LOGGER.log("Check connection status after "+this.options.retryConnectionInterval+"ms."),this._retryConnectionTimer=setTimeout(this._retryConnectionTimeout,this.options.retryConnectionInterval))},WMKS.VNCDecoder.prototype.setRenderCanvas=function(a){this._canvas[0]=a,this._canvas[0].ctx=a.getContext("2d");if(!this._canvas[0].ctx.createImageData)throw"no canvas imagedata support"},WMKS.CONST.KB={ControlKeys:[8,9,13,16,17,18,19,20,27,33,34,35,36,37,38,39,40,45,46,91,92,93,112,113,114,115,116,117,118,119,120,121,122,123,144,145,240],Modifiers:[16,17,18,91,92],WestEuroLanguage:["de-DE","it-IT","es-ES","pt-BR","pt-PT","fr-FR","fr-CH","de-CH"],Diacritics:[192],KEY_CODE:{Shift:16,Ctrl:17,Alt:18,Meta:91,Enter:13,CapsLock:20},SoftKBRawKeyCodes:[8,9,13],keyInputDefaultValue:" ",ANSIShiftSymbols:'~!@#$%^&*()_+{}|:"<>?',ANSINoShiftSymbols:"`-=[]\\;',./1234567890",WindowsKeys:{left:91,right:92},VScanMap:{}},WMKS.BROWSER.isMacOS()&&(WMKS.CONST.KB.Modifiers=[16,17,18,91,92,224]),WMKS.CONST.KB.ANSISpecialSymbols=WMKS.CONST.KB.ANSIShiftSymbols+WMKS.CONST.KB.ANSINoShiftSymbols,WMKS.KeyboardManager=function(a){"use strict";if(!a||!a.vncDecoder)return null;this._vncDecoder=a.vncDecoder,this.ignoredRawKeyCodes=a.ignoredRawKeyCodes,this.fixANSIEquivalentKeys=a.fixANSIEquivalentKeys,this.mapMetaToCtrlForKeys=a.mapMetaToCtrlForKeys,this.keyDownKeyTimer=null,this.keyDownIdentifier=null,this.pendingKey=null,this.addCtrlKey=!1,this.activeModifiers=[],this.keyToUnicodeMap={},this.keyToRawMap={},this.keyboardLayoutId=a.keyboardLayoutId,this.UnicodeToVScanMap=WMKS.CONST.KB.VScanMap[this.keyboardLayoutId],this._windowsKeyManager={enabled:a.enableWindowsKey,windowsOn:!1,leftWindowsDown:!1,rightWindowsDown:!1,modifiedKeyMap:{Pause:19},modifiedKey:null,reset:function(){this.windowsOn=!1,this.leftWindowsDown=!1,this.rightWindowsDown=!1,this.modifiedKey=null},keyboardHandler:function(a){a.keyCode===WMKS.CONST.KB.WindowsKeys.left||a.keyCode===224?(this.leftWindowsDown=a.type==="keydown",this.leftWindowsDown||(this.windowsOn=!1)):a.keyCode===WMKS.CONST.KB.WindowsKeys.right&&(this.rightWindowsDown=a.type==="keydown",this.rightWindowsDown||(this.windowsOn=!1))},modifyKey:function(a){return a===3&&(this.windowsOn?(a=this.modifiedKeyMap.Pause,this.modifiedKey=3):this.modifiedKey===3&&(a=this.modifiedKeyMap.Pause,this.modifiedKey=null)),a}},this._extractKeyCodeFromEvent=function(a){var b=0,c=!1;if(a.keyCode)b=a.keyCode,this.keyboardLayoutId=="pt-PT"&&WMKS.BROWSER.isChrome()&&(a.keyCode===186||a.keyCode===191)&&WMKS.BROWSER.isWindows()&&(a.keyCode===186?b=180:b=126),this.keyboardLayoutId=="de-DE"&&a.keyCode==192&&WMKS.BROWSER.isFirefox()&&(b=187),(this.keyboardLayoutId==="fr-CH"||this.keyboardLayoutId==="de-CH")&&WMKS.BROWSER.isWindows()&&a.keyCode===221&&(b=94);else if(a.which)b=a.which;else if(a.keyIdentifier&&a.keyIdentifier.substring(0,2)==="U+"){b=parseInt("0x"+a.keyIdentifier.slice(2),16);if(b)c=!0;else return WMKS.LOGGER.log("assert: Unicode identifier="+a.keyIdentifier+" int conversion failed, keyCode="+b),null}else if(a.keyCode===0&&WMKS.BROWSER.isFirefox()&&a.key&&this._vncDecoder.allowVMWKeyEvent2UnicodeAndRaw)b=0;else{this._vncDecoder.allowVMWKeyEvent2UnicodeAndRaw||(b=this.handleInternationalKeyboard(a,b)),this.keyboardLayoutId=="ja-JP_106/109"&&!WMKS.BROWSER.isFirefox()&&a.keyCode===0&&(b=165);if(!b)return WMKS.LOGGER.trace("assert: could not read keycode from event, keyIdentifier="+a.keyIdentifier),null}return!c&&this._windowsKeyManager.enabled&&(b=this._windowsKeyManager.modifyKey(b)),{keyCode:b,isUnicode:c}},this.onKeyDown=function(a){var b,c=0,d=!1,e=this;b=this._extractKeyCodeFromEvent(a);if(!b)return WMKS.LOGGER.log("Extraction of keyCode from keyUp event failed."),!1;c=b.keyCode,d=b.isUnicode,this._syncModifiers(a);if(c===0)return WMKS.LOGGER.log("onKeyDown: Do not send 0 to server."),!0;if($.inArray(c,WMKS.CONST.KB.Modifiers)!==-1)return a.returnValue=!1,!1;if(WMKS.CONST.KB.ControlKeys.indexOf(c)!==-1)return a.returnValue=!1,this._handleControlKeys(c);if(d)return WMKS.LOGGER.log("Send unicode down from keyIdentifier: "+c),e.sendKey(c,!1,!0),a.returnValue=!1,!1;this.keyDownKeyTimer!==null&&(WMKS.LOGGER.log("assert: nuking an existing keyDownKeyTimer"),clearTimeout(this.keyDownKeyTimer));var f=0;return WMKS.BROWSER.isFirefox()&&WMKS.BROWSER.isMacOS()&&a.altKey===!0&&a.ctrlKey===!0&&!this.allowVMWKeyEvent2UnicodeAndRaw?f=1:f=0,this.keyDownKeyTimer=setTimeout(function(){e.sendKey(c,!1,!1),e.keyDownKeyTimer=null,e.pendingKey=null},f),this.pendingKey=c,a.originalEvent&&a.originalEvent.keyIdentifier&&(this.keyDownIdentifier=a.originalEvent.keyIdentifier),a.returnValue=this.activeModifiers.length!==1||this.activeModifiers[0]!==WMKS.CONST.KB.KEY_CODE.Alt&&this.activeModifiers[0]!==WMKS.CONST.KB.KEY_CODE.Ctrl&&this.activeModifiers[0]!==WMKS.CONST.KB.WindowsKeys.left&&this.activeModifiers[0]!==WMKS.CONST.KB.WindowsKeys.right,a.returnValue},this._handleControlKeys=function(a){if(this.isAddCapsLockEvent(a)){this.sendKey(a,!1,!1),this.sendKey(a,!0,!1);return}return this.sendKey(a,!1,!1),!1},this.isAddCapsLockEvent=function(a){return a===WMKS.CONST.KB.KEY_CODE.CapsLock&&WMKS.BROWSER.isMacOS()||a===240&&WMKS.BROWSER.isWindows()},this._handleCapsLockKey=function(a){if(this.isAddCapsLockEvent(a)&&!this._vncDecoder.allowVMWKeyEvent2UnicodeAndRaw)return this.sendKey(a,!1,!1),this.sendKey(a,!0,!1),!1},this._syncModifiers=function(a){var b,c,d,e,f=[a.shiftKey,a.ctrlKey,a.altKey,a.metaKey,!1,!1];a.altGraphKey===!0&&(f[1]=f[2]=!0),f=this.resetEventValue(a,f),a.metaKey===!0&&this.mapMetaToCtrlForKeys.indexOf(a.keyCode)!==-1&&(f[1]=!0,f[3]=!1);if(this._windowsKeyManager.enabled){this._windowsKeyManager.keyboardHandler(a);if(a.ctrlKey===!0)if(this._windowsKeyManager.leftWindowsDown||this.activeModifiers.indexOf(WMKS.CONST.KB.WindowsKeys.left)!==-1)f[1]=!1,f[3]=!0,this._windowsKeyManager.windowsOn=!0;else if(this._windowsKeyManager.rightWindowsDown||this.activeModifiers.indexOf(WMKS.CONST.KB.WindowsKeys.right)!==-1)f[1]=!1,f[4]=!0,this._windowsKeyManager.windowsOn=!0}for(d=0;d=32)b=a.charCode,c=!1;else if(a.keyCode)b=a.keyCode,b=this.remapUncontrolKey(a,b,c).keyCode,c=this.remapUncontrolKey(a,b,c).isRaw;else return WMKS.LOGGER.log("assert: could not read keypress event"),!1;this.keyDownKeyTimer!==null&&(clearTimeout(this.keyDownKeyTimer),this.keyDownKeyTimer=null);if(c&&WMKS.CONST.KB.ControlKeys.indexOf(b)!==-1)return!1;if(this.handleUnusefulKeys(a))return!1;a=this.fixDeFrChSpecialKeys(a,this.pendingKey,b),this._syncModifiers(a),this.pendingKey!==null&&(c?this.keyToRawMap[this.pendingKey]=b:this.keyToUnicodeMap[this.pendingKey]=b);if(this.fixANSIEquivalentKeys&&a.originalEvent){if(a.originalEvent.key)h=a.originalEvent.key;else if(!WMKS.BROWSER.isWindows()||!WMKS.BROWSER.isChrome())a.originalEvent.keyIdentifier===""&&this.keyDownIdentifier?h=String.fromCharCode(parseInt(this.keyDownIdentifier.replace("U+",""),16)):a.originalEvent.keyIdentifier&&(h=String.fromCharCode(parseInt(a.originalEvent.keyIdentifier.replace("U+",""),16)));h&&(f=h.charCodeAt(0)!==b,d=WMKS.CONST.KB.ANSIShiftSymbols.indexOf(h)!==-1&&this.activeModifiers.indexOf(WMKS.CONST.KB.KEY_CODE.Shift)===-1,e=WMKS.CONST.KB.ANSINoShiftSymbols.indexOf(h)!==-1&&this.activeModifiers.indexOf(WMKS.CONST.KB.KEY_CODE.Shift)!==-1,g=WMKS.CONST.KB.ANSISpecialSymbols.indexOf(h)!==-1)}return this.keyDownIdentifier=null,this.fixANSIEquivalentKeys&&h&&g&&(f||d||e)?(e&&this.sendKey(WMKS.CONST.KB.KEY_CODE.Shift,!0,!1),this.handleSoftKb(h.charCodeAt(0),!0),e&&this.sendKey
+(WMKS.CONST.KB.KEY_CODE.Shift,!1,!1)):(this._vncDecoder.allowVMWKeyEvent2UnicodeAndRaw||(b=this.handleInternationalKeyboard(a,b,this.pendingKey)),this.pendingKey!==null&&(c?this.keyToRawMap[this.pendingKey]=b:this.keyToUnicodeMap[this.pendingKey]=b),this.sendAndfixWrongKeys(a,b,c,this.pendingKey)),(this.pendingKey===50&&b===126||this.pendingKey===55&&b===96)&&!c&&(WMKS.LOGGER.debug("Sending extra up for Unicode "+b+" so one isn't missed."),this.sendKey(b,!0,!c)),this.pendingKey=null,!1},this.fixDeFrChSpecialKeys=function(a,b,c){return(this.keyboardLayoutId==="de-CH"||this.keyboardLayoutId==="fr-CH")&&WMKS.BROWSER.isWindows()&&WMKS.BROWSER.isFirefox()&&(a.charCode===176&&b===176?(a.keyCode=1176,a.charCode=1176):a.charCode===167&&b===167&&(a.keyCode=1167,a.charCode=1167)),a},this.sendAndfixWrongKeys=function(a,b,c,d){var e=this.isSmallKeyboardKey(a,b,d),f=this.isAddShiftKey(a,b),g=this.isAddAltGr(a,b),h=this.isDeleteShiftKey(a,b);if(e||f||h||g){if(e||f)this.sendKey(16,!1,!1),this.sendKey(b,!1,!c),this.sendKey(16,!0,!1);h&&(this.sendKey(16,!0,!1),this.sendKey(b,!1,!c),this.sendKey(16,!1,!1)),g&&(this.sendKey(17,!1,!1),this.sendKey(18,!1,!1),this.sendKey(b,!1,!c),this.sendKey(17,!0,!1),this.sendKey(18,!0,!1))}else this.sendKey(b,!1,!c)},this.isSmallKeyboardKey=function(a,b,c){var d=!1,e=WMKS.keyboardUtils._SmallKeyboardKey[this.keyboardLayoutId];return a.shiftKey===!1&&a.altKey===!1&&a.ctrlKey===!1&&this.isFitSmallKeyboardPendingKey(b,c)&&!!e&&e.indexOf(b)!==-1&&(d=!0),d},this.isFitSmallKeyboardPendingKey=function(a,b){var c=!0,d=WMKS.keyboardUtils._smallKeyboardPendingKey[this.keyboardLayoutId];return d&&d[a]&&WMKS.BROWSER.isWindows()&&(d[a]===b||typeof d[a]=="object"&&d[a].indexOf(b)!==-1)&&(c=!1),c},this.isMacChromeVscancodeFr=function(){return WMKS.BROWSER.isMacOS()&&!this._vncDecoder.allowVMWKeyEvent2UnicodeAndRaw&&this.keyboardLayoutId=="fr-FR"},this.isAddShiftKey=function(a,b){var c=a.keyCode||a.charCode;return c==167&&this.isMacChromeVscancodeFr()},this.isDeleteShiftKey=function(a,b){var c=a.keyCode||a.charCode;return(c==95||c==42||c==35)&&this.isMacChromeVscancodeFr()&&a.shiftKey},this.isAddAltGr=function(a,b){var c=a.keyCode||a.charCode;return(c==64||c==35)&&this.isMacChromeVscancodeFr()},this.handleUnusefulKeys=function(a){var b=!1,c;return WMKS.BROWSER.isIE()&&WMKS.BROWSER.version.major>10&&(c=WMKS.keyboardUtils._keypressUnusefulKeys[this.keyboardLayoutId],!!c&&c.indexOf(a.keyCode)!==-1&&(b=!0)),b},this.remapUncontrolKey=function(a,b,c){var d=WMKS.BROWSER.isChrome()&&a.altKey&&a.ctrlKey,c=!0,e,f=WMKS.keyboardUtils._remapUncontrolKeys[this.keyboardLayoutId];return d&&(f!==undefined&&(e=f[a.keyCode]),e!==undefined&&(c=!1,b=e)),{keyCode:b,isRaw:c}},this.handleInternationalKeyboard=function(a,b,c){var d=WMKS.BROWSER.isChrome()&&a.altKey&&a.ctrlKey,e=WMKS.BROWSER.isFirefox()&&a.altKey&&a.ctrlKey,f=a.keyCode===0&&WMKS.BROWSER.isFirefox()&&a.key&&a.charCode===0,g=WMKS.CONST.KB.WestEuroLanguage.indexOf(this.keyboardLayoutId)!==-1;!g&&a.keyCode===0&&WMKS.BROWSER.isFirefox()&&a.key&&!b&&(b=0);switch(this.keyboardLayoutId){case"ja-JP_106/109":b=this.getRemapPendingKey(b,c);break;case"de-DE":(b==123||b==124||b==125)&&(d||WMKS.BROWSER.isFirefox)&&WMKS.BROWSER.isWindows()&&(b==123?b=124:b==124?b=8804:b==125&&(b=8800)),b==192&&WMKS.BROWSER.isFirefox()&&WMKS.BROWSER.isMacOS()&&(b=187),b=this.getRemapPendingKey(b,c);break;case"it-IT":a.keyCode===37&&d&&(b=a.keyCode+1e3),f&&a.key=="#"&&WMKS.BROWSER.isWindows()&&(b=35);break;case"es-ES":a.keyCode===0&&WMKS.BROWSER.isFirefox()&&(a.key==" "||a.key=="Dead")&&a.charCode==0&&a.which==0&&(b=222),f&&a.key=="\\"&&WMKS.BROWSER.isWindows()&&(b=186),(a.keyCode===48||a.keyCode===34)&&d&&(b=a.keyCode+1e3),b=this.getRemapPendingKey(b,c);break;case"pt-PT":(b==123||b==167)&&(d||WMKS.BROWSER.isFirefox)&&WMKS.BROWSER.isWindows()&&(b==123?b=55:b==167&&(b=52)),WMKS.BROWSER.isFirefox&&WMKS.BROWSER.isWindows()&&(a.key=="«"&&(b=187),a.key=="À"&&(b=333)),a.keyCode==192&&WMKS.BROWSER.isChrome&&WMKS.BROWSER.isWindows()&&(b=333);break;case"fr-FR":a.keyCode===29&&WMKS.BROWSER.isChrome()&&a.key!="€"&&WMKS.BROWSER.isMacOS()&&(b=124),b=this.getRemapPendingKey(b,c);break;case"fr-CH":case"de-CH":if(a.ctrlKey===!0&&a.altKey===!0){var h=a.keyCode||a.which;WMKS.BROWSER.isMacOS()&&(h===61&&(b=187),a.keyCode===34&&WMKS.BROWSER.isChrome()&&(b=224))}(a.keyCode||a.which)===96&&(WMKS.BROWSER.isChrome()||WMKS.BROWSER.isFirefox())&&WMKS.BROWSER.isWindows()&&a.key==="`"&&(b=94);if(f||WMKS.BROWSER.isMacOS()&&e)b=this.getKeyCodeFromKey(a,b)||b;WMKS.BROWSER.isWindows()&&e&&(b=this.getRemapFrChAltgrKey(b)),a.key==="§"&&e&&WMKS.BROWSER.isMacOS()&&(b=232),a.key==="À"&&(a.keyCode||a.which)===192&&this.keyboardLayoutId==="de-CH"&&c!==65&&(WMKS.BROWSER.isMacOS()||WMKS.BROWSER.isFirefox()&&WMKS.BROWSER.isWindows())&&(b=1224),b=this.getRemapPendingKey(b,c)}return g&&(f||e)&&this.keyboardLayoutId!=="fr-CH"&&this.keyboardLayoutId!=="de-CH"&&(a.charCode===176&&WMKS.BROWSER.isMacOS()&&e?b=0:b=this.getKeyCodeFromKey(a,b)||b),b},this.getRemapFrChAltgrKey=function(a){var b=WMKS.keyboardUtils._remapFrChAltgrKey;return b&&b[a]&&(a=b[a]),a},this.getRemapPendingKey=function(a,b){var c=WMKS.keyboardUtils._remapPending[this.keyboardLayoutId];return c&&c[a]&&c[a]===b&&WMKS.BROWSER.isWindows()&&(a=b),a},this.getKeyCodeFromKey=function(a,b){var c=WMKS.keyboardUtils._charToKeycode[this.keyboardLayoutId];return c&&(b=c[a.key]),b},this.onKeyUp=function(a){var b,c,d,e,f=!1;return a.preventDefault?a.preventDefault():a.returnValue=!1,this.keyDownIdentifier=null,c=this._extractKeyCodeFromEvent(a),c?(b=c.keyCode,f=c.isUnicode,this._syncModifiers(a),b===0?(WMKS.LOGGER.log("onKeyUp: Do not send 0 to server."),!0):$.inArray(b,WMKS.CONST.KB.Modifiers)!==-1?!1:(this._handleCapsLockKey(b),f?(WMKS.LOGGER.log("Sending unicode key up from keyIdentifier: "+b),this.sendKey(b,!0,!0)):this.keyToUnicodeMap.hasOwnProperty(b)?(d=this.keyToUnicodeMap[b],this.sendKey(d,!0,!0),delete this.keyToUnicodeMap[b]):this.keyToRawMap.hasOwnProperty(b)?(e=this.keyToRawMap[b],this.sendKey(e,!0,!1),delete this.keyToRawMap[b]):this.sendKey(b,!0,!1),!1)):(WMKS.LOGGER.debug("Extraction of keyCode from keyUp event failed."),!1)},this.onKeyUpSoftKb=function(a){return a.stopPropagation(),a.preventDefault(),!1},this.onKeyDownSoftKb=function(a){var b=a.keyCode||a.which;return b&&WMKS.CONST.KB.SoftKBRawKeyCodes.indexOf(b)!==-1?(this.handleSoftKb(b,!1),!1):!0},this.onKeyPressSoftKb=function(a){var b=a.keyCode||a.which;return WMKS.BROWSER.isAndroid()&&WMKS.BROWSER.isChrome()?!0:($(a.target).val(WMKS.CONST.KB.keyInputDefaultValue),this.handleSoftKb(b,!0),!0)},this.onInputTextSoftKb=function(a){var b=$(a.target),c=b.val(),d=WMKS.CONST.KB.keyInputDefaultValue.length;return WMKS.BROWSER.isIOS()?(b.val(WMKS.CONST.KB.keyInputDefaultValue),!1):(d>0&&(c=c.substring(d)),c.length>1?(c=c.charAt(0).toLowerCase()+c.slice(1),this.processInputString(c)):WMKS.BROWSER.isAndroid()&&WMKS.BROWSER.isChrome()&&this.processInputString(c),b.val(WMKS.CONST.KB.keyInputDefaultValue),!0)},this.processInputString=function(a,b){var c,d=!1;for(c=0;c=0&&this._keysDownVScan.splice(c,1)}this._vncDecoder.onKeyVScan(a,b)},WMKS.keyboardMapper.prototype.doKeyUnicode=function(a,b){if(!this._vncDecoder.useVMWKeyEvent)return;if(b)this._keysDownUnicode.push(a);else{var c=this._keysDownUnicode.indexOf(a);c>=0&&this._keysDownUnicode.splice(c,1)}var d=this._tableUnicodeToVScan[a];d&&(b?this.beginTypematic(d&511):this.cancelTypematic(d&511),this._vncDecoder.onKeyVScan(d&511,b))},WMKS.keyboardMapper.prototype.doReleaseAll=function(){var a;for(a=0;a0&&console.log("Warning: Could not release all Unicode keys.");for(a=0;a=0)return;this.cancelTypematicDelay(),this.cancelTypematicPeriod(),this._vncDecoder.typematicState===1&&this.startTypematicDelay(a)},WMKS.keyboardMapper.prototype.cancelTypematic=function(a){this._typematicKeyVScan===a&&(this.cancelTypematicDelay(),this.cancelTypematicPeriod())},WMKS.keyboardMapper.prototype.cancelTypematicDelay=function(){this._typematicDelayTimer!==null&&clearTimeout(this._typematicDelayTimer),this._typematicDelayTimer=null},WMKS.keyboardMapper.prototype.cancelTypematicPeriod=function(){this._typematicPeriodTimer!==null&&clearInterval(this._typematicPeriodTimer),this._typematicPeriodTimer=null},WMKS.keyboardMapper.prototype.startTypematicDelay=function(a){var b=this;this._typematicKeyVScan=a,this._typematicDelayTimer=setTimeout(function(){b._typematicPeriodTimer=setInterval(function(){b._vncDecoder.onKeyVScan(b._typematicKeyVScan,1)},b._vncDecoder.typematicPeriod/1e3)},this._vncDecoder.typematicDelay/1e3)},WMKS.keyboardMapper.prototype._tableUnicodeToVScan={32:57,13:28,97:30,98:48,99:46,100:32,101:18,102:33,103:34,104:35,105:23,106:36,107:37,108:38,109:50,110:49,111:24,112:25,113:16,114:19,115:31,116:20,117:22,118:47,119:17,120:45,121:21,122:44,49:2,50:3,51:4,52:5,53:6,54:7,55:8,56:9,57:10,48:11,59:39,61:13,44:51,45:12,46:52,47:53,96:41,91:26,92:43,93:27,39:40,65:30,66:48,67:46,68:32,69:18,70:33,71:34,72:35,73:23,74:36,75:37,76:38,77:50,78:49,79:24,80:25,81:16,82:19,83:31,84:20,85:22,86:47,87:17,88:45,89:21,90:44,33:2,64:3,35:4,36:5,37:6,94:7,38:8,42:9,40:10,41:11,58:39,43:13,60:51,95:12,62:52,63:53,126:41,123:26,124:43,125:27,34:40},WMKS.CONST.TOUCH={FEATURE:{SoftKeyboard:0,ExtendedKeypad:1,Trackpad:2},tapMoveCorrectionDistancePx:10,additionalTouchIgnoreGapMs:1200,touchMoveSampleMinCount:2,minKeyboardToggleTime:50,leftDragDelayMs:300,OP:{none:"none",scroll:"scroll",drag:"drag",move:"move",tap_twice:"double-click",tap_1finger:"click",tap_3finger:"tap-3f"},SCROLL:{minDeltaDistancePx:20},DOUBLE_TAP:{tapGapInTime:250,tapGapBonusTime:200,tapGapBonus4TimeRatio:.4,tapGapInDistance:40}},WMKS.TouchHandler=function(a){"use strict";if(!a||!a.canvas||!a.widgetProto||!a.keyboardManager)return WMKS.LOGGER.warn("Invalid params set for TouchHandler."),null;var b=a.widgetProto,c=a.keyboardManager,d={visible:!1,lastToggleTime:0},e=[],f=a.canvas,g=a.onToggle,h=null,i={currentTouchFingers:-1,firstTouch:null,currentTouch:null,touchArray:[],tapStartTime:null,touchMoveCount:0,skipScrollCount:0,scrollCount:0,zoomCount:0,opType:WMKS.CONST.TOUCH.OP.none},j={inputProxy:null,cursorIcon:null,clickFeedback:null,dragFeedback:null,pulseFeedback:null,scrollFeedback:null,keypad:null,trackpad:null};this._verifyQuickTouches=function(a,b,c){return i.opType===WMKS.CONST.TOUCH.OP.none&&b>50&&c===1?(WMKS.LOGGER.debug("Special case - touchmove#: "+c+", targetTouches#: "+a.targetTouches.length+", dist: "+b+", scale: "+a.scale),!0):!1},this._initDragEventAndSendFeedback=function(a){if(i.opType===WMKS.CONST.TOUCH.OP.drag){var c=this._applyZoomCorrectionToTouchXY(a);b.sendMouseButtonMessage(c,!0,WMKS.CONST.CLICK.left),this._showFeedback(j.dragFeedback,a)}},this._initTwoFingerTouch=function(a,b){i.opType===WMKS.CONST.TOUCH.OP.none&&(i.currentTouchFingers=2,i.touchArray.push(a),i.touchArray.push(b),i.firstTouch=WMKS.UTIL.TOUCH.copyTouch(WMKS.UTIL.TOUCH.leftmostOf(a,b)),i.currentTouch=WMKS.UTIL.TOUCH.copyTouch(i.firstTouch))},this._sendScrollEventMessage=function(a){var c=0,d=0,e,f,g,h;if(i.opType===WMKS.CONST.TOUCH.OP.scroll){e=a.clientX-i.currentTouch.clientX,f=a.clientY-i.currentTouch.clientY,g=this._calculateMouseWheelDeltas(e,f),c=g.wheelDeltaX,d=g.wheelDeltaY;if(c!==0||d!==0)h=this._applyZoomCorrectionToTouchXY(i.touchArray[0]),b.sendScrollMessage(h,c,d),c!==0&&(i.currentTouch.clientX=a.clientX),d!==0&&(i.currentTouch.clientY=a.clientY)}},this._calculateMouseWheelDeltas=function(a,c){var d=0,e=0,f=Math.abs(a),g=Math.abs(c),h=f>WMKS.CONST.TOUCH.SCROLL.minDeltaDistancePx,i=g>WMKS.CONST.TOUCH.SCROLL.minDeltaDistancePx,j;return h&&i&&(g0?1:-1),i&&(e=c>0?-1:1),b.options.reverseScrollY&&(e*=-1),{wheelDeltaX:d,wheelDeltaY:e}},this._updatePreScrollState=function(a){var b=a.clientY-i.currentTouch.clientY;i.scrollCount++,b<0?i.skipScrollCount--:i.skipScrollCount++},this._sendResidualScrollEventMessage=function(){if(i.skipScrollCount!==0&&i.currentTouch){var a,c;c=i.skipScrollCount<0?-1:1,WMKS.LOGGER.debug("Sending a residual scroll message."),WMKS.LOGGER.debug("Cur touch: "+i.currentTouch.pageX+" , "+i.currentTouch.pageY),i.skipScrollCount=0,a=this._applyZoomCorrectionToTouchXY(i.currentTouch),b.sendScrollMessage(a,c,0)}},this._isDoubleTap=function(a,b){var c,d;if(i.currentTouch===null||i.tapStartTime===null||i.opType!==WMKS.CONST.TOUCH.OP.none)return!1;c=WMKS.UTIL.TOUCH.touchDistance(i.currentTouch,a.targetTouches[0]),d=b-i.tapStartTime;if(cWMKS.CONST.TOUCH.additionalTouchIgnoreGapMs&&i.opType===WMKS.CONST.TOUCH.OP.drag&&(c=this._applyZoomCorrectionToTouchXY(a.targetTouches[0]),b.sendMouseButtonMessage(c,!0,WMKS.CONST.CLICK.left),this._resetTouchState())),this._initTwoFingerTouch(WMKS.UTIL.TOUCH.copyTouch(a.targetTouches[0]),WMKS.UTIL.TOUCH.copyTouch(a.targetTouches[1])),!0;if(a.targetTouches.length===3)return i.opType===WMKS.CONST.TOUCH.OP.none&&(i.opType=WMKS.CONST.TOUCH.OP.tap_3finger,this.toggleKeyboard(),i.currentTouchFingers=3),!1},this._onTouchMove=function(a){var c,d;h!==null&&(clearTimeout(h),h=null),i.touchMoveCount++;if(i.currentTouchFingers===-1)return!0;if(i.opType===WMKS.CONST.TOUCH.OP.scroll)return this._sendScrollEventMessage(a.targetTouches[0]),!1;if(i.opType===WMKS.CONST.TOUCH.OP.drag)return i.currentTouch=WMKS.UTIL.TOUCH.copyTouch(a.targetTouches[0]),this.moveCursor(a.targetTouches[0].pageX,a.targetTouches[0].pageY),d=this._applyZoomCorrectionToTouchXY(a.targetTouches[0]),b.sendMouseMoveMessage(d),!1;if(i.opType===WMKS.CONST.TOUCH.OP.tap_3finger)return!1;if(i.currentTouchFingers!==a.targetTouches.length){if(i.currentTouchFingers!==2||a.targetTouches.length!==1)return i.currentTouchFingers===1&&a.targetTouches.length===2?(WMKS.LOGGER.debug("touch: 1 -> 2, init 2fingertap if no opType: "+i.opType),this._initTwoFingerTouch(WMKS.UTIL.TOUCH.copyTouch(a.targetTouches[0]),WMKS.UTIL.TOUCH.copyTouch(a.targetTouches[1])),!0):(WMKS.LOGGER.debug("touch: 2 -> 1: infer as PINCH/ZOOM."),this._resetTouchState(),!0);if(i.opType===WMKS.CONST.TOUCH.OP.none&&a.scale===1)return WMKS.LOGGER.debug("touch: 2 -> 1 & !scroll, hence right-click."),this._sendTwoTouchEvent(i.firstTouch,i.firstTouch,WMKS.CONST.CLICK.right,a),this._resetTouchState(),!1}else{if(i.currentTouchFingers===1)return c=WMKS.UTIL.TOUCH.touchDistance(a.targetTouches[0],i.currentTouch),this._verifyQuickTouches(a,c,i.touchMoveCount)?(this._initTwoFingerTouch(WMKS.UTIL.TOUCH.copyTouch(i.firstTouch),WMKS.UTIL.TOUCH.copyTouch(a.targetTouches[0])),i.opType=WMKS.CONST.TOUCH.OP.scroll,!1):c5.2){this._updatePreScrollState(a.targetTouches[0]);if(i.scrollCount>=WMKS.CONST.TOUCH.touchMoveSampleMinCount)return this._showFeedback(j.scrollFeedback,i.firstTouch,{position:"left",offsetLeft:-50,offsetTop:-25}),i.opType=WMKS.CONST.TOUCH.OP.scroll,i.currentTouch=WMKS.UTIL.TOUCH.copyTouch(a.targetTouches[0]),!1}else{i.zoomCount++;if(i.zoomCount>=WMKS.CONST.TOUCH.touchMoveSampleMinCount)return this._resetTouchState(),!0}return!0}}return!0},this._onTouchEnd=function(a){var c,d;h!==null&&(clearTimeout(h),h=null);if(i.currentTouchFingers===-1)return!0;if(a.targetTouches.length===0){i.skipScrollCount!==0&&(i.opType=WMKS.CONST.TOUCH.OP.scroll);switch(i.opType){case WMKS.CONST.TOUCH.OP.scroll:return this._sendResidualScrollEventMessage(a),this._resetTouchState(),!1;case WMKS.CONST.TOUCH.OP.tap_twice:return this._sendTwoTouchEvent(i.firstTouch,i.currentTouch,WMKS.CONST.CLICK.left,a),this._resetTouchState(),!1;case WMKS.CONST.TOUCH.OP.tap_3finger:return this._resetTouchState(),!1;case WMKS.CONST.TOUCH.OP.drag:return d=a.changedTouches,d.length===1?(c=this._applyZoomCorrectionToTouchXY(d[0]),b.sendMouseButtonMessage(c,!1,WMKS.CONST.CLICK.left)):WMKS.LOGGER.warn("Unexpected touch# "+d.length+" changed in a drag operation!"),this._resetTouchState(),!1;default:if(i.currentTouchFingers===1)return this._sendTwoTouchEvent(i.firstTouch,i.currentTouch,WMKS.CONST.CLICK.left,a),this._resetTouchState(!0),!1;if(i.currentTouchFingers===2)return this._sendTwoTouchEvent(i.firstTouch,i.firstTouch,WMKS.CONST.CLICK.right,a),this._resetTouchState(),!1}return this._resetTouchState(),!1}},this._resetTouchState=function(a){a||(i.tapStartTime=null,i.currentTouch=null),i.currentTouchFingers=-1,i.opType=WMKS.CONST.TOUCH.OP.none,i.firstTouch=null,i.touchArray.length=0,i.touchMoveCount=0,i.skipScrollCount=0,i.scrollCount=0,i.zoomCount=0},this._sendTwoTouchEvent=function(a,c,d){var e=this._applyZoomCorrectionToTouchXY(a);return b.sendMouseButtonMessage(e,!0,d),i.opType===WMKS.CONST.TOUCH.OP.tap_twice?(b.sendMouseButtonMessage(e,!1,d),this._showFeedback(j.clickFeedback,a,{showTwice:!0})):(e=this._applyZoomCorrectionToTouchXY(c),b.sendMouseButtonMessage(e,!1,d),this._showFeedback(j.clickFeedback,a)),!0},this.addToRepositionQueue=function(a){a&&e.push(a)},this.widgetRepositionOnRotation=function(a){var b,c,d,e,f,g=!1;return WMKS.BROWSER.isTouchDevice()?!a||a.is(":hidden")?!1:(b=a.width(),c=a.height(),e=window.innerWidth,f=window.innerHeight,WMKS.UTIL.TOUCH.isPortraitOrientation()?a.offset().left+b>e&&(a.offset({left:String(e-b-5)}),g=!0):a.offset().top+c>f&&(a.offset({top:String(f-c-5)}),g=!0),g):(WMKS.LOGGER.warn("Widget reposition ignored, this is not a touch device."),!1)},this._repositionFloatingElementsOnRotation=function(a){var b=this,c=f.offset();this.widgetRepositionOnRotation(j.inputProxy),this.widgetRepositionOnRotation(j.cursorIcon),j.clickFeedback.offset(c),j.dragFeedback.offset(c),j.pulseFeedback.offset(c),j.scrollFeedback.offset(c),$.each(e,function(a,c){try{b.widgetRepositionOnRotation(c)}catch(d){WMKS.LOGGER.warn("Custom element reposition failed: "+d)}})},this._onOrientationChange=function(a){var b=this;this._isInputInFocus()&&$(window).one("resize",function(a){setTimeout(function(){$(window).trigger("orientationchange"),b._repositionFloatingElementsOnRotation()},500)})},this._applyZoomCorrectionToTouchXY=function(a){return a===null?(WMKS.LOGGER.warn("Unexpected: touch is null."),null):b.getEventPosition(a)},this._showFeedback=function(a,b,c){var d,e,f,g=c||{};if(!b||!a){WMKS.LOGGER.trace("No touch value / feedback object, skip feedback.");return}e=g.offsetLeft||0,f=g.offsetTop||0,d=WMKS.UTIL.TOUCH.getRelativePositionMultiplier(g.position),a.css({left:b.pageX+e+a.outerWidth()*d.width,top:b.pageY+f+a.outerHeight()*d.height}),this.moveCursor(b.pageX,b.pageY),a.removeClass("animate-feedback-indicator animate-double-feedback-indicator"),g.showTwice?setTimeout(function(){a.addClass("animate-double-feedback-indicator")},0):setTimeout(function(){a.addClass("animate-feedback-indicator")},0)},this.moveCursor=function(a,b){j.cursorIcon&&j.cursorIcon.css({left:a,top:b})},this.setCursorVisibility=function(a){j.cursorIcon&&(a?j.cursorIcon.show():j.cursorIcon.hide())},this._sendKeyInput=function(a){b.sendKeyInput(a)},this.onCaretPositionChanged=function(a){var b,c;j.inputProxy&&(b=a.x,c=a.y,b").addClass("feedback-container cursor-icon").appendTo(b),j.clickFeedback=$("").addClass("feedback-container tap-icon").appendTo(b),j.dragFeedback=$("").addClass("feedback-container drag-icon").appendTo(b),j.pulseFeedback=$("").addClass("feedback-container pulse-icon").appendTo(b),j.scrollFeedback=$("").addClass("feedback-container scroll-icon").appendTo(b),b.find(".feedback-container").bind("touchmove.wmks",function(b){return a._onTouchMove(b.originalEvent)}).bind("touchstart.wmks",function(b){return a._onTouchStart(b.originalEvent)}).bind("touchend.wmks",function(b){return a._onTouchEnd(b.originalEvent)})},this.disconnectEvents=function(){if(!f)return;f.unbind("orientationchange.wmks.icons").unbind("orientationchange.wmks").unbind("touchmove.wmks").unbind("touchstart.wmks").unbind("touchend.wmks"),f.find(".feedback-container").unbind("touchmove.wmks").unbind("touchstart.wmks").unbind("touchend.wmks")},this.initializeMobileFeature=function(a){if(!WMKS.BROWSER.isTouchDevice())return;switch(a){case WMKS.CONST.TOUCH.FEATURE.Trackpad:j.trackpad=new WMKS.trackpadManager(b,f),j.trackpad.initialize();break;case WMKS.CONST.TOUCH.FEATURE.ExtendedKeypad:j.keypad=new WMKS.extendedKeypad({widget:b,parentElement:f.parent(),keyboardManager:c}),j.keypad.initialize();break;case WMKS.CONST.TOUCH.FEATURE.SoftKeyboard:j.inputProxy=this.initSoftKeyboard();break;default:WMKS.LOGGER.error("Invalid mobile feature type: "+a)}},this.initSoftKeyboard=function(){var a=this,b=c,d=$('').val(WMKS.CONST.KB.keyInputDefaultValue).attr({id:"input-proxy",autocorrect:"off",autocapitalize:"off"}).css({"font-size":"1px",width:"1px",height:"1px","background-color":"transparent",color:"transparent","box-shadow":0,outline:"none",border:0,padding:0,left:-1,top:-1,overflow:"hidden",position:"absolute"}).bind("blur",function(b){return a._onInputBlur(b)}).bind("focus",function(b){return a._onInputFocus(b)}).bind("input",function(a){return b.onInputTextSoftKb(a)}).bind("keydown",function(a){return b.onKeyDownSoftKb(a)}).bind("keyup",function(a){return b.onKeyUpSoftKb(a)}).bind("keypress",function(a){return b.onKeyPressSoftKb(a)}).insertBefore(f.parent());return WMKS.BROWSER.isIOS()&&d.css({"-webkit-touch-callout":"none"}),d},this.removeMobileFeature=function(a){switch(a){case WMKS.CONST.TOUCH.FEATURE.Trackpad:j.trackpad&&(j.trackpad.destroy(),j.trackpad=null);break;case WMKS.CONST.TOUCH.FEATURE.ExtendedKeypad:j.keypad&&(j.keypad.destroy(),j.keypad=null);break;case WMKS.CONST.TOUCH.FEATURE.SoftKeyboard:j.inputProxy&&(d.visible&&this.toggleKeyboard(!1),j.inputProxy.remove(),j.inputProxy=null);break;default:WMKS.LOGGER.error("Invalid mobile feature type: "+a)}},this.destroy=function(){this.disconnectEvents(),this.removeMobileFeature(WMKS.CONST.TOUCH.FEATURE.SoftKeyboard),this.removeMobileFeature(WMKS.CONST.TOUCH.FEATURE.ExtendedKeypad),this.removeMobileFeature(WMKS.CONST.TOUCH.FEATURE.Trackpad),b=null,f=null,c=null,i=null,j=null,e.length=0,e=null}},WMKS.UTIL.TOUCH={isLandscapeOrientation
+:function(){return window.orientation===90||window.orientation===-90},isPortraitOrientation:function(){return window.orientation===0||window.orientation===180},getRelativePositionMultiplier:function(a){var b=-0.5,c=-0.5;return!a||(a.indexOf("left")!==-1?b=-1:a.indexOf("right")!==-1&&(b=1),a.indexOf("top")!==-1?c=-1:a.indexOf("bottom")!==-1&&(c=1)),{width:b,height:c}},touchEqual:function(a,b){return a.screenX===b.screenX&&a.screenY===b.screenY},touchDistance:function(a,b){return WMKS.UTIL.getLineLength(b.screenX-a.screenX,b.screenY-a.screenY)},touchAngleBwLines:function(a,b,c,d){var e=Math.atan2(a.screenY-b.screenY,a.screenX-b.screenX),f=Math.atan2(c.screenY-d.screenY,c.screenX-d.screenX);return e-f},copyTouch:function(a){var b={screenX:a.screenX,screenY:a.screenY,clientX:a.clientX,clientY:a.clientY,pageX:a.pageX,pageY:a.pageY};return b},leftmostOf:function(a,b){return a.screenX>1,this.sendMouseButtonMessage(d,b,e)}},WMKS.widgetProto.sendMouseButtonMessage=function(a,b,c){return this._vncDecoder&&(b?this._mouseDownBMask|=c:this._mouseDownBMask&=~c,(this._mousePosGuest.x!==a.x||this._mousePosGuest.y!==a.y)&&this.sendMouseMoveMessage(a),this._vncDecoder.onMouseButton(a.x,a.y,b,c)),!0},WMKS.widgetProto._onMouseWheel=function(a){if(this._vncDecoder&&this._isCanvasMouseEvent(a)){var b=a||window.event,c=this.getEventPosition(b),d=Math.max(Math.min(a.wheelDeltaX,1),-1),e=Math.max(Math.min(a.wheelDeltaY,1),-1);return this.options.reverseScrollY&&(e*=-1),this.sendScrollMessage(c,d,e),a.stopPropagation(),a.preventDefault(),!1}},WMKS.widgetProto.sendScrollMessage=function(a,b,c){this._vncDecoder&&this._vncDecoder.onMouseWheel(a.x,a.y,b,c)},WMKS.widgetProto._onMouseMove=function(a){if(this._vncDecoder&&this._isCanvasMouseEvent(a)){var b=a||window.event,c=this.getEventPosition(b);this.sendMouseMoveMessage(c)}return!0},WMKS.widgetProto.sendMouseMoveMessage=function(a){this._vncDecoder&&(this._vncDecoder.onMouseMove(a.x,a.y),this._mousePosGuest=a,this._touchHandler&&this._touchHandler.onCaretPositionChanged(a))},WMKS.widgetProto._onBlur=function(a){return this.connected&&(this._keyboardManager.cancelModifiers(),this._vncDecoder.onMouseButton(this._mousePosGuest.x,this._mousePosGuest.y,0,this._mouseDownBMask),this._mouseDownBMask=0),!0},WMKS.widgetProto._onPaste=function(a){var b=a.originalEvent,c=this;if(b&&b.clipboardData){var d=b.clipboardData.items;if(d)for(var e=0;e0?(this._keyboardManager.sendKey(d,!1,!1),(d!==20||WMKS.BROWSER.isMacOS())&&c.push(d)):d<0&&this._keyboardManager.sendKey(0-d,!0,!0)}for(b=c.length-1;b>=0;b--)this._keyboardManager.sendKey(c[b],!0,!1)},WMKS.widgetProto.rescale=function(){this.rescaleOrResize(!0)},WMKS.widgetProto.updateFitGuestSize=function(a){var b=this.element.width()*this._pixelRatio,c=this.element.height()*this._pixelRatio;if(!this.options.fitGuest||a&&this._guestWidth===b&&this._guestWidth===c)return;this._vncDecoder.onRequestResolution(b,c)},WMKS.widgetProto.updateTopology=function(a){var b;if(!this.options.fitGuest)return;for(b=0;b