@nethesis/phone-island 1.1.1 → 1.1.3

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.
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../../node_modules/tslib/tslib.es6.js"),t=require("./janus.js"),r=require("../../store/index.js"),s=require("../../node_modules/webrtc-adapter/src/js/adapter_core.js"),a=require("../devices/devices.js");function o(e){return e?e.replace(/["\\\r\n\t]/g,"").trim().replace(/^\*+\s*/,""):""}function c(e,s){return new Promise(function(a,o){var c=r.store.getState().webrtc.sipcall;c.createOffer({tracks:s,success:function(r){t.default.debug("Got SDP!"),t.default.debug(r),c.send({message:{request:"call",uri:e,autoaccept_reinvites:!1},jsep:r}),a(!0)},error:function(e){t.default.error("WebRTC error...",e),t.default.error("WebRTC error call on createOffer: ",e),o(!1)}})})}exports.answerWebRTC=function(){var e,s=r.store.getState().webrtc,o=s.sipcall,c=s.jsepGlobal;if(console.log("[JSEP] answerWebRTC called",{hasSipcall:!!o,hasJsepGlobal:!!c,sipcallId:null===(e=null==o?void 0:o.getId)||void 0===e?void 0:e.call(o),timestamp:(new Date).toISOString()}),o&&c){var n=a.getCurrentAudioInputDeviceId(),i=[];n?i.push({type:"audio",capture:{deviceId:{exact:n}},recv:!0}):i.push({type:"audio",capture:!0,recv:!0});try{o.createAnswer({jsep:c,tracks:i,success:function(e){o.send({message:{request:"accept",autoaccept_reinvites:!1},jsep:e})},error:function(e){t.default.error("WebRTC error:",e),e&&("object"==typeof e&&469===e.code||"string"==typeof e&&e.includes("Unexpected ANSWER"))?(console.warn('Got "Unexpected ANSWER" error, forcing the answer anyway'),o.send({message:{request:"accept",autoaccept_reinvites:!1}})):o.send({message:{request:"decline",code:480}})}})}catch(e){console.error("Exception in createAnswer:",e),o.send({message:{request:"accept",autoaccept_reinvites:!1}})}}},exports.call=c,exports.callSipURI=function(s,o){var n=this;void 0===o&&(o={}),a.getSupportedDevices(function(){return e.__awaiter(n,void 0,void 0,function(){var n,i,u;return e.__generator(this,function(e){switch(e.label){case 0:return t.default.log(o.video?"This is a SIP video call":"This is a SIP call"),n=a.getCurrentAudioInputDeviceId(),i=[],n?i.push({type:"audio",capture:{deviceId:{exact:n}},recv:!0}):i.push({type:"audio",capture:!0,recv:!0}),o.video&&(u=a.getCurrentVideoInputDeviceId(),i.push({type:"video",capture:!u||{deviceId:{exact:u}},recv:!0}),r.store.dispatch.currentCall.updateCurrentCall({isLocalVideoEnabled:!0}),r.store.dispatch.currentCall.setVideoTrackAdded(!0)),[4,c(s,i)];case 1:return e.sent(),[2]}})})})},exports.detach=function(){var e=r.store.getState().webrtc.sipcall;if(e)return e.detach()},exports.handleRemote=function(e){var t=r.store.getState().webrtc.sipcall;t&&t.handleRemoteJsep({jsep:e,error:function(e){console.error("WebRTC error... "+JSON.stringify(e));t.send({message:{request:"hangup"}}),t.hangup()}})},exports.hangup=function(){var e=r.store.getState().webrtc.sipcall;e&&e.send({message:{request:"hangup"}})},exports.muteWebRTC=function(){var e=r.store.getState().webrtc.sipcall;return e.muteAudio(),e.isAudioMuted()},exports.pauseWebRTC=function(){var e=r.store.getState().webrtc.sipcall;try{return e.send({message:{request:"hold"}}),!0}catch(e){return console.error(e),!1}},exports.register=function(e){var t=e.sipExten,s=e.sipSecret,a=e.sipHost,c=e.sipPort,n=r.store.getState().webrtc,i=n.sipcall,u=n.registered,p=r.store.getState().currentUser.name;u?console.log("[REGISTER] Already registered, skipping registration request",{sipExten:t,timestamp:(new Date).toISOString()}):i&&(console.log("[REGISTER] Sending registration request",{sipExten:t,timestamp:(new Date).toISOString()}),i.send({message:{request:"register",username:"sip:".concat(t,"@").concat(a),display_name:o(p),secret:s,proxy:"sip:".concat(a,":").concat(c),outbound_proxy:"sip:".concat(a,":").concat(c),sips:!1,refresh:!1}}))},exports.sendDTMF=function(e){var t=r.store.getState().webrtc.sipcall;"chrome"===s.default.browserDetails.browser?t.dtmf({dtmf:{tones:e}}):t.send({message:{request:"dtmf_info",digit:"".concat(e)}})},exports.toSipDisplayName=o,exports.unmuteWebRTC=function(){var e=r.store.getState().webrtc.sipcall;return e.unmuteAudio(),!e.isAudioMuted()},exports.unpauseWebRTC=function(){var e=r.store.getState().webrtc.sipcall;try{return e.send({message:{request:"unhold"}}),!0}catch(e){return console.error(e),!1}},exports.unregister=function(){var e=r.store.getState().webrtc.sipcall;e&&e.send({message:{request:"unregister"}})};
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../../node_modules/tslib/tslib.es6.js"),t=require("./janus.js"),r=require("../../store/index.js"),s=require("../../node_modules/webrtc-adapter/src/js/adapter_core.js"),a=require("../devices/devices.js");function n(e){return e?e.replace(/["\\\r\n\t]/g,"").trim().replace(/^\*+\s*/,""):""}function o(e,s){return new Promise(function(a,n){var o=r.store.getState().webrtc.sipcall;o.createOffer({tracks:s,success:function(r){t.default.debug("Got SDP!"),t.default.debug(r),o.send({message:{request:"call",uri:e,autoaccept_reinvites:!1},jsep:r}),a(!0)},error:function(e){t.default.error("WebRTC error...",e),t.default.error("WebRTC error call on createOffer: ",e),n(!1)}})})}exports.answerWebRTC=function(){var e,s=r.store.getState().webrtc,n=s.sipcall,o=s.jsepGlobal;if(console.log("[JSEP] answerWebRTC called",{hasSipcall:!!n,hasJsepGlobal:!!o,sipcallId:null===(e=null==n?void 0:n.getId)||void 0===e?void 0:e.call(n),timestamp:(new Date).toISOString()}),n&&o){var c=a.getCurrentAudioInputDeviceId(),i=[];c?i.push({type:"audio",capture:{deviceId:{exact:c}},recv:!0}):i.push({type:"audio",capture:!0,recv:!0});try{n.createAnswer({jsep:o,tracks:i,success:function(e){n.send({message:{request:"accept",autoaccept_reinvites:!1},jsep:e})},error:function(e){t.default.error("WebRTC error:",e),e&&("object"==typeof e&&469===e.code||"string"==typeof e&&e.includes("Unexpected ANSWER"))?(console.warn('Got "Unexpected ANSWER" error, forcing the answer anyway'),n.send({message:{request:"accept",autoaccept_reinvites:!1}})):n.send({message:{request:"decline",code:480}})}})}catch(e){console.error("Exception in createAnswer:",e),n.send({message:{request:"accept",autoaccept_reinvites:!1}})}}},exports.call=o,exports.callSipURI=function(s,n){var c=this;void 0===n&&(n={}),a.getSupportedDevices(function(){return e.__awaiter(c,void 0,void 0,function(){var c,i,u;return e.__generator(this,function(e){switch(e.label){case 0:t.default.log(n.video?"This is a SIP video call":"This is a SIP call"),c=a.getCurrentAudioInputDeviceId(),i=[],c?i.push({type:"audio",capture:{deviceId:{exact:c}},recv:!0}):i.push({type:"audio",capture:!0,recv:!0}),n.video&&(u=a.getCurrentVideoInputDeviceId(),i.push({type:"video",capture:!u||{deviceId:{exact:u}},recv:!0}),r.store.dispatch.currentCall.updateCurrentCall({isLocalVideoEnabled:!0}),r.store.dispatch.currentCall.setVideoTrackAdded(!0)),e.label=1;case 1:return e.trys.push([1,3,,5]),[4,o(s,i)];case 2:return e.sent(),[3,5];case 3:return e.sent(),n.video?(t.default.warn("Video call could not start, calling in audio only"),r.store.dispatch.currentCall.updateCurrentCall({isLocalVideoEnabled:!1}),r.store.dispatch.currentCall.setVideoTrackAdded(!1),r.store.getState().webrtc.sipcall.hangup(!1),[4,o(s,i.filter(function(e){return"video"!==e.type})).catch(function(){})]):[2];case 4:return e.sent(),[3,5];case 5:return[2]}})})})},exports.detach=function(){var e=r.store.getState().webrtc.sipcall;if(e)return e.detach()},exports.handleRemote=function(e){var t=r.store.getState().webrtc.sipcall;t&&t.handleRemoteJsep({jsep:e,error:function(e){console.error("WebRTC error... "+JSON.stringify(e));t.send({message:{request:"hangup"}}),t.hangup()}})},exports.hangup=function(){var e=r.store.getState().webrtc.sipcall;e&&e.send({message:{request:"hangup"}})},exports.muteWebRTC=function(){var e=r.store.getState().webrtc.sipcall;return e.muteAudio(),e.isAudioMuted()},exports.pauseWebRTC=function(){var e=r.store.getState().webrtc.sipcall;try{return e.send({message:{request:"hold"}}),!0}catch(e){return console.error(e),!1}},exports.register=function(e){var t=e.sipExten,s=e.sipSecret,a=e.sipHost,o=e.sipPort,c=r.store.getState().webrtc,i=c.sipcall,u=c.registered,l=r.store.getState().currentUser.name;u?console.log("[REGISTER] Already registered, skipping registration request",{sipExten:t,timestamp:(new Date).toISOString()}):i&&(console.log("[REGISTER] Sending registration request",{sipExten:t,timestamp:(new Date).toISOString()}),i.send({message:{request:"register",username:"sip:".concat(t,"@").concat(a),display_name:n(l),secret:s,proxy:"sip:".concat(a,":").concat(o),outbound_proxy:"sip:".concat(a,":").concat(o),sips:!1,refresh:!1}}))},exports.sendDTMF=function(e){var t=r.store.getState().webrtc.sipcall;"chrome"===s.default.browserDetails.browser?t.dtmf({dtmf:{tones:e}}):t.send({message:{request:"dtmf_info",digit:"".concat(e)}})},exports.toSipDisplayName=n,exports.unmuteWebRTC=function(){var e=r.store.getState().webrtc.sipcall;return e.unmuteAudio(),!e.isAudioMuted()},exports.unpauseWebRTC=function(){var e=r.store.getState().webrtc.sipcall;try{return e.send({message:{request:"unhold"}}),!0}catch(e){return console.error(e),!1}},exports.unregister=function(){var e=r.store.getState().webrtc.sipcall;e&&e.send({message:{request:"unregister"}})};
2
2
  //# sourceMappingURL=messages.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"messages.js","sources":["../../../src/lib/webrtc/messages.ts"],"sourcesContent":["// Copyright (C) 2024 Nethesis S.r.l.\n// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport Janus from './janus'\nimport { store } from '../../store'\nimport adapter from 'webrtc-adapter'\nimport {\n getCurrentAudioInputDeviceId,\n getCurrentVideoInputDeviceId,\n getSupportedDevices,\n} from '../devices/devices'\nimport { getJSONItem } from '../../utils'\nimport { JanusTrack } from '../../types'\n\n// Strip chars that break the SIP Contact header: a leading \"*\" is read by Asterisk as\n// the wildcard Contact (REGISTER dropped), quotes and backslashes make sofia-sip fail.\nexport function toSipDisplayName(name?: string): string {\n if (!name) {\n return ''\n }\n return name\n .replace(/[\"\\\\\\r\\n\\t]/g, '')\n .trim()\n .replace(/^\\*+\\s*/, '')\n}\n\nexport function register({\n sipExten,\n sipSecret,\n sipHost,\n sipPort,\n}: {\n sipExten: string\n sipSecret: string\n sipHost: string\n sipPort: string\n}) {\n const { sipcall, registered }: { sipcall: any; registered: boolean } = store.getState().webrtc\n const { name } = store.getState().currentUser\n\n // Prevent multiple registrations if already registered\n if (registered) {\n console.log('[REGISTER] Already registered, skipping registration request', {\n sipExten,\n timestamp: new Date().toISOString()\n })\n return\n }\n\n if (sipcall) {\n console.log('[REGISTER] Sending registration request', {\n sipExten,\n timestamp: new Date().toISOString()\n })\n sipcall.send({\n message: {\n request: 'register',\n username: `sip:${sipExten}@${sipHost}`,\n display_name: toSipDisplayName(name),\n secret: sipSecret,\n proxy: `sip:${sipHost}:${sipPort}`,\n outbound_proxy: `sip:${sipHost}:${sipPort}`,\n sips: false,\n refresh: false,\n },\n })\n }\n}\n\nexport function answerWebRTC() {\n const { sipcall, jsepGlobal }: { sipcall: any; jsepGlobal: any } = store.getState().webrtc\n\n console.log('[JSEP] answerWebRTC called', {\n hasSipcall: !!sipcall,\n hasJsepGlobal: !!jsepGlobal,\n sipcallId: sipcall?.getId?.(),\n timestamp: new Date().toISOString()\n })\n\n if (sipcall && jsepGlobal) {\n let currentAudioInputDeviceId = getCurrentAudioInputDeviceId()\n const tracks: any[] = []\n\n if (currentAudioInputDeviceId) {\n tracks.push({\n type: 'audio',\n capture: { deviceId: { exact: currentAudioInputDeviceId } },\n recv: true,\n })\n } else {\n tracks.push({ type: 'audio', capture: true, recv: true })\n }\n\n // For incoming calls, directly create an answer without first calling handleRemoteJsep\n // because Janus has already provided us with an offer\n try {\n sipcall.createAnswer({\n jsep: jsepGlobal,\n tracks: tracks,\n success: (jsep) => {\n sipcall.send({\n message: {\n request: 'accept',\n autoaccept_reinvites: false,\n },\n jsep: jsep,\n })\n },\n error: (error) => {\n // If there's an error during createAnswer, check if it's error 469 (Unexpected ANSWER)\n // @ts-ignore\n Janus.error('WebRTC error:', error)\n\n // Check if the error contains code 469 or the message \"Unexpected ANSWER\"\n if (\n error &&\n ((typeof error === 'object' && error.code === 469) ||\n (typeof error === 'string' && error.includes('Unexpected ANSWER')))\n ) {\n console.warn('Got \"Unexpected ANSWER\" error, forcing the answer anyway')\n // Force sending the accept message even without JSEP\n sipcall.send({\n message: {\n request: 'accept',\n autoaccept_reinvites: false,\n },\n })\n } else {\n // For other types of errors, decline the call\n sipcall.send({\n message: {\n request: 'decline',\n code: 480,\n },\n })\n }\n },\n })\n } catch (error) {\n console.error('Exception in createAnswer:', error)\n\n // Even in case of an exception, try to accept the call\n sipcall.send({\n message: {\n request: 'accept',\n autoaccept_reinvites: false,\n },\n })\n }\n }\n}\n\nexport function decline() {\n const { sipcall }: { sipcall: any } = store.getState().webrtc\n if (sipcall) {\n sipcall.send({\n message: {\n request: 'decline',\n },\n })\n }\n}\n\nexport function hangup() {\n const { sipcall }: { sipcall: any } = store.getState().webrtc\n if (sipcall) {\n sipcall.send({\n message: {\n request: 'hangup',\n },\n })\n }\n}\n\nexport function unregister() {\n const { sipcall }: { sipcall: any } = store.getState().webrtc\n if (sipcall) {\n sipcall.send({\n message: {\n request: 'unregister',\n },\n })\n }\n}\n\nexport function detach() {\n const { sipcall }: { sipcall: any } = store.getState().webrtc\n if (sipcall) {\n return sipcall.detach()\n }\n}\n\nexport function handleRemote(jsep: any) {\n const { sipcall }: { sipcall: any } = store.getState().webrtc\n if (sipcall) {\n sipcall.handleRemoteJsep({\n jsep: jsep,\n error: function (error) {\n console.error('WebRTC error... ' + JSON.stringify(error))\n\n var hangup = {\n request: 'hangup',\n }\n sipcall.send({\n message: hangup,\n })\n sipcall.hangup()\n },\n })\n }\n}\n\nexport function callSipURI(sipURI: string, options: { video?: boolean } = {}) {\n getSupportedDevices(async () => {\n // @ts-ignore\n Janus.log(options.video ? 'This is a SIP video call' : 'This is a SIP call')\n\n let currentAudioInputDeviceId = getCurrentAudioInputDeviceId()\n\n const tracks: JanusTrack[] = []\n\n if (currentAudioInputDeviceId) {\n tracks.push({\n type: 'audio',\n capture: { deviceId: { exact: currentAudioInputDeviceId } },\n recv: true,\n })\n } else {\n tracks.push({ type: 'audio', capture: true, recv: true })\n }\n\n // Put the camera in the first INVITE: desk phones such as the Yealink T58W\n // accept video only when it is offered from the start and reject a later upgrade\n if (options.video) {\n const currentVideoInputDeviceId = getCurrentVideoInputDeviceId()\n tracks.push({\n type: 'video',\n capture: currentVideoInputDeviceId ? { deviceId: { exact: currentVideoInputDeviceId } } : true,\n recv: true,\n })\n store.dispatch.currentCall.updateCurrentCall({ isLocalVideoEnabled: true })\n store.dispatch.currentCall.setVideoTrackAdded(true)\n }\n\n await call(sipURI, tracks)\n })\n}\n\nexport function call(sipURI: string, tracks: JanusTrack[]) {\n return new Promise((resolve, reject) => {\n const { sipcall }: { sipcall: any } = store.getState().webrtc\n\n sipcall.createOffer({\n tracks: tracks,\n success: function (jsep: any) {\n // @ts-ignore\n Janus.debug('Got SDP!')\n // @ts-ignore\n Janus.debug(jsep)\n sipcall.send({\n message: {\n request: 'call',\n uri: sipURI,\n autoaccept_reinvites: false,\n },\n jsep: jsep,\n })\n resolve(true)\n },\n error: function (error) {\n // @ts-ignore\n Janus.error('WebRTC error...', error)\n // @ts-ignore\n Janus.error('WebRTC error call on createOffer: ', error)\n reject(false)\n },\n })\n })\n}\n\n/**\n * Mute current call so the counterpart can't listen the current user\n * @returns The muted status\n */\nexport function muteWebRTC(): boolean {\n // Initialize sipcall\n const { sipcall }: { sipcall: any } = store.getState().webrtc\n // Uset the janus library functions to mute call\n sipcall.muteAudio()\n return sipcall.isAudioMuted()\n}\n\n/**\n * Unmute current call so the counterpart can listen the current user\n * @returns The muted status\n */\nexport function unmuteWebRTC(): boolean {\n // Initialize sipcall\n const { sipcall }: { sipcall: any } = store.getState().webrtc\n // Use the janus library functions to unmute call\n sipcall.unmuteAudio()\n return !sipcall.isAudioMuted()\n}\n\n/**\n * Pause current call so the counterpart listens the pause ringtone\n * @returns The true if no errors occurs\n */\nexport function pauseWebRTC() {\n // Initialize sipcall\n const { sipcall }: { sipcall: any } = store.getState().webrtc\n // Send hold message\n try {\n sipcall.send({\n message: {\n request: 'hold',\n },\n })\n return true\n } catch (err) {\n console.error(err)\n return false\n }\n}\n\n/**\n * Unpause the current call so the counterpart listens the current user\n * @returns The true if no errors occurs\n */\nexport function unpauseWebRTC() {\n // Initialize sipcall\n const { sipcall }: { sipcall: any } = store.getState().webrtc\n // Send hold message\n try {\n sipcall.send({\n message: {\n request: 'unhold',\n },\n })\n return true\n } catch (err) {\n console.error(err)\n return false\n }\n}\n\n/**\n * Send DTMF messages to Janus\n */\nexport function sendDTMF(key: string) {\n // Initialize sipcall\n const { sipcall }: { sipcall: any } = store.getState().webrtc\n if (adapter.browserDetails.browser === 'chrome') {\n sipcall.dtmf({\n dtmf: {\n tones: key,\n },\n })\n } else {\n sipcall.send({\n message: {\n request: 'dtmf_info',\n digit: `${key}`,\n },\n })\n }\n}\n"],"names":["toSipDisplayName","name","replace","trim","call","sipURI","tracks","Promise","resolve","reject","sipcall","store","getState","webrtc","createOffer","success","jsep","Janus","debug","send","message","request","uri","autoaccept_reinvites","error","_b","jsepGlobal","console","log","hasSipcall","hasJsepGlobal","sipcallId","getId","_a","timestamp","Date","toISOString","currentAudioInputDeviceId","getCurrentAudioInputDeviceId","push","type","capture","deviceId","exact","recv","createAnswer","code","includes","warn","options","_this","this","getSupportedDevices","__awaiter","video","currentVideoInputDeviceId","getCurrentVideoInputDeviceId","dispatch","currentCall","updateCurrentCall","isLocalVideoEnabled","setVideoTrackAdded","sent","detach","handleRemoteJsep","JSON","stringify","hangup","muteAudio","isAudioMuted","err","sipExten","sipSecret","sipHost","sipPort","registered","currentUser","username","concat","display_name","secret","proxy","outbound_proxy","sips","refresh","key","adapter","browserDetails","browser","dtmf","tones","digit","unmuteAudio"],"mappings":"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"}
1
+ {"version":3,"file":"messages.js","sources":["../../../src/lib/webrtc/messages.ts"],"sourcesContent":["// Copyright (C) 2024 Nethesis S.r.l.\n// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport Janus from './janus'\nimport { store } from '../../store'\nimport adapter from 'webrtc-adapter'\nimport {\n getCurrentAudioInputDeviceId,\n getCurrentVideoInputDeviceId,\n getSupportedDevices,\n} from '../devices/devices'\nimport { getJSONItem } from '../../utils'\nimport { JanusTrack } from '../../types'\n\n// Strip chars that break the SIP Contact header: a leading \"*\" is read by Asterisk as\n// the wildcard Contact (REGISTER dropped), quotes and backslashes make sofia-sip fail.\nexport function toSipDisplayName(name?: string): string {\n if (!name) {\n return ''\n }\n return name\n .replace(/[\"\\\\\\r\\n\\t]/g, '')\n .trim()\n .replace(/^\\*+\\s*/, '')\n}\n\nexport function register({\n sipExten,\n sipSecret,\n sipHost,\n sipPort,\n}: {\n sipExten: string\n sipSecret: string\n sipHost: string\n sipPort: string\n}) {\n const { sipcall, registered }: { sipcall: any; registered: boolean } = store.getState().webrtc\n const { name } = store.getState().currentUser\n\n // Prevent multiple registrations if already registered\n if (registered) {\n console.log('[REGISTER] Already registered, skipping registration request', {\n sipExten,\n timestamp: new Date().toISOString()\n })\n return\n }\n\n if (sipcall) {\n console.log('[REGISTER] Sending registration request', {\n sipExten,\n timestamp: new Date().toISOString()\n })\n sipcall.send({\n message: {\n request: 'register',\n username: `sip:${sipExten}@${sipHost}`,\n display_name: toSipDisplayName(name),\n secret: sipSecret,\n proxy: `sip:${sipHost}:${sipPort}`,\n outbound_proxy: `sip:${sipHost}:${sipPort}`,\n sips: false,\n refresh: false,\n },\n })\n }\n}\n\nexport function answerWebRTC() {\n const { sipcall, jsepGlobal }: { sipcall: any; jsepGlobal: any } = store.getState().webrtc\n\n console.log('[JSEP] answerWebRTC called', {\n hasSipcall: !!sipcall,\n hasJsepGlobal: !!jsepGlobal,\n sipcallId: sipcall?.getId?.(),\n timestamp: new Date().toISOString()\n })\n\n if (sipcall && jsepGlobal) {\n let currentAudioInputDeviceId = getCurrentAudioInputDeviceId()\n const tracks: any[] = []\n\n if (currentAudioInputDeviceId) {\n tracks.push({\n type: 'audio',\n capture: { deviceId: { exact: currentAudioInputDeviceId } },\n recv: true,\n })\n } else {\n tracks.push({ type: 'audio', capture: true, recv: true })\n }\n\n // For incoming calls, directly create an answer without first calling handleRemoteJsep\n // because Janus has already provided us with an offer\n try {\n sipcall.createAnswer({\n jsep: jsepGlobal,\n tracks: tracks,\n success: (jsep) => {\n sipcall.send({\n message: {\n request: 'accept',\n autoaccept_reinvites: false,\n },\n jsep: jsep,\n })\n },\n error: (error) => {\n // If there's an error during createAnswer, check if it's error 469 (Unexpected ANSWER)\n // @ts-ignore\n Janus.error('WebRTC error:', error)\n\n // Check if the error contains code 469 or the message \"Unexpected ANSWER\"\n if (\n error &&\n ((typeof error === 'object' && error.code === 469) ||\n (typeof error === 'string' && error.includes('Unexpected ANSWER')))\n ) {\n console.warn('Got \"Unexpected ANSWER\" error, forcing the answer anyway')\n // Force sending the accept message even without JSEP\n sipcall.send({\n message: {\n request: 'accept',\n autoaccept_reinvites: false,\n },\n })\n } else {\n // For other types of errors, decline the call\n sipcall.send({\n message: {\n request: 'decline',\n code: 480,\n },\n })\n }\n },\n })\n } catch (error) {\n console.error('Exception in createAnswer:', error)\n\n // Even in case of an exception, try to accept the call\n sipcall.send({\n message: {\n request: 'accept',\n autoaccept_reinvites: false,\n },\n })\n }\n }\n}\n\nexport function decline() {\n const { sipcall }: { sipcall: any } = store.getState().webrtc\n if (sipcall) {\n sipcall.send({\n message: {\n request: 'decline',\n },\n })\n }\n}\n\nexport function hangup() {\n const { sipcall }: { sipcall: any } = store.getState().webrtc\n if (sipcall) {\n sipcall.send({\n message: {\n request: 'hangup',\n },\n })\n }\n}\n\nexport function unregister() {\n const { sipcall }: { sipcall: any } = store.getState().webrtc\n if (sipcall) {\n sipcall.send({\n message: {\n request: 'unregister',\n },\n })\n }\n}\n\nexport function detach() {\n const { sipcall }: { sipcall: any } = store.getState().webrtc\n if (sipcall) {\n return sipcall.detach()\n }\n}\n\nexport function handleRemote(jsep: any) {\n const { sipcall }: { sipcall: any } = store.getState().webrtc\n if (sipcall) {\n sipcall.handleRemoteJsep({\n jsep: jsep,\n error: function (error) {\n console.error('WebRTC error... ' + JSON.stringify(error))\n\n var hangup = {\n request: 'hangup',\n }\n sipcall.send({\n message: hangup,\n })\n sipcall.hangup()\n },\n })\n }\n}\n\nexport function callSipURI(sipURI: string, options: { video?: boolean } = {}) {\n getSupportedDevices(async () => {\n // @ts-ignore\n Janus.log(options.video ? 'This is a SIP video call' : 'This is a SIP call')\n\n let currentAudioInputDeviceId = getCurrentAudioInputDeviceId()\n\n const tracks: JanusTrack[] = []\n\n if (currentAudioInputDeviceId) {\n tracks.push({\n type: 'audio',\n capture: { deviceId: { exact: currentAudioInputDeviceId } },\n recv: true,\n })\n } else {\n tracks.push({ type: 'audio', capture: true, recv: true })\n }\n\n // Put the camera in the first INVITE: desk phones such as the Yealink T58W\n // accept video only when it is offered from the start and reject a later upgrade\n if (options.video) {\n const currentVideoInputDeviceId = getCurrentVideoInputDeviceId()\n tracks.push({\n type: 'video',\n capture: currentVideoInputDeviceId ? { deviceId: { exact: currentVideoInputDeviceId } } : true,\n recv: true,\n })\n store.dispatch.currentCall.updateCurrentCall({ isLocalVideoEnabled: true })\n store.dispatch.currentCall.setVideoTrackAdded(true)\n }\n\n try {\n await call(sipURI, tracks)\n } catch (error) {\n if (!options.video) return\n // No camera (permission denied, busy or missing): call in audio only rather than not at all\n // @ts-ignore\n Janus.warn('Video call could not start, calling in audio only')\n store.dispatch.currentCall.updateCurrentCall({ isLocalVideoEnabled: false })\n store.dispatch.currentCall.setVideoTrackAdded(false)\n // Drop the half-prepared PeerConnection locally, nothing was sent yet\n const { sipcall }: { sipcall: any } = store.getState().webrtc\n sipcall.hangup(false)\n await call(sipURI, tracks.filter((track) => track.type !== 'video')).catch(() => {})\n }\n })\n}\n\nexport function call(sipURI: string, tracks: JanusTrack[]) {\n return new Promise((resolve, reject) => {\n const { sipcall }: { sipcall: any } = store.getState().webrtc\n\n sipcall.createOffer({\n tracks: tracks,\n success: function (jsep: any) {\n // @ts-ignore\n Janus.debug('Got SDP!')\n // @ts-ignore\n Janus.debug(jsep)\n sipcall.send({\n message: {\n request: 'call',\n uri: sipURI,\n autoaccept_reinvites: false,\n },\n jsep: jsep,\n })\n resolve(true)\n },\n error: function (error) {\n // @ts-ignore\n Janus.error('WebRTC error...', error)\n // @ts-ignore\n Janus.error('WebRTC error call on createOffer: ', error)\n reject(false)\n },\n })\n })\n}\n\n/**\n * Mute current call so the counterpart can't listen the current user\n * @returns The muted status\n */\nexport function muteWebRTC(): boolean {\n // Initialize sipcall\n const { sipcall }: { sipcall: any } = store.getState().webrtc\n // Uset the janus library functions to mute call\n sipcall.muteAudio()\n return sipcall.isAudioMuted()\n}\n\n/**\n * Unmute current call so the counterpart can listen the current user\n * @returns The muted status\n */\nexport function unmuteWebRTC(): boolean {\n // Initialize sipcall\n const { sipcall }: { sipcall: any } = store.getState().webrtc\n // Use the janus library functions to unmute call\n sipcall.unmuteAudio()\n return !sipcall.isAudioMuted()\n}\n\n/**\n * Pause current call so the counterpart listens the pause ringtone\n * @returns The true if no errors occurs\n */\nexport function pauseWebRTC() {\n // Initialize sipcall\n const { sipcall }: { sipcall: any } = store.getState().webrtc\n // Send hold message\n try {\n sipcall.send({\n message: {\n request: 'hold',\n },\n })\n return true\n } catch (err) {\n console.error(err)\n return false\n }\n}\n\n/**\n * Unpause the current call so the counterpart listens the current user\n * @returns The true if no errors occurs\n */\nexport function unpauseWebRTC() {\n // Initialize sipcall\n const { sipcall }: { sipcall: any } = store.getState().webrtc\n // Send hold message\n try {\n sipcall.send({\n message: {\n request: 'unhold',\n },\n })\n return true\n } catch (err) {\n console.error(err)\n return false\n }\n}\n\n/**\n * Send DTMF messages to Janus\n */\nexport function sendDTMF(key: string) {\n // Initialize sipcall\n const { sipcall }: { sipcall: any } = store.getState().webrtc\n if (adapter.browserDetails.browser === 'chrome') {\n sipcall.dtmf({\n dtmf: {\n tones: key,\n },\n })\n } else {\n sipcall.send({\n message: {\n request: 'dtmf_info',\n digit: `${key}`,\n },\n })\n }\n}\n"],"names":["toSipDisplayName","name","replace","trim","call","sipURI","tracks","Promise","resolve","reject","sipcall","store","getState","webrtc","createOffer","success","jsep","Janus","debug","send","message","request","uri","autoaccept_reinvites","error","_b","jsepGlobal","console","log","hasSipcall","hasJsepGlobal","sipcallId","getId","_a","timestamp","Date","toISOString","currentAudioInputDeviceId","getCurrentAudioInputDeviceId","push","type","capture","deviceId","exact","recv","createAnswer","code","includes","warn","options","_this","this","getSupportedDevices","__awaiter","video","currentVideoInputDeviceId","getCurrentVideoInputDeviceId","dispatch","currentCall","updateCurrentCall","isLocalVideoEnabled","setVideoTrackAdded","sent","hangup","filter","track","catch","detach","handleRemoteJsep","JSON","stringify","muteAudio","isAudioMuted","err","sipExten","sipSecret","sipHost","sipPort","registered","currentUser","username","concat","display_name","secret","proxy","outbound_proxy","sips","refresh","key","adapter","browserDetails","browser","dtmf","tones","digit","unmuteAudio"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../node_modules/tslib/tslib.es6.js"),r=require("../node_modules/@rematch/core/dist/core.esm.js").createModel()({state:{active:!1,plugin:null,role:"",room:"",source:"",remoteFeed:null,localTracks:null,remoteTracks:null,localVideos:0,remoteVideos:0,localScreenStream:null,remoteScreenStream:null,isStartingScreenShare:!1,isJoiningScreenShare:!1,isLeavingScreenShare:!1},reducers:{update:function(r,s){return e.__assign(e.__assign({},r),s)}}});exports.screenShare=r;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../node_modules/tslib/tslib.es6.js"),r=require("../node_modules/@rematch/core/dist/core.esm.js").createModel()({state:{active:!1,plugin:null,role:"",room:"",source:"",remoteFeed:null,localTracks:null,remoteTracks:null,localVideos:0,remoteVideos:0,localScreenStream:null,pendingScreenStream:null,remoteScreenStream:null,isStartingScreenShare:!1,isJoiningScreenShare:!1,isLeavingScreenShare:!1},reducers:{update:function(r,l){return e.__assign(e.__assign({},r),l)}}});exports.screenShare=r;
2
2
  //# sourceMappingURL=screenShare.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"screenShare.js","sources":["../../src/models/screenShare.ts"],"sourcesContent":["// Copyright (C) 2025 Nethesis S.r.l.\n// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport { createModel } from '@rematch/core'\nimport type { RootModel } from '.'\n\nexport interface ScreenShareTypes {\n active?: boolean\n plugin?: any\n role?: 'publisher' | 'listener' | ''\n room?: string\n source?: string\n remoteFeed?: any\n localTracks?: any\n remoteTracks?: any\n localVideos?: number\n remoteVideos?: number\n localScreenStream?: MediaStream\n remoteScreenStream?: MediaStream\n isStartingScreenShare?: boolean\n isJoiningScreenShare?: boolean\n isLeavingScreenShare?: boolean\n}\n\nconst defaultState = {\n active: false,\n plugin: null as any,\n role: '',\n room: '',\n source: '',\n remoteFeed: null as any,\n localTracks: null as any,\n remoteTracks: null as any,\n localVideos: 0,\n remoteVideos: 0,\n localScreenStream: null as MediaStream | null,\n remoteScreenStream: null as MediaStream | null,\n isStartingScreenShare: false,\n isJoiningScreenShare: false,\n isLeavingScreenShare: false,\n}\n\nexport const screenShare = createModel<RootModel>()({\n state: defaultState,\n reducers: {\n update: (state, payload: ScreenShareTypes) => {\n return {\n ...state,\n ...payload,\n }\n },\n },\n})\n"],"names":["screenShare","createModel","state","active","plugin","role","room","source","remoteFeed","localTracks","remoteTracks","localVideos","remoteVideos","localScreenStream","remoteScreenStream","isStartingScreenShare","isJoiningScreenShare","isLeavingScreenShare","reducers","update","payload","__assign"],"mappings":"wHA0CaA,4DAAyBC,aAAXA,CAAyB,CAClDC,MAnBmB,CACnBC,QAAQ,EACRC,OAAQ,KACRC,KAAM,GACNC,KAAM,GACNC,OAAQ,GACRC,WAAY,KACZC,YAAa,KACbC,aAAc,KACdC,YAAa,EACbC,aAAc,EACdC,kBAAmB,KACnBC,mBAAoB,KACpBC,uBAAuB,EACvBC,sBAAsB,EACtBC,sBAAsB,GAKtBC,SAAU,CACRC,OAAQ,SAACjB,EAAOkB,GACd,OACKC,EAAAA,SAAAA,EAAAA,SAAA,CAAA,EAAAnB,GACAkB,EAEN"}
1
+ {"version":3,"file":"screenShare.js","sources":["../../src/models/screenShare.ts"],"sourcesContent":["// Copyright (C) 2025 Nethesis S.r.l.\n// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport { createModel } from '@rematch/core'\nimport type { RootModel } from '.'\n\nexport interface ScreenShareTypes {\n active?: boolean\n plugin?: any\n role?: 'publisher' | 'listener' | ''\n room?: string\n source?: string\n remoteFeed?: any\n localTracks?: any\n remoteTracks?: any\n localVideos?: number\n remoteVideos?: number\n localScreenStream?: MediaStream\n pendingScreenStream?: MediaStream | null\n remoteScreenStream?: MediaStream\n isStartingScreenShare?: boolean\n isJoiningScreenShare?: boolean\n isLeavingScreenShare?: boolean\n}\n\nconst defaultState = {\n active: false,\n plugin: null as any,\n role: '',\n room: '',\n source: '',\n remoteFeed: null as any,\n localTracks: null as any,\n remoteTracks: null as any,\n localVideos: 0,\n remoteVideos: 0,\n localScreenStream: null as MediaStream | null,\n pendingScreenStream: null as MediaStream | null,\n remoteScreenStream: null as MediaStream | null,\n isStartingScreenShare: false,\n isJoiningScreenShare: false,\n isLeavingScreenShare: false,\n}\n\nexport const screenShare = createModel<RootModel>()({\n state: defaultState,\n reducers: {\n update: (state, payload: ScreenShareTypes) => {\n return {\n ...state,\n ...payload,\n }\n },\n },\n})\n"],"names":["screenShare","createModel","state","active","plugin","role","room","source","remoteFeed","localTracks","remoteTracks","localVideos","remoteVideos","localScreenStream","pendingScreenStream","remoteScreenStream","isStartingScreenShare","isJoiningScreenShare","isLeavingScreenShare","reducers","update","payload","__assign"],"mappings":"wHA4CaA,4DAAyBC,aAAXA,CAAyB,CAClDC,MApBmB,CACnBC,QAAQ,EACRC,OAAQ,KACRC,KAAM,GACNC,KAAM,GACNC,OAAQ,GACRC,WAAY,KACZC,YAAa,KACbC,aAAc,KACdC,YAAa,EACbC,aAAc,EACdC,kBAAmB,KACnBC,oBAAqB,KACrBC,mBAAoB,KACpBC,uBAAuB,EACvBC,sBAAsB,EACtBC,sBAAsB,GAKtBC,SAAU,CACRC,OAAQ,SAAClB,EAAOmB,GACd,OACKC,EAAAA,SAAAA,EAAAA,SAAA,CAAA,EAAApB,GACAmB,EAEN"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e="@nethesis/phone-island",s="Nethesis",t="1.1.1",i="NethVoice CTI Phone Island",r=["nethserver","nethesis","nethvoice","phone","island"],o="https://github.com/nethesis/phone-island#readme",n="https://github.com/nethesis/dev/issues",p={type:"git",url:"https://github.com/nethesis/phone-island.git"},d=["dist"],l="dist/index.js",c="dist/index.d.ts",a={access:"public"},m={main:!1,types:!1,default:{distDir:"./dist-widget"}},u={"@fortawesome/fontawesome-svg-core":"7.3.1","@fortawesome/free-solid-svg-icons":"7.3.1","@fortawesome/react-fontawesome":"3.5.0","@headlessui/react":"^2.2.8","@nethesis/nethesis-solid-svg-icons":"github:nethesis/Font-Awesome#ns-solid","@rematch/core":"^2.2.0","@rematch/immer":"^2.1.3","@rematch/select":"^3.1.2",buffer:"^5.7.1","framer-motion":"^12.0.0",i18next:"^22.4.9","i18next-browser-languagedetector":"^7.0.1",immer:"^9.0.21","js-base64":"^3.7.3",lodash:"^4.17.21","mic-check":"^1.1.0",moment:"^2.31.0",react:"^18.2.0","react-dom":"^18.2.0","react-i18next":"^12.1.5","react-moment":"^1.1.2","react-redux":"^8.0.5","react-tooltip":"^5.28.0",redux:"^4.2.0","socket.io-client":"^4.5.3","styled-components":"^5.3.6","webm-duration-fix":"^1.0.4","webrtc-adapter":"^9.0.1"},h={start:"npm run dev",dev:"node scripts/generate-dev-host.js && parcel .dev/phone-island-dev.html --port 6006 --open",test:"tsc --noEmit",watch:"rollup -w -c","watch:css":"BROWSERSLIST_IGNORE_OLD_DATA=1 npx tailwindcss -o ./dist/index.css --watch",build:"rm -rf ./dist && npm run build:css && rollup -c","build:css":"BROWSERSLIST_IGNORE_OLD_DATA=1 NODE_ENV=production npx tailwindcss -o ./dist/index.css --minify","build:win":"del /s /q dist && npm run build:wincss && rollup -c --configPlugin typescript","build:wincss":"set BROWSERSLIST_IGNORE_OLD_DATA=1 && set NODE_ENV=production && npx tailwindcss -o ./dist/index.css --minify","build:widget":"rm -rf ./dist-widget && parcel build ./src/index.widget.tsx --no-source-maps","serve:widget":"rm -rf ./widget-example/static/* && cp -rf ./dist-widget/* ./widget-example/static && npx http-server ./widget-example -o -c-1",release:"npm publish","release:widget":"node check-publish.js patch && npm version patch -m v%s",format:"prettier --write './**/*.{js,jsx,ts,tsx,css,md,json}' --config ./.prettierrc",bump:"node bump-version.js","build-pack":"npm run bump && npm run build && npm pack","build-pack:win":"npm run bump && npm run build:win && npm pack","publish:minor":"node check-publish.js minor && npm version minor --allow-same-version -m v%s --force","publish:major":"node check-publish.js major && npm version major --allow-same-version -m v%s --force","publish:patch":"node check-publish.js patch && npm version patch --allow-same-version -m v%s --force","publish:dev":"node publish-dev.js",preversion:"rm -rf dist-widget && npm run build:widget && git add dist-widget/index.widget.js dist-widget/index.widget.css && git commit -m 'chore(widget): release for jsDelivr'",postversion:"git push origin main --tags","revert-bump":"node revert-bump.js"},b={production:[">0.2%","not dead","not op_mini all"],development:["last 1 chrome version","last 1 firefox version","last 1 safari version"]},g={"@babel/core":"^7.20.2","@babel/preset-env":"^7.20.2","@rollup/plugin-babel":"^7.0.0","@rollup/plugin-commonjs":"^23.0.2","@rollup/plugin-json":"^6.1.0","@rollup/plugin-node-resolve":"^16.0.0","@rollup/plugin-terser":"^1.0.0","@rollup/plugin-typescript":"^9.0.2","@types/react":"^18.0.26","@types/react-dom":"^18.0.9","@types/styled-components":"^5.1.26",parcel:"^2.0.0",postcss:"^8.4.49",prettier:"^2.8.0",rollup:"^2.79.1","tailwind-scrollbar":"^3.1.0",tailwindcss:"^3.4.16",typescript:"^4.8.4"},w="GPL-3.0-or-later",v={name:e,author:s,version:t,description:i,keywords:r,homepage:o,bugs:n,repository:p,private:!1,files:d,main:l,types:c,publishConfig:a,targets:m,dependencies:u,scripts:h,browserslist:b,devDependencies:g,license:w};exports.author=s,exports.browserslist=b,exports.bugs=n,exports.default=v,exports.dependencies=u,exports.description=i,exports.devDependencies=g,exports.files=d,exports.homepage=o,exports.keywords=r,exports.license=w,exports.main=l,exports.name=e,exports.publishConfig=a,exports.repository=p,exports.scripts=h,exports.targets=m,exports.types=c,exports.version=t;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e="@nethesis/phone-island",s="Nethesis",t="1.1.3",i="NethVoice CTI Phone Island",r=["nethserver","nethesis","nethvoice","phone","island"],o="https://github.com/nethesis/phone-island#readme",n="https://github.com/nethesis/dev/issues",p={type:"git",url:"https://github.com/nethesis/phone-island.git"},d=["dist"],l="dist/index.js",c="dist/index.d.ts",a={access:"public"},m={main:!1,types:!1,default:{distDir:"./dist-widget"}},u={"@fortawesome/fontawesome-svg-core":"7.3.1","@fortawesome/free-solid-svg-icons":"7.3.1","@fortawesome/react-fontawesome":"3.5.0","@headlessui/react":"^2.2.8","@nethesis/nethesis-solid-svg-icons":"github:nethesis/Font-Awesome#ns-solid","@rematch/core":"^2.2.0","@rematch/immer":"^2.1.3","@rematch/select":"^3.1.2",buffer:"^5.7.1","framer-motion":"^12.0.0",i18next:"^22.4.9","i18next-browser-languagedetector":"^7.0.1",immer:"^9.0.21","js-base64":"^3.7.3",lodash:"^4.17.21","mic-check":"^1.1.0",moment:"^2.31.0",react:"^18.2.0","react-dom":"^18.2.0","react-i18next":"^12.1.5","react-moment":"^1.1.2","react-redux":"^8.0.5","react-tooltip":"^5.28.0",redux:"^4.2.0","socket.io-client":"^4.5.3","styled-components":"^5.3.6","webm-duration-fix":"^1.0.4","webrtc-adapter":"^9.0.1"},h={start:"npm run dev",dev:"node scripts/generate-dev-host.js && parcel .dev/phone-island-dev.html --port 6006 --open",test:"tsc --noEmit",watch:"rollup -w -c","watch:css":"BROWSERSLIST_IGNORE_OLD_DATA=1 npx tailwindcss -o ./dist/index.css --watch",build:"rm -rf ./dist && npm run build:css && rollup -c","build:css":"BROWSERSLIST_IGNORE_OLD_DATA=1 NODE_ENV=production npx tailwindcss -o ./dist/index.css --minify","build:win":"del /s /q dist && npm run build:wincss && rollup -c --configPlugin typescript","build:wincss":"set BROWSERSLIST_IGNORE_OLD_DATA=1 && set NODE_ENV=production && npx tailwindcss -o ./dist/index.css --minify","build:widget":"rm -rf ./dist-widget && parcel build ./src/index.widget.tsx --no-source-maps","serve:widget":"rm -rf ./widget-example/static/* && cp -rf ./dist-widget/* ./widget-example/static && npx http-server ./widget-example -o -c-1",release:"npm publish","release:widget":"node check-publish.js patch && npm version patch -m v%s",format:"prettier --write './**/*.{js,jsx,ts,tsx,css,md,json}' --config ./.prettierrc",bump:"node bump-version.js","build-pack":"npm run bump && npm run build && npm pack","build-pack:win":"npm run bump && npm run build:win && npm pack","publish:minor":"node check-publish.js minor && npm version minor --allow-same-version -m v%s --force","publish:major":"node check-publish.js major && npm version major --allow-same-version -m v%s --force","publish:patch":"node check-publish.js patch && npm version patch --allow-same-version -m v%s --force","publish:dev":"node publish-dev.js",preversion:"rm -rf dist-widget && npm run build:widget && git add dist-widget/index.widget.js dist-widget/index.widget.css && git commit -m 'chore(widget): release for jsDelivr'",postversion:"git push origin main --tags","revert-bump":"node revert-bump.js"},b={production:[">0.2%","not dead","not op_mini all"],development:["last 1 chrome version","last 1 firefox version","last 1 safari version"]},g={"@babel/core":"^7.20.2","@babel/preset-env":"^7.20.2","@rollup/plugin-babel":"^7.0.0","@rollup/plugin-commonjs":"^23.0.2","@rollup/plugin-json":"^6.1.0","@rollup/plugin-node-resolve":"^16.0.0","@rollup/plugin-terser":"^1.0.0","@rollup/plugin-typescript":"^9.0.2","@types/react":"^18.0.26","@types/react-dom":"^18.0.9","@types/styled-components":"^5.1.26",parcel:"^2.0.0",postcss:"^8.4.49",prettier:"^2.8.0",rollup:"^2.79.1","tailwind-scrollbar":"^3.1.0",tailwindcss:"^3.4.16",typescript:"^4.8.4"},w="GPL-3.0-or-later",v={name:e,author:s,version:t,description:i,keywords:r,homepage:o,bugs:n,repository:p,private:!1,files:d,main:l,types:c,publishConfig:a,targets:m,dependencies:u,scripts:h,browserslist:b,devDependencies:g,license:w};exports.author=s,exports.browserslist=b,exports.bugs=n,exports.default=v,exports.dependencies=u,exports.description=i,exports.devDependencies=g,exports.files=d,exports.homepage=o,exports.keywords=r,exports.license=w,exports.main=l,exports.name=e,exports.publishConfig=a,exports.repository=p,exports.scripts=h,exports.targets=m,exports.types=c,exports.version=t;
2
2
  //# sourceMappingURL=package.json.js.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nethesis/phone-island",
3
3
  "author": "Nethesis",
4
- "version": "1.1.1",
4
+ "version": "1.1.3",
5
5
  "description": "NethVoice CTI Phone Island",
6
6
  "keywords": [
7
7
  "nethserver",