@alan-ai/alan-sdk-web 1.8.42 → 1.8.43

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/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\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'}));
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 === 'afterText') {\n postMessage(['alanAudio', 'playAfterText', 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]);
@@ -219,6 +219,10 @@
219
219
  alanAudio.playText(e.data[2]);
220
220
  return;
221
221
  }
222
+ if (e.data[1] === 'playAfterText') {
223
+ alanAudio.playAfterText(e.data[2]);
224
+ return;
225
+ }
222
226
  if (e.data[1] === 'playAudio' || e.data[1] === 'playFrame') {
223
227
  alanAudio.playAudio(e.data[2]);
224
228
  return;
@@ -656,6 +660,8 @@
656
660
  fireEvent('command', o.event);
657
661
  } else if (o.text) {
658
662
  fireEvent('text', o.text);
663
+ } else if (o.afterText) {
664
+ fireEvent('afterText', o.afterText);
659
665
  } else if (o.popup) {
660
666
  fireEvent('popup', o.popup);
661
667
  } else if (o.audio) {
@@ -708,9 +714,21 @@
708
714
  return playState === PLAY_ACTIVE;
709
715
  };
710
716
 
711
- ns.playText = function(text) {
717
+ ns.playText = function (text) {
718
+ if (text && text.ctx && text.ctx.opts && text.ctx.opts.force === true) {
719
+ fireEvent('text', text);
720
+ } else {
721
+ audioContext.resume().then(() => {
722
+ audioQueue.push({ text: text });
723
+ _handleQueue();
724
+ });
725
+ }
726
+ };
727
+
728
+ ns.playAfterText = function(afterText) {
712
729
  audioContext.resume().then(()=> {
713
- audioQueue.push({text: text});
730
+
731
+ audioQueue.push({afterText: afterText});
714
732
  _handleQueue();
715
733
  });
716
734
  };
@@ -844,9 +862,56 @@
844
862
 
845
863
  })(typeof(window) !== 'undefined' ? (function() {window.alanAudio = {}; return window.alanAudio})() : exports);
846
864
 
