SPB Git forge

spb/admin-ka

Public
41commits 1branches 0releases
172.9 MBsize
maindefault branch
19 days agolast push
JavaScript 65.5% Python 17.8% CSS 13% HTML 3.7%
132.4 KB · 3,398 lines javascript
Raw Blame History
1"use strict";23function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }4Object.defineProperty(exports, "__esModule", {5  value: true6});7exports["default"] = void 0;8var _int = require("./util/int.js");9var Log = _interopRequireWildcard(require("./util/logging.js"));10var _strings = require("./util/strings.js");11var _browser = require("./util/browser.js");12var _element = require("./util/element.js");13var _events = require("./util/events.js");14var _eventtarget = _interopRequireDefault(require("./util/eventtarget.js"));15var _display = _interopRequireDefault(require("./display.js"));16var _inflator = _interopRequireDefault(require("./inflator.js"));17var _deflator = _interopRequireDefault(require("./deflator.js"));18var _keyboard = _interopRequireDefault(require("./input/keyboard.js"));19var _gesturehandler = _interopRequireDefault(require("./input/gesturehandler.js"));20var _cursor = _interopRequireDefault(require("./util/cursor.js"));21var _websock = _interopRequireDefault(require("./websock.js"));22var _keysym = _interopRequireDefault(require("./input/keysym.js"));23var _xtscancodes = _interopRequireDefault(require("./input/xtscancodes.js"));24var _encodings = require("./encodings.js");25var _ra = _interopRequireDefault(require("./ra2.js"));26var _crypto = _interopRequireDefault(require("./crypto/crypto.js"));27var _raw = _interopRequireDefault(require("./decoders/raw.js"));28var _copyrect = _interopRequireDefault(require("./decoders/copyrect.js"));29var _rre = _interopRequireDefault(require("./decoders/rre.js"));30var _hextile = _interopRequireDefault(require("./decoders/hextile.js"));31var _zlib = _interopRequireDefault(require("./decoders/zlib.js"));32var _tight = _interopRequireDefault(require("./decoders/tight.js"));33var _tightpng = _interopRequireDefault(require("./decoders/tightpng.js"));34var _zrle = _interopRequireDefault(require("./decoders/zrle.js"));35var _jpeg = _interopRequireDefault(require("./decoders/jpeg.js"));36var _h = _interopRequireDefault(require("./decoders/h264.js"));37function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }38function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }39function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }40function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator["return"] && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, "catch": function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }41function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }42function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }43function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }44function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }45function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }46function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }47function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }48function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }49function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }50function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }51function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }52function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }53function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }54function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }55function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }56function _possibleConstructorReturn(t, e) { if (e && ("object" == _typeof(e) || "function" == typeof e)) return e; if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined"); return _assertThisInitialized(t); }57function _assertThisInitialized(e) { if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return e; }58function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }59function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); }60function _inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, "prototype", { writable: !1 }), e && _setPrototypeOf(t, e); }61function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); } /*62 * noVNC: HTML5 VNC client63 * Copyright (C) 2020 The noVNC authors64 * Licensed under MPL 2.0 (see LICENSE.txt)65 *66 * See README.md for usage and integration instructions.67 *68 */69// How many seconds to wait for a disconnect to finish70var DISCONNECT_TIMEOUT = 3;71var DEFAULT_BACKGROUND = 'rgb(40, 40, 40)';7273// Minimum wait (ms) between two mouse moves74var MOUSE_MOVE_DELAY = 17;7576// Wheel thresholds77var WHEEL_STEP = 50; // Pixels needed for one step78var WHEEL_LINE_HEIGHT = 19; // Assumed pixels for one line step7980// Gesture thresholds81var GESTURE_ZOOMSENS = 75;82var GESTURE_SCRLSENS = 50;83var DOUBLE_TAP_TIMEOUT = 1000;84var DOUBLE_TAP_THRESHOLD = 50;8586// Security types87var securityTypeNone = 1;88var securityTypeVNCAuth = 2;89var securityTypeRA2ne = 6;90var securityTypeTight = 16;91var securityTypeVeNCrypt = 19;92var securityTypeXVP = 22;93var securityTypeARD = 30;94var securityTypeMSLogonII = 113;9596// Special Tight security types97var securityTypeUnixLogon = 129;9899// VeNCrypt security types100var securityTypePlain = 256;101102// Extended clipboard pseudo-encoding formats103var extendedClipboardFormatText = 1;104/*eslint-disable no-unused-vars */105var extendedClipboardFormatRtf = 1 << 1;106var extendedClipboardFormatHtml = 1 << 2;107var extendedClipboardFormatDib = 1 << 3;108var extendedClipboardFormatFiles = 1 << 4;109/*eslint-enable */110111// Extended clipboard pseudo-encoding actions112var extendedClipboardActionCaps = 1 << 24;113var extendedClipboardActionRequest = 1 << 25;114var extendedClipboardActionPeek = 1 << 26;115var extendedClipboardActionNotify = 1 << 27;116var extendedClipboardActionProvide = 1 << 28;117var RFB = exports["default"] = /*#__PURE__*/function (_EventTargetMixin) {118  function RFB(target, urlOrChannel, options) {119    var _this;120    _classCallCheck(this, RFB);121    if (!target) {122      throw new Error("Must specify target");123    }124    if (!urlOrChannel) {125      throw new Error("Must specify URL, WebSocket or RTCDataChannel");126    }127128    // We rely on modern APIs which might not be available in an129    // insecure context130    if (!window.isSecureContext) {131      Log.Error("noVNC requires a secure context (TLS). Expect crashes!");132    }133    _this = _callSuper(this, RFB);134    _this._target = target;135    if (typeof urlOrChannel === "string") {136      _this._url = urlOrChannel;137    } else {138      _this._url = null;139      _this._rawChannel = urlOrChannel;140    }141142    // Connection details143    options = options || {};144    _this._rfbCredentials = options.credentials || {};145    _this._shared = 'shared' in options ? !!options.shared : true;146    _this._repeaterID = options.repeaterID || '';147    _this._wsProtocols = options.wsProtocols || [];148149    // Internal state150    _this._rfbConnectionState = '';151    _this._rfbInitState = '';152    _this._rfbAuthScheme = -1;153    _this._rfbCleanDisconnect = true;154    _this._rfbRSAAESAuthenticationState = null;155156    // Server capabilities157    _this._rfbVersion = 0;158    _this._rfbMaxVersion = 3.8;159    _this._rfbTightVNC = false;160    _this._rfbVeNCryptState = 0;161    _this._rfbXvpVer = 0;162    _this._fbWidth = 0;163    _this._fbHeight = 0;164    _this._fbName = "";165    _this._capabilities = {166      power: false167    };168    _this._supportsFence = false;169    _this._supportsContinuousUpdates = false;170    _this._enabledContinuousUpdates = false;171    _this._supportsSetDesktopSize = false;172    _this._screenID = 0;173    _this._screenFlags = 0;174    _this._pendingRemoteResize = false;175    _this._lastResize = 0;176    _this._qemuExtKeyEventSupported = false;177    _this._extendedPointerEventSupported = false;178    _this._clipboardText = null;179    _this._clipboardServerCapabilitiesActions = {};180    _this._clipboardServerCapabilitiesFormats = {};181182    // Internal objects183    _this._sock = null; // Websock object184    _this._display = null; // Display object185    _this._flushing = false; // Display flushing state186    _this._keyboard = null; // Keyboard input handler object187    _this._gestures = null; // Gesture input handler object188    _this._resizeObserver = null; // Resize observer object189190    // Timers191    _this._disconnTimer = null; // disconnection timer192    _this._resizeTimeout = null; // resize rate limiting193    _this._mouseMoveTimer = null;194195    // Decoder states196    _this._decoders = {};197    _this._FBU = {198      rects: 0,199      x: 0,200      y: 0,201      width: 0,202      height: 0,203      encoding: null204    };205206    // Mouse state207    _this._mousePos = {};208    _this._mouseButtonMask = 0;209    _this._mouseLastMoveTime = 0;210    _this._viewportDragging = false;211    _this._viewportDragPos = {};212    _this._viewportHasMoved = false;213    _this._accumulatedWheelDeltaX = 0;214    _this._accumulatedWheelDeltaY = 0;215216    // Gesture state217    _this._gestureLastTapTime = null;218    _this._gestureFirstDoubleTapEv = null;219    _this._gestureLastMagnitudeX = 0;220    _this._gestureLastMagnitudeY = 0;221222    // Bound event handlers223    _this._eventHandlers = {224      focusCanvas: _this._focusCanvas.bind(_this),225      handleResize: _this._handleResize.bind(_this),226      handleMouse: _this._handleMouse.bind(_this),227      handleWheel: _this._handleWheel.bind(_this),228      handleGesture: _this._handleGesture.bind(_this),229      handleRSAAESCredentialsRequired: _this._handleRSAAESCredentialsRequired.bind(_this),230      handleRSAAESServerVerification: _this._handleRSAAESServerVerification.bind(_this)231    };232233    // main setup234    Log.Debug(">> RFB.constructor");235236    // Create DOM elements237    _this._screen = document.createElement('div');238    _this._screen.style.display = 'flex';239    _this._screen.style.width = '100%';240    _this._screen.style.height = '100%';241    _this._screen.style.overflow = 'auto';242    _this._screen.style.background = DEFAULT_BACKGROUND;243    _this._canvas = document.createElement('canvas');244    _this._canvas.style.margin = 'auto';245    // Some browsers add an outline on focus246    _this._canvas.style.outline = 'none';247    _this._canvas.width = 0;248    _this._canvas.height = 0;249    _this._canvas.tabIndex = -1;250    _this._screen.appendChild(_this._canvas);251252    // Cursor253    _this._cursor = new _cursor["default"]();254255    // XXX: TightVNC 2.8.11 sends no cursor at all until Windows changes256    // it. Result: no cursor at all until a window border or an edit field257    // is hit blindly. But there are also VNC servers that draw the cursor258    // in the framebuffer and don't send the empty local cursor. There is259    // no way to satisfy both sides.260    //261    // The spec is unclear on this "initial cursor" issue. Many other262    // viewers (TigerVNC, RealVNC, Remmina) display an arrow as the263    // initial cursor instead.264    _this._cursorImage = RFB.cursors.none;265266    // populate decoder array with objects267    _this._decoders[_encodings.encodings.encodingRaw] = new _raw["default"]();268    _this._decoders[_encodings.encodings.encodingCopyRect] = new _copyrect["default"]();269    _this._decoders[_encodings.encodings.encodingRRE] = new _rre["default"]();270    _this._decoders[_encodings.encodings.encodingHextile] = new _hextile["default"]();271    _this._decoders[_encodings.encodings.encodingZlib] = new _zlib["default"]();272    _this._decoders[_encodings.encodings.encodingTight] = new _tight["default"]();273    _this._decoders[_encodings.encodings.encodingTightPNG] = new _tightpng["default"]();274    _this._decoders[_encodings.encodings.encodingZRLE] = new _zrle["default"]();275    _this._decoders[_encodings.encodings.encodingJPEG] = new _jpeg["default"]();276    _this._decoders[_encodings.encodings.encodingH264] = new _h["default"]();277278    // NB: nothing that needs explicit teardown should be done279    // before this point, since this can throw an exception280    try {281      _this._display = new _display["default"](_this._canvas);282    } catch (exc) {283      Log.Error("Display exception: " + exc);284      throw exc;285    }286    _this._keyboard = new _keyboard["default"](_this._canvas);287    _this._keyboard.onkeyevent = _this._handleKeyEvent.bind(_this);288    _this._remoteCapsLock = null; // Null indicates unknown or irrelevant289    _this._remoteNumLock = null;290    _this._gestures = new _gesturehandler["default"]();291    _this._sock = new _websock["default"]();292    _this._sock.on('open', _this._socketOpen.bind(_this));293    _this._sock.on('close', _this._socketClose.bind(_this));294    _this._sock.on('message', _this._handleMessage.bind(_this));295    _this._sock.on('error', _this._socketError.bind(_this));296    _this._expectedClientWidth = null;297    _this._expectedClientHeight = null;298    _this._resizeObserver = new ResizeObserver(_this._eventHandlers.handleResize);299300    // All prepared, kick off the connection301    _this._updateConnectionState('connecting');302    Log.Debug("<< RFB.constructor");303304    // ===== PROPERTIES =====305306    _this.dragViewport = false;307    _this.focusOnClick = true;308    _this._viewOnly = false;309    _this._clipViewport = false;310    _this._clippingViewport = false;311    _this._scaleViewport = false;312    _this._resizeSession = false;313    _this._showDotCursor = false;314    if (options.showDotCursor !== undefined) {315      Log.Warn("Specifying showDotCursor as a RFB constructor argument is deprecated");316      _this._showDotCursor = options.showDotCursor;317    }318    _this._qualityLevel = 6;319    _this._compressionLevel = 2;320    return _this;321  }322323  // ===== PROPERTIES =====324  _inherits(RFB, _EventTargetMixin);325  return _createClass(RFB, [{326    key: "viewOnly",327    get: function get() {328      return this._viewOnly;329    },330    set: function set(viewOnly) {331      this._viewOnly = viewOnly;332      if (this._rfbConnectionState === "connecting" || this._rfbConnectionState === "connected") {333        if (viewOnly) {334          this._keyboard.ungrab();335        } else {336          this._keyboard.grab();337        }338      }339    }340  }, {341    key: "capabilities",342    get: function get() {343      return this._capabilities;344    }345  }, {346    key: "clippingViewport",347    get: function get() {348      return this._clippingViewport;349    }350  }, {351    key: "_setClippingViewport",352    value: function _setClippingViewport(on) {353      if (on === this._clippingViewport) {354        return;355      }356      this._clippingViewport = on;357      this.dispatchEvent(new CustomEvent("clippingviewport", {358        detail: this._clippingViewport359      }));360    }361  }, {362    key: "touchButton",363    get: function get() {364      return 0;365    },366    set: function set(button) {367      Log.Warn("Using old API!");368    }369  }, {370    key: "clipViewport",371    get: function get() {372      return this._clipViewport;373    },374    set: function set(viewport) {375      this._clipViewport = viewport;376      this._updateClip();377    }378  }, {379    key: "scaleViewport",380    get: function get() {381      return this._scaleViewport;382    },383    set: function set(scale) {384      this._scaleViewport = scale;385      // Scaling trumps clipping, so we may need to adjust386      // clipping when enabling or disabling scaling387      if (scale && this._clipViewport) {388        this._updateClip();389      }390      this._updateScale();391      if (!scale && this._clipViewport) {392        this._updateClip();393      }394    }395  }, {396    key: "resizeSession",397    get: function get() {398      return this._resizeSession;399    },400    set: function set(resize) {401      this._resizeSession = resize;402      if (resize) {403        this._requestRemoteResize();404      }405    }406  }, {407    key: "showDotCursor",408    get: function get() {409      return this._showDotCursor;410    },411    set: function set(show) {412      this._showDotCursor = show;413      this._refreshCursor();414    }415  }, {416    key: "background",417    get: function get() {418      return this._screen.style.background;419    },420    set: function set(cssValue) {421      this._screen.style.background = cssValue;422    }423  }, {424    key: "qualityLevel",425    get: function get() {426      return this._qualityLevel;427    },428    set: function set(qualityLevel) {429      if (!Number.isInteger(qualityLevel) || qualityLevel < 0 || qualityLevel > 9) {430        Log.Error("qualityLevel must be an integer between 0 and 9");431        return;432      }433      if (this._qualityLevel === qualityLevel) {434        return;435      }436      this._qualityLevel = qualityLevel;437      if (this._rfbConnectionState === 'connected') {438        this._sendEncodings();439      }440    }441  }, {442    key: "compressionLevel",443    get: function get() {444      return this._compressionLevel;445    },446    set: function set(compressionLevel) {447      if (!Number.isInteger(compressionLevel) || compressionLevel < 0 || compressionLevel > 9) {448        Log.Error("compressionLevel must be an integer between 0 and 9");449        return;450      }451      if (this._compressionLevel === compressionLevel) {452        return;453      }454      this._compressionLevel = compressionLevel;455      if (this._rfbConnectionState === 'connected') {456        this._sendEncodings();457      }458    }459460    // ===== PUBLIC METHODS =====461  }, {462    key: "disconnect",463    value: function disconnect() {464      this._updateConnectionState('disconnecting');465      this._sock.off('error');466      this._sock.off('message');467      this._sock.off('open');468      if (this._rfbRSAAESAuthenticationState !== null) {469        this._rfbRSAAESAuthenticationState.disconnect();470      }471    }472  }, {473    key: "approveServer",474    value: function approveServer() {475      if (this._rfbRSAAESAuthenticationState !== null) {476        this._rfbRSAAESAuthenticationState.approveServer();477      }478    }479  }, {480    key: "sendCredentials",481    value: function sendCredentials(creds) {482      this._rfbCredentials = creds;483      this._resumeAuthentication();484    }485  }, {486    key: "sendCtrlAltDel",487    value: function sendCtrlAltDel() {488      if (this._rfbConnectionState !== 'connected' || this._viewOnly) {489        return;490      }491      Log.Info("Sending Ctrl-Alt-Del");492      this.sendKey(_keysym["default"].XK_Control_L, "ControlLeft", true);493      this.sendKey(_keysym["default"].XK_Alt_L, "AltLeft", true);494      this.sendKey(_keysym["default"].XK_Delete, "Delete", true);495      this.sendKey(_keysym["default"].XK_Delete, "Delete", false);496      this.sendKey(_keysym["default"].XK_Alt_L, "AltLeft", false);497      this.sendKey(_keysym["default"].XK_Control_L, "ControlLeft", false);498    }499  }, {500    key: "machineShutdown",501    value: function machineShutdown() {502      this._xvpOp(1, 2);503    }504  }, {505    key: "machineReboot",506    value: function machineReboot() {507      this._xvpOp(1, 3);508    }509  }, {510    key: "machineReset",511    value: function machineReset() {512      this._xvpOp(1, 4);513    }514515    // Send a key press. If 'down' is not specified then send a down key516    // followed by an up key.517  }, {518    key: "sendKey",519    value: function sendKey(keysym, code, down) {520      if (this._rfbConnectionState !== 'connected' || this._viewOnly) {521        return;522      }523      if (down === undefined) {524        this.sendKey(keysym, code, true);525        this.sendKey(keysym, code, false);526        return;527      }528      var scancode = _xtscancodes["default"][code];529      if (this._qemuExtKeyEventSupported && scancode) {530        // 0 is NoSymbol531        keysym = keysym || 0;532        Log.Info("Sending key (" + (down ? "down" : "up") + "): keysym " + keysym + ", scancode " + scancode);533        RFB.messages.QEMUExtendedKeyEvent(this._sock, keysym, down, scancode);534      } else {535        if (!keysym) {536          return;537        }538        Log.Info("Sending keysym (" + (down ? "down" : "up") + "): " + keysym);539        RFB.messages.keyEvent(this._sock, keysym, down ? 1 : 0);540      }541    }542  }, {543    key: "focus",544    value: function focus(options) {545      this._canvas.focus(options);546    }547  }, {548    key: "blur",549    value: function blur() {550      this._canvas.blur();551    }552  }, {553    key: "clipboardPasteFrom",554    value: function clipboardPasteFrom(text) {555      if (this._rfbConnectionState !== 'connected' || this._viewOnly) {556        return;557      }558      if (this._clipboardServerCapabilitiesFormats[extendedClipboardFormatText] && this._clipboardServerCapabilitiesActions[extendedClipboardActionNotify]) {559        this._clipboardText = text;560        RFB.messages.extendedClipboardNotify(this._sock, [extendedClipboardFormatText]);561      } else {562        var length, i;563        var data;564        length = 0;565        // eslint-disable-next-line no-unused-vars566        var _iterator = _createForOfIteratorHelper(text),567          _step;568        try {569          for (_iterator.s(); !(_step = _iterator.n()).done;) {570            var codePoint = _step.value;571            length++;572          }573        } catch (err) {574          _iterator.e(err);575        } finally {576          _iterator.f();577        }578        data = new Uint8Array(length);579        i = 0;580        var _iterator2 = _createForOfIteratorHelper(text),581          _step2;582        try {583          for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {584            var _codePoint = _step2.value;585            var code = _codePoint.codePointAt(0);586587            /* Only ISO 8859-1 is supported */588            if (code > 0xff) {589              code = 0x3f; // '?'590            }591            data[i++] = code;592          }593        } catch (err) {594          _iterator2.e(err);595        } finally {596          _iterator2.f();597        }598        RFB.messages.clientCutText(this._sock, data);599      }600    }601  }, {602    key: "getImageData",603    value: function getImageData() {604      return this._display.getImageData();605    }606  }, {607    key: "toDataURL",608    value: function toDataURL(type, encoderOptions) {609      return this._display.toDataURL(type, encoderOptions);610    }611  }, {612    key: "toBlob",613    value: function toBlob(callback, type, quality) {614      return this._display.toBlob(callback, type, quality);615    }616617    // ===== PRIVATE METHODS =====618  }, {619    key: "_connect",620    value: function _connect() {621      Log.Debug(">> RFB.connect");622      if (this._url) {623        Log.Info("connecting to ".concat(this._url));624        this._sock.open(this._url, this._wsProtocols);625      } else {626        Log.Info("attaching ".concat(this._rawChannel, " to Websock"));627        this._sock.attach(this._rawChannel);628        if (this._sock.readyState === 'closed') {629          throw Error("Cannot use already closed WebSocket/RTCDataChannel");630        }631        if (this._sock.readyState === 'open') {632          // FIXME: _socketOpen() can in theory call _fail(), which633          //        isn't allowed this early, but I'm not sure that can634          //        happen without a bug messing up our state variables635          this._socketOpen();636        }637      }638639      // Make our elements part of the page640      this._target.appendChild(this._screen);641      this._gestures.attach(this._canvas);642      this._cursor.attach(this._canvas);643      this._refreshCursor();644645      // Monitor size changes of the screen element646      this._resizeObserver.observe(this._screen);647648      // Always grab focus on some kind of click event649      this._canvas.addEventListener("mousedown", this._eventHandlers.focusCanvas);650      this._canvas.addEventListener("touchstart", this._eventHandlers.focusCanvas);651652      // Mouse events653      this._canvas.addEventListener('mousedown', this._eventHandlers.handleMouse);654      this._canvas.addEventListener('mouseup', this._eventHandlers.handleMouse);655      this._canvas.addEventListener('mousemove', this._eventHandlers.handleMouse);656      // Prevent middle-click pasting (see handler for why we bind to document)657      this._canvas.addEventListener('click', this._eventHandlers.handleMouse);658      // preventDefault() on mousedown doesn't stop this event for some659      // reason so we have to explicitly block it660      this._canvas.addEventListener('contextmenu', this._eventHandlers.handleMouse);661662      // Wheel events663      this._canvas.addEventListener("wheel", this._eventHandlers.handleWheel);664665      // Gesture events666      this._canvas.addEventListener("gesturestart", this._eventHandlers.handleGesture);667      this._canvas.addEventListener("gesturemove", this._eventHandlers.handleGesture);668      this._canvas.addEventListener("gestureend", this._eventHandlers.handleGesture);669      Log.Debug("<< RFB.connect");670    }671  }, {672    key: "_disconnect",673    value: function _disconnect() {674      Log.Debug(">> RFB.disconnect");675      this._cursor.detach();676      this._canvas.removeEventListener("gesturestart", this._eventHandlers.handleGesture);677      this._canvas.removeEventListener("gesturemove", this._eventHandlers.handleGesture);678      this._canvas.removeEventListener("gestureend", this._eventHandlers.handleGesture);679      this._canvas.removeEventListener("wheel", this._eventHandlers.handleWheel);680      this._canvas.removeEventListener('mousedown', this._eventHandlers.handleMouse);681      this._canvas.removeEventListener('mouseup', this._eventHandlers.handleMouse);682      this._canvas.removeEventListener('mousemove', this._eventHandlers.handleMouse);683      this._canvas.removeEventListener('click', this._eventHandlers.handleMouse);684      this._canvas.removeEventListener('contextmenu', this._eventHandlers.handleMouse);685      this._canvas.removeEventListener("mousedown", this._eventHandlers.focusCanvas);686      this._canvas.removeEventListener("touchstart", this._eventHandlers.focusCanvas);687      this._resizeObserver.disconnect();688      this._keyboard.ungrab();689      this._gestures.detach();690      this._sock.close();691      try {692        this._target.removeChild(this._screen);693      } catch (e) {694        if (e.name === 'NotFoundError') {695          // Some cases where the initial connection fails696          // can disconnect before the _screen is created697        } else {698          throw e;699        }700      }701      clearTimeout(this._resizeTimeout);702      clearTimeout(this._mouseMoveTimer);703      Log.Debug("<< RFB.disconnect");704    }705  }, {706    key: "_socketOpen",707    value: function _socketOpen() {708      if (this._rfbConnectionState === 'connecting' && this._rfbInitState === '') {709        this._rfbInitState = 'ProtocolVersion';710        Log.Debug("Starting VNC handshake");711      } else {712        this._fail("Unexpected server connection while " + this._rfbConnectionState);713      }714    }715  }, {716    key: "_socketClose",717    value: function _socketClose(e) {718      Log.Debug("WebSocket on-close event");719      var msg = "";720      if (e.code) {721        msg = "(code: " + e.code;722        if (e.reason) {723          msg += ", reason: " + e.reason;724        }725        msg += ")";726      }727      switch (this._rfbConnectionState) {728        case 'connecting':729          this._fail("Connection closed " + msg);730          break;731        case 'connected':732          // Handle disconnects that were initiated server-side733          this._updateConnectionState('disconnecting');734          this._updateConnectionState('disconnected');735          break;736        case 'disconnecting':737          // Normal disconnection path738          this._updateConnectionState('disconnected');739          break;740        case 'disconnected':741          this._fail("Unexpected server disconnect " + "when already disconnected " + msg);742          break;743        default:744          this._fail("Unexpected server disconnect before connecting " + msg);745          break;746      }747      this._sock.off('close');748      // Delete reference to raw channel to allow cleanup.749      this._rawChannel = null;750    }751  }, {752    key: "_socketError",753    value: function _socketError(e) {754      Log.Warn("WebSocket on-error event");755    }756  }, {757    key: "_focusCanvas",758    value: function _focusCanvas(event) {759      if (!this.focusOnClick) {760        return;761      }762      this.focus({763        preventScroll: true764      });765    }766  }, {767    key: "_setDesktopName",768    value: function _setDesktopName(name) {769      this._fbName = name;770      this.dispatchEvent(new CustomEvent("desktopname", {771        detail: {772          name: this._fbName773        }774      }));775    }776  }, {777    key: "_saveExpectedClientSize",778    value: function _saveExpectedClientSize() {779      this._expectedClientWidth = this._screen.clientWidth;780      this._expectedClientHeight = this._screen.clientHeight;781    }782  }, {783    key: "_currentClientSize",784    value: function _currentClientSize() {785      return [this._screen.clientWidth, this._screen.clientHeight];786    }787  }, {788    key: "_clientHasExpectedSize",789    value: function _clientHasExpectedSize() {790      var _this$_currentClientS = this._currentClientSize(),791        _this$_currentClientS2 = _slicedToArray(_this$_currentClientS, 2),792        currentWidth = _this$_currentClientS2[0],793        currentHeight = _this$_currentClientS2[1];794      return currentWidth == this._expectedClientWidth && currentHeight == this._expectedClientHeight;795    }796797    // Handle browser window resizes798  }, {799    key: "_handleResize",800    value: function _handleResize() {801      var _this2 = this;802      // Don't change anything if the client size is already as expected803      if (this._clientHasExpectedSize()) {804        return;805      }806      // If the window resized then our screen element might have807      // as well. Update the viewport dimensions.808      window.requestAnimationFrame(function () {809        _this2._updateClip();810        _this2._updateScale();811        _this2._saveExpectedClientSize();812      });813814      // Request changing the resolution of the remote display to815      // the size of the local browser viewport.816      this._requestRemoteResize();817    }818819    // Update state of clipping in Display object, and make sure the820    // configured viewport matches the current screen size821  }, {822    key: "_updateClip",823    value: function _updateClip() {824      var curClip = this._display.clipViewport;825      var newClip = this._clipViewport;826      if (this._scaleViewport) {827        // Disable viewport clipping if we are scaling828        newClip = false;829      }830      if (curClip !== newClip) {831        this._display.clipViewport = newClip;832      }833      if (newClip) {834        // When clipping is enabled, the screen is limited to835        // the size of the container.836        var size = this._screenSize();837        this._display.viewportChangeSize(size.w, size.h);838        this._fixScrollbars();839        this._setClippingViewport(size.w < this._display.width || size.h < this._display.height);840      } else {841        this._setClippingViewport(false);842      }843844      // When changing clipping we might show or hide scrollbars.845      // This causes the expected client dimensions to change.846      if (curClip !== newClip) {847        this._saveExpectedClientSize();848      }849    }850  }, {851    key: "_updateScale",852    value: function _updateScale() {853      if (!this._scaleViewport) {854        this._display.scale = 1.0;855      } else {856        var size = this._screenSize();857        this._display.autoscale(size.w, size.h);858      }859      this._fixScrollbars();860    }861862    // Requests a change of remote desktop size. This message is an extension863    // and may only be sent if we have received an ExtendedDesktopSize message864  }, {865    key: "_requestRemoteResize",866    value: function _requestRemoteResize() {867      if (!this._resizeSession) {868        return;869      }870      if (this._viewOnly) {871        return;872      }873      if (!this._supportsSetDesktopSize) {874        return;875      }876877      // Rate limit to one pending resize at a time878      if (this._pendingRemoteResize) {879        return;880      }881882      // And no more than once every 100ms883      if (Date.now() - this._lastResize < 100) {884        clearTimeout(this._resizeTimeout);885        this._resizeTimeout = setTimeout(this._requestRemoteResize.bind(this), 100 - (Date.now() - this._lastResize));886        return;887      }888      this._resizeTimeout = null;889      var size = this._screenSize();890891      // Do we actually change anything?892      if (size.w === this._fbWidth && size.h === this._fbHeight) {893        return;894      }895      this._pendingRemoteResize = true;896      this._lastResize = Date.now();897      RFB.messages.setDesktopSize(this._sock, Math.floor(size.w), Math.floor(size.h), this._screenID, this._screenFlags);898      Log.Debug('Requested new desktop size: ' + size.w + 'x' + size.h);899    }900901    // Gets the the size of the available screen902  }, {903    key: "_screenSize",904    value: function _screenSize() {905      var r = this._screen.getBoundingClientRect();906      return {907        w: r.width,908        h: r.height909      };910    }911  }, {912    key: "_fixScrollbars",913    value: function _fixScrollbars() {914      // This is a hack because Safari on macOS screws up the calculation915      // for when scrollbars are needed. We get scrollbars when making the916      // browser smaller, despite remote resize being enabled. So to fix it917      // we temporarily toggle them off and on.918      var orig = this._screen.style.overflow;919      this._screen.style.overflow = 'hidden';920      // Force Safari to recalculate the layout by asking for921      // an element's dimensions922      this._screen.getBoundingClientRect();923      this._screen.style.overflow = orig;924    }925926    /*927     * Connection states:928     *   connecting929     *   connected930     *   disconnecting931     *   disconnected - permanent state932     */933  }, {934    key: "_updateConnectionState",935    value: function _updateConnectionState(state) {936      var _this3 = this;937      var oldstate = this._rfbConnectionState;938      if (state === oldstate) {939        Log.Debug("Already in state '" + state + "', ignoring");940        return;941      }942943      // The 'disconnected' state is permanent for each RFB object944      if (oldstate === 'disconnected') {945        Log.Error("Tried changing state of a disconnected RFB object");946        return;947      }948949      // Ensure proper transitions before doing anything950      switch (state) {951        case 'connected':952          if (oldstate !== 'connecting') {953            Log.Error("Bad transition to connected state, " + "previous connection state: " + oldstate);954            return;955          }956          break;957        case 'disconnected':958          if (oldstate !== 'disconnecting') {959            Log.Error("Bad transition to disconnected state, " + "previous connection state: " + oldstate);960            return;961          }962          break;963        case 'connecting':964          if (oldstate !== '') {965            Log.Error("Bad transition to connecting state, " + "previous connection state: " + oldstate);966            return;967          }968          break;969        case 'disconnecting':970          if (oldstate !== 'connected' && oldstate !== 'connecting') {971            Log.Error("Bad transition to disconnecting state, " + "previous connection state: " + oldstate);972            return;973          }974          break;975        default:976          Log.Error("Unknown connection state: " + state);977          return;978      }979980      // State change actions981982      this._rfbConnectionState = state;983      Log.Debug("New state '" + state + "', was '" + oldstate + "'.");984      if (this._disconnTimer && state !== 'disconnecting') {985        Log.Debug("Clearing disconnect timer");986        clearTimeout(this._disconnTimer);987        this._disconnTimer = null;988989        // make sure we don't get a double event990        this._sock.off('close');991      }992      switch (state) {993        case 'connecting':994          this._connect();995          break;996        case 'connected':997          this.dispatchEvent(new CustomEvent("connect", {998            detail: {}999          }));1000          break;1001        case 'disconnecting':1002          this._disconnect();1003          this._disconnTimer = setTimeout(function () {1004            Log.Error("Disconnection timed out.");1005            _this3._updateConnectionState('disconnected');1006          }, DISCONNECT_TIMEOUT * 1000);1007          break;1008        case 'disconnected':1009          this.dispatchEvent(new CustomEvent("disconnect", {1010            detail: {1011              clean: this._rfbCleanDisconnect1012            }1013          }));1014          break;1015      }1016    }10171018    /* Print errors and disconnect1019     *1020     * The parameter 'details' is used for information that1021     * should be logged but not sent to the user interface.1022     */1023  }, {1024    key: "_fail",1025    value: function _fail(details) {1026      switch (this._rfbConnectionState) {1027        case 'disconnecting':1028          Log.Error("Failed when disconnecting: " + details);1029          break;1030        case 'connected':1031          Log.Error("Failed while connected: " + details);1032          break;1033        case 'connecting':1034          Log.Error("Failed when connecting: " + details);1035          break;1036        default:1037          Log.Error("RFB failure: " + details);1038          break;1039      }1040      this._rfbCleanDisconnect = false; //This is sent to the UI10411042      // Transition to disconnected without waiting for socket to close1043      this._updateConnectionState('disconnecting');1044      this._updateConnectionState('disconnected');1045      return false;1046    }1047  }, {1048    key: "_setCapability",1049    value: function _setCapability(cap, val) {1050      this._capabilities[cap] = val;1051      this.dispatchEvent(new CustomEvent("capabilities", {1052        detail: {1053          capabilities: this._capabilities1054        }1055      }));1056    }1057  }, {1058    key: "_handleMessage",1059    value: function _handleMessage() {1060      if (this._sock.rQwait("message", 1)) {1061        Log.Warn("handleMessage called on an empty receive queue");1062        return;1063      }1064      switch (this._rfbConnectionState) {1065        case 'disconnected':1066          Log.Error("Got data while disconnected");1067          break;1068        case 'connected':1069          while (true) {1070            if (this._flushing) {1071              break;1072            }1073            if (!this._normalMsg()) {1074              break;1075            }1076            if (this._sock.rQwait("message", 1)) {1077              break;1078            }1079          }1080          break;1081        case 'connecting':1082          while (this._rfbConnectionState === 'connecting') {1083            if (!this._initMsg()) {1084              break;1085            }1086          }1087          break;1088        default:1089          Log.Error("Got data while in an invalid state");1090          break;1091      }1092    }1093  }, {1094    key: "_handleKeyEvent",1095    value: function _handleKeyEvent(keysym, code, down, numlock, capslock) {1096      // If remote state of capslock is known, and it doesn't match the local led state of1097      // the keyboard, we send a capslock keypress first to bring it into sync.1098      // If we just pressed CapsLock, or we toggled it remotely due to it being out of sync1099      // we clear the remote state so that we don't send duplicate or spurious fixes,1100      // since it may take some time to receive the new remote CapsLock state.1101      if (code == 'CapsLock' && down) {1102        this._remoteCapsLock = null;1103      }1104      if (this._remoteCapsLock !== null && capslock !== null && this._remoteCapsLock !== capslock && down) {1105        Log.Debug("Fixing remote caps lock");1106        this.sendKey(_keysym["default"].XK_Caps_Lock, 'CapsLock', true);1107        this.sendKey(_keysym["default"].XK_Caps_Lock, 'CapsLock', false);1108        // We clear the remote capsLock state when we do this to prevent issues with doing this twice1109        // before we receive an update of the the remote state.1110        this._remoteCapsLock = null;1111      }11121113      // Logic for numlock is exactly the same.1114      if (code == 'NumLock' && down) {1115        this._remoteNumLock = null;1116      }1117      if (this._remoteNumLock !== null && numlock !== null && this._remoteNumLock !== numlock && down) {1118        Log.Debug("Fixing remote num lock");1119        this.sendKey(_keysym["default"].XK_Num_Lock, 'NumLock', true);1120        this.sendKey(_keysym["default"].XK_Num_Lock, 'NumLock', false);1121        this._remoteNumLock = null;1122      }1123      this.sendKey(keysym, code, down);1124    }1125  }, {1126    key: "_handleMouse",1127    value: function _handleMouse(ev) {1128      /*1129       * We don't check connection status or viewOnly here as the1130       * mouse events might be used to control the viewport1131       */11321133      if (ev.type === 'click') {1134        /*1135         * Note: This is only needed for the 'click' event as it fails1136         *       to fire properly for the target element so we have1137         *       to listen on the document element instead.1138         */1139        if (ev.target !== this._canvas) {1140          return;1141        }1142      }11431144      // FIXME: if we're in view-only and not dragging,1145      //        should we stop events?1146      ev.stopPropagation();1147      ev.preventDefault();1148      if (ev.type === 'click' || ev.type === 'contextmenu') {1149        return;1150      }1151      var pos = (0, _element.clientToElement)(ev.clientX, ev.clientY, this._canvas);1152      var bmask = RFB._convertButtonMask(ev.buttons);1153      var down = ev.type == 'mousedown';1154      switch (ev.type) {1155        case 'mousedown':1156        case 'mouseup':1157          if (this.dragViewport) {1158            if (down && !this._viewportDragging) {1159              this._viewportDragging = true;1160              this._viewportDragPos = {1161                'x': pos.x,1162                'y': pos.y1163              };1164              this._viewportHasMoved = false;1165              this._flushMouseMoveTimer(pos.x, pos.y);11661167              // Skip sending mouse events, instead save the current1168              // mouse mask so we can send it later.1169              this._mouseButtonMask = bmask;1170              break;1171            } else {1172              this._viewportDragging = false;11731174              // If we actually performed a drag then we are done1175              // here and should not send any mouse events1176              if (this._viewportHasMoved) {1177                this._mouseButtonMask = bmask;1178                break;1179              }1180              // Otherwise we treat this as a mouse click event.1181              // Send the previously saved button mask, followed1182              // by the current button mask at the end of this1183              // function.1184              this._sendMouse(pos.x, pos.y, this._mouseButtonMask);1185            }1186          }1187          if (down) {1188            (0, _events.setCapture)(this._canvas);1189          }1190          this._handleMouseButton(pos.x, pos.y, bmask);1191          break;1192        case 'mousemove':1193          if (this._viewportDragging) {1194            var deltaX = this._viewportDragPos.x - pos.x;1195            var deltaY = this._viewportDragPos.y - pos.y;1196            if (this._viewportHasMoved || Math.abs(deltaX) > _browser.dragThreshold || Math.abs(deltaY) > _browser.dragThreshold) {1197              this._viewportHasMoved = true;1198              this._viewportDragPos = {1199                'x': pos.x,1200                'y': pos.y1201              };1202              this._display.viewportChangePos(deltaX, deltaY);1203            }12041205            // Skip sending mouse events1206            break;1207          }1208          this._handleMouseMove(pos.x, pos.y);1209          break;1210      }1211    }1212  }, {1213    key: "_handleMouseButton",1214    value: function _handleMouseButton(x, y, bmask) {1215      // Flush waiting move event first1216      this._flushMouseMoveTimer(x, y);1217      this._mouseButtonMask = bmask;1218      this._sendMouse(x, y, this._mouseButtonMask);1219    }1220  }, {1221    key: "_handleMouseMove",1222    value: function _handleMouseMove(x, y) {1223      var _this4 = this;1224      this._mousePos = {1225        'x': x,1226        'y': y1227      };12281229      // Limit many mouse move events to one every MOUSE_MOVE_DELAY ms1230      if (this._mouseMoveTimer == null) {1231        var timeSinceLastMove = Date.now() - this._mouseLastMoveTime;1232        if (timeSinceLastMove > MOUSE_MOVE_DELAY) {1233          this._sendMouse(x, y, this._mouseButtonMask);1234          this._mouseLastMoveTime = Date.now();1235        } else {1236          // Too soon since the latest move, wait the remaining time1237          this._mouseMoveTimer = setTimeout(function () {1238            _this4._handleDelayedMouseMove();1239          }, MOUSE_MOVE_DELAY - timeSinceLastMove);1240        }1241      }1242    }1243  }, {1244    key: "_handleDelayedMouseMove",1245    value: function _handleDelayedMouseMove() {1246      this._mouseMoveTimer = null;1247      this._sendMouse(this._mousePos.x, this._mousePos.y, this._mouseButtonMask);1248      this._mouseLastMoveTime = Date.now();1249    }1250  }, {1251    key: "_sendMouse",1252    value: function _sendMouse(x, y, mask) {1253      if (this._rfbConnectionState !== 'connected') {1254        return;1255      }1256      if (this._viewOnly) {1257        return;1258      } // View only, skip mouse events12591260      // Highest bit in mask is never sent to the server1261      if (mask & 0x8000) {1262        throw new Error("Illegal mouse button mask (mask: " + mask + ")");1263      }1264      var extendedMouseButtons = mask & 0x7f80;1265      if (this._extendedPointerEventSupported && extendedMouseButtons) {1266        RFB.messages.extendedPointerEvent(this._sock, this._display.absX(x), this._display.absY(y), mask);1267      } else {1268        RFB.messages.pointerEvent(this._sock, this._display.absX(x), this._display.absY(y), mask);1269      }1270    }1271  }, {1272    key: "_handleWheel",1273    value: function _handleWheel(ev) {1274      if (this._rfbConnectionState !== 'connected') {1275        return;1276      }1277      if (this._viewOnly) {1278        return;1279      } // View only, skip mouse events12801281      ev.stopPropagation();1282      ev.preventDefault();1283      var pos = (0, _element.clientToElement)(ev.clientX, ev.clientY, this._canvas);1284      var bmask = RFB._convertButtonMask(ev.buttons);1285      var dX = ev.deltaX;1286      var dY = ev.deltaY;12871288      // Pixel units unless it's non-zero.1289      // Note that if deltamode is line or page won't matter since we aren't1290      // sending the mouse wheel delta to the server anyway.1291      // The difference between pixel and line can be important however since1292      // we have a threshold that can be smaller than the line height.1293      if (ev.deltaMode !== 0) {1294        dX *= WHEEL_LINE_HEIGHT;1295        dY *= WHEEL_LINE_HEIGHT;1296      }12971298      // Mouse wheel events are sent in steps over VNC. This means that the VNC1299      // protocol can't handle a wheel event with specific distance or speed.1300      // Therefor, if we get a lot of small mouse wheel events we combine them.1301      this._accumulatedWheelDeltaX += dX;1302      this._accumulatedWheelDeltaY += dY;13031304      // Generate a mouse wheel step event when the accumulated delta1305      // for one of the axes is large enough.1306      if (Math.abs(this._accumulatedWheelDeltaX) >= WHEEL_STEP) {1307        if (this._accumulatedWheelDeltaX < 0) {1308          this._handleMouseButton(pos.x, pos.y, bmask | 1 << 5);1309          this._handleMouseButton(pos.x, pos.y, bmask);1310        } else if (this._accumulatedWheelDeltaX > 0) {1311          this._handleMouseButton(pos.x, pos.y, bmask | 1 << 6);1312          this._handleMouseButton(pos.x, pos.y, bmask);1313        }1314        this._accumulatedWheelDeltaX = 0;1315      }1316      if (Math.abs(this._accumulatedWheelDeltaY) >= WHEEL_STEP) {1317        if (this._accumulatedWheelDeltaY < 0) {1318          this._handleMouseButton(pos.x, pos.y, bmask | 1 << 3);1319          this._handleMouseButton(pos.x, pos.y, bmask);1320        } else if (this._accumulatedWheelDeltaY > 0) {1321          this._handleMouseButton(pos.x, pos.y, bmask | 1 << 4);1322          this._handleMouseButton(pos.x, pos.y, bmask);1323        }1324        this._accumulatedWheelDeltaY = 0;1325      }1326    }1327  }, {1328    key: "_fakeMouseMove",1329    value: function _fakeMouseMove(ev, elementX, elementY) {1330      this._handleMouseMove(elementX, elementY);1331      this._cursor.move(ev.detail.clientX, ev.detail.clientY);1332    }1333  }, {1334    key: "_handleTapEvent",1335    value: function _handleTapEvent(ev, bmask) {1336      var pos = (0, _element.clientToElement)(ev.detail.clientX, ev.detail.clientY, this._canvas);13371338      // If the user quickly taps multiple times we assume they meant to1339      // hit the same spot, so slightly adjust coordinates13401341      if (this._gestureLastTapTime !== null && Date.now() - this._gestureLastTapTime < DOUBLE_TAP_TIMEOUT && this._gestureFirstDoubleTapEv.detail.type === ev.detail.type) {1342        var dx = this._gestureFirstDoubleTapEv.detail.clientX - ev.detail.clientX;1343        var dy = this._gestureFirstDoubleTapEv.detail.clientY - ev.detail.clientY;1344        var distance = Math.hypot(dx, dy);1345        if (distance < DOUBLE_TAP_THRESHOLD) {1346          pos = (0, _element.clientToElement)(this._gestureFirstDoubleTapEv.detail.clientX, this._gestureFirstDoubleTapEv.detail.clientY, this._canvas);1347        } else {1348          this._gestureFirstDoubleTapEv = ev;1349        }1350      } else {1351        this._gestureFirstDoubleTapEv = ev;1352      }1353      this._gestureLastTapTime = Date.now();1354      this._fakeMouseMove(this._gestureFirstDoubleTapEv, pos.x, pos.y);1355      this._handleMouseButton(pos.x, pos.y, bmask);1356      this._handleMouseButton(pos.x, pos.y, 0x0);1357    }1358  }, {1359    key: "_handleGesture",1360    value: function _handleGesture(ev) {1361      var magnitude;1362      var pos = (0, _element.clientToElement)(ev.detail.clientX, ev.detail.clientY, this._canvas);1363      switch (ev.type) {1364        case 'gesturestart':1365          switch (ev.detail.type) {1366            case 'onetap':1367              this._handleTapEvent(ev, 0x1);1368              break;1369            case 'twotap':1370              this._handleTapEvent(ev, 0x4);1371              break;1372            case 'threetap':1373              this._handleTapEvent(ev, 0x2);1374              break;1375            case 'drag':1376              if (this.dragViewport) {1377                this._viewportHasMoved = false;1378                this._viewportDragging = true;1379                this._viewportDragPos = {1380                  'x': pos.x,1381                  'y': pos.y1382                };1383              } else {1384                this._fakeMouseMove(ev, pos.x, pos.y);1385                this._handleMouseButton(pos.x, pos.y, 0x1);1386              }1387              break;1388            case 'longpress':1389              if (this.dragViewport) {1390                // If dragViewport is true, we need to wait to see1391                // if we have dragged outside the threshold before1392                // sending any events to the server.1393                this._viewportHasMoved = false;1394                this._viewportDragPos = {1395                  'x': pos.x,1396                  'y': pos.y1397                };1398              } else {1399                this._fakeMouseMove(ev, pos.x, pos.y);1400                this._handleMouseButton(pos.x, pos.y, 0x4);1401              }1402              break;1403            case 'twodrag':1404              this._gestureLastMagnitudeX = ev.detail.magnitudeX;1405              this._gestureLastMagnitudeY = ev.detail.magnitudeY;1406              this._fakeMouseMove(ev, pos.x, pos.y);1407              break;1408            case 'pinch':1409              this._gestureLastMagnitudeX = Math.hypot(ev.detail.magnitudeX, ev.detail.magnitudeY);1410              this._fakeMouseMove(ev, pos.x, pos.y);1411              break;1412          }1413          break;1414        case 'gesturemove':1415          switch (ev.detail.type) {1416            case 'onetap':1417            case 'twotap':1418            case 'threetap':1419              break;1420            case 'drag':1421            case 'longpress':1422              if (this.dragViewport) {1423                this._viewportDragging = true;1424                var deltaX = this._viewportDragPos.x - pos.x;1425                var deltaY = this._viewportDragPos.y - pos.y;1426                if (this._viewportHasMoved || Math.abs(deltaX) > _browser.dragThreshold || Math.abs(deltaY) > _browser.dragThreshold) {1427                  this._viewportHasMoved = true;1428                  this._viewportDragPos = {1429                    'x': pos.x,1430                    'y': pos.y1431                  };1432                  this._display.viewportChangePos(deltaX, deltaY);1433                }1434              } else {1435                this._fakeMouseMove(ev, pos.x, pos.y);1436              }1437              break;1438            case 'twodrag':1439              // Always scroll in the same position.1440              // We don't know if the mouse was moved so we need to move it1441              // every update.1442              this._fakeMouseMove(ev, pos.x, pos.y);1443              while (ev.detail.magnitudeY - this._gestureLastMagnitudeY > GESTURE_SCRLSENS) {1444                this._handleMouseButton(pos.x, pos.y, 0x8);1445                this._handleMouseButton(pos.x, pos.y, 0x0);1446                this._gestureLastMagnitudeY += GESTURE_SCRLSENS;1447              }1448              while (ev.detail.magnitudeY - this._gestureLastMagnitudeY < -GESTURE_SCRLSENS) {1449                this._handleMouseButton(pos.x, pos.y, 0x10);1450                this._handleMouseButton(pos.x, pos.y, 0x0);1451                this._gestureLastMagnitudeY -= GESTURE_SCRLSENS;1452              }1453              while (ev.detail.magnitudeX - this._gestureLastMagnitudeX > GESTURE_SCRLSENS) {1454                this._handleMouseButton(pos.x, pos.y, 0x20);1455                this._handleMouseButton(pos.x, pos.y, 0x0);1456                this._gestureLastMagnitudeX += GESTURE_SCRLSENS;1457              }1458              while (ev.detail.magnitudeX - this._gestureLastMagnitudeX < -GESTURE_SCRLSENS) {1459                this._handleMouseButton(pos.x, pos.y, 0x40);1460                this._handleMouseButton(pos.x, pos.y, 0x0);1461                this._gestureLastMagnitudeX -= GESTURE_SCRLSENS;1462              }1463              break;1464            case 'pinch':1465              // Always scroll in the same position.1466              // We don't know if the mouse was moved so we need to move it1467              // every update.1468              this._fakeMouseMove(ev, pos.x, pos.y);1469              magnitude = Math.hypot(ev.detail.magnitudeX, ev.detail.magnitudeY);1470              if (Math.abs(magnitude - this._gestureLastMagnitudeX) > GESTURE_ZOOMSENS) {1471                this._handleKeyEvent(_keysym["default"].XK_Control_L, "ControlLeft", true);1472                while (magnitude - this._gestureLastMagnitudeX > GESTURE_ZOOMSENS) {1473                  this._handleMouseButton(pos.x, pos.y, 0x8);1474                  this._handleMouseButton(pos.x, pos.y, 0x0);1475                  this._gestureLastMagnitudeX += GESTURE_ZOOMSENS;1476                }1477                while (magnitude - this._gestureLastMagnitudeX < -GESTURE_ZOOMSENS) {1478                  this._handleMouseButton(pos.x, pos.y, 0x10);1479                  this._handleMouseButton(pos.x, pos.y, 0x0);1480                  this._gestureLastMagnitudeX -= GESTURE_ZOOMSENS;1481                }1482              }1483              this._handleKeyEvent(_keysym["default"].XK_Control_L, "ControlLeft", false);1484              break;1485          }1486          break;1487        case 'gestureend':1488          switch (ev.detail.type) {1489            case 'onetap':1490            case 'twotap':1491            case 'threetap':1492            case 'pinch':1493            case 'twodrag':1494              break;1495            case 'drag':1496              if (this.dragViewport) {1497                this._viewportDragging = false;1498              } else {1499                this._fakeMouseMove(ev, pos.x, pos.y);1500                this._handleMouseButton(pos.x, pos.y, 0x0);1501              }1502              break;1503            case 'longpress':1504              if (this._viewportHasMoved) {1505                // We don't want to send any events if we have moved1506                // our viewport1507                break;1508              }1509              if (this.dragViewport && !this._viewportHasMoved) {1510                this._fakeMouseMove(ev, pos.x, pos.y);1511                // If dragViewport is true, we need to wait to see1512                // if we have dragged outside the threshold before1513                // sending any events to the server.1514                this._handleMouseButton(pos.x, pos.y, 0x4);1515                this._handleMouseButton(pos.x, pos.y, 0x0);1516                this._viewportDragging = false;1517              } else {1518                this._fakeMouseMove(ev, pos.x, pos.y);1519                this._handleMouseButton(pos.x, pos.y, 0x0);1520              }1521              break;1522          }1523          break;1524      }1525    }1526  }, {1527    key: "_flushMouseMoveTimer",1528    value: function _flushMouseMoveTimer(x, y) {1529      if (this._mouseMoveTimer !== null) {1530        clearTimeout(this._mouseMoveTimer);1531        this._mouseMoveTimer = null;1532        this._sendMouse(x, y, this._mouseButtonMask);1533      }1534    }15351536    // Message handlers1537  }, {1538    key: "_negotiateProtocolVersion",1539    value: function _negotiateProtocolVersion() {1540      if (this._sock.rQwait("version", 12)) {1541        return false;1542      }1543      var sversion = this._sock.rQshiftStr(12).substr(4, 7);1544      Log.Info("Server ProtocolVersion: " + sversion);1545      var isRepeater = 0;1546      switch (sversion) {1547        case "000.000":1548          // UltraVNC repeater1549          isRepeater = 1;1550          break;1551        case "003.003":1552        case "003.006":1553          // UltraVNC1554          this._rfbVersion = 3.3;1555          break;1556        case "003.007":1557          this._rfbVersion = 3.7;1558          break;1559        case "003.008":1560        case "003.889": // Apple Remote Desktop1561        case "004.000": // Intel AMT KVM1562        case "004.001": // RealVNC 4.61563        case "005.000":1564          // RealVNC 5.31565          this._rfbVersion = 3.8;1566          break;1567        default:1568          return this._fail("Invalid server version " + sversion);1569      }1570      if (isRepeater) {1571        var repeaterID = "ID:" + this._repeaterID;1572        while (repeaterID.length < 250) {1573          repeaterID += "\0";1574        }1575        this._sock.sQpushString(repeaterID);1576        this._sock.flush();1577        return true;1578      }1579      if (this._rfbVersion > this._rfbMaxVersion) {1580        this._rfbVersion = this._rfbMaxVersion;1581      }1582      var cversion = "00" + parseInt(this._rfbVersion, 10) + ".00" + this._rfbVersion * 10 % 10;1583      this._sock.sQpushString("RFB " + cversion + "\n");1584      this._sock.flush();1585      Log.Debug('Sent ProtocolVersion: ' + cversion);1586      this._rfbInitState = 'Security';1587    }1588  }, {1589    key: "_isSupportedSecurityType",1590    value: function _isSupportedSecurityType(type) {1591      var clientTypes = [securityTypeNone, securityTypeVNCAuth, securityTypeRA2ne, securityTypeTight, securityTypeVeNCrypt, securityTypeXVP, securityTypeARD, securityTypeMSLogonII, securityTypePlain];1592      return clientTypes.includes(type);1593    }1594  }, {1595    key: "_negotiateSecurity",1596    value: function _negotiateSecurity() {1597      if (this._rfbVersion >= 3.7) {1598        // Server sends supported list, client decides1599        var numTypes = this._sock.rQshift8();1600        if (this._sock.rQwait("security type", numTypes, 1)) {1601          return false;1602        }1603        if (numTypes === 0) {1604          this._rfbInitState = "SecurityReason";1605          this._securityContext = "no security types";1606          this._securityStatus = 1;1607          return true;1608        }1609        var types = this._sock.rQshiftBytes(numTypes);1610        Log.Debug("Server security types: " + types);16111612        // Look for a matching security type in the order that the1613        // server prefers1614        this._rfbAuthScheme = -1;1615        var _iterator3 = _createForOfIteratorHelper(types),1616          _step3;1617        try {1618          for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {1619            var type = _step3.value;1620            if (this._isSupportedSecurityType(type)) {1621              this._rfbAuthScheme = type;1622              break;1623            }1624          }1625        } catch (err) {1626          _iterator3.e(err);1627        } finally {1628          _iterator3.f();1629        }1630        if (this._rfbAuthScheme === -1) {1631          return this._fail("Unsupported security types (types: " + types + ")");1632        }1633        this._sock.sQpush8(this._rfbAuthScheme);1634        this._sock.flush();1635      } else {1636        // Server decides1637        if (this._sock.rQwait("security scheme", 4)) {1638          return false;1639        }1640        this._rfbAuthScheme = this._sock.rQshift32();1641        if (this._rfbAuthScheme == 0) {1642          this._rfbInitState = "SecurityReason";1643          this._securityContext = "authentication scheme";1644          this._securityStatus = 1;1645          return true;1646        }1647      }1648      this._rfbInitState = 'Authentication';1649      Log.Debug('Authenticating using scheme: ' + this._rfbAuthScheme);1650      return true;1651    }1652  }, {1653    key: "_handleSecurityReason",1654    value: function _handleSecurityReason() {1655      if (this._sock.rQwait("reason length", 4)) {1656        return false;1657      }1658      var strlen = this._sock.rQshift32();1659      var reason = "";1660      if (strlen > 0) {1661        if (this._sock.rQwait("reason", strlen, 4)) {1662          return false;1663        }1664        reason = this._sock.rQshiftStr(strlen);1665      }1666      if (reason !== "") {1667        this.dispatchEvent(new CustomEvent("securityfailure", {1668          detail: {1669            status: this._securityStatus,1670            reason: reason1671          }1672        }));1673        return this._fail("Security negotiation failed on " + this._securityContext + " (reason: " + reason + ")");1674      } else {1675        this.dispatchEvent(new CustomEvent("securityfailure", {1676          detail: {1677            status: this._securityStatus1678          }1679        }));1680        return this._fail("Security negotiation failed on " + this._securityContext);1681      }1682    }16831684    // authentication1685  }, {1686    key: "_negotiateXvpAuth",1687    value: function _negotiateXvpAuth() {1688      if (this._rfbCredentials.username === undefined || this._rfbCredentials.password === undefined || this._rfbCredentials.target === undefined) {1689        this.dispatchEvent(new CustomEvent("credentialsrequired", {1690          detail: {1691            types: ["username", "password", "target"]1692          }1693        }));1694        return false;1695      }1696      this._sock.sQpush8(this._rfbCredentials.username.length);1697      this._sock.sQpush8(this._rfbCredentials.target.length);1698      this._sock.sQpushString(this._rfbCredentials.username);1699      this._sock.sQpushString(this._rfbCredentials.target);1700      this._sock.flush();1701      this._rfbAuthScheme = securityTypeVNCAuth;1702      return this._negotiateAuthentication();1703    }17041705    // VeNCrypt authentication, currently only supports version 0.2 and only Plain subtype1706  }, {1707    key: "_negotiateVeNCryptAuth",1708    value: function _negotiateVeNCryptAuth() {1709      // waiting for VeNCrypt version1710      if (this._rfbVeNCryptState == 0) {1711        if (this._sock.rQwait("vencrypt version", 2)) {1712          return false;1713        }1714        var major = this._sock.rQshift8();1715        var minor = this._sock.rQshift8();1716        if (!(major == 0 && minor == 2)) {1717          return this._fail("Unsupported VeNCrypt version " + major + "." + minor);1718        }1719        this._sock.sQpush8(0);1720        this._sock.sQpush8(2);1721        this._sock.flush();1722        this._rfbVeNCryptState = 1;1723      }17241725      // waiting for ACK1726      if (this._rfbVeNCryptState == 1) {1727        if (this._sock.rQwait("vencrypt ack", 1)) {1728          return false;1729        }1730        var res = this._sock.rQshift8();1731        if (res != 0) {1732          return this._fail("VeNCrypt failure " + res);1733        }1734        this._rfbVeNCryptState = 2;1735      }1736      // must fall through here (i.e. no "else if"), beacause we may have already received1737      // the subtypes length and won't be called again17381739      if (this._rfbVeNCryptState == 2) {1740        // waiting for subtypes length1741        if (this._sock.rQwait("vencrypt subtypes length", 1)) {1742          return false;1743        }1744        var subtypesLength = this._sock.rQshift8();1745        if (subtypesLength < 1) {1746          return this._fail("VeNCrypt subtypes empty");1747        }1748        this._rfbVeNCryptSubtypesLength = subtypesLength;1749        this._rfbVeNCryptState = 3;1750      }17511752      // waiting for subtypes list1753      if (this._rfbVeNCryptState == 3) {1754        if (this._sock.rQwait("vencrypt subtypes", 4 * this._rfbVeNCryptSubtypesLength)) {1755          return false;1756        }1757        var subtypes = [];1758        for (var i = 0; i < this._rfbVeNCryptSubtypesLength; i++) {1759          subtypes.push(this._sock.rQshift32());1760        }17611762        // Look for a matching security type in the order that the1763        // server prefers1764        this._rfbAuthScheme = -1;1765        for (var _i = 0, _subtypes = subtypes; _i < _subtypes.length; _i++) {1766          var type = _subtypes[_i];1767          // Avoid getting in to a loop1768          if (type === securityTypeVeNCrypt) {1769            continue;1770          }1771          if (this._isSupportedSecurityType(type)) {1772            this._rfbAuthScheme = type;1773            break;1774          }1775        }1776        if (this._rfbAuthScheme === -1) {1777          return this._fail("Unsupported security types (types: " + subtypes + ")");1778        }1779        this._sock.sQpush32(this._rfbAuthScheme);1780        this._sock.flush();1781        this._rfbVeNCryptState = 4;1782        return true;1783      }1784    }1785  }, {1786    key: "_negotiatePlainAuth",1787    value: function _negotiatePlainAuth() {1788      if (this._rfbCredentials.username === undefined || this._rfbCredentials.password === undefined) {1789        this.dispatchEvent(new CustomEvent("credentialsrequired", {1790          detail: {1791            types: ["username", "password"]1792          }1793        }));1794        return false;1795      }1796      var user = (0, _strings.encodeUTF8)(this._rfbCredentials.username);1797      var pass = (0, _strings.encodeUTF8)(this._rfbCredentials.password);1798      this._sock.sQpush32(user.length);1799      this._sock.sQpush32(pass.length);1800      this._sock.sQpushString(user);1801      this._sock.sQpushString(pass);1802      this._sock.flush();1803      this._rfbInitState = "SecurityResult";1804      return true;1805    }1806  }, {1807    key: "_negotiateStdVNCAuth",1808    value: function _negotiateStdVNCAuth() {1809      if (this._sock.rQwait("auth challenge", 16)) {1810        return false;1811      }1812      if (this._rfbCredentials.password === undefined) {1813        this.dispatchEvent(new CustomEvent("credentialsrequired", {1814          detail: {1815            types: ["password"]1816          }1817        }));1818        return false;1819      }18201821      // TODO(directxman12): make genDES not require an Array1822      var challenge = Array.prototype.slice.call(this._sock.rQshiftBytes(16));1823      var response = RFB.genDES(this._rfbCredentials.password, challenge);1824      this._sock.sQpushBytes(response);1825      this._sock.flush();1826      this._rfbInitState = "SecurityResult";1827      return true;1828    }1829  }, {1830    key: "_negotiateARDAuth",1831    value: function _negotiateARDAuth() {1832      if (this._rfbCredentials.username === undefined || this._rfbCredentials.password === undefined) {1833        this.dispatchEvent(new CustomEvent("credentialsrequired", {1834          detail: {1835            types: ["username", "password"]1836          }1837        }));1838        return false;1839      }1840      if (this._rfbCredentials.ardPublicKey != undefined && this._rfbCredentials.ardCredentials != undefined) {1841        // if the async web crypto is done return the results1842        this._sock.sQpushBytes(this._rfbCredentials.ardCredentials);1843        this._sock.sQpushBytes(this._rfbCredentials.ardPublicKey);1844        this._sock.flush();1845        this._rfbCredentials.ardCredentials = null;1846        this._rfbCredentials.ardPublicKey = null;1847        this._rfbInitState = "SecurityResult";1848        return true;1849      }1850      if (this._sock.rQwait("read ard", 4)) {1851        return false;1852      }1853      var generator = this._sock.rQshiftBytes(2); // DH base generator value18541855      var keyLength = this._sock.rQshift16();1856      if (this._sock.rQwait("read ard keylength", keyLength * 2, 4)) {1857        return false;1858      }18591860      // read the server values1861      var prime = this._sock.rQshiftBytes(keyLength); // predetermined prime modulus1862      var serverPublicKey = this._sock.rQshiftBytes(keyLength); // other party's public key18631864      var clientKey = _crypto["default"].generateKey({1865        name: "DH",1866        g: generator,1867        p: prime1868      }, false, ["deriveBits"]);1869      this._negotiateARDAuthAsync(keyLength, serverPublicKey, clientKey);1870      return false;1871    }1872  }, {1873    key: "_negotiateARDAuthAsync",1874    value: function () {1875      var _negotiateARDAuthAsync2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(keyLength, serverPublicKey, clientKey) {1876        var clientPublicKey, sharedKey, username, password, credentials, i, _i2, key, cipher, encrypted;1877        return _regeneratorRuntime().wrap(function _callee$(_context) {1878          while (1) switch (_context.prev = _context.next) {1879            case 0:1880              clientPublicKey = _crypto["default"].exportKey("raw", clientKey.publicKey);1881              sharedKey = _crypto["default"].deriveBits({1882                name: "DH",1883                "public": serverPublicKey1884              }, clientKey.privateKey, keyLength * 8);1885              username = (0, _strings.encodeUTF8)(this._rfbCredentials.username).substring(0, 63);1886              password = (0, _strings.encodeUTF8)(this._rfbCredentials.password).substring(0, 63);1887              credentials = window.crypto.getRandomValues(new Uint8Array(128));1888              for (i = 0; i < username.length; i++) {1889                credentials[i] = username.charCodeAt(i);1890              }1891              credentials[username.length] = 0;1892              for (_i2 = 0; _i2 < password.length; _i2++) {1893                credentials[64 + _i2] = password.charCodeAt(_i2);1894              }1895              credentials[64 + password.length] = 0;1896              _context.next = 11;1897              return _crypto["default"].digest("MD5", sharedKey);1898            case 11:1899              key = _context.sent;1900              _context.next = 14;1901              return _crypto["default"].importKey("raw", key, {1902                name: "AES-ECB"1903              }, false, ["encrypt"]);1904            case 14:1905              cipher = _context.sent;1906              _context.next = 17;1907              return _crypto["default"].encrypt({1908                name: "AES-ECB"1909              }, cipher, credentials);1910            case 17:1911              encrypted = _context.sent;1912              this._rfbCredentials.ardCredentials = encrypted;1913              this._rfbCredentials.ardPublicKey = clientPublicKey;1914              this._resumeAuthentication();1915            case 21:1916            case "end":1917              return _context.stop();1918          }1919        }, _callee, this);1920      }));1921      function _negotiateARDAuthAsync(_x, _x2, _x3) {1922        return _negotiateARDAuthAsync2.apply(this, arguments);1923      }1924      return _negotiateARDAuthAsync;1925    }()1926  }, {1927    key: "_negotiateTightUnixAuth",1928    value: function _negotiateTightUnixAuth() {1929      if (this._rfbCredentials.username === undefined || this._rfbCredentials.password === undefined) {1930        this.dispatchEvent(new CustomEvent("credentialsrequired", {1931          detail: {1932            types: ["username", "password"]1933          }1934        }));1935        return false;1936      }1937      this._sock.sQpush32(this._rfbCredentials.username.length);1938      this._sock.sQpush32(this._rfbCredentials.password.length);1939      this._sock.sQpushString(this._rfbCredentials.username);1940      this._sock.sQpushString(this._rfbCredentials.password);1941      this._sock.flush();1942      this._rfbInitState = "SecurityResult";1943      return true;1944    }1945  }, {1946    key: "_negotiateTightTunnels",1947    value: function _negotiateTightTunnels(numTunnels) {1948      var clientSupportedTunnelTypes = {1949        0: {1950          vendor: 'TGHT',1951          signature: 'NOTUNNEL'1952        }1953      };1954      var serverSupportedTunnelTypes = {};1955      // receive tunnel capabilities1956      for (var i = 0; i < numTunnels; i++) {1957        var capCode = this._sock.rQshift32();1958        var capVendor = this._sock.rQshiftStr(4);1959        var capSignature = this._sock.rQshiftStr(8);1960        serverSupportedTunnelTypes[capCode] = {1961          vendor: capVendor,1962          signature: capSignature1963        };1964      }1965      Log.Debug("Server Tight tunnel types: " + serverSupportedTunnelTypes);19661967      // Siemens touch panels have a VNC server that supports NOTUNNEL,1968      // but forgets to advertise it. Try to detect such servers by1969      // looking for their custom tunnel type.1970      if (serverSupportedTunnelTypes[1] && serverSupportedTunnelTypes[1].vendor === "SICR" && serverSupportedTunnelTypes[1].signature === "SCHANNEL") {1971        Log.Debug("Detected Siemens server. Assuming NOTUNNEL support.");1972        serverSupportedTunnelTypes[0] = {1973          vendor: 'TGHT',1974          signature: 'NOTUNNEL'1975        };1976      }19771978      // choose the notunnel type1979      if (serverSupportedTunnelTypes[0]) {1980        if (serverSupportedTunnelTypes[0].vendor != clientSupportedTunnelTypes[0].vendor || serverSupportedTunnelTypes[0].signature != clientSupportedTunnelTypes[0].signature) {1981          return this._fail("Client's tunnel type had the incorrect " + "vendor or signature");1982        }1983        Log.Debug("Selected tunnel type: " + clientSupportedTunnelTypes[0]);1984        this._sock.sQpush32(0); // use NOTUNNEL1985        this._sock.flush();1986        return false; // wait until we receive the sub auth count to continue1987      } else {1988        return this._fail("Server wanted tunnels, but doesn't support " + "the notunnel type");1989      }1990    }1991  }, {1992    key: "_negotiateTightAuth",1993    value: function _negotiateTightAuth() {1994      if (!this._rfbTightVNC) {1995        // first pass, do the tunnel negotiation1996        if (this._sock.rQwait("num tunnels", 4)) {1997          return false;1998        }1999        var numTunnels = this._sock.rQshift32();2000        if (numTunnels > 0 && this._sock.rQwait("tunnel capabilities", 16 * numTunnels, 4)) {2001          return false;2002        }2003        this._rfbTightVNC = true;2004        if (numTunnels > 0) {2005          this._negotiateTightTunnels(numTunnels);2006          return false; // wait until we receive the sub auth to continue2007        }2008      }20092010      // second pass, do the sub-auth negotiation2011      if (this._sock.rQwait("sub auth count", 4)) {2012        return false;2013      }2014      var subAuthCount = this._sock.rQshift32();2015      if (subAuthCount === 0) {2016        // empty sub-auth list received means 'no auth' subtype selected2017        this._rfbInitState = 'SecurityResult';2018        return true;2019      }2020      if (this._sock.rQwait("sub auth capabilities", 16 * subAuthCount, 4)) {2021        return false;2022      }2023      var clientSupportedTypes = {2024        'STDVNOAUTH__': 1,2025        'STDVVNCAUTH_': 2,2026        'TGHTULGNAUTH': 1292027      };2028      var serverSupportedTypes = [];2029      for (var i = 0; i < subAuthCount; i++) {2030        this._sock.rQshift32(); // capNum2031        var capabilities = this._sock.rQshiftStr(12);2032        serverSupportedTypes.push(capabilities);2033      }2034      Log.Debug("Server Tight authentication types: " + serverSupportedTypes);2035      for (var authType in clientSupportedTypes) {2036        if (serverSupportedTypes.indexOf(authType) != -1) {2037          this._sock.sQpush32(clientSupportedTypes[authType]);2038          this._sock.flush();2039          Log.Debug("Selected authentication type: " + authType);2040          switch (authType) {2041            case 'STDVNOAUTH__':2042              // no auth2043              this._rfbInitState = 'SecurityResult';2044              return true;2045            case 'STDVVNCAUTH_':2046              this._rfbAuthScheme = securityTypeVNCAuth;2047              return true;2048            case 'TGHTULGNAUTH':2049              this._rfbAuthScheme = securityTypeUnixLogon;2050              return true;2051            default:2052              return this._fail("Unsupported tiny auth scheme " + "(scheme: " + authType + ")");2053          }2054        }2055      }2056      return this._fail("No supported sub-auth types!");2057    }2058  }, {2059    key: "_handleRSAAESCredentialsRequired",2060    value: function _handleRSAAESCredentialsRequired(event) {2061      this.dispatchEvent(event);2062    }2063  }, {2064    key: "_handleRSAAESServerVerification",2065    value: function _handleRSAAESServerVerification(event) {2066      this.dispatchEvent(event);2067    }2068  }, {2069    key: "_negotiateRA2neAuth",2070    value: function _negotiateRA2neAuth() {2071      var _this5 = this;2072      if (this._rfbRSAAESAuthenticationState === null) {2073        this._rfbRSAAESAuthenticationState = new _ra["default"](this._sock, function () {2074          return _this5._rfbCredentials;2075        });2076        this._rfbRSAAESAuthenticationState.addEventListener("serververification", this._eventHandlers.handleRSAAESServerVerification);2077        this._rfbRSAAESAuthenticationState.addEventListener("credentialsrequired", this._eventHandlers.handleRSAAESCredentialsRequired);2078      }2079      this._rfbRSAAESAuthenticationState.checkInternalEvents();2080      if (!this._rfbRSAAESAuthenticationState.hasStarted) {2081        this._rfbRSAAESAuthenticationState.negotiateRA2neAuthAsync()["catch"](function (e) {2082          if (e.message !== "disconnect normally") {2083            _this5._fail(e.message);2084          }2085        }).then(function () {2086          _this5._rfbInitState = "SecurityResult";2087          return true;2088        })["finally"](function () {2089          _this5._rfbRSAAESAuthenticationState.removeEventListener("serververification", _this5._eventHandlers.handleRSAAESServerVerification);2090          _this5._rfbRSAAESAuthenticationState.removeEventListener("credentialsrequired", _this5._eventHandlers.handleRSAAESCredentialsRequired);2091          _this5._rfbRSAAESAuthenticationState = null;2092        });2093      }2094      return false;2095    }2096  }, {2097    key: "_negotiateMSLogonIIAuth",2098    value: function _negotiateMSLogonIIAuth() {2099      if (this._sock.rQwait("mslogonii dh param", 24)) {2100        return false;2101      }2102      if (this._rfbCredentials.username === undefined || this._rfbCredentials.password === undefined) {2103        this.dispatchEvent(new CustomEvent("credentialsrequired", {2104          detail: {2105            types: ["username", "password"]2106          }2107        }));2108        return false;2109      }2110      var g = this._sock.rQshiftBytes(8);2111      var p = this._sock.rQshiftBytes(8);2112      var A = this._sock.rQshiftBytes(8);2113      var dhKey = _crypto["default"].generateKey({2114        name: "DH",2115        g: g,2116        p: p2117      }, true, ["deriveBits"]);2118      var B = _crypto["default"].exportKey("raw", dhKey.publicKey);2119      var secret = _crypto["default"].deriveBits({2120        name: "DH",2121        "public": A2122      }, dhKey.privateKey, 64);2123      var key = _crypto["default"].importKey("raw", secret, {2124        name: "DES-CBC"2125      }, false, ["encrypt"]);2126      var username = (0, _strings.encodeUTF8)(this._rfbCredentials.username).substring(0, 255);2127      var password = (0, _strings.encodeUTF8)(this._rfbCredentials.password).substring(0, 63);2128      var usernameBytes = new Uint8Array(256);2129      var passwordBytes = new Uint8Array(64);2130      window.crypto.getRandomValues(usernameBytes);2131      window.crypto.getRandomValues(passwordBytes);2132      for (var i = 0; i < username.length; i++) {2133        usernameBytes[i] = username.charCodeAt(i);2134      }2135      usernameBytes[username.length] = 0;2136      for (var _i3 = 0; _i3 < password.length; _i3++) {2137        passwordBytes[_i3] = password.charCodeAt(_i3);2138      }2139      passwordBytes[password.length] = 0;2140      usernameBytes = _crypto["default"].encrypt({2141        name: "DES-CBC",2142        iv: secret2143      }, key, usernameBytes);2144      passwordBytes = _crypto["default"].encrypt({2145        name: "DES-CBC",2146        iv: secret2147      }, key, passwordBytes);2148      this._sock.sQpushBytes(B);2149      this._sock.sQpushBytes(usernameBytes);2150      this._sock.sQpushBytes(passwordBytes);2151      this._sock.flush();2152      this._rfbInitState = "SecurityResult";2153      return true;2154    }2155  }, {2156    key: "_negotiateAuthentication",2157    value: function _negotiateAuthentication() {2158      switch (this._rfbAuthScheme) {2159        case securityTypeNone:2160          if (this._rfbVersion >= 3.8) {2161            this._rfbInitState = 'SecurityResult';2162          } else {2163            this._rfbInitState = 'ClientInitialisation';2164          }2165          return true;2166        case securityTypeXVP:2167          return this._negotiateXvpAuth();2168        case securityTypeARD:2169          return this._negotiateARDAuth();2170        case securityTypeVNCAuth:2171          return this._negotiateStdVNCAuth();2172        case securityTypeTight:2173          return this._negotiateTightAuth();2174        case securityTypeVeNCrypt:2175          return this._negotiateVeNCryptAuth();2176        case securityTypePlain:2177          return this._negotiatePlainAuth();2178        case securityTypeUnixLogon:2179          return this._negotiateTightUnixAuth();2180        case securityTypeRA2ne:2181          return this._negotiateRA2neAuth();2182        case securityTypeMSLogonII:2183          return this._negotiateMSLogonIIAuth();2184        default:2185          return this._fail("Unsupported auth scheme (scheme: " + this._rfbAuthScheme + ")");2186      }2187    }2188  }, {2189    key: "_handleSecurityResult",2190    value: function _handleSecurityResult() {2191      if (this._sock.rQwait('VNC auth response ', 4)) {2192        return false;2193      }2194      var status = this._sock.rQshift32();2195      if (status === 0) {2196        // OK2197        this._rfbInitState = 'ClientInitialisation';2198        Log.Debug('Authentication OK');2199        return true;2200      } else {2201        if (this._rfbVersion >= 3.8) {2202          this._rfbInitState = "SecurityReason";2203          this._securityContext = "security result";2204          this._securityStatus = status;2205          return true;2206        } else {2207          this.dispatchEvent(new CustomEvent("securityfailure", {2208            detail: {2209              status: status2210            }2211          }));2212          return this._fail("Security handshake failed");2213        }2214      }2215    }2216  }, {2217    key: "_negotiateServerInit",2218    value: function _negotiateServerInit() {2219      if (this._sock.rQwait("server initialization", 24)) {2220        return false;2221      }22222223      /* Screen size */2224      var width = this._sock.rQshift16();2225      var height = this._sock.rQshift16();22262227      /* PIXEL_FORMAT */2228      var bpp = this._sock.rQshift8();2229      var depth = this._sock.rQshift8();2230      var bigEndian = this._sock.rQshift8();2231      var trueColor = this._sock.rQshift8();2232      var redMax = this._sock.rQshift16();2233      var greenMax = this._sock.rQshift16();2234      var blueMax = this._sock.rQshift16();2235      var redShift = this._sock.rQshift8();2236      var greenShift = this._sock.rQshift8();2237      var blueShift = this._sock.rQshift8();2238      this._sock.rQskipBytes(3); // padding22392240      // NB(directxman12): we don't want to call any callbacks or print messages until2241      //                   *after* we're past the point where we could backtrack22422243      /* Connection name/title */2244      var nameLength = this._sock.rQshift32();2245      if (this._sock.rQwait('server init name', nameLength, 24)) {2246        return false;2247      }2248      var name = this._sock.rQshiftStr(nameLength);2249      name = (0, _strings.decodeUTF8)(name, true);2250      if (this._rfbTightVNC) {2251        if (this._sock.rQwait('TightVNC extended server init header', 8, 24 + nameLength)) {2252          return false;2253        }2254        // In TightVNC mode, ServerInit message is extended2255        var numServerMessages = this._sock.rQshift16();2256        var numClientMessages = this._sock.rQshift16();2257        var numEncodings = this._sock.rQshift16();2258        this._sock.rQskipBytes(2); // padding22592260        var totalMessagesLength = (numServerMessages + numClientMessages + numEncodings) * 16;2261        if (this._sock.rQwait('TightVNC extended server init header', totalMessagesLength, 32 + nameLength)) {2262          return false;2263        }22642265        // we don't actually do anything with the capability information that TIGHT sends,2266        // so we just skip the all of this.22672268        // TIGHT server message capabilities2269        this._sock.rQskipBytes(16 * numServerMessages);22702271        // TIGHT client message capabilities2272        this._sock.rQskipBytes(16 * numClientMessages);22732274        // TIGHT encoding capabilities2275        this._sock.rQskipBytes(16 * numEncodings);2276      }22772278      // NB(directxman12): these are down here so that we don't run them multiple times2279      //                   if we backtrack2280      Log.Info("Screen: " + width + "x" + height + ", bpp: " + bpp + ", depth: " + depth + ", bigEndian: " + bigEndian + ", trueColor: " + trueColor + ", redMax: " + redMax + ", greenMax: " + greenMax + ", blueMax: " + blueMax + ", redShift: " + redShift + ", greenShift: " + greenShift + ", blueShift: " + blueShift);22812282      // we're past the point where we could backtrack, so it's safe to call this2283      this._setDesktopName(name);2284      this._resize(width, height);2285      if (!this._viewOnly) {2286        this._keyboard.grab();2287      }2288      this._fbDepth = 24;2289      if (this._fbName === "Intel(r) AMT KVM") {2290        Log.Warn("Intel AMT KVM only supports 8/16 bit depths. Using low color mode.");2291        this._fbDepth = 8;2292      }2293      RFB.messages.pixelFormat(this._sock, this._fbDepth, true);2294      this._sendEncodings();2295      RFB.messages.fbUpdateRequest(this._sock, false, 0, 0, this._fbWidth, this._fbHeight);2296      this._updateConnectionState('connected');2297      return true;2298    }2299  }, {2300    key: "_sendEncodings",2301    value: function _sendEncodings() {2302      var encs = [];23032304      // In preference order2305      encs.push(_encodings.encodings.encodingCopyRect);2306      // Only supported with full depth support2307      if (this._fbDepth == 24) {2308        if (_browser.supportsWebCodecsH264Decode) {2309          encs.push(_encodings.encodings.encodingH264);2310        }2311        encs.push(_encodings.encodings.encodingTight);2312        encs.push(_encodings.encodings.encodingTightPNG);2313        encs.push(_encodings.encodings.encodingZRLE);2314        encs.push(_encodings.encodings.encodingJPEG);2315        encs.push(_encodings.encodings.encodingHextile);2316        encs.push(_encodings.encodings.encodingRRE);2317        encs.push(_encodings.encodings.encodingZlib);2318      }2319      encs.push(_encodings.encodings.encodingRaw);23202321      // Psuedo-encoding settings2322      encs.push(_encodings.encodings.pseudoEncodingQualityLevel0 + this._qualityLevel);2323      encs.push(_encodings.encodings.pseudoEncodingCompressLevel0 + this._compressionLevel);2324      encs.push(_encodings.encodings.pseudoEncodingDesktopSize);2325      encs.push(_encodings.encodings.pseudoEncodingLastRect);2326      encs.push(_encodings.encodings.pseudoEncodingQEMUExtendedKeyEvent);2327      encs.push(_encodings.encodings.pseudoEncodingQEMULedEvent);2328      encs.push(_encodings.encodings.pseudoEncodingExtendedDesktopSize);2329      encs.push(_encodings.encodings.pseudoEncodingXvp);2330      encs.push(_encodings.encodings.pseudoEncodingFence);2331      encs.push(_encodings.encodings.pseudoEncodingContinuousUpdates);2332      encs.push(_encodings.encodings.pseudoEncodingDesktopName);2333      encs.push(_encodings.encodings.pseudoEncodingExtendedClipboard);2334      encs.push(_encodings.encodings.pseudoEncodingExtendedMouseButtons);2335      if (this._fbDepth == 24) {2336        encs.push(_encodings.encodings.pseudoEncodingVMwareCursor);2337        encs.push(_encodings.encodings.pseudoEncodingCursor);2338      }2339      RFB.messages.clientEncodings(this._sock, encs);2340    }23412342    /* RFB protocol initialization states:2343     *   ProtocolVersion2344     *   Security2345     *   Authentication2346     *   SecurityResult2347     *   ClientInitialization - not triggered by server message2348     *   ServerInitialization2349     */2350  }, {2351    key: "_initMsg",2352    value: function _initMsg() {2353      switch (this._rfbInitState) {2354        case 'ProtocolVersion':2355          return this._negotiateProtocolVersion();2356        case 'Security':2357          return this._negotiateSecurity();2358        case 'Authentication':2359          return this._negotiateAuthentication();2360        case 'SecurityResult':2361          return this._handleSecurityResult();2362        case 'SecurityReason':2363          return this._handleSecurityReason();2364        case 'ClientInitialisation':2365          this._sock.sQpush8(this._shared ? 1 : 0); // ClientInitialisation2366          this._sock.flush();2367          this._rfbInitState = 'ServerInitialisation';2368          return true;2369        case 'ServerInitialisation':2370          return this._negotiateServerInit();2371        default:2372          return this._fail("Unknown init state (state: " + this._rfbInitState + ")");2373      }2374    }23752376    // Resume authentication handshake after it was paused for some2377    // reason, e.g. waiting for a password from the user2378  }, {2379    key: "_resumeAuthentication",2380    value: function _resumeAuthentication() {2381      // We use setTimeout() so it's run in its own context, just like2382      // it originally did via the WebSocket's event handler2383      setTimeout(this._initMsg.bind(this), 0);2384    }2385  }, {2386    key: "_handleSetColourMapMsg",2387    value: function _handleSetColourMapMsg() {2388      Log.Debug("SetColorMapEntries");2389      return this._fail("Unexpected SetColorMapEntries message");2390    }2391  }, {2392    key: "_handleServerCutText",2393    value: function _handleServerCutText() {2394      Log.Debug("ServerCutText");2395      if (this._sock.rQwait("ServerCutText header", 7, 1)) {2396        return false;2397      }2398      this._sock.rQskipBytes(3); // Padding23992400      var length = this._sock.rQshift32();2401      length = (0, _int.toSigned32bit)(length);2402      if (this._sock.rQwait("ServerCutText content", Math.abs(length), 8)) {2403        return false;2404      }2405      if (length >= 0) {2406        //Standard msg2407        var text = this._sock.rQshiftStr(length);2408        if (this._viewOnly) {2409          return true;2410        }2411        this.dispatchEvent(new CustomEvent("clipboard", {2412          detail: {2413            text: text2414          }2415        }));2416      } else {2417        //Extended msg.2418        length = Math.abs(length);2419        var flags = this._sock.rQshift32();2420        var formats = flags & 0x0000FFFF;2421        var actions = flags & 0xFF000000;2422        var isCaps = !!(actions & extendedClipboardActionCaps);2423        if (isCaps) {2424          this._clipboardServerCapabilitiesFormats = {};2425          this._clipboardServerCapabilitiesActions = {};24262427          // Update our server capabilities for Formats2428          for (var i = 0; i <= 15; i++) {2429            var index = 1 << i;24302431            // Check if format flag is set.2432            if (formats & index) {2433              this._clipboardServerCapabilitiesFormats[index] = true;2434              // We don't send unsolicited clipboard, so we2435              // ignore the size2436              this._sock.rQshift32();2437            }2438          }24392440          // Update our server capabilities for Actions2441          for (var _i4 = 24; _i4 <= 31; _i4++) {2442            var _index = 1 << _i4;2443            this._clipboardServerCapabilitiesActions[_index] = !!(actions & _index);2444          }24452446          /*  Caps handling done, send caps with the clients2447              capabilities set as a response */2448          var clientActions = [extendedClipboardActionCaps, extendedClipboardActionRequest, extendedClipboardActionPeek, extendedClipboardActionNotify, extendedClipboardActionProvide];2449          RFB.messages.extendedClipboardCaps(this._sock, clientActions, {2450            extendedClipboardFormatText: 02451          });2452        } else if (actions === extendedClipboardActionRequest) {2453          if (this._viewOnly) {2454            return true;2455          }24562457          // Check if server has told us it can handle Provide and there is clipboard data to send.2458          if (this._clipboardText != null && this._clipboardServerCapabilitiesActions[extendedClipboardActionProvide]) {2459            if (formats & extendedClipboardFormatText) {2460              RFB.messages.extendedClipboardProvide(this._sock, [extendedClipboardFormatText], [this._clipboardText]);2461            }2462          }2463        } else if (actions === extendedClipboardActionPeek) {2464          if (this._viewOnly) {2465            return true;2466          }2467          if (this._clipboardServerCapabilitiesActions[extendedClipboardActionNotify]) {2468            if (this._clipboardText != null) {2469              RFB.messages.extendedClipboardNotify(this._sock, [extendedClipboardFormatText]);2470            } else {2471              RFB.messages.extendedClipboardNotify(this._sock, []);2472            }2473          }2474        } else if (actions === extendedClipboardActionNotify) {2475          if (this._viewOnly) {2476            return true;2477          }2478          if (this._clipboardServerCapabilitiesActions[extendedClipboardActionRequest]) {2479            if (formats & extendedClipboardFormatText) {2480              RFB.messages.extendedClipboardRequest(this._sock, [extendedClipboardFormatText]);2481            }2482          }2483        } else if (actions === extendedClipboardActionProvide) {2484          if (this._viewOnly) {2485            return true;2486          }2487          if (!(formats & extendedClipboardFormatText)) {2488            return true;2489          }2490          // Ignore what we had in our clipboard client side.2491          this._clipboardText = null;24922493          // FIXME: Should probably verify that this data was actually requested2494          var zlibStream = this._sock.rQshiftBytes(length - 4);2495          var streamInflator = new _inflator["default"]();2496          var textData = null;2497          streamInflator.setInput(zlibStream);2498          for (var _i5 = 0; _i5 <= 15; _i5++) {2499            var format = 1 << _i5;2500            if (formats & format) {2501              var size = 0x00;2502              var sizeArray = streamInflator.inflate(4);2503              size |= sizeArray[0] << 24;2504              size |= sizeArray[1] << 16;2505              size |= sizeArray[2] << 8;2506              size |= sizeArray[3];2507              var chunk = streamInflator.inflate(size);2508              if (format === extendedClipboardFormatText) {2509                textData = chunk;2510              }2511            }2512          }2513          streamInflator.setInput(null);2514          if (textData !== null) {2515            var tmpText = "";2516            for (var _i6 = 0; _i6 < textData.length; _i6++) {2517              tmpText += String.fromCharCode(textData[_i6]);2518            }2519            textData = tmpText;2520            textData = (0, _strings.decodeUTF8)(textData);2521            if (textData.length > 0 && "\0" === textData.charAt(textData.length - 1)) {2522              textData = textData.slice(0, -1);2523            }2524            textData = textData.replaceAll("\r\n", "\n");2525            this.dispatchEvent(new CustomEvent("clipboard", {2526              detail: {2527                text: textData2528              }2529            }));2530          }2531        } else {2532          return this._fail("Unexpected action in extended clipboard message: " + actions);2533        }2534      }2535      return true;2536    }2537  }, {2538    key: "_handleServerFenceMsg",2539    value: function _handleServerFenceMsg() {2540      if (this._sock.rQwait("ServerFence header", 8, 1)) {2541        return false;2542      }2543      this._sock.rQskipBytes(3); // Padding2544      var flags = this._sock.rQshift32();2545      var length = this._sock.rQshift8();2546      if (this._sock.rQwait("ServerFence payload", length, 9)) {2547        return false;2548      }2549      if (length > 64) {2550        Log.Warn("Bad payload length (" + length + ") in fence response");2551        length = 64;2552      }2553      var payload = this._sock.rQshiftStr(length);2554      this._supportsFence = true;25552556      /*2557       * Fence flags2558       *2559       *  (1<<0)  - BlockBefore2560       *  (1<<1)  - BlockAfter2561       *  (1<<2)  - SyncNext2562       *  (1<<31) - Request2563       */25642565      if (!(flags & 1 << 31)) {2566        return this._fail("Unexpected fence response");2567      }25682569      // Filter out unsupported flags2570      // FIXME: support syncNext2571      flags &= 1 << 0 | 1 << 1;25722573      // BlockBefore and BlockAfter are automatically handled by2574      // the fact that we process each incoming message2575      // synchronuosly.2576      RFB.messages.clientFence(this._sock, flags, payload);2577      return true;2578    }2579  }, {2580    key: "_handleXvpMsg",2581    value: function _handleXvpMsg() {2582      if (this._sock.rQwait("XVP version and message", 3, 1)) {2583        return false;2584      }2585      this._sock.rQskipBytes(1); // Padding2586      var xvpVer = this._sock.rQshift8();2587      var xvpMsg = this._sock.rQshift8();2588      switch (xvpMsg) {2589        case 0:2590          // XVP_FAIL2591          Log.Error("XVP operation failed");2592          break;2593        case 1:2594          // XVP_INIT2595          this._rfbXvpVer = xvpVer;2596          Log.Info("XVP extensions enabled (version " + this._rfbXvpVer + ")");2597          this._setCapability("power", true);2598          break;2599        default:2600          this._fail("Illegal server XVP message (msg: " + xvpMsg + ")");2601          break;2602      }2603      return true;2604    }2605  }, {2606    key: "_normalMsg",2607    value: function _normalMsg() {2608      var msgType;2609      if (this._FBU.rects > 0) {2610        msgType = 0;2611      } else {2612        msgType = this._sock.rQshift8();2613      }2614      var first, ret;2615      switch (msgType) {2616        case 0:2617          // FramebufferUpdate2618          ret = this._framebufferUpdate();2619          if (ret && !this._enabledContinuousUpdates) {2620            RFB.messages.fbUpdateRequest(this._sock, true, 0, 0, this._fbWidth, this._fbHeight);2621          }2622          return ret;2623        case 1:2624          // SetColorMapEntries2625          return this._handleSetColourMapMsg();2626        case 2:2627          // Bell2628          Log.Debug("Bell");2629          this.dispatchEvent(new CustomEvent("bell", {2630            detail: {}2631          }));2632          return true;2633        case 3:2634          // ServerCutText2635          return this._handleServerCutText();2636        case 150:2637          // EndOfContinuousUpdates2638          first = !this._supportsContinuousUpdates;2639          this._supportsContinuousUpdates = true;2640          this._enabledContinuousUpdates = false;2641          if (first) {2642            this._enabledContinuousUpdates = true;2643            this._updateContinuousUpdates();2644            Log.Info("Enabling continuous updates.");2645          } else {2646            // FIXME: We need to send a framebufferupdaterequest here2647            // if we add support for turning off continuous updates2648          }2649          return true;2650        case 248:2651          // ServerFence2652          return this._handleServerFenceMsg();2653        case 250:2654          // XVP2655          return this._handleXvpMsg();2656        default:2657          this._fail("Unexpected server message (type " + msgType + ")");2658          Log.Debug("sock.rQpeekBytes(30): " + this._sock.rQpeekBytes(30));2659          return true;2660      }2661    }2662  }, {2663    key: "_framebufferUpdate",2664    value: function _framebufferUpdate() {2665      var _this6 = this;2666      if (this._FBU.rects === 0) {2667        if (this._sock.rQwait("FBU header", 3, 1)) {2668          return false;2669        }2670        this._sock.rQskipBytes(1); // Padding2671        this._FBU.rects = this._sock.rQshift16();26722673        // Make sure the previous frame is fully rendered first2674        // to avoid building up an excessive queue2675        if (this._display.pending()) {2676          this._flushing = true;2677          this._display.flush().then(function () {2678            _this6._flushing = false;2679            // Resume processing2680            if (!_this6._sock.rQwait("message", 1)) {2681              _this6._handleMessage();2682            }2683          });2684          return false;2685        }2686      }2687      while (this._FBU.rects > 0) {2688        if (this._FBU.encoding === null) {2689          if (this._sock.rQwait("rect header", 12)) {2690            return false;2691          }2692          /* New FramebufferUpdate */26932694          this._FBU.x = this._sock.rQshift16();2695          this._FBU.y = this._sock.rQshift16();2696          this._FBU.width = this._sock.rQshift16();2697          this._FBU.height = this._sock.rQshift16();2698          this._FBU.encoding = this._sock.rQshift32();2699          /* Encodings are signed */2700          this._FBU.encoding >>= 0;2701        }2702        if (!this._handleRect()) {2703          return false;2704        }2705        this._FBU.rects--;2706        this._FBU.encoding = null;2707      }2708      this._display.flip();2709      return true; // We finished this FBU2710    }2711  }, {2712    key: "_handleRect",2713    value: function _handleRect() {2714      switch (this._FBU.encoding) {2715        case _encodings.encodings.pseudoEncodingLastRect:2716          this._FBU.rects = 1; // Will be decreased when we return2717          return true;2718        case _encodings.encodings.pseudoEncodingVMwareCursor:2719          return this._handleVMwareCursor();2720        case _encodings.encodings.pseudoEncodingCursor:2721          return this._handleCursor();2722        case _encodings.encodings.pseudoEncodingQEMUExtendedKeyEvent:2723          this._qemuExtKeyEventSupported = true;2724          return true;2725        case _encodings.encodings.pseudoEncodingDesktopName:2726          return this._handleDesktopName();2727        case _encodings.encodings.pseudoEncodingDesktopSize:2728          this._resize(this._FBU.width, this._FBU.height);2729          return true;2730        case _encodings.encodings.pseudoEncodingExtendedDesktopSize:2731          return this._handleExtendedDesktopSize();2732        case _encodings.encodings.pseudoEncodingExtendedMouseButtons:2733          this._extendedPointerEventSupported = true;2734          return true;2735        case _encodings.encodings.pseudoEncodingQEMULedEvent:2736          return this._handleLedEvent();2737        default:2738          return this._handleDataRect();2739      }2740    }2741  }, {2742    key: "_handleVMwareCursor",2743    value: function _handleVMwareCursor() {2744      var hotx = this._FBU.x; // hotspot-x2745      var hoty = this._FBU.y; // hotspot-y2746      var w = this._FBU.width;2747      var h = this._FBU.height;2748      if (this._sock.rQwait("VMware cursor encoding", 1)) {2749        return false;2750      }2751      var cursorType = this._sock.rQshift8();2752      this._sock.rQshift8(); //Padding27532754      var rgba;2755      var bytesPerPixel = 4;27562757      //Classic cursor2758      if (cursorType == 0) {2759        //Used to filter away unimportant bits.2760        //OR is used for correct conversion in js.2761        var PIXEL_MASK = 0xffffff00 | 0;2762        rgba = new Array(w * h * bytesPerPixel);2763        if (this._sock.rQwait("VMware cursor classic encoding", w * h * bytesPerPixel * 2, 2)) {2764          return false;2765        }2766        var andMask = new Array(w * h);2767        for (var pixel = 0; pixel < w * h; pixel++) {2768          andMask[pixel] = this._sock.rQshift32();2769        }2770        var xorMask = new Array(w * h);2771        for (var _pixel = 0; _pixel < w * h; _pixel++) {2772          xorMask[_pixel] = this._sock.rQshift32();2773        }2774        for (var _pixel2 = 0; _pixel2 < w * h; _pixel2++) {2775          if (andMask[_pixel2] == 0) {2776            //Fully opaque pixel2777            var bgr = xorMask[_pixel2];2778            var r = bgr >> 8 & 0xff;2779            var g = bgr >> 16 & 0xff;2780            var b = bgr >> 24 & 0xff;2781            rgba[_pixel2 * bytesPerPixel] = r; //r2782            rgba[_pixel2 * bytesPerPixel + 1] = g; //g2783            rgba[_pixel2 * bytesPerPixel + 2] = b; //b2784            rgba[_pixel2 * bytesPerPixel + 3] = 0xff; //a2785          } else if ((andMask[_pixel2] & PIXEL_MASK) == PIXEL_MASK) {2786            //Only screen value matters, no mouse colouring2787            if (xorMask[_pixel2] == 0) {2788              //Transparent pixel2789              rgba[_pixel2 * bytesPerPixel] = 0x00;2790              rgba[_pixel2 * bytesPerPixel + 1] = 0x00;2791              rgba[_pixel2 * bytesPerPixel + 2] = 0x00;2792              rgba[_pixel2 * bytesPerPixel + 3] = 0x00;2793            } else if ((xorMask[_pixel2] & PIXEL_MASK) == PIXEL_MASK) {2794              //Inverted pixel, not supported in browsers.2795              //Fully opaque instead.2796              rgba[_pixel2 * bytesPerPixel] = 0x00;2797              rgba[_pixel2 * bytesPerPixel + 1] = 0x00;2798              rgba[_pixel2 * bytesPerPixel + 2] = 0x00;2799              rgba[_pixel2 * bytesPerPixel + 3] = 0xff;2800            } else {2801              //Unhandled xorMask2802              rgba[_pixel2 * bytesPerPixel] = 0x00;2803              rgba[_pixel2 * bytesPerPixel + 1] = 0x00;2804              rgba[_pixel2 * bytesPerPixel + 2] = 0x00;2805              rgba[_pixel2 * bytesPerPixel + 3] = 0xff;2806            }2807          } else {2808            //Unhandled andMask2809            rgba[_pixel2 * bytesPerPixel] = 0x00;2810            rgba[_pixel2 * bytesPerPixel + 1] = 0x00;2811            rgba[_pixel2 * bytesPerPixel + 2] = 0x00;2812            rgba[_pixel2 * bytesPerPixel + 3] = 0xff;2813          }2814        }28152816        //Alpha cursor.2817      } else if (cursorType == 1) {2818        if (this._sock.rQwait("VMware cursor alpha encoding", w * h * 4, 2)) {2819          return false;2820        }2821        rgba = new Array(w * h * bytesPerPixel);2822        for (var _pixel3 = 0; _pixel3 < w * h; _pixel3++) {2823          var data = this._sock.rQshift32();2824          rgba[_pixel3 * 4] = data >> 24 & 0xff; //r2825          rgba[_pixel3 * 4 + 1] = data >> 16 & 0xff; //g2826          rgba[_pixel3 * 4 + 2] = data >> 8 & 0xff; //b2827          rgba[_pixel3 * 4 + 3] = data & 0xff; //a2828        }2829      } else {2830        Log.Warn("The given cursor type is not supported: " + cursorType + " given.");2831        return false;2832      }2833      this._updateCursor(rgba, hotx, hoty, w, h);2834      return true;2835    }2836  }, {2837    key: "_handleCursor",2838    value: function _handleCursor() {2839      var hotx = this._FBU.x; // hotspot-x2840      var hoty = this._FBU.y; // hotspot-y2841      var w = this._FBU.width;2842      var h = this._FBU.height;2843      var pixelslength = w * h * 4;2844      var masklength = Math.ceil(w / 8) * h;2845      var bytes = pixelslength + masklength;2846      if (this._sock.rQwait("cursor encoding", bytes)) {2847        return false;2848      }28492850      // Decode from BGRX pixels + bit mask to RGBA2851      var pixels = this._sock.rQshiftBytes(pixelslength);2852      var mask = this._sock.rQshiftBytes(masklength);2853      var rgba = new Uint8Array(w * h * 4);2854      var pixIdx = 0;2855      for (var y = 0; y < h; y++) {2856        for (var x = 0; x < w; x++) {2857          var maskIdx = y * Math.ceil(w / 8) + Math.floor(x / 8);2858          var alpha = mask[maskIdx] << x % 8 & 0x80 ? 255 : 0;2859          rgba[pixIdx] = pixels[pixIdx + 2];2860          rgba[pixIdx + 1] = pixels[pixIdx + 1];2861          rgba[pixIdx + 2] = pixels[pixIdx];2862          rgba[pixIdx + 3] = alpha;2863          pixIdx += 4;2864        }2865      }2866      this._updateCursor(rgba, hotx, hoty, w, h);2867      return true;2868    }2869  }, {2870    key: "_handleDesktopName",2871    value: function _handleDesktopName() {2872      if (this._sock.rQwait("DesktopName", 4)) {2873        return false;2874      }2875      var length = this._sock.rQshift32();2876      if (this._sock.rQwait("DesktopName", length, 4)) {2877        return false;2878      }2879      var name = this._sock.rQshiftStr(length);2880      name = (0, _strings.decodeUTF8)(name, true);2881      this._setDesktopName(name);2882      return true;2883    }2884  }, {2885    key: "_handleLedEvent",2886    value: function _handleLedEvent() {2887      if (this._sock.rQwait("LED status", 1)) {2888        return false;2889      }2890      var data = this._sock.rQshift8();2891      // ScrollLock state can be retrieved with data & 1. This is currently not needed.2892      var numLock = data & 2 ? true : false;2893      var capsLock = data & 4 ? true : false;2894      this._remoteCapsLock = capsLock;2895      this._remoteNumLock = numLock;2896      return true;2897    }2898  }, {2899    key: "_handleExtendedDesktopSize",2900    value: function _handleExtendedDesktopSize() {2901      if (this._sock.rQwait("ExtendedDesktopSize", 4)) {2902        return false;2903      }2904      var numberOfScreens = this._sock.rQpeek8();2905      var bytes = 4 + numberOfScreens * 16;2906      if (this._sock.rQwait("ExtendedDesktopSize", bytes)) {2907        return false;2908      }2909      var firstUpdate = !this._supportsSetDesktopSize;2910      this._supportsSetDesktopSize = true;2911      this._sock.rQskipBytes(1); // number-of-screens2912      this._sock.rQskipBytes(3); // padding29132914      for (var i = 0; i < numberOfScreens; i += 1) {2915        // Save the id and flags of the first screen2916        if (i === 0) {2917          this._screenID = this._sock.rQshift32(); // id2918          this._sock.rQskipBytes(2); // x-position2919          this._sock.rQskipBytes(2); // y-position2920          this._sock.rQskipBytes(2); // width2921          this._sock.rQskipBytes(2); // height2922          this._screenFlags = this._sock.rQshift32(); // flags2923        } else {2924          this._sock.rQskipBytes(16);2925        }2926      }29272928      /*2929       * The x-position indicates the reason for the change:2930       *2931       *  0 - server resized on its own2932       *  1 - this client requested the resize2933       *  2 - another client requested the resize2934       */29352936      if (this._FBU.x === 1) {2937        this._pendingRemoteResize = false;2938      }29392940      // We need to handle errors when we requested the resize.2941      if (this._FBU.x === 1 && this._FBU.y !== 0) {2942        var msg = "";2943        // The y-position indicates the status code from the server2944        switch (this._FBU.y) {2945          case 1:2946            msg = "Resize is administratively prohibited";2947            break;2948          case 2:2949            msg = "Out of resources";2950            break;2951          case 3:2952            msg = "Invalid screen layout";2953            break;2954          default:2955            msg = "Unknown reason";2956            break;2957        }2958        Log.Warn("Server did not accept the resize request: " + msg);2959      } else {2960        this._resize(this._FBU.width, this._FBU.height);2961      }29622963      // Normally we only apply the current resize mode after a2964      // window resize event. However there is no such trigger on the2965      // initial connect. And we don't know if the server supports2966      // resizing until we've gotten here.2967      if (firstUpdate) {2968        this._requestRemoteResize();2969      }2970      if (this._FBU.x === 1 && this._FBU.y === 0) {2971        // We might have resized again whilst waiting for the2972        // previous request, so check if we are in sync2973        this._requestRemoteResize();2974      }2975      return true;2976    }2977  }, {2978    key: "_handleDataRect",2979    value: function _handleDataRect() {2980      var decoder = this._decoders[this._FBU.encoding];2981      if (!decoder) {2982        this._fail("Unsupported encoding (encoding: " + this._FBU.encoding + ")");2983        return false;2984      }2985      try {2986        return decoder.decodeRect(this._FBU.x, this._FBU.y, this._FBU.width, this._FBU.height, this._sock, this._display, this._fbDepth);2987      } catch (err) {2988        this._fail("Error decoding rect: " + err);2989        return false;2990      }2991    }2992  }, {2993    key: "_updateContinuousUpdates",2994    value: function _updateContinuousUpdates() {2995      if (!this._enabledContinuousUpdates) {2996        return;2997      }2998      RFB.messages.enableContinuousUpdates(this._sock, true, 0, 0, this._fbWidth, this._fbHeight);2999    }30003001    // Handle resize-messages from the server3002  }, {3003    key: "_resize",3004    value: function _resize(width, height) {3005      this._fbWidth = width;3006      this._fbHeight = height;3007      this._display.resize(this._fbWidth, this._fbHeight);30083009      // Adjust the visible viewport based on the new dimensions3010      this._updateClip();3011      this._updateScale();3012      this._updateContinuousUpdates();30133014      // Keep this size until browser client size changes3015      this._saveExpectedClientSize();3016    }3017  }, {3018    key: "_xvpOp",3019    value: function _xvpOp(ver, op) {3020      if (this._rfbXvpVer < ver) {3021        return;3022      }3023      Log.Info("Sending XVP operation " + op + " (version " + ver + ")");3024      RFB.messages.xvpOp(this._sock, ver, op);3025    }3026  }, {3027    key: "_updateCursor",3028    value: function _updateCursor(rgba, hotx, hoty, w, h) {3029      this._cursorImage = {3030        rgbaPixels: rgba,3031        hotx: hotx,3032        hoty: hoty,3033        w: w,3034        h: h3035      };3036      this._refreshCursor();3037    }3038  }, {3039    key: "_shouldShowDotCursor",3040    value: function _shouldShowDotCursor() {3041      // Called when this._cursorImage is updated3042      if (!this._showDotCursor) {3043        // User does not want to see the dot, so...3044        return false;3045      }30463047      // The dot should not be shown if the cursor is already visible,3048      // i.e. contains at least one not-fully-transparent pixel.3049      // So iterate through all alpha bytes in rgba and stop at the3050      // first non-zero.3051      for (var i = 3; i < this._cursorImage.rgbaPixels.length; i += 4) {3052        if (this._cursorImage.rgbaPixels[i]) {3053          return false;3054        }3055      }30563057      // At this point, we know that the cursor is fully transparent, and3058      // the user wants to see the dot instead of this.3059      return true;3060    }3061  }, {3062    key: "_refreshCursor",3063    value: function _refreshCursor() {3064      if (this._rfbConnectionState !== "connecting" && this._rfbConnectionState !== "connected") {3065        return;3066      }3067      var image = this._shouldShowDotCursor() ? RFB.cursors.dot : this._cursorImage;3068      this._cursor.change(image.rgbaPixels, image.hotx, image.hoty, image.w, image.h);3069    }3070  }], [{3071    key: "_convertButtonMask",3072    value: function _convertButtonMask(buttons) {3073      /* The bits in MouseEvent.buttons property correspond3074       * to the following mouse buttons:3075       *     0: Left3076       *     1: Right3077       *     2: Middle3078       *     3: Back3079       *     4: Forward3080       *3081       * These bits needs to be converted to what they are defined as3082       * in the RFB protocol.3083       */30843085      var buttonMaskMap = {3086        0: 1 << 0,3087        // Left3088        1: 1 << 2,3089        // Right3090        2: 1 << 1,3091        // Middle3092        3: 1 << 7,3093        // Back3094        4: 1 << 8 // Forward3095      };3096      var bmask = 0;3097      for (var i = 0; i < 5; i++) {3098        if (buttons & 1 << i) {3099          bmask |= buttonMaskMap[i];3100        }3101      }3102      return bmask;3103    }3104  }, {3105    key: "genDES",3106    value: function genDES(password, challenge) {3107      var passwordChars = password.split('').map(function (c) {3108        return c.charCodeAt(0);3109      });3110      var key = _crypto["default"].importKey("raw", passwordChars, {3111        name: "DES-ECB"3112      }, false, ["encrypt"]);3113      return _crypto["default"].encrypt({3114        name: "DES-ECB"3115      }, key, challenge);3116    }3117  }]);3118}(_eventtarget["default"]); // Class Methods3119RFB.messages = {3120  keyEvent: function keyEvent(sock, keysym, down) {3121    sock.sQpush8(4); // msg-type3122    sock.sQpush8(down);3123    sock.sQpush16(0);3124    sock.sQpush32(keysym);3125    sock.flush();3126  },3127  QEMUExtendedKeyEvent: function QEMUExtendedKeyEvent(sock, keysym, down, keycode) {3128    function getRFBkeycode(xtScanCode) {3129      var upperByte = keycode >> 8;3130      var lowerByte = keycode & 0x00ff;3131      if (upperByte === 0xe0 && lowerByte < 0x7f) {3132        return lowerByte | 0x80;3133      }3134      return xtScanCode;3135    }3136    sock.sQpush8(255); // msg-type3137    sock.sQpush8(0); // sub msg-type31383139    sock.sQpush16(down);3140    sock.sQpush32(keysym);3141    var RFBkeycode = getRFBkeycode(keycode);3142    sock.sQpush32(RFBkeycode);3143    sock.flush();3144  },3145  pointerEvent: function pointerEvent(sock, x, y, mask) {3146    sock.sQpush8(5); // msg-type31473148    // Marker bit must be set to 0, otherwise the server might3149    // confuse the marker bit with the highest bit in a normal3150    // PointerEvent message.3151    mask = mask & 0x7f;3152    sock.sQpush8(mask);3153    sock.sQpush16(x);3154    sock.sQpush16(y);3155    sock.flush();3156  },3157  extendedPointerEvent: function extendedPointerEvent(sock, x, y, mask) {3158    sock.sQpush8(5); // msg-type31593160    var higherBits = mask >> 7 & 0xff;31613162    // Bits 2-7 are reserved3163    if (higherBits & 0xfc) {3164      throw new Error("Invalid mouse button mask: " + mask);3165    }3166    var lowerBits = mask & 0x7f;3167    lowerBits |= 0x80; // Set marker bit to 131683169    sock.sQpush8(lowerBits);3170    sock.sQpush16(x);3171    sock.sQpush16(y);3172    sock.sQpush8(higherBits);3173    sock.flush();3174  },3175  // Used to build Notify and Request data.3176  _buildExtendedClipboardFlags: function _buildExtendedClipboardFlags(actions, formats) {3177    var data = new Uint8Array(4);3178    var formatFlag = 0x00000000;3179    var actionFlag = 0x00000000;3180    for (var i = 0; i < actions.length; i++) {3181      actionFlag |= actions[i];3182    }3183    for (var _i7 = 0; _i7 < formats.length; _i7++) {3184      formatFlag |= formats[_i7];3185    }3186    data[0] = actionFlag >> 24; // Actions3187    data[1] = 0x00; // Reserved3188    data[2] = 0x00; // Reserved3189    data[3] = formatFlag; // Formats31903191    return data;3192  },3193  extendedClipboardProvide: function extendedClipboardProvide(sock, formats, inData) {3194    // Deflate incomming data and their sizes3195    var deflator = new _deflator["default"]();3196    var dataToDeflate = [];3197    for (var i = 0; i < formats.length; i++) {3198      // We only support the format Text at this time3199      if (formats[i] != extendedClipboardFormatText) {3200        throw new Error("Unsupported extended clipboard format for Provide message.");3201      }32023203      // Change lone \r or \n into \r\n as defined in rfbproto3204      inData[i] = inData[i].replace(/\r\n|\r|\n/gm, "\r\n");32053206      // Check if it already has \03207      var text = (0, _strings.encodeUTF8)(inData[i] + "\0");3208      dataToDeflate.push(text.length >> 24 & 0xFF, text.length >> 16 & 0xFF, text.length >> 8 & 0xFF, text.length & 0xFF);3209      for (var j = 0; j < text.length; j++) {3210        dataToDeflate.push(text.charCodeAt(j));3211      }3212    }3213    var deflatedData = deflator.deflate(new Uint8Array(dataToDeflate));32143215    // Build data  to send3216    var data = new Uint8Array(4 + deflatedData.length);3217    data.set(RFB.messages._buildExtendedClipboardFlags([extendedClipboardActionProvide], formats));3218    data.set(deflatedData, 4);3219    RFB.messages.clientCutText(sock, data, true);3220  },3221  extendedClipboardNotify: function extendedClipboardNotify(sock, formats) {3222    var flags = RFB.messages._buildExtendedClipboardFlags([extendedClipboardActionNotify], formats);3223    RFB.messages.clientCutText(sock, flags, true);3224  },3225  extendedClipboardRequest: function extendedClipboardRequest(sock, formats) {3226    var flags = RFB.messages._buildExtendedClipboardFlags([extendedClipboardActionRequest], formats);3227    RFB.messages.clientCutText(sock, flags, true);3228  },3229  extendedClipboardCaps: function extendedClipboardCaps(sock, actions, formats) {3230    var formatKeys = Object.keys(formats);3231    var data = new Uint8Array(4 + 4 * formatKeys.length);3232    formatKeys.map(function (x) {3233      return parseInt(x);3234    });3235    formatKeys.sort(function (a, b) {3236      return a - b;3237    });3238    data.set(RFB.messages._buildExtendedClipboardFlags(actions, []));3239    var loopOffset = 4;3240    for (var i = 0; i < formatKeys.length; i++) {3241      data[loopOffset] = formats[formatKeys[i]] >> 24;3242      data[loopOffset + 1] = formats[formatKeys[i]] >> 16;3243      data[loopOffset + 2] = formats[formatKeys[i]] >> 8;3244      data[loopOffset + 3] = formats[formatKeys[i]] >> 0;3245      loopOffset += 4;3246      data[3] |= 1 << formatKeys[i]; // Update our format flags3247    }3248    RFB.messages.clientCutText(sock, data, true);3249  },3250  clientCutText: function clientCutText(sock, data) {3251    var extended = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;3252    sock.sQpush8(6); // msg-type32533254    sock.sQpush8(0); // padding3255    sock.sQpush8(0); // padding3256    sock.sQpush8(0); // padding32573258    var length;3259    if (extended) {3260      length = (0, _int.toUnsigned32bit)(-data.length);3261    } else {3262      length = data.length;3263    }3264    sock.sQpush32(length);3265    sock.sQpushBytes(data);3266    sock.flush();3267  },3268  setDesktopSize: function setDesktopSize(sock, width, height, id, flags) {3269    sock.sQpush8(251); // msg-type32703271    sock.sQpush8(0); // padding32723273    sock.sQpush16(width);3274    sock.sQpush16(height);3275    sock.sQpush8(1); // number-of-screens32763277    sock.sQpush8(0); // padding32783279    // screen array3280    sock.sQpush32(id);3281    sock.sQpush16(0); // x-position3282    sock.sQpush16(0); // y-position3283    sock.sQpush16(width);3284    sock.sQpush16(height);3285    sock.sQpush32(flags);3286    sock.flush();3287  },3288  clientFence: function clientFence(sock, flags, payload) {3289    sock.sQpush8(248); // msg-type32903291    sock.sQpush8(0); // padding3292    sock.sQpush8(0); // padding3293    sock.sQpush8(0); // padding32943295    sock.sQpush32(flags);3296    sock.sQpush8(payload.length);3297    sock.sQpushString(payload);3298    sock.flush();3299  },3300  enableContinuousUpdates: function enableContinuousUpdates(sock, enable, x, y, width, height) {3301    sock.sQpush8(150); // msg-type33023303    sock.sQpush8(enable);3304    sock.sQpush16(x);3305    sock.sQpush16(y);3306    sock.sQpush16(width);3307    sock.sQpush16(height);3308    sock.flush();3309  },3310  pixelFormat: function pixelFormat(sock, depth, trueColor) {3311    var bpp;3312    if (depth > 16) {3313      bpp = 32;3314    } else if (depth > 8) {3315      bpp = 16;3316    } else {3317      bpp = 8;3318    }3319    var bits = Math.floor(depth / 3);3320    sock.sQpush8(0); // msg-type33213322    sock.sQpush8(0); // padding3323    sock.sQpush8(0); // padding3324    sock.sQpush8(0); // padding33253326    sock.sQpush8(bpp);3327    sock.sQpush8(depth);3328    sock.sQpush8(0); // little-endian3329    sock.sQpush8(trueColor ? 1 : 0);3330    sock.sQpush16((1 << bits) - 1); // red-max3331    sock.sQpush16((1 << bits) - 1); // green-max3332    sock.sQpush16((1 << bits) - 1); // blue-max33333334    sock.sQpush8(bits * 0); // red-shift3335    sock.sQpush8(bits * 1); // green-shift3336    sock.sQpush8(bits * 2); // blue-shift33373338    sock.sQpush8(0); // padding3339    sock.sQpush8(0); // padding3340    sock.sQpush8(0); // padding33413342    sock.flush();3343  },3344  clientEncodings: function clientEncodings(sock, encodings) {3345    sock.sQpush8(2); // msg-type33463347    sock.sQpush8(0); // padding33483349    sock.sQpush16(encodings.length);3350    for (var i = 0; i < encodings.length; i++) {3351      sock.sQpush32(encodings[i]);3352    }3353    sock.flush();3354  },3355  fbUpdateRequest: function fbUpdateRequest(sock, incremental, x, y, w, h) {3356    if (typeof x === "undefined") {3357      x = 0;3358    }3359    if (typeof y === "undefined") {3360      y = 0;3361    }3362    sock.sQpush8(3); // msg-type33633364    sock.sQpush8(incremental ? 1 : 0);3365    sock.sQpush16(x);3366    sock.sQpush16(y);3367    sock.sQpush16(w);3368    sock.sQpush16(h);3369    sock.flush();3370  },3371  xvpOp: function xvpOp(sock, ver, op) {3372    sock.sQpush8(250); // msg-type33733374    sock.sQpush8(0); // padding33753376    sock.sQpush8(ver);3377    sock.sQpush8(op);3378    sock.flush();3379  }3380};3381RFB.cursors = {3382  none: {3383    rgbaPixels: new Uint8Array(),3384    w: 0,3385    h: 0,3386    hotx: 0,3387    hoty: 03388  },3389  dot: {3390    /* eslint-disable indent */3391    rgbaPixels: new Uint8Array([255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 255]),3392    /* eslint-enable indent */3393    w: 3,3394    h: 3,3395    hotx: 1,3396    hoty: 13397  }3398};