Feature/azure recognition (#46)

* add support for microsoft speech recognition

* update to drachtio-fsmrf that support microsoft stt

* gather and transcribe now support microsoft
This commit is contained in:
Dave Horton
2021-11-26 16:40:25 -06:00
committed by GitHub
parent fe1778e9ae
commit 1e93973419
6 changed files with 180 additions and 66 deletions

View File

@@ -3,7 +3,8 @@ const {
TaskName,
TaskPreconditions,
GoogleTranscriptionEvents,
AwsTranscriptionEvents
AwsTranscriptionEvents,
AzureTranscriptionEvents
} = require('../utils/constants');
const makeTask = require('./make_task');
@@ -33,6 +34,12 @@ class TaskGather extends Task {
this.vocabularyName = recognizer.vocabularyName;
this.vocabularyFilterName = recognizer.vocabularyFilterName;
this.filterMethod = recognizer.filterMethod;
/* microsoft options */
this.outputFormat = recognizer.outputFormat || 'simple';
this.profanityOption = recognizer.profanityOption || 'raw';
this.requestSnr = recognizer.requestSnr || false;
this.initialSpeechTimeoutMs = recognizer.initialSpeechTimeoutMs || 0;
}
this.digitBuffer = '';
@@ -63,7 +70,7 @@ class TaskGather extends Task {
this.sttCredentials = cs.getSpeechCredentials(this.vendor, 'stt');
if (this.needsStt && !this.sttCredentials) {
const {writeAlerts, AlertType} = cs.srf.locals;
this.logger.info(`TaskGather:exec - ERROR stt using ${this.vendor} requested but not creds supplied`);
this.logger.info(`TaskGather:exec - ERROR stt using ${this.vendor} requested but creds not supplied`);
writeAlerts({
account_sid: cs.accountSid,
alert_type: AlertType.STT_NOT_PROVISIONED,
@@ -106,6 +113,8 @@ class TaskGather extends Task {
ep.removeCustomEventListener(GoogleTranscriptionEvents.Transcription);
ep.removeCustomEventListener(GoogleTranscriptionEvents.EndOfUtterance);
ep.removeCustomEventListener(AwsTranscriptionEvents.Transcription);
ep.removeCustomEventListener(AzureTranscriptionEvents.Transcription);
ep.removeCustomEventListener(AzureTranscriptionEvents.NoSpeechDetected);
}
kill(cs) {
@@ -135,7 +144,9 @@ class TaskGather extends Task {
GOOGLE_SPEECH_SINGLE_UTTERANCE: true,
GOOGLE_SPEECH_MODEL: 'command_and_search'
});
if (this.hints && this.hints.length > 1) opts.GOOGLE_SPEECH_HINTS = this.hints.join(',');
if (this.hints && this.hints.length > 1) {
opts.GOOGLE_SPEECH_HINTS = this.hints.map((h) => h.trim()).join(',');
}
if (this.altLanguages && this.altLanguages.length > 1) {
opts.GOOGLE_SPEECH_ALTERNATIVE_LANGUAGE_CODES = this.altLanguages.join(',');
}
@@ -145,22 +156,41 @@ class TaskGather extends Task {
ep.addCustomEventListener(GoogleTranscriptionEvents.Transcription, this._onTranscription.bind(this, cs, ep));
ep.addCustomEventListener(GoogleTranscriptionEvents.EndOfUtterance, this._onEndOfUtterance.bind(this, cs, ep));
}
else {
else if (['aws', 'polly'].includes(this.vendor)) {
if (this.vocabularyName) opts.AWS_VOCABULARY_NAME = this.vocabularyName;
if (this.vocabularyFilterName) {
opts.AWS_VOCABULARY_NAME = this.vocabularyFilterName;
opts.AWS_VOCABULARY_FILTER_METHOD = this.filterMethod || 'mask';
}
Object.assign(opts, {
AWS_ACCESS_KEY_ID: this.sttCredentials.accessKeyId,
AWS_SECRET_ACCESS_KEY: this.sttCredentials.secretAccessKey,
AWS_REGION: this.sttCredentials.region
});
if (this.sttCredentials) {
Object.assign(opts, {
AWS_ACCESS_KEY_ID: this.sttCredentials.accessKeyId,
AWS_SECRET_ACCESS_KEY: this.sttCredentials.secretAccessKey,
AWS_REGION: this.sttCredentials.region
});
}
ep.addCustomEventListener(AwsTranscriptionEvents.Transcription, this._onTranscription.bind(this, cs, ep));
}
else if ('microsoft' === this.vendor) {
if (this.sttCredentials) {
Object.assign(opts, {
'AZURE_SUBSCRIPTION_KEY': this.sttCredentials.api_key,
'AZURE_REGION': this.sttCredentials.region
});
}
if (this.hints && this.hints.length > 1) {
opts.AZURE_SPEECH_HINTS = this.hints.map((h) => h.trim()).join(',');
}
//if (this.requestSnr) opts.AZURE_REQUEST_SNR = 1;
//if (this.profanityOption !== 'raw') opts.AZURE_PROFANITY_OPTION = this.profanityOption;
if (this.initialSpeechTimeoutMs > 0) opts.AZURE_INITIAL_SPEECH_TIMEOUT_MS = this.initialSpeechTimeoutMs;
opts.AZURE_USE_OUTPUT_FORMAT_DETAILED = 1;
ep.addCustomEventListener(AzureTranscriptionEvents.Transcription, this._onTranscription.bind(this, cs, ep));
ep.addCustomEventListener(AzureTranscriptionEvents.NoSpeechDetected, this._onNoSpeechDetected.bind(this, cs, ep));
}
await ep.set(opts)
.catch((err) => this.logger.info(err, 'Error setting channel variables'));
}
_startTranscribing(ep) {
@@ -208,11 +238,21 @@ class TaskGather extends Task {
_onTranscription(cs, ep, evt) {
if ('aws' === this.vendor && Array.isArray(evt) && evt.length > 0) evt = evt[0];
this.logger.debug(evt, 'TaskGather:_onTranscription');
const final = evt.is_final;
if (final) {
this._resolve('speech', evt);
if ('microsoft' === this.vendor) {
const nbest = evt.NBest;
const newEvent = {
is_final: evt.RecognitionStatus === 'Success',
alternatives: [
{
confidence: nbest[0].Confidence,
transcript: nbest[0].Display
}
]
};
evt = newEvent;
}
this.logger.debug(evt, 'TaskGather:_onTranscription');
if (evt.is_final) this._resolve('speech', evt);
else if (this.partialResultHook) {
this.cs.requestor.request(this.partialResultHook, Object.assign({speech: evt}, this.cs.callInfo))
.catch((err) => this.logger.info(err, 'GatherTask:_onTranscription error'));
@@ -225,6 +265,10 @@ class TaskGather extends Task {
}
}
_onNoSpeechDetected(cs, ep) {
this._resolve('timeout');
}
async _resolve(reason, evt) {
if (this.resolved) return;
this.resolved = true;

View File

@@ -348,7 +348,7 @@
"properties": {
"vendor": {
"type": "string",
"enum": ["google", "aws", "polly", "default"]
"enum": ["google", "aws", "polly", "microsoft", "default"]
},
"language": "string",
"voice": "string",
@@ -365,7 +365,7 @@
"properties": {
"vendor": {
"type": "string",
"enum": ["google", "aws", "default"]
"enum": ["google", "aws", "microsoft", "default"]
},
"language": "string",
"hints": "array",
@@ -405,7 +405,24 @@
"mask",
"tag"
]
}
},
"outputFormat": {
"type": "string",
"enum": [
"simple",
"detailed"
]
},
"profanityOption": {
"type": "string",
"enum": [
"masked",
"removed",
"raw"
]
},
"requestSnr": "boolean",
"initialSpeechTimeoutMs": "number"
},
"required": [
"vendor"

View File

@@ -3,6 +3,7 @@ const {
TaskName,
TaskPreconditions,
GoogleTranscriptionEvents,
AzureTranscriptionEvents,
AwsTranscriptionEvents
} = require('../utils/constants');
@@ -38,6 +39,12 @@ class TaskTranscribe extends Task {
this.vocabularyName = recognizer.vocabularyName;
this.vocabularyFilterName = recognizer.vocabularyFilterName;
this.filterMethod = recognizer.filterMethod;
/* microsoft options */
this.outputFormat = recognizer.outputFormat || 'simple';
this.profanityOption = recognizer.profanityOption || 'raw';
this.requestSnr = recognizer.requestSnr || false;
this.initialSpeechTimeoutMs = recognizer.initialSpeechTimeoutMs || 0;
}
get name() { return TaskName.Transcribe; }
@@ -53,7 +60,13 @@ class TaskTranscribe extends Task {
try {
if (!this.sttCredentials) {
// TODO: generate alert (actually should be done by cs.getSpeechCredentials)
const {writeAlerts, AlertType} = cs.srf.locals;
this.logger.info(`TaskTranscribe:exec - ERROR stt using ${this.vendor} requested but creds not supplied`);
writeAlerts({
account_sid: cs.accountSid,
alert_type: AlertType.STT_NOT_PROVISIONED,
vendor: this.vendor
}).catch((err) => this.logger.info({err}, 'Error generating alert for no stt'));
throw new Error('no provisioned speech credentials for TTS');
}
await this._startTranscribing(cs, ep);
@@ -70,6 +83,8 @@ class TaskTranscribe extends Task {
ep.removeCustomEventListener(AwsTranscriptionEvents.Transcription);
ep.removeCustomEventListener(AwsTranscriptionEvents.NoAudioDetected);
ep.removeCustomEventListener(AwsTranscriptionEvents.MaxDurationExceeded);
ep.removeCustomEventListener(AzureTranscriptionEvents.Transcription);
ep.removeCustomEventListener(AzureTranscriptionEvents.NoSpeechDetected);
}
async kill(cs) {
@@ -96,6 +111,8 @@ class TaskTranscribe extends Task {
ep.addCustomEventListener(AwsTranscriptionEvents.NoAudioDetected, this._onNoAudio.bind(this, cs, ep));
ep.addCustomEventListener(AwsTranscriptionEvents.MaxDurationExceeded,
this._onMaxDurationExceeded.bind(this, cs, ep));
ep.addCustomEventListener(AzureTranscriptionEvents.Transcription, this._onTranscription.bind(this, cs, ep));
ep.addCustomEventListener(AzureTranscriptionEvents.NoSpeechDetected, this._onNoAudio.bind(this, cs, ep));
if (this.vendor === 'google') {
if (this.sttCredentials) opts.GOOGLE_APPLICATION_CREDENTIALS = JSON.stringify(this.sttCredentials.credentials);
@@ -164,6 +181,22 @@ class TaskTranscribe extends Task {
await ep.set(opts)
.catch((err) => this.logger.info(err, 'TaskTranscribe:_startTranscribing with aws'));
}
else if (this.vendor === 'microsoft') {
Object.assign(opts, {
'AZURE_SUBSCRIPTION_KEY': this.sttCredentials.api_key,
'AZURE_REGION': this.sttCredentials.region
});
if (this.hints && this.hints.length > 1) {
opts.AZURE_SPEECH_HINTS = this.hints.map((h) => h.trim()).join(',');
}
if (this.requestSnr) opts.AZURE_REQUEST_SNR = 1;
if (this.profanityOption !== 'raw') opts.AZURE_PROFANITY_OPTION = this.profanityOption;
if (this.initialSpeechTimeoutMs > 0) opts.AZURE_INITIAL_SPEECH_TIMEOUT_MS = this.initialSpeechTimeoutMs;
if (this.outputFormat !== 'simple') opts.AZURE_USE_OUTPUT_FORMAT_DETAILED = 1;
await ep.set(opts)
.catch((err) => this.logger.info(err, 'TaskTranscribe:_startTranscribing with azure'));
}
await this._transcribe(ep);
}
@@ -178,6 +211,20 @@ class TaskTranscribe extends Task {
_onTranscription(cs, ep, evt) {
if ('aws' === this.vendor && Array.isArray(evt) && evt.length > 0) evt = evt[0];
if ('microsoft' === this.vendor) {
const nbest = evt.NBest;
const alternatives = nbest.map((n) => {
return {
confidence: n.Confidence,
transcript: n.Display
};
});
const newEvent = {
is_final: evt.RecognitionStatus === 'Success',
alternatives
};
evt = newEvent;
}
this.logger.debug(evt, 'TaskTranscribe:_onTranscription');
this.cs.requestor.request(this.transcriptionHook, Object.assign({speech: evt}, this.cs.callInfo))

View File

@@ -65,6 +65,12 @@
"NoAudioDetected": "aws_transcribe::no_audio_detected",
"MaxDurationExceeded": "aws_transcribe::max_duration_exceeded"
},
"AzureTranscriptionEvents": {
"Transcription": "azure_transcribe::transcription",
"StartOfUtterance": "azure_transcribe::start_of_utterance",
"EndOfUtterance": "azure_transcribe::end_of_utterance",
"NoSpeechDetected": "azure_transcribe::no_speech_detected"
},
"ListenEvents": {
"Connect": "mod_audio_fork::connect",
"ConnectFailure": "mod_audio_fork::connect_failed",

94
package-lock.json generated
View File

@@ -18,7 +18,7 @@
"cidr-matcher": "^2.1.1",
"debug": "^4.3.1",
"deepcopy": "^2.1.0",
"drachtio-fsmrf": "^2.0.7",
"drachtio-fsmrf": "^2.0.11",
"drachtio-srf": "^4.4.55",
"express": "^4.17.1",
"ip": "^1.1.5",
@@ -1466,15 +1466,15 @@
}
},
"node_modules/drachtio-fsmrf": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/drachtio-fsmrf/-/drachtio-fsmrf-2.0.7.tgz",
"integrity": "sha512-jI6Cfho5OZGfp2OpCtOW0aFtklf4JfG55lsqyMiJmaWcKlfIgcvH79FHhG9osQ2ur7ygxH8V2bo6Fsi02LxzHw==",
"version": "2.0.11",
"resolved": "https://registry.npmjs.org/drachtio-fsmrf/-/drachtio-fsmrf-2.0.11.tgz",
"integrity": "sha512-3U1tHBh2fJd8cGbUMV+Gc2laq5VxIynmP3Ue0eRW35Za7Sp7/ucPfxbJ2OZc0PlokRCQYGvCyjTdTv8SPzoajQ==",
"dependencies": {
"async": "^1.4.2",
"debug": "^2.2.0",
"debug": "^2.6.9",
"delegates": "^0.1.0",
"drachtio-modesl": "^1.2.0",
"drachtio-srf": "^4.4.47",
"drachtio-modesl": "^1.2.2",
"drachtio-srf": "^4.4.59",
"lodash": "^4.17.21",
"minimist": "^1.2.5",
"only": "0.0.2",
@@ -1513,12 +1513,12 @@
}
},
"node_modules/drachtio-modesl": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/drachtio-modesl/-/drachtio-modesl-1.2.0.tgz",
"integrity": "sha512-nkua3RfYnT32OvglERO2zWzJZAfQooZIarZVVAye+iGqTwYJ69X7bU7du5SBHz/jBl+LgeWITMP2fMe2TelxmA==",
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/drachtio-modesl/-/drachtio-modesl-1.2.2.tgz",
"integrity": "sha512-4+SVtMahFfqbxP+TIBN0usc9iMJX5Sl/vkJ3lMj3OmIRto18lkUUpFOBbj/PZbFZMoeXLz4tAWNzlzEBCC7bBw==",
"dependencies": {
"debug": "^4.1.1",
"eventemitter2": "^4.1",
"eventemitter2": "^6.4.4",
"uuid": "^3.1.0",
"xml2js": "^0.4.19"
},
@@ -1536,9 +1536,9 @@
}
},
"node_modules/drachtio-sip": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/drachtio-sip/-/drachtio-sip-0.6.0.tgz",
"integrity": "sha512-C8Y33rVpP0KwmZmBMxBjhbj58kktVFlzc+Od2g6TgOaqeEyF0JhwrHnech+iEtr2A2eKBlA85C9cCRh1+QpoRA==",
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/drachtio-sip/-/drachtio-sip-0.6.2.tgz",
"integrity": "sha512-BkiRZq3Yq2WVSGY3M7Hv4yX4dIW/o0/4xNMcm26IxT71YIRy07UtbQUHaMI3P2HfPu5zK6RoQW2MHrxPXtz6ZQ==",
"dependencies": {
"debug": "^4.3.1",
"eslint-plugin-promise": "^5.1.0",
@@ -1546,9 +1546,9 @@
}
},
"node_modules/drachtio-sip/node_modules/eslint-plugin-promise": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.1.0.tgz",
"integrity": "sha512-NGmI6BH5L12pl7ScQHbg7tvtk4wPxxj8yPHH47NvSmMtFneC077PSeY3huFj06ZWZvtbfxSPt3RuOQD5XcR4ng==",
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.1.1.tgz",
"integrity": "sha512-XgdcdyNzHfmlQyweOPTxmc7pIsS6dE4MvwhXWMQ2Dxs1XAL2GJDilUsjWen6TWik0aSI+zD/PqocZBblcm9rdA==",
"engines": {
"node": "^10.12.0 || >=12.0.0"
},
@@ -1557,15 +1557,15 @@
}
},
"node_modules/drachtio-srf": {
"version": "4.4.55",
"resolved": "https://registry.npmjs.org/drachtio-srf/-/drachtio-srf-4.4.55.tgz",
"integrity": "sha512-wADXzcEdxD748iSK2KepD9LEiA+XW0nE2zNV89azKk0AafZGD0+DLMf1m8IOBnFE30H91pJI74Z8fO652+QB0A==",
"version": "4.4.59",
"resolved": "https://registry.npmjs.org/drachtio-srf/-/drachtio-srf-4.4.59.tgz",
"integrity": "sha512-hrW9bZ8TZR9JQ3pqI+nyrI1eAzEOwHuvm1lNL1fbmZmRddKJzYdylkgVoyURs/OlT/nANy/M43GrQjcGP4psPw==",
"dependencies": {
"async": "^1.4.2",
"debug": "^3.2.7",
"delegates": "^0.1.0",
"deprecate": "^1.1.1",
"drachtio-sip": "^0.6.0",
"drachtio-sip": "^0.6.2",
"node-noop": "0.0.1",
"only": "0.0.2",
"sdp-transform": "^2.14.1",
@@ -2010,9 +2010,9 @@
}
},
"node_modules/eventemitter2": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-4.1.2.tgz",
"integrity": "sha1-DhqEd6+CGm7zmVsxG/dMI6UkfxU="
"version": "6.4.5",
"resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.5.tgz",
"integrity": "sha512-bXE7Dyc1i6oQElDG0jMRZJrRAn9QR2xyyFGmBdZleNmyQX0FqGYmhZIrIrpPfm/w//LTo4tVQGOGQcGCb5q9uw=="
},
"node_modules/events": {
"version": "1.1.1",
@@ -6444,15 +6444,15 @@
}
},
"drachtio-fsmrf": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/drachtio-fsmrf/-/drachtio-fsmrf-2.0.7.tgz",
"integrity": "sha512-jI6Cfho5OZGfp2OpCtOW0aFtklf4JfG55lsqyMiJmaWcKlfIgcvH79FHhG9osQ2ur7ygxH8V2bo6Fsi02LxzHw==",
"version": "2.0.11",
"resolved": "https://registry.npmjs.org/drachtio-fsmrf/-/drachtio-fsmrf-2.0.11.tgz",
"integrity": "sha512-3U1tHBh2fJd8cGbUMV+Gc2laq5VxIynmP3Ue0eRW35Za7Sp7/ucPfxbJ2OZc0PlokRCQYGvCyjTdTv8SPzoajQ==",
"requires": {
"async": "^1.4.2",
"debug": "^2.2.0",
"debug": "^2.6.9",
"delegates": "^0.1.0",
"drachtio-modesl": "^1.2.0",
"drachtio-srf": "^4.4.47",
"drachtio-modesl": "^1.2.2",
"drachtio-srf": "^4.4.59",
"lodash": "^4.17.21",
"minimist": "^1.2.5",
"only": "0.0.2",
@@ -6486,12 +6486,12 @@
}
},
"drachtio-modesl": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/drachtio-modesl/-/drachtio-modesl-1.2.0.tgz",
"integrity": "sha512-nkua3RfYnT32OvglERO2zWzJZAfQooZIarZVVAye+iGqTwYJ69X7bU7du5SBHz/jBl+LgeWITMP2fMe2TelxmA==",
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/drachtio-modesl/-/drachtio-modesl-1.2.2.tgz",
"integrity": "sha512-4+SVtMahFfqbxP+TIBN0usc9iMJX5Sl/vkJ3lMj3OmIRto18lkUUpFOBbj/PZbFZMoeXLz4tAWNzlzEBCC7bBw==",
"requires": {
"debug": "^4.1.1",
"eventemitter2": "^4.1",
"eventemitter2": "^6.4.4",
"uuid": "^3.1.0",
"xml2js": "^0.4.19"
},
@@ -6504,9 +6504,9 @@
}
},
"drachtio-sip": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/drachtio-sip/-/drachtio-sip-0.6.0.tgz",
"integrity": "sha512-C8Y33rVpP0KwmZmBMxBjhbj58kktVFlzc+Od2g6TgOaqeEyF0JhwrHnech+iEtr2A2eKBlA85C9cCRh1+QpoRA==",
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/drachtio-sip/-/drachtio-sip-0.6.2.tgz",
"integrity": "sha512-BkiRZq3Yq2WVSGY3M7Hv4yX4dIW/o0/4xNMcm26IxT71YIRy07UtbQUHaMI3P2HfPu5zK6RoQW2MHrxPXtz6ZQ==",
"requires": {
"debug": "^4.3.1",
"eslint-plugin-promise": "^5.1.0",
@@ -6514,23 +6514,23 @@
},
"dependencies": {
"eslint-plugin-promise": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.1.0.tgz",
"integrity": "sha512-NGmI6BH5L12pl7ScQHbg7tvtk4wPxxj8yPHH47NvSmMtFneC077PSeY3huFj06ZWZvtbfxSPt3RuOQD5XcR4ng==",
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.1.1.tgz",
"integrity": "sha512-XgdcdyNzHfmlQyweOPTxmc7pIsS6dE4MvwhXWMQ2Dxs1XAL2GJDilUsjWen6TWik0aSI+zD/PqocZBblcm9rdA==",
"requires": {}
}
}
},
"drachtio-srf": {
"version": "4.4.55",
"resolved": "https://registry.npmjs.org/drachtio-srf/-/drachtio-srf-4.4.55.tgz",
"integrity": "sha512-wADXzcEdxD748iSK2KepD9LEiA+XW0nE2zNV89azKk0AafZGD0+DLMf1m8IOBnFE30H91pJI74Z8fO652+QB0A==",
"version": "4.4.59",
"resolved": "https://registry.npmjs.org/drachtio-srf/-/drachtio-srf-4.4.59.tgz",
"integrity": "sha512-hrW9bZ8TZR9JQ3pqI+nyrI1eAzEOwHuvm1lNL1fbmZmRddKJzYdylkgVoyURs/OlT/nANy/M43GrQjcGP4psPw==",
"requires": {
"async": "^1.4.2",
"debug": "^3.2.7",
"delegates": "^0.1.0",
"deprecate": "^1.1.1",
"drachtio-sip": "^0.6.0",
"drachtio-sip": "^0.6.2",
"node-noop": "0.0.1",
"only": "0.0.2",
"sdp-transform": "^2.14.1",
@@ -6873,9 +6873,9 @@
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="
},
"eventemitter2": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-4.1.2.tgz",
"integrity": "sha1-DhqEd6+CGm7zmVsxG/dMI6UkfxU="
"version": "6.4.5",
"resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.5.tgz",
"integrity": "sha512-bXE7Dyc1i6oQElDG0jMRZJrRAn9QR2xyyFGmBdZleNmyQX0FqGYmhZIrIrpPfm/w//LTo4tVQGOGQcGCb5q9uw=="
},
"events": {
"version": "1.1.1",

View File

@@ -36,7 +36,7 @@
"cidr-matcher": "^2.1.1",
"debug": "^4.3.1",
"deepcopy": "^2.1.0",
"drachtio-fsmrf": "^2.0.7",
"drachtio-fsmrf": "^2.0.11",
"drachtio-srf": "^4.4.55",
"express": "^4.17.1",
"ip": "^1.1.5",