@alan-ai/alan-sdk-web 1.8.32 → 1.8.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AlanButton.d.ts +2 -0
- package/dist/alan_lib.js +62 -32
- package/dist/alan_lib.min.js +1 -1
- package/package.json +1 -1
- package/dist/.DS_Store +0 -0
package/dist/AlanButton.d.ts
CHANGED
package/dist/alan_lib.js
CHANGED
|
@@ -208,7 +208,7 @@
|
|
|
208
208
|
|
|
209
209
|
function ConnectionWrapper() {
|
|
210
210
|
var _this = this;
|
|
211
|
-
this._worker = new Worker(window.URL.createObjectURL(new Blob(["(function(ns) {\n 'use strict';\n\n var SENT_TS = 1;\n var REMOTE_TS = 2;\n var TIMESTAMP = 3;\n var AUDIO_DATA = 4;\n var JSON_DATA = 5;\n\n AlanFrame.fields = [\n propUint64(SENT_TS, 'sentTs'),\n propUint64(REMOTE_TS, 'remoteTs'),\n propUint64(TIMESTAMP, 'timestamp'),\n propBytes(AUDIO_DATA, 'audioData'),\n propJson(JSON_DATA, 'jsonData'),\n ];\n\n function AlanFrameProp(type, name, sizeF, readF, writeF) {\n this.type = type;\n this.name = name;\n this.sizeF = sizeF;\n this.writeF = writeF;\n this.readF = readF;\n }\n\n function fixedSize(size) {\n return function() {\n return size;\n }\n }\n\n function bufferSize(buffer) {\n return 4 + byteLength(buffer);\n }\n\n function writeUIntN(uint8array, value, nBytes, offset) {\n for (var i = 0; i < nBytes; i++ ) {\n uint8array[offset + i] = 0xFF & value;\n value /= 256;\n }\n }\n\n function readUIntN(uint8array, nBytes, offset) {\n var r = 0;\n for (var i = nBytes - 1; i >= 0; i-- ) {\n r *= 256;\n r += 0xFF & uint8array[offset + i];\n }\n return r;\n }\n\n function writeUInt64(uint8array, value, offset) {\n writeUIntN(uint8array, value, 8, offset);\n }\n\n function readUInt64(uint8array, offset) {\n return readUIntN(uint8array, 8, offset);\n }\n\n function writeUInt32(uint8array, value, offset) {\n writeUIntN(uint8array, value, 4, offset);\n }\n\n function readUInt32(uint8array, offset) {\n return readUIntN(uint8array, 4, offset);\n }\n\n function writeBuffer(uint8array, buffer, offset) {\n buffer = toUint8(buffer);\n writeUInt32(uint8array, buffer.length, offset);\n for (var i = 0; i < buffer.length; i++ ) {\n uint8array[offset + 4 + i] = buffer[i];\n }\n }\n\n function readBuffer(uint8array, offset) {\n var size = readUInt32(uint8array, offset);\n if (size > 1024 * 1024) {\n throw new Error('buffer too big');\n }\n return uint8array.subarray(offset + 4, offset + 4 + size);\n }\n\n function readUTF8(uint8array, offset) {\n var size = readUInt32(uint8array, offset);\n if (size > 1024 * 1024) {\n throw new Error('string too big');\n }\n return String.fromCharCode.apply(null, uint8array.slice(offset + 4, offset + 4 + size));\n }\n\n function writeUTF8(uint8array, string, offset) {\n writeUInt32(uint8array, string.length, offset);\n for (var i = 0; i < string.length; i++ ) {\n uint8array[offset + 4 + i] = string.charCodeAt(i);\n }\n }\n\n function sizeUTF8(string) {\n return 4 + string.length;\n }\n\n function propUint32(type, name) {\n return new AlanFrameProp(type, name, fixedSize(4), readUInt32, writeUInt32);\n }\n\n function propUint64(type, name) {\n return new AlanFrameProp(type, name, fixedSize(8), readUInt64, writeUInt64);\n }\n\n function propBytes(type, name) {\n return new AlanFrameProp(type, name, bufferSize, readBuffer, writeBuffer);\n }\n\n function propJson(type, name) {\n return new AlanFrameProp(type, name, sizeUTF8, readUTF8, writeUTF8);\n }\n\n AlanFrame.fieldByType = function(type) {\n for (var i = 0; i < AlanFrame.fields.length; i++ ) {\n var frame = AlanFrame.fields[i];\n if (frame.type === type) {\n return frame;\n }\n }\n throw new Error('invalid field: ' + type);\n };\n\n function AlanFrame() {\n this.version = 1;\n }\n\n AlanFrame.prototype.write = function() {\n var result = new Uint8Array(this.writeSize());\n var offset = 1;\n result[0] = 1;\n for (var i = 0; i < AlanFrame.fields.length; i++ ) {\n var field = AlanFrame.fields[i];\n var value = this[field.name];\n if (value) {\n result[offset++] = field.type;\n field.writeF(result, value, offset);\n offset += field.sizeF(value);\n }\n }\n return result.buffer;\n };\n\n /**\n * @returns UInt8Array\n */\n AlanFrame.prototype.writeSize = function() {\n var size = 1;\n for (var i = 0; i < AlanFrame.fields.length; i++ ) {\n var field = AlanFrame.fields[i];\n var value = this[field.name];\n if (value) {\n size += 1 + field.sizeF(value);\n }\n }\n return size;\n };\n\n AlanFrame.prototype.toString = function() {\n var first = true, str = '';\n for (var k in this) {\n if (this.hasOwnProperty(k)) {\n if (first) {\n str += k + ' = ';\n first = false;\n } else {\n str += ', ' + k + ' = ';\n }\n var v = this[k];\n if (typeof(v) === 'object') {\n str += 'bytes[' + byteLength(v) + ']';\n } else {\n str += v;\n }\n }\n }\n return str;\n };\n\n function byteLength(b) {\n if (b instanceof Uint8Array) {\n return b.length;\n }\n if (b instanceof ArrayBuffer) {\n return b.byteLength;\n }\n }\n\n function toArrayBuffer(buffer) {\n if (buffer instanceof ArrayBuffer) {\n return buffer;\n }\n return buffer.buffer;\n }\n\n function toUint8(buffer) {\n if (buffer instanceof Uint8Array) {\n return buffer;\n }\n if (buffer instanceof ArrayBuffer) {\n return new Uint8Array(buffer);\n }\n throw new Error('invalid buffer type');\n }\n\n function parse(uint8array) {\n uint8array = toUint8(uint8array);\n var r = new AlanFrame();\n var offset = 0;\n r.version = uint8array[offset++];\n while (offset < uint8array.length) {\n var frame = AlanFrame.fieldByType(uint8array[offset++]);\n r[frame.name] = frame.readF(uint8array, offset);\n offset += frame.sizeF(r[frame.name]);\n }\n return r;\n }\n\n ns.create = function() {\n return new AlanFrame();\n };\n\n ns.parse = parse;\n\n})(typeof(window) !== 'undefined' ? (function() {window.alanFrame = {}; return window.alanFrame; })() :\n typeof(WorkerGlobalScope) !== 'undefined' ? (function() {alanFrame = {}; return alanFrame; })() :\n exports);\n\n\n'use strict';\n\nvar ALAN_OFF = 'off';\nvar ALAN_SPEAKING = 'speaking';\nvar ALAN_LISTENING = 'listening';\n\nfunction ConnectionImpl(config, auth, mode) {\n var _this = this;\n this._config = config;\n this._auth = auth;\n this._mode = mode;\n this._projectId = config.projectId;\n this._url = config.url;\n this._connected = false;\n this._authorized = false;\n this._dialogId = null;\n this._callId = 1;\n this._callSent = {};\n this._callWait = [];\n this._failed = false;\n this._closed = false;\n this._reconnectTimeout = 100;\n this._cleanups = [];\n this._format = null;\n this._formatSent = false;\n this._frameQueue = [];\n this._remoteSentTs = 0;\n this._remoteRecvTs = 0;\n this._rtt = 25;\n this._rttAlpha = 1./16;\n this._alanState = ALAN_OFF;\n this._sendTimer = setInterval(_this._flushQueue.bind(_this), 50);\n this._visualState = {};\n this._addCleanup(function() {clearInterval(_this._sendTimer);});\n this._connect();\n console.log('Alan: connection created');\n}\n\nConnectionImpl.prototype._addCleanup = function(f) {\n this._cleanups.push(f);\n};\n\nConnectionImpl.prototype._onConnectStatus = function(s) {\n console.log('Alan: connection status - ' + s);\n this._fire('connectStatus', s);\n};\n\nConnectionImpl.prototype._fire = function(event, object) {\n if (event === 'options') {\n if (object.versions) {\n object.versions['alanbase:web'] = this._config.version;\n }\n }\n postMessage(['fireEvent', event, object]);\n};\n\nConnectionImpl.prototype._connect = function() {\n var _this = this;\n if (this._socket) {\n console.error('socket is already connected');\n return;\n }\n console.log('Alan: connecting - ' + getConnectionDetails(this._url));\n this._socket = new WebSocket(this._url);\n this._socket.binaryType = 'arraybuffer';\n this._socket.onopen = function(e) {\n console.info('Alan: connected');\n _this._connected = true;\n _this._reconnectTimeout = 100;\n _this._fire('connection', {status: 'connected'});\n if (_this._auth) {\n _this._fire('connection', {status: 'authorizing'});\n _this._callAuth();\n } else {\n _this._callWait.forEach(function(c) { _this._sendCall(c); });\n _this._callWait = [];\n }\n };\n this._socket.onmessage = function(msg) {\n if (msg.data instanceof ArrayBuffer) {\n var f = alanFrame.parse(msg.data);\n if (f.sentTs > 0) {\n _this._remoteSentTs = f.sentTs;\n _this._remoteRecvTs = Date.now();\n } else {\n _this._remoteSentTs = null;\n _this._remoteRecvTs = null;\n }\n var rtt = 0;\n if (f.remoteTs) {\n rtt = Date.now() - f.remoteTs;\n }\n _this._rtt = _this._rttAlpha * rtt + (1 - _this._rttAlpha) * _this._rtt;\n var uint8 = new Uint8Array(f.audioData);\n var frame = [];\n var batch = 10000;\n for (var offset = 0; offset < uint8.byteLength; offset += batch) {\n var b = uint8.subarray(offset, Math.min(uint8.byteLength, offset + batch));\n let a = String.fromCharCode.apply(null, b);\n frame.push(a);\n }\n frame = frame.join('');\n postMessage(['alanAudio', 'playFrame', frame]);\n } else if (typeof(msg.data) === 'string') {\n msg = JSON.parse(msg.data);\n if (msg.i) {\n var c = _this._callSent[msg.i];\n delete _this._callSent[msg.i];\n if (c && c.callback) {\n c.callback(msg.e, msg.r);\n }\n } else if (msg.e) {\n if (msg.e === 'text') {\n postMessage(['alanAudio', 'playText', msg.p]);\n } else if (msg.e === 'showPopup') {\n postMessage(['alanAudio', 'showPopup', msg.p]);\n } else if (msg.e === 'command') {\n postMessage(['alanAudio', 'playCommand', msg.p]);\n } else if (msg.e === 'inactivity') {\n postMessage(['alanAudio', 'stop']);\n } else {\n _this._fire(msg.e, msg.p);\n }\n }\n } else {\n console.error('invalid message type');\n }\n };\n this._socket.onerror = function(evt) {\n console.error('Alan: connection closed due to error: ', evt);\n };\n this._socket.onclose = function(evt) {\n console.info('Alan: connection closed');\n _this._connected = false;\n _this._authorized = false;\n _this._socket = null;\n _this._onConnectStatus('disconnected');\n if (!_this._failed && _this._reconnectTimeout && !_this._closed) {\n console.log('Alan: reconnecting in %s ms.', _this._reconnectTimeout);\n _this._reConnect = setTimeout(_this._connect.bind(_this), _this._reconnectTimeout);\n if (_this._reconnectTimeout < 3000) {\n _this._reconnectTimeout *= 2;\n } else {\n _this._reconnectTimeout += 500;\n }\n _this._reconnectTimeout = Math.min(7000, _this._reconnectTimeout);\n }\n };\n this._addCleanup(function() {\n if (this._socket) {\n this._socket.close();\n this._socket = null;\n }\n });\n};\n\nConnectionImpl.prototype._callAuth = function() {\n var _this = this;\n var callback = function(err, r) {\n if (!err && r.status === 'authorized') {\n _this._authorized = true;\n _this._formatSent = false;\n if (r.dialogId) {\n postMessage(['setDialogId', r.dialogId]);\n _this._dialogId = r.dialogId;\n }\n _this._onAuthorized();\n _this._onConnectStatus('authorized');\n } else if (err === 'auth-failed') {\n _this._onConnectStatus('auth-failed');\n if (_this._socket) {\n _this._socket.close();\n _this._socket = null;\n _this._failed = true;\n }\n } else {\n _this._onConnectStatus('invalid-auth-response');\n console.log('Alan: invalid auth response', err, r);\n }\n };\n var authParam = this._auth;\n authParam.timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n if (this._dialogId) {\n authParam.dialogId = this._dialogId;\n }\n authParam.mode = this._mode;\n this._sendCall({cid: this._callId++, method: '_auth_', callback: callback, param: authParam});\n return this;\n};\n\nConnectionImpl.prototype._sendCall = function(call) {\n this._sendFormatIfNeeded(false);\n this._socket.send(JSON.stringify({i: call.cid, m: call.method, p: call.param}));\n if (call.callback) {\n this._callSent[call.cid] = call;\n }\n};\n\nConnectionImpl.prototype._onAuthorized = function() {\n var _this = this;\n this._callWait.forEach(function(c) {\n _this._sendCall(c);\n });\n this._callWait = [];\n};\n\nConnectionImpl.prototype.close = function() {\n for (var i = 0; i < this._cleanups.length; i++ ) {\n this._cleanups[i]();\n }\n this._cleanups = [];\n this._closed = true;\n \n if (this._socket && (this._socket.readyState === WebSocket.OPEN || this._socket.readyState === WebSocket.CONNECTING)) {\n this._socket.close();\n this._socket = null;\n }\n console.log('Alan: closed connection to: ' + getConnectionDetails(this._url));\n //close(); TODO: delete it!\n};\n\nConnectionImpl.prototype.call = function(cid, method, param) {\n var call = {cid: cid, method: method, param: param, callback: function(err, obj) {\n if (cid) {\n postMessage(['callback', cid, err, obj]);\n }\n }};\n if (this._authorized || this._connected && !this._auth) {\n this._sendCall(call);\n } else {\n this._callWait.push(call);\n }\n};\n\nConnectionImpl.prototype.setVisual = function(state) {\n this._visualState = state;\n this.call(null, '_visual_', state);\n};\n\nConnectionImpl.prototype._sendFrame = function(frame) {\n if (!this._socket) {\n console.error('sendFrame to closed socket');\n return;\n }\n frame.sentTs = Date.now();\n if (this._remoteSentTs > 0 && this._remoteRecvTs > 0) {\n frame.remoteTs = this._remoteSentTs + Date.now() - this._remoteRecvTs;\n }\n this._socket.send(frame.write());\n};\n\nConnectionImpl.prototype._listen = function() {\n var f = alanFrame.create();\n f.jsonData = JSON.stringify({signal: 'listen'});\n this._frameQueue.push(f);\n this._alanState = ALAN_LISTENING;\n};\n\nConnectionImpl.prototype._stopListen = function() {\n var f = alanFrame.create();\n f.jsonData = JSON.stringify({signal: 'stopListen'});\n this._frameQueue.push(f);\n this._alanState = ALAN_OFF;\n};\n\nConnectionImpl.prototype._onAudioFormat = function(format) {\n this._formatSent = false;\n this._format = format;\n};\n\nConnectionImpl.prototype._onMicFrame = function(sampleRate, frame) {\n if (this._alanState === ALAN_SPEAKING) {\n return;\n }\n if (this._alanState === ALAN_OFF) {\n this._listen();\n }\n if (this._alanState !== ALAN_LISTENING) {\n console.error('invalid alan state: ' + this._alanState);\n return;\n }\n this._sendFormatIfNeeded(true);\n var f = alanFrame.create();\n f.audioData = frame;\n this._frameQueue.push(f);\n};\n\nConnectionImpl.prototype._sendFormatIfNeeded = function(inQueue) {\n if (!this._format || this._formatSent) {\n return;\n }\n this._formatSent = true;\n var f = alanFrame.create();\n f.jsonData = JSON.stringify({format: this._format});\n if (inQueue) {\n this._frameQueue.push(f);\n } else {\n this._sendFrame(f);\n }\n};\n\nConnectionImpl.prototype._flushQueue = function() {\n if (!this._socket || !this._connected) {\n var d = 0;\n while (this._frameQueue.length > 100 && !this._frameQueue[0].jsonData) {\n this._frameQueue.shift();\n d++;\n }\n if (d > 0) {\n console.error('dropped: %s, frames', d);\n }\n return;\n }\n while (this._frameQueue.length > 0 && this._socket && this._socket.bufferedAmount < 64 * 1024) {\n this._sendFrame(this._frameQueue.shift());\n }\n};\n\nfunction getConnectionDetails(url){\n var urlParts = url.split('/');\n var projectId = urlParts[4];\n var environment = urlParts[5];\n var host = urlParts[2];\n\n if (projectId && environment && host) {\n return ' (ProjectID: ' + projectId + ', environment: ' + environment + ', host: ' + host + ')';\n }\n\n return url;\n}\n\nfunction connectProject(config, auth, mode) {\n var c = new ConnectionImpl(config, auth, mode);\n c.onAudioEvent = function(event, arg1, arg2) {\n if (event === 'format') {\n c._onAudioFormat(arg1);\n } else if (event === 'frame') {\n c._onMicFrame(arg1, arg2);\n } else if (event === 'micStop' || event === 'playStart') {\n c._stopListen();\n } else {\n console.error('unknown audio event: ' + event, arg1, arg2);\n }\n };\n return c;\n}\n\nvar factories = {\n connectProject: connectProject,\n};\n\nvar currentConnect = null;\n\nonmessage = function(e) {\n var name = e.data[0];\n try {\n if (!currentConnect) {\n currentConnect = factories[name].apply(null, e.data.slice(1, e.data.length));\n } else {\n currentConnect[name].apply(currentConnect, e.data.slice(1, e.data.length));\n }\n } catch(e) {\n console.error('error calling: ' + name, e);\n }\n};\n"]),{type: 'text/javascript'}));
|
|
211
|
+
this._worker = new Worker(window.URL.createObjectURL(new Blob(["(function(ns) {\n 'use strict';\n\n var SENT_TS = 1;\n var REMOTE_TS = 2;\n var TIMESTAMP = 3;\n var AUDIO_DATA = 4;\n var JSON_DATA = 5;\n\n AlanFrame.fields = [\n propUint64(SENT_TS, 'sentTs'),\n propUint64(REMOTE_TS, 'remoteTs'),\n propUint64(TIMESTAMP, 'timestamp'),\n propBytes(AUDIO_DATA, 'audioData'),\n propJson(JSON_DATA, 'jsonData'),\n ];\n\n function AlanFrameProp(type, name, sizeF, readF, writeF) {\n this.type = type;\n this.name = name;\n this.sizeF = sizeF;\n this.writeF = writeF;\n this.readF = readF;\n }\n\n function fixedSize(size) {\n return function() {\n return size;\n }\n }\n\n function bufferSize(buffer) {\n return 4 + byteLength(buffer);\n }\n\n function writeUIntN(uint8array, value, nBytes, offset) {\n for (var i = 0; i < nBytes; i++ ) {\n uint8array[offset + i] = 0xFF & value;\n value /= 256;\n }\n }\n\n function readUIntN(uint8array, nBytes, offset) {\n var r = 0;\n for (var i = nBytes - 1; i >= 0; i-- ) {\n r *= 256;\n r += 0xFF & uint8array[offset + i];\n }\n return r;\n }\n\n function writeUInt64(uint8array, value, offset) {\n writeUIntN(uint8array, value, 8, offset);\n }\n\n function readUInt64(uint8array, offset) {\n return readUIntN(uint8array, 8, offset);\n }\n\n function writeUInt32(uint8array, value, offset) {\n writeUIntN(uint8array, value, 4, offset);\n }\n\n function readUInt32(uint8array, offset) {\n return readUIntN(uint8array, 4, offset);\n }\n\n function writeBuffer(uint8array, buffer, offset) {\n buffer = toUint8(buffer);\n writeUInt32(uint8array, buffer.length, offset);\n for (var i = 0; i < buffer.length; i++ ) {\n uint8array[offset + 4 + i] = buffer[i];\n }\n }\n\n function readBuffer(uint8array, offset) {\n var size = readUInt32(uint8array, offset);\n if (size > 1024 * 1024) {\n throw new Error('buffer too big');\n }\n return uint8array.subarray(offset + 4, offset + 4 + size);\n }\n\n function readUTF8(uint8array, offset) {\n var size = readUInt32(uint8array, offset);\n if (size > 1024 * 1024) {\n throw new Error('string too big');\n }\n return String.fromCharCode.apply(null, uint8array.slice(offset + 4, offset + 4 + size));\n }\n\n function writeUTF8(uint8array, string, offset) {\n writeUInt32(uint8array, string.length, offset);\n for (var i = 0; i < string.length; i++ ) {\n uint8array[offset + 4 + i] = string.charCodeAt(i);\n }\n }\n\n function sizeUTF8(string) {\n return 4 + string.length;\n }\n\n function propUint32(type, name) {\n return new AlanFrameProp(type, name, fixedSize(4), readUInt32, writeUInt32);\n }\n\n function propUint64(type, name) {\n return new AlanFrameProp(type, name, fixedSize(8), readUInt64, writeUInt64);\n }\n\n function propBytes(type, name) {\n return new AlanFrameProp(type, name, bufferSize, readBuffer, writeBuffer);\n }\n\n function propJson(type, name) {\n return new AlanFrameProp(type, name, sizeUTF8, readUTF8, writeUTF8);\n }\n\n AlanFrame.fieldByType = function(type) {\n for (var i = 0; i < AlanFrame.fields.length; i++ ) {\n var frame = AlanFrame.fields[i];\n if (frame.type === type) {\n return frame;\n }\n }\n throw new Error('invalid field: ' + type);\n };\n\n function AlanFrame() {\n this.version = 1;\n }\n\n AlanFrame.prototype.write = function() {\n var result = new Uint8Array(this.writeSize());\n var offset = 1;\n result[0] = 1;\n for (var i = 0; i < AlanFrame.fields.length; i++ ) {\n var field = AlanFrame.fields[i];\n var value = this[field.name];\n if (value) {\n result[offset++] = field.type;\n field.writeF(result, value, offset);\n offset += field.sizeF(value);\n }\n }\n return result.buffer;\n };\n\n /**\n * @returns UInt8Array\n */\n AlanFrame.prototype.writeSize = function() {\n var size = 1;\n for (var i = 0; i < AlanFrame.fields.length; i++ ) {\n var field = AlanFrame.fields[i];\n var value = this[field.name];\n if (value) {\n size += 1 + field.sizeF(value);\n }\n }\n return size;\n };\n\n AlanFrame.prototype.toString = function() {\n var first = true, str = '';\n for (var k in this) {\n if (this.hasOwnProperty(k)) {\n if (first) {\n str += k + ' = ';\n first = false;\n } else {\n str += ', ' + k + ' = ';\n }\n var v = this[k];\n if (typeof(v) === 'object') {\n str += 'bytes[' + byteLength(v) + ']';\n } else {\n str += v;\n }\n }\n }\n return str;\n };\n\n function byteLength(b) {\n if (b instanceof Uint8Array) {\n return b.length;\n }\n if (b instanceof ArrayBuffer) {\n return b.byteLength;\n }\n }\n\n function toArrayBuffer(buffer) {\n if (buffer instanceof ArrayBuffer) {\n return buffer;\n }\n return buffer.buffer;\n }\n\n function toUint8(buffer) {\n if (buffer instanceof Uint8Array) {\n return buffer;\n }\n if (buffer instanceof ArrayBuffer) {\n return new Uint8Array(buffer);\n }\n throw new Error('invalid buffer type');\n }\n\n function parse(uint8array) {\n uint8array = toUint8(uint8array);\n var r = new AlanFrame();\n var offset = 0;\n r.version = uint8array[offset++];\n while (offset < uint8array.length) {\n var frame = AlanFrame.fieldByType(uint8array[offset++]);\n r[frame.name] = frame.readF(uint8array, offset);\n offset += frame.sizeF(r[frame.name]);\n }\n return r;\n }\n\n ns.create = function() {\n return new AlanFrame();\n };\n\n ns.parse = parse;\n\n})(typeof(window) !== 'undefined' ? (function() {window.alanFrame = {}; return window.alanFrame; })() :\n typeof(WorkerGlobalScope) !== 'undefined' ? (function() {alanFrame = {}; return alanFrame; })() :\n exports);\n\n\n'use strict';\n\n\n\nvar ALAN_OFF = 'off';\nvar ALAN_SPEAKING = 'speaking';\nvar ALAN_LISTENING = 'listening';\n\nfunction ConnectionImpl(config, auth, mode) {\n var _this = this;\n this._config = config;\n this._auth = auth;\n this._mode = mode;\n this._projectId = config.projectId;\n this._url = config.url;\n this._connected = false;\n this._authorized = false;\n this._dialogId = null;\n this._callId = 1;\n this._callSent = {};\n this._callWait = [];\n this._failed = false;\n this._closed = false;\n this._reconnectTimeout = 100;\n this._cleanups = [];\n this._format = null;\n this._formatSent = false;\n this._frameQueue = [];\n this._remoteSentTs = 0;\n this._remoteRecvTs = 0;\n this._rtt = 25;\n this._rttAlpha = 1./16;\n this._alanState = ALAN_OFF;\n this._sendTimer = setInterval(_this._flushQueue.bind(_this), 50);\n this._visualState = {};\n this._addCleanup(function() {clearInterval(_this._sendTimer);});\n this._connect();\n console.log('Alan: connection created');\n}\n\nConnectionImpl.prototype._addCleanup = function(f) {\n this._cleanups.push(f);\n};\n\nConnectionImpl.prototype._onConnectStatus = function(s) {\n console.log('Alan: connection status - ' + s);\n this._fire('connectStatus', s);\n};\n\nConnectionImpl.prototype._fire = function(event, object) {\n if (event === 'options') {\n if (object.versions) {\n object.versions['alanbase:web'] = this._config.version;\n }\n }\n postMessage(['fireEvent', event, object]);\n};\n\nConnectionImpl.prototype._connect = function() {\n var _this = this;\n if (this._socket) {\n console.error('socket is already connected');\n return;\n }\n console.log('Alan: connecting - ' + getConnectionDetails(this._url));\n this._socket = new WebSocket(this._url);\n this._socket.binaryType = 'arraybuffer';\n this._socket.onopen = function(e) {\n console.info('Alan: connected');\n _this._connected = true;\n _this._reconnectTimeout = 100;\n _this._fire('connection', {status: 'connected'});\n if (_this._auth) {\n _this._fire('connection', {status: 'authorizing'});\n _this._callAuth();\n } else {\n _this._callWait.forEach(function(c) { _this._sendCall(c); });\n _this._callWait = [];\n }\n };\n this._socket.onmessage = function(msg) {\n if (msg.data instanceof ArrayBuffer) {\n var f = alanFrame.parse(msg.data);\n if (f.sentTs > 0) {\n _this._remoteSentTs = f.sentTs;\n _this._remoteRecvTs = Date.now();\n } else {\n _this._remoteSentTs = null;\n _this._remoteRecvTs = null;\n }\n var rtt = 0;\n if (f.remoteTs) {\n rtt = Date.now() - f.remoteTs;\n }\n _this._rtt = _this._rttAlpha * rtt + (1 - _this._rttAlpha) * _this._rtt;\n var uint8 = new Uint8Array(f.audioData);\n var frame = [];\n var batch = 10000;\n for (var offset = 0; offset < uint8.byteLength; offset += batch) {\n var b = uint8.subarray(offset, Math.min(uint8.byteLength, offset + batch));\n let a = String.fromCharCode.apply(null, b);\n frame.push(a);\n }\n frame = frame.join('');\n postMessage(['alanAudio', 'playFrame', frame]);\n } else if (typeof(msg.data) === 'string') {\n msg = JSON.parse(msg.data);\n if (msg.i) {\n var c = _this._callSent[msg.i];\n delete _this._callSent[msg.i];\n if (c && c.callback) {\n c.callback(msg.e, msg.r);\n }\n } else if (msg.e) {\n if (msg.e === 'text') {\n postMessage(['alanAudio', 'playText', msg.p]);\n } else if (msg.e === 'showPopup') {\n postMessage(['alanAudio', 'showPopup', msg.p]);\n } else if (msg.e === 'command') {\n postMessage(['alanAudio', 'playCommand', msg.p]);\n } else if (msg.e === 'inactivity') {\n postMessage(['alanAudio', 'stop']);\n } else {\n _this._fire(msg.e, msg.p);\n }\n }\n } else {\n console.error('invalid message type');\n }\n };\n this._socket.onerror = function(evt) {\n console.error('Alan: connection closed due to error: ', evt);\n };\n this._socket.onclose = function(evt) {\n console.info('Alan: connection closed');\n _this._connected = false;\n _this._authorized = false;\n _this._socket = null;\n _this._onConnectStatus('disconnected');\n if (!_this._failed && _this._reconnectTimeout && !_this._closed) {\n console.log('Alan: reconnecting in %s ms.', _this._reconnectTimeout);\n _this._reConnect = setTimeout(_this._connect.bind(_this), _this._reconnectTimeout);\n if (_this._reconnectTimeout < 3000) {\n _this._reconnectTimeout *= 2;\n } else {\n _this._reconnectTimeout += 500;\n }\n _this._reconnectTimeout = Math.min(7000, _this._reconnectTimeout);\n }\n };\n this._addCleanup(function() {\n if (this._socket) {\n this._socket.close();\n this._socket = null;\n }\n });\n};\n\nConnectionImpl.prototype._callAuth = function() {\n var _this = this;\n var callback = function(err, r) {\n if (!err && r.status === 'authorized') {\n _this._authorized = true;\n _this._formatSent = false;\n if (r.dialogId) {\n postMessage(['setDialogId', r.dialogId]);\n _this._dialogId = r.dialogId;\n }\n _this._onAuthorized();\n _this._onConnectStatus('authorized');\n } else if (err === 'auth-failed') {\n _this._onConnectStatus('auth-failed');\n if (_this._socket) {\n _this._socket.close();\n _this._socket = null;\n _this._failed = true;\n }\n } else {\n _this._onConnectStatus('invalid-auth-response');\n console.log('Alan: invalid auth response', err, r);\n }\n };\n var authParam = this._auth;\n authParam.timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n if (this._dialogId) {\n authParam.dialogId = this._dialogId;\n }\n authParam.mode = this._mode;\n this._sendCall({cid: this._callId++, method: '_auth_', callback: callback, param: authParam});\n return this;\n};\n\nConnectionImpl.prototype._sendCall = function(call) {\n this._sendFormatIfNeeded(false);\n this._socket.send(JSON.stringify({i: call.cid, m: call.method, p: call.param}));\n if (call.callback) {\n this._callSent[call.cid] = call;\n }\n};\n\nConnectionImpl.prototype._onAuthorized = function() {\n var _this = this;\n this._callWait.forEach(function(c) {\n _this._sendCall(c);\n });\n this._callWait = [];\n};\n\nConnectionImpl.prototype.close = function() {\n for (var i = 0; i < this._cleanups.length; i++ ) {\n this._cleanups[i]();\n }\n this._cleanups = [];\n this._closed = true;\n \n if (this._socket && (this._socket.readyState === WebSocket.OPEN || this._socket.readyState === WebSocket.CONNECTING)) {\n this._socket.close();\n this._socket = null;\n }\n console.log('Alan: closed connection to: ' + getConnectionDetails(this._url));\n //close(); TODO: delete it!\n};\n\nConnectionImpl.prototype.call = function(cid, method, param) {\n var call = {cid: cid, method: method, param: param, callback: function(err, obj) {\n if (cid) {\n postMessage(['callback', cid, err, obj]);\n }\n }};\n if (this._authorized || this._connected && !this._auth) {\n this._sendCall(call);\n } else {\n this._callWait.push(call);\n }\n};\n\nConnectionImpl.prototype.setVisual = function(state) {\n this._visualState = state;\n this.call(null, '_visual_', state);\n};\n\nConnectionImpl.prototype._sendFrame = function(frame) {\n if (!this._socket) {\n console.error('sendFrame to closed socket');\n return;\n }\n frame.sentTs = Date.now();\n if (this._remoteSentTs > 0 && this._remoteRecvTs > 0) {\n frame.remoteTs = this._remoteSentTs + Date.now() - this._remoteRecvTs;\n }\n this._socket.send(frame.write());\n};\n\nConnectionImpl.prototype._listen = function() {\n var f = alanFrame.create();\n f.jsonData = JSON.stringify({signal: 'listen'});\n this._frameQueue.push(f);\n this._alanState = ALAN_LISTENING;\n};\n\nConnectionImpl.prototype._stopListen = function() {\n var f = alanFrame.create();\n f.jsonData = JSON.stringify({signal: 'stopListen'});\n this._frameQueue.push(f);\n this._alanState = ALAN_OFF;\n};\n\nConnectionImpl.prototype._onAudioFormat = function(format) {\n this._formatSent = false;\n this._format = format;\n};\n\nConnectionImpl.prototype._onMicFrame = function(sampleRate, frame) {\n if (this._alanState === ALAN_SPEAKING) {\n return;\n }\n if (this._alanState === ALAN_OFF) {\n this._listen();\n }\n if (this._alanState !== ALAN_LISTENING) {\n console.error('invalid alan state: ' + this._alanState);\n return;\n }\n this._sendFormatIfNeeded(true);\n var f = alanFrame.create();\n f.audioData = frame;\n this._frameQueue.push(f);\n};\n\nConnectionImpl.prototype._sendFormatIfNeeded = function(inQueue) {\n if (!this._format || this._formatSent) {\n return;\n }\n this._formatSent = true;\n var f = alanFrame.create();\n f.jsonData = JSON.stringify({format: this._format});\n if (inQueue) {\n this._frameQueue.push(f);\n } else {\n this._sendFrame(f);\n }\n};\n\nConnectionImpl.prototype._flushQueue = function() {\n if (!this._socket || !this._connected) {\n var d = 0;\n while (this._frameQueue.length > 100 && !this._frameQueue[0].jsonData) {\n this._frameQueue.shift();\n d++;\n }\n if (d > 0) {\n console.error('dropped: %s, frames', d);\n }\n return;\n }\n while (this._frameQueue.length > 0 && this._socket && this._socket.bufferedAmount < 64 * 1024) {\n this._sendFrame(this._frameQueue.shift());\n }\n};\n\nfunction getConnectionDetails(url){\n var urlParts = url.split('/');\n var projectId = urlParts[4];\n var environment = urlParts[5];\n var host = urlParts[2];\n\n if (projectId && environment && host) {\n return ' (ProjectID: ' + projectId + ', environment: ' + environment + ', host: ' + host + ')';\n }\n\n return url;\n}\n\nfunction connectProject(config, auth, mode) {\n var c = new ConnectionImpl(config, auth, mode);\n c.onAudioEvent = function(event, arg1, arg2) {\n if (event === 'format') {\n c._onAudioFormat(arg1);\n } else if (event === 'frame') {\n c._onMicFrame(arg1, arg2);\n } else if (event === 'micStop' || event === 'playStart') {\n c._stopListen();\n } else {\n console.error('unknown audio event: ' + event, arg1, arg2);\n }\n };\n return c;\n}\n\nvar factories = {\n connectProject: connectProject,\n};\n\nvar currentConnect = null;\n\nonmessage = function(e) {\n var name = e.data[0];\n try {\n if (!currentConnect) {\n currentConnect = factories[name].apply(null, e.data.slice(1, e.data.length));\n } else {\n currentConnect[name].apply(currentConnect, e.data.slice(1, e.data.length));\n }\n } catch(e) {\n console.error('error calling: ' + name, e);\n }\n};\n"]),{type: 'text/javascript'}));
|
|
212
212
|
this._worker.onmessage = function(e) {
|
|
213
213
|
if (e.data[0] === 'fireEvent') {
|
|
214
214
|
_this._fire(e.data[1], e.data[2]);
|
|
@@ -780,7 +780,7 @@
|
|
|
780
780
|
|
|
781
781
|
/// <reference types="../global" />
|
|
782
782
|
(function (ns) {
|
|
783
|
-
var alanButtonVersion = '1.8.
|
|
783
|
+
var alanButtonVersion = '1.8.35';
|
|
784
784
|
if (window.alanBtn) {
|
|
785
785
|
console.warn('Alan: the Alan Button source code has already added (v.' + alanButtonVersion + ')');
|
|
786
786
|
}
|
|
@@ -788,6 +788,7 @@
|
|
|
788
788
|
var currentProjectId = null;
|
|
789
789
|
var deviceId;
|
|
790
790
|
var firstClick = null;
|
|
791
|
+
var btnInstance;
|
|
791
792
|
// Define base properties for disable/enable button functionality
|
|
792
793
|
var isLocalStorageAvailable = false;
|
|
793
794
|
try {
|
|
@@ -833,6 +834,11 @@
|
|
|
833
834
|
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
|
|
834
835
|
s4() + '-' + s4() + s4() + s4();
|
|
835
836
|
}
|
|
837
|
+
var AlanButtonTextMessageType;
|
|
838
|
+
(function (AlanButtonTextMessageType) {
|
|
839
|
+
AlanButtonTextMessageType["Request"] = "request";
|
|
840
|
+
AlanButtonTextMessageType["Response"] = "response";
|
|
841
|
+
})(AlanButtonTextMessageType || (AlanButtonTextMessageType = {}));
|
|
836
842
|
function alanBtn(options) {
|
|
837
843
|
options = options || {};
|
|
838
844
|
var btnDisabled = false;
|
|
@@ -842,6 +848,7 @@
|
|
|
842
848
|
var absolutePosition = false;
|
|
843
849
|
var micWasStoppedByTimeout = false;
|
|
844
850
|
var keepButtonPositionAfterDnD = false;
|
|
851
|
+
var dragAndDropEnabled = true;
|
|
845
852
|
// Btn modes
|
|
846
853
|
var mode;
|
|
847
854
|
if (options.mode === 'tutor') {
|
|
@@ -855,10 +862,13 @@
|
|
|
855
862
|
mode = 'component';
|
|
856
863
|
}
|
|
857
864
|
console.log('Alan: v.' + alanButtonVersion);
|
|
858
|
-
if (window.tutorProject && !isTutorMode()) {
|
|
859
|
-
|
|
865
|
+
if (window.tutorProject && !isTutorMode() && btnInstance) {
|
|
866
|
+
if (currentProjectId === options.key) {
|
|
867
|
+
return btnInstance;
|
|
868
|
+
}
|
|
869
|
+
throw new Error('The Alan Button instance has already been created. There cannot be two Alan Button instances created at the same time connected to the different projects.');
|
|
860
870
|
}
|
|
861
|
-
|
|
871
|
+
btnInstance = {
|
|
862
872
|
// Common public API
|
|
863
873
|
version: alanButtonVersion,
|
|
864
874
|
setVisualState: function (visualStateData) {
|
|
@@ -916,6 +926,9 @@
|
|
|
916
926
|
isActive: function () {
|
|
917
927
|
return isAlanActive;
|
|
918
928
|
},
|
|
929
|
+
sendText: function (text) {
|
|
930
|
+
window.tutorProject.call('text', { text: text });
|
|
931
|
+
},
|
|
919
932
|
//deprecated
|
|
920
933
|
callClientApi: function (method, data, callback) {
|
|
921
934
|
console.error('The "callClientApi" method is deprecated. Please use the "callProjectApi: instead.\n\nSee more info here: https://alan.app/docs/client-api/methods/common-api/?highlight=callprojectapi#callprojectapi');
|
|
@@ -949,7 +962,10 @@
|
|
|
949
962
|
remove: function () {
|
|
950
963
|
alanAudio.stop();
|
|
951
964
|
window.tutorProject.close();
|
|
952
|
-
|
|
965
|
+
window.tutorProject.off('scripts', onScriptsCb);
|
|
966
|
+
window.tutorProject.off('text', onTextCbInMicBtn);
|
|
967
|
+
rootEl.innerHTML = '';
|
|
968
|
+
btnInstance = null;
|
|
953
969
|
if (!isTutorMode()) {
|
|
954
970
|
window.tutorProject = null;
|
|
955
971
|
}
|
|
@@ -1316,7 +1332,7 @@
|
|
|
1316
1332
|
}
|
|
1317
1333
|
if (absolutePosition) {
|
|
1318
1334
|
el.style.position = 'absolute';
|
|
1319
|
-
el.classList.add('
|
|
1335
|
+
el.classList.add('alan-btn-lib__absolute-positioned');
|
|
1320
1336
|
}
|
|
1321
1337
|
if (topPos) {
|
|
1322
1338
|
el.style.bottom = '';
|
|
@@ -1329,14 +1345,14 @@
|
|
|
1329
1345
|
if (isLeftAligned) {
|
|
1330
1346
|
btn.style.left = '0';
|
|
1331
1347
|
btn.style.right = '';
|
|
1332
|
-
recognisedTextHolder.classList.remove('
|
|
1333
|
-
recognisedTextHolder.classList.add('
|
|
1348
|
+
recognisedTextHolder.classList.remove('alan-btn-lib__left-side');
|
|
1349
|
+
recognisedTextHolder.classList.add('alan-btn-lib__right-side');
|
|
1334
1350
|
}
|
|
1335
1351
|
else {
|
|
1336
1352
|
btn.style.right = '0';
|
|
1337
1353
|
btn.style.left = '';
|
|
1338
|
-
recognisedTextHolder.classList.remove('
|
|
1339
|
-
recognisedTextHolder.classList.add('
|
|
1354
|
+
recognisedTextHolder.classList.remove('alan-btn-lib__right-side');
|
|
1355
|
+
recognisedTextHolder.classList.add('alan-btn-lib__left-side');
|
|
1340
1356
|
}
|
|
1341
1357
|
}
|
|
1342
1358
|
function applyBtnSizeOptions(size) {
|
|
@@ -1698,8 +1714,8 @@
|
|
|
1698
1714
|
keyFrames += getStyleSheetMarker() + '.alanBtn{transform: scale(1);' + transitionCss + ';} .alanBtn' + hoverSelector + '{transform: scale(1.11111);transition:' + transitionCss + ';}.alanBtn:focus {transform: scale(1);' + transitionCss + '; border: solid 3px #50e3c2; outline: none; }';
|
|
1699
1715
|
}
|
|
1700
1716
|
keyFrames += getStyleSheetMarker() + '.alanBtn-recognised-text-holder { position:fixed; transform: translateY(' + (isTopAligned ? '-' : '') + '50%); max-width:236px; font-family: Helvetica, Arial, sans-serif; font-size: 14px; line-height: 18px; min-height: 40px; color: #000; font-weight: normal; background-color: #fff; border-radius:10px; box-shadow: 0px 1px 14px rgba(0, 0, 0, 0.35); display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack: activate;-ms-flex-pack: start;justify-content: start;}';
|
|
1701
|
-
keyFrames += getStyleSheetMarker() + ' .alanBtn-recognised-text-holder.
|
|
1702
|
-
keyFrames += getStyleSheetMarker() + ' .alanBtn-recognised-text-holder.
|
|
1717
|
+
keyFrames += getStyleSheetMarker() + ' .alanBtn-recognised-text-holder.alan-btn-lib__with-text.alan-btn-lib__left-side { text-align: left;}';
|
|
1718
|
+
keyFrames += getStyleSheetMarker() + ' .alanBtn-recognised-text-holder.alan-btn-lib__with-text.alan-btn-lib__right-side { text-align: right;}';
|
|
1703
1719
|
keyFrames += getStyleSheetMarker() + ' .alanBtn-recognised-text-holder .alanBtn-recognised-text-content:not(:empty) {padding: 10px;}';
|
|
1704
1720
|
keyFrames += getStyleSheetMarker(true) + '.alanBtn-recognised-text-holder-long { font-size: 12px!important;line-height: 1.4!important;} ';
|
|
1705
1721
|
keyFrames += getStyleSheetMarker(true) + '.alanBtn-recognised-text-holder-super-long { font-size: 11px!important;line-height: 1.4!important;} ';
|
|
@@ -1723,11 +1739,11 @@
|
|
|
1723
1739
|
keyFrames += getStyleSheetMarker() + '.alan-alert-popup {border-radius:10px; box-shadow: 0px 5px 14px rgba(3, 3, 3, 0.25);padding:12px;padding-right:24px;text-align: center;width: 220px;background: rgb(255 255 255);position: fixed;left: 50%;transform: translateX(-50%);top: 10%; color: #000;font-size: 14px;line-height: 18px;}';
|
|
1724
1740
|
keyFrames += getStyleSheetMarker() + '.alan-alert-popup__close-btn {background:url("' + popupCloseIconImgBase64 + '") no-repeat center;cursor:pointer; background-size:100% 100%;position: absolute;top: 12px;right: 12px;width: 14px;height: 14px;}';
|
|
1725
1741
|
keyFrames += getStyleSheetMarker() + '.alan-overlay {position: fixed;top: 0;left: 0;right: 0;bottom: 0;z-index: 99;background: rgba(0, 0, 0, 0.57);opacity: 0;-webkit-animation: alan-fade-in 0.5s 0.2s forwards;-moz-animation: alan-fade-in 0.5s 0.2s forwards;-o-animation: alan-fade-in 0.5s 0.2s forwards;animation: alan-fade-in 0.5s 0.2s forwards;}';
|
|
1726
|
-
keyFrames += getStyleSheetMarker() + '.alan-overlay-popup.
|
|
1727
|
-
keyFrames += getStyleSheetMarker() + '.alan-overlay-popup.
|
|
1728
|
-
keyFrames += getStyleSheetMarker() + '.alan-overlay-popup.
|
|
1729
|
-
keyFrames += getStyleSheetMarker() + '.alan-overlay-popup.
|
|
1730
|
-
keyFrames += getStyleSheetMarker() + '.alan-overlay-popup.
|
|
1742
|
+
keyFrames += getStyleSheetMarker() + '.alan-overlay-popup.alan-btn-lib__default-popup {border-radius:10px; box-shadow: 0px 5px 14px rgba(3, 3, 3, 0.25);padding:6px 30px 6px 12px;text-align: left;width: 220px;background: rgb(255 255 255);}';
|
|
1743
|
+
keyFrames += getStyleSheetMarker() + '.alan-overlay-popup.alan-btn-lib__top.alan-btn-lib__right {border-top-right-radius: 0!important;}';
|
|
1744
|
+
keyFrames += getStyleSheetMarker() + '.alan-overlay-popup.alan-btn-lib__top.alan-btn-lib__left {border-top-left-radius: 0!important;}';
|
|
1745
|
+
keyFrames += getStyleSheetMarker() + '.alan-overlay-popup.alan-btn-lib__bottom.alan-btn-lib__left {border-bottom-left-radius: 0!important;}';
|
|
1746
|
+
keyFrames += getStyleSheetMarker() + '.alan-overlay-popup.alan-btn-lib__bottom.alan-btn-lib__right {border-bottom-right-radius: 0!important;}';
|
|
1731
1747
|
keyFrames += getStyleSheetMarker() + '.alan-overlay-popup {position: fixed;opacity: 0;-webkit-animation: alan-fade-in 0.5s 0.2s forwards;-moz-animation: alan-fade-in 0.5s 0.2s forwards;-o-animation: alan-fade-in 0.5s 0.2s forwards;animation: alan-fade-in 0.5s 0.2s forwards;}';
|
|
1732
1748
|
keyFrames += getStyleSheetMarker() + '.alan-overlay-popup__body {position:relative;color: #0D1940;font-size: 16px;line-height: 20px;}';
|
|
1733
1749
|
keyFrames += getStyleSheetMarker() + '.alan-overlay-popup__ok {background:url("' + popupCloseIconImgBase64 + '") no-repeat center; background-size:100% 100%;min-height:14px;height:14px;max-height:14px;min-width:14px;width:14px;max-width:14px;opacity:0;transition:opacity 300ms ease-in-out;position:absolute;top:8px;right:8px;cursor: pointer;pointer-events: auto!important;}';
|
|
@@ -1867,6 +1883,8 @@
|
|
|
1867
1883
|
});
|
|
1868
1884
|
window.tutorProject.on('connectStatus', onConnectStatusChange);
|
|
1869
1885
|
window.tutorProject.on('options', onOptionsReceived);
|
|
1886
|
+
window.tutorProject.on('scripts', onScriptsCb);
|
|
1887
|
+
window.tutorProject.on('text', onTextCbInMicBtn);
|
|
1870
1888
|
//window.tutorProject.on('popup', onPopup);
|
|
1871
1889
|
// console.info('BTN: tutorProject', options.key);
|
|
1872
1890
|
}
|
|
@@ -2065,6 +2083,9 @@
|
|
|
2065
2083
|
if (isMobile() || isTutorMode()) {
|
|
2066
2084
|
return;
|
|
2067
2085
|
}
|
|
2086
|
+
if (options.onEvent) {
|
|
2087
|
+
options.onEvent(Object.assign(p, { name: 'popup' }));
|
|
2088
|
+
}
|
|
2068
2089
|
if (p) {
|
|
2069
2090
|
showPopup(p.popup ? p.popup : p);
|
|
2070
2091
|
}
|
|
@@ -2109,7 +2130,7 @@
|
|
|
2109
2130
|
document.getElementsByTagName('head')[0].appendChild(popupStyle);
|
|
2110
2131
|
}
|
|
2111
2132
|
}
|
|
2112
|
-
popup.classList.add(isLeftAligned ? '
|
|
2133
|
+
popup.classList.add(isLeftAligned ? 'alan-btn-lib__left' : 'alan-btn-lib__right');
|
|
2113
2134
|
if (!absolutePosition) {
|
|
2114
2135
|
if (!isLeftAligned) {
|
|
2115
2136
|
popup.style.right = initRightPos + (-buttonMarginInPopup || 0) + 'px';
|
|
@@ -2118,12 +2139,12 @@
|
|
|
2118
2139
|
popup.style.left = rootElClientRect.x + (-buttonMarginInPopup || 0) + 'px';
|
|
2119
2140
|
}
|
|
2120
2141
|
if (rootElClientRect.top > 80) {
|
|
2121
|
-
popup.classList.add('
|
|
2142
|
+
popup.classList.add('alan-btn-lib__bottom');
|
|
2122
2143
|
popup.style.top = rootElClientRect.top + (buttonMarginInPopup ? (_btnSize + buttonMarginInPopup) : (-popup2BtnMargin)) + 'px';
|
|
2123
2144
|
popup.style.setProperty('transform', 'translateY(-100%)', 'important');
|
|
2124
2145
|
}
|
|
2125
2146
|
else {
|
|
2126
|
-
popup.classList.add('
|
|
2147
|
+
popup.classList.add('alan-btn-lib__top');
|
|
2127
2148
|
popup.style.top = rootElClientRect.top + (buttonMarginInPopup ? (-buttonMarginInPopup) : (_btnSize + popup2BtnMargin)) + 'px';
|
|
2128
2149
|
}
|
|
2129
2150
|
}
|
|
@@ -2131,11 +2152,11 @@
|
|
|
2131
2152
|
popup.style.position = 'absolute';
|
|
2132
2153
|
popup.style[isLeftAligned ? 'left' : 'right'] = (-buttonMarginInPopup || 0) + 'px';
|
|
2133
2154
|
popup.style[isTopAligned ? 'top' : 'bottom'] = (buttonMarginInPopup ? -buttonMarginInPopup : (_btnSize + popup2BtnMargin)) + 'px';
|
|
2134
|
-
popup.classList.add(isTopAligned ? '
|
|
2155
|
+
popup.classList.add(isTopAligned ? 'alan-btn-lib__top' : 'alan-btn-lib__bottom');
|
|
2135
2156
|
}
|
|
2136
2157
|
if (!popupOptions.html) {
|
|
2137
2158
|
if (message) {
|
|
2138
|
-
popup.classList.add('
|
|
2159
|
+
popup.classList.add('alan-btn-lib__default-popup');
|
|
2139
2160
|
popup.innerHTML = '<div class="alan-overlay-popup__body">' + message + '</div>';
|
|
2140
2161
|
}
|
|
2141
2162
|
}
|
|
@@ -2259,7 +2280,7 @@
|
|
|
2259
2280
|
if (!options.hideRecognizedText) {
|
|
2260
2281
|
if (recognisedTextHolder.classList.value.indexOf('alanBtn-text-appearing') === -1) {
|
|
2261
2282
|
recognisedTextHolder.style.opacity = '1';
|
|
2262
|
-
recognisedTextHolder.classList.add('
|
|
2283
|
+
recognisedTextHolder.classList.add('alan-btn-lib__with-text');
|
|
2263
2284
|
recognisedTextHolder.classList.add('alanBtn-text-appearing');
|
|
2264
2285
|
recognisedTextHolder.classList.remove('alanBtn-text-disappearing');
|
|
2265
2286
|
}
|
|
@@ -2270,7 +2291,7 @@
|
|
|
2270
2291
|
}
|
|
2271
2292
|
recognisedTextContent.innerHTML = recognisedText;
|
|
2272
2293
|
}
|
|
2273
|
-
if (recognisedTextHolder.classList.contains('
|
|
2294
|
+
if (recognisedTextHolder.classList.contains('alan-btn-lib__absolute-positioned')) {
|
|
2274
2295
|
if (recognisedText.length < 33) {
|
|
2275
2296
|
recognisedTextHolder.style.whiteSpace = 'nowrap';
|
|
2276
2297
|
recognisedTextHolder.style.minWidth = 'auto';
|
|
@@ -2318,28 +2339,32 @@
|
|
|
2318
2339
|
recognisedTextContent.innerHTML = '';
|
|
2319
2340
|
recognisedTextHolder.classList.remove('alanBtn-recognised-text-holder-long');
|
|
2320
2341
|
recognisedTextHolder.classList.remove('alanBtn-recognised-text-holder-super-long');
|
|
2321
|
-
recognisedTextHolder.classList.remove('
|
|
2342
|
+
recognisedTextHolder.classList.remove('alan-btn-lib__with-text');
|
|
2322
2343
|
}, delay || 810);
|
|
2323
2344
|
}
|
|
2324
2345
|
}
|
|
2325
2346
|
function onOptionsReceived(data) {
|
|
2347
|
+
var _a, _b, _c;
|
|
2326
2348
|
if (data && data.web) {
|
|
2327
|
-
keepButtonPositionAfterDnD = data.web.keepButtonPositionAfterDnD;
|
|
2349
|
+
keepButtonPositionAfterDnD = ((_a = data.web.alanButtonDragAndDrop) === null || _a === void 0 ? void 0 : _a.keepButtonPositionAfterDnD) || data.web.keepButtonPositionAfterDnD;
|
|
2328
2350
|
if (!keepButtonPositionAfterDnD) {
|
|
2329
2351
|
clearSavedBtnPosition();
|
|
2330
2352
|
}
|
|
2331
|
-
setButtonPosition(
|
|
2353
|
+
setButtonPosition(keepButtonPositionAfterDnD);
|
|
2332
2354
|
}
|
|
2333
2355
|
else {
|
|
2334
2356
|
setButtonPosition();
|
|
2335
2357
|
}
|
|
2358
|
+
if (data && data.web) {
|
|
2359
|
+
dragAndDropEnabled = (_b = data.web.alanButtonDragAndDrop) === null || _b === void 0 ? void 0 : _b.dragAndDropEnabled;
|
|
2360
|
+
}
|
|
2336
2361
|
if (data && data.web && data.web.hideS2TPanel === true) {
|
|
2337
2362
|
hideSpeach2TextPanel();
|
|
2338
2363
|
}
|
|
2339
2364
|
else {
|
|
2340
2365
|
showSpeach2TextPanel();
|
|
2341
2366
|
}
|
|
2342
|
-
if (data && data.web && data.web.popupEnabled === true) {
|
|
2367
|
+
if (data && data.web && (((_c = data.web.alanButtonPopup) === null || _c === void 0 ? void 0 : _c.popupEnabled) === true || data.web.popupEnabled === true)) {
|
|
2343
2368
|
popupEnabled = true;
|
|
2344
2369
|
}
|
|
2345
2370
|
else {
|
|
@@ -2409,7 +2434,6 @@
|
|
|
2409
2434
|
playSoundNext();
|
|
2410
2435
|
isAlanActive = true;
|
|
2411
2436
|
if (window.tutorProject) {
|
|
2412
|
-
window.tutorProject.on('text', onTextCbInMicBtn);
|
|
2413
2437
|
window.tutorProject.on('parsed', onParsedCbInMicBtn);
|
|
2414
2438
|
window.tutorProject.on('recognized', onRecognizedCbInMicBtn);
|
|
2415
2439
|
window.tutorProject.on('connectStatus', onConnectStatusChange);
|
|
@@ -2433,7 +2457,6 @@
|
|
|
2433
2457
|
switchState(DEFAULT);
|
|
2434
2458
|
isAlanActive = false;
|
|
2435
2459
|
if (window.tutorProject) {
|
|
2436
|
-
window.tutorProject.off('text', onTextCbInMicBtn);
|
|
2437
2460
|
window.tutorProject.off('parsed', onParsedCbInMicBtn);
|
|
2438
2461
|
window.tutorProject.off('recognized', onRecognizedCbInMicBtn);
|
|
2439
2462
|
window.tutorProject.off('connectStatus', onConnectStatusChange);
|
|
@@ -2525,7 +2548,7 @@
|
|
|
2525
2548
|
function onTextCbInMicBtn(e) {
|
|
2526
2549
|
// console.info('BTN: onTextCb', e, new Date());
|
|
2527
2550
|
if (options.onEvent) {
|
|
2528
|
-
options.onEvent(Object.assign(e, { name: 'text' }));
|
|
2551
|
+
options.onEvent(Object.assign(e, { name: 'text', type: AlanButtonTextMessageType.Response }));
|
|
2529
2552
|
}
|
|
2530
2553
|
turnOffVoiceFn();
|
|
2531
2554
|
}
|
|
@@ -2561,6 +2584,11 @@
|
|
|
2561
2584
|
}
|
|
2562
2585
|
turnOffVoiceFn();
|
|
2563
2586
|
}
|
|
2587
|
+
function onScriptsCb(e) {
|
|
2588
|
+
if (options.onEvent) {
|
|
2589
|
+
options.onEvent(Object.assign(e, { name: 'scripts' }));
|
|
2590
|
+
}
|
|
2591
|
+
}
|
|
2564
2592
|
function playSoundOn() {
|
|
2565
2593
|
if (!soundOnAudioDoesNotExist) {
|
|
2566
2594
|
soundOnAudio.currentTime = 0;
|
|
@@ -3110,6 +3138,8 @@
|
|
|
3110
3138
|
var newLeftPos, newTopPos;
|
|
3111
3139
|
if (!posInfo)
|
|
3112
3140
|
return;
|
|
3141
|
+
if (!dragAndDropEnabled)
|
|
3142
|
+
return;
|
|
3113
3143
|
if (dndIsDown) {
|
|
3114
3144
|
togglePopupVisibility(false);
|
|
3115
3145
|
hideRecognisedText(0, true);
|