web-speech-cognitive-services
Advanced tools
Comparing version 0.0.1-master.869e22a to 0.0.1-master.da41f39
@@ -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", |
146
README.md
@@ -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 |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
50796
364
150
18
1