865
+ var __assign = (this && this.__assign) || function () {
866
+ __assign = Object.assign || function(t) {
867
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
868
+ s = arguments[i];
869
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
870
+ t[p] = s[p];
871
+ }
872
+ return t;
873
+ };
874
+ return __assign.apply(this, arguments);
875
+ };
876
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
877
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
878
+ return new (P || (P = Promise))(function (resolve, reject) {
879
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
880
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
881
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
882
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
883
+ });
884
+ };
885
+ var __generator = (this && this.__generator) || function (thisArg, body) {
886
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
887
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
888
+ function verb(n) { return function (v) { return step([n, v]); }; }
889
+ function step(op) {
890
+ if (f) throw new TypeError("Generator is already executing.");
891
+ while (_) try {
892
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
893
+ if (y = 0, t) op = [op[0] & 2, t.value];
894
+ switch (op[0]) {
895
+ case 0: case 1: t = op; break;
896
+ case 4: _.label++; return { value: op[1], done: false };
897
+ case 5: _.label++; y = op[1]; op = [0]; continue;
898
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
899
+ default:
900
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
901
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
902
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
903
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
904
+ if (t[2]) _.ops.pop();
905
+ _.trys.pop(); continue;
906
+ }
907
+ op = body.call(thisArg, _);
908
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
909
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
910
+ }
911
+ };
847
912
  /// <reference types="../global" />
848
913
  (function (ns) {
849
- var alanButtonVersion = '1.8.42';
914
+ var alanButtonVersion = '1.8.43';
850
915
  if (window.alanBtn) {
851
916
  console.warn('Alan: the Alan Button source code has already added (v.' + alanButtonVersion + ')');
852
917
  }
@@ -855,6 +920,11 @@
855
920
  var deviceId;
856
921
  var firstClick = null;
857
922
  var btnInstance;
923
+ var textChatIsHidden = true;
924
+ var textChatIsAvailable = false;
925
+ var voiceEnabledInTextChat = true;
926
+ var textChatMessages = [];
927
+ var textChatOptions = null;
858
928
  // Define base properties for disable/enable button functionality
859
929
  var isLocalStorageAvailable = false;
860
930
  try {
@@ -909,7 +979,7 @@
909
979
  })(AlanButtonTextMessageType || (AlanButtonTextMessageType = {}));
910
980
  function alanBtn(options) {
911
981
  options = options || {};
912
- var btnDisabled = false;
982
+ var btnDisabled = true;
913
983
  var hideS2TPanel = false;
914
984
  var popupEnabled = true;
915
985
  var pinned = false;
@@ -917,7 +987,6 @@
917
987
  var micWasStoppedByTimeout = false;
918
988
  var keepButtonPositionAfterDnD = false;
919
989
  var dragAndDropEnabled = true;
920
- // Btn modes
921
990
  var mode;
922
991
  if (options.mode === 'tutor') {
923
992
  mode = 'tutor';
@@ -986,16 +1055,13 @@
986
1055
  return activateAlanButton();
987
1056
  },
988
1057
  deactivate: function () {
989
- if (btnDisabled) {
990
- return;
991
- }
992
- alanAudio.stop();
1058
+ deactivateAlanButton();
993
1059
  },
994
1060
  isActive: function () {
995
1061
  return isAlanActive;
996
1062
  },
997
1063
  sendText: function (text) {
998
- window.tutorProject.call('text', { text: text });
1064
+ _sendText(text);
999
1065
  },
1000
1066
  //deprecated
1001
1067
  callClientApi: function (method, data, callback) {
@@ -1034,6 +1100,7 @@
1034
1100
  window.tutorProject.off('text', onTextCbInMicBtn);
1035
1101
  window.tutorProject.off('parsed', onParsedCbInMicBtn);
1036
1102
  alanAudio.off('command', onCommandCbInMicBtn);
1103
+ alanAudio.off('afterText', onAfterTextCbInMicBtn);
1037
1104
  rootEl.innerHTML = '';
1038
1105
  btnInstance = null;
1039
1106
  if (!isTutorMode()) {
@@ -1162,6 +1229,7 @@
1162
1229
  pulsatingMicAnimation = 'alan-mic-pulsating 1.4s ease-in-out infinite';
1163
1230
  pulsatingTriangleMicAnimation = 'alan-triangle-mic-pulsating 1.2s ease-in-out infinite';
1164
1231
  }
1232
+ var pulsatingAnimationForMicBtnInTextChat = 'alan-text-chat-pulsating 2s ease-in-out infinite';
1165
1233
  var gradientAnimation = 'alan-gradient 3s ease-in-out infinite';
1166
1234
  var disconnectedLoaderAnimation = 'disconnected-loader-animation 2s linear infinite';
1167
1235
  // Set alanAudio
@@ -1171,9 +1239,15 @@
1171
1239
  var body = document.getElementsByTagName('body')[0];
1172
1240
  var btn = document.createElement('div');
1173
1241
  var micIconSrc = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAABQCAYAAACOEfKtAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAH9SURBVHgB7dvvUcIwGMfxByfADdjAEdQN3EA2YATcAJ2AEXADdALcgG4AGzwm13DQkNKWQBvK93OXF4W0Z36mf5IUEQAAAAAAAAAAgPOo6ocpS91bmfIuOM2ENHJhlVnbOoIwF1CVleCYCWas9U0kEQ+SjibXuDdJxEASYbtVg+rbwWDwKAm41QDFBJjE357SKXyTCDASAUYiwEgEGIkAIxFgJAKMRICRWgvQTRZs3IzLxef2rn38zmlxqmoT+L6Rpse/ltbGk36j/bFsKJRTqvZva6zc2TXQtHfofbSV+rYVx2pNmwFm3vbI2/6R+r4rjvUnLWkzQL9Rz972l9T3WXGsTPrGTsN794FloM5Uq00D+/kLUb28Cw8DYbwE6k1LgrOPKJNA/dBaykj6SItrvdZaAzcAzZc3bTBzVyYl9YZ6vJK3kL6yPS7QW+ZyJhvW3fS+HdPAWaDRiyYNdz1vecl/xs0oOe12p3Plxd+d2mX7t/482MnKlutt9i48CnydSf5M+Cv7xxFb78mUsSnDkn1ezeAjk3uh+Y0i1JOaWuu9vi/jTueZns/u29kwLhma98Z5g+CWpjwLirT4/Oezn01S63HJvNrhs4kdbqfyKoePKf1IBBiJACMRYCQCjESAkVIO8HDhKBM0o/tZFzsTzY9sAAAAAAAAAABAjH+9EqX09fBHaQAAAABJRU5ErkJggg==';
1242
+ var alanLogoIconSrc = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKAAAACgCAYAAACLz2ctAAAAAXNSR0IArs4c6QAACw9JREFUeAHtnWusHVUVx1t5CVatj8rDB20pPgBJQbAmGJIStLFJRW1DWiXaVKG8Ykz0g4lRI6mPL34yihg0BD9IMDGgQaNJtSIGEilig2hViBaoiFUQRVGR+vvTc5vL7bln9pmzXzPnv5Lde87MmrX2/u01a/bM3me6YIHFBEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABHIRWJjLUU1+9u/f/1zqs5KylLKYcgTl5ZRVlOdTcsl+HD1E+RHluoULF/4tl+Na/ExdABJ8i4C/jjIs0A5j+5spr6HkFgXiVoLw4dyOS/p7TknnhXyvxu+w4FN1/ke5lfKAvmQWZeCrMvss7m6qApDstwzixzdQ12VxO+XpBr0Uu8+kjjpBpkamJgDpWA03zgrs2f+gd3ugbmy1y6jr1PTL1DSUKDmZ8qIxomU3uk+NoR9LdTmG1sYyVrudqQjAQUZ5w5idoeD7yZjHxFK/hDofHstYzXamIgDpgNdR5rvxGNU/97Pz36MUEu07AbvrE9muymzvA3CQSc5oSV13xTtaHjvpYVuou55X9lp6H4D03mmUYyboRT2S+ccEx7c99CUcuKntwV05rtcBSAY5ko7QjMckoscxOyYxMMGx76UNbYYOE7jMe2ivAxCUCj4F4aSyFwOPTmqkxfEKvve1OK4zh/Q2AMkcR9MLuvzGkh/HMjSmnY20RZfjXkpvA5DeOpMS81HGI9j7U4Eo0I3I+wv4zeKylwE4GDfp0UtsKfVc8F20qWkKMXZbs9jrZQBCTg+dU7RN40DdFecWZfKtuZ3m8Jeik3LUe14fZAqt79O0WwrRQoWfpjAcYHMtbVsaoNcpld4FIPTPpmjhQSp5HMP3pTI+wq766ooR+zu5q1cBSIZYQi8sy9ATd2TwMczFatqYYmw7zFeWbb0KQIgp++WQJ3DyyxyOhvi4csi2zm7qTQCSGTSB/4qMPbEzo6/ZrlbRVt1k9UJ6E4D0Rq7sN9PxT/Lhrpkvmf/2ZizYiwAkI5xIABybOQjkbhdFd8a55XTafG5upyn8dT4A6Qjd8ebOfjN9cS8fvjfzJfPfywdtz+w2rrvOByA4TqK8OC6WIGvKfBoHfoVSYun+CvyuoXRaOh2AZADVP/SHRrE7ard+SE55EMM3xTYeaO9SGMSc7w50G0+t0wEIBv2A/AXxcARb0hrB2Tcg1/K9xNJ93fVfEFzrChU7G4CDM7/U44h7yXwHV0nzeR99e0Oh/v0ALI4q5Htit50NQFp+CmWSpfZt4Wm8d/eQg69n28GgHLI/1aYlGL4wlfHUdjsZgJzxWuXc9odGkzK9h4z3z7lG2KYXC3197vZM3zfDZFEmX1HddDIAIXA6pcRlR29M+MWIHvgG+0os3X8hfi8aUa9qd3UuADnTtUL49YWI7iLTzXuzMciMXy1Ut3fDRkvROiWdC0Do6tJ7RAHKmnq7J8Dvt9B5OEAvtorGw1tiG01tr1MBOBjn6OajhNxNhtMleKQMdPRwuoRsgFGJKcnWbe1UANJK/dDosNatbX+gbjo07RYqt6D4h1DliHq6Obs4or3kpjoTgJzZGmjrwXMJuYvMpscvQYKuXulxdZByfKV1sHpVfLNpLHYmAGm+ptxSLrWfj7Ce7f16vp0jtm9vedwIk0G7dIW4LEizAqVOBCBntH6YrUUHJeROMpqm3sYSjtFihS+OdVA85bfArNTVYqxWdCIAaVGp5VaP4ft3YxGdpUwQ3s7Xn8/alPPj5TmdtfVVfQByJh9H40qNaXa2yX5zOqNUFjwHdivn1KW6r9UHIMTeWIjaX/B7/6S+CWDNG982qZ2Wx1e/dL/qAOQMfiXglQFLiMZ+sZbbf6lEA/B5BgzPKeQ7yG21AQi4kkvtHyH4oj3Hw9Zv6I3vB/VIfCW9db/E04OgllQbgNR+GeWlQa2Ir/Sz+CYXXINNPR/MLa/F4fm5nYb6qzIAOWNVr1J3vnvJWA+FAgzVw+YedL8dqh9ZT0v3S8wgNTajygCk1q+maOajhKTIfjPtuJYPjfPJM8oR/56IrXUR7UUzVV0ADs5UzfmWkD1kqmQvoRzYvrFEw/CppfuaK65KqgtA6Gi1S6nVvXdm6J3r8KHFDblFTxM25Hba5K+quyPOUK3z20RZQtENiBaf5qqjFpr+kTKO6DGNluJrmX5w8NLOSzhGJbc8isMLqGuJE2BoW3N17lDnczfSMeex7fOU6p/gz6073zXl9h4691dD9j1rE+18Hhtupix+1o48X75MHTUWrUKqCUA6RTcd6sRlVZBpV4k9HLaSDlamGSm09yIUPjRSKc1Ore5RFlTmLi41jQE/Bo0uB586U3PWH9eHAPkmOn8O0IutovH15thG29qrIgOSDY6nAfdRjm7bkIqO01jyZDLMA011ot3vREcnXm5RHZUF9+V2PNdfLRnwE1SsD8EnvkdRPqkPAfIddPRumdyiOlaxdL94BiQLLAeGVhzrDrgvoim3U8kwu5saRPvXoPPpJr0E+5/C5gbqWOIEONicGjLgVdSmT8EnuJr22qYPAfIDdH4boBdb5XAMXhrb6Lj2igYgZ/9pVHjTuJXuiP562tf48iQykJ4lllq0uoY6rijJs2gA0nBdekrXIRV/DW8+G2KcILwNvV0hupF1VMeiS/eLdT5n3ioa//bIQGszpx8HrQ6sVKkseC511JWoiBQLQFr7mSItzu80NAvupGp35K/eMx6vLOS3zOWPM+58GnxeqUZn9qv/1+MdgT5LZcGzqKOuSNmlVAacluw306Hb6OBG1owFNY+8feagzH+vyOzvGXeNUGJXio7Q0/+zY9ut3N6p1E9zvyFyNUpPhyhG1jmFvgkdr0ZznTUAB1lgW7Tad8vQp2j/kU1VJgv+Hp1bmvQS7df/PZI1JrI6A5qygBacTqMspdFbAxt+DXqaqcgty3C4NqdTPQfKIoOzX1NuauS0ipb7n0SWe6IJALw+gs7GJr0E+/dicz11/G8C24eYzJkBL8b7NAef4B9LCV0D+DV0n9RBmeUE/GmcnkWyZEDO5mNojZZbHZelVXU70ULQ5WSYvzZVE26apdjSpJdgv15LouVayU+AXBnwgzTIwXcgUrTy+6MHPjb+ez0af2/Uiq+g1+FtjG/2UIvJMyBnsYJcYx/9yMhygMC/+PMyMoyWx48U+G1GocRMxWP4fSt1TPpIKEcG1F2vgw8Is0SLb9806/uojzewc98ohUT7FmN3eSLbB83mCECdSZZDCWic1SiDcVipt2slv/wnD0AAPgjlmxpJT5fCrXDRLwCDBF29U+bmIOV4Sjvwq6FTUkk+BlTtGccs4s/nKOsp03wzomds36V8mM59nL9jCRzfxgEXUlZQdBlPIcrMP6R8gTpW8wP2FA21TRMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARPoC4H/A+Gj/yJlPcQaAAAAAElFTkSuQmCC';
1174
1243
  var roundedTriangleSecondLayerSrc = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iODBweCIgaGVpZ2h0PSI4MHB4IiB2aWV3Qm94PSIwIDAgODAgODAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDUyLjEgKDY3MDQ4KSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5BbGFuIEJ1dHRvbiAvIEFuaW1hdGlvbiAvIGJ1dHRvbi1pbm5lci1zaGFwZTwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxkZWZzPgogICAgICAgIDxsaW5lYXJHcmFkaWVudCB4MT0iMTAwJSIgeTE9IjMuNzQ5Mzk5NDZlLTMxJSIgeDI9IjIuODYwODIwMDklIiB5Mj0iOTcuMTM5MTc5OSUiIGlkPSJsaW5lYXJHcmFkaWVudC0xIj4KICAgICAgICAgICAgPHN0b3Agc3RvcC1jb2xvcj0iIzAwMDAwMCIgc3RvcC1vcGFjaXR5PSIwLjEyIiBvZmZzZXQ9IjAlIj48L3N0b3A+CiAgICAgICAgICAgIDxzdG9wIHN0b3AtY29sb3I9IiMwMDAwMDAiIHN0b3Atb3BhY2l0eT0iMC4wNCIgb2Zmc2V0PSIxMDAlIj48L3N0b3A+CiAgICAgICAgPC9saW5lYXJHcmFkaWVudD4KICAgIDwvZGVmcz4KICAgIDxnIGlkPSJBbGFuLUJ1dHRvbi0vLUFuaW1hdGlvbi0vLWJ1dHRvbi1pbm5lci1zaGFwZSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPHBhdGggZD0iTTQwLjEwMDU0MjIsOSBMNDAuMTAwNTQyMiw5IEM1MC4wNzA0NzUxLDkgNTkuMTUxNjIzNSwxNC43MzM3OTM4IDYzLjQzODA5OCwyMy43MzUyMjE0IEw3MC40MjIwMjY3LDM4LjQwMTE5NyBDNzUuMTcxMDE0NSw0OC4zNzM4ODQ0IDcwLjkzNjM2OTMsNjAuMzA4MTYwMSA2MC45NjM2ODE5LDY1LjA1NzE0NzggQzU4LjI3NzU5NDksNjYuMzM2MjYwOCA1NS4zMzk5NzQ0LDY3IDUyLjM2NDg3ODksNjcgTDI3LjgzNjIwNTQsNjcgQzE2Ljc5MDUxMDQsNjcgNy44MzYyMDU0Myw1OC4wNDU2OTUgNy44MzYyMDU0Myw0NyBDNy44MzYyMDU0Myw0NC4wMjQ5MDQ1IDguNDk5OTQ0NTksNDEuMDg3Mjg0IDkuNzc5MDU3NiwzOC40MDExOTcgTDE2Ljc2Mjk4NjQsMjMuNzM1MjIxNCBDMjEuMDQ5NDYwOCwxNC43MzM3OTM4IDMwLjEzMDYwOTIsOSA0MC4xMDA1NDIyLDkgWiIgaWQ9ImlubmVyLWJnIiBmaWxsPSJ1cmwoI2xpbmVhckdyYWRpZW50LTEpIj48L3BhdGg+CiAgICA8L2c+Cjwvc3ZnPg==\n';
1175
1244
  var circleSecondLayerSrc = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iODBweCIgaGVpZ2h0PSI4MHB4IiB2aWV3Qm94PSIwIDAgODAgODAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDUyLjEgKDY3MDQ4KSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5BbGFuIEJ1dHRvbiAvIEFuaW1hdGlvbiAvIGJ1dHRvbi1pbm5lci1zaGFwZS1zcGVha2luZyBiYWNrPC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGRlZnM+CiAgICAgICAgPGxpbmVhckdyYWRpZW50IHgxPSIxMDAlIiB5MT0iMy43NDkzOTk0NmUtMzElIiB4Mj0iMi44NjA4MjAwOSUiIHkyPSI5Ny4xMzkxNzk5JSIgaWQ9ImxpbmVhckdyYWRpZW50LTEiPgogICAgICAgICAgICA8c3RvcCBzdG9wLWNvbG9yPSIjMDAwMDAwIiBzdG9wLW9wYWNpdHk9IjAuMTIiIG9mZnNldD0iMCUiPjwvc3RvcD4KICAgICAgICAgICAgPHN0b3Agc3RvcC1jb2xvcj0iIzAwMDAwMCIgc3RvcC1vcGFjaXR5PSIwLjA0IiBvZmZzZXQ9IjEwMCUiPjwvc3RvcD4KICAgICAgICA8L2xpbmVhckdyYWRpZW50PgogICAgPC9kZWZzPgogICAgPGcgaWQ9IkFsYW4tQnV0dG9uLS8tQW5pbWF0aW9uLS8tYnV0dG9uLWlubmVyLXNoYXBlLXNwZWFraW5nLWJhY2siIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxjaXJjbGUgaWQ9ImlubmVyLWJnIiBmaWxsPSJ1cmwoI2xpbmVhckdyYWRpZW50LTEpIiBjeD0iNDAiIGN5PSI0MCIgcj0iMzIiPjwvY2lyY2xlPgogICAgPC9nPgo8L3N2Zz4=\n';
1176
1245
  var micIconDiv = document.createElement('div');
1246
+ var unreadChatMsgCount = 0;
1247
+ var chatHolderDiv = document.createElement('div');
1248
+ var chatNotificationsBubble = document.createElement('div');
1249
+ chatNotificationsBubble.id = 'chat-notifications-bubble';
1250
+ chatNotificationsBubble.classList.add('alan-btn__chat-notifications-bubble');
1177
1251
  var defaultStateBtnIconImg = document.createElement('img');
1178
1252
  var listenStateBtnIconImg = document.createElement('img');
1179
1253
  var processStateBtnIconImg = document.createElement('img');
@@ -1266,9 +1340,6 @@
1266
1340
  }
1267
1341
  return NO_VOICE_SUPPORT;
1268
1342
  }
1269
- //#endregion
1270
- //#region Define settings based on the btn mode
1271
- // For now we have two modes: small - for tutor, and big for demo
1272
1343
  var btnModes = {
1273
1344
  "tutor": {
1274
1345
  btnSize: 44,
@@ -1332,6 +1403,7 @@
1332
1403
  recognisedTextContent.classList.add('alanBtn-recognised-text-content');
1333
1404
  recognisedTextHolder.classList.add('alanBtn-recognised-text-holder');
1334
1405
  setTextPanelPosition(recognisedTextHolder);
1406
+ setTextChatPosition(chatHolderDiv);
1335
1407
  function setButtonPosition(keepBtnPosition) {
1336
1408
  var _savedBtnPosition = keepBtnPosition ? getSavedBtnPosition() : null;
1337
1409
  if (_savedBtnPosition) {
@@ -1378,6 +1450,70 @@
1378
1450
  rootEl.style.setProperty('top', '');
1379
1451
  }
1380
1452
  }
1453
+ function setTextChatPosition(el, topPos) {
1454
+ if (textChatIsHidden) {
1455
+ return;
1456
+ }
1457
+ el.style.zIndex = btnZIndex + 2;
1458
+ if (isMobile()) {
1459
+ return;
1460
+ }
1461
+ setTimeout(function () {
1462
+ var _a, _b;
1463
+ var defaultMargin = 12;
1464
+ var chatHeight = el.clientHeight;
1465
+ if (isLeftAligned) {
1466
+ el.style.right = '';
1467
+ el.style.left = defaultMargin + 'px';
1468
+ }
1469
+ else {
1470
+ el.style.left = '';
1471
+ el.style.right = defaultMargin + 'px';
1472
+ }
1473
+ var btnTopPos = (_a = rootEl.getBoundingClientRect()) === null || _a === void 0 ? void 0 : _a.top;
1474
+ var btnBottomPos = (_b = rootEl.getBoundingClientRect()) === null || _b === void 0 ? void 0 : _b.bottom;
1475
+ var isTopPartOfTheScreen = btnTopPos < window.innerHeight / 2;
1476
+ var newTopPos = 0;
1477
+ var newBottomPos = 0;
1478
+ if (isTopPartOfTheScreen) {
1479
+ if (defaultMargin + chatHeight > btnBottomPos) { // popup can cover the btn
1480
+ newTopPos = defaultMargin;
1481
+ }
1482
+ else {
1483
+ newTopPos = btnBottomPos - chatHeight + defaultMargin;
1484
+ }
1485
+ if (chatHeight >= window.innerHeight) {
1486
+ newTopPos = 0;
1487
+ }
1488
+ }
1489
+ else {
1490
+ if (defaultMargin + chatHeight > window.innerHeight - btnTopPos) { // popup can cover the btn
1491
+ newBottomPos = defaultMargin;
1492
+ }
1493
+ else {
1494
+ newBottomPos = window.innerHeight - btnBottomPos - defaultMargin;
1495
+ }
1496
+ if (chatHeight >= window.innerHeight) {
1497
+ newBottomPos = 0;
1498
+ }
1499
+ }
1500
+ if (isTopPartOfTheScreen) {
1501
+ el.style.bottom = '';
1502
+ el.style.top = newTopPos + 'px';
1503
+ }
1504
+ else {
1505
+ el.style.top = '';
1506
+ el.style.bottom = newBottomPos + 'px';
1507
+ }
1508
+ el.style.display = 'flex';
1509
+ setTimeout(function () {
1510
+ var textareaEl = document.getElementById('chatTextarea');
1511
+ if (textareaEl) {
1512
+ textareaEl.focus();
1513
+ }
1514
+ }, 0);
1515
+ }, 0);
1516
+ }
1381
1517
  function setTextPanelPosition(el, topPos) {
1382
1518
  var _btnSize = parseInt(btnSize, 10);
1383
1519
  if (isLeftAligned) {
@@ -1425,7 +1561,9 @@
1425
1561
  recognisedTextHolder.classList.add('alan-btn-lib__left-side');
1426
1562
  }
1427
1563
  }
1428
- function applyBtnSizeOptions(size) {
1564
+ function changeBtnSize(size) {
1565
+ if (!size)
1566
+ return;
1429
1567
  btnSize = size;
1430
1568
  btn.style.width = size + 'px';
1431
1569
  btn.style.minWidth = size + 'px';
@@ -1439,11 +1577,15 @@
1439
1577
  rootEl.style.minHeight = size + 'px';
1440
1578
  rootEl.style.height = size + 'px';
1441
1579
  rootEl.style.maxHeight = size + 'px';
1580
+ }
1581
+ function applyBtnSizeOptions(size) {
1582
+ changeBtnSize(size);
1442
1583
  if (isMobile()) {
1443
1584
  recognisedTextHolder.style.maxWidth = 'calc(100vw - ' + (parseInt(sideBtnPos, 10) + parseInt(btnSize, 10) + 20) + 'px)';
1444
1585
  }
1445
1586
  applySizeSettingsToBlurLayers([btnOval1, btnOval2]);
1446
1587
  setTextPanelPosition(recognisedTextHolder);
1588
+ setTextChatPosition(chatHolderDiv);
1447
1589
  }
1448
1590
  // Define base styles for btn
1449
1591
  btn.style.color = '#fff';
@@ -1670,6 +1812,19 @@
1670
1812
  'rgb(122, 40, 255)'
1671
1813
  ]
1672
1814
  }
1815
+ },
1816
+ "textChat": {
1817
+ "background": {
1818
+ "color": ["#1eb6e5", "#1995ff"],
1819
+ "angle": 45
1820
+ },
1821
+ "hover": {
1822
+ "color": ["#1ba3ce", "#1686e5"],
1823
+ "angle": 45
1824
+ },
1825
+ "shadow": {
1826
+ "color": ["#6693bc", "#b3c9de"]
1827
+ }
1673
1828
  }
1674
1829
  };
1675
1830
  btnOval1.style.transform = 'rotate(-315deg)';
@@ -1760,7 +1915,9 @@
1760
1915
  function getStyleSheetMarker(andFlag) {
1761
1916
  return '.alan-' + getProjectId() + (andFlag ? '' : ' ');
1762
1917
  }
1763
- function createAlanStyleSheet(btnOptions) {
1918
+ function createAlanStyleSheet(webOptions) {
1919
+ var _a;
1920
+ var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67;
1764
1921
  var style;
1765
1922
  var keyFrames = '';
1766
1923
  var projectId = getProjectId();
@@ -1808,6 +1965,66 @@
1808
1965
  keyFrames += getStyleSheetMarker() + '.alan-overlay-for-alert {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;}';
1809
1966
  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;}';
1810
1967
  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;}';
1968
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat-holder {\n position: fixed;\n height: ".concat(((_d = (_c = (_b = webOptions === null || webOptions === void 0 ? void 0 : webOptions.chatOptions) === null || _b === void 0 ? void 0 : _b.textChat) === null || _c === void 0 ? void 0 : _c.popup) === null || _d === void 0 ? void 0 : _d.height) || "100", "%;\n min-height: ").concat(((_g = (_f = (_e = webOptions === null || webOptions === void 0 ? void 0 : webOptions.chatOptions) === null || _e === void 0 ? void 0 : _e.textChat) === null || _f === void 0 ? void 0 : _f.popup) === null || _g === void 0 ? void 0 : _g.minHeight) || "400", "px;\n max-height: ").concat(((_k = (_j = (_h = webOptions === null || webOptions === void 0 ? void 0 : webOptions.chatOptions) === null || _h === void 0 ? void 0 : _h.textChat) === null || _j === void 0 ? void 0 : _j.popup) === null || _k === void 0 ? void 0 : _k.maxHeight) || "1200", "px;\n width: 346px;\n min-width: 346px;\n max-width: 346px;\n display: none;\n }");
1969
+ keyFrames += '.mobile' + getStyleSheetMarker() + ".alan-btn__chat-holder {\n position: fixed; \n height: 100%;\n min-height: 100%;\n max-height: 100%;\n width: 100vw;\n min-width: 100vw;\n max-width: 100vw;\n display: none;\n top: 0;\n bottom:0;\n left:0;\n right:0;\n border-radius: 0px;\n }";
1970
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat {\n height: 100%;\n position: relative;\n overflow: hidden;\n display: flex;\n width: 100%;\n min-width: 100%;\n max-width: 100%;\n flex: 2;\n position: relative;\n flex-direction: column;\n background-color: ".concat(((_o = (_m = (_l = webOptions === null || webOptions === void 0 ? void 0 : webOptions.chatOptions) === null || _l === void 0 ? void 0 : _l.textChat) === null || _m === void 0 ? void 0 : _m.popup) === null || _o === void 0 ? void 0 : _o.backgroundColor) || "#FFFFFF", ";\n box-shadow: 0px 5px 44px rgba(0, 0, 0, 0.15);\n border-radius: 8px;\n }");
1971
+ keyFrames += '.mobile' + getStyleSheetMarker() + ".alan-btn__chat {\n border-radius: 0px;\n }";
1972
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat-textarea-holder {\n width: 100%;\n height: 76px;\n max-height: 76px;\n min-height: 76px;\n box-shadow: 0px 5px 44px rgba(0, 0, 0, 0.15);\n }";
1973
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat-messages-empty-block {\n flex: 1 1 auto;\n }";
1974
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat-messages {\n width: 100%;\n height: calc(100% - 136px);\n max-height: calc(100% - 136px);\n min-height: calc(100% - 136px);\n overflow-y: scroll;\n overflow-x: hidden;\n padding: 20px 12px;\n display: flex;\n flex-shrink: 0;\n flex-direction: column;\n }";
1975
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat-header {\n width: 100%;\n height: 60px;\n max-height: 60px;\n min-height: 60px;\n line-height: 60px;\n box-shadow: 0px 5px 44px rgb(0 0 0 / 15%);\n color: #0f2029;\n padding: 0px 12px;\n font-size: ".concat(((_r = (_q = (_p = webOptions === null || webOptions === void 0 ? void 0 : webOptions.chatOptions) === null || _p === void 0 ? void 0 : _p.textChat) === null || _q === void 0 ? void 0 : _q.header) === null || _r === void 0 ? void 0 : _r.fontSize) || 20, "px;\n background-color: ").concat(((_u = (_t = (_s = webOptions === null || webOptions === void 0 ? void 0 : webOptions.chatOptions) === null || _s === void 0 ? void 0 : _s.textChat) === null || _t === void 0 ? void 0 : _t.header) === null || _u === void 0 ? void 0 : _u.backgroundColor) || "#FFFFFF", ";\n color: ").concat(((_x = (_w = (_v = webOptions === null || webOptions === void 0 ? void 0 : webOptions.chatOptions) === null || _v === void 0 ? void 0 : _v.textChat) === null || _w === void 0 ? void 0 : _w.header) === null || _x === void 0 ? void 0 : _x.color) || "#000000", ";\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n padding-right: 24px;\n }");
1976
+ keyFrames += getStyleSheetMarker() + ".alan-btn__close-chat-btn {\n position: absolute;\n right: 12px;\n top: 0;\n height: 60px;\n display: flex;\n align-items: center;\n cursor: pointer;\n pointer-events: all;\n }";
1977
+ keyFrames += getStyleSheetMarker() + ".alan-btn__close-chat-btn svg path {\n fill: ".concat(((_2 = (_1 = (_0 = (_z = (_y = webOptions === null || webOptions === void 0 ? void 0 : webOptions.chatOptions) === null || _y === void 0 ? void 0 : _y.textChat) === null || _z === void 0 ? void 0 : _z.popup) === null || _0 === void 0 ? void 0 : _0.icons) === null || _1 === void 0 ? void 0 : _1["default"]) === null || _2 === void 0 ? void 0 : _2.fill) || "#C8C8CC", ";\n }");
1978
+ keyFrames += getStyleSheetMarker() + ".alan-btn__close-chat-btn:hover svg path {\n fill: ".concat(((_7 = (_6 = (_5 = (_4 = (_3 = webOptions === null || webOptions === void 0 ? void 0 : webOptions.chatOptions) === null || _3 === void 0 ? void 0 : _3.textChat) === null || _4 === void 0 ? void 0 : _4.popup) === null || _5 === void 0 ? void 0 : _5.icons) === null || _6 === void 0 ? void 0 : _6.hover) === null || _7 === void 0 ? void 0 : _7.fill) || "#007AFF", ";\n }");
1979
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat-messages::-webkit-scrollbar {\n width: 6px;\n height: 6px;\n }";
1980
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat-messages::-webkit-scrollbar-thumb {\n border-radius: 3px;\n background-color: rgba(224, 224, 224, 0.795);\n transition: background-color 300ms ease-in-out;\n }";
1981
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat-messages::-webkit-scrollbar-thumb:hover {\n background-color: rgba(230, 230, 230, 0.856);\n transition: background-color 300ms ease-in-out;\n }";
1982
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat-messages::-webkit-scrollbar-track {\n border-radius: 3px;\n background: transparent;\n }";
1983
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat-textarea {\n position: absolute;\n left: 8px;\n bottom: 8px;\n width: calc(100% - 16px);\n border-radius: 6px;\n border: 1px solid #C8C8CC;\n background: #fff;\n overflow-y: auto;\n outline: none;\n resize: none;\n font-size: 13px;\n line-height: 1.25;\n text-align: left;\n color: #0f2029;\n padding: 12px 48px 12px 12px;\n -webkit-user-select: text;\n -khtml-user-select: text;\n -moz-user-select: text;\n -ms-user-select: text;\n user-select: text;\n transition: opacity 300ms ease-in-out;\n }";
1984
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat-holder.alan-text-chat__voice-enabled .alan-btn__chat-send-btn {\n right: 56px;\n }";
1985
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat-holder.alan-text-chat__voice-enabled .alan-btn__chat-textarea {\n padding: 12px 92px 12px 12px;\n }";
1986
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat.active .alan-btn__chat-textarea {\n opacity: 0.2;\n transition: opacity 300ms ease-in-out;\n pointer-events: none;\n -webkit-touch-callout: none;\n -webkit-user-select: none;\n -khtml-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n }";
1987
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat.active .alan-btn__chat-send-btn {\n opacity: 0.2;\n pointer-events: none;\n transition: opacity 300ms ease-in-out;\n }";
1988
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat-send-btn {\n position: absolute;\n transition: opacity 300ms ease-in-out;\n right: 12px;\n bottom: 16px;\n min-width: 40px;\n width: 40px;\n max-width: 40px;\n height: 40px;\n max-height: 40px;\n min-height: 40px;\n display: flex;\n flex-direction: row;\n cursor: pointer;\n justify-content: center;\n align-items: center;\n border-radius: 50%;\n -webkit-touch-callout: none; /* iOS Safari */\n -webkit-user-select: none; /* Chrome/Safari/Opera */\n -khtml-user-select: none; /* Konqueror */\n -moz-user-select: none; /* Firefox */\n -ms-user-select: none; /* IE/Edge */\n user-select: none;\n }";
1989
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat-send-btn svg {\n width: 22px;\n position: relative;\n left: 2px;\n }";
1990
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat-send-btn svg path {\n fill: ".concat(((_12 = (_11 = (_10 = (_9 = (_8 = webOptions === null || webOptions === void 0 ? void 0 : webOptions.chatOptions) === null || _8 === void 0 ? void 0 : _8.textChat) === null || _9 === void 0 ? void 0 : _9.popup) === null || _10 === void 0 ? void 0 : _10.icons) === null || _11 === void 0 ? void 0 : _11["default"]) === null || _12 === void 0 ? void 0 : _12.fill) || "#C8C8CC", ";\n }");
1991
+ if (!isMobile()) {
1992
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat-send-btn:hover svg path {\n fill: ".concat(((_17 = (_16 = (_15 = (_14 = (_13 = webOptions === null || webOptions === void 0 ? void 0 : webOptions.chatOptions) === null || _13 === void 0 ? void 0 : _13.textChat) === null || _14 === void 0 ? void 0 : _14.popup) === null || _15 === void 0 ? void 0 : _15.icons) === null || _16 === void 0 ? void 0 : _16.hover) === null || _17 === void 0 ? void 0 : _17.fill) || "#007AFF", ";\n }");
1993
+ }
1994
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat-mic-btn {\n position: absolute;\n right: 12px;\n bottom: 16px;\n min-width: 40px;\n width: 40px;\n max-width: 40px;\n height: 40px;\n max-height: 40px;\n min-height: 40px;\n display: flex;\n flex-direction: row;\n cursor: pointer;\n justify-content: center;\n align-items: center;\n border-radius: 50%;\n }";
1995
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat-mic-btn.active::before {\n content: '';\n position: absolute;\n z-index: -1;\n left: 0;\n top: 0;\n height: 100%;\n width: 100%;\n background-color: ".concat(((_22 = (_21 = (_20 = (_19 = (_18 = webOptions === null || webOptions === void 0 ? void 0 : webOptions.chatOptions) === null || _18 === void 0 ? void 0 : _18.textChat) === null || _19 === void 0 ? void 0 : _19.popup) === null || _20 === void 0 ? void 0 : _20.icons) === null || _21 === void 0 ? void 0 : _21["default"]) === null || _22 === void 0 ? void 0 : _22.fill) || "#C8C8CC", ";\n opacity: 0.3;\n border-radius: 50%;\n }");
1996
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat-notifications-bubble {\n position: absolute;\n right: 4px;\n top: -4px;\n height: 20px;\n width: 20px;\n background-color: ".concat(((_25 = (_24 = (_23 = webOptions === null || webOptions === void 0 ? void 0 : webOptions.chatOptions) === null || _23 === void 0 ? void 0 : _23.textChat) === null || _24 === void 0 ? void 0 : _24.notifications) === null || _25 === void 0 ? void 0 : _25.backgroundColor) || "rgba(208, 2, 27, 1)", ";\n color: ").concat(((_28 = (_27 = (_26 = webOptions === null || webOptions === void 0 ? void 0 : webOptions.chatOptions) === null || _26 === void 0 ? void 0 : _26.textChat) === null || _27 === void 0 ? void 0 : _27.notifications) === null || _28 === void 0 ? void 0 : _28.color) || "rgba(255, 255, 255, 1)", ";\n border-radius: 50%;\n z-index: ").concat(btnZIndex + 1, ";\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n font-size: 10px;\n }");
1997
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat-notifications-bubble:empty {\n display: none;\n }";
1998
+ if (!isMobile()) {
1999
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat-mic-btn.active:hover::before {\n opacity: 0.35;\n }";
2000
+ }
2001
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat-mic-btn svg {\n width: 22px;\n }";
2002
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat-mic-btn svg path {\n fill: ".concat(((_33 = (_32 = (_31 = (_30 = (_29 = webOptions === null || webOptions === void 0 ? void 0 : webOptions.chatOptions) === null || _29 === void 0 ? void 0 : _29.textChat) === null || _30 === void 0 ? void 0 : _30.popup) === null || _31 === void 0 ? void 0 : _31.icons) === null || _32 === void 0 ? void 0 : _32["default"]) === null || _33 === void 0 ? void 0 : _33.fill) || "#C8C8CC", ";\n }");
2003
+ if (!isMobile()) {
2004
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat-mic-btn:hover svg path {\n fill: ".concat(((_38 = (_37 = (_36 = (_35 = (_34 = webOptions === null || webOptions === void 0 ? void 0 : webOptions.chatOptions) === null || _34 === void 0 ? void 0 : _34.textChat) === null || _35 === void 0 ? void 0 : _35.popup) === null || _36 === void 0 ? void 0 : _36.icons) === null || _37 === void 0 ? void 0 : _37.hover) === null || _38 === void 0 ? void 0 : _38.fill) || "#007AFF", ";\n }");
2005
+ }
2006
+ keyFrames += getStyleSheetMarker() + ".alan-text-chat__animated-btn-bars {\n height:40px;\n width:40px;\n border-radius: 50%;\n justify-content: center;\n align-items: center;\n background: ".concat(((_43 = (_42 = (_41 = (_40 = (_39 = webOptions === null || webOptions === void 0 ? void 0 : webOptions.chatOptions) === null || _39 === void 0 ? void 0 : _39.textChat) === null || _40 === void 0 ? void 0 : _40.popup) === null || _41 === void 0 ? void 0 : _41.icons) === null || _42 === void 0 ? void 0 : _42.hover) === null || _43 === void 0 ? void 0 : _43.fill) || "#007AFF", ";\n display:none;\n }");
2007
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat-mic-btn.active .alan-text-chat__animated-btn-bars {\n display: flex;\n }";
2008
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat-mic-btn.active svg {\n display: none;\n }";
2009
+ keyFrames += getStyleSheetMarker() + ".alan-text-chat__bar {\n background: #ffffff;\n bottom: 1px;\n height: 3px;\n width: 2px;\n margin: 0px 1px;\n border-radius: 5px;\n }";
2010
+ keyFrames += getStyleSheetMarker() + ".alan-text-chat__bar-1 {\n animation: alan-btn__sound-bar-1 0ms -1200ms linear infinite alternate;\n }";
2011
+ keyFrames += getStyleSheetMarker() + ".alan-text-chat__bar-2 {\n animation: alan-btn__sound-bar-2 0ms -1200ms linear infinite alternate;\n }";
2012
+ keyFrames += getStyleSheetMarker() + ".alan-text-chat__bar-3 {\n animation: alan-btn__sound-bar-3 0ms -1200ms linear infinite alternate;\n }";
2013
+ keyFrames += getStyleSheetMarker() + generateKeyFrame('alan-btn__sound-bar-1', "\n 0% {\n \n height: 3px; \n }\n 100% {\n \n height: 10px; \n }");
2014
+ keyFrames += getStyleSheetMarker() + generateKeyFrame('alan-btn__sound-bar-2', "\n 0% {\n \n height: 8px; \n }\n 100% {\n \n height: 15px; \n }");
2015
+ keyFrames += getStyleSheetMarker() + generateKeyFrame('alan-btn__sound-bar-3', "\n 0% {\n \n height: 12px; \n }\n 100% {\n \n height: 28px; \n }");
2016
+ keyFrames += getStyleSheetMarker() + ".alan-text-chat__bar:nth-child(1) { animation-duration: 474ms; }";
2017
+ keyFrames += getStyleSheetMarker() + ".alan-text-chat__bar:nth-child(2) { animation-duration: 433ms; }";
2018
+ keyFrames += getStyleSheetMarker() + ".alan-text-chat__bar:nth-child(3) { animation-duration: 407ms; }";
2019
+ keyFrames += getStyleSheetMarker() + ".alan-text-chat__bar:nth-child(4) { animation-duration: 458ms; }";
2020
+ keyFrames += getStyleSheetMarker() + ".alan-text-chat__bar:nth-child(5) { animation-duration: 400ms; }";
2021
+ keyFrames += getStyleSheetMarker() + ".alan-text-chat__bar:nth-child(6) { animation-duration: 427ms; }";
2022
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat-request {\n margin-bottom: 16px;\n max-width: 100%;\n padding: 9px;\n line-height: 1.46;\n display: block;\n float: right;\n clear: both;\n border-radius: 16px 16px 0 16px;\n position: relative;\n background-color: ".concat(((_47 = (_46 = (_45 = (_44 = webOptions === null || webOptions === void 0 ? void 0 : webOptions.chatOptions) === null || _44 === void 0 ? void 0 : _44.textChat) === null || _45 === void 0 ? void 0 : _45.bubbles) === null || _46 === void 0 ? void 0 : _46.request) === null || _47 === void 0 ? void 0 : _47.backgroundColor) || "#0078FF", ";\n color: ").concat(((_51 = (_50 = (_49 = (_48 = webOptions === null || webOptions === void 0 ? void 0 : webOptions.chatOptions) === null || _48 === void 0 ? void 0 : _48.textChat) === null || _49 === void 0 ? void 0 : _49.bubbles) === null || _50 === void 0 ? void 0 : _50.request) === null || _51 === void 0 ? void 0 : _51.color) || "#ffffff", ";\n font-size: ").concat(((_55 = (_54 = (_53 = (_52 = webOptions === null || webOptions === void 0 ? void 0 : webOptions.chatOptions) === null || _52 === void 0 ? void 0 : _52.textChat) === null || _53 === void 0 ? void 0 : _53.bubbles) === null || _54 === void 0 ? void 0 : _54.request) === null || _55 === void 0 ? void 0 : _55.fontSize) || "14", "px;\n word-break: break-word;\n text-align: right;\n -webkit-touch-callout: text; /* iOS Safari */\n -webkit-user-select: text; /* Chrome/Safari/Opera */\n -khtml-user-select: text; /* Konqueror */\n -moz-user-select: text; /* Firefox */\n -ms-user-select: text; /* IE/Edge */\n user-select: text;\n }");
2023
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat-request * {\n -webkit-touch-callout: text; /* iOS Safari */\n -webkit-user-select: text; /* Chrome/Safari/Opera */\n -khtml-user-select: text; /* Konqueror */\n -moz-user-select: text; /* Firefox */\n -ms-user-select: text; /* IE/Edge */\n user-select: text;\n }";
2024
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat-response {\n margin-bottom: 16px;\n max-width: 100%;\n padding: 9px;\n line-height: 1.46;\n display: block;\n float: left;\n clear: both;\n border-radius: 0 16px 16px 16px;\n position: relative;\n background-color: ".concat(((_59 = (_58 = (_57 = (_56 = webOptions === null || webOptions === void 0 ? void 0 : webOptions.chatOptions) === null || _56 === void 0 ? void 0 : _56.textChat) === null || _57 === void 0 ? void 0 : _57.bubbles) === null || _58 === void 0 ? void 0 : _58.response) === null || _59 === void 0 ? void 0 : _59.backgroundColor) || "#E9E9EB", ";\n color: ").concat(((_63 = (_62 = (_61 = (_60 = webOptions === null || webOptions === void 0 ? void 0 : webOptions.chatOptions) === null || _60 === void 0 ? void 0 : _60.textChat) === null || _61 === void 0 ? void 0 : _61.bubbles) === null || _62 === void 0 ? void 0 : _62.response) === null || _63 === void 0 ? void 0 : _63.color) || "#0f2029", ";\n font-size: ").concat(((_67 = (_66 = (_65 = (_64 = webOptions === null || webOptions === void 0 ? void 0 : webOptions.chatOptions) === null || _64 === void 0 ? void 0 : _64.textChat) === null || _65 === void 0 ? void 0 : _65.bubbles) === null || _66 === void 0 ? void 0 : _66.response) === null || _67 === void 0 ? void 0 : _67.fontSize) || "14", "px;\n word-break: break-word;\n text-align: left;\n -webkit-touch-callout: text; /* iOS Safari */\n -webkit-user-select: text; /* Chrome/Safari/Opera */\n -khtml-user-select: text; /* Konqueror */\n -moz-user-select: text; /* Firefox */\n -ms-user-select: text; /* IE/Edge */\n user-select: text;\n }");
2025
+ keyFrames += getStyleSheetMarker() + ".alan-btn__chat-response * {\n -webkit-touch-callout: text; /* iOS Safari */\n -webkit-user-select: text; /* Chrome/Safari/Opera */\n -khtml-user-select: text; /* Konqueror */\n -moz-user-select: text; /* Firefox */\n -ms-user-select: text; /* IE/Edge */\n user-select: text;\n }";
2026
+ keyFrames += getStyleSheetMarker(true) + ".text-chat-is-opened .alanBtn {\n display: none;\n }";
2027
+ keyFrames += getStyleSheetMarker(true) + ".text-chat-is-opened .alanBtn-recognised-text-holder {\n display: none;\n }";
1811
2028
  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;}';
1812
2029
  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);}';
1813
2030
  keyFrames += getStyleSheetMarker() + '.alan-overlay-popup.alan-btn-lib__top.alan-btn-lib__right {border-top-right-radius: 0!important;}';
@@ -1821,6 +2038,7 @@
1821
2038
  keyFrames += getStyleSheetMarker() + '.alan-overlay-popup:hover .alan-overlay-popup__ok{opacity:1;transition:opacity 300ms ease-in-out;}';
1822
2039
  keyFrames += getStyleSheetMarker() + generateKeyFrame('alan-gradient', '0%{backgroundPosition: 0 0;}50%{backgroundPosition: -100% 0;}100%{backgroundPosition: 0 0;}');
1823
2040
  keyFrames += getStyleSheetMarker() + generateKeyFrame('alan-pulsating', '0%{transform: scale(1.11111);}50%{transform: scale(1.0);}100%{transform: scale(1.11111);}');
2041
+ keyFrames += getStyleSheetMarker() + generateKeyFrame('alan-text-chat-pulsating', '0%{transform: scale(1.09);}50%{transform: scale(1.0);}100%{transform: scale(1.09);}');
1824
2042
  keyFrames += getStyleSheetMarker() + generateKeyFrame('alan-mic-pulsating', '0%{transform: scale(0.91);}50%{transform: scale(1.0);}100%{transform: scale(0.91);}');
1825
2043
  keyFrames += getStyleSheetMarker() + generateKeyFrame('alan-triangle-mic-pulsating', '0%{transform: scale(0.94);}50%{transform: scale(1.0);}100%{transform: scale(0.94);}');
1826
2044
  keyFrames += getStyleSheetMarker() + generateKeyFrame('alan-fade-in', '0%{opacity: 0;}100%{opacity:1;}');
@@ -1871,23 +2089,22 @@
1871
2089
  keyFrames += getStyleSheetMarker() + generateKeyFrame('alan-text-fade-in', '0%{ opacity: 0; } 100%{ opacity: 1; }');
1872
2090
  keyFrames += getStyleSheetMarker() + '.alanBtn-bg-default.super-hidden{opacity:0!important;display:none;}';
1873
2091
  var predefinedBtnColorOptions = defaultBtnColorOptions;
1874
- if (btnOptions) {
1875
- if (btnOptions.btnLayerOptions) { //old settings
2092
+ if (webOptions === null || webOptions === void 0 ? void 0 : webOptions.btnOptions) {
2093
+ if (webOptions === null || webOptions === void 0 ? void 0 : webOptions.btnOptions.btnLayerOptions) { //old settings
1876
2094
  predefinedBtnColorOptions = defaultBtnColorOptions;
1877
2095
  }
1878
2096
  else {
1879
- predefinedBtnColorOptions = btnOptions || defaultBtnColorOptions;
2097
+ predefinedBtnColorOptions = (webOptions === null || webOptions === void 0 ? void 0 : webOptions.btnOptions) ? __assign(__assign({}, defaultBtnColorOptions), webOptions === null || webOptions === void 0 ? void 0 : webOptions.btnOptions) : defaultBtnColorOptions;
1880
2098
  }
1881
2099
  }
1882
- var btnBackgroundOptionKeys = Object.keys(predefinedBtnColorOptions);
1883
2100
  var tempLayer;
1884
2101
  var stateName;
1885
- var stateMapping = {
1886
- idle: ['default'],
1887
- listen: ['listening'],
1888
- process: ['intermediate', 'understood'],
1889
- reply: ['speaking']
1890
- };
2102
+ var stateMapping = (_a = {},
2103
+ _a[textChatIsAvailable ? 'textChat' : 'idle'] = ['default'],
2104
+ _a.listen = ['listening'],
2105
+ _a.process = ['intermediate', 'understood'],
2106
+ _a.reply = ['speaking'],
2107
+ _a);
1891
2108
  var stateNameClasses, stateNameClass;
1892
2109
  var states = Object.keys(stateMapping);
1893
2110
  for (i = 0; i < states.length; i++) {
@@ -1957,6 +2174,7 @@
1957
2174
  window.tutorProject.on('text', onTextCbInMicBtn);
1958
2175
  window.tutorProject.on('parsed', onParsedCbInMicBtn);
1959
2176
  alanAudio.on('command', onCommandCbInMicBtn);
2177
+ alanAudio.on('afterText', onAfterTextCbInMicBtn);
1960
2178
  //window.tutorProject.on('popup', onPopup);
1961
2179
  // console.info('BTN: tutorProject', options.key);
1962
2180
  }
@@ -1980,6 +2198,27 @@
1980
2198
  }
1981
2199
  return mode;
1982
2200
  }
2201
+ function throttle(func, wait) {
2202
+ if (wait === void 0) { wait = 100; }
2203
+ var timer = null;
2204
+ var throttlePause;
2205
+ return function () {
2206
+ var args = [];
2207
+ for (var _i = 0; _i < arguments.length; _i++) {
2208
+ args[_i] = arguments[_i];
2209
+ }
2210
+ if (!throttlePause) {
2211
+ func.apply(this, args);
2212
+ throttlePause = true;
2213
+ if (timer === null) {
2214
+ timer = setTimeout(function () {
2215
+ timer = null;
2216
+ throttlePause = false;
2217
+ }, wait);
2218
+ }
2219
+ }
2220
+ };
2221
+ }
1983
2222
  function debounce(func, wait) {
1984
2223
  var timeout;
1985
2224
  var delay = wait || 100;
@@ -2059,18 +2298,15 @@
2059
2298
  sendClientEvent({ micPermissionPrompt: true });
2060
2299
  }
2061
2300
  if (result.state !== 'granted') {
2062
- sendClientEvent({ buttonClicked: true, micAllowed: false });
2063
- }
2064
- else {
2065
- sendClientEvent({ buttonClicked: true, micAllowed: true });
2301
+ sendClientEvent({ micAllowed: false });
2066
2302
  }
2067
2303
  })["catch"](function (error) {
2068
2304
  console.warn('Not possible to detect mic permissions, details: ', error);
2069
- setTimeout(function () { return sendClientEvent({ buttonClicked: true, micAllowed: alanAudio.isMicAllowed() }); }, 300);
2305
+ setTimeout(function () { return sendClientEvent({ micAllowed: alanAudio.isMicAllowed() }); }, 300);
2070
2306
  });
2071
2307
  }
2072
2308
  else {
2073
- setTimeout(function () { return sendClientEvent({ buttonClicked: true, micAllowed: alanAudio.isMicAllowed() }); }, 300);
2309
+ setTimeout(function () { return sendClientEvent({ micAllowed: alanAudio.isMicAllowed() }); }, 300);
2074
2310
  }
2075
2311
  }
2076
2312
  alanAudio.on('popup', onPopup);
@@ -2093,17 +2329,71 @@
2093
2329
  options.onMicStarted();
2094
2330
  }
2095
2331
  }
2096
- function activateAlanButton() {
2332
+ function sendFirstClickEvent() {
2097
2333
  if (!firstClick) {
2098
2334
  firstClick = true;
2099
2335
  sendClientEvent({ firstClick: true });
2100
2336
  }
2337
+ }
2338
+ function onBtnClick() {
2339
+ if (afterMouseMove)
2340
+ return;
2341
+ if (!dndBackAnimFinished)
2342
+ return;
2343
+ if (textChatIsAvailable && textChatIsHidden) {
2344
+ activateAlanButton();
2345
+ }
2346
+ else {
2347
+ activateVoiceBtn();
2348
+ //remove focus state from the btn after click
2349
+ this.blur();
2350
+ }
2351
+ }
2352
+ function onBtnClickInTextChat() {
2353
+ activateVoiceBtn();
2354
+ }
2355
+ function activateVoiceBtn() {
2356
+ if (alanAudio) {
2357
+ if (state === 'default') {
2358
+ activateAlanButton();
2359
+ }
2360
+ else {
2361
+ alanAudio.stop();
2362
+ }
2363
+ }
2364
+ else {
2365
+ throw new Error('No alan audio instance was provided');
2366
+ }
2367
+ }
2368
+ btn.addEventListener('click', onBtnClick);
2369
+ function activateAlanButton(opts) {
2370
+ hidePopup(null);
2371
+ sendFirstClickEvent();
2101
2372
  if (state === 'default') {
2102
2373
  coldPlayForSoundNext();
2103
2374
  }
2375
+ var continueWithAudio = true;
2376
+ if (textChatIsAvailable) {
2377
+ continueWithAudio = false;
2378
+ if (textChatIsHidden) {
2379
+ sendClientEvent({ buttonClicked: true });
2380
+ showTextChat();
2381
+ setTextChatPosition(chatHolderDiv);
2382
+ }
2383
+ if ((opts === null || opts === void 0 ? void 0 : opts.activate) === true && voiceEnabledInTextChat) {
2384
+ if (voiceEnabledInTextChat) {
2385
+ continueWithAudio = true;
2386
+ }
2387
+ }
2388
+ }
2389
+ if (!continueWithAudio) {
2390
+ return new Promise(function (resolve) {
2391
+ resolve();
2392
+ });
2393
+ }
2104
2394
  if (currentErrMsg) {
2105
2395
  if (currentErrMsg === MIC_BLOCKED_MSG) {
2106
- sendClientEvent({ buttonClicked: true, micAllowed: false });
2396
+ sendClientEvent({ micAllowed: false });
2107
2397
  showAlert(currentErrMsg);
2108
2398
  }
2109
2399
  else {
@@ -2143,14 +2433,14 @@
2143
2433
  break;
2144
2434
  case PERMISSION_DENIED:
2145
2435
  reject({ err: MIC_BLOCKED_CODE });
2146
- sendClientEvent({ buttonClicked: true, micAllowed: false });
2436
+ sendClientEvent({ micAllowed: false });
2147
2437
  break;
2148
2438
  case LISTENING:
2149
2439
  case SPEAKING:
2150
2440
  case INTERMEDIATE:
2151
2441
  case UNDERSTOOD:
2152
2442
  resolve();
2153
- sendClientEvent({ buttonClicked: true, micAllowed: true });
2443
+ sendClientEvent({ micAllowed: true });
2154
2444
  break;
2155
2445
  default:
2156
2446
  }
@@ -2161,6 +2451,27 @@
2161
2451
  });
2162
2452
  return activatePromise;
2163
2453
  }
2454
+ function deactivateAlanButton() {
2455
+ if (btnDisabled) {
2456
+ return;
2457
+ }
2458
+ alanAudio.stop();
2459
+ }
2460
+ function sendText(text) {
2461
+ return new Promise(function (resolve, reject) {
2462
+ window.tutorProject.call('text', { text: text }, function (e, res) {
2463
+ if (e) {
2464
+ reject({ error: e });
2465
+ }
2466
+ else if (res && res.error) {
2467
+ reject(__assign({}, res));
2468
+ }
2469
+ else {
2470
+ resolve(res);
2471
+ }
2472
+ });
2473
+ });
2474
+ }
2164
2475
  function checkIfPlayAllowed() {
2165
2476
  if (alanAudio.isAudioRunning()) {
2166
2477
  sendClientEvent({ playAllowed: true });
@@ -2185,6 +2496,8 @@
2185
2496
  return;
2186
2497
  if (!popupEnabled)
2187
2498
  return;
2499
+ if (!textChatIsHidden)
2500
+ return;
2188
2501
  savedPopupOptions = popupOptions;
2189
2502
  var message = popupOptions.message;
2190
2503
  var buttonMarginInPopup = popupOptions.buttonMarginInPopup;
@@ -2324,29 +2637,13 @@
2324
2637
  }
2325
2638
  }
2326
2639
  }
2327
- btn.addEventListener('click', function (e) {
2328
- if (afterMouseMove)
2329
- return;
2330
- if (!dndBackAnimFinished)
2331
- return;
2332
- hidePopup(null);
2333
- if (alanAudio) {
2334
- if (state === 'default') {
2335
- activateAlanButton();
2336
- }
2337
- else {
2338
- alanAudio.stop();
2339
- }
2340
- }
2341
- else {
2342
- throw new Error('No alan audio instance was provided');
2343
- }
2344
- //remove focus state from the btn after click
2345
- this.blur();
2346
- });
2347
2640
  function showRecognisedText(e) {
2348
2641
  var recognisedText = '';
2349
- if (hideS2TPanel || dndIsDown) {
2642
+ if (hideS2TPanel || dndIsDown || !isAlanActive) {
2643
+ return;
2644
+ }
2645
+ if (!textChatIsHidden) {
2646
+ renderMessageInTextChat(Object.assign(e, { type: 'request' }));
2350
2647
  return;
2351
2648
  }
2352
2649
  recognisedTextVisible = true;
@@ -2417,7 +2714,8 @@
2417
2714
  }
2418
2715
  }
2419
2716
  function onOptionsReceived(data) {
2420
- var _a, _b, _c;
2717
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
2718
+ console.log('Alan: options received');
2421
2719
  if (data && data.web) {
2422
2720
  keepButtonPositionAfterDnD = ((_a = data.web.alanButtonDragAndDrop) === null || _a === void 0 ? void 0 : _a.keepButtonPositionAfterDnD) || data.web.keepButtonPositionAfterDnD;
2423
2721
  if (!keepButtonPositionAfterDnD) {
@@ -2444,12 +2742,27 @@
2444
2742
  popupEnabled = false;
2445
2743
  hidePopup();
2446
2744
  }
2745
+ if (!isTutorMode()) {
2746
+ if (data && data.web && ((_e = (_d = data.web.chatOptions) === null || _d === void 0 ? void 0 : _d.textChat) === null || _e === void 0 ? void 0 : _e.enabled) === true) {
2747
+ textChatIsAvailable = true;
2748
+ voiceEnabledInTextChat = (_h = (_g = (_f = data.web.chatOptions) === null || _f === void 0 ? void 0 : _f.textChat) === null || _g === void 0 ? void 0 : _g.voice) === null || _h === void 0 ? void 0 : _h.enabled;
2749
+ textChatOptions = (_j = data.web.chatOptions) === null || _j === void 0 ? void 0 : _j.textChat;
2750
+ initTextChat();
2751
+ if (((_m = (_l = (_k = data.web.chatOptions) === null || _k === void 0 ? void 0 : _k.textChat) === null || _l === void 0 ? void 0 : _l.popup) === null || _m === void 0 ? void 0 : _m.openByDefualt) === true) {
2752
+ showTextChat();
2753
+ }
2754
+ }
2755
+ else {
2756
+ textChatIsAvailable = false;
2757
+ hideTextChat();
2758
+ }
2759
+ }
2447
2760
  if (data && data.web && data.web.timeout !== undefined) {
2448
2761
  turnOffTimeout = data.web.timeout;
2449
2762
  setTurnOffVoiceTimeout();
2450
2763
  }
2451
2764
  if (data && data.web) {
2452
- applyBtnOptions(data.web.btnOptions);
2765
+ applyBtnOptions(data.web);
2453
2766
  }
2454
2767
  applyLogoOptions(data);
2455
2768
  if (options.mode !== 'tutor') {
@@ -2468,7 +2781,9 @@
2468
2781
  }
2469
2782
  else {
2470
2783
  // sendClientEvent({ buttonReady: true });
2471
- showBtn();
2784
+ if (btnDisabled) {
2785
+ showBtn();
2786
+ }
2472
2787
  }
2473
2788
  }
2474
2789
  function onConnectStatusChange(res) {
@@ -2615,25 +2930,46 @@
2615
2930
  switchState(LISTENING);
2616
2931
  turnOffVoiceFn();
2617
2932
  }
2618
- function onTextCbInMicBtn(e) {
2619
- // console.info('BTN: onTextCb', e, new Date());
2933
+ function _onTextCb(e) {
2934
+ console.info('BTN: onTextCb', e, new Date());
2935
+ var event = Object.assign(e, { name: 'text', type: AlanButtonTextMessageType.Response });
2620
2936
  if (options.onEvent) {
2621
- options.onEvent(Object.assign(e, { name: 'text', type: AlanButtonTextMessageType.Response }));
2937
+ options.onEvent(event);
2622
2938
  }
2939
+ renderMessageInTextChat(event);
2623
2940
  turnOffVoiceFn();
2624
2941
  }
2942
+ function onTextCbInMicBtn(e) {
2943
+ var _a, _b, _c, _d;
2944
+ if (!isAlanActive && ((_b = (_a = e.ctx) === null || _a === void 0 ? void 0 : _a.opts) === null || _b === void 0 ? void 0 : _b.activate) === true) {
2945
+ activateAlanButton({ activate: (_d = (_c = e.ctx) === null || _c === void 0 ? void 0 : _c.opts) === null || _d === void 0 ? void 0 : _d.activate }).then(function () {
2946
+ _onTextCb(e);
2947
+ });
2948
+ }
2949
+ else {
2950
+ _onTextCb(e);
2951
+ }
2952
+ }
2953
+ function onAfterTextCbInMicBtn(e) {
2954
+ var _a, _b;
2955
+ if (isAlanActive && ((_b = (_a = e.ctx) === null || _a === void 0 ? void 0 : _a.opts) === null || _b === void 0 ? void 0 : _b.deactivate) === true) {
2956
+ deactivateAlanButton();
2957
+ }
2958
+ }
2625
2959
  function onParsedCbInMicBtn(e) {
2626
2960
  // console.info('BTN: onParsedCb', e, new Date());
2961
+ var event = Object.assign(e, { name: 'parsed' });
2627
2962
  if (options.onEvent) {
2628
- options.onEvent(Object.assign(e, { name: 'parsed' }));
2963
+ options.onEvent(event);
2629
2964
  }
2630
2965
  turnOffVoiceFn();
2631
- showRecognisedText(e);
2966
+ showRecognisedText(event);
2632
2967
  }
2633
2968
  function onRecognizedCbInMicBtn(e) {
2634
2969
  // console.info('BTN: onRecognizedTextCb', e, new Date());
2970
+ var event = Object.assign(e, { name: 'recognized' });
2635
2971
  if (options.onEvent) {
2636
- options.onEvent(Object.assign(e, { name: 'recognized' }));
2972
+ options.onEvent(event);
2637
2973
  }
2638
2974
  if (e.final === true) {
2639
2975
  switchState(UNDERSTOOD);
@@ -2641,12 +2977,11 @@
2641
2977
  else {
2642
2978
  switchState(INTERMEDIATE);
2643
2979
  }
2644
- showRecognisedText(e);
2980
+ showRecognisedText(event);
2645
2981
  turnOffVoiceFn();
2646
2982
  }
2647
- function onCommandCbInMicBtn(e) {
2648
- var _a, _b;
2649
- // console.info('BTN: onCommandCbInMicBtn', e, new Date());
2983
+ function _onCommandCb(e) {
2984
+ var _a, _b, _c, _d;
2650
2985
  if (isAlanActive || (!isAlanActive && ((_b = (_a = e.ctx) === null || _a === void 0 ? void 0 : _a.opts) === null || _b === void 0 ? void 0 : _b.force) === true)) {
2651
2986
  if (options.onCommand) {
2652
2987
  options.onCommand(e.data);
@@ -2654,9 +2989,24 @@
2654
2989
  }
2655
2990
  if (isAlanActive) {
2656
2991
  switchState(LISTENING);
2992
+ if (((_d = (_c = e.ctx) === null || _c === void 0 ? void 0 : _c.opts) === null || _d === void 0 ? void 0 : _d.deactivate) === true) {
2993
+ deactivateAlanButton();
2994
+ }
2657
2995
  }
2658
2996
  turnOffVoiceFn();
2659
2997
  }
2998
+ function onCommandCbInMicBtn(e) {
2999
+ var _a, _b;
3000
+ // console.info('BTN: onCommandCbInMicBtn', e, new Date());
3001
+ if (!isAlanActive && (((_b = (_a = e.ctx) === null || _a === void 0 ? void 0 : _a.opts) === null || _b === void 0 ? void 0 : _b.activate) === true)) {
3002
+ activateAlanButton().then(function () {
3003
+ _onCommandCb(e);
3004
+ });
3005
+ }
3006
+ else {
3007
+ _onCommandCb(e);
3008
+ }
3009
+ }
2660
3010
  function onScriptsCb(e) {
2661
3011
  if (options.onEvent) {
2662
3012
  options.onEvent(Object.assign(e, { name: 'scripts' }));
@@ -2705,6 +3055,218 @@
2705
3055
  logosToHide[i].style.opacity = 0;
2706
3056
  }
2707
3057
  }
3058
+ function escapeHtml(text) {
3059
+ var resultStr = text;
3060
+ var entityMap = {
3061
+ "<script>": "&lt;script&gt;",
3062
+ "</script>": "&lt;/script&gt;"
3063
+ };
3064
+ for (var key in entityMap) {
3065
+ var r = new RegExp("".concat(key), 'gi');
3066
+ resultStr = String(resultStr).replace(r, entityMap[key]);
3067
+ }
3068
+ return resultStr;
3069
+ }
3070
+ function renderMessageInTextChat(msg) {
3071
+ if (!textChatIsAvailable)
3072
+ return;
3073
+ console.info('==== MSG', msg);
3074
+ var msgInd = null;
3075
+ var msgHtml = '';
3076
+ var isNewMsg = true;
3077
+ if (msg.name === 'text' || msg.name === 'parsed' || msg.name === 'recognized') {
3078
+ msgHtml = '<div class="' + (msg.type === 'request' ? 'alan-btn__chat-request' : 'alan-btn__chat-response') + '">' +
3079
+ escapeHtml(msg.text) + '</div>';
3080
+ }
3081
+ if ((msg.name === 'recognized' || msg.name === 'parsed' || msg.name === 'text') && textChatMessages.length > 0) {
3082
+ var lastMsg = textChatMessages[textChatMessages.length - 1];
3083
+ if ((lastMsg.name === 'recognized' && msg.name === 'recognized') ||
3084
+ (lastMsg.name === 'recognized' && msg.name === 'parsed' && msg.text === lastMsg.text) ||
3085
+ (msg.type === 'request' && lastMsg.type === 'request' && lastMsg.reqId && msg.reqId === lastMsg.reqId)) {
3086
+ msgInd = textChatMessages.length - 1;
3087
+ textChatMessages[msgInd] = msg;
3088
+ isNewMsg = false;
3089
+ }
3090
+ }
3091
+ if (isNewMsg) {
3092
+ textChatMessages.push(msg);
3093
+ var msgHolder = document.getElementById('chatMessages');
3094
+ var div = document.createElement('div');
3095
+ div.id = 'msg-' + (textChatMessages.length - 1);
3096
+ div.innerHTML = msgHtml;
3097
+ msgHolder.appendChild(div);
3098
+ if (textChatIsAvailable && textChatIsHidden && msg.type === 'response') {
3099
+ unreadChatMsgCount++;
3100
+ }
3101
+ setTimeout(function () {
3102
+ document.getElementById('chatMessages').scroll({
3103
+ top: document.getElementById('chatMessages').scrollHeight + 500,
3104
+ left: 0,
3105
+ behavior: 'smooth'
3106
+ });
3107
+ }, 300);
3108
+ }
3109
+ else {
3110
+ if (document.getElementById('msg-' + msgInd)) {
3111
+ document.getElementById('msg-' + msgInd).innerHTML = msgHtml;
3112
+ }
3113
+ }
3114
+ if (textChatIsAvailable && textChatIsHidden) {
3115
+ showChatNotifications();
3116
+ }
3117
+ }
3118
+ function _sendText(text) {
3119
+ return __awaiter(this, void 0, void 0, function () {
3120
+ var msg, res;
3121
+ return __generator(this, function (_a) {
3122
+ switch (_a.label) {
3123
+ case 0:
3124
+ msg = { text: text, type: 'request', name: 'text' };
3125
+ textChatMessages.push(msg);
3126
+ return [4 /*yield*/, sendText(text)];
3127
+ case 1:
3128
+ res = _a.sent();
3129
+ msg = __assign(__assign({}, msg), { reqId: res.reqId });
3130
+ renderMessageInTextChat(msg);
3131
+ return [2 /*return*/];
3132
+ }
3133
+ });
3134
+ });
3135
+ }
3136
+ var sendMessageToTextChat = throttle(function sendMessageToTextChat() {
3137
+ return __awaiter(this, void 0, void 0, function () {
3138
+ var textareaEl, text;
3139
+ return __generator(this, function (_a) {
3140
+ textareaEl = document.getElementById('chatTextarea');
3141
+ text = textareaEl.value;
3142
+ if (text.trim() === '')
3143
+ return [2 /*return*/];
3144
+ textareaEl.value = '';
3145
+ _sendText(text);
3146
+ return [2 /*return*/];
3147
+ });
3148
+ });
3149
+ }, 1000);
3150
+ function onChatTextAreaKeyDown(e) {
3151
+ var keyCode = e.keyCode || e.which;
3152
+ if (keyCode === 13) {
3153
+ sendMessageToTextChat();
3154
+ e.stopPropagation();
3155
+ e.preventDefault();
3156
+ }
3157
+ }
3158
+ function initTextChat() {
3159
+ var _a, _b, _c;
3160
+ var chatDiv = document.getElementById('alan-text-chat');
3161
+ var textareaDiv = document.getElementById('textarea-holder');
3162
+ var chatTextarea = document.getElementById('chatTextarea');
3163
+ var simpleAlanBtn = document.getElementById('chat-mic-btn');
3164
+ var chatSendBtn = document.getElementById('chat-send-btn');
3165
+ var headerDiv = document.getElementById('chat-header');
3166
+ var headerTille = document.getElementById('chat-header-title');
3167
+ if (!document.getElementById('alan-text-chat')) {
3168
+ chatDiv = document.createElement('div');
3169
+ chatDiv.id = 'alan-text-chat';
3170
+ chatDiv.classList.add('alan-btn__chat');
3171
+ var messagesDiv = document.createElement('div');
3172
+ messagesDiv.id = 'chatMessages';
3173
+ messagesDiv.classList.add('alan-btn__chat-messages');
3174
+ var messagesEmptyDiv = document.createElement('div');
3175
+ messagesEmptyDiv.classList.add('alan-btn__chat-messages-empty-block');
3176
+ messagesDiv.appendChild(messagesEmptyDiv);
3177
+ headerDiv = document.createElement('div');
3178
+ headerDiv.id = 'chat-header';
3179
+ headerDiv.classList.add('alan-btn__chat-header');
3180
+ headerTille = document.createElement('span');
3181
+ headerTille.id = 'chat-header-title';
3182
+ headerDiv.appendChild(headerTille);
3183
+ var closeChatBtnImg = document.createElement('div');
3184
+ closeChatBtnImg.innerHTML = "\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M13.1195 2.47218C13.5523 2.03918 13.5502 1.33489 13.1193 0.904189L13.0217 0.806586C12.5887 0.373581 11.8875 0.372614 11.4537 0.806392L7.1601 5.1C7.05127 5.20902 6.87582 5.21 6.76583 5.1L2.47222 0.806392C2.03922 0.373581 1.33493 0.375712 0.904226 0.806586L0.806624 0.904189C0.373619 1.33719 0.372652 2.03841 0.80643 2.47218L5.10004 6.76579C5.20906 6.87462 5.21003 7.05007 5.10004 7.16006L0.80643 11.4537C0.373619 11.8867 0.375751 12.591 0.806624 13.0217L0.904226 13.1193C1.33723 13.5523 2.03844 13.5532 2.47222 13.1195L6.76583 8.82585C6.87466 8.71683 7.05011 8.71586 7.1601 8.82585L11.4537 13.1195C11.8867 13.5523 12.591 13.5501 13.0217 13.1193L13.1193 13.0217C13.5523 12.5887 13.5533 11.8874 13.1195 11.4537L8.82589 7.16006C8.71687 7.05123 8.7159 6.87578 8.82589 6.76579L13.1195 2.47218Z\" fill=\"white\"/>\n</svg>\n";
3185
+ closeChatBtnImg.classList.add('alan-btn__close-chat-btn');
3186
+ headerDiv.appendChild(closeChatBtnImg);
3187
+ closeChatBtnImg.addEventListener('click', closeTextChat);
3188
+ textareaDiv = document.createElement('div');
3189
+ textareaDiv.id = 'textarea-holder';
3190
+ textareaDiv.classList.add('alan-btn__chat-textarea-holder');
3191
+ chatTextarea = document.createElement('textarea');
3192
+ chatTextarea.id = 'chatTextarea';
3193
+ chatTextarea.setAttribute('rows', '2');
3194
+ chatTextarea.classList.add('alan-btn__chat-textarea');
3195
+ chatTextarea.addEventListener('keydown', onChatTextAreaKeyDown);
3196
+ chatSendBtn = document.createElement('div');
3197
+ chatSendBtn.id = 'chat-send-btn';
3198
+ chatSendBtn.classList.add('alan-btn__chat-send-btn');
3199
+ chatSendBtn.addEventListener('click', sendMessageToTextChat);
3200
+ chatSendBtn.innerHTML = "\n <svg width=\"26\" height=\"26\" viewBox=\"0 0 26 26\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M0.0297638 24.7941L2.2258 15.2839C2.31247 14.8792 2.65916 14.5612 3.09273 14.5034L15.3735 13.2314C15.7202 13.2026 15.7202 12.6822 15.3735 12.6243L3.09273 11.4391C2.65937 11.4102 2.31249 11.0923 2.2258 10.6876L0.0297638 1.20624C-0.172404 0.396854 0.694524 -0.267944 1.44571 0.107737L25.4582 12.1328C26.1806 12.5087 26.1806 13.5493 25.4582 13.925L1.44571 25.8923C0.694473 26.2679 -0.172404 25.6031 0.0297638 24.7938V24.7941Z\" fill=\"#007AFF\"/>\n</svg>";
3201
+ textareaDiv.appendChild(chatTextarea);
3202
+ textareaDiv.appendChild(chatSendBtn);
3203
+ chatDiv.appendChild(headerDiv);
3204
+ chatDiv.appendChild(messagesDiv);
3205
+ chatDiv.appendChild(textareaDiv);
3206
+ chatHolderDiv.appendChild(chatDiv);
3207
+ chatHolderDiv.classList.add('alan-btn__chat-holder');
3208
+ }
3209
+ if (headerTille) {
3210
+ var title = ((_a = textChatOptions === null || textChatOptions === void 0 ? void 0 : textChatOptions.header) === null || _a === void 0 ? void 0 : _a.label) || 'Alan Virtual Assistant';
3211
+ headerTille.innerText = title;
3212
+ headerTille.setAttribute('title', title);
3213
+ }
3214
+ if (voiceEnabledInTextChat) {
3215
+ chatTextarea.setAttribute('placeholder', 'Type here or use your mic with button...');
3216
+ chatHolderDiv.classList.add('alan-text-chat__voice-enabled');
3217
+ if (!simpleAlanBtn) {
3218
+ simpleAlanBtn = document.createElement('div');
3219
+ simpleAlanBtn.classList.add('alan-btn__chat-mic-btn');
3220
+ simpleAlanBtn.id = 'chat-mic-btn';
3221
+ simpleAlanBtn.addEventListener('click', function () {
3222
+ onBtnClickInTextChat();
3223
+ });
3224
+ simpleAlanBtn.innerHTML = "\n <svg width=\"41\" height=\"56\" viewBox=\"0 0 41 56\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M29.2564 26.3571C29.2564 31.2186 25.3614 35.1429 20.5 35.1429C15.6386 35.1429 11.7143 31.2186 11.7143 26.3571V8.78571C11.7143 3.92429 15.6386 0 20.5 0C25.3614 0 29.2857 3.92429 29.2857 8.78571L29.2564 26.3571ZM20.5 41.2929C28.5829 41.2929 36.0214 35.1429 36.0214 26.3571H41C41 36.3729 33.0343 44.6314 23.4286 46.0371V55.6429H17.5714V46.0371C7.96571 44.6021 0 36.3436 0 26.3571H4.97857C4.97857 35.1429 12.4171 41.2929 20.5 41.2929Z\" fill=\"#2C9EFF\"/>\n </svg>\n <div class=\"alan-text-chat__animated-btn-bars\">\n <div class=\"alan-text-chat__bar alan-text-chat__bar-1\"></div>\n <div class=\"alan-text-chat__bar alan-text-chat__bar-2\"></div>\n <div class=\"alan-text-chat__bar alan-text-chat__bar-3\"></div>\n <div class=\"alan-text-chat__bar alan-text-chat__bar-3\"></div>\n <div class=\"alan-text-chat__bar alan-text-chat__bar-2\"></div>\n <div class=\"alan-text-chat__bar alan-text-chat__bar-1\"></div>\n </div>";
3225
+ if (textareaDiv) {
3226
+ textareaDiv.appendChild(simpleAlanBtn);
3227
+ }
3228
+ }
3229
+ }
3230
+ else {
3231
+ if (simpleAlanBtn) {
3232
+ simpleAlanBtn.removeEventListener('click', onBtnClickInTextChat);
3233
+ simpleAlanBtn.remove();
3234
+ }
3235
+ chatTextarea.setAttribute('placeholder', 'Type here...');
3236
+ chatHolderDiv.classList.remove('alan-text-chat__voice-enabled');
3237
+ }
3238
+ if (chatTextarea) {
3239
+ if ((_b = textChatOptions === null || textChatOptions === void 0 ? void 0 : textChatOptions.textarea) === null || _b === void 0 ? void 0 : _b.placeholder) {
3240
+ chatTextarea.setAttribute('placeholder', (_c = textChatOptions === null || textChatOptions === void 0 ? void 0 : textChatOptions.textarea) === null || _c === void 0 ? void 0 : _c.placeholder);
3241
+ }
3242
+ }
3243
+ }
3244
+ function showTextChat() {
3245
+ hideChatNotifications();
3246
+ hidePopup();
3247
+ chatHolderDiv.style.display = 'flex';
3248
+ textChatIsHidden = false;
3249
+ rootEl.classList.add('text-chat-is-opened');
3250
+ }
3251
+ function hideTextChat() {
3252
+ deactivateAlanButton();
3253
+ chatHolderDiv.style.display = 'none';
3254
+ rootEl.classList.remove('text-chat-is-opened');
3255
+ textChatIsHidden = true;
3256
+ }
3257
+ function closeTextChat() {
3258
+ hideTextChat();
3259
+ }
3260
+ function showChatNotifications() {
3261
+ if (unreadChatMsgCount > 0) {
3262
+ chatNotificationsBubble.innerHTML = unreadChatMsgCount > 99 ? "99+" : "".concat(unreadChatMsgCount);
3263
+ chatNotificationsBubble.style.display = 'flex';
3264
+ }
3265
+ }
3266
+ function hideChatNotifications() {
3267
+ unreadChatMsgCount = 0;
3268
+ chatNotificationsBubble.style.display = 'none';
3269
+ }
2708
3270
  function switchState(newState) {
2709
3271
  if (options.onButtonState) {
2710
3272
  options.onButtonState(btnStateMapping[newState]);
@@ -2969,6 +3531,34 @@
2969
3531
  rootEl.classList.remove("alan-btn-offline");
2970
3532
  rootEl.classList.remove("alan-btn-no-voice-support");
2971
3533
  }
3534
+ if (textChatIsAvailable) {
3535
+ var simpleAlanBtn = document.getElementById('chat-mic-btn');
3536
+ var textChatEl = document.getElementById('alan-text-chat');
3537
+ if (simpleAlanBtn) {
3538
+ if (newState === LISTENING ||
3539
+ newState === INTERMEDIATE ||
3540
+ newState === SPEAKING ||
3541
+ newState === UNDERSTOOD) {
3542
+ simpleAlanBtn.classList.add('active');
3543
+ simpleAlanBtn.style.animation = pulsatingAnimationForMicBtnInTextChat;
3544
+ }
3545
+ else {
3546
+ simpleAlanBtn.classList.remove('active');
3547
+ simpleAlanBtn.style.animation = '';
3548
+ }
3549
+ }
3550
+ if (textChatEl) {
3551
+ if (newState === LISTENING ||
3552
+ newState === INTERMEDIATE ||
3553
+ newState === SPEAKING ||
3554
+ newState === UNDERSTOOD) {
3555
+ textChatEl.classList.add('active');
3556
+ }
3557
+ else {
3558
+ textChatEl.classList.remove('active');
3559
+ }
3560
+ }
3561
+ }
2972
3562
  state = newState;
2973
3563
  }
2974
3564
  //#endregion
@@ -3071,6 +3661,8 @@
3071
3661
  recognisedTextHolder.appendChild(recognisedTextContent);
3072
3662
  rootEl.appendChild(recognisedTextHolder);
3073
3663
  rootEl.appendChild(btn);
3664
+ rootEl.appendChild(chatHolderDiv);
3665
+ btn.appendChild(chatNotificationsBubble);
3074
3666
  btnDisabled = false;
3075
3667
  sendClientEvent({ buttonReady: true });
3076
3668
  }
@@ -3088,9 +3680,9 @@
3088
3680
  hideS2TPanel = true;
3089
3681
  hideRecognisedText();
3090
3682
  }
3091
- function applyBtnOptions(btnOptions) {
3092
- if (btnOptions) {
3093
- createAlanStyleSheet(btnOptions);
3683
+ function applyBtnOptions(webOptions) {
3684
+ if (webOptions) {
3685
+ createAlanStyleSheet(webOptions);
3094
3686
  }
3095
3687
  else {
3096
3688
  createAlanStyleSheet();
@@ -3103,38 +3695,49 @@
3103
3695
  !data.web.logoIdle &&
3104
3696
  !data.web.logoListen &&
3105
3697
  !data.web.logoProcess &&
3106
- !data.web.logoReply) {
3698
+ !data.web.logoReply &&
3699
+ !data.web.logoTextChat) {
3107
3700
  listenStateBtnIconImg.src = data.web.logoUrl;
3108
3701
  processStateBtnIconImg.src = data.web.logoUrl;
3109
3702
  replyStateBtnIconImg.src = data.web.logoUrl;
3110
3703
  }
3111
3704
  else {
3112
- if (data.web.logoIdle) {
3113
- defaultStateBtnIconImg.src = data.web.logoIdle;
3114
- }
3115
- else {
3116
- defaultStateBtnIconImg.src = micIconSrc;
3117
- }
3118
- if (data.web.logoListen) {
3119
- listenStateBtnIconImg.src = data.web.logoListen;
3120
- }
3121
- else {
3122
- listenStateBtnIconImg.removeAttribute('src');
3123
- listenStateBtnIconImg.style.opacity = '0';
3124
- }
3125
- if (data.web.logoProcess) {
3126
- processStateBtnIconImg.src = data.web.logoProcess;
3127
- }
3128
- else {
3129
- processStateBtnIconImg.removeAttribute('src');
3130
- processStateBtnIconImg.style.opacity = '0';
3131
- }
3132
- if (data.web.logoReply) {
3133
- replyStateBtnIconImg.src = data.web.logoReply;
3705
+ if (textChatIsAvailable) {
3706
+ if (data.web.logoTextChat) {
3707
+ defaultStateBtnIconImg.src = data.web.logoTextChat;
3708
+ }
3709
+ else {
3710
+ defaultStateBtnIconImg.src = alanLogoIconSrc;
3711
+ }
3134
3712
  }
3135
3713
  else {
3136
- replyStateBtnIconImg.removeAttribute('src');
3137
- replyStateBtnIconImg.style.opacity = '0';
3714
+ if (data.web.logoIdle) {
3715
+ defaultStateBtnIconImg.src = data.web.logoIdle;
3716
+ }
3717
+ else {
3718
+ defaultStateBtnIconImg.src = micIconSrc;
3719
+ }
3720
+ if (data.web.logoListen) {
3721
+ listenStateBtnIconImg.src = data.web.logoListen;
3722
+ }
3723
+ else {
3724
+ listenStateBtnIconImg.removeAttribute('src');
3725
+ listenStateBtnIconImg.style.opacity = '0';
3726
+ }
3727
+ if (data.web.logoProcess) {
3728
+ processStateBtnIconImg.src = data.web.logoProcess;
3729
+ }
3730
+ else {
3731
+ processStateBtnIconImg.removeAttribute('src');
3732
+ processStateBtnIconImg.style.opacity = '0';
3733
+ }
3734
+ if (data.web.logoReply) {
3735
+ replyStateBtnIconImg.src = data.web.logoReply;
3736
+ }
3737
+ else {
3738
+ replyStateBtnIconImg.removeAttribute('src');
3739
+ replyStateBtnIconImg.style.opacity = '0';
3740
+ }
3138
3741
  }
3139
3742
  }
3140
3743
  }
@@ -3162,8 +3765,8 @@
3162
3765
  try {
3163
3766
  alanBtnSavedOptions = JSON.parse(localStorage.getItem(getStorageKey()));
3164
3767
  if (alanBtnSavedOptions && alanBtnSavedOptions.web) {
3165
- if (alanBtnSavedOptions.web.btnOptions) {
3166
- applyBtnOptions(alanBtnSavedOptions.web.btnOptions);
3768
+ if (alanBtnSavedOptions.web) {
3769
+ applyBtnOptions(alanBtnSavedOptions.web);
3167
3770
  }
3168
3771
  }
3169
3772
  }
@@ -3223,6 +3826,9 @@
3223
3826
  rootEl.style.setProperty('top', dndBtnTopPos + 'px', 'important');
3224
3827
  rootEl.style.setProperty('bottom', 'auto', 'important');
3225
3828
  }
3829
+ if (Math.abs(tempDeltaX) > 15 || Math.abs(tempDeltaY) > 15) {
3830
+ hideTextChat();
3831
+ }
3226
3832
  afterMouseMove = true;
3227
3833
  newLeftPos = dndBtnLeftPos + posInfo.clientX - dndInitMousePos[0];
3228
3834
  newTopPos = dndBtnTopPos + posInfo.clientY - dndInitMousePos[1];
@@ -3258,6 +3864,7 @@
3258
3864
  isLeftAligned = true;
3259
3865
  isRightAligned = false;
3260
3866
  setTextPanelPosition(recognisedTextHolder, curY);
3867
+ setTextChatPosition(chatHolderDiv, curY);
3261
3868
  btnWasMoved = true;
3262
3869
  setTimeout(function () {
3263
3870
  togglePopupVisibility(true);
@@ -3272,6 +3879,7 @@
3272
3879
  isLeftAligned = false;
3273
3880
  isRightAligned = true;
3274
3881
  setTextPanelPosition(recognisedTextHolder, curY);
3882
+ setTextChatPosition(chatHolderDiv, curY);
3275
3883
  saveBtnPosition('right', dndFinalHorPos, curY);
3276
3884
  btnWasMoved = true;
3277
3885
  dndBackAnimFinished = true;