Socket
Socket
Sign inDemoInstall

web-speech-cognitive-services

Package Overview
Dependencies
Maintainers
1
Versions
153
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

web-speech-cognitive-services - npm Package Compare versions

Comparing version 0.0.1-master.869e22a to 0.0.1-master.da41f39

336

lib/CognitiveServicesSpeechRecognition.js

@@ -7,2 +7,4 @@ 'use strict';

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

@@ -14,2 +16,6 @@

var _eventAsPromise = require('event-as-promise');
var _eventAsPromise2 = _interopRequireDefault(_eventAsPromise);
var _memoizeOne = require('memoize-one');

@@ -23,2 +29,4 @@

function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }

@@ -77,6 +85,6 @@

var name = 'Browser';
var osVersion = "0.0.1-master.869e22a";
var osVersion = "0.0.1-master.da41f39";
var manufacturer = 'web-speech-cognitive-services';
var model = 'web-speech-cognitive-services';
var deviceVersion = "0.0.1-master.869e22a";
var deviceVersion = "0.0.1-master.da41f39";

@@ -144,139 +152,202 @@ var config = new CognitiveSpeech.RecognizerConfig(new CognitiveSpeech.SpeechConfig(new CognitiveSpeech.Context(new CognitiveSpeech.OS(platform, name, osVersion), new CognitiveSpeech.Device(manufacturer, model, deviceVersion))), mode, lang, CognitiveSpeech.SpeechResultFormat.Detailed);

_createClass(CognitiveServicesSpeechRecognition, [{
key: '_transitTo',
value: function _transitTo(nextReadyState) {
// console.log(`_transitTo: readyState = ${ this.readyState }, nextReadyState = ${ nextReadyState }`);
key: 'abort',
value: function abort() {
// TODO: Should redesign how to stop a recognition session
// After abort is called, we should not saw it is a "success", "silent", or "no match"
var _ref3 = this.recognizer || {},
AudioSource = _ref3.AudioSource;
if (nextReadyState > this.readyState) {
var lifecycleEvents = [null, null, this.onstart, this.onaudiostart, this.onsoundstart, this.onspeechstart, this.onspeechend, this.onsoundend, this.onaudioend, this.onend];
AudioSource && AudioSource.TurnOff();
if (this.readyState === AUDIO_START && nextReadyState >= AUDIO_END) {
// If soundstart, speechstart, speechend, and soundend are not fired after audiostart,
// we can skip them and just fire audioend directly
this.readyState = SOUND_END;
}
this._aborted = true;
}
}, {
key: 'emit',
value: function emit(name, event) {
var listener = this['on' + name];
for (var transition = this.readyState + 1; transition <= nextReadyState; transition++) {
var eventListener = lifecycleEvents[transition];
// eventListener && console.log(`Firing "${ EVENT_TYPES[transition] }"`);
eventListener && eventListener({ type: EVENT_TYPES[transition] });
}
if (nextReadyState === END) {
this.readyState = IDLE;
} else {
this.readyState = nextReadyState;
}
}
listener && listener.call(this, _extends({}, event, { type: name }));
}
}, {
key: '_handleDetailedPhrase',
value: function _handleDetailedPhrase(event) {
console.log(event);
key: 'stop',
value: function stop() {
throw new Error('not supported');
}
}, {
key: 'start',
value: function () {
var _ref4 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3() {
var recognizer, _toPromise, eventListener, promises, error, listeningStarted, recognitionStarted, gotFirstHypothesis, speechHypothesis, speechDetailedPhrase, recognitionResult;
this._transitTo(AUDIO_END);
return regeneratorRuntime.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
recognizer = this.recognizer = this.createRecognizer(window.localStorage.getItem('SPEECH_KEY'), this.lang);
_toPromise = toPromise(), eventListener = _toPromise.eventListener, promises = _objectWithoutProperties(_toPromise, ['eventListener']);
if (CognitiveSpeech.RecognitionStatus[event.Result.RecognitionStatus] === CognitiveSpeech.RecognitionStatus.Success) {
var nBest = event.Result.NBest;
recognizer.Recognize(eventListener);
this._aborted = false;
this.onresult && this.onresult(buildSpeechResult(event.Result.NBest[0].Display, event.Result.NBest[0].Confidence, true));
} else {
this.onerror && this.onerror({ error: event.Result.RecognitionStatus, type: 'error' });
}
}
}, {
key: '_handleHypothesis',
value: function _handleHypothesis(event) {
console.log(event);
_context3.next = 6;
return promises.recognitionTriggered;
this.onresult && this.onresult(buildSpeechResult(event.Result.Text, .5, false));
}
}, {
key: 'abort',
value: function abort() {
var _ref3 = this.recognizer || {},
AudioSource = _ref3.AudioSource;
case 6:
error = void 0;
_context3.next = 9;
return Promise.race([promises.listeningStarted, promises.recognitionEnded]);
console.log('ABORT: ' + AudioSource);
case 9:
listeningStarted = _context3.sent;
AudioSource && AudioSource.TurnOff();
}
}, {
key: 'handleRecognize',
value: function handleRecognize(event) {
try {
var name = event.Name;
if (!(listeningStarted.Name === 'RecognitionEndedEvent')) {
_context3.next = 14;
break;
}
// Possibly not authorized to use microphone
if (listeningStarted.Status === CognitiveSpeech.RecognitionCompletionStatus.AudioSourceError) {
error = 'not-allowed';
} else {
error = CognitiveSpeech.RecognitionCompletionStatus[listeningStarted.Status];
}
_context3.next = 51;
break;
console.log('handleRecognize: ' + name);
case 14:
this.emit('start');
switch (name) {
case 'ListeningStartedEvent':
this._transitTo(AUDIO_START);
break;
_context3.next = 17;
return promises.connectingToService;
case 'RecognitionEndedEvent':
if (event.Status !== CognitiveSpeech.RecognitionCompletionStatus.Success) {
this._transitTo(AUDIO_END);
this.onerror && this.onerror({ error: CognitiveSpeech.RecognitionCompletionStatus[event.Status], type: 'error' });
}
case 17:
_context3.next = 19;
return Promise.race([promises.recognitionStarted, promises.recognitionEnded]);
this._transitTo(END);
case 19:
recognitionStarted = _context3.sent;
break;
case 'RecognitionStartedEvent':
this._transitTo(SPEECH_START);
break;
this.emit('audiostart');
case 'RecognitionTriggeredEvent':
this._transitTo(START);
break;
if (!(recognitionStarted.Name === 'RecognitionEndedEvent')) {
_context3.next = 25;
break;
}
case 'SpeechEndDetectedEvent':
this._transitTo(SPEECH_END);
break;
// Possibly network error
if (recognitionStarted.Status === CognitiveSpeech.RecognitionCompletionStatus.ConnectError) {
error = 'network';
} else {
error = CognitiveSpeech.RecognitionCompletionStatus[recognitionStarted.Status];
}
_context3.next = 36;
break;
case 'SpeechStartDetectedEvent':
this._transitTo(SPEECH_START);
break;
case 25:
gotFirstHypothesis = void 0;
case 'SpeechHypothesisEvent':
this._handleHypothesis(event);
break;
case 26:
_context3.next = 28;
return Promise.race([promises.getSpeechHypothesisPromise(), promises.speechEndDetected]);
case 'SpeechDetailedPhraseEvent':
this._handleDetailedPhrase(event);
break;
case 28:
speechHypothesis = _context3.sent;
case 'ConnectingToServiceEvent':
case 'SpeechSimplePhraseEvent':
break;
if (!(speechHypothesis.Name === 'SpeechEndDetectedEvent')) {
_context3.next = 31;
break;
}
default:
console.warn('Unexpected event "' + name + '" from Cognitive Services, please file a bug to https://github.com/compulim/web-speech-cognitive-services');
break;
}
} catch (err) {
// Cognitive Services will hide all exceptions thrown in the event listener
// We need to show it otherwise when exception happen, we will not know what's going on
console.error(err);
throw err;
return _context3.abrupt('break', 35);
case 31:
if (!gotFirstHypothesis) {
gotFirstHypothesis = true;
this.emit('soundstart');
this.emit('speechstart');
}
this.emit('result', buildSpeechResult(speechHypothesis.Result.Text, .5, false));
case 33:
_context3.next = 26;
break;
case 35:
if (gotFirstHypothesis) {
this.emit('speechend');
this.emit('soundend');
}
case 36:
this.emit('audioend');
if (!this._aborted) {
_context3.next = 43;
break;
}
error = 'aborted';
_context3.next = 41;
return promises.recognitionEnded;
case 41:
_context3.next = 51;
break;
case 43:
_context3.next = 45;
return Promise.race([promises.speechDetailedPhrase, promises.recognitionEnded]);
case 45:
speechDetailedPhrase = _context3.sent;
if (!(speechDetailedPhrase.Name !== 'RecognitionEndedEvent')) {
_context3.next = 51;
break;
}
recognitionResult = CognitiveSpeech.RecognitionStatus[speechDetailedPhrase.Result.RecognitionStatus];
if (recognitionResult === CognitiveSpeech.RecognitionStatus.Success) {
this.emit('result', buildSpeechResult(speechDetailedPhrase.Result.NBest[0].Display, speechDetailedPhrase.Result.NBest[0].Confidence, true));
} else if (recognitionResult !== CognitiveSpeech.RecognitionStatus.NoMatch) {
// Possibly silent or muted
if (recognitionResult === CognitiveSpeech.RecognitionStatus.InitialSilenceTimeout) {
error = 'no-speech';
} else {
error = speechDetailedPhrase.Result.RecognitionStatus;
}
}
_context3.next = 51;
return promises.recognitionEnded;
case 51:
error && this.emit('error', { error: error });
this.emit('end');
case 53:
case 'end':
return _context3.stop();
}
}
}, _callee3, this);
}));
function start() {
return _ref4.apply(this, arguments);
}
}
}, {
key: 'start',
value: function start() {
this.recognizer = this.createRecognizer(window.localStorage.getItem('SPEECH_KEY'), this.lang);
this.recognizer.Recognize(this.handleRecognize.bind(this));
this._transitTo(START);
}
return start;
}()
}, {
key: 'stop',
value: function stop() {
throw new Error('not supported');
}
}, {
key: 'grammars',

@@ -336,3 +407,46 @@ get: function get() {

function toPromise() {
var events = {
ConnectingToServiceEvent: new _eventAsPromise2.default(),
ListeningStartedEvent: new _eventAsPromise2.default(),
RecognitionEndedEvent: new _eventAsPromise2.default(),
RecognitionStartedEvent: new _eventAsPromise2.default(),
RecognitionTriggeredEvent: new _eventAsPromise2.default(),
SpeechDetailedPhraseEvent: new _eventAsPromise2.default(),
SpeechEndDetectedEvent: new _eventAsPromise2.default(),
SpeechHypothesisEvent: new _eventAsPromise2.default(),
SpeechSimplePhraseEvent: new _eventAsPromise2.default(),
SpeechStartDetectedEvent: new _eventAsPromise2.default()
};
return {
connectingToService: events.ConnectingToServiceEvent.upcoming(),
listeningStarted: events.ListeningStartedEvent.upcoming(),
recognitionEnded: events.RecognitionEndedEvent.upcoming(),
recognitionStarted: events.RecognitionStartedEvent.upcoming(),
recognitionTriggered: events.RecognitionTriggeredEvent.upcoming(),
speechDetailedPhrase: events.SpeechDetailedPhraseEvent.upcoming(),
speechEndDetected: events.SpeechEndDetectedEvent.upcoming(),
getSpeechHypothesisPromise: function getSpeechHypothesisPromise() {
return events.SpeechHypothesisEvent.upcoming();
},
speechSimplePhrase: events.SpeechSimplePhraseEvent.upcoming(),
speechStartDetected: events.SpeechStartDetectedEvent.upcoming(),
eventListener: function eventListener(event) {
var name = event.Name;
var eventAsPromise = events[name];
console.log('handling ' + name);
if (eventAsPromise) {
eventAsPromise.eventListener.call(null, event);
} else {
console.warn('Unexpected event "' + name + '" from Cognitive Services, please file a bug to https://github.com/compulim/web-speech-cognitive-services');
}
}
};
}
exports.default = CognitiveServicesSpeechRecognition;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9Db2duaXRpdmVTZXJ2aWNlc1NwZWVjaFJlY29nbml0aW9uLmpzIl0sIm5hbWVzIjpbIkNvZ25pdGl2ZVNwZWVjaCIsIlVOSU5JVCIsIklETEUiLCJTVEFSVCIsIkFVRElPX1NUQVJUIiwiU09VTkRfU1RBUlQiLCJTUEVFQ0hfU1RBUlQiLCJTUEVFQ0hfRU5EIiwiU09VTkRfRU5EIiwiQVVESU9fRU5EIiwiRU5EIiwiRVZFTlRfVFlQRVMiLCJidWlsZFNwZWVjaFJlc3VsdCIsInRyYW5zY3JpcHQiLCJjb25maWRlbmNlIiwiaXNGaW5hbCIsInJlc3VsdCIsInJlc3VsdHMiLCJ0eXBlIiwiQ29nbml0aXZlU2VydmljZXNTcGVlY2hSZWNvZ25pdGlvbiIsIl9sYW5nIiwicmVhZHlTdGF0ZSIsIm9uYXVkaW9zdGFydCIsIm9uYXVkaW9lbmQiLCJvbmVuZCIsIm9uZXJyb3IiLCJvbm5vbWF0Y2giLCJvbnJlc3VsdCIsIm9uc291bmRzdGFydCIsIm9uc291bmRlbmQiLCJvbnNwZWVjaHN0YXJ0Iiwib25zcGVlY2hlbmQiLCJvbnN0YXJ0IiwiY3JlYXRlUmVjb2duaXplciIsInN1YnNjcmlwdGlvbktleU9yVG9rZW5GZXRjaCIsImxhbmciLCJuYXZpZ2F0b3IiLCJsYW5ndWFnZSIsIm1vZGUiLCJSZWNvZ25pdGlvbk1vZGUiLCJJbnRlcmFjdGl2ZSIsInBsYXRmb3JtIiwid2luZG93IiwidXNlckFnZW50IiwibmFtZSIsIm9zVmVyc2lvbiIsIm1hbnVmYWN0dXJlciIsIm1vZGVsIiwiZGV2aWNlVmVyc2lvbiIsImNvbmZpZyIsIlJlY29nbml6ZXJDb25maWciLCJTcGVlY2hDb25maWciLCJDb250ZXh0IiwiT1MiLCJEZXZpY2UiLCJTcGVlY2hSZXN1bHRGb3JtYXQiLCJEZXRhaWxlZCIsImF1dGgiLCJDb2duaXRpdmVUb2tlbkF1dGhlbnRpY2F0aW9uIiwiYXV0aEZldGNoRXZlbnRJRCIsIkNvZ25pdGl2ZVN1YnNjcmlwdGlvbktleUF1dGhlbnRpY2F0aW9uIiwiQ3JlYXRlUmVjb2duaXplciIsIm5leHRSZWFkeVN0YXRlIiwibGlmZWN5Y2xlRXZlbnRzIiwidHJhbnNpdGlvbiIsImV2ZW50TGlzdGVuZXIiLCJldmVudCIsImNvbnNvbGUiLCJsb2ciLCJfdHJhbnNpdFRvIiwiUmVjb2duaXRpb25TdGF0dXMiLCJSZXN1bHQiLCJTdWNjZXNzIiwibkJlc3QiLCJOQmVzdCIsIkRpc3BsYXkiLCJDb25maWRlbmNlIiwiZXJyb3IiLCJUZXh0IiwicmVjb2duaXplciIsIkF1ZGlvU291cmNlIiwiVHVybk9mZiIsIk5hbWUiLCJTdGF0dXMiLCJSZWNvZ25pdGlvbkNvbXBsZXRpb25TdGF0dXMiLCJfaGFuZGxlSHlwb3RoZXNpcyIsIl9oYW5kbGVEZXRhaWxlZFBocmFzZSIsIndhcm4iLCJlcnIiLCJsb2NhbFN0b3JhZ2UiLCJnZXRJdGVtIiwiUmVjb2duaXplIiwiaGFuZGxlUmVjb2duaXplIiwiYmluZCIsIkVycm9yIiwibmV4dEdyYW1tYXJzIiwibmV4dExhbmciLCJuZXh0Q29udGludW91cyIsIm5leHRJbnRlcmltUmVzdWx0cyIsIm5leHRNYXhBbHRlcm5hdGl2ZXMiLCJuZXh0U2VydmljZVVSSSJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7QUFBQTs7SUFBWUEsZTs7QUFDWjs7Ozs7Ozs7Ozs7O0FBRUEsSUFBTUMsU0FBUyxDQUFmO0FBQ0EsSUFBTUMsT0FBTyxDQUFiO0FBQ0EsSUFBTUMsUUFBUSxDQUFkO0FBQ0EsSUFBTUMsY0FBYyxDQUFwQjtBQUNBLElBQU1DLGNBQWMsQ0FBcEI7QUFDQSxJQUFNQyxlQUFlLENBQXJCO0FBQ0EsSUFBTUMsYUFBYSxDQUFuQjtBQUNBLElBQU1DLFlBQVksQ0FBbEI7QUFDQSxJQUFNQyxZQUFZLENBQWxCO0FBQ0EsSUFBTUMsTUFBTSxDQUFaOztBQUVBLElBQU1DLGNBQWMsQ0FDbEIsSUFEa0IsRUFFbEIsSUFGa0IsRUFHbEIsT0FIa0IsRUFJbEIsWUFKa0IsRUFLbEIsWUFMa0IsRUFNbEIsYUFOa0IsRUFPbEIsV0FQa0Is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cUJDLElBQXJCLENBQTBCLElBQTFCLENBQTFCO0FBQ0EsV0FBS3hCLFVBQUwsQ0FBZ0JsRSxLQUFoQjtBQUNEOzs7MkJBRU07QUFDTCxZQUFNLElBQUkyRixLQUFKLENBQVUsZUFBVixDQUFOO0FBQ0Q7Ozt3QkF0S2M7QUFBRTtBQUFTLEs7c0JBQ2JDLFksRUFBYztBQUN6QjtBQUNEOzs7d0JBRVU7QUFBRSxhQUFPLEtBQUszRSxLQUFaO0FBQW9CLEs7c0JBQ3hCNEUsUSxFQUFVO0FBQUUsV0FBSzVFLEtBQUwsR0FBYTRFLFFBQWI7QUFBd0I7Ozt3QkFFNUI7QUFBRSxhQUFPLEtBQVA7QUFBZSxLO3NCQUNuQkMsYyxFQUFnQjtBQUFFLFlBQU0sSUFBSUgsS0FBSixDQUFVLGVBQVYsQ0FBTjtBQUFtQzs7O3dCQUUvQztBQUFFLGFBQU8sSUFBUDtBQUFjLEs7c0JBQ2xCSSxrQixFQUFvQjtBQUNyQyxVQUFJLENBQUNBLGtCQUFMLEVBQXlCO0FBQ3ZCLGNBQU0sSUFBSUosS0FBSixDQUFVLGVBQVYsQ0FBTjtBQUNEO0FBQ0Y7Ozt3QkFFcUI7QUFBRSxhQUFPLENBQVA7QUFBVyxLO3NCQUNmSyxtQixFQUFxQjtBQUFFLFlBQU0sSUFBSUwsS0FBSixDQUFVLGVBQVYsQ0FBTjtBQUFtQzs7O3dCQUU3RDtBQUFFLGFBQU8sSUFBUDtBQUFjLEs7c0JBQ2xCTSxjLEVBQWdCO0FBQUUsWUFBTSxJQUFJTixLQUFKLENBQVUsZUFBVixDQUFOO0FBQW1DOzs7Ozs7a0JBbUp2RDNFLGtDIiwiZmlsZSI6IkNvZ25pdGl2ZVNlcnZpY2VzU3BlZWNoUmVjb2duaXRpb24uanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBDb2duaXRpdmVTcGVlY2ggZnJvbSAnbWljcm9zb2Z0LXNwZWVjaC1icm93c2VyLXNkayc7XG5pbXBvcnQgbWVtb2l6ZSBmcm9tICdtZW1vaXplLW9uZSc7XG5cbmNvbnN0IFVOSU5JVCA9IDA7XG5jb25zdCBJRExFID0gMTtcbmNvbnN0IFNUQVJUID0gMjtcbmNvbnN0IEFVRElPX1NUQVJUID0gMztcbmNvbnN0IFNPVU5EX1NUQVJUID0gNDtcbmNvbnN0IFNQRUVDSF9TVEFSVCA9IDU7XG5jb25zdCBTUEVFQ0hfRU5EID0gNjtcbmNvbnN0IFNPVU5EX0VORCA9IDc7XG5jb25zdCBBVURJT19FTkQgPSA4O1xuY29uc3QgRU5EID0gOTtcblxuY29uc3QgRVZFTlRfVFlQRVMgPSBbXG4gIG51bGwsXG4gIG51bGwsXG4gICdzdGFydCcsXG4gICdhdWRpb3N0YXJ0JyxcbiAgJ3NvdW5kc3RhcnQnLFxuICAnc3BlZWNoc3RhcnQnLFxuICAnc3BlZWNoZW5kJyxcbiAgJ3NvdW5kZW5kJyxcbiAgJ2F1ZGlvZW5kJyxcbiAgJ2VuZCdcbl07XG5cbmZ1bmN0aW9uIGJ1aWxkU3BlZWNoUmVzdWx0KHRyYW5zY3JpcHQsIGNvbmZpZGVuY2UsIGlzRmluYWwpIHtcbiAgY29uc3QgcmVzdWx0ID0gW3sgY29uZmlkZW5jZSwgdHJhbnNjcmlwdCB9XTtcblxuICByZXN1bHQuaXNGaW5hbCA9IGlzRmluYWw7XG5cbiAgcmV0dXJuIHsgcmVzdWx0czogW3Jlc3VsdF0sIHR5cGU6ICdyZXN1bHQnIH07XG59XG5cbmNsYXNzIENvZ25pdGl2ZVNlcnZpY2VzU3BlZWNoUmVjb2duaXRpb24ge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLl9sYW5nID0gJyc7XG5cbiAgICB0aGlzLnJlYWR5U3RhdGUgPSAwO1xuXG4gICAgdGhpcy5vbmF1ZGlvc3RhcnQgPSBudWxsO1xuICAgIHRoaXMub25hdWRpb2VuZCA9IG51bGw7XG4gICAgdGhpcy5vbmVuZCA9IG51bGw7XG4gICAgdGhpcy5vbmVycm9yID0gbnVsbDtcbiAgICB0aGlzLm9ubm9tYXRjaCA9IG51bGw7XG4gICAgdGhpcy5vbnJlc3VsdCA9IG51bGw7XG4gICAgdGhpcy5vbnNvdW5kc3RhcnQgPSBudWxsO1xuICAgIHRoaXMub25zb3VuZGVuZCA9IG51bGw7XG4gICAgdGhpcy5vbnNwZWVjaHN0YXJ0ID0gbnVsbDtcbiAgICB0aGlzLm9uc3BlZWNoZW5kID0gbnVsbDtcbiAgICB0aGlzLm9uc3RhcnQgPSBudWxsO1xuXG4gICAgdGhpcy5jcmVhdGVSZWNvZ25pemVyID0gbWVtb2l6ZSgoXG4gICAgICBzdWJzY3JpcHRpb25LZXlPclRva2VuRmV0Y2gsXG4gICAgICBsYW5nID0gbmF2aWdhdG9yLmxhbmd1YWdlLFxuICAgICAgbW9kZSA9IENvZ25pdGl2ZVNwZWVjaC5SZWNvZ25pdGlvbk1vZGUuSW50ZXJhY3RpdmVcbiAgICApID0+IHtcbiAgICAgIGNvbnN0IHBsYXRmb3JtID0gd2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQ7XG4gICAgICBjb25zdCBuYW1lID0gJ0Jyb3dzZXInO1xuICAgICAgY29uc3Qgb3NWZXJzaW9uID0gVkVSU0lPTjtcbiAgICAgIGNvbnN0IG1hbnVmYWN0dXJlciA9ICd3ZWItc3BlZWNoLWNvZ25pdGl2ZS1zZXJ2aWNlcyc7XG4gICAgICBjb25zdCBtb2RlbCA9ICd3ZWItc3BlZWNoLWNvZ25pdGl2ZS1zZXJ2aWNlcyc7XG4gICAgICBjb25zdCBkZXZpY2VWZXJzaW9uID0gVkVSU0lPTjtcblxuICAgICAgY29uc3QgY29uZmlnID0gbmV3IENvZ25pdGl2ZVNwZWVjaC5SZWNvZ25pemVyQ29uZmlnKFxuICAgICAgICBuZXcgQ29nbml0aXZlU3BlZWNoLlNwZWVjaENvbmZpZyhcbiAgICAgICAgICBuZXcgQ29nbml0aXZlU3BlZWNoLkNvbnRleHQoXG4gICAgICAgICAgICBuZXcgQ29nbml0aXZlU3BlZWNoLk9TKHBsYXRmb3JtLCBuYW1lLCBvc1ZlcnNpb24pLFxuICAgICAgICAgICAgbmV3IENvZ25pdGl2ZVNwZWVjaC5EZXZpY2UobWFudWZhY3R1cmVyLCBtb2RlbCwgZGV2aWNlVmVyc2lvbilcbiAgICAgICAgICApXG4gICAgICAgICksXG4gICAgICAgIG1vZGUsXG4gICAgICAgIGxhbmcsXG4gICAgICAgIENvZ25pdGl2ZVNwZWVjaC5TcGVlY2hSZXN1bHRGb3JtYXQuRGV0YWlsZWRcbiAgICAgICk7XG5cbiAgICAgIGxldCBhdXRoO1xuXG4gICAgICBpZiAodHlwZW9mIHN1YnNjcmlwdGlvbktleU9yVG9rZW5GZXRjaCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBhdXRoID0gbmV3IENvZ25pdGl2ZVNwZWVjaC5Db2duaXRpdmVUb2tlbkF1dGhlbnRpY2F0aW9uKFxuICAgICAgICAgIGFzeW5jIGF1dGhGZXRjaEV2ZW50SUQgPT4gYXdhaXQgc3Vic2NyaXB0aW9uS2V5T3JUb2tlbkZldGNoKGF1dGhGZXRjaEV2ZW50SUQsIGZhbHNlKSxcbiAgICAgICAgICBhc3luYyBhdXRoRmV0Y2hFdmVudElEID0+IGF3YWl0IHN1YnNjcmlwdGlvbktleU9yVG9rZW5GZXRjaChhdXRoRmV0Y2hFdmVudElELCB0cnVlKVxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXV0aCA9IG5ldyBDb2duaXRpdmVTcGVlY2guQ29nbml0aXZlU3Vic2NyaXB0aW9uS2V5QXV0aGVudGljYXRpb24oc3Vic2NyaXB0aW9uS2V5T3JUb2tlbkZldGNoKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIENvZ25pdGl2ZVNwZWVjaC5DcmVhdGVSZWNvZ25pemVyKGNvbmZpZywgYXV0aCk7XG4gICAgfSk7XG4gIH1cblxuICBnZXQgZ3JhbW1hcnMoKSB7IHJldHVybjsgfVxuICBzZXQgZ3JhbW1hcnMobmV4dEdyYW1tYXJzKSB7XG4gICAgLy8gdGhyb3cgbmV3IEVycm9yKCdub3Qgc3VwcG9ydGVkJyk7XG4gIH1cblxuICBnZXQgbGFuZygpIHsgcmV0dXJuIHRoaXMuX2xhbmc7IH1cbiAgc2V0IGxhbmcobmV4dExhbmcpIHsgdGhpcy5fbGFuZyA9IG5leHRMYW5nOyB9XG5cbiAgZ2V0IGNvbnRpbnVvdXMoKSB7IHJldHVybiBmYWxzZTsgfVxuICBzZXQgY29udGludW91cyhuZXh0Q29udGludW91cykgeyB0aHJvdyBuZXcgRXJyb3IoJ25vdCBzdXBwb3J0ZWQnKTsgfVxuXG4gIGdldCBpbnRlcmltUmVzdWx0cygpIHsgcmV0dXJuIHRydWU7IH1cbiAgc2V0IGludGVyaW1SZXN1bHRzKG5leHRJbnRlcmltUmVzdWx0cykge1xuICAgIGlmICghbmV4dEludGVyaW1SZXN1bHRzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vdCBzdXBwb3J0ZWQnKTtcbiAgICB9XG4gIH1cblxuICBnZXQgbWF4QWx0ZXJuYXRpdmVzKCkgeyByZXR1cm4gMTsgfVxuICBzZXQgbWF4QWx0ZXJuYXRpdmVzKG5leHRNYXhBbHRlcm5hdGl2ZXMpIHsgdGhyb3cgbmV3IEVycm9yKCdub3Qgc3VwcG9ydGVkJyk7IH1cblxuICBnZXQgc2VydmljZVVSSSgpIHsgcmV0dXJuIG51bGw7IH1cbiAgc2V0IHNlcnZpY2VVUkkobmV4dFNlcnZpY2VVUkkpIHsgdGhyb3cgbmV3IEVycm9yKCdub3Qgc3VwcG9ydGVkJyk7IH1cblxuICBfdHJhbnNpdFRvKG5leHRSZWFkeVN0YXRlKSB7XG4gICAgLy8gY29uc29sZS5sb2coYF90cmFuc2l0VG86IHJlYWR5U3RhdGUgPSAkeyB0aGlzLnJlYWR5U3RhdGUgfSwgbmV4dFJlYWR5U3RhdGUgPSAkeyBuZXh0UmVhZHlTdGF0ZSB9YCk7XG5cbiAgICBpZiAobmV4dFJlYWR5U3RhdGUgPiB0aGlzLnJlYWR5U3RhdGUpIHtcbiAgICAgIGNvbnN0IGxpZmVjeWNsZUV2ZW50cyA9IFtcbiAgICAgICAgbnVsbCxcbiAgICAgICAgbnVsbCxcbiAgICAgICAgdGhpcy5vbnN0YXJ0LFxuICAgICAgICB0aGlzLm9uYXVkaW9zdGFydCxcbiAgICAgICAgdGhpcy5vbnNvdW5kc3RhcnQsXG4gICAgICAgIHRoaXMub25zcGVlY2hzdGFydCxcbiAgICAgICAgdGhpcy5vbnNwZWVjaGVuZCxcbiAgICAgICAgdGhpcy5vbnNvdW5kZW5kLFxuICAgICAgICB0aGlzLm9uYXVkaW9lbmQsXG4gICAgICAgIHRoaXMub25lbmRcbiAgICAgIF07XG5cbiAgICAgIGlmIChcbiAgICAgICAgdGhpcy5yZWFkeVN0YXRlID09PSBBVURJT19TVEFSVFxuICAgICAgICAmJiBuZXh0UmVhZHlTdGF0ZSA+PSBBVURJT19FTkRcbiAgICAgICkge1xuICAgICAgICAvLyBJZiBzb3VuZHN0YXJ0LCBzcGVlY2hzdGFydCwgc3BlZWNoZW5kLCBhbmQgc291bmRlbmQgYXJlIG5vdCBmaXJlZCBhZnRlciBhdWRpb3N0YXJ0LFxuICAgICAgICAvLyB3ZSBjYW4gc2tpcCB0aGVtIGFuZCBqdXN0IGZpcmUgYXVkaW9lbmQgZGlyZWN0bHlcbiAgICAgICAgdGhpcy5yZWFkeVN0YXRlID0gU09VTkRfRU5EO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGxldCB0cmFuc2l0aW9uID0gdGhpcy5yZWFkeVN0YXRlICsgMTsgdHJhbnNpdGlvbiA8PSBuZXh0UmVhZHlTdGF0ZTsgdHJhbnNpdGlvbisrKSB7XG4gICAgICAgIGNvbnN0IGV2ZW50TGlzdGVuZXIgPSBsaWZlY3ljbGVFdmVudHNbdHJhbnNpdGlvbl07XG5cbiAgICAgICAgLy8gZXZlbnRMaXN0ZW5lciAmJiBjb25zb2xlLmxvZyhgRmlyaW5nIFwiJHsgRVZFTlRfVFlQRVNbdHJhbnNpdGlvbl0gfVwiYCk7XG4gICAgICAgIGV2ZW50TGlzdGVuZXIgJiYgZXZlbnRMaXN0ZW5lcih7IHR5cGU6IEVWRU5UX1RZUEVTW3RyYW5zaXRpb25dIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAobmV4dFJlYWR5U3RhdGUgPT09IEVORCkge1xuICAgICAgICB0aGlzLnJlYWR5U3RhdGUgPSBJRExFO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5yZWFkeVN0YXRlID0gbmV4dFJlYWR5U3RhdGU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgX2hhbmRsZURldGFpbGVkUGhyYXNlKGV2ZW50KSB7XG4gICAgY29uc29sZS5sb2coZXZlbnQpO1xuXG4gICAgdGhpcy5fdHJhbnNpdFRvKEFVRElPX0VORCk7XG5cbiAgICBpZiAoQ29nbml0aXZlU3BlZWNoLlJlY29nbml0aW9uU3RhdHVzW2V2ZW50LlJlc3VsdC5SZWNvZ25pdGlvblN0YXR1c10gPT09IENvZ25pdGl2ZVNwZWVjaC5SZWNvZ25pdGlvblN0YXR1cy5TdWNjZXNzKSB7XG4gICAgICBjb25zdCB7IE5CZXN0OiBuQmVzdCB9ID0gZXZlbnQuUmVzdWx0O1xuXG4gICAgICB0aGlzLm9ucmVzdWx0ICYmIHRoaXMub25yZXN1bHQoYnVpbGRTcGVlY2hSZXN1bHQoZXZlbnQuUmVzdWx0Lk5CZXN0WzBdLkRpc3BsYXksIGV2ZW50LlJlc3VsdC5OQmVzdFswXS5Db25maWRlbmNlLCB0cnVlKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMub25lcnJvciAmJiB0aGlzLm9uZXJyb3IoeyBlcnJvcjogZXZlbnQuUmVzdWx0LlJlY29nbml0aW9uU3RhdHVzLCB0eXBlOiAnZXJyb3InIH0pO1xuICAgIH1cbiAgfVxuXG4gIF9oYW5kbGVIeXBvdGhlc2lzKGV2ZW50KSB7XG4gICAgY29uc29sZS5sb2coZXZlbnQpO1xuXG4gICAgdGhpcy5vbnJlc3VsdCAmJiB0aGlzLm9ucmVzdWx0KGJ1aWxkU3BlZWNoUmVzdWx0KGV2ZW50LlJlc3VsdC5UZXh0LCAuNSwgZmFsc2UpKTtcbiAgfVxuXG4gIGFib3J0KCkge1xuICAgIGNvbnN0IHsgQXVkaW9Tb3VyY2UgfSA9IHRoaXMucmVjb2duaXplciB8fCB7fTtcblxuICAgIGNvbnNvbGUubG9nKGBBQk9SVDogJHsgQXVkaW9Tb3VyY2UgfWApO1xuXG4gICAgQXVkaW9Tb3VyY2UgJiYgQXVkaW9Tb3VyY2UuVHVybk9mZigpO1xuICB9XG5cbiAgaGFuZGxlUmVjb2duaXplKGV2ZW50KSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHsgTmFtZTogbmFtZSB9ID0gZXZlbnQ7XG5cbiAgICAgIGNvbnNvbGUubG9nKGBoYW5kbGVSZWNvZ25pemU6ICR7IG5hbWUgfWApO1xuXG4gICAgICBzd2l0Y2ggKG5hbWUpIHtcbiAgICAgIGNhc2UgJ0xpc3RlbmluZ1N0YXJ0ZWRFdmVudCc6XG4gICAgICAgIHRoaXMuX3RyYW5zaXRUbyhBVURJT19TVEFSVCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdSZWNvZ25pdGlvbkVuZGVkRXZlbnQnOlxuICAgICAgICBpZiAoZXZlbnQuU3RhdHVzICE9PSBDb2duaXRpdmVTcGVlY2guUmVjb2duaXRpb25Db21wbGV0aW9uU3RhdHVzLlN1Y2Nlc3MpIHtcbiAgICAgICAgICB0aGlzLl90cmFuc2l0VG8oQVVESU9fRU5EKTtcbiAgICAgICAgICB0aGlzLm9uZXJyb3IgJiYgdGhpcy5vbmVycm9yKHsgZXJyb3I6IENvZ25pdGl2ZVNwZWVjaC5SZWNvZ25pdGlvbkNvbXBsZXRpb25TdGF0dXNbZXZlbnQuU3RhdHVzXSwgdHlwZTogJ2Vycm9yJyB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX3RyYW5zaXRUbyhFTkQpO1xuXG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdSZWNvZ25pdGlvblN0YXJ0ZWRFdmVudCc6XG4gICAgICAgIHRoaXMuX3RyYW5zaXRUbyhTUEVFQ0hfU1RBUlQpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnUmVjb2duaXRpb25UcmlnZ2VyZWRFdmVudCc6XG4gICAgICAgIHRoaXMuX3RyYW5zaXRUbyhTVEFSVCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdTcGVlY2hFbmREZXRlY3RlZEV2ZW50JzpcbiAgICAgICAgdGhpcy5fdHJhbnNpdFRvKFNQRUVDSF9FTkQpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnU3BlZWNoU3RhcnREZXRlY3RlZEV2ZW50JzpcbiAgICAgICAgdGhpcy5fdHJhbnNpdFRvKFNQRUVDSF9TVEFSVCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdTcGVlY2hIeXBvdGhlc2lzRXZlbnQnOlxuICAgICAgICB0aGlzLl9oYW5kbGVIeXBvdGhlc2lzKGV2ZW50KTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ1NwZWVjaERldGFpbGVkUGhyYXNlRXZlbnQnOlxuICAgICAgICB0aGlzLl9oYW5kbGVEZXRhaWxlZFBocmFzZShldmVudCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdDb25uZWN0aW5nVG9TZXJ2aWNlRXZlbnQnOlxuICAgICAgY2FzZSAnU3BlZWNoU2ltcGxlUGhyYXNlRXZlbnQnOlxuICAgICAgICBicmVhaztcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgY29uc29sZS53YXJuKGBVbmV4cGVjdGVkIGV2ZW50IFxcXCIkeyBuYW1lIH1cXFwiIGZyb20gQ29nbml0aXZlIFNlcnZpY2VzLCBwbGVhc2UgZmlsZSBhIGJ1ZyB0byBodHRwczovL2dpdGh1Yi5jb20vY29tcHVsaW0vd2ViLXNwZWVjaC1jb2duaXRpdmUtc2VydmljZXNgKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAvLyBDb2duaXRpdmUgU2VydmljZXMgd2lsbCBoaWRlIGFsbCBleGNlcHRpb25zIHRocm93biBpbiB0aGUgZXZlbnQgbGlzdGVuZXJcbiAgICAgIC8vIFdlIG5lZWQgdG8gc2hvdyBpdCBvdGhlcndpc2Ugd2hlbiBleGNlcHRpb24gaGFwcGVuLCB3ZSB3aWxsIG5vdCBrbm93IHdoYXQncyBnb2luZyBvblxuICAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgfVxuXG4gIHN0YXJ0KCkge1xuICAgIHRoaXMucmVjb2duaXplciA9IHRoaXMuY3JlYXRlUmVjb2duaXplcihcbiAgICAgIHdpbmRvdy5sb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnU1BFRUNIX0tFWScpLFxuICAgICAgdGhpcy5sYW5nXG4gICAgKTtcblxuICAgIHRoaXMucmVjb2duaXplci5SZWNvZ25pemUodGhpcy5oYW5kbGVSZWNvZ25pemUuYmluZCh0aGlzKSk7XG4gICAgdGhpcy5fdHJhbnNpdFRvKFNUQVJUKTtcbiAgfVxuXG4gIHN0b3AoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdub3Qgc3VwcG9ydGVkJyk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQ29nbml0aXZlU2VydmljZXNTcGVlY2hSZWNvZ25pdGlvblxuIl19
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9Db2duaXRpdmVTZXJ2aWNlc1NwZWVjaFJlY29nbml0aW9uLmpzIl0sIm5hbWVzIjpbIkNvZ25pdGl2ZVNwZWVjaCIsIlVOSU5JVCIsIklETEUiLCJTVEFSVCIsIkFVRElPX1NUQVJUIiwiU09VTkRfU1RBUlQiLCJTUEVFQ0hfU1RBUlQiLCJTUEVFQ0hfRU5EIiwiU09VTkRfRU5EIiwiQVVESU9fRU5EIiwiRU5EIiwiRVZFTlRfVFlQRVMiLCJidWlsZFNwZWVjaFJlc3VsdCIsInRyYW5zY3JpcHQiLCJjb25maWRlbmNlIiwiaXNGaW5hbCIsInJlc3VsdCIsInJlc3VsdHMiLCJ0eXBlIiwiQ29nbml0aXZlU2VydmljZXNTcGVlY2hSZWNvZ25pdGlvbiIsIl9sYW5nIiwicmVhZHlTdGF0ZSIsIm9uYXVkaW9zdGFydCIsIm9uYXVkaW9lbmQiLCJvbmVuZCIsIm9uZXJyb3IiLCJvbm5vbWF0Y2giLCJvbnJlc3VsdCIsIm9uc291bmRzdGFydCIsIm9uc291bmRlbmQiLCJvbnNwZWVjaHN0YXJ0Iiwib25zcGVlY2hlbmQiLCJvbnN0YXJ0IiwiY3JlYXRlUmVjb2duaXplciIsInN1YnNjcmlwdGlvbktleU9yVG9rZW5GZXRjaCIsImxhbmciLCJuYXZpZ2F0b3IiLCJsYW5ndWFnZSIsIm1vZGUiLCJSZWNvZ25pdGlvbk1vZGUiLCJJbnRlcmFjdGl2ZSIsInBsYXRmb3JtIiwid2luZG93IiwidXNlckFnZW50IiwibmFtZSIsIm9zVmVyc2lvbiIsIm1hbnVmYWN0dXJlciIsIm1vZGVsIiwiZGV2aWNlVmVyc2lvbiIsImNvbmZpZyIsIlJlY29nbml6ZXJDb25maWciLCJTcGVlY2hDb25maWciLCJDb250ZXh0IiwiT1MiLCJEZXZpY2UiLCJTcGVlY2hSZXN1bHRGb3JtYXQiLCJEZXRhaWxlZCIsImF1dGgiLCJDb2duaXRpdmVUb2tlbkF1dGhlbnRpY2F0aW9uIiwiYXV0aEZldGNoRXZlbnRJRCIsIkNvZ25pdGl2ZVN1YnNjcmlwdGlvbktleUF1dGhlbnRpY2F0aW9uIiwiQ3JlYXRlUmVjb2duaXplciIsInJlY29nbml6ZXIiLCJBdWRpb1NvdXJjZSIsIlR1cm5PZmYiLCJfYWJvcnRlZCIsImV2ZW50IiwibGlzdGVuZXIiLCJjYWxsIiwiRXJyb3IiLCJsb2NhbFN0b3JhZ2UiLCJnZXRJdGVtIiwidG9Qcm9taXNlIiwiZXZlbnRMaXN0ZW5lciIsInByb21pc2VzIiwiUmVjb2duaXplIiwicmVjb2duaXRpb25UcmlnZ2VyZWQiLCJlcnJvciIsIlByb21pc2UiLCJyYWNlIiwibGlzdGVuaW5nU3RhcnRlZCIsInJlY29nbml0aW9uRW5kZWQiLCJOYW1lIiwiU3RhdHVzIiwiUmVjb2duaXRpb25Db21wbGV0aW9uU3RhdHVzIiwiQXVkaW9Tb3VyY2VFcnJvciIsImVtaXQiLCJjb25uZWN0aW5nVG9TZXJ2aWNlIiwicmVjb2duaXRpb25TdGFydGVkIiwiQ29ubmVjdEVycm9yIiwiZ290Rmlyc3RIeXBvdGhlc2lzIiwiZ2V0U3BlZWNoSHlwb3RoZXNpc1Byb21pc2UiLCJzcGVlY2hFbmREZXRlY3RlZCIsInNwZWVjaEh5cG90aGVzaXMiLCJSZXN1bHQiLCJUZXh0Iiwic3BlZWNoRGV0YWlsZWRQaHJhc2UiLCJyZWNvZ25pdGlvblJlc3VsdCIsIlJlY29nbml0aW9uU3RhdHVzIiwiU3VjY2VzcyIsIk5CZXN0IiwiRGlzcGxheSIsIkNvbmZpZGVuY2UiLCJOb01hdGNoIiwiSW5pdGlhbFNpbGVuY2VUaW1lb3V0IiwibmV4dEdyYW1tYXJzIiwibmV4dExhbmciLCJuZXh0Q29udGludW91cyIsIm5leHRJbnRlcmltUmVzdWx0cyIsIm5leHRNYXhBbHRlcm5hdGl2ZXMiLCJuZXh0U2VydmljZVVSSSIsImV2ZW50cyIsIkNvbm5lY3RpbmdUb1NlcnZpY2VFdmVudCIsIkV2ZW50QXNQcm9taXNlIiwiTGlzdGVuaW5nU3RhcnRlZEV2ZW50IiwiUmVjb2duaXRpb25FbmRlZEV2ZW50IiwiUmVjb2duaXRpb25TdGFydGVkRXZlbnQiLCJSZWNvZ25pdGlvblRyaWdnZXJlZEV2ZW50IiwiU3BlZWNoRGV0YWlsZWRQaHJhc2VFdmVudCIsIlNwZWVjaEVuZERldGVjdGVkRXZlbnQiLCJTcGVlY2hIeXBvdGhlc2lzRXZlbnQiLCJTcGVlY2hTaW1wbGVQaHJhc2VFdmVudCIsIlNwZWVjaFN0YXJ0RGV0ZWN0ZWRFdmVudCIsInVwY29taW5nIiwic3BlZWNoU2ltcGxlUGhyYXNlIiwic3BlZWNoU3RhcnREZXRlY3RlZCIsImV2ZW50QXNQcm9taXNlIiwiY29uc29sZSIsImxvZyIsIndhcm4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFBQTs7SUFBWUEsZTs7QUFDWjs7OztBQUNBOzs7Ozs7Ozs7Ozs7OztBQUVBLElBQU1DLFNBQVMsQ0FBZjtBQUNBLElBQU1DLE9BQU8sQ0FBYjtBQUNBLElBQU1DLFFBQVEsQ0FBZDtBQUNBLElBQU1DLGNBQWMsQ0FBcEI7QUFDQSxJQUFNQyxjQUFjLENBQXBCO0FBQ0EsSUFBTUMsZUFBZSxDQUFyQjtBQUNBLElBQU1DLGFBQWEsQ0FBbkI7QUFDQSxJQUFNQyxZQUFZLENBQWxCO0FBQ0EsSUFBTUMsWUFBWSxDQUFsQjtBQUNBLElBQU1DLE1BQU0sQ0FBWjs7QUFFQSxJQUFNQyxjQUFjLENBQ2xCLElBRGtCLEVBRWxCLElBRmtCLEVBR2xCLE9BSGtCLEVBSWxCLFlBSmtCLEVBS2xCLFlBTGtCLEVBTWxCLGFBTmtCLEVBT2xCLFdBUGtCLEVBUWxCLFVBUmtCLEVBU2xCLFVBVGtCLEVBVWxCLEtBVmtCLENBQXBCOztBQWFBLFNBQVNDLGlCQUFULENBQTJCQyxVQUEzQixFQUF1Q0MsVUFBdkMsRUFBbURDLE9BQW5ELEVBQTREO0FBQzFELE1BQU1DLFNBQVMsQ0FBQyxFQUFFRixzQkFBRixFQUFjRCxzQkFBZCxFQUFELENBQWY7O0FBRUFHLFNBQU9ELE9BQVAsR0FBaUJBLE9BQWpCOztBQUVBLFNBQU8sRUFBRUUsU0FBUyxDQUFDRCxNQUFELENBQVgsRUFBcUJFLE1BQU0sUUFBM0IsRUFBUDtBQUNEOztJQUVLQyxrQztBQUNKLGdEQUFjO0FBQUE7O0FBQUE7O0FBQ1os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LHVCQUFQLENBQStCRSxRQUEvQixFQVRmO0FBVUxFLHlCQUFxQmQsT0FBT1csd0JBQVAsQ0FBZ0NDLFFBQWhDLEVBVmhCO0FBV0xsRCxtQkFBZSw4QkFBUztBQUFBLFVBQ1I3QixJQURRLEdBQ0NzQixLQURELENBQ2RnQixJQURjOztBQUV0QixVQUFNNEMsaUJBQWlCZixPQUFPbkUsSUFBUCxDQUF2Qjs7QUFFQW1GLGNBQVFDLEdBQVIsZUFBeUJwRixJQUF6Qjs7QUFFQSxVQUFJa0YsY0FBSixFQUFvQjtBQUNsQkEsdUJBQWVyRCxhQUFmLENBQTZCTCxJQUE3QixDQUFrQyxJQUFsQyxFQUF3Q0YsS0FBeEM7QUFDRCxPQUZELE1BRU87QUFDTDZELGdCQUFRRSxJQUFSLHdCQUFvQ3JGLElBQXBDO0FBQ0Q7QUFDRjtBQXRCSSxHQUFQO0FBd0JEOztrQkFFY3pCLGtDIiwiZmlsZSI6IkNvZ25pdGl2ZVNlcnZpY2VzU3BlZWNoUmVjb2duaXRpb24uanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBDb2duaXRpdmVTcGVlY2ggZnJvbSAnbWljcm9zb2Z0LXNwZWVjaC1icm93c2VyLXNkayc7XG5pbXBvcnQgRXZlbnRBc1Byb21pc2UgZnJvbSAnZXZlbnQtYXMtcHJvbWlzZSc7XG5pbXBvcnQgbWVtb2l6ZSBmcm9tICdtZW1vaXplLW9uZSc7XG5cbmNvbnN0IFVOSU5JVCA9IDA7XG5jb25zdCBJRExFID0gMTtcbmNvbnN0IFNUQVJUID0gMjtcbmNvbnN0IEFVRElPX1NUQVJUID0gMztcbmNvbnN0IFNPVU5EX1NUQVJUID0gNDtcbmNvbnN0IFNQRUVDSF9TVEFSVCA9IDU7XG5jb25zdCBTUEVFQ0hfRU5EID0gNjtcbmNvbnN0IFNPVU5EX0VORCA9IDc7XG5jb25zdCBBVURJT19FTkQgPSA4O1xuY29uc3QgRU5EID0gOTtcblxuY29uc3QgRVZFTlRfVFlQRVMgPSBbXG4gIG51bGwsXG4gIG51bGwsXG4gICdzdGFydCcsXG4gICdhdWRpb3N0YXJ0JyxcbiAgJ3NvdW5kc3RhcnQnLFxuICAnc3BlZWNoc3RhcnQnLFxuICAnc3BlZWNoZW5kJyxcbiAgJ3NvdW5kZW5kJyxcbiAgJ2F1ZGlvZW5kJyxcbiAgJ2VuZCdcbl07XG5cbmZ1bmN0aW9uIGJ1aWxkU3BlZWNoUmVzdWx0KHRyYW5zY3JpcHQsIGNvbmZpZGVuY2UsIGlzRmluYWwpIHtcbiAgY29uc3QgcmVzdWx0ID0gW3sgY29uZmlkZW5jZSwgdHJhbnNjcmlwdCB9XTtcblxuICByZXN1bHQuaXNGaW5hbCA9IGlzRmluYWw7XG5cbiAgcmV0dXJuIHsgcmVzdWx0czogW3Jlc3VsdF0sIHR5cGU6ICdyZXN1bHQnIH07XG59XG5cbmNsYXNzIENvZ25pdGl2ZVNlcnZpY2VzU3BlZWNoUmVjb2duaXRpb24ge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLl9sYW5nID0gJyc7XG5cbiAgICB0aGlzLnJlYWR5U3RhdGUgPSAwO1xuXG4gICAgdGhpcy5vbmF1ZGlvc3RhcnQgPSBudWxsO1xuICAgIHRoaXMub25hdWRpb2VuZCA9IG51bGw7XG4gICAgdGhpcy5vbmVuZCA9IG51bGw7XG4gICAgdGhpcy5vbmVycm9yID0gbnVsbDtcbiAgICB0aGlzLm9ubm9tYXRjaCA9IG51bGw7XG4gICAgdGhpcy5vbnJlc3VsdCA9IG51bGw7XG4gICAgdGhpcy5vbnNvdW5kc3RhcnQgPSBudWxsO1xuICAgIHRoaXMub25zb3VuZGVuZCA9IG51bGw7XG4gICAgdGhpcy5vbnNwZWVjaHN0YXJ0ID0gbnVsbDtcbiAgICB0aGlzLm9uc3BlZWNoZW5kID0gbnVsbDtcbiAgICB0aGlzLm9uc3RhcnQgPSBudWxsO1xuXG4gICAgdGhpcy5jcmVhdGVSZWNvZ25pemVyID0gbWVtb2l6ZSgoXG4gICAgICBzdWJzY3JpcHRpb25LZXlPclRva2VuRmV0Y2gsXG4gICAgICBsYW5nID0gbmF2aWdhdG9yLmxhbmd1YWdlLFxuICAgICAgbW9kZSA9IENvZ25pdGl2ZVNwZWVjaC5SZWNvZ25pdGlvbk1vZGUuSW50ZXJhY3RpdmVcbiAgICApID0+IHtcbiAgICAgIGNvbnN0IHBsYXRmb3JtID0gd2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQ7XG4gICAgICBjb25zdCBuYW1lID0gJ0Jyb3dzZXInO1xuICAgICAgY29uc3Qgb3NWZXJzaW9uID0gVkVSU0lPTjtcbiAgICAgIGNvbnN0IG1hbnVmYWN0dXJlciA9ICd3ZWItc3BlZWNoLWNvZ25pdGl2ZS1zZXJ2aWNlcyc7XG4gICAgICBjb25zdCBtb2RlbCA9ICd3ZWItc3BlZWNoLWNvZ25pdGl2ZS1zZXJ2aWNlcyc7XG4gICAgICBjb25zdCBkZXZpY2VWZXJzaW9uID0gVkVSU0lPTjtcblxuICAgICAgY29uc3QgY29uZmlnID0gbmV3IENvZ25pdGl2ZVNwZWVjaC5SZWNvZ25pemVyQ29uZmlnKFxuICAgICAgICBuZXcgQ29nbml0aXZlU3BlZWNoLlNwZWVjaENvbmZpZyhcbiAgICAgICAgICBuZXcgQ29nbml0aXZlU3BlZWNoLkNvbnRleHQoXG4gICAgICAgICAgICBuZXcgQ29nbml0aXZlU3BlZWNoLk9TKHBsYXRmb3JtLCBuYW1lLCBvc1ZlcnNpb24pLFxuICAgICAgICAgICAgbmV3IENvZ25pdGl2ZVNwZWVjaC5EZXZpY2UobWFudWZhY3R1cmVyLCBtb2RlbCwgZGV2aWNlVmVyc2lvbilcbiAgICAgICAgICApXG4gICAgICAgICksXG4gICAgICAgIG1vZGUsXG4gICAgICAgIGxhbmcsXG4gICAgICAgIENvZ25pdGl2ZVNwZWVjaC5TcGVlY2hSZXN1bHRGb3JtYXQuRGV0YWlsZWRcbiAgICAgICk7XG5cbiAgICAgIGxldCBhdXRoO1xuXG4gICAgICBpZiAodHlwZW9mIHN1YnNjcmlwdGlvbktleU9yVG9rZW5GZXRjaCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBhdXRoID0gbmV3IENvZ25pdGl2ZVNwZWVjaC5Db2duaXRpdmVUb2tlbkF1dGhlbnRpY2F0aW9uKFxuICAgICAgICAgIGFzeW5jIGF1dGhGZXRjaEV2ZW50SUQgPT4gYXdhaXQgc3Vic2NyaXB0aW9uS2V5T3JUb2tlbkZldGNoKGF1dGhGZXRjaEV2ZW50SUQsIGZhbHNlKSxcbiAgICAgICAgICBhc3luYyBhdXRoRmV0Y2hFdmVudElEID0+IGF3YWl0IHN1YnNjcmlwdGlvbktleU9yVG9rZW5GZXRjaChhdXRoRmV0Y2hFdmVudElELCB0cnVlKVxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXV0aCA9IG5ldyBDb2duaXRpdmVTcGVlY2guQ29nbml0aXZlU3Vic2NyaXB0aW9uS2V5QXV0aGVudGljYXRpb24oc3Vic2NyaXB0aW9uS2V5T3JUb2tlbkZldGNoKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIENvZ25pdGl2ZVNwZWVjaC5DcmVhdGVSZWNvZ25pemVyKGNvbmZpZywgYXV0aCk7XG4gICAgfSk7XG4gIH1cblxuICBnZXQgZ3JhbW1hcnMoKSB7IHJldHVybjsgfVxuICBzZXQgZ3JhbW1hcnMobmV4dEdyYW1tYXJzKSB7XG4gICAgLy8gdGhyb3cgbmV3IEVycm9yKCdub3Qgc3VwcG9ydGVkJyk7XG4gIH1cblxuICBnZXQgbGFuZygpIHsgcmV0dXJuIHRoaXMuX2xhbmc7IH1cbiAgc2V0IGxhbmcobmV4dExhbmcpIHsgdGhpcy5fbGFuZyA9IG5leHRMYW5nOyB9XG5cbiAgZ2V0IGNvbnRpbnVvdXMoKSB7IHJldHVybiBmYWxzZTsgfVxuICBzZXQgY29udGludW91cyhuZXh0Q29udGludW91cykgeyB0aHJvdyBuZXcgRXJyb3IoJ25vdCBzdXBwb3J0ZWQnKTsgfVxuXG4gIGdldCBpbnRlcmltUmVzdWx0cygpIHsgcmV0dXJuIHRydWU7IH1cbiAgc2V0IGludGVyaW1SZXN1bHRzKG5leHRJbnRlcmltUmVzdWx0cykge1xuICAgIGlmICghbmV4dEludGVyaW1SZXN1bHRzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vdCBzdXBwb3J0ZWQnKTtcbiAgICB9XG4gIH1cblxuICBnZXQgbWF4QWx0ZXJuYXRpdmVzKCkgeyByZXR1cm4gMTsgfVxuICBzZXQgbWF4QWx0ZXJuYXRpdmVzKG5leHRNYXhBbHRlcm5hdGl2ZXMpIHsgdGhyb3cgbmV3IEVycm9yKCdub3Qgc3VwcG9ydGVkJyk7IH1cblxuICBnZXQgc2VydmljZVVSSSgpIHsgcmV0dXJuIG51bGw7IH1cbiAgc2V0IHNlcnZpY2VVUkkobmV4dFNlcnZpY2VVUkkpIHsgdGhyb3cgbmV3IEVycm9yKCdub3Qgc3VwcG9ydGVkJyk7IH1cblxuICBhYm9ydCgpIHtcbiAgICAvLyBUT0RPOiBTaG91bGQgcmVkZXNpZ24gaG93IHRvIHN0b3AgYSByZWNvZ25pdGlvbiBzZXNzaW9uXG4gICAgLy8gICAgICAgQWZ0ZXIgYWJvcnQgaXMgY2FsbGVkLCB3ZSBzaG91bGQgbm90IHNhdyBpdCBpcyBhIFwic3VjY2Vzc1wiLCBcInNpbGVudFwiLCBvciBcIm5vIG1hdGNoXCJcbiAgICBjb25zdCB7IEF1ZGlvU291cmNlIH0gPSB0aGlzLnJlY29nbml6ZXIgfHwge307XG5cbiAgICBBdWRpb1NvdXJjZSAmJiBBdWRpb1NvdXJjZS5UdXJuT2ZmKCk7XG5cbiAgICB0aGlzLl9hYm9ydGVkID0gdHJ1ZTtcbiAgfVxuXG4gIGVtaXQobmFtZSwgZXZlbnQpIHtcbiAgICBjb25zdCBsaXN0ZW5lciA9IHRoaXNbYG9uJHsgbmFtZSB9YF07XG5cbiAgICBsaXN0ZW5lciAmJiBsaXN0ZW5lci5jYWxsKHRoaXMsIHsgLi4uZXZlbnQsIHR5cGU6IG5hbWUgfSk7XG4gIH1cblxuICBzdG9wKCkge1xuICAgIHRocm93IG5ldyBFcnJvcignbm90IHN1cHBvcnRlZCcpO1xuICB9XG5cbiAgYXN5bmMgc3RhcnQoKSB7XG4gICAgY29uc3QgcmVjb2duaXplciA9IHRoaXMucmVjb2duaXplciA9IHRoaXMuY3JlYXRlUmVjb2duaXplcihcbiAgICAgIHdpbmRvdy5sb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnU1BFRUNIX0tFWScpLFxuICAgICAgdGhpcy5sYW5nXG4gICAgKTtcblxuICAgIGNvbnN0IHsgZXZlbnRMaXN0ZW5lciwgLi4ucHJvbWlzZXMgfSA9IHRvUHJvbWlzZSgpO1xuXG4gICAgcmVjb2duaXplci5SZWNvZ25pemUoZXZlbnRMaXN0ZW5lcik7XG4gICAgdGhpcy5fYWJvcnRlZCA9IGZhbHNlO1xuXG4gICAgYXdhaXQgcHJvbWlzZXMucmVjb2duaXRpb25UcmlnZ2VyZWQ7XG5cbiAgICBsZXQgZXJyb3I7XG5cbiAgICBjb25zdCBsaXN0ZW5pbmdTdGFydGVkID0gYXdhaXQgUHJvbWlzZS5yYWNlKFtcbiAgICAgIHByb21pc2VzLmxpc3RlbmluZ1N0YXJ0ZWQsXG4gICAgICBwcm9taXNlcy5yZWNvZ25pdGlvbkVuZGVkXG4gICAgXSk7XG5cbiAgICBpZiAobGlzdGVuaW5nU3RhcnRlZC5OYW1lID09PSAnUmVjb2duaXRpb25FbmRlZEV2ZW50Jykge1xuICAgICAgLy8gUG9zc2libHkgbm90IGF1dGhvcml6ZWQgdG8gdXNlIG1pY3JvcGhvbmVcbiAgICAgIGlmIChsaXN0ZW5pbmdTdGFydGVkLlN0YXR1cyA9PT0gQ29nbml0aXZlU3BlZWNoLlJlY29nbml0aW9uQ29tcGxldGlvblN0YXR1cy5BdWRpb1NvdXJjZUVycm9yKSB7XG4gICAgICAgIGVycm9yID0gJ25vdC1hbGxvd2VkJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVycm9yID0gQ29nbml0aXZlU3BlZWNoLlJlY29nbml0aW9uQ29tcGxldGlvblN0YXR1c1tsaXN0ZW5pbmdTdGFydGVkLlN0YXR1c107XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZW1pdCgnc3RhcnQnKTtcblxuICAgICAgYXdhaXQgcHJvbWlzZXMuY29ubmVjdGluZ1RvU2VydmljZTtcblxuICAgICAgY29uc3QgcmVjb2duaXRpb25TdGFydGVkID0gYXdhaXQgUHJvbWlzZS5yYWNlKFtcbiAgICAgICAgcHJvbWlzZXMucmVjb2duaXRpb25TdGFydGVkLFxuICAgICAgICBwcm9taXNlcy5yZWNvZ25pdGlvbkVuZGVkXG4gICAgICBdKTtcblxuICAgICAgdGhpcy5lbWl0KCdhdWRpb3N0YXJ0Jyk7XG5cbiAgICAgIGlmIChyZWNvZ25pdGlvblN0YXJ0ZWQuTmFtZSA9PT0gJ1JlY29nbml0aW9uRW5kZWRFdmVudCcpIHtcbiAgICAgICAgLy8gUG9zc2libHkgbmV0d29yayBlcnJvclxuICAgICAgICBpZiAocmVjb2duaXRpb25TdGFydGVkLlN0YXR1cyA9PT0gQ29nbml0aXZlU3BlZWNoLlJlY29nbml0aW9uQ29tcGxldGlvblN0YXR1cy5Db25uZWN0RXJyb3IpIHtcbiAgICAgICAgICBlcnJvciA9ICduZXR3b3JrJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBlcnJvciA9IENvZ25pdGl2ZVNwZWVjaC5SZWNvZ25pdGlvbkNvbXBsZXRpb25TdGF0dXNbcmVjb2duaXRpb25TdGFydGVkLlN0YXR1c107XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxldCBnb3RGaXJzdEh5cG90aGVzaXM7XG5cbiAgICAgICAgZm9yICg7Oykge1xuICAgICAgICAgIGNvbnN0IHNwZWVjaEh5cG90aGVzaXMgPSBhd2FpdCBQcm9taXNlLnJhY2UoW1xuICAgICAgICAgICAgcHJvbWlzZXMuZ2V0U3BlZWNoSHlwb3RoZXNpc1Byb21pc2UoKSxcbiAgICAgICAgICAgIHByb21pc2VzLnNwZWVjaEVuZERldGVjdGVkXG4gICAgICAgICAgXSk7XG5cbiAgICAgICAgICBpZiAoc3BlZWNoSHlwb3RoZXNpcy5OYW1lID09PSAnU3BlZWNoRW5kRGV0ZWN0ZWRFdmVudCcpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICghZ290Rmlyc3RIeXBvdGhlc2lzKSB7XG4gICAgICAgICAgICBnb3RGaXJzdEh5cG90aGVzaXMgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5lbWl0KCdzb3VuZHN0YXJ0Jyk7XG4gICAgICAgICAgICB0aGlzLmVtaXQoJ3NwZWVjaHN0YXJ0Jyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGhpcy5lbWl0KCdyZXN1bHQnLCBidWlsZFNwZWVjaFJlc3VsdChzcGVlY2hIeXBvdGhlc2lzLlJlc3VsdC5UZXh0LCAuNSwgZmFsc2UpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChnb3RGaXJzdEh5cG90aGVzaXMpIHtcbiAgICAgICAgICB0aGlzLmVtaXQoJ3NwZWVjaGVuZCcpO1xuICAgICAgICAgIHRoaXMuZW1pdCgnc291bmRlbmQnKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB0aGlzLmVtaXQoJ2F1ZGlvZW5kJyk7XG5cbiAgICAgIGlmICh0aGlzLl9hYm9ydGVkKSB7XG4gICAgICAgIGVycm9yID0gJ2Fib3J0ZWQnO1xuXG4gICAgICAgIGF3YWl0IHByb21pc2VzLnJlY29nbml0aW9uRW5kZWQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBzcGVlY2hEZXRhaWxlZFBocmFzZSA9IGF3YWl0IFByb21pc2UucmFjZShbXG4gICAgICAgICAgcHJvbWlzZXMuc3BlZWNoRGV0YWlsZWRQaHJhc2UsXG4gICAgICAgICAgcHJvbWlzZXMucmVjb2duaXRpb25FbmRlZFxuICAgICAgICBdKTtcblxuICAgICAgICBpZiAoc3BlZWNoRGV0YWlsZWRQaHJhc2UuTmFtZSAhPT0gJ1JlY29nbml0aW9uRW5kZWRFdmVudCcpIHtcbiAgICAgICAgICBjb25zdCByZWNvZ25pdGlvblJlc3VsdCA9IENvZ25pdGl2ZVNwZWVjaC5SZWNvZ25pdGlvblN0YXR1c1tzcGVlY2hEZXRhaWxlZFBocmFzZS5SZXN1bHQuUmVjb2duaXRpb25TdGF0dXNdO1xuXG4gICAgICAgICAgaWYgKHJlY29nbml0aW9uUmVzdWx0ID09PSBDb2duaXRpdmVTcGVlY2guUmVjb2duaXRpb25TdGF0dXMuU3VjY2Vzcykge1xuICAgICAgICAgICAgdGhpcy5lbWl0KCdyZXN1bHQnLCBidWlsZFNwZWVjaFJlc3VsdChzcGVlY2hEZXRhaWxlZFBocmFzZS5SZXN1bHQuTkJlc3RbMF0uRGlzcGxheSwgc3BlZWNoRGV0YWlsZWRQaHJhc2UuUmVzdWx0Lk5CZXN0WzBdLkNvbmZpZGVuY2UsIHRydWUpKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHJlY29nbml0aW9uUmVzdWx0ICE9PSBDb2duaXRpdmVTcGVlY2guUmVjb2duaXRpb25TdGF0dXMuTm9NYXRjaCkge1xuICAgICAgICAgICAgLy8gUG9zc2libHkgc2lsZW50IG9yIG11dGVkXG4gICAgICAgICAgICBpZiAocmVjb2duaXRpb25SZXN1bHQgPT09IENvZ25pdGl2ZVNwZWVjaC5SZWNvZ25pdGlvblN0YXR1cy5Jbml0aWFsU2lsZW5jZVRpbWVvdXQpIHtcbiAgICAgICAgICAgICAgZXJyb3IgPSAnbm8tc3BlZWNoJztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGVycm9yID0gc3BlZWNoRGV0YWlsZWRQaHJhc2UuUmVzdWx0LlJlY29nbml0aW9uU3RhdHVzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGF3YWl0IHByb21pc2VzLnJlY29nbml0aW9uRW5kZWQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBlcnJvciAmJiB0aGlzLmVtaXQoJ2Vycm9yJywgeyBlcnJvciB9KTtcbiAgICB0aGlzLmVtaXQoJ2VuZCcpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHRvUHJvbWlzZSgpIHtcbiAgY29uc3QgZXZlbnRzID0ge1xuICAgIENvbm5lY3RpbmdUb1NlcnZpY2VFdmVudDogbmV3IEV2ZW50QXNQcm9taXNlKCksXG4gICAgTGlzdGVuaW5nU3RhcnRlZEV2ZW50OiBuZXcgRXZlbnRBc1Byb21pc2UoKSxcbiAgICBSZWNvZ25pdGlvbkVuZGVkRXZlbnQ6IG5ldyBFdmVudEFzUHJvbWlzZSgpLFxuICAgIFJlY29nbml0aW9uU3RhcnRlZEV2ZW50OiBuZXcgRXZlbnRBc1Byb21pc2UoKSxcbiAgICBSZWNvZ25pdGlvblRyaWdnZXJlZEV2ZW50OiBuZXcgRXZlbnRBc1Byb21pc2UoKSxcbiAgICBTcGVlY2hEZXRhaWxlZFBocmFzZUV2ZW50OiBuZXcgRXZlbnRBc1Byb21pc2UoKSxcbiAgICBTcGVlY2hFbmREZXRlY3RlZEV2ZW50OiBuZXcgRXZlbnRBc1Byb21pc2UoKSxcbiAgICBTcGVlY2hIeXBvdGhlc2lzRXZlbnQ6IG5ldyBFdmVudEFzUHJvbWlzZSgpLFxuICAgIFNwZWVjaFNpbXBsZVBocmFzZUV2ZW50OiBuZXcgRXZlbnRBc1Byb21pc2UoKSxcbiAgICBTcGVlY2hTdGFydERldGVjdGVkRXZlbnQ6IG5ldyBFdmVudEFzUHJvbWlzZSgpXG4gIH07XG5cbiAgcmV0dXJuIHtcbiAgICBjb25uZWN0aW5nVG9TZXJ2aWNlOiBldmVudHMuQ29ubmVjdGluZ1RvU2VydmljZUV2ZW50LnVwY29taW5nKCksXG4gICAgbGlzdGVuaW5nU3RhcnRlZDogZXZlbnRzLkxpc3RlbmluZ1N0YXJ0ZWRFdmVudC51cGNvbWluZygpLFxuICAgIHJlY29nbml0aW9uRW5kZWQ6IGV2ZW50cy5SZWNvZ25pdGlvbkVuZGVkRXZlbnQudXBjb21pbmcoKSxcbiAgICByZWNvZ25pdGlvblN0YXJ0ZWQ6IGV2ZW50cy5SZWNvZ25pdGlvblN0YXJ0ZWRFdmVudC51cGNvbWluZygpLFxuICAgIHJlY29nbml0aW9uVHJpZ2dlcmVkOiBldmVudHMuUmVjb2duaXRpb25UcmlnZ2VyZWRFdmVudC51cGNvbWluZygpLFxuICAgIHNwZWVjaERldGFpbGVkUGhyYXNlOiBldmVudHMuU3BlZWNoRGV0YWlsZWRQaHJhc2VFdmVudC51cGNvbWluZygpLFxuICAgIHNwZWVjaEVuZERldGVjdGVkOiBldmVudHMuU3BlZWNoRW5kRGV0ZWN0ZWRFdmVudC51cGNvbWluZygpLFxuICAgIGdldFNwZWVjaEh5cG90aGVzaXNQcm9taXNlOiAoKSA9PiBldmVudHMuU3BlZWNoSHlwb3RoZXNpc0V2ZW50LnVwY29taW5nKCksXG4gICAgc3BlZWNoU2ltcGxlUGhyYXNlOiBldmVudHMuU3BlZWNoU2ltcGxlUGhyYXNlRXZlbnQudXBjb21pbmcoKSxcbiAgICBzcGVlY2hTdGFydERldGVjdGVkOiBldmVudHMuU3BlZWNoU3RhcnREZXRlY3RlZEV2ZW50LnVwY29taW5nKCksXG4gICAgZXZlbnRMaXN0ZW5lcjogZXZlbnQgPT4ge1xuICAgICAgY29uc3QgeyBOYW1lOiBuYW1lIH0gPSBldmVudDtcbiAgICAgIGNvbnN0IGV2ZW50QXNQcm9taXNlID0gZXZlbnRzW25hbWVdO1xuXG4gICAgICBjb25zb2xlLmxvZyhgaGFuZGxpbmcgJHsgbmFtZSB9YCk7XG5cbiAgICAgIGlmIChldmVudEFzUHJvbWlzZSkge1xuICAgICAgICBldmVudEFzUHJvbWlzZS5ldmVudExpc3RlbmVyLmNhbGwobnVsbCwgZXZlbnQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS53YXJuKGBVbmV4cGVjdGVkIGV2ZW50IFxcXCIkeyBuYW1lIH1cXFwiIGZyb20gQ29nbml0aXZlIFNlcnZpY2VzLCBwbGVhc2UgZmlsZSBhIGJ1ZyB0byBodHRwczovL2dpdGh1Yi5jb20vY29tcHVsaW0vd2ViLXNwZWVjaC1jb2duaXRpdmUtc2VydmljZXNgKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG59XG5cbmV4cG9ydCBkZWZhdWx0IENvZ25pdGl2ZVNlcnZpY2VzU3BlZWNoUmVjb2duaXRpb25cbiJdfQ==
{
"name": "web-speech-cognitive-services",
"version": "0.0.1-master.869e22a",
"version": "0.0.1-master.da41f39",
"description": "",

@@ -31,8 +31,10 @@ "keywords": [],

"babel-plugin-version-transform": "^1.0.0",
"babel-polyfill": "^6.26.0",
"babel-preset-stage-3": "^6.24.1",
"classnames": "^2.2.6",
"event-as-promise": "^1.0.3",
"glamor": "^2.20.40",
"jest": "^22.4.4",
"lerna": "^2.11.0",
"microsoft-speech-browser-sdk": "0.0.12",
"microsoft-speech-browser-sdk": "^0.0.12",
"react": "^16.4.1",

@@ -39,0 +41,0 @@ "react-dictate-button": "^1.0.0",

@@ -7,2 +7,33 @@ # web-speech-cognitive-services

## Test matrix
Browsers are all latest as of 2018-06-28, except macOS was 10.13.1 (2017-10-31), instead of 10.13.5. But there should be no change on the matrix since Safari does not support Web Speech API.
Overall in point form:
* With Web Speech API only, web dev can enable speech recognition on most popular platforms, except iOS
* iOS: No browsers on iOS support Web Speech API
* Some platforms requires non-default browser
* With Cognitive Services Speech-to-Text, all popular platforms with their default browsers are supported
* iOS: Chrome and Edge does not support Cognitive Services because WebRTC is disabled
| Platform | OS | Browser | Cognitive Services (WebRTC) | Web Speech API |
| - | - | - | - | - |
| PC | Windows 10 (1803) | Chrome 67.0.3396.99 | Yes | Yes |
| PC | Windows 10 (1803) | Edge 42.17134.1.0 | Yes | No, `SpeechRecognition` not implemented |
| PC | Windows 10 (1803) | Firefox 61.0 | Yes | No, `SpeechRecognition` not implemented |
| MacBook Pro | macOS High Sierra 10.13.1 | Chrome 67.0.3396.99 | Yes | Yes |
| MacBook Pro | macOS High Sierra 10.13.1 | Safari 11.0.1 | Yes | No, `SpeechRecognition` not implemented |
| Apple iPhone X | iOS 11.4 | Chrome 67.0.3396.87 | No, `AudioSourceError` | No, `SpeechRecognition` not implemented |
| Apple iPhone X | iOS 11.4 | Edge 42.2.2.0 | No, `AudioSourceError` | No, `SpeechRecognition` not implemented |
| Apple iPhone X | iOS 11.4 | Safari | Yes | No, `SpeechRecognition` not implemented |
| Apple iPod (6th gen) | iOS 11.4 | Chrome 67.0.3396.87 | No, `AudioSourceError` | No, `SpeechRecognition` not implemented |
| Apple iPod (6th gen) | iOS 11.4 | Edge 42.2.2.0 | No, `AudioSourceError` | No, `SpeechRecognition` not implemented |
| Apple iPod (6th gen) | iOS 11.4 | Safari | No, `AudioSourceError` | No, `SpeechRecognition` not implemented |
| Google Pixel 2 | Android 8.1.0 | Chrome 67.0.3396.87 | Yes | Yes |
| Google Pixel 2 | Android 8.1.0 | Edge 42.0.0.2057 | Yes | Yes |
| Google Pixel 2 | Android 8.1.0 | Firefox 60.1.0 | Yes | Yes |
| Microsoft Lumia 950 | Windows 10 (1709) | Edge 40.15254.489.0 | No, `AudioSourceError` | No, `SpeechRecognition` not implemented |
| Microsoft Xbox One | Windows 10 (?) | Edge ? | No, `AudioSourceError` | No, `SpeechRecognition` not implemented |
## Event lifecycle mapping from Cognitive Services

@@ -24,35 +55,90 @@

* Happy path
1. `RecognitionTriggeredEvent`
2. `ListeningStartedEvent`
3. `ConnectingToServiceEvent`
4. `RecognitionStartedEvent`
5. `SpeechHypothesisEvent` (could be more than one)
6. `SpeechEndDetectedEvent`
7. `SpeechSimplePhraseEvent`
8. `RecognitionEndedEvent`
* Cognitive Services
1. `RecognitionTriggeredEvent`
2. `ListeningStartedEvent`
3. `ConnectingToServiceEvent`
4. `RecognitionStartedEvent`
5. `SpeechHypothesisEvent` (could be more than one)
6. `SpeechEndDetectedEvent`
7. `SpeechDetailedPhraseEvent`
8. `RecognitionEndedEvent`
* Web Speech API
1. `start`
2. `audiostart`
3. `soundstart`
4. `speechstart`
5. `result` (multiple times)
6. `speechend`
7. `soundend`
8. `audioend`
9. `result(results = [{ isFinal = true }])`
10. `end`
* Abort is called during recognition
* Cognitive Services
* Essentially muted the speech, that could still result in success, silent, or no match
* Web Speech API
1. `start`
2. `audiostart`
3. `soundstart` (optional)
4. `speechstart` (optional)
5. `result` (optional)
6. `speechend` (optional)
7. `soundend` (optional)
8. `audioend`
9. `error(error = 'aborted')`
10. `end`
* Network issues
1. `RecognitionTriggeredEvent`
2. `ListeningStartedEvent`
3. `ConnectingToServiceEvent`
4. `SpeechSimplePhraseEvent`
5. `RecognitionEndedEvent`
* Cognitive Services
1. `RecognitionTriggeredEvent`
2. `ListeningStartedEvent`
3. `ConnectingToServiceEvent`
5. `RecognitionEndedEvent(Result.RecognitionStatus = 'ConnectError')`
* Web Speech API
1. `start`
2. `audiostart`
3. `audioend`
4. `error(error = 'network')`
5. `end`
* Audio muted or volume too low
1. `RecognitionTriggeredEvent`
2. `ListeningStartedEvent`
3. `ConnectingToServiceEvent`
4. `RecognitionStartedEvent`
5. `SpeechEndDetectedEvent`
6. `SpeechSimplePhraseEvent(Result.RecognitionStatus = 'InitialSilenceTimeout')`
7. `RecognitionEndedEvent`
* Cognitive Services
1. `RecognitionTriggeredEvent`
2. `ListeningStartedEvent`
3. `ConnectingToServiceEvent`
4. `RecognitionStartedEvent`
5. `SpeechEndDetectedEvent`
6. `SpeechDetailedPhraseEvent(Result.RecognitionStatus = 'InitialSilenceTimeout')`
7. `RecognitionEndedEvent`
* Web Speech API
1. `start`
2. `audiostart`
3. `audioend`
4. `error(error = 'no-speech')`
5. `end`
* Failed to recognize speech (a.k.a. no match)
1. `RecognitionTriggeredEvent`
2. `ListeningStartedEvent`
3. `ConnectingToServiceEvent`
4. `RecognitionStartedEvent`
5. `SpeechHypothesisEvent` (could be more than one)
6. `SpeechEndDetectedEvent`
7. `SpeechSimplePhraseEvent(Result.RecognitionStatus = 'NoMatch')`
8. `RecognitionEndedEvent`
* User abort
* Essentially muted the speech, that could result in success, silent, or no match
* Cognitive Services
1. `RecognitionTriggeredEvent`
2. `ListeningStartedEvent`
3. `ConnectingToServiceEvent`
4. `RecognitionStartedEvent`
5. `SpeechHypothesisEvent` (could be more than one)
6. `SpeechEndDetectedEvent`
7. `SpeechDetailedPhraseEvent(Result.RecognitionStatus = 'NoMatch')`
8. `RecognitionEndedEvent`
* Web Speech API
1. `start`
2. `audiostart`
3. `soundstart`
4. `speechstart`
5. `result`
6. `speechend`
7. `soundend`
8. `audioend`
9. `end`
* Not authorized to use microphone
* Cognitive Services
1. `RecognitionTriggeredEvent`
2. `RecognitionEndedEvent(Result.RecognitionStatus = 'AudioSourceError')`
* Web Speech API
1. `error(error = 'not-allowed')`
2. `end`

@@ -59,0 +145,0 @@ # Contributions

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc