1 (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.novnc = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
4 Object.defineProperty(exports, "__esModule", {
8 var _logging = require('./util/logging.js');
10 var Log = _interopRequireWildcard(_logging);
12 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
15 /* Convert data (an array of integers) to a Base64 string. */
16 toBase64Table: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split(''),
19 encode: function (data) {
23 var toBase64Table = this.toBase64Table;
24 var length = data.length;
25 var lengthpad = length % 3;
26 // Convert every three bytes to 4 ascii characters.
28 for (var i = 0; i < length - 2; i += 3) {
29 result += toBase64Table[data[i] >> 2];
30 result += toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)];
31 result += toBase64Table[((data[i + 1] & 0x0f) << 2) + (data[i + 2] >> 6)];
32 result += toBase64Table[data[i + 2] & 0x3f];
35 // Convert the remaining 1 or 2 bytes, pad out to 4 characters.
37 if (lengthpad === 2) {
38 j = length - lengthpad;
39 result += toBase64Table[data[j] >> 2];
40 result += toBase64Table[((data[j] & 0x03) << 4) + (data[j + 1] >> 4)];
41 result += toBase64Table[(data[j + 1] & 0x0f) << 2];
42 result += toBase64Table[64];
43 } else if (lengthpad === 1) {
44 j = length - lengthpad;
45 result += toBase64Table[data[j] >> 2];
46 result += toBase64Table[(data[j] & 0x03) << 4];
47 result += toBase64Table[64];
48 result += toBase64Table[64];
54 /* Convert Base64 data to a string */
55 toBinaryTable: [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, 0, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1],
57 decode: function (data, offset) {
60 offset = typeof offset !== 'undefined' ? offset : 0;
61 var toBinaryTable = this.toBinaryTable;
62 var base64Pad = this.base64Pad;
63 var result, result_length;
64 var leftbits = 0; // number of bits decoded, but yet to be appended
65 var leftdata = 0; // bits decoded, but yet to be appended
66 var data_length = data.indexOf('=') - offset;
68 if (data_length < 0) {
69 data_length = data.length - offset;
72 /* Every four characters is 3 resulting numbers */
73 result_length = (data_length >> 2) * 3 + Math.floor(data_length % 4 / 1.5);
74 result = new Array(result_length);
76 // Convert one by one.
77 for (var idx = 0, i = offset; i < data.length; i++) {
78 var c = toBinaryTable[data.charCodeAt(i) & 0x7f];
79 var padding = data.charAt(i) === base64Pad;
80 // Skip illegal characters and whitespace
82 Log.Error("Illegal character code " + data.charCodeAt(i) + " at position " + i);
86 // Collect data into leftdata, update bitcount
87 leftdata = leftdata << 6 | c;
90 // If we have 8 or more bits, append 8 bits to the result
93 // Append if not padding.
95 result[idx++] = leftdata >> leftbits & 0xff;
97 leftdata &= (1 << leftbits) - 1;
101 // If there are any bits left, the base64 string was corrupted
103 err = new Error('Corrupted base64 string');
104 err.name = 'Base64-Error';
110 }; /* End of Base64 namespace */
111 /* This Source Code Form is subject to the terms of the Mozilla Public
112 * License, v. 2.0. If a copy of the MPL was not distributed with this
113 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
115 // From: http://hg.mozilla.org/mozilla-central/raw-file/ec10630b1a54/js/src/devtools/jint/sunspider/string-base64.js
116 },{"./util/logging.js":19}],2:[function(require,module,exports){
119 Object.defineProperty(exports, "__esModule", {
122 exports.default = DES;
124 * Ported from Flashlight VNC ActionScript implementation:
125 * http://www.wizhelp.com/flashlight-vnc/
127 * Full attribution follows:
129 * -------------------------------------------------------------------------
131 * This DES class has been extracted from package Acme.Crypto for use in VNC.
132 * The unnecessary odd parity code has been removed.
135 * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
137 * This software is distributed in the hope that it will be useful,
138 * but WITHOUT ANY WARRANTY; without even the implied warranty of
139 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
142 * DesCipher - the DES encryption method
144 * The meat of this code is by Dave Zimmerman <dzimm@widget.com>, and is:
146 * Copyright (c) 1996 Widget Workshop, Inc. All Rights Reserved.
148 * Permission to use, copy, modify, and distribute this software
149 * and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and
150 * without fee is hereby granted, provided that this copyright notice is kept
153 * WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY
154 * OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
155 * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
156 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE LIABLE
157 * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
158 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
160 * THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE
161 * CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
162 * PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
163 * NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE
164 * SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE
165 * SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE
166 * PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). WIDGET WORKSHOP
167 * SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR
168 * HIGH RISK ACTIVITIES.
173 * Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
175 * Redistribution and use in source and binary forms, with or without
176 * modification, are permitted provided that the following conditions
178 * 1. Redistributions of source code must retain the above copyright
179 * notice, this list of conditions and the following disclaimer.
180 * 2. Redistributions in binary form must reproduce the above copyright
181 * notice, this list of conditions and the following disclaimer in the
182 * documentation and/or other materials provided with the distribution.
184 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
185 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
186 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
187 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
188 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
189 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
190 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
191 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
192 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
193 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
196 * Visit the ACME Labs Java page for up-to-date versions of this and other
197 * fine Java utilities: http://www.acme.com/java/
200 function DES(passwd) {
203 // Tables, permutations, S-boxes, etc.
205 var PC2 = [13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31],
206 totrot = [1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28],
224 a = 1 << 16;b = 1 << 24;c = a | b;d = 1 << 2;e = 1 << 10;f = d | e;
225 SP1 = [c | e, z | z, a | z, c | f, c | d, a | f, z | d, a | z, z | e, c | e, c | f, z | e, b | f, c | d, b | z, z | d, z | f, b | e, b | e, a | e, a | e, c | z, c | z, b | f, a | d, b | d, b | d, a | d, z | z, z | f, a | f, b | z, a | z, c | f, z | d, c | z, c | e, b | z, b | z, z | e, c | d, a | z, a | e, b | d, z | e, z | d, b | f, a | f, c | f, a | d, c | z, b | f, b | d, z | f, a | f, c | e, z | f, b | e, b | e, z | z, a | d, a | e, z | z, c | d];
226 a = 1 << 20;b = 1 << 31;c = a | b;d = 1 << 5;e = 1 << 15;f = d | e;
227 SP2 = [c | f, b | e, z | e, a | f, a | z, z | d, c | d, b | f, b | d, c | f, c | e, b | z, b | e, a | z, z | d, c | d, a | e, a | d, b | f, z | z, b | z, z | e, a | f, c | z, a | d, b | d, z | z, a | e, z | f, c | e, c | z, z | f, z | z, a | f, c | d, a | z, b | f, c | z, c | e, z | e, c | z, b | e, z | d, c | f, a | f, z | d, z | e, b | z, z | f, c | e, a | z, b | d, a | d, b | f, b | d, a | d, a | e, z | z, b | e, z | f, b | z, c | d, c | f, a | e];
228 a = 1 << 17;b = 1 << 27;c = a | b;d = 1 << 3;e = 1 << 9;f = d | e;
229 SP3 = [z | f, c | e, z | z, c | d, b | e, z | z, a | f, b | e, a | d, b | d, b | d, a | z, c | f, a | d, c | z, z | f, b | z, z | d, c | e, z | e, a | e, c | z, c | d, a | f, b | f, a | e, a | z, b | f, z | d, c | f, z | e, b | z, c | e, b | z, a | d, z | f, a | z, c | e, b | e, z | z, z | e, a | d, c | f, b | e, b | d, z | e, z | z, c | d, b | f, a | z, b | z, c | f, z | d, a | f, a | e, b | d, c | z, b | f, z | f, c | z, a | f, z | d, c | d, a | e];
230 a = 1 << 13;b = 1 << 23;c = a | b;d = 1 << 0;e = 1 << 7;f = d | e;
231 SP4 = [c | d, a | f, a | f, z | e, c | e, b | f, b | d, a | d, z | z, c | z, c | z, c | f, z | f, z | z, b | e, b | d, z | d, a | z, b | z, c | d, z | e, b | z, a | d, a | e, b | f, z | d, a | e, b | e, a | z, c | e, c | f, z | f, b | e, b | d, c | z, c | f, z | f, z | z, z | z, c | z, a | e, b | e, b | f, z | d, c | d, a | f, a | f, z | e, c | f, z | f, z | d, a | z, b | d, a | d, c | e, b | f, a | d, a | e, b | z, c | d, z | e, b | z, a | z, c | e];
232 a = 1 << 25;b = 1 << 30;c = a | b;d = 1 << 8;e = 1 << 19;f = d | e;
233 SP5 = [z | d, a | f, a | e, c | d, z | e, z | d, b | z, a | e, b | f, z | e, a | d, b | f, c | d, c | e, z | f, b | z, a | z, b | e, b | e, z | z, b | d, c | f, c | f, a | d, c | e, b | d, z | z, c | z, a | f, a | z, c | z, z | f, z | e, c | d, z | d, a | z, b | z, a | e, c | d, b | f, a | d, b | z, c | e, a | f, b | f, z | d, a | z, c | e, c | f, z | f, c | z, c | f, a | e, z | z, b | e, c | z, z | f, a | d, b | d, z | e, z | z, b | e, a | f, b | d];
234 a = 1 << 22;b = 1 << 29;c = a | b;d = 1 << 4;e = 1 << 14;f = d | e;
235 SP6 = [b | d, c | z, z | e, c | f, c | z, z | d, c | f, a | z, b | e, a | f, a | z, b | d, a | d, b | e, b | z, z | f, z | z, a | d, b | f, z | e, a | e, b | f, z | d, c | d, c | d, z | z, a | f, c | e, z | f, a | e, c | e, b | z, b | e, z | d, c | d, a | e, c | f, a | z, z | f, b | d, a | z, b | e, b | z, z | f, b | d, c | f, a | e, c | z, a | f, c | e, z | z, c | d, z | d, z | e, c | z, a | f, z | e, a | d, b | f, z | z, c | e, b | z, a | d, b | f];
236 a = 1 << 21;b = 1 << 26;c = a | b;d = 1 << 1;e = 1 << 11;f = d | e;
237 SP7 = [a | z, c | d, b | f, z | z, z | e, b | f, a | f, c | e, c | f, a | z, z | z, b | d, z | d, b | z, c | d, z | f, b | e, a | f, a | d, b | e, b | d, c | z, c | e, a | d, c | z, z | e, z | f, c | f, a | e, z | d, b | z, a | e, b | z, a | e, a | z, b | f, b | f, c | d, c | d, z | d, a | d, b | z, b | e, a | z, c | e, z | f, a | f, c | e, z | f, b | d, c | f, c | z, a | e, z | z, z | d, c | f, z | z, a | f, c | z, z | e, b | d, b | e, z | e, a | d];
238 a = 1 << 18;b = 1 << 28;c = a | b;d = 1 << 6;e = 1 << 12;f = d | e;
239 SP8 = [b | f, z | e, a | z, c | f, b | z, b | f, z | d, b | z, a | d, c | z, c | f, a | e, c | e, a | f, z | e, z | d, c | z, b | d, b | e, z | f, a | e, a | d, c | d, c | e, z | f, z | z, z | z, c | d, b | d, b | e, a | f, a | z, a | f, a | z, c | e, z | e, z | d, c | d, z | e, a | f, b | e, z | d, b | d, c | z, c | d, b | z, a | z, b | f, z | z, c | f, a | d, b | d, c | z, b | e, b | f, z | z, c | f, a | e, a | e, z | f, z | f, a | d, b | z, c | e];
242 function setKeys(keyBlock) {
257 for (j = 0, l = 56; j < 56; ++j, l -= 8) {
258 l += l < -5 ? 65 : l < -3 ? 31 : l < -1 ? 63 : l === 27 ? 35 : 0; // PC1
260 pc1m[j] = (keyBlock[l >>> 3] & 1 << m) !== 0 ? 1 : 0;
263 for (i = 0; i < 16; ++i) {
267 for (o = 28; o < 59; o += 28) {
268 for (j = o - 28; j < o; ++j) {
273 pcr[j] = pc1m[l - 28];
277 for (j = 0; j < 24; ++j) {
278 if (pcr[PC2[j]] !== 0) {
279 kn[m] |= 1 << 23 - j;
281 if (pcr[PC2[j + 24]] !== 0) {
282 kn[n] |= 1 << 23 - j;
288 for (i = 0, rawi = 0, KnLi = 0; i < 16; ++i) {
291 keys[KnLi] = (raw0 & 0x00fc0000) << 6;
292 keys[KnLi] |= (raw0 & 0x00000fc0) << 10;
293 keys[KnLi] |= (raw1 & 0x00fc0000) >>> 10;
294 keys[KnLi] |= (raw1 & 0x00000fc0) >>> 6;
296 keys[KnLi] = (raw0 & 0x0003f000) << 12;
297 keys[KnLi] |= (raw0 & 0x0000003f) << 16;
298 keys[KnLi] |= (raw1 & 0x0003f000) >>> 4;
299 keys[KnLi] |= raw1 & 0x0000003f;
304 // Encrypt 8 bytes of text
305 function enc8(text) {
312 x; // left, right, accumulator
314 // Squash 8 bytes to 2 ints
315 l = b[i++] << 24 | b[i++] << 16 | b[i++] << 8 | b[i++];
316 r = b[i++] << 24 | b[i++] << 16 | b[i++] << 8 | b[i++];
318 x = (l >>> 4 ^ r) & 0x0f0f0f0f;
321 x = (l >>> 16 ^ r) & 0x0000ffff;
324 x = (r >>> 2 ^ l) & 0x33333333;
327 x = (r >>> 8 ^ l) & 0x00ff00ff;
330 r = r << 1 | r >>> 31 & 1;
331 x = (l ^ r) & 0xaaaaaaaa;
334 l = l << 1 | l >>> 31 & 1;
336 for (i = 0; i < 8; ++i) {
337 x = r << 28 | r >>> 4;
339 fval = SP7[x & 0x3f];
340 fval |= SP5[x >>> 8 & 0x3f];
341 fval |= SP3[x >>> 16 & 0x3f];
342 fval |= SP1[x >>> 24 & 0x3f];
343 x = r ^ keys[keysi++];
344 fval |= SP8[x & 0x3f];
345 fval |= SP6[x >>> 8 & 0x3f];
346 fval |= SP4[x >>> 16 & 0x3f];
347 fval |= SP2[x >>> 24 & 0x3f];
349 x = l << 28 | l >>> 4;
351 fval = SP7[x & 0x3f];
352 fval |= SP5[x >>> 8 & 0x3f];
353 fval |= SP3[x >>> 16 & 0x3f];
354 fval |= SP1[x >>> 24 & 0x3f];
355 x = l ^ keys[keysi++];
356 fval |= SP8[x & 0x0000003f];
357 fval |= SP6[x >>> 8 & 0x3f];
358 fval |= SP4[x >>> 16 & 0x3f];
359 fval |= SP2[x >>> 24 & 0x3f];
363 r = r << 31 | r >>> 1;
364 x = (l ^ r) & 0xaaaaaaaa;
367 l = l << 31 | l >>> 1;
368 x = (l >>> 8 ^ r) & 0x00ff00ff;
371 x = (l >>> 2 ^ r) & 0x33333333;
374 x = (r >>> 16 ^ l) & 0x0000ffff;
377 x = (r >>> 4 ^ l) & 0x0f0f0f0f;
381 // Spread ints to bytes
383 for (i = 0; i < 8; i++) {
384 b[i] = (x[i >>> 2] >>> 8 * (3 - i % 4)) % 256;
392 // Encrypt 16 bytes of text using passwd as key
393 function encrypt(t) {
394 return enc8(t.slice(0, 8)).concat(enc8(t.slice(8, 16)));
397 setKeys(passwd); // Setup keys
398 return { 'encrypt': encrypt }; // Public interface
400 },{}],3:[function(require,module,exports){
403 Object.defineProperty(exports, "__esModule", {
406 exports.default = Display;
408 var _logging = require("./util/logging.js");
410 var Log = _interopRequireWildcard(_logging);
412 var _base = require("./base64.js");
414 var _base2 = _interopRequireDefault(_base);
416 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
418 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
421 * noVNC: HTML5 VNC client
422 * Copyright (C) 2012 Joel Martin
423 * Copyright (C) 2015 Samuel Mannehed for Cendio AB
424 * Licensed under MPL 2.0 (see LICENSE.txt)
426 * See README.md for usage and integration instructions.
429 function Display(target) {
430 this._drawCtx = null;
431 this._c_forceCanvas = false;
433 this._renderQ = []; // queue drawing actions for in-oder rendering
434 this._flushing = false;
436 // the full frame buffer (logical canvas) size
440 this._prevDrawStyle = "";
442 this._tile16x16 = null;
446 Log.Debug(">> Display.constructor");
448 // The visible canvas
449 this._target = target;
452 throw new Error("Target must be set");
455 if (typeof this._target === 'string') {
456 throw new Error('target must be a DOM element');
459 if (!this._target.getContext) {
460 throw new Error("no getContext method");
463 this._targetCtx = this._target.getContext('2d');
465 // the visible canvas viewport (i.e. what actually gets seen)
466 this._viewportLoc = { 'x': 0, 'y': 0, 'w': this._target.width, 'h': this._target.height };
468 // The hidden canvas, where we do the actual rendering
469 this._backbuffer = document.createElement('canvas');
470 this._drawCtx = this._backbuffer.getContext('2d');
472 this._damageBounds = { left: 0, top: 0,
473 right: this._backbuffer.width,
474 bottom: this._backbuffer.height };
476 Log.Debug("User Agent: " + navigator.userAgent);
480 // Check canvas features
481 if (!('createImageData' in this._drawCtx)) {
482 throw new Error("Canvas does not support createImageData");
485 this._tile16x16 = this._drawCtx.createImageData(16, 16);
486 Log.Debug("<< Display.constructor");
489 var SUPPORTS_IMAGEDATA_CONSTRUCTOR = false;
491 new ImageData(new Uint8ClampedArray(4), 1, 1);
492 SUPPORTS_IMAGEDATA_CONSTRUCTOR = true;
497 Display.prototype = {
498 // ===== PROPERTIES =====
505 this._rescale(scale);
508 _clipViewport: false,
510 return this._clipViewport;
512 set clipViewport(viewport) {
513 this._clipViewport = viewport;
514 // May need to readjust the viewport dimensions
515 var vp = this._viewportLoc;
516 this.viewportChangeSize(vp.w, vp.h);
517 this.viewportChangePos(0, 0);
521 return this._fb_width;
524 return this._fb_height;
529 // ===== EVENT HANDLERS =====
531 onflush: function () {}, // A flush request has finished
533 // ===== PUBLIC METHODS =====
535 viewportChangePos: function (deltaX, deltaY) {
536 var vp = this._viewportLoc;
537 deltaX = Math.floor(deltaX);
538 deltaY = Math.floor(deltaY);
540 if (!this._clipViewport) {
541 deltaX = -vp.w; // clamped later of out of bounds
545 var vx2 = vp.x + vp.w - 1;
546 var vy2 = vp.y + vp.h - 1;
550 if (deltaX < 0 && vp.x + deltaX < 0) {
553 if (vx2 + deltaX >= this._fb_width) {
554 deltaX -= vx2 + deltaX - this._fb_width + 1;
557 if (vp.y + deltaY < 0) {
560 if (vy2 + deltaY >= this._fb_height) {
561 deltaY -= vy2 + deltaY - this._fb_height + 1;
564 if (deltaX === 0 && deltaY === 0) {
567 Log.Debug("viewportChange deltaX: " + deltaX + ", deltaY: " + deltaY);
572 this._damage(vp.x, vp.y, vp.w, vp.h);
577 viewportChangeSize: function (width, height) {
579 if (!this._clipViewport || typeof width === "undefined" || typeof height === "undefined") {
581 Log.Debug("Setting viewport to full display region");
582 width = this._fb_width;
583 height = this._fb_height;
586 if (width > this._fb_width) {
587 width = this._fb_width;
589 if (height > this._fb_height) {
590 height = this._fb_height;
593 var vp = this._viewportLoc;
594 if (vp.w !== width || vp.h !== height) {
598 var canvas = this._target;
599 canvas.width = width;
600 canvas.height = height;
602 // The position might need to be updated if we've grown
603 this.viewportChangePos(0, 0);
605 this._damage(vp.x, vp.y, vp.w, vp.h);
608 // Update the visible size of the target canvas
609 this._rescale(this._scale);
614 return x / this._scale + this._viewportLoc.x;
618 return y / this._scale + this._viewportLoc.y;
621 resize: function (width, height) {
622 this._prevDrawStyle = "";
624 this._fb_width = width;
625 this._fb_height = height;
627 var canvas = this._backbuffer;
628 if (canvas.width !== width || canvas.height !== height) {
630 // We have to save the canvas data since changing the size will clear it
632 if (canvas.width > 0 && canvas.height > 0) {
633 saveImg = this._drawCtx.getImageData(0, 0, canvas.width, canvas.height);
636 if (canvas.width !== width) {
637 canvas.width = width;
639 if (canvas.height !== height) {
640 canvas.height = height;
644 this._drawCtx.putImageData(saveImg, 0, 0);
648 // Readjust the viewport as it may be incorrectly sized
650 var vp = this._viewportLoc;
651 this.viewportChangeSize(vp.w, vp.h);
652 this.viewportChangePos(0, 0);
655 // Track what parts of the visible canvas that need updating
656 _damage: function (x, y, w, h) {
657 if (x < this._damageBounds.left) {
658 this._damageBounds.left = x;
660 if (y < this._damageBounds.top) {
661 this._damageBounds.top = y;
663 if (x + w > this._damageBounds.right) {
664 this._damageBounds.right = x + w;
666 if (y + h > this._damageBounds.bottom) {
667 this._damageBounds.bottom = y + h;
671 // Update the visible canvas with the contents of the
673 flip: function (from_queue) {
674 if (this._renderQ.length !== 0 && !from_queue) {
679 var x, y, vx, vy, w, h;
681 x = this._damageBounds.left;
682 y = this._damageBounds.top;
683 w = this._damageBounds.right - x;
684 h = this._damageBounds.bottom - y;
686 vx = x - this._viewportLoc.x;
687 vy = y - this._viewportLoc.y;
700 if (vx + w > this._viewportLoc.w) {
701 w = this._viewportLoc.w - vx;
703 if (vy + h > this._viewportLoc.h) {
704 h = this._viewportLoc.h - vy;
707 if (w > 0 && h > 0) {
708 // FIXME: We may need to disable image smoothing here
709 // as well (see copyImage()), but we haven't
710 // noticed any problem yet.
711 this._targetCtx.drawImage(this._backbuffer, x, y, w, h, vx, vy, w, h);
714 this._damageBounds.left = this._damageBounds.top = 65535;
715 this._damageBounds.right = this._damageBounds.bottom = 0;
721 this.resize(this._logo.width, this._logo.height);
722 this.imageRect(0, 0, this._logo.type, this._logo.data);
724 this.resize(240, 20);
725 this._drawCtx.clearRect(0, 0, this._fb_width, this._fb_height);
730 pending: function () {
731 return this._renderQ.length > 0;
735 if (this._renderQ.length === 0) {
738 this._flushing = true;
742 fillRect: function (x, y, width, height, color, from_queue) {
743 if (this._renderQ.length !== 0 && !from_queue) {
753 this._setFillColor(color);
754 this._drawCtx.fillRect(x, y, width, height);
755 this._damage(x, y, width, height);
759 copyImage: function (old_x, old_y, new_x, new_y, w, h, from_queue) {
760 if (this._renderQ.length !== 0 && !from_queue) {
771 // Due to this bug among others [1] we need to disable the image-smoothing to
772 // avoid getting a blur effect when copying data.
774 // 1. https://bugzilla.mozilla.org/show_bug.cgi?id=1194719
776 // We need to set these every time since all properties are reset
777 // when the the size is changed
778 this._drawCtx.mozImageSmoothingEnabled = false;
779 this._drawCtx.webkitImageSmoothingEnabled = false;
780 this._drawCtx.msImageSmoothingEnabled = false;
781 this._drawCtx.imageSmoothingEnabled = false;
783 this._drawCtx.drawImage(this._backbuffer, old_x, old_y, w, h, new_x, new_y, w, h);
784 this._damage(new_x, new_y, w, h);
788 imageRect: function (x, y, mime, arr) {
789 var img = new Image();
790 img.src = "data: " + mime + ";base64," + _base2.default.encode(arr);
799 // start updating a tile
800 startTile: function (x, y, width, height, color) {
803 if (width === 16 && height === 16) {
804 this._tile = this._tile16x16;
806 this._tile = this._drawCtx.createImageData(width, height);
810 var green = color[1];
813 var data = this._tile.data;
814 for (var i = 0; i < width * height * 4; i += 4) {
822 // update sub-rectangle of the current tile
823 subTile: function (x, y, w, h, color) {
825 var green = color[1];
830 var data = this._tile.data;
831 var width = this._tile.width;
832 for (var j = y; j < yend; j++) {
833 for (var i = x; i < xend; i++) {
834 var p = (i + j * width) * 4;
843 // draw the current tile to the screen
844 finishTile: function () {
845 this._drawCtx.putImageData(this._tile, this._tile_x, this._tile_y);
846 this._damage(this._tile_x, this._tile_y, this._tile.width, this._tile.height);
849 blitImage: function (x, y, width, height, arr, offset, from_queue) {
850 if (this._renderQ.length !== 0 && !from_queue) {
851 // NB(directxman12): it's technically more performant here to use preallocated arrays,
852 // but it's a lot of extra work for not a lot of payoff -- if we're using the render queue,
853 // this probably isn't getting called *nearly* as much
854 var new_arr = new Uint8Array(width * height * 4);
855 new_arr.set(new Uint8Array(arr.buffer, 0, new_arr.length));
865 this._bgrxImageData(x, y, width, height, arr, offset);
869 blitRgbImage: function (x, y, width, height, arr, offset, from_queue) {
870 if (this._renderQ.length !== 0 && !from_queue) {
871 // NB(directxman12): it's technically more performant here to use preallocated arrays,
872 // but it's a lot of extra work for not a lot of payoff -- if we're using the render queue,
873 // this probably isn't getting called *nearly* as much
874 var new_arr = new Uint8Array(width * height * 3);
875 new_arr.set(new Uint8Array(arr.buffer, 0, new_arr.length));
885 this._rgbImageData(x, y, width, height, arr, offset);
889 blitRgbxImage: function (x, y, width, height, arr, offset, from_queue) {
890 if (this._renderQ.length !== 0 && !from_queue) {
891 // NB(directxman12): it's technically more performant here to use preallocated arrays,
892 // but it's a lot of extra work for not a lot of payoff -- if we're using the render queue,
893 // this probably isn't getting called *nearly* as much
894 var new_arr = new Uint8Array(width * height * 4);
895 new_arr.set(new Uint8Array(arr.buffer, 0, new_arr.length));
905 this._rgbxImageData(x, y, width, height, arr, offset);
909 drawImage: function (img, x, y) {
910 this._drawCtx.drawImage(img, x, y);
911 this._damage(x, y, img.width, img.height);
914 changeCursor: function (pixels, mask, hotx, hoty, w, h) {
915 Display.changeCursor(this._target, pixels, mask, hotx, hoty, w, h);
918 defaultCursor: function () {
919 this._target.style.cursor = "default";
922 disableLocalCursor: function () {
923 this._target.style.cursor = "none";
926 autoscale: function (containerWidth, containerHeight) {
927 var vp = this._viewportLoc;
928 var targetAspectRatio = containerWidth / containerHeight;
929 var fbAspectRatio = vp.w / vp.h;
932 if (fbAspectRatio >= targetAspectRatio) {
933 scaleRatio = containerWidth / vp.w;
935 scaleRatio = containerHeight / vp.h;
938 this._rescale(scaleRatio);
941 // ===== PRIVATE METHODS =====
943 _rescale: function (factor) {
944 this._scale = factor;
945 var vp = this._viewportLoc;
947 // NB(directxman12): If you set the width directly, or set the
948 // style width to a number, the canvas is cleared.
949 // However, if you set the style width to a string
950 // ('NNNpx'), the canvas is scaled without clearing.
951 var width = Math.round(factor * vp.w) + 'px';
952 var height = Math.round(factor * vp.h) + 'px';
954 if (this._target.style.width !== width || this._target.style.height !== height) {
955 this._target.style.width = width;
956 this._target.style.height = height;
960 _setFillColor: function (color) {
961 var newStyle = 'rgb(' + color[2] + ',' + color[1] + ',' + color[0] + ')';
962 if (newStyle !== this._prevDrawStyle) {
963 this._drawCtx.fillStyle = newStyle;
964 this._prevDrawStyle = newStyle;
968 _rgbImageData: function (x, y, width, height, arr, offset) {
969 var img = this._drawCtx.createImageData(width, height);
971 for (var i = 0, j = offset; i < width * height * 4; i += 4, j += 3) {
973 data[i + 1] = arr[j + 1];
974 data[i + 2] = arr[j + 2];
975 data[i + 3] = 255; // Alpha
977 this._drawCtx.putImageData(img, x, y);
978 this._damage(x, y, img.width, img.height);
981 _bgrxImageData: function (x, y, width, height, arr, offset) {
982 var img = this._drawCtx.createImageData(width, height);
984 for (var i = 0, j = offset; i < width * height * 4; i += 4, j += 4) {
985 data[i] = arr[j + 2];
986 data[i + 1] = arr[j + 1];
987 data[i + 2] = arr[j];
988 data[i + 3] = 255; // Alpha
990 this._drawCtx.putImageData(img, x, y);
991 this._damage(x, y, img.width, img.height);
994 _rgbxImageData: function (x, y, width, height, arr, offset) {
995 // NB(directxman12): arr must be an Type Array view
997 if (SUPPORTS_IMAGEDATA_CONSTRUCTOR) {
998 img = new ImageData(new Uint8ClampedArray(arr.buffer, arr.byteOffset, width * height * 4), width, height);
1000 img = this._drawCtx.createImageData(width, height);
1001 img.data.set(new Uint8ClampedArray(arr.buffer, arr.byteOffset, width * height * 4));
1003 this._drawCtx.putImageData(img, x, y);
1004 this._damage(x, y, img.width, img.height);
1007 _renderQ_push: function (action) {
1008 this._renderQ.push(action);
1009 if (this._renderQ.length === 1) {
1010 // If this can be rendered immediately it will be, otherwise
1011 // the scanner will wait for the relevant event
1012 this._scan_renderQ();
1016 _resume_renderQ: function () {
1017 // "this" is the object that is ready, not the
1019 this.removeEventListener('load', this._noVNC_display._resume_renderQ);
1020 this._noVNC_display._scan_renderQ();
1023 _scan_renderQ: function () {
1025 while (ready && this._renderQ.length > 0) {
1026 var a = this._renderQ[0];
1032 this.copyImage(a.old_x, a.old_y, a.x, a.y, a.width, a.height, true);
1035 this.fillRect(a.x, a.y, a.width, a.height, a.color, true);
1038 this.blitImage(a.x, a.y, a.width, a.height, a.data, 0, true);
1041 this.blitRgbImage(a.x, a.y, a.width, a.height, a.data, 0, true);
1044 this.blitRgbxImage(a.x, a.y, a.width, a.height, a.data, 0, true);
1047 if (a.img.complete) {
1048 this.drawImage(a.img, a.x, a.y);
1050 a.img._noVNC_display = this;
1051 a.img.addEventListener('load', this._resume_renderQ);
1052 // We need to wait for this image to 'load'
1053 // to keep things in-order
1060 this._renderQ.shift();
1064 if (this._renderQ.length === 0 && this._flushing) {
1065 this._flushing = false;
1072 Display.changeCursor = function (target, pixels, mask, hotx, hoty, w, h) {
1073 if (w === 0 || h === 0) {
1074 target.style.cursor = 'none';
1080 for (y = 0; y < h; y++) {
1081 for (x = 0; x < w; x++) {
1082 var idx = y * Math.ceil(w / 8) + Math.floor(x / 8);
1083 var alpha = mask[idx] << x % 8 & 0x80 ? 255 : 0;
1084 idx = (w * y + x) * 4;
1085 cur.push(pixels[idx + 2]); // red
1086 cur.push(pixels[idx + 1]); // green
1087 cur.push(pixels[idx]); // blue
1088 cur.push(alpha); // alpha
1092 var canvas = document.createElement('canvas');
1093 var ctx = canvas.getContext('2d');
1099 if (SUPPORTS_IMAGEDATA_CONSTRUCTOR) {
1100 img = new ImageData(new Uint8ClampedArray(cur), w, h);
1102 img = ctx.createImageData(w, h);
1103 img.data.set(new Uint8ClampedArray(cur));
1105 ctx.clearRect(0, 0, w, h);
1106 ctx.putImageData(img, 0, 0);
1108 var url = canvas.toDataURL();
1109 target.style.cursor = 'url(' + url + ')' + hotx + ' ' + hoty + ', default';
1111 },{"./base64.js":1,"./util/logging.js":19}],4:[function(require,module,exports){
1114 Object.defineProperty(exports, "__esModule", {
1117 exports.encodingName = encodingName;
1119 * noVNC: HTML5 VNC client
1120 * Copyright (C) 2017 Pierre Ossman for Cendio AB
1121 * Licensed under MPL 2.0 (see LICENSE.txt)
1123 * See README.md for usage and integration instructions.
1126 var encodings = exports.encodings = {
1128 encodingCopyRect: 1,
1133 pseudoEncodingQualityLevel9: -23,
1134 pseudoEncodingQualityLevel0: -32,
1135 pseudoEncodingDesktopSize: -223,
1136 pseudoEncodingLastRect: -224,
1137 pseudoEncodingCursor: -239,
1138 pseudoEncodingQEMUExtendedKeyEvent: -258,
1139 pseudoEncodingTightPNG: -260,
1140 pseudoEncodingExtendedDesktopSize: -308,
1141 pseudoEncodingXvp: -309,
1142 pseudoEncodingFence: -312,
1143 pseudoEncodingContinuousUpdates: -313,
1144 pseudoEncodingCompressLevel9: -247,
1145 pseudoEncodingCompressLevel0: -256
1148 function encodingName(num) {
1150 case encodings.encodingRaw:
1152 case encodings.encodingCopyRect:
1154 case encodings.encodingRRE:
1156 case encodings.encodingHextile:
1158 case encodings.encodingTight:
1161 return "[unknown encoding " + num + "]";
1164 },{}],5:[function(require,module,exports){
1167 Object.defineProperty(exports, "__esModule", {
1170 exports.default = Inflate;
1172 var _inflate = require("../lib/vendor/pako/lib/zlib/inflate.js");
1174 var _zstream = require("../lib/vendor/pako/lib/zlib/zstream.js");
1176 var _zstream2 = _interopRequireDefault(_zstream);
1178 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
1180 Inflate.prototype = {
1181 inflate: function (data, flush, expected) {
1182 this.strm.input = data;
1183 this.strm.avail_in = this.strm.input.length;
1184 this.strm.next_in = 0;
1185 this.strm.next_out = 0;
1187 // resize our output buffer if it's too small
1188 // (we could just use multiple chunks, but that would cause an extra
1189 // allocation each time to flatten the chunks)
1190 if (expected > this.chunkSize) {
1191 this.chunkSize = expected;
1192 this.strm.output = new Uint8Array(this.chunkSize);
1195 this.strm.avail_out = this.chunkSize;
1197 (0, _inflate.inflate)(this.strm, flush);
1199 return new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out);
1202 reset: function () {
1203 (0, _inflate.inflateReset)(this.strm);
1207 function Inflate() {
1208 this.strm = new _zstream2.default();
1209 this.chunkSize = 1024 * 10 * 10;
1210 this.strm.output = new Uint8Array(this.chunkSize);
1211 this.windowBits = 5;
1213 (0, _inflate.inflateInit)(this.strm, this.windowBits);
1215 },{"../lib/vendor/pako/lib/zlib/inflate.js":26,"../lib/vendor/pako/lib/zlib/zstream.js":28}],6:[function(require,module,exports){
1218 Object.defineProperty(exports, "__esModule", {
1222 var _keysym = require("./keysym.js");
1224 var _keysym2 = _interopRequireDefault(_keysym);
1226 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
1229 * Mapping between HTML key values and VNC/X11 keysyms for "special"
1230 * keys that cannot be handled via their Unicode codepoint.
1232 * See https://www.w3.org/TR/uievents-key/ for possible values.
1235 var DOMKeyTable = {}; /*
1236 * noVNC: HTML5 VNC client
1237 * Copyright (C) 2017 Pierre Ossman for Cendio AB
1238 * Licensed under MPL 2.0 or any later version (see LICENSE.txt)
1241 function addStandard(key, standard) {
1242 if (standard === undefined) throw "Undefined keysym for key \"" + key + "\"";
1243 if (key in DOMKeyTable) throw "Duplicate entry for key \"" + key + "\"";
1244 DOMKeyTable[key] = [standard, standard, standard, standard];
1247 function addLeftRight(key, left, right) {
1248 if (left === undefined) throw "Undefined keysym for key \"" + key + "\"";
1249 if (right === undefined) throw "Undefined keysym for key \"" + key + "\"";
1250 if (key in DOMKeyTable) throw "Duplicate entry for key \"" + key + "\"";
1251 DOMKeyTable[key] = [left, left, right, left];
1254 function addNumpad(key, standard, numpad) {
1255 if (standard === undefined) throw "Undefined keysym for key \"" + key + "\"";
1256 if (numpad === undefined) throw "Undefined keysym for key \"" + key + "\"";
1257 if (key in DOMKeyTable) throw "Duplicate entry for key \"" + key + "\"";
1258 DOMKeyTable[key] = [standard, standard, standard, numpad];
1261 // 2.2. Modifier Keys
1263 addLeftRight("Alt", _keysym2.default.XK_Alt_L, _keysym2.default.XK_Alt_R);
1264 addStandard("AltGraph", _keysym2.default.XK_ISO_Level3_Shift);
1265 addStandard("CapsLock", _keysym2.default.XK_Caps_Lock);
1266 addLeftRight("Control", _keysym2.default.XK_Control_L, _keysym2.default.XK_Control_R);
1269 addLeftRight("Hyper", _keysym2.default.XK_Super_L, _keysym2.default.XK_Super_R);
1270 addLeftRight("Meta", _keysym2.default.XK_Super_L, _keysym2.default.XK_Super_R);
1271 addStandard("NumLock", _keysym2.default.XK_Num_Lock);
1272 addStandard("ScrollLock", _keysym2.default.XK_Scroll_Lock);
1273 addLeftRight("Shift", _keysym2.default.XK_Shift_L, _keysym2.default.XK_Shift_R);
1274 addLeftRight("Super", _keysym2.default.XK_Super_L, _keysym2.default.XK_Super_R);
1278 // 2.3. Whitespace Keys
1280 addNumpad("Enter", _keysym2.default.XK_Return, _keysym2.default.XK_KP_Enter);
1281 addStandard("Tab", _keysym2.default.XK_Tab);
1282 addNumpad(" ", _keysym2.default.XK_space, _keysym2.default.XK_KP_Space);
1284 // 2.4. Navigation Keys
1286 addNumpad("ArrowDown", _keysym2.default.XK_Down, _keysym2.default.XK_KP_Down);
1287 addNumpad("ArrowUp", _keysym2.default.XK_Up, _keysym2.default.XK_KP_Up);
1288 addNumpad("ArrowLeft", _keysym2.default.XK_Left, _keysym2.default.XK_KP_Left);
1289 addNumpad("ArrowRight", _keysym2.default.XK_Right, _keysym2.default.XK_KP_Right);
1290 addNumpad("End", _keysym2.default.XK_End, _keysym2.default.XK_KP_End);
1291 addNumpad("Home", _keysym2.default.XK_Home, _keysym2.default.XK_KP_Home);
1292 addNumpad("PageDown", _keysym2.default.XK_Next, _keysym2.default.XK_KP_Next);
1293 addNumpad("PageUp", _keysym2.default.XK_Prior, _keysym2.default.XK_KP_Prior);
1295 // 2.5. Editing Keys
1297 addStandard("Backspace", _keysym2.default.XK_BackSpace);
1298 addStandard("Clear", _keysym2.default.XK_Clear);
1299 addStandard("Copy", _keysym2.default.XF86XK_Copy);
1301 addStandard("Cut", _keysym2.default.XF86XK_Cut);
1302 addNumpad("Delete", _keysym2.default.XK_Delete, _keysym2.default.XK_KP_Delete);
1305 addNumpad("Insert", _keysym2.default.XK_Insert, _keysym2.default.XK_KP_Insert);
1306 addStandard("Paste", _keysym2.default.XF86XK_Paste);
1307 addStandard("Redo", _keysym2.default.XK_Redo);
1308 addStandard("Undo", _keysym2.default.XK_Undo);
1313 // - Again (could just be XK_Redo)
1315 addStandard("Cancel", _keysym2.default.XK_Cancel);
1316 addStandard("ContextMenu", _keysym2.default.XK_Menu);
1317 addStandard("Escape", _keysym2.default.XK_Escape);
1318 addStandard("Execute", _keysym2.default.XK_Execute);
1319 addStandard("Find", _keysym2.default.XK_Find);
1320 addStandard("Help", _keysym2.default.XK_Help);
1321 addStandard("Pause", _keysym2.default.XK_Pause);
1324 addStandard("Select", _keysym2.default.XK_Select);
1325 addStandard("ZoomIn", _keysym2.default.XF86XK_ZoomIn);
1326 addStandard("ZoomOut", _keysym2.default.XF86XK_ZoomOut);
1330 addStandard("BrightnessDown", _keysym2.default.XF86XK_MonBrightnessDown);
1331 addStandard("BrightnessUp", _keysym2.default.XF86XK_MonBrightnessUp);
1332 addStandard("Eject", _keysym2.default.XF86XK_Eject);
1333 addStandard("LogOff", _keysym2.default.XF86XK_LogOff);
1334 addStandard("Power", _keysym2.default.XF86XK_PowerOff);
1335 addStandard("PowerOff", _keysym2.default.XF86XK_PowerDown);
1336 addStandard("PrintScreen", _keysym2.default.XK_Print);
1337 addStandard("Hibernate", _keysym2.default.XF86XK_Hibernate);
1338 addStandard("Standby", _keysym2.default.XF86XK_Standby);
1339 addStandard("WakeUp", _keysym2.default.XF86XK_WakeUp);
1341 // 2.8. IME and Composition Keys
1343 addStandard("AllCandidates", _keysym2.default.XK_MultipleCandidate);
1344 addStandard("Alphanumeric", _keysym2.default.XK_Eisu_Shift); // could also be _Eisu_Toggle
1345 addStandard("CodeInput", _keysym2.default.XK_Codeinput);
1346 addStandard("Compose", _keysym2.default.XK_Multi_key);
1347 addStandard("Convert", _keysym2.default.XK_Henkan);
1350 addStandard("GroupFirst", _keysym2.default.XK_ISO_First_Group);
1351 addStandard("GroupLast", _keysym2.default.XK_ISO_Last_Group);
1352 addStandard("GroupNext", _keysym2.default.XK_ISO_Next_Group);
1353 addStandard("GroupPrevious", _keysym2.default.XK_ISO_Prev_Group);
1354 // - ModeChange (XK_Mode_switch is often used for AltGr)
1356 addStandard("NonConvert", _keysym2.default.XK_Muhenkan);
1357 addStandard("PreviousCandidate", _keysym2.default.XK_PreviousCandidate);
1359 addStandard("SingleCandidate", _keysym2.default.XK_SingleCandidate);
1360 addStandard("HangulMode", _keysym2.default.XK_Hangul);
1361 addStandard("HanjaMode", _keysym2.default.XK_Hangul_Hanja);
1362 addStandard("JunjuaMode", _keysym2.default.XK_Hangul_Jeonja);
1363 addStandard("Eisu", _keysym2.default.XK_Eisu_toggle);
1364 addStandard("Hankaku", _keysym2.default.XK_Hankaku);
1365 addStandard("Hiragana", _keysym2.default.XK_Hiragana);
1366 addStandard("HiraganaKatakana", _keysym2.default.XK_Hiragana_Katakana);
1367 addStandard("KanaMode", _keysym2.default.XK_Kana_Shift); // could also be _Kana_Lock
1368 addStandard("KanjiMode", _keysym2.default.XK_Kanji);
1369 addStandard("Katakana", _keysym2.default.XK_Katakana);
1370 addStandard("Romaji", _keysym2.default.XK_Romaji);
1371 addStandard("Zenkaku", _keysym2.default.XK_Zenkaku);
1372 addStandard("ZenkakuHanaku", _keysym2.default.XK_Zenkaku_Hankaku);
1374 // 2.9. General-Purpose Function Keys
1376 addStandard("F1", _keysym2.default.XK_F1);
1377 addStandard("F2", _keysym2.default.XK_F2);
1378 addStandard("F3", _keysym2.default.XK_F3);
1379 addStandard("F4", _keysym2.default.XK_F4);
1380 addStandard("F5", _keysym2.default.XK_F5);
1381 addStandard("F6", _keysym2.default.XK_F6);
1382 addStandard("F7", _keysym2.default.XK_F7);
1383 addStandard("F8", _keysym2.default.XK_F8);
1384 addStandard("F9", _keysym2.default.XK_F9);
1385 addStandard("F10", _keysym2.default.XK_F10);
1386 addStandard("F11", _keysym2.default.XK_F11);
1387 addStandard("F12", _keysym2.default.XK_F12);
1388 addStandard("F13", _keysym2.default.XK_F13);
1389 addStandard("F14", _keysym2.default.XK_F14);
1390 addStandard("F15", _keysym2.default.XK_F15);
1391 addStandard("F16", _keysym2.default.XK_F16);
1392 addStandard("F17", _keysym2.default.XK_F17);
1393 addStandard("F18", _keysym2.default.XK_F18);
1394 addStandard("F19", _keysym2.default.XK_F19);
1395 addStandard("F20", _keysym2.default.XK_F20);
1396 addStandard("F21", _keysym2.default.XK_F21);
1397 addStandard("F22", _keysym2.default.XK_F22);
1398 addStandard("F23", _keysym2.default.XK_F23);
1399 addStandard("F24", _keysym2.default.XK_F24);
1400 addStandard("F25", _keysym2.default.XK_F25);
1401 addStandard("F26", _keysym2.default.XK_F26);
1402 addStandard("F27", _keysym2.default.XK_F27);
1403 addStandard("F28", _keysym2.default.XK_F28);
1404 addStandard("F29", _keysym2.default.XK_F29);
1405 addStandard("F30", _keysym2.default.XK_F30);
1406 addStandard("F31", _keysym2.default.XK_F31);
1407 addStandard("F32", _keysym2.default.XK_F32);
1408 addStandard("F33", _keysym2.default.XK_F33);
1409 addStandard("F34", _keysym2.default.XK_F34);
1410 addStandard("F35", _keysym2.default.XK_F35);
1413 // 2.10. Multimedia Keys
1417 addStandard("Close", _keysym2.default.XF86XK_Close);
1418 addStandard("MailForward", _keysym2.default.XF86XK_MailForward);
1419 addStandard("MailReply", _keysym2.default.XF86XK_Reply);
1420 addStandard("MainSend", _keysym2.default.XF86XK_Send);
1421 addStandard("MediaFastForward", _keysym2.default.XF86XK_AudioForward);
1422 addStandard("MediaPause", _keysym2.default.XF86XK_AudioPause);
1423 addStandard("MediaPlay", _keysym2.default.XF86XK_AudioPlay);
1424 addStandard("MediaRecord", _keysym2.default.XF86XK_AudioRecord);
1425 addStandard("MediaRewind", _keysym2.default.XF86XK_AudioRewind);
1426 addStandard("MediaStop", _keysym2.default.XF86XK_AudioStop);
1427 addStandard("MediaTrackNext", _keysym2.default.XF86XK_AudioNext);
1428 addStandard("MediaTrackPrevious", _keysym2.default.XF86XK_AudioPrev);
1429 addStandard("New", _keysym2.default.XF86XK_New);
1430 addStandard("Open", _keysym2.default.XF86XK_Open);
1431 addStandard("Print", _keysym2.default.XK_Print);
1432 addStandard("Save", _keysym2.default.XF86XK_Save);
1433 addStandard("SpellCheck", _keysym2.default.XF86XK_Spell);
1435 // 2.11. Multimedia Numpad Keys
1442 // - AudioBalanceLeft
1443 // - AudioBalanceRight
1445 // - AudioBassBoostDown
1446 // - AudioBassBoostToggle
1447 // - AudioBassBoostUp
1449 // - AudioFaderFront
1451 // - AudioSurroundModeNext
1452 // - AudioTrebleDown
1454 addStandard("AudioVolumeDown", _keysym2.default.XF86XK_AudioLowerVolume);
1455 addStandard("AudioVolumeUp", _keysym2.default.XF86XK_AudioRaiseVolume);
1456 addStandard("AudioVolumeMute", _keysym2.default.XF86XK_AudioMute);
1457 // - MicrophoneToggle
1458 // - MicrophoneVolumeDown
1459 // - MicrophoneVolumeUp
1460 addStandard("MicrophoneVolumeMute", _keysym2.default.XF86XK_AudioMicMute);
1462 // 2.13. Speech Keys
1464 // - SpeechCorrectionList
1465 // - SpeechInputToggle
1467 // 2.14. Application Keys
1469 addStandard("LaunchCalculator", _keysym2.default.XF86XK_Calculator);
1470 addStandard("LaunchCalendar", _keysym2.default.XF86XK_Calendar);
1471 addStandard("LaunchMail", _keysym2.default.XF86XK_Mail);
1472 addStandard("LaunchMediaPlayer", _keysym2.default.XF86XK_AudioMedia);
1473 addStandard("LaunchMusicPlayer", _keysym2.default.XF86XK_Music);
1474 addStandard("LaunchMyComputer", _keysym2.default.XF86XK_MyComputer);
1475 addStandard("LaunchPhone", _keysym2.default.XF86XK_Phone);
1476 addStandard("LaunchScreenSaver", _keysym2.default.XF86XK_ScreenSaver);
1477 addStandard("LaunchSpreadsheet", _keysym2.default.XF86XK_Excel);
1478 addStandard("LaunchWebBrowser", _keysym2.default.XF86XK_WWW);
1479 addStandard("LaunchWebCam", _keysym2.default.XF86XK_WebCam);
1480 addStandard("LaunchWordProcessor", _keysym2.default.XF86XK_Word);
1482 // 2.15. Browser Keys
1484 addStandard("BrowserBack", _keysym2.default.XF86XK_Back);
1485 addStandard("BrowserFavorites", _keysym2.default.XF86XK_Favorites);
1486 addStandard("BrowserForward", _keysym2.default.XF86XK_Forward);
1487 addStandard("BrowserHome", _keysym2.default.XF86XK_HomePage);
1488 addStandard("BrowserRefresh", _keysym2.default.XF86XK_Refresh);
1489 addStandard("BrowserSearch", _keysym2.default.XF86XK_Search);
1490 addStandard("BrowserStop", _keysym2.default.XF86XK_Stop);
1492 // 2.16. Mobile Phone Keys
1494 // - A whole bunch...
1498 // - A whole bunch...
1500 // 2.18. Media Controller Keys
1502 // - A whole bunch...
1503 addStandard("Dimmer", _keysym2.default.XF86XK_BrightnessAdjust);
1504 addStandard("MediaAudioTrack", _keysym2.default.XF86XK_AudioCycleTrack);
1505 addStandard("RandomToggle", _keysym2.default.XF86XK_AudioRandomPlay);
1506 addStandard("SplitScreenToggle", _keysym2.default.XF86XK_SplitScreen);
1507 addStandard("Subtitle", _keysym2.default.XF86XK_Subtitle);
1508 addStandard("VideoModeNext", _keysym2.default.XF86XK_Next_VMode);
1512 addNumpad("=", _keysym2.default.XK_equal, _keysym2.default.XK_KP_Equal);
1513 addNumpad("+", _keysym2.default.XK_plus, _keysym2.default.XK_KP_Add);
1514 addNumpad("-", _keysym2.default.XK_minus, _keysym2.default.XK_KP_Subtract);
1515 addNumpad("*", _keysym2.default.XK_asterisk, _keysym2.default.XK_KP_Multiply);
1516 addNumpad("/", _keysym2.default.XK_slash, _keysym2.default.XK_KP_Divide);
1517 addNumpad(".", _keysym2.default.XK_period, _keysym2.default.XK_KP_Decimal);
1518 addNumpad(",", _keysym2.default.XK_comma, _keysym2.default.XK_KP_Separator);
1519 addNumpad("0", _keysym2.default.XK_0, _keysym2.default.XK_KP_0);
1520 addNumpad("1", _keysym2.default.XK_1, _keysym2.default.XK_KP_1);
1521 addNumpad("2", _keysym2.default.XK_2, _keysym2.default.XK_KP_2);
1522 addNumpad("3", _keysym2.default.XK_3, _keysym2.default.XK_KP_3);
1523 addNumpad("4", _keysym2.default.XK_4, _keysym2.default.XK_KP_4);
1524 addNumpad("5", _keysym2.default.XK_5, _keysym2.default.XK_KP_5);
1525 addNumpad("6", _keysym2.default.XK_6, _keysym2.default.XK_KP_6);
1526 addNumpad("7", _keysym2.default.XK_7, _keysym2.default.XK_KP_7);
1527 addNumpad("8", _keysym2.default.XK_8, _keysym2.default.XK_KP_8);
1528 addNumpad("9", _keysym2.default.XK_9, _keysym2.default.XK_KP_9);
1530 exports.default = DOMKeyTable;
1531 },{"./keysym.js":9}],7:[function(require,module,exports){
1534 Object.defineProperty(exports, "__esModule", {
1538 * noVNC: HTML5 VNC client
1539 * Copyright (C) 2017 Pierre Ossman for Cendio AB
1540 * Licensed under MPL 2.0 or any later version (see LICENSE.txt)
1544 * Fallback mapping between HTML key codes (physical keys) and
1545 * HTML key values. This only works for keys that don't vary
1546 * between layouts. We also omit those who manage fine by mapping the
1547 * Unicode representation.
1549 * See https://www.w3.org/TR/uievents-code/ for possible codes.
1550 * See https://www.w3.org/TR/uievents-key/ for possible values.
1555 // 3.1.1.1. Writing System Keys
1557 'Backspace': 'Backspace',
1559 // 3.1.1.2. Functional Keys
1562 'AltRight': 'Alt', // This could also be 'AltGraph'
1563 'CapsLock': 'CapsLock',
1564 'ContextMenu': 'ContextMenu',
1565 'ControlLeft': 'Control',
1566 'ControlRight': 'Control',
1569 'MetaRight': 'Meta',
1570 'ShiftLeft': 'Shift',
1571 'ShiftRight': 'Shift',
1573 // FIXME: Japanese/Korean keys
1575 // 3.1.2. Control Pad Section
1582 'PageDown': 'PageDown',
1585 // 3.1.3. Arrow Pad Section
1587 'ArrowDown': 'ArrowDown',
1588 'ArrowLeft': 'ArrowLeft',
1589 'ArrowRight': 'ArrowRight',
1590 'ArrowUp': 'ArrowUp',
1592 // 3.1.4. Numpad Section
1594 'NumLock': 'NumLock',
1595 'NumpadBackspace': 'Backspace',
1596 'NumpadClear': 'Clear',
1598 // 3.1.5. Function Section
1636 'PrintScreen': 'PrintScreen',
1637 'ScrollLock': 'ScrollLock',
1640 // 3.1.6. Media Keys
1642 'BrowserBack': 'BrowserBack',
1643 'BrowserFavorites': 'BrowserFavorites',
1644 'BrowserForward': 'BrowserForward',
1645 'BrowserHome': 'BrowserHome',
1646 'BrowserRefresh': 'BrowserRefresh',
1647 'BrowserSearch': 'BrowserSearch',
1648 'BrowserStop': 'BrowserStop',
1650 'LaunchApp1': 'LaunchMyComputer',
1651 'LaunchApp2': 'LaunchCalendar',
1652 'LaunchMail': 'LaunchMail',
1653 'MediaPlayPause': 'MediaPlay',
1654 'MediaStop': 'MediaStop',
1655 'MediaTrackNext': 'MediaTrackNext',
1656 'MediaTrackPrevious': 'MediaTrackPrevious',
1659 'AudioVolumeDown': 'AudioVolumeDown',
1660 'AudioVolumeMute': 'AudioVolumeMute',
1661 'AudioVolumeUp': 'AudioVolumeUp',
1664 },{}],8:[function(require,module,exports){
1667 Object.defineProperty(exports, "__esModule", {
1670 exports.default = Keyboard;
1672 var _logging = require('../util/logging.js');
1674 var Log = _interopRequireWildcard(_logging);
1676 var _events = require('../util/events.js');
1678 var _util = require('./util.js');
1680 var KeyboardUtil = _interopRequireWildcard(_util);
1682 var _keysym = require('./keysym.js');
1684 var _keysym2 = _interopRequireDefault(_keysym);
1686 var _browser = require('../util/browser.js');
1688 var browser = _interopRequireWildcard(_browser);
1690 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
1692 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
1695 // Keyboard event handler
1698 function Keyboard(target) {
1699 this._target = target || null;
1701 this._keyDownList = {}; // List of depressed keys
1702 // (even if they are happy)
1703 this._pendingKey = null; // Key waiting for keypress
1705 // keep these here so we can refer to them later
1706 this._eventHandlers = {
1707 'keyup': this._handleKeyUp.bind(this),
1708 'keydown': this._handleKeyDown.bind(this),
1709 'keypress': this._handleKeyPress.bind(this),
1710 'blur': this._allKeysUp.bind(this)
1713 * noVNC: HTML5 VNC client
1714 * Copyright (C) 2012 Joel Martin
1715 * Copyright (C) 2013 Samuel Mannehed for Cendio AB
1716 * Licensed under MPL 2.0 or any later version (see LICENSE.txt)
1721 Keyboard.prototype = {
1722 // ===== EVENT HANDLERS =====
1724 onkeyevent: function () {}, // Handler for key press/release
1726 // ===== PRIVATE METHODS =====
1728 _sendKeyEvent: function (keysym, code, down) {
1729 Log.Debug("onkeyevent " + (down ? "down" : "up") + ", keysym: " + keysym, ", code: " + code);
1731 // Windows sends CtrlLeft+AltRight when you press
1732 // AltGraph, which tends to confuse the hell out of
1733 // remote systems. Fake a release of these keys until
1734 // there is a way to detect AltGraph properly.
1735 var fakeAltGraph = false;
1736 if (down && browser.isWindows()) {
1737 if (code !== 'ControlLeft' && code !== 'AltRight' && 'ControlLeft' in this._keyDownList && 'AltRight' in this._keyDownList) {
1738 fakeAltGraph = true;
1739 this.onkeyevent(this._keyDownList['AltRight'], 'AltRight', false);
1740 this.onkeyevent(this._keyDownList['ControlLeft'], 'ControlLeft', false);
1744 this.onkeyevent(keysym, code, down);
1747 this.onkeyevent(this._keyDownList['ControlLeft'], 'ControlLeft', true);
1748 this.onkeyevent(this._keyDownList['AltRight'], 'AltRight', true);
1752 _getKeyCode: function (e) {
1753 var code = KeyboardUtil.getKeycode(e);
1754 if (code !== 'Unidentified') {
1758 // Unstable, but we don't have anything else to go on
1759 // (don't use it for 'keypress' events thought since
1760 // WebKit sets it to the same as charCode)
1761 if (e.keyCode && e.type !== 'keypress') {
1762 // 229 is used for composition events
1763 if (e.keyCode !== 229) {
1764 return 'Platform' + e.keyCode;
1768 // A precursor to the final DOM3 standard. Unfortunately it
1769 // is not layout independent, so it is as bad as using keyCode
1770 if (e.keyIdentifier) {
1771 // Non-character key?
1772 if (e.keyIdentifier.substr(0, 2) !== 'U+') {
1773 return e.keyIdentifier;
1776 var codepoint = parseInt(e.keyIdentifier.substr(2), 16);
1777 var char = String.fromCharCode(codepoint);
1778 // Some implementations fail to uppercase the symbols
1779 char = char.toUpperCase();
1781 return 'Platform' + char.charCodeAt();
1784 return 'Unidentified';
1787 _handleKeyDown: function (e) {
1788 var code = this._getKeyCode(e);
1789 var keysym = KeyboardUtil.getKeysym(e);
1791 // We cannot handle keys we cannot track, but we also need
1792 // to deal with virtual keyboards which omit key info
1793 // (iOS omits tracking info on keyup events, which forces us to
1794 // special treat that platform here)
1795 if (code === 'Unidentified' || browser.isIOS()) {
1797 // If it's a virtual keyboard then it should be
1798 // sufficient to just send press and release right
1800 this._sendKeyEvent(keysym, code, true);
1801 this._sendKeyEvent(keysym, code, false);
1804 (0, _events.stopEvent)(e);
1808 // Alt behaves more like AltGraph on macOS, so shuffle the
1809 // keys around a bit to make things more sane for the remote
1810 // server. This method is used by RealVNC and TigerVNC (and
1811 // possibly others).
1812 if (browser.isMac()) {
1814 case _keysym2.default.XK_Super_L:
1815 keysym = _keysym2.default.XK_Alt_L;
1817 case _keysym2.default.XK_Super_R:
1818 keysym = _keysym2.default.XK_Super_L;
1820 case _keysym2.default.XK_Alt_L:
1821 keysym = _keysym2.default.XK_Mode_switch;
1823 case _keysym2.default.XK_Alt_R:
1824 keysym = _keysym2.default.XK_ISO_Level3_Shift;
1829 // Is this key already pressed? If so, then we must use the
1830 // same keysym or we'll confuse the server
1831 if (code in this._keyDownList) {
1832 keysym = this._keyDownList[code];
1835 // macOS doesn't send proper key events for modifiers, only
1836 // state change events. That gets extra confusing for CapsLock
1837 // which toggles on each press, but not on release. So pretend
1838 // it was a quick press and release of the button.
1839 if (browser.isMac() && code === 'CapsLock') {
1840 this._sendKeyEvent(_keysym2.default.XK_Caps_Lock, 'CapsLock', true);
1841 this._sendKeyEvent(_keysym2.default.XK_Caps_Lock, 'CapsLock', false);
1842 (0, _events.stopEvent)(e);
1846 // If this is a legacy browser then we'll need to wait for
1847 // a keypress event as well
1848 // (IE and Edge has a broken KeyboardEvent.key, so we can't
1849 // just check for the presence of that field)
1850 if (!keysym && (!e.key || browser.isIE() || browser.isEdge())) {
1851 this._pendingKey = code;
1852 // However we might not get a keypress event if the key
1853 // is non-printable, which needs some special fallback
1855 setTimeout(this._handleKeyPressTimeout.bind(this), 10, e);
1859 this._pendingKey = null;
1860 (0, _events.stopEvent)(e);
1862 this._keyDownList[code] = keysym;
1864 this._sendKeyEvent(keysym, code, true);
1867 // Legacy event for browsers without code/key
1868 _handleKeyPress: function (e) {
1869 (0, _events.stopEvent)(e);
1871 // Are we expecting a keypress?
1872 if (this._pendingKey === null) {
1876 var code = this._getKeyCode(e);
1877 var keysym = KeyboardUtil.getKeysym(e);
1879 // The key we were waiting for?
1880 if (code !== 'Unidentified' && code != this._pendingKey) {
1884 code = this._pendingKey;
1885 this._pendingKey = null;
1888 Log.Info('keypress with no keysym:', e);
1892 this._keyDownList[code] = keysym;
1894 this._sendKeyEvent(keysym, code, true);
1896 _handleKeyPressTimeout: function (e) {
1897 // Did someone manage to sort out the key already?
1898 if (this._pendingKey === null) {
1904 code = this._pendingKey;
1905 this._pendingKey = null;
1907 // We have no way of knowing the proper keysym with the
1908 // information given, but the following are true for most
1910 if (e.keyCode >= 0x30 && e.keyCode <= 0x39) {
1913 } else if (e.keyCode >= 0x41 && e.keyCode <= 0x5a) {
1915 var char = String.fromCharCode(e.keyCode);
1916 // A feeble attempt at the correct case
1917 if (e.shiftKey) char = char.toUpperCase();else char = char.toLowerCase();
1918 keysym = char.charCodeAt();
1924 this._keyDownList[code] = keysym;
1926 this._sendKeyEvent(keysym, code, true);
1929 _handleKeyUp: function (e) {
1930 (0, _events.stopEvent)(e);
1932 var code = this._getKeyCode(e);
1934 // See comment in _handleKeyDown()
1935 if (browser.isMac() && code === 'CapsLock') {
1936 this._sendKeyEvent(_keysym2.default.XK_Caps_Lock, 'CapsLock', true);
1937 this._sendKeyEvent(_keysym2.default.XK_Caps_Lock, 'CapsLock', false);
1941 // Do we really think this key is down?
1942 if (!(code in this._keyDownList)) {
1946 this._sendKeyEvent(this._keyDownList[code], code, false);
1948 delete this._keyDownList[code];
1951 _allKeysUp: function () {
1952 Log.Debug(">> Keyboard.allKeysUp");
1953 for (var code in this._keyDownList) {
1954 this._sendKeyEvent(this._keyDownList[code], code, false);
1956 this._keyDownList = {};
1957 Log.Debug("<< Keyboard.allKeysUp");
1960 // ===== PUBLIC METHODS =====
1963 //Log.Debug(">> Keyboard.grab");
1964 var c = this._target;
1966 c.addEventListener('keydown', this._eventHandlers.keydown);
1967 c.addEventListener('keyup', this._eventHandlers.keyup);
1968 c.addEventListener('keypress', this._eventHandlers.keypress);
1970 // Release (key up) if window loses focus
1971 window.addEventListener('blur', this._eventHandlers.blur);
1973 //Log.Debug("<< Keyboard.grab");
1976 ungrab: function () {
1977 //Log.Debug(">> Keyboard.ungrab");
1978 var c = this._target;
1980 c.removeEventListener('keydown', this._eventHandlers.keydown);
1981 c.removeEventListener('keyup', this._eventHandlers.keyup);
1982 c.removeEventListener('keypress', this._eventHandlers.keypress);
1983 window.removeEventListener('blur', this._eventHandlers.blur);
1985 // Release (key up) all keys that are in a down state
1988 //Log.Debug(">> Keyboard.ungrab");
1991 },{"../util/browser.js":16,"../util/events.js":17,"../util/logging.js":19,"./keysym.js":9,"./util.js":12}],9:[function(require,module,exports){
1994 Object.defineProperty(exports, "__esModule", {
1998 XK_VoidSymbol: 0xffffff, /* Void symbol */
2000 XK_BackSpace: 0xff08, /* Back space, back char */
2002 XK_Linefeed: 0xff0a, /* Linefeed, LF */
2004 XK_Return: 0xff0d, /* Return, enter */
2005 XK_Pause: 0xff13, /* Pause, hold */
2006 XK_Scroll_Lock: 0xff14,
2009 XK_Delete: 0xffff, /* Delete, rubout */
2011 /* International & multi-key character composition */
2013 XK_Multi_key: 0xff20, /* Multi-key character compose */
2014 XK_Codeinput: 0xff37,
2015 XK_SingleCandidate: 0xff3c,
2016 XK_MultipleCandidate: 0xff3d,
2017 XK_PreviousCandidate: 0xff3e,
2019 /* Japanese keyboard support */
2021 XK_Kanji: 0xff21, /* Kanji, Kanji convert */
2022 XK_Muhenkan: 0xff22, /* Cancel Conversion */
2023 XK_Henkan_Mode: 0xff23, /* Start/Stop Conversion */
2024 XK_Henkan: 0xff23, /* Alias for Henkan_Mode */
2025 XK_Romaji: 0xff24, /* to Romaji */
2026 XK_Hiragana: 0xff25, /* to Hiragana */
2027 XK_Katakana: 0xff26, /* to Katakana */
2028 XK_Hiragana_Katakana: 0xff27, /* Hiragana/Katakana toggle */
2029 XK_Zenkaku: 0xff28, /* to Zenkaku */
2030 XK_Hankaku: 0xff29, /* to Hankaku */
2031 XK_Zenkaku_Hankaku: 0xff2a, /* Zenkaku/Hankaku toggle */
2032 XK_Touroku: 0xff2b, /* Add to Dictionary */
2033 XK_Massyo: 0xff2c, /* Delete from Dictionary */
2034 XK_Kana_Lock: 0xff2d, /* Kana Lock */
2035 XK_Kana_Shift: 0xff2e, /* Kana Shift */
2036 XK_Eisu_Shift: 0xff2f, /* Alphanumeric Shift */
2037 XK_Eisu_toggle: 0xff30, /* Alphanumeric toggle */
2038 XK_Kanji_Bangou: 0xff37, /* Codeinput */
2039 XK_Zen_Koho: 0xff3d, /* Multiple/All Candidate(s) */
2040 XK_Mae_Koho: 0xff3e, /* Previous Candidate */
2042 /* Cursor control & motion */
2045 XK_Left: 0xff51, /* Move left, left arrow */
2046 XK_Up: 0xff52, /* Move up, up arrow */
2047 XK_Right: 0xff53, /* Move right, right arrow */
2048 XK_Down: 0xff54, /* Move down, down arrow */
2049 XK_Prior: 0xff55, /* Prior, previous */
2051 XK_Next: 0xff56, /* Next */
2052 XK_Page_Down: 0xff56,
2053 XK_End: 0xff57, /* EOL */
2054 XK_Begin: 0xff58, /* BOL */
2056 /* Misc functions */
2058 XK_Select: 0xff60, /* Select, mark */
2060 XK_Execute: 0xff62, /* Execute, run, do */
2061 XK_Insert: 0xff63, /* Insert, insert here */
2063 XK_Redo: 0xff66, /* Redo, again */
2065 XK_Find: 0xff68, /* Find, search */
2066 XK_Cancel: 0xff69, /* Cancel, stop, abort, exit */
2067 XK_Help: 0xff6a, /* Help */
2069 XK_Mode_switch: 0xff7e, /* Character set switch */
2070 XK_script_switch: 0xff7e, /* Alias for mode_switch */
2071 XK_Num_Lock: 0xff7f,
2073 /* Keypad functions, keypad numbers cleverly chosen to map to ASCII */
2075 XK_KP_Space: 0xff80, /* Space */
2077 XK_KP_Enter: 0xff8d, /* Enter */
2078 XK_KP_F1: 0xff91, /* PF1, KP_A, ... */
2085 XK_KP_Right: 0xff98,
2087 XK_KP_Prior: 0xff9a,
2088 XK_KP_Page_Up: 0xff9a,
2090 XK_KP_Page_Down: 0xff9b,
2092 XK_KP_Begin: 0xff9d,
2093 XK_KP_Insert: 0xff9e,
2094 XK_KP_Delete: 0xff9f,
2095 XK_KP_Equal: 0xffbd, /* Equals */
2096 XK_KP_Multiply: 0xffaa,
2098 XK_KP_Separator: 0xffac, /* Separator, often comma */
2099 XK_KP_Subtract: 0xffad,
2100 XK_KP_Decimal: 0xffae,
2101 XK_KP_Divide: 0xffaf,
2115 * Auxiliary functions; note the duplicate definitions for left and right
2116 * function keys; Sun keyboards and a few other manufacturers have such
2117 * function key groups on the left and/or right sides of the keyboard.
2118 * We've not found a keyboard with more than 35 function keys total.
2184 XK_Shift_L: 0xffe1, /* Left shift */
2185 XK_Shift_R: 0xffe2, /* Right shift */
2186 XK_Control_L: 0xffe3, /* Left control */
2187 XK_Control_R: 0xffe4, /* Right control */
2188 XK_Caps_Lock: 0xffe5, /* Caps lock */
2189 XK_Shift_Lock: 0xffe6, /* Shift lock */
2191 XK_Meta_L: 0xffe7, /* Left meta */
2192 XK_Meta_R: 0xffe8, /* Right meta */
2193 XK_Alt_L: 0xffe9, /* Left alt */
2194 XK_Alt_R: 0xffea, /* Right alt */
2195 XK_Super_L: 0xffeb, /* Left super */
2196 XK_Super_R: 0xffec, /* Right super */
2197 XK_Hyper_L: 0xffed, /* Left hyper */
2198 XK_Hyper_R: 0xffee, /* Right hyper */
2201 * Keyboard (XKB) Extension function and modifier keys
2202 * (from Appendix C of "The X Keyboard Extension: Protocol Specification")
2206 XK_ISO_Level3_Shift: 0xfe03, /* AltGr */
2207 XK_ISO_Next_Group: 0xfe08,
2208 XK_ISO_Prev_Group: 0xfe0a,
2209 XK_ISO_First_Group: 0xfe0c,
2210 XK_ISO_Last_Group: 0xfe0e,
2214 * (ISO/IEC 8859-1: Unicode U+0020..U+00FF)
2218 XK_space: 0x0020, /* U+0020 SPACE */
2219 XK_exclam: 0x0021, /* U+0021 EXCLAMATION MARK */
2220 XK_quotedbl: 0x0022, /* U+0022 QUOTATION MARK */
2221 XK_numbersign: 0x0023, /* U+0023 NUMBER SIGN */
2222 XK_dollar: 0x0024, /* U+0024 DOLLAR SIGN */
2223 XK_percent: 0x0025, /* U+0025 PERCENT SIGN */
2224 XK_ampersand: 0x0026, /* U+0026 AMPERSAND */
2225 XK_apostrophe: 0x0027, /* U+0027 APOSTROPHE */
2226 XK_quoteright: 0x0027, /* deprecated */
2227 XK_parenleft: 0x0028, /* U+0028 LEFT PARENTHESIS */
2228 XK_parenright: 0x0029, /* U+0029 RIGHT PARENTHESIS */
2229 XK_asterisk: 0x002a, /* U+002A ASTERISK */
2230 XK_plus: 0x002b, /* U+002B PLUS SIGN */
2231 XK_comma: 0x002c, /* U+002C COMMA */
2232 XK_minus: 0x002d, /* U+002D HYPHEN-MINUS */
2233 XK_period: 0x002e, /* U+002E FULL STOP */
2234 XK_slash: 0x002f, /* U+002F SOLIDUS */
2235 XK_0: 0x0030, /* U+0030 DIGIT ZERO */
2236 XK_1: 0x0031, /* U+0031 DIGIT ONE */
2237 XK_2: 0x0032, /* U+0032 DIGIT TWO */
2238 XK_3: 0x0033, /* U+0033 DIGIT THREE */
2239 XK_4: 0x0034, /* U+0034 DIGIT FOUR */
2240 XK_5: 0x0035, /* U+0035 DIGIT FIVE */
2241 XK_6: 0x0036, /* U+0036 DIGIT SIX */
2242 XK_7: 0x0037, /* U+0037 DIGIT SEVEN */
2243 XK_8: 0x0038, /* U+0038 DIGIT EIGHT */
2244 XK_9: 0x0039, /* U+0039 DIGIT NINE */
2245 XK_colon: 0x003a, /* U+003A COLON */
2246 XK_semicolon: 0x003b, /* U+003B SEMICOLON */
2247 XK_less: 0x003c, /* U+003C LESS-THAN SIGN */
2248 XK_equal: 0x003d, /* U+003D EQUALS SIGN */
2249 XK_greater: 0x003e, /* U+003E GREATER-THAN SIGN */
2250 XK_question: 0x003f, /* U+003F QUESTION MARK */
2251 XK_at: 0x0040, /* U+0040 COMMERCIAL AT */
2252 XK_A: 0x0041, /* U+0041 LATIN CAPITAL LETTER A */
2253 XK_B: 0x0042, /* U+0042 LATIN CAPITAL LETTER B */
2254 XK_C: 0x0043, /* U+0043 LATIN CAPITAL LETTER C */
2255 XK_D: 0x0044, /* U+0044 LATIN CAPITAL LETTER D */
2256 XK_E: 0x0045, /* U+0045 LATIN CAPITAL LETTER E */
2257 XK_F: 0x0046, /* U+0046 LATIN CAPITAL LETTER F */
2258 XK_G: 0x0047, /* U+0047 LATIN CAPITAL LETTER G */
2259 XK_H: 0x0048, /* U+0048 LATIN CAPITAL LETTER H */
2260 XK_I: 0x0049, /* U+0049 LATIN CAPITAL LETTER I */
2261 XK_J: 0x004a, /* U+004A LATIN CAPITAL LETTER J */
2262 XK_K: 0x004b, /* U+004B LATIN CAPITAL LETTER K */
2263 XK_L: 0x004c, /* U+004C LATIN CAPITAL LETTER L */
2264 XK_M: 0x004d, /* U+004D LATIN CAPITAL LETTER M */
2265 XK_N: 0x004e, /* U+004E LATIN CAPITAL LETTER N */
2266 XK_O: 0x004f, /* U+004F LATIN CAPITAL LETTER O */
2267 XK_P: 0x0050, /* U+0050 LATIN CAPITAL LETTER P */
2268 XK_Q: 0x0051, /* U+0051 LATIN CAPITAL LETTER Q */
2269 XK_R: 0x0052, /* U+0052 LATIN CAPITAL LETTER R */
2270 XK_S: 0x0053, /* U+0053 LATIN CAPITAL LETTER S */
2271 XK_T: 0x0054, /* U+0054 LATIN CAPITAL LETTER T */
2272 XK_U: 0x0055, /* U+0055 LATIN CAPITAL LETTER U */
2273 XK_V: 0x0056, /* U+0056 LATIN CAPITAL LETTER V */
2274 XK_W: 0x0057, /* U+0057 LATIN CAPITAL LETTER W */
2275 XK_X: 0x0058, /* U+0058 LATIN CAPITAL LETTER X */
2276 XK_Y: 0x0059, /* U+0059 LATIN CAPITAL LETTER Y */
2277 XK_Z: 0x005a, /* U+005A LATIN CAPITAL LETTER Z */
2278 XK_bracketleft: 0x005b, /* U+005B LEFT SQUARE BRACKET */
2279 XK_backslash: 0x005c, /* U+005C REVERSE SOLIDUS */
2280 XK_bracketright: 0x005d, /* U+005D RIGHT SQUARE BRACKET */
2281 XK_asciicircum: 0x005e, /* U+005E CIRCUMFLEX ACCENT */
2282 XK_underscore: 0x005f, /* U+005F LOW LINE */
2283 XK_grave: 0x0060, /* U+0060 GRAVE ACCENT */
2284 XK_quoteleft: 0x0060, /* deprecated */
2285 XK_a: 0x0061, /* U+0061 LATIN SMALL LETTER A */
2286 XK_b: 0x0062, /* U+0062 LATIN SMALL LETTER B */
2287 XK_c: 0x0063, /* U+0063 LATIN SMALL LETTER C */
2288 XK_d: 0x0064, /* U+0064 LATIN SMALL LETTER D */
2289 XK_e: 0x0065, /* U+0065 LATIN SMALL LETTER E */
2290 XK_f: 0x0066, /* U+0066 LATIN SMALL LETTER F */
2291 XK_g: 0x0067, /* U+0067 LATIN SMALL LETTER G */
2292 XK_h: 0x0068, /* U+0068 LATIN SMALL LETTER H */
2293 XK_i: 0x0069, /* U+0069 LATIN SMALL LETTER I */
2294 XK_j: 0x006a, /* U+006A LATIN SMALL LETTER J */
2295 XK_k: 0x006b, /* U+006B LATIN SMALL LETTER K */
2296 XK_l: 0x006c, /* U+006C LATIN SMALL LETTER L */
2297 XK_m: 0x006d, /* U+006D LATIN SMALL LETTER M */
2298 XK_n: 0x006e, /* U+006E LATIN SMALL LETTER N */
2299 XK_o: 0x006f, /* U+006F LATIN SMALL LETTER O */
2300 XK_p: 0x0070, /* U+0070 LATIN SMALL LETTER P */
2301 XK_q: 0x0071, /* U+0071 LATIN SMALL LETTER Q */
2302 XK_r: 0x0072, /* U+0072 LATIN SMALL LETTER R */
2303 XK_s: 0x0073, /* U+0073 LATIN SMALL LETTER S */
2304 XK_t: 0x0074, /* U+0074 LATIN SMALL LETTER T */
2305 XK_u: 0x0075, /* U+0075 LATIN SMALL LETTER U */
2306 XK_v: 0x0076, /* U+0076 LATIN SMALL LETTER V */
2307 XK_w: 0x0077, /* U+0077 LATIN SMALL LETTER W */
2308 XK_x: 0x0078, /* U+0078 LATIN SMALL LETTER X */
2309 XK_y: 0x0079, /* U+0079 LATIN SMALL LETTER Y */
2310 XK_z: 0x007a, /* U+007A LATIN SMALL LETTER Z */
2311 XK_braceleft: 0x007b, /* U+007B LEFT CURLY BRACKET */
2312 XK_bar: 0x007c, /* U+007C VERTICAL LINE */
2313 XK_braceright: 0x007d, /* U+007D RIGHT CURLY BRACKET */
2314 XK_asciitilde: 0x007e, /* U+007E TILDE */
2316 XK_nobreakspace: 0x00a0, /* U+00A0 NO-BREAK SPACE */
2317 XK_exclamdown: 0x00a1, /* U+00A1 INVERTED EXCLAMATION MARK */
2318 XK_cent: 0x00a2, /* U+00A2 CENT SIGN */
2319 XK_sterling: 0x00a3, /* U+00A3 POUND SIGN */
2320 XK_currency: 0x00a4, /* U+00A4 CURRENCY SIGN */
2321 XK_yen: 0x00a5, /* U+00A5 YEN SIGN */
2322 XK_brokenbar: 0x00a6, /* U+00A6 BROKEN BAR */
2323 XK_section: 0x00a7, /* U+00A7 SECTION SIGN */
2324 XK_diaeresis: 0x00a8, /* U+00A8 DIAERESIS */
2325 XK_copyright: 0x00a9, /* U+00A9 COPYRIGHT SIGN */
2326 XK_ordfeminine: 0x00aa, /* U+00AA FEMININE ORDINAL INDICATOR */
2327 XK_guillemotleft: 0x00ab, /* U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */
2328 XK_notsign: 0x00ac, /* U+00AC NOT SIGN */
2329 XK_hyphen: 0x00ad, /* U+00AD SOFT HYPHEN */
2330 XK_registered: 0x00ae, /* U+00AE REGISTERED SIGN */
2331 XK_macron: 0x00af, /* U+00AF MACRON */
2332 XK_degree: 0x00b0, /* U+00B0 DEGREE SIGN */
2333 XK_plusminus: 0x00b1, /* U+00B1 PLUS-MINUS SIGN */
2334 XK_twosuperior: 0x00b2, /* U+00B2 SUPERSCRIPT TWO */
2335 XK_threesuperior: 0x00b3, /* U+00B3 SUPERSCRIPT THREE */
2336 XK_acute: 0x00b4, /* U+00B4 ACUTE ACCENT */
2337 XK_mu: 0x00b5, /* U+00B5 MICRO SIGN */
2338 XK_paragraph: 0x00b6, /* U+00B6 PILCROW SIGN */
2339 XK_periodcentered: 0x00b7, /* U+00B7 MIDDLE DOT */
2340 XK_cedilla: 0x00b8, /* U+00B8 CEDILLA */
2341 XK_onesuperior: 0x00b9, /* U+00B9 SUPERSCRIPT ONE */
2342 XK_masculine: 0x00ba, /* U+00BA MASCULINE ORDINAL INDICATOR */
2343 XK_guillemotright: 0x00bb, /* U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */
2344 XK_onequarter: 0x00bc, /* U+00BC VULGAR FRACTION ONE QUARTER */
2345 XK_onehalf: 0x00bd, /* U+00BD VULGAR FRACTION ONE HALF */
2346 XK_threequarters: 0x00be, /* U+00BE VULGAR FRACTION THREE QUARTERS */
2347 XK_questiondown: 0x00bf, /* U+00BF INVERTED QUESTION MARK */
2348 XK_Agrave: 0x00c0, /* U+00C0 LATIN CAPITAL LETTER A WITH GRAVE */
2349 XK_Aacute: 0x00c1, /* U+00C1 LATIN CAPITAL LETTER A WITH ACUTE */
2350 XK_Acircumflex: 0x00c2, /* U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
2351 XK_Atilde: 0x00c3, /* U+00C3 LATIN CAPITAL LETTER A WITH TILDE */
2352 XK_Adiaeresis: 0x00c4, /* U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS */
2353 XK_Aring: 0x00c5, /* U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE */
2354 XK_AE: 0x00c6, /* U+00C6 LATIN CAPITAL LETTER AE */
2355 XK_Ccedilla: 0x00c7, /* U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA */
2356 XK_Egrave: 0x00c8, /* U+00C8 LATIN CAPITAL LETTER E WITH GRAVE */
2357 XK_Eacute: 0x00c9, /* U+00C9 LATIN CAPITAL LETTER E WITH ACUTE */
2358 XK_Ecircumflex: 0x00ca, /* U+00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
2359 XK_Ediaeresis: 0x00cb, /* U+00CB LATIN CAPITAL LETTER E WITH DIAERESIS */
2360 XK_Igrave: 0x00cc, /* U+00CC LATIN CAPITAL LETTER I WITH GRAVE */
2361 XK_Iacute: 0x00cd, /* U+00CD LATIN CAPITAL LETTER I WITH ACUTE */
2362 XK_Icircumflex: 0x00ce, /* U+00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
2363 XK_Idiaeresis: 0x00cf, /* U+00CF LATIN CAPITAL LETTER I WITH DIAERESIS */
2364 XK_ETH: 0x00d0, /* U+00D0 LATIN CAPITAL LETTER ETH */
2365 XK_Eth: 0x00d0, /* deprecated */
2366 XK_Ntilde: 0x00d1, /* U+00D1 LATIN CAPITAL LETTER N WITH TILDE */
2367 XK_Ograve: 0x00d2, /* U+00D2 LATIN CAPITAL LETTER O WITH GRAVE */
2368 XK_Oacute: 0x00d3, /* U+00D3 LATIN CAPITAL LETTER O WITH ACUTE */
2369 XK_Ocircumflex: 0x00d4, /* U+00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
2370 XK_Otilde: 0x00d5, /* U+00D5 LATIN CAPITAL LETTER O WITH TILDE */
2371 XK_Odiaeresis: 0x00d6, /* U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS */
2372 XK_multiply: 0x00d7, /* U+00D7 MULTIPLICATION SIGN */
2373 XK_Oslash: 0x00d8, /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */
2374 XK_Ooblique: 0x00d8, /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */
2375 XK_Ugrave: 0x00d9, /* U+00D9 LATIN CAPITAL LETTER U WITH GRAVE */
2376 XK_Uacute: 0x00da, /* U+00DA LATIN CAPITAL LETTER U WITH ACUTE */
2377 XK_Ucircumflex: 0x00db, /* U+00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
2378 XK_Udiaeresis: 0x00dc, /* U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS */
2379 XK_Yacute: 0x00dd, /* U+00DD LATIN CAPITAL LETTER Y WITH ACUTE */
2380 XK_THORN: 0x00de, /* U+00DE LATIN CAPITAL LETTER THORN */
2381 XK_Thorn: 0x00de, /* deprecated */
2382 XK_ssharp: 0x00df, /* U+00DF LATIN SMALL LETTER SHARP S */
2383 XK_agrave: 0x00e0, /* U+00E0 LATIN SMALL LETTER A WITH GRAVE */
2384 XK_aacute: 0x00e1, /* U+00E1 LATIN SMALL LETTER A WITH ACUTE */
2385 XK_acircumflex: 0x00e2, /* U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX */
2386 XK_atilde: 0x00e3, /* U+00E3 LATIN SMALL LETTER A WITH TILDE */
2387 XK_adiaeresis: 0x00e4, /* U+00E4 LATIN SMALL LETTER A WITH DIAERESIS */
2388 XK_aring: 0x00e5, /* U+00E5 LATIN SMALL LETTER A WITH RING ABOVE */
2389 XK_ae: 0x00e6, /* U+00E6 LATIN SMALL LETTER AE */
2390 XK_ccedilla: 0x00e7, /* U+00E7 LATIN SMALL LETTER C WITH CEDILLA */
2391 XK_egrave: 0x00e8, /* U+00E8 LATIN SMALL LETTER E WITH GRAVE */
2392 XK_eacute: 0x00e9, /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */
2393 XK_ecircumflex: 0x00ea, /* U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX */
2394 XK_ediaeresis: 0x00eb, /* U+00EB LATIN SMALL LETTER E WITH DIAERESIS */
2395 XK_igrave: 0x00ec, /* U+00EC LATIN SMALL LETTER I WITH GRAVE */
2396 XK_iacute: 0x00ed, /* U+00ED LATIN SMALL LETTER I WITH ACUTE */
2397 XK_icircumflex: 0x00ee, /* U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX */
2398 XK_idiaeresis: 0x00ef, /* U+00EF LATIN SMALL LETTER I WITH DIAERESIS */
2399 XK_eth: 0x00f0, /* U+00F0 LATIN SMALL LETTER ETH */
2400 XK_ntilde: 0x00f1, /* U+00F1 LATIN SMALL LETTER N WITH TILDE */
2401 XK_ograve: 0x00f2, /* U+00F2 LATIN SMALL LETTER O WITH GRAVE */
2402 XK_oacute: 0x00f3, /* U+00F3 LATIN SMALL LETTER O WITH ACUTE */
2403 XK_ocircumflex: 0x00f4, /* U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX */
2404 XK_otilde: 0x00f5, /* U+00F5 LATIN SMALL LETTER O WITH TILDE */
2405 XK_odiaeresis: 0x00f6, /* U+00F6 LATIN SMALL LETTER O WITH DIAERESIS */
2406 XK_division: 0x00f7, /* U+00F7 DIVISION SIGN */
2407 XK_oslash: 0x00f8, /* U+00F8 LATIN SMALL LETTER O WITH STROKE */
2408 XK_ooblique: 0x00f8, /* U+00F8 LATIN SMALL LETTER O WITH STROKE */
2409 XK_ugrave: 0x00f9, /* U+00F9 LATIN SMALL LETTER U WITH GRAVE */
2410 XK_uacute: 0x00fa, /* U+00FA LATIN SMALL LETTER U WITH ACUTE */
2411 XK_ucircumflex: 0x00fb, /* U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX */
2412 XK_udiaeresis: 0x00fc, /* U+00FC LATIN SMALL LETTER U WITH DIAERESIS */
2413 XK_yacute: 0x00fd, /* U+00FD LATIN SMALL LETTER Y WITH ACUTE */
2414 XK_thorn: 0x00fe, /* U+00FE LATIN SMALL LETTER THORN */
2415 XK_ydiaeresis: 0x00ff, /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */
2422 XK_Hangul: 0xff31, /* Hangul start/stop(toggle) */
2423 XK_Hangul_Hanja: 0xff34, /* Start Hangul->Hanja Conversion */
2424 XK_Hangul_Jeonja: 0xff38, /* Jeonja mode */
2427 * XFree86 vendor specific keysyms.
2429 * The XFree86 keysym range is 0x10080001 - 0x1008FFFF.
2432 XF86XK_ModeLock: 0x1008FF01,
2433 XF86XK_MonBrightnessUp: 0x1008FF02,
2434 XF86XK_MonBrightnessDown: 0x1008FF03,
2435 XF86XK_KbdLightOnOff: 0x1008FF04,
2436 XF86XK_KbdBrightnessUp: 0x1008FF05,
2437 XF86XK_KbdBrightnessDown: 0x1008FF06,
2438 XF86XK_Standby: 0x1008FF10,
2439 XF86XK_AudioLowerVolume: 0x1008FF11,
2440 XF86XK_AudioMute: 0x1008FF12,
2441 XF86XK_AudioRaiseVolume: 0x1008FF13,
2442 XF86XK_AudioPlay: 0x1008FF14,
2443 XF86XK_AudioStop: 0x1008FF15,
2444 XF86XK_AudioPrev: 0x1008FF16,
2445 XF86XK_AudioNext: 0x1008FF17,
2446 XF86XK_HomePage: 0x1008FF18,
2447 XF86XK_Mail: 0x1008FF19,
2448 XF86XK_Start: 0x1008FF1A,
2449 XF86XK_Search: 0x1008FF1B,
2450 XF86XK_AudioRecord: 0x1008FF1C,
2451 XF86XK_Calculator: 0x1008FF1D,
2452 XF86XK_Memo: 0x1008FF1E,
2453 XF86XK_ToDoList: 0x1008FF1F,
2454 XF86XK_Calendar: 0x1008FF20,
2455 XF86XK_PowerDown: 0x1008FF21,
2456 XF86XK_ContrastAdjust: 0x1008FF22,
2457 XF86XK_RockerUp: 0x1008FF23,
2458 XF86XK_RockerDown: 0x1008FF24,
2459 XF86XK_RockerEnter: 0x1008FF25,
2460 XF86XK_Back: 0x1008FF26,
2461 XF86XK_Forward: 0x1008FF27,
2462 XF86XK_Stop: 0x1008FF28,
2463 XF86XK_Refresh: 0x1008FF29,
2464 XF86XK_PowerOff: 0x1008FF2A,
2465 XF86XK_WakeUp: 0x1008FF2B,
2466 XF86XK_Eject: 0x1008FF2C,
2467 XF86XK_ScreenSaver: 0x1008FF2D,
2468 XF86XK_WWW: 0x1008FF2E,
2469 XF86XK_Sleep: 0x1008FF2F,
2470 XF86XK_Favorites: 0x1008FF30,
2471 XF86XK_AudioPause: 0x1008FF31,
2472 XF86XK_AudioMedia: 0x1008FF32,
2473 XF86XK_MyComputer: 0x1008FF33,
2474 XF86XK_VendorHome: 0x1008FF34,
2475 XF86XK_LightBulb: 0x1008FF35,
2476 XF86XK_Shop: 0x1008FF36,
2477 XF86XK_History: 0x1008FF37,
2478 XF86XK_OpenURL: 0x1008FF38,
2479 XF86XK_AddFavorite: 0x1008FF39,
2480 XF86XK_HotLinks: 0x1008FF3A,
2481 XF86XK_BrightnessAdjust: 0x1008FF3B,
2482 XF86XK_Finance: 0x1008FF3C,
2483 XF86XK_Community: 0x1008FF3D,
2484 XF86XK_AudioRewind: 0x1008FF3E,
2485 XF86XK_BackForward: 0x1008FF3F,
2486 XF86XK_Launch0: 0x1008FF40,
2487 XF86XK_Launch1: 0x1008FF41,
2488 XF86XK_Launch2: 0x1008FF42,
2489 XF86XK_Launch3: 0x1008FF43,
2490 XF86XK_Launch4: 0x1008FF44,
2491 XF86XK_Launch5: 0x1008FF45,
2492 XF86XK_Launch6: 0x1008FF46,
2493 XF86XK_Launch7: 0x1008FF47,
2494 XF86XK_Launch8: 0x1008FF48,
2495 XF86XK_Launch9: 0x1008FF49,
2496 XF86XK_LaunchA: 0x1008FF4A,
2497 XF86XK_LaunchB: 0x1008FF4B,
2498 XF86XK_LaunchC: 0x1008FF4C,
2499 XF86XK_LaunchD: 0x1008FF4D,
2500 XF86XK_LaunchE: 0x1008FF4E,
2501 XF86XK_LaunchF: 0x1008FF4F,
2502 XF86XK_ApplicationLeft: 0x1008FF50,
2503 XF86XK_ApplicationRight: 0x1008FF51,
2504 XF86XK_Book: 0x1008FF52,
2505 XF86XK_CD: 0x1008FF53,
2506 XF86XK_Calculater: 0x1008FF54,
2507 XF86XK_Clear: 0x1008FF55,
2508 XF86XK_Close: 0x1008FF56,
2509 XF86XK_Copy: 0x1008FF57,
2510 XF86XK_Cut: 0x1008FF58,
2511 XF86XK_Display: 0x1008FF59,
2512 XF86XK_DOS: 0x1008FF5A,
2513 XF86XK_Documents: 0x1008FF5B,
2514 XF86XK_Excel: 0x1008FF5C,
2515 XF86XK_Explorer: 0x1008FF5D,
2516 XF86XK_Game: 0x1008FF5E,
2517 XF86XK_Go: 0x1008FF5F,
2518 XF86XK_iTouch: 0x1008FF60,
2519 XF86XK_LogOff: 0x1008FF61,
2520 XF86XK_Market: 0x1008FF62,
2521 XF86XK_Meeting: 0x1008FF63,
2522 XF86XK_MenuKB: 0x1008FF65,
2523 XF86XK_MenuPB: 0x1008FF66,
2524 XF86XK_MySites: 0x1008FF67,
2525 XF86XK_New: 0x1008FF68,
2526 XF86XK_News: 0x1008FF69,
2527 XF86XK_OfficeHome: 0x1008FF6A,
2528 XF86XK_Open: 0x1008FF6B,
2529 XF86XK_Option: 0x1008FF6C,
2530 XF86XK_Paste: 0x1008FF6D,
2531 XF86XK_Phone: 0x1008FF6E,
2532 XF86XK_Q: 0x1008FF70,
2533 XF86XK_Reply: 0x1008FF72,
2534 XF86XK_Reload: 0x1008FF73,
2535 XF86XK_RotateWindows: 0x1008FF74,
2536 XF86XK_RotationPB: 0x1008FF75,
2537 XF86XK_RotationKB: 0x1008FF76,
2538 XF86XK_Save: 0x1008FF77,
2539 XF86XK_ScrollUp: 0x1008FF78,
2540 XF86XK_ScrollDown: 0x1008FF79,
2541 XF86XK_ScrollClick: 0x1008FF7A,
2542 XF86XK_Send: 0x1008FF7B,
2543 XF86XK_Spell: 0x1008FF7C,
2544 XF86XK_SplitScreen: 0x1008FF7D,
2545 XF86XK_Support: 0x1008FF7E,
2546 XF86XK_TaskPane: 0x1008FF7F,
2547 XF86XK_Terminal: 0x1008FF80,
2548 XF86XK_Tools: 0x1008FF81,
2549 XF86XK_Travel: 0x1008FF82,
2550 XF86XK_UserPB: 0x1008FF84,
2551 XF86XK_User1KB: 0x1008FF85,
2552 XF86XK_User2KB: 0x1008FF86,
2553 XF86XK_Video: 0x1008FF87,
2554 XF86XK_WheelButton: 0x1008FF88,
2555 XF86XK_Word: 0x1008FF89,
2556 XF86XK_Xfer: 0x1008FF8A,
2557 XF86XK_ZoomIn: 0x1008FF8B,
2558 XF86XK_ZoomOut: 0x1008FF8C,
2559 XF86XK_Away: 0x1008FF8D,
2560 XF86XK_Messenger: 0x1008FF8E,
2561 XF86XK_WebCam: 0x1008FF8F,
2562 XF86XK_MailForward: 0x1008FF90,
2563 XF86XK_Pictures: 0x1008FF91,
2564 XF86XK_Music: 0x1008FF92,
2565 XF86XK_Battery: 0x1008FF93,
2566 XF86XK_Bluetooth: 0x1008FF94,
2567 XF86XK_WLAN: 0x1008FF95,
2568 XF86XK_UWB: 0x1008FF96,
2569 XF86XK_AudioForward: 0x1008FF97,
2570 XF86XK_AudioRepeat: 0x1008FF98,
2571 XF86XK_AudioRandomPlay: 0x1008FF99,
2572 XF86XK_Subtitle: 0x1008FF9A,
2573 XF86XK_AudioCycleTrack: 0x1008FF9B,
2574 XF86XK_CycleAngle: 0x1008FF9C,
2575 XF86XK_FrameBack: 0x1008FF9D,
2576 XF86XK_FrameForward: 0x1008FF9E,
2577 XF86XK_Time: 0x1008FF9F,
2578 XF86XK_Select: 0x1008FFA0,
2579 XF86XK_View: 0x1008FFA1,
2580 XF86XK_TopMenu: 0x1008FFA2,
2581 XF86XK_Red: 0x1008FFA3,
2582 XF86XK_Green: 0x1008FFA4,
2583 XF86XK_Yellow: 0x1008FFA5,
2584 XF86XK_Blue: 0x1008FFA6,
2585 XF86XK_Suspend: 0x1008FFA7,
2586 XF86XK_Hibernate: 0x1008FFA8,
2587 XF86XK_TouchpadToggle: 0x1008FFA9,
2588 XF86XK_TouchpadOn: 0x1008FFB0,
2589 XF86XK_TouchpadOff: 0x1008FFB1,
2590 XF86XK_AudioMicMute: 0x1008FFB2,
2591 XF86XK_Switch_VT_1: 0x1008FE01,
2592 XF86XK_Switch_VT_2: 0x1008FE02,
2593 XF86XK_Switch_VT_3: 0x1008FE03,
2594 XF86XK_Switch_VT_4: 0x1008FE04,
2595 XF86XK_Switch_VT_5: 0x1008FE05,
2596 XF86XK_Switch_VT_6: 0x1008FE06,
2597 XF86XK_Switch_VT_7: 0x1008FE07,
2598 XF86XK_Switch_VT_8: 0x1008FE08,
2599 XF86XK_Switch_VT_9: 0x1008FE09,
2600 XF86XK_Switch_VT_10: 0x1008FE0A,
2601 XF86XK_Switch_VT_11: 0x1008FE0B,
2602 XF86XK_Switch_VT_12: 0x1008FE0C,
2603 XF86XK_Ungrab: 0x1008FE20,
2604 XF86XK_ClearGrab: 0x1008FE21,
2605 XF86XK_Next_VMode: 0x1008FE22,
2606 XF86XK_Prev_VMode: 0x1008FE23,
2607 XF86XK_LogWindowTree: 0x1008FE24,
2608 XF86XK_LogGrabInfo: 0x1008FE25
2610 },{}],10:[function(require,module,exports){
2613 Object.defineProperty(exports, "__esModule", {
2617 * Mapping from Unicode codepoints to X11/RFB keysyms
2619 * This file was automatically generated from keysymdef.h
2623 /* Functions at the bottom */
2626 0x0100: 0x03c0, // XK_Amacron
2627 0x0101: 0x03e0, // XK_amacron
2628 0x0102: 0x01c3, // XK_Abreve
2629 0x0103: 0x01e3, // XK_abreve
2630 0x0104: 0x01a1, // XK_Aogonek
2631 0x0105: 0x01b1, // XK_aogonek
2632 0x0106: 0x01c6, // XK_Cacute
2633 0x0107: 0x01e6, // XK_cacute
2634 0x0108: 0x02c6, // XK_Ccircumflex
2635 0x0109: 0x02e6, // XK_ccircumflex
2636 0x010a: 0x02c5, // XK_Cabovedot
2637 0x010b: 0x02e5, // XK_cabovedot
2638 0x010c: 0x01c8, // XK_Ccaron
2639 0x010d: 0x01e8, // XK_ccaron
2640 0x010e: 0x01cf, // XK_Dcaron
2641 0x010f: 0x01ef, // XK_dcaron
2642 0x0110: 0x01d0, // XK_Dstroke
2643 0x0111: 0x01f0, // XK_dstroke
2644 0x0112: 0x03aa, // XK_Emacron
2645 0x0113: 0x03ba, // XK_emacron
2646 0x0116: 0x03cc, // XK_Eabovedot
2647 0x0117: 0x03ec, // XK_eabovedot
2648 0x0118: 0x01ca, // XK_Eogonek
2649 0x0119: 0x01ea, // XK_eogonek
2650 0x011a: 0x01cc, // XK_Ecaron
2651 0x011b: 0x01ec, // XK_ecaron
2652 0x011c: 0x02d8, // XK_Gcircumflex
2653 0x011d: 0x02f8, // XK_gcircumflex
2654 0x011e: 0x02ab, // XK_Gbreve
2655 0x011f: 0x02bb, // XK_gbreve
2656 0x0120: 0x02d5, // XK_Gabovedot
2657 0x0121: 0x02f5, // XK_gabovedot
2658 0x0122: 0x03ab, // XK_Gcedilla
2659 0x0123: 0x03bb, // XK_gcedilla
2660 0x0124: 0x02a6, // XK_Hcircumflex
2661 0x0125: 0x02b6, // XK_hcircumflex
2662 0x0126: 0x02a1, // XK_Hstroke
2663 0x0127: 0x02b1, // XK_hstroke
2664 0x0128: 0x03a5, // XK_Itilde
2665 0x0129: 0x03b5, // XK_itilde
2666 0x012a: 0x03cf, // XK_Imacron
2667 0x012b: 0x03ef, // XK_imacron
2668 0x012e: 0x03c7, // XK_Iogonek
2669 0x012f: 0x03e7, // XK_iogonek
2670 0x0130: 0x02a9, // XK_Iabovedot
2671 0x0131: 0x02b9, // XK_idotless
2672 0x0134: 0x02ac, // XK_Jcircumflex
2673 0x0135: 0x02bc, // XK_jcircumflex
2674 0x0136: 0x03d3, // XK_Kcedilla
2675 0x0137: 0x03f3, // XK_kcedilla
2676 0x0138: 0x03a2, // XK_kra
2677 0x0139: 0x01c5, // XK_Lacute
2678 0x013a: 0x01e5, // XK_lacute
2679 0x013b: 0x03a6, // XK_Lcedilla
2680 0x013c: 0x03b6, // XK_lcedilla
2681 0x013d: 0x01a5, // XK_Lcaron
2682 0x013e: 0x01b5, // XK_lcaron
2683 0x0141: 0x01a3, // XK_Lstroke
2684 0x0142: 0x01b3, // XK_lstroke
2685 0x0143: 0x01d1, // XK_Nacute
2686 0x0144: 0x01f1, // XK_nacute
2687 0x0145: 0x03d1, // XK_Ncedilla
2688 0x0146: 0x03f1, // XK_ncedilla
2689 0x0147: 0x01d2, // XK_Ncaron
2690 0x0148: 0x01f2, // XK_ncaron
2691 0x014a: 0x03bd, // XK_ENG
2692 0x014b: 0x03bf, // XK_eng
2693 0x014c: 0x03d2, // XK_Omacron
2694 0x014d: 0x03f2, // XK_omacron
2695 0x0150: 0x01d5, // XK_Odoubleacute
2696 0x0151: 0x01f5, // XK_odoubleacute
2697 0x0152: 0x13bc, // XK_OE
2698 0x0153: 0x13bd, // XK_oe
2699 0x0154: 0x01c0, // XK_Racute
2700 0x0155: 0x01e0, // XK_racute
2701 0x0156: 0x03a3, // XK_Rcedilla
2702 0x0157: 0x03b3, // XK_rcedilla
2703 0x0158: 0x01d8, // XK_Rcaron
2704 0x0159: 0x01f8, // XK_rcaron
2705 0x015a: 0x01a6, // XK_Sacute
2706 0x015b: 0x01b6, // XK_sacute
2707 0x015c: 0x02de, // XK_Scircumflex
2708 0x015d: 0x02fe, // XK_scircumflex
2709 0x015e: 0x01aa, // XK_Scedilla
2710 0x015f: 0x01ba, // XK_scedilla
2711 0x0160: 0x01a9, // XK_Scaron
2712 0x0161: 0x01b9, // XK_scaron
2713 0x0162: 0x01de, // XK_Tcedilla
2714 0x0163: 0x01fe, // XK_tcedilla
2715 0x0164: 0x01ab, // XK_Tcaron
2716 0x0165: 0x01bb, // XK_tcaron
2717 0x0166: 0x03ac, // XK_Tslash
2718 0x0167: 0x03bc, // XK_tslash
2719 0x0168: 0x03dd, // XK_Utilde
2720 0x0169: 0x03fd, // XK_utilde
2721 0x016a: 0x03de, // XK_Umacron
2722 0x016b: 0x03fe, // XK_umacron
2723 0x016c: 0x02dd, // XK_Ubreve
2724 0x016d: 0x02fd, // XK_ubreve
2725 0x016e: 0x01d9, // XK_Uring
2726 0x016f: 0x01f9, // XK_uring
2727 0x0170: 0x01db, // XK_Udoubleacute
2728 0x0171: 0x01fb, // XK_udoubleacute
2729 0x0172: 0x03d9, // XK_Uogonek
2730 0x0173: 0x03f9, // XK_uogonek
2731 0x0178: 0x13be, // XK_Ydiaeresis
2732 0x0179: 0x01ac, // XK_Zacute
2733 0x017a: 0x01bc, // XK_zacute
2734 0x017b: 0x01af, // XK_Zabovedot
2735 0x017c: 0x01bf, // XK_zabovedot
2736 0x017d: 0x01ae, // XK_Zcaron
2737 0x017e: 0x01be, // XK_zcaron
2738 0x0192: 0x08f6, // XK_function
2739 0x01d2: 0x10001d1, // XK_Ocaron
2740 0x02c7: 0x01b7, // XK_caron
2741 0x02d8: 0x01a2, // XK_breve
2742 0x02d9: 0x01ff, // XK_abovedot
2743 0x02db: 0x01b2, // XK_ogonek
2744 0x02dd: 0x01bd, // XK_doubleacute
2745 0x0385: 0x07ae, // XK_Greek_accentdieresis
2746 0x0386: 0x07a1, // XK_Greek_ALPHAaccent
2747 0x0388: 0x07a2, // XK_Greek_EPSILONaccent
2748 0x0389: 0x07a3, // XK_Greek_ETAaccent
2749 0x038a: 0x07a4, // XK_Greek_IOTAaccent
2750 0x038c: 0x07a7, // XK_Greek_OMICRONaccent
2751 0x038e: 0x07a8, // XK_Greek_UPSILONaccent
2752 0x038f: 0x07ab, // XK_Greek_OMEGAaccent
2753 0x0390: 0x07b6, // XK_Greek_iotaaccentdieresis
2754 0x0391: 0x07c1, // XK_Greek_ALPHA
2755 0x0392: 0x07c2, // XK_Greek_BETA
2756 0x0393: 0x07c3, // XK_Greek_GAMMA
2757 0x0394: 0x07c4, // XK_Greek_DELTA
2758 0x0395: 0x07c5, // XK_Greek_EPSILON
2759 0x0396: 0x07c6, // XK_Greek_ZETA
2760 0x0397: 0x07c7, // XK_Greek_ETA
2761 0x0398: 0x07c8, // XK_Greek_THETA
2762 0x0399: 0x07c9, // XK_Greek_IOTA
2763 0x039a: 0x07ca, // XK_Greek_KAPPA
2764 0x039b: 0x07cb, // XK_Greek_LAMDA
2765 0x039c: 0x07cc, // XK_Greek_MU
2766 0x039d: 0x07cd, // XK_Greek_NU
2767 0x039e: 0x07ce, // XK_Greek_XI
2768 0x039f: 0x07cf, // XK_Greek_OMICRON
2769 0x03a0: 0x07d0, // XK_Greek_PI
2770 0x03a1: 0x07d1, // XK_Greek_RHO
2771 0x03a3: 0x07d2, // XK_Greek_SIGMA
2772 0x03a4: 0x07d4, // XK_Greek_TAU
2773 0x03a5: 0x07d5, // XK_Greek_UPSILON
2774 0x03a6: 0x07d6, // XK_Greek_PHI
2775 0x03a7: 0x07d7, // XK_Greek_CHI
2776 0x03a8: 0x07d8, // XK_Greek_PSI
2777 0x03a9: 0x07d9, // XK_Greek_OMEGA
2778 0x03aa: 0x07a5, // XK_Greek_IOTAdieresis
2779 0x03ab: 0x07a9, // XK_Greek_UPSILONdieresis
2780 0x03ac: 0x07b1, // XK_Greek_alphaaccent
2781 0x03ad: 0x07b2, // XK_Greek_epsilonaccent
2782 0x03ae: 0x07b3, // XK_Greek_etaaccent
2783 0x03af: 0x07b4, // XK_Greek_iotaaccent
2784 0x03b0: 0x07ba, // XK_Greek_upsilonaccentdieresis
2785 0x03b1: 0x07e1, // XK_Greek_alpha
2786 0x03b2: 0x07e2, // XK_Greek_beta
2787 0x03b3: 0x07e3, // XK_Greek_gamma
2788 0x03b4: 0x07e4, // XK_Greek_delta
2789 0x03b5: 0x07e5, // XK_Greek_epsilon
2790 0x03b6: 0x07e6, // XK_Greek_zeta
2791 0x03b7: 0x07e7, // XK_Greek_eta
2792 0x03b8: 0x07e8, // XK_Greek_theta
2793 0x03b9: 0x07e9, // XK_Greek_iota
2794 0x03ba: 0x07ea, // XK_Greek_kappa
2795 0x03bb: 0x07eb, // XK_Greek_lamda
2796 0x03bc: 0x07ec, // XK_Greek_mu
2797 0x03bd: 0x07ed, // XK_Greek_nu
2798 0x03be: 0x07ee, // XK_Greek_xi
2799 0x03bf: 0x07ef, // XK_Greek_omicron
2800 0x03c0: 0x07f0, // XK_Greek_pi
2801 0x03c1: 0x07f1, // XK_Greek_rho
2802 0x03c2: 0x07f3, // XK_Greek_finalsmallsigma
2803 0x03c3: 0x07f2, // XK_Greek_sigma
2804 0x03c4: 0x07f4, // XK_Greek_tau
2805 0x03c5: 0x07f5, // XK_Greek_upsilon
2806 0x03c6: 0x07f6, // XK_Greek_phi
2807 0x03c7: 0x07f7, // XK_Greek_chi
2808 0x03c8: 0x07f8, // XK_Greek_psi
2809 0x03c9: 0x07f9, // XK_Greek_omega
2810 0x03ca: 0x07b5, // XK_Greek_iotadieresis
2811 0x03cb: 0x07b9, // XK_Greek_upsilondieresis
2812 0x03cc: 0x07b7, // XK_Greek_omicronaccent
2813 0x03cd: 0x07b8, // XK_Greek_upsilonaccent
2814 0x03ce: 0x07bb, // XK_Greek_omegaaccent
2815 0x0401: 0x06b3, // XK_Cyrillic_IO
2816 0x0402: 0x06b1, // XK_Serbian_DJE
2817 0x0403: 0x06b2, // XK_Macedonia_GJE
2818 0x0404: 0x06b4, // XK_Ukrainian_IE
2819 0x0405: 0x06b5, // XK_Macedonia_DSE
2820 0x0406: 0x06b6, // XK_Ukrainian_I
2821 0x0407: 0x06b7, // XK_Ukrainian_YI
2822 0x0408: 0x06b8, // XK_Cyrillic_JE
2823 0x0409: 0x06b9, // XK_Cyrillic_LJE
2824 0x040a: 0x06ba, // XK_Cyrillic_NJE
2825 0x040b: 0x06bb, // XK_Serbian_TSHE
2826 0x040c: 0x06bc, // XK_Macedonia_KJE
2827 0x040e: 0x06be, // XK_Byelorussian_SHORTU
2828 0x040f: 0x06bf, // XK_Cyrillic_DZHE
2829 0x0410: 0x06e1, // XK_Cyrillic_A
2830 0x0411: 0x06e2, // XK_Cyrillic_BE
2831 0x0412: 0x06f7, // XK_Cyrillic_VE
2832 0x0413: 0x06e7, // XK_Cyrillic_GHE
2833 0x0414: 0x06e4, // XK_Cyrillic_DE
2834 0x0415: 0x06e5, // XK_Cyrillic_IE
2835 0x0416: 0x06f6, // XK_Cyrillic_ZHE
2836 0x0417: 0x06fa, // XK_Cyrillic_ZE
2837 0x0418: 0x06e9, // XK_Cyrillic_I
2838 0x0419: 0x06ea, // XK_Cyrillic_SHORTI
2839 0x041a: 0x06eb, // XK_Cyrillic_KA
2840 0x041b: 0x06ec, // XK_Cyrillic_EL
2841 0x041c: 0x06ed, // XK_Cyrillic_EM
2842 0x041d: 0x06ee, // XK_Cyrillic_EN
2843 0x041e: 0x06ef, // XK_Cyrillic_O
2844 0x041f: 0x06f0, // XK_Cyrillic_PE
2845 0x0420: 0x06f2, // XK_Cyrillic_ER
2846 0x0421: 0x06f3, // XK_Cyrillic_ES
2847 0x0422: 0x06f4, // XK_Cyrillic_TE
2848 0x0423: 0x06f5, // XK_Cyrillic_U
2849 0x0424: 0x06e6, // XK_Cyrillic_EF
2850 0x0425: 0x06e8, // XK_Cyrillic_HA
2851 0x0426: 0x06e3, // XK_Cyrillic_TSE
2852 0x0427: 0x06fe, // XK_Cyrillic_CHE
2853 0x0428: 0x06fb, // XK_Cyrillic_SHA
2854 0x0429: 0x06fd, // XK_Cyrillic_SHCHA
2855 0x042a: 0x06ff, // XK_Cyrillic_HARDSIGN
2856 0x042b: 0x06f9, // XK_Cyrillic_YERU
2857 0x042c: 0x06f8, // XK_Cyrillic_SOFTSIGN
2858 0x042d: 0x06fc, // XK_Cyrillic_E
2859 0x042e: 0x06e0, // XK_Cyrillic_YU
2860 0x042f: 0x06f1, // XK_Cyrillic_YA
2861 0x0430: 0x06c1, // XK_Cyrillic_a
2862 0x0431: 0x06c2, // XK_Cyrillic_be
2863 0x0432: 0x06d7, // XK_Cyrillic_ve
2864 0x0433: 0x06c7, // XK_Cyrillic_ghe
2865 0x0434: 0x06c4, // XK_Cyrillic_de
2866 0x0435: 0x06c5, // XK_Cyrillic_ie
2867 0x0436: 0x06d6, // XK_Cyrillic_zhe
2868 0x0437: 0x06da, // XK_Cyrillic_ze
2869 0x0438: 0x06c9, // XK_Cyrillic_i
2870 0x0439: 0x06ca, // XK_Cyrillic_shorti
2871 0x043a: 0x06cb, // XK_Cyrillic_ka
2872 0x043b: 0x06cc, // XK_Cyrillic_el
2873 0x043c: 0x06cd, // XK_Cyrillic_em
2874 0x043d: 0x06ce, // XK_Cyrillic_en
2875 0x043e: 0x06cf, // XK_Cyrillic_o
2876 0x043f: 0x06d0, // XK_Cyrillic_pe
2877 0x0440: 0x06d2, // XK_Cyrillic_er
2878 0x0441: 0x06d3, // XK_Cyrillic_es
2879 0x0442: 0x06d4, // XK_Cyrillic_te
2880 0x0443: 0x06d5, // XK_Cyrillic_u
2881 0x0444: 0x06c6, // XK_Cyrillic_ef
2882 0x0445: 0x06c8, // XK_Cyrillic_ha
2883 0x0446: 0x06c3, // XK_Cyrillic_tse
2884 0x0447: 0x06de, // XK_Cyrillic_che
2885 0x0448: 0x06db, // XK_Cyrillic_sha
2886 0x0449: 0x06dd, // XK_Cyrillic_shcha
2887 0x044a: 0x06df, // XK_Cyrillic_hardsign
2888 0x044b: 0x06d9, // XK_Cyrillic_yeru
2889 0x044c: 0x06d8, // XK_Cyrillic_softsign
2890 0x044d: 0x06dc, // XK_Cyrillic_e
2891 0x044e: 0x06c0, // XK_Cyrillic_yu
2892 0x044f: 0x06d1, // XK_Cyrillic_ya
2893 0x0451: 0x06a3, // XK_Cyrillic_io
2894 0x0452: 0x06a1, // XK_Serbian_dje
2895 0x0453: 0x06a2, // XK_Macedonia_gje
2896 0x0454: 0x06a4, // XK_Ukrainian_ie
2897 0x0455: 0x06a5, // XK_Macedonia_dse
2898 0x0456: 0x06a6, // XK_Ukrainian_i
2899 0x0457: 0x06a7, // XK_Ukrainian_yi
2900 0x0458: 0x06a8, // XK_Cyrillic_je
2901 0x0459: 0x06a9, // XK_Cyrillic_lje
2902 0x045a: 0x06aa, // XK_Cyrillic_nje
2903 0x045b: 0x06ab, // XK_Serbian_tshe
2904 0x045c: 0x06ac, // XK_Macedonia_kje
2905 0x045e: 0x06ae, // XK_Byelorussian_shortu
2906 0x045f: 0x06af, // XK_Cyrillic_dzhe
2907 0x0490: 0x06bd, // XK_Ukrainian_GHE_WITH_UPTURN
2908 0x0491: 0x06ad, // XK_Ukrainian_ghe_with_upturn
2909 0x05d0: 0x0ce0, // XK_hebrew_aleph
2910 0x05d1: 0x0ce1, // XK_hebrew_bet
2911 0x05d2: 0x0ce2, // XK_hebrew_gimel
2912 0x05d3: 0x0ce3, // XK_hebrew_dalet
2913 0x05d4: 0x0ce4, // XK_hebrew_he
2914 0x05d5: 0x0ce5, // XK_hebrew_waw
2915 0x05d6: 0x0ce6, // XK_hebrew_zain
2916 0x05d7: 0x0ce7, // XK_hebrew_chet
2917 0x05d8: 0x0ce8, // XK_hebrew_tet
2918 0x05d9: 0x0ce9, // XK_hebrew_yod
2919 0x05da: 0x0cea, // XK_hebrew_finalkaph
2920 0x05db: 0x0ceb, // XK_hebrew_kaph
2921 0x05dc: 0x0cec, // XK_hebrew_lamed
2922 0x05dd: 0x0ced, // XK_hebrew_finalmem
2923 0x05de: 0x0cee, // XK_hebrew_mem
2924 0x05df: 0x0cef, // XK_hebrew_finalnun
2925 0x05e0: 0x0cf0, // XK_hebrew_nun
2926 0x05e1: 0x0cf1, // XK_hebrew_samech
2927 0x05e2: 0x0cf2, // XK_hebrew_ayin
2928 0x05e3: 0x0cf3, // XK_hebrew_finalpe
2929 0x05e4: 0x0cf4, // XK_hebrew_pe
2930 0x05e5: 0x0cf5, // XK_hebrew_finalzade
2931 0x05e6: 0x0cf6, // XK_hebrew_zade
2932 0x05e7: 0x0cf7, // XK_hebrew_qoph
2933 0x05e8: 0x0cf8, // XK_hebrew_resh
2934 0x05e9: 0x0cf9, // XK_hebrew_shin
2935 0x05ea: 0x0cfa, // XK_hebrew_taw
2936 0x060c: 0x05ac, // XK_Arabic_comma
2937 0x061b: 0x05bb, // XK_Arabic_semicolon
2938 0x061f: 0x05bf, // XK_Arabic_question_mark
2939 0x0621: 0x05c1, // XK_Arabic_hamza
2940 0x0622: 0x05c2, // XK_Arabic_maddaonalef
2941 0x0623: 0x05c3, // XK_Arabic_hamzaonalef
2942 0x0624: 0x05c4, // XK_Arabic_hamzaonwaw
2943 0x0625: 0x05c5, // XK_Arabic_hamzaunderalef
2944 0x0626: 0x05c6, // XK_Arabic_hamzaonyeh
2945 0x0627: 0x05c7, // XK_Arabic_alef
2946 0x0628: 0x05c8, // XK_Arabic_beh
2947 0x0629: 0x05c9, // XK_Arabic_tehmarbuta
2948 0x062a: 0x05ca, // XK_Arabic_teh
2949 0x062b: 0x05cb, // XK_Arabic_theh
2950 0x062c: 0x05cc, // XK_Arabic_jeem
2951 0x062d: 0x05cd, // XK_Arabic_hah
2952 0x062e: 0x05ce, // XK_Arabic_khah
2953 0x062f: 0x05cf, // XK_Arabic_dal
2954 0x0630: 0x05d0, // XK_Arabic_thal
2955 0x0631: 0x05d1, // XK_Arabic_ra
2956 0x0632: 0x05d2, // XK_Arabic_zain
2957 0x0633: 0x05d3, // XK_Arabic_seen
2958 0x0634: 0x05d4, // XK_Arabic_sheen
2959 0x0635: 0x05d5, // XK_Arabic_sad
2960 0x0636: 0x05d6, // XK_Arabic_dad
2961 0x0637: 0x05d7, // XK_Arabic_tah
2962 0x0638: 0x05d8, // XK_Arabic_zah
2963 0x0639: 0x05d9, // XK_Arabic_ain
2964 0x063a: 0x05da, // XK_Arabic_ghain
2965 0x0640: 0x05e0, // XK_Arabic_tatweel
2966 0x0641: 0x05e1, // XK_Arabic_feh
2967 0x0642: 0x05e2, // XK_Arabic_qaf
2968 0x0643: 0x05e3, // XK_Arabic_kaf
2969 0x0644: 0x05e4, // XK_Arabic_lam
2970 0x0645: 0x05e5, // XK_Arabic_meem
2971 0x0646: 0x05e6, // XK_Arabic_noon
2972 0x0647: 0x05e7, // XK_Arabic_ha
2973 0x0648: 0x05e8, // XK_Arabic_waw
2974 0x0649: 0x05e9, // XK_Arabic_alefmaksura
2975 0x064a: 0x05ea, // XK_Arabic_yeh
2976 0x064b: 0x05eb, // XK_Arabic_fathatan
2977 0x064c: 0x05ec, // XK_Arabic_dammatan
2978 0x064d: 0x05ed, // XK_Arabic_kasratan
2979 0x064e: 0x05ee, // XK_Arabic_fatha
2980 0x064f: 0x05ef, // XK_Arabic_damma
2981 0x0650: 0x05f0, // XK_Arabic_kasra
2982 0x0651: 0x05f1, // XK_Arabic_shadda
2983 0x0652: 0x05f2, // XK_Arabic_sukun
2984 0x0e01: 0x0da1, // XK_Thai_kokai
2985 0x0e02: 0x0da2, // XK_Thai_khokhai
2986 0x0e03: 0x0da3, // XK_Thai_khokhuat
2987 0x0e04: 0x0da4, // XK_Thai_khokhwai
2988 0x0e05: 0x0da5, // XK_Thai_khokhon
2989 0x0e06: 0x0da6, // XK_Thai_khorakhang
2990 0x0e07: 0x0da7, // XK_Thai_ngongu
2991 0x0e08: 0x0da8, // XK_Thai_chochan
2992 0x0e09: 0x0da9, // XK_Thai_choching
2993 0x0e0a: 0x0daa, // XK_Thai_chochang
2994 0x0e0b: 0x0dab, // XK_Thai_soso
2995 0x0e0c: 0x0dac, // XK_Thai_chochoe
2996 0x0e0d: 0x0dad, // XK_Thai_yoying
2997 0x0e0e: 0x0dae, // XK_Thai_dochada
2998 0x0e0f: 0x0daf, // XK_Thai_topatak
2999 0x0e10: 0x0db0, // XK_Thai_thothan
3000 0x0e11: 0x0db1, // XK_Thai_thonangmontho
3001 0x0e12: 0x0db2, // XK_Thai_thophuthao
3002 0x0e13: 0x0db3, // XK_Thai_nonen
3003 0x0e14: 0x0db4, // XK_Thai_dodek
3004 0x0e15: 0x0db5, // XK_Thai_totao
3005 0x0e16: 0x0db6, // XK_Thai_thothung
3006 0x0e17: 0x0db7, // XK_Thai_thothahan
3007 0x0e18: 0x0db8, // XK_Thai_thothong
3008 0x0e19: 0x0db9, // XK_Thai_nonu
3009 0x0e1a: 0x0dba, // XK_Thai_bobaimai
3010 0x0e1b: 0x0dbb, // XK_Thai_popla
3011 0x0e1c: 0x0dbc, // XK_Thai_phophung
3012 0x0e1d: 0x0dbd, // XK_Thai_fofa
3013 0x0e1e: 0x0dbe, // XK_Thai_phophan
3014 0x0e1f: 0x0dbf, // XK_Thai_fofan
3015 0x0e20: 0x0dc0, // XK_Thai_phosamphao
3016 0x0e21: 0x0dc1, // XK_Thai_moma
3017 0x0e22: 0x0dc2, // XK_Thai_yoyak
3018 0x0e23: 0x0dc3, // XK_Thai_rorua
3019 0x0e24: 0x0dc4, // XK_Thai_ru
3020 0x0e25: 0x0dc5, // XK_Thai_loling
3021 0x0e26: 0x0dc6, // XK_Thai_lu
3022 0x0e27: 0x0dc7, // XK_Thai_wowaen
3023 0x0e28: 0x0dc8, // XK_Thai_sosala
3024 0x0e29: 0x0dc9, // XK_Thai_sorusi
3025 0x0e2a: 0x0dca, // XK_Thai_sosua
3026 0x0e2b: 0x0dcb, // XK_Thai_hohip
3027 0x0e2c: 0x0dcc, // XK_Thai_lochula
3028 0x0e2d: 0x0dcd, // XK_Thai_oang
3029 0x0e2e: 0x0dce, // XK_Thai_honokhuk
3030 0x0e2f: 0x0dcf, // XK_Thai_paiyannoi
3031 0x0e30: 0x0dd0, // XK_Thai_saraa
3032 0x0e31: 0x0dd1, // XK_Thai_maihanakat
3033 0x0e32: 0x0dd2, // XK_Thai_saraaa
3034 0x0e33: 0x0dd3, // XK_Thai_saraam
3035 0x0e34: 0x0dd4, // XK_Thai_sarai
3036 0x0e35: 0x0dd5, // XK_Thai_saraii
3037 0x0e36: 0x0dd6, // XK_Thai_saraue
3038 0x0e37: 0x0dd7, // XK_Thai_sarauee
3039 0x0e38: 0x0dd8, // XK_Thai_sarau
3040 0x0e39: 0x0dd9, // XK_Thai_sarauu
3041 0x0e3a: 0x0dda, // XK_Thai_phinthu
3042 0x0e3f: 0x0ddf, // XK_Thai_baht
3043 0x0e40: 0x0de0, // XK_Thai_sarae
3044 0x0e41: 0x0de1, // XK_Thai_saraae
3045 0x0e42: 0x0de2, // XK_Thai_sarao
3046 0x0e43: 0x0de3, // XK_Thai_saraaimaimuan
3047 0x0e44: 0x0de4, // XK_Thai_saraaimaimalai
3048 0x0e45: 0x0de5, // XK_Thai_lakkhangyao
3049 0x0e46: 0x0de6, // XK_Thai_maiyamok
3050 0x0e47: 0x0de7, // XK_Thai_maitaikhu
3051 0x0e48: 0x0de8, // XK_Thai_maiek
3052 0x0e49: 0x0de9, // XK_Thai_maitho
3053 0x0e4a: 0x0dea, // XK_Thai_maitri
3054 0x0e4b: 0x0deb, // XK_Thai_maichattawa
3055 0x0e4c: 0x0dec, // XK_Thai_thanthakhat
3056 0x0e4d: 0x0ded, // XK_Thai_nikhahit
3057 0x0e50: 0x0df0, // XK_Thai_leksun
3058 0x0e51: 0x0df1, // XK_Thai_leknung
3059 0x0e52: 0x0df2, // XK_Thai_leksong
3060 0x0e53: 0x0df3, // XK_Thai_leksam
3061 0x0e54: 0x0df4, // XK_Thai_leksi
3062 0x0e55: 0x0df5, // XK_Thai_lekha
3063 0x0e56: 0x0df6, // XK_Thai_lekhok
3064 0x0e57: 0x0df7, // XK_Thai_lekchet
3065 0x0e58: 0x0df8, // XK_Thai_lekpaet
3066 0x0e59: 0x0df9, // XK_Thai_lekkao
3067 0x2002: 0x0aa2, // XK_enspace
3068 0x2003: 0x0aa1, // XK_emspace
3069 0x2004: 0x0aa3, // XK_em3space
3070 0x2005: 0x0aa4, // XK_em4space
3071 0x2007: 0x0aa5, // XK_digitspace
3072 0x2008: 0x0aa6, // XK_punctspace
3073 0x2009: 0x0aa7, // XK_thinspace
3074 0x200a: 0x0aa8, // XK_hairspace
3075 0x2012: 0x0abb, // XK_figdash
3076 0x2013: 0x0aaa, // XK_endash
3077 0x2014: 0x0aa9, // XK_emdash
3078 0x2015: 0x07af, // XK_Greek_horizbar
3079 0x2017: 0x0cdf, // XK_hebrew_doublelowline
3080 0x2018: 0x0ad0, // XK_leftsinglequotemark
3081 0x2019: 0x0ad1, // XK_rightsinglequotemark
3082 0x201a: 0x0afd, // XK_singlelowquotemark
3083 0x201c: 0x0ad2, // XK_leftdoublequotemark
3084 0x201d: 0x0ad3, // XK_rightdoublequotemark
3085 0x201e: 0x0afe, // XK_doublelowquotemark
3086 0x2020: 0x0af1, // XK_dagger
3087 0x2021: 0x0af2, // XK_doubledagger
3088 0x2022: 0x0ae6, // XK_enfilledcircbullet
3089 0x2025: 0x0aaf, // XK_doubbaselinedot
3090 0x2026: 0x0aae, // XK_ellipsis
3091 0x2030: 0x0ad5, // XK_permille
3092 0x2032: 0x0ad6, // XK_minutes
3093 0x2033: 0x0ad7, // XK_seconds
3094 0x2038: 0x0afc, // XK_caret
3095 0x203e: 0x047e, // XK_overline
3096 0x20a9: 0x0eff, // XK_Korean_Won
3097 0x20ac: 0x20ac, // XK_EuroSign
3098 0x2105: 0x0ab8, // XK_careof
3099 0x2116: 0x06b0, // XK_numerosign
3100 0x2117: 0x0afb, // XK_phonographcopyright
3101 0x211e: 0x0ad4, // XK_prescription
3102 0x2122: 0x0ac9, // XK_trademark
3103 0x2153: 0x0ab0, // XK_onethird
3104 0x2154: 0x0ab1, // XK_twothirds
3105 0x2155: 0x0ab2, // XK_onefifth
3106 0x2156: 0x0ab3, // XK_twofifths
3107 0x2157: 0x0ab4, // XK_threefifths
3108 0x2158: 0x0ab5, // XK_fourfifths
3109 0x2159: 0x0ab6, // XK_onesixth
3110 0x215a: 0x0ab7, // XK_fivesixths
3111 0x215b: 0x0ac3, // XK_oneeighth
3112 0x215c: 0x0ac4, // XK_threeeighths
3113 0x215d: 0x0ac5, // XK_fiveeighths
3114 0x215e: 0x0ac6, // XK_seveneighths
3115 0x2190: 0x08fb, // XK_leftarrow
3116 0x2191: 0x08fc, // XK_uparrow
3117 0x2192: 0x08fd, // XK_rightarrow
3118 0x2193: 0x08fe, // XK_downarrow
3119 0x21d2: 0x08ce, // XK_implies
3120 0x21d4: 0x08cd, // XK_ifonlyif
3121 0x2202: 0x08ef, // XK_partialderivative
3122 0x2207: 0x08c5, // XK_nabla
3123 0x2218: 0x0bca, // XK_jot
3124 0x221a: 0x08d6, // XK_radical
3125 0x221d: 0x08c1, // XK_variation
3126 0x221e: 0x08c2, // XK_infinity
3127 0x2227: 0x08de, // XK_logicaland
3128 0x2228: 0x08df, // XK_logicalor
3129 0x2229: 0x08dc, // XK_intersection
3130 0x222a: 0x08dd, // XK_union
3131 0x222b: 0x08bf, // XK_integral
3132 0x2234: 0x08c0, // XK_therefore
3133 0x223c: 0x08c8, // XK_approximate
3134 0x2243: 0x08c9, // XK_similarequal
3135 0x2245: 0x1002248, // XK_approxeq
3136 0x2260: 0x08bd, // XK_notequal
3137 0x2261: 0x08cf, // XK_identical
3138 0x2264: 0x08bc, // XK_lessthanequal
3139 0x2265: 0x08be, // XK_greaterthanequal
3140 0x2282: 0x08da, // XK_includedin
3141 0x2283: 0x08db, // XK_includes
3142 0x22a2: 0x0bfc, // XK_righttack
3143 0x22a3: 0x0bdc, // XK_lefttack
3144 0x22a4: 0x0bc2, // XK_downtack
3145 0x22a5: 0x0bce, // XK_uptack
3146 0x2308: 0x0bd3, // XK_upstile
3147 0x230a: 0x0bc4, // XK_downstile
3148 0x2315: 0x0afa, // XK_telephonerecorder
3149 0x2320: 0x08a4, // XK_topintegral
3150 0x2321: 0x08a5, // XK_botintegral
3151 0x2395: 0x0bcc, // XK_quad
3152 0x239b: 0x08ab, // XK_topleftparens
3153 0x239d: 0x08ac, // XK_botleftparens
3154 0x239e: 0x08ad, // XK_toprightparens
3155 0x23a0: 0x08ae, // XK_botrightparens
3156 0x23a1: 0x08a7, // XK_topleftsqbracket
3157 0x23a3: 0x08a8, // XK_botleftsqbracket
3158 0x23a4: 0x08a9, // XK_toprightsqbracket
3159 0x23a6: 0x08aa, // XK_botrightsqbracket
3160 0x23a8: 0x08af, // XK_leftmiddlecurlybrace
3161 0x23ac: 0x08b0, // XK_rightmiddlecurlybrace
3162 0x23b7: 0x08a1, // XK_leftradical
3163 0x23ba: 0x09ef, // XK_horizlinescan1
3164 0x23bb: 0x09f0, // XK_horizlinescan3
3165 0x23bc: 0x09f2, // XK_horizlinescan7
3166 0x23bd: 0x09f3, // XK_horizlinescan9
3167 0x2409: 0x09e2, // XK_ht
3168 0x240a: 0x09e5, // XK_lf
3169 0x240b: 0x09e9, // XK_vt
3170 0x240c: 0x09e3, // XK_ff
3171 0x240d: 0x09e4, // XK_cr
3172 0x2423: 0x0aac, // XK_signifblank
3173 0x2424: 0x09e8, // XK_nl
3174 0x2500: 0x08a3, // XK_horizconnector
3175 0x2502: 0x08a6, // XK_vertconnector
3176 0x250c: 0x08a2, // XK_topleftradical
3177 0x2510: 0x09eb, // XK_uprightcorner
3178 0x2514: 0x09ed, // XK_lowleftcorner
3179 0x2518: 0x09ea, // XK_lowrightcorner
3180 0x251c: 0x09f4, // XK_leftt
3181 0x2524: 0x09f5, // XK_rightt
3182 0x252c: 0x09f7, // XK_topt
3183 0x2534: 0x09f6, // XK_bott
3184 0x253c: 0x09ee, // XK_crossinglines
3185 0x2592: 0x09e1, // XK_checkerboard
3186 0x25aa: 0x0ae7, // XK_enfilledsqbullet
3187 0x25ab: 0x0ae1, // XK_enopensquarebullet
3188 0x25ac: 0x0adb, // XK_filledrectbullet
3189 0x25ad: 0x0ae2, // XK_openrectbullet
3190 0x25ae: 0x0adf, // XK_emfilledrect
3191 0x25af: 0x0acf, // XK_emopenrectangle
3192 0x25b2: 0x0ae8, // XK_filledtribulletup
3193 0x25b3: 0x0ae3, // XK_opentribulletup
3194 0x25b6: 0x0add, // XK_filledrighttribullet
3195 0x25b7: 0x0acd, // XK_rightopentriangle
3196 0x25bc: 0x0ae9, // XK_filledtribulletdown
3197 0x25bd: 0x0ae4, // XK_opentribulletdown
3198 0x25c0: 0x0adc, // XK_filledlefttribullet
3199 0x25c1: 0x0acc, // XK_leftopentriangle
3200 0x25c6: 0x09e0, // XK_soliddiamond
3201 0x25cb: 0x0ace, // XK_emopencircle
3202 0x25cf: 0x0ade, // XK_emfilledcircle
3203 0x25e6: 0x0ae0, // XK_enopencircbullet
3204 0x2606: 0x0ae5, // XK_openstar
3205 0x260e: 0x0af9, // XK_telephone
3206 0x2613: 0x0aca, // XK_signaturemark
3207 0x261c: 0x0aea, // XK_leftpointer
3208 0x261e: 0x0aeb, // XK_rightpointer
3209 0x2640: 0x0af8, // XK_femalesymbol
3210 0x2642: 0x0af7, // XK_malesymbol
3211 0x2663: 0x0aec, // XK_club
3212 0x2665: 0x0aee, // XK_heart
3213 0x2666: 0x0aed, // XK_diamond
3214 0x266d: 0x0af6, // XK_musicalflat
3215 0x266f: 0x0af5, // XK_musicalsharp
3216 0x2713: 0x0af3, // XK_checkmark
3217 0x2717: 0x0af4, // XK_ballotcross
3218 0x271d: 0x0ad9, // XK_latincross
3219 0x2720: 0x0af0, // XK_maltesecross
3220 0x27e8: 0x0abc, // XK_leftanglebracket
3221 0x27e9: 0x0abe, // XK_rightanglebracket
3222 0x3001: 0x04a4, // XK_kana_comma
3223 0x3002: 0x04a1, // XK_kana_fullstop
3224 0x300c: 0x04a2, // XK_kana_openingbracket
3225 0x300d: 0x04a3, // XK_kana_closingbracket
3226 0x309b: 0x04de, // XK_voicedsound
3227 0x309c: 0x04df, // XK_semivoicedsound
3228 0x30a1: 0x04a7, // XK_kana_a
3229 0x30a2: 0x04b1, // XK_kana_A
3230 0x30a3: 0x04a8, // XK_kana_i
3231 0x30a4: 0x04b2, // XK_kana_I
3232 0x30a5: 0x04a9, // XK_kana_u
3233 0x30a6: 0x04b3, // XK_kana_U
3234 0x30a7: 0x04aa, // XK_kana_e
3235 0x30a8: 0x04b4, // XK_kana_E
3236 0x30a9: 0x04ab, // XK_kana_o
3237 0x30aa: 0x04b5, // XK_kana_O
3238 0x30ab: 0x04b6, // XK_kana_KA
3239 0x30ad: 0x04b7, // XK_kana_KI
3240 0x30af: 0x04b8, // XK_kana_KU
3241 0x30b1: 0x04b9, // XK_kana_KE
3242 0x30b3: 0x04ba, // XK_kana_KO
3243 0x30b5: 0x04bb, // XK_kana_SA
3244 0x30b7: 0x04bc, // XK_kana_SHI
3245 0x30b9: 0x04bd, // XK_kana_SU
3246 0x30bb: 0x04be, // XK_kana_SE
3247 0x30bd: 0x04bf, // XK_kana_SO
3248 0x30bf: 0x04c0, // XK_kana_TA
3249 0x30c1: 0x04c1, // XK_kana_CHI
3250 0x30c3: 0x04af, // XK_kana_tsu
3251 0x30c4: 0x04c2, // XK_kana_TSU
3252 0x30c6: 0x04c3, // XK_kana_TE
3253 0x30c8: 0x04c4, // XK_kana_TO
3254 0x30ca: 0x04c5, // XK_kana_NA
3255 0x30cb: 0x04c6, // XK_kana_NI
3256 0x30cc: 0x04c7, // XK_kana_NU
3257 0x30cd: 0x04c8, // XK_kana_NE
3258 0x30ce: 0x04c9, // XK_kana_NO
3259 0x30cf: 0x04ca, // XK_kana_HA
3260 0x30d2: 0x04cb, // XK_kana_HI
3261 0x30d5: 0x04cc, // XK_kana_FU
3262 0x30d8: 0x04cd, // XK_kana_HE
3263 0x30db: 0x04ce, // XK_kana_HO
3264 0x30de: 0x04cf, // XK_kana_MA
3265 0x30df: 0x04d0, // XK_kana_MI
3266 0x30e0: 0x04d1, // XK_kana_MU
3267 0x30e1: 0x04d2, // XK_kana_ME
3268 0x30e2: 0x04d3, // XK_kana_MO
3269 0x30e3: 0x04ac, // XK_kana_ya
3270 0x30e4: 0x04d4, // XK_kana_YA
3271 0x30e5: 0x04ad, // XK_kana_yu
3272 0x30e6: 0x04d5, // XK_kana_YU
3273 0x30e7: 0x04ae, // XK_kana_yo
3274 0x30e8: 0x04d6, // XK_kana_YO
3275 0x30e9: 0x04d7, // XK_kana_RA
3276 0x30ea: 0x04d8, // XK_kana_RI
3277 0x30eb: 0x04d9, // XK_kana_RU
3278 0x30ec: 0x04da, // XK_kana_RE
3279 0x30ed: 0x04db, // XK_kana_RO
3280 0x30ef: 0x04dc, // XK_kana_WA
3281 0x30f2: 0x04a6, // XK_kana_WO
3282 0x30f3: 0x04dd, // XK_kana_N
3283 0x30fb: 0x04a5, // XK_kana_conjunctive
3284 0x30fc: 0x04b0 // XK_prolongedsound
3288 lookup: function (u) {
3289 // Latin-1 is one-to-one mapping
3290 if (u >= 0x20 && u <= 0xff) {
3294 // Lookup table (fairly random)
3295 var keysym = codepoints[u];
3296 if (keysym !== undefined) {
3300 // General mapping as final fallback
3301 return 0x01000000 | u;
3304 },{}],11:[function(require,module,exports){
3307 Object.defineProperty(exports, "__esModule", {
3310 exports.default = Mouse;
3312 var _logging = require('../util/logging.js');
3314 var Log = _interopRequireWildcard(_logging);
3316 var _browser = require('../util/browser.js');
3318 var _events = require('../util/events.js');
3320 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
3322 var WHEEL_STEP = 10; // Delta threshold for a mouse wheel step
3324 * noVNC: HTML5 VNC client
3325 * Copyright (C) 2012 Joel Martin
3326 * Copyright (C) 2013 Samuel Mannehed for Cendio AB
3327 * Licensed under MPL 2.0 or any later version (see LICENSE.txt)
3330 var WHEEL_STEP_TIMEOUT = 50; // ms
3331 var WHEEL_LINE_HEIGHT = 19;
3333 function Mouse(target) {
3334 this._target = target || document;
3336 this._doubleClickTimer = null;
3337 this._lastTouchPos = null;
3340 this._wheelStepXTimer = null;
3341 this._wheelStepYTimer = null;
3342 this._accumulatedWheelDeltaX = 0;
3343 this._accumulatedWheelDeltaY = 0;
3345 this._eventHandlers = {
3346 'mousedown': this._handleMouseDown.bind(this),
3347 'mouseup': this._handleMouseUp.bind(this),
3348 'mousemove': this._handleMouseMove.bind(this),
3349 'mousewheel': this._handleMouseWheel.bind(this),
3350 'mousedisable': this._handleMouseDisable.bind(this)
3355 // ===== PROPERTIES =====
3357 touchButton: 1, // Button mask (1, 2, 4) for touch devices (0 means ignore clicks)
3359 // ===== EVENT HANDLERS =====
3361 onmousebutton: function () {}, // Handler for mouse button click/release
3362 onmousemove: function () {}, // Handler for mouse movement
3364 // ===== PRIVATE METHODS =====
3366 _resetDoubleClickTimer: function () {
3367 this._doubleClickTimer = null;
3370 _handleMouseButton: function (e, down) {
3371 this._updateMousePosition(e);
3372 var pos = this._pos;
3375 if (e.touches || e.changedTouches) {
3378 // When two touches occur within 500 ms of each other and are
3379 // close enough together a double click is triggered.
3381 if (this._doubleClickTimer === null) {
3382 this._lastTouchPos = pos;
3384 clearTimeout(this._doubleClickTimer);
3386 // When the distance between the two touches is small enough
3387 // force the position of the latter touch to the position of
3390 var xs = this._lastTouchPos.x - pos.x;
3391 var ys = this._lastTouchPos.y - pos.y;
3392 var d = Math.sqrt(xs * xs + ys * ys);
3394 // The goal is to trigger on a certain physical width, the
3395 // devicePixelRatio brings us a bit closer but is not optimal.
3396 var threshold = 20 * (window.devicePixelRatio || 1);
3397 if (d < threshold) {
3398 pos = this._lastTouchPos;
3401 this._doubleClickTimer = setTimeout(this._resetDoubleClickTimer.bind(this), 500);
3403 bmask = this.touchButton;
3405 } else if (e.which) {
3406 /* everything except IE */
3407 bmask = 1 << e.button;
3409 /* IE including 9 */
3410 bmask = (e.button & 0x1) + // Left
3411 (e.button & 0x2) * 2 + // Right
3412 (e.button & 0x4) / 2; // Middle
3415 Log.Debug("onmousebutton " + (down ? "down" : "up") + ", x: " + pos.x + ", y: " + pos.y + ", bmask: " + bmask);
3416 this.onmousebutton(pos.x, pos.y, down, bmask);
3418 (0, _events.stopEvent)(e);
3421 _handleMouseDown: function (e) {
3422 // Touch events have implicit capture
3423 if (e.type === "mousedown") {
3424 (0, _events.setCapture)(this._target);
3427 this._handleMouseButton(e, 1);
3430 _handleMouseUp: function (e) {
3431 this._handleMouseButton(e, 0);
3434 // Mouse wheel events are sent in steps over VNC. This means that the VNC
3435 // protocol can't handle a wheel event with specific distance or speed.
3436 // Therefor, if we get a lot of small mouse wheel events we combine them.
3437 _generateWheelStepX: function () {
3439 if (this._accumulatedWheelDeltaX < 0) {
3440 this.onmousebutton(this._pos.x, this._pos.y, 1, 1 << 5);
3441 this.onmousebutton(this._pos.x, this._pos.y, 0, 1 << 5);
3442 } else if (this._accumulatedWheelDeltaX > 0) {
3443 this.onmousebutton(this._pos.x, this._pos.y, 1, 1 << 6);
3444 this.onmousebutton(this._pos.x, this._pos.y, 0, 1 << 6);
3447 this._accumulatedWheelDeltaX = 0;
3450 _generateWheelStepY: function () {
3452 if (this._accumulatedWheelDeltaY < 0) {
3453 this.onmousebutton(this._pos.x, this._pos.y, 1, 1 << 3);
3454 this.onmousebutton(this._pos.x, this._pos.y, 0, 1 << 3);
3455 } else if (this._accumulatedWheelDeltaY > 0) {
3456 this.onmousebutton(this._pos.x, this._pos.y, 1, 1 << 4);
3457 this.onmousebutton(this._pos.x, this._pos.y, 0, 1 << 4);
3460 this._accumulatedWheelDeltaY = 0;
3463 _resetWheelStepTimers: function () {
3464 window.clearTimeout(this._wheelStepXTimer);
3465 window.clearTimeout(this._wheelStepYTimer);
3466 this._wheelStepXTimer = null;
3467 this._wheelStepYTimer = null;
3470 _handleMouseWheel: function (e) {
3471 this._resetWheelStepTimers();
3473 this._updateMousePosition(e);
3478 // Pixel units unless it's non-zero.
3479 // Note that if deltamode is line or page won't matter since we aren't
3480 // sending the mouse wheel delta to the server anyway.
3481 // The difference between pixel and line can be important however since
3482 // we have a threshold that can be smaller than the line height.
3483 if (e.deltaMode !== 0) {
3484 dX *= WHEEL_LINE_HEIGHT;
3485 dY *= WHEEL_LINE_HEIGHT;
3488 this._accumulatedWheelDeltaX += dX;
3489 this._accumulatedWheelDeltaY += dY;
3491 // Generate a mouse wheel step event when the accumulated delta
3492 // for one of the axes is large enough.
3493 // Small delta events that do not pass the threshold get sent
3495 if (Math.abs(this._accumulatedWheelDeltaX) > WHEEL_STEP) {
3496 this._generateWheelStepX();
3498 this._wheelStepXTimer = window.setTimeout(this._generateWheelStepX.bind(this), WHEEL_STEP_TIMEOUT);
3500 if (Math.abs(this._accumulatedWheelDeltaY) > WHEEL_STEP) {
3501 this._generateWheelStepY();
3503 this._wheelStepYTimer = window.setTimeout(this._generateWheelStepY.bind(this), WHEEL_STEP_TIMEOUT);
3506 (0, _events.stopEvent)(e);
3509 _handleMouseMove: function (e) {
3510 this._updateMousePosition(e);
3511 this.onmousemove(this._pos.x, this._pos.y);
3512 (0, _events.stopEvent)(e);
3515 _handleMouseDisable: function (e) {
3517 * Stop propagation if inside canvas area
3518 * Note: This is only needed for the 'click' event as it fails
3519 * to fire properly for the target element so we have
3520 * to listen on the document element instead.
3522 if (e.target == this._target) {
3523 (0, _events.stopEvent)(e);
3527 // Update coordinates relative to target
3528 _updateMousePosition: function (e) {
3529 e = (0, _events.getPointerEvent)(e);
3530 var bounds = this._target.getBoundingClientRect();
3532 // Clip to target bounds
3533 if (e.clientX < bounds.left) {
3535 } else if (e.clientX >= bounds.right) {
3536 x = bounds.width - 1;
3538 x = e.clientX - bounds.left;
3540 if (e.clientY < bounds.top) {
3542 } else if (e.clientY >= bounds.bottom) {
3543 y = bounds.height - 1;
3545 y = e.clientY - bounds.top;
3547 this._pos = { x: x, y: y };
3550 // ===== PUBLIC METHODS =====
3553 var c = this._target;
3555 if (_browser.isTouchDevice) {
3556 c.addEventListener('touchstart', this._eventHandlers.mousedown);
3557 c.addEventListener('touchend', this._eventHandlers.mouseup);
3558 c.addEventListener('touchmove', this._eventHandlers.mousemove);
3560 c.addEventListener('mousedown', this._eventHandlers.mousedown);
3561 c.addEventListener('mouseup', this._eventHandlers.mouseup);
3562 c.addEventListener('mousemove', this._eventHandlers.mousemove);
3563 c.addEventListener('wheel', this._eventHandlers.mousewheel);
3565 /* Prevent middle-click pasting (see above for why we bind to document) */
3566 document.addEventListener('click', this._eventHandlers.mousedisable);
3568 /* preventDefault() on mousedown doesn't stop this event for some
3569 reason so we have to explicitly block it */
3570 c.addEventListener('contextmenu', this._eventHandlers.mousedisable);
3573 ungrab: function () {
3574 var c = this._target;
3576 this._resetWheelStepTimers();
3578 if (_browser.isTouchDevice) {
3579 c.removeEventListener('touchstart', this._eventHandlers.mousedown);
3580 c.removeEventListener('touchend', this._eventHandlers.mouseup);
3581 c.removeEventListener('touchmove', this._eventHandlers.mousemove);
3583 c.removeEventListener('mousedown', this._eventHandlers.mousedown);
3584 c.removeEventListener('mouseup', this._eventHandlers.mouseup);
3585 c.removeEventListener('mousemove', this._eventHandlers.mousemove);
3586 c.removeEventListener('wheel', this._eventHandlers.mousewheel);
3588 document.removeEventListener('click', this._eventHandlers.mousedisable);
3590 c.removeEventListener('contextmenu', this._eventHandlers.mousedisable);
3593 },{"../util/browser.js":16,"../util/events.js":17,"../util/logging.js":19}],12:[function(require,module,exports){
3596 Object.defineProperty(exports, "__esModule", {
3599 exports.getKeycode = getKeycode;
3600 exports.getKey = getKey;
3601 exports.getKeysym = getKeysym;
3603 var _keysym = require("./keysym.js");
3605 var _keysym2 = _interopRequireDefault(_keysym);
3607 var _keysymdef = require("./keysymdef.js");
3609 var _keysymdef2 = _interopRequireDefault(_keysymdef);
3611 var _vkeys = require("./vkeys.js");
3613 var _vkeys2 = _interopRequireDefault(_vkeys);
3615 var _fixedkeys = require("./fixedkeys.js");
3617 var _fixedkeys2 = _interopRequireDefault(_fixedkeys);
3619 var _domkeytable = require("./domkeytable.js");
3621 var _domkeytable2 = _interopRequireDefault(_domkeytable);
3623 var _browser = require("../util/browser.js");
3625 var browser = _interopRequireWildcard(_browser);
3627 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
3629 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
3631 // Get 'KeyboardEvent.code', handling legacy browsers
3632 function getKeycode(evt) {
3633 // Are we getting proper key identifiers?
3634 // (unfortunately Firefox and Chrome are crappy here and gives
3635 // us an empty string on some platforms, rather than leaving it
3638 // Mozilla isn't fully in sync with the spec yet
3649 // The de-facto standard is to use Windows Virtual-Key codes
3650 // in the 'keyCode' field for non-printable characters. However
3651 // Webkit sets it to the same as charCode in 'keypress' events.
3652 if (evt.type !== 'keypress' && evt.keyCode in _vkeys2.default) {
3653 var code = _vkeys2.default[evt.keyCode];
3655 // macOS has messed up this code for some reason
3656 if (browser.isMac() && code === 'ContextMenu') {
3660 // The keyCode doesn't distinguish between left and right
3661 // for the standard modifiers
3662 if (evt.location === 2) {
3665 return 'ShiftRight';
3667 return 'ControlRight';
3673 // Nor a bunch of the numpad keys
3674 if (evt.location === 3) {
3677 return 'NumpadDecimal';
3697 return 'NumpadEnter';
3704 return 'Unidentified';
3707 // Get 'KeyboardEvent.key', handling legacy browsers
3708 function getKey(evt) {
3709 // Are we getting a proper key value?
3710 if (evt.key !== undefined) {
3711 // IE and Edge use some ancient version of the spec
3712 // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8860571/
3719 return 'ScrollLock';
3723 return 'ContextMenu';
3729 return 'ArrowRight';
3746 // Mozilla isn't fully in sync with the spec yet
3752 // iOS leaks some OS names
3754 case 'UIKeyInputUpArrow':
3756 case 'UIKeyInputDownArrow':
3758 case 'UIKeyInputLeftArrow':
3760 case 'UIKeyInputRightArrow':
3761 return 'ArrowRight';
3762 case 'UIKeyInputEscape':
3766 // IE and Edge have broken handling of AltGraph so we cannot
3767 // trust them for printable characters
3768 if (evt.key.length !== 1 || !browser.isIE() && !browser.isEdge()) {
3773 // Try to deduce it based on the physical key
3774 var code = getKeycode(evt);
3775 if (code in _fixedkeys2.default) {
3776 return _fixedkeys2.default[code];
3779 // If that failed, then see if we have a printable character
3781 return String.fromCharCode(evt.charCode);
3784 // At this point we have nothing left to go on
3785 return 'Unidentified';
3788 // Get the most reliable keysym value we can get from a key event
3789 function getKeysym(evt) {
3790 var key = getKey(evt);
3792 if (key === 'Unidentified') {
3796 // First look up special keys
3797 if (key in _domkeytable2.default) {
3798 var location = evt.location;
3800 // Safari screws up location for the right cmd key
3801 if (key === 'Meta' && location === 0) {
3805 if (location === undefined || location > 3) {
3809 return _domkeytable2.default[key][location];
3812 // Now we need to look at the Unicode symbol instead
3816 // Special key? (FIXME: Should have been caught earlier)
3817 if (key.length !== 1) {
3821 codepoint = key.charCodeAt();
3823 return _keysymdef2.default.lookup(codepoint);
3828 },{"../util/browser.js":16,"./domkeytable.js":6,"./fixedkeys.js":7,"./keysym.js":9,"./keysymdef.js":10,"./vkeys.js":13}],13:[function(require,module,exports){
3831 Object.defineProperty(exports, "__esModule", {
3835 * noVNC: HTML5 VNC client
3836 * Copyright (C) 2017 Pierre Ossman for Cendio AB
3837 * Licensed under MPL 2.0 or any later version (see LICENSE.txt)
3841 * Mapping between Microsoft® Windows® Virtual-Key codes and
3848 0x0a: 'NumpadClear',
3851 0x11: 'ControlLeft',
3870 0x2c: 'PrintScreen',
3886 0x5d: 'ContextMenu',
3898 0x6a: 'NumpadMultiply',
3900 0x6c: 'NumpadDecimal',
3901 0x6d: 'NumpadSubtract',
3902 0x6e: 'NumpadDecimal', // Duplicate, because buggy on Windows
3903 0x6f: 'NumpadDivide',
3930 0xa6: 'BrowserBack',
3931 0xa7: 'BrowserForward',
3932 0xa8: 'BrowserRefresh',
3933 0xa9: 'BrowserStop',
3934 0xaa: 'BrowserSearch',
3935 0xab: 'BrowserFavorites',
3936 0xac: 'BrowserHome',
3937 0xad: 'AudioVolumeMute',
3938 0xae: 'AudioVolumeDown',
3939 0xaf: 'AudioVolumeUp',
3940 0xb0: 'MediaTrackNext',
3941 0xb1: 'MediaTrackPrevious',
3943 0xb3: 'MediaPlayPause',
3945 0xb5: 'MediaSelect',
3948 0xe1: 'AltRight' // Only when it is AltGraph
3950 },{}],14:[function(require,module,exports){
3953 Object.defineProperty(exports, "__esModule", {
3957 * This file is auto-generated from keymaps.csv on 2017-05-31 16:20
3958 * Database checksum sha256(92fd165507f2a3b8c5b3fa56e425d45788dbcb98cf067a307527d91ce22cab94)
3959 * To re-generate, run:
3960 * keymap-gen --lang=js code-map keymaps.csv html atset1
3963 "Again": 0xe005, /* html:Again (Again) -> linux:129 (KEY_AGAIN) -> atset1:57349 */
3964 "AltLeft": 0x38, /* html:AltLeft (AltLeft) -> linux:56 (KEY_LEFTALT) -> atset1:56 */
3965 "AltRight": 0xe038, /* html:AltRight (AltRight) -> linux:100 (KEY_RIGHTALT) -> atset1:57400 */
3966 "ArrowDown": 0xe050, /* html:ArrowDown (ArrowDown) -> linux:108 (KEY_DOWN) -> atset1:57424 */
3967 "ArrowLeft": 0xe04b, /* html:ArrowLeft (ArrowLeft) -> linux:105 (KEY_LEFT) -> atset1:57419 */
3968 "ArrowRight": 0xe04d, /* html:ArrowRight (ArrowRight) -> linux:106 (KEY_RIGHT) -> atset1:57421 */
3969 "ArrowUp": 0xe048, /* html:ArrowUp (ArrowUp) -> linux:103 (KEY_UP) -> atset1:57416 */
3970 "AudioVolumeDown": 0xe02e, /* html:AudioVolumeDown (AudioVolumeDown) -> linux:114 (KEY_VOLUMEDOWN) -> atset1:57390 */
3971 "AudioVolumeMute": 0xe020, /* html:AudioVolumeMute (AudioVolumeMute) -> linux:113 (KEY_MUTE) -> atset1:57376 */
3972 "AudioVolumeUp": 0xe030, /* html:AudioVolumeUp (AudioVolumeUp) -> linux:115 (KEY_VOLUMEUP) -> atset1:57392 */
3973 "Backquote": 0x29, /* html:Backquote (Backquote) -> linux:41 (KEY_GRAVE) -> atset1:41 */
3974 "Backslash": 0x2b, /* html:Backslash (Backslash) -> linux:43 (KEY_BACKSLASH) -> atset1:43 */
3975 "Backspace": 0xe, /* html:Backspace (Backspace) -> linux:14 (KEY_BACKSPACE) -> atset1:14 */
3976 "BracketLeft": 0x1a, /* html:BracketLeft (BracketLeft) -> linux:26 (KEY_LEFTBRACE) -> atset1:26 */
3977 "BracketRight": 0x1b, /* html:BracketRight (BracketRight) -> linux:27 (KEY_RIGHTBRACE) -> atset1:27 */
3978 "BrowserBack": 0xe06a, /* html:BrowserBack (BrowserBack) -> linux:158 (KEY_BACK) -> atset1:57450 */
3979 "BrowserFavorites": 0xe066, /* html:BrowserFavorites (BrowserFavorites) -> linux:156 (KEY_BOOKMARKS) -> atset1:57446 */
3980 "BrowserForward": 0xe069, /* html:BrowserForward (BrowserForward) -> linux:159 (KEY_FORWARD) -> atset1:57449 */
3981 "BrowserHome": 0xe032, /* html:BrowserHome (BrowserHome) -> linux:172 (KEY_HOMEPAGE) -> atset1:57394 */
3982 "BrowserRefresh": 0xe067, /* html:BrowserRefresh (BrowserRefresh) -> linux:173 (KEY_REFRESH) -> atset1:57447 */
3983 "BrowserSearch": 0xe065, /* html:BrowserSearch (BrowserSearch) -> linux:217 (KEY_SEARCH) -> atset1:57445 */
3984 "BrowserStop": 0xe068, /* html:BrowserStop (BrowserStop) -> linux:128 (KEY_STOP) -> atset1:57448 */
3985 "CapsLock": 0x3a, /* html:CapsLock (CapsLock) -> linux:58 (KEY_CAPSLOCK) -> atset1:58 */
3986 "Comma": 0x33, /* html:Comma (Comma) -> linux:51 (KEY_COMMA) -> atset1:51 */
3987 "ContextMenu": 0xe05d, /* html:ContextMenu (ContextMenu) -> linux:127 (KEY_COMPOSE) -> atset1:57437 */
3988 "ControlLeft": 0x1d, /* html:ControlLeft (ControlLeft) -> linux:29 (KEY_LEFTCTRL) -> atset1:29 */
3989 "ControlRight": 0xe01d, /* html:ControlRight (ControlRight) -> linux:97 (KEY_RIGHTCTRL) -> atset1:57373 */
3990 "Convert": 0x79, /* html:Convert (Convert) -> linux:92 (KEY_HENKAN) -> atset1:121 */
3991 "Copy": 0xe078, /* html:Copy (Copy) -> linux:133 (KEY_COPY) -> atset1:57464 */
3992 "Cut": 0xe03c, /* html:Cut (Cut) -> linux:137 (KEY_CUT) -> atset1:57404 */
3993 "Delete": 0xe053, /* html:Delete (Delete) -> linux:111 (KEY_DELETE) -> atset1:57427 */
3994 "Digit0": 0xb, /* html:Digit0 (Digit0) -> linux:11 (KEY_0) -> atset1:11 */
3995 "Digit1": 0x2, /* html:Digit1 (Digit1) -> linux:2 (KEY_1) -> atset1:2 */
3996 "Digit2": 0x3, /* html:Digit2 (Digit2) -> linux:3 (KEY_2) -> atset1:3 */
3997 "Digit3": 0x4, /* html:Digit3 (Digit3) -> linux:4 (KEY_3) -> atset1:4 */
3998 "Digit4": 0x5, /* html:Digit4 (Digit4) -> linux:5 (KEY_4) -> atset1:5 */
3999 "Digit5": 0x6, /* html:Digit5 (Digit5) -> linux:6 (KEY_5) -> atset1:6 */
4000 "Digit6": 0x7, /* html:Digit6 (Digit6) -> linux:7 (KEY_6) -> atset1:7 */
4001 "Digit7": 0x8, /* html:Digit7 (Digit7) -> linux:8 (KEY_7) -> atset1:8 */
4002 "Digit8": 0x9, /* html:Digit8 (Digit8) -> linux:9 (KEY_8) -> atset1:9 */
4003 "Digit9": 0xa, /* html:Digit9 (Digit9) -> linux:10 (KEY_9) -> atset1:10 */
4004 "Eject": 0xe07d, /* html:Eject (Eject) -> linux:162 (KEY_EJECTCLOSECD) -> atset1:57469 */
4005 "End": 0xe04f, /* html:End (End) -> linux:107 (KEY_END) -> atset1:57423 */
4006 "Enter": 0x1c, /* html:Enter (Enter) -> linux:28 (KEY_ENTER) -> atset1:28 */
4007 "Equal": 0xd, /* html:Equal (Equal) -> linux:13 (KEY_EQUAL) -> atset1:13 */
4008 "Escape": 0x1, /* html:Escape (Escape) -> linux:1 (KEY_ESC) -> atset1:1 */
4009 "F1": 0x3b, /* html:F1 (F1) -> linux:59 (KEY_F1) -> atset1:59 */
4010 "F10": 0x44, /* html:F10 (F10) -> linux:68 (KEY_F10) -> atset1:68 */
4011 "F11": 0x57, /* html:F11 (F11) -> linux:87 (KEY_F11) -> atset1:87 */
4012 "F12": 0x58, /* html:F12 (F12) -> linux:88 (KEY_F12) -> atset1:88 */
4013 "F13": 0x5d, /* html:F13 (F13) -> linux:183 (KEY_F13) -> atset1:93 */
4014 "F14": 0x5e, /* html:F14 (F14) -> linux:184 (KEY_F14) -> atset1:94 */
4015 "F15": 0x5f, /* html:F15 (F15) -> linux:185 (KEY_F15) -> atset1:95 */
4016 "F16": 0x55, /* html:F16 (F16) -> linux:186 (KEY_F16) -> atset1:85 */
4017 "F17": 0xe003, /* html:F17 (F17) -> linux:187 (KEY_F17) -> atset1:57347 */
4018 "F18": 0xe077, /* html:F18 (F18) -> linux:188 (KEY_F18) -> atset1:57463 */
4019 "F19": 0xe004, /* html:F19 (F19) -> linux:189 (KEY_F19) -> atset1:57348 */
4020 "F2": 0x3c, /* html:F2 (F2) -> linux:60 (KEY_F2) -> atset1:60 */
4021 "F20": 0x5a, /* html:F20 (F20) -> linux:190 (KEY_F20) -> atset1:90 */
4022 "F21": 0x74, /* html:F21 (F21) -> linux:191 (KEY_F21) -> atset1:116 */
4023 "F22": 0xe079, /* html:F22 (F22) -> linux:192 (KEY_F22) -> atset1:57465 */
4024 "F23": 0x6d, /* html:F23 (F23) -> linux:193 (KEY_F23) -> atset1:109 */
4025 "F24": 0x6f, /* html:F24 (F24) -> linux:194 (KEY_F24) -> atset1:111 */
4026 "F3": 0x3d, /* html:F3 (F3) -> linux:61 (KEY_F3) -> atset1:61 */
4027 "F4": 0x3e, /* html:F4 (F4) -> linux:62 (KEY_F4) -> atset1:62 */
4028 "F5": 0x3f, /* html:F5 (F5) -> linux:63 (KEY_F5) -> atset1:63 */
4029 "F6": 0x40, /* html:F6 (F6) -> linux:64 (KEY_F6) -> atset1:64 */
4030 "F7": 0x41, /* html:F7 (F7) -> linux:65 (KEY_F7) -> atset1:65 */
4031 "F8": 0x42, /* html:F8 (F8) -> linux:66 (KEY_F8) -> atset1:66 */
4032 "F9": 0x43, /* html:F9 (F9) -> linux:67 (KEY_F9) -> atset1:67 */
4033 "Find": 0xe041, /* html:Find (Find) -> linux:136 (KEY_FIND) -> atset1:57409 */
4034 "Help": 0xe075, /* html:Help (Help) -> linux:138 (KEY_HELP) -> atset1:57461 */
4035 "Hiragana": 0x77, /* html:Hiragana (Lang4) -> linux:91 (KEY_HIRAGANA) -> atset1:119 */
4036 "Home": 0xe047, /* html:Home (Home) -> linux:102 (KEY_HOME) -> atset1:57415 */
4037 "Insert": 0xe052, /* html:Insert (Insert) -> linux:110 (KEY_INSERT) -> atset1:57426 */
4038 "IntlBackslash": 0x56, /* html:IntlBackslash (IntlBackslash) -> linux:86 (KEY_102ND) -> atset1:86 */
4039 "IntlRo": 0x73, /* html:IntlRo (IntlRo) -> linux:89 (KEY_RO) -> atset1:115 */
4040 "IntlYen": 0x7d, /* html:IntlYen (IntlYen) -> linux:124 (KEY_YEN) -> atset1:125 */
4041 "KanaMode": 0x70, /* html:KanaMode (KanaMode) -> linux:93 (KEY_KATAKANAHIRAGANA) -> atset1:112 */
4042 "Katakana": 0x78, /* html:Katakana (Lang3) -> linux:90 (KEY_KATAKANA) -> atset1:120 */
4043 "KeyA": 0x1e, /* html:KeyA (KeyA) -> linux:30 (KEY_A) -> atset1:30 */
4044 "KeyB": 0x30, /* html:KeyB (KeyB) -> linux:48 (KEY_B) -> atset1:48 */
4045 "KeyC": 0x2e, /* html:KeyC (KeyC) -> linux:46 (KEY_C) -> atset1:46 */
4046 "KeyD": 0x20, /* html:KeyD (KeyD) -> linux:32 (KEY_D) -> atset1:32 */
4047 "KeyE": 0x12, /* html:KeyE (KeyE) -> linux:18 (KEY_E) -> atset1:18 */
4048 "KeyF": 0x21, /* html:KeyF (KeyF) -> linux:33 (KEY_F) -> atset1:33 */
4049 "KeyG": 0x22, /* html:KeyG (KeyG) -> linux:34 (KEY_G) -> atset1:34 */
4050 "KeyH": 0x23, /* html:KeyH (KeyH) -> linux:35 (KEY_H) -> atset1:35 */
4051 "KeyI": 0x17, /* html:KeyI (KeyI) -> linux:23 (KEY_I) -> atset1:23 */
4052 "KeyJ": 0x24, /* html:KeyJ (KeyJ) -> linux:36 (KEY_J) -> atset1:36 */
4053 "KeyK": 0x25, /* html:KeyK (KeyK) -> linux:37 (KEY_K) -> atset1:37 */
4054 "KeyL": 0x26, /* html:KeyL (KeyL) -> linux:38 (KEY_L) -> atset1:38 */
4055 "KeyM": 0x32, /* html:KeyM (KeyM) -> linux:50 (KEY_M) -> atset1:50 */
4056 "KeyN": 0x31, /* html:KeyN (KeyN) -> linux:49 (KEY_N) -> atset1:49 */
4057 "KeyO": 0x18, /* html:KeyO (KeyO) -> linux:24 (KEY_O) -> atset1:24 */
4058 "KeyP": 0x19, /* html:KeyP (KeyP) -> linux:25 (KEY_P) -> atset1:25 */
4059 "KeyQ": 0x10, /* html:KeyQ (KeyQ) -> linux:16 (KEY_Q) -> atset1:16 */
4060 "KeyR": 0x13, /* html:KeyR (KeyR) -> linux:19 (KEY_R) -> atset1:19 */
4061 "KeyS": 0x1f, /* html:KeyS (KeyS) -> linux:31 (KEY_S) -> atset1:31 */
4062 "KeyT": 0x14, /* html:KeyT (KeyT) -> linux:20 (KEY_T) -> atset1:20 */
4063 "KeyU": 0x16, /* html:KeyU (KeyU) -> linux:22 (KEY_U) -> atset1:22 */
4064 "KeyV": 0x2f, /* html:KeyV (KeyV) -> linux:47 (KEY_V) -> atset1:47 */
4065 "KeyW": 0x11, /* html:KeyW (KeyW) -> linux:17 (KEY_W) -> atset1:17 */
4066 "KeyX": 0x2d, /* html:KeyX (KeyX) -> linux:45 (KEY_X) -> atset1:45 */
4067 "KeyY": 0x15, /* html:KeyY (KeyY) -> linux:21 (KEY_Y) -> atset1:21 */
4068 "KeyZ": 0x2c, /* html:KeyZ (KeyZ) -> linux:44 (KEY_Z) -> atset1:44 */
4069 "Lang3": 0x78, /* html:Lang3 (Lang3) -> linux:90 (KEY_KATAKANA) -> atset1:120 */
4070 "Lang4": 0x77, /* html:Lang4 (Lang4) -> linux:91 (KEY_HIRAGANA) -> atset1:119 */
4071 "Lang5": 0x76, /* html:Lang5 (Lang5) -> linux:85 (KEY_ZENKAKUHANKAKU) -> atset1:118 */
4072 "LaunchApp1": 0xe06b, /* html:LaunchApp1 (LaunchApp1) -> linux:157 (KEY_COMPUTER) -> atset1:57451 */
4073 "LaunchApp2": 0xe021, /* html:LaunchApp2 (LaunchApp2) -> linux:140 (KEY_CALC) -> atset1:57377 */
4074 "LaunchMail": 0xe06c, /* html:LaunchMail (LaunchMail) -> linux:155 (KEY_MAIL) -> atset1:57452 */
4075 "MediaPlayPause": 0xe022, /* html:MediaPlayPause (MediaPlayPause) -> linux:164 (KEY_PLAYPAUSE) -> atset1:57378 */
4076 "MediaSelect": 0xe06d, /* html:MediaSelect (MediaSelect) -> linux:226 (KEY_MEDIA) -> atset1:57453 */
4077 "MediaStop": 0xe024, /* html:MediaStop (MediaStop) -> linux:166 (KEY_STOPCD) -> atset1:57380 */
4078 "MediaTrackNext": 0xe019, /* html:MediaTrackNext (MediaTrackNext) -> linux:163 (KEY_NEXTSONG) -> atset1:57369 */
4079 "MediaTrackPrevious": 0xe010, /* html:MediaTrackPrevious (MediaTrackPrevious) -> linux:165 (KEY_PREVIOUSSONG) -> atset1:57360 */
4080 "MetaLeft": 0xe05b, /* html:MetaLeft (MetaLeft) -> linux:125 (KEY_LEFTMETA) -> atset1:57435 */
4081 "MetaRight": 0xe05c, /* html:MetaRight (MetaRight) -> linux:126 (KEY_RIGHTMETA) -> atset1:57436 */
4082 "Minus": 0xc, /* html:Minus (Minus) -> linux:12 (KEY_MINUS) -> atset1:12 */
4083 "NonConvert": 0x7b, /* html:NonConvert (NonConvert) -> linux:94 (KEY_MUHENKAN) -> atset1:123 */
4084 "NumLock": 0x45, /* html:NumLock (NumLock) -> linux:69 (KEY_NUMLOCK) -> atset1:69 */
4085 "Numpad0": 0x52, /* html:Numpad0 (Numpad0) -> linux:82 (KEY_KP0) -> atset1:82 */
4086 "Numpad1": 0x4f, /* html:Numpad1 (Numpad1) -> linux:79 (KEY_KP1) -> atset1:79 */
4087 "Numpad2": 0x50, /* html:Numpad2 (Numpad2) -> linux:80 (KEY_KP2) -> atset1:80 */
4088 "Numpad3": 0x51, /* html:Numpad3 (Numpad3) -> linux:81 (KEY_KP3) -> atset1:81 */
4089 "Numpad4": 0x4b, /* html:Numpad4 (Numpad4) -> linux:75 (KEY_KP4) -> atset1:75 */
4090 "Numpad5": 0x4c, /* html:Numpad5 (Numpad5) -> linux:76 (KEY_KP5) -> atset1:76 */
4091 "Numpad6": 0x4d, /* html:Numpad6 (Numpad6) -> linux:77 (KEY_KP6) -> atset1:77 */
4092 "Numpad7": 0x47, /* html:Numpad7 (Numpad7) -> linux:71 (KEY_KP7) -> atset1:71 */
4093 "Numpad8": 0x48, /* html:Numpad8 (Numpad8) -> linux:72 (KEY_KP8) -> atset1:72 */
4094 "Numpad9": 0x49, /* html:Numpad9 (Numpad9) -> linux:73 (KEY_KP9) -> atset1:73 */
4095 "NumpadAdd": 0x4e, /* html:NumpadAdd (NumpadAdd) -> linux:78 (KEY_KPPLUS) -> atset1:78 */
4096 "NumpadComma": 0x7e, /* html:NumpadComma (NumpadComma) -> linux:121 (KEY_KPCOMMA) -> atset1:126 */
4097 "NumpadDecimal": 0x53, /* html:NumpadDecimal (NumpadDecimal) -> linux:83 (KEY_KPDOT) -> atset1:83 */
4098 "NumpadDivide": 0xe035, /* html:NumpadDivide (NumpadDivide) -> linux:98 (KEY_KPSLASH) -> atset1:57397 */
4099 "NumpadEnter": 0xe01c, /* html:NumpadEnter (NumpadEnter) -> linux:96 (KEY_KPENTER) -> atset1:57372 */
4100 "NumpadEqual": 0x59, /* html:NumpadEqual (NumpadEqual) -> linux:117 (KEY_KPEQUAL) -> atset1:89 */
4101 "NumpadMultiply": 0x37, /* html:NumpadMultiply (NumpadMultiply) -> linux:55 (KEY_KPASTERISK) -> atset1:55 */
4102 "NumpadParenLeft": 0xe076, /* html:NumpadParenLeft (NumpadParenLeft) -> linux:179 (KEY_KPLEFTPAREN) -> atset1:57462 */
4103 "NumpadParenRight": 0xe07b, /* html:NumpadParenRight (NumpadParenRight) -> linux:180 (KEY_KPRIGHTPAREN) -> atset1:57467 */
4104 "NumpadSubtract": 0x4a, /* html:NumpadSubtract (NumpadSubtract) -> linux:74 (KEY_KPMINUS) -> atset1:74 */
4105 "Open": 0x64, /* html:Open (Open) -> linux:134 (KEY_OPEN) -> atset1:100 */
4106 "PageDown": 0xe051, /* html:PageDown (PageDown) -> linux:109 (KEY_PAGEDOWN) -> atset1:57425 */
4107 "PageUp": 0xe049, /* html:PageUp (PageUp) -> linux:104 (KEY_PAGEUP) -> atset1:57417 */
4108 "Paste": 0x65, /* html:Paste (Paste) -> linux:135 (KEY_PASTE) -> atset1:101 */
4109 "Pause": 0xe046, /* html:Pause (Pause) -> linux:119 (KEY_PAUSE) -> atset1:57414 */
4110 "Period": 0x34, /* html:Period (Period) -> linux:52 (KEY_DOT) -> atset1:52 */
4111 "Power": 0xe05e, /* html:Power (Power) -> linux:116 (KEY_POWER) -> atset1:57438 */
4112 "PrintScreen": 0x54, /* html:PrintScreen (PrintScreen) -> linux:99 (KEY_SYSRQ) -> atset1:84 */
4113 "Props": 0xe006, /* html:Props (Props) -> linux:130 (KEY_PROPS) -> atset1:57350 */
4114 "Quote": 0x28, /* html:Quote (Quote) -> linux:40 (KEY_APOSTROPHE) -> atset1:40 */
4115 "ScrollLock": 0x46, /* html:ScrollLock (ScrollLock) -> linux:70 (KEY_SCROLLLOCK) -> atset1:70 */
4116 "Semicolon": 0x27, /* html:Semicolon (Semicolon) -> linux:39 (KEY_SEMICOLON) -> atset1:39 */
4117 "ShiftLeft": 0x2a, /* html:ShiftLeft (ShiftLeft) -> linux:42 (KEY_LEFTSHIFT) -> atset1:42 */
4118 "ShiftRight": 0x36, /* html:ShiftRight (ShiftRight) -> linux:54 (KEY_RIGHTSHIFT) -> atset1:54 */
4119 "Slash": 0x35, /* html:Slash (Slash) -> linux:53 (KEY_SLASH) -> atset1:53 */
4120 "Sleep": 0xe05f, /* html:Sleep (Sleep) -> linux:142 (KEY_SLEEP) -> atset1:57439 */
4121 "Space": 0x39, /* html:Space (Space) -> linux:57 (KEY_SPACE) -> atset1:57 */
4122 "Suspend": 0xe025, /* html:Suspend (Suspend) -> linux:205 (KEY_SUSPEND) -> atset1:57381 */
4123 "Tab": 0xf, /* html:Tab (Tab) -> linux:15 (KEY_TAB) -> atset1:15 */
4124 "Undo": 0xe007, /* html:Undo (Undo) -> linux:131 (KEY_UNDO) -> atset1:57351 */
4125 "WakeUp": 0xe063 /* html:WakeUp (WakeUp) -> linux:143 (KEY_WAKEUP) -> atset1:57443 */
4127 },{}],15:[function(require,module,exports){
4130 Object.defineProperty(exports, "__esModule", {
4133 exports.default = RFB;
4135 var _logging = require('./util/logging.js');
4137 var Log = _interopRequireWildcard(_logging);
4139 var _strings = require('./util/strings.js');
4141 var _browser = require('./util/browser.js');
4143 var _eventtarget = require('./util/eventtarget.js');
4145 var _eventtarget2 = _interopRequireDefault(_eventtarget);
4147 var _display = require('./display.js');
4149 var _display2 = _interopRequireDefault(_display);
4151 var _keyboard = require('./input/keyboard.js');
4153 var _keyboard2 = _interopRequireDefault(_keyboard);
4155 var _mouse = require('./input/mouse.js');
4157 var _mouse2 = _interopRequireDefault(_mouse);
4159 var _websock = require('./websock.js');
4161 var _websock2 = _interopRequireDefault(_websock);
4163 var _des = require('./des.js');
4165 var _des2 = _interopRequireDefault(_des);
4167 var _keysym = require('./input/keysym.js');
4169 var _keysym2 = _interopRequireDefault(_keysym);
4171 var _xtscancodes = require('./input/xtscancodes.js');
4173 var _xtscancodes2 = _interopRequireDefault(_xtscancodes);
4175 var _inflator = require('./inflator.js');
4177 var _inflator2 = _interopRequireDefault(_inflator);
4179 var _encodings = require('./encodings.js');
4181 require('./util/polyfill.js');
4183 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
4185 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
4187 /*jslint white: false, browser: true */
4188 /*global window, Util, Display, Keyboard, Mouse, Websock, Websock_native, Base64, DES, KeyTable, Inflator, XtScancode */
4190 // How many seconds to wait for a disconnect to finish
4192 * noVNC: HTML5 VNC client
4193 * Copyright (C) 2012 Joel Martin
4194 * Copyright (C) 2017 Samuel Mannehed for Cendio AB
4195 * Licensed under MPL 2.0 (see LICENSE.txt)
4197 * See README.md for usage and integration instructions.
4199 * TIGHT decoder portion:
4200 * (c) 2012 Michael Tinglof, Joe Balaz, Les Piech (Mercuri.ca)
4203 var DISCONNECT_TIMEOUT = 3;
4205 function RFB(target, url, options) {
4207 throw Error("Must specify target");
4210 throw Error("Must specify URL");
4213 this._target = target;
4216 // Connection details
4217 options = options || {};
4218 this._rfb_credentials = options.credentials || {};
4219 this._shared = 'shared' in options ? !!options.shared : true;
4220 this._repeaterID = options.repeaterID || '';
4223 this._rfb_connection_state = '';
4224 this._rfb_init_state = '';
4225 this._rfb_auth_scheme = '';
4226 this._rfb_clean_disconnect = true;
4228 // Server capabilities
4229 this._rfb_version = 0;
4230 this._rfb_max_version = 3.8;
4231 this._rfb_tightvnc = false;
4232 this._rfb_xvp_ver = 0;
4235 this._fb_height = 0;
4239 this._capabilities = { power: false };
4241 this._supportsFence = false;
4243 this._supportsContinuousUpdates = false;
4244 this._enabledContinuousUpdates = false;
4246 this._supportsSetDesktopSize = false;
4247 this._screen_id = 0;
4248 this._screen_flags = 0;
4250 this._qemuExtKeyEventSupported = false;
4253 this._sock = null; // Websock object
4254 this._display = null; // Display object
4255 this._flushing = false; // Display flushing state
4256 this._keyboard = null; // Keyboard input handler object
4257 this._mouse = null; // Mouse input handler object
4260 this._disconnTimer = null; // disconnection timer
4261 this._resizeTimeout = null; // resize rate limiting
4263 // Decoder states and stats
4264 this._encHandlers = {};
4265 this._encStats = {};
4269 subrects: 0, // RRE and HEXTILE
4271 tiles: 0, // HEXTILE
4280 zlibs: [] // TIGHT zlib streams
4282 for (var i = 0; i < 4; i++) {
4283 this._FBU.zlibs[i] = new _inflator2.default();
4286 this._destBuff = null;
4287 this._paletteBuff = new Uint8Array(1024); // 256 * 4 (max palette size * max bytes-per-pixel)
4289 this._rre_chunk_sz = 100;
4305 this._mouse_buttonMask = 0;
4306 this._mouse_arr = [];
4307 this._viewportDragging = false;
4308 this._viewportDragPos = {};
4309 this._viewportHasMoved = false;
4311 // Bound event handlers
4312 this._eventHandlers = {
4313 focusCanvas: this._focusCanvas.bind(this),
4314 windowResize: this._windowResize.bind(this)
4318 Log.Debug(">> RFB.constructor");
4320 // Create DOM elements
4321 this._screen = document.createElement('div');
4322 this._screen.style.display = 'flex';
4323 this._screen.style.width = '100%';
4324 this._screen.style.height = '100%';
4325 this._screen.style.overflow = 'auto';
4326 this._screen.style.backgroundColor = 'rgb(40, 40, 40)';
4327 this._canvas = document.createElement('canvas');
4328 this._canvas.style.margin = 'auto';
4329 // Some browsers add an outline on focus
4330 this._canvas.style.outline = 'none';
4331 // IE miscalculates width without this :(
4332 this._canvas.style.flexShrink = '0';
4333 this._canvas.width = 0;
4334 this._canvas.height = 0;
4335 this._canvas.tabIndex = -1;
4336 this._screen.appendChild(this._canvas);
4338 // populate encHandlers with bound versions
4339 this._encHandlers[_encodings.encodings.encodingRaw] = RFB.encodingHandlers.RAW.bind(this);
4340 this._encHandlers[_encodings.encodings.encodingCopyRect] = RFB.encodingHandlers.COPYRECT.bind(this);
4341 this._encHandlers[_encodings.encodings.encodingRRE] = RFB.encodingHandlers.RRE.bind(this);
4342 this._encHandlers[_encodings.encodings.encodingHextile] = RFB.encodingHandlers.HEXTILE.bind(this);
4343 this._encHandlers[_encodings.encodings.encodingTight] = RFB.encodingHandlers.TIGHT.bind(this);
4345 this._encHandlers[_encodings.encodings.pseudoEncodingDesktopSize] = RFB.encodingHandlers.DesktopSize.bind(this);
4346 this._encHandlers[_encodings.encodings.pseudoEncodingLastRect] = RFB.encodingHandlers.last_rect.bind(this);
4347 this._encHandlers[_encodings.encodings.pseudoEncodingCursor] = RFB.encodingHandlers.Cursor.bind(this);
4348 this._encHandlers[_encodings.encodings.pseudoEncodingQEMUExtendedKeyEvent] = RFB.encodingHandlers.QEMUExtendedKeyEvent.bind(this);
4349 this._encHandlers[_encodings.encodings.pseudoEncodingExtendedDesktopSize] = RFB.encodingHandlers.ExtendedDesktopSize.bind(this);
4351 // NB: nothing that needs explicit teardown should be done
4352 // before this point, since this can throw an exception
4354 this._display = new _display2.default(this._canvas);
4356 Log.Error("Display exception: " + exc);
4359 this._display.onflush = this._onFlush.bind(this);
4360 this._display.clear();
4362 this._keyboard = new _keyboard2.default(this._canvas);
4363 this._keyboard.onkeyevent = this._handleKeyEvent.bind(this);
4365 this._mouse = new _mouse2.default(this._canvas);
4366 this._mouse.onmousebutton = this._handleMouseButton.bind(this);
4367 this._mouse.onmousemove = this._handleMouseMove.bind(this);
4369 this._sock = new _websock2.default();
4370 this._sock.on('message', this._handle_message.bind(this));
4371 this._sock.on('open', function () {
4372 if (this._rfb_connection_state === 'connecting' && this._rfb_init_state === '') {
4373 this._rfb_init_state = 'ProtocolVersion';
4374 Log.Debug("Starting VNC handshake");
4376 this._fail("Unexpected server connection while " + this._rfb_connection_state);
4379 this._sock.on('close', function (e) {
4380 Log.Debug("WebSocket on-close event");
4383 msg = "(code: " + e.code;
4385 msg += ", reason: " + e.reason;
4389 switch (this._rfb_connection_state) {
4391 this._fail("Connection closed " + msg);
4394 // Handle disconnects that were initiated server-side
4395 this._updateConnectionState('disconnecting');
4396 this._updateConnectionState('disconnected');
4398 case 'disconnecting':
4399 // Normal disconnection path
4400 this._updateConnectionState('disconnected');
4402 case 'disconnected':
4403 this._fail("Unexpected server disconnect " + "when already disconnected " + msg);
4406 this._fail("Unexpected server disconnect before connecting " + msg);
4409 this._sock.off('close');
4411 this._sock.on('error', function (e) {
4412 Log.Warn("WebSocket on-error event");
4415 // Slight delay of the actual connection so that the caller has
4416 // time to set up callbacks
4417 setTimeout(this._updateConnectionState.bind(this, 'connecting'));
4419 Log.Debug("<< RFB.constructor");
4423 // ===== PROPERTIES =====
4425 dragViewport: false,
4430 return this._viewOnly;
4432 set viewOnly(viewOnly) {
4433 this._viewOnly = viewOnly;
4435 if (this._rfb_connection_state === "connecting" || this._rfb_connection_state === "connected") {
4437 this._keyboard.ungrab();
4438 this._mouse.ungrab();
4440 this._keyboard.grab();
4446 get capabilities() {
4447 return this._capabilities;
4451 return this._mouse.touchButton;
4453 set touchButton(button) {
4454 this._mouse.touchButton = button;
4457 _clipViewport: false,
4458 get clipViewport() {
4459 return this._clipViewport;
4461 set clipViewport(viewport) {
4462 this._clipViewport = viewport;
4466 _scaleViewport: false,
4467 get scaleViewport() {
4468 return this._scaleViewport;
4470 set scaleViewport(scale) {
4471 this._scaleViewport = scale;
4472 // Scaling trumps clipping, so we may need to adjust
4473 // clipping when enabling or disabling scaling
4474 if (scale && this._clipViewport) {
4477 this._updateScale();
4478 if (!scale && this._clipViewport) {
4483 _resizeSession: false,
4484 get resizeSession() {
4485 return this._resizeSession;
4487 set resizeSession(resize) {
4488 this._resizeSession = resize;
4490 this._requestRemoteResize();
4494 // ===== PUBLIC METHODS =====
4496 disconnect: function () {
4497 this._updateConnectionState('disconnecting');
4498 this._sock.off('error');
4499 this._sock.off('message');
4500 this._sock.off('open');
4503 sendCredentials: function (creds) {
4504 this._rfb_credentials = creds;
4505 setTimeout(this._init_msg.bind(this), 0);
4508 sendCtrlAltDel: function () {
4509 if (this._rfb_connection_state !== 'connected' || this._viewOnly) {
4512 Log.Info("Sending Ctrl-Alt-Del");
4514 this.sendKey(_keysym2.default.XK_Control_L, "ControlLeft", true);
4515 this.sendKey(_keysym2.default.XK_Alt_L, "AltLeft", true);
4516 this.sendKey(_keysym2.default.XK_Delete, "Delete", true);
4517 this.sendKey(_keysym2.default.XK_Delete, "Delete", false);
4518 this.sendKey(_keysym2.default.XK_Alt_L, "AltLeft", false);
4519 this.sendKey(_keysym2.default.XK_Control_L, "ControlLeft", false);
4522 machineShutdown: function () {
4526 machineReboot: function () {
4530 machineReset: function () {
4534 // Send a key press. If 'down' is not specified then send a down key
4535 // followed by an up key.
4536 sendKey: function (keysym, code, down) {
4537 if (this._rfb_connection_state !== 'connected' || this._viewOnly) {
4541 if (down === undefined) {
4542 this.sendKey(keysym, code, true);
4543 this.sendKey(keysym, code, false);
4547 var scancode = _xtscancodes2.default[code];
4549 if (this._qemuExtKeyEventSupported && scancode) {
4551 keysym = keysym || 0;
4553 Log.Info("Sending key (" + (down ? "down" : "up") + "): keysym " + keysym + ", scancode " + scancode);
4555 RFB.messages.QEMUExtendedKeyEvent(this._sock, keysym, down, scancode);
4560 Log.Info("Sending keysym (" + (down ? "down" : "up") + "): " + keysym);
4561 RFB.messages.keyEvent(this._sock, keysym, down ? 1 : 0);
4565 focus: function () {
4566 this._canvas.focus();
4570 this._canvas.blur();
4573 clipboardPasteFrom: function (text) {
4574 if (this._rfb_connection_state !== 'connected' || this._viewOnly) {
4577 RFB.messages.clientCutText(this._sock, text);
4580 // ===== PRIVATE METHODS =====
4582 _connect: function () {
4583 Log.Debug(">> RFB.connect");
4585 Log.Info("connecting to " + this._url);
4588 // WebSocket.onopen transitions to the RFB init states
4589 this._sock.open(this._url, ['binary']);
4591 if (e.name === 'SyntaxError') {
4592 this._fail("Invalid host or port (" + e + ")");
4594 this._fail("Error when opening socket (" + e + ")");
4598 // Make our elements part of the page
4599 this._target.appendChild(this._screen);
4601 // Monitor size changes of the screen
4602 // FIXME: Use ResizeObserver, or hidden overflow
4603 window.addEventListener('resize', this._eventHandlers.windowResize);
4605 // Always grab focus on some kind of click event
4606 this._canvas.addEventListener("mousedown", this._eventHandlers.focusCanvas);
4607 this._canvas.addEventListener("touchstart", this._eventHandlers.focusCanvas);
4609 Log.Debug("<< RFB.connect");
4612 _disconnect: function () {
4613 Log.Debug(">> RFB.disconnect");
4614 this._canvas.removeEventListener("mousedown", this._eventHandlers.focusCanvas);
4615 this._canvas.removeEventListener("touchstart", this._eventHandlers.focusCanvas);
4616 window.removeEventListener('resize', this._eventHandlers.windowResize);
4617 this._keyboard.ungrab();
4618 this._mouse.ungrab();
4620 this._print_stats();
4622 this._target.removeChild(this._screen);
4624 if (e.name === 'NotFoundError') {
4625 // Some cases where the initial connection fails
4626 // can disconnect before the _screen is created
4631 clearTimeout(this._resizeTimeout);
4632 Log.Debug("<< RFB.disconnect");
4635 _print_stats: function () {
4636 var stats = this._encStats;
4638 Log.Info("Encoding stats for this connection:");
4639 Object.keys(stats).forEach(function (key) {
4641 if (s[0] + s[1] > 0) {
4642 Log.Info(" " + (0, _encodings.encodingName)(key) + ": " + s[0] + " rects");
4646 Log.Info("Encoding stats since page load:");
4647 Object.keys(stats).forEach(function (key) {
4649 Log.Info(" " + (0, _encodings.encodingName)(key) + ": " + s[1] + " rects");
4653 _focusCanvas: function (event) {
4654 // Respect earlier handlers' request to not do side-effects
4655 if (event.defaultPrevented) {
4659 if (!this.focusOnClick) {
4666 _windowResize: function (event) {
4667 // If the window resized then our screen element might have
4668 // as well. Update the viewport dimensions.
4669 window.requestAnimationFrame(function () {
4671 this._updateScale();
4674 if (this._resizeSession) {
4675 // Request changing the resolution of the remote display to
4676 // the size of the local browser viewport.
4678 // In order to not send multiple requests before the browser-resize
4679 // is finished we wait 0.5 seconds before sending the request.
4680 clearTimeout(this._resizeTimeout);
4681 this._resizeTimeout = setTimeout(this._requestRemoteResize.bind(this), 500);
4685 // Update state of clipping in Display object, and make sure the
4686 // configured viewport matches the current screen size
4687 _updateClip: function () {
4688 var cur_clip = this._display.clipViewport;
4689 var new_clip = this._clipViewport;
4691 if (this._scaleViewport) {
4692 // Disable viewport clipping if we are scaling
4696 if (cur_clip !== new_clip) {
4697 this._display.clipViewport = new_clip;
4701 // When clipping is enabled, the screen is limited to
4702 // the size of the container.
4703 let size = this._screenSize();
4704 this._display.viewportChangeSize(size.w, size.h);
4705 this._fixScrollbars();
4709 _updateScale: function () {
4710 if (!this._scaleViewport) {
4711 this._display.scale = 1.0;
4713 let size = this._screenSize();
4714 this._display.autoscale(size.w, size.h);
4716 this._fixScrollbars();
4719 // Requests a change of remote desktop size. This message is an extension
4720 // and may only be sent if we have received an ExtendedDesktopSize message
4721 _requestRemoteResize: function () {
4722 clearTimeout(this._resizeTimeout);
4723 this._resizeTimeout = null;
4725 if (!this._resizeSession || this._viewOnly || !this._supportsSetDesktopSize) {
4729 let size = this._screenSize();
4730 RFB.messages.setDesktopSize(this._sock, size.w, size.h, this._screen_id, this._screen_flags);
4732 Log.Debug('Requested new desktop size: ' + size.w + 'x' + size.h);
4735 // Gets the the size of the available screen
4736 _screenSize: function () {
4737 return { w: this._screen.offsetWidth,
4738 h: this._screen.offsetHeight };
4741 _fixScrollbars: function () {
4742 // This is a hack because Chrome screws up the calculation
4743 // for when scrollbars are needed. So to fix it we temporarily
4744 // toggle them off and on.
4745 var orig = this._screen.style.overflow;
4746 this._screen.style.overflow = 'hidden';
4747 // Force Chrome to recalculate the layout by asking for
4748 // an element's dimensions
4749 this._screen.getBoundingClientRect();
4750 this._screen.style.overflow = orig;
4754 * Connection states:
4758 * disconnected - permanent state
4760 _updateConnectionState: function (state) {
4761 var oldstate = this._rfb_connection_state;
4763 if (state === oldstate) {
4764 Log.Debug("Already in state '" + state + "', ignoring");
4768 // The 'disconnected' state is permanent for each RFB object
4769 if (oldstate === 'disconnected') {
4770 Log.Error("Tried changing state of a disconnected RFB object");
4774 // Ensure proper transitions before doing anything
4777 if (oldstate !== 'connecting') {
4778 Log.Error("Bad transition to connected state, " + "previous connection state: " + oldstate);
4783 case 'disconnected':
4784 if (oldstate !== 'disconnecting') {
4785 Log.Error("Bad transition to disconnected state, " + "previous connection state: " + oldstate);
4791 if (oldstate !== '') {
4792 Log.Error("Bad transition to connecting state, " + "previous connection state: " + oldstate);
4797 case 'disconnecting':
4798 if (oldstate !== 'connected' && oldstate !== 'connecting') {
4799 Log.Error("Bad transition to disconnecting state, " + "previous connection state: " + oldstate);
4805 Log.Error("Unknown connection state: " + state);
4809 // State change actions
4811 this._rfb_connection_state = state;
4813 var smsg = "New state '" + state + "', was '" + oldstate + "'.";
4816 if (this._disconnTimer && state !== 'disconnecting') {
4817 Log.Debug("Clearing disconnect timer");
4818 clearTimeout(this._disconnTimer);
4819 this._disconnTimer = null;
4821 // make sure we don't get a double event
4822 this._sock.off('close');
4831 var event = new CustomEvent("connect", { detail: {} });
4832 this.dispatchEvent(event);
4835 case 'disconnecting':
4838 this._disconnTimer = setTimeout(function () {
4839 Log.Error("Disconnection timed out.");
4840 this._updateConnectionState('disconnected');
4841 }.bind(this), DISCONNECT_TIMEOUT * 1000);
4844 case 'disconnected':
4845 event = new CustomEvent("disconnect", { detail: { clean: this._rfb_clean_disconnect } });
4846 this.dispatchEvent(event);
4851 /* Print errors and disconnect
4853 * The parameter 'details' is used for information that
4854 * should be logged but not sent to the user interface.
4856 _fail: function (details) {
4857 switch (this._rfb_connection_state) {
4858 case 'disconnecting':
4859 Log.Error("Failed when disconnecting: " + details);
4862 Log.Error("Failed while connected: " + details);
4865 Log.Error("Failed when connecting: " + details);
4868 Log.Error("RFB failure: " + details);
4871 this._rfb_clean_disconnect = false; //This is sent to the UI
4873 // Transition to disconnected without waiting for socket to close
4874 this._updateConnectionState('disconnecting');
4875 this._updateConnectionState('disconnected');
4880 _setCapability: function (cap, val) {
4881 this._capabilities[cap] = val;
4882 var event = new CustomEvent("capabilities", { detail: { capabilities: this._capabilities } });
4883 this.dispatchEvent(event);
4886 _handle_message: function () {
4887 if (this._sock.rQlen() === 0) {
4888 Log.Warn("handle_message called on an empty receive queue");
4892 switch (this._rfb_connection_state) {
4893 case 'disconnected':
4894 Log.Error("Got data while disconnected");
4898 if (this._flushing) {
4901 if (!this._normal_msg()) {
4904 if (this._sock.rQlen() === 0) {
4915 _handleKeyEvent: function (keysym, code, down) {
4916 this.sendKey(keysym, code, down);
4919 _handleMouseButton: function (x, y, down, bmask) {
4921 this._mouse_buttonMask |= bmask;
4923 this._mouse_buttonMask &= ~bmask;
4926 if (this.dragViewport) {
4927 if (down && !this._viewportDragging) {
4928 this._viewportDragging = true;
4929 this._viewportDragPos = { 'x': x, 'y': y };
4930 this._viewportHasMoved = false;
4932 // Skip sending mouse events
4935 this._viewportDragging = false;
4937 // If we actually performed a drag then we are done
4938 // here and should not send any mouse events
4939 if (this._viewportHasMoved) {
4943 // Otherwise we treat this as a mouse click event.
4944 // Send the button down event here, as the button up
4945 // event is sent at the end of this function.
4946 RFB.messages.pointerEvent(this._sock, this._display.absX(x), this._display.absY(y), bmask);
4950 if (this._viewOnly) {
4952 } // View only, skip mouse events
4954 if (this._rfb_connection_state !== 'connected') {
4957 RFB.messages.pointerEvent(this._sock, this._display.absX(x), this._display.absY(y), this._mouse_buttonMask);
4960 _handleMouseMove: function (x, y) {
4961 if (this._viewportDragging) {
4962 var deltaX = this._viewportDragPos.x - x;
4963 var deltaY = this._viewportDragPos.y - y;
4965 // The goal is to trigger on a certain physical width, the
4966 // devicePixelRatio brings us a bit closer but is not optimal.
4967 var dragThreshold = 10 * (window.devicePixelRatio || 1);
4969 if (this._viewportHasMoved || Math.abs(deltaX) > dragThreshold || Math.abs(deltaY) > dragThreshold) {
4970 this._viewportHasMoved = true;
4972 this._viewportDragPos = { 'x': x, 'y': y };
4973 this._display.viewportChangePos(deltaX, deltaY);
4976 // Skip sending mouse events
4980 if (this._viewOnly) {
4982 } // View only, skip mouse events
4984 if (this._rfb_connection_state !== 'connected') {
4987 RFB.messages.pointerEvent(this._sock, this._display.absX(x), this._display.absY(y), this._mouse_buttonMask);
4992 _negotiate_protocol_version: function () {
4993 if (this._sock.rQlen() < 12) {
4994 return this._fail("Received incomplete protocol version.");
4997 var sversion = this._sock.rQshiftStr(12).substr(4, 7);
4998 Log.Info("Server ProtocolVersion: " + sversion);
4999 var is_repeater = 0;
5002 // UltraVNC repeater
5006 case "003.006": // UltraVNC
5008 // Apple Remote Desktop
5009 this._rfb_version = 3.3;
5012 this._rfb_version = 3.7;
5015 case "004.000": // Intel AMT KVM
5016 case "004.001": // RealVNC 4.6
5019 this._rfb_version = 3.8;
5022 return this._fail("Invalid server version " + sversion);
5026 var repeaterID = "ID:" + this._repeaterID;
5027 while (repeaterID.length < 250) {
5030 this._sock.send_string(repeaterID);
5034 if (this._rfb_version > this._rfb_max_version) {
5035 this._rfb_version = this._rfb_max_version;
5038 var cversion = "00" + parseInt(this._rfb_version, 10) + ".00" + this._rfb_version * 10 % 10;
5039 this._sock.send_string("RFB " + cversion + "\n");
5040 Log.Debug('Sent ProtocolVersion: ' + cversion);
5042 this._rfb_init_state = 'Security';
5045 _negotiate_security: function () {
5046 // Polyfill since IE and PhantomJS doesn't have
5047 // TypedArray.includes()
5048 function includes(item, array) {
5049 for (var i = 0; i < array.length; i++) {
5050 if (array[i] === item) {
5057 if (this._rfb_version >= 3.7) {
5058 // Server sends supported list, client decides
5059 var num_types = this._sock.rQshift8();
5060 if (this._sock.rQwait("security type", num_types, 1)) {
5064 if (num_types === 0) {
5065 return this._handle_security_failure("no security types");
5068 var types = this._sock.rQshiftBytes(num_types);
5069 Log.Debug("Server security types: " + types);
5071 // Look for each auth in preferred order
5072 this._rfb_auth_scheme = 0;
5073 if (includes(1, types)) {
5074 this._rfb_auth_scheme = 1; // None
5075 } else if (includes(22, types)) {
5076 this._rfb_auth_scheme = 22; // XVP
5077 } else if (includes(16, types)) {
5078 this._rfb_auth_scheme = 16; // Tight
5079 } else if (includes(2, types)) {
5080 this._rfb_auth_scheme = 2; // VNC Auth
5082 return this._fail("Unsupported security types (types: " + types + ")");
5085 this._sock.send([this._rfb_auth_scheme]);
5088 if (this._sock.rQwait("security scheme", 4)) {
5091 this._rfb_auth_scheme = this._sock.rQshift32();
5094 this._rfb_init_state = 'Authentication';
5095 Log.Debug('Authenticating using scheme: ' + this._rfb_auth_scheme);
5097 return this._init_msg(); // jump to authentication
5101 * Get the security failure reason if sent from the server and
5102 * send the 'securityfailure' event.
5104 * - The optional parameter context can be used to add some extra
5105 * context to the log output.
5107 * - The optional parameter security_result_status can be used to
5108 * add a custom status code to the event.
5110 _handle_security_failure: function (context, security_result_status) {
5112 if (typeof context === 'undefined') {
5115 context = " on " + context;
5118 if (typeof security_result_status === 'undefined') {
5119 security_result_status = 1; // fail
5122 if (this._sock.rQwait("reason length", 4)) {
5125 let strlen = this._sock.rQshift32();
5129 if (this._sock.rQwait("reason", strlen, 8)) {
5132 reason = this._sock.rQshiftStr(strlen);
5135 if (reason !== "") {
5137 let event = new CustomEvent("securityfailure", { detail: { status: security_result_status, reason: reason } });
5138 this.dispatchEvent(event);
5140 return this._fail("Security negotiation failed" + context + " (reason: " + reason + ")");
5143 let event = new CustomEvent("securityfailure", { detail: { status: security_result_status } });
5144 this.dispatchEvent(event);
5146 return this._fail("Security negotiation failed" + context);
5151 _negotiate_xvp_auth: function () {
5152 if (!this._rfb_credentials.username || !this._rfb_credentials.password || !this._rfb_credentials.target) {
5153 var event = new CustomEvent("credentialsrequired", { detail: { types: ["username", "password", "target"] } });
5154 this.dispatchEvent(event);
5158 var xvp_auth_str = String.fromCharCode(this._rfb_credentials.username.length) + String.fromCharCode(this._rfb_credentials.target.length) + this._rfb_credentials.username + this._rfb_credentials.target;
5159 this._sock.send_string(xvp_auth_str);
5160 this._rfb_auth_scheme = 2;
5161 return this._negotiate_authentication();
5164 _negotiate_std_vnc_auth: function () {
5165 if (this._sock.rQwait("auth challenge", 16)) {
5169 if (!this._rfb_credentials.password) {
5170 var event = new CustomEvent("credentialsrequired", { detail: { types: ["password"] } });
5171 this.dispatchEvent(event);
5175 // TODO(directxman12): make genDES not require an Array
5176 var challenge = Array.prototype.slice.call(this._sock.rQshiftBytes(16));
5177 var response = RFB.genDES(this._rfb_credentials.password, challenge);
5178 this._sock.send(response);
5179 this._rfb_init_state = "SecurityResult";
5183 _negotiate_tight_tunnels: function (numTunnels) {
5184 var clientSupportedTunnelTypes = {
5185 0: { vendor: 'TGHT', signature: 'NOTUNNEL' }
5187 var serverSupportedTunnelTypes = {};
5188 // receive tunnel capabilities
5189 for (var i = 0; i < numTunnels; i++) {
5190 var cap_code = this._sock.rQshift32();
5191 var cap_vendor = this._sock.rQshiftStr(4);
5192 var cap_signature = this._sock.rQshiftStr(8);
5193 serverSupportedTunnelTypes[cap_code] = { vendor: cap_vendor, signature: cap_signature };
5196 // choose the notunnel type
5197 if (serverSupportedTunnelTypes[0]) {
5198 if (serverSupportedTunnelTypes[0].vendor != clientSupportedTunnelTypes[0].vendor || serverSupportedTunnelTypes[0].signature != clientSupportedTunnelTypes[0].signature) {
5199 return this._fail("Client's tunnel type had the incorrect " + "vendor or signature");
5201 this._sock.send([0, 0, 0, 0]); // use NOTUNNEL
5202 return false; // wait until we receive the sub auth count to continue
5204 return this._fail("Server wanted tunnels, but doesn't support " + "the notunnel type");
5208 _negotiate_tight_auth: function () {
5209 if (!this._rfb_tightvnc) {
5210 // first pass, do the tunnel negotiation
5211 if (this._sock.rQwait("num tunnels", 4)) {
5214 var numTunnels = this._sock.rQshift32();
5215 if (numTunnels > 0 && this._sock.rQwait("tunnel capabilities", 16 * numTunnels, 4)) {
5219 this._rfb_tightvnc = true;
5221 if (numTunnels > 0) {
5222 this._negotiate_tight_tunnels(numTunnels);
5223 return false; // wait until we receive the sub auth to continue
5227 // second pass, do the sub-auth negotiation
5228 if (this._sock.rQwait("sub auth count", 4)) {
5231 var subAuthCount = this._sock.rQshift32();
5232 if (subAuthCount === 0) {
5233 // empty sub-auth list received means 'no auth' subtype selected
5234 this._rfb_init_state = 'SecurityResult';
5238 if (this._sock.rQwait("sub auth capabilities", 16 * subAuthCount, 4)) {
5242 var clientSupportedTypes = {
5247 var serverSupportedTypes = [];
5249 for (var i = 0; i < subAuthCount; i++) {
5250 var capNum = this._sock.rQshift32();
5251 var capabilities = this._sock.rQshiftStr(12);
5252 serverSupportedTypes.push(capabilities);
5255 for (var authType in clientSupportedTypes) {
5256 if (serverSupportedTypes.indexOf(authType) != -1) {
5257 this._sock.send([0, 0, 0, clientSupportedTypes[authType]]);
5260 case 'STDVNOAUTH__':
5262 this._rfb_init_state = 'SecurityResult';
5264 case 'STDVVNCAUTH_':
5266 this._rfb_auth_scheme = 2;
5267 return this._init_msg();
5269 return this._fail("Unsupported tiny auth scheme " + "(scheme: " + authType + ")");
5274 return this._fail("No supported sub-auth types!");
5277 _negotiate_authentication: function () {
5278 switch (this._rfb_auth_scheme) {
5280 // connection failed
5281 return this._handle_security_failure("authentication scheme");
5285 if (this._rfb_version >= 3.8) {
5286 this._rfb_init_state = 'SecurityResult';
5289 this._rfb_init_state = 'ClientInitialisation';
5290 return this._init_msg();
5294 return this._negotiate_xvp_auth();
5297 // VNC authentication
5298 return this._negotiate_std_vnc_auth();
5301 // TightVNC Security Type
5302 return this._negotiate_tight_auth();
5305 return this._fail("Unsupported auth scheme (scheme: " + this._rfb_auth_scheme + ")");
5309 _handle_security_result: function () {
5310 if (this._sock.rQwait('VNC auth response ', 4)) {
5314 let status = this._sock.rQshift32();
5318 this._rfb_init_state = 'ClientInitialisation';
5319 Log.Debug('Authentication OK');
5320 return this._init_msg();
5322 if (this._rfb_version >= 3.8) {
5323 return this._handle_security_failure("security result", status);
5325 let event = new CustomEvent("securityfailure", { detail: { status: status } });
5326 this.dispatchEvent(event);
5328 return this._fail("Security handshake failed");
5333 _negotiate_server_init: function () {
5334 if (this._sock.rQwait("server initialization", 24)) {
5339 var width = this._sock.rQshift16();
5340 var height = this._sock.rQshift16();
5343 var bpp = this._sock.rQshift8();
5344 var depth = this._sock.rQshift8();
5345 var big_endian = this._sock.rQshift8();
5346 var true_color = this._sock.rQshift8();
5348 var red_max = this._sock.rQshift16();
5349 var green_max = this._sock.rQshift16();
5350 var blue_max = this._sock.rQshift16();
5351 var red_shift = this._sock.rQshift8();
5352 var green_shift = this._sock.rQshift8();
5353 var blue_shift = this._sock.rQshift8();
5354 this._sock.rQskipBytes(3); // padding
5356 // NB(directxman12): we don't want to call any callbacks or print messages until
5357 // *after* we're past the point where we could backtrack
5359 /* Connection name/title */
5360 var name_length = this._sock.rQshift32();
5361 if (this._sock.rQwait('server init name', name_length, 24)) {
5364 this._fb_name = (0, _strings.decodeUTF8)(this._sock.rQshiftStr(name_length));
5366 if (this._rfb_tightvnc) {
5367 if (this._sock.rQwait('TightVNC extended server init header', 8, 24 + name_length)) {
5370 // In TightVNC mode, ServerInit message is extended
5371 var numServerMessages = this._sock.rQshift16();
5372 var numClientMessages = this._sock.rQshift16();
5373 var numEncodings = this._sock.rQshift16();
5374 this._sock.rQskipBytes(2); // padding
5376 var totalMessagesLength = (numServerMessages + numClientMessages + numEncodings) * 16;
5377 if (this._sock.rQwait('TightVNC extended server init header', totalMessagesLength, 32 + name_length)) {
5381 // we don't actually do anything with the capability information that TIGHT sends,
5382 // so we just skip the all of this.
5384 // TIGHT server message capabilities
5385 this._sock.rQskipBytes(16 * numServerMessages);
5387 // TIGHT client message capabilities
5388 this._sock.rQskipBytes(16 * numClientMessages);
5390 // TIGHT encoding capabilities
5391 this._sock.rQskipBytes(16 * numEncodings);
5394 // NB(directxman12): these are down here so that we don't run them multiple times
5396 Log.Info("Screen: " + width + "x" + height + ", bpp: " + bpp + ", depth: " + depth + ", big_endian: " + big_endian + ", true_color: " + true_color + ", red_max: " + red_max + ", green_max: " + green_max + ", blue_max: " + blue_max + ", red_shift: " + red_shift + ", green_shift: " + green_shift + ", blue_shift: " + blue_shift);
5398 if (big_endian !== 0) {
5399 Log.Warn("Server native endian is not little endian");
5402 if (red_shift !== 16) {
5403 Log.Warn("Server native red-shift is not 16");
5406 if (blue_shift !== 0) {
5407 Log.Warn("Server native blue-shift is not 0");
5410 // we're past the point where we could backtrack, so it's safe to call this
5411 var event = new CustomEvent("desktopname", { detail: { name: this._fb_name } });
5412 this.dispatchEvent(event);
5414 this._resize(width, height);
5416 if (!this._viewOnly) {
5417 this._keyboard.grab();
5419 if (!this._viewOnly) {
5423 this._fb_depth = 24;
5425 if (this._fb_name === "Intel(r) AMT KVM") {
5426 Log.Warn("Intel AMT KVM only supports 8/16 bit depths. Using low color mode.");
5430 RFB.messages.pixelFormat(this._sock, this._fb_depth, true);
5431 this._sendEncodings();
5432 RFB.messages.fbUpdateRequest(this._sock, false, 0, 0, this._fb_width, this._fb_height);
5434 this._timing.fbu_rt_start = new Date().getTime();
5435 this._timing.pixels = 0;
5437 // Cursor will be server side until the server decides to honor
5438 // our request and send over the cursor image
5439 this._display.disableLocalCursor();
5441 this._updateConnectionState('connected');
5445 _sendEncodings: function () {
5448 // In preference order
5449 encs.push(_encodings.encodings.encodingCopyRect);
5450 // Only supported with full depth support
5451 if (this._fb_depth == 24) {
5452 encs.push(_encodings.encodings.encodingTight);
5453 encs.push(_encodings.encodings.encodingHextile);
5454 encs.push(_encodings.encodings.encodingRRE);
5456 encs.push(_encodings.encodings.encodingRaw);
5458 // Psuedo-encoding settings
5459 encs.push(_encodings.encodings.pseudoEncodingTightPNG);
5460 encs.push(_encodings.encodings.pseudoEncodingQualityLevel0 + 6);
5461 encs.push(_encodings.encodings.pseudoEncodingCompressLevel0 + 2);
5463 encs.push(_encodings.encodings.pseudoEncodingDesktopSize);
5464 encs.push(_encodings.encodings.pseudoEncodingLastRect);
5465 encs.push(_encodings.encodings.pseudoEncodingQEMUExtendedKeyEvent);
5466 encs.push(_encodings.encodings.pseudoEncodingExtendedDesktopSize);
5467 encs.push(_encodings.encodings.pseudoEncodingXvp);
5468 encs.push(_encodings.encodings.pseudoEncodingFence);
5469 encs.push(_encodings.encodings.pseudoEncodingContinuousUpdates);
5471 if ((0, _browser.supportsCursorURIs)() && !_browser.isTouchDevice && this._fb_depth == 24) {
5472 encs.push(_encodings.encodings.pseudoEncodingCursor);
5475 RFB.messages.clientEncodings(this._sock, encs);
5478 /* RFB protocol initialization states:
5483 * ClientInitialization - not triggered by server message
5484 * ServerInitialization
5486 _init_msg: function () {
5487 switch (this._rfb_init_state) {
5488 case 'ProtocolVersion':
5489 return this._negotiate_protocol_version();
5492 return this._negotiate_security();
5494 case 'Authentication':
5495 return this._negotiate_authentication();
5497 case 'SecurityResult':
5498 return this._handle_security_result();
5500 case 'ClientInitialisation':
5501 this._sock.send([this._shared ? 1 : 0]); // ClientInitialisation
5502 this._rfb_init_state = 'ServerInitialisation';
5505 case 'ServerInitialisation':
5506 return this._negotiate_server_init();
5509 return this._fail("Unknown init state (state: " + this._rfb_init_state + ")");
5513 _handle_set_colour_map_msg: function () {
5514 Log.Debug("SetColorMapEntries");
5516 return this._fail("Unexpected SetColorMapEntries message");
5519 _handle_server_cut_text: function () {
5520 Log.Debug("ServerCutText");
5522 if (this._sock.rQwait("ServerCutText header", 7, 1)) {
5525 this._sock.rQskipBytes(3); // Padding
5526 var length = this._sock.rQshift32();
5527 if (this._sock.rQwait("ServerCutText", length, 8)) {
5531 var text = this._sock.rQshiftStr(length);
5533 if (this._viewOnly) {
5537 var event = new CustomEvent("clipboard", { detail: { text: text } });
5538 this.dispatchEvent(event);
5543 _handle_server_fence_msg: function () {
5544 if (this._sock.rQwait("ServerFence header", 8, 1)) {
5547 this._sock.rQskipBytes(3); // Padding
5548 var flags = this._sock.rQshift32();
5549 var length = this._sock.rQshift8();
5551 if (this._sock.rQwait("ServerFence payload", length, 9)) {
5556 Log.Warn("Bad payload length (" + length + ") in fence response");
5560 var payload = this._sock.rQshiftStr(length);
5562 this._supportsFence = true;
5567 * (1<<0) - BlockBefore
5568 * (1<<1) - BlockAfter
5573 if (!(flags & 1 << 31)) {
5574 return this._fail("Unexpected fence response");
5577 // Filter out unsupported flags
5578 // FIXME: support syncNext
5579 flags &= 1 << 0 | 1 << 1;
5581 // BlockBefore and BlockAfter are automatically handled by
5582 // the fact that we process each incoming message
5584 RFB.messages.clientFence(this._sock, flags, payload);
5589 _handle_xvp_msg: function () {
5590 if (this._sock.rQwait("XVP version and message", 3, 1)) {
5593 this._sock.rQskip8(); // Padding
5594 var xvp_ver = this._sock.rQshift8();
5595 var xvp_msg = this._sock.rQshift8();
5600 Log.Error("XVP Operation Failed");
5604 this._rfb_xvp_ver = xvp_ver;
5605 Log.Info("XVP extensions enabled (version " + this._rfb_xvp_ver + ")");
5606 this._setCapability("power", true);
5609 this._fail("Illegal server XVP message (msg: " + xvp_msg + ")");
5616 _normal_msg: function () {
5619 if (this._FBU.rects > 0) {
5622 msg_type = this._sock.rQshift8();
5627 // FramebufferUpdate
5628 var ret = this._framebufferUpdate();
5629 if (ret && !this._enabledContinuousUpdates) {
5630 RFB.messages.fbUpdateRequest(this._sock, true, 0, 0, this._fb_width, this._fb_height);
5635 // SetColorMapEntries
5636 return this._handle_set_colour_map_msg();
5641 var event = new CustomEvent("bell", { detail: {} });
5642 this.dispatchEvent(event);
5647 return this._handle_server_cut_text();
5650 // EndOfContinuousUpdates
5651 var first = !this._supportsContinuousUpdates;
5652 this._supportsContinuousUpdates = true;
5653 this._enabledContinuousUpdates = false;
5655 this._enabledContinuousUpdates = true;
5656 this._updateContinuousUpdates();
5657 Log.Info("Enabling continuous updates.");
5659 // FIXME: We need to send a framebufferupdaterequest here
5660 // if we add support for turning off continuous updates
5666 return this._handle_server_fence_msg();
5670 return this._handle_xvp_msg();
5673 this._fail("Unexpected server message (type " + msg_type + ")");
5674 Log.Debug("sock.rQslice(0, 30): " + this._sock.rQslice(0, 30));
5679 _onFlush: function () {
5680 this._flushing = false;
5681 // Resume processing
5682 if (this._sock.rQlen() > 0) {
5683 this._handle_message();
5687 _framebufferUpdate: function () {
5691 if (this._FBU.rects === 0) {
5692 if (this._sock.rQwait("FBU header", 3, 1)) {
5695 this._sock.rQskip8(); // Padding
5696 this._FBU.rects = this._sock.rQshift16();
5697 this._FBU.bytes = 0;
5698 this._timing.cur_fbu = 0;
5699 if (this._timing.fbu_rt_start > 0) {
5700 now = new Date().getTime();
5701 Log.Info("First FBU latency: " + (now - this._timing.fbu_rt_start));
5704 // Make sure the previous frame is fully rendered first
5705 // to avoid building up an excessive queue
5706 if (this._display.pending()) {
5707 this._flushing = true;
5708 this._display.flush();
5713 while (this._FBU.rects > 0) {
5714 if (this._rfb_connection_state !== 'connected') {
5718 if (this._sock.rQwait("FBU", this._FBU.bytes)) {
5721 if (this._FBU.bytes === 0) {
5722 if (this._sock.rQwait("rect header", 12)) {
5725 /* New FramebufferUpdate */
5727 var hdr = this._sock.rQshiftBytes(12);
5728 this._FBU.x = (hdr[0] << 8) + hdr[1];
5729 this._FBU.y = (hdr[2] << 8) + hdr[3];
5730 this._FBU.width = (hdr[4] << 8) + hdr[5];
5731 this._FBU.height = (hdr[6] << 8) + hdr[7];
5732 this._FBU.encoding = parseInt((hdr[8] << 24) + (hdr[9] << 16) + (hdr[10] << 8) + hdr[11], 10);
5734 if (!this._encHandlers[this._FBU.encoding]) {
5735 this._fail("Unsupported encoding (encoding: " + this._FBU.encoding + ")");
5740 this._timing.last_fbu = new Date().getTime();
5742 ret = this._encHandlers[this._FBU.encoding]();
5744 now = new Date().getTime();
5745 this._timing.cur_fbu += now - this._timing.last_fbu;
5748 if (!(this._FBU.encoding in this._encStats)) {
5749 this._encStats[this._FBU.encoding] = [0, 0];
5751 this._encStats[this._FBU.encoding][0]++;
5752 this._encStats[this._FBU.encoding][1]++;
5753 this._timing.pixels += this._FBU.width * this._FBU.height;
5756 if (this._timing.pixels >= this._fb_width * this._fb_height) {
5757 if (this._FBU.width === this._fb_width && this._FBU.height === this._fb_height || this._timing.fbu_rt_start > 0) {
5758 this._timing.full_fbu_total += this._timing.cur_fbu;
5759 this._timing.full_fbu_cnt++;
5760 Log.Info("Timing of full FBU, curr: " + this._timing.cur_fbu + ", total: " + this._timing.full_fbu_total + ", cnt: " + this._timing.full_fbu_cnt + ", avg: " + this._timing.full_fbu_total / this._timing.full_fbu_cnt);
5763 if (this._timing.fbu_rt_start > 0) {
5764 var fbu_rt_diff = now - this._timing.fbu_rt_start;
5765 this._timing.fbu_rt_total += fbu_rt_diff;
5766 this._timing.fbu_rt_cnt++;
5767 Log.Info("full FBU round-trip, cur: " + fbu_rt_diff + ", total: " + this._timing.fbu_rt_total + ", cnt: " + this._timing.fbu_rt_cnt + ", avg: " + this._timing.fbu_rt_total / this._timing.fbu_rt_cnt);
5768 this._timing.fbu_rt_start = 0;
5777 this._display.flip();
5779 return true; // We finished this FBU
5782 _updateContinuousUpdates: function () {
5783 if (!this._enabledContinuousUpdates) {
5787 RFB.messages.enableContinuousUpdates(this._sock, true, 0, 0, this._fb_width, this._fb_height);
5790 _resize: function (width, height) {
5791 this._fb_width = width;
5792 this._fb_height = height;
5794 this._destBuff = new Uint8Array(this._fb_width * this._fb_height * 4);
5796 this._display.resize(this._fb_width, this._fb_height);
5798 // Adjust the visible viewport based on the new dimensions
5800 this._updateScale();
5802 this._timing.fbu_rt_start = new Date().getTime();
5803 this._updateContinuousUpdates();
5806 _xvpOp: function (ver, op) {
5807 if (this._rfb_xvp_ver < ver) {
5810 Log.Info("Sending XVP operation " + op + " (version " + ver + ")");
5811 RFB.messages.xvpOp(this._sock, ver, op);
5815 Object.assign(RFB.prototype, _eventtarget2.default);
5819 keyEvent: function (sock, keysym, down) {
5820 var buff = sock._sQ;
5821 var offset = sock._sQlen;
5823 buff[offset] = 4; // msg-type
5824 buff[offset + 1] = down;
5826 buff[offset + 2] = 0;
5827 buff[offset + 3] = 0;
5829 buff[offset + 4] = keysym >> 24;
5830 buff[offset + 5] = keysym >> 16;
5831 buff[offset + 6] = keysym >> 8;
5832 buff[offset + 7] = keysym;
5838 QEMUExtendedKeyEvent: function (sock, keysym, down, keycode) {
5839 function getRFBkeycode(xt_scancode) {
5840 var upperByte = keycode >> 8;
5841 var lowerByte = keycode & 0x00ff;
5842 if (upperByte === 0xe0 && lowerByte < 0x7f) {
5843 lowerByte = lowerByte | 0x80;
5849 var buff = sock._sQ;
5850 var offset = sock._sQlen;
5852 buff[offset] = 255; // msg-type
5853 buff[offset + 1] = 0; // sub msg-type
5855 buff[offset + 2] = down >> 8;
5856 buff[offset + 3] = down;
5858 buff[offset + 4] = keysym >> 24;
5859 buff[offset + 5] = keysym >> 16;
5860 buff[offset + 6] = keysym >> 8;
5861 buff[offset + 7] = keysym;
5863 var RFBkeycode = getRFBkeycode(keycode);
5865 buff[offset + 8] = RFBkeycode >> 24;
5866 buff[offset + 9] = RFBkeycode >> 16;
5867 buff[offset + 10] = RFBkeycode >> 8;
5868 buff[offset + 11] = RFBkeycode;
5874 pointerEvent: function (sock, x, y, mask) {
5875 var buff = sock._sQ;
5876 var offset = sock._sQlen;
5878 buff[offset] = 5; // msg-type
5880 buff[offset + 1] = mask;
5882 buff[offset + 2] = x >> 8;
5883 buff[offset + 3] = x;
5885 buff[offset + 4] = y >> 8;
5886 buff[offset + 5] = y;
5892 // TODO(directxman12): make this unicode compatible?
5893 clientCutText: function (sock, text) {
5894 var buff = sock._sQ;
5895 var offset = sock._sQlen;
5897 buff[offset] = 6; // msg-type
5899 buff[offset + 1] = 0; // padding
5900 buff[offset + 2] = 0; // padding
5901 buff[offset + 3] = 0; // padding
5903 var n = text.length;
5905 buff[offset + 4] = n >> 24;
5906 buff[offset + 5] = n >> 16;
5907 buff[offset + 6] = n >> 8;
5908 buff[offset + 7] = n;
5910 for (var i = 0; i < n; i++) {
5911 buff[offset + 8 + i] = text.charCodeAt(i);
5914 sock._sQlen += 8 + n;
5918 setDesktopSize: function (sock, width, height, id, flags) {
5919 var buff = sock._sQ;
5920 var offset = sock._sQlen;
5922 buff[offset] = 251; // msg-type
5923 buff[offset + 1] = 0; // padding
5924 buff[offset + 2] = width >> 8; // width
5925 buff[offset + 3] = width;
5926 buff[offset + 4] = height >> 8; // height
5927 buff[offset + 5] = height;
5929 buff[offset + 6] = 1; // number-of-screens
5930 buff[offset + 7] = 0; // padding
5933 buff[offset + 8] = id >> 24; // id
5934 buff[offset + 9] = id >> 16;
5935 buff[offset + 10] = id >> 8;
5936 buff[offset + 11] = id;
5937 buff[offset + 12] = 0; // x-position
5938 buff[offset + 13] = 0;
5939 buff[offset + 14] = 0; // y-position
5940 buff[offset + 15] = 0;
5941 buff[offset + 16] = width >> 8; // width
5942 buff[offset + 17] = width;
5943 buff[offset + 18] = height >> 8; // height
5944 buff[offset + 19] = height;
5945 buff[offset + 20] = flags >> 24; // flags
5946 buff[offset + 21] = flags >> 16;
5947 buff[offset + 22] = flags >> 8;
5948 buff[offset + 23] = flags;
5954 clientFence: function (sock, flags, payload) {
5955 var buff = sock._sQ;
5956 var offset = sock._sQlen;
5958 buff[offset] = 248; // msg-type
5960 buff[offset + 1] = 0; // padding
5961 buff[offset + 2] = 0; // padding
5962 buff[offset + 3] = 0; // padding
5964 buff[offset + 4] = flags >> 24; // flags
5965 buff[offset + 5] = flags >> 16;
5966 buff[offset + 6] = flags >> 8;
5967 buff[offset + 7] = flags;
5969 var n = payload.length;
5971 buff[offset + 8] = n; // length
5973 for (var i = 0; i < n; i++) {
5974 buff[offset + 9 + i] = payload.charCodeAt(i);
5977 sock._sQlen += 9 + n;
5981 enableContinuousUpdates: function (sock, enable, x, y, width, height) {
5982 var buff = sock._sQ;
5983 var offset = sock._sQlen;
5985 buff[offset] = 150; // msg-type
5986 buff[offset + 1] = enable; // enable-flag
5988 buff[offset + 2] = x >> 8; // x
5989 buff[offset + 3] = x;
5990 buff[offset + 4] = y >> 8; // y
5991 buff[offset + 5] = y;
5992 buff[offset + 6] = width >> 8; // width
5993 buff[offset + 7] = width;
5994 buff[offset + 8] = height >> 8; // height
5995 buff[offset + 9] = height;
6001 pixelFormat: function (sock, depth, true_color) {
6002 var buff = sock._sQ;
6003 var offset = sock._sQlen;
6009 } else if (depth > 8) {
6015 bits = Math.floor(depth / 3);
6017 buff[offset] = 0; // msg-type
6019 buff[offset + 1] = 0; // padding
6020 buff[offset + 2] = 0; // padding
6021 buff[offset + 3] = 0; // padding
6023 buff[offset + 4] = bpp; // bits-per-pixel
6024 buff[offset + 5] = depth; // depth
6025 buff[offset + 6] = 0; // little-endian
6026 buff[offset + 7] = true_color ? 1 : 0; // true-color
6028 buff[offset + 8] = 0; // red-max
6029 buff[offset + 9] = (1 << bits) - 1; // red-max
6031 buff[offset + 10] = 0; // green-max
6032 buff[offset + 11] = (1 << bits) - 1; // green-max
6034 buff[offset + 12] = 0; // blue-max
6035 buff[offset + 13] = (1 << bits) - 1; // blue-max
6037 buff[offset + 14] = bits * 2; // red-shift
6038 buff[offset + 15] = bits * 1; // green-shift
6039 buff[offset + 16] = bits * 0; // blue-shift
6041 buff[offset + 17] = 0; // padding
6042 buff[offset + 18] = 0; // padding
6043 buff[offset + 19] = 0; // padding
6049 clientEncodings: function (sock, encodings) {
6050 var buff = sock._sQ;
6051 var offset = sock._sQlen;
6053 buff[offset] = 2; // msg-type
6054 buff[offset + 1] = 0; // padding
6056 buff[offset + 2] = encodings.length >> 8;
6057 buff[offset + 3] = encodings.length;
6061 for (i = 0; i < encodings.length; i++) {
6062 var enc = encodings[i];
6063 buff[j] = enc >> 24;
6064 buff[j + 1] = enc >> 16;
6065 buff[j + 2] = enc >> 8;
6071 sock._sQlen += j - offset;
6075 fbUpdateRequest: function (sock, incremental, x, y, w, h) {
6076 var buff = sock._sQ;
6077 var offset = sock._sQlen;
6079 if (typeof x === "undefined") {
6082 if (typeof y === "undefined") {
6086 buff[offset] = 3; // msg-type
6087 buff[offset + 1] = incremental ? 1 : 0;
6089 buff[offset + 2] = x >> 8 & 0xFF;
6090 buff[offset + 3] = x & 0xFF;
6092 buff[offset + 4] = y >> 8 & 0xFF;
6093 buff[offset + 5] = y & 0xFF;
6095 buff[offset + 6] = w >> 8 & 0xFF;
6096 buff[offset + 7] = w & 0xFF;
6098 buff[offset + 8] = h >> 8 & 0xFF;
6099 buff[offset + 9] = h & 0xFF;
6105 xvpOp: function (sock, ver, op) {
6106 var buff = sock._sQ;
6107 var offset = sock._sQlen;
6109 buff[offset] = 250; // msg-type
6110 buff[offset + 1] = 0; // padding
6112 buff[offset + 2] = ver;
6113 buff[offset + 3] = op;
6120 RFB.genDES = function (password, challenge) {
6122 for (var i = 0; i < password.length; i++) {
6123 passwd.push(password.charCodeAt(i));
6125 return new _des2.default(passwd).encrypt(challenge);
6128 RFB.encodingHandlers = {
6130 if (this._FBU.lines === 0) {
6131 this._FBU.lines = this._FBU.height;
6134 var pixelSize = this._fb_depth == 8 ? 1 : 4;
6135 this._FBU.bytes = this._FBU.width * pixelSize; // at least a line
6136 if (this._sock.rQwait("RAW", this._FBU.bytes)) {
6139 var cur_y = this._FBU.y + (this._FBU.height - this._FBU.lines);
6140 var curr_height = Math.min(this._FBU.lines, Math.floor(this._sock.rQlen() / (this._FBU.width * pixelSize)));
6141 var data = this._sock.get_rQ();
6142 var index = this._sock.get_rQi();
6143 if (this._fb_depth == 8) {
6144 var pixels = this._FBU.width * curr_height;
6145 var newdata = new Uint8Array(pixels * 4);
6147 for (i = 0; i < pixels; i++) {
6148 newdata[i * 4 + 0] = (data[index + i] >> 0 & 0x3) * 255 / 3;
6149 newdata[i * 4 + 1] = (data[index + i] >> 2 & 0x3) * 255 / 3;
6150 newdata[i * 4 + 2] = (data[index + i] >> 4 & 0x3) * 255 / 3;
6151 newdata[i * 4 + 4] = 0;
6156 this._display.blitImage(this._FBU.x, cur_y, this._FBU.width, curr_height, data, index);
6157 this._sock.rQskipBytes(this._FBU.width * curr_height * pixelSize);
6158 this._FBU.lines -= curr_height;
6160 if (this._FBU.lines > 0) {
6161 this._FBU.bytes = this._FBU.width * pixelSize; // At least another line
6164 this._FBU.bytes = 0;
6170 COPYRECT: function () {
6171 this._FBU.bytes = 4;
6172 if (this._sock.rQwait("COPYRECT", 4)) {
6175 this._display.copyImage(this._sock.rQshift16(), this._sock.rQshift16(), this._FBU.x, this._FBU.y, this._FBU.width, this._FBU.height);
6178 this._FBU.bytes = 0;
6184 if (this._FBU.subrects === 0) {
6185 this._FBU.bytes = 4 + 4;
6186 if (this._sock.rQwait("RRE", 4 + 4)) {
6189 this._FBU.subrects = this._sock.rQshift32();
6190 color = this._sock.rQshiftBytes(4); // Background
6191 this._display.fillRect(this._FBU.x, this._FBU.y, this._FBU.width, this._FBU.height, color);
6194 while (this._FBU.subrects > 0 && this._sock.rQlen() >= 4 + 8) {
6195 color = this._sock.rQshiftBytes(4);
6196 var x = this._sock.rQshift16();
6197 var y = this._sock.rQshift16();
6198 var width = this._sock.rQshift16();
6199 var height = this._sock.rQshift16();
6200 this._display.fillRect(this._FBU.x + x, this._FBU.y + y, width, height, color);
6201 this._FBU.subrects--;
6204 if (this._FBU.subrects > 0) {
6205 var chunk = Math.min(this._rre_chunk_sz, this._FBU.subrects);
6206 this._FBU.bytes = (4 + 8) * chunk;
6209 this._FBU.bytes = 0;
6215 HEXTILE: function () {
6216 var rQ = this._sock.get_rQ();
6217 var rQi = this._sock.get_rQi();
6219 if (this._FBU.tiles === 0) {
6220 this._FBU.tiles_x = Math.ceil(this._FBU.width / 16);
6221 this._FBU.tiles_y = Math.ceil(this._FBU.height / 16);
6222 this._FBU.total_tiles = this._FBU.tiles_x * this._FBU.tiles_y;
6223 this._FBU.tiles = this._FBU.total_tiles;
6226 while (this._FBU.tiles > 0) {
6227 this._FBU.bytes = 1;
6228 if (this._sock.rQwait("HEXTILE subencoding", this._FBU.bytes)) {
6231 var subencoding = rQ[rQi]; // Peek
6232 if (subencoding > 30) {
6234 this._fail("Illegal hextile subencoding (subencoding: " + subencoding + ")");
6239 var curr_tile = this._FBU.total_tiles - this._FBU.tiles;
6240 var tile_x = curr_tile % this._FBU.tiles_x;
6241 var tile_y = Math.floor(curr_tile / this._FBU.tiles_x);
6242 var x = this._FBU.x + tile_x * 16;
6243 var y = this._FBU.y + tile_y * 16;
6244 var w = Math.min(16, this._FBU.x + this._FBU.width - x);
6245 var h = Math.min(16, this._FBU.y + this._FBU.height - y);
6247 // Figure out how much we are expecting
6248 if (subencoding & 0x01) {
6250 this._FBU.bytes += w * h * 4;
6252 if (subencoding & 0x02) {
6254 this._FBU.bytes += 4;
6256 if (subencoding & 0x04) {
6258 this._FBU.bytes += 4;
6260 if (subencoding & 0x08) {
6262 this._FBU.bytes++; // Since we aren't shifting it off
6263 if (this._sock.rQwait("hextile subrects header", this._FBU.bytes)) {
6266 subrects = rQ[rQi + this._FBU.bytes - 1]; // Peek
6267 if (subencoding & 0x10) {
6269 this._FBU.bytes += subrects * (4 + 2);
6271 this._FBU.bytes += subrects * 2;
6276 if (this._sock.rQwait("hextile", this._FBU.bytes)) {
6280 // We know the encoding and have a whole tile
6281 this._FBU.subencoding = rQ[rQi];
6283 if (this._FBU.subencoding === 0) {
6284 if (this._FBU.lastsubencoding & 0x01) {
6285 // Weird: ignore blanks are RAW
6286 Log.Debug(" Ignoring blank after RAW");
6288 this._display.fillRect(x, y, w, h, this._FBU.background);
6290 } else if (this._FBU.subencoding & 0x01) {
6292 this._display.blitImage(x, y, w, h, rQ, rQi);
6293 rQi += this._FBU.bytes - 1;
6295 if (this._FBU.subencoding & 0x02) {
6297 this._FBU.background = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]];
6300 if (this._FBU.subencoding & 0x04) {
6302 this._FBU.foreground = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]];
6306 this._display.startTile(x, y, w, h, this._FBU.background);
6307 if (this._FBU.subencoding & 0x08) {
6312 for (var s = 0; s < subrects; s++) {
6314 if (this._FBU.subencoding & 0x10) {
6316 color = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]];
6319 color = this._FBU.foreground;
6328 var sw = (wh >> 4) + 1;
6329 var sh = (wh & 0x0f) + 1;
6331 this._display.subTile(sx, sy, sw, sh, color);
6334 this._display.finishTile();
6336 this._sock.set_rQi(rQi);
6337 this._FBU.lastsubencoding = this._FBU.subencoding;
6338 this._FBU.bytes = 0;
6342 if (this._FBU.tiles === 0) {
6349 TIGHT: function () {
6350 this._FBU.bytes = 1; // compression-control byte
6351 if (this._sock.rQwait("TIGHT compression-control", this._FBU.bytes)) {
6355 var checksum = function (data) {
6357 for (var i = 0; i < data.length; i++) {
6359 if (sum > 65536) sum -= 65536;
6364 var resetStreams = 0;
6366 var decompress = function (data, expected) {
6367 for (var i = 0; i < 4; i++) {
6368 if (resetStreams >> i & 1) {
6369 this._FBU.zlibs[i].reset();
6370 Log.Info("Reset zlib stream " + i);
6374 //var uncompressed = this._FBU.zlibs[streamId].uncompress(data, 0);
6375 var uncompressed = this._FBU.zlibs[streamId].inflate(data, true, expected);
6376 /*if (uncompressed.status !== 0) {
6377 Log.Error("Invalid data in zlib stream");
6380 //return uncompressed.data;
6381 return uncompressed;
6384 var indexedToRGBX2Color = function (data, palette, width, height) {
6385 // Convert indexed (palette based) image data to RGB
6386 // TODO: reduce number of calculations inside loop
6387 var dest = this._destBuff;
6388 var w = Math.floor((width + 7) / 8);
6389 var w1 = Math.floor(width / 8);
6391 /*for (var y = 0; y < height; y++) {
6393 var yoffset = y * width;
6394 var ybitoffset = y * w;
6395 var xoffset, targetbyte;
6396 for (x = 0; x < w1; x++) {
6397 xoffset = yoffset + x * 8;
6398 targetbyte = data[ybitoffset + x];
6399 for (b = 7; b >= 0; b--) {
6400 dp = (xoffset + 7 - b) * 3;
6401 sp = (targetbyte >> b & 1) * 3;
6402 dest[dp] = palette[sp];
6403 dest[dp + 1] = palette[sp + 1];
6404 dest[dp + 2] = palette[sp + 2];
6407 xoffset = yoffset + x * 8;
6408 targetbyte = data[ybitoffset + x];
6409 for (b = 7; b >= 8 - width % 8; b--) {
6410 dp = (xoffset + 7 - b) * 3;
6411 sp = (targetbyte >> b & 1) * 3;
6412 dest[dp] = palette[sp];
6413 dest[dp + 1] = palette[sp + 1];
6414 dest[dp + 2] = palette[sp + 2];
6418 for (var y = 0; y < height; y++) {
6420 for (x = 0; x < w1; x++) {
6421 for (b = 7; b >= 0; b--) {
6422 dp = (y * width + x * 8 + 7 - b) * 4;
6423 sp = (data[y * w + x] >> b & 1) * 3;
6424 dest[dp] = palette[sp];
6425 dest[dp + 1] = palette[sp + 1];
6426 dest[dp + 2] = palette[sp + 2];
6431 for (b = 7; b >= 8 - width % 8; b--) {
6432 dp = (y * width + x * 8 + 7 - b) * 4;
6433 sp = (data[y * w + x] >> b & 1) * 3;
6434 dest[dp] = palette[sp];
6435 dest[dp + 1] = palette[sp + 1];
6436 dest[dp + 2] = palette[sp + 2];
6444 var indexedToRGBX = function (data, palette, width, height) {
6445 // Convert indexed (palette based) image data to RGB
6446 var dest = this._destBuff;
6447 var total = width * height * 4;
6448 for (var i = 0, j = 0; i < total; i += 4, j++) {
6449 var sp = data[j] * 3;
6450 dest[i] = palette[sp];
6451 dest[i + 1] = palette[sp + 1];
6452 dest[i + 2] = palette[sp + 2];
6459 var rQi = this._sock.get_rQi();
6460 var rQ = this._sock.rQwhole();
6462 var cl_header, cl_data;
6464 var handlePalette = function () {
6465 var numColors = rQ[rQi + 2] + 1;
6466 var paletteSize = numColors * 3;
6467 this._FBU.bytes += paletteSize;
6468 if (this._sock.rQwait("TIGHT palette " + cmode, this._FBU.bytes)) {
6472 var bpp = numColors <= 2 ? 1 : 8;
6473 var rowSize = Math.floor((this._FBU.width * bpp + 7) / 8);
6475 if (rowSize * this._FBU.height < 12) {
6478 cl_data = rowSize * this._FBU.height;
6479 //clength = [0, rowSize * this._FBU.height];
6481 // begin inline getTightCLength (returning two-item arrays is bad for performance with GC)
6482 var cl_offset = rQi + 3 + paletteSize;
6485 cl_data += rQ[cl_offset] & 0x7f;
6486 if (rQ[cl_offset] & 0x80) {
6488 cl_data += (rQ[cl_offset + 1] & 0x7f) << 7;
6489 if (rQ[cl_offset + 1] & 0x80) {
6491 cl_data += rQ[cl_offset + 2] << 14;
6494 // end inline getTightCLength
6497 this._FBU.bytes += cl_header + cl_data;
6498 if (this._sock.rQwait("TIGHT " + cmode, this._FBU.bytes)) {
6502 // Shift ctl, filter id, num colors, palette entries, and clength off
6503 this._sock.rQskipBytes(3);
6504 //var palette = this._sock.rQshiftBytes(paletteSize);
6505 this._sock.rQshiftTo(this._paletteBuff, paletteSize);
6506 this._sock.rQskipBytes(cl_header);
6509 data = this._sock.rQshiftBytes(cl_data);
6511 data = decompress(this._sock.rQshiftBytes(cl_data), rowSize * this._FBU.height);
6514 // Convert indexed (palette based) image data to RGB
6516 if (numColors == 2) {
6517 rgbx = indexedToRGBX2Color(data, this._paletteBuff, this._FBU.width, this._FBU.height);
6518 this._display.blitRgbxImage(this._FBU.x, this._FBU.y, this._FBU.width, this._FBU.height, rgbx, 0, false);
6520 rgbx = indexedToRGBX(data, this._paletteBuff, this._FBU.width, this._FBU.height);
6521 this._display.blitRgbxImage(this._FBU.x, this._FBU.y, this._FBU.width, this._FBU.height, rgbx, 0, false);
6527 var handleCopy = function () {
6529 var uncompressedSize = this._FBU.width * this._FBU.height * 3;
6530 if (uncompressedSize < 12) {
6533 cl_data = uncompressedSize;
6535 // begin inline getTightCLength (returning two-item arrays is for peformance with GC)
6536 var cl_offset = rQi + 1;
6539 cl_data += rQ[cl_offset] & 0x7f;
6540 if (rQ[cl_offset] & 0x80) {
6542 cl_data += (rQ[cl_offset + 1] & 0x7f) << 7;
6543 if (rQ[cl_offset + 1] & 0x80) {
6545 cl_data += rQ[cl_offset + 2] << 14;
6548 // end inline getTightCLength
6550 this._FBU.bytes = 1 + cl_header + cl_data;
6551 if (this._sock.rQwait("TIGHT " + cmode, this._FBU.bytes)) {
6555 // Shift ctl, clength off
6556 this._sock.rQshiftBytes(1 + cl_header);
6559 data = this._sock.rQshiftBytes(cl_data);
6561 data = decompress(this._sock.rQshiftBytes(cl_data), uncompressedSize);
6564 this._display.blitRgbImage(this._FBU.x, this._FBU.y, this._FBU.width, this._FBU.height, data, 0, false);
6569 var ctl = this._sock.rQpeek8();
6571 // Keep tight reset bits
6572 resetStreams = ctl & 0xF;
6574 // Figure out filter
6576 streamId = ctl & 0x3;
6578 if (ctl === 0x08) cmode = "fill";else if (ctl === 0x09) cmode = "jpeg";else if (ctl === 0x0A) cmode = "png";else if (ctl & 0x04) cmode = "filter";else if (ctl < 0x04) cmode = "copy";else return this._fail("Illegal tight compression received (ctl: " + ctl + ")");
6581 // fill use depth because TPIXELs drop the padding byte
6584 this._FBU.bytes += 3;
6588 this._FBU.bytes += 3;
6592 this._FBU.bytes += 3;
6595 // filter id + num colors if palette
6596 this._FBU.bytes += 2;
6602 if (this._sock.rQwait("TIGHT " + cmode, this._FBU.bytes)) {
6606 // Determine FBU.bytes
6610 this._display.fillRect(this._FBU.x, this._FBU.y, this._FBU.width, this._FBU.height, [rQ[rQi + 3], rQ[rQi + 2], rQ[rQi + 1]], false);
6611 this._sock.rQskipBytes(4);
6615 // begin inline getTightCLength (returning two-item arrays is for peformance with GC)
6616 var cl_offset = rQi + 1;
6619 cl_data += rQ[cl_offset] & 0x7f;
6620 if (rQ[cl_offset] & 0x80) {
6622 cl_data += (rQ[cl_offset + 1] & 0x7f) << 7;
6623 if (rQ[cl_offset + 1] & 0x80) {
6625 cl_data += rQ[cl_offset + 2] << 14;
6628 // end inline getTightCLength
6629 this._FBU.bytes = 1 + cl_header + cl_data; // ctl + clength size + jpeg-data
6630 if (this._sock.rQwait("TIGHT " + cmode, this._FBU.bytes)) {
6634 // We have everything, render it
6635 this._sock.rQskipBytes(1 + cl_header); // shift off clt + compact length
6636 data = this._sock.rQshiftBytes(cl_data);
6637 this._display.imageRect(this._FBU.x, this._FBU.y, "image/" + cmode, data);
6640 var filterId = rQ[rQi + 1];
6641 if (filterId === 1) {
6642 if (!handlePalette()) {
6646 // Filter 0, Copy could be valid here, but servers don't send it as an explicit filter
6647 // Filter 2, Gradient is valid but not use if jpeg is enabled
6648 this._fail("Unsupported tight subencoding received " + "(filter: " + filterId + ")");
6652 if (!handleCopy()) {
6658 this._FBU.bytes = 0;
6664 last_rect: function () {
6665 this._FBU.rects = 0;
6669 ExtendedDesktopSize: function () {
6670 this._FBU.bytes = 1;
6671 if (this._sock.rQwait("ExtendedDesktopSize", this._FBU.bytes)) {
6675 var firstUpdate = !this._supportsSetDesktopSize;
6676 this._supportsSetDesktopSize = true;
6678 // Normally we only apply the current resize mode after a
6679 // window resize event. However there is no such trigger on the
6680 // initial connect. And we don't know if the server supports
6681 // resizing until we've gotten here.
6683 this._requestRemoteResize();
6686 var number_of_screens = this._sock.rQpeek8();
6688 this._FBU.bytes = 4 + number_of_screens * 16;
6689 if (this._sock.rQwait("ExtendedDesktopSize", this._FBU.bytes)) {
6693 this._sock.rQskipBytes(1); // number-of-screens
6694 this._sock.rQskipBytes(3); // padding
6696 for (var i = 0; i < number_of_screens; i += 1) {
6697 // Save the id and flags of the first screen
6699 this._screen_id = this._sock.rQshiftBytes(4); // id
6700 this._sock.rQskipBytes(2); // x-position
6701 this._sock.rQskipBytes(2); // y-position
6702 this._sock.rQskipBytes(2); // width
6703 this._sock.rQskipBytes(2); // height
6704 this._screen_flags = this._sock.rQshiftBytes(4); // flags
6706 this._sock.rQskipBytes(16);
6711 * The x-position indicates the reason for the change:
6713 * 0 - server resized on its own
6714 * 1 - this client requested the resize
6715 * 2 - another client requested the resize
6718 // We need to handle errors when we requested the resize.
6719 if (this._FBU.x === 1 && this._FBU.y !== 0) {
6721 // The y-position indicates the status code from the server
6722 switch (this._FBU.y) {
6724 msg = "Resize is administratively prohibited";
6727 msg = "Out of resources";
6730 msg = "Invalid screen layout";
6733 msg = "Unknown reason";
6736 Log.Warn("Server did not accept the resize request: " + msg);
6738 this._resize(this._FBU.width, this._FBU.height);
6741 this._FBU.bytes = 0;
6742 this._FBU.rects -= 1;
6746 DesktopSize: function () {
6747 this._resize(this._FBU.width, this._FBU.height);
6748 this._FBU.bytes = 0;
6749 this._FBU.rects -= 1;
6753 Cursor: function () {
6754 Log.Debug(">> set_cursor");
6755 var x = this._FBU.x; // hotspot-x
6756 var y = this._FBU.y; // hotspot-y
6757 var w = this._FBU.width;
6758 var h = this._FBU.height;
6760 var pixelslength = w * h * 4;
6761 var masklength = Math.floor((w + 7) / 8) * h;
6763 this._FBU.bytes = pixelslength + masklength;
6764 if (this._sock.rQwait("cursor encoding", this._FBU.bytes)) {
6768 this._display.changeCursor(this._sock.rQshiftBytes(pixelslength), this._sock.rQshiftBytes(masklength), x, y, w, h);
6770 this._FBU.bytes = 0;
6773 Log.Debug("<< set_cursor");
6777 QEMUExtendedKeyEvent: function () {
6780 // Old Safari doesn't support creating keyboard events
6782 var keyboardEvent = document.createEvent("keyboardEvent");
6783 if (keyboardEvent.code !== undefined) {
6784 this._qemuExtKeyEventSupported = true;
6789 },{"./des.js":2,"./display.js":3,"./encodings.js":4,"./inflator.js":5,"./input/keyboard.js":8,"./input/keysym.js":9,"./input/mouse.js":11,"./input/xtscancodes.js":14,"./util/browser.js":16,"./util/eventtarget.js":18,"./util/logging.js":19,"./util/polyfill.js":20,"./util/strings.js":21,"./websock.js":29}],16:[function(require,module,exports){
6792 Object.defineProperty(exports, "__esModule", {
6795 exports.isTouchDevice = undefined;
6796 exports.supportsCursorURIs = supportsCursorURIs;
6797 exports.isMac = isMac;
6798 exports.isIE = isIE;
6799 exports.isEdge = isEdge;
6800 exports.isWindows = isWindows;
6801 exports.isIOS = isIOS;
6803 var _logging = require('./logging.js');
6805 var Log = _interopRequireWildcard(_logging);
6807 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
6810 var isTouchDevice = exports.isTouchDevice = 'ontouchstart' in document.documentElement ||
6811 // requried for Chrome debugger
6812 document.ontouchstart !== undefined ||
6813 // required for MS Surface
6814 navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0; /*
6815 * noVNC: HTML5 VNC client
6816 * Copyright (C) 2012 Joel Martin
6817 * Licensed under MPL 2.0 (see LICENSE.txt)
6819 * See README.md for usage and integration instructions.
6822 window.addEventListener('touchstart', function onFirstTouch() {
6823 exports.isTouchDevice = isTouchDevice = true;
6824 window.removeEventListener('touchstart', onFirstTouch, false);
6827 var _cursor_uris_supported = null;
6829 function supportsCursorURIs() {
6830 if (_cursor_uris_supported === null) {
6832 var target = document.createElement('canvas');
6833 target.style.cursor = 'url("data:image/x-icon;base64,AAACAAEACAgAAAIAAgA4AQAAFgAAACgAAAAIAAAAEAAAAAEAIAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAAAAAAAAAAAAAAAAAAAAA==") 2 2, default';
6835 if (target.style.cursor) {
6836 Log.Info("Data URI scheme cursor supported");
6837 _cursor_uris_supported = true;
6839 Log.Warn("Data URI scheme cursor not supported");
6840 _cursor_uris_supported = false;
6843 Log.Error("Data URI scheme cursor test exception: " + exc);
6844 _cursor_uris_supported = false;
6848 return _cursor_uris_supported;
6852 return navigator && !!/mac/i.exec(navigator.platform);
6856 return navigator && !!/trident/i.exec(navigator.userAgent);
6860 return navigator && !!/edge/i.exec(navigator.userAgent);
6863 function isWindows() {
6864 return navigator && !!/win/i.exec(navigator.platform);
6868 return navigator && (!!/ipad/i.exec(navigator.platform) || !!/iphone/i.exec(navigator.platform) || !!/ipod/i.exec(navigator.platform));
6870 },{"./logging.js":19}],17:[function(require,module,exports){
6873 Object.defineProperty(exports, "__esModule", {
6876 exports.getPointerEvent = getPointerEvent;
6877 exports.stopEvent = stopEvent;
6878 exports.setCapture = setCapture;
6879 exports.releaseCapture = releaseCapture;
6881 * noVNC: HTML5 VNC client
6882 * Copyright (C) 2012 Joel Martin
6883 * Licensed under MPL 2.0 (see LICENSE.txt)
6885 * See README.md for usage and integration instructions.
6889 * Cross-browser event and position routines
6892 function getPointerEvent(e) {
6893 return e.changedTouches ? e.changedTouches[0] : e.touches ? e.touches[0] : e;
6896 function stopEvent(e) {
6897 e.stopPropagation();
6901 // Emulate Element.setCapture() when not supported
6902 var _captureRecursion = false;
6903 var _captureElem = null;
6904 function _captureProxy(e) {
6905 // Recursion protection as we'll see our own event
6906 if (_captureRecursion) return;
6908 // Clone the event as we cannot dispatch an already dispatched event
6909 var newEv = new e.constructor(e.type, e);
6911 _captureRecursion = true;
6912 _captureElem.dispatchEvent(newEv);
6913 _captureRecursion = false;
6915 // Avoid double events
6916 e.stopPropagation();
6918 // Respect the wishes of the redirected event handlers
6919 if (newEv.defaultPrevented) {
6923 // Implicitly release the capture on button release
6924 if (e.type === "mouseup") {
6929 // Follow cursor style of target element
6930 function _captureElemChanged() {
6931 var captureElem = document.getElementById("noVNC_mouse_capture_elem");
6932 captureElem.style.cursor = window.getComputedStyle(_captureElem).cursor;
6934 var _captureObserver = new MutationObserver(_captureElemChanged);
6936 var _captureIndex = 0;
6938 function setCapture(elem) {
6939 if (elem.setCapture) {
6943 // IE releases capture on 'click' events which might not trigger
6944 elem.addEventListener('mouseup', releaseCapture);
6946 // Release any existing capture in case this method is
6947 // called multiple times without coordination
6950 var captureElem = document.getElementById("noVNC_mouse_capture_elem");
6952 if (captureElem === null) {
6953 captureElem = document.createElement("div");
6954 captureElem.id = "noVNC_mouse_capture_elem";
6955 captureElem.style.position = "fixed";
6956 captureElem.style.top = "0px";
6957 captureElem.style.left = "0px";
6958 captureElem.style.width = "100%";
6959 captureElem.style.height = "100%";
6960 captureElem.style.zIndex = 10000;
6961 captureElem.style.display = "none";
6962 document.body.appendChild(captureElem);
6964 // This is to make sure callers don't get confused by having
6965 // our blocking element as the target
6966 captureElem.addEventListener('contextmenu', _captureProxy);
6968 captureElem.addEventListener('mousemove', _captureProxy);
6969 captureElem.addEventListener('mouseup', _captureProxy);
6972 _captureElem = elem;
6975 // Track cursor and get initial cursor
6976 _captureObserver.observe(elem, { attributes: true });
6977 _captureElemChanged();
6979 captureElem.style.display = "";
6981 // We listen to events on window in order to keep tracking if it
6982 // happens to leave the viewport
6983 window.addEventListener('mousemove', _captureProxy);
6984 window.addEventListener('mouseup', _captureProxy);
6988 function releaseCapture() {
6989 if (document.releaseCapture) {
6991 document.releaseCapture();
6993 if (!_captureElem) {
6997 // There might be events already queued, so we need to wait for
6998 // them to flush. E.g. contextmenu in Microsoft Edge
6999 window.setTimeout(function (expected) {
7000 // Only clear it if it's the expected grab (i.e. no one
7001 // else has initiated a new grab)
7002 if (_captureIndex === expected) {
7003 _captureElem = null;
7005 }, 0, _captureIndex);
7007 _captureObserver.disconnect();
7009 var captureElem = document.getElementById("noVNC_mouse_capture_elem");
7010 captureElem.style.display = "none";
7012 window.removeEventListener('mousemove', _captureProxy);
7013 window.removeEventListener('mouseup', _captureProxy);
7016 },{}],18:[function(require,module,exports){
7019 Object.defineProperty(exports, "__esModule", {
7023 * noVNC: HTML5 VNC client
7024 * Copyright 2017 Pierre Ossman for Cendio AB
7025 * Licensed under MPL 2.0 (see LICENSE.txt)
7027 * See README.md for usage and integration instructions.
7030 var EventTargetMixin = {
7033 addEventListener: function (type, callback) {
7034 if (!this._listeners) {
7035 this._listeners = new Map();
7037 if (!this._listeners.has(type)) {
7038 this._listeners.set(type, new Set());
7040 this._listeners.get(type).add(callback);
7043 removeEventListener: function (type, callback) {
7044 if (!this._listeners || !this._listeners.has(type)) {
7047 this._listeners.get(type).delete(callback);
7050 dispatchEvent: function (event) {
7051 if (!this._listeners || !this._listeners.has(event.type)) {
7054 this._listeners.get(event.type).forEach(function (callback) {
7055 callback.call(this, event);
7057 return !event.defaultPrevented;
7061 exports.default = EventTargetMixin;
7062 },{}],19:[function(require,module,exports){
7065 Object.defineProperty(exports, "__esModule", {
7068 exports.init_logging = init_logging;
7069 exports.get_logging = get_logging;
7071 * noVNC: HTML5 VNC client
7072 * Copyright (C) 2012 Joel Martin
7073 * Licensed under MPL 2.0 (see LICENSE.txt)
7075 * See README.md for usage and integration instructions.
7079 * Logging/debug routines
7082 var _log_level = 'warn';
7084 var Debug = function (msg) {};
7085 var Info = function (msg) {};
7086 var Warn = function (msg) {};
7087 var Error = function (msg) {};
7089 function init_logging(level) {
7090 if (typeof level === 'undefined') {
7096 exports.Debug = Debug = exports.Info = Info = exports.Warn = Warn = exports.Error = Error = function (msg) {};
7097 if (typeof window.console !== "undefined") {
7100 exports.Debug = Debug = console.debug.bind(window.console);
7102 exports.Info = Info = console.info.bind(window.console);
7104 exports.Warn = Warn = console.warn.bind(window.console);
7106 exports.Error = Error = console.error.bind(window.console);
7110 throw new Error("invalid logging type '" + level + "'");
7114 function get_logging() {
7117 exports.Debug = Debug;
7118 exports.Info = Info;
7119 exports.Warn = Warn;
7120 exports.Error = Error;
7122 // Initialize logging level
7125 },{}],20:[function(require,module,exports){
7129 * noVNC: HTML5 VNC client
7130 * Copyright 2017 Pierre Ossman for noVNC
7131 * Licensed under MPL 2.0 or any later version (see LICENSE.txt)
7134 /* Polyfills to provide new APIs in old browsers */
7136 /* Object.assign() (taken from MDN) */
7137 if (typeof Object.assign != 'function') {
7138 // Must be writable: true, enumerable: false, configurable: true
7139 Object.defineProperty(Object, "assign", {
7140 value: function assign(target, varArgs) {
7141 // .length of function is 2
7144 if (target == null) {
7145 // TypeError if undefined or null
7146 throw new TypeError('Cannot convert undefined or null to object');
7149 var to = Object(target);
7151 for (var index = 1; index < arguments.length; index++) {
7152 var nextSource = arguments[index];
7154 if (nextSource != null) {
7155 // Skip over if undefined or null
7156 for (var nextKey in nextSource) {
7157 // Avoid bugs when hasOwnProperty is shadowed
7158 if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
7159 to[nextKey] = nextSource[nextKey];
7171 /* CustomEvent constructor (taken from MDN) */
7173 function CustomEvent(event, params) {
7174 params = params || { bubbles: false, cancelable: false, detail: undefined };
7175 var evt = document.createEvent('CustomEvent');
7176 evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
7180 CustomEvent.prototype = window.Event.prototype;
7182 if (typeof window.CustomEvent !== "function") {
7183 window.CustomEvent = CustomEvent;
7186 },{}],21:[function(require,module,exports){
7189 Object.defineProperty(exports, "__esModule", {
7192 exports.decodeUTF8 = decodeUTF8;
7194 * noVNC: HTML5 VNC client
7195 * Copyright (C) 2012 Joel Martin
7196 * Licensed under MPL 2.0 (see LICENSE.txt)
7198 * See README.md for usage and integration instructions.
7204 function decodeUTF8(utf8string) {
7207 return decodeURIComponent(escape(utf8string));
7209 },{}],22:[function(require,module,exports){
7212 Object.defineProperty(exports, "__esModule", {
7215 exports.shrinkBuf = shrinkBuf;
7216 exports.arraySet = arraySet;
7217 exports.flattenChunks = flattenChunks;
7218 // reduce buffer size, avoiding mem copy
7219 function shrinkBuf(buf, size) {
7220 if (buf.length === size) {
7224 return buf.subarray(0, size);
7230 function arraySet(dest, src, src_offs, len, dest_offs) {
7231 if (src.subarray && dest.subarray) {
7232 dest.set(src.subarray(src_offs, src_offs + len), dest_offs);
7235 // Fallback to ordinary array
7236 for (var i = 0; i < len; i++) {
7237 dest[dest_offs + i] = src[src_offs + i];
7241 // Join array of chunks to single array.
7242 function flattenChunks(chunks) {
7243 var i, l, len, pos, chunk, result;
7245 // calculate data length
7247 for (i = 0, l = chunks.length; i < l; i++) {
7248 len += chunks[i].length;
7252 result = new Uint8Array(len);
7254 for (i = 0, l = chunks.length; i < l; i++) {
7256 result.set(chunk, pos);
7257 pos += chunk.length;
7263 var Buf8 = exports.Buf8 = Uint8Array;
7264 var Buf16 = exports.Buf16 = Uint16Array;
7265 var Buf32 = exports.Buf32 = Int32Array;
7266 },{}],23:[function(require,module,exports){
7269 Object.defineProperty(exports, "__esModule", {
7272 exports.default = adler32;
7273 // Note: adler32 takes 12% for level 0 and 2% for level 6.
7274 // It doesn't worth to make additional optimizationa as in original.
7275 // Small size is preferable.
7277 function adler32(adler, buf, len, pos) {
7278 var s1 = adler & 0xffff | 0,
7279 s2 = adler >>> 16 & 0xffff | 0,
7283 // Set limit ~ twice less than 5552, to keep
7284 // s2 in 31-bits, because we force signed ints.
7285 // in other case %= will fail.
7286 n = len > 2000 ? 2000 : len;
7290 s1 = s1 + buf[pos++] | 0;
7298 return s1 | s2 << 16 | 0;
7300 },{}],24:[function(require,module,exports){
7303 Object.defineProperty(exports, "__esModule", {
7306 exports.default = makeTable;
7307 // Note: we can't get significant speed boost here.
7308 // So write code to minimize size - no pregenerated tables
7309 // and array tools dependencies.
7312 // Use ordinary array, since untyped makes no boost here
7313 function makeTable() {
7317 for (var n = 0; n < 256; n++) {
7319 for (var k = 0; k < 8; k++) {
7320 c = c & 1 ? 0xEDB88320 ^ c >>> 1 : c >>> 1;
7328 // Create table on load. Just 255 signed longs. Not a problem.
7329 var crcTable = makeTable();
7331 function crc32(crc, buf, len, pos) {
7337 for (var i = pos; i < end; i++) {
7338 crc = crc >>> 8 ^ t[(crc ^ buf[i]) & 0xFF];
7341 return crc ^ -1; // >>> 0;
7343 },{}],25:[function(require,module,exports){
7346 Object.defineProperty(exports, "__esModule", {
7349 exports.default = inflate_fast;
7350 // See state defs from inflate.js
7351 var BAD = 30; /* got a data error -- remain here until reset */
7352 var TYPE = 12; /* i: waiting for type bits, including last-flag bit */
7355 Decode literal, length, and distance codes and write out the resulting
7356 literal and match bytes until either not enough input or output is
7357 available, an end-of-block is encountered, or a data error is encountered.
7358 When large enough input and output buffers are supplied to inflate(), for
7359 example, a 16K input buffer and a 64K output buffer, more than 95% of the
7360 inflate execution time is spent in this routine.
7366 strm.avail_out >= 258
7367 start >= strm.avail_out
7370 On return, state.mode is one of:
7372 LEN -- ran out of enough output space or enough available input
7373 TYPE -- reached end of block code, inflate() to interpret next block
7374 BAD -- error in block data
7378 - The maximum input bits used by a length/distance pair is 15 bits for the
7379 length code, 5 bits for the length extra, 15 bits for the distance code,
7380 and 13 bits for the distance extra. This totals 48 bits, or six bytes.
7381 Therefore if strm.avail_in >= 6, then there is enough input to avoid
7382 checking for available input while decoding.
7384 - The maximum bytes that a single length/distance pair can output is 258
7385 bytes, which is the maximum length that can be coded. inflate_fast()
7386 requires strm.avail_out >= 258 for each loop to avoid checking for
7389 function inflate_fast(strm, start) {
7391 var _in; /* local strm.input */
7392 var last; /* have enough input while in < last */
7393 var _out; /* local strm.output */
7394 var beg; /* inflate()'s initial strm.output */
7395 var end; /* while out < end, enough space available */
7396 //#ifdef INFLATE_STRICT
7397 var dmax; /* maximum distance from zlib header */
7399 var wsize; /* window size or zero if not using window */
7400 var whave; /* valid bytes in the window */
7401 var wnext; /* window write index */
7402 // Use `s_window` instead `window`, avoid conflict with instrumentation tools
7403 var s_window; /* allocated sliding window, if wsize != 0 */
7404 var hold; /* local strm.hold */
7405 var bits; /* local strm.bits */
7406 var lcode; /* local strm.lencode */
7407 var dcode; /* local strm.distcode */
7408 var lmask; /* mask for first level of length codes */
7409 var dmask; /* mask for first level of distance codes */
7410 var here; /* retrieved table entry */
7411 var op; /* code bits, operation, extra bits, or */
7412 /* window position, window bytes to copy */
7413 var len; /* match length, unused bytes */
7414 var dist; /* match distance */
7415 var from; /* where to copy match from */
7418 var input, output; // JS specific, because we have no pointers
7420 /* copy state to local variables */
7422 //here = state.here;
7425 last = _in + (strm.avail_in - 5);
7426 _out = strm.next_out;
7427 output = strm.output;
7428 beg = _out - (start - strm.avail_out);
7429 end = _out + (strm.avail_out - 257);
7430 //#ifdef INFLATE_STRICT
7433 wsize = state.wsize;
7434 whave = state.whave;
7435 wnext = state.wnext;
7436 s_window = state.window;
7439 lcode = state.lencode;
7440 dcode = state.distcode;
7441 lmask = (1 << state.lenbits) - 1;
7442 dmask = (1 << state.distbits) - 1;
7444 /* decode literals and length/distances until end-of-block or not enough
7445 input data or output space */
7449 hold += input[_in++] << bits;
7451 hold += input[_in++] << bits;
7455 here = lcode[hold & lmask];
7459 op = here >>> 24 /*here.bits*/;
7462 op = here >>> 16 & 0xff /*here.op*/;
7465 //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
7466 // "inflate: literal '%c'\n" :
7467 // "inflate: literal 0x%02x\n", here.val));
7468 output[_out++] = here & 0xffff /*here.val*/;
7469 } else if (op & 16) {
7471 len = here & 0xffff /*here.val*/;
7472 op &= 15; /* number of extra bits */
7475 hold += input[_in++] << bits;
7478 len += hold & (1 << op) - 1;
7482 //Tracevv((stderr, "inflate: length %u\n", len));
7484 hold += input[_in++] << bits;
7486 hold += input[_in++] << bits;
7489 here = dcode[hold & dmask];
7493 op = here >>> 24 /*here.bits*/;
7496 op = here >>> 16 & 0xff /*here.op*/;
7500 dist = here & 0xffff /*here.val*/;
7501 op &= 15; /* number of extra bits */
7503 hold += input[_in++] << bits;
7506 hold += input[_in++] << bits;
7510 dist += hold & (1 << op) - 1;
7511 //#ifdef INFLATE_STRICT
7513 strm.msg = 'invalid distance too far back';
7520 //Tracevv((stderr, "inflate: distance %u\n", dist));
7521 op = _out - beg; /* max distance in output */
7523 /* see if copy from window */
7524 op = dist - op; /* distance back in window */
7527 strm.msg = 'invalid distance too far back';
7532 // (!) This block is disabled in zlib defailts,
7533 // don't enable it for binary compatibility
7534 //#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
7535 // if (len <= op - whave) {
7537 // output[_out++] = 0;
7541 // len -= op - whave;
7543 // output[_out++] = 0;
7544 // } while (--op > whave);
7546 // from = _out - dist;
7548 // output[_out++] = output[from++];
7554 from = 0; // window index
7555 from_source = s_window;
7557 /* very common case */
7560 /* some from window */
7563 output[_out++] = s_window[from++];
7565 from = _out - dist; /* rest from output */
7566 from_source = output;
7568 } else if (wnext < op) {
7569 /* wrap around window */
7570 from += wsize + wnext - op;
7573 /* some from end of window */
7576 output[_out++] = s_window[from++];
7580 /* some from start of window */
7584 output[_out++] = s_window[from++];
7586 from = _out - dist; /* rest from output */
7587 from_source = output;
7591 /* contiguous in window */
7594 /* some from window */
7597 output[_out++] = s_window[from++];
7599 from = _out - dist; /* rest from output */
7600 from_source = output;
7604 output[_out++] = from_source[from++];
7605 output[_out++] = from_source[from++];
7606 output[_out++] = from_source[from++];
7610 output[_out++] = from_source[from++];
7612 output[_out++] = from_source[from++];
7616 from = _out - dist; /* copy direct from output */
7618 /* minimum length is three */
7619 output[_out++] = output[from++];
7620 output[_out++] = output[from++];
7621 output[_out++] = output[from++];
7625 output[_out++] = output[from++];
7627 output[_out++] = output[from++];
7631 } else if ((op & 64) === 0) {
7632 /* 2nd level distance code */
7633 here = dcode[(here & 0xffff) + ( /*here.val*/hold & (1 << op) - 1)];
7636 strm.msg = 'invalid distance code';
7641 break; // need to emulate goto via "continue"
7643 } else if ((op & 64) === 0) {
7644 /* 2nd level length code */
7645 here = lcode[(here & 0xffff) + ( /*here.val*/hold & (1 << op) - 1)];
7647 } else if (op & 32) {
7649 //Tracevv((stderr, "inflate: end of block\n"));
7653 strm.msg = 'invalid literal/length code';
7658 break; // need to emulate goto via "continue"
7660 } while (_in < last && _out < end);
7662 /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
7666 hold &= (1 << bits) - 1;
7668 /* update state and return */
7670 strm.next_out = _out;
7671 strm.avail_in = _in < last ? 5 + (last - _in) : 5 - (_in - last);
7672 strm.avail_out = _out < end ? 257 + (end - _out) : 257 - (_out - end);
7677 },{}],26:[function(require,module,exports){
7680 Object.defineProperty(exports, "__esModule", {
7683 exports.inflateInfo = exports.inflateSetDictionary = exports.inflateGetHeader = exports.inflateEnd = exports.inflate = exports.inflateInit2 = exports.inflateInit = exports.inflateResetKeep = exports.inflateReset2 = exports.inflateReset = undefined;
7685 var _common = require("../utils/common.js");
7687 var utils = _interopRequireWildcard(_common);
7689 var _adler = require("./adler32.js");
7691 var _adler2 = _interopRequireDefault(_adler);
7693 var _crc = require("./crc32.js");
7695 var _crc2 = _interopRequireDefault(_crc);
7697 var _inffast = require("./inffast.js");
7699 var _inffast2 = _interopRequireDefault(_inffast);
7701 var _inftrees = require("./inftrees.js");
7703 var _inftrees2 = _interopRequireDefault(_inftrees);
7705 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
7707 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
7713 /* Public constants ==========================================================*/
7714 /* ===========================================================================*/
7716 /* Allowed flush values; see deflate() and inflate() below for details */
7717 //var Z_NO_FLUSH = 0;
7718 //var Z_PARTIAL_FLUSH = 1;
7719 //var Z_SYNC_FLUSH = 2;
7720 //var Z_FULL_FLUSH = 3;
7725 /* Return codes for the compression/decompression functions. Negative values
7726 * are errors, positive values are used for special but normal events.
7729 var Z_STREAM_END = 1;
7730 var Z_NEED_DICT = 2;
7732 var Z_STREAM_ERROR = -2;
7733 var Z_DATA_ERROR = -3;
7734 var Z_MEM_ERROR = -4;
7735 var Z_BUF_ERROR = -5;
7736 //var Z_VERSION_ERROR = -6;
7738 /* The deflate compression method */
7741 /* STATES ====================================================================*/
7742 /* ===========================================================================*/
7744 var HEAD = 1; /* i: waiting for magic header */
7745 var FLAGS = 2; /* i: waiting for method and flags (gzip) */
7746 var TIME = 3; /* i: waiting for modification time (gzip) */
7747 var OS = 4; /* i: waiting for extra flags and operating system (gzip) */
7748 var EXLEN = 5; /* i: waiting for extra length (gzip) */
7749 var EXTRA = 6; /* i: waiting for extra bytes (gzip) */
7750 var NAME = 7; /* i: waiting for end of file name (gzip) */
7751 var COMMENT = 8; /* i: waiting for end of comment (gzip) */
7752 var HCRC = 9; /* i: waiting for header crc (gzip) */
7753 var DICTID = 10; /* i: waiting for dictionary check value */
7754 var DICT = 11; /* waiting for inflateSetDictionary() call */
7755 var TYPE = 12; /* i: waiting for type bits, including last-flag bit */
7756 var TYPEDO = 13; /* i: same, but skip check to exit inflate on new block */
7757 var STORED = 14; /* i: waiting for stored size (length and complement) */
7758 var COPY_ = 15; /* i/o: same as COPY below, but only first time in */
7759 var COPY = 16; /* i/o: waiting for input or output to copy stored block */
7760 var TABLE = 17; /* i: waiting for dynamic block table lengths */
7761 var LENLENS = 18; /* i: waiting for code length code lengths */
7762 var CODELENS = 19; /* i: waiting for length/lit and distance code lengths */
7763 var LEN_ = 20; /* i: same as LEN below, but only first time in */
7764 var LEN = 21; /* i: waiting for length/lit/eob code */
7765 var LENEXT = 22; /* i: waiting for length extra bits */
7766 var DIST = 23; /* i: waiting for distance code */
7767 var DISTEXT = 24; /* i: waiting for distance extra bits */
7768 var MATCH = 25; /* o: waiting for output space to copy string */
7769 var LIT = 26; /* o: waiting for output space to write literal */
7770 var CHECK = 27; /* i: waiting for 32-bit check value */
7771 var LENGTH = 28; /* i: waiting for 32-bit length (gzip) */
7772 var DONE = 29; /* finished check, done -- remain here until reset */
7773 var BAD = 30; /* got a data error -- remain here until reset */
7774 var MEM = 31; /* got an inflate() memory error -- remain here until reset */
7775 var SYNC = 32; /* looking for synchronization bytes to restart inflate() */
7777 /* ===========================================================================*/
7779 var ENOUGH_LENS = 852;
7780 var ENOUGH_DISTS = 592;
7781 //var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS);
7784 /* 32K LZ77 window */
7785 var DEF_WBITS = MAX_WBITS;
7787 function zswap32(q) {
7788 return (q >>> 24 & 0xff) + (q >>> 8 & 0xff00) + ((q & 0xff00) << 8) + ((q & 0xff) << 24);
7791 function InflateState() {
7792 this.mode = 0; /* current inflate mode */
7793 this.last = false; /* true if processing last block */
7794 this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */
7795 this.havedict = false; /* true if dictionary provided */
7796 this.flags = 0; /* gzip header method and flags (0 if zlib) */
7797 this.dmax = 0; /* zlib header max distance (INFLATE_STRICT) */
7798 this.check = 0; /* protected copy of check value */
7799 this.total = 0; /* protected copy of output count */
7801 this.head = null; /* where to save gzip header information */
7803 /* sliding window */
7804 this.wbits = 0; /* log base 2 of requested window size */
7805 this.wsize = 0; /* window size or zero if not using window */
7806 this.whave = 0; /* valid bytes in the window */
7807 this.wnext = 0; /* window write index */
7808 this.window = null; /* allocated sliding window, if needed */
7810 /* bit accumulator */
7811 this.hold = 0; /* input bit accumulator */
7812 this.bits = 0; /* number of bits in "in" */
7814 /* for string and stored block copying */
7815 this.length = 0; /* literal or length of data to copy */
7816 this.offset = 0; /* distance back to copy string from */
7818 /* for table and code decoding */
7819 this.extra = 0; /* extra bits needed */
7821 /* fixed and dynamic code tables */
7822 this.lencode = null; /* starting table for length/literal codes */
7823 this.distcode = null; /* starting table for distance codes */
7824 this.lenbits = 0; /* index bits for lencode */
7825 this.distbits = 0; /* index bits for distcode */
7827 /* dynamic table building */
7828 this.ncode = 0; /* number of code length code lengths */
7829 this.nlen = 0; /* number of length code lengths */
7830 this.ndist = 0; /* number of distance code lengths */
7831 this.have = 0; /* number of code lengths in lens[] */
7832 this.next = null; /* next available space in codes[] */
7834 this.lens = new utils.Buf16(320); /* temporary storage for code lengths */
7835 this.work = new utils.Buf16(288); /* work area for code table building */
7838 because we don't have pointers in js, we use lencode and distcode directly
7839 as buffers so we don't need codes
7841 //this.codes = new utils.Buf32(ENOUGH); /* space for code tables */
7842 this.lendyn = null; /* dynamic table for length/literal codes (JS specific) */
7843 this.distdyn = null; /* dynamic table for distance codes (JS specific) */
7844 this.sane = 0; /* if false, allow invalid distance too far */
7845 this.back = 0; /* bits back of last unprocessed length/lit */
7846 this.was = 0; /* initial length of match */
7849 function inflateResetKeep(strm) {
7852 if (!strm || !strm.state) {
7853 return Z_STREAM_ERROR;
7856 strm.total_in = strm.total_out = state.total = 0;
7857 strm.msg = ''; /*Z_NULL*/
7859 /* to support ill-conceived Java test suite */
7860 strm.adler = state.wrap & 1;
7866 state.head = null /*Z_NULL*/;
7869 //state.lencode = state.distcode = state.next = state.codes;
7870 state.lencode = state.lendyn = new utils.Buf32(ENOUGH_LENS);
7871 state.distcode = state.distdyn = new utils.Buf32(ENOUGH_DISTS);
7875 //Tracev((stderr, "inflate: reset\n"));
7879 function inflateReset(strm) {
7882 if (!strm || !strm.state) {
7883 return Z_STREAM_ERROR;
7889 return inflateResetKeep(strm);
7892 function inflateReset2(strm, windowBits) {
7897 if (!strm || !strm.state) {
7898 return Z_STREAM_ERROR;
7902 /* extract wrap request from windowBits parameter */
7903 if (windowBits < 0) {
7905 windowBits = -windowBits;
7907 wrap = (windowBits >> 4) + 1;
7908 if (windowBits < 48) {
7913 /* set number of window bits, free window if different */
7914 if (windowBits && (windowBits < 8 || windowBits > 15)) {
7915 return Z_STREAM_ERROR;
7917 if (state.window !== null && state.wbits !== windowBits) {
7918 state.window = null;
7921 /* update state and reset the rest of it */
7923 state.wbits = windowBits;
7924 return inflateReset(strm);
7927 function inflateInit2(strm, windowBits) {
7932 return Z_STREAM_ERROR;
7934 //strm.msg = Z_NULL; /* in case we return an error */
7936 state = new InflateState();
7938 //if (state === Z_NULL) return Z_MEM_ERROR;
7939 //Tracev((stderr, "inflate: allocated\n"));
7941 state.window = null /*Z_NULL*/;
7942 ret = inflateReset2(strm, windowBits);
7944 strm.state = null /*Z_NULL*/;
7949 function inflateInit(strm) {
7950 return inflateInit2(strm, DEF_WBITS);
7954 Return state with length and distance decoding tables and index sizes set to
7955 fixed code decoding. Normally this returns fixed tables from inffixed.h.
7956 If BUILDFIXED is defined, then instead this routine builds the tables the
7957 first time it's called, and returns those tables the first time and
7958 thereafter. This reduces the size of the code by about 2K bytes, in
7959 exchange for a little execution time. However, BUILDFIXED should not be
7960 used for threaded applications, since the rewriting of the tables and virgin
7961 may not be thread-safe.
7965 var lenfix, distfix; // We have no pointers in JS, so keep tables separate
7967 function fixedtables(state) {
7968 /* build fixed huffman tables if first call (may not be thread safe) */
7972 lenfix = new utils.Buf32(512);
7973 distfix = new utils.Buf32(32);
7975 /* literal/length table */
7978 state.lens[sym++] = 8;
7981 state.lens[sym++] = 9;
7984 state.lens[sym++] = 7;
7987 state.lens[sym++] = 8;
7990 (0, _inftrees2.default)(LENS, state.lens, 0, 288, lenfix, 0, state.work, { bits: 9 });
7992 /* distance table */
7995 state.lens[sym++] = 5;
7998 (0, _inftrees2.default)(DISTS, state.lens, 0, 32, distfix, 0, state.work, { bits: 5 });
8000 /* do this just once */
8004 state.lencode = lenfix;
8006 state.distcode = distfix;
8011 Update the window with the last wsize (normally 32K) bytes written before
8012 returning. If window does not exist yet, create it. This is only called
8013 when a window is already in use, or when output has been written during this
8014 inflate call, but the end of the deflate stream has not been reached yet.
8015 It is also called to create a window for dictionary data when a dictionary
8018 Providing output buffers larger than 32K to inflate() should provide a speed
8019 advantage, since only the last 32K of output is copied to the sliding window
8020 upon return from inflate(), and since all distances after the first 32K of
8021 output will fall in the output data, making match copies simpler and faster.
8022 The advantage may be dependent on the size of the processor's data caches.
8024 function updatewindow(strm, src, end, copy) {
8026 var state = strm.state;
8028 /* if it hasn't been done already, allocate space for the window */
8029 if (state.window === null) {
8030 state.wsize = 1 << state.wbits;
8034 state.window = new utils.Buf8(state.wsize);
8037 /* copy state->wsize or less output bytes into the circular window */
8038 if (copy >= state.wsize) {
8039 utils.arraySet(state.window, src, end - state.wsize, state.wsize, 0);
8041 state.whave = state.wsize;
8043 dist = state.wsize - state.wnext;
8047 //zmemcpy(state->window + state->wnext, end - copy, dist);
8048 utils.arraySet(state.window, src, end - copy, dist, state.wnext);
8051 //zmemcpy(state->window, end - copy, copy);
8052 utils.arraySet(state.window, src, end - copy, copy, 0);
8054 state.whave = state.wsize;
8056 state.wnext += dist;
8057 if (state.wnext === state.wsize) {
8060 if (state.whave < state.wsize) {
8061 state.whave += dist;
8068 function inflate(strm, flush) {
8070 var input, output; // input/output buffers
8071 var next; /* next input INDEX */
8072 var put; /* next output INDEX */
8073 var have, left; /* available input and output */
8074 var hold; /* bit buffer */
8075 var bits; /* bits in bit buffer */
8076 var _in, _out; /* save starting available input and output */
8077 var copy; /* number of stored or match bytes to copy */
8078 var from; /* where to copy match bytes from */
8080 var here = 0; /* current decoding table entry */
8081 var here_bits, here_op, here_val; // paked "here" denormalized (JS specific)
8082 //var last; /* parent table entry */
8083 var last_bits, last_op, last_val; // paked "last" denormalized (JS specific)
8084 var len; /* length to copy for repeats, bits to drop */
8085 var ret; /* return code */
8086 var hbuf = new utils.Buf8(4); /* buffer for gzip header crc calculation */
8089 var n; // temporary var for NEED_BITS
8091 var order = /* permutation of code lengths */
8092 [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15];
8094 if (!strm || !strm.state || !strm.output || !strm.input && strm.avail_in !== 0) {
8095 return Z_STREAM_ERROR;
8099 if (state.mode === TYPE) {
8100 state.mode = TYPEDO;
8104 put = strm.next_out;
8105 output = strm.output;
8106 left = strm.avail_out;
8107 next = strm.next_in;
8109 have = strm.avail_in;
8118 inf_leave: // goto emulation
8120 switch (state.mode) {
8122 if (state.wrap === 0) {
8123 state.mode = TYPEDO;
8132 hold += input[next++] << bits;
8136 if (state.wrap & 2 && hold === 0x8b1f) {
8138 state.check = 0 /*crc32(0L, Z_NULL, 0)*/;
8139 //=== CRC2(state.check, hold);
8140 hbuf[0] = hold & 0xff;
8141 hbuf[1] = hold >>> 8 & 0xff;
8142 state.check = (0, _crc2.default)(state.check, hbuf, 2, 0);
8152 state.flags = 0; /* expect zlib header */
8154 state.head.done = false;
8156 if (!(state.wrap & 1) || /* check if zlib header allowed */
8157 (((hold & 0xff) << /*BITS(8)*/8) + (hold >> 8)) % 31) {
8158 strm.msg = 'incorrect header check';
8162 if ((hold & 0x0f) !== /*BITS(4)*/Z_DEFLATED) {
8163 strm.msg = 'unknown compression method';
8167 //--- DROPBITS(4) ---//
8171 len = (hold & 0x0f) + /*BITS(4)*/8;
8172 if (state.wbits === 0) {
8174 } else if (len > state.wbits) {
8175 strm.msg = 'invalid window size';
8179 state.dmax = 1 << len;
8180 //Tracev((stderr, "inflate: zlib header ok\n"));
8181 strm.adler = state.check = 1 /*adler32(0L, Z_NULL, 0)*/;
8182 state.mode = hold & 0x200 ? DICTID : TYPE;
8189 //=== NEEDBITS(16); */
8195 hold += input[next++] << bits;
8200 if ((state.flags & 0xff) !== Z_DEFLATED) {
8201 strm.msg = 'unknown compression method';
8205 if (state.flags & 0xe000) {
8206 strm.msg = 'unknown header flags set';
8211 state.head.text = hold >> 8 & 1;
8213 if (state.flags & 0x0200) {
8214 //=== CRC2(state.check, hold);
8215 hbuf[0] = hold & 0xff;
8216 hbuf[1] = hold >>> 8 & 0xff;
8217 state.check = (0, _crc2.default)(state.check, hbuf, 2, 0);
8227 //=== NEEDBITS(32); */
8233 hold += input[next++] << bits;
8238 state.head.time = hold;
8240 if (state.flags & 0x0200) {
8241 //=== CRC4(state.check, hold)
8242 hbuf[0] = hold & 0xff;
8243 hbuf[1] = hold >>> 8 & 0xff;
8244 hbuf[2] = hold >>> 16 & 0xff;
8245 hbuf[3] = hold >>> 24 & 0xff;
8246 state.check = (0, _crc2.default)(state.check, hbuf, 4, 0);
8256 //=== NEEDBITS(16); */
8262 hold += input[next++] << bits;
8267 state.head.xflags = hold & 0xff;
8268 state.head.os = hold >> 8;
8270 if (state.flags & 0x0200) {
8271 //=== CRC2(state.check, hold);
8272 hbuf[0] = hold & 0xff;
8273 hbuf[1] = hold >>> 8 & 0xff;
8274 state.check = (0, _crc2.default)(state.check, hbuf, 2, 0);
8284 if (state.flags & 0x0400) {
8285 //=== NEEDBITS(16); */
8291 hold += input[next++] << bits;
8295 state.length = hold;
8297 state.head.extra_len = hold;
8299 if (state.flags & 0x0200) {
8300 //=== CRC2(state.check, hold);
8301 hbuf[0] = hold & 0xff;
8302 hbuf[1] = hold >>> 8 & 0xff;
8303 state.check = (0, _crc2.default)(state.check, hbuf, 2, 0);
8310 } else if (state.head) {
8311 state.head.extra = null /*Z_NULL*/;
8316 if (state.flags & 0x0400) {
8317 copy = state.length;
8323 len = state.head.extra_len - state.length;
8324 if (!state.head.extra) {
8325 // Use untyped array for more conveniend processing later
8326 state.head.extra = new Array(state.head.extra_len);
8328 utils.arraySet(state.head.extra, input, next,
8329 // extra field is limited to 65536 bytes
8330 // - no need for additional size check
8332 /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/
8334 //zmemcpy(state.head.extra + len, next,
8335 // len + copy > state.head.extra_max ?
8336 // state.head.extra_max - len : copy);
8338 if (state.flags & 0x0200) {
8339 state.check = (0, _crc2.default)(state.check, input, copy, next);
8343 state.length -= copy;
8353 if (state.flags & 0x0800) {
8359 // TODO: 2 or 1 bytes?
8360 len = input[next + copy++];
8361 /* use constant limit because in js we should not preallocate memory */
8362 if (state.head && len && state.length < 65536 /*state.head.name_max*/) {
8363 state.head.name += String.fromCharCode(len);
8365 } while (len && copy < have);
8367 if (state.flags & 0x0200) {
8368 state.check = (0, _crc2.default)(state.check, input, copy, next);
8375 } else if (state.head) {
8376 state.head.name = null;
8379 state.mode = COMMENT;
8382 if (state.flags & 0x1000) {
8388 len = input[next + copy++];
8389 /* use constant limit because in js we should not preallocate memory */
8390 if (state.head && len && state.length < 65536 /*state.head.comm_max*/) {
8391 state.head.comment += String.fromCharCode(len);
8393 } while (len && copy < have);
8394 if (state.flags & 0x0200) {
8395 state.check = (0, _crc2.default)(state.check, input, copy, next);
8402 } else if (state.head) {
8403 state.head.comment = null;
8408 if (state.flags & 0x0200) {
8409 //=== NEEDBITS(16); */
8415 hold += input[next++] << bits;
8419 if (hold !== (state.check & 0xffff)) {
8420 strm.msg = 'header crc mismatch';
8430 state.head.hcrc = state.flags >> 9 & 1;
8431 state.head.done = true;
8433 strm.adler = state.check = 0;
8437 //=== NEEDBITS(32); */
8443 hold += input[next++] << bits;
8447 strm.adler = state.check = zswap32(hold);
8455 if (state.havedict === 0) {
8457 strm.next_out = put;
8458 strm.avail_out = left;
8459 strm.next_in = next;
8460 strm.avail_in = have;
8466 strm.adler = state.check = 1 /*adler32(0L, Z_NULL, 0)*/;
8470 if (flush === Z_BLOCK || flush === Z_TREES) {
8476 //--- BYTEBITS() ---//
8483 //=== NEEDBITS(3); */
8489 hold += input[next++] << bits;
8493 state.last = hold & 0x01 /*BITS(1)*/;
8494 //--- DROPBITS(1) ---//
8499 switch (hold & 0x03) {/*BITS(2)*/case 0:
8501 //Tracev((stderr, "inflate: stored block%s\n",
8502 // state.last ? " (last)" : ""));
8503 state.mode = STORED;
8508 //Tracev((stderr, "inflate: fixed codes block%s\n",
8509 // state.last ? " (last)" : ""));
8510 state.mode = LEN_; /* decode codes */
8511 if (flush === Z_TREES) {
8512 //--- DROPBITS(2) ---//
8521 //Tracev((stderr, "inflate: dynamic codes block%s\n",
8522 // state.last ? " (last)" : ""));
8526 strm.msg = 'invalid block type';
8529 //--- DROPBITS(2) ---//
8535 //--- BYTEBITS() ---// /* go to byte boundary */
8539 //=== NEEDBITS(32); */
8545 hold += input[next++] << bits;
8549 if ((hold & 0xffff) !== (hold >>> 16 ^ 0xffff)) {
8550 strm.msg = 'invalid stored block lengths';
8554 state.length = hold & 0xffff;
8555 //Tracev((stderr, "inflate: stored length %u\n",
8562 if (flush === Z_TREES) {
8570 copy = state.length;
8581 //--- zmemcpy(put, next, copy); ---
8582 utils.arraySet(output, input, next, copy, put);
8588 state.length -= copy;
8591 //Tracev((stderr, "inflate: stored end\n"));
8595 //=== NEEDBITS(14); */
8601 hold += input[next++] << bits;
8605 state.nlen = (hold & 0x1f) + /*BITS(5)*/257;
8606 //--- DROPBITS(5) ---//
8610 state.ndist = (hold & 0x1f) + /*BITS(5)*/1;
8611 //--- DROPBITS(5) ---//
8615 state.ncode = (hold & 0x0f) + /*BITS(4)*/4;
8616 //--- DROPBITS(4) ---//
8620 //#ifndef PKZIP_BUG_WORKAROUND
8621 if (state.nlen > 286 || state.ndist > 30) {
8622 strm.msg = 'too many length or distance symbols';
8627 //Tracev((stderr, "inflate: table sizes ok\n"));
8629 state.mode = LENLENS;
8632 while (state.have < state.ncode) {
8639 hold += input[next++] << bits;
8643 state.lens[order[state.have++]] = hold & 0x07; //BITS(3);
8644 //--- DROPBITS(3) ---//
8649 while (state.have < 19) {
8650 state.lens[order[state.have++]] = 0;
8652 // We have separate tables & no pointers. 2 commented lines below not needed.
8653 //state.next = state.codes;
8654 //state.lencode = state.next;
8655 // Switch to use dynamic table
8656 state.lencode = state.lendyn;
8659 opts = { bits: state.lenbits };
8660 ret = (0, _inftrees2.default)(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts);
8661 state.lenbits = opts.bits;
8664 strm.msg = 'invalid code lengths set';
8668 //Tracev((stderr, "inflate: code lengths ok\n"));
8670 state.mode = CODELENS;
8673 while (state.have < state.nlen + state.ndist) {
8675 here = state.lencode[hold & (1 << state.lenbits) - 1]; /*BITS(state.lenbits)*/
8676 here_bits = here >>> 24;
8677 here_op = here >>> 16 & 0xff;
8678 here_val = here & 0xffff;
8680 if (here_bits <= bits) {
8683 //--- PULLBYTE() ---//
8688 hold += input[next++] << bits;
8692 if (here_val < 16) {
8693 //--- DROPBITS(here.bits) ---//
8694 hold >>>= here_bits;
8697 state.lens[state.have++] = here_val;
8699 if (here_val === 16) {
8700 //=== NEEDBITS(here.bits + 2);
8707 hold += input[next++] << bits;
8711 //--- DROPBITS(here.bits) ---//
8712 hold >>>= here_bits;
8715 if (state.have === 0) {
8716 strm.msg = 'invalid bit length repeat';
8720 len = state.lens[state.have - 1];
8721 copy = 3 + (hold & 0x03); //BITS(2);
8722 //--- DROPBITS(2) ---//
8726 } else if (here_val === 17) {
8727 //=== NEEDBITS(here.bits + 3);
8734 hold += input[next++] << bits;
8738 //--- DROPBITS(here.bits) ---//
8739 hold >>>= here_bits;
8743 copy = 3 + (hold & 0x07); //BITS(3);
8744 //--- DROPBITS(3) ---//
8749 //=== NEEDBITS(here.bits + 7);
8756 hold += input[next++] << bits;
8760 //--- DROPBITS(here.bits) ---//
8761 hold >>>= here_bits;
8765 copy = 11 + (hold & 0x7f); //BITS(7);
8766 //--- DROPBITS(7) ---//
8771 if (state.have + copy > state.nlen + state.ndist) {
8772 strm.msg = 'invalid bit length repeat';
8777 state.lens[state.have++] = len;
8782 /* handle error breaks in while */
8783 if (state.mode === BAD) {
8787 /* check for end-of-block code (better have one) */
8788 if (state.lens[256] === 0) {
8789 strm.msg = 'invalid code -- missing end-of-block';
8794 /* build code tables -- note: do not change the lenbits or distbits
8795 values here (9 and 6) without reading the comments in inftrees.h
8796 concerning the ENOUGH constants, which depend on those values */
8799 opts = { bits: state.lenbits };
8800 ret = (0, _inftrees2.default)(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts);
8801 // We have separate tables & no pointers. 2 commented lines below not needed.
8802 // state.next_index = opts.table_index;
8803 state.lenbits = opts.bits;
8804 // state.lencode = state.next;
8807 strm.msg = 'invalid literal/lengths set';
8813 //state.distcode.copy(state.codes);
8814 // Switch to use dynamic table
8815 state.distcode = state.distdyn;
8816 opts = { bits: state.distbits };
8817 ret = (0, _inftrees2.default)(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts);
8818 // We have separate tables & no pointers. 2 commented lines below not needed.
8819 // state.next_index = opts.table_index;
8820 state.distbits = opts.bits;
8821 // state.distcode = state.next;
8824 strm.msg = 'invalid distances set';
8828 //Tracev((stderr, 'inflate: codes ok\n'));
8830 if (flush === Z_TREES) {
8838 if (have >= 6 && left >= 258) {
8840 strm.next_out = put;
8841 strm.avail_out = left;
8842 strm.next_in = next;
8843 strm.avail_in = have;
8847 (0, _inffast2.default)(strm, _out);
8849 put = strm.next_out;
8850 output = strm.output;
8851 left = strm.avail_out;
8852 next = strm.next_in;
8854 have = strm.avail_in;
8859 if (state.mode === TYPE) {
8866 here = state.lencode[hold & (1 << state.lenbits) - 1]; /*BITS(state.lenbits)*/
8867 here_bits = here >>> 24;
8868 here_op = here >>> 16 & 0xff;
8869 here_val = here & 0xffff;
8871 if (here_bits <= bits) {
8874 //--- PULLBYTE() ---//
8879 hold += input[next++] << bits;
8883 if (here_op && (here_op & 0xf0) === 0) {
8884 last_bits = here_bits;
8886 last_val = here_val;
8888 here = state.lencode[last_val + ((hold & (1 << last_bits + last_op) - 1) >> /*BITS(last.bits + last.op)*/last_bits)];
8889 here_bits = here >>> 24;
8890 here_op = here >>> 16 & 0xff;
8891 here_val = here & 0xffff;
8893 if (last_bits + here_bits <= bits) {
8896 //--- PULLBYTE() ---//
8901 hold += input[next++] << bits;
8905 //--- DROPBITS(last.bits) ---//
8906 hold >>>= last_bits;
8909 state.back += last_bits;
8911 //--- DROPBITS(here.bits) ---//
8912 hold >>>= here_bits;
8915 state.back += here_bits;
8916 state.length = here_val;
8917 if (here_op === 0) {
8918 //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
8919 // "inflate: literal '%c'\n" :
8920 // "inflate: literal 0x%02x\n", here.val));
8925 //Tracevv((stderr, "inflate: end of block\n"));
8931 strm.msg = 'invalid literal/length code';
8935 state.extra = here_op & 15;
8936 state.mode = LENEXT;
8940 //=== NEEDBITS(state.extra);
8947 hold += input[next++] << bits;
8951 state.length += hold & (1 << state.extra) - 1 /*BITS(state.extra)*/;
8952 //--- DROPBITS(state.extra) ---//
8953 hold >>>= state.extra;
8954 bits -= state.extra;
8956 state.back += state.extra;
8958 //Tracevv((stderr, "inflate: length %u\n", state.length));
8959 state.was = state.length;
8964 here = state.distcode[hold & (1 << state.distbits) - 1]; /*BITS(state.distbits)*/
8965 here_bits = here >>> 24;
8966 here_op = here >>> 16 & 0xff;
8967 here_val = here & 0xffff;
8969 if (here_bits <= bits) {
8972 //--- PULLBYTE() ---//
8977 hold += input[next++] << bits;
8981 if ((here_op & 0xf0) === 0) {
8982 last_bits = here_bits;
8984 last_val = here_val;
8986 here = state.distcode[last_val + ((hold & (1 << last_bits + last_op) - 1) >> /*BITS(last.bits + last.op)*/last_bits)];
8987 here_bits = here >>> 24;
8988 here_op = here >>> 16 & 0xff;
8989 here_val = here & 0xffff;
8991 if (last_bits + here_bits <= bits) {
8994 //--- PULLBYTE() ---//
8999 hold += input[next++] << bits;
9003 //--- DROPBITS(last.bits) ---//
9004 hold >>>= last_bits;
9007 state.back += last_bits;
9009 //--- DROPBITS(here.bits) ---//
9010 hold >>>= here_bits;
9013 state.back += here_bits;
9015 strm.msg = 'invalid distance code';
9019 state.offset = here_val;
9020 state.extra = here_op & 15;
9021 state.mode = DISTEXT;
9025 //=== NEEDBITS(state.extra);
9032 hold += input[next++] << bits;
9036 state.offset += hold & (1 << state.extra) - 1 /*BITS(state.extra)*/;
9037 //--- DROPBITS(state.extra) ---//
9038 hold >>>= state.extra;
9039 bits -= state.extra;
9041 state.back += state.extra;
9043 //#ifdef INFLATE_STRICT
9044 if (state.offset > state.dmax) {
9045 strm.msg = 'invalid distance too far back';
9050 //Tracevv((stderr, "inflate: distance %u\n", state.offset));
9058 if (state.offset > copy) {
9059 /* copy from window */
9060 copy = state.offset - copy;
9061 if (copy > state.whave) {
9063 strm.msg = 'invalid distance too far back';
9067 // (!) This block is disabled in zlib defailts,
9068 // don't enable it for binary compatibility
9069 //#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
9070 // Trace((stderr, "inflate.c too far\n"));
9071 // copy -= state.whave;
9072 // if (copy > state.length) { copy = state.length; }
9073 // if (copy > left) { copy = left; }
9075 // state.length -= copy;
9077 // output[put++] = 0;
9078 // } while (--copy);
9079 // if (state.length === 0) { state.mode = LEN; }
9083 if (copy > state.wnext) {
9084 copy -= state.wnext;
9085 from = state.wsize - copy;
9087 from = state.wnext - copy;
9089 if (copy > state.length) {
9090 copy = state.length;
9092 from_source = state.window;
9094 /* copy from output */
9095 from_source = output;
9096 from = put - state.offset;
9097 copy = state.length;
9103 state.length -= copy;
9105 output[put++] = from_source[from++];
9107 if (state.length === 0) {
9115 output[put++] = state.length;
9127 // Use '|' insdead of '+' to make sure that result is signed
9128 hold |= input[next++] << bits;
9133 strm.total_out += _out;
9134 state.total += _out;
9136 strm.adler = state.check =
9137 /*UPDATE(state.check, put - _out, _out);*/
9138 state.flags ? (0, _crc2.default)(state.check, output, _out, put - _out) : (0, _adler2.default)(state.check, output, _out, put - _out);
9141 // NB: crc32 stored as signed 32-bit int, zswap32 returns signed too
9142 if ((state.flags ? hold : zswap32(hold)) !== state.check) {
9143 strm.msg = 'incorrect data check';
9151 //Tracev((stderr, "inflate: check matches trailer\n"));
9153 state.mode = LENGTH;
9156 if (state.wrap && state.flags) {
9163 hold += input[next++] << bits;
9167 if (hold !== (state.total & 0xffffffff)) {
9168 strm.msg = 'incorrect length check';
9176 //Tracev((stderr, "inflate: length matches trailer\n"));
9191 return Z_STREAM_ERROR;
9195 // inf_leave <- here is real place for "goto inf_leave", emulated via "break inf_leave"
9198 Return from inflate(), updating the total counts and the check value.
9199 If there was no progress during the inflate() call, return a buffer
9200 error. Call updatewindow() to create and/or update the window state.
9201 Note: a memory error from inflate() is non-recoverable.
9205 strm.next_out = put;
9206 strm.avail_out = left;
9207 strm.next_in = next;
9208 strm.avail_in = have;
9213 if (state.wsize || _out !== strm.avail_out && state.mode < BAD && (state.mode < CHECK || flush !== Z_FINISH)) {
9214 if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out)) {
9219 _in -= strm.avail_in;
9220 _out -= strm.avail_out;
9221 strm.total_in += _in;
9222 strm.total_out += _out;
9223 state.total += _out;
9224 if (state.wrap && _out) {
9225 strm.adler = state.check = /*UPDATE(state.check, strm.next_out - _out, _out);*/
9226 state.flags ? (0, _crc2.default)(state.check, output, _out, strm.next_out - _out) : (0, _adler2.default)(state.check, output, _out, strm.next_out - _out);
9228 strm.data_type = state.bits + (state.last ? 64 : 0) + (state.mode === TYPE ? 128 : 0) + (state.mode === LEN_ || state.mode === COPY_ ? 256 : 0);
9229 if ((_in === 0 && _out === 0 || flush === Z_FINISH) && ret === Z_OK) {
9235 function inflateEnd(strm) {
9237 if (!strm || !strm.state /*|| strm->zfree == (free_func)0*/) {
9238 return Z_STREAM_ERROR;
9241 var state = strm.state;
9243 state.window = null;
9249 function inflateGetHeader(strm, head) {
9253 if (!strm || !strm.state) {
9254 return Z_STREAM_ERROR;
9257 if ((state.wrap & 2) === 0) {
9258 return Z_STREAM_ERROR;
9261 /* save header structure */
9267 function inflateSetDictionary(strm, dictionary) {
9268 var dictLength = dictionary.length;
9275 if (!strm /* == Z_NULL */ || !strm.state /* == Z_NULL */) {
9276 return Z_STREAM_ERROR;
9280 if (state.wrap !== 0 && state.mode !== DICT) {
9281 return Z_STREAM_ERROR;
9284 /* check for correct dictionary identifier */
9285 if (state.mode === DICT) {
9286 dictid = 1; /* adler32(0, null, 0)*/
9287 /* dictid = adler32(dictid, dictionary, dictLength); */
9288 dictid = (0, _adler2.default)(dictid, dictionary, dictLength, 0);
9289 if (dictid !== state.check) {
9290 return Z_DATA_ERROR;
9293 /* copy dictionary to window using updatewindow(), which will amend the
9294 existing dictionary if appropriate */
9295 ret = updatewindow(strm, dictionary, dictLength, dictLength);
9301 // Tracev((stderr, "inflate: dictionary set\n"));
9305 exports.inflateReset = inflateReset;
9306 exports.inflateReset2 = inflateReset2;
9307 exports.inflateResetKeep = inflateResetKeep;
9308 exports.inflateInit = inflateInit;
9309 exports.inflateInit2 = inflateInit2;
9310 exports.inflate = inflate;
9311 exports.inflateEnd = inflateEnd;
9312 exports.inflateGetHeader = inflateGetHeader;
9313 exports.inflateSetDictionary = inflateSetDictionary;
9314 var inflateInfo = exports.inflateInfo = 'pako inflate (from Nodeca project)';
9317 exports.inflateCopy = inflateCopy;
9318 exports.inflateGetDictionary = inflateGetDictionary;
9319 exports.inflateMark = inflateMark;
9320 exports.inflatePrime = inflatePrime;
9321 exports.inflateSync = inflateSync;
9322 exports.inflateSyncPoint = inflateSyncPoint;
9323 exports.inflateUndermine = inflateUndermine;
9325 },{"../utils/common.js":22,"./adler32.js":23,"./crc32.js":24,"./inffast.js":25,"./inftrees.js":27}],27:[function(require,module,exports){
9328 Object.defineProperty(exports, "__esModule", {
9331 exports.default = inflate_table;
9333 var _common = require("../utils/common.js");
9335 var utils = _interopRequireWildcard(_common);
9337 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
9340 var ENOUGH_LENS = 852;
9341 var ENOUGH_DISTS = 592;
9342 //var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS);
9348 var lbase = [/* Length codes 257..285 base */
9349 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0];
9351 var lext = [/* Length codes 257..285 extra */
9352 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78];
9354 var dbase = [/* Distance codes 0..29 base */
9355 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0];
9357 var dext = [/* Distance codes 0..29 extra */
9358 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 64, 64];
9360 function inflate_table(type, lens, lens_index, codes, table, table_index, work, opts) {
9361 var bits = opts.bits;
9362 //here = opts.here; /* table entry for duplication */
9364 var len = 0; /* a code's length in bits */
9365 var sym = 0; /* index of code symbols */
9367 max = 0; /* minimum and maximum code lengths */
9368 var root = 0; /* number of index bits for root table */
9369 var curr = 0; /* number of index bits for current table */
9370 var drop = 0; /* code bits to drop for sub-table */
9371 var left = 0; /* number of prefix codes available */
9372 var used = 0; /* code entries in table used */
9373 var huff = 0; /* Huffman code */
9374 var incr; /* for incrementing code, index */
9375 var fill; /* index for replicating entries */
9376 var low; /* low bits for current root entry */
9377 var mask; /* mask for low root bits */
9378 var next; /* next available space in table */
9379 var base = null; /* base value table to use */
9381 // var shoextra; /* extra bits table to use */
9382 var end; /* use base and extra for symbol > end */
9383 var count = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1]; /* number of codes of each length */
9384 var offs = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1]; /* offsets in table for each length */
9386 var extra_index = 0;
9388 var here_bits, here_op, here_val;
9391 Process a set of code lengths to create a canonical Huffman code. The
9392 code lengths are lens[0..codes-1]. Each length corresponds to the
9393 symbols 0..codes-1. The Huffman code is generated by first sorting the
9394 symbols by length from short to long, and retaining the symbol order
9395 for codes with equal lengths. Then the code starts with all zero bits
9396 for the first code of the shortest length, and the codes are integer
9397 increments for the same length, and zeros are appended as the length
9398 increases. For the deflate format, these bits are stored backwards
9399 from their more natural integer increment ordering, and so when the
9400 decoding tables are built in the large loop below, the integer codes
9401 are incremented backwards.
9402 This routine assumes, but does not check, that all of the entries in
9403 lens[] are in the range 0..MAXBITS. The caller must assure this.
9404 1..MAXBITS is interpreted as that code length. zero means that that
9405 symbol does not occur in this code.
9406 The codes are sorted by computing a count of codes for each length,
9407 creating from that a table of starting indices for each length in the
9408 sorted table, and then entering the symbols in order in the sorted
9409 table. The sorted table is work[], with that space being provided by
9411 The length counts are used for other purposes as well, i.e. finding
9412 the minimum and maximum length codes, determining if there are any
9413 codes at all, checking for a valid set of lengths, and looking ahead
9414 at length counts to determine sub-table sizes when building the
9418 /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
9419 for (len = 0; len <= MAXBITS; len++) {
9422 for (sym = 0; sym < codes; sym++) {
9423 count[lens[lens_index + sym]]++;
9426 /* bound code lengths, force root to be within code lengths */
9428 for (max = MAXBITS; max >= 1; max--) {
9429 if (count[max] !== 0) {
9437 /* no symbols to code at all */
9438 //table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */
9439 //table.bits[opts.table_index] = 1; //here.bits = (var char)1;
9440 //table.val[opts.table_index++] = 0; //here.val = (var short)0;
9441 table[table_index++] = 1 << 24 | 64 << 16 | 0;
9443 //table.op[opts.table_index] = 64;
9444 //table.bits[opts.table_index] = 1;
9445 //table.val[opts.table_index++] = 0;
9446 table[table_index++] = 1 << 24 | 64 << 16 | 0;
9449 return 0; /* no symbols, but wait for decoding to report error */
9451 for (min = 1; min < max; min++) {
9452 if (count[min] !== 0) {
9460 /* check for an over-subscribed or incomplete set of lengths */
9462 for (len = 1; len <= MAXBITS; len++) {
9467 } /* over-subscribed */
9469 if (left > 0 && (type === CODES || max !== 1)) {
9470 return -1; /* incomplete set */
9473 /* generate offsets into symbol table for each length for sorting */
9475 for (len = 1; len < MAXBITS; len++) {
9476 offs[len + 1] = offs[len] + count[len];
9479 /* sort symbols by length, by symbol order within each length */
9480 for (sym = 0; sym < codes; sym++) {
9481 if (lens[lens_index + sym] !== 0) {
9482 work[offs[lens[lens_index + sym]]++] = sym;
9487 Create and fill in decoding tables. In this loop, the table being
9488 filled is at next and has curr index bits. The code being used is huff
9489 with length len. That code is converted to an index by dropping drop
9490 bits off of the bottom. For codes where len is less than drop + curr,
9491 those top drop + curr - len bits are incremented through all values to
9492 fill the table with replicated entries.
9493 root is the number of index bits for the root table. When len exceeds
9494 root, sub-tables are created pointed to by the root entry with an index
9495 of the low root bits of huff. This is saved in low to check for when a
9496 new sub-table should be started. drop is zero when the root table is
9497 being filled, and drop is root when sub-tables are being filled.
9498 When a new sub-table is needed, it is necessary to look ahead in the
9499 code lengths to determine what size sub-table is needed. The length
9500 counts are used for this, and so count[] is decremented as codes are
9501 entered in the tables.
9502 used keeps track of how many table entries have been allocated from the
9503 provided *table space. It is checked for LENS and DIST tables against
9504 the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
9505 the initial root table size constants. See the comments in inftrees.h
9506 for more information.
9507 sym increments through all symbols, and the loop terminates when
9508 all codes of length max, i.e. all codes, have been processed. This
9509 routine permits incomplete codes, so another loop after this one fills
9510 in the rest of the decoding tables with invalid code markers.
9513 /* set up for code type */
9514 // poor man optimization - use if-else instead of switch,
9515 // to avoid deopts in old v8
9516 if (type === CODES) {
9517 base = extra = work; /* dummy value--not used */
9519 } else if (type === LENS) {
9532 /* initialize opts for loop */
9533 huff = 0; /* starting code */
9534 sym = 0; /* starting code symbol */
9535 len = min; /* starting code length */
9536 next = table_index; /* current table to fill in */
9537 curr = root; /* current table index bits */
9538 drop = 0; /* current bits to drop from code for index */
9539 low = -1; /* trigger new sub-table when len > root */
9540 used = 1 << root; /* use root table entries */
9541 mask = used - 1; /* mask for comparing low */
9543 /* check available table space */
9544 if (type === LENS && used > ENOUGH_LENS || type === DISTS && used > ENOUGH_DISTS) {
9548 /* process all codes and make table entries */
9550 /* create table entry */
9551 here_bits = len - drop;
9552 if (work[sym] < end) {
9554 here_val = work[sym];
9555 } else if (work[sym] > end) {
9556 here_op = extra[extra_index + work[sym]];
9557 here_val = base[base_index + work[sym]];
9559 here_op = 32 + 64; /* end of block */
9563 /* replicate for those indices with low len bits equal to huff */
9564 incr = 1 << len - drop;
9566 min = fill; /* save offset to next table */
9569 table[next + (huff >> drop) + fill] = here_bits << 24 | here_op << 16 | here_val | 0;
9570 } while (fill !== 0);
9572 /* backwards increment the len-bit code huff */
9573 incr = 1 << len - 1;
9574 while (huff & incr) {
9584 /* go to next symbol, update count, len */
9586 if (--count[len] === 0) {
9590 len = lens[lens_index + work[sym]];
9593 /* create new sub-table if needed */
9594 if (len > root && (huff & mask) !== low) {
9595 /* if first time, transition to sub-tables */
9600 /* increment past last table */
9601 next += min; /* here min is 1 << curr */
9603 /* determine length of next table */
9606 while (curr + drop < max) {
9607 left -= count[curr + drop];
9615 /* check for enough space */
9617 if (type === LENS && used > ENOUGH_LENS || type === DISTS && used > ENOUGH_DISTS) {
9621 /* point entry in root table to sub-table */
9623 /*table.op[low] = curr;
9624 table.bits[low] = root;
9625 table.val[low] = next - opts.table_index;*/
9626 table[low] = root << 24 | curr << 16 | next - table_index | 0;
9630 /* fill in remaining table entry if code is incomplete (guaranteed to have
9631 at most one remaining entry, since if the code is incomplete, the
9632 maximum code length that was allowed to get this far is one bit) */
9634 //table.op[next + huff] = 64; /* invalid code marker */
9635 //table.bits[next + huff] = len - drop;
9636 //table.val[next + huff] = 0;
9637 table[next + huff] = len - drop << 24 | 64 << 16 | 0;
9640 /* set return parameters */
9641 //opts.table_index += used;
9645 },{"../utils/common.js":22}],28:[function(require,module,exports){
9648 Object.defineProperty(exports, "__esModule", {
9651 exports.default = ZStream;
9652 function ZStream() {
9653 /* next input byte */
9654 this.input = null; // JS specific, because we have no pointers
9656 /* number of bytes available at input */
9658 /* total number of input bytes read so far */
9660 /* next output byte should be put there */
9661 this.output = null; // JS specific, because we have no pointers
9663 /* remaining free space at output */
9665 /* total number of bytes output so far */
9667 /* last error message, NULL if no error */
9668 this.msg = '' /*Z_NULL*/;
9669 /* not visible by applications */
9671 /* best guess about the data type: binary or text */
9672 this.data_type = 2 /*Z_UNKNOWN*/;
9673 /* adler32 value of the uncompressed data */
9676 },{}],29:[function(require,module,exports){
9679 Object.defineProperty(exports, "__esModule", {
9682 exports.default = Websock;
9684 var _logging = require('./util/logging.js');
9686 var Log = _interopRequireWildcard(_logging);
9688 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
9690 function Websock() {
9693 this._websocket = null; // WebSocket object
9695 this._rQi = 0; // Receive queue index
9696 this._rQlen = 0; // Next write position in the receive queue
9697 this._rQbufferSize = 1024 * 1024 * 4; // Receive queue buffer size (4 MiB)
9698 this._rQmax = this._rQbufferSize / 8;
9699 // called in init: this._rQ = new Uint8Array(this._rQbufferSize);
9700 this._rQ = null; // Receive queue
9702 this._sQbufferSize = 1024 * 10; // 10 KiB
9703 // called in init: this._sQ = new Uint8Array(this._sQbufferSize);
9705 this._sQ = null; // Send queue
9707 this._eventHandlers = {
9708 'message': function () {},
9709 'open': function () {},
9710 'close': function () {},
9711 'error': function () {}
9714 * Websock: high-performance binary WebSockets
9715 * Copyright (C) 2012 Joel Martin
9716 * Licensed under MPL 2.0 (see LICENSE.txt)
9718 * Websock is similar to the standard WebSocket object but with extra
9721 * Websock has built-in receive queue buffering; the message event
9722 * does not contain actual data but is simply a notification that
9723 * there is new data available. Several rQ* methods are available to
9724 * read binary data off of the receive queue.
9729 // this has performance issues in some versions Chromium, and
9730 // doesn't gain a tremendous amount of performance increase in Firefox
9731 // at the moment. It may be valuable to turn it on in the future.
9732 var ENABLE_COPYWITHIN = false;
9734 var MAX_RQ_GROW_SIZE = 40 * 1024 * 1024; // 40 MiB
9736 var typedArrayToString = function () {
9737 // This is only for PhantomJS, which doesn't like apply-ing
9738 // with Typed Arrays
9740 var arr = new Uint8Array([1, 2, 3]);
9741 String.fromCharCode.apply(null, arr);
9742 return function (a) {
9743 return String.fromCharCode.apply(null, a);
9746 return function (a) {
9747 return String.fromCharCode.apply(null, Array.prototype.slice.call(a));
9752 Websock.prototype = {
9753 // Getters and Setters
9754 get_sQ: function () {
9758 get_rQ: function () {
9762 get_rQi: function () {
9766 set_rQi: function (val) {
9771 rQlen: function () {
9772 return this._rQlen - this._rQi;
9775 rQpeek8: function () {
9776 return this._rQ[this._rQi];
9779 rQshift8: function () {
9780 return this._rQ[this._rQi++];
9783 rQskip8: function () {
9787 rQskipBytes: function (num) {
9791 // TODO(directxman12): test performance with these vs a DataView
9792 rQshift16: function () {
9793 return (this._rQ[this._rQi++] << 8) + this._rQ[this._rQi++];
9796 rQshift32: function () {
9797 return (this._rQ[this._rQi++] << 24) + (this._rQ[this._rQi++] << 16) + (this._rQ[this._rQi++] << 8) + this._rQ[this._rQi++];
9800 rQshiftStr: function (len) {
9801 if (typeof len === 'undefined') {
9804 var arr = new Uint8Array(this._rQ.buffer, this._rQi, len);
9806 return typedArrayToString(arr);
9809 rQshiftBytes: function (len) {
9810 if (typeof len === 'undefined') {
9814 return new Uint8Array(this._rQ.buffer, this._rQi - len, len);
9817 rQshiftTo: function (target, len) {
9818 if (len === undefined) {
9821 // TODO: make this just use set with views when using a ArrayBuffer to store the rQ
9822 target.set(new Uint8Array(this._rQ.buffer, this._rQi, len));
9826 rQwhole: function () {
9827 return new Uint8Array(this._rQ.buffer, 0, this._rQlen);
9830 rQslice: function (start, end) {
9832 return new Uint8Array(this._rQ.buffer, this._rQi + start, end - start);
9834 return new Uint8Array(this._rQ.buffer, this._rQi + start, this._rQlen - this._rQi - start);
9838 // Check to see if we must wait for 'num' bytes (default to FBU.bytes)
9839 // to be available in the receive queue. Return true if we need to
9840 // wait (and possibly print a debug message), otherwise false.
9841 rQwait: function (msg, num, goback) {
9842 var rQlen = this._rQlen - this._rQi; // Skip rQlen() function call
9845 if (this._rQi < goback) {
9846 throw new Error("rQwait cannot backup " + goback + " bytes");
9848 this._rQi -= goback;
9850 return true; // true means need more data
9857 flush: function () {
9858 if (this._sQlen > 0 && this._websocket.readyState === WebSocket.OPEN) {
9859 this._websocket.send(this._encode_message());
9864 send: function (arr) {
9865 this._sQ.set(arr, this._sQlen);
9866 this._sQlen += arr.length;
9870 send_string: function (str) {
9871 this.send(str.split('').map(function (chr) {
9872 return chr.charCodeAt(0);
9877 off: function (evt) {
9878 this._eventHandlers[evt] = function () {};
9881 on: function (evt, handler) {
9882 this._eventHandlers[evt] = handler;
9885 _allocate_buffers: function () {
9886 this._rQ = new Uint8Array(this._rQbufferSize);
9887 this._sQ = new Uint8Array(this._sQbufferSize);
9891 this._allocate_buffers();
9893 this._websocket = null;
9896 open: function (uri, protocols) {
9897 var ws_schema = uri.match(/^([a-z]+):\/\//)[1];
9900 this._websocket = new WebSocket(uri, protocols);
9901 this._websocket.binaryType = 'arraybuffer';
9903 this._websocket.onmessage = this._recv_message.bind(this);
9904 this._websocket.onopen = function () {
9905 Log.Debug('>> WebSock.onopen');
9906 if (this._websocket.protocol) {
9907 Log.Info("Server choose sub-protocol: " + this._websocket.protocol);
9910 this._eventHandlers.open();
9911 Log.Debug("<< WebSock.onopen");
9913 this._websocket.onclose = function (e) {
9914 Log.Debug(">> WebSock.onclose");
9915 this._eventHandlers.close(e);
9916 Log.Debug("<< WebSock.onclose");
9918 this._websocket.onerror = function (e) {
9919 Log.Debug(">> WebSock.onerror: " + e);
9920 this._eventHandlers.error(e);
9921 Log.Debug("<< WebSock.onerror: " + e);
9925 close: function () {
9926 if (this._websocket) {
9927 if (this._websocket.readyState === WebSocket.OPEN || this._websocket.readyState === WebSocket.CONNECTING) {
9928 Log.Info("Closing WebSocket connection");
9929 this._websocket.close();
9932 this._websocket.onmessage = function (e) {
9939 _encode_message: function () {
9940 // Put in a binary arraybuffer
9941 // according to the spec, you can send ArrayBufferViews with the send method
9942 return new Uint8Array(this._sQ.buffer, 0, this._sQlen);
9945 _expand_compact_rQ: function (min_fit) {
9946 var resizeNeeded = min_fit || this._rQlen - this._rQi > this._rQbufferSize / 2;
9949 // just double the size if we need to do compaction
9950 this._rQbufferSize *= 2;
9952 // otherwise, make sure we satisy rQlen - rQi + min_fit < rQbufferSize / 8
9953 this._rQbufferSize = (this._rQlen - this._rQi + min_fit) * 8;
9957 // we don't want to grow unboundedly
9958 if (this._rQbufferSize > MAX_RQ_GROW_SIZE) {
9959 this._rQbufferSize = MAX_RQ_GROW_SIZE;
9960 if (this._rQbufferSize - this._rQlen - this._rQi < min_fit) {
9961 throw new Exception("Receive Queue buffer exceeded " + MAX_RQ_GROW_SIZE + " bytes, and the new message could not fit");
9966 var old_rQbuffer = this._rQ.buffer;
9967 this._rQmax = this._rQbufferSize / 8;
9968 this._rQ = new Uint8Array(this._rQbufferSize);
9969 this._rQ.set(new Uint8Array(old_rQbuffer, this._rQi));
9971 if (ENABLE_COPYWITHIN) {
9972 this._rQ.copyWithin(0, this._rQi);
9974 this._rQ.set(new Uint8Array(this._rQ.buffer, this._rQi));
9978 this._rQlen = this._rQlen - this._rQi;
9982 _decode_message: function (data) {
9983 // push arraybuffer values onto the end
9984 var u8 = new Uint8Array(data);
9985 if (u8.length > this._rQbufferSize - this._rQlen) {
9986 this._expand_compact_rQ(u8.length);
9988 this._rQ.set(u8, this._rQlen);
9989 this._rQlen += u8.length;
9992 _recv_message: function (e) {
9993 this._decode_message(e.data);
9994 if (this.rQlen() > 0) {
9995 this._eventHandlers.message();
9996 // Compact the receive queue
9997 if (this._rQlen == this._rQi) {
10000 } else if (this._rQlen > this._rQmax) {
10001 this._expand_compact_rQ();
10004 Log.Debug("Ignoring empty message");
10008 },{"./util/logging.js":19}]},{},[15])(15)