You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3936 lines
102 KiB
3936 lines
102 KiB
'use strict';
|
|
var Guacamole = Guacamole || {};
|
|
Guacamole.ArrayBufferReader = function(b) {
|
|
var a = this;
|
|
b.onblob = function(b) {
|
|
b = window.atob(b);
|
|
for (
|
|
var c = new ArrayBuffer(b.length), e = new Uint8Array(c), d = 0;
|
|
d < b.length;
|
|
d++
|
|
)
|
|
e[d] = b.charCodeAt(d);
|
|
if (a.ondata) a.ondata(c);
|
|
};
|
|
b.onend = function() {
|
|
if (a.onend) a.onend();
|
|
};
|
|
this.onend = this.ondata = null;
|
|
};
|
|
Guacamole = Guacamole || {};
|
|
Guacamole.ArrayBufferWriter = function(b) {
|
|
function a(a) {
|
|
for (var c = '', d = 0; d < a.byteLength; d++)
|
|
c += String.fromCharCode(a[d]);
|
|
b.sendBlob(window.btoa(c));
|
|
}
|
|
var d = this;
|
|
b.onack = function(a) {
|
|
if (d.onack) d.onack(a);
|
|
};
|
|
this.blobLength = Guacamole.ArrayBufferWriter.DEFAULT_BLOB_LENGTH;
|
|
this.sendData = function(b) {
|
|
b = new Uint8Array(b);
|
|
if (b.length <= d.blobLength) a(b);
|
|
else
|
|
for (var c = 0; c < b.length; c += d.blobLength)
|
|
a(b.subarray(c, c + d.blobLength));
|
|
};
|
|
this.sendEnd = function() {
|
|
b.sendEnd();
|
|
};
|
|
this.onack = null;
|
|
};
|
|
Guacamole.ArrayBufferWriter.DEFAULT_BLOB_LENGTH = 6048;
|
|
Guacamole = Guacamole || {};
|
|
Guacamole.AudioContextFactory = {
|
|
singleton: null,
|
|
getAudioContext: function() {
|
|
var b = window.AudioContext || window.webkitAudioContext;
|
|
if (b)
|
|
try {
|
|
return (
|
|
Guacamole.AudioContextFactory.singleton ||
|
|
(Guacamole.AudioContextFactory.singleton = new b()),
|
|
Guacamole.AudioContextFactory.singleton
|
|
);
|
|
} catch (a) {}
|
|
return null;
|
|
},
|
|
};
|
|
Guacamole = Guacamole || {};
|
|
Guacamole.AudioPlayer = function() {
|
|
this.sync = function() {};
|
|
};
|
|
Guacamole.AudioPlayer.isSupportedType = function(b) {
|
|
return Guacamole.RawAudioPlayer.isSupportedType(b);
|
|
};
|
|
Guacamole.AudioPlayer.getSupportedTypes = function() {
|
|
return Guacamole.RawAudioPlayer.getSupportedTypes();
|
|
};
|
|
Guacamole.AudioPlayer.getInstance = function(b, a) {
|
|
return Guacamole.RawAudioPlayer.isSupportedType(a)
|
|
? new Guacamole.RawAudioPlayer(b, a)
|
|
: null;
|
|
};
|
|
Guacamole.RawAudioPlayer = function(b, a) {
|
|
var d = Guacamole.RawAudioFormat.parse(a),
|
|
c = Guacamole.AudioContextFactory.getAudioContext(),
|
|
e = c.currentTime;
|
|
b = new Guacamole.ArrayBufferReader(b);
|
|
var f = 1 === d.bytesPerSample ? window.Int8Array : window.Int16Array,
|
|
k = 1 === d.bytesPerSample ? 128 : 32768,
|
|
m = [],
|
|
n = function(a) {
|
|
if (1 >= a.length) return a[0];
|
|
var b = 0;
|
|
a.forEach(function(a) {
|
|
b += a.length;
|
|
});
|
|
var c = 0,
|
|
d = new f(b);
|
|
a.forEach(function(a) {
|
|
d.set(a, c);
|
|
c += a.length;
|
|
});
|
|
return d;
|
|
};
|
|
b.ondata = function(a) {
|
|
m.push(new f(new f(a)));
|
|
if ((a = n(m))) {
|
|
var b = Number.MAX_VALUE,
|
|
p = a.length,
|
|
g = Math.floor(0.02 * d.rate);
|
|
for (
|
|
g = Math.max(
|
|
d.channels * g,
|
|
d.channels * (Math.floor(a.length / d.channels) - g),
|
|
);
|
|
g < a.length;
|
|
g += d.channels
|
|
) {
|
|
for (var t = 0, q = 0; q < d.channels; q++) t += Math.abs(a[g + q]);
|
|
t <= b && ((p = g + d.channels), (b = t));
|
|
}
|
|
m =
|
|
p === a.length
|
|
? [a]
|
|
: [
|
|
new f(a.buffer.slice(0, p * d.bytesPerSample)),
|
|
new f(a.buffer.slice(p * d.bytesPerSample)),
|
|
];
|
|
a = m.shift();
|
|
} else a = null;
|
|
if (a) {
|
|
b = c.currentTime;
|
|
e < b && (e = b);
|
|
b = c.createBufferSource();
|
|
b.connect(c.destination);
|
|
b.start || (b.start = b.noteOn);
|
|
p = a;
|
|
g = p.length / d.channels;
|
|
t = c.currentTime;
|
|
e < t && (e = t);
|
|
t = c.createBuffer(d.channels, g, d.rate);
|
|
for (q = 0; q < d.channels; q++)
|
|
for (var u = t.getChannelData(q), w = q, r = 0; r < g; r++)
|
|
(u[r] = p[w] / k), (w += d.channels);
|
|
b.buffer = t;
|
|
b.start(e);
|
|
e += a.length / d.channels / d.rate;
|
|
}
|
|
};
|
|
this.sync = function() {
|
|
e = Math.min(e, c.currentTime + 0.3);
|
|
};
|
|
};
|
|
Guacamole.RawAudioPlayer.prototype = new Guacamole.AudioPlayer();
|
|
Guacamole.RawAudioPlayer.isSupportedType = function(b) {
|
|
return Guacamole.AudioContextFactory.getAudioContext()
|
|
? null !== Guacamole.RawAudioFormat.parse(b)
|
|
: !1;
|
|
};
|
|
Guacamole.RawAudioPlayer.getSupportedTypes = function() {
|
|
return Guacamole.AudioContextFactory.getAudioContext()
|
|
? ['audio/L8', 'audio/L16']
|
|
: [];
|
|
};
|
|
Guacamole = Guacamole || {};
|
|
Guacamole.AudioRecorder = function() {
|
|
this.onerror = this.onclose = null;
|
|
};
|
|
Guacamole.AudioRecorder.isSupportedType = function(b) {
|
|
return Guacamole.RawAudioRecorder.isSupportedType(b);
|
|
};
|
|
Guacamole.AudioRecorder.getSupportedTypes = function() {
|
|
return Guacamole.RawAudioRecorder.getSupportedTypes();
|
|
};
|
|
Guacamole.AudioRecorder.getInstance = function(b, a) {
|
|
return Guacamole.RawAudioRecorder.isSupportedType(a)
|
|
? new Guacamole.RawAudioRecorder(b, a)
|
|
: null;
|
|
};
|
|
Guacamole.RawAudioRecorder = function(b, a) {
|
|
var d = this,
|
|
c = Guacamole.RawAudioFormat.parse(a),
|
|
e = Guacamole.AudioContextFactory.getAudioContext();
|
|
navigator.mediaDevices || (navigator.mediaDevices = {});
|
|
navigator.mediaDevices.getUserMedia ||
|
|
(navigator.mediaDevices.getUserMedia = (
|
|
navigator.getUserMedia ||
|
|
navigator.webkitGetUserMedia ||
|
|
navigator.mozGetUserMedia ||
|
|
navigator.msGetUserMedia
|
|
).bind(navigator));
|
|
var f = new Guacamole.ArrayBufferWriter(b),
|
|
k = 1 === c.bytesPerSample ? window.Int8Array : window.Int16Array,
|
|
m = 1 === c.bytesPerSample ? 128 : 32768,
|
|
n = 0,
|
|
g = 0,
|
|
l = null,
|
|
p = null,
|
|
v = null,
|
|
t = function(a) {
|
|
if (0 === a) return 1;
|
|
a *= Math.PI;
|
|
return Math.sin(a) / a;
|
|
},
|
|
q = function(a) {
|
|
n += a.length;
|
|
var b = Math.round((n * c.rate) / a.sampleRate) - g;
|
|
g += b;
|
|
for (var d = new k(b * c.channels), h = 0; h < c.channels; h++)
|
|
for (var e = a.getChannelData(h), q = h, f = 0; f < b; f++) {
|
|
for (
|
|
var u = q,
|
|
p = e,
|
|
l = (f / (b - 1)) * (p.length - 1),
|
|
G = Math.floor(l) + 3,
|
|
r = 0,
|
|
w = Math.floor(l) - 3 + 1;
|
|
w <= G;
|
|
w++
|
|
) {
|
|
var v = p[w] || 0;
|
|
var D = l - w;
|
|
D = -3 < D && 3 > D ? t(D) * t(D / 3) : 0;
|
|
r += v * D;
|
|
}
|
|
d[u] = r * m;
|
|
q += c.channels;
|
|
}
|
|
return d;
|
|
},
|
|
u = function(a) {
|
|
v = e.createScriptProcessor(2048, c.channels, c.channels);
|
|
v.connect(e.destination);
|
|
v.onaudioprocess = function(a) {
|
|
f.sendData(q(a.inputBuffer).buffer);
|
|
};
|
|
p = e.createMediaStreamSource(a);
|
|
p.connect(v);
|
|
'suspended' === e.state && e.resume();
|
|
l = a;
|
|
},
|
|
w = function() {
|
|
f.sendEnd();
|
|
if (d.onerror) d.onerror();
|
|
};
|
|
f.onack = function(a) {
|
|
if (a.code !== Guacamole.Status.Code.SUCCESS || l) {
|
|
p && p.disconnect();
|
|
v && v.disconnect();
|
|
if (l) for (var b = l.getTracks(), c = 0; c < b.length; c++) b[c].stop();
|
|
l = p = v = null;
|
|
f.sendEnd();
|
|
f.onack = null;
|
|
if (a.code === Guacamole.Status.Code.RESOURCE_CLOSED) {
|
|
if (d.onclose) d.onclose();
|
|
} else if (d.onerror) d.onerror();
|
|
} else
|
|
(a = navigator.mediaDevices.getUserMedia({ audio: !0 }, u, w)) &&
|
|
a.then &&
|
|
a.then(u, w);
|
|
};
|
|
};
|
|
Guacamole.RawAudioRecorder.prototype = new Guacamole.AudioRecorder();
|
|
Guacamole.RawAudioRecorder.isSupportedType = function(b) {
|
|
return Guacamole.AudioContextFactory.getAudioContext()
|
|
? null !== Guacamole.RawAudioFormat.parse(b)
|
|
: !1;
|
|
};
|
|
Guacamole.RawAudioRecorder.getSupportedTypes = function() {
|
|
return Guacamole.AudioContextFactory.getAudioContext()
|
|
? ['audio/L8', 'audio/L16']
|
|
: [];
|
|
};
|
|
Guacamole = Guacamole || {};
|
|
Guacamole.BlobReader = function(b, a) {
|
|
var d = this,
|
|
c = 0;
|
|
var e = window.BlobBuilder
|
|
? new BlobBuilder()
|
|
: window.WebKitBlobBuilder
|
|
? new WebKitBlobBuilder()
|
|
: window.MozBlobBuilder
|
|
? new MozBlobBuilder()
|
|
: new (function() {
|
|
var b = [];
|
|
this.append = function(c) {
|
|
b.push(new Blob([c], { type: a }));
|
|
};
|
|
this.getBlob = function() {
|
|
return new Blob(b, { type: a });
|
|
};
|
|
})();
|
|
b.onblob = function(a) {
|
|
a = window.atob(a);
|
|
for (
|
|
var f = new ArrayBuffer(a.length), m = new Uint8Array(f), n = 0;
|
|
n < a.length;
|
|
n++
|
|
)
|
|
m[n] = a.charCodeAt(n);
|
|
e.append(f);
|
|
c += f.byteLength;
|
|
if (d.onprogress) d.onprogress(f.byteLength);
|
|
b.sendAck('OK', 0);
|
|
};
|
|
b.onend = function() {
|
|
if (d.onend) d.onend();
|
|
};
|
|
this.getLength = function() {
|
|
return c;
|
|
};
|
|
this.getBlob = function() {
|
|
return e.getBlob();
|
|
};
|
|
this.onend = this.onprogress = null;
|
|
};
|
|
Guacamole = Guacamole || {};
|
|
Guacamole.BlobWriter = function(b) {
|
|
var a = this,
|
|
d = new Guacamole.ArrayBufferWriter(b);
|
|
d.onack = function(b) {
|
|
if (a.onack) a.onack(b);
|
|
};
|
|
this.sendBlob = function(b) {
|
|
var c = 0,
|
|
f = new FileReader(),
|
|
k = function() {
|
|
if (c >= b.size) {
|
|
if (a.oncomplete) a.oncomplete(b);
|
|
} else {
|
|
a: {
|
|
var e = c;
|
|
var n = c + d.blobLength,
|
|
g = (b.slice || b.webkitSlice || b.mozSlice).bind(b),
|
|
l = n - e;
|
|
if (l !== n) {
|
|
var p = g(e, l);
|
|
if (p.size === l) {
|
|
e = p;
|
|
break a;
|
|
}
|
|
}
|
|
e = g(e, n);
|
|
}
|
|
c += d.blobLength;
|
|
f.readAsArrayBuffer(e);
|
|
}
|
|
};
|
|
f.onload = function() {
|
|
d.sendData(f.result);
|
|
d.onack = function(e) {
|
|
if (a.onack) a.onack(e);
|
|
if (!e.isError()) {
|
|
if (a.onprogress) a.onprogress(b, c - d.blobLength);
|
|
k();
|
|
}
|
|
};
|
|
};
|
|
f.onerror = function() {
|
|
if (a.onerror) a.onerror(b, c, f.error);
|
|
};
|
|
k();
|
|
};
|
|
this.sendEnd = function() {
|
|
d.sendEnd();
|
|
};
|
|
this.oncomplete = this.onprogress = this.onerror = this.onack = null;
|
|
};
|
|
Guacamole = Guacamole || {};
|
|
Guacamole.Client = function(b) {
|
|
function a(h) {
|
|
if (h != e && ((e = h), c.onstatechange)) c.onstatechange(e);
|
|
}
|
|
function d() {
|
|
return 3 == e || 2 == e;
|
|
}
|
|
var c = this,
|
|
e = 0,
|
|
f = 0,
|
|
k = null,
|
|
m = { 0: 'butt', 1: 'round', 2: 'square' },
|
|
n = { 0: 'bevel', 1: 'miter', 2: 'round' },
|
|
g = new Guacamole.Display(),
|
|
l = {},
|
|
p = {},
|
|
v = [],
|
|
t = [],
|
|
q = [],
|
|
u = new Guacamole.IntegerPool(),
|
|
w = [];
|
|
this.exportState = function(h) {
|
|
var a = { currentState: e, currentTimestamp: f, layers: {} },
|
|
b = {},
|
|
c;
|
|
for (c in l) b[c] = l[c];
|
|
g.flush(function() {
|
|
for (var c in b) {
|
|
var d = parseInt(c),
|
|
e = b[c],
|
|
x = e.toCanvas(),
|
|
q = { width: e.width, height: e.height };
|
|
e.width && e.height && (q.url = x.toDataURL('image/png'));
|
|
if (0 < d) {
|
|
q.x = e.x;
|
|
q.y = e.y;
|
|
q.z = e.z;
|
|
q.alpha = e.alpha;
|
|
q.matrix = e.matrix;
|
|
d = q;
|
|
a: {
|
|
x = void 0;
|
|
if ((e = e.parent))
|
|
for (x in l)
|
|
if (e === l[x]) {
|
|
e = parseInt(x);
|
|
break a;
|
|
}
|
|
e = null;
|
|
}
|
|
d.parent = e;
|
|
}
|
|
a.layers[c] = q;
|
|
}
|
|
h(a);
|
|
});
|
|
};
|
|
this.importState = function(h, a) {
|
|
var b;
|
|
e = h.currentState;
|
|
f = h.currentTimestamp;
|
|
for (b in l) {
|
|
var c = parseInt(b);
|
|
0 < c && g.dispose(l[b]);
|
|
}
|
|
l = {};
|
|
for (b in h.layers) {
|
|
c = parseInt(b);
|
|
var d = h.layers[b],
|
|
x = r(c);
|
|
g.resize(x, d.width, d.height);
|
|
d.url &&
|
|
(g.setChannelMask(x, Guacamole.Layer.SRC), g.draw(x, 0, 0, d.url));
|
|
0 < c &&
|
|
0 <= d.parent &&
|
|
((c = r(d.parent)),
|
|
g.move(x, c, d.x, d.y, d.z),
|
|
g.shade(x, d.alpha),
|
|
(d = d.matrix),
|
|
g.distort(x, d[0], d[1], d[2], d[3], d[4], d[5]));
|
|
}
|
|
g.flush(a);
|
|
};
|
|
this.getDisplay = function() {
|
|
return g;
|
|
};
|
|
this.sendSize = function(h, a) {
|
|
d() && b.sendMessage('size', h, a);
|
|
};
|
|
this.sendKeyEvent = function(h, a) {
|
|
d() && b.sendMessage('key', a, h);
|
|
};
|
|
this.sendMouseState = function(h, a) {
|
|
if (d()) {
|
|
var c = h.x,
|
|
e = h.y;
|
|
a && ((c /= g.getScale()), (e /= g.getScale()));
|
|
g.moveCursor(Math.floor(c), Math.floor(e));
|
|
a = 0;
|
|
h.left && (a |= 1);
|
|
h.middle && (a |= 2);
|
|
h.right && (a |= 4);
|
|
h.up && (a |= 8);
|
|
h.down && (a |= 16);
|
|
b.sendMessage('mouse', Math.floor(c), Math.floor(e), a);
|
|
}
|
|
};
|
|
this.sendTouchState = function(a, c) {
|
|
if (d()) {
|
|
var h = a.x,
|
|
e = a.y;
|
|
c && ((h /= g.getScale()), (e /= g.getScale()));
|
|
b.sendMessage(
|
|
'touch',
|
|
a.id,
|
|
Math.floor(h),
|
|
Math.floor(e),
|
|
Math.floor(a.radiusX),
|
|
Math.floor(a.radiusY),
|
|
a.angle,
|
|
a.force,
|
|
);
|
|
}
|
|
};
|
|
this.createOutputStream = function() {
|
|
var a = u.next();
|
|
return (w[a] = new Guacamole.OutputStream(c, a));
|
|
};
|
|
this.createAudioStream = function(a) {
|
|
var h = c.createOutputStream();
|
|
b.sendMessage('audio', h.index, a);
|
|
return h;
|
|
};
|
|
this.createFileStream = function(a, d) {
|
|
var h = c.createOutputStream();
|
|
b.sendMessage('file', h.index, a, d);
|
|
return h;
|
|
};
|
|
this.createPipeStream = function(a, d) {
|
|
var h = c.createOutputStream();
|
|
b.sendMessage('pipe', h.index, a, d);
|
|
return h;
|
|
};
|
|
this.createClipboardStream = function(a) {
|
|
var h = c.createOutputStream();
|
|
b.sendMessage('clipboard', h.index, a);
|
|
return h;
|
|
};
|
|
this.createArgumentValueStream = function(a, d) {
|
|
var h = c.createOutputStream();
|
|
b.sendMessage('argv', h.index, a, d);
|
|
return h;
|
|
};
|
|
this.createObjectOutputStream = function(a, d, e) {
|
|
var h = c.createOutputStream();
|
|
b.sendMessage('put', a, h.index, d, e);
|
|
return h;
|
|
};
|
|
this.requestObjectInputStream = function(a, c) {
|
|
d() && b.sendMessage('get', a, c);
|
|
};
|
|
this.sendAck = function(a, c, e) {
|
|
d() && b.sendMessage('ack', a, c, e);
|
|
};
|
|
this.sendBlob = function(a, c) {
|
|
d() && b.sendMessage('blob', a, c);
|
|
};
|
|
this.endStream = function(a) {
|
|
d() && (b.sendMessage('end', a), w[a] && (u.free(a), delete w[a]));
|
|
};
|
|
this.onsync = this.onrequired = this.onpipe = this.onfilesystem = this.onfile = this.onclipboard = this.onargv = this.onmultitouch = this.onvideo = this.onaudio = this.onerror = this.onname = this.onstatechange = null;
|
|
var r = function(a) {
|
|
var h = l[a];
|
|
h ||
|
|
((h =
|
|
0 === a
|
|
? g.getDefaultLayer()
|
|
: 0 < a
|
|
? g.createLayer()
|
|
: g.createBuffer()),
|
|
(l[a] = h));
|
|
return h;
|
|
},
|
|
y = {
|
|
'miter-limit': function(a, b) {
|
|
g.setMiterLimit(a, parseFloat(b));
|
|
},
|
|
'multi-touch': function(a, b) {
|
|
if (c.onmultitouch && a instanceof Guacamole.Display.VisibleLayer)
|
|
c.onmultitouch(a, parseInt(b));
|
|
},
|
|
},
|
|
z = {
|
|
ack: function(a) {
|
|
var h = parseInt(a[0]),
|
|
b = a[1];
|
|
a = parseInt(a[2]);
|
|
var c = w[h];
|
|
if (c) {
|
|
if (c.onack) c.onack(new Guacamole.Status(a, b));
|
|
256 <= a && w[h] === c && (u.free(h), delete w[h]);
|
|
}
|
|
},
|
|
arc: function(a) {
|
|
var h = r(parseInt(a[0])),
|
|
b = parseInt(a[1]),
|
|
c = parseInt(a[2]),
|
|
d = parseInt(a[3]),
|
|
e = parseFloat(a[4]),
|
|
q = parseFloat(a[5]);
|
|
a = parseInt(a[6]);
|
|
g.arc(h, b, c, d, e, q, 0 != a);
|
|
},
|
|
argv: function(a) {
|
|
var h = parseInt(a[0]),
|
|
b = a[1];
|
|
a = a[2];
|
|
c.onargv
|
|
? ((h = t[h] = new Guacamole.InputStream(c, h)), c.onargv(h, b, a))
|
|
: c.sendAck(h, 'Receiving argument values unsupported', 256);
|
|
},
|
|
audio: function(a) {
|
|
var h = parseInt(a[0]);
|
|
a = a[1];
|
|
var b = (t[h] = new Guacamole.InputStream(c, h)),
|
|
d = null;
|
|
c.onaudio && (d = c.onaudio(b, a));
|
|
d || (d = Guacamole.AudioPlayer.getInstance(b, a));
|
|
d ? ((p[h] = d), c.sendAck(h, 'OK', 0)) : c.sendAck(h, 'BAD TYPE', 783);
|
|
},
|
|
blob: function(a) {
|
|
var h = parseInt(a[0]);
|
|
a = a[1];
|
|
if ((h = t[h]) && h.onblob) h.onblob(a);
|
|
},
|
|
body: function(a) {
|
|
var h = parseInt(a[0]);
|
|
h = q[h];
|
|
var b = parseInt(a[1]),
|
|
d = a[2];
|
|
a = a[3];
|
|
h && h.onbody
|
|
? ((b = t[b] = new Guacamole.InputStream(c, b)), h.onbody(b, d, a))
|
|
: c.sendAck(b, 'Receipt of body unsupported', 256);
|
|
},
|
|
cfill: function(a) {
|
|
var b = parseInt(a[0]),
|
|
h = r(parseInt(a[1])),
|
|
c = parseInt(a[2]),
|
|
d = parseInt(a[3]),
|
|
e = parseInt(a[4]);
|
|
a = parseInt(a[5]);
|
|
g.setChannelMask(h, b);
|
|
g.fillColor(h, c, d, e, a);
|
|
},
|
|
clip: function(a) {
|
|
a = r(parseInt(a[0]));
|
|
g.clip(a);
|
|
},
|
|
clipboard: function(a) {
|
|
var b = parseInt(a[0]);
|
|
a = a[1];
|
|
c.onclipboard
|
|
? ((b = t[b] = new Guacamole.InputStream(c, b)), c.onclipboard(b, a))
|
|
: c.sendAck(b, 'Clipboard unsupported', 256);
|
|
},
|
|
close: function(a) {
|
|
a = r(parseInt(a[0]));
|
|
g.close(a);
|
|
},
|
|
copy: function(a) {
|
|
var b = r(parseInt(a[0])),
|
|
h = parseInt(a[1]),
|
|
c = parseInt(a[2]),
|
|
d = parseInt(a[3]),
|
|
e = parseInt(a[4]),
|
|
q = parseInt(a[5]),
|
|
f = r(parseInt(a[6])),
|
|
u = parseInt(a[7]);
|
|
a = parseInt(a[8]);
|
|
g.setChannelMask(f, q);
|
|
g.copy(b, h, c, d, e, f, u, a);
|
|
},
|
|
cstroke: function(a) {
|
|
var b = parseInt(a[0]),
|
|
h = r(parseInt(a[1])),
|
|
c = m[parseInt(a[2])],
|
|
d = n[parseInt(a[3])],
|
|
e = parseInt(a[4]),
|
|
q = parseInt(a[5]),
|
|
f = parseInt(a[6]),
|
|
u = parseInt(a[7]);
|
|
a = parseInt(a[8]);
|
|
g.setChannelMask(h, b);
|
|
g.strokeColor(h, c, d, e, q, f, u, a);
|
|
},
|
|
cursor: function(a) {
|
|
var b = parseInt(a[0]),
|
|
h = parseInt(a[1]),
|
|
c = r(parseInt(a[2])),
|
|
d = parseInt(a[3]),
|
|
e = parseInt(a[4]),
|
|
q = parseInt(a[5]);
|
|
a = parseInt(a[6]);
|
|
g.setCursor(b, h, c, d, e, q, a);
|
|
},
|
|
curve: function(a) {
|
|
var b = r(parseInt(a[0])),
|
|
h = parseInt(a[1]),
|
|
c = parseInt(a[2]),
|
|
d = parseInt(a[3]),
|
|
e = parseInt(a[4]),
|
|
q = parseInt(a[5]);
|
|
a = parseInt(a[6]);
|
|
g.curveTo(b, h, c, d, e, q, a);
|
|
},
|
|
disconnect: function(a) {
|
|
c.disconnect();
|
|
},
|
|
dispose: function(a) {
|
|
a = parseInt(a[0]);
|
|
if (0 < a) {
|
|
var b = r(a);
|
|
g.dispose(b);
|
|
delete l[a];
|
|
} else 0 > a && delete l[a];
|
|
},
|
|
distort: function(a) {
|
|
var b = parseInt(a[0]),
|
|
c = parseFloat(a[1]),
|
|
h = parseFloat(a[2]),
|
|
d = parseFloat(a[3]),
|
|
e = parseFloat(a[4]),
|
|
q = parseFloat(a[5]);
|
|
a = parseFloat(a[6]);
|
|
0 <= b && ((b = r(b)), g.distort(b, c, h, d, e, q, a));
|
|
},
|
|
error: function(a) {
|
|
var b = a[0];
|
|
a = parseInt(a[1]);
|
|
if (c.onerror) c.onerror(new Guacamole.Status(a, b));
|
|
c.disconnect();
|
|
},
|
|
end: function(a) {
|
|
a = parseInt(a[0]);
|
|
var b = t[a];
|
|
if (b) {
|
|
if (b.onend) b.onend();
|
|
delete t[a];
|
|
}
|
|
},
|
|
file: function(a) {
|
|
var b = parseInt(a[0]),
|
|
h = a[1];
|
|
a = a[2];
|
|
c.onfile
|
|
? ((b = t[b] = new Guacamole.InputStream(c, b)), c.onfile(b, h, a))
|
|
: c.sendAck(b, 'File transfer unsupported', 256);
|
|
},
|
|
filesystem: function(a) {
|
|
var b = parseInt(a[0]);
|
|
a = a[1];
|
|
c.onfilesystem &&
|
|
((b = q[b] = new Guacamole.Object(c, b)), c.onfilesystem(b, a));
|
|
},
|
|
identity: function(a) {
|
|
a = r(parseInt(a[0]));
|
|
g.setTransform(a, 1, 0, 0, 1, 0, 0);
|
|
},
|
|
img: function(a) {
|
|
var b = parseInt(a[0]),
|
|
h = parseInt(a[1]),
|
|
d = r(parseInt(a[2])),
|
|
e = a[3],
|
|
q = parseInt(a[4]);
|
|
a = parseInt(a[5]);
|
|
b = t[b] = new Guacamole.InputStream(c, b);
|
|
g.setChannelMask(d, h);
|
|
g.drawStream(d, q, a, b, e);
|
|
},
|
|
jpeg: function(a) {
|
|
var b = parseInt(a[0]),
|
|
c = r(parseInt(a[1])),
|
|
d = parseInt(a[2]),
|
|
h = parseInt(a[3]);
|
|
a = a[4];
|
|
g.setChannelMask(c, b);
|
|
g.draw(c, d, h, 'data:image/jpeg;base64,' + a);
|
|
},
|
|
lfill: function(a) {
|
|
var b = parseInt(a[0]),
|
|
c = r(parseInt(a[1]));
|
|
a = r(parseInt(a[2]));
|
|
g.setChannelMask(c, b);
|
|
g.fillLayer(c, a);
|
|
},
|
|
line: function(a) {
|
|
var b = r(parseInt(a[0])),
|
|
c = parseInt(a[1]);
|
|
a = parseInt(a[2]);
|
|
g.lineTo(b, c, a);
|
|
},
|
|
lstroke: function(a) {
|
|
var b = parseInt(a[0]),
|
|
c = r(parseInt(a[1]));
|
|
a = r(parseInt(a[2]));
|
|
g.setChannelMask(c, b);
|
|
g.strokeLayer(c, a);
|
|
},
|
|
mouse: function(a) {
|
|
var b = parseInt(a[0]);
|
|
a = parseInt(a[1]);
|
|
g.showCursor(!0);
|
|
g.moveCursor(b, a);
|
|
},
|
|
move: function(a) {
|
|
var b = parseInt(a[0]),
|
|
c = parseInt(a[1]),
|
|
d = parseInt(a[2]),
|
|
e = parseInt(a[3]);
|
|
a = parseInt(a[4]);
|
|
0 < b && 0 <= c && ((b = r(b)), (c = r(c)), g.move(b, c, d, e, a));
|
|
},
|
|
name: function(a) {
|
|
if (c.onname) c.onname(a[0]);
|
|
},
|
|
nest: function(a) {
|
|
var c = parseInt(a[0]),
|
|
d = v[c];
|
|
null == d &&
|
|
((d = v[c] = new Guacamole.Parser()),
|
|
(d.oninstruction = b.oninstruction));
|
|
d.receive(a[1]);
|
|
},
|
|
pipe: function(a) {
|
|
var b = parseInt(a[0]),
|
|
d = a[1];
|
|
a = a[2];
|
|
c.onpipe
|
|
? ((b = t[b] = new Guacamole.InputStream(c, b)), c.onpipe(b, d, a))
|
|
: c.sendAck(b, 'Named pipes unsupported', 256);
|
|
},
|
|
png: function(a) {
|
|
var b = parseInt(a[0]),
|
|
c = r(parseInt(a[1])),
|
|
d = parseInt(a[2]),
|
|
e = parseInt(a[3]);
|
|
a = a[4];
|
|
g.setChannelMask(c, b);
|
|
g.draw(c, d, e, 'data:image/png;base64,' + a);
|
|
},
|
|
pop: function(a) {
|
|
a = r(parseInt(a[0]));
|
|
g.pop(a);
|
|
},
|
|
push: function(a) {
|
|
a = r(parseInt(a[0]));
|
|
g.push(a);
|
|
},
|
|
rect: function(a) {
|
|
var b = r(parseInt(a[0])),
|
|
c = parseInt(a[1]),
|
|
d = parseInt(a[2]),
|
|
e = parseInt(a[3]);
|
|
a = parseInt(a[4]);
|
|
g.rect(b, c, d, e, a);
|
|
},
|
|
required: function(a) {
|
|
if (c.onrequired) c.onrequired(a);
|
|
},
|
|
reset: function(a) {
|
|
a = r(parseInt(a[0]));
|
|
g.reset(a);
|
|
},
|
|
set: function(a) {
|
|
var b = r(parseInt(a[0])),
|
|
c = a[2];
|
|
(a = y[a[1]]) && a(b, c);
|
|
},
|
|
shade: function(a) {
|
|
var b = parseInt(a[0]);
|
|
a = parseInt(a[1]);
|
|
0 <= b && ((b = r(b)), g.shade(b, a));
|
|
},
|
|
size: function(a) {
|
|
var b = parseInt(a[0]);
|
|
b = r(b);
|
|
var c = parseInt(a[1]);
|
|
a = parseInt(a[2]);
|
|
g.resize(b, c, a);
|
|
},
|
|
start: function(a) {
|
|
var b = r(parseInt(a[0])),
|
|
c = parseInt(a[1]);
|
|
a = parseInt(a[2]);
|
|
g.moveTo(b, c, a);
|
|
},
|
|
sync: function(d) {
|
|
var q = parseInt(d[0]);
|
|
g.flush(function() {
|
|
for (var a in p) {
|
|
var c = p[a];
|
|
c && c.sync();
|
|
}
|
|
q !== f && (b.sendMessage('sync', q), (f = q));
|
|
});
|
|
2 === e && a(3);
|
|
if (c.onsync) c.onsync(q);
|
|
},
|
|
transfer: function(a) {
|
|
var b = r(parseInt(a[0])),
|
|
c = parseInt(a[1]),
|
|
d = parseInt(a[2]),
|
|
e = parseInt(a[3]),
|
|
q = parseInt(a[4]),
|
|
f = parseInt(a[5]),
|
|
h = r(parseInt(a[6])),
|
|
u = parseInt(a[7]);
|
|
a = parseInt(a[8]);
|
|
3 === f
|
|
? g.put(b, c, d, e, q, h, u, a)
|
|
: 5 !== f &&
|
|
g.transfer(
|
|
b,
|
|
c,
|
|
d,
|
|
e,
|
|
q,
|
|
h,
|
|
u,
|
|
a,
|
|
Guacamole.Client.DefaultTransferFunction[f],
|
|
);
|
|
},
|
|
transform: function(a) {
|
|
var b = r(parseInt(a[0])),
|
|
c = parseFloat(a[1]),
|
|
d = parseFloat(a[2]),
|
|
e = parseFloat(a[3]),
|
|
q = parseFloat(a[4]),
|
|
f = parseFloat(a[5]);
|
|
a = parseFloat(a[6]);
|
|
g.transform(b, c, d, e, q, f, a);
|
|
},
|
|
undefine: function(a) {
|
|
a = parseInt(a[0]);
|
|
if ((a = q[a]) && a.onundefine) a.onundefine();
|
|
},
|
|
video: function(a) {
|
|
var b = parseInt(a[0]),
|
|
d = r(parseInt(a[1]));
|
|
a = a[2];
|
|
var e = (t[b] = new Guacamole.InputStream(c, b)),
|
|
q = null;
|
|
c.onvideo && (q = c.onvideo(e, d, a));
|
|
q || (q = Guacamole.VideoPlayer.getInstance(e, d, a));
|
|
q ? c.sendAck(b, 'OK', 0) : c.sendAck(b, 'BAD TYPE', 783);
|
|
},
|
|
};
|
|
b.oninstruction = function(a, b) {
|
|
(a = z[a]) && a(b);
|
|
};
|
|
this.disconnect = function() {
|
|
5 != e &&
|
|
4 != e &&
|
|
(a(4),
|
|
k && window.clearInterval(k),
|
|
b.sendMessage('disconnect'),
|
|
b.disconnect(),
|
|
a(5));
|
|
};
|
|
this.connect = function(c) {
|
|
a(1);
|
|
try {
|
|
b.connect(c);
|
|
} catch (x) {
|
|
throw (a(0), x);
|
|
}
|
|
k = window.setInterval(function() {
|
|
b.sendMessage('nop');
|
|
}, 5e3);
|
|
a(2);
|
|
};
|
|
};
|
|
Guacamole.Client.DefaultTransferFunction = {
|
|
0: function(b, a) {
|
|
a.red = a.green = a.blue = 0;
|
|
},
|
|
15: function(b, a) {
|
|
a.red = a.green = a.blue = 255;
|
|
},
|
|
3: function(b, a) {
|
|
a.red = b.red;
|
|
a.green = b.green;
|
|
a.blue = b.blue;
|
|
a.alpha = b.alpha;
|
|
},
|
|
5: function(b, a) {},
|
|
12: function(b, a) {
|
|
a.red = 255 & ~b.red;
|
|
a.green = 255 & ~b.green;
|
|
a.blue = 255 & ~b.blue;
|
|
a.alpha = b.alpha;
|
|
},
|
|
10: function(b, a) {
|
|
a.red = 255 & ~a.red;
|
|
a.green = 255 & ~a.green;
|
|
a.blue = 255 & ~a.blue;
|
|
},
|
|
1: function(b, a) {
|
|
a.red &= b.red;
|
|
a.green &= b.green;
|
|
a.blue &= b.blue;
|
|
},
|
|
14: function(b, a) {
|
|
a.red = 255 & ~(b.red & a.red);
|
|
a.green = 255 & ~(b.green & a.green);
|
|
a.blue = 255 & ~(b.blue & a.blue);
|
|
},
|
|
7: function(b, a) {
|
|
a.red |= b.red;
|
|
a.green |= b.green;
|
|
a.blue |= b.blue;
|
|
},
|
|
8: function(b, a) {
|
|
a.red = 255 & ~(b.red | a.red);
|
|
a.green = 255 & ~(b.green | a.green);
|
|
a.blue = 255 & ~(b.blue | a.blue);
|
|
},
|
|
6: function(b, a) {
|
|
a.red ^= b.red;
|
|
a.green ^= b.green;
|
|
a.blue ^= b.blue;
|
|
},
|
|
9: function(b, a) {
|
|
a.red = 255 & ~(b.red ^ a.red);
|
|
a.green = 255 & ~(b.green ^ a.green);
|
|
a.blue = 255 & ~(b.blue ^ a.blue);
|
|
},
|
|
4: function(b, a) {
|
|
a.red &= 255 & ~b.red;
|
|
a.green &= 255 & ~b.green;
|
|
a.blue &= 255 & ~b.blue;
|
|
},
|
|
13: function(b, a) {
|
|
a.red = 255 & (~b.red | a.red);
|
|
a.green = 255 & (~b.green | a.green);
|
|
a.blue = 255 & (~b.blue | a.blue);
|
|
},
|
|
2: function(b, a) {
|
|
a.red = 255 & b.red & ~a.red;
|
|
a.green = 255 & b.green & ~a.green;
|
|
a.blue = 255 & b.blue & ~a.blue;
|
|
},
|
|
11: function(b, a) {
|
|
a.red = 255 & (b.red | ~a.red);
|
|
a.green = 255 & (b.green | ~a.green);
|
|
a.blue = 255 & (b.blue | ~a.blue);
|
|
},
|
|
};
|
|
Guacamole = Guacamole || {};
|
|
Guacamole.DataURIReader = function(b, a) {
|
|
var d = this,
|
|
c = 'data:' + a + ';base64,';
|
|
b.onblob = function(a) {
|
|
c += a;
|
|
};
|
|
b.onend = function() {
|
|
if (d.onend) d.onend();
|
|
};
|
|
this.getURI = function() {
|
|
return c;
|
|
};
|
|
this.onend = null;
|
|
};
|
|
Guacamole = Guacamole || {};
|
|
Guacamole.Display = function() {
|
|
function b() {
|
|
for (var a = 0; a < t.length; ) {
|
|
var b = t[a];
|
|
if (!b.isReady()) break;
|
|
b.flush();
|
|
a++;
|
|
}
|
|
t.splice(0, a);
|
|
}
|
|
function a(a, b) {
|
|
this.isReady = function() {
|
|
for (var a = 0; a < b.length; a++) if (b[a].blocked) return !1;
|
|
return !0;
|
|
};
|
|
this.flush = function() {
|
|
for (var c = 0; c < b.length; c++) b[c].execute();
|
|
a && a();
|
|
};
|
|
}
|
|
function d(a, c) {
|
|
var d = this;
|
|
this.blocked = c;
|
|
this.unblock = function() {
|
|
d.blocked && ((d.blocked = !1), b());
|
|
};
|
|
this.execute = function() {
|
|
a && a();
|
|
};
|
|
}
|
|
function c(a, b) {
|
|
a = new d(a, b);
|
|
v.push(a);
|
|
return a;
|
|
}
|
|
var e = this,
|
|
f = 0,
|
|
k = 0,
|
|
m = 1,
|
|
n = document.createElement('div');
|
|
n.style.position = 'relative';
|
|
n.style.width = f + 'px';
|
|
n.style.height = k + 'px';
|
|
n.style.transformOrigin = n.style.webkitTransformOrigin = n.style.MozTransformOrigin = n.style.OTransformOrigin = n.style.msTransformOrigin =
|
|
'0 0';
|
|
var g = new Guacamole.Display.VisibleLayer(f, k),
|
|
l = new Guacamole.Display.VisibleLayer(0, 0);
|
|
l.setChannelMask(Guacamole.Layer.SRC);
|
|
n.appendChild(g.getElement());
|
|
n.appendChild(l.getElement());
|
|
var p = document.createElement('div');
|
|
p.style.position = 'relative';
|
|
p.style.width = f * m + 'px';
|
|
p.style.height = k * m + 'px';
|
|
p.appendChild(n);
|
|
this.cursorY = this.cursorX = this.cursorHotspotY = this.cursorHotspotX = 0;
|
|
this.oncursor = this.onresize = null;
|
|
var v = [],
|
|
t = [];
|
|
this.getElement = function() {
|
|
return p;
|
|
};
|
|
this.getWidth = function() {
|
|
return f;
|
|
};
|
|
this.getHeight = function() {
|
|
return k;
|
|
};
|
|
this.getDefaultLayer = function() {
|
|
return g;
|
|
};
|
|
this.getCursorLayer = function() {
|
|
return l;
|
|
};
|
|
this.createLayer = function() {
|
|
var a = new Guacamole.Display.VisibleLayer(f, k);
|
|
a.move(g, 0, 0, 0);
|
|
return a;
|
|
};
|
|
this.createBuffer = function() {
|
|
var a = new Guacamole.Layer(0, 0);
|
|
a.autosize = 1;
|
|
return a;
|
|
};
|
|
this.flush = function(c) {
|
|
t.push(new a(c, v));
|
|
v = [];
|
|
b();
|
|
};
|
|
this.setCursor = function(a, b, d, f, p, g, h) {
|
|
c(function() {
|
|
e.cursorHotspotX = a;
|
|
e.cursorHotspotY = b;
|
|
l.resize(g, h);
|
|
l.copy(d, f, p, g, h, 0, 0);
|
|
e.moveCursor(e.cursorX, e.cursorY);
|
|
if (e.oncursor) e.oncursor(l.toCanvas(), a, b);
|
|
});
|
|
};
|
|
this.showCursor = function(a) {
|
|
var b = l.getElement(),
|
|
c = b.parentNode;
|
|
!1 === a ? c && c.removeChild(b) : c !== n && n.appendChild(b);
|
|
};
|
|
this.moveCursor = function(a, b) {
|
|
l.translate(a - e.cursorHotspotX, b - e.cursorHotspotY);
|
|
e.cursorX = a;
|
|
e.cursorY = b;
|
|
};
|
|
this.resize = function(a, b, d) {
|
|
c(function() {
|
|
a.resize(b, d);
|
|
if (
|
|
a === g &&
|
|
((f = b),
|
|
(k = d),
|
|
(n.style.width = f + 'px'),
|
|
(n.style.height = k + 'px'),
|
|
(p.style.width = f * m + 'px'),
|
|
(p.style.height = k * m + 'px'),
|
|
e.onresize)
|
|
)
|
|
e.onresize(b, d);
|
|
});
|
|
};
|
|
this.drawImage = function(a, b, d, e) {
|
|
c(function() {
|
|
a.drawImage(b, d, e);
|
|
});
|
|
};
|
|
this.drawBlob = function(a, b, d, e) {
|
|
if (window.createImageBitmap) {
|
|
var f;
|
|
var q = c(function() {
|
|
a.drawImage(b, d, f);
|
|
}, !0);
|
|
window.createImageBitmap(e).then(function(a) {
|
|
f = a;
|
|
q.unblock();
|
|
});
|
|
} else {
|
|
var p = URL.createObjectURL(e);
|
|
q = c(function() {
|
|
u.width && u.height && a.drawImage(b, d, u);
|
|
URL.revokeObjectURL(p);
|
|
}, !0);
|
|
var u = new Image();
|
|
u.onload = q.unblock;
|
|
u.onerror = q.unblock;
|
|
u.src = p;
|
|
}
|
|
};
|
|
this.drawStream = function(a, b, c, d, f) {
|
|
if (window.createImageBitmap) {
|
|
var q = new Guacamole.BlobReader(d, f);
|
|
q.onend = function() {
|
|
e.drawBlob(a, b, c, q.getBlob());
|
|
};
|
|
} else
|
|
(q = new Guacamole.DataURIReader(d, f)),
|
|
(q.onend = function() {
|
|
e.draw(a, b, c, q.getURI());
|
|
});
|
|
};
|
|
this.draw = function(a, b, d, e) {
|
|
var f = c(function() {
|
|
q.width && q.height && a.drawImage(b, d, q);
|
|
}, !0),
|
|
q = new Image();
|
|
q.onload = f.unblock;
|
|
q.onerror = f.unblock;
|
|
q.src = e;
|
|
};
|
|
this.play = function(a, b, d, e) {
|
|
var f = document.createElement('video');
|
|
f.type = b;
|
|
f.src = e;
|
|
f.addEventListener(
|
|
'play',
|
|
function() {
|
|
function b() {
|
|
a.drawImage(0, 0, f);
|
|
f.ended || window.setTimeout(b, 20);
|
|
}
|
|
b();
|
|
},
|
|
!1,
|
|
);
|
|
c(f.play);
|
|
};
|
|
this.transfer = function(a, b, d, e, f, p, h, g, l) {
|
|
c(function() {
|
|
p.transfer(a, b, d, e, f, h, g, l);
|
|
});
|
|
};
|
|
this.put = function(a, b, d, e, f, p, h, g) {
|
|
c(function() {
|
|
p.put(a, b, d, e, f, h, g);
|
|
});
|
|
};
|
|
this.copy = function(a, b, d, e, f, p, h, g) {
|
|
c(function() {
|
|
p.copy(a, b, d, e, f, h, g);
|
|
});
|
|
};
|
|
this.moveTo = function(a, b, d) {
|
|
c(function() {
|
|
a.moveTo(b, d);
|
|
});
|
|
};
|
|
this.lineTo = function(a, b, d) {
|
|
c(function() {
|
|
a.lineTo(b, d);
|
|
});
|
|
};
|
|
this.arc = function(a, b, d, e, f, p, g) {
|
|
c(function() {
|
|
a.arc(b, d, e, f, p, g);
|
|
});
|
|
};
|
|
this.curveTo = function(a, b, d, e, f, p, g) {
|
|
c(function() {
|
|
a.curveTo(b, d, e, f, p, g);
|
|
});
|
|
};
|
|
this.close = function(a) {
|
|
c(function() {
|
|
a.close();
|
|
});
|
|
};
|
|
this.rect = function(a, b, d, e, f) {
|
|
c(function() {
|
|
a.rect(b, d, e, f);
|
|
});
|
|
};
|
|
this.clip = function(a) {
|
|
c(function() {
|
|
a.clip();
|
|
});
|
|
};
|
|
this.strokeColor = function(a, b, d, e, f, p, g, l) {
|
|
c(function() {
|
|
a.strokeColor(b, d, e, f, p, g, l);
|
|
});
|
|
};
|
|
this.fillColor = function(a, b, d, e, f) {
|
|
c(function() {
|
|
a.fillColor(b, d, e, f);
|
|
});
|
|
};
|
|
this.strokeLayer = function(a, b, d, e, f) {
|
|
c(function() {
|
|
a.strokeLayer(b, d, e, f);
|
|
});
|
|
};
|
|
this.fillLayer = function(a, b) {
|
|
c(function() {
|
|
a.fillLayer(b);
|
|
});
|
|
};
|
|
this.push = function(a) {
|
|
c(function() {
|
|
a.push();
|
|
});
|
|
};
|
|
this.pop = function(a) {
|
|
c(function() {
|
|
a.pop();
|
|
});
|
|
};
|
|
this.reset = function(a) {
|
|
c(function() {
|
|
a.reset();
|
|
});
|
|
};
|
|
this.setTransform = function(a, b, d, e, f, p, g) {
|
|
c(function() {
|
|
a.setTransform(b, d, e, f, p, g);
|
|
});
|
|
};
|
|
this.transform = function(a, b, d, e, f, p, g) {
|
|
c(function() {
|
|
a.transform(b, d, e, f, p, g);
|
|
});
|
|
};
|
|
this.setChannelMask = function(a, b) {
|
|
c(function() {
|
|
a.setChannelMask(b);
|
|
});
|
|
};
|
|
this.setMiterLimit = function(a, b) {
|
|
c(function() {
|
|
a.setMiterLimit(b);
|
|
});
|
|
};
|
|
this.dispose = function(a) {
|
|
c(function() {
|
|
a.dispose();
|
|
});
|
|
};
|
|
this.distort = function(a, b, d, e, f, p, g) {
|
|
c(function() {
|
|
a.distort(b, d, e, f, p, g);
|
|
});
|
|
};
|
|
this.move = function(a, b, d, e, f) {
|
|
c(function() {
|
|
a.move(b, d, e, f);
|
|
});
|
|
};
|
|
this.shade = function(a, b) {
|
|
c(function() {
|
|
a.shade(b);
|
|
});
|
|
};
|
|
this.scale = function(a) {
|
|
n.style.transform = n.style.WebkitTransform = n.style.MozTransform = n.style.OTransform = n.style.msTransform =
|
|
'scale(' + a + ',' + a + ')';
|
|
m = a;
|
|
p.style.width = f * m + 'px';
|
|
p.style.height = k * m + 'px';
|
|
};
|
|
this.getScale = function() {
|
|
return m;
|
|
};
|
|
this.flatten = function() {
|
|
function a(a) {
|
|
var b = [],
|
|
c;
|
|
for (c in a.children) b.push(a.children[c]);
|
|
b.sort(function(a, b) {
|
|
var c = a.z - b.z;
|
|
if (0 !== c) return c;
|
|
a = a.getElement();
|
|
b = b.getElement().compareDocumentPosition(a);
|
|
return b & Node.DOCUMENT_POSITION_PRECEDING
|
|
? -1
|
|
: b & Node.DOCUMENT_POSITION_FOLLOWING
|
|
? 1
|
|
: 0;
|
|
});
|
|
return b;
|
|
}
|
|
function b(c, e, f) {
|
|
if (0 < c.width && 0 < c.height) {
|
|
var p = d.globalAlpha;
|
|
d.globalAlpha *= c.alpha / 255;
|
|
d.drawImage(c.getCanvas(), e, f);
|
|
c = a(c);
|
|
for (var g = 0; g < c.length; g++) {
|
|
var q = c[g];
|
|
b(q, e + q.x, f + q.y);
|
|
}
|
|
d.globalAlpha = p;
|
|
}
|
|
}
|
|
var c = document.createElement('canvas');
|
|
c.width = g.width;
|
|
c.height = g.height;
|
|
var d = c.getContext('2d');
|
|
b(g, 0, 0);
|
|
return c;
|
|
};
|
|
};
|
|
Guacamole.Display.VisibleLayer = function(b, a) {
|
|
Guacamole.Layer.apply(this, [b, a]);
|
|
var d = this;
|
|
this.__unique_id = Guacamole.Display.VisibleLayer.__next_id++;
|
|
this.alpha = 255;
|
|
this.z = this.y = this.x = 0;
|
|
this.matrix = [1, 0, 0, 1, 0, 0];
|
|
this.parent = null;
|
|
this.children = {};
|
|
var c = d.getCanvas();
|
|
c.style.position = 'absolute';
|
|
c.style.left = '0px';
|
|
c.style.top = '0px';
|
|
var e = document.createElement('div');
|
|
e.appendChild(c);
|
|
e.style.width = b + 'px';
|
|
e.style.height = a + 'px';
|
|
e.style.position = 'absolute';
|
|
e.style.left = '0px';
|
|
e.style.top = '0px';
|
|
e.style.overflow = 'hidden';
|
|
var f = this.resize;
|
|
this.resize = function(a, b) {
|
|
e.style.width = a + 'px';
|
|
e.style.height = b + 'px';
|
|
f(a, b);
|
|
};
|
|
this.getElement = function() {
|
|
return e;
|
|
};
|
|
var k = 'translate(0px, 0px)',
|
|
m = 'matrix(1, 0, 0, 1, 0, 0)';
|
|
this.translate = function(a, b) {
|
|
d.x = a;
|
|
d.y = b;
|
|
k = 'translate(' + a + 'px,' + b + 'px)';
|
|
e.style.transform = e.style.WebkitTransform = e.style.MozTransform = e.style.OTransform = e.style.msTransform =
|
|
k + ' ' + m;
|
|
};
|
|
this.move = function(a, b, c, f) {
|
|
d.parent !== a &&
|
|
(d.parent && delete d.parent.children[d.__unique_id],
|
|
(d.parent = a),
|
|
(a.children[d.__unique_id] = d),
|
|
a.getElement().appendChild(e));
|
|
d.translate(b, c);
|
|
d.z = f;
|
|
e.style.zIndex = f;
|
|
};
|
|
this.shade = function(a) {
|
|
d.alpha = a;
|
|
e.style.opacity = a / 255;
|
|
};
|
|
this.dispose = function() {
|
|
d.parent && (delete d.parent.children[d.__unique_id], (d.parent = null));
|
|
e.parentNode && e.parentNode.removeChild(e);
|
|
};
|
|
this.distort = function(a, b, c, f, v, t) {
|
|
d.matrix = [a, b, c, f, v, t];
|
|
m = 'matrix(' + a + ',' + b + ',' + c + ',' + f + ',' + v + ',' + t + ')';
|
|
e.style.transform = e.style.WebkitTransform = e.style.MozTransform = e.style.OTransform = e.style.msTransform =
|
|
k + ' ' + m;
|
|
};
|
|
};
|
|
Guacamole.Display.VisibleLayer.__next_id = 0;
|
|
Guacamole = Guacamole || {};
|
|
Guacamole.Event = function(b) {
|
|
this.type = b;
|
|
this.timestamp = new Date().getTime();
|
|
this.getAge = function() {
|
|
return new Date().getTime() - this.timestamp;
|
|
};
|
|
this.invokeLegacyHandler = function(a) {};
|
|
};
|
|
Guacamole.Event.DOMEvent = function(b, a) {
|
|
Guacamole.Event.call(this, b);
|
|
a = a || [];
|
|
Array.isArray(a) || (a = [a]);
|
|
this.preventDefault = function() {
|
|
a.forEach(function(a) {
|
|
a.preventDefault && a.preventDefault();
|
|
a.returnValue = !1;
|
|
});
|
|
};
|
|
this.stopPropagation = function() {
|
|
a.forEach(function(a) {
|
|
a.stopPropagation();
|
|
});
|
|
};
|
|
};
|
|
Guacamole.Event.DOMEvent.cancelEvent = function(b) {
|
|
b.stopPropagation();
|
|
b.preventDefault && b.preventDefault();
|
|
b.returnValue = !1;
|
|
};
|
|
Guacamole.Event.Target = function() {
|
|
var b = {};
|
|
this.on = function(a, d) {
|
|
var c = b[a];
|
|
c || (b[a] = c = []);
|
|
c.push(d);
|
|
};
|
|
this.onEach = function(a, b) {
|
|
a.forEach(function(a) {
|
|
this.on(a, b);
|
|
}, this);
|
|
};
|
|
this.dispatch = function(a) {
|
|
a.invokeLegacyHandler(this);
|
|
var d = b[a.type];
|
|
if (d) for (var c = 0; c < d.length; c++) d[c](a, this);
|
|
};
|
|
this.off = function(a, d) {
|
|
a = b[a];
|
|
if (!a) return !1;
|
|
for (var c = 0; c < a.length; c++)
|
|
if (a[c] === d) return a.splice(c, 1), !0;
|
|
return !1;
|
|
};
|
|
this.offEach = function(a, b) {
|
|
var c = !1;
|
|
a.forEach(function(a) {
|
|
c |= this.off(a, b);
|
|
}, this);
|
|
return c;
|
|
};
|
|
};
|
|
Guacamole = Guacamole || {};
|
|
Guacamole.InputSink = function() {
|
|
var b = this,
|
|
a = document.createElement('textarea');
|
|
a.style.position = 'fixed';
|
|
a.style.outline = 'none';
|
|
a.style.border = 'none';
|
|
a.style.margin = '0';
|
|
a.style.padding = '0';
|
|
a.style.height = '0';
|
|
a.style.width = '0';
|
|
a.style.left = '0';
|
|
a.style.bottom = '0';
|
|
a.style.resize = 'none';
|
|
a.style.background = 'transparent';
|
|
a.style.color = 'transparent';
|
|
a.addEventListener(
|
|
'keypress',
|
|
function(b) {
|
|
a.value = '';
|
|
},
|
|
!1,
|
|
);
|
|
a.addEventListener(
|
|
'compositionend',
|
|
function(b) {
|
|
b.data && (a.value = '');
|
|
},
|
|
!1,
|
|
);
|
|
a.addEventListener(
|
|
'input',
|
|
function(b) {
|
|
b.data && !b.isComposing && (a.value = '');
|
|
},
|
|
!1,
|
|
);
|
|
a.addEventListener(
|
|
'focus',
|
|
function() {
|
|
window.setTimeout(function() {
|
|
a.click();
|
|
a.select();
|
|
}, 0);
|
|
},
|
|
!0,
|
|
);
|
|
this.focus = function() {
|
|
window.setTimeout(function() {
|
|
a.focus();
|
|
}, 0);
|
|
};
|
|
this.getElement = function() {
|
|
return a;
|
|
};
|
|
document.addEventListener(
|
|
'keydown',
|
|
function(a) {
|
|
if (
|
|
(a = document.activeElement) &&
|
|
a !== document.body &&
|
|
((a = a.getBoundingClientRect()),
|
|
0 < a.left + a.width && 0 < a.top + a.height)
|
|
)
|
|
return;
|
|
b.focus();
|
|
},
|
|
!0,
|
|
);
|
|
};
|
|
Guacamole = Guacamole || {};
|
|
Guacamole.InputStream = function(b, a) {
|
|
var d = this;
|
|
this.index = a;
|
|
this.onend = this.onblob = null;
|
|
this.sendAck = function(a, e) {
|
|
b.sendAck(d.index, a, e);
|
|
};
|
|
};
|
|
Guacamole = Guacamole || {};
|
|
Guacamole.IntegerPool = function() {
|
|
var b = this,
|
|
a = [];
|
|
this.next_int = 0;
|
|
this.next = function() {
|
|
return 0 < a.length ? a.shift() : b.next_int++;
|
|
};
|
|
this.free = function(b) {
|
|
a.push(b);
|
|
};
|
|
};
|
|
Guacamole = Guacamole || {};
|
|
Guacamole.JSONReader = function(b) {
|
|
var a = this;
|
|
b = new Guacamole.StringReader(b);
|
|
var d = '';
|
|
this.getLength = function() {
|
|
return d.length;
|
|
};
|
|
this.getJSON = function() {
|
|
return JSON.parse(d);
|
|
};
|
|
b.ontext = function(b) {
|
|
d += b;
|
|
if (a.onprogress) a.onprogress(b.length);
|
|
};
|
|
b.onend = function() {
|
|
if (a.onend) a.onend();
|
|
};
|
|
this.onend = this.onprogress = null;
|
|
};
|
|
Guacamole = Guacamole || {};
|
|
Guacamole.Keyboard = function(b) {
|
|
function a(a, b, c) {
|
|
if (!a) return null;
|
|
var e = a.indexOf('U+');
|
|
if (0 <= e)
|
|
(a = a.substring(e + 2)), (a = String.fromCharCode(parseInt(a, 16)));
|
|
else if (1 !== a.length || 3 === b) return A(u[a], b);
|
|
!0 === c ? (a = a.toUpperCase()) : !1 === c && (a = a.toLowerCase());
|
|
c = a.charCodeAt(0);
|
|
return d(c);
|
|
}
|
|
function d(a) {
|
|
return 31 >= a || (127 <= a && 159 >= a)
|
|
? 65280 | a
|
|
: 0 <= a && 255 >= a
|
|
? a
|
|
: 256 <= a && 1114111 >= a
|
|
? 16777216 | a
|
|
: null;
|
|
}
|
|
function c() {
|
|
var a = F();
|
|
if (!a) return !1;
|
|
do {
|
|
var b = a;
|
|
a = F();
|
|
} while (null !== a);
|
|
a: {
|
|
for (var c in e.pressed)
|
|
if (!r[c]) {
|
|
a = !1;
|
|
break a;
|
|
}
|
|
a = !0;
|
|
}
|
|
a && e.reset();
|
|
return b.defaultPrevented;
|
|
}
|
|
var e = this,
|
|
f = '_GUAC_KEYBOARD_HANDLED_BY_' + Guacamole.Keyboard._nextID++;
|
|
this.onkeyup = this.onkeydown = null;
|
|
var k = !1,
|
|
m = !1,
|
|
n = !1;
|
|
navigator &&
|
|
navigator.platform &&
|
|
(navigator.platform.match(/ipad|iphone|ipod/i)
|
|
? (k = !0)
|
|
: navigator.platform.match(/^mac/i) && (n = m = !0));
|
|
var g = function(a) {
|
|
var b = this;
|
|
this.keyCode = a ? a.which || a.keyCode : 0;
|
|
this.keyIdentifier = a && a.keyIdentifier;
|
|
this.key = a && a.key;
|
|
var c = a
|
|
? 'location' in a
|
|
? a.location
|
|
: 'keyLocation' in a
|
|
? a.keyLocation
|
|
: 0
|
|
: 0;
|
|
this.location = c;
|
|
this.modifiers = a
|
|
? Guacamole.Keyboard.ModifierState.fromKeyboardEvent(a)
|
|
: new Guacamole.Keyboard.ModifierState();
|
|
this.timestamp = new Date().getTime();
|
|
this.defaultPrevented = !1;
|
|
this.keysym = null;
|
|
this.reliable = !1;
|
|
this.getAge = function() {
|
|
return new Date().getTime() - b.timestamp;
|
|
};
|
|
},
|
|
l = function(b) {
|
|
g.call(this, b);
|
|
this.keysym =
|
|
a(this.key, this.location) || A(q[this.keyCode], this.location);
|
|
this.keyupReliable = !k;
|
|
if ((b = this.keysym))
|
|
(b = this.keysym),
|
|
(b = !((0 <= b && 255 >= b) || 16777216 === (b & 4294901760)));
|
|
b && (this.reliable = !0);
|
|
if ((b = !this.keysym)) {
|
|
b = this.keyCode;
|
|
var c = this.keyIdentifier;
|
|
if (c) {
|
|
var d = c.indexOf('U+');
|
|
-1 === d
|
|
? (b = !0)
|
|
: ((c = parseInt(c.substring(d + 2), 16)),
|
|
(b =
|
|
b !== c || (65 <= b && 90 >= b) || (48 <= b && 57 >= b)
|
|
? !0
|
|
: !1));
|
|
} else b = !1;
|
|
}
|
|
b &&
|
|
(this.keysym = a(
|
|
this.keyIdentifier,
|
|
this.location,
|
|
this.modifiers.shift,
|
|
));
|
|
this.modifiers.meta && 65511 !== this.keysym && 65512 !== this.keysym
|
|
? (this.keyupReliable = !1)
|
|
: 65509 === this.keysym && n && (this.keyupReliable = !1);
|
|
b = !this.modifiers.ctrl && !m;
|
|
if (
|
|
(!this.modifiers.alt && this.modifiers.ctrl) ||
|
|
(b && this.modifiers.alt) ||
|
|
this.modifiers.meta ||
|
|
this.modifiers.hyper
|
|
)
|
|
this.reliable = !0;
|
|
z[this.keyCode] = this.keysym;
|
|
};
|
|
l.prototype = new g();
|
|
var p = function(a) {
|
|
g.call(this, a);
|
|
this.keysym = d(this.keyCode);
|
|
this.reliable = !0;
|
|
};
|
|
p.prototype = new g();
|
|
var v = function(b) {
|
|
g.call(this, b);
|
|
this.keysym =
|
|
A(q[this.keyCode], this.location) || a(this.key, this.location);
|
|
e.pressed[this.keysym] || (this.keysym = z[this.keyCode] || this.keysym);
|
|
this.reliable = !0;
|
|
};
|
|
v.prototype = new g();
|
|
var t = [],
|
|
q = {
|
|
8: [65288],
|
|
9: [65289],
|
|
12: [65291, 65291, 65291, 65461],
|
|
13: [65293],
|
|
16: [65505, 65505, 65506],
|
|
17: [65507, 65507, 65508],
|
|
18: [65513, 65513, 65027],
|
|
19: [65299],
|
|
20: [65509],
|
|
27: [65307],
|
|
32: [32],
|
|
33: [65365, 65365, 65365, 65465],
|
|
34: [65366, 65366, 65366, 65459],
|
|
35: [65367, 65367, 65367, 65457],
|
|
36: [65360, 65360, 65360, 65463],
|
|
37: [65361, 65361, 65361, 65460],
|
|
38: [65362, 65362, 65362, 65464],
|
|
39: [65363, 65363, 65363, 65462],
|
|
40: [65364, 65364, 65364, 65458],
|
|
45: [65379, 65379, 65379, 65456],
|
|
46: [65535, 65535, 65535, 65454],
|
|
91: [65511],
|
|
92: [65512],
|
|
93: [65383],
|
|
96: [65456],
|
|
97: [65457],
|
|
98: [65458],
|
|
99: [65459],
|
|
100: [65460],
|
|
101: [65461],
|
|
102: [65462],
|
|
103: [65463],
|
|
104: [65464],
|
|
105: [65465],
|
|
106: [65450],
|
|
107: [65451],
|
|
109: [65453],
|
|
110: [65454],
|
|
111: [65455],
|
|
112: [65470],
|
|
113: [65471],
|
|
114: [65472],
|
|
115: [65473],
|
|
116: [65474],
|
|
117: [65475],
|
|
118: [65476],
|
|
119: [65477],
|
|
120: [65478],
|
|
121: [65479],
|
|
122: [65480],
|
|
123: [65481],
|
|
144: [65407],
|
|
145: [65300],
|
|
225: [65027],
|
|
},
|
|
u = {
|
|
Again: [65382],
|
|
AllCandidates: [65341],
|
|
Alphanumeric: [65328],
|
|
Alt: [65513, 65513, 65027],
|
|
Attn: [64782],
|
|
AltGraph: [65027],
|
|
ArrowDown: [65364],
|
|
ArrowLeft: [65361],
|
|
ArrowRight: [65363],
|
|
ArrowUp: [65362],
|
|
Backspace: [65288],
|
|
CapsLock: [65509],
|
|
Cancel: [65385],
|
|
Clear: [65291],
|
|
Convert: [65313],
|
|
Copy: [64789],
|
|
Crsel: [64796],
|
|
CrSel: [64796],
|
|
CodeInput: [65335],
|
|
Compose: [65312],
|
|
Control: [65507, 65507, 65508],
|
|
ContextMenu: [65383],
|
|
Delete: [65535],
|
|
Down: [65364],
|
|
End: [65367],
|
|
Enter: [65293],
|
|
EraseEof: [64774],
|
|
Escape: [65307],
|
|
Execute: [65378],
|
|
Exsel: [64797],
|
|
ExSel: [64797],
|
|
F1: [65470],
|
|
F2: [65471],
|
|
F3: [65472],
|
|
F4: [65473],
|
|
F5: [65474],
|
|
F6: [65475],
|
|
F7: [65476],
|
|
F8: [65477],
|
|
F9: [65478],
|
|
F10: [65479],
|
|
F11: [65480],
|
|
F12: [65481],
|
|
F13: [65482],
|
|
F14: [65483],
|
|
F15: [65484],
|
|
F16: [65485],
|
|
F17: [65486],
|
|
F18: [65487],
|
|
F19: [65488],
|
|
F20: [65489],
|
|
F21: [65490],
|
|
F22: [65491],
|
|
F23: [65492],
|
|
F24: [65493],
|
|
Find: [65384],
|
|
GroupFirst: [65036],
|
|
GroupLast: [65038],
|
|
GroupNext: [65032],
|
|
GroupPrevious: [65034],
|
|
FullWidth: null,
|
|
HalfWidth: null,
|
|
HangulMode: [65329],
|
|
Hankaku: [65321],
|
|
HanjaMode: [65332],
|
|
Help: [65386],
|
|
Hiragana: [65317],
|
|
HiraganaKatakana: [65319],
|
|
Home: [65360],
|
|
Hyper: [65517, 65517, 65518],
|
|
Insert: [65379],
|
|
JapaneseHiragana: [65317],
|
|
JapaneseKatakana: [65318],
|
|
JapaneseRomaji: [65316],
|
|
JunjaMode: [65336],
|
|
KanaMode: [65325],
|
|
KanjiMode: [65313],
|
|
Katakana: [65318],
|
|
Left: [65361],
|
|
Meta: [65511, 65511, 65512],
|
|
ModeChange: [65406],
|
|
NumLock: [65407],
|
|
PageDown: [65366],
|
|
PageUp: [65365],
|
|
Pause: [65299],
|
|
Play: [64790],
|
|
PreviousCandidate: [65342],
|
|
PrintScreen: [65377],
|
|
Redo: [65382],
|
|
Right: [65363],
|
|
RomanCharacters: null,
|
|
Scroll: [65300],
|
|
Select: [65376],
|
|
Separator: [65452],
|
|
Shift: [65505, 65505, 65506],
|
|
SingleCandidate: [65340],
|
|
Super: [65515, 65515, 65516],
|
|
Tab: [65289],
|
|
UIKeyInputDownArrow: [65364],
|
|
UIKeyInputEscape: [65307],
|
|
UIKeyInputLeftArrow: [65361],
|
|
UIKeyInputRightArrow: [65363],
|
|
UIKeyInputUpArrow: [65362],
|
|
Up: [65362],
|
|
Undo: [65381],
|
|
Win: [65511, 65511, 65512],
|
|
Zenkaku: [65320],
|
|
ZenkakuHankaku: [65322],
|
|
},
|
|
w = {
|
|
65027: !0,
|
|
65505: !0,
|
|
65506: !0,
|
|
65507: !0,
|
|
65508: !0,
|
|
65509: !0,
|
|
65511: !0,
|
|
65512: !0,
|
|
65513: !0,
|
|
65514: !0,
|
|
65515: !0,
|
|
65516: !0,
|
|
};
|
|
this.modifiers = new Guacamole.Keyboard.ModifierState();
|
|
this.pressed = {};
|
|
var r = {},
|
|
y = {},
|
|
z = {},
|
|
h = null,
|
|
x = null,
|
|
A = function(a, b) {
|
|
return a ? a[b] || a[0] : null;
|
|
};
|
|
this.press = function(a) {
|
|
if (null !== a) {
|
|
if (!e.pressed[a] && ((e.pressed[a] = !0), e.onkeydown)) {
|
|
var b = e.onkeydown(a);
|
|
y[a] = b;
|
|
window.clearTimeout(h);
|
|
window.clearInterval(x);
|
|
w[a] ||
|
|
(h = window.setTimeout(function() {
|
|
x = window.setInterval(function() {
|
|
e.onkeyup(a);
|
|
e.onkeydown(a);
|
|
}, 50);
|
|
}, 500));
|
|
return b;
|
|
}
|
|
return y[a] || !1;
|
|
}
|
|
};
|
|
this.release = function(a) {
|
|
if (
|
|
e.pressed[a] &&
|
|
(delete e.pressed[a],
|
|
delete r[a],
|
|
window.clearTimeout(h),
|
|
window.clearInterval(x),
|
|
null !== a && e.onkeyup)
|
|
)
|
|
e.onkeyup(a);
|
|
};
|
|
this.type = function(a) {
|
|
for (var b = 0; b < a.length; b++) {
|
|
var c = a.codePointAt ? a.codePointAt(b) : a.charCodeAt(b);
|
|
c = d(c);
|
|
e.press(c);
|
|
e.release(c);
|
|
}
|
|
};
|
|
this.reset = function() {
|
|
for (var a in e.pressed) e.release(parseInt(a));
|
|
t = [];
|
|
};
|
|
var B = function(a, b, c) {
|
|
var d = c.modifiers[a];
|
|
a = e.modifiers[a];
|
|
if (-1 === b.indexOf(c.keysym))
|
|
if (a && !1 === d) for (d = 0; d < b.length; d++) e.release(b[d]);
|
|
else if (!a && d) {
|
|
for (d = 0; d < b.length; d++) if (e.pressed[b[d]]) return;
|
|
b = b[0];
|
|
c.keysym && (r[b] = !0);
|
|
e.press(b);
|
|
}
|
|
},
|
|
C = function(a) {
|
|
B('alt', [65513, 65514, 65027], a);
|
|
B('shift', [65505, 65506], a);
|
|
B('ctrl', [65507, 65508], a);
|
|
B('meta', [65511, 65512], a);
|
|
B('hyper', [65515, 65516], a);
|
|
e.modifiers = a.modifiers;
|
|
},
|
|
F = function() {
|
|
var a = t[0];
|
|
if (!a) return null;
|
|
if (a instanceof l) {
|
|
var b = null,
|
|
c = [];
|
|
if (65511 === a.keysym || 65512 === a.keysym) {
|
|
if (1 === t.length) return null;
|
|
if (t[1].keysym !== a.keysym) {
|
|
if (!t[1].modifiers.meta) return t.shift();
|
|
} else if (t[1] instanceof l) return t.shift();
|
|
}
|
|
a.reliable
|
|
? ((b = a.keysym), (c = t.splice(0, 1)))
|
|
: t[1] instanceof p
|
|
? ((b = t[1].keysym), (c = t.splice(0, 2)))
|
|
: t[1] && ((b = a.keysym), (c = t.splice(0, 1)));
|
|
if (0 < c.length) {
|
|
C(a);
|
|
if (b) {
|
|
e.modifiers.ctrl &&
|
|
e.modifiers.alt &&
|
|
!((65 <= b && 90 >= b) || (97 <= b && 122 >= b)) &&
|
|
(255 >= b || 16777216 === (b & 4278190080)) &&
|
|
(e.release(65507),
|
|
e.release(65508),
|
|
e.release(65513),
|
|
e.release(65514));
|
|
var d = !e.press(b);
|
|
z[a.keyCode] = b;
|
|
a.keyupReliable || e.release(b);
|
|
for (b = 0; b < c.length; b++) c[b].defaultPrevented = d;
|
|
}
|
|
return a;
|
|
}
|
|
} else {
|
|
if (a instanceof v && !k) {
|
|
if ((b = a.keysym))
|
|
e.release(b), delete z[a.keyCode], (a.defaultPrevented = !0);
|
|
else return e.reset(), a;
|
|
C(a);
|
|
}
|
|
return t.shift();
|
|
}
|
|
return null;
|
|
},
|
|
E = function(a) {
|
|
return a[f] ? !1 : (a[f] = !0);
|
|
};
|
|
this.listenTo = function(a) {
|
|
a.addEventListener(
|
|
'keydown',
|
|
function(a) {
|
|
if (e.onkeydown && E(a)) {
|
|
var b = new l(a);
|
|
229 !== b.keyCode && (t.push(b), c() && a.preventDefault());
|
|
}
|
|
},
|
|
!0,
|
|
);
|
|
a.addEventListener(
|
|
'keypress',
|
|
function(a) {
|
|
(e.onkeydown || e.onkeyup) &&
|
|
E(a) &&
|
|
(t.push(new p(a)), c() && a.preventDefault());
|
|
},
|
|
!0,
|
|
);
|
|
a.addEventListener(
|
|
'keyup',
|
|
function(a) {
|
|
e.onkeyup && E(a) && (a.preventDefault(), t.push(new v(a)), c());
|
|
},
|
|
!0,
|
|
);
|
|
var b = function(b) {
|
|
(e.onkeydown || e.onkeyup) &&
|
|
E(b) &&
|
|
b.data &&
|
|
!b.isComposing &&
|
|
(a.removeEventListener('compositionend', d, !1), e.type(b.data));
|
|
},
|
|
d = function(c) {
|
|
(e.onkeydown || e.onkeyup) &&
|
|
E(c) &&
|
|
c.data &&
|
|
(a.removeEventListener('input', b, !1), e.type(c.data));
|
|
};
|
|
a.addEventListener('input', b, !1);
|
|
a.addEventListener('compositionend', d, !1);
|
|
};
|
|
b && e.listenTo(b);
|
|
};
|
|
Guacamole.Keyboard._nextID = 0;
|
|
Guacamole.Keyboard.ModifierState = function() {
|
|
this.hyper = this.meta = this.alt = this.ctrl = this.shift = !1;
|
|
};
|
|
Guacamole.Keyboard.ModifierState.fromKeyboardEvent = function(b) {
|
|
var a = new Guacamole.Keyboard.ModifierState();
|
|
a.shift = b.shiftKey;
|
|
a.ctrl = b.ctrlKey;
|
|
a.alt = b.altKey;
|
|
a.meta = b.metaKey;
|
|
b.getModifierState &&
|
|
(a.hyper =
|
|
b.getModifierState('OS') ||
|
|
b.getModifierState('Super') ||
|
|
b.getModifierState('Hyper') ||
|
|
b.getModifierState('Win'));
|
|
return a;
|
|
};
|
|
Guacamole = Guacamole || {};
|
|
Guacamole.Layer = function(b, a) {
|
|
function d(a, b, d, e) {
|
|
a = d + a;
|
|
b = e + b;
|
|
c.resize(a > c.width ? a : c.width, b > c.height ? b : c.height);
|
|
}
|
|
var c = this,
|
|
e = document.createElement('canvas'),
|
|
f = e.getContext('2d');
|
|
f.save();
|
|
var k = !0,
|
|
m = !0,
|
|
n = 0,
|
|
g = {
|
|
1: 'destination-in',
|
|
2: 'destination-out',
|
|
4: 'source-in',
|
|
6: 'source-atop',
|
|
8: 'source-out',
|
|
9: 'destination-atop',
|
|
10: 'xor',
|
|
11: 'destination-over',
|
|
12: 'copy',
|
|
14: 'source-over',
|
|
15: 'lighter',
|
|
},
|
|
l = function(a, b) {
|
|
a = a || 0;
|
|
b = b || 0;
|
|
var d = 64 * Math.ceil(a / 64),
|
|
p = 64 * Math.ceil(b / 64);
|
|
if (e.width !== d || e.height !== p) {
|
|
var g = null;
|
|
k ||
|
|
0 === e.width ||
|
|
0 === e.height ||
|
|
((g = document.createElement('canvas')),
|
|
(g.width = Math.min(c.width, a)),
|
|
(g.height = Math.min(c.height, b)),
|
|
g
|
|
.getContext('2d')
|
|
.drawImage(e, 0, 0, g.width, g.height, 0, 0, g.width, g.height));
|
|
var l = f.globalCompositeOperation;
|
|
e.width = d;
|
|
e.height = p;
|
|
g && f.drawImage(g, 0, 0, g.width, g.height, 0, 0, g.width, g.height);
|
|
f.globalCompositeOperation = l;
|
|
n = 0;
|
|
f.save();
|
|
} else c.reset();
|
|
c.width = a;
|
|
c.height = b;
|
|
};
|
|
this.autosize = !1;
|
|
this.width = b;
|
|
this.height = a;
|
|
this.getCanvas = function() {
|
|
return e;
|
|
};
|
|
this.toCanvas = function() {
|
|
var a = document.createElement('canvas');
|
|
a.width = c.width;
|
|
a.height = c.height;
|
|
a.getContext('2d').drawImage(c.getCanvas(), 0, 0);
|
|
return a;
|
|
};
|
|
this.resize = function(a, b) {
|
|
(a === c.width && b === c.height) || l(a, b);
|
|
};
|
|
this.drawImage = function(a, b, e) {
|
|
c.autosize && d(a, b, e.width, e.height);
|
|
f.drawImage(e, a, b);
|
|
k = !1;
|
|
};
|
|
this.transfer = function(a, b, e, g, l, n, m, y) {
|
|
var p = a.getCanvas();
|
|
if (
|
|
!(b >= p.width || e >= p.height) &&
|
|
(b + g > p.width && (g = p.width - b),
|
|
e + l > p.height && (l = p.height - e),
|
|
0 !== g && 0 !== l)
|
|
) {
|
|
c.autosize && d(n, m, g, l);
|
|
a = a
|
|
.getCanvas()
|
|
.getContext('2d')
|
|
.getImageData(b, e, g, l);
|
|
b = f.getImageData(n, m, g, l);
|
|
for (e = 0; e < g * l * 4; e += 4) {
|
|
p = new Guacamole.Layer.Pixel(
|
|
a.data[e],
|
|
a.data[e + 1],
|
|
a.data[e + 2],
|
|
a.data[e + 3],
|
|
);
|
|
var q = new Guacamole.Layer.Pixel(
|
|
b.data[e],
|
|
b.data[e + 1],
|
|
b.data[e + 2],
|
|
b.data[e + 3],
|
|
);
|
|
y(p, q);
|
|
b.data[e] = q.red;
|
|
b.data[e + 1] = q.green;
|
|
b.data[e + 2] = q.blue;
|
|
b.data[e + 3] = q.alpha;
|
|
}
|
|
f.putImageData(b, n, m);
|
|
k = !1;
|
|
}
|
|
};
|
|
this.put = function(a, b, e, g, l, n, m) {
|
|
var p = a.getCanvas();
|
|
b >= p.width ||
|
|
e >= p.height ||
|
|
(b + g > p.width && (g = p.width - b),
|
|
e + l > p.height && (l = p.height - e),
|
|
0 !== g &&
|
|
0 !== l &&
|
|
(c.autosize && d(n, m, g, l),
|
|
(a = a
|
|
.getCanvas()
|
|
.getContext('2d')
|
|
.getImageData(b, e, g, l)),
|
|
f.putImageData(a, n, m),
|
|
(k = !1)));
|
|
};
|
|
this.copy = function(a, b, e, g, l, n, m) {
|
|
a = a.getCanvas();
|
|
b >= a.width ||
|
|
e >= a.height ||
|
|
(b + g > a.width && (g = a.width - b),
|
|
e + l > a.height && (l = a.height - e),
|
|
0 !== g &&
|
|
0 !== l &&
|
|
(c.autosize && d(n, m, g, l),
|
|
f.drawImage(a, b, e, g, l, n, m, g, l),
|
|
(k = !1)));
|
|
};
|
|
this.moveTo = function(a, b) {
|
|
m && (f.beginPath(), (m = !1));
|
|
c.autosize && d(a, b, 0, 0);
|
|
f.moveTo(a, b);
|
|
};
|
|
this.lineTo = function(a, b) {
|
|
m && (f.beginPath(), (m = !1));
|
|
c.autosize && d(a, b, 0, 0);
|
|
f.lineTo(a, b);
|
|
};
|
|
this.arc = function(a, b, e, g, l, n) {
|
|
m && (f.beginPath(), (m = !1));
|
|
c.autosize && d(a, b, 0, 0);
|
|
f.arc(a, b, e, g, l, n);
|
|
};
|
|
this.curveTo = function(a, b, e, g, l, n) {
|
|
m && (f.beginPath(), (m = !1));
|
|
c.autosize && d(l, n, 0, 0);
|
|
f.bezierCurveTo(a, b, e, g, l, n);
|
|
};
|
|
this.close = function() {
|
|
f.closePath();
|
|
m = !0;
|
|
};
|
|
this.rect = function(a, b, e, g) {
|
|
m && (f.beginPath(), (m = !1));
|
|
c.autosize && d(a, b, e, g);
|
|
f.rect(a, b, e, g);
|
|
};
|
|
this.clip = function() {
|
|
f.clip();
|
|
m = !0;
|
|
};
|
|
this.strokeColor = function(a, b, c, d, e, g, l) {
|
|
f.lineCap = a;
|
|
f.lineJoin = b;
|
|
f.lineWidth = c;
|
|
f.strokeStyle = 'rgba(' + d + ',' + e + ',' + g + ',' + l / 255 + ')';
|
|
f.stroke();
|
|
k = !1;
|
|
m = !0;
|
|
};
|
|
this.fillColor = function(a, b, c, d) {
|
|
f.fillStyle = 'rgba(' + a + ',' + b + ',' + c + ',' + d / 255 + ')';
|
|
f.fill();
|
|
k = !1;
|
|
m = !0;
|
|
};
|
|
this.strokeLayer = function(a, b, c, d) {
|
|
f.lineCap = a;
|
|
f.lineJoin = b;
|
|
f.lineWidth = c;
|
|
f.strokeStyle = f.createPattern(d.getCanvas(), 'repeat');
|
|
f.stroke();
|
|
k = !1;
|
|
m = !0;
|
|
};
|
|
this.fillLayer = function(a) {
|
|
f.fillStyle = f.createPattern(a.getCanvas(), 'repeat');
|
|
f.fill();
|
|
k = !1;
|
|
m = !0;
|
|
};
|
|
this.push = function() {
|
|
f.save();
|
|
n++;
|
|
};
|
|
this.pop = function() {
|
|
0 < n && (f.restore(), n--);
|
|
};
|
|
this.reset = function() {
|
|
for (; 0 < n; ) f.restore(), n--;
|
|
f.restore();
|
|
f.save();
|
|
f.beginPath();
|
|
m = !1;
|
|
};
|
|
this.setTransform = function(a, b, c, d, e, g) {
|
|
f.setTransform(a, b, c, d, e, g);
|
|
};
|
|
this.transform = function(a, b, c, d, e, g) {
|
|
f.transform(a, b, c, d, e, g);
|
|
};
|
|
this.setChannelMask = function(a) {
|
|
f.globalCompositeOperation = g[a];
|
|
};
|
|
this.setMiterLimit = function(a) {
|
|
f.miterLimit = a;
|
|
};
|
|
l(b, a);
|
|
e.style.zIndex = -1;
|
|
};
|
|
Guacamole.Layer.ROUT = 2;
|
|
Guacamole.Layer.ATOP = 6;
|
|
Guacamole.Layer.XOR = 10;
|
|
Guacamole.Layer.ROVER = 11;
|
|
Guacamole.Layer.OVER = 14;
|
|
Guacamole.Layer.PLUS = 15;
|
|
Guacamole.Layer.RIN = 1;
|
|
Guacamole.Layer.IN = 4;
|
|
Guacamole.Layer.OUT = 8;
|
|
Guacamole.Layer.RATOP = 9;
|
|
Guacamole.Layer.SRC = 12;
|
|
Guacamole.Layer.Pixel = function(b, a, d, c) {
|
|
this.red = b;
|
|
this.green = a;
|
|
this.blue = d;
|
|
this.alpha = c;
|
|
};
|
|
Guacamole = Guacamole || {};
|
|
Guacamole.Mouse = function(b) {
|
|
function a() {
|
|
f = c.touchMouseThreshold;
|
|
}
|
|
function d(a) {
|
|
var b = a.deltaY || -a.wheelDeltaY || -a.wheelDelta;
|
|
b
|
|
? 1 === a.deltaMode
|
|
? (b = a.deltaY * c.PIXELS_PER_LINE)
|
|
: 2 === a.deltaMode && (b = a.deltaY * c.PIXELS_PER_PAGE)
|
|
: (b = a.detail * c.PIXELS_PER_LINE);
|
|
k += b;
|
|
if (k <= -c.scrollThreshold) {
|
|
do c.click(Guacamole.Mouse.State.Buttons.UP), (k += c.scrollThreshold);
|
|
while (k <= -c.scrollThreshold);
|
|
k = 0;
|
|
}
|
|
if (k >= c.scrollThreshold) {
|
|
do c.click(Guacamole.Mouse.State.Buttons.DOWN), (k -= c.scrollThreshold);
|
|
while (k >= c.scrollThreshold);
|
|
k = 0;
|
|
}
|
|
Guacamole.Event.DOMEvent.cancelEvent(a);
|
|
}
|
|
Guacamole.Mouse.Event.Target.call(this);
|
|
var c = this;
|
|
this.touchMouseThreshold = 3;
|
|
this.scrollThreshold = 53;
|
|
this.PIXELS_PER_LINE = 18;
|
|
this.PIXELS_PER_PAGE = 16 * this.PIXELS_PER_LINE;
|
|
var e = [
|
|
Guacamole.Mouse.State.Buttons.LEFT,
|
|
Guacamole.Mouse.State.Buttons.MIDDLE,
|
|
Guacamole.Mouse.State.Buttons.RIGHT,
|
|
],
|
|
f = 0,
|
|
k = 0;
|
|
b.addEventListener(
|
|
'contextmenu',
|
|
function(a) {
|
|
Guacamole.Event.DOMEvent.cancelEvent(a);
|
|
},
|
|
!1,
|
|
);
|
|
b.addEventListener(
|
|
'mousemove',
|
|
function(a) {
|
|
f
|
|
? (Guacamole.Event.DOMEvent.cancelEvent(a), f--)
|
|
: c.move(
|
|
Guacamole.Position.fromClientPosition(b, a.clientX, a.clientY),
|
|
a,
|
|
);
|
|
},
|
|
!1,
|
|
);
|
|
b.addEventListener(
|
|
'mousedown',
|
|
function(a) {
|
|
if (f) Guacamole.Event.DOMEvent.cancelEvent(a);
|
|
else {
|
|
var b = e[a.button];
|
|
b && c.press(b, a);
|
|
}
|
|
},
|
|
!1,
|
|
);
|
|
b.addEventListener(
|
|
'mouseup',
|
|
function(a) {
|
|
if (f) Guacamole.Event.DOMEvent.cancelEvent(a);
|
|
else {
|
|
var b = e[a.button];
|
|
b && c.release(b, a);
|
|
}
|
|
},
|
|
!1,
|
|
);
|
|
b.addEventListener(
|
|
'mouseout',
|
|
function(a) {
|
|
a || (a = window.event);
|
|
for (var d = a.relatedTarget || a.toElement; d; ) {
|
|
if (d === b) return;
|
|
d = d.parentNode;
|
|
}
|
|
c.reset(a);
|
|
c.out(a);
|
|
},
|
|
!1,
|
|
);
|
|
b.addEventListener(
|
|
'selectstart',
|
|
function(a) {
|
|
Guacamole.Event.DOMEvent.cancelEvent(a);
|
|
},
|
|
!1,
|
|
);
|
|
b.addEventListener('touchmove', a, !1);
|
|
b.addEventListener('touchstart', a, !1);
|
|
b.addEventListener('touchend', a, !1);
|
|
b.addEventListener('DOMMouseScroll', d, !1);
|
|
b.addEventListener('mousewheel', d, !1);
|
|
b.addEventListener('wheel', d, !1);
|
|
var m = (function() {
|
|
var a = document.createElement('div');
|
|
if (!('cursor' in a.style)) return !1;
|
|
try {
|
|
a.style.cursor =
|
|
'url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEX///+nxBvIAAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg\x3d\x3d) 0 0, auto';
|
|
} catch (g) {
|
|
return !1;
|
|
}
|
|
return /\burl\([^()]*\)\s+0\s+0\b/.test(a.style.cursor || '');
|
|
})();
|
|
this.setCursor = function(a, c, d) {
|
|
return m
|
|
? ((a = a.toDataURL('image/png')),
|
|
(b.style.cursor = 'url(' + a + ') ' + c + ' ' + d + ', auto'),
|
|
!0)
|
|
: !1;
|
|
};
|
|
};
|
|
Guacamole.Mouse.State = function(b) {
|
|
var a = function(a, b, e, f, k, m, n) {
|
|
return { x: a, y: b, left: e, middle: f, right: k, up: m, down: n };
|
|
};
|
|
b = 1 < arguments.length ? a.apply(this, arguments) : b || {};
|
|
Guacamole.Position.call(this, b);
|
|
this.left = b.left || !1;
|
|
this.middle = b.middle || !1;
|
|
this.right = b.right || !1;
|
|
this.up = b.up || !1;
|
|
this.down = b.down || !1;
|
|
};
|
|
Guacamole.Mouse.State.Buttons = {
|
|
LEFT: 'left',
|
|
MIDDLE: 'middle',
|
|
RIGHT: 'right',
|
|
UP: 'up',
|
|
DOWN: 'down',
|
|
};
|
|
Guacamole.Mouse.Event = function(b, a, d) {
|
|
Guacamole.Event.DOMEvent.call(this, b, d);
|
|
var c = 'on' + this.type;
|
|
this.state = a;
|
|
this.invokeLegacyHandler = function(a) {
|
|
a[c] && (this.preventDefault(), this.stopPropagation(), a[c](this.state));
|
|
};
|
|
};
|
|
Guacamole.Mouse.Event.Target = function() {
|
|
Guacamole.Event.Target.call(this);
|
|
this.currentState = new Guacamole.Mouse.State();
|
|
this.press = function(b, a) {
|
|
this.currentState[b] ||
|
|
((this.currentState[b] = !0),
|
|
this.dispatch(
|
|
new Guacamole.Mouse.Event('mousedown', this.currentState, a),
|
|
));
|
|
};
|
|
this.release = function(b, a) {
|
|
this.currentState[b] &&
|
|
((this.currentState[b] = !1),
|
|
this.dispatch(
|
|
new Guacamole.Mouse.Event('mouseup', this.currentState, a),
|
|
));
|
|
};
|
|
this.click = function(b, a) {
|
|
this.press(b, a);
|
|
this.release(b, a);
|
|
};
|
|
this.move = function(b, a) {
|
|
if (this.currentState.x !== b.x || this.currentState.y !== b.y)
|
|
(this.currentState.x = b.x),
|
|
(this.currentState.y = b.y),
|
|
this.dispatch(
|
|
new Guacamole.Mouse.Event('mousemove', this.currentState, a),
|
|
);
|
|
};
|
|
this.out = function(b) {
|
|
this.dispatch(new Guacamole.Mouse.Event('mouseout', this.currentState, b));
|
|
};
|
|
this.reset = function(b) {
|
|
for (var a in Guacamole.Mouse.State.Buttons)
|
|
this.release(Guacamole.Mouse.State.Buttons[a], b);
|
|
};
|
|
};
|
|
Guacamole.Mouse.Touchpad = function(b) {
|
|
Guacamole.Mouse.Event.Target.call(this);
|
|
var a = this;
|
|
this.scrollThreshold = 20 * (window.devicePixelRatio || 1);
|
|
this.clickTimingThreshold = 250;
|
|
this.clickMoveThreshold = 10 * (window.devicePixelRatio || 1);
|
|
this.currentState = new Guacamole.Mouse.State();
|
|
var d = 0,
|
|
c = 0,
|
|
e = 0,
|
|
f = 0,
|
|
k = 0,
|
|
m = { 1: 'left', 2: 'right', 3: 'middle' },
|
|
n = !1,
|
|
g = null;
|
|
b.addEventListener(
|
|
'touchend',
|
|
function(b) {
|
|
b.preventDefault();
|
|
if (n && 0 === b.touches.length) {
|
|
var c = new Date().getTime(),
|
|
e = m[d];
|
|
a.currentState[e] &&
|
|
(a.release(e, b), g && (window.clearTimeout(g), (g = null)));
|
|
c - f <= a.clickTimingThreshold &&
|
|
k < a.clickMoveThreshold &&
|
|
(a.press(e, b),
|
|
(g = window.setTimeout(function() {
|
|
a.release(e, b);
|
|
n = !1;
|
|
}, a.clickTimingThreshold)));
|
|
g || (n = !1);
|
|
}
|
|
},
|
|
!1,
|
|
);
|
|
b.addEventListener(
|
|
'touchstart',
|
|
function(a) {
|
|
a.preventDefault();
|
|
d = Math.min(a.touches.length, 3);
|
|
g && (window.clearTimeout(g), (g = null));
|
|
n ||
|
|
((n = !0),
|
|
(a = a.touches[0]),
|
|
(c = a.clientX),
|
|
(e = a.clientY),
|
|
(f = new Date().getTime()),
|
|
(k = 0));
|
|
},
|
|
!1,
|
|
);
|
|
b.addEventListener(
|
|
'touchmove',
|
|
function(g) {
|
|
g.preventDefault();
|
|
var l = g.touches[0],
|
|
m = l.clientX - c,
|
|
n = l.clientY - e;
|
|
k += Math.abs(m) + Math.abs(n);
|
|
if (1 === d) {
|
|
var q = 1 + k / (new Date().getTime() - f),
|
|
u = new Guacamole.Position(a.currentState);
|
|
u.x += m * q;
|
|
u.y += n * q;
|
|
u.x = Math.min(Math.max(0, u.x), b.offsetWidth - 1);
|
|
u.y = Math.min(Math.max(0, u.y), b.offsetHeight - 1);
|
|
a.move(u, g);
|
|
c = l.clientX;
|
|
e = l.clientY;
|
|
} else
|
|
2 === d &&
|
|
Math.abs(n) >= a.scrollThreshold &&
|
|
(a.click(0 < n ? 'down' : 'up', g), (c = l.clientX), (e = l.clientY));
|
|
},
|
|
!1,
|
|
);
|
|
};
|
|
Guacamole.Mouse.Touchscreen = function(b) {
|
|
function a(a) {
|
|
var b = a.touches[0] || a.changedTouches[0];
|
|
a = b.clientX - k;
|
|
b = b.clientY - m;
|
|
return Math.sqrt(a * a + b * b) >= e.clickMoveThreshold;
|
|
}
|
|
function d(a) {
|
|
a = a.touches[0];
|
|
f = !0;
|
|
k = a.clientX;
|
|
m = a.clientY;
|
|
}
|
|
function c() {
|
|
window.clearTimeout(n);
|
|
window.clearTimeout(g);
|
|
f = !1;
|
|
}
|
|
Guacamole.Mouse.Event.Target.call(this);
|
|
var e = this,
|
|
f = !1,
|
|
k = null,
|
|
m = null,
|
|
n = null,
|
|
g = null;
|
|
this.scrollThreshold = 20 * (window.devicePixelRatio || 1);
|
|
this.clickTimingThreshold = 250;
|
|
this.clickMoveThreshold = 16 * (window.devicePixelRatio || 1);
|
|
this.longPressThreshold = 500;
|
|
b.addEventListener(
|
|
'touchend',
|
|
function(d) {
|
|
if (f)
|
|
if (0 !== d.touches.length || 1 !== d.changedTouches.length) c();
|
|
else if (
|
|
(window.clearTimeout(g),
|
|
e.release(Guacamole.Mouse.State.Buttons.LEFT, d),
|
|
!a(d) && (d.preventDefault(), !e.currentState.left))
|
|
) {
|
|
var l = d.changedTouches[0];
|
|
e.move(
|
|
Guacamole.Position.fromClientPosition(b, l.clientX, l.clientY),
|
|
);
|
|
e.press(Guacamole.Mouse.State.Buttons.LEFT, d);
|
|
n = window.setTimeout(function() {
|
|
e.release(Guacamole.Mouse.State.Buttons.LEFT, d);
|
|
c();
|
|
}, e.clickTimingThreshold);
|
|
}
|
|
},
|
|
!1,
|
|
);
|
|
b.addEventListener(
|
|
'touchstart',
|
|
function(a) {
|
|
1 !== a.touches.length
|
|
? c()
|
|
: (a.preventDefault(),
|
|
d(a),
|
|
window.clearTimeout(n),
|
|
(g = window.setTimeout(function() {
|
|
var d = a.touches[0];
|
|
e.move(
|
|
Guacamole.Position.fromClientPosition(b, d.clientX, d.clientY),
|
|
);
|
|
e.click(Guacamole.Mouse.State.Buttons.RIGHT, a);
|
|
c();
|
|
}, e.longPressThreshold)));
|
|
},
|
|
!1,
|
|
);
|
|
b.addEventListener(
|
|
'touchmove',
|
|
function(d) {
|
|
if (f)
|
|
if ((a(d) && window.clearTimeout(g), 1 !== d.touches.length)) c();
|
|
else if (e.currentState.left) {
|
|
d.preventDefault();
|
|
var m = d.touches[0];
|
|
e.move(
|
|
Guacamole.Position.fromClientPosition(b, m.clientX, m.clientY),
|
|
d,
|
|
);
|
|
}
|
|
},
|
|
!1,
|
|
);
|
|
};
|
|
Guacamole = Guacamole = Guacamole || {};
|
|
Guacamole.Object = function(b, a) {
|
|
var d = this,
|
|
c = {};
|
|
this.index = a;
|
|
this.onbody = function(a, b, d) {
|
|
var e = c[d];
|
|
if (e) {
|
|
var f = e.shift();
|
|
0 === e.length && delete c[d];
|
|
d = f;
|
|
} else d = null;
|
|
d && d(a, b);
|
|
};
|
|
this.onundefine = null;
|
|
this.requestInputStream = function(a, f) {
|
|
if (f) {
|
|
var e = c[a];
|
|
e || ((e = []), (c[a] = e));
|
|
e.push(f);
|
|
}
|
|
b.requestObjectInputStream(d.index, a);
|
|
};
|
|
this.createOutputStream = function(a, c) {
|
|
return b.createObjectOutputStream(d.index, a, c);
|
|
};
|
|
};
|
|
Guacamole.Object.ROOT_STREAM = '/';
|
|
Guacamole.Object.STREAM_INDEX_MIMETYPE =
|
|
'application/vnd.glyptodon.guacamole.stream-index+json';
|
|
Guacamole = Guacamole || {};
|
|
Guacamole.OnScreenKeyboard = function(b) {
|
|
var a = this,
|
|
d = {},
|
|
c = {},
|
|
e = [],
|
|
f = function(a, b) {
|
|
a.classList ? a.classList.add(b) : (a.className += ' ' + b);
|
|
},
|
|
k = function(a, b) {
|
|
a.classList
|
|
? a.classList.remove(b)
|
|
: (a.className = a.className.replace(/([^ ]+)[ ]*/g, function(a, c) {
|
|
return c === b ? '' : a;
|
|
}));
|
|
},
|
|
m = 0,
|
|
n = function(a, b, c, d) {
|
|
this.width = b;
|
|
this.height = c;
|
|
this.scale = function(e) {
|
|
a.style.width = b * e + 'px';
|
|
a.style.height = c * e + 'px';
|
|
d &&
|
|
((a.style.lineHeight = c * e + 'px'), (a.style.fontSize = e + 'px'));
|
|
};
|
|
},
|
|
g = function(b) {
|
|
b = a.keys[b];
|
|
if (!b) return null;
|
|
for (var c = b.length - 1; 0 <= c; c--) {
|
|
var e = b[c];
|
|
a: {
|
|
var f = e.requires;
|
|
for (var g = 0; g < f.length; g++)
|
|
if (!(f[g] in d)) {
|
|
f = !1;
|
|
break a;
|
|
}
|
|
f = !0;
|
|
}
|
|
if (f) return e;
|
|
}
|
|
return null;
|
|
},
|
|
l = function(b, e) {
|
|
if (!c[b]) {
|
|
f(e, 'guac-keyboard-pressed');
|
|
e = g(b);
|
|
if (e.modifier) {
|
|
var m = 'guac-keyboard-modifier-' + t(e.modifier),
|
|
l = d[e.modifier];
|
|
if (void 0 === l) {
|
|
if ((f(v, m), (d[e.modifier] = e.keysym) && a.onkeydown))
|
|
a.onkeydown(e.keysym);
|
|
} else if ((k(v, m), delete d[e.modifier], l && a.onkeyup))
|
|
a.onkeyup(l);
|
|
} else if (a.onkeydown) a.onkeydown(e.keysym);
|
|
c[b] = !0;
|
|
}
|
|
},
|
|
p = function(b, d) {
|
|
if (c[b]) {
|
|
k(d, 'guac-keyboard-pressed');
|
|
d = g(b);
|
|
if (!d.modifier && a.onkeyup) a.onkeyup(d.keysym);
|
|
c[b] = !1;
|
|
}
|
|
},
|
|
v = document.createElement('div');
|
|
v.className = 'guac-keyboard';
|
|
v.onselectstart = v.onmousemove = v.onmouseup = v.onmousedown = function(a) {
|
|
m && m--;
|
|
a.stopPropagation();
|
|
return !1;
|
|
};
|
|
this.touchMouseThreshold = 3;
|
|
this.onkeyup = this.onkeydown = null;
|
|
this.layout = new Guacamole.OnScreenKeyboard.Layout(b);
|
|
this.getElement = function() {
|
|
return v;
|
|
};
|
|
this.resize = function(b) {
|
|
b = Math.floor((10 * b) / a.layout.width) / 10;
|
|
for (var c = 0; c < e.length; c++) e[c].scale(b);
|
|
};
|
|
this.keys = (function(a) {
|
|
var c = {},
|
|
d;
|
|
for (d in b.keys) {
|
|
var e = d;
|
|
var f = d;
|
|
var g = a[d];
|
|
if (g instanceof Array) {
|
|
for (var m = [], l = 0; l < g.length; l++)
|
|
m.push(new Guacamole.OnScreenKeyboard.Key(g[l], f));
|
|
f = m;
|
|
} else
|
|
f =
|
|
'number' === typeof g
|
|
? [new Guacamole.OnScreenKeyboard.Key({ name: f, keysym: g })]
|
|
: 'string' === typeof g
|
|
? [new Guacamole.OnScreenKeyboard.Key({ name: f, title: g })]
|
|
: [new Guacamole.OnScreenKeyboard.Key(g, f)];
|
|
c[e] = f;
|
|
}
|
|
return c;
|
|
})(b.keys);
|
|
var t = function(a) {
|
|
return a
|
|
.replace(/([a-z])([A-Z])/g, '$1-$2')
|
|
.replace(/[^A-Za-z0-9]+/g, '-')
|
|
.toLowerCase();
|
|
};
|
|
(function y(b, c, d) {
|
|
var g,
|
|
h = document.createElement('div');
|
|
d && f(h, 'guac-keyboard-' + t(d));
|
|
if (c instanceof Array)
|
|
for (f(h, 'guac-keyboard-group'), g = 0; g < c.length; g++) y(h, c[g]);
|
|
else if (c instanceof Object) {
|
|
f(h, 'guac-keyboard-group');
|
|
var k = Object.keys(c).sort();
|
|
for (g = 0; g < k.length; g++) (d = k[g]), y(h, c[d], d);
|
|
} else if ('number' === typeof c)
|
|
f(h, 'guac-keyboard-gap'), e.push(new n(h, c, c));
|
|
else if ('string' === typeof c) {
|
|
g = c;
|
|
1 === g.length && (g = '0x' + g.charCodeAt(0).toString(16));
|
|
f(h, 'guac-keyboard-key-container');
|
|
var r = document.createElement('div');
|
|
r.className = 'guac-keyboard-key guac-keyboard-key-' + t(g);
|
|
if ((d = a.keys[c]))
|
|
for (g = 0; g < d.length; g++) {
|
|
k = d[g];
|
|
var v = document.createElement('div');
|
|
v.className = 'guac-keyboard-cap';
|
|
v.textContent = k.title;
|
|
for (var C = 0; C < k.requires.length; C++) {
|
|
var u = k.requires[C];
|
|
f(v, 'guac-keyboard-requires-' + t(u));
|
|
f(r, 'guac-keyboard-uses-' + t(u));
|
|
}
|
|
r.appendChild(v);
|
|
}
|
|
h.appendChild(r);
|
|
e.push(new n(h, a.layout.keyWidths[c] || 1, 1, !0));
|
|
g = function(a) {
|
|
a.preventDefault();
|
|
0 === m && p(c, r);
|
|
};
|
|
r.addEventListener(
|
|
'touchstart',
|
|
function(b) {
|
|
b.preventDefault();
|
|
m = a.touchMouseThreshold;
|
|
l(c, r);
|
|
},
|
|
!0,
|
|
);
|
|
r.addEventListener(
|
|
'touchend',
|
|
function(b) {
|
|
b.preventDefault();
|
|
m = a.touchMouseThreshold;
|
|
p(c, r);
|
|
},
|
|
!0,
|
|
);
|
|
r.addEventListener(
|
|
'mousedown',
|
|
function(a) {
|
|
a.preventDefault();
|
|
0 === m && l(c, r);
|
|
},
|
|
!0,
|
|
);
|
|
r.addEventListener('mouseup', g, !0);
|
|
r.addEventListener('mouseout', g, !0);
|
|
}
|
|
b.appendChild(h);
|
|
})(v, b.layout);
|
|
};
|
|
Guacamole.OnScreenKeyboard.Layout = function(b) {
|
|
this.language = b.language;
|
|
this.type = b.type;
|
|
this.keys = b.keys;
|
|
this.layout = b.layout;
|
|
this.width = b.width;
|
|
this.keyWidths = b.keyWidths || {};
|
|
};
|
|
Guacamole.OnScreenKeyboard.Key = function(b, a) {
|
|
this.name = a || b.name;
|
|
this.title = b.title || this.name;
|
|
(a = b.keysym) ||
|
|
((a = this.title) && 1 === a.length
|
|
? ((a = a.charCodeAt(0)),
|
|
(a =
|
|
0 <= a && 255 >= a
|
|
? a
|
|
: 256 <= a && 1114111 >= a
|
|
? 16777216 | a
|
|
: null))
|
|
: (a = null));
|
|
this.keysym = a;
|
|
this.modifier = b.modifier;
|
|
this.requires = b.requires || [];
|
|
};
|
|
Guacamole = Guacamole || {};
|
|
Guacamole.OutputStream = function(b, a) {
|
|
var d = this;
|
|
this.index = a;
|
|
this.onack = null;
|
|
this.sendBlob = function(a) {
|
|
b.sendBlob(d.index, a);
|
|
};
|
|
this.sendEnd = function() {
|
|
b.endStream(d.index);
|
|
};
|
|
};
|
|
Guacamole = Guacamole || {};
|
|
Guacamole.Parser = function() {
|
|
var b = this,
|
|
a = '',
|
|
d = [],
|
|
c = -1,
|
|
e = 0;
|
|
this.receive = function(f) {
|
|
4096 < e && c >= e && ((a = a.substring(e)), (c -= e), (e = 0));
|
|
for (a += f; c < a.length; ) {
|
|
if (c >= e) {
|
|
f = a.substring(e, c);
|
|
var k = a.substring(c, c + 1);
|
|
d.push(f);
|
|
if (';' == k) {
|
|
f = d.shift();
|
|
if (null != b.oninstruction) b.oninstruction(f, d);
|
|
d.length = 0;
|
|
} else if (',' != k) throw Error('Illegal terminator.');
|
|
e = c + 1;
|
|
}
|
|
f = a.indexOf('.', e);
|
|
if (-1 != f) {
|
|
k = parseInt(a.substring(c + 1, f));
|
|
if (isNaN(k)) throw Error('Non-numeric character in element length.');
|
|
e = f + 1;
|
|
c = e + k;
|
|
} else {
|
|
e = a.length;
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
this.oninstruction = null;
|
|
};
|
|
Guacamole = Guacamole || {};
|
|
Guacamole.Position = function(b) {
|
|
b = b || {};
|
|
this.x = b.x || 0;
|
|
this.y = b.y || 0;
|
|
this.fromClientPosition = function(a, b, c) {
|
|
this.x = b - a.offsetLeft;
|
|
this.y = c - a.offsetTop;
|
|
for (a = a.offsetParent; a && a !== document.body; )
|
|
(this.x -= a.offsetLeft - a.scrollLeft),
|
|
(this.y -= a.offsetTop - a.scrollTop),
|
|
(a = a.offsetParent);
|
|
a &&
|
|
((b = document.body.scrollTop || document.documentElement.scrollTop),
|
|
(this.x -=
|
|
a.offsetLeft -
|
|
(document.body.scrollLeft || document.documentElement.scrollLeft)),
|
|
(this.y -= a.offsetTop - b));
|
|
};
|
|
};
|
|
Guacamole.Position.fromClientPosition = function(b, a, d) {
|
|
var c = new Guacamole.Position();
|
|
c.fromClientPosition(b, a, d);
|
|
return c;
|
|
};
|
|
Guacamole = Guacamole || {};
|
|
Guacamole.RawAudioFormat = function(b) {
|
|
this.bytesPerSample = b.bytesPerSample;
|
|
this.channels = b.channels;
|
|
this.rate = b.rate;
|
|
};
|
|
Guacamole.RawAudioFormat.parse = function(b) {
|
|
var a = null,
|
|
d = 1;
|
|
if ('audio/L8;' === b.substring(0, 9)) {
|
|
b = b.substring(9);
|
|
var c = 1;
|
|
} else if ('audio/L16;' === b.substring(0, 10))
|
|
(b = b.substring(10)), (c = 2);
|
|
else return null;
|
|
b = b.split(',');
|
|
for (var e = 0; e < b.length; e++) {
|
|
var f = b[e],
|
|
k = f.indexOf('\x3d');
|
|
if (-1 === k) return null;
|
|
var m = f.substring(0, k);
|
|
f = f.substring(k + 1);
|
|
switch (m) {
|
|
case 'channels':
|
|
d = parseInt(f);
|
|
break;
|
|
case 'rate':
|
|
a = parseInt(f);
|
|
break;
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
return null === a
|
|
? null
|
|
: new Guacamole.RawAudioFormat({ bytesPerSample: c, channels: d, rate: a });
|
|
};
|
|
Guacamole = Guacamole || {};
|
|
Guacamole.SessionRecording = function(b) {
|
|
var a = this,
|
|
d = [],
|
|
c = [],
|
|
e = 0,
|
|
f = 0,
|
|
k = new Guacamole.SessionRecording._PlaybackTunnel(),
|
|
m = new Guacamole.Client(k),
|
|
n = -1,
|
|
g = null,
|
|
l = null,
|
|
p = null;
|
|
m.connect();
|
|
m.getDisplay().showCursor(!1);
|
|
b.oninstruction = function(b, g) {
|
|
var l = new Guacamole.SessionRecording._Frame.Instruction(b, g.slice());
|
|
c.push(l);
|
|
e += l.getSize();
|
|
if ('sync' === b) {
|
|
b = parseInt(g[0]);
|
|
g = new Guacamole.SessionRecording._Frame(b, c);
|
|
d.push(g);
|
|
if (1 === d.length || (16384 <= e && 5e3 <= b - f))
|
|
(g.keyframe = !0), (f = b), (e = 0);
|
|
c = [];
|
|
if (a.onprogress) a.onprogress(a.getDuration());
|
|
}
|
|
};
|
|
var v = function(a) {
|
|
return 0 === d.length ? 0 : a - d[0].timestamp;
|
|
},
|
|
t = function x(a, b, c) {
|
|
if (a === b) return a;
|
|
var e = Math.floor((a + b) / 2),
|
|
f = v(d[e].timestamp);
|
|
return c < f && e > a
|
|
? x(a, e - 1, c)
|
|
: c > f && e < b
|
|
? x(e + 1, b, c)
|
|
: e;
|
|
},
|
|
q = function(a) {
|
|
var b = d[a];
|
|
for (a = 0; a < b.instructions.length; a++) {
|
|
var c = b.instructions[a];
|
|
k.receiveInstruction(c.opcode, c.args);
|
|
}
|
|
b.keyframe &&
|
|
!b.clientState &&
|
|
m.exportState(function(a) {
|
|
b.clientState = a;
|
|
});
|
|
},
|
|
u = function A(b, c, e) {
|
|
window.clearTimeout(p);
|
|
p = window.setTimeout(function() {
|
|
var f;
|
|
for (f = b; 0 <= f; f--) {
|
|
var g = d[f];
|
|
if (f === n) break;
|
|
if (g.clientState) {
|
|
m.importState(g.clientState);
|
|
break;
|
|
}
|
|
}
|
|
f++;
|
|
for (
|
|
g = new Date().getTime();
|
|
f <= b && !(5 <= new Date().getTime() - g);
|
|
f++
|
|
)
|
|
q(f);
|
|
n = f - 1;
|
|
if (a.onseek) a.onseek(a.getPosition());
|
|
n !== b ? A(b, c, Math.max(e - (new Date().getTime() - g), 0)) : c();
|
|
}, e || 0);
|
|
},
|
|
w = function h() {
|
|
if (n + 1 < d.length) {
|
|
var b = Math.max(d[n + 1].timestamp - g + l - new Date().getTime(), 0);
|
|
u(
|
|
n + 1,
|
|
function() {
|
|
h();
|
|
},
|
|
b,
|
|
);
|
|
} else a.pause();
|
|
};
|
|
this.onseek = this.onpause = this.onplay = this.onprogress = null;
|
|
this.connect = function(a) {
|
|
b.connect(a);
|
|
};
|
|
this.disconnect = function() {
|
|
b.disconnect();
|
|
};
|
|
this.getDisplay = function() {
|
|
return m.getDisplay();
|
|
};
|
|
this.isPlaying = function() {
|
|
return !!g;
|
|
};
|
|
this.getPosition = function() {
|
|
return -1 === n ? 0 : v(d[n].timestamp);
|
|
};
|
|
this.getDuration = function() {
|
|
return 0 === d.length ? 0 : v(d[d.length - 1].timestamp);
|
|
};
|
|
this.play = function() {
|
|
if (!a.isPlaying() && n + 1 < d.length) {
|
|
if (a.onplay) a.onplay();
|
|
g = d[n + 1].timestamp;
|
|
l = new Date().getTime();
|
|
w();
|
|
}
|
|
};
|
|
this.seek = function(b, c) {
|
|
if (0 !== d.length) {
|
|
var e = a.isPlaying();
|
|
a.pause();
|
|
u(t(0, d.length - 1, b), function() {
|
|
e && a.play();
|
|
c && c();
|
|
});
|
|
}
|
|
};
|
|
this.pause = function() {
|
|
window.clearTimeout(p);
|
|
if (a.isPlaying()) {
|
|
if (a.onpause) a.onpause();
|
|
l = g = null;
|
|
}
|
|
};
|
|
};
|
|
Guacamole.SessionRecording._Frame = function(b, a) {
|
|
this.keyframe = !1;
|
|
this.timestamp = b;
|
|
this.instructions = a;
|
|
this.clientState = null;
|
|
};
|
|
Guacamole.SessionRecording._Frame.Instruction = function(b, a) {
|
|
var d = this;
|
|
this.opcode = b;
|
|
this.args = a;
|
|
this.getSize = function() {
|
|
for (var a = d.opcode.length, b = 0; b < d.args.length; b++)
|
|
a += d.args[b].length;
|
|
return a;
|
|
};
|
|
};
|
|
Guacamole.SessionRecording._PlaybackTunnel = function() {
|
|
var b = this;
|
|
this.connect = function(a) {};
|
|
this.sendMessage = function(a) {};
|
|
this.disconnect = function() {};
|
|
this.receiveInstruction = function(a, d) {
|
|
if (b.oninstruction) b.oninstruction(a, d);
|
|
};
|
|
};
|
|
Guacamole = Guacamole || {};
|
|
Guacamole.Status = function(b, a) {
|
|
var d = this;
|
|
this.code = b;
|
|
this.message = a;
|
|
this.isError = function() {
|
|
return 0 > d.code || 255 < d.code;
|
|
};
|
|
};
|
|
Guacamole.Status.Code = {
|
|
SUCCESS: 0,
|
|
UNSUPPORTED: 256,
|
|
SERVER_ERROR: 512,
|
|
SERVER_BUSY: 513,
|
|
UPSTREAM_TIMEOUT: 514,
|
|
UPSTREAM_ERROR: 515,
|
|
RESOURCE_NOT_FOUND: 516,
|
|
RESOURCE_CONFLICT: 517,
|
|
RESOURCE_CLOSED: 518,
|
|
UPSTREAM_NOT_FOUND: 519,
|
|
UPSTREAM_UNAVAILABLE: 520,
|
|
SESSION_CONFLICT: 521,
|
|
SESSION_TIMEOUT: 522,
|
|
SESSION_CLOSED: 523,
|
|
CLIENT_BAD_REQUEST: 768,
|
|
CLIENT_UNAUTHORIZED: 769,
|
|
CLIENT_FORBIDDEN: 771,
|
|
CLIENT_TIMEOUT: 776,
|
|
CLIENT_OVERRUN: 781,
|
|
CLIENT_BAD_TYPE: 783,
|
|
CLIENT_TOO_MANY: 797,
|
|
};
|
|
Guacamole.Status.Code.fromHTTPCode = function(b) {
|
|
switch (b) {
|
|
case 400:
|
|
return Guacamole.Status.Code.CLIENT_BAD_REQUEST;
|
|
case 403:
|
|
return Guacamole.Status.Code.CLIENT_FORBIDDEN;
|
|
case 404:
|
|
return Guacamole.Status.Code.RESOURCE_NOT_FOUND;
|
|
case 429:
|
|
return Guacamole.Status.Code.CLIENT_TOO_MANY;
|
|
case 503:
|
|
return Guacamole.Status.Code.SERVER_BUSY;
|
|
}
|
|
return Guacamole.Status.Code.SERVER_ERROR;
|
|
};
|
|
Guacamole.Status.Code.fromWebSocketCode = function(b) {
|
|
switch (b) {
|
|
case 1e3:
|
|
return Guacamole.Status.Code.SUCCESS;
|
|
case 1006:
|
|
case 1015:
|
|
return Guacamole.Status.Code.UPSTREAM_NOT_FOUND;
|
|
case 1001:
|
|
case 1012:
|
|
case 1013:
|
|
case 1014:
|
|
return Guacamole.Status.Code.UPSTREAM_UNAVAILABLE;
|
|
}
|
|
return Guacamole.Status.Code.SERVER_ERROR;
|
|
};
|
|
Guacamole = Guacamole || {};
|
|
Guacamole.StringReader = function(b) {
|
|
var a = this;
|
|
b = new Guacamole.ArrayBufferReader(b);
|
|
var d = 0,
|
|
c = 0;
|
|
b.ondata = function(b) {
|
|
var e = '';
|
|
b = new Uint8Array(b);
|
|
for (var k = 0; k < b.length; k++) {
|
|
var m = b[k];
|
|
0 === d
|
|
? 127 === (m | 127)
|
|
? (e += String.fromCharCode(m))
|
|
: 223 === (m | 31)
|
|
? ((c = m & 31), (d = 1))
|
|
: 239 === (m | 15)
|
|
? ((c = m & 15), (d = 2))
|
|
: 247 === (m | 7)
|
|
? ((c = m & 7), (d = 3))
|
|
: (e += '�')
|
|
: 191 === (m | 63)
|
|
? ((c = (c << 6) | (m & 63)),
|
|
d--,
|
|
0 === d && (e += String.fromCharCode(c)))
|
|
: ((d = 0), (e += '�'));
|
|
}
|
|
if (a.ontext) a.ontext(e);
|
|
};
|
|
b.onend = function() {
|
|
if (a.onend) a.onend();
|
|
};
|
|
this.onend = this.ontext = null;
|
|
};
|
|
Guacamole = Guacamole || {};
|
|
Guacamole.StringWriter = function(b) {
|
|
function a(b) {
|
|
if (127 >= b) {
|
|
var c = 0;
|
|
var d = 1;
|
|
} else if (2047 >= b) (c = 192), (d = 2);
|
|
else if (65535 >= b) (c = 224), (d = 3);
|
|
else if (2097151 >= b) (c = 240), (d = 4);
|
|
else {
|
|
a(65533);
|
|
return;
|
|
}
|
|
var e = d;
|
|
if (k + e >= f.length) {
|
|
var m = new Uint8Array(2 * (k + e));
|
|
m.set(f);
|
|
f = m;
|
|
}
|
|
k += e;
|
|
e = k - 1;
|
|
for (m = 1; m < d; m++) (f[e--] = 128 | (b & 63)), (b >>= 6);
|
|
f[e] = c | b;
|
|
}
|
|
function d(b) {
|
|
for (var c = 0; c < b.length; c++) {
|
|
var d = b.charCodeAt(c);
|
|
a(d);
|
|
}
|
|
if (0 < k) return (b = f.subarray(0, k)), (k = 0), b;
|
|
}
|
|
var c = this,
|
|
e = new Guacamole.ArrayBufferWriter(b),
|
|
f = new Uint8Array(8192),
|
|
k = 0;
|
|
e.onack = function(a) {
|
|
if (c.onack) c.onack(a);
|
|
};
|
|
this.sendText = function(a) {
|
|
a.length && e.sendData(d(a));
|
|
};
|
|
this.sendEnd = function() {
|
|
e.sendEnd();
|
|
};
|
|
this.onack = null;
|
|
};
|
|
Guacamole = Guacamole || {};
|
|
Guacamole.Touch = function(b) {
|
|
Guacamole.Event.Target.call(this);
|
|
var a = this,
|
|
d = Math.floor(16 * window.devicePixelRatio);
|
|
this.touches = {};
|
|
this.activeTouches = 0;
|
|
b.addEventListener(
|
|
'touchstart',
|
|
function(c) {
|
|
for (var e = 0; e < c.changedTouches.length; e++) {
|
|
var f = c.changedTouches[e],
|
|
k = f.identifier;
|
|
a.touches[k] ||
|
|
((k = a.touches[k] = new Guacamole.Touch.State({
|
|
id: k,
|
|
radiusX: f.radiusX || d,
|
|
radiusY: f.radiusY || d,
|
|
angle: f.angle || 0,
|
|
force: f.force || 1,
|
|
})),
|
|
a.activeTouches++,
|
|
k.fromClientPosition(b, f.clientX, f.clientY),
|
|
a.dispatch(new Guacamole.Touch.Event('touchmove', c, k)));
|
|
}
|
|
},
|
|
!1,
|
|
);
|
|
b.addEventListener(
|
|
'touchmove',
|
|
function(c) {
|
|
for (var e = 0; e < c.changedTouches.length; e++) {
|
|
var f = c.changedTouches[e],
|
|
k = a.touches[f.identifier];
|
|
k &&
|
|
(f.force && (k.force = f.force),
|
|
(k.angle = f.angle || 0),
|
|
(k.radiusX = f.radiusX || d),
|
|
(k.radiusY = f.radiusY || d),
|
|
k.fromClientPosition(b, f.clientX, f.clientY),
|
|
a.dispatch(new Guacamole.Touch.Event('touchmove', c, k)));
|
|
}
|
|
},
|
|
!1,
|
|
);
|
|
b.addEventListener(
|
|
'touchend',
|
|
function(c) {
|
|
for (var d = 0; d < c.changedTouches.length; d++) {
|
|
var f = c.changedTouches[d],
|
|
k = f.identifier,
|
|
m = a.touches[k];
|
|
m &&
|
|
(delete a.touches[k],
|
|
a.activeTouches--,
|
|
(m.force = 0),
|
|
m.fromClientPosition(b, f.clientX, f.clientY),
|
|
a.dispatch(new Guacamole.Touch.Event('touchend', c, m)));
|
|
}
|
|
},
|
|
!1,
|
|
);
|
|
};
|
|
Guacamole.Touch.State = function(b) {
|
|
b = b || {};
|
|
Guacamole.Position.call(this, b);
|
|
this.id = b.id || 0;
|
|
this.radiusX = b.radiusX || 0;
|
|
this.radiusY = b.radiusY || 0;
|
|
this.angle = b.angle || 0;
|
|
this.force = b.force || 1;
|
|
};
|
|
Guacamole.Touch.Event = function(b, a, d) {
|
|
Guacamole.Event.DOMEvent.call(this, b, [a]);
|
|
this.state = d;
|
|
};
|
|
Guacamole = Guacamole || {};
|
|
Guacamole.Tunnel = function() {
|
|
this.connect = function(b) {};
|
|
this.disconnect = function() {};
|
|
this.sendMessage = function(b) {};
|
|
this.setState = function(b) {
|
|
if (b !== this.state && ((this.state = b), this.onstatechange))
|
|
this.onstatechange(b);
|
|
};
|
|
this.setUUID = function(b) {
|
|
this.uuid = b;
|
|
if (this.onuuid) this.onuuid(b);
|
|
};
|
|
this.isConnected = function() {
|
|
return (
|
|
this.state === Guacamole.Tunnel.State.OPEN ||
|
|
this.state === Guacamole.Tunnel.State.UNSTABLE
|
|
);
|
|
};
|
|
this.state = Guacamole.Tunnel.State.CONNECTING;
|
|
this.receiveTimeout = 15e3;
|
|
this.unstableThreshold = 1500;
|
|
this.oninstruction = this.onstatechange = this.onerror = this.onuuid = this.uuid = null;
|
|
};
|
|
Guacamole.Tunnel.INTERNAL_DATA_OPCODE = '';
|
|
Guacamole.Tunnel.State = { CONNECTING: 0, OPEN: 1, CLOSED: 2, UNSTABLE: 3 };
|
|
Guacamole.HTTPTunnel = function(b, a, d) {
|
|
function c(a, b) {
|
|
for (var c in b) a.setRequestHeader(c, b[c]);
|
|
}
|
|
function e() {
|
|
window.clearTimeout(y);
|
|
window.clearTimeout(z);
|
|
l.state === Guacamole.Tunnel.State.UNSTABLE &&
|
|
l.setState(Guacamole.Tunnel.State.OPEN);
|
|
y = window.setTimeout(function() {
|
|
f(
|
|
new Guacamole.Status(
|
|
Guacamole.Status.Code.UPSTREAM_TIMEOUT,
|
|
'Server timeout.',
|
|
),
|
|
);
|
|
}, l.receiveTimeout);
|
|
z = window.setTimeout(function() {
|
|
l.setState(Guacamole.Tunnel.State.UNSTABLE);
|
|
}, l.unstableThreshold);
|
|
}
|
|
function f(a) {
|
|
window.clearTimeout(y);
|
|
window.clearTimeout(z);
|
|
window.clearInterval(h);
|
|
if (l.state !== Guacamole.Tunnel.State.CLOSED) {
|
|
if (
|
|
a.code !== Guacamole.Status.Code.SUCCESS &&
|
|
l.onerror &&
|
|
(l.state === Guacamole.Tunnel.State.CONNECTING ||
|
|
a.code !== Guacamole.Status.Code.RESOURCE_NOT_FOUND)
|
|
)
|
|
l.onerror(a);
|
|
u = !1;
|
|
l.setState(Guacamole.Tunnel.State.CLOSED);
|
|
}
|
|
}
|
|
function k() {
|
|
if (l.isConnected())
|
|
if (0 < w.length) {
|
|
u = !0;
|
|
var a = new XMLHttpRequest();
|
|
a.open('POST', t + l.uuid);
|
|
a.withCredentials = r;
|
|
c(a, x);
|
|
a.setRequestHeader('Content-type', 'application/octet-stream');
|
|
a.setRequestHeader('Guacamole-Tunnel-Token', A);
|
|
a.onreadystatechange = function() {
|
|
4 === a.readyState && (e(), 200 !== a.status ? m(a) : k());
|
|
};
|
|
a.send(w);
|
|
w = '';
|
|
} else u = !1;
|
|
}
|
|
function m(a) {
|
|
var b = parseInt(a.getResponseHeader('Guacamole-Status-Code'));
|
|
b
|
|
? ((a = a.getResponseHeader('Guacamole-Error-Message')),
|
|
f(new Guacamole.Status(b, a)))
|
|
: a.status
|
|
? f(
|
|
new Guacamole.Status(
|
|
Guacamole.Status.Code.fromHTTPCode(a.status),
|
|
a.statusText,
|
|
),
|
|
)
|
|
: f(new Guacamole.Status(Guacamole.Status.Code.UPSTREAM_NOT_FOUND));
|
|
}
|
|
function n(a) {
|
|
function b() {
|
|
if (!l.isConnected()) null !== c && clearInterval(c);
|
|
else if (!(2 > a.readyState)) {
|
|
try {
|
|
var f = a.status;
|
|
} catch (H) {
|
|
f = 200;
|
|
}
|
|
d || 200 !== f || (d = g());
|
|
if (3 === a.readyState || 4 === a.readyState)
|
|
if (
|
|
(e(),
|
|
1 === q &&
|
|
(3 !== a.readyState || c
|
|
? 4 === a.readyState && c && clearInterval(c)
|
|
: (c = setInterval(b, 30))),
|
|
0 === a.status)
|
|
)
|
|
l.disconnect();
|
|
else if (200 !== a.status) m(a);
|
|
else {
|
|
try {
|
|
var t = a.responseText;
|
|
} catch (H) {
|
|
return;
|
|
}
|
|
for (; h < t.length; ) {
|
|
if (h >= k) {
|
|
f = t.substring(k, h);
|
|
var r = t.substring(h, h + 1);
|
|
p.push(f);
|
|
if (';' === r) {
|
|
f = p.shift();
|
|
if (l.oninstruction) l.oninstruction(f, p);
|
|
p.length = 0;
|
|
}
|
|
k = h + 1;
|
|
}
|
|
f = t.indexOf('.', k);
|
|
if (-1 !== f) {
|
|
r = parseInt(t.substring(h + 1, f));
|
|
if (0 === r) {
|
|
c && clearInterval(c);
|
|
a.onreadystatechange = null;
|
|
a.abort();
|
|
d && n(d);
|
|
break;
|
|
}
|
|
k = f + 1;
|
|
h = k + r;
|
|
} else {
|
|
k = t.length;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var c = null,
|
|
d = null,
|
|
f = 0,
|
|
h = -1,
|
|
k = 0,
|
|
p = [];
|
|
a.onreadystatechange =
|
|
1 === q
|
|
? function() {
|
|
3 === a.readyState &&
|
|
(f++, 2 <= f && ((q = 0), (a.onreadystatechange = b)));
|
|
b();
|
|
}
|
|
: b;
|
|
b();
|
|
}
|
|
function g() {
|
|
var a = new XMLHttpRequest();
|
|
a.open('GET', v + l.uuid + ':' + B++);
|
|
a.setRequestHeader('Guacamole-Tunnel-Token', A);
|
|
a.withCredentials = r;
|
|
c(a, x);
|
|
a.send(null);
|
|
return a;
|
|
}
|
|
var l = this,
|
|
p = b + '?connect',
|
|
v = b + '?read:',
|
|
t = b + '?write:',
|
|
q = 1,
|
|
u = !1,
|
|
w = '',
|
|
r = !!a,
|
|
y = null,
|
|
z = null,
|
|
h = null,
|
|
x = d || {},
|
|
A = null;
|
|
this.sendMessage = function() {
|
|
function a(a) {
|
|
a = new String(a);
|
|
return a.length + '.' + a;
|
|
}
|
|
if (l.isConnected() && 0 !== arguments.length) {
|
|
for (var b = a(arguments[0]), c = 1; c < arguments.length; c++)
|
|
b += ',' + a(arguments[c]);
|
|
w += b + ';';
|
|
u || k();
|
|
}
|
|
};
|
|
var B = 0;
|
|
this.connect = function(a) {
|
|
e();
|
|
l.setState(Guacamole.Tunnel.State.CONNECTING);
|
|
var b = new XMLHttpRequest();
|
|
b.onreadystatechange = function() {
|
|
4 === b.readyState &&
|
|
(200 !== b.status
|
|
? m(b)
|
|
: (e(),
|
|
l.setUUID(b.responseText),
|
|
(A = b.getResponseHeader('Guacamole-Tunnel-Token'))
|
|
? (l.setState(Guacamole.Tunnel.State.OPEN),
|
|
(h = setInterval(function() {
|
|
l.sendMessage('nop');
|
|
}, 500)),
|
|
n(g()))
|
|
: f(
|
|
new Guacamole.Status(
|
|
Guacamole.Status.Code.UPSTREAM_NOT_FOUND,
|
|
),
|
|
)));
|
|
};
|
|
b.open('POST', p, !0);
|
|
b.withCredentials = r;
|
|
c(b, x);
|
|
b.setRequestHeader(
|
|
'Content-type',
|
|
'application/x-www-form-urlencoded; charset\x3dUTF-8',
|
|
);
|
|
b.send(a);
|
|
};
|
|
this.disconnect = function() {
|
|
f(new Guacamole.Status(Guacamole.Status.Code.SUCCESS, 'Manually closed.'));
|
|
};
|
|
};
|
|
Guacamole.HTTPTunnel.prototype = new Guacamole.Tunnel();
|
|
Guacamole.WebSocketTunnel = function(b) {
|
|
function a() {
|
|
window.clearTimeout(f);
|
|
window.clearTimeout(k);
|
|
c.state === Guacamole.Tunnel.State.UNSTABLE &&
|
|
c.setState(Guacamole.Tunnel.State.OPEN);
|
|
f = window.setTimeout(function() {
|
|
d(
|
|
new Guacamole.Status(
|
|
Guacamole.Status.Code.UPSTREAM_TIMEOUT,
|
|
'Server timeout.',
|
|
),
|
|
);
|
|
}, c.receiveTimeout);
|
|
k = window.setTimeout(function() {
|
|
c.setState(Guacamole.Tunnel.State.UNSTABLE);
|
|
}, c.unstableThreshold);
|
|
}
|
|
function d(a) {
|
|
window.clearTimeout(f);
|
|
window.clearTimeout(k);
|
|
window.clearInterval(m);
|
|
if (c.state !== Guacamole.Tunnel.State.CLOSED) {
|
|
if (a.code !== Guacamole.Status.Code.SUCCESS && c.onerror) c.onerror(a);
|
|
c.setState(Guacamole.Tunnel.State.CLOSED);
|
|
e.close();
|
|
}
|
|
}
|
|
var c = this,
|
|
e = null,
|
|
f = null,
|
|
k = null,
|
|
m = null,
|
|
n = { 'http:': 'ws:', 'https:': 'wss:' };
|
|
if ('ws:' !== b.substring(0, 3) && 'wss:' !== b.substring(0, 4))
|
|
if (((n = n[window.location.protocol]), '/' === b.substring(0, 1)))
|
|
b = n + '//' + window.location.host + b;
|
|
else {
|
|
var g = window.location.pathname.lastIndexOf('/');
|
|
g = window.location.pathname.substring(0, g + 1);
|
|
b = n + '//' + window.location.host + g + b;
|
|
}
|
|
this.sendMessage = function(a) {
|
|
function b(a) {
|
|
a = new String(a);
|
|
return a.length + '.' + a;
|
|
}
|
|
if (c.isConnected() && 0 !== arguments.length) {
|
|
for (var d = b(arguments[0]), f = 1; f < arguments.length; f++)
|
|
d += ',' + b(arguments[f]);
|
|
e.send(d + ';');
|
|
}
|
|
};
|
|
this.connect = function(f) {
|
|
a();
|
|
c.setState(Guacamole.Tunnel.State.CONNECTING);
|
|
e = new WebSocket(b + '?' + f, 'guacamole');
|
|
e.onopen = function(b) {
|
|
a();
|
|
m = setInterval(function() {
|
|
c.sendMessage(
|
|
Guacamole.Tunnel.INTERNAL_DATA_OPCODE,
|
|
'ping',
|
|
new Date().getTime(),
|
|
);
|
|
}, 500);
|
|
};
|
|
e.onclose = function(a) {
|
|
a.reason
|
|
? d(new Guacamole.Status(parseInt(a.reason), a.reason))
|
|
: a.code
|
|
? d(
|
|
new Guacamole.Status(
|
|
Guacamole.Status.Code.fromWebSocketCode(a.code),
|
|
),
|
|
)
|
|
: d(new Guacamole.Status(Guacamole.Status.Code.UPSTREAM_NOT_FOUND));
|
|
};
|
|
e.onmessage = function(b) {
|
|
a();
|
|
b = b.data;
|
|
var e = 0,
|
|
f = [];
|
|
do {
|
|
var g = b.indexOf('.', e);
|
|
if (-1 !== g) {
|
|
var l = parseInt(b.substring(l + 1, g));
|
|
e = g + 1;
|
|
l = e + l;
|
|
} else
|
|
d(
|
|
new Guacamole.Status(
|
|
Guacamole.Status.Code.SERVER_ERROR,
|
|
'Incomplete instruction.',
|
|
),
|
|
);
|
|
e = b.substring(e, l);
|
|
g = b.substring(l, l + 1);
|
|
f.push(e);
|
|
if (';' === g) {
|
|
e = f.shift();
|
|
null === c.uuid &&
|
|
(e === Guacamole.Tunnel.INTERNAL_DATA_OPCODE && c.setUUID(f[0]),
|
|
c.setState(Guacamole.Tunnel.State.OPEN));
|
|
if (e !== Guacamole.Tunnel.INTERNAL_DATA_OPCODE && c.oninstruction)
|
|
c.oninstruction(e, f);
|
|
f.length = 0;
|
|
}
|
|
e = l + 1;
|
|
} while (e < b.length);
|
|
};
|
|
};
|
|
this.disconnect = function() {
|
|
d(new Guacamole.Status(Guacamole.Status.Code.SUCCESS, 'Manually closed.'));
|
|
};
|
|
};
|
|
Guacamole.WebSocketTunnel.prototype = new Guacamole.Tunnel();
|
|
Guacamole.ChainedTunnel = function(b) {
|
|
function a(b) {
|
|
function k() {
|
|
b.onstatechange = d.onstatechange;
|
|
b.oninstruction = d.oninstruction;
|
|
b.onerror = d.onerror;
|
|
b.onuuid = d.onuuid;
|
|
b.uuid && d.setUUID(b.uuid);
|
|
f = b;
|
|
}
|
|
d.disconnect = b.disconnect;
|
|
d.sendMessage = b.sendMessage;
|
|
var g = function(c) {
|
|
if (c && c.code === Guacamole.Status.Code.UPSTREAM_TIMEOUT)
|
|
return (e = []), null;
|
|
if ((c = e.shift()))
|
|
(b.onerror = null),
|
|
(b.oninstruction = null),
|
|
(b.onstatechange = null),
|
|
a(c);
|
|
return c;
|
|
};
|
|
b.onstatechange = function(a) {
|
|
switch (a) {
|
|
case Guacamole.Tunnel.State.OPEN:
|
|
k();
|
|
if (d.onstatechange) d.onstatechange(a);
|
|
break;
|
|
case Guacamole.Tunnel.State.CLOSED:
|
|
if (!g() && d.onstatechange) d.onstatechange(a);
|
|
}
|
|
};
|
|
b.oninstruction = function(a, b) {
|
|
k();
|
|
if (d.oninstruction) d.oninstruction(a, b);
|
|
};
|
|
b.onerror = function(a) {
|
|
if (!g(a) && d.onerror) d.onerror(a);
|
|
};
|
|
b.connect(c);
|
|
}
|
|
for (var d = this, c, e = [], f = null, k = 0; k < arguments.length; k++)
|
|
e.push(arguments[k]);
|
|
this.connect = function(b) {
|
|
c = b;
|
|
if ((b = f ? f : e.shift())) a(b);
|
|
else if (d.onerror)
|
|
d.onerror(Guacamole.Status.Code.SERVER_ERROR, 'No tunnels to try.');
|
|
};
|
|
};
|
|
Guacamole.ChainedTunnel.prototype = new Guacamole.Tunnel();
|
|
Guacamole.StaticHTTPTunnel = function(b, a, d) {
|
|
function c(a, b) {
|
|
for (var c in b) a.setRequestHeader(c, b[c]);
|
|
}
|
|
var e = this,
|
|
f = null,
|
|
k = d || {};
|
|
this.sendMessage = function(a) {};
|
|
this.connect = function(d) {
|
|
e.disconnect();
|
|
e.setState(Guacamole.Tunnel.State.CONNECTING);
|
|
f = new XMLHttpRequest();
|
|
f.open('GET', b);
|
|
f.withCredentials = !!a;
|
|
c(f, k);
|
|
f.responseType = 'text';
|
|
f.send(null);
|
|
var m = 0,
|
|
g = new Guacamole.Parser();
|
|
g.oninstruction = function(a, b) {
|
|
if (e.oninstruction) e.oninstruction(a, b);
|
|
};
|
|
f.onreadystatechange = function() {
|
|
if (3 === f.readyState || 4 === f.readyState) {
|
|
e.setState(Guacamole.Tunnel.State.OPEN);
|
|
var a = f.responseText,
|
|
b = a.length;
|
|
m < b && (g.receive(a.substring(m)), (m = b));
|
|
}
|
|
4 === f.readyState && e.disconnect();
|
|
};
|
|
f.onerror = function() {
|
|
if (e.onerror)
|
|
e.onerror(
|
|
new Guacamole.Status(
|
|
Guacamole.Status.Code.fromHTTPCode(f.status),
|
|
f.statusText,
|
|
),
|
|
);
|
|
e.disconnect();
|
|
};
|
|
};
|
|
this.disconnect = function() {
|
|
f && (f.abort(), (f = null));
|
|
e.setState(Guacamole.Tunnel.State.CLOSED);
|
|
};
|
|
};
|
|
Guacamole.StaticHTTPTunnel.prototype = new Guacamole.Tunnel();
|
|
Guacamole = Guacamole || {};
|
|
Guacamole.API_VERSION = '1.4.0';
|
|
Guacamole = Guacamole || {};
|
|
Guacamole.VideoPlayer = function() {
|
|
this.sync = function() {};
|
|
};
|
|
Guacamole.VideoPlayer.isSupportedType = function(b) {
|
|
return !1;
|
|
};
|
|
Guacamole.VideoPlayer.getSupportedTypes = function() {
|
|
return [];
|
|
};
|
|
Guacamole.VideoPlayer.getInstance = function(b, a, d) {
|
|
return null;
|
|
};
|