Drop privileges in VNC proxy if requested
[invirt/packages/invirt-web.git] / code / static / novnc-1.0.js
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){
2 'use strict';
3
4 Object.defineProperty(exports, "__esModule", {
5     value: true
6 });
7
8 var _logging = require('./util/logging.js');
9
10 var Log = _interopRequireWildcard(_logging);
11
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; } }
13
14 exports.default = {
15     /* Convert data (an array of integers) to a Base64 string. */
16     toBase64Table: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split(''),
17     base64Pad: '=',
18
19     encode: function (data) {
20         "use strict";
21
22         var result = '';
23         var toBase64Table = this.toBase64Table;
24         var length = data.length;
25         var lengthpad = length % 3;
26         // Convert every three bytes to 4 ascii characters.
27
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];
33         }
34
35         // Convert the remaining 1 or 2 bytes, pad out to 4 characters.
36         var j = 0;
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];
49         }
50
51         return result;
52     },
53
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],
56
57     decode: function (data, offset) {
58         "use strict";
59
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;
67
68         if (data_length < 0) {
69             data_length = data.length - offset;
70         }
71
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);
75
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
81             if (c === -1) {
82                 Log.Error("Illegal character code " + data.charCodeAt(i) + " at position " + i);
83                 continue;
84             }
85
86             // Collect data into leftdata, update bitcount
87             leftdata = leftdata << 6 | c;
88             leftbits += 6;
89
90             // If we have 8 or more bits, append 8 bits to the result
91             if (leftbits >= 8) {
92                 leftbits -= 8;
93                 // Append if not padding.
94                 if (!padding) {
95                     result[idx++] = leftdata >> leftbits & 0xff;
96                 }
97                 leftdata &= (1 << leftbits) - 1;
98             }
99         }
100
101         // If there are any bits left, the base64 string was corrupted
102         if (leftbits) {
103             err = new Error('Corrupted base64 string');
104             err.name = 'Base64-Error';
105             throw err;
106         }
107
108         return result;
109     }
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/. */
114
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){
117 "use strict";
118
119 Object.defineProperty(exports, "__esModule", {
120     value: true
121 });
122 exports.default = DES;
123 /*
124  * Ported from Flashlight VNC ActionScript implementation:
125  *     http://www.wizhelp.com/flashlight-vnc/
126  *
127  * Full attribution follows:
128  *
129  * -------------------------------------------------------------------------
130  *
131  * This DES class has been extracted from package Acme.Crypto for use in VNC.
132  * The unnecessary odd parity code has been removed.
133  *
134  * These changes are:
135  *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
136  *
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.
140  *
141
142  * DesCipher - the DES encryption method
143  *
144  * The meat of this code is by Dave Zimmerman <dzimm@widget.com>, and is:
145  *
146  * Copyright (c) 1996 Widget Workshop, Inc. All Rights Reserved.
147  *
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
151  * intact.
152  *
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.
159  *
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.
169  *
170  *
171  * The rest is:
172  *
173  * Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>.  All rights reserved.
174  *
175  * Redistribution and use in source and binary forms, with or without
176  * modification, are permitted provided that the following conditions
177  * are met:
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.
183  *
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
194  * SUCH DAMAGE.
195  *
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/
198  */
199
200 function DES(passwd) {
201     "use strict";
202
203     // Tables, permutations, S-boxes, etc.
204
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],
207         z = 0x0,
208         a,
209         b,
210         c,
211         d,
212         e,
213         f,
214         SP1,
215         SP2,
216         SP3,
217         SP4,
218         SP5,
219         SP6,
220         SP7,
221         SP8,
222         keys = [];
223
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];
240
241     // Set the key.
242     function setKeys(keyBlock) {
243         var i,
244             j,
245             l,
246             m,
247             n,
248             o,
249             pc1m = [],
250             pcr = [],
251             kn = [],
252             raw0,
253             raw1,
254             rawi,
255             KnLi;
256
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
259             m = l & 0x7;
260             pc1m[j] = (keyBlock[l >>> 3] & 1 << m) !== 0 ? 1 : 0;
261         }
262
263         for (i = 0; i < 16; ++i) {
264             m = i << 1;
265             n = m + 1;
266             kn[m] = kn[n] = 0;
267             for (o = 28; o < 59; o += 28) {
268                 for (j = o - 28; j < o; ++j) {
269                     l = j + totrot[i];
270                     if (l < o) {
271                         pcr[j] = pc1m[l];
272                     } else {
273                         pcr[j] = pc1m[l - 28];
274                     }
275                 }
276             }
277             for (j = 0; j < 24; ++j) {
278                 if (pcr[PC2[j]] !== 0) {
279                     kn[m] |= 1 << 23 - j;
280                 }
281                 if (pcr[PC2[j + 24]] !== 0) {
282                     kn[n] |= 1 << 23 - j;
283                 }
284             }
285         }
286
287         // cookey
288         for (i = 0, rawi = 0, KnLi = 0; i < 16; ++i) {
289             raw0 = kn[rawi++];
290             raw1 = kn[rawi++];
291             keys[KnLi] = (raw0 & 0x00fc0000) << 6;
292             keys[KnLi] |= (raw0 & 0x00000fc0) << 10;
293             keys[KnLi] |= (raw1 & 0x00fc0000) >>> 10;
294             keys[KnLi] |= (raw1 & 0x00000fc0) >>> 6;
295             ++KnLi;
296             keys[KnLi] = (raw0 & 0x0003f000) << 12;
297             keys[KnLi] |= (raw0 & 0x0000003f) << 16;
298             keys[KnLi] |= (raw1 & 0x0003f000) >>> 4;
299             keys[KnLi] |= raw1 & 0x0000003f;
300             ++KnLi;
301         }
302     }
303
304     // Encrypt 8 bytes of text
305     function enc8(text) {
306         var i = 0,
307             b = text.slice(),
308             fval,
309             keysi = 0,
310             l,
311             r,
312             x; // left, right, accumulator
313
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++];
317
318         x = (l >>> 4 ^ r) & 0x0f0f0f0f;
319         r ^= x;
320         l ^= x << 4;
321         x = (l >>> 16 ^ r) & 0x0000ffff;
322         r ^= x;
323         l ^= x << 16;
324         x = (r >>> 2 ^ l) & 0x33333333;
325         l ^= x;
326         r ^= x << 2;
327         x = (r >>> 8 ^ l) & 0x00ff00ff;
328         l ^= x;
329         r ^= x << 8;
330         r = r << 1 | r >>> 31 & 1;
331         x = (l ^ r) & 0xaaaaaaaa;
332         l ^= x;
333         r ^= x;
334         l = l << 1 | l >>> 31 & 1;
335
336         for (i = 0; i < 8; ++i) {
337             x = r << 28 | r >>> 4;
338             x ^= keys[keysi++];
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];
348             l ^= fval;
349             x = l << 28 | l >>> 4;
350             x ^= keys[keysi++];
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];
360             r ^= fval;
361         }
362
363         r = r << 31 | r >>> 1;
364         x = (l ^ r) & 0xaaaaaaaa;
365         l ^= x;
366         r ^= x;
367         l = l << 31 | l >>> 1;
368         x = (l >>> 8 ^ r) & 0x00ff00ff;
369         r ^= x;
370         l ^= x << 8;
371         x = (l >>> 2 ^ r) & 0x33333333;
372         r ^= x;
373         l ^= x << 2;
374         x = (r >>> 16 ^ l) & 0x0000ffff;
375         l ^= x;
376         r ^= x << 16;
377         x = (r >>> 4 ^ l) & 0x0f0f0f0f;
378         l ^= x;
379         r ^= x << 4;
380
381         // Spread ints to bytes
382         x = [r, l];
383         for (i = 0; i < 8; i++) {
384             b[i] = (x[i >>> 2] >>> 8 * (3 - i % 4)) % 256;
385             if (b[i] < 0) {
386                 b[i] += 256;
387             } // unsigned
388         }
389         return b;
390     }
391
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)));
395     }
396
397     setKeys(passwd); // Setup keys
398     return { 'encrypt': encrypt }; // Public interface
399 }; // function DES
400 },{}],3:[function(require,module,exports){
401 "use strict";
402
403 Object.defineProperty(exports, "__esModule", {
404     value: true
405 });
406 exports.default = Display;
407
408 var _logging = require("./util/logging.js");
409
410 var Log = _interopRequireWildcard(_logging);
411
412 var _base = require("./base64.js");
413
414 var _base2 = _interopRequireDefault(_base);
415
416 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
417
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; } }
419
420 /*
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)
425  *
426  * See README.md for usage and integration instructions.
427  */
428
429 function Display(target) {
430     this._drawCtx = null;
431     this._c_forceCanvas = false;
432
433     this._renderQ = []; // queue drawing actions for in-oder rendering
434     this._flushing = false;
435
436     // the full frame buffer (logical canvas) size
437     this._fb_width = 0;
438     this._fb_height = 0;
439
440     this._prevDrawStyle = "";
441     this._tile = null;
442     this._tile16x16 = null;
443     this._tile_x = 0;
444     this._tile_y = 0;
445
446     Log.Debug(">> Display.constructor");
447
448     // The visible canvas
449     this._target = target;
450
451     if (!this._target) {
452         throw new Error("Target must be set");
453     }
454
455     if (typeof this._target === 'string') {
456         throw new Error('target must be a DOM element');
457     }
458
459     if (!this._target.getContext) {
460         throw new Error("no getContext method");
461     }
462
463     this._targetCtx = this._target.getContext('2d');
464
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 };
467
468     // The hidden canvas, where we do the actual rendering
469     this._backbuffer = document.createElement('canvas');
470     this._drawCtx = this._backbuffer.getContext('2d');
471
472     this._damageBounds = { left: 0, top: 0,
473         right: this._backbuffer.width,
474         bottom: this._backbuffer.height };
475
476     Log.Debug("User Agent: " + navigator.userAgent);
477
478     this.clear();
479
480     // Check canvas features
481     if (!('createImageData' in this._drawCtx)) {
482         throw new Error("Canvas does not support createImageData");
483     }
484
485     this._tile16x16 = this._drawCtx.createImageData(16, 16);
486     Log.Debug("<< Display.constructor");
487 };
488
489 var SUPPORTS_IMAGEDATA_CONSTRUCTOR = false;
490 try {
491     new ImageData(new Uint8ClampedArray(4), 1, 1);
492     SUPPORTS_IMAGEDATA_CONSTRUCTOR = true;
493 } catch (ex) {
494     // ignore failure
495 }
496
497 Display.prototype = {
498     // ===== PROPERTIES =====
499
500     _scale: 1.0,
501     get scale() {
502         return this._scale;
503     },
504     set scale(scale) {
505         this._rescale(scale);
506     },
507
508     _clipViewport: false,
509     get clipViewport() {
510         return this._clipViewport;
511     },
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);
518     },
519
520     get width() {
521         return this._fb_width;
522     },
523     get height() {
524         return this._fb_height;
525     },
526
527     logo: null,
528
529     // ===== EVENT HANDLERS =====
530
531     onflush: function () {}, // A flush request has finished
532
533     // ===== PUBLIC METHODS =====
534
535     viewportChangePos: function (deltaX, deltaY) {
536         var vp = this._viewportLoc;
537         deltaX = Math.floor(deltaX);
538         deltaY = Math.floor(deltaY);
539
540         if (!this._clipViewport) {
541             deltaX = -vp.w; // clamped later of out of bounds
542             deltaY = -vp.h;
543         }
544
545         var vx2 = vp.x + vp.w - 1;
546         var vy2 = vp.y + vp.h - 1;
547
548         // Position change
549
550         if (deltaX < 0 && vp.x + deltaX < 0) {
551             deltaX = -vp.x;
552         }
553         if (vx2 + deltaX >= this._fb_width) {
554             deltaX -= vx2 + deltaX - this._fb_width + 1;
555         }
556
557         if (vp.y + deltaY < 0) {
558             deltaY = -vp.y;
559         }
560         if (vy2 + deltaY >= this._fb_height) {
561             deltaY -= vy2 + deltaY - this._fb_height + 1;
562         }
563
564         if (deltaX === 0 && deltaY === 0) {
565             return;
566         }
567         Log.Debug("viewportChange deltaX: " + deltaX + ", deltaY: " + deltaY);
568
569         vp.x += deltaX;
570         vp.y += deltaY;
571
572         this._damage(vp.x, vp.y, vp.w, vp.h);
573
574         this.flip();
575     },
576
577     viewportChangeSize: function (width, height) {
578
579         if (!this._clipViewport || typeof width === "undefined" || typeof height === "undefined") {
580
581             Log.Debug("Setting viewport to full display region");
582             width = this._fb_width;
583             height = this._fb_height;
584         }
585
586         if (width > this._fb_width) {
587             width = this._fb_width;
588         }
589         if (height > this._fb_height) {
590             height = this._fb_height;
591         }
592
593         var vp = this._viewportLoc;
594         if (vp.w !== width || vp.h !== height) {
595             vp.w = width;
596             vp.h = height;
597
598             var canvas = this._target;
599             canvas.width = width;
600             canvas.height = height;
601
602             // The position might need to be updated if we've grown
603             this.viewportChangePos(0, 0);
604
605             this._damage(vp.x, vp.y, vp.w, vp.h);
606             this.flip();
607
608             // Update the visible size of the target canvas
609             this._rescale(this._scale);
610         }
611     },
612
613     absX: function (x) {
614         return x / this._scale + this._viewportLoc.x;
615     },
616
617     absY: function (y) {
618         return y / this._scale + this._viewportLoc.y;
619     },
620
621     resize: function (width, height) {
622         this._prevDrawStyle = "";
623
624         this._fb_width = width;
625         this._fb_height = height;
626
627         var canvas = this._backbuffer;
628         if (canvas.width !== width || canvas.height !== height) {
629
630             // We have to save the canvas data since changing the size will clear it
631             var saveImg = null;
632             if (canvas.width > 0 && canvas.height > 0) {
633                 saveImg = this._drawCtx.getImageData(0, 0, canvas.width, canvas.height);
634             }
635
636             if (canvas.width !== width) {
637                 canvas.width = width;
638             }
639             if (canvas.height !== height) {
640                 canvas.height = height;
641             }
642
643             if (saveImg) {
644                 this._drawCtx.putImageData(saveImg, 0, 0);
645             }
646         }
647
648         // Readjust the viewport as it may be incorrectly sized
649         // and positioned
650         var vp = this._viewportLoc;
651         this.viewportChangeSize(vp.w, vp.h);
652         this.viewportChangePos(0, 0);
653     },
654
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;
659         }
660         if (y < this._damageBounds.top) {
661             this._damageBounds.top = y;
662         }
663         if (x + w > this._damageBounds.right) {
664             this._damageBounds.right = x + w;
665         }
666         if (y + h > this._damageBounds.bottom) {
667             this._damageBounds.bottom = y + h;
668         }
669     },
670
671     // Update the visible canvas with the contents of the
672     // rendering canvas
673     flip: function (from_queue) {
674         if (this._renderQ.length !== 0 && !from_queue) {
675             this._renderQ_push({
676                 'type': 'flip'
677             });
678         } else {
679             var x, y, vx, vy, w, h;
680
681             x = this._damageBounds.left;
682             y = this._damageBounds.top;
683             w = this._damageBounds.right - x;
684             h = this._damageBounds.bottom - y;
685
686             vx = x - this._viewportLoc.x;
687             vy = y - this._viewportLoc.y;
688
689             if (vx < 0) {
690                 w += vx;
691                 x -= vx;
692                 vx = 0;
693             }
694             if (vy < 0) {
695                 h += vy;
696                 y -= vy;
697                 vy = 0;
698             }
699
700             if (vx + w > this._viewportLoc.w) {
701                 w = this._viewportLoc.w - vx;
702             }
703             if (vy + h > this._viewportLoc.h) {
704                 h = this._viewportLoc.h - vy;
705             }
706
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);
712             }
713
714             this._damageBounds.left = this._damageBounds.top = 65535;
715             this._damageBounds.right = this._damageBounds.bottom = 0;
716         }
717     },
718
719     clear: function () {
720         if (this._logo) {
721             this.resize(this._logo.width, this._logo.height);
722             this.imageRect(0, 0, this._logo.type, this._logo.data);
723         } else {
724             this.resize(240, 20);
725             this._drawCtx.clearRect(0, 0, this._fb_width, this._fb_height);
726         }
727         this.flip();
728     },
729
730     pending: function () {
731         return this._renderQ.length > 0;
732     },
733
734     flush: function () {
735         if (this._renderQ.length === 0) {
736             this.onflush();
737         } else {
738             this._flushing = true;
739         }
740     },
741
742     fillRect: function (x, y, width, height, color, from_queue) {
743         if (this._renderQ.length !== 0 && !from_queue) {
744             this._renderQ_push({
745                 'type': 'fill',
746                 'x': x,
747                 'y': y,
748                 'width': width,
749                 'height': height,
750                 'color': color
751             });
752         } else {
753             this._setFillColor(color);
754             this._drawCtx.fillRect(x, y, width, height);
755             this._damage(x, y, width, height);
756         }
757     },
758
759     copyImage: function (old_x, old_y, new_x, new_y, w, h, from_queue) {
760         if (this._renderQ.length !== 0 && !from_queue) {
761             this._renderQ_push({
762                 'type': 'copy',
763                 'old_x': old_x,
764                 'old_y': old_y,
765                 'x': new_x,
766                 'y': new_y,
767                 'width': w,
768                 'height': h
769             });
770         } else {
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.
773             //
774             // 1. https://bugzilla.mozilla.org/show_bug.cgi?id=1194719
775             //
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;
782
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);
785         }
786     },
787
788     imageRect: function (x, y, mime, arr) {
789         var img = new Image();
790         img.src = "data: " + mime + ";base64," + _base2.default.encode(arr);
791         this._renderQ_push({
792             'type': 'img',
793             'img': img,
794             'x': x,
795             'y': y
796         });
797     },
798
799     // start updating a tile
800     startTile: function (x, y, width, height, color) {
801         this._tile_x = x;
802         this._tile_y = y;
803         if (width === 16 && height === 16) {
804             this._tile = this._tile16x16;
805         } else {
806             this._tile = this._drawCtx.createImageData(width, height);
807         }
808
809         var red = color[2];
810         var green = color[1];
811         var blue = color[0];
812
813         var data = this._tile.data;
814         for (var i = 0; i < width * height * 4; i += 4) {
815             data[i] = red;
816             data[i + 1] = green;
817             data[i + 2] = blue;
818             data[i + 3] = 255;
819         }
820     },
821
822     // update sub-rectangle of the current tile
823     subTile: function (x, y, w, h, color) {
824         var red = color[2];
825         var green = color[1];
826         var blue = color[0];
827         var xend = x + w;
828         var yend = y + h;
829
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;
835                 data[p] = red;
836                 data[p + 1] = green;
837                 data[p + 2] = blue;
838                 data[p + 3] = 255;
839             }
840         }
841     },
842
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);
847     },
848
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));
856             this._renderQ_push({
857                 'type': 'blit',
858                 'data': new_arr,
859                 'x': x,
860                 'y': y,
861                 'width': width,
862                 'height': height
863             });
864         } else {
865             this._bgrxImageData(x, y, width, height, arr, offset);
866         }
867     },
868
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));
876             this._renderQ_push({
877                 'type': 'blitRgb',
878                 'data': new_arr,
879                 'x': x,
880                 'y': y,
881                 'width': width,
882                 'height': height
883             });
884         } else {
885             this._rgbImageData(x, y, width, height, arr, offset);
886         }
887     },
888
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));
896             this._renderQ_push({
897                 'type': 'blitRgbx',
898                 'data': new_arr,
899                 'x': x,
900                 'y': y,
901                 'width': width,
902                 'height': height
903             });
904         } else {
905             this._rgbxImageData(x, y, width, height, arr, offset);
906         }
907     },
908
909     drawImage: function (img, x, y) {
910         this._drawCtx.drawImage(img, x, y);
911         this._damage(x, y, img.width, img.height);
912     },
913
914     changeCursor: function (pixels, mask, hotx, hoty, w, h) {
915         Display.changeCursor(this._target, pixels, mask, hotx, hoty, w, h);
916     },
917
918     defaultCursor: function () {
919         this._target.style.cursor = "default";
920     },
921
922     disableLocalCursor: function () {
923         this._target.style.cursor = "none";
924     },
925
926     autoscale: function (containerWidth, containerHeight) {
927         var vp = this._viewportLoc;
928         var targetAspectRatio = containerWidth / containerHeight;
929         var fbAspectRatio = vp.w / vp.h;
930
931         var scaleRatio;
932         if (fbAspectRatio >= targetAspectRatio) {
933             scaleRatio = containerWidth / vp.w;
934         } else {
935             scaleRatio = containerHeight / vp.h;
936         }
937
938         this._rescale(scaleRatio);
939     },
940
941     // ===== PRIVATE METHODS =====
942
943     _rescale: function (factor) {
944         this._scale = factor;
945         var vp = this._viewportLoc;
946
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';
953
954         if (this._target.style.width !== width || this._target.style.height !== height) {
955             this._target.style.width = width;
956             this._target.style.height = height;
957         }
958     },
959
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;
965         }
966     },
967
968     _rgbImageData: function (x, y, width, height, arr, offset) {
969         var img = this._drawCtx.createImageData(width, height);
970         var data = img.data;
971         for (var i = 0, j = offset; i < width * height * 4; i += 4, j += 3) {
972             data[i] = arr[j];
973             data[i + 1] = arr[j + 1];
974             data[i + 2] = arr[j + 2];
975             data[i + 3] = 255; // Alpha
976         }
977         this._drawCtx.putImageData(img, x, y);
978         this._damage(x, y, img.width, img.height);
979     },
980
981     _bgrxImageData: function (x, y, width, height, arr, offset) {
982         var img = this._drawCtx.createImageData(width, height);
983         var data = img.data;
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
989         }
990         this._drawCtx.putImageData(img, x, y);
991         this._damage(x, y, img.width, img.height);
992     },
993
994     _rgbxImageData: function (x, y, width, height, arr, offset) {
995         // NB(directxman12): arr must be an Type Array view
996         var img;
997         if (SUPPORTS_IMAGEDATA_CONSTRUCTOR) {
998             img = new ImageData(new Uint8ClampedArray(arr.buffer, arr.byteOffset, width * height * 4), width, height);
999         } else {
1000             img = this._drawCtx.createImageData(width, height);
1001             img.data.set(new Uint8ClampedArray(arr.buffer, arr.byteOffset, width * height * 4));
1002         }
1003         this._drawCtx.putImageData(img, x, y);
1004         this._damage(x, y, img.width, img.height);
1005     },
1006
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();
1013         }
1014     },
1015
1016     _resume_renderQ: function () {
1017         // "this" is the object that is ready, not the
1018         // display object
1019         this.removeEventListener('load', this._noVNC_display._resume_renderQ);
1020         this._noVNC_display._scan_renderQ();
1021     },
1022
1023     _scan_renderQ: function () {
1024         var ready = true;
1025         while (ready && this._renderQ.length > 0) {
1026             var a = this._renderQ[0];
1027             switch (a.type) {
1028                 case 'flip':
1029                     this.flip(true);
1030                     break;
1031                 case 'copy':
1032                     this.copyImage(a.old_x, a.old_y, a.x, a.y, a.width, a.height, true);
1033                     break;
1034                 case 'fill':
1035                     this.fillRect(a.x, a.y, a.width, a.height, a.color, true);
1036                     break;
1037                 case 'blit':
1038                     this.blitImage(a.x, a.y, a.width, a.height, a.data, 0, true);
1039                     break;
1040                 case 'blitRgb':
1041                     this.blitRgbImage(a.x, a.y, a.width, a.height, a.data, 0, true);
1042                     break;
1043                 case 'blitRgbx':
1044                     this.blitRgbxImage(a.x, a.y, a.width, a.height, a.data, 0, true);
1045                     break;
1046                 case 'img':
1047                     if (a.img.complete) {
1048                         this.drawImage(a.img, a.x, a.y);
1049                     } else {
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
1054                         ready = false;
1055                     }
1056                     break;
1057             }
1058
1059             if (ready) {
1060                 this._renderQ.shift();
1061             }
1062         }
1063
1064         if (this._renderQ.length === 0 && this._flushing) {
1065             this._flushing = false;
1066             this.onflush();
1067         }
1068     }
1069 };
1070
1071 // Class Methods
1072 Display.changeCursor = function (target, pixels, mask, hotx, hoty, w, h) {
1073     if (w === 0 || h === 0) {
1074         target.style.cursor = 'none';
1075         return;
1076     }
1077
1078     var cur = [];
1079     var y, x;
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
1089         }
1090     }
1091
1092     var canvas = document.createElement('canvas');
1093     var ctx = canvas.getContext('2d');
1094
1095     canvas.width = w;
1096     canvas.height = h;
1097
1098     var img;
1099     if (SUPPORTS_IMAGEDATA_CONSTRUCTOR) {
1100         img = new ImageData(new Uint8ClampedArray(cur), w, h);
1101     } else {
1102         img = ctx.createImageData(w, h);
1103         img.data.set(new Uint8ClampedArray(cur));
1104     }
1105     ctx.clearRect(0, 0, w, h);
1106     ctx.putImageData(img, 0, 0);
1107
1108     var url = canvas.toDataURL();
1109     target.style.cursor = 'url(' + url + ')' + hotx + ' ' + hoty + ', default';
1110 };
1111 },{"./base64.js":1,"./util/logging.js":19}],4:[function(require,module,exports){
1112 "use strict";
1113
1114 Object.defineProperty(exports, "__esModule", {
1115     value: true
1116 });
1117 exports.encodingName = encodingName;
1118 /*
1119  * noVNC: HTML5 VNC client
1120  * Copyright (C) 2017 Pierre Ossman for Cendio AB
1121  * Licensed under MPL 2.0 (see LICENSE.txt)
1122  *
1123  * See README.md for usage and integration instructions.
1124  */
1125
1126 var encodings = exports.encodings = {
1127     encodingRaw: 0,
1128     encodingCopyRect: 1,
1129     encodingRRE: 2,
1130     encodingHextile: 5,
1131     encodingTight: 7,
1132
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
1146 };
1147
1148 function encodingName(num) {
1149     switch (num) {
1150         case encodings.encodingRaw:
1151             return "Raw";
1152         case encodings.encodingCopyRect:
1153             return "CopyRect";
1154         case encodings.encodingRRE:
1155             return "RRE";
1156         case encodings.encodingHextile:
1157             return "Hextile";
1158         case encodings.encodingTight:
1159             return "Tight";
1160         default:
1161             return "[unknown encoding " + num + "]";
1162     }
1163 }
1164 },{}],5:[function(require,module,exports){
1165 "use strict";
1166
1167 Object.defineProperty(exports, "__esModule", {
1168     value: true
1169 });
1170 exports.default = Inflate;
1171
1172 var _inflate = require("../lib/vendor/pako/lib/zlib/inflate.js");
1173
1174 var _zstream = require("../lib/vendor/pako/lib/zlib/zstream.js");
1175
1176 var _zstream2 = _interopRequireDefault(_zstream);
1177
1178 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
1179
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;
1186
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);
1193         }
1194
1195         this.strm.avail_out = this.chunkSize;
1196
1197         (0, _inflate.inflate)(this.strm, flush);
1198
1199         return new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out);
1200     },
1201
1202     reset: function () {
1203         (0, _inflate.inflateReset)(this.strm);
1204     }
1205 };
1206
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;
1212
1213     (0, _inflate.inflateInit)(this.strm, this.windowBits);
1214 };
1215 },{"../lib/vendor/pako/lib/zlib/inflate.js":26,"../lib/vendor/pako/lib/zlib/zstream.js":28}],6:[function(require,module,exports){
1216 "use strict";
1217
1218 Object.defineProperty(exports, "__esModule", {
1219     value: true
1220 });
1221
1222 var _keysym = require("./keysym.js");
1223
1224 var _keysym2 = _interopRequireDefault(_keysym);
1225
1226 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
1227
1228 /*
1229  * Mapping between HTML key values and VNC/X11 keysyms for "special"
1230  * keys that cannot be handled via their Unicode codepoint.
1231  *
1232  * See https://www.w3.org/TR/uievents-key/ for possible values.
1233  */
1234
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)
1239                        */
1240
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];
1245 }
1246
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];
1252 }
1253
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];
1259 }
1260
1261 // 2.2. Modifier Keys
1262
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);
1267 // - Fn
1268 // - FnLock
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);
1275 // - Symbol
1276 // - SymbolLock
1277
1278 // 2.3. Whitespace Keys
1279
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);
1283
1284 // 2.4. Navigation Keys
1285
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);
1294
1295 // 2.5. Editing Keys
1296
1297 addStandard("Backspace", _keysym2.default.XK_BackSpace);
1298 addStandard("Clear", _keysym2.default.XK_Clear);
1299 addStandard("Copy", _keysym2.default.XF86XK_Copy);
1300 // - CrSel
1301 addStandard("Cut", _keysym2.default.XF86XK_Cut);
1302 addNumpad("Delete", _keysym2.default.XK_Delete, _keysym2.default.XK_KP_Delete);
1303 // - EraseEof
1304 // - ExSel
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);
1309
1310 // 2.6. UI Keys
1311
1312 // - Accept
1313 // - Again (could just be XK_Redo)
1314 // - Attn
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);
1322 // - Play
1323 // - Props
1324 addStandard("Select", _keysym2.default.XK_Select);
1325 addStandard("ZoomIn", _keysym2.default.XF86XK_ZoomIn);
1326 addStandard("ZoomOut", _keysym2.default.XF86XK_ZoomOut);
1327
1328 // 2.7. Device Keys
1329
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);
1340
1341 // 2.8. IME and Composition Keys
1342
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);
1348 // - Dead
1349 // - FinalMode
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)
1355 // - NextCandidate
1356 addStandard("NonConvert", _keysym2.default.XK_Muhenkan);
1357 addStandard("PreviousCandidate", _keysym2.default.XK_PreviousCandidate);
1358 // - Process
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);
1373
1374 // 2.9. General-Purpose Function Keys
1375
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);
1411 // - Soft1...
1412
1413 // 2.10. Multimedia Keys
1414
1415 // - ChannelDown
1416 // - ChannelUp
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);
1434
1435 // 2.11. Multimedia Numpad Keys
1436
1437 // - Key11
1438 // - Key12
1439
1440 // 2.12. Audio Keys
1441
1442 // - AudioBalanceLeft
1443 // - AudioBalanceRight
1444 // - AudioBassDown
1445 // - AudioBassBoostDown
1446 // - AudioBassBoostToggle
1447 // - AudioBassBoostUp
1448 // - AudioBassUp
1449 // - AudioFaderFront
1450 // - AudioFaderRear
1451 // - AudioSurroundModeNext
1452 // - AudioTrebleDown
1453 // - AudioTrebleUp
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);
1461
1462 // 2.13. Speech Keys
1463
1464 // - SpeechCorrectionList
1465 // - SpeechInputToggle
1466
1467 // 2.14. Application Keys
1468
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);
1481
1482 // 2.15. Browser Keys
1483
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);
1491
1492 // 2.16. Mobile Phone Keys
1493
1494 // - A whole bunch...
1495
1496 // 2.17. TV Keys
1497
1498 // - A whole bunch...
1499
1500 // 2.18. Media Controller Keys
1501
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);
1509
1510 // Extra: Numpad
1511
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);
1529
1530 exports.default = DOMKeyTable;
1531 },{"./keysym.js":9}],7:[function(require,module,exports){
1532 'use strict';
1533
1534 Object.defineProperty(exports, "__esModule", {
1535     value: true
1536 });
1537 /*
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)
1541  */
1542
1543 /*
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.
1548  *
1549  * See https://www.w3.org/TR/uievents-code/ for possible codes.
1550  * See https://www.w3.org/TR/uievents-key/ for possible values.
1551  */
1552
1553 exports.default = {
1554
1555     // 3.1.1.1. Writing System Keys
1556
1557     'Backspace': 'Backspace',
1558
1559     // 3.1.1.2. Functional Keys
1560
1561     'AltLeft': 'Alt',
1562     'AltRight': 'Alt', // This could also be 'AltGraph'
1563     'CapsLock': 'CapsLock',
1564     'ContextMenu': 'ContextMenu',
1565     'ControlLeft': 'Control',
1566     'ControlRight': 'Control',
1567     'Enter': 'Enter',
1568     'MetaLeft': 'Meta',
1569     'MetaRight': 'Meta',
1570     'ShiftLeft': 'Shift',
1571     'ShiftRight': 'Shift',
1572     'Tab': 'Tab',
1573     // FIXME: Japanese/Korean keys
1574
1575     // 3.1.2. Control Pad Section
1576
1577     'Delete': 'Delete',
1578     'End': 'End',
1579     'Help': 'Help',
1580     'Home': 'Home',
1581     'Insert': 'Insert',
1582     'PageDown': 'PageDown',
1583     'PageUp': 'PageUp',
1584
1585     // 3.1.3. Arrow Pad Section
1586
1587     'ArrowDown': 'ArrowDown',
1588     'ArrowLeft': 'ArrowLeft',
1589     'ArrowRight': 'ArrowRight',
1590     'ArrowUp': 'ArrowUp',
1591
1592     // 3.1.4. Numpad Section
1593
1594     'NumLock': 'NumLock',
1595     'NumpadBackspace': 'Backspace',
1596     'NumpadClear': 'Clear',
1597
1598     // 3.1.5. Function Section
1599
1600     'Escape': 'Escape',
1601     'F1': 'F1',
1602     'F2': 'F2',
1603     'F3': 'F3',
1604     'F4': 'F4',
1605     'F5': 'F5',
1606     'F6': 'F6',
1607     'F7': 'F7',
1608     'F8': 'F8',
1609     'F9': 'F9',
1610     'F10': 'F10',
1611     'F11': 'F11',
1612     'F12': 'F12',
1613     'F13': 'F13',
1614     'F14': 'F14',
1615     'F15': 'F15',
1616     'F16': 'F16',
1617     'F17': 'F17',
1618     'F18': 'F18',
1619     'F19': 'F19',
1620     'F20': 'F20',
1621     'F21': 'F21',
1622     'F22': 'F22',
1623     'F23': 'F23',
1624     'F24': 'F24',
1625     'F25': 'F25',
1626     'F26': 'F26',
1627     'F27': 'F27',
1628     'F28': 'F28',
1629     'F29': 'F29',
1630     'F30': 'F30',
1631     'F31': 'F31',
1632     'F32': 'F32',
1633     'F33': 'F33',
1634     'F34': 'F34',
1635     'F35': 'F35',
1636     'PrintScreen': 'PrintScreen',
1637     'ScrollLock': 'ScrollLock',
1638     'Pause': 'Pause',
1639
1640     // 3.1.6. Media Keys
1641
1642     'BrowserBack': 'BrowserBack',
1643     'BrowserFavorites': 'BrowserFavorites',
1644     'BrowserForward': 'BrowserForward',
1645     'BrowserHome': 'BrowserHome',
1646     'BrowserRefresh': 'BrowserRefresh',
1647     'BrowserSearch': 'BrowserSearch',
1648     'BrowserStop': 'BrowserStop',
1649     'Eject': 'Eject',
1650     'LaunchApp1': 'LaunchMyComputer',
1651     'LaunchApp2': 'LaunchCalendar',
1652     'LaunchMail': 'LaunchMail',
1653     'MediaPlayPause': 'MediaPlay',
1654     'MediaStop': 'MediaStop',
1655     'MediaTrackNext': 'MediaTrackNext',
1656     'MediaTrackPrevious': 'MediaTrackPrevious',
1657     'Power': 'Power',
1658     'Sleep': 'Sleep',
1659     'AudioVolumeDown': 'AudioVolumeDown',
1660     'AudioVolumeMute': 'AudioVolumeMute',
1661     'AudioVolumeUp': 'AudioVolumeUp',
1662     'WakeUp': 'WakeUp'
1663 };
1664 },{}],8:[function(require,module,exports){
1665 'use strict';
1666
1667 Object.defineProperty(exports, "__esModule", {
1668     value: true
1669 });
1670 exports.default = Keyboard;
1671
1672 var _logging = require('../util/logging.js');
1673
1674 var Log = _interopRequireWildcard(_logging);
1675
1676 var _events = require('../util/events.js');
1677
1678 var _util = require('./util.js');
1679
1680 var KeyboardUtil = _interopRequireWildcard(_util);
1681
1682 var _keysym = require('./keysym.js');
1683
1684 var _keysym2 = _interopRequireDefault(_keysym);
1685
1686 var _browser = require('../util/browser.js');
1687
1688 var browser = _interopRequireWildcard(_browser);
1689
1690 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
1691
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; } }
1693
1694 //
1695 // Keyboard event handler
1696 //
1697
1698 function Keyboard(target) {
1699     this._target = target || null;
1700
1701     this._keyDownList = {}; // List of depressed keys
1702     // (even if they are happy)
1703     this._pendingKey = null; // Key waiting for keypress
1704
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)
1711     };
1712 } /*
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)
1717    */
1718
1719 ;
1720
1721 Keyboard.prototype = {
1722     // ===== EVENT HANDLERS =====
1723
1724     onkeyevent: function () {}, // Handler for key press/release
1725
1726     // ===== PRIVATE METHODS =====
1727
1728     _sendKeyEvent: function (keysym, code, down) {
1729         Log.Debug("onkeyevent " + (down ? "down" : "up") + ", keysym: " + keysym, ", code: " + code);
1730
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);
1741             }
1742         }
1743
1744         this.onkeyevent(keysym, code, down);
1745
1746         if (fakeAltGraph) {
1747             this.onkeyevent(this._keyDownList['ControlLeft'], 'ControlLeft', true);
1748             this.onkeyevent(this._keyDownList['AltRight'], 'AltRight', true);
1749         }
1750     },
1751
1752     _getKeyCode: function (e) {
1753         var code = KeyboardUtil.getKeycode(e);
1754         if (code !== 'Unidentified') {
1755             return code;
1756         }
1757
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;
1765             }
1766         }
1767
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;
1774             }
1775
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();
1780
1781             return 'Platform' + char.charCodeAt();
1782         }
1783
1784         return 'Unidentified';
1785     },
1786
1787     _handleKeyDown: function (e) {
1788         var code = this._getKeyCode(e);
1789         var keysym = KeyboardUtil.getKeysym(e);
1790
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()) {
1796             if (keysym) {
1797                 // If it's a virtual keyboard then it should be
1798                 // sufficient to just send press and release right
1799                 // after each other
1800                 this._sendKeyEvent(keysym, code, true);
1801                 this._sendKeyEvent(keysym, code, false);
1802             }
1803
1804             (0, _events.stopEvent)(e);
1805             return;
1806         }
1807
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()) {
1813             switch (keysym) {
1814                 case _keysym2.default.XK_Super_L:
1815                     keysym = _keysym2.default.XK_Alt_L;
1816                     break;
1817                 case _keysym2.default.XK_Super_R:
1818                     keysym = _keysym2.default.XK_Super_L;
1819                     break;
1820                 case _keysym2.default.XK_Alt_L:
1821                     keysym = _keysym2.default.XK_Mode_switch;
1822                     break;
1823                 case _keysym2.default.XK_Alt_R:
1824                     keysym = _keysym2.default.XK_ISO_Level3_Shift;
1825                     break;
1826             }
1827         }
1828
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];
1833         }
1834
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);
1843             return;
1844         }
1845
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
1854             // handling
1855             setTimeout(this._handleKeyPressTimeout.bind(this), 10, e);
1856             return;
1857         }
1858
1859         this._pendingKey = null;
1860         (0, _events.stopEvent)(e);
1861
1862         this._keyDownList[code] = keysym;
1863
1864         this._sendKeyEvent(keysym, code, true);
1865     },
1866
1867     // Legacy event for browsers without code/key
1868     _handleKeyPress: function (e) {
1869         (0, _events.stopEvent)(e);
1870
1871         // Are we expecting a keypress?
1872         if (this._pendingKey === null) {
1873             return;
1874         }
1875
1876         var code = this._getKeyCode(e);
1877         var keysym = KeyboardUtil.getKeysym(e);
1878
1879         // The key we were waiting for?
1880         if (code !== 'Unidentified' && code != this._pendingKey) {
1881             return;
1882         }
1883
1884         code = this._pendingKey;
1885         this._pendingKey = null;
1886
1887         if (!keysym) {
1888             Log.Info('keypress with no keysym:', e);
1889             return;
1890         }
1891
1892         this._keyDownList[code] = keysym;
1893
1894         this._sendKeyEvent(keysym, code, true);
1895     },
1896     _handleKeyPressTimeout: function (e) {
1897         // Did someone manage to sort out the key already?
1898         if (this._pendingKey === null) {
1899             return;
1900         }
1901
1902         var code, keysym;
1903
1904         code = this._pendingKey;
1905         this._pendingKey = null;
1906
1907         // We have no way of knowing the proper keysym with the
1908         // information given, but the following are true for most
1909         // layouts
1910         if (e.keyCode >= 0x30 && e.keyCode <= 0x39) {
1911             // Digit
1912             keysym = e.keyCode;
1913         } else if (e.keyCode >= 0x41 && e.keyCode <= 0x5a) {
1914             // Character (A-Z)
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();
1919         } else {
1920             // Unknown, give up
1921             keysym = 0;
1922         }
1923
1924         this._keyDownList[code] = keysym;
1925
1926         this._sendKeyEvent(keysym, code, true);
1927     },
1928
1929     _handleKeyUp: function (e) {
1930         (0, _events.stopEvent)(e);
1931
1932         var code = this._getKeyCode(e);
1933
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);
1938             return;
1939         }
1940
1941         // Do we really think this key is down?
1942         if (!(code in this._keyDownList)) {
1943             return;
1944         }
1945
1946         this._sendKeyEvent(this._keyDownList[code], code, false);
1947
1948         delete this._keyDownList[code];
1949     },
1950
1951     _allKeysUp: function () {
1952         Log.Debug(">> Keyboard.allKeysUp");
1953         for (var code in this._keyDownList) {
1954             this._sendKeyEvent(this._keyDownList[code], code, false);
1955         };
1956         this._keyDownList = {};
1957         Log.Debug("<< Keyboard.allKeysUp");
1958     },
1959
1960     // ===== PUBLIC METHODS =====
1961
1962     grab: function () {
1963         //Log.Debug(">> Keyboard.grab");
1964         var c = this._target;
1965
1966         c.addEventListener('keydown', this._eventHandlers.keydown);
1967         c.addEventListener('keyup', this._eventHandlers.keyup);
1968         c.addEventListener('keypress', this._eventHandlers.keypress);
1969
1970         // Release (key up) if window loses focus
1971         window.addEventListener('blur', this._eventHandlers.blur);
1972
1973         //Log.Debug("<< Keyboard.grab");
1974     },
1975
1976     ungrab: function () {
1977         //Log.Debug(">> Keyboard.ungrab");
1978         var c = this._target;
1979
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);
1984
1985         // Release (key up) all keys that are in a down state
1986         this._allKeysUp();
1987
1988         //Log.Debug(">> Keyboard.ungrab");
1989     }
1990 };
1991 },{"../util/browser.js":16,"../util/events.js":17,"../util/logging.js":19,"./keysym.js":9,"./util.js":12}],9:[function(require,module,exports){
1992 "use strict";
1993
1994 Object.defineProperty(exports, "__esModule", {
1995   value: true
1996 });
1997 exports.default = {
1998   XK_VoidSymbol: 0xffffff, /* Void symbol */
1999
2000   XK_BackSpace: 0xff08, /* Back space, back char */
2001   XK_Tab: 0xff09,
2002   XK_Linefeed: 0xff0a, /* Linefeed, LF */
2003   XK_Clear: 0xff0b,
2004   XK_Return: 0xff0d, /* Return, enter */
2005   XK_Pause: 0xff13, /* Pause, hold */
2006   XK_Scroll_Lock: 0xff14,
2007   XK_Sys_Req: 0xff15,
2008   XK_Escape: 0xff1b,
2009   XK_Delete: 0xffff, /* Delete, rubout */
2010
2011   /* International & multi-key character composition */
2012
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,
2018
2019   /* Japanese keyboard support */
2020
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 */
2041
2042   /* Cursor control & motion */
2043
2044   XK_Home: 0xff50,
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 */
2050   XK_Page_Up: 0xff55,
2051   XK_Next: 0xff56, /* Next */
2052   XK_Page_Down: 0xff56,
2053   XK_End: 0xff57, /* EOL */
2054   XK_Begin: 0xff58, /* BOL */
2055
2056   /* Misc functions */
2057
2058   XK_Select: 0xff60, /* Select, mark */
2059   XK_Print: 0xff61,
2060   XK_Execute: 0xff62, /* Execute, run, do */
2061   XK_Insert: 0xff63, /* Insert, insert here */
2062   XK_Undo: 0xff65,
2063   XK_Redo: 0xff66, /* Redo, again */
2064   XK_Menu: 0xff67,
2065   XK_Find: 0xff68, /* Find, search */
2066   XK_Cancel: 0xff69, /* Cancel, stop, abort, exit */
2067   XK_Help: 0xff6a, /* Help */
2068   XK_Break: 0xff6b,
2069   XK_Mode_switch: 0xff7e, /* Character set switch */
2070   XK_script_switch: 0xff7e, /* Alias for mode_switch */
2071   XK_Num_Lock: 0xff7f,
2072
2073   /* Keypad functions, keypad numbers cleverly chosen to map to ASCII */
2074
2075   XK_KP_Space: 0xff80, /* Space */
2076   XK_KP_Tab: 0xff89,
2077   XK_KP_Enter: 0xff8d, /* Enter */
2078   XK_KP_F1: 0xff91, /* PF1, KP_A, ... */
2079   XK_KP_F2: 0xff92,
2080   XK_KP_F3: 0xff93,
2081   XK_KP_F4: 0xff94,
2082   XK_KP_Home: 0xff95,
2083   XK_KP_Left: 0xff96,
2084   XK_KP_Up: 0xff97,
2085   XK_KP_Right: 0xff98,
2086   XK_KP_Down: 0xff99,
2087   XK_KP_Prior: 0xff9a,
2088   XK_KP_Page_Up: 0xff9a,
2089   XK_KP_Next: 0xff9b,
2090   XK_KP_Page_Down: 0xff9b,
2091   XK_KP_End: 0xff9c,
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,
2097   XK_KP_Add: 0xffab,
2098   XK_KP_Separator: 0xffac, /* Separator, often comma */
2099   XK_KP_Subtract: 0xffad,
2100   XK_KP_Decimal: 0xffae,
2101   XK_KP_Divide: 0xffaf,
2102
2103   XK_KP_0: 0xffb0,
2104   XK_KP_1: 0xffb1,
2105   XK_KP_2: 0xffb2,
2106   XK_KP_3: 0xffb3,
2107   XK_KP_4: 0xffb4,
2108   XK_KP_5: 0xffb5,
2109   XK_KP_6: 0xffb6,
2110   XK_KP_7: 0xffb7,
2111   XK_KP_8: 0xffb8,
2112   XK_KP_9: 0xffb9,
2113
2114   /*
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.
2119    */
2120
2121   XK_F1: 0xffbe,
2122   XK_F2: 0xffbf,
2123   XK_F3: 0xffc0,
2124   XK_F4: 0xffc1,
2125   XK_F5: 0xffc2,
2126   XK_F6: 0xffc3,
2127   XK_F7: 0xffc4,
2128   XK_F8: 0xffc5,
2129   XK_F9: 0xffc6,
2130   XK_F10: 0xffc7,
2131   XK_F11: 0xffc8,
2132   XK_L1: 0xffc8,
2133   XK_F12: 0xffc9,
2134   XK_L2: 0xffc9,
2135   XK_F13: 0xffca,
2136   XK_L3: 0xffca,
2137   XK_F14: 0xffcb,
2138   XK_L4: 0xffcb,
2139   XK_F15: 0xffcc,
2140   XK_L5: 0xffcc,
2141   XK_F16: 0xffcd,
2142   XK_L6: 0xffcd,
2143   XK_F17: 0xffce,
2144   XK_L7: 0xffce,
2145   XK_F18: 0xffcf,
2146   XK_L8: 0xffcf,
2147   XK_F19: 0xffd0,
2148   XK_L9: 0xffd0,
2149   XK_F20: 0xffd1,
2150   XK_L10: 0xffd1,
2151   XK_F21: 0xffd2,
2152   XK_R1: 0xffd2,
2153   XK_F22: 0xffd3,
2154   XK_R2: 0xffd3,
2155   XK_F23: 0xffd4,
2156   XK_R3: 0xffd4,
2157   XK_F24: 0xffd5,
2158   XK_R4: 0xffd5,
2159   XK_F25: 0xffd6,
2160   XK_R5: 0xffd6,
2161   XK_F26: 0xffd7,
2162   XK_R6: 0xffd7,
2163   XK_F27: 0xffd8,
2164   XK_R7: 0xffd8,
2165   XK_F28: 0xffd9,
2166   XK_R8: 0xffd9,
2167   XK_F29: 0xffda,
2168   XK_R9: 0xffda,
2169   XK_F30: 0xffdb,
2170   XK_R10: 0xffdb,
2171   XK_F31: 0xffdc,
2172   XK_R11: 0xffdc,
2173   XK_F32: 0xffdd,
2174   XK_R12: 0xffdd,
2175   XK_F33: 0xffde,
2176   XK_R13: 0xffde,
2177   XK_F34: 0xffdf,
2178   XK_R14: 0xffdf,
2179   XK_F35: 0xffe0,
2180   XK_R15: 0xffe0,
2181
2182   /* Modifiers */
2183
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 */
2190
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 */
2199
2200   /*
2201    * Keyboard (XKB) Extension function and modifier keys
2202    * (from Appendix C of "The X Keyboard Extension: Protocol Specification")
2203    * Byte 3 = 0xfe
2204    */
2205
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,
2211
2212   /*
2213    * Latin 1
2214    * (ISO/IEC 8859-1: Unicode U+0020..U+00FF)
2215    * Byte 3: 0
2216    */
2217
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 */
2315
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 */
2416
2417   /*
2418    * Korean
2419    * Byte 3 = 0x0e
2420    */
2421
2422   XK_Hangul: 0xff31, /* Hangul start/stop(toggle) */
2423   XK_Hangul_Hanja: 0xff34, /* Start Hangul->Hanja Conversion */
2424   XK_Hangul_Jeonja: 0xff38, /* Jeonja mode */
2425
2426   /*
2427    * XFree86 vendor specific keysyms.
2428    *
2429    * The XFree86 keysym range is 0x10080001 - 0x1008FFFF.
2430    */
2431
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
2609 };
2610 },{}],10:[function(require,module,exports){
2611 "use strict";
2612
2613 Object.defineProperty(exports, "__esModule", {
2614     value: true
2615 });
2616 /*
2617  * Mapping from Unicode codepoints to X11/RFB keysyms
2618  *
2619  * This file was automatically generated from keysymdef.h
2620  * DO NOT EDIT!
2621  */
2622
2623 /* Functions at the bottom */
2624
2625 var codepoints = {
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
3285 };
3286
3287 exports.default = {
3288     lookup: function (u) {
3289         // Latin-1 is one-to-one mapping
3290         if (u >= 0x20 && u <= 0xff) {
3291             return u;
3292         }
3293
3294         // Lookup table (fairly random)
3295         var keysym = codepoints[u];
3296         if (keysym !== undefined) {
3297             return keysym;
3298         }
3299
3300         // General mapping as final fallback
3301         return 0x01000000 | u;
3302     }
3303 };
3304 },{}],11:[function(require,module,exports){
3305 'use strict';
3306
3307 Object.defineProperty(exports, "__esModule", {
3308     value: true
3309 });
3310 exports.default = Mouse;
3311
3312 var _logging = require('../util/logging.js');
3313
3314 var Log = _interopRequireWildcard(_logging);
3315
3316 var _browser = require('../util/browser.js');
3317
3318 var _events = require('../util/events.js');
3319
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; } }
3321
3322 var WHEEL_STEP = 10; // Delta threshold for a mouse wheel step
3323 /*
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)
3328  */
3329
3330 var WHEEL_STEP_TIMEOUT = 50; // ms
3331 var WHEEL_LINE_HEIGHT = 19;
3332
3333 function Mouse(target) {
3334     this._target = target || document;
3335
3336     this._doubleClickTimer = null;
3337     this._lastTouchPos = null;
3338
3339     this._pos = null;
3340     this._wheelStepXTimer = null;
3341     this._wheelStepYTimer = null;
3342     this._accumulatedWheelDeltaX = 0;
3343     this._accumulatedWheelDeltaY = 0;
3344
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)
3351     };
3352 };
3353
3354 Mouse.prototype = {
3355     // ===== PROPERTIES =====
3356
3357     touchButton: 1, // Button mask (1, 2, 4) for touch devices (0 means ignore clicks)
3358
3359     // ===== EVENT HANDLERS =====
3360
3361     onmousebutton: function () {}, // Handler for mouse button click/release
3362     onmousemove: function () {}, // Handler for mouse movement
3363
3364     // ===== PRIVATE METHODS =====
3365
3366     _resetDoubleClickTimer: function () {
3367         this._doubleClickTimer = null;
3368     },
3369
3370     _handleMouseButton: function (e, down) {
3371         this._updateMousePosition(e);
3372         var pos = this._pos;
3373
3374         var bmask;
3375         if (e.touches || e.changedTouches) {
3376             // Touch device
3377
3378             // When two touches occur within 500 ms of each other and are
3379             // close enough together a double click is triggered.
3380             if (down == 1) {
3381                 if (this._doubleClickTimer === null) {
3382                     this._lastTouchPos = pos;
3383                 } else {
3384                     clearTimeout(this._doubleClickTimer);
3385
3386                     // When the distance between the two touches is small enough
3387                     // force the position of the latter touch to the position of
3388                     // the first.
3389
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);
3393
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;
3399                     }
3400                 }
3401                 this._doubleClickTimer = setTimeout(this._resetDoubleClickTimer.bind(this), 500);
3402             }
3403             bmask = this.touchButton;
3404             // If bmask is set
3405         } else if (e.which) {
3406             /* everything except IE */
3407             bmask = 1 << e.button;
3408         } else {
3409             /* IE including 9 */
3410             bmask = (e.button & 0x1) + // Left
3411             (e.button & 0x2) * 2 + // Right
3412             (e.button & 0x4) / 2; // Middle
3413         }
3414
3415         Log.Debug("onmousebutton " + (down ? "down" : "up") + ", x: " + pos.x + ", y: " + pos.y + ", bmask: " + bmask);
3416         this.onmousebutton(pos.x, pos.y, down, bmask);
3417
3418         (0, _events.stopEvent)(e);
3419     },
3420
3421     _handleMouseDown: function (e) {
3422         // Touch events have implicit capture
3423         if (e.type === "mousedown") {
3424             (0, _events.setCapture)(this._target);
3425         }
3426
3427         this._handleMouseButton(e, 1);
3428     },
3429
3430     _handleMouseUp: function (e) {
3431         this._handleMouseButton(e, 0);
3432     },
3433
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 () {
3438
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);
3445         }
3446
3447         this._accumulatedWheelDeltaX = 0;
3448     },
3449
3450     _generateWheelStepY: function () {
3451
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);
3458         }
3459
3460         this._accumulatedWheelDeltaY = 0;
3461     },
3462
3463     _resetWheelStepTimers: function () {
3464         window.clearTimeout(this._wheelStepXTimer);
3465         window.clearTimeout(this._wheelStepYTimer);
3466         this._wheelStepXTimer = null;
3467         this._wheelStepYTimer = null;
3468     },
3469
3470     _handleMouseWheel: function (e) {
3471         this._resetWheelStepTimers();
3472
3473         this._updateMousePosition(e);
3474
3475         var dX = e.deltaX;
3476         var dY = e.deltaY;
3477
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;
3486         }
3487
3488         this._accumulatedWheelDeltaX += dX;
3489         this._accumulatedWheelDeltaY += dY;
3490
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
3494         // after a timeout.
3495         if (Math.abs(this._accumulatedWheelDeltaX) > WHEEL_STEP) {
3496             this._generateWheelStepX();
3497         } else {
3498             this._wheelStepXTimer = window.setTimeout(this._generateWheelStepX.bind(this), WHEEL_STEP_TIMEOUT);
3499         }
3500         if (Math.abs(this._accumulatedWheelDeltaY) > WHEEL_STEP) {
3501             this._generateWheelStepY();
3502         } else {
3503             this._wheelStepYTimer = window.setTimeout(this._generateWheelStepY.bind(this), WHEEL_STEP_TIMEOUT);
3504         }
3505
3506         (0, _events.stopEvent)(e);
3507     },
3508
3509     _handleMouseMove: function (e) {
3510         this._updateMousePosition(e);
3511         this.onmousemove(this._pos.x, this._pos.y);
3512         (0, _events.stopEvent)(e);
3513     },
3514
3515     _handleMouseDisable: function (e) {
3516         /*
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.
3521          */
3522         if (e.target == this._target) {
3523             (0, _events.stopEvent)(e);
3524         }
3525     },
3526
3527     // Update coordinates relative to target
3528     _updateMousePosition: function (e) {
3529         e = (0, _events.getPointerEvent)(e);
3530         var bounds = this._target.getBoundingClientRect();
3531         var x, y;
3532         // Clip to target bounds
3533         if (e.clientX < bounds.left) {
3534             x = 0;
3535         } else if (e.clientX >= bounds.right) {
3536             x = bounds.width - 1;
3537         } else {
3538             x = e.clientX - bounds.left;
3539         }
3540         if (e.clientY < bounds.top) {
3541             y = 0;
3542         } else if (e.clientY >= bounds.bottom) {
3543             y = bounds.height - 1;
3544         } else {
3545             y = e.clientY - bounds.top;
3546         }
3547         this._pos = { x: x, y: y };
3548     },
3549
3550     // ===== PUBLIC METHODS =====
3551
3552     grab: function () {
3553         var c = this._target;
3554
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);
3559         }
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);
3564
3565         /* Prevent middle-click pasting (see above for why we bind to document) */
3566         document.addEventListener('click', this._eventHandlers.mousedisable);
3567
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);
3571     },
3572
3573     ungrab: function () {
3574         var c = this._target;
3575
3576         this._resetWheelStepTimers();
3577
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);
3582         }
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);
3587
3588         document.removeEventListener('click', this._eventHandlers.mousedisable);
3589
3590         c.removeEventListener('contextmenu', this._eventHandlers.mousedisable);
3591     }
3592 };
3593 },{"../util/browser.js":16,"../util/events.js":17,"../util/logging.js":19}],12:[function(require,module,exports){
3594 "use strict";
3595
3596 Object.defineProperty(exports, "__esModule", {
3597     value: true
3598 });
3599 exports.getKeycode = getKeycode;
3600 exports.getKey = getKey;
3601 exports.getKeysym = getKeysym;
3602
3603 var _keysym = require("./keysym.js");
3604
3605 var _keysym2 = _interopRequireDefault(_keysym);
3606
3607 var _keysymdef = require("./keysymdef.js");
3608
3609 var _keysymdef2 = _interopRequireDefault(_keysymdef);
3610
3611 var _vkeys = require("./vkeys.js");
3612
3613 var _vkeys2 = _interopRequireDefault(_vkeys);
3614
3615 var _fixedkeys = require("./fixedkeys.js");
3616
3617 var _fixedkeys2 = _interopRequireDefault(_fixedkeys);
3618
3619 var _domkeytable = require("./domkeytable.js");
3620
3621 var _domkeytable2 = _interopRequireDefault(_domkeytable);
3622
3623 var _browser = require("../util/browser.js");
3624
3625 var browser = _interopRequireWildcard(_browser);
3626
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; } }
3628
3629 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
3630
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
3636     // undefined)
3637     if (evt.code) {
3638         // Mozilla isn't fully in sync with the spec yet
3639         switch (evt.code) {
3640             case 'OSLeft':
3641                 return 'MetaLeft';
3642             case 'OSRight':
3643                 return 'MetaRight';
3644         }
3645
3646         return evt.code;
3647     }
3648
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];
3654
3655         // macOS has messed up this code for some reason
3656         if (browser.isMac() && code === 'ContextMenu') {
3657             code = 'MetaRight';
3658         }
3659
3660         // The keyCode doesn't distinguish between left and right
3661         // for the standard modifiers
3662         if (evt.location === 2) {
3663             switch (code) {
3664                 case 'ShiftLeft':
3665                     return 'ShiftRight';
3666                 case 'ControlLeft':
3667                     return 'ControlRight';
3668                 case 'AltLeft':
3669                     return 'AltRight';
3670             }
3671         }
3672
3673         // Nor a bunch of the numpad keys
3674         if (evt.location === 3) {
3675             switch (code) {
3676                 case 'Delete':
3677                     return 'NumpadDecimal';
3678                 case 'Insert':
3679                     return 'Numpad0';
3680                 case 'End':
3681                     return 'Numpad1';
3682                 case 'ArrowDown':
3683                     return 'Numpad2';
3684                 case 'PageDown':
3685                     return 'Numpad3';
3686                 case 'ArrowLeft':
3687                     return 'Numpad4';
3688                 case 'ArrowRight':
3689                     return 'Numpad6';
3690                 case 'Home':
3691                     return 'Numpad7';
3692                 case 'ArrowUp':
3693                     return 'Numpad8';
3694                 case 'PageUp':
3695                     return 'Numpad9';
3696                 case 'Enter':
3697                     return 'NumpadEnter';
3698             }
3699         }
3700
3701         return code;
3702     }
3703
3704     return 'Unidentified';
3705 }
3706
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/
3713         switch (evt.key) {
3714             case 'Spacebar':
3715                 return ' ';
3716             case 'Esc':
3717                 return 'Escape';
3718             case 'Scroll':
3719                 return 'ScrollLock';
3720             case 'Win':
3721                 return 'Meta';
3722             case 'Apps':
3723                 return 'ContextMenu';
3724             case 'Up':
3725                 return 'ArrowUp';
3726             case 'Left':
3727                 return 'ArrowLeft';
3728             case 'Right':
3729                 return 'ArrowRight';
3730             case 'Down':
3731                 return 'ArrowDown';
3732             case 'Del':
3733                 return 'Delete';
3734             case 'Divide':
3735                 return '/';
3736             case 'Multiply':
3737                 return '*';
3738             case 'Subtract':
3739                 return '-';
3740             case 'Add':
3741                 return '+';
3742             case 'Decimal':
3743                 return evt.char;
3744         }
3745
3746         // Mozilla isn't fully in sync with the spec yet
3747         switch (evt.key) {
3748             case 'OS':
3749                 return 'Meta';
3750         }
3751
3752         // iOS leaks some OS names
3753         switch (evt.key) {
3754             case 'UIKeyInputUpArrow':
3755                 return 'ArrowUp';
3756             case 'UIKeyInputDownArrow':
3757                 return 'ArrowDown';
3758             case 'UIKeyInputLeftArrow':
3759                 return 'ArrowLeft';
3760             case 'UIKeyInputRightArrow':
3761                 return 'ArrowRight';
3762             case 'UIKeyInputEscape':
3763                 return 'Escape';
3764         }
3765
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()) {
3769             return evt.key;
3770         }
3771     }
3772
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];
3777     }
3778
3779     // If that failed, then see if we have a printable character
3780     if (evt.charCode) {
3781         return String.fromCharCode(evt.charCode);
3782     }
3783
3784     // At this point we have nothing left to go on
3785     return 'Unidentified';
3786 }
3787
3788 // Get the most reliable keysym value we can get from a key event
3789 function getKeysym(evt) {
3790     var key = getKey(evt);
3791
3792     if (key === 'Unidentified') {
3793         return null;
3794     }
3795
3796     // First look up special keys
3797     if (key in _domkeytable2.default) {
3798         var location = evt.location;
3799
3800         // Safari screws up location for the right cmd key
3801         if (key === 'Meta' && location === 0) {
3802             location = 2;
3803         }
3804
3805         if (location === undefined || location > 3) {
3806             location = 0;
3807         }
3808
3809         return _domkeytable2.default[key][location];
3810     }
3811
3812     // Now we need to look at the Unicode symbol instead
3813
3814     var codepoint;
3815
3816     // Special key? (FIXME: Should have been caught earlier)
3817     if (key.length !== 1) {
3818         return null;
3819     }
3820
3821     codepoint = key.charCodeAt();
3822     if (codepoint) {
3823         return _keysymdef2.default.lookup(codepoint);
3824     }
3825
3826     return null;
3827 }
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){
3829 'use strict';
3830
3831 Object.defineProperty(exports, "__esModule", {
3832   value: true
3833 });
3834 /*
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)
3838  */
3839
3840 /*
3841  * Mapping between Microsoft® Windows® Virtual-Key codes and
3842  * HTML key codes.
3843  */
3844
3845 exports.default = {
3846   0x08: 'Backspace',
3847   0x09: 'Tab',
3848   0x0a: 'NumpadClear',
3849   0x0d: 'Enter',
3850   0x10: 'ShiftLeft',
3851   0x11: 'ControlLeft',
3852   0x12: 'AltLeft',
3853   0x13: 'Pause',
3854   0x14: 'CapsLock',
3855   0x15: 'Lang1',
3856   0x19: 'Lang2',
3857   0x1b: 'Escape',
3858   0x1c: 'Convert',
3859   0x1d: 'NonConvert',
3860   0x20: 'Space',
3861   0x21: 'PageUp',
3862   0x22: 'PageDown',
3863   0x23: 'End',
3864   0x24: 'Home',
3865   0x25: 'ArrowLeft',
3866   0x26: 'ArrowUp',
3867   0x27: 'ArrowRight',
3868   0x28: 'ArrowDown',
3869   0x29: 'Select',
3870   0x2c: 'PrintScreen',
3871   0x2d: 'Insert',
3872   0x2e: 'Delete',
3873   0x2f: 'Help',
3874   0x30: 'Digit0',
3875   0x31: 'Digit1',
3876   0x32: 'Digit2',
3877   0x33: 'Digit3',
3878   0x34: 'Digit4',
3879   0x35: 'Digit5',
3880   0x36: 'Digit6',
3881   0x37: 'Digit7',
3882   0x38: 'Digit8',
3883   0x39: 'Digit9',
3884   0x5b: 'MetaLeft',
3885   0x5c: 'MetaRight',
3886   0x5d: 'ContextMenu',
3887   0x5f: 'Sleep',
3888   0x60: 'Numpad0',
3889   0x61: 'Numpad1',
3890   0x62: 'Numpad2',
3891   0x63: 'Numpad3',
3892   0x64: 'Numpad4',
3893   0x65: 'Numpad5',
3894   0x66: 'Numpad6',
3895   0x67: 'Numpad7',
3896   0x68: 'Numpad8',
3897   0x69: 'Numpad9',
3898   0x6a: 'NumpadMultiply',
3899   0x6b: 'NumpadAdd',
3900   0x6c: 'NumpadDecimal',
3901   0x6d: 'NumpadSubtract',
3902   0x6e: 'NumpadDecimal', // Duplicate, because buggy on Windows
3903   0x6f: 'NumpadDivide',
3904   0x70: 'F1',
3905   0x71: 'F2',
3906   0x72: 'F3',
3907   0x73: 'F4',
3908   0x74: 'F5',
3909   0x75: 'F6',
3910   0x76: 'F7',
3911   0x77: 'F8',
3912   0x78: 'F9',
3913   0x79: 'F10',
3914   0x7a: 'F11',
3915   0x7b: 'F12',
3916   0x7c: 'F13',
3917   0x7d: 'F14',
3918   0x7e: 'F15',
3919   0x7f: 'F16',
3920   0x80: 'F17',
3921   0x81: 'F18',
3922   0x82: 'F19',
3923   0x83: 'F20',
3924   0x84: 'F21',
3925   0x85: 'F22',
3926   0x86: 'F23',
3927   0x87: 'F24',
3928   0x90: 'NumLock',
3929   0x91: 'ScrollLock',
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',
3942   0xb2: 'MediaStop',
3943   0xb3: 'MediaPlayPause',
3944   0xb4: 'LaunchMail',
3945   0xb5: 'MediaSelect',
3946   0xb6: 'LaunchApp1',
3947   0xb7: 'LaunchApp2',
3948   0xe1: 'AltRight' // Only when it is AltGraph
3949 };
3950 },{}],14:[function(require,module,exports){
3951 "use strict";
3952
3953 Object.defineProperty(exports, "__esModule", {
3954   value: true
3955 });
3956 /*
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
3961 */
3962 exports.default = {
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 */
4126 };
4127 },{}],15:[function(require,module,exports){
4128 'use strict';
4129
4130 Object.defineProperty(exports, "__esModule", {
4131     value: true
4132 });
4133 exports.default = RFB;
4134
4135 var _logging = require('./util/logging.js');
4136
4137 var Log = _interopRequireWildcard(_logging);
4138
4139 var _strings = require('./util/strings.js');
4140
4141 var _browser = require('./util/browser.js');
4142
4143 var _eventtarget = require('./util/eventtarget.js');
4144
4145 var _eventtarget2 = _interopRequireDefault(_eventtarget);
4146
4147 var _display = require('./display.js');
4148
4149 var _display2 = _interopRequireDefault(_display);
4150
4151 var _keyboard = require('./input/keyboard.js');
4152
4153 var _keyboard2 = _interopRequireDefault(_keyboard);
4154
4155 var _mouse = require('./input/mouse.js');
4156
4157 var _mouse2 = _interopRequireDefault(_mouse);
4158
4159 var _websock = require('./websock.js');
4160
4161 var _websock2 = _interopRequireDefault(_websock);
4162
4163 var _des = require('./des.js');
4164
4165 var _des2 = _interopRequireDefault(_des);
4166
4167 var _keysym = require('./input/keysym.js');
4168
4169 var _keysym2 = _interopRequireDefault(_keysym);
4170
4171 var _xtscancodes = require('./input/xtscancodes.js');
4172
4173 var _xtscancodes2 = _interopRequireDefault(_xtscancodes);
4174
4175 var _inflator = require('./inflator.js');
4176
4177 var _inflator2 = _interopRequireDefault(_inflator);
4178
4179 var _encodings = require('./encodings.js');
4180
4181 require('./util/polyfill.js');
4182
4183 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
4184
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; } }
4186
4187 /*jslint white: false, browser: true */
4188 /*global window, Util, Display, Keyboard, Mouse, Websock, Websock_native, Base64, DES, KeyTable, Inflator, XtScancode */
4189
4190 // How many seconds to wait for a disconnect to finish
4191 /*
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)
4196  *
4197  * See README.md for usage and integration instructions.
4198  *
4199  * TIGHT decoder portion:
4200  * (c) 2012 Michael Tinglof, Joe Balaz, Les Piech (Mercuri.ca)
4201  */
4202
4203 var DISCONNECT_TIMEOUT = 3;
4204
4205 function RFB(target, url, options) {
4206     if (!target) {
4207         throw Error("Must specify target");
4208     }
4209     if (!url) {
4210         throw Error("Must specify URL");
4211     }
4212
4213     this._target = target;
4214     this._url = url;
4215
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 || '';
4221
4222     // Internal state
4223     this._rfb_connection_state = '';
4224     this._rfb_init_state = '';
4225     this._rfb_auth_scheme = '';
4226     this._rfb_clean_disconnect = true;
4227
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;
4233
4234     this._fb_width = 0;
4235     this._fb_height = 0;
4236
4237     this._fb_name = "";
4238
4239     this._capabilities = { power: false };
4240
4241     this._supportsFence = false;
4242
4243     this._supportsContinuousUpdates = false;
4244     this._enabledContinuousUpdates = false;
4245
4246     this._supportsSetDesktopSize = false;
4247     this._screen_id = 0;
4248     this._screen_flags = 0;
4249
4250     this._qemuExtKeyEventSupported = false;
4251
4252     // Internal objects
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
4258
4259     // Timers
4260     this._disconnTimer = null; // disconnection timer
4261     this._resizeTimeout = null; // resize rate limiting
4262
4263     // Decoder states and stats
4264     this._encHandlers = {};
4265     this._encStats = {};
4266
4267     this._FBU = {
4268         rects: 0,
4269         subrects: 0, // RRE and HEXTILE
4270         lines: 0, // RAW
4271         tiles: 0, // HEXTILE
4272         bytes: 0,
4273         x: 0,
4274         y: 0,
4275         width: 0,
4276         height: 0,
4277         encoding: 0,
4278         subencoding: -1,
4279         background: null,
4280         zlibs: [] // TIGHT zlib streams
4281     };
4282     for (var i = 0; i < 4; i++) {
4283         this._FBU.zlibs[i] = new _inflator2.default();
4284     }
4285
4286     this._destBuff = null;
4287     this._paletteBuff = new Uint8Array(1024); // 256 * 4 (max palette size * max bytes-per-pixel)
4288
4289     this._rre_chunk_sz = 100;
4290
4291     this._timing = {
4292         last_fbu: 0,
4293         fbu_total: 0,
4294         fbu_total_cnt: 0,
4295         full_fbu_total: 0,
4296         full_fbu_cnt: 0,
4297
4298         fbu_rt_start: 0,
4299         fbu_rt_total: 0,
4300         fbu_rt_cnt: 0,
4301         pixels: 0
4302     };
4303
4304     // Mouse state
4305     this._mouse_buttonMask = 0;
4306     this._mouse_arr = [];
4307     this._viewportDragging = false;
4308     this._viewportDragPos = {};
4309     this._viewportHasMoved = false;
4310
4311     // Bound event handlers
4312     this._eventHandlers = {
4313         focusCanvas: this._focusCanvas.bind(this),
4314         windowResize: this._windowResize.bind(this)
4315     };
4316
4317     // main setup
4318     Log.Debug(">> RFB.constructor");
4319
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);
4337
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);
4344
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);
4350
4351     // NB: nothing that needs explicit teardown should be done
4352     // before this point, since this can throw an exception
4353     try {
4354         this._display = new _display2.default(this._canvas);
4355     } catch (exc) {
4356         Log.Error("Display exception: " + exc);
4357         throw exc;
4358     }
4359     this._display.onflush = this._onFlush.bind(this);
4360     this._display.clear();
4361
4362     this._keyboard = new _keyboard2.default(this._canvas);
4363     this._keyboard.onkeyevent = this._handleKeyEvent.bind(this);
4364
4365     this._mouse = new _mouse2.default(this._canvas);
4366     this._mouse.onmousebutton = this._handleMouseButton.bind(this);
4367     this._mouse.onmousemove = this._handleMouseMove.bind(this);
4368
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");
4375         } else {
4376             this._fail("Unexpected server connection while " + this._rfb_connection_state);
4377         }
4378     }.bind(this));
4379     this._sock.on('close', function (e) {
4380         Log.Debug("WebSocket on-close event");
4381         var msg = "";
4382         if (e.code) {
4383             msg = "(code: " + e.code;
4384             if (e.reason) {
4385                 msg += ", reason: " + e.reason;
4386             }
4387             msg += ")";
4388         }
4389         switch (this._rfb_connection_state) {
4390             case 'connecting':
4391                 this._fail("Connection closed " + msg);
4392                 break;
4393             case 'connected':
4394                 // Handle disconnects that were initiated server-side
4395                 this._updateConnectionState('disconnecting');
4396                 this._updateConnectionState('disconnected');
4397                 break;
4398             case 'disconnecting':
4399                 // Normal disconnection path
4400                 this._updateConnectionState('disconnected');
4401                 break;
4402             case 'disconnected':
4403                 this._fail("Unexpected server disconnect " + "when already disconnected " + msg);
4404                 break;
4405             default:
4406                 this._fail("Unexpected server disconnect before connecting " + msg);
4407                 break;
4408         }
4409         this._sock.off('close');
4410     }.bind(this));
4411     this._sock.on('error', function (e) {
4412         Log.Warn("WebSocket on-error event");
4413     });
4414
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'));
4418
4419     Log.Debug("<< RFB.constructor");
4420 };
4421
4422 RFB.prototype = {
4423     // ===== PROPERTIES =====
4424
4425     dragViewport: false,
4426     focusOnClick: true,
4427
4428     _viewOnly: false,
4429     get viewOnly() {
4430         return this._viewOnly;
4431     },
4432     set viewOnly(viewOnly) {
4433         this._viewOnly = viewOnly;
4434
4435         if (this._rfb_connection_state === "connecting" || this._rfb_connection_state === "connected") {
4436             if (viewOnly) {
4437                 this._keyboard.ungrab();
4438                 this._mouse.ungrab();
4439             } else {
4440                 this._keyboard.grab();
4441                 this._mouse.grab();
4442             }
4443         }
4444     },
4445
4446     get capabilities() {
4447         return this._capabilities;
4448     },
4449
4450     get touchButton() {
4451         return this._mouse.touchButton;
4452     },
4453     set touchButton(button) {
4454         this._mouse.touchButton = button;
4455     },
4456
4457     _clipViewport: false,
4458     get clipViewport() {
4459         return this._clipViewport;
4460     },
4461     set clipViewport(viewport) {
4462         this._clipViewport = viewport;
4463         this._updateClip();
4464     },
4465
4466     _scaleViewport: false,
4467     get scaleViewport() {
4468         return this._scaleViewport;
4469     },
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) {
4475             this._updateClip();
4476         }
4477         this._updateScale();
4478         if (!scale && this._clipViewport) {
4479             this._updateClip();
4480         }
4481     },
4482
4483     _resizeSession: false,
4484     get resizeSession() {
4485         return this._resizeSession;
4486     },
4487     set resizeSession(resize) {
4488         this._resizeSession = resize;
4489         if (resize) {
4490             this._requestRemoteResize();
4491         }
4492     },
4493
4494     // ===== PUBLIC METHODS =====
4495
4496     disconnect: function () {
4497         this._updateConnectionState('disconnecting');
4498         this._sock.off('error');
4499         this._sock.off('message');
4500         this._sock.off('open');
4501     },
4502
4503     sendCredentials: function (creds) {
4504         this._rfb_credentials = creds;
4505         setTimeout(this._init_msg.bind(this), 0);
4506     },
4507
4508     sendCtrlAltDel: function () {
4509         if (this._rfb_connection_state !== 'connected' || this._viewOnly) {
4510             return;
4511         }
4512         Log.Info("Sending Ctrl-Alt-Del");
4513
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);
4520     },
4521
4522     machineShutdown: function () {
4523         this._xvpOp(1, 2);
4524     },
4525
4526     machineReboot: function () {
4527         this._xvpOp(1, 3);
4528     },
4529
4530     machineReset: function () {
4531         this._xvpOp(1, 4);
4532     },
4533
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) {
4538             return;
4539         }
4540
4541         if (down === undefined) {
4542             this.sendKey(keysym, code, true);
4543             this.sendKey(keysym, code, false);
4544             return;
4545         }
4546
4547         var scancode = _xtscancodes2.default[code];
4548
4549         if (this._qemuExtKeyEventSupported && scancode) {
4550             // 0 is NoSymbol
4551             keysym = keysym || 0;
4552
4553             Log.Info("Sending key (" + (down ? "down" : "up") + "): keysym " + keysym + ", scancode " + scancode);
4554
4555             RFB.messages.QEMUExtendedKeyEvent(this._sock, keysym, down, scancode);
4556         } else {
4557             if (!keysym) {
4558                 return;
4559             }
4560             Log.Info("Sending keysym (" + (down ? "down" : "up") + "): " + keysym);
4561             RFB.messages.keyEvent(this._sock, keysym, down ? 1 : 0);
4562         }
4563     },
4564
4565     focus: function () {
4566         this._canvas.focus();
4567     },
4568
4569     blur: function () {
4570         this._canvas.blur();
4571     },
4572
4573     clipboardPasteFrom: function (text) {
4574         if (this._rfb_connection_state !== 'connected' || this._viewOnly) {
4575             return;
4576         }
4577         RFB.messages.clientCutText(this._sock, text);
4578     },
4579
4580     // ===== PRIVATE METHODS =====
4581
4582     _connect: function () {
4583         Log.Debug(">> RFB.connect");
4584
4585         Log.Info("connecting to " + this._url);
4586
4587         try {
4588             // WebSocket.onopen transitions to the RFB init states
4589             this._sock.open(this._url, ['binary']);
4590         } catch (e) {
4591             if (e.name === 'SyntaxError') {
4592                 this._fail("Invalid host or port (" + e + ")");
4593             } else {
4594                 this._fail("Error when opening socket (" + e + ")");
4595             }
4596         }
4597
4598         // Make our elements part of the page
4599         this._target.appendChild(this._screen);
4600
4601         // Monitor size changes of the screen
4602         // FIXME: Use ResizeObserver, or hidden overflow
4603         window.addEventListener('resize', this._eventHandlers.windowResize);
4604
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);
4608
4609         Log.Debug("<< RFB.connect");
4610     },
4611
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();
4619         this._sock.close();
4620         this._print_stats();
4621         try {
4622             this._target.removeChild(this._screen);
4623         } catch (e) {
4624             if (e.name === 'NotFoundError') {
4625                 // Some cases where the initial connection fails
4626                 // can disconnect before the _screen is created
4627             } else {
4628                 throw e;
4629             }
4630         }
4631         clearTimeout(this._resizeTimeout);
4632         Log.Debug("<< RFB.disconnect");
4633     },
4634
4635     _print_stats: function () {
4636         var stats = this._encStats;
4637
4638         Log.Info("Encoding stats for this connection:");
4639         Object.keys(stats).forEach(function (key) {
4640             var s = stats[key];
4641             if (s[0] + s[1] > 0) {
4642                 Log.Info("    " + (0, _encodings.encodingName)(key) + ": " + s[0] + " rects");
4643             }
4644         });
4645
4646         Log.Info("Encoding stats since page load:");
4647         Object.keys(stats).forEach(function (key) {
4648             var s = stats[key];
4649             Log.Info("    " + (0, _encodings.encodingName)(key) + ": " + s[1] + " rects");
4650         });
4651     },
4652
4653     _focusCanvas: function (event) {
4654         // Respect earlier handlers' request to not do side-effects
4655         if (event.defaultPrevented) {
4656             return;
4657         }
4658
4659         if (!this.focusOnClick) {
4660             return;
4661         }
4662
4663         this.focus();
4664     },
4665
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 () {
4670             this._updateClip();
4671             this._updateScale();
4672         }.bind(this));
4673
4674         if (this._resizeSession) {
4675             // Request changing the resolution of the remote display to
4676             // the size of the local browser viewport.
4677
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);
4682         }
4683     },
4684
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;
4690
4691         if (this._scaleViewport) {
4692             // Disable viewport clipping if we are scaling
4693             new_clip = false;
4694         }
4695
4696         if (cur_clip !== new_clip) {
4697             this._display.clipViewport = new_clip;
4698         }
4699
4700         if (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();
4706         }
4707     },
4708
4709     _updateScale: function () {
4710         if (!this._scaleViewport) {
4711             this._display.scale = 1.0;
4712         } else {
4713             let size = this._screenSize();
4714             this._display.autoscale(size.w, size.h);
4715         }
4716         this._fixScrollbars();
4717     },
4718
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;
4724
4725         if (!this._resizeSession || this._viewOnly || !this._supportsSetDesktopSize) {
4726             return;
4727         }
4728
4729         let size = this._screenSize();
4730         RFB.messages.setDesktopSize(this._sock, size.w, size.h, this._screen_id, this._screen_flags);
4731
4732         Log.Debug('Requested new desktop size: ' + size.w + 'x' + size.h);
4733     },
4734
4735     // Gets the the size of the available screen
4736     _screenSize: function () {
4737         return { w: this._screen.offsetWidth,
4738             h: this._screen.offsetHeight };
4739     },
4740
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;
4751     },
4752
4753     /*
4754      * Connection states:
4755      *   connecting
4756      *   connected
4757      *   disconnecting
4758      *   disconnected - permanent state
4759      */
4760     _updateConnectionState: function (state) {
4761         var oldstate = this._rfb_connection_state;
4762
4763         if (state === oldstate) {
4764             Log.Debug("Already in state '" + state + "', ignoring");
4765             return;
4766         }
4767
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");
4771             return;
4772         }
4773
4774         // Ensure proper transitions before doing anything
4775         switch (state) {
4776             case 'connected':
4777                 if (oldstate !== 'connecting') {
4778                     Log.Error("Bad transition to connected state, " + "previous connection state: " + oldstate);
4779                     return;
4780                 }
4781                 break;
4782
4783             case 'disconnected':
4784                 if (oldstate !== 'disconnecting') {
4785                     Log.Error("Bad transition to disconnected state, " + "previous connection state: " + oldstate);
4786                     return;
4787                 }
4788                 break;
4789
4790             case 'connecting':
4791                 if (oldstate !== '') {
4792                     Log.Error("Bad transition to connecting state, " + "previous connection state: " + oldstate);
4793                     return;
4794                 }
4795                 break;
4796
4797             case 'disconnecting':
4798                 if (oldstate !== 'connected' && oldstate !== 'connecting') {
4799                     Log.Error("Bad transition to disconnecting state, " + "previous connection state: " + oldstate);
4800                     return;
4801                 }
4802                 break;
4803
4804             default:
4805                 Log.Error("Unknown connection state: " + state);
4806                 return;
4807         }
4808
4809         // State change actions
4810
4811         this._rfb_connection_state = state;
4812
4813         var smsg = "New state '" + state + "', was '" + oldstate + "'.";
4814         Log.Debug(smsg);
4815
4816         if (this._disconnTimer && state !== 'disconnecting') {
4817             Log.Debug("Clearing disconnect timer");
4818             clearTimeout(this._disconnTimer);
4819             this._disconnTimer = null;
4820
4821             // make sure we don't get a double event
4822             this._sock.off('close');
4823         }
4824
4825         switch (state) {
4826             case 'connecting':
4827                 this._connect();
4828                 break;
4829
4830             case 'connected':
4831                 var event = new CustomEvent("connect", { detail: {} });
4832                 this.dispatchEvent(event);
4833                 break;
4834
4835             case 'disconnecting':
4836                 this._disconnect();
4837
4838                 this._disconnTimer = setTimeout(function () {
4839                     Log.Error("Disconnection timed out.");
4840                     this._updateConnectionState('disconnected');
4841                 }.bind(this), DISCONNECT_TIMEOUT * 1000);
4842                 break;
4843
4844             case 'disconnected':
4845                 event = new CustomEvent("disconnect", { detail: { clean: this._rfb_clean_disconnect } });
4846                 this.dispatchEvent(event);
4847                 break;
4848         }
4849     },
4850
4851     /* Print errors and disconnect
4852      *
4853      * The parameter 'details' is used for information that
4854      * should be logged but not sent to the user interface.
4855      */
4856     _fail: function (details) {
4857         switch (this._rfb_connection_state) {
4858             case 'disconnecting':
4859                 Log.Error("Failed when disconnecting: " + details);
4860                 break;
4861             case 'connected':
4862                 Log.Error("Failed while connected: " + details);
4863                 break;
4864             case 'connecting':
4865                 Log.Error("Failed when connecting: " + details);
4866                 break;
4867             default:
4868                 Log.Error("RFB failure: " + details);
4869                 break;
4870         }
4871         this._rfb_clean_disconnect = false; //This is sent to the UI
4872
4873         // Transition to disconnected without waiting for socket to close
4874         this._updateConnectionState('disconnecting');
4875         this._updateConnectionState('disconnected');
4876
4877         return false;
4878     },
4879
4880     _setCapability: function (cap, val) {
4881         this._capabilities[cap] = val;
4882         var event = new CustomEvent("capabilities", { detail: { capabilities: this._capabilities } });
4883         this.dispatchEvent(event);
4884     },
4885
4886     _handle_message: function () {
4887         if (this._sock.rQlen() === 0) {
4888             Log.Warn("handle_message called on an empty receive queue");
4889             return;
4890         }
4891
4892         switch (this._rfb_connection_state) {
4893             case 'disconnected':
4894                 Log.Error("Got data while disconnected");
4895                 break;
4896             case 'connected':
4897                 while (true) {
4898                     if (this._flushing) {
4899                         break;
4900                     }
4901                     if (!this._normal_msg()) {
4902                         break;
4903                     }
4904                     if (this._sock.rQlen() === 0) {
4905                         break;
4906                     }
4907                 }
4908                 break;
4909             default:
4910                 this._init_msg();
4911                 break;
4912         }
4913     },
4914
4915     _handleKeyEvent: function (keysym, code, down) {
4916         this.sendKey(keysym, code, down);
4917     },
4918
4919     _handleMouseButton: function (x, y, down, bmask) {
4920         if (down) {
4921             this._mouse_buttonMask |= bmask;
4922         } else {
4923             this._mouse_buttonMask &= ~bmask;
4924         }
4925
4926         if (this.dragViewport) {
4927             if (down && !this._viewportDragging) {
4928                 this._viewportDragging = true;
4929                 this._viewportDragPos = { 'x': x, 'y': y };
4930                 this._viewportHasMoved = false;
4931
4932                 // Skip sending mouse events
4933                 return;
4934             } else {
4935                 this._viewportDragging = false;
4936
4937                 // If we actually performed a drag then we are done
4938                 // here and should not send any mouse events
4939                 if (this._viewportHasMoved) {
4940                     return;
4941                 }
4942
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);
4947             }
4948         }
4949
4950         if (this._viewOnly) {
4951             return;
4952         } // View only, skip mouse events
4953
4954         if (this._rfb_connection_state !== 'connected') {
4955             return;
4956         }
4957         RFB.messages.pointerEvent(this._sock, this._display.absX(x), this._display.absY(y), this._mouse_buttonMask);
4958     },
4959
4960     _handleMouseMove: function (x, y) {
4961         if (this._viewportDragging) {
4962             var deltaX = this._viewportDragPos.x - x;
4963             var deltaY = this._viewportDragPos.y - y;
4964
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);
4968
4969             if (this._viewportHasMoved || Math.abs(deltaX) > dragThreshold || Math.abs(deltaY) > dragThreshold) {
4970                 this._viewportHasMoved = true;
4971
4972                 this._viewportDragPos = { 'x': x, 'y': y };
4973                 this._display.viewportChangePos(deltaX, deltaY);
4974             }
4975
4976             // Skip sending mouse events
4977             return;
4978         }
4979
4980         if (this._viewOnly) {
4981             return;
4982         } // View only, skip mouse events
4983
4984         if (this._rfb_connection_state !== 'connected') {
4985             return;
4986         }
4987         RFB.messages.pointerEvent(this._sock, this._display.absX(x), this._display.absY(y), this._mouse_buttonMask);
4988     },
4989
4990     // Message Handlers
4991
4992     _negotiate_protocol_version: function () {
4993         if (this._sock.rQlen() < 12) {
4994             return this._fail("Received incomplete protocol version.");
4995         }
4996
4997         var sversion = this._sock.rQshiftStr(12).substr(4, 7);
4998         Log.Info("Server ProtocolVersion: " + sversion);
4999         var is_repeater = 0;
5000         switch (sversion) {
5001             case "000.000":
5002                 // UltraVNC repeater
5003                 is_repeater = 1;
5004                 break;
5005             case "003.003":
5006             case "003.006": // UltraVNC
5007             case "003.889":
5008                 // Apple Remote Desktop
5009                 this._rfb_version = 3.3;
5010                 break;
5011             case "003.007":
5012                 this._rfb_version = 3.7;
5013                 break;
5014             case "003.008":
5015             case "004.000": // Intel AMT KVM
5016             case "004.001": // RealVNC 4.6
5017             case "005.000":
5018                 // RealVNC 5.3
5019                 this._rfb_version = 3.8;
5020                 break;
5021             default:
5022                 return this._fail("Invalid server version " + sversion);
5023         }
5024
5025         if (is_repeater) {
5026             var repeaterID = "ID:" + this._repeaterID;
5027             while (repeaterID.length < 250) {
5028                 repeaterID += "\0";
5029             }
5030             this._sock.send_string(repeaterID);
5031             return true;
5032         }
5033
5034         if (this._rfb_version > this._rfb_max_version) {
5035             this._rfb_version = this._rfb_max_version;
5036         }
5037
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);
5041
5042         this._rfb_init_state = 'Security';
5043     },
5044
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) {
5051                     return true;
5052                 }
5053             }
5054             return false;
5055         }
5056
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)) {
5061                 return false;
5062             }
5063
5064             if (num_types === 0) {
5065                 return this._handle_security_failure("no security types");
5066             }
5067
5068             var types = this._sock.rQshiftBytes(num_types);
5069             Log.Debug("Server security types: " + types);
5070
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
5081             } else {
5082                 return this._fail("Unsupported security types (types: " + types + ")");
5083             }
5084
5085             this._sock.send([this._rfb_auth_scheme]);
5086         } else {
5087             // Server decides
5088             if (this._sock.rQwait("security scheme", 4)) {
5089                 return false;
5090             }
5091             this._rfb_auth_scheme = this._sock.rQshift32();
5092         }
5093
5094         this._rfb_init_state = 'Authentication';
5095         Log.Debug('Authenticating using scheme: ' + this._rfb_auth_scheme);
5096
5097         return this._init_msg(); // jump to authentication
5098     },
5099
5100     /*
5101      * Get the security failure reason if sent from the server and
5102      * send the 'securityfailure' event.
5103      *
5104      * - The optional parameter context can be used to add some extra
5105      *   context to the log output.
5106      *
5107      * - The optional parameter security_result_status can be used to
5108      *   add a custom status code to the event.
5109      */
5110     _handle_security_failure: function (context, security_result_status) {
5111
5112         if (typeof context === 'undefined') {
5113             context = "";
5114         } else {
5115             context = " on " + context;
5116         }
5117
5118         if (typeof security_result_status === 'undefined') {
5119             security_result_status = 1; // fail
5120         }
5121
5122         if (this._sock.rQwait("reason length", 4)) {
5123             return false;
5124         }
5125         let strlen = this._sock.rQshift32();
5126         let reason = "";
5127
5128         if (strlen > 0) {
5129             if (this._sock.rQwait("reason", strlen, 8)) {
5130                 return false;
5131             }
5132             reason = this._sock.rQshiftStr(strlen);
5133         }
5134
5135         if (reason !== "") {
5136
5137             let event = new CustomEvent("securityfailure", { detail: { status: security_result_status, reason: reason } });
5138             this.dispatchEvent(event);
5139
5140             return this._fail("Security negotiation failed" + context + " (reason: " + reason + ")");
5141         } else {
5142
5143             let event = new CustomEvent("securityfailure", { detail: { status: security_result_status } });
5144             this.dispatchEvent(event);
5145
5146             return this._fail("Security negotiation failed" + context);
5147         }
5148     },
5149
5150     // authentication
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);
5155             return false;
5156         }
5157
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();
5162     },
5163
5164     _negotiate_std_vnc_auth: function () {
5165         if (this._sock.rQwait("auth challenge", 16)) {
5166             return false;
5167         }
5168
5169         if (!this._rfb_credentials.password) {
5170             var event = new CustomEvent("credentialsrequired", { detail: { types: ["password"] } });
5171             this.dispatchEvent(event);
5172             return false;
5173         }
5174
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";
5180         return true;
5181     },
5182
5183     _negotiate_tight_tunnels: function (numTunnels) {
5184         var clientSupportedTunnelTypes = {
5185             0: { vendor: 'TGHT', signature: 'NOTUNNEL' }
5186         };
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 };
5194         }
5195
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");
5200             }
5201             this._sock.send([0, 0, 0, 0]); // use NOTUNNEL
5202             return false; // wait until we receive the sub auth count to continue
5203         } else {
5204             return this._fail("Server wanted tunnels, but doesn't support " + "the notunnel type");
5205         }
5206     },
5207
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)) {
5212                 return false;
5213             }
5214             var numTunnels = this._sock.rQshift32();
5215             if (numTunnels > 0 && this._sock.rQwait("tunnel capabilities", 16 * numTunnels, 4)) {
5216                 return false;
5217             }
5218
5219             this._rfb_tightvnc = true;
5220
5221             if (numTunnels > 0) {
5222                 this._negotiate_tight_tunnels(numTunnels);
5223                 return false; // wait until we receive the sub auth to continue
5224             }
5225         }
5226
5227         // second pass, do the sub-auth negotiation
5228         if (this._sock.rQwait("sub auth count", 4)) {
5229             return false;
5230         }
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';
5235             return true;
5236         }
5237
5238         if (this._sock.rQwait("sub auth capabilities", 16 * subAuthCount, 4)) {
5239             return false;
5240         }
5241
5242         var clientSupportedTypes = {
5243             'STDVNOAUTH__': 1,
5244             'STDVVNCAUTH_': 2
5245         };
5246
5247         var serverSupportedTypes = [];
5248
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);
5253         }
5254
5255         for (var authType in clientSupportedTypes) {
5256             if (serverSupportedTypes.indexOf(authType) != -1) {
5257                 this._sock.send([0, 0, 0, clientSupportedTypes[authType]]);
5258
5259                 switch (authType) {
5260                     case 'STDVNOAUTH__':
5261                         // no auth
5262                         this._rfb_init_state = 'SecurityResult';
5263                         return true;
5264                     case 'STDVVNCAUTH_':
5265                         // VNC auth
5266                         this._rfb_auth_scheme = 2;
5267                         return this._init_msg();
5268                     default:
5269                         return this._fail("Unsupported tiny auth scheme " + "(scheme: " + authType + ")");
5270                 }
5271             }
5272         }
5273
5274         return this._fail("No supported sub-auth types!");
5275     },
5276
5277     _negotiate_authentication: function () {
5278         switch (this._rfb_auth_scheme) {
5279             case 0:
5280                 // connection failed
5281                 return this._handle_security_failure("authentication scheme");
5282
5283             case 1:
5284                 // no auth
5285                 if (this._rfb_version >= 3.8) {
5286                     this._rfb_init_state = 'SecurityResult';
5287                     return true;
5288                 }
5289                 this._rfb_init_state = 'ClientInitialisation';
5290                 return this._init_msg();
5291
5292             case 22:
5293                 // XVP auth
5294                 return this._negotiate_xvp_auth();
5295
5296             case 2:
5297                 // VNC authentication
5298                 return this._negotiate_std_vnc_auth();
5299
5300             case 16:
5301                 // TightVNC Security Type
5302                 return this._negotiate_tight_auth();
5303
5304             default:
5305                 return this._fail("Unsupported auth scheme (scheme: " + this._rfb_auth_scheme + ")");
5306         }
5307     },
5308
5309     _handle_security_result: function () {
5310         if (this._sock.rQwait('VNC auth response ', 4)) {
5311             return false;
5312         }
5313
5314         let status = this._sock.rQshift32();
5315
5316         if (status === 0) {
5317             // OK
5318             this._rfb_init_state = 'ClientInitialisation';
5319             Log.Debug('Authentication OK');
5320             return this._init_msg();
5321         } else {
5322             if (this._rfb_version >= 3.8) {
5323                 return this._handle_security_failure("security result", status);
5324             } else {
5325                 let event = new CustomEvent("securityfailure", { detail: { status: status } });
5326                 this.dispatchEvent(event);
5327
5328                 return this._fail("Security handshake failed");
5329             }
5330         }
5331     },
5332
5333     _negotiate_server_init: function () {
5334         if (this._sock.rQwait("server initialization", 24)) {
5335             return false;
5336         }
5337
5338         /* Screen size */
5339         var width = this._sock.rQshift16();
5340         var height = this._sock.rQshift16();
5341
5342         /* PIXEL_FORMAT */
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();
5347
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
5355
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
5358
5359         /* Connection name/title */
5360         var name_length = this._sock.rQshift32();
5361         if (this._sock.rQwait('server init name', name_length, 24)) {
5362             return false;
5363         }
5364         this._fb_name = (0, _strings.decodeUTF8)(this._sock.rQshiftStr(name_length));
5365
5366         if (this._rfb_tightvnc) {
5367             if (this._sock.rQwait('TightVNC extended server init header', 8, 24 + name_length)) {
5368                 return false;
5369             }
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
5375
5376             var totalMessagesLength = (numServerMessages + numClientMessages + numEncodings) * 16;
5377             if (this._sock.rQwait('TightVNC extended server init header', totalMessagesLength, 32 + name_length)) {
5378                 return false;
5379             }
5380
5381             // we don't actually do anything with the capability information that TIGHT sends,
5382             // so we just skip the all of this.
5383
5384             // TIGHT server message capabilities
5385             this._sock.rQskipBytes(16 * numServerMessages);
5386
5387             // TIGHT client message capabilities
5388             this._sock.rQskipBytes(16 * numClientMessages);
5389
5390             // TIGHT encoding capabilities
5391             this._sock.rQskipBytes(16 * numEncodings);
5392         }
5393
5394         // NB(directxman12): these are down here so that we don't run them multiple times
5395         //                   if we backtrack
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);
5397
5398         if (big_endian !== 0) {
5399             Log.Warn("Server native endian is not little endian");
5400         }
5401
5402         if (red_shift !== 16) {
5403             Log.Warn("Server native red-shift is not 16");
5404         }
5405
5406         if (blue_shift !== 0) {
5407             Log.Warn("Server native blue-shift is not 0");
5408         }
5409
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);
5413
5414         this._resize(width, height);
5415
5416         if (!this._viewOnly) {
5417             this._keyboard.grab();
5418         }
5419         if (!this._viewOnly) {
5420             this._mouse.grab();
5421         }
5422
5423         this._fb_depth = 24;
5424
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.");
5427             this._fb_depth = 8;
5428         }
5429
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);
5433
5434         this._timing.fbu_rt_start = new Date().getTime();
5435         this._timing.pixels = 0;
5436
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();
5440
5441         this._updateConnectionState('connected');
5442         return true;
5443     },
5444
5445     _sendEncodings: function () {
5446         var encs = [];
5447
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);
5455         }
5456         encs.push(_encodings.encodings.encodingRaw);
5457
5458         // Psuedo-encoding settings
5459         encs.push(_encodings.encodings.pseudoEncodingTightPNG);
5460         encs.push(_encodings.encodings.pseudoEncodingQualityLevel0 + 6);
5461         encs.push(_encodings.encodings.pseudoEncodingCompressLevel0 + 2);
5462
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);
5470
5471         if ((0, _browser.supportsCursorURIs)() && !_browser.isTouchDevice && this._fb_depth == 24) {
5472             encs.push(_encodings.encodings.pseudoEncodingCursor);
5473         }
5474
5475         RFB.messages.clientEncodings(this._sock, encs);
5476     },
5477
5478     /* RFB protocol initialization states:
5479      *   ProtocolVersion
5480      *   Security
5481      *   Authentication
5482      *   SecurityResult
5483      *   ClientInitialization - not triggered by server message
5484      *   ServerInitialization
5485      */
5486     _init_msg: function () {
5487         switch (this._rfb_init_state) {
5488             case 'ProtocolVersion':
5489                 return this._negotiate_protocol_version();
5490
5491             case 'Security':
5492                 return this._negotiate_security();
5493
5494             case 'Authentication':
5495                 return this._negotiate_authentication();
5496
5497             case 'SecurityResult':
5498                 return this._handle_security_result();
5499
5500             case 'ClientInitialisation':
5501                 this._sock.send([this._shared ? 1 : 0]); // ClientInitialisation
5502                 this._rfb_init_state = 'ServerInitialisation';
5503                 return true;
5504
5505             case 'ServerInitialisation':
5506                 return this._negotiate_server_init();
5507
5508             default:
5509                 return this._fail("Unknown init state (state: " + this._rfb_init_state + ")");
5510         }
5511     },
5512
5513     _handle_set_colour_map_msg: function () {
5514         Log.Debug("SetColorMapEntries");
5515
5516         return this._fail("Unexpected SetColorMapEntries message");
5517     },
5518
5519     _handle_server_cut_text: function () {
5520         Log.Debug("ServerCutText");
5521
5522         if (this._sock.rQwait("ServerCutText header", 7, 1)) {
5523             return false;
5524         }
5525         this._sock.rQskipBytes(3); // Padding
5526         var length = this._sock.rQshift32();
5527         if (this._sock.rQwait("ServerCutText", length, 8)) {
5528             return false;
5529         }
5530
5531         var text = this._sock.rQshiftStr(length);
5532
5533         if (this._viewOnly) {
5534             return true;
5535         }
5536
5537         var event = new CustomEvent("clipboard", { detail: { text: text } });
5538         this.dispatchEvent(event);
5539
5540         return true;
5541     },
5542
5543     _handle_server_fence_msg: function () {
5544         if (this._sock.rQwait("ServerFence header", 8, 1)) {
5545             return false;
5546         }
5547         this._sock.rQskipBytes(3); // Padding
5548         var flags = this._sock.rQshift32();
5549         var length = this._sock.rQshift8();
5550
5551         if (this._sock.rQwait("ServerFence payload", length, 9)) {
5552             return false;
5553         }
5554
5555         if (length > 64) {
5556             Log.Warn("Bad payload length (" + length + ") in fence response");
5557             length = 64;
5558         }
5559
5560         var payload = this._sock.rQshiftStr(length);
5561
5562         this._supportsFence = true;
5563
5564         /*
5565          * Fence flags
5566          *
5567          *  (1<<0)  - BlockBefore
5568          *  (1<<1)  - BlockAfter
5569          *  (1<<2)  - SyncNext
5570          *  (1<<31) - Request
5571          */
5572
5573         if (!(flags & 1 << 31)) {
5574             return this._fail("Unexpected fence response");
5575         }
5576
5577         // Filter out unsupported flags
5578         // FIXME: support syncNext
5579         flags &= 1 << 0 | 1 << 1;
5580
5581         // BlockBefore and BlockAfter are automatically handled by
5582         // the fact that we process each incoming message
5583         // synchronuosly.
5584         RFB.messages.clientFence(this._sock, flags, payload);
5585
5586         return true;
5587     },
5588
5589     _handle_xvp_msg: function () {
5590         if (this._sock.rQwait("XVP version and message", 3, 1)) {
5591             return false;
5592         }
5593         this._sock.rQskip8(); // Padding
5594         var xvp_ver = this._sock.rQshift8();
5595         var xvp_msg = this._sock.rQshift8();
5596
5597         switch (xvp_msg) {
5598             case 0:
5599                 // XVP_FAIL
5600                 Log.Error("XVP Operation Failed");
5601                 break;
5602             case 1:
5603                 // XVP_INIT
5604                 this._rfb_xvp_ver = xvp_ver;
5605                 Log.Info("XVP extensions enabled (version " + this._rfb_xvp_ver + ")");
5606                 this._setCapability("power", true);
5607                 break;
5608             default:
5609                 this._fail("Illegal server XVP message (msg: " + xvp_msg + ")");
5610                 break;
5611         }
5612
5613         return true;
5614     },
5615
5616     _normal_msg: function () {
5617         var msg_type;
5618
5619         if (this._FBU.rects > 0) {
5620             msg_type = 0;
5621         } else {
5622             msg_type = this._sock.rQshift8();
5623         }
5624
5625         switch (msg_type) {
5626             case 0:
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);
5631                 }
5632                 return ret;
5633
5634             case 1:
5635                 // SetColorMapEntries
5636                 return this._handle_set_colour_map_msg();
5637
5638             case 2:
5639                 // Bell
5640                 Log.Debug("Bell");
5641                 var event = new CustomEvent("bell", { detail: {} });
5642                 this.dispatchEvent(event);
5643                 return true;
5644
5645             case 3:
5646                 // ServerCutText
5647                 return this._handle_server_cut_text();
5648
5649             case 150:
5650                 // EndOfContinuousUpdates
5651                 var first = !this._supportsContinuousUpdates;
5652                 this._supportsContinuousUpdates = true;
5653                 this._enabledContinuousUpdates = false;
5654                 if (first) {
5655                     this._enabledContinuousUpdates = true;
5656                     this._updateContinuousUpdates();
5657                     Log.Info("Enabling continuous updates.");
5658                 } else {
5659                     // FIXME: We need to send a framebufferupdaterequest here
5660                     // if we add support for turning off continuous updates
5661                 }
5662                 return true;
5663
5664             case 248:
5665                 // ServerFence
5666                 return this._handle_server_fence_msg();
5667
5668             case 250:
5669                 // XVP
5670                 return this._handle_xvp_msg();
5671
5672             default:
5673                 this._fail("Unexpected server message (type " + msg_type + ")");
5674                 Log.Debug("sock.rQslice(0, 30): " + this._sock.rQslice(0, 30));
5675                 return true;
5676         }
5677     },
5678
5679     _onFlush: function () {
5680         this._flushing = false;
5681         // Resume processing
5682         if (this._sock.rQlen() > 0) {
5683             this._handle_message();
5684         }
5685     },
5686
5687     _framebufferUpdate: function () {
5688         var ret = true;
5689         var now;
5690
5691         if (this._FBU.rects === 0) {
5692             if (this._sock.rQwait("FBU header", 3, 1)) {
5693                 return false;
5694             }
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));
5702             }
5703
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();
5709                 return false;
5710             }
5711         }
5712
5713         while (this._FBU.rects > 0) {
5714             if (this._rfb_connection_state !== 'connected') {
5715                 return false;
5716             }
5717
5718             if (this._sock.rQwait("FBU", this._FBU.bytes)) {
5719                 return false;
5720             }
5721             if (this._FBU.bytes === 0) {
5722                 if (this._sock.rQwait("rect header", 12)) {
5723                     return false;
5724                 }
5725                 /* New FramebufferUpdate */
5726
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);
5733
5734                 if (!this._encHandlers[this._FBU.encoding]) {
5735                     this._fail("Unsupported encoding (encoding: " + this._FBU.encoding + ")");
5736                     return false;
5737                 }
5738             }
5739
5740             this._timing.last_fbu = new Date().getTime();
5741
5742             ret = this._encHandlers[this._FBU.encoding]();
5743
5744             now = new Date().getTime();
5745             this._timing.cur_fbu += now - this._timing.last_fbu;
5746
5747             if (ret) {
5748                 if (!(this._FBU.encoding in this._encStats)) {
5749                     this._encStats[this._FBU.encoding] = [0, 0];
5750                 }
5751                 this._encStats[this._FBU.encoding][0]++;
5752                 this._encStats[this._FBU.encoding][1]++;
5753                 this._timing.pixels += this._FBU.width * this._FBU.height;
5754             }
5755
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);
5761                 }
5762
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;
5769                 }
5770             }
5771
5772             if (!ret) {
5773                 return ret;
5774             } // need more data
5775         }
5776
5777         this._display.flip();
5778
5779         return true; // We finished this FBU
5780     },
5781
5782     _updateContinuousUpdates: function () {
5783         if (!this._enabledContinuousUpdates) {
5784             return;
5785         }
5786
5787         RFB.messages.enableContinuousUpdates(this._sock, true, 0, 0, this._fb_width, this._fb_height);
5788     },
5789
5790     _resize: function (width, height) {
5791         this._fb_width = width;
5792         this._fb_height = height;
5793
5794         this._destBuff = new Uint8Array(this._fb_width * this._fb_height * 4);
5795
5796         this._display.resize(this._fb_width, this._fb_height);
5797
5798         // Adjust the visible viewport based on the new dimensions
5799         this._updateClip();
5800         this._updateScale();
5801
5802         this._timing.fbu_rt_start = new Date().getTime();
5803         this._updateContinuousUpdates();
5804     },
5805
5806     _xvpOp: function (ver, op) {
5807         if (this._rfb_xvp_ver < ver) {
5808             return;
5809         }
5810         Log.Info("Sending XVP operation " + op + " (version " + ver + ")");
5811         RFB.messages.xvpOp(this._sock, ver, op);
5812     }
5813 };
5814
5815 Object.assign(RFB.prototype, _eventtarget2.default);
5816
5817 // Class Methods
5818 RFB.messages = {
5819     keyEvent: function (sock, keysym, down) {
5820         var buff = sock._sQ;
5821         var offset = sock._sQlen;
5822
5823         buff[offset] = 4; // msg-type
5824         buff[offset + 1] = down;
5825
5826         buff[offset + 2] = 0;
5827         buff[offset + 3] = 0;
5828
5829         buff[offset + 4] = keysym >> 24;
5830         buff[offset + 5] = keysym >> 16;
5831         buff[offset + 6] = keysym >> 8;
5832         buff[offset + 7] = keysym;
5833
5834         sock._sQlen += 8;
5835         sock.flush();
5836     },
5837
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;
5844                 return lowerByte;
5845             }
5846             return xt_scancode;
5847         }
5848
5849         var buff = sock._sQ;
5850         var offset = sock._sQlen;
5851
5852         buff[offset] = 255; // msg-type
5853         buff[offset + 1] = 0; // sub msg-type
5854
5855         buff[offset + 2] = down >> 8;
5856         buff[offset + 3] = down;
5857
5858         buff[offset + 4] = keysym >> 24;
5859         buff[offset + 5] = keysym >> 16;
5860         buff[offset + 6] = keysym >> 8;
5861         buff[offset + 7] = keysym;
5862
5863         var RFBkeycode = getRFBkeycode(keycode);
5864
5865         buff[offset + 8] = RFBkeycode >> 24;
5866         buff[offset + 9] = RFBkeycode >> 16;
5867         buff[offset + 10] = RFBkeycode >> 8;
5868         buff[offset + 11] = RFBkeycode;
5869
5870         sock._sQlen += 12;
5871         sock.flush();
5872     },
5873
5874     pointerEvent: function (sock, x, y, mask) {
5875         var buff = sock._sQ;
5876         var offset = sock._sQlen;
5877
5878         buff[offset] = 5; // msg-type
5879
5880         buff[offset + 1] = mask;
5881
5882         buff[offset + 2] = x >> 8;
5883         buff[offset + 3] = x;
5884
5885         buff[offset + 4] = y >> 8;
5886         buff[offset + 5] = y;
5887
5888         sock._sQlen += 6;
5889         sock.flush();
5890     },
5891
5892     // TODO(directxman12): make this unicode compatible?
5893     clientCutText: function (sock, text) {
5894         var buff = sock._sQ;
5895         var offset = sock._sQlen;
5896
5897         buff[offset] = 6; // msg-type
5898
5899         buff[offset + 1] = 0; // padding
5900         buff[offset + 2] = 0; // padding
5901         buff[offset + 3] = 0; // padding
5902
5903         var n = text.length;
5904
5905         buff[offset + 4] = n >> 24;
5906         buff[offset + 5] = n >> 16;
5907         buff[offset + 6] = n >> 8;
5908         buff[offset + 7] = n;
5909
5910         for (var i = 0; i < n; i++) {
5911             buff[offset + 8 + i] = text.charCodeAt(i);
5912         }
5913
5914         sock._sQlen += 8 + n;
5915         sock.flush();
5916     },
5917
5918     setDesktopSize: function (sock, width, height, id, flags) {
5919         var buff = sock._sQ;
5920         var offset = sock._sQlen;
5921
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;
5928
5929         buff[offset + 6] = 1; // number-of-screens
5930         buff[offset + 7] = 0; // padding
5931
5932         // screen array
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;
5949
5950         sock._sQlen += 24;
5951         sock.flush();
5952     },
5953
5954     clientFence: function (sock, flags, payload) {
5955         var buff = sock._sQ;
5956         var offset = sock._sQlen;
5957
5958         buff[offset] = 248; // msg-type
5959
5960         buff[offset + 1] = 0; // padding
5961         buff[offset + 2] = 0; // padding
5962         buff[offset + 3] = 0; // padding
5963
5964         buff[offset + 4] = flags >> 24; // flags
5965         buff[offset + 5] = flags >> 16;
5966         buff[offset + 6] = flags >> 8;
5967         buff[offset + 7] = flags;
5968
5969         var n = payload.length;
5970
5971         buff[offset + 8] = n; // length
5972
5973         for (var i = 0; i < n; i++) {
5974             buff[offset + 9 + i] = payload.charCodeAt(i);
5975         }
5976
5977         sock._sQlen += 9 + n;
5978         sock.flush();
5979     },
5980
5981     enableContinuousUpdates: function (sock, enable, x, y, width, height) {
5982         var buff = sock._sQ;
5983         var offset = sock._sQlen;
5984
5985         buff[offset] = 150; // msg-type
5986         buff[offset + 1] = enable; // enable-flag
5987
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;
5996
5997         sock._sQlen += 10;
5998         sock.flush();
5999     },
6000
6001     pixelFormat: function (sock, depth, true_color) {
6002         var buff = sock._sQ;
6003         var offset = sock._sQlen;
6004
6005         var bpp, bits;
6006
6007         if (depth > 16) {
6008             bpp = 32;
6009         } else if (depth > 8) {
6010             bpp = 16;
6011         } else {
6012             bpp = 8;
6013         }
6014
6015         bits = Math.floor(depth / 3);
6016
6017         buff[offset] = 0; // msg-type
6018
6019         buff[offset + 1] = 0; // padding
6020         buff[offset + 2] = 0; // padding
6021         buff[offset + 3] = 0; // padding
6022
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
6027
6028         buff[offset + 8] = 0; // red-max
6029         buff[offset + 9] = (1 << bits) - 1; // red-max
6030
6031         buff[offset + 10] = 0; // green-max
6032         buff[offset + 11] = (1 << bits) - 1; // green-max
6033
6034         buff[offset + 12] = 0; // blue-max
6035         buff[offset + 13] = (1 << bits) - 1; // blue-max
6036
6037         buff[offset + 14] = bits * 2; // red-shift
6038         buff[offset + 15] = bits * 1; // green-shift
6039         buff[offset + 16] = bits * 0; // blue-shift
6040
6041         buff[offset + 17] = 0; // padding
6042         buff[offset + 18] = 0; // padding
6043         buff[offset + 19] = 0; // padding
6044
6045         sock._sQlen += 20;
6046         sock.flush();
6047     },
6048
6049     clientEncodings: function (sock, encodings) {
6050         var buff = sock._sQ;
6051         var offset = sock._sQlen;
6052
6053         buff[offset] = 2; // msg-type
6054         buff[offset + 1] = 0; // padding
6055
6056         buff[offset + 2] = encodings.length >> 8;
6057         buff[offset + 3] = encodings.length;
6058
6059         var i,
6060             j = offset + 4;
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;
6066             buff[j + 3] = enc;
6067
6068             j += 4;
6069         }
6070
6071         sock._sQlen += j - offset;
6072         sock.flush();
6073     },
6074
6075     fbUpdateRequest: function (sock, incremental, x, y, w, h) {
6076         var buff = sock._sQ;
6077         var offset = sock._sQlen;
6078
6079         if (typeof x === "undefined") {
6080             x = 0;
6081         }
6082         if (typeof y === "undefined") {
6083             y = 0;
6084         }
6085
6086         buff[offset] = 3; // msg-type
6087         buff[offset + 1] = incremental ? 1 : 0;
6088
6089         buff[offset + 2] = x >> 8 & 0xFF;
6090         buff[offset + 3] = x & 0xFF;
6091
6092         buff[offset + 4] = y >> 8 & 0xFF;
6093         buff[offset + 5] = y & 0xFF;
6094
6095         buff[offset + 6] = w >> 8 & 0xFF;
6096         buff[offset + 7] = w & 0xFF;
6097
6098         buff[offset + 8] = h >> 8 & 0xFF;
6099         buff[offset + 9] = h & 0xFF;
6100
6101         sock._sQlen += 10;
6102         sock.flush();
6103     },
6104
6105     xvpOp: function (sock, ver, op) {
6106         var buff = sock._sQ;
6107         var offset = sock._sQlen;
6108
6109         buff[offset] = 250; // msg-type
6110         buff[offset + 1] = 0; // padding
6111
6112         buff[offset + 2] = ver;
6113         buff[offset + 3] = op;
6114
6115         sock._sQlen += 4;
6116         sock.flush();
6117     }
6118 };
6119
6120 RFB.genDES = function (password, challenge) {
6121     var passwd = [];
6122     for (var i = 0; i < password.length; i++) {
6123         passwd.push(password.charCodeAt(i));
6124     }
6125     return new _des2.default(passwd).encrypt(challenge);
6126 };
6127
6128 RFB.encodingHandlers = {
6129     RAW: function () {
6130         if (this._FBU.lines === 0) {
6131             this._FBU.lines = this._FBU.height;
6132         }
6133
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)) {
6137             return false;
6138         }
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);
6146             var i;
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;
6152             }
6153             data = newdata;
6154             index = 0;
6155         }
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;
6159
6160         if (this._FBU.lines > 0) {
6161             this._FBU.bytes = this._FBU.width * pixelSize; // At least another line
6162         } else {
6163             this._FBU.rects--;
6164             this._FBU.bytes = 0;
6165         }
6166
6167         return true;
6168     },
6169
6170     COPYRECT: function () {
6171         this._FBU.bytes = 4;
6172         if (this._sock.rQwait("COPYRECT", 4)) {
6173             return false;
6174         }
6175         this._display.copyImage(this._sock.rQshift16(), this._sock.rQshift16(), this._FBU.x, this._FBU.y, this._FBU.width, this._FBU.height);
6176
6177         this._FBU.rects--;
6178         this._FBU.bytes = 0;
6179         return true;
6180     },
6181
6182     RRE: function () {
6183         var color;
6184         if (this._FBU.subrects === 0) {
6185             this._FBU.bytes = 4 + 4;
6186             if (this._sock.rQwait("RRE", 4 + 4)) {
6187                 return false;
6188             }
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);
6192         }
6193
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--;
6202         }
6203
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;
6207         } else {
6208             this._FBU.rects--;
6209             this._FBU.bytes = 0;
6210         }
6211
6212         return true;
6213     },
6214
6215     HEXTILE: function () {
6216         var rQ = this._sock.get_rQ();
6217         var rQi = this._sock.get_rQi();
6218
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;
6224         }
6225
6226         while (this._FBU.tiles > 0) {
6227             this._FBU.bytes = 1;
6228             if (this._sock.rQwait("HEXTILE subencoding", this._FBU.bytes)) {
6229                 return false;
6230             }
6231             var subencoding = rQ[rQi]; // Peek
6232             if (subencoding > 30) {
6233                 // Raw
6234                 this._fail("Illegal hextile subencoding (subencoding: " + subencoding + ")");
6235                 return false;
6236             }
6237
6238             var subrects = 0;
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);
6246
6247             // Figure out how much we are expecting
6248             if (subencoding & 0x01) {
6249                 // Raw
6250                 this._FBU.bytes += w * h * 4;
6251             } else {
6252                 if (subencoding & 0x02) {
6253                     // Background
6254                     this._FBU.bytes += 4;
6255                 }
6256                 if (subencoding & 0x04) {
6257                     // Foreground
6258                     this._FBU.bytes += 4;
6259                 }
6260                 if (subencoding & 0x08) {
6261                     // AnySubrects
6262                     this._FBU.bytes++; // Since we aren't shifting it off
6263                     if (this._sock.rQwait("hextile subrects header", this._FBU.bytes)) {
6264                         return false;
6265                     }
6266                     subrects = rQ[rQi + this._FBU.bytes - 1]; // Peek
6267                     if (subencoding & 0x10) {
6268                         // SubrectsColoured
6269                         this._FBU.bytes += subrects * (4 + 2);
6270                     } else {
6271                         this._FBU.bytes += subrects * 2;
6272                     }
6273                 }
6274             }
6275
6276             if (this._sock.rQwait("hextile", this._FBU.bytes)) {
6277                 return false;
6278             }
6279
6280             // We know the encoding and have a whole tile
6281             this._FBU.subencoding = rQ[rQi];
6282             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");
6287                 } else {
6288                     this._display.fillRect(x, y, w, h, this._FBU.background);
6289                 }
6290             } else if (this._FBU.subencoding & 0x01) {
6291                 // Raw
6292                 this._display.blitImage(x, y, w, h, rQ, rQi);
6293                 rQi += this._FBU.bytes - 1;
6294             } else {
6295                 if (this._FBU.subencoding & 0x02) {
6296                     // Background
6297                     this._FBU.background = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]];
6298                     rQi += 4;
6299                 }
6300                 if (this._FBU.subencoding & 0x04) {
6301                     // Foreground
6302                     this._FBU.foreground = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]];
6303                     rQi += 4;
6304                 }
6305
6306                 this._display.startTile(x, y, w, h, this._FBU.background);
6307                 if (this._FBU.subencoding & 0x08) {
6308                     // AnySubrects
6309                     subrects = rQ[rQi];
6310                     rQi++;
6311
6312                     for (var s = 0; s < subrects; s++) {
6313                         var color;
6314                         if (this._FBU.subencoding & 0x10) {
6315                             // SubrectsColoured
6316                             color = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]];
6317                             rQi += 4;
6318                         } else {
6319                             color = this._FBU.foreground;
6320                         }
6321                         var xy = rQ[rQi];
6322                         rQi++;
6323                         var sx = xy >> 4;
6324                         var sy = xy & 0x0f;
6325
6326                         var wh = rQ[rQi];
6327                         rQi++;
6328                         var sw = (wh >> 4) + 1;
6329                         var sh = (wh & 0x0f) + 1;
6330
6331                         this._display.subTile(sx, sy, sw, sh, color);
6332                     }
6333                 }
6334                 this._display.finishTile();
6335             }
6336             this._sock.set_rQi(rQi);
6337             this._FBU.lastsubencoding = this._FBU.subencoding;
6338             this._FBU.bytes = 0;
6339             this._FBU.tiles--;
6340         }
6341
6342         if (this._FBU.tiles === 0) {
6343             this._FBU.rects--;
6344         }
6345
6346         return true;
6347     },
6348
6349     TIGHT: function () {
6350         this._FBU.bytes = 1; // compression-control byte
6351         if (this._sock.rQwait("TIGHT compression-control", this._FBU.bytes)) {
6352             return false;
6353         }
6354
6355         var checksum = function (data) {
6356             var sum = 0;
6357             for (var i = 0; i < data.length; i++) {
6358                 sum += data[i];
6359                 if (sum > 65536) sum -= 65536;
6360             }
6361             return sum;
6362         };
6363
6364         var resetStreams = 0;
6365         var streamId = -1;
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);
6371                 }
6372             }
6373
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");
6378             }*/
6379
6380             //return uncompressed.data;
6381             return uncompressed;
6382         }.bind(this);
6383
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);
6390
6391             /*for (var y = 0; y < height; y++) {
6392                 var b, x, dp, sp;
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];
6405                     }
6406                 }
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];
6415                 }
6416             }*/
6417
6418             for (var y = 0; y < height; y++) {
6419                 var b, x, dp, sp;
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];
6427                         dest[dp + 3] = 255;
6428                     }
6429                 }
6430
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];
6437                     dest[dp + 3] = 255;
6438                 }
6439             }
6440
6441             return dest;
6442         }.bind(this);
6443
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];
6453                 dest[i + 3] = 255;
6454             }
6455
6456             return dest;
6457         }.bind(this);
6458
6459         var rQi = this._sock.get_rQi();
6460         var rQ = this._sock.rQwhole();
6461         var cmode, data;
6462         var cl_header, cl_data;
6463
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)) {
6469                 return false;
6470             }
6471
6472             var bpp = numColors <= 2 ? 1 : 8;
6473             var rowSize = Math.floor((this._FBU.width * bpp + 7) / 8);
6474             var raw = false;
6475             if (rowSize * this._FBU.height < 12) {
6476                 raw = true;
6477                 cl_header = 0;
6478                 cl_data = rowSize * this._FBU.height;
6479                 //clength = [0, rowSize * this._FBU.height];
6480             } else {
6481                 // begin inline getTightCLength (returning two-item arrays is bad for performance with GC)
6482                 var cl_offset = rQi + 3 + paletteSize;
6483                 cl_header = 1;
6484                 cl_data = 0;
6485                 cl_data += rQ[cl_offset] & 0x7f;
6486                 if (rQ[cl_offset] & 0x80) {
6487                     cl_header++;
6488                     cl_data += (rQ[cl_offset + 1] & 0x7f) << 7;
6489                     if (rQ[cl_offset + 1] & 0x80) {
6490                         cl_header++;
6491                         cl_data += rQ[cl_offset + 2] << 14;
6492                     }
6493                 }
6494                 // end inline getTightCLength
6495             }
6496
6497             this._FBU.bytes += cl_header + cl_data;
6498             if (this._sock.rQwait("TIGHT " + cmode, this._FBU.bytes)) {
6499                 return false;
6500             }
6501
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);
6507
6508             if (raw) {
6509                 data = this._sock.rQshiftBytes(cl_data);
6510             } else {
6511                 data = decompress(this._sock.rQshiftBytes(cl_data), rowSize * this._FBU.height);
6512             }
6513
6514             // Convert indexed (palette based) image data to RGB
6515             var rgbx;
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);
6519             } else {
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);
6522             }
6523
6524             return true;
6525         }.bind(this);
6526
6527         var handleCopy = function () {
6528             var raw = false;
6529             var uncompressedSize = this._FBU.width * this._FBU.height * 3;
6530             if (uncompressedSize < 12) {
6531                 raw = true;
6532                 cl_header = 0;
6533                 cl_data = uncompressedSize;
6534             } else {
6535                 // begin inline getTightCLength (returning two-item arrays is for peformance with GC)
6536                 var cl_offset = rQi + 1;
6537                 cl_header = 1;
6538                 cl_data = 0;
6539                 cl_data += rQ[cl_offset] & 0x7f;
6540                 if (rQ[cl_offset] & 0x80) {
6541                     cl_header++;
6542                     cl_data += (rQ[cl_offset + 1] & 0x7f) << 7;
6543                     if (rQ[cl_offset + 1] & 0x80) {
6544                         cl_header++;
6545                         cl_data += rQ[cl_offset + 2] << 14;
6546                     }
6547                 }
6548                 // end inline getTightCLength
6549             }
6550             this._FBU.bytes = 1 + cl_header + cl_data;
6551             if (this._sock.rQwait("TIGHT " + cmode, this._FBU.bytes)) {
6552                 return false;
6553             }
6554
6555             // Shift ctl, clength off
6556             this._sock.rQshiftBytes(1 + cl_header);
6557
6558             if (raw) {
6559                 data = this._sock.rQshiftBytes(cl_data);
6560             } else {
6561                 data = decompress(this._sock.rQshiftBytes(cl_data), uncompressedSize);
6562             }
6563
6564             this._display.blitRgbImage(this._FBU.x, this._FBU.y, this._FBU.width, this._FBU.height, data, 0, false);
6565
6566             return true;
6567         }.bind(this);
6568
6569         var ctl = this._sock.rQpeek8();
6570
6571         // Keep tight reset bits
6572         resetStreams = ctl & 0xF;
6573
6574         // Figure out filter
6575         ctl = ctl >> 4;
6576         streamId = ctl & 0x3;
6577
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 + ")");
6579
6580         switch (cmode) {
6581             // fill use depth because TPIXELs drop the padding byte
6582             case "fill":
6583                 // TPIXEL
6584                 this._FBU.bytes += 3;
6585                 break;
6586             case "jpeg":
6587                 // max clength
6588                 this._FBU.bytes += 3;
6589                 break;
6590             case "png":
6591                 // max clength
6592                 this._FBU.bytes += 3;
6593                 break;
6594             case "filter":
6595                 // filter id + num colors if palette
6596                 this._FBU.bytes += 2;
6597                 break;
6598             case "copy":
6599                 break;
6600         }
6601
6602         if (this._sock.rQwait("TIGHT " + cmode, this._FBU.bytes)) {
6603             return false;
6604         }
6605
6606         // Determine FBU.bytes
6607         switch (cmode) {
6608             case "fill":
6609                 // skip ctl byte
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);
6612                 break;
6613             case "png":
6614             case "jpeg":
6615                 // begin inline getTightCLength (returning two-item arrays is for peformance with GC)
6616                 var cl_offset = rQi + 1;
6617                 cl_header = 1;
6618                 cl_data = 0;
6619                 cl_data += rQ[cl_offset] & 0x7f;
6620                 if (rQ[cl_offset] & 0x80) {
6621                     cl_header++;
6622                     cl_data += (rQ[cl_offset + 1] & 0x7f) << 7;
6623                     if (rQ[cl_offset + 1] & 0x80) {
6624                         cl_header++;
6625                         cl_data += rQ[cl_offset + 2] << 14;
6626                     }
6627                 }
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)) {
6631                     return false;
6632                 }
6633
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);
6638                 break;
6639             case "filter":
6640                 var filterId = rQ[rQi + 1];
6641                 if (filterId === 1) {
6642                     if (!handlePalette()) {
6643                         return false;
6644                     }
6645                 } else {
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 + ")");
6649                 }
6650                 break;
6651             case "copy":
6652                 if (!handleCopy()) {
6653                     return false;
6654                 }
6655                 break;
6656         }
6657
6658         this._FBU.bytes = 0;
6659         this._FBU.rects--;
6660
6661         return true;
6662     },
6663
6664     last_rect: function () {
6665         this._FBU.rects = 0;
6666         return true;
6667     },
6668
6669     ExtendedDesktopSize: function () {
6670         this._FBU.bytes = 1;
6671         if (this._sock.rQwait("ExtendedDesktopSize", this._FBU.bytes)) {
6672             return false;
6673         }
6674
6675         var firstUpdate = !this._supportsSetDesktopSize;
6676         this._supportsSetDesktopSize = true;
6677
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.
6682         if (firstUpdate) {
6683             this._requestRemoteResize();
6684         }
6685
6686         var number_of_screens = this._sock.rQpeek8();
6687
6688         this._FBU.bytes = 4 + number_of_screens * 16;
6689         if (this._sock.rQwait("ExtendedDesktopSize", this._FBU.bytes)) {
6690             return false;
6691         }
6692
6693         this._sock.rQskipBytes(1); // number-of-screens
6694         this._sock.rQskipBytes(3); // padding
6695
6696         for (var i = 0; i < number_of_screens; i += 1) {
6697             // Save the id and flags of the first screen
6698             if (i === 0) {
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
6705             } else {
6706                 this._sock.rQskipBytes(16);
6707             }
6708         }
6709
6710         /*
6711          * The x-position indicates the reason for the change:
6712          *
6713          *  0 - server resized on its own
6714          *  1 - this client requested the resize
6715          *  2 - another client requested the resize
6716          */
6717
6718         // We need to handle errors when we requested the resize.
6719         if (this._FBU.x === 1 && this._FBU.y !== 0) {
6720             var msg = "";
6721             // The y-position indicates the status code from the server
6722             switch (this._FBU.y) {
6723                 case 1:
6724                     msg = "Resize is administratively prohibited";
6725                     break;
6726                 case 2:
6727                     msg = "Out of resources";
6728                     break;
6729                 case 3:
6730                     msg = "Invalid screen layout";
6731                     break;
6732                 default:
6733                     msg = "Unknown reason";
6734                     break;
6735             }
6736             Log.Warn("Server did not accept the resize request: " + msg);
6737         } else {
6738             this._resize(this._FBU.width, this._FBU.height);
6739         }
6740
6741         this._FBU.bytes = 0;
6742         this._FBU.rects -= 1;
6743         return true;
6744     },
6745
6746     DesktopSize: function () {
6747         this._resize(this._FBU.width, this._FBU.height);
6748         this._FBU.bytes = 0;
6749         this._FBU.rects -= 1;
6750         return true;
6751     },
6752
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;
6759
6760         var pixelslength = w * h * 4;
6761         var masklength = Math.floor((w + 7) / 8) * h;
6762
6763         this._FBU.bytes = pixelslength + masklength;
6764         if (this._sock.rQwait("cursor encoding", this._FBU.bytes)) {
6765             return false;
6766         }
6767
6768         this._display.changeCursor(this._sock.rQshiftBytes(pixelslength), this._sock.rQshiftBytes(masklength), x, y, w, h);
6769
6770         this._FBU.bytes = 0;
6771         this._FBU.rects--;
6772
6773         Log.Debug("<< set_cursor");
6774         return true;
6775     },
6776
6777     QEMUExtendedKeyEvent: function () {
6778         this._FBU.rects--;
6779
6780         // Old Safari doesn't support creating keyboard events
6781         try {
6782             var keyboardEvent = document.createEvent("keyboardEvent");
6783             if (keyboardEvent.code !== undefined) {
6784                 this._qemuExtKeyEventSupported = true;
6785             }
6786         } catch (err) {}
6787     }
6788 };
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){
6790 'use strict';
6791
6792 Object.defineProperty(exports, "__esModule", {
6793     value: true
6794 });
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;
6802
6803 var _logging = require('./logging.js');
6804
6805 var Log = _interopRequireWildcard(_logging);
6806
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; } }
6808
6809 // Touch detection
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)
6818                                                                  *
6819                                                                  * See README.md for usage and integration instructions.
6820                                                                  */
6821
6822 window.addEventListener('touchstart', function onFirstTouch() {
6823     exports.isTouchDevice = isTouchDevice = true;
6824     window.removeEventListener('touchstart', onFirstTouch, false);
6825 }, false);
6826
6827 var _cursor_uris_supported = null;
6828
6829 function supportsCursorURIs() {
6830     if (_cursor_uris_supported === null) {
6831         try {
6832             var target = document.createElement('canvas');
6833             target.style.cursor = 'url("data:image/x-icon;base64,AAACAAEACAgAAAIAAgA4AQAAFgAAACgAAAAIAAAAEAAAAAEAIAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAAAAAAAAAAAAAAAAAAAAA==") 2 2, default';
6834
6835             if (target.style.cursor) {
6836                 Log.Info("Data URI scheme cursor supported");
6837                 _cursor_uris_supported = true;
6838             } else {
6839                 Log.Warn("Data URI scheme cursor not supported");
6840                 _cursor_uris_supported = false;
6841             }
6842         } catch (exc) {
6843             Log.Error("Data URI scheme cursor test exception: " + exc);
6844             _cursor_uris_supported = false;
6845         }
6846     }
6847
6848     return _cursor_uris_supported;
6849 };
6850
6851 function isMac() {
6852     return navigator && !!/mac/i.exec(navigator.platform);
6853 }
6854
6855 function isIE() {
6856     return navigator && !!/trident/i.exec(navigator.userAgent);
6857 }
6858
6859 function isEdge() {
6860     return navigator && !!/edge/i.exec(navigator.userAgent);
6861 }
6862
6863 function isWindows() {
6864     return navigator && !!/win/i.exec(navigator.platform);
6865 }
6866
6867 function isIOS() {
6868     return navigator && (!!/ipad/i.exec(navigator.platform) || !!/iphone/i.exec(navigator.platform) || !!/ipod/i.exec(navigator.platform));
6869 }
6870 },{"./logging.js":19}],17:[function(require,module,exports){
6871 "use strict";
6872
6873 Object.defineProperty(exports, "__esModule", {
6874     value: true
6875 });
6876 exports.getPointerEvent = getPointerEvent;
6877 exports.stopEvent = stopEvent;
6878 exports.setCapture = setCapture;
6879 exports.releaseCapture = releaseCapture;
6880 /*
6881  * noVNC: HTML5 VNC client
6882  * Copyright (C) 2012 Joel Martin
6883  * Licensed under MPL 2.0 (see LICENSE.txt)
6884  *
6885  * See README.md for usage and integration instructions.
6886  */
6887
6888 /*
6889  * Cross-browser event and position routines
6890  */
6891
6892 function getPointerEvent(e) {
6893     return e.changedTouches ? e.changedTouches[0] : e.touches ? e.touches[0] : e;
6894 };
6895
6896 function stopEvent(e) {
6897     e.stopPropagation();
6898     e.preventDefault();
6899 };
6900
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;
6907
6908     // Clone the event as we cannot dispatch an already dispatched event
6909     var newEv = new e.constructor(e.type, e);
6910
6911     _captureRecursion = true;
6912     _captureElem.dispatchEvent(newEv);
6913     _captureRecursion = false;
6914
6915     // Avoid double events
6916     e.stopPropagation();
6917
6918     // Respect the wishes of the redirected event handlers
6919     if (newEv.defaultPrevented) {
6920         e.preventDefault();
6921     }
6922
6923     // Implicitly release the capture on button release
6924     if (e.type === "mouseup") {
6925         releaseCapture();
6926     }
6927 };
6928
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;
6933 };
6934 var _captureObserver = new MutationObserver(_captureElemChanged);
6935
6936 var _captureIndex = 0;
6937
6938 function setCapture(elem) {
6939     if (elem.setCapture) {
6940
6941         elem.setCapture();
6942
6943         // IE releases capture on 'click' events which might not trigger
6944         elem.addEventListener('mouseup', releaseCapture);
6945     } else {
6946         // Release any existing capture in case this method is
6947         // called multiple times without coordination
6948         releaseCapture();
6949
6950         var captureElem = document.getElementById("noVNC_mouse_capture_elem");
6951
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);
6963
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);
6967
6968             captureElem.addEventListener('mousemove', _captureProxy);
6969             captureElem.addEventListener('mouseup', _captureProxy);
6970         }
6971
6972         _captureElem = elem;
6973         _captureIndex++;
6974
6975         // Track cursor and get initial cursor
6976         _captureObserver.observe(elem, { attributes: true });
6977         _captureElemChanged();
6978
6979         captureElem.style.display = "";
6980
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);
6985     }
6986 };
6987
6988 function releaseCapture() {
6989     if (document.releaseCapture) {
6990
6991         document.releaseCapture();
6992     } else {
6993         if (!_captureElem) {
6994             return;
6995         }
6996
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;
7004             }
7005         }, 0, _captureIndex);
7006
7007         _captureObserver.disconnect();
7008
7009         var captureElem = document.getElementById("noVNC_mouse_capture_elem");
7010         captureElem.style.display = "none";
7011
7012         window.removeEventListener('mousemove', _captureProxy);
7013         window.removeEventListener('mouseup', _captureProxy);
7014     }
7015 };
7016 },{}],18:[function(require,module,exports){
7017 "use strict";
7018
7019 Object.defineProperty(exports, "__esModule", {
7020    value: true
7021 });
7022 /*
7023  * noVNC: HTML5 VNC client
7024  * Copyright 2017 Pierre Ossman for Cendio AB
7025  * Licensed under MPL 2.0 (see LICENSE.txt)
7026  *
7027  * See README.md for usage and integration instructions.
7028  */
7029
7030 var EventTargetMixin = {
7031    _listeners: null,
7032
7033    addEventListener: function (type, callback) {
7034       if (!this._listeners) {
7035          this._listeners = new Map();
7036       }
7037       if (!this._listeners.has(type)) {
7038          this._listeners.set(type, new Set());
7039       }
7040       this._listeners.get(type).add(callback);
7041    },
7042
7043    removeEventListener: function (type, callback) {
7044       if (!this._listeners || !this._listeners.has(type)) {
7045          return;
7046       }
7047       this._listeners.get(type).delete(callback);
7048    },
7049
7050    dispatchEvent: function (event) {
7051       if (!this._listeners || !this._listeners.has(event.type)) {
7052          return true;
7053       }
7054       this._listeners.get(event.type).forEach(function (callback) {
7055          callback.call(this, event);
7056       }, this);
7057       return !event.defaultPrevented;
7058    }
7059 };
7060
7061 exports.default = EventTargetMixin;
7062 },{}],19:[function(require,module,exports){
7063 'use strict';
7064
7065 Object.defineProperty(exports, "__esModule", {
7066     value: true
7067 });
7068 exports.init_logging = init_logging;
7069 exports.get_logging = get_logging;
7070 /*
7071  * noVNC: HTML5 VNC client
7072  * Copyright (C) 2012 Joel Martin
7073  * Licensed under MPL 2.0 (see LICENSE.txt)
7074  *
7075  * See README.md for usage and integration instructions.
7076  */
7077
7078 /*
7079  * Logging/debug routines
7080  */
7081
7082 var _log_level = 'warn';
7083
7084 var Debug = function (msg) {};
7085 var Info = function (msg) {};
7086 var Warn = function (msg) {};
7087 var Error = function (msg) {};
7088
7089 function init_logging(level) {
7090     if (typeof level === 'undefined') {
7091         level = _log_level;
7092     } else {
7093         _log_level = level;
7094     }
7095
7096     exports.Debug = Debug = exports.Info = Info = exports.Warn = Warn = exports.Error = Error = function (msg) {};
7097     if (typeof window.console !== "undefined") {
7098         switch (level) {
7099             case 'debug':
7100                 exports.Debug = Debug = console.debug.bind(window.console);
7101             case 'info':
7102                 exports.Info = Info = console.info.bind(window.console);
7103             case 'warn':
7104                 exports.Warn = Warn = console.warn.bind(window.console);
7105             case 'error':
7106                 exports.Error = Error = console.error.bind(window.console);
7107             case 'none':
7108                 break;
7109             default:
7110                 throw new Error("invalid logging type '" + level + "'");
7111         }
7112     }
7113 };
7114 function get_logging() {
7115     return _log_level;
7116 };
7117 exports.Debug = Debug;
7118 exports.Info = Info;
7119 exports.Warn = Warn;
7120 exports.Error = Error;
7121
7122 // Initialize logging level
7123
7124 init_logging();
7125 },{}],20:[function(require,module,exports){
7126 'use strict';
7127
7128 /*
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)
7132  */
7133
7134 /* Polyfills to provide new APIs in old browsers */
7135
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
7142             'use strict';
7143
7144             if (target == null) {
7145                 // TypeError if undefined or null
7146                 throw new TypeError('Cannot convert undefined or null to object');
7147             }
7148
7149             var to = Object(target);
7150
7151             for (var index = 1; index < arguments.length; index++) {
7152                 var nextSource = arguments[index];
7153
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];
7160                         }
7161                     }
7162                 }
7163             }
7164             return to;
7165         },
7166         writable: true,
7167         configurable: true
7168     });
7169 }
7170
7171 /* CustomEvent constructor (taken from MDN) */
7172 (function () {
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);
7177         return evt;
7178     }
7179
7180     CustomEvent.prototype = window.Event.prototype;
7181
7182     if (typeof window.CustomEvent !== "function") {
7183         window.CustomEvent = CustomEvent;
7184     }
7185 })();
7186 },{}],21:[function(require,module,exports){
7187 "use strict";
7188
7189 Object.defineProperty(exports, "__esModule", {
7190   value: true
7191 });
7192 exports.decodeUTF8 = decodeUTF8;
7193 /*
7194  * noVNC: HTML5 VNC client
7195  * Copyright (C) 2012 Joel Martin
7196  * Licensed under MPL 2.0 (see LICENSE.txt)
7197  *
7198  * See README.md for usage and integration instructions.
7199  */
7200
7201 /*
7202  * Decode from UTF-8
7203  */
7204 function decodeUTF8(utf8string) {
7205   "use strict";
7206
7207   return decodeURIComponent(escape(utf8string));
7208 };
7209 },{}],22:[function(require,module,exports){
7210 "use strict";
7211
7212 Object.defineProperty(exports, "__esModule", {
7213   value: true
7214 });
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) {
7221     return buf;
7222   }
7223   if (buf.subarray) {
7224     return buf.subarray(0, size);
7225   }
7226   buf.length = size;
7227   return buf;
7228 };
7229
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);
7233     return;
7234   }
7235   // Fallback to ordinary array
7236   for (var i = 0; i < len; i++) {
7237     dest[dest_offs + i] = src[src_offs + i];
7238   }
7239 }
7240
7241 // Join array of chunks to single array.
7242 function flattenChunks(chunks) {
7243   var i, l, len, pos, chunk, result;
7244
7245   // calculate data length
7246   len = 0;
7247   for (i = 0, l = chunks.length; i < l; i++) {
7248     len += chunks[i].length;
7249   }
7250
7251   // join chunks
7252   result = new Uint8Array(len);
7253   pos = 0;
7254   for (i = 0, l = chunks.length; i < l; i++) {
7255     chunk = chunks[i];
7256     result.set(chunk, pos);
7257     pos += chunk.length;
7258   }
7259
7260   return result;
7261 }
7262
7263 var Buf8 = exports.Buf8 = Uint8Array;
7264 var Buf16 = exports.Buf16 = Uint16Array;
7265 var Buf32 = exports.Buf32 = Int32Array;
7266 },{}],23:[function(require,module,exports){
7267 "use strict";
7268
7269 Object.defineProperty(exports, "__esModule", {
7270   value: true
7271 });
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.
7276
7277 function adler32(adler, buf, len, pos) {
7278   var s1 = adler & 0xffff | 0,
7279       s2 = adler >>> 16 & 0xffff | 0,
7280       n = 0;
7281
7282   while (len !== 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;
7287     len -= n;
7288
7289     do {
7290       s1 = s1 + buf[pos++] | 0;
7291       s2 = s2 + s1 | 0;
7292     } while (--n);
7293
7294     s1 %= 65521;
7295     s2 %= 65521;
7296   }
7297
7298   return s1 | s2 << 16 | 0;
7299 }
7300 },{}],24:[function(require,module,exports){
7301 "use strict";
7302
7303 Object.defineProperty(exports, "__esModule", {
7304   value: true
7305 });
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.
7310
7311
7312 // Use ordinary array, since untyped makes no boost here
7313 function makeTable() {
7314   var c,
7315       table = [];
7316
7317   for (var n = 0; n < 256; n++) {
7318     c = n;
7319     for (var k = 0; k < 8; k++) {
7320       c = c & 1 ? 0xEDB88320 ^ c >>> 1 : c >>> 1;
7321     }
7322     table[n] = c;
7323   }
7324
7325   return table;
7326 }
7327
7328 // Create table on load. Just 255 signed longs. Not a problem.
7329 var crcTable = makeTable();
7330
7331 function crc32(crc, buf, len, pos) {
7332   var t = crcTable,
7333       end = pos + len;
7334
7335   crc ^= -1;
7336
7337   for (var i = pos; i < end; i++) {
7338     crc = crc >>> 8 ^ t[(crc ^ buf[i]) & 0xFF];
7339   }
7340
7341   return crc ^ -1; // >>> 0;
7342 }
7343 },{}],25:[function(require,module,exports){
7344 'use strict';
7345
7346 Object.defineProperty(exports, "__esModule", {
7347   value: true
7348 });
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 */
7353
7354 /*
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.
7361
7362    Entry assumptions:
7363
7364         state.mode === LEN
7365         strm.avail_in >= 6
7366         strm.avail_out >= 258
7367         start >= strm.avail_out
7368         state.bits < 8
7369
7370    On return, state.mode is one of:
7371
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
7375
7376    Notes:
7377
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.
7383
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
7387       output space.
7388  */
7389 function inflate_fast(strm, start) {
7390   var state;
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 */
7398   //#endif
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 */
7416   var from_source;
7417
7418   var input, output; // JS specific, because we have no pointers
7419
7420   /* copy state to local variables */
7421   state = strm.state;
7422   //here = state.here;
7423   _in = strm.next_in;
7424   input = strm.input;
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
7431   dmax = state.dmax;
7432   //#endif
7433   wsize = state.wsize;
7434   whave = state.whave;
7435   wnext = state.wnext;
7436   s_window = state.window;
7437   hold = state.hold;
7438   bits = state.bits;
7439   lcode = state.lencode;
7440   dcode = state.distcode;
7441   lmask = (1 << state.lenbits) - 1;
7442   dmask = (1 << state.distbits) - 1;
7443
7444   /* decode literals and length/distances until end-of-block or not enough
7445      input data or output space */
7446
7447   top: do {
7448     if (bits < 15) {
7449       hold += input[_in++] << bits;
7450       bits += 8;
7451       hold += input[_in++] << bits;
7452       bits += 8;
7453     }
7454
7455     here = lcode[hold & lmask];
7456
7457     dolen: for (;;) {
7458       // Goto emulation
7459       op = here >>> 24 /*here.bits*/;
7460       hold >>>= op;
7461       bits -= op;
7462       op = here >>> 16 & 0xff /*here.op*/;
7463       if (op === 0) {
7464         /* literal */
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) {
7470         /* length base */
7471         len = here & 0xffff /*here.val*/;
7472         op &= 15; /* number of extra bits */
7473         if (op) {
7474           if (bits < op) {
7475             hold += input[_in++] << bits;
7476             bits += 8;
7477           }
7478           len += hold & (1 << op) - 1;
7479           hold >>>= op;
7480           bits -= op;
7481         }
7482         //Tracevv((stderr, "inflate:         length %u\n", len));
7483         if (bits < 15) {
7484           hold += input[_in++] << bits;
7485           bits += 8;
7486           hold += input[_in++] << bits;
7487           bits += 8;
7488         }
7489         here = dcode[hold & dmask];
7490
7491         dodist: for (;;) {
7492           // goto emulation
7493           op = here >>> 24 /*here.bits*/;
7494           hold >>>= op;
7495           bits -= op;
7496           op = here >>> 16 & 0xff /*here.op*/;
7497
7498           if (op & 16) {
7499             /* distance base */
7500             dist = here & 0xffff /*here.val*/;
7501             op &= 15; /* number of extra bits */
7502             if (bits < op) {
7503               hold += input[_in++] << bits;
7504               bits += 8;
7505               if (bits < op) {
7506                 hold += input[_in++] << bits;
7507                 bits += 8;
7508               }
7509             }
7510             dist += hold & (1 << op) - 1;
7511             //#ifdef INFLATE_STRICT
7512             if (dist > dmax) {
7513               strm.msg = 'invalid distance too far back';
7514               state.mode = BAD;
7515               break top;
7516             }
7517             //#endif
7518             hold >>>= op;
7519             bits -= op;
7520             //Tracevv((stderr, "inflate:         distance %u\n", dist));
7521             op = _out - beg; /* max distance in output */
7522             if (dist > op) {
7523               /* see if copy from window */
7524               op = dist - op; /* distance back in window */
7525               if (op > whave) {
7526                 if (state.sane) {
7527                   strm.msg = 'invalid distance too far back';
7528                   state.mode = BAD;
7529                   break top;
7530                 }
7531
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) {
7536                 //                  do {
7537                 //                    output[_out++] = 0;
7538                 //                  } while (--len);
7539                 //                  continue top;
7540                 //                }
7541                 //                len -= op - whave;
7542                 //                do {
7543                 //                  output[_out++] = 0;
7544                 //                } while (--op > whave);
7545                 //                if (op === 0) {
7546                 //                  from = _out - dist;
7547                 //                  do {
7548                 //                    output[_out++] = output[from++];
7549                 //                  } while (--len);
7550                 //                  continue top;
7551                 //                }
7552                 //#endif
7553               }
7554               from = 0; // window index
7555               from_source = s_window;
7556               if (wnext === 0) {
7557                 /* very common case */
7558                 from += wsize - op;
7559                 if (op < len) {
7560                   /* some from window */
7561                   len -= op;
7562                   do {
7563                     output[_out++] = s_window[from++];
7564                   } while (--op);
7565                   from = _out - dist; /* rest from output */
7566                   from_source = output;
7567                 }
7568               } else if (wnext < op) {
7569                 /* wrap around window */
7570                 from += wsize + wnext - op;
7571                 op -= wnext;
7572                 if (op < len) {
7573                   /* some from end of window */
7574                   len -= op;
7575                   do {
7576                     output[_out++] = s_window[from++];
7577                   } while (--op);
7578                   from = 0;
7579                   if (wnext < len) {
7580                     /* some from start of window */
7581                     op = wnext;
7582                     len -= op;
7583                     do {
7584                       output[_out++] = s_window[from++];
7585                     } while (--op);
7586                     from = _out - dist; /* rest from output */
7587                     from_source = output;
7588                   }
7589                 }
7590               } else {
7591                 /* contiguous in window */
7592                 from += wnext - op;
7593                 if (op < len) {
7594                   /* some from window */
7595                   len -= op;
7596                   do {
7597                     output[_out++] = s_window[from++];
7598                   } while (--op);
7599                   from = _out - dist; /* rest from output */
7600                   from_source = output;
7601                 }
7602               }
7603               while (len > 2) {
7604                 output[_out++] = from_source[from++];
7605                 output[_out++] = from_source[from++];
7606                 output[_out++] = from_source[from++];
7607                 len -= 3;
7608               }
7609               if (len) {
7610                 output[_out++] = from_source[from++];
7611                 if (len > 1) {
7612                   output[_out++] = from_source[from++];
7613                 }
7614               }
7615             } else {
7616               from = _out - dist; /* copy direct from output */
7617               do {
7618                 /* minimum length is three */
7619                 output[_out++] = output[from++];
7620                 output[_out++] = output[from++];
7621                 output[_out++] = output[from++];
7622                 len -= 3;
7623               } while (len > 2);
7624               if (len) {
7625                 output[_out++] = output[from++];
7626                 if (len > 1) {
7627                   output[_out++] = output[from++];
7628                 }
7629               }
7630             }
7631           } else if ((op & 64) === 0) {
7632             /* 2nd level distance code */
7633             here = dcode[(here & 0xffff) + ( /*here.val*/hold & (1 << op) - 1)];
7634             continue dodist;
7635           } else {
7636             strm.msg = 'invalid distance code';
7637             state.mode = BAD;
7638             break top;
7639           }
7640
7641           break; // need to emulate goto via "continue"
7642         }
7643       } else if ((op & 64) === 0) {
7644         /* 2nd level length code */
7645         here = lcode[(here & 0xffff) + ( /*here.val*/hold & (1 << op) - 1)];
7646         continue dolen;
7647       } else if (op & 32) {
7648         /* end-of-block */
7649         //Tracevv((stderr, "inflate:         end of block\n"));
7650         state.mode = TYPE;
7651         break top;
7652       } else {
7653         strm.msg = 'invalid literal/length code';
7654         state.mode = BAD;
7655         break top;
7656       }
7657
7658       break; // need to emulate goto via "continue"
7659     }
7660   } while (_in < last && _out < end);
7661
7662   /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
7663   len = bits >> 3;
7664   _in -= len;
7665   bits -= len << 3;
7666   hold &= (1 << bits) - 1;
7667
7668   /* update state and return */
7669   strm.next_in = _in;
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);
7673   state.hold = hold;
7674   state.bits = bits;
7675   return;
7676 };
7677 },{}],26:[function(require,module,exports){
7678 "use strict";
7679
7680 Object.defineProperty(exports, "__esModule", {
7681   value: true
7682 });
7683 exports.inflateInfo = exports.inflateSetDictionary = exports.inflateGetHeader = exports.inflateEnd = exports.inflate = exports.inflateInit2 = exports.inflateInit = exports.inflateResetKeep = exports.inflateReset2 = exports.inflateReset = undefined;
7684
7685 var _common = require("../utils/common.js");
7686
7687 var utils = _interopRequireWildcard(_common);
7688
7689 var _adler = require("./adler32.js");
7690
7691 var _adler2 = _interopRequireDefault(_adler);
7692
7693 var _crc = require("./crc32.js");
7694
7695 var _crc2 = _interopRequireDefault(_crc);
7696
7697 var _inffast = require("./inffast.js");
7698
7699 var _inffast2 = _interopRequireDefault(_inffast);
7700
7701 var _inftrees = require("./inftrees.js");
7702
7703 var _inftrees2 = _interopRequireDefault(_inftrees);
7704
7705 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
7706
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; } }
7708
7709 var CODES = 0;
7710 var LENS = 1;
7711 var DISTS = 2;
7712
7713 /* Public constants ==========================================================*/
7714 /* ===========================================================================*/
7715
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;
7721 var Z_FINISH = 4;
7722 var Z_BLOCK = 5;
7723 var Z_TREES = 6;
7724
7725 /* Return codes for the compression/decompression functions. Negative values
7726  * are errors, positive values are used for special but normal events.
7727  */
7728 var Z_OK = 0;
7729 var Z_STREAM_END = 1;
7730 var Z_NEED_DICT = 2;
7731 //var Z_ERRNO         = -1;
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;
7737
7738 /* The deflate compression method */
7739 var Z_DEFLATED = 8;
7740
7741 /* STATES ====================================================================*/
7742 /* ===========================================================================*/
7743
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() */
7776
7777 /* ===========================================================================*/
7778
7779 var ENOUGH_LENS = 852;
7780 var ENOUGH_DISTS = 592;
7781 //var ENOUGH =  (ENOUGH_LENS+ENOUGH_DISTS);
7782
7783 var MAX_WBITS = 15;
7784 /* 32K LZ77 window */
7785 var DEF_WBITS = MAX_WBITS;
7786
7787 function zswap32(q) {
7788   return (q >>> 24 & 0xff) + (q >>> 8 & 0xff00) + ((q & 0xff00) << 8) + ((q & 0xff) << 24);
7789 }
7790
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 */
7800   // TODO: may be {}
7801   this.head = null; /* where to save gzip header information */
7802
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 */
7809
7810   /* bit accumulator */
7811   this.hold = 0; /* input bit accumulator */
7812   this.bits = 0; /* number of bits in "in" */
7813
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 */
7817
7818   /* for table and code decoding */
7819   this.extra = 0; /* extra bits needed */
7820
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 */
7826
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[] */
7833
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 */
7836
7837   /*
7838    because we don't have pointers in js, we use lencode and distcode directly
7839    as buffers so we don't need codes
7840   */
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 */
7847 }
7848
7849 function inflateResetKeep(strm) {
7850   var state;
7851
7852   if (!strm || !strm.state) {
7853     return Z_STREAM_ERROR;
7854   }
7855   state = strm.state;
7856   strm.total_in = strm.total_out = state.total = 0;
7857   strm.msg = ''; /*Z_NULL*/
7858   if (state.wrap) {
7859     /* to support ill-conceived Java test suite */
7860     strm.adler = state.wrap & 1;
7861   }
7862   state.mode = HEAD;
7863   state.last = 0;
7864   state.havedict = 0;
7865   state.dmax = 32768;
7866   state.head = null /*Z_NULL*/;
7867   state.hold = 0;
7868   state.bits = 0;
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);
7872
7873   state.sane = 1;
7874   state.back = -1;
7875   //Tracev((stderr, "inflate: reset\n"));
7876   return Z_OK;
7877 }
7878
7879 function inflateReset(strm) {
7880   var state;
7881
7882   if (!strm || !strm.state) {
7883     return Z_STREAM_ERROR;
7884   }
7885   state = strm.state;
7886   state.wsize = 0;
7887   state.whave = 0;
7888   state.wnext = 0;
7889   return inflateResetKeep(strm);
7890 }
7891
7892 function inflateReset2(strm, windowBits) {
7893   var wrap;
7894   var state;
7895
7896   /* get the state */
7897   if (!strm || !strm.state) {
7898     return Z_STREAM_ERROR;
7899   }
7900   state = strm.state;
7901
7902   /* extract wrap request from windowBits parameter */
7903   if (windowBits < 0) {
7904     wrap = 0;
7905     windowBits = -windowBits;
7906   } else {
7907     wrap = (windowBits >> 4) + 1;
7908     if (windowBits < 48) {
7909       windowBits &= 15;
7910     }
7911   }
7912
7913   /* set number of window bits, free window if different */
7914   if (windowBits && (windowBits < 8 || windowBits > 15)) {
7915     return Z_STREAM_ERROR;
7916   }
7917   if (state.window !== null && state.wbits !== windowBits) {
7918     state.window = null;
7919   }
7920
7921   /* update state and reset the rest of it */
7922   state.wrap = wrap;
7923   state.wbits = windowBits;
7924   return inflateReset(strm);
7925 }
7926
7927 function inflateInit2(strm, windowBits) {
7928   var ret;
7929   var state;
7930
7931   if (!strm) {
7932     return Z_STREAM_ERROR;
7933   }
7934   //strm.msg = Z_NULL;                 /* in case we return an error */
7935
7936   state = new InflateState();
7937
7938   //if (state === Z_NULL) return Z_MEM_ERROR;
7939   //Tracev((stderr, "inflate: allocated\n"));
7940   strm.state = state;
7941   state.window = null /*Z_NULL*/;
7942   ret = inflateReset2(strm, windowBits);
7943   if (ret !== Z_OK) {
7944     strm.state = null /*Z_NULL*/;
7945   }
7946   return ret;
7947 }
7948
7949 function inflateInit(strm) {
7950   return inflateInit2(strm, DEF_WBITS);
7951 }
7952
7953 /*
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.
7962  */
7963 var virgin = true;
7964
7965 var lenfix, distfix; // We have no pointers in JS, so keep tables separate
7966
7967 function fixedtables(state) {
7968   /* build fixed huffman tables if first call (may not be thread safe) */
7969   if (virgin) {
7970     var sym;
7971
7972     lenfix = new utils.Buf32(512);
7973     distfix = new utils.Buf32(32);
7974
7975     /* literal/length table */
7976     sym = 0;
7977     while (sym < 144) {
7978       state.lens[sym++] = 8;
7979     }
7980     while (sym < 256) {
7981       state.lens[sym++] = 9;
7982     }
7983     while (sym < 280) {
7984       state.lens[sym++] = 7;
7985     }
7986     while (sym < 288) {
7987       state.lens[sym++] = 8;
7988     }
7989
7990     (0, _inftrees2.default)(LENS, state.lens, 0, 288, lenfix, 0, state.work, { bits: 9 });
7991
7992     /* distance table */
7993     sym = 0;
7994     while (sym < 32) {
7995       state.lens[sym++] = 5;
7996     }
7997
7998     (0, _inftrees2.default)(DISTS, state.lens, 0, 32, distfix, 0, state.work, { bits: 5 });
7999
8000     /* do this just once */
8001     virgin = false;
8002   }
8003
8004   state.lencode = lenfix;
8005   state.lenbits = 9;
8006   state.distcode = distfix;
8007   state.distbits = 5;
8008 }
8009
8010 /*
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
8016  is loaded.
8017
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.
8023  */
8024 function updatewindow(strm, src, end, copy) {
8025   var dist;
8026   var state = strm.state;
8027
8028   /* if it hasn't been done already, allocate space for the window */
8029   if (state.window === null) {
8030     state.wsize = 1 << state.wbits;
8031     state.wnext = 0;
8032     state.whave = 0;
8033
8034     state.window = new utils.Buf8(state.wsize);
8035   }
8036
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);
8040     state.wnext = 0;
8041     state.whave = state.wsize;
8042   } else {
8043     dist = state.wsize - state.wnext;
8044     if (dist > copy) {
8045       dist = copy;
8046     }
8047     //zmemcpy(state->window + state->wnext, end - copy, dist);
8048     utils.arraySet(state.window, src, end - copy, dist, state.wnext);
8049     copy -= dist;
8050     if (copy) {
8051       //zmemcpy(state->window, end - copy, copy);
8052       utils.arraySet(state.window, src, end - copy, copy, 0);
8053       state.wnext = copy;
8054       state.whave = state.wsize;
8055     } else {
8056       state.wnext += dist;
8057       if (state.wnext === state.wsize) {
8058         state.wnext = 0;
8059       }
8060       if (state.whave < state.wsize) {
8061         state.whave += dist;
8062       }
8063     }
8064   }
8065   return 0;
8066 }
8067
8068 function inflate(strm, flush) {
8069   var state;
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 */
8079   var from_source;
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 */
8087   var opts;
8088
8089   var n; // temporary var for NEED_BITS
8090
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];
8093
8094   if (!strm || !strm.state || !strm.output || !strm.input && strm.avail_in !== 0) {
8095     return Z_STREAM_ERROR;
8096   }
8097
8098   state = strm.state;
8099   if (state.mode === TYPE) {
8100     state.mode = TYPEDO;
8101   } /* skip check */
8102
8103   //--- LOAD() ---
8104   put = strm.next_out;
8105   output = strm.output;
8106   left = strm.avail_out;
8107   next = strm.next_in;
8108   input = strm.input;
8109   have = strm.avail_in;
8110   hold = state.hold;
8111   bits = state.bits;
8112   //---
8113
8114   _in = have;
8115   _out = left;
8116   ret = Z_OK;
8117
8118   inf_leave: // goto emulation
8119   for (;;) {
8120     switch (state.mode) {
8121       case HEAD:
8122         if (state.wrap === 0) {
8123           state.mode = TYPEDO;
8124           break;
8125         }
8126         //=== NEEDBITS(16);
8127         while (bits < 16) {
8128           if (have === 0) {
8129             break inf_leave;
8130           }
8131           have--;
8132           hold += input[next++] << bits;
8133           bits += 8;
8134         }
8135         //===//
8136         if (state.wrap & 2 && hold === 0x8b1f) {
8137           /* gzip header */
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);
8143           //===//
8144
8145           //=== INITBITS();
8146           hold = 0;
8147           bits = 0;
8148           //===//
8149           state.mode = FLAGS;
8150           break;
8151         }
8152         state.flags = 0; /* expect zlib header */
8153         if (state.head) {
8154           state.head.done = false;
8155         }
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';
8159           state.mode = BAD;
8160           break;
8161         }
8162         if ((hold & 0x0f) !== /*BITS(4)*/Z_DEFLATED) {
8163           strm.msg = 'unknown compression method';
8164           state.mode = BAD;
8165           break;
8166         }
8167         //--- DROPBITS(4) ---//
8168         hold >>>= 4;
8169         bits -= 4;
8170         //---//
8171         len = (hold & 0x0f) + /*BITS(4)*/8;
8172         if (state.wbits === 0) {
8173           state.wbits = len;
8174         } else if (len > state.wbits) {
8175           strm.msg = 'invalid window size';
8176           state.mode = BAD;
8177           break;
8178         }
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;
8183         //=== INITBITS();
8184         hold = 0;
8185         bits = 0;
8186         //===//
8187         break;
8188       case FLAGS:
8189         //=== NEEDBITS(16); */
8190         while (bits < 16) {
8191           if (have === 0) {
8192             break inf_leave;
8193           }
8194           have--;
8195           hold += input[next++] << bits;
8196           bits += 8;
8197         }
8198         //===//
8199         state.flags = hold;
8200         if ((state.flags & 0xff) !== Z_DEFLATED) {
8201           strm.msg = 'unknown compression method';
8202           state.mode = BAD;
8203           break;
8204         }
8205         if (state.flags & 0xe000) {
8206           strm.msg = 'unknown header flags set';
8207           state.mode = BAD;
8208           break;
8209         }
8210         if (state.head) {
8211           state.head.text = hold >> 8 & 1;
8212         }
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);
8218           //===//
8219         }
8220         //=== INITBITS();
8221         hold = 0;
8222         bits = 0;
8223         //===//
8224         state.mode = TIME;
8225       /* falls through */
8226       case TIME:
8227         //=== NEEDBITS(32); */
8228         while (bits < 32) {
8229           if (have === 0) {
8230             break inf_leave;
8231           }
8232           have--;
8233           hold += input[next++] << bits;
8234           bits += 8;
8235         }
8236         //===//
8237         if (state.head) {
8238           state.head.time = hold;
8239         }
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);
8247           //===
8248         }
8249         //=== INITBITS();
8250         hold = 0;
8251         bits = 0;
8252         //===//
8253         state.mode = OS;
8254       /* falls through */
8255       case OS:
8256         //=== NEEDBITS(16); */
8257         while (bits < 16) {
8258           if (have === 0) {
8259             break inf_leave;
8260           }
8261           have--;
8262           hold += input[next++] << bits;
8263           bits += 8;
8264         }
8265         //===//
8266         if (state.head) {
8267           state.head.xflags = hold & 0xff;
8268           state.head.os = hold >> 8;
8269         }
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);
8275           //===//
8276         }
8277         //=== INITBITS();
8278         hold = 0;
8279         bits = 0;
8280         //===//
8281         state.mode = EXLEN;
8282       /* falls through */
8283       case EXLEN:
8284         if (state.flags & 0x0400) {
8285           //=== NEEDBITS(16); */
8286           while (bits < 16) {
8287             if (have === 0) {
8288               break inf_leave;
8289             }
8290             have--;
8291             hold += input[next++] << bits;
8292             bits += 8;
8293           }
8294           //===//
8295           state.length = hold;
8296           if (state.head) {
8297             state.head.extra_len = hold;
8298           }
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);
8304             //===//
8305           }
8306           //=== INITBITS();
8307           hold = 0;
8308           bits = 0;
8309           //===//
8310         } else if (state.head) {
8311           state.head.extra = null /*Z_NULL*/;
8312         }
8313         state.mode = EXTRA;
8314       /* falls through */
8315       case EXTRA:
8316         if (state.flags & 0x0400) {
8317           copy = state.length;
8318           if (copy > have) {
8319             copy = have;
8320           }
8321           if (copy) {
8322             if (state.head) {
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);
8327               }
8328               utils.arraySet(state.head.extra, input, next,
8329               // extra field is limited to 65536 bytes
8330               // - no need for additional size check
8331               copy,
8332               /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/
8333               len);
8334               //zmemcpy(state.head.extra + len, next,
8335               //        len + copy > state.head.extra_max ?
8336               //        state.head.extra_max - len : copy);
8337             }
8338             if (state.flags & 0x0200) {
8339               state.check = (0, _crc2.default)(state.check, input, copy, next);
8340             }
8341             have -= copy;
8342             next += copy;
8343             state.length -= copy;
8344           }
8345           if (state.length) {
8346             break inf_leave;
8347           }
8348         }
8349         state.length = 0;
8350         state.mode = NAME;
8351       /* falls through */
8352       case NAME:
8353         if (state.flags & 0x0800) {
8354           if (have === 0) {
8355             break inf_leave;
8356           }
8357           copy = 0;
8358           do {
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);
8364             }
8365           } while (len && copy < have);
8366
8367           if (state.flags & 0x0200) {
8368             state.check = (0, _crc2.default)(state.check, input, copy, next);
8369           }
8370           have -= copy;
8371           next += copy;
8372           if (len) {
8373             break inf_leave;
8374           }
8375         } else if (state.head) {
8376           state.head.name = null;
8377         }
8378         state.length = 0;
8379         state.mode = COMMENT;
8380       /* falls through */
8381       case COMMENT:
8382         if (state.flags & 0x1000) {
8383           if (have === 0) {
8384             break inf_leave;
8385           }
8386           copy = 0;
8387           do {
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);
8392             }
8393           } while (len && copy < have);
8394           if (state.flags & 0x0200) {
8395             state.check = (0, _crc2.default)(state.check, input, copy, next);
8396           }
8397           have -= copy;
8398           next += copy;
8399           if (len) {
8400             break inf_leave;
8401           }
8402         } else if (state.head) {
8403           state.head.comment = null;
8404         }
8405         state.mode = HCRC;
8406       /* falls through */
8407       case HCRC:
8408         if (state.flags & 0x0200) {
8409           //=== NEEDBITS(16); */
8410           while (bits < 16) {
8411             if (have === 0) {
8412               break inf_leave;
8413             }
8414             have--;
8415             hold += input[next++] << bits;
8416             bits += 8;
8417           }
8418           //===//
8419           if (hold !== (state.check & 0xffff)) {
8420             strm.msg = 'header crc mismatch';
8421             state.mode = BAD;
8422             break;
8423           }
8424           //=== INITBITS();
8425           hold = 0;
8426           bits = 0;
8427           //===//
8428         }
8429         if (state.head) {
8430           state.head.hcrc = state.flags >> 9 & 1;
8431           state.head.done = true;
8432         }
8433         strm.adler = state.check = 0;
8434         state.mode = TYPE;
8435         break;
8436       case DICTID:
8437         //=== NEEDBITS(32); */
8438         while (bits < 32) {
8439           if (have === 0) {
8440             break inf_leave;
8441           }
8442           have--;
8443           hold += input[next++] << bits;
8444           bits += 8;
8445         }
8446         //===//
8447         strm.adler = state.check = zswap32(hold);
8448         //=== INITBITS();
8449         hold = 0;
8450         bits = 0;
8451         //===//
8452         state.mode = DICT;
8453       /* falls through */
8454       case DICT:
8455         if (state.havedict === 0) {
8456           //--- RESTORE() ---
8457           strm.next_out = put;
8458           strm.avail_out = left;
8459           strm.next_in = next;
8460           strm.avail_in = have;
8461           state.hold = hold;
8462           state.bits = bits;
8463           //---
8464           return Z_NEED_DICT;
8465         }
8466         strm.adler = state.check = 1 /*adler32(0L, Z_NULL, 0)*/;
8467         state.mode = TYPE;
8468       /* falls through */
8469       case TYPE:
8470         if (flush === Z_BLOCK || flush === Z_TREES) {
8471           break inf_leave;
8472         }
8473       /* falls through */
8474       case TYPEDO:
8475         if (state.last) {
8476           //--- BYTEBITS() ---//
8477           hold >>>= bits & 7;
8478           bits -= bits & 7;
8479           //---//
8480           state.mode = CHECK;
8481           break;
8482         }
8483         //=== NEEDBITS(3); */
8484         while (bits < 3) {
8485           if (have === 0) {
8486             break inf_leave;
8487           }
8488           have--;
8489           hold += input[next++] << bits;
8490           bits += 8;
8491         }
8492         //===//
8493         state.last = hold & 0x01 /*BITS(1)*/;
8494         //--- DROPBITS(1) ---//
8495         hold >>>= 1;
8496         bits -= 1;
8497         //---//
8498
8499         switch (hold & 0x03) {/*BITS(2)*/case 0:
8500             /* stored block */
8501             //Tracev((stderr, "inflate:     stored block%s\n",
8502             //        state.last ? " (last)" : ""));
8503             state.mode = STORED;
8504             break;
8505           case 1:
8506             /* fixed block */
8507             fixedtables(state);
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) ---//
8513               hold >>>= 2;
8514               bits -= 2;
8515               //---//
8516               break inf_leave;
8517             }
8518             break;
8519           case 2:
8520             /* dynamic block */
8521             //Tracev((stderr, "inflate:     dynamic codes block%s\n",
8522             //        state.last ? " (last)" : ""));
8523             state.mode = TABLE;
8524             break;
8525           case 3:
8526             strm.msg = 'invalid block type';
8527             state.mode = BAD;
8528         }
8529         //--- DROPBITS(2) ---//
8530         hold >>>= 2;
8531         bits -= 2;
8532         //---//
8533         break;
8534       case STORED:
8535         //--- BYTEBITS() ---// /* go to byte boundary */
8536         hold >>>= bits & 7;
8537         bits -= bits & 7;
8538         //---//
8539         //=== NEEDBITS(32); */
8540         while (bits < 32) {
8541           if (have === 0) {
8542             break inf_leave;
8543           }
8544           have--;
8545           hold += input[next++] << bits;
8546           bits += 8;
8547         }
8548         //===//
8549         if ((hold & 0xffff) !== (hold >>> 16 ^ 0xffff)) {
8550           strm.msg = 'invalid stored block lengths';
8551           state.mode = BAD;
8552           break;
8553         }
8554         state.length = hold & 0xffff;
8555         //Tracev((stderr, "inflate:       stored length %u\n",
8556         //        state.length));
8557         //=== INITBITS();
8558         hold = 0;
8559         bits = 0;
8560         //===//
8561         state.mode = COPY_;
8562         if (flush === Z_TREES) {
8563           break inf_leave;
8564         }
8565       /* falls through */
8566       case COPY_:
8567         state.mode = COPY;
8568       /* falls through */
8569       case COPY:
8570         copy = state.length;
8571         if (copy) {
8572           if (copy > have) {
8573             copy = have;
8574           }
8575           if (copy > left) {
8576             copy = left;
8577           }
8578           if (copy === 0) {
8579             break inf_leave;
8580           }
8581           //--- zmemcpy(put, next, copy); ---
8582           utils.arraySet(output, input, next, copy, put);
8583           //---//
8584           have -= copy;
8585           next += copy;
8586           left -= copy;
8587           put += copy;
8588           state.length -= copy;
8589           break;
8590         }
8591         //Tracev((stderr, "inflate:       stored end\n"));
8592         state.mode = TYPE;
8593         break;
8594       case TABLE:
8595         //=== NEEDBITS(14); */
8596         while (bits < 14) {
8597           if (have === 0) {
8598             break inf_leave;
8599           }
8600           have--;
8601           hold += input[next++] << bits;
8602           bits += 8;
8603         }
8604         //===//
8605         state.nlen = (hold & 0x1f) + /*BITS(5)*/257;
8606         //--- DROPBITS(5) ---//
8607         hold >>>= 5;
8608         bits -= 5;
8609         //---//
8610         state.ndist = (hold & 0x1f) + /*BITS(5)*/1;
8611         //--- DROPBITS(5) ---//
8612         hold >>>= 5;
8613         bits -= 5;
8614         //---//
8615         state.ncode = (hold & 0x0f) + /*BITS(4)*/4;
8616         //--- DROPBITS(4) ---//
8617         hold >>>= 4;
8618         bits -= 4;
8619         //---//
8620         //#ifndef PKZIP_BUG_WORKAROUND
8621         if (state.nlen > 286 || state.ndist > 30) {
8622           strm.msg = 'too many length or distance symbols';
8623           state.mode = BAD;
8624           break;
8625         }
8626         //#endif
8627         //Tracev((stderr, "inflate:       table sizes ok\n"));
8628         state.have = 0;
8629         state.mode = LENLENS;
8630       /* falls through */
8631       case LENLENS:
8632         while (state.have < state.ncode) {
8633           //=== NEEDBITS(3);
8634           while (bits < 3) {
8635             if (have === 0) {
8636               break inf_leave;
8637             }
8638             have--;
8639             hold += input[next++] << bits;
8640             bits += 8;
8641           }
8642           //===//
8643           state.lens[order[state.have++]] = hold & 0x07; //BITS(3);
8644           //--- DROPBITS(3) ---//
8645           hold >>>= 3;
8646           bits -= 3;
8647           //---//
8648         }
8649         while (state.have < 19) {
8650           state.lens[order[state.have++]] = 0;
8651         }
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;
8657         state.lenbits = 7;
8658
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;
8662
8663         if (ret) {
8664           strm.msg = 'invalid code lengths set';
8665           state.mode = BAD;
8666           break;
8667         }
8668         //Tracev((stderr, "inflate:       code lengths ok\n"));
8669         state.have = 0;
8670         state.mode = CODELENS;
8671       /* falls through */
8672       case CODELENS:
8673         while (state.have < state.nlen + state.ndist) {
8674           for (;;) {
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;
8679
8680             if (here_bits <= bits) {
8681               break;
8682             }
8683             //--- PULLBYTE() ---//
8684             if (have === 0) {
8685               break inf_leave;
8686             }
8687             have--;
8688             hold += input[next++] << bits;
8689             bits += 8;
8690             //---//
8691           }
8692           if (here_val < 16) {
8693             //--- DROPBITS(here.bits) ---//
8694             hold >>>= here_bits;
8695             bits -= here_bits;
8696             //---//
8697             state.lens[state.have++] = here_val;
8698           } else {
8699             if (here_val === 16) {
8700               //=== NEEDBITS(here.bits + 2);
8701               n = here_bits + 2;
8702               while (bits < n) {
8703                 if (have === 0) {
8704                   break inf_leave;
8705                 }
8706                 have--;
8707                 hold += input[next++] << bits;
8708                 bits += 8;
8709               }
8710               //===//
8711               //--- DROPBITS(here.bits) ---//
8712               hold >>>= here_bits;
8713               bits -= here_bits;
8714               //---//
8715               if (state.have === 0) {
8716                 strm.msg = 'invalid bit length repeat';
8717                 state.mode = BAD;
8718                 break;
8719               }
8720               len = state.lens[state.have - 1];
8721               copy = 3 + (hold & 0x03); //BITS(2);
8722               //--- DROPBITS(2) ---//
8723               hold >>>= 2;
8724               bits -= 2;
8725               //---//
8726             } else if (here_val === 17) {
8727               //=== NEEDBITS(here.bits + 3);
8728               n = here_bits + 3;
8729               while (bits < n) {
8730                 if (have === 0) {
8731                   break inf_leave;
8732                 }
8733                 have--;
8734                 hold += input[next++] << bits;
8735                 bits += 8;
8736               }
8737               //===//
8738               //--- DROPBITS(here.bits) ---//
8739               hold >>>= here_bits;
8740               bits -= here_bits;
8741               //---//
8742               len = 0;
8743               copy = 3 + (hold & 0x07); //BITS(3);
8744               //--- DROPBITS(3) ---//
8745               hold >>>= 3;
8746               bits -= 3;
8747               //---//
8748             } else {
8749               //=== NEEDBITS(here.bits + 7);
8750               n = here_bits + 7;
8751               while (bits < n) {
8752                 if (have === 0) {
8753                   break inf_leave;
8754                 }
8755                 have--;
8756                 hold += input[next++] << bits;
8757                 bits += 8;
8758               }
8759               //===//
8760               //--- DROPBITS(here.bits) ---//
8761               hold >>>= here_bits;
8762               bits -= here_bits;
8763               //---//
8764               len = 0;
8765               copy = 11 + (hold & 0x7f); //BITS(7);
8766               //--- DROPBITS(7) ---//
8767               hold >>>= 7;
8768               bits -= 7;
8769               //---//
8770             }
8771             if (state.have + copy > state.nlen + state.ndist) {
8772               strm.msg = 'invalid bit length repeat';
8773               state.mode = BAD;
8774               break;
8775             }
8776             while (copy--) {
8777               state.lens[state.have++] = len;
8778             }
8779           }
8780         }
8781
8782         /* handle error breaks in while */
8783         if (state.mode === BAD) {
8784           break;
8785         }
8786
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';
8790           state.mode = BAD;
8791           break;
8792         }
8793
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 */
8797         state.lenbits = 9;
8798
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;
8805
8806         if (ret) {
8807           strm.msg = 'invalid literal/lengths set';
8808           state.mode = BAD;
8809           break;
8810         }
8811
8812         state.distbits = 6;
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;
8822
8823         if (ret) {
8824           strm.msg = 'invalid distances set';
8825           state.mode = BAD;
8826           break;
8827         }
8828         //Tracev((stderr, 'inflate:       codes ok\n'));
8829         state.mode = LEN_;
8830         if (flush === Z_TREES) {
8831           break inf_leave;
8832         }
8833       /* falls through */
8834       case LEN_:
8835         state.mode = LEN;
8836       /* falls through */
8837       case LEN:
8838         if (have >= 6 && left >= 258) {
8839           //--- RESTORE() ---
8840           strm.next_out = put;
8841           strm.avail_out = left;
8842           strm.next_in = next;
8843           strm.avail_in = have;
8844           state.hold = hold;
8845           state.bits = bits;
8846           //---
8847           (0, _inffast2.default)(strm, _out);
8848           //--- LOAD() ---
8849           put = strm.next_out;
8850           output = strm.output;
8851           left = strm.avail_out;
8852           next = strm.next_in;
8853           input = strm.input;
8854           have = strm.avail_in;
8855           hold = state.hold;
8856           bits = state.bits;
8857           //---
8858
8859           if (state.mode === TYPE) {
8860             state.back = -1;
8861           }
8862           break;
8863         }
8864         state.back = 0;
8865         for (;;) {
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;
8870
8871           if (here_bits <= bits) {
8872             break;
8873           }
8874           //--- PULLBYTE() ---//
8875           if (have === 0) {
8876             break inf_leave;
8877           }
8878           have--;
8879           hold += input[next++] << bits;
8880           bits += 8;
8881           //---//
8882         }
8883         if (here_op && (here_op & 0xf0) === 0) {
8884           last_bits = here_bits;
8885           last_op = here_op;
8886           last_val = here_val;
8887           for (;;) {
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;
8892
8893             if (last_bits + here_bits <= bits) {
8894               break;
8895             }
8896             //--- PULLBYTE() ---//
8897             if (have === 0) {
8898               break inf_leave;
8899             }
8900             have--;
8901             hold += input[next++] << bits;
8902             bits += 8;
8903             //---//
8904           }
8905           //--- DROPBITS(last.bits) ---//
8906           hold >>>= last_bits;
8907           bits -= last_bits;
8908           //---//
8909           state.back += last_bits;
8910         }
8911         //--- DROPBITS(here.bits) ---//
8912         hold >>>= here_bits;
8913         bits -= here_bits;
8914         //---//
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));
8921           state.mode = LIT;
8922           break;
8923         }
8924         if (here_op & 32) {
8925           //Tracevv((stderr, "inflate:         end of block\n"));
8926           state.back = -1;
8927           state.mode = TYPE;
8928           break;
8929         }
8930         if (here_op & 64) {
8931           strm.msg = 'invalid literal/length code';
8932           state.mode = BAD;
8933           break;
8934         }
8935         state.extra = here_op & 15;
8936         state.mode = LENEXT;
8937       /* falls through */
8938       case LENEXT:
8939         if (state.extra) {
8940           //=== NEEDBITS(state.extra);
8941           n = state.extra;
8942           while (bits < n) {
8943             if (have === 0) {
8944               break inf_leave;
8945             }
8946             have--;
8947             hold += input[next++] << bits;
8948             bits += 8;
8949           }
8950           //===//
8951           state.length += hold & (1 << state.extra) - 1 /*BITS(state.extra)*/;
8952           //--- DROPBITS(state.extra) ---//
8953           hold >>>= state.extra;
8954           bits -= state.extra;
8955           //---//
8956           state.back += state.extra;
8957         }
8958         //Tracevv((stderr, "inflate:         length %u\n", state.length));
8959         state.was = state.length;
8960         state.mode = DIST;
8961       /* falls through */
8962       case DIST:
8963         for (;;) {
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;
8968
8969           if (here_bits <= bits) {
8970             break;
8971           }
8972           //--- PULLBYTE() ---//
8973           if (have === 0) {
8974             break inf_leave;
8975           }
8976           have--;
8977           hold += input[next++] << bits;
8978           bits += 8;
8979           //---//
8980         }
8981         if ((here_op & 0xf0) === 0) {
8982           last_bits = here_bits;
8983           last_op = here_op;
8984           last_val = here_val;
8985           for (;;) {
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;
8990
8991             if (last_bits + here_bits <= bits) {
8992               break;
8993             }
8994             //--- PULLBYTE() ---//
8995             if (have === 0) {
8996               break inf_leave;
8997             }
8998             have--;
8999             hold += input[next++] << bits;
9000             bits += 8;
9001             //---//
9002           }
9003           //--- DROPBITS(last.bits) ---//
9004           hold >>>= last_bits;
9005           bits -= last_bits;
9006           //---//
9007           state.back += last_bits;
9008         }
9009         //--- DROPBITS(here.bits) ---//
9010         hold >>>= here_bits;
9011         bits -= here_bits;
9012         //---//
9013         state.back += here_bits;
9014         if (here_op & 64) {
9015           strm.msg = 'invalid distance code';
9016           state.mode = BAD;
9017           break;
9018         }
9019         state.offset = here_val;
9020         state.extra = here_op & 15;
9021         state.mode = DISTEXT;
9022       /* falls through */
9023       case DISTEXT:
9024         if (state.extra) {
9025           //=== NEEDBITS(state.extra);
9026           n = state.extra;
9027           while (bits < n) {
9028             if (have === 0) {
9029               break inf_leave;
9030             }
9031             have--;
9032             hold += input[next++] << bits;
9033             bits += 8;
9034           }
9035           //===//
9036           state.offset += hold & (1 << state.extra) - 1 /*BITS(state.extra)*/;
9037           //--- DROPBITS(state.extra) ---//
9038           hold >>>= state.extra;
9039           bits -= state.extra;
9040           //---//
9041           state.back += state.extra;
9042         }
9043         //#ifdef INFLATE_STRICT
9044         if (state.offset > state.dmax) {
9045           strm.msg = 'invalid distance too far back';
9046           state.mode = BAD;
9047           break;
9048         }
9049         //#endif
9050         //Tracevv((stderr, "inflate:         distance %u\n", state.offset));
9051         state.mode = MATCH;
9052       /* falls through */
9053       case MATCH:
9054         if (left === 0) {
9055           break inf_leave;
9056         }
9057         copy = _out - left;
9058         if (state.offset > copy) {
9059           /* copy from window */
9060           copy = state.offset - copy;
9061           if (copy > state.whave) {
9062             if (state.sane) {
9063               strm.msg = 'invalid distance too far back';
9064               state.mode = BAD;
9065               break;
9066             }
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; }
9074             //          left -= copy;
9075             //          state.length -= copy;
9076             //          do {
9077             //            output[put++] = 0;
9078             //          } while (--copy);
9079             //          if (state.length === 0) { state.mode = LEN; }
9080             //          break;
9081             //#endif
9082           }
9083           if (copy > state.wnext) {
9084             copy -= state.wnext;
9085             from = state.wsize - copy;
9086           } else {
9087             from = state.wnext - copy;
9088           }
9089           if (copy > state.length) {
9090             copy = state.length;
9091           }
9092           from_source = state.window;
9093         } else {
9094           /* copy from output */
9095           from_source = output;
9096           from = put - state.offset;
9097           copy = state.length;
9098         }
9099         if (copy > left) {
9100           copy = left;
9101         }
9102         left -= copy;
9103         state.length -= copy;
9104         do {
9105           output[put++] = from_source[from++];
9106         } while (--copy);
9107         if (state.length === 0) {
9108           state.mode = LEN;
9109         }
9110         break;
9111       case LIT:
9112         if (left === 0) {
9113           break inf_leave;
9114         }
9115         output[put++] = state.length;
9116         left--;
9117         state.mode = LEN;
9118         break;
9119       case CHECK:
9120         if (state.wrap) {
9121           //=== NEEDBITS(32);
9122           while (bits < 32) {
9123             if (have === 0) {
9124               break inf_leave;
9125             }
9126             have--;
9127             // Use '|' insdead of '+' to make sure that result is signed
9128             hold |= input[next++] << bits;
9129             bits += 8;
9130           }
9131           //===//
9132           _out -= left;
9133           strm.total_out += _out;
9134           state.total += _out;
9135           if (_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);
9139           }
9140           _out = left;
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';
9144             state.mode = BAD;
9145             break;
9146           }
9147           //=== INITBITS();
9148           hold = 0;
9149           bits = 0;
9150           //===//
9151           //Tracev((stderr, "inflate:   check matches trailer\n"));
9152         }
9153         state.mode = LENGTH;
9154       /* falls through */
9155       case LENGTH:
9156         if (state.wrap && state.flags) {
9157           //=== NEEDBITS(32);
9158           while (bits < 32) {
9159             if (have === 0) {
9160               break inf_leave;
9161             }
9162             have--;
9163             hold += input[next++] << bits;
9164             bits += 8;
9165           }
9166           //===//
9167           if (hold !== (state.total & 0xffffffff)) {
9168             strm.msg = 'incorrect length check';
9169             state.mode = BAD;
9170             break;
9171           }
9172           //=== INITBITS();
9173           hold = 0;
9174           bits = 0;
9175           //===//
9176           //Tracev((stderr, "inflate:   length matches trailer\n"));
9177         }
9178         state.mode = DONE;
9179       /* falls through */
9180       case DONE:
9181         ret = Z_STREAM_END;
9182         break inf_leave;
9183       case BAD:
9184         ret = Z_DATA_ERROR;
9185         break inf_leave;
9186       case MEM:
9187         return Z_MEM_ERROR;
9188       case SYNC:
9189       /* falls through */
9190       default:
9191         return Z_STREAM_ERROR;
9192     }
9193   }
9194
9195   // inf_leave <- here is real place for "goto inf_leave", emulated via "break inf_leave"
9196
9197   /*
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.
9202    */
9203
9204   //--- RESTORE() ---
9205   strm.next_out = put;
9206   strm.avail_out = left;
9207   strm.next_in = next;
9208   strm.avail_in = have;
9209   state.hold = hold;
9210   state.bits = bits;
9211   //---
9212
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)) {
9215       state.mode = MEM;
9216       return Z_MEM_ERROR;
9217     }
9218   }
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);
9227   }
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) {
9230     ret = Z_BUF_ERROR;
9231   }
9232   return ret;
9233 }
9234
9235 function inflateEnd(strm) {
9236
9237   if (!strm || !strm.state /*|| strm->zfree == (free_func)0*/) {
9238       return Z_STREAM_ERROR;
9239     }
9240
9241   var state = strm.state;
9242   if (state.window) {
9243     state.window = null;
9244   }
9245   strm.state = null;
9246   return Z_OK;
9247 }
9248
9249 function inflateGetHeader(strm, head) {
9250   var state;
9251
9252   /* check state */
9253   if (!strm || !strm.state) {
9254     return Z_STREAM_ERROR;
9255   }
9256   state = strm.state;
9257   if ((state.wrap & 2) === 0) {
9258     return Z_STREAM_ERROR;
9259   }
9260
9261   /* save header structure */
9262   state.head = head;
9263   head.done = false;
9264   return Z_OK;
9265 }
9266
9267 function inflateSetDictionary(strm, dictionary) {
9268   var dictLength = dictionary.length;
9269
9270   var state;
9271   var dictid;
9272   var ret;
9273
9274   /* check state */
9275   if (!strm /* == Z_NULL */ || !strm.state /* == Z_NULL */) {
9276       return Z_STREAM_ERROR;
9277     }
9278   state = strm.state;
9279
9280   if (state.wrap !== 0 && state.mode !== DICT) {
9281     return Z_STREAM_ERROR;
9282   }
9283
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;
9291     }
9292   }
9293   /* copy dictionary to window using updatewindow(), which will amend the
9294    existing dictionary if appropriate */
9295   ret = updatewindow(strm, dictionary, dictLength, dictLength);
9296   if (ret) {
9297     state.mode = MEM;
9298     return Z_MEM_ERROR;
9299   }
9300   state.havedict = 1;
9301   // Tracev((stderr, "inflate:   dictionary set\n"));
9302   return Z_OK;
9303 }
9304
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)';
9315
9316 /* Not implemented
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;
9324 */
9325 },{"../utils/common.js":22,"./adler32.js":23,"./crc32.js":24,"./inffast.js":25,"./inftrees.js":27}],27:[function(require,module,exports){
9326 "use strict";
9327
9328 Object.defineProperty(exports, "__esModule", {
9329   value: true
9330 });
9331 exports.default = inflate_table;
9332
9333 var _common = require("../utils/common.js");
9334
9335 var utils = _interopRequireWildcard(_common);
9336
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; } }
9338
9339 var MAXBITS = 15;
9340 var ENOUGH_LENS = 852;
9341 var ENOUGH_DISTS = 592;
9342 //var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS);
9343
9344 var CODES = 0;
9345 var LENS = 1;
9346 var DISTS = 2;
9347
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];
9350
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];
9353
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];
9356
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];
9359
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 */
9363
9364   var len = 0; /* a code's length in bits */
9365   var sym = 0; /* index of code symbols */
9366   var min = 0,
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 */
9380   var base_index = 0;
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 */
9385   var extra = null;
9386   var extra_index = 0;
9387
9388   var here_bits, here_op, here_val;
9389
9390   /*
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
9410    the caller.
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
9415    decoding tables.
9416    */
9417
9418   /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
9419   for (len = 0; len <= MAXBITS; len++) {
9420     count[len] = 0;
9421   }
9422   for (sym = 0; sym < codes; sym++) {
9423     count[lens[lens_index + sym]]++;
9424   }
9425
9426   /* bound code lengths, force root to be within code lengths */
9427   root = bits;
9428   for (max = MAXBITS; max >= 1; max--) {
9429     if (count[max] !== 0) {
9430       break;
9431     }
9432   }
9433   if (root > max) {
9434     root = max;
9435   }
9436   if (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;
9442
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;
9447
9448     opts.bits = 1;
9449     return 0; /* no symbols, but wait for decoding to report error */
9450   }
9451   for (min = 1; min < max; min++) {
9452     if (count[min] !== 0) {
9453       break;
9454     }
9455   }
9456   if (root < min) {
9457     root = min;
9458   }
9459
9460   /* check for an over-subscribed or incomplete set of lengths */
9461   left = 1;
9462   for (len = 1; len <= MAXBITS; len++) {
9463     left <<= 1;
9464     left -= count[len];
9465     if (left < 0) {
9466       return -1;
9467     } /* over-subscribed */
9468   }
9469   if (left > 0 && (type === CODES || max !== 1)) {
9470     return -1; /* incomplete set */
9471   }
9472
9473   /* generate offsets into symbol table for each length for sorting */
9474   offs[1] = 0;
9475   for (len = 1; len < MAXBITS; len++) {
9476     offs[len + 1] = offs[len] + count[len];
9477   }
9478
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;
9483     }
9484   }
9485
9486   /*
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.
9511    */
9512
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 */
9518     end = 19;
9519   } else if (type === LENS) {
9520     base = lbase;
9521     base_index -= 257;
9522     extra = lext;
9523     extra_index -= 257;
9524     end = 256;
9525   } else {
9526     /* DISTS */
9527     base = dbase;
9528     extra = dext;
9529     end = -1;
9530   }
9531
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 */
9542
9543   /* check available table space */
9544   if (type === LENS && used > ENOUGH_LENS || type === DISTS && used > ENOUGH_DISTS) {
9545     return 1;
9546   }
9547
9548   /* process all codes and make table entries */
9549   for (;;) {
9550     /* create table entry */
9551     here_bits = len - drop;
9552     if (work[sym] < end) {
9553       here_op = 0;
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]];
9558     } else {
9559       here_op = 32 + 64; /* end of block */
9560       here_val = 0;
9561     }
9562
9563     /* replicate for those indices with low len bits equal to huff */
9564     incr = 1 << len - drop;
9565     fill = 1 << curr;
9566     min = fill; /* save offset to next table */
9567     do {
9568       fill -= incr;
9569       table[next + (huff >> drop) + fill] = here_bits << 24 | here_op << 16 | here_val | 0;
9570     } while (fill !== 0);
9571
9572     /* backwards increment the len-bit code huff */
9573     incr = 1 << len - 1;
9574     while (huff & incr) {
9575       incr >>= 1;
9576     }
9577     if (incr !== 0) {
9578       huff &= incr - 1;
9579       huff += incr;
9580     } else {
9581       huff = 0;
9582     }
9583
9584     /* go to next symbol, update count, len */
9585     sym++;
9586     if (--count[len] === 0) {
9587       if (len === max) {
9588         break;
9589       }
9590       len = lens[lens_index + work[sym]];
9591     }
9592
9593     /* create new sub-table if needed */
9594     if (len > root && (huff & mask) !== low) {
9595       /* if first time, transition to sub-tables */
9596       if (drop === 0) {
9597         drop = root;
9598       }
9599
9600       /* increment past last table */
9601       next += min; /* here min is 1 << curr */
9602
9603       /* determine length of next table */
9604       curr = len - drop;
9605       left = 1 << curr;
9606       while (curr + drop < max) {
9607         left -= count[curr + drop];
9608         if (left <= 0) {
9609           break;
9610         }
9611         curr++;
9612         left <<= 1;
9613       }
9614
9615       /* check for enough space */
9616       used += 1 << curr;
9617       if (type === LENS && used > ENOUGH_LENS || type === DISTS && used > ENOUGH_DISTS) {
9618         return 1;
9619       }
9620
9621       /* point entry in root table to sub-table */
9622       low = huff & mask;
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;
9627     }
9628   }
9629
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) */
9633   if (huff !== 0) {
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;
9638   }
9639
9640   /* set return parameters */
9641   //opts.table_index += used;
9642   opts.bits = root;
9643   return 0;
9644 };
9645 },{"../utils/common.js":22}],28:[function(require,module,exports){
9646 'use strict';
9647
9648 Object.defineProperty(exports, "__esModule", {
9649   value: true
9650 });
9651 exports.default = ZStream;
9652 function ZStream() {
9653   /* next input byte */
9654   this.input = null; // JS specific, because we have no pointers
9655   this.next_in = 0;
9656   /* number of bytes available at input */
9657   this.avail_in = 0;
9658   /* total number of input bytes read so far */
9659   this.total_in = 0;
9660   /* next output byte should be put there */
9661   this.output = null; // JS specific, because we have no pointers
9662   this.next_out = 0;
9663   /* remaining free space at output */
9664   this.avail_out = 0;
9665   /* total number of bytes output so far */
9666   this.total_out = 0;
9667   /* last error message, NULL if no error */
9668   this.msg = '' /*Z_NULL*/;
9669   /* not visible by applications */
9670   this.state = null;
9671   /* best guess about the data type: binary or text */
9672   this.data_type = 2 /*Z_UNKNOWN*/;
9673   /* adler32 value of the uncompressed data */
9674   this.adler = 0;
9675 }
9676 },{}],29:[function(require,module,exports){
9677 'use strict';
9678
9679 Object.defineProperty(exports, "__esModule", {
9680     value: true
9681 });
9682 exports.default = Websock;
9683
9684 var _logging = require('./util/logging.js');
9685
9686 var Log = _interopRequireWildcard(_logging);
9687
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; } }
9689
9690 function Websock() {
9691     "use strict";
9692
9693     this._websocket = null; // WebSocket object
9694
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
9701
9702     this._sQbufferSize = 1024 * 10; // 10 KiB
9703     // called in init: this._sQ = new Uint8Array(this._sQbufferSize);
9704     this._sQlen = 0;
9705     this._sQ = null; // Send queue
9706
9707     this._eventHandlers = {
9708         'message': function () {},
9709         'open': function () {},
9710         'close': function () {},
9711         'error': function () {}
9712     };
9713 } /*
9714    * Websock: high-performance binary WebSockets
9715    * Copyright (C) 2012 Joel Martin
9716    * Licensed under MPL 2.0 (see LICENSE.txt)
9717    *
9718    * Websock is similar to the standard WebSocket object but with extra
9719    * buffer handling.
9720    *
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.
9725    */
9726
9727 ;
9728
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;
9733
9734 var MAX_RQ_GROW_SIZE = 40 * 1024 * 1024; // 40 MiB
9735
9736 var typedArrayToString = function () {
9737     // This is only for PhantomJS, which doesn't like apply-ing
9738     // with Typed Arrays
9739     try {
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);
9744         };
9745     } catch (ex) {
9746         return function (a) {
9747             return String.fromCharCode.apply(null, Array.prototype.slice.call(a));
9748         };
9749     }
9750 }();
9751
9752 Websock.prototype = {
9753     // Getters and Setters
9754     get_sQ: function () {
9755         return this._sQ;
9756     },
9757
9758     get_rQ: function () {
9759         return this._rQ;
9760     },
9761
9762     get_rQi: function () {
9763         return this._rQi;
9764     },
9765
9766     set_rQi: function (val) {
9767         this._rQi = val;
9768     },
9769
9770     // Receive Queue
9771     rQlen: function () {
9772         return this._rQlen - this._rQi;
9773     },
9774
9775     rQpeek8: function () {
9776         return this._rQ[this._rQi];
9777     },
9778
9779     rQshift8: function () {
9780         return this._rQ[this._rQi++];
9781     },
9782
9783     rQskip8: function () {
9784         this._rQi++;
9785     },
9786
9787     rQskipBytes: function (num) {
9788         this._rQi += num;
9789     },
9790
9791     // TODO(directxman12): test performance with these vs a DataView
9792     rQshift16: function () {
9793         return (this._rQ[this._rQi++] << 8) + this._rQ[this._rQi++];
9794     },
9795
9796     rQshift32: function () {
9797         return (this._rQ[this._rQi++] << 24) + (this._rQ[this._rQi++] << 16) + (this._rQ[this._rQi++] << 8) + this._rQ[this._rQi++];
9798     },
9799
9800     rQshiftStr: function (len) {
9801         if (typeof len === 'undefined') {
9802             len = this.rQlen();
9803         }
9804         var arr = new Uint8Array(this._rQ.buffer, this._rQi, len);
9805         this._rQi += len;
9806         return typedArrayToString(arr);
9807     },
9808
9809     rQshiftBytes: function (len) {
9810         if (typeof len === 'undefined') {
9811             len = this.rQlen();
9812         }
9813         this._rQi += len;
9814         return new Uint8Array(this._rQ.buffer, this._rQi - len, len);
9815     },
9816
9817     rQshiftTo: function (target, len) {
9818         if (len === undefined) {
9819             len = this.rQlen();
9820         }
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));
9823         this._rQi += len;
9824     },
9825
9826     rQwhole: function () {
9827         return new Uint8Array(this._rQ.buffer, 0, this._rQlen);
9828     },
9829
9830     rQslice: function (start, end) {
9831         if (end) {
9832             return new Uint8Array(this._rQ.buffer, this._rQi + start, end - start);
9833         } else {
9834             return new Uint8Array(this._rQ.buffer, this._rQi + start, this._rQlen - this._rQi - start);
9835         }
9836     },
9837
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
9843         if (rQlen < num) {
9844             if (goback) {
9845                 if (this._rQi < goback) {
9846                     throw new Error("rQwait cannot backup " + goback + " bytes");
9847                 }
9848                 this._rQi -= goback;
9849             }
9850             return true; // true means need more data
9851         }
9852         return false;
9853     },
9854
9855     // Send Queue
9856
9857     flush: function () {
9858         if (this._sQlen > 0 && this._websocket.readyState === WebSocket.OPEN) {
9859             this._websocket.send(this._encode_message());
9860             this._sQlen = 0;
9861         }
9862     },
9863
9864     send: function (arr) {
9865         this._sQ.set(arr, this._sQlen);
9866         this._sQlen += arr.length;
9867         this.flush();
9868     },
9869
9870     send_string: function (str) {
9871         this.send(str.split('').map(function (chr) {
9872             return chr.charCodeAt(0);
9873         }));
9874     },
9875
9876     // Event Handlers
9877     off: function (evt) {
9878         this._eventHandlers[evt] = function () {};
9879     },
9880
9881     on: function (evt, handler) {
9882         this._eventHandlers[evt] = handler;
9883     },
9884
9885     _allocate_buffers: function () {
9886         this._rQ = new Uint8Array(this._rQbufferSize);
9887         this._sQ = new Uint8Array(this._sQbufferSize);
9888     },
9889
9890     init: function () {
9891         this._allocate_buffers();
9892         this._rQi = 0;
9893         this._websocket = null;
9894     },
9895
9896     open: function (uri, protocols) {
9897         var ws_schema = uri.match(/^([a-z]+):\/\//)[1];
9898         this.init();
9899
9900         this._websocket = new WebSocket(uri, protocols);
9901         this._websocket.binaryType = 'arraybuffer';
9902
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);
9908             }
9909
9910             this._eventHandlers.open();
9911             Log.Debug("<< WebSock.onopen");
9912         }.bind(this);
9913         this._websocket.onclose = function (e) {
9914             Log.Debug(">> WebSock.onclose");
9915             this._eventHandlers.close(e);
9916             Log.Debug("<< WebSock.onclose");
9917         }.bind(this);
9918         this._websocket.onerror = function (e) {
9919             Log.Debug(">> WebSock.onerror: " + e);
9920             this._eventHandlers.error(e);
9921             Log.Debug("<< WebSock.onerror: " + e);
9922         }.bind(this);
9923     },
9924
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();
9930             }
9931
9932             this._websocket.onmessage = function (e) {
9933                 return;
9934             };
9935         }
9936     },
9937
9938     // private methods
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);
9943     },
9944
9945     _expand_compact_rQ: function (min_fit) {
9946         var resizeNeeded = min_fit || this._rQlen - this._rQi > this._rQbufferSize / 2;
9947         if (resizeNeeded) {
9948             if (!min_fit) {
9949                 // just double the size if we need to do compaction
9950                 this._rQbufferSize *= 2;
9951             } else {
9952                 // otherwise, make sure we satisy rQlen - rQi + min_fit < rQbufferSize / 8
9953                 this._rQbufferSize = (this._rQlen - this._rQi + min_fit) * 8;
9954             }
9955         }
9956
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");
9962             }
9963         }
9964
9965         if (resizeNeeded) {
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));
9970         } else {
9971             if (ENABLE_COPYWITHIN) {
9972                 this._rQ.copyWithin(0, this._rQi);
9973             } else {
9974                 this._rQ.set(new Uint8Array(this._rQ.buffer, this._rQi));
9975             }
9976         }
9977
9978         this._rQlen = this._rQlen - this._rQi;
9979         this._rQi = 0;
9980     },
9981
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);
9987         }
9988         this._rQ.set(u8, this._rQlen);
9989         this._rQlen += u8.length;
9990     },
9991
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) {
9998                 this._rQlen = 0;
9999                 this._rQi = 0;
10000             } else if (this._rQlen > this._rQmax) {
10001                 this._expand_compact_rQ();
10002             }
10003         } else {
10004             Log.Debug("Ignoring empty message");
10005         }
10006     }
10007 };
10008 },{"./util/logging.js":19}]},{},[15])(15)
10009 });