2019-03-27 17:43:00 -04:00
( function ( ) { function r ( e , n , t ) { function o ( i , f ) { if ( ! n [ i ] ) { if ( ! e [ i ] ) { var c = "function" == typeof require && require ; if ( ! f && c ) return c ( i , ! 0 ) ; if ( u ) return u ( i , ! 0 ) ; var a = new Error ( "Cannot find module '" + i + "'" ) ; throw a . code = "MODULE_NOT_FOUND" , a } var p = n [ i ] = { exports : { } } ; e [ i ] [ 0 ] . call ( p . exports , function ( r ) { var n = e [ i ] [ 1 ] [ r ] ; return o ( n || r ) } , p , p . exports , r , e , n , t ) } return n [ i ] . exports } for ( var u = "function" == typeof require && require , i = 0 ; i < t . length ; i ++ ) o ( t [ i ] ) ; return o } return r } ) ( ) ( { 1 : [ function ( require , module , exports ) {
/ *
* The MIT License ( MIT )
*
* Copyright ( c ) 2014 Patrick Gansterer < paroga @ paroga . com >
*
* Permission is hereby granted , free of charge , to any person obtaining a copy
* of this software and associated documentation files ( the "Software" ) , to deal
* in the Software without restriction , including without limitation the rights
* to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
* copies of the Software , and to permit persons to whom the Software is
* furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED "AS IS" , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE .
* /
( function ( global , undefined ) { "use strict" ;
var POW _2 _24 = Math . pow ( 2 , - 24 ) ,
POW _2 _32 = Math . pow ( 2 , 32 ) ,
POW _2 _53 = Math . pow ( 2 , 53 ) ;
function encode ( value ) {
var data = new ArrayBuffer ( 256 ) ;
var dataView = new DataView ( data ) ;
var lastLength ;
var offset = 0 ;
function ensureSpace ( length ) {
var newByteLength = data . byteLength ;
var requiredLength = offset + length ;
while ( newByteLength < requiredLength )
newByteLength *= 2 ;
if ( newByteLength !== data . byteLength ) {
var oldDataView = dataView ;
data = new ArrayBuffer ( newByteLength ) ;
dataView = new DataView ( data ) ;
var uint32count = ( offset + 3 ) >> 2 ;
for ( var i = 0 ; i < uint32count ; ++ i )
dataView . setUint32 ( i * 4 , oldDataView . getUint32 ( i * 4 ) ) ;
}
lastLength = length ;
return dataView ;
}
function write ( ) {
offset += lastLength ;
}
function writeFloat64 ( value ) {
write ( ensureSpace ( 8 ) . setFloat64 ( offset , value ) ) ;
}
function writeUint8 ( value ) {
write ( ensureSpace ( 1 ) . setUint8 ( offset , value ) ) ;
}
function writeUint8Array ( value ) {
var dataView = ensureSpace ( value . length ) ;
for ( var i = 0 ; i < value . length ; ++ i )
dataView . setUint8 ( offset + i , value [ i ] ) ;
write ( ) ;
}
function writeUint16 ( value ) {
write ( ensureSpace ( 2 ) . setUint16 ( offset , value ) ) ;
}
function writeUint32 ( value ) {
write ( ensureSpace ( 4 ) . setUint32 ( offset , value ) ) ;
}
function writeUint64 ( value ) {
var low = value % POW _2 _32 ;
var high = ( value - low ) / POW _2 _32 ;
var dataView = ensureSpace ( 8 ) ;
dataView . setUint32 ( offset , high ) ;
dataView . setUint32 ( offset + 4 , low ) ;
write ( ) ;
}
function writeTypeAndLength ( type , length ) {
if ( length < 24 ) {
writeUint8 ( type << 5 | length ) ;
} else if ( length < 0x100 ) {
writeUint8 ( type << 5 | 24 ) ;
writeUint8 ( length ) ;
} else if ( length < 0x10000 ) {
writeUint8 ( type << 5 | 25 ) ;
writeUint16 ( length ) ;
} else if ( length < 0x100000000 ) {
writeUint8 ( type << 5 | 26 ) ;
writeUint32 ( length ) ;
} else {
writeUint8 ( type << 5 | 27 ) ;
writeUint64 ( length ) ;
}
}
function encodeItem ( value ) {
var i ;
if ( value === false )
return writeUint8 ( 0xf4 ) ;
if ( value === true )
return writeUint8 ( 0xf5 ) ;
if ( value === null )
return writeUint8 ( 0xf6 ) ;
if ( value === undefined )
return writeUint8 ( 0xf7 ) ;
switch ( typeof value ) {
case "number" :
if ( Math . floor ( value ) === value ) {
if ( 0 <= value && value <= POW _2 _53 )
return writeTypeAndLength ( 0 , value ) ;
if ( - POW _2 _53 <= value && value < 0 )
return writeTypeAndLength ( 1 , - ( value + 1 ) ) ;
}
writeUint8 ( 0xfb ) ;
return writeFloat64 ( value ) ;
case "string" :
var utf8data = [ ] ;
for ( i = 0 ; i < value . length ; ++ i ) {
var charCode = value . charCodeAt ( i ) ;
if ( charCode < 0x80 ) {
utf8data . push ( charCode ) ;
} else if ( charCode < 0x800 ) {
utf8data . push ( 0xc0 | charCode >> 6 ) ;
utf8data . push ( 0x80 | charCode & 0x3f ) ;
} else if ( charCode < 0xd800 ) {
utf8data . push ( 0xe0 | charCode >> 12 ) ;
utf8data . push ( 0x80 | ( charCode >> 6 ) & 0x3f ) ;
utf8data . push ( 0x80 | charCode & 0x3f ) ;
} else {
charCode = ( charCode & 0x3ff ) << 10 ;
charCode |= value . charCodeAt ( ++ i ) & 0x3ff ;
charCode += 0x10000 ;
utf8data . push ( 0xf0 | charCode >> 18 ) ;
utf8data . push ( 0x80 | ( charCode >> 12 ) & 0x3f ) ;
utf8data . push ( 0x80 | ( charCode >> 6 ) & 0x3f ) ;
utf8data . push ( 0x80 | charCode & 0x3f ) ;
}
}
writeTypeAndLength ( 3 , utf8data . length ) ;
return writeUint8Array ( utf8data ) ;
default :
var length ;
if ( Array . isArray ( value ) ) {
length = value . length ;
writeTypeAndLength ( 4 , length ) ;
for ( i = 0 ; i < length ; ++ i )
encodeItem ( value [ i ] ) ;
} else if ( value instanceof Uint8Array ) {
writeTypeAndLength ( 2 , value . length ) ;
writeUint8Array ( value ) ;
} else {
var keys = Object . keys ( value ) ;
length = keys . length ;
writeTypeAndLength ( 5 , length ) ;
for ( i = 0 ; i < length ; ++ i ) {
var key = keys [ i ] ;
encodeItem ( key ) ;
encodeItem ( value [ key ] ) ;
}
}
}
}
encodeItem ( value ) ;
if ( "slice" in data )
return data . slice ( 0 , offset ) ;
var ret = new ArrayBuffer ( offset ) ;
var retView = new DataView ( ret ) ;
for ( var i = 0 ; i < offset ; ++ i )
retView . setUint8 ( i , dataView . getUint8 ( i ) ) ;
return ret ;
}
function decode ( data , tagger , simpleValue ) {
var dataView = new DataView ( data ) ;
var offset = 0 ;
if ( typeof tagger !== "function" )
tagger = function ( value ) { return value ; } ;
if ( typeof simpleValue !== "function" )
simpleValue = function ( ) { return undefined ; } ;
function read ( value , length ) {
offset += length ;
return value ;
}
function readArrayBuffer ( length ) {
return read ( new Uint8Array ( data , offset , length ) , length ) ;
}
function readFloat16 ( ) {
var tempArrayBuffer = new ArrayBuffer ( 4 ) ;
var tempDataView = new DataView ( tempArrayBuffer ) ;
var value = readUint16 ( ) ;
var sign = value & 0x8000 ;
var exponent = value & 0x7c00 ;
var fraction = value & 0x03ff ;
if ( exponent === 0x7c00 )
exponent = 0xff << 10 ;
else if ( exponent !== 0 )
exponent += ( 127 - 15 ) << 10 ;
else if ( fraction !== 0 )
return fraction * POW _2 _24 ;
tempDataView . setUint32 ( 0 , sign << 16 | exponent << 13 | fraction << 13 ) ;
return tempDataView . getFloat32 ( 0 ) ;
}
function readFloat32 ( ) {
return read ( dataView . getFloat32 ( offset ) , 4 ) ;
}
function readFloat64 ( ) {
return read ( dataView . getFloat64 ( offset ) , 8 ) ;
}
function readUint8 ( ) {
return read ( dataView . getUint8 ( offset ) , 1 ) ;
}
function readUint16 ( ) {
return read ( dataView . getUint16 ( offset ) , 2 ) ;
}
function readUint32 ( ) {
return read ( dataView . getUint32 ( offset ) , 4 ) ;
}
function readUint64 ( ) {
return readUint32 ( ) * POW _2 _32 + readUint32 ( ) ;
}
function readBreak ( ) {
if ( dataView . getUint8 ( offset ) !== 0xff )
return false ;
offset += 1 ;
return true ;
}
function readLength ( additionalInformation ) {
if ( additionalInformation < 24 )
return additionalInformation ;
if ( additionalInformation === 24 )
return readUint8 ( ) ;
if ( additionalInformation === 25 )
return readUint16 ( ) ;
if ( additionalInformation === 26 )
return readUint32 ( ) ;
if ( additionalInformation === 27 )
return readUint64 ( ) ;
if ( additionalInformation === 31 )
return - 1 ;
throw "Invalid length encoding" ;
}
function readIndefiniteStringLength ( majorType ) {
var initialByte = readUint8 ( ) ;
if ( initialByte === 0xff )
return - 1 ;
var length = readLength ( initialByte & 0x1f ) ;
if ( length < 0 || ( initialByte >> 5 ) !== majorType )
throw "Invalid indefinite length element" ;
return length ;
}
function appendUtf16data ( utf16data , length ) {
for ( var i = 0 ; i < length ; ++ i ) {
var value = readUint8 ( ) ;
if ( value & 0x80 ) {
if ( value < 0xe0 ) {
value = ( value & 0x1f ) << 6
| ( readUint8 ( ) & 0x3f ) ;
length -= 1 ;
} else if ( value < 0xf0 ) {
value = ( value & 0x0f ) << 12
| ( readUint8 ( ) & 0x3f ) << 6
| ( readUint8 ( ) & 0x3f ) ;
length -= 2 ;
} else {
value = ( value & 0x0f ) << 18
| ( readUint8 ( ) & 0x3f ) << 12
| ( readUint8 ( ) & 0x3f ) << 6
| ( readUint8 ( ) & 0x3f ) ;
length -= 3 ;
}
}
if ( value < 0x10000 ) {
utf16data . push ( value ) ;
} else {
value -= 0x10000 ;
utf16data . push ( 0xd800 | ( value >> 10 ) ) ;
utf16data . push ( 0xdc00 | ( value & 0x3ff ) ) ;
}
}
}
function decodeItem ( ) {
var initialByte = readUint8 ( ) ;
var majorType = initialByte >> 5 ;
var additionalInformation = initialByte & 0x1f ;
var i ;
var length ;
if ( majorType === 7 ) {
switch ( additionalInformation ) {
case 25 :
return readFloat16 ( ) ;
case 26 :
return readFloat32 ( ) ;
case 27 :
return readFloat64 ( ) ;
}
}
length = readLength ( additionalInformation ) ;
if ( length < 0 && ( majorType < 2 || 6 < majorType ) )
throw "Invalid length" ;
switch ( majorType ) {
case 0 :
return length ;
case 1 :
return - 1 - length ;
case 2 :
if ( length < 0 ) {
var elements = [ ] ;
var fullArrayLength = 0 ;
while ( ( length = readIndefiniteStringLength ( majorType ) ) >= 0 ) {
fullArrayLength += length ;
elements . push ( readArrayBuffer ( length ) ) ;
}
var fullArray = new Uint8Array ( fullArrayLength ) ;
var fullArrayOffset = 0 ;
for ( i = 0 ; i < elements . length ; ++ i ) {
fullArray . set ( elements [ i ] , fullArrayOffset ) ;
fullArrayOffset += elements [ i ] . length ;
}
return fullArray ;
}
return readArrayBuffer ( length ) ;
case 3 :
var utf16data = [ ] ;
if ( length < 0 ) {
while ( ( length = readIndefiniteStringLength ( majorType ) ) >= 0 )
appendUtf16data ( utf16data , length ) ;
} else
appendUtf16data ( utf16data , length ) ;
return String . fromCharCode . apply ( null , utf16data ) ;
case 4 :
var retArray ;
if ( length < 0 ) {
retArray = [ ] ;
while ( ! readBreak ( ) )
retArray . push ( decodeItem ( ) ) ;
} else {
retArray = new Array ( length ) ;
for ( i = 0 ; i < length ; ++ i )
retArray [ i ] = decodeItem ( ) ;
}
return retArray ;
case 5 :
var retObject = { } ;
for ( i = 0 ; i < length || length < 0 && ! readBreak ( ) ; ++ i ) {
var key = decodeItem ( ) ;
retObject [ key ] = decodeItem ( ) ;
}
return retObject ;
case 6 :
return tagger ( decodeItem ( ) , length ) ;
case 7 :
switch ( length ) {
case 20 :
return false ;
case 21 :
return true ;
case 22 :
return null ;
case 23 :
return undefined ;
default :
return simpleValue ( length ) ;
}
}
}
var ret = decodeItem ( ) ;
if ( offset !== data . byteLength )
throw "Remaining bytes" ;
return ret ;
}
var obj = { encode : encode , decode : decode } ;
if ( typeof define === "function" && define . amd )
define ( "cbor/cbor" , obj ) ;
else if ( typeof module !== 'undefined' && module . exports )
module . exports = obj ;
else if ( ! global . CBOR )
global . CBOR = obj ;
} ) ( this ) ;
} , { } ] , 2 : [ function ( require , module , exports ) {
( function ( process ) {
/ * !
* EventEmitter2
* https : //github.com/hij1nx/EventEmitter2
*
* Copyright ( c ) 2013 hij1nx
* Licensed under the MIT license .
* /
; ! function ( undefined ) {
var isArray = Array . isArray ? Array . isArray : function _isArray ( obj ) {
return Object . prototype . toString . call ( obj ) === "[object Array]" ;
} ;
var defaultMaxListeners = 10 ;
function init ( ) {
this . _events = { } ;
if ( this . _conf ) {
configure . call ( this , this . _conf ) ;
}
}
function configure ( conf ) {
if ( conf ) {
this . _conf = conf ;
conf . delimiter && ( this . delimiter = conf . delimiter ) ;
this . _maxListeners = conf . maxListeners !== undefined ? conf . maxListeners : defaultMaxListeners ;
conf . wildcard && ( this . wildcard = conf . wildcard ) ;
conf . newListener && ( this . newListener = conf . newListener ) ;
conf . verboseMemoryLeak && ( this . verboseMemoryLeak = conf . verboseMemoryLeak ) ;
if ( this . wildcard ) {
this . listenerTree = { } ;
}
} else {
this . _maxListeners = defaultMaxListeners ;
}
}
function logPossibleMemoryLeak ( count , eventName ) {
var errorMsg = '(node) warning: possible EventEmitter memory ' +
'leak detected. ' + count + ' listeners added. ' +
'Use emitter.setMaxListeners() to increase limit.' ;
if ( this . verboseMemoryLeak ) {
errorMsg += ' Event name: ' + eventName + '.' ;
}
if ( typeof process !== 'undefined' && process . emitWarning ) {
var e = new Error ( errorMsg ) ;
e . name = 'MaxListenersExceededWarning' ;
e . emitter = this ;
e . count = count ;
process . emitWarning ( e ) ;
} else {
console . error ( errorMsg ) ;
if ( console . trace ) {
console . trace ( ) ;
}
}
}
function EventEmitter ( conf ) {
this . _events = { } ;
this . newListener = false ;
this . verboseMemoryLeak = false ;
configure . call ( this , conf ) ;
}
EventEmitter . EventEmitter2 = EventEmitter ; // backwards compatibility for exporting EventEmitter property
//
// Attention, function return type now is array, always !
// It has zero elements if no any matches found and one or more
// elements (leafs) if there are matches
//
function searchListenerTree ( handlers , type , tree , i ) {
if ( ! tree ) {
return [ ] ;
}
var listeners = [ ] , leaf , len , branch , xTree , xxTree , isolatedBranch , endReached ,
typeLength = type . length , currentType = type [ i ] , nextType = type [ i + 1 ] ;
if ( i === typeLength && tree . _listeners ) {
//
// If at the end of the event(s) list and the tree has listeners
// invoke those listeners.
//
if ( typeof tree . _listeners === 'function' ) {
handlers && handlers . push ( tree . _listeners ) ;
return [ tree ] ;
} else {
for ( leaf = 0 , len = tree . _listeners . length ; leaf < len ; leaf ++ ) {
handlers && handlers . push ( tree . _listeners [ leaf ] ) ;
}
return [ tree ] ;
}
}
if ( ( currentType === '*' || currentType === '**' ) || tree [ currentType ] ) {
//
// If the event emitted is '*' at this part
// or there is a concrete match at this patch
//
if ( currentType === '*' ) {
for ( branch in tree ) {
if ( branch !== '_listeners' && tree . hasOwnProperty ( branch ) ) {
listeners = listeners . concat ( searchListenerTree ( handlers , type , tree [ branch ] , i + 1 ) ) ;
}
}
return listeners ;
} else if ( currentType === '**' ) {
endReached = ( i + 1 === typeLength || ( i + 2 === typeLength && nextType === '*' ) ) ;
if ( endReached && tree . _listeners ) {
// The next element has a _listeners, add it to the handlers.
listeners = listeners . concat ( searchListenerTree ( handlers , type , tree , typeLength ) ) ;
}
for ( branch in tree ) {
if ( branch !== '_listeners' && tree . hasOwnProperty ( branch ) ) {
if ( branch === '*' || branch === '**' ) {
if ( tree [ branch ] . _listeners && ! endReached ) {
listeners = listeners . concat ( searchListenerTree ( handlers , type , tree [ branch ] , typeLength ) ) ;
}
listeners = listeners . concat ( searchListenerTree ( handlers , type , tree [ branch ] , i ) ) ;
} else if ( branch === nextType ) {
listeners = listeners . concat ( searchListenerTree ( handlers , type , tree [ branch ] , i + 2 ) ) ;
} else {
// No match on this one, shift into the tree but not in the type array.
listeners = listeners . concat ( searchListenerTree ( handlers , type , tree [ branch ] , i ) ) ;
}
}
}
return listeners ;
}
listeners = listeners . concat ( searchListenerTree ( handlers , type , tree [ currentType ] , i + 1 ) ) ;
}
xTree = tree [ '*' ] ;
if ( xTree ) {
//
// If the listener tree will allow any match for this part,
// then recursively explore all branches of the tree
//
searchListenerTree ( handlers , type , xTree , i + 1 ) ;
}
xxTree = tree [ '**' ] ;
if ( xxTree ) {
if ( i < typeLength ) {
if ( xxTree . _listeners ) {
// If we have a listener on a '**', it will catch all, so add its handler.
searchListenerTree ( handlers , type , xxTree , typeLength ) ;
}
// Build arrays of matching next branches and others.
for ( branch in xxTree ) {
if ( branch !== '_listeners' && xxTree . hasOwnProperty ( branch ) ) {
if ( branch === nextType ) {
// We know the next element will match, so jump twice.
searchListenerTree ( handlers , type , xxTree [ branch ] , i + 2 ) ;
} else if ( branch === currentType ) {
// Current node matches, move into the tree.
searchListenerTree ( handlers , type , xxTree [ branch ] , i + 1 ) ;
} else {
isolatedBranch = { } ;
isolatedBranch [ branch ] = xxTree [ branch ] ;
searchListenerTree ( handlers , type , { '**' : isolatedBranch } , i + 1 ) ;
}
}
}
} else if ( xxTree . _listeners ) {
// We have reached the end and still on a '**'
searchListenerTree ( handlers , type , xxTree , typeLength ) ;
} else if ( xxTree [ '*' ] && xxTree [ '*' ] . _listeners ) {
searchListenerTree ( handlers , type , xxTree [ '*' ] , typeLength ) ;
}
}
return listeners ;
}
function growListenerTree ( type , listener ) {
type = typeof type === 'string' ? type . split ( this . delimiter ) : type . slice ( ) ;
//
// Looks for two consecutive '**', if so, don't add the event at all.
//
for ( var i = 0 , len = type . length ; i + 1 < len ; i ++ ) {
if ( type [ i ] === '**' && type [ i + 1 ] === '**' ) {
return ;
}
}
var tree = this . listenerTree ;
var name = type . shift ( ) ;
while ( name !== undefined ) {
if ( ! tree [ name ] ) {
tree [ name ] = { } ;
}
tree = tree [ name ] ;
if ( type . length === 0 ) {
if ( ! tree . _listeners ) {
tree . _listeners = listener ;
}
else {
if ( typeof tree . _listeners === 'function' ) {
tree . _listeners = [ tree . _listeners ] ;
}
tree . _listeners . push ( listener ) ;
if (
! tree . _listeners . warned &&
this . _maxListeners > 0 &&
tree . _listeners . length > this . _maxListeners
) {
tree . _listeners . warned = true ;
logPossibleMemoryLeak . call ( this , tree . _listeners . length , name ) ;
}
}
return true ;
}
name = type . shift ( ) ;
}
return true ;
}
// By default EventEmitters will print a warning if more than
// 10 listeners are added to it. This is a useful default which
// helps finding memory leaks.
//
// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
EventEmitter . prototype . delimiter = '.' ;
EventEmitter . prototype . setMaxListeners = function ( n ) {
if ( n !== undefined ) {
this . _maxListeners = n ;
if ( ! this . _conf ) this . _conf = { } ;
this . _conf . maxListeners = n ;
}
} ;
EventEmitter . prototype . event = '' ;
EventEmitter . prototype . once = function ( event , fn ) {
return this . _once ( event , fn , false ) ;
} ;
EventEmitter . prototype . prependOnceListener = function ( event , fn ) {
return this . _once ( event , fn , true ) ;
} ;
EventEmitter . prototype . _once = function ( event , fn , prepend ) {
this . _many ( event , 1 , fn , prepend ) ;
return this ;
} ;
EventEmitter . prototype . many = function ( event , ttl , fn ) {
return this . _many ( event , ttl , fn , false ) ;
}
EventEmitter . prototype . prependMany = function ( event , ttl , fn ) {
return this . _many ( event , ttl , fn , true ) ;
}
EventEmitter . prototype . _many = function ( event , ttl , fn , prepend ) {
var self = this ;
if ( typeof fn !== 'function' ) {
throw new Error ( 'many only accepts instances of Function' ) ;
}
function listener ( ) {
if ( -- ttl === 0 ) {
self . off ( event , listener ) ;
}
return fn . apply ( this , arguments ) ;
}
listener . _origin = fn ;
this . _on ( event , listener , prepend ) ;
return self ;
} ;
EventEmitter . prototype . emit = function ( ) {
this . _events || init . call ( this ) ;
var type = arguments [ 0 ] ;
if ( type === 'newListener' && ! this . newListener ) {
if ( ! this . _events . newListener ) {
return false ;
}
}
var al = arguments . length ;
var args , l , i , j ;
var handler ;
if ( this . _all && this . _all . length ) {
handler = this . _all . slice ( ) ;
if ( al > 3 ) {
args = new Array ( al ) ;
for ( j = 0 ; j < al ; j ++ ) args [ j ] = arguments [ j ] ;
}
for ( i = 0 , l = handler . length ; i < l ; i ++ ) {
this . event = type ;
switch ( al ) {
case 1 :
handler [ i ] . call ( this , type ) ;
break ;
case 2 :
handler [ i ] . call ( this , type , arguments [ 1 ] ) ;
break ;
case 3 :
handler [ i ] . call ( this , type , arguments [ 1 ] , arguments [ 2 ] ) ;
break ;
default :
handler [ i ] . apply ( this , args ) ;
}
}
}
if ( this . wildcard ) {
handler = [ ] ;
var ns = typeof type === 'string' ? type . split ( this . delimiter ) : type . slice ( ) ;
searchListenerTree . call ( this , handler , ns , this . listenerTree , 0 ) ;
} else {
handler = this . _events [ type ] ;
if ( typeof handler === 'function' ) {
this . event = type ;
switch ( al ) {
case 1 :
handler . call ( this ) ;
break ;
case 2 :
handler . call ( this , arguments [ 1 ] ) ;
break ;
case 3 :
handler . call ( this , arguments [ 1 ] , arguments [ 2 ] ) ;
break ;
default :
args = new Array ( al - 1 ) ;
for ( j = 1 ; j < al ; j ++ ) args [ j - 1 ] = arguments [ j ] ;
handler . apply ( this , args ) ;
}
return true ;
} else if ( handler ) {
// need to make copy of handlers because list can change in the middle
// of emit call
handler = handler . slice ( ) ;
}
}
if ( handler && handler . length ) {
if ( al > 3 ) {
args = new Array ( al - 1 ) ;
for ( j = 1 ; j < al ; j ++ ) args [ j - 1 ] = arguments [ j ] ;
}
for ( i = 0 , l = handler . length ; i < l ; i ++ ) {
this . event = type ;
switch ( al ) {
case 1 :
handler [ i ] . call ( this ) ;
break ;
case 2 :
handler [ i ] . call ( this , arguments [ 1 ] ) ;
break ;
case 3 :
handler [ i ] . call ( this , arguments [ 1 ] , arguments [ 2 ] ) ;
break ;
default :
handler [ i ] . apply ( this , args ) ;
}
}
return true ;
} else if ( ! this . _all && type === 'error' ) {
if ( arguments [ 1 ] instanceof Error ) {
throw arguments [ 1 ] ; // Unhandled 'error' event
} else {
throw new Error ( "Uncaught, unspecified 'error' event." ) ;
}
return false ;
}
return ! ! this . _all ;
} ;
EventEmitter . prototype . emitAsync = function ( ) {
this . _events || init . call ( this ) ;
var type = arguments [ 0 ] ;
if ( type === 'newListener' && ! this . newListener ) {
if ( ! this . _events . newListener ) { return Promise . resolve ( [ false ] ) ; }
}
var promises = [ ] ;
var al = arguments . length ;
var args , l , i , j ;
var handler ;
if ( this . _all ) {
if ( al > 3 ) {
args = new Array ( al ) ;
for ( j = 1 ; j < al ; j ++ ) args [ j ] = arguments [ j ] ;
}
for ( i = 0 , l = this . _all . length ; i < l ; i ++ ) {
this . event = type ;
switch ( al ) {
case 1 :
promises . push ( this . _all [ i ] . call ( this , type ) ) ;
break ;
case 2 :
promises . push ( this . _all [ i ] . call ( this , type , arguments [ 1 ] ) ) ;
break ;
case 3 :
promises . push ( this . _all [ i ] . call ( this , type , arguments [ 1 ] , arguments [ 2 ] ) ) ;
break ;
default :
promises . push ( this . _all [ i ] . apply ( this , args ) ) ;
}
}
}
if ( this . wildcard ) {
handler = [ ] ;
var ns = typeof type === 'string' ? type . split ( this . delimiter ) : type . slice ( ) ;
searchListenerTree . call ( this , handler , ns , this . listenerTree , 0 ) ;
} else {
handler = this . _events [ type ] ;
}
if ( typeof handler === 'function' ) {
this . event = type ;
switch ( al ) {
case 1 :
promises . push ( handler . call ( this ) ) ;
break ;
case 2 :
promises . push ( handler . call ( this , arguments [ 1 ] ) ) ;
break ;
case 3 :
promises . push ( handler . call ( this , arguments [ 1 ] , arguments [ 2 ] ) ) ;
break ;
default :
args = new Array ( al - 1 ) ;
for ( j = 1 ; j < al ; j ++ ) args [ j - 1 ] = arguments [ j ] ;
promises . push ( handler . apply ( this , args ) ) ;
}
} else if ( handler && handler . length ) {
handler = handler . slice ( ) ;
if ( al > 3 ) {
args = new Array ( al - 1 ) ;
for ( j = 1 ; j < al ; j ++ ) args [ j - 1 ] = arguments [ j ] ;
}
for ( i = 0 , l = handler . length ; i < l ; i ++ ) {
this . event = type ;
switch ( al ) {
case 1 :
promises . push ( handler [ i ] . call ( this ) ) ;
break ;
case 2 :
promises . push ( handler [ i ] . call ( this , arguments [ 1 ] ) ) ;
break ;
case 3 :
promises . push ( handler [ i ] . call ( this , arguments [ 1 ] , arguments [ 2 ] ) ) ;
break ;
default :
promises . push ( handler [ i ] . apply ( this , args ) ) ;
}
}
} else if ( ! this . _all && type === 'error' ) {
if ( arguments [ 1 ] instanceof Error ) {
return Promise . reject ( arguments [ 1 ] ) ; // Unhandled 'error' event
} else {
return Promise . reject ( "Uncaught, unspecified 'error' event." ) ;
}
}
return Promise . all ( promises ) ;
} ;
EventEmitter . prototype . on = function ( type , listener ) {
return this . _on ( type , listener , false ) ;
} ;
EventEmitter . prototype . prependListener = function ( type , listener ) {
return this . _on ( type , listener , true ) ;
} ;
EventEmitter . prototype . onAny = function ( fn ) {
return this . _onAny ( fn , false ) ;
} ;
EventEmitter . prototype . prependAny = function ( fn ) {
return this . _onAny ( fn , true ) ;
} ;
EventEmitter . prototype . addListener = EventEmitter . prototype . on ;
EventEmitter . prototype . _onAny = function ( fn , prepend ) {
if ( typeof fn !== 'function' ) {
throw new Error ( 'onAny only accepts instances of Function' ) ;
}
if ( ! this . _all ) {
this . _all = [ ] ;
}
// Add the function to the event listener collection.
if ( prepend ) {
this . _all . unshift ( fn ) ;
} else {
this . _all . push ( fn ) ;
}
return this ;
}
EventEmitter . prototype . _on = function ( type , listener , prepend ) {
if ( typeof type === 'function' ) {
this . _onAny ( type , listener ) ;
return this ;
}
if ( typeof listener !== 'function' ) {
throw new Error ( 'on only accepts instances of Function' ) ;
}
this . _events || init . call ( this ) ;
// To avoid recursion in the case that type == "newListeners"! Before
// adding it to the listeners, first emit "newListeners".
this . emit ( 'newListener' , type , listener ) ;
if ( this . wildcard ) {
growListenerTree . call ( this , type , listener ) ;
return this ;
}
if ( ! this . _events [ type ] ) {
// Optimize the case of one listener. Don't need the extra array object.
this . _events [ type ] = listener ;
}
else {
if ( typeof this . _events [ type ] === 'function' ) {
// Change to array.
this . _events [ type ] = [ this . _events [ type ] ] ;
}
// If we've already got an array, just add
if ( prepend ) {
this . _events [ type ] . unshift ( listener ) ;
} else {
this . _events [ type ] . push ( listener ) ;
}
// Check for listener leak
if (
! this . _events [ type ] . warned &&
this . _maxListeners > 0 &&
this . _events [ type ] . length > this . _maxListeners
) {
this . _events [ type ] . warned = true ;
logPossibleMemoryLeak . call ( this , this . _events [ type ] . length , type ) ;
}
}
return this ;
}
EventEmitter . prototype . off = function ( type , listener ) {
if ( typeof listener !== 'function' ) {
throw new Error ( 'removeListener only takes instances of Function' ) ;
}
var handlers , leafs = [ ] ;
if ( this . wildcard ) {
var ns = typeof type === 'string' ? type . split ( this . delimiter ) : type . slice ( ) ;
leafs = searchListenerTree . call ( this , null , ns , this . listenerTree , 0 ) ;
}
else {
// does not use listeners(), so no side effect of creating _events[type]
if ( ! this . _events [ type ] ) return this ;
handlers = this . _events [ type ] ;
leafs . push ( { _listeners : handlers } ) ;
}
for ( var iLeaf = 0 ; iLeaf < leafs . length ; iLeaf ++ ) {
var leaf = leafs [ iLeaf ] ;
handlers = leaf . _listeners ;
if ( isArray ( handlers ) ) {
var position = - 1 ;
for ( var i = 0 , length = handlers . length ; i < length ; i ++ ) {
if ( handlers [ i ] === listener ||
( handlers [ i ] . listener && handlers [ i ] . listener === listener ) ||
( handlers [ i ] . _origin && handlers [ i ] . _origin === listener ) ) {
position = i ;
break ;
}
}
if ( position < 0 ) {
continue ;
}
if ( this . wildcard ) {
leaf . _listeners . splice ( position , 1 ) ;
}
else {
this . _events [ type ] . splice ( position , 1 ) ;
}
if ( handlers . length === 0 ) {
if ( this . wildcard ) {
delete leaf . _listeners ;
}
else {
delete this . _events [ type ] ;
}
}
this . emit ( "removeListener" , type , listener ) ;
return this ;
}
else if ( handlers === listener ||
( handlers . listener && handlers . listener === listener ) ||
( handlers . _origin && handlers . _origin === listener ) ) {
if ( this . wildcard ) {
delete leaf . _listeners ;
}
else {
delete this . _events [ type ] ;
}
this . emit ( "removeListener" , type , listener ) ;
}
}
function recursivelyGarbageCollect ( root ) {
if ( root === undefined ) {
return ;
}
var keys = Object . keys ( root ) ;
for ( var i in keys ) {
var key = keys [ i ] ;
var obj = root [ key ] ;
if ( ( obj instanceof Function ) || ( typeof obj !== "object" ) || ( obj === null ) )
continue ;
if ( Object . keys ( obj ) . length > 0 ) {
recursivelyGarbageCollect ( root [ key ] ) ;
}
if ( Object . keys ( obj ) . length === 0 ) {
delete root [ key ] ;
}
}
}
recursivelyGarbageCollect ( this . listenerTree ) ;
return this ;
} ;
EventEmitter . prototype . offAny = function ( fn ) {
var i = 0 , l = 0 , fns ;
if ( fn && this . _all && this . _all . length > 0 ) {
fns = this . _all ;
for ( i = 0 , l = fns . length ; i < l ; i ++ ) {
if ( fn === fns [ i ] ) {
fns . splice ( i , 1 ) ;
this . emit ( "removeListenerAny" , fn ) ;
return this ;
}
}
} else {
fns = this . _all ;
for ( i = 0 , l = fns . length ; i < l ; i ++ )
this . emit ( "removeListenerAny" , fns [ i ] ) ;
this . _all = [ ] ;
}
return this ;
} ;
EventEmitter . prototype . removeListener = EventEmitter . prototype . off ;
EventEmitter . prototype . removeAllListeners = function ( type ) {
if ( arguments . length === 0 ) {
! this . _events || init . call ( this ) ;
return this ;
}
if ( this . wildcard ) {
var ns = typeof type === 'string' ? type . split ( this . delimiter ) : type . slice ( ) ;
var leafs = searchListenerTree . call ( this , null , ns , this . listenerTree , 0 ) ;
for ( var iLeaf = 0 ; iLeaf < leafs . length ; iLeaf ++ ) {
var leaf = leafs [ iLeaf ] ;
leaf . _listeners = null ;
}
}
else if ( this . _events ) {
this . _events [ type ] = null ;
}
return this ;
} ;
EventEmitter . prototype . listeners = function ( type ) {
if ( this . wildcard ) {
var handlers = [ ] ;
var ns = typeof type === 'string' ? type . split ( this . delimiter ) : type . slice ( ) ;
searchListenerTree . call ( this , handlers , ns , this . listenerTree , 0 ) ;
return handlers ;
}
this . _events || init . call ( this ) ;
if ( ! this . _events [ type ] ) this . _events [ type ] = [ ] ;
if ( ! isArray ( this . _events [ type ] ) ) {
this . _events [ type ] = [ this . _events [ type ] ] ;
}
return this . _events [ type ] ;
} ;
EventEmitter . prototype . eventNames = function ( ) {
return Object . keys ( this . _events ) ;
}
EventEmitter . prototype . listenerCount = function ( type ) {
return this . listeners ( type ) . length ;
} ;
EventEmitter . prototype . listenersAny = function ( ) {
if ( this . _all ) {
return this . _all ;
}
else {
return [ ] ;
}
} ;
if ( typeof define === 'function' && define . amd ) {
// AMD. Register as an anonymous module.
define ( function ( ) {
return EventEmitter ;
} ) ;
} else if ( typeof exports === 'object' ) {
// CommonJS
module . exports = EventEmitter ;
}
else {
// Browser global.
window . EventEmitter2 = EventEmitter ;
}
} ( ) ;
} ) . call ( this , require ( '_process' ) )
} , { "_process" : 4 } ] , 3 : [ function ( require , module , exports ) {
/ *
object - assign
( c ) Sindre Sorhus
@ license MIT
* /
2015-05-29 16:21:09 -04:00
'use strict' ;
2019-03-27 17:43:00 -04:00
/* eslint-disable no-unused-vars */
var getOwnPropertySymbols = Object . getOwnPropertySymbols ;
var hasOwnProperty = Object . prototype . hasOwnProperty ;
var propIsEnumerable = Object . prototype . propertyIsEnumerable ;
2015-05-29 16:21:09 -04:00
2019-03-27 17:43:00 -04:00
function toObject ( val ) {
if ( val === null || val === undefined ) {
2015-05-29 16:21:09 -04:00
throw new TypeError ( 'Object.assign cannot be called with null or undefined' ) ;
}
return Object ( val ) ;
}
2019-03-27 17:43:00 -04:00
function shouldUseNative ( ) {
try {
if ( ! Object . assign ) {
return false ;
}
// Detect buggy property enumeration order in older V8 versions.
// https://bugs.chromium.org/p/v8/issues/detail?id=4118
var test1 = new String ( 'abc' ) ; // eslint-disable-line no-new-wrappers
test1 [ 5 ] = 'de' ;
if ( Object . getOwnPropertyNames ( test1 ) [ 0 ] === '5' ) {
return false ;
}
// https://bugs.chromium.org/p/v8/issues/detail?id=3056
var test2 = { } ;
for ( var i = 0 ; i < 10 ; i ++ ) {
test2 [ '_' + String . fromCharCode ( i ) ] = i ;
}
var order2 = Object . getOwnPropertyNames ( test2 ) . map ( function ( n ) {
return test2 [ n ] ;
} ) ;
if ( order2 . join ( '' ) !== '0123456789' ) {
return false ;
}
// https://bugs.chromium.org/p/v8/issues/detail?id=3056
var test3 = { } ;
'abcdefghijklmnopqrst' . split ( '' ) . forEach ( function ( letter ) {
test3 [ letter ] = letter ;
} ) ;
if ( Object . keys ( Object . assign ( { } , test3 ) ) . join ( '' ) !==
'abcdefghijklmnopqrst' ) {
return false ;
}
return true ;
} catch ( err ) {
// We don't expect any of the above to throw, but better to be safe.
return false ;
}
}
module . exports = shouldUseNative ( ) ? Object . assign : function ( target , source ) {
2015-05-29 16:21:09 -04:00
var from ;
2019-03-27 17:43:00 -04:00
var to = toObject ( target ) ;
var symbols ;
2015-05-29 16:21:09 -04:00
for ( var s = 1 ; s < arguments . length ; s ++ ) {
2019-03-27 17:43:00 -04:00
from = Object ( arguments [ s ] ) ;
for ( var key in from ) {
if ( hasOwnProperty . call ( from , key ) ) {
to [ key ] = from [ key ] ;
}
}
2015-05-29 16:21:09 -04:00
2019-03-27 17:43:00 -04:00
if ( getOwnPropertySymbols ) {
symbols = getOwnPropertySymbols ( from ) ;
for ( var i = 0 ; i < symbols . length ; i ++ ) {
if ( propIsEnumerable . call ( from , symbols [ i ] ) ) {
to [ symbols [ i ] ] = from [ symbols [ i ] ] ;
}
}
2015-05-29 16:21:09 -04:00
}
}
return to ;
} ;
2019-03-27 17:43:00 -04:00
} , { } ] , 4 : [ function ( require , module , exports ) {
// shim for using process in browser
var process = module . exports = { } ;
// cached from whatever global is present so that test runners that stub it
// don't break things. But we need to wrap it in a try catch in case it is
// wrapped in strict mode code which doesn't define any globals. It's inside a
// function because try/catches deoptimize in certain engines.
var cachedSetTimeout ;
var cachedClearTimeout ;
function defaultSetTimout ( ) {
throw new Error ( 'setTimeout has not been defined' ) ;
}
function defaultClearTimeout ( ) {
throw new Error ( 'clearTimeout has not been defined' ) ;
}
( function ( ) {
try {
if ( typeof setTimeout === 'function' ) {
cachedSetTimeout = setTimeout ;
} else {
cachedSetTimeout = defaultSetTimout ;
}
} catch ( e ) {
cachedSetTimeout = defaultSetTimout ;
}
try {
if ( typeof clearTimeout === 'function' ) {
cachedClearTimeout = clearTimeout ;
} else {
cachedClearTimeout = defaultClearTimeout ;
}
} catch ( e ) {
cachedClearTimeout = defaultClearTimeout ;
}
} ( ) )
function runTimeout ( fun ) {
if ( cachedSetTimeout === setTimeout ) {
//normal enviroments in sane situations
return setTimeout ( fun , 0 ) ;
}
// if setTimeout wasn't available but was latter defined
if ( ( cachedSetTimeout === defaultSetTimout || ! cachedSetTimeout ) && setTimeout ) {
cachedSetTimeout = setTimeout ;
return setTimeout ( fun , 0 ) ;
}
try {
// when when somebody has screwed with setTimeout but no I.E. maddness
return cachedSetTimeout ( fun , 0 ) ;
} catch ( e ) {
try {
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
return cachedSetTimeout . call ( null , fun , 0 ) ;
} catch ( e ) {
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
return cachedSetTimeout . call ( this , fun , 0 ) ;
}
}
}
function runClearTimeout ( marker ) {
if ( cachedClearTimeout === clearTimeout ) {
//normal enviroments in sane situations
return clearTimeout ( marker ) ;
}
// if clearTimeout wasn't available but was latter defined
if ( ( cachedClearTimeout === defaultClearTimeout || ! cachedClearTimeout ) && clearTimeout ) {
cachedClearTimeout = clearTimeout ;
return clearTimeout ( marker ) ;
}
try {
// when when somebody has screwed with setTimeout but no I.E. maddness
return cachedClearTimeout ( marker ) ;
} catch ( e ) {
try {
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
return cachedClearTimeout . call ( null , marker ) ;
} catch ( e ) {
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
// Some versions of I.E. have different rules for clearTimeout vs setTimeout
return cachedClearTimeout . call ( this , marker ) ;
}
}
}
var queue = [ ] ;
var draining = false ;
var currentQueue ;
var queueIndex = - 1 ;
function cleanUpNextTick ( ) {
if ( ! draining || ! currentQueue ) {
return ;
}
draining = false ;
if ( currentQueue . length ) {
queue = currentQueue . concat ( queue ) ;
} else {
queueIndex = - 1 ;
}
if ( queue . length ) {
drainQueue ( ) ;
}
}
function drainQueue ( ) {
if ( draining ) {
return ;
}
var timeout = runTimeout ( cleanUpNextTick ) ;
draining = true ;
var len = queue . length ;
while ( len ) {
currentQueue = queue ;
queue = [ ] ;
while ( ++ queueIndex < len ) {
if ( currentQueue ) {
currentQueue [ queueIndex ] . run ( ) ;
}
}
queueIndex = - 1 ;
len = queue . length ;
}
currentQueue = null ;
draining = false ;
runClearTimeout ( timeout ) ;
}
process . nextTick = function ( fun ) {
var args = new Array ( arguments . length - 1 ) ;
if ( arguments . length > 1 ) {
for ( var i = 1 ; i < arguments . length ; i ++ ) {
args [ i - 1 ] = arguments [ i ] ;
}
}
queue . push ( new Item ( fun , args ) ) ;
if ( queue . length === 1 && ! draining ) {
runTimeout ( drainQueue ) ;
}
} ;
// v8 likes predictible objects
function Item ( fun , array ) {
this . fun = fun ;
this . array = array ;
}
Item . prototype . run = function ( ) {
this . fun . apply ( null , this . array ) ;
} ;
process . title = 'browser' ;
process . browser = true ;
process . env = { } ;
process . argv = [ ] ;
process . version = '' ; // empty string to avoid regexp issues
process . versions = { } ;
function noop ( ) { }
process . on = noop ;
process . addListener = noop ;
process . once = noop ;
process . off = noop ;
process . removeListener = noop ;
process . removeAllListeners = noop ;
process . emit = noop ;
process . prependListener = noop ;
process . prependOnceListener = noop ;
process . listeners = function ( name ) { return [ ] }
process . binding = function ( name ) {
throw new Error ( 'process.binding is not supported' ) ;
} ;
process . cwd = function ( ) { return '/' } ;
process . chdir = function ( dir ) {
throw new Error ( 'process.chdir is not supported' ) ;
} ;
process . umask = function ( ) { return 0 ; } ;
} , { } ] , 5 : [ function ( require , module , exports ) {
var bundleFn = arguments [ 3 ] ;
var sources = arguments [ 4 ] ;
var cache = arguments [ 5 ] ;
var stringify = JSON . stringify ;
module . exports = function ( fn , options ) {
var wkey ;
var cacheKeys = Object . keys ( cache ) ;
for ( var i = 0 , l = cacheKeys . length ; i < l ; i ++ ) {
var key = cacheKeys [ i ] ;
var exp = cache [ key ] . exports ;
// Using babel as a transpiler to use esmodule, the export will always
// be an object with the default export as a property of it. To ensure
// the existing api and babel esmodule exports are both supported we
// check for both
if ( exp === fn || exp && exp . default === fn ) {
wkey = key ;
break ;
}
}
if ( ! wkey ) {
wkey = Math . floor ( Math . pow ( 16 , 8 ) * Math . random ( ) ) . toString ( 16 ) ;
var wcache = { } ;
for ( var i = 0 , l = cacheKeys . length ; i < l ; i ++ ) {
var key = cacheKeys [ i ] ;
wcache [ key ] = key ;
}
sources [ wkey ] = [
'function(require,module,exports){' + fn + '(self); }' ,
wcache
] ;
}
var skey = Math . floor ( Math . pow ( 16 , 8 ) * Math . random ( ) ) . toString ( 16 ) ;
var scache = { } ; scache [ wkey ] = wkey ;
sources [ skey ] = [
'function(require,module,exports){' +
// try to call default if defined to also support babel esmodule exports
'var f = require(' + stringify ( wkey ) + ');' +
'(f.default ? f.default : f)(self);' +
'}' ,
scache
] ;
var workerSources = { } ;
resolveSources ( skey ) ;
function resolveSources ( key ) {
workerSources [ key ] = true ;
for ( var depPath in sources [ key ] [ 1 ] ) {
var depKey = sources [ key ] [ 1 ] [ depPath ] ;
if ( ! workerSources [ depKey ] ) {
resolveSources ( depKey ) ;
}
}
}
var src = '(' + bundleFn + ')({'
+ Object . keys ( workerSources ) . map ( function ( key ) {
return stringify ( key ) + ':['
+ sources [ key ] [ 0 ]
+ ',' + stringify ( sources [ key ] [ 1 ] ) + ']'
;
} ) . join ( ',' )
+ '},{},[' + stringify ( skey ) + '])'
;
var URL = window . URL || window . webkitURL || window . mozURL || window . msURL ;
var blob = new Blob ( [ src ] , { type : 'text/javascript' } ) ;
if ( options && options . bare ) { return blob ; }
var workerUrl = URL . createObjectURL ( blob ) ;
var worker = new Worker ( workerUrl ) ;
worker . objectURL = workerUrl ;
return worker ;
} ;
2015-05-29 16:21:09 -04:00
2019-03-27 17:43:00 -04:00
} , { } ] , 6 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
/ * *
2019-03-27 17:43:00 -04:00
* @ fileOverview
2015-05-29 16:21:09 -04:00
* @ author Russell Toris - rctoris @ wpi . edu
* /
2019-03-27 17:43:00 -04:00
/ * *
* If you use roslib in a browser , all the classes will be exported to a global variable called ROSLIB .
*
* If you use nodejs , this is the variable you get when you require ( 'roslib' )
* /
2015-05-29 16:21:09 -04:00
var ROSLIB = this . ROSLIB || {
2019-03-27 17:43:00 -04:00
REVISION : '1.0.1'
2015-05-29 16:21:09 -04:00
} ;
var assign = require ( 'object-assign' ) ;
// Add core components
assign ( ROSLIB , require ( './core' ) ) ;
assign ( ROSLIB , require ( './actionlib' ) ) ;
assign ( ROSLIB , require ( './math' ) ) ;
assign ( ROSLIB , require ( './tf' ) ) ;
assign ( ROSLIB , require ( './urdf' ) ) ;
module . exports = ROSLIB ;
2019-03-27 17:43:00 -04:00
} , { "./actionlib" : 12 , "./core" : 21 , "./math" : 26 , "./tf" : 29 , "./urdf" : 41 , "object-assign" : 3 } ] , 7 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
( function ( global ) {
global . ROSLIB = require ( './RosLib' ) ;
} ) . call ( this , typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : { } )
2019-03-27 17:43:00 -04:00
} , { "./RosLib" : 6 } ] , 8 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
/ * *
2019-03-27 17:43:00 -04:00
* @ fileOverview
2015-05-29 16:21:09 -04:00
* @ author Russell Toris - rctoris @ wpi . edu
* /
var Topic = require ( '../core/Topic' ) ;
var Message = require ( '../core/Message' ) ;
2019-03-27 17:43:00 -04:00
var EventEmitter2 = require ( 'eventemitter2' ) . EventEmitter2 ;
2015-05-29 16:21:09 -04:00
/ * *
* An actionlib action client .
*
* Emits the following events :
* * 'timeout' - if a timeout occurred while sending a goal
* * 'status' - the status messages received from the action server
* * 'feedback' - the feedback messages received from the action server
* * 'result' - the result returned from the action server
*
* @ constructor
* @ param options - object with following keys :
* * ros - the ROSLIB . Ros connection handle
* * serverName - the action server name , like / fibonacci
* * actionName - the action message name , like 'actionlib_tutorials/FibonacciAction'
* * timeout - the timeout length when connecting to the action server
* /
function ActionClient ( options ) {
var that = this ;
options = options || { } ;
this . ros = options . ros ;
this . serverName = options . serverName ;
this . actionName = options . actionName ;
this . timeout = options . timeout ;
2019-03-27 17:43:00 -04:00
this . omitFeedback = options . omitFeedback ;
this . omitStatus = options . omitStatus ;
this . omitResult = options . omitResult ;
2015-05-29 16:21:09 -04:00
this . goals = { } ;
// flag to check if a status has been received
var receivedStatus = false ;
// create the topics associated with actionlib
2019-03-27 17:43:00 -04:00
this . feedbackListener = new Topic ( {
2015-05-29 16:21:09 -04:00
ros : this . ros ,
name : this . serverName + '/feedback' ,
messageType : this . actionName + 'Feedback'
} ) ;
2019-03-27 17:43:00 -04:00
this . statusListener = new Topic ( {
2015-05-29 16:21:09 -04:00
ros : this . ros ,
name : this . serverName + '/status' ,
messageType : 'actionlib_msgs/GoalStatusArray'
} ) ;
2019-03-27 17:43:00 -04:00
this . resultListener = new Topic ( {
2015-05-29 16:21:09 -04:00
ros : this . ros ,
name : this . serverName + '/result' ,
messageType : this . actionName + 'Result'
} ) ;
this . goalTopic = new Topic ( {
ros : this . ros ,
name : this . serverName + '/goal' ,
messageType : this . actionName + 'Goal'
} ) ;
this . cancelTopic = new Topic ( {
ros : this . ros ,
name : this . serverName + '/cancel' ,
messageType : 'actionlib_msgs/GoalID'
} ) ;
// advertise the goal and cancel topics
this . goalTopic . advertise ( ) ;
this . cancelTopic . advertise ( ) ;
// subscribe to the status topic
2019-03-27 17:43:00 -04:00
if ( ! this . omitStatus ) {
this . statusListener . subscribe ( function ( statusMessage ) {
receivedStatus = true ;
statusMessage . status _list . forEach ( function ( status ) {
var goal = that . goals [ status . goal _id . id ] ;
if ( goal ) {
goal . emit ( 'status' , status ) ;
}
} ) ;
2015-05-29 16:21:09 -04:00
} ) ;
2019-03-27 17:43:00 -04:00
}
2015-05-29 16:21:09 -04:00
// subscribe the the feedback topic
2019-03-27 17:43:00 -04:00
if ( ! this . omitFeedback ) {
this . feedbackListener . subscribe ( function ( feedbackMessage ) {
var goal = that . goals [ feedbackMessage . status . goal _id . id ] ;
if ( goal ) {
goal . emit ( 'status' , feedbackMessage . status ) ;
goal . emit ( 'feedback' , feedbackMessage . feedback ) ;
}
} ) ;
}
2015-05-29 16:21:09 -04:00
// subscribe to the result topic
2019-03-27 17:43:00 -04:00
if ( ! this . omitResult ) {
this . resultListener . subscribe ( function ( resultMessage ) {
var goal = that . goals [ resultMessage . status . goal _id . id ] ;
2015-05-29 16:21:09 -04:00
2019-03-27 17:43:00 -04:00
if ( goal ) {
goal . emit ( 'status' , resultMessage . status ) ;
goal . emit ( 'result' , resultMessage . result ) ;
}
} ) ;
}
2015-05-29 16:21:09 -04:00
// If timeout specified, emit a 'timeout' event if the action server does not respond
if ( this . timeout ) {
setTimeout ( function ( ) {
if ( ! receivedStatus ) {
that . emit ( 'timeout' ) ;
}
} , this . timeout ) ;
}
}
ActionClient . prototype . _ _proto _ _ = EventEmitter2 . prototype ;
/ * *
* Cancel all goals associated with this ActionClient .
* /
ActionClient . prototype . cancel = function ( ) {
var cancelMessage = new Message ( ) ;
this . cancelTopic . publish ( cancelMessage ) ;
} ;
2019-03-27 17:43:00 -04:00
/ * *
* Unsubscribe and unadvertise all topics associated with this ActionClient .
* /
ActionClient . prototype . dispose = function ( ) {
this . goalTopic . unadvertise ( ) ;
this . cancelTopic . unadvertise ( ) ;
if ( ! this . omitStatus ) { this . statusListener . unsubscribe ( ) ; }
if ( ! this . omitFeedback ) { this . feedbackListener . unsubscribe ( ) ; }
if ( ! this . omitResult ) { this . resultListener . unsubscribe ( ) ; }
} ;
2015-05-29 16:21:09 -04:00
module . exports = ActionClient ;
2019-03-27 17:43:00 -04:00
} , { "../core/Message" : 13 , "../core/Topic" : 20 , "eventemitter2" : 2 } ] , 9 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
/ * *
2019-03-27 17:43:00 -04:00
* @ fileOverview
* @ author Justin Young - justin @ oodar . com . au
2015-05-29 16:21:09 -04:00
* @ author Russell Toris - rctoris @ wpi . edu
* /
2019-03-27 17:43:00 -04:00
var Topic = require ( '../core/Topic' ) ;
2015-05-29 16:21:09 -04:00
var Message = require ( '../core/Message' ) ;
2019-03-27 17:43:00 -04:00
var EventEmitter2 = require ( 'eventemitter2' ) . EventEmitter2 ;
/ * *
* An actionlib action listener
*
* Emits the following events :
* * 'status' - the status messages received from the action server
* * 'feedback' - the feedback messages received from the action server
* * 'result' - the result returned from the action server
*
* @ constructor
* @ param options - object with following keys :
* * ros - the ROSLIB . Ros connection handle
* * serverName - the action server name , like / fibonacci
* * actionName - the action message name , like 'actionlib_tutorials/FibonacciAction'
* /
function ActionListener ( options ) {
var that = this ;
options = options || { } ;
this . ros = options . ros ;
this . serverName = options . serverName ;
this . actionName = options . actionName ;
this . timeout = options . timeout ;
this . omitFeedback = options . omitFeedback ;
this . omitStatus = options . omitStatus ;
this . omitResult = options . omitResult ;
// create the topics associated with actionlib
var goalListener = new Topic ( {
ros : this . ros ,
name : this . serverName + '/goal' ,
messageType : this . actionName + 'Goal'
} ) ;
var feedbackListener = new Topic ( {
ros : this . ros ,
name : this . serverName + '/feedback' ,
messageType : this . actionName + 'Feedback'
} ) ;
var statusListener = new Topic ( {
ros : this . ros ,
name : this . serverName + '/status' ,
messageType : 'actionlib_msgs/GoalStatusArray'
} ) ;
var resultListener = new Topic ( {
ros : this . ros ,
name : this . serverName + '/result' ,
messageType : this . actionName + 'Result'
} ) ;
goalListener . subscribe ( function ( goalMessage ) {
that . emit ( 'goal' , goalMessage ) ;
} ) ;
statusListener . subscribe ( function ( statusMessage ) {
statusMessage . status _list . forEach ( function ( status ) {
that . emit ( 'status' , status ) ;
} ) ;
} ) ;
feedbackListener . subscribe ( function ( feedbackMessage ) {
that . emit ( 'status' , feedbackMessage . status ) ;
that . emit ( 'feedback' , feedbackMessage . feedback ) ;
} ) ;
// subscribe to the result topic
resultListener . subscribe ( function ( resultMessage ) {
that . emit ( 'status' , resultMessage . status ) ;
that . emit ( 'result' , resultMessage . result ) ;
} ) ;
}
ActionListener . prototype . _ _proto _ _ = EventEmitter2 . prototype ;
module . exports = ActionListener ;
} , { "../core/Message" : 13 , "../core/Topic" : 20 , "eventemitter2" : 2 } ] , 10 : [ function ( require , module , exports ) {
/ * *
* @ fileOverview
* @ author Russell Toris - rctoris @ wpi . edu
* /
var Message = require ( '../core/Message' ) ;
var EventEmitter2 = require ( 'eventemitter2' ) . EventEmitter2 ;
2015-05-29 16:21:09 -04:00
/ * *
* An actionlib goal goal is associated with an action server .
*
* Emits the following events :
* * 'timeout' - if a timeout occurred while sending a goal
*
* @ constructor
* @ param object with following keys :
* * actionClient - the ROSLIB . ActionClient to use with this goal
* * goalMessage - The JSON object containing the goal for the action server
* /
function Goal ( options ) {
var that = this ;
this . actionClient = options . actionClient ;
this . goalMessage = options . goalMessage ;
this . isFinished = false ;
// Used to create random IDs
var date = new Date ( ) ;
// Create a random ID
this . goalID = 'goal_' + Math . random ( ) + '_' + date . getTime ( ) ;
// Fill in the goal message
this . goalMessage = new Message ( {
goal _id : {
stamp : {
secs : 0 ,
nsecs : 0
} ,
id : this . goalID
} ,
goal : this . goalMessage
} ) ;
this . on ( 'status' , function ( status ) {
that . status = status ;
} ) ;
this . on ( 'result' , function ( result ) {
that . isFinished = true ;
that . result = result ;
} ) ;
this . on ( 'feedback' , function ( feedback ) {
that . feedback = feedback ;
} ) ;
// Add the goal
this . actionClient . goals [ this . goalID ] = this ;
}
Goal . prototype . _ _proto _ _ = EventEmitter2 . prototype ;
/ * *
* Send the goal to the action server .
*
* @ param timeout ( optional ) - a timeout length for the goal ' s result
* /
Goal . prototype . send = function ( timeout ) {
var that = this ;
that . actionClient . goalTopic . publish ( that . goalMessage ) ;
if ( timeout ) {
setTimeout ( function ( ) {
if ( ! that . isFinished ) {
that . emit ( 'timeout' ) ;
}
} , timeout ) ;
}
} ;
/ * *
* Cancel the current goal .
* /
Goal . prototype . cancel = function ( ) {
var cancelMessage = new Message ( {
id : this . goalID
} ) ;
this . actionClient . cancelTopic . publish ( cancelMessage ) ;
} ;
module . exports = Goal ;
2019-03-27 17:43:00 -04:00
} , { "../core/Message" : 13 , "eventemitter2" : 2 } ] , 11 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
/ * *
2019-03-27 17:43:00 -04:00
* @ fileOverview
2015-05-29 16:21:09 -04:00
* @ author Laura Lindzey - lindzey @ gmail . com
* /
var Topic = require ( '../core/Topic' ) ;
var Message = require ( '../core/Message' ) ;
2019-03-27 17:43:00 -04:00
var EventEmitter2 = require ( 'eventemitter2' ) . EventEmitter2 ;
2015-05-29 16:21:09 -04:00
/ * *
* An actionlib action server client .
*
* Emits the following events :
* * 'goal' - goal sent by action client
* * 'cancel' - action client has canceled the request
*
* @ constructor
* @ param options - object with following keys :
* * ros - the ROSLIB . Ros connection handle
* * serverName - the action server name , like / fibonacci
* * actionName - the action message name , like 'actionlib_tutorials/FibonacciAction'
* /
function SimpleActionServer ( options ) {
var that = this ;
options = options || { } ;
this . ros = options . ros ;
this . serverName = options . serverName ;
this . actionName = options . actionName ;
// create and advertise publishers
this . feedbackPublisher = new Topic ( {
ros : this . ros ,
name : this . serverName + '/feedback' ,
messageType : this . actionName + 'Feedback'
} ) ;
this . feedbackPublisher . advertise ( ) ;
var statusPublisher = new Topic ( {
ros : this . ros ,
name : this . serverName + '/status' ,
messageType : 'actionlib_msgs/GoalStatusArray'
} ) ;
statusPublisher . advertise ( ) ;
this . resultPublisher = new Topic ( {
ros : this . ros ,
name : this . serverName + '/result' ,
messageType : this . actionName + 'Result'
} ) ;
this . resultPublisher . advertise ( ) ;
// create and subscribe to listeners
var goalListener = new Topic ( {
ros : this . ros ,
name : this . serverName + '/goal' ,
messageType : this . actionName + 'Goal'
} ) ;
var cancelListener = new Topic ( {
ros : this . ros ,
name : this . serverName + '/cancel' ,
messageType : 'actionlib_msgs/GoalID'
} ) ;
// Track the goals and their status in order to publish status...
this . statusMessage = new Message ( {
header : {
stamp : { secs : 0 , nsecs : 100 } ,
frame _id : ''
} ,
status _list : [ ]
} ) ;
// needed for handling preemption prompted by a new goal being received
this . currentGoal = null ; // currently tracked goal
this . nextGoal = null ; // the one that'll be preempting
goalListener . subscribe ( function ( goalMessage ) {
if ( that . currentGoal ) {
that . nextGoal = goalMessage ;
// needs to happen AFTER rest is set up
that . emit ( 'cancel' ) ;
} else {
that . statusMessage . status _list = [ { goal _id : goalMessage . goal _id , status : 1 } ] ;
that . currentGoal = goalMessage ;
that . emit ( 'goal' , goalMessage . goal ) ;
}
} ) ;
// helper function for determing ordering of timestamps
// returns t1 < t2
var isEarlier = function ( t1 , t2 ) {
if ( t1 . secs > t2 . secs ) {
return false ;
} else if ( t1 . secs < t2 . secs ) {
return true ;
} else if ( t1 . nsecs < t2 . nsecs ) {
return true ;
} else {
return false ;
}
} ;
// TODO: this may be more complicated than necessary, since I'm
// not sure if the callbacks can ever wind up with a scenario
// where we've been preempted by a next goal, it hasn't finished
// processing, and then we get a cancel message
cancelListener . subscribe ( function ( cancelMessage ) {
// cancel ALL goals if both empty
if ( cancelMessage . stamp . secs === 0 && cancelMessage . stamp . secs === 0 && cancelMessage . id === '' ) {
that . nextGoal = null ;
if ( that . currentGoal ) {
that . emit ( 'cancel' ) ;
}
} else { // treat id and stamp independently
if ( that . currentGoal && cancelMessage . id === that . currentGoal . goal _id . id ) {
that . emit ( 'cancel' ) ;
} else if ( that . nextGoal && cancelMessage . id === that . nextGoal . goal _id . id ) {
that . nextGoal = null ;
}
if ( that . nextGoal && isEarlier ( that . nextGoal . goal _id . stamp ,
cancelMessage . stamp ) ) {
that . nextGoal = null ;
}
if ( that . currentGoal && isEarlier ( that . currentGoal . goal _id . stamp ,
cancelMessage . stamp ) ) {
that . emit ( 'cancel' ) ;
}
}
} ) ;
// publish status at pseudo-fixed rate; required for clients to know they've connected
var statusInterval = setInterval ( function ( ) {
var currentTime = new Date ( ) ;
var secs = Math . floor ( currentTime . getTime ( ) / 1000 ) ;
var nsecs = Math . round ( 1000000000 * ( currentTime . getTime ( ) / 1000 - secs ) ) ;
that . statusMessage . header . stamp . secs = secs ;
that . statusMessage . header . stamp . nsecs = nsecs ;
statusPublisher . publish ( that . statusMessage ) ;
} , 500 ) ; // publish every 500ms
}
SimpleActionServer . prototype . _ _proto _ _ = EventEmitter2 . prototype ;
/ * *
* Set action state to succeeded and return to client
* /
SimpleActionServer . prototype . setSucceeded = function ( result2 ) {
var resultMessage = new Message ( {
status : { goal _id : this . currentGoal . goal _id , status : 3 } ,
result : result2
} ) ;
this . resultPublisher . publish ( resultMessage ) ;
this . statusMessage . status _list = [ ] ;
if ( this . nextGoal ) {
this . currentGoal = this . nextGoal ;
this . nextGoal = null ;
this . emit ( 'goal' , this . currentGoal . goal ) ;
} else {
this . currentGoal = null ;
}
} ;
/ * *
* Function to send feedback
* /
SimpleActionServer . prototype . sendFeedback = function ( feedback2 ) {
var feedbackMessage = new Message ( {
status : { goal _id : this . currentGoal . goal _id , status : 1 } ,
feedback : feedback2
} ) ;
this . feedbackPublisher . publish ( feedbackMessage ) ;
} ;
/ * *
* Handle case where client requests preemption
* /
SimpleActionServer . prototype . setPreempted = function ( ) {
this . statusMessage . status _list = [ ] ;
var resultMessage = new Message ( {
status : { goal _id : this . currentGoal . goal _id , status : 2 } ,
} ) ;
this . resultPublisher . publish ( resultMessage ) ;
if ( this . nextGoal ) {
this . currentGoal = this . nextGoal ;
this . nextGoal = null ;
this . emit ( 'goal' , this . currentGoal . goal ) ;
} else {
this . currentGoal = null ;
}
} ;
module . exports = SimpleActionServer ;
2019-03-27 17:43:00 -04:00
} , { "../core/Message" : 13 , "../core/Topic" : 20 , "eventemitter2" : 2 } ] , 12 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
var Ros = require ( '../core/Ros' ) ;
var mixin = require ( '../mixin' ) ;
var action = module . exports = {
ActionClient : require ( './ActionClient' ) ,
2019-03-27 17:43:00 -04:00
ActionListener : require ( './ActionListener' ) ,
2015-05-29 16:21:09 -04:00
Goal : require ( './Goal' ) ,
SimpleActionServer : require ( './SimpleActionServer' )
} ;
mixin ( Ros , [ 'ActionClient' , 'SimpleActionServer' ] , action ) ;
2019-03-27 17:43:00 -04:00
} , { "../core/Ros" : 15 , "../mixin" : 27 , "./ActionClient" : 8 , "./ActionListener" : 9 , "./Goal" : 10 , "./SimpleActionServer" : 11 } ] , 13 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
/ * *
2019-03-27 17:43:00 -04:00
* @ fileoverview
2015-05-29 16:21:09 -04:00
* @ author Brandon Alexander - baalexander @ gmail . com
* /
var assign = require ( 'object-assign' ) ;
/ * *
* Message objects are used for publishing and subscribing to and from topics .
*
* @ constructor
* @ param values - object matching the fields defined in the . msg definition file
* /
function Message ( values ) {
assign ( this , values ) ;
}
module . exports = Message ;
2019-03-27 17:43:00 -04:00
} , { "object-assign" : 3 } ] , 14 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
/ * *
2019-03-27 17:43:00 -04:00
* @ fileoverview
2015-05-29 16:21:09 -04:00
* @ author Brandon Alexander - baalexander @ gmail . com
* /
var Service = require ( './Service' ) ;
var ServiceRequest = require ( './ServiceRequest' ) ;
/ * *
* A ROS parameter .
*
* @ constructor
* @ param options - possible keys include :
* * ros - the ROSLIB . Ros connection handle
* * name - the param name , like max _vel _x
* /
function Param ( options ) {
options = options || { } ;
this . ros = options . ros ;
this . name = options . name ;
}
/ * *
* Fetches the value of the param .
*
* @ param callback - function with the following params :
* * value - the value of the param from ROS .
* /
Param . prototype . get = function ( callback ) {
var paramClient = new Service ( {
ros : this . ros ,
name : '/rosapi/get_param' ,
serviceType : 'rosapi/GetParam'
} ) ;
var request = new ServiceRequest ( {
name : this . name
} ) ;
paramClient . callService ( request , function ( result ) {
var value = JSON . parse ( result . value ) ;
callback ( value ) ;
} ) ;
} ;
/ * *
* Sets the value of the param in ROS .
*
* @ param value - value to set param to .
* /
Param . prototype . set = function ( value , callback ) {
var paramClient = new Service ( {
ros : this . ros ,
name : '/rosapi/set_param' ,
serviceType : 'rosapi/SetParam'
} ) ;
var request = new ServiceRequest ( {
name : this . name ,
value : JSON . stringify ( value )
} ) ;
paramClient . callService ( request , callback ) ;
} ;
/ * *
* Delete this parameter on the ROS server .
* /
Param . prototype . delete = function ( callback ) {
var paramClient = new Service ( {
ros : this . ros ,
name : '/rosapi/delete_param' ,
serviceType : 'rosapi/DeleteParam'
} ) ;
var request = new ServiceRequest ( {
name : this . name
} ) ;
paramClient . callService ( request , callback ) ;
} ;
module . exports = Param ;
2019-03-27 17:43:00 -04:00
} , { "./Service" : 16 , "./ServiceRequest" : 17 } ] , 15 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
/ * *
2019-03-27 17:43:00 -04:00
* @ fileoverview
2015-05-29 16:21:09 -04:00
* @ author Brandon Alexander - baalexander @ gmail . com
* /
2019-03-27 17:43:00 -04:00
var WebSocket = require ( 'ws' ) ;
var WorkerSocket = require ( '../util/workerSocket' ) ;
2015-05-29 16:21:09 -04:00
var socketAdapter = require ( './SocketAdapter.js' ) ;
var Service = require ( './Service' ) ;
var ServiceRequest = require ( './ServiceRequest' ) ;
var assign = require ( 'object-assign' ) ;
2019-03-27 17:43:00 -04:00
var EventEmitter2 = require ( 'eventemitter2' ) . EventEmitter2 ;
2015-05-29 16:21:09 -04:00
/ * *
* Manages connection to the server and all interactions with ROS .
*
* Emits the following events :
* * 'error' - there was an error with ROS
* * 'connection' - connected to the WebSocket server
* * 'close' - disconnected to the WebSocket server
* * < topicName > - a message came from rosbridge with the given topic name
* * < serviceID > - a service response came from rosbridge with the given ID
*
* @ constructor
2019-03-27 17:43:00 -04:00
* @ param options - possible keys include : < br >
* * url ( optional ) - ( can be specified later with ` connect ` ) the WebSocket URL for rosbridge or the node server url to connect using socket . io ( if socket . io exists in the page ) < br >
* * groovyCompatibility - don ' t use interfaces that changed after the last groovy release or rosbridge _suite and related tools ( defaults to true )
* * transportLibrary ( optional ) - one of 'websocket' , 'workersocket' ( default ) , 'socket.io' or RTCPeerConnection instance controlling how the connection is created in ` connect ` .
* * transportOptions ( optional ) - the options to use use when creating a connection . Currently only used if ` transportLibrary ` is RTCPeerConnection .
2015-05-29 16:21:09 -04:00
* /
function Ros ( options ) {
options = options || { } ;
this . socket = null ;
this . idCounter = 0 ;
this . isConnected = false ;
2019-03-27 17:43:00 -04:00
this . transportLibrary = options . transportLibrary || 'websocket' ;
this . transportOptions = options . transportOptions || { } ;
2015-05-29 16:21:09 -04:00
if ( typeof options . groovyCompatibility === 'undefined' ) {
this . groovyCompatibility = true ;
}
else {
this . groovyCompatibility = options . groovyCompatibility ;
}
// Sets unlimited event listeners.
this . setMaxListeners ( 0 ) ;
// begin by checking if a URL was given
if ( options . url ) {
this . connect ( options . url ) ;
}
}
Ros . prototype . _ _proto _ _ = EventEmitter2 . prototype ;
/ * *
* Connect to the specified WebSocket .
*
2019-03-27 17:43:00 -04:00
* @ param url - WebSocket URL or RTCDataChannel label for Rosbridge
2015-05-29 16:21:09 -04:00
* /
Ros . prototype . connect = function ( url ) {
2019-03-27 17:43:00 -04:00
if ( this . transportLibrary === 'socket.io' ) {
this . socket = assign ( io ( url , { 'force new connection' : true } ) , socketAdapter ( this ) ) ;
this . socket . on ( 'connect' , this . socket . onopen ) ;
this . socket . on ( 'data' , this . socket . onmessage ) ;
this . socket . on ( 'close' , this . socket . onclose ) ;
this . socket . on ( 'error' , this . socket . onerror ) ;
} else if ( this . transportLibrary . constructor . name === 'RTCPeerConnection' ) {
this . socket = assign ( this . transportLibrary . createDataChannel ( url , this . transportOptions ) , socketAdapter ( this ) ) ;
} else if ( this . transportLibrary === 'websocket' ) {
if ( ! this . socket || this . socket . readyState === WebSocket . CLOSED ) {
var sock = new WebSocket ( url ) ;
sock . binaryType = 'arraybuffer' ;
this . socket = assign ( sock , socketAdapter ( this ) ) ;
}
} else if ( this . transportLibrary === 'workersocket' ) {
this . socket = assign ( new WorkerSocket ( url ) , socketAdapter ( this ) ) ;
} else {
throw 'Unknown transportLibrary: ' + this . transportLibrary . toString ( ) ;
}
2015-05-29 16:21:09 -04:00
} ;
/ * *
* Disconnect from the WebSocket server .
* /
Ros . prototype . close = function ( ) {
if ( this . socket ) {
this . socket . close ( ) ;
}
} ;
/ * *
* Sends an authorization request to the server .
*
* @ param mac - MAC ( hash ) string given by the trusted source .
* @ param client - IP of the client .
* @ param dest - IP of the destination .
* @ param rand - Random string given by the trusted source .
* @ param t - Time of the authorization request .
* @ param level - User level as a string given by the client .
* @ param end - End time of the client ' s session .
* /
Ros . prototype . authenticate = function ( mac , client , dest , rand , t , level , end ) {
// create the request
var auth = {
op : 'auth' ,
mac : mac ,
client : client ,
dest : dest ,
rand : rand ,
t : t ,
level : level ,
end : end
} ;
// send the request
this . callOnConnection ( auth ) ;
} ;
/ * *
* Sends the message over the WebSocket , but queues the message up if not yet
* connected .
* /
Ros . prototype . callOnConnection = function ( message ) {
var that = this ;
var messageJson = JSON . stringify ( message ) ;
2019-03-27 17:43:00 -04:00
var emitter = null ;
if ( this . transportLibrary === 'socket.io' ) {
emitter = function ( msg ) { that . socket . emit ( 'operation' , msg ) ; } ;
} else {
emitter = function ( msg ) { that . socket . send ( msg ) ; } ;
}
2015-05-29 16:21:09 -04:00
if ( ! this . isConnected ) {
that . once ( 'connection' , function ( ) {
2019-03-27 17:43:00 -04:00
emitter ( messageJson ) ;
2015-05-29 16:21:09 -04:00
} ) ;
} else {
2019-03-27 17:43:00 -04:00
emitter ( messageJson ) ;
}
} ;
/ * *
* Sends a set _level request to the server
*
* @ param level - Status level ( none , error , warning , info )
* @ param id - Optional : Operation ID to change status level on
* /
Ros . prototype . setStatusLevel = function ( level , id ) {
var levelMsg = {
op : 'set_level' ,
level : level ,
id : id
} ;
this . callOnConnection ( levelMsg ) ;
} ;
/ * *
* Retrieves Action Servers in ROS as an array of string
*
* * actionservers - Array of action server names
* /
Ros . prototype . getActionServers = function ( callback , failedCallback ) {
var getActionServers = new Service ( {
ros : this ,
name : '/rosapi/action_servers' ,
serviceType : 'rosapi/GetActionServers'
} ) ;
var request = new ServiceRequest ( { } ) ;
if ( typeof failedCallback === 'function' ) {
getActionServers . callService ( request ,
function ( result ) {
callback ( result . action _servers ) ;
} ,
function ( message ) {
failedCallback ( message ) ;
}
) ;
} else {
getActionServers . callService ( request , function ( result ) {
callback ( result . action _servers ) ;
} ) ;
2015-05-29 16:21:09 -04:00
}
} ;
/ * *
* Retrieves list of topics in ROS as an array .
*
* @ param callback function with params :
* * topics - Array of topic names
* /
2019-03-27 17:43:00 -04:00
Ros . prototype . getTopics = function ( callback , failedCallback ) {
2015-05-29 16:21:09 -04:00
var topicsClient = new Service ( {
ros : this ,
name : '/rosapi/topics' ,
serviceType : 'rosapi/Topics'
} ) ;
var request = new ServiceRequest ( ) ;
2019-03-27 17:43:00 -04:00
if ( typeof failedCallback === 'function' ) {
topicsClient . callService ( request ,
function ( result ) {
callback ( result ) ;
} ,
function ( message ) {
failedCallback ( message ) ;
}
) ;
} else {
topicsClient . callService ( request , function ( result ) {
callback ( result ) ;
} ) ;
}
2015-05-29 16:21:09 -04:00
} ;
/ * *
* Retrieves Topics in ROS as an array as specific type
*
* @ param topicType topic type to find :
* @ param callback function with params :
* * topics - Array of topic names
* /
2019-03-27 17:43:00 -04:00
Ros . prototype . getTopicsForType = function ( topicType , callback , failedCallback ) {
2015-05-29 16:21:09 -04:00
var topicsForTypeClient = new Service ( {
ros : this ,
name : '/rosapi/topics_for_type' ,
serviceType : 'rosapi/TopicsForType'
} ) ;
var request = new ServiceRequest ( {
type : topicType
} ) ;
2019-03-27 17:43:00 -04:00
if ( typeof failedCallback === 'function' ) {
topicsForTypeClient . callService ( request ,
function ( result ) {
callback ( result . topics ) ;
} ,
function ( message ) {
failedCallback ( message ) ;
}
) ;
} else {
topicsForTypeClient . callService ( request , function ( result ) {
callback ( result . topics ) ;
} ) ;
}
2015-05-29 16:21:09 -04:00
} ;
/ * *
* Retrieves list of active service names in ROS .
*
* @ param callback - function with the following params :
* * services - array of service names
* /
2019-03-27 17:43:00 -04:00
Ros . prototype . getServices = function ( callback , failedCallback ) {
2015-05-29 16:21:09 -04:00
var servicesClient = new Service ( {
ros : this ,
name : '/rosapi/services' ,
serviceType : 'rosapi/Services'
} ) ;
var request = new ServiceRequest ( ) ;
2019-03-27 17:43:00 -04:00
if ( typeof failedCallback === 'function' ) {
servicesClient . callService ( request ,
function ( result ) {
callback ( result . services ) ;
} ,
function ( message ) {
failedCallback ( message ) ;
}
) ;
} else {
servicesClient . callService ( request , function ( result ) {
callback ( result . services ) ;
} ) ;
}
2015-05-29 16:21:09 -04:00
} ;
/ * *
* Retrieves list of services in ROS as an array as specific type
*
* @ param serviceType service type to find :
* @ param callback function with params :
* * topics - Array of service names
* /
2019-03-27 17:43:00 -04:00
Ros . prototype . getServicesForType = function ( serviceType , callback , failedCallback ) {
2015-05-29 16:21:09 -04:00
var servicesForTypeClient = new Service ( {
ros : this ,
name : '/rosapi/services_for_type' ,
serviceType : 'rosapi/ServicesForType'
} ) ;
var request = new ServiceRequest ( {
type : serviceType
} ) ;
2019-03-27 17:43:00 -04:00
if ( typeof failedCallback === 'function' ) {
servicesForTypeClient . callService ( request ,
function ( result ) {
callback ( result . services ) ;
} ,
function ( message ) {
failedCallback ( message ) ;
}
) ;
} else {
servicesForTypeClient . callService ( request , function ( result ) {
callback ( result . services ) ;
} ) ;
}
} ;
2015-05-29 16:21:09 -04:00
2019-03-27 17:43:00 -04:00
/ * *
* Retrieves a detail of ROS service request .
*
* @ param service name of service :
* @ param callback - function with params :
* * type - String of the service type
* /
Ros . prototype . getServiceRequestDetails = function ( type , callback , failedCallback ) {
var serviceTypeClient = new Service ( {
ros : this ,
name : '/rosapi/service_request_details' ,
serviceType : 'rosapi/ServiceRequestDetails'
} ) ;
var request = new ServiceRequest ( {
type : type
2015-05-29 16:21:09 -04:00
} ) ;
2019-03-27 17:43:00 -04:00
if ( typeof failedCallback === 'function' ) {
serviceTypeClient . callService ( request ,
function ( result ) {
callback ( result ) ;
} ,
function ( message ) {
failedCallback ( message ) ;
}
) ;
} else {
serviceTypeClient . callService ( request , function ( result ) {
callback ( result ) ;
} ) ;
}
} ;
/ * *
* Retrieves a detail of ROS service request .
*
* @ param service name of service :
* @ param callback - function with params :
* * type - String of the service type
* /
Ros . prototype . getServiceResponseDetails = function ( type , callback , failedCallback ) {
var serviceTypeClient = new Service ( {
ros : this ,
name : '/rosapi/service_response_details' ,
serviceType : 'rosapi/ServiceResponseDetails'
} ) ;
var request = new ServiceRequest ( {
type : type
} ) ;
if ( typeof failedCallback === 'function' ) {
serviceTypeClient . callService ( request ,
function ( result ) {
callback ( result ) ;
} ,
function ( message ) {
failedCallback ( message ) ;
}
) ;
} else {
serviceTypeClient . callService ( request , function ( result ) {
callback ( result ) ;
} ) ;
}
2015-05-29 16:21:09 -04:00
} ;
/ * *
* Retrieves list of active node names in ROS .
*
* @ param callback - function with the following params :
* * nodes - array of node names
* /
2019-03-27 17:43:00 -04:00
Ros . prototype . getNodes = function ( callback , failedCallback ) {
2015-05-29 16:21:09 -04:00
var nodesClient = new Service ( {
ros : this ,
name : '/rosapi/nodes' ,
serviceType : 'rosapi/Nodes'
} ) ;
var request = new ServiceRequest ( ) ;
2019-03-27 17:43:00 -04:00
if ( typeof failedCallback === 'function' ) {
nodesClient . callService ( request ,
function ( result ) {
callback ( result . nodes ) ;
} ,
function ( message ) {
failedCallback ( message ) ;
}
) ;
} else {
nodesClient . callService ( request , function ( result ) {
callback ( result . nodes ) ;
} ) ;
}
} ;
2015-05-29 16:21:09 -04:00
2019-03-27 17:43:00 -04:00
/ * *
* Retrieves list subscribed topics , publishing topics and services of a specific node
*
* @ param node name of the node :
* @ param callback - function with params :
* * publications - array of published topic names
* * subscriptions - array of subscribed topic names
* * services - array of service names hosted
* /
Ros . prototype . getNodeDetails = function ( node , callback , failedCallback ) {
var nodesClient = new Service ( {
ros : this ,
name : '/rosapi/node_details' ,
serviceType : 'rosapi/NodeDetails'
} ) ;
var request = new ServiceRequest ( {
node : node
2015-05-29 16:21:09 -04:00
} ) ;
2019-03-27 17:43:00 -04:00
if ( typeof failedCallback === 'function' ) {
nodesClient . callService ( request ,
function ( result ) {
callback ( result . subscribing , result . publishing , result . services ) ;
} ,
function ( message ) {
failedCallback ( message ) ;
}
) ;
} else {
nodesClient . callService ( request , function ( result ) {
callback ( result ) ;
} ) ;
}
2015-05-29 16:21:09 -04:00
} ;
/ * *
* Retrieves list of param names from the ROS Parameter Server .
*
* @ param callback function with params :
* * params - array of param names .
* /
2019-03-27 17:43:00 -04:00
Ros . prototype . getParams = function ( callback , failedCallback ) {
2015-05-29 16:21:09 -04:00
var paramsClient = new Service ( {
ros : this ,
name : '/rosapi/get_param_names' ,
serviceType : 'rosapi/GetParamNames'
} ) ;
var request = new ServiceRequest ( ) ;
2019-03-27 17:43:00 -04:00
if ( typeof failedCallback === 'function' ) {
paramsClient . callService ( request ,
function ( result ) {
callback ( result . names ) ;
} ,
function ( message ) {
failedCallback ( message ) ;
}
) ;
} else {
paramsClient . callService ( request , function ( result ) {
callback ( result . names ) ;
} ) ;
}
2015-05-29 16:21:09 -04:00
} ;
/ * *
* Retrieves a type of ROS topic .
*
2019-03-27 17:43:00 -04:00
* @ param topic name of the topic :
2015-05-29 16:21:09 -04:00
* @ param callback - function with params :
* * type - String of the topic type
* /
2019-03-27 17:43:00 -04:00
Ros . prototype . getTopicType = function ( topic , callback , failedCallback ) {
2015-05-29 16:21:09 -04:00
var topicTypeClient = new Service ( {
ros : this ,
name : '/rosapi/topic_type' ,
serviceType : 'rosapi/TopicType'
} ) ;
var request = new ServiceRequest ( {
topic : topic
} ) ;
2019-03-27 17:43:00 -04:00
if ( typeof failedCallback === 'function' ) {
topicTypeClient . callService ( request ,
function ( result ) {
callback ( result . type ) ;
} ,
function ( message ) {
failedCallback ( message ) ;
}
) ;
} else {
topicTypeClient . callService ( request , function ( result ) {
callback ( result . type ) ;
} ) ;
}
} ;
/ * *
* Retrieves a type of ROS service .
*
* @ param service name of service :
* @ param callback - function with params :
* * type - String of the service type
* /
Ros . prototype . getServiceType = function ( service , callback , failedCallback ) {
var serviceTypeClient = new Service ( {
ros : this ,
name : '/rosapi/service_type' ,
serviceType : 'rosapi/ServiceType'
} ) ;
var request = new ServiceRequest ( {
service : service
2015-05-29 16:21:09 -04:00
} ) ;
2019-03-27 17:43:00 -04:00
if ( typeof failedCallback === 'function' ) {
serviceTypeClient . callService ( request ,
function ( result ) {
callback ( result . type ) ;
} ,
function ( message ) {
failedCallback ( message ) ;
}
) ;
} else {
serviceTypeClient . callService ( request , function ( result ) {
callback ( result . type ) ;
} ) ;
}
2015-05-29 16:21:09 -04:00
} ;
/ * *
* Retrieves a detail of ROS message .
*
* @ param callback - function with params :
* * details - Array of the message detail
* @ param message - String of a topic type
* /
2019-03-27 17:43:00 -04:00
Ros . prototype . getMessageDetails = function ( message , callback , failedCallback ) {
2015-05-29 16:21:09 -04:00
var messageDetailClient = new Service ( {
ros : this ,
name : '/rosapi/message_details' ,
serviceType : 'rosapi/MessageDetails'
} ) ;
var request = new ServiceRequest ( {
type : message
} ) ;
2019-03-27 17:43:00 -04:00
if ( typeof failedCallback === 'function' ) {
messageDetailClient . callService ( request ,
function ( result ) {
callback ( result . typedefs ) ;
} ,
function ( message ) {
failedCallback ( message ) ;
}
) ;
} else {
messageDetailClient . callService ( request , function ( result ) {
callback ( result . typedefs ) ;
} ) ;
}
2015-05-29 16:21:09 -04:00
} ;
/ * *
* Decode a typedefs into a dictionary like ` rosmsg show foo/bar `
*
* @ param defs - array of type _def dictionary
* /
Ros . prototype . decodeTypeDefs = function ( defs ) {
var that = this ;
// calls itself recursively to resolve type definition using hints.
var decodeTypeDefsRec = function ( theType , hints ) {
var typeDefDict = { } ;
for ( var i = 0 ; i < theType . fieldnames . length ; i ++ ) {
var arrayLen = theType . fieldarraylen [ i ] ;
var fieldName = theType . fieldnames [ i ] ;
var fieldType = theType . fieldtypes [ i ] ;
if ( fieldType . indexOf ( '/' ) === - 1 ) { // check the fieldType includes '/' or not
if ( arrayLen === - 1 ) {
typeDefDict [ fieldName ] = fieldType ;
}
else {
typeDefDict [ fieldName ] = [ fieldType ] ;
}
}
else {
// lookup the name
var sub = false ;
for ( var j = 0 ; j < hints . length ; j ++ ) {
if ( hints [ j ] . type . toString ( ) === fieldType . toString ( ) ) {
sub = hints [ j ] ;
break ;
}
}
if ( sub ) {
var subResult = decodeTypeDefsRec ( sub , hints ) ;
if ( arrayLen === - 1 ) {
}
else {
typeDefDict [ fieldName ] = [ subResult ] ;
}
}
else {
that . emit ( 'error' , 'Cannot find ' + fieldType + ' in decodeTypeDefs' ) ;
}
}
}
return typeDefDict ;
} ;
2019-03-27 17:43:00 -04:00
2015-05-29 16:21:09 -04:00
return decodeTypeDefsRec ( defs [ 0 ] , defs ) ;
} ;
module . exports = Ros ;
2019-03-27 17:43:00 -04:00
} , { "../util/workerSocket" : 47 , "./Service" : 16 , "./ServiceRequest" : 17 , "./SocketAdapter.js" : 19 , "eventemitter2" : 2 , "object-assign" : 3 , "ws" : 43 } ] , 16 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
/ * *
2019-03-27 17:43:00 -04:00
* @ fileoverview
2015-05-29 16:21:09 -04:00
* @ author Brandon Alexander - baalexander @ gmail . com
* /
var ServiceResponse = require ( './ServiceResponse' ) ;
2019-03-27 17:43:00 -04:00
var ServiceRequest = require ( './ServiceRequest' ) ;
var EventEmitter2 = require ( 'eventemitter2' ) . EventEmitter2 ;
2015-05-29 16:21:09 -04:00
/ * *
* A ROS service client .
*
* @ constructor
* @ params options - possible keys include :
* * ros - the ROSLIB . Ros connection handle
* * name - the service name , like / add _two _ints
* * serviceType - the service type , like 'rospy_tutorials/AddTwoInts'
* /
function Service ( options ) {
options = options || { } ;
this . ros = options . ros ;
this . name = options . name ;
this . serviceType = options . serviceType ;
2019-03-27 17:43:00 -04:00
this . isAdvertised = false ;
2015-05-29 16:21:09 -04:00
2019-03-27 17:43:00 -04:00
this . _serviceCallback = null ;
}
Service . prototype . _ _proto _ _ = EventEmitter2 . prototype ;
2015-05-29 16:21:09 -04:00
/ * *
2019-03-27 17:43:00 -04:00
* Calls the service . Returns the service response in the
* callback . Does nothing if this service is currently advertised .
2015-05-29 16:21:09 -04:00
*
* @ param request - the ROSLIB . ServiceRequest to send
* @ param callback - function with params :
* * response - the response from the service request
* @ param failedCallback - the callback function when the service call failed ( optional ) . Params :
* * error - the error message reported by ROS
* /
Service . prototype . callService = function ( request , callback , failedCallback ) {
2019-03-27 17:43:00 -04:00
if ( this . isAdvertised ) {
return ;
}
2015-05-29 16:21:09 -04:00
var serviceCallId = 'call_service:' + this . name + ':' + ( ++ this . ros . idCounter ) ;
if ( callback || failedCallback ) {
this . ros . once ( serviceCallId , function ( message ) {
if ( message . result !== undefined && message . result === false ) {
if ( typeof failedCallback === 'function' ) {
failedCallback ( message . values ) ;
}
} else if ( typeof callback === 'function' ) {
callback ( new ServiceResponse ( message . values ) ) ;
}
} ) ;
}
var call = {
op : 'call_service' ,
id : serviceCallId ,
service : this . name ,
2019-03-27 17:43:00 -04:00
type : this . serviceType ,
2015-05-29 16:21:09 -04:00
args : request
} ;
this . ros . callOnConnection ( call ) ;
} ;
2019-03-27 17:43:00 -04:00
/ * *
* Advertise the service . This turns the Service object from a client
* into a server . The callback will be called with every request
* that ' s made on this service .
*
* @ param callback - This works similarly to the callback for a C ++ service and should take the following params :
* * request - the service request
* * response - an empty dictionary . Take care not to overwrite this . Instead , only modify the values within .
* It should return true if the service has finished successfully ,
* i . e . without any fatal errors .
* /
Service . prototype . advertise = function ( callback ) {
if ( this . isAdvertised || typeof callback !== 'function' ) {
return ;
}
this . _serviceCallback = callback ;
this . ros . on ( this . name , this . _serviceResponse . bind ( this ) ) ;
this . ros . callOnConnection ( {
op : 'advertise_service' ,
type : this . serviceType ,
service : this . name
} ) ;
this . isAdvertised = true ;
} ;
Service . prototype . unadvertise = function ( ) {
if ( ! this . isAdvertised ) {
return ;
}
this . ros . callOnConnection ( {
op : 'unadvertise_service' ,
service : this . name
} ) ;
this . isAdvertised = false ;
} ;
Service . prototype . _serviceResponse = function ( rosbridgeRequest ) {
var response = { } ;
var success = this . _serviceCallback ( rosbridgeRequest . args , response ) ;
var call = {
op : 'service_response' ,
service : this . name ,
values : new ServiceResponse ( response ) ,
result : success
} ;
if ( rosbridgeRequest . id ) {
call . id = rosbridgeRequest . id ;
}
this . ros . callOnConnection ( call ) ;
} ;
2015-05-29 16:21:09 -04:00
module . exports = Service ;
2019-03-27 17:43:00 -04:00
} , { "./ServiceRequest" : 17 , "./ServiceResponse" : 18 , "eventemitter2" : 2 } ] , 17 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
/ * *
2019-03-27 17:43:00 -04:00
* @ fileoverview
2015-05-29 16:21:09 -04:00
* @ author Brandon Alexander - balexander @ willowgarage . com
* /
var assign = require ( 'object-assign' ) ;
/ * *
* A ServiceRequest is passed into the service call .
*
* @ constructor
* @ param values - object matching the fields defined in the . srv definition file
* /
function ServiceRequest ( values ) {
assign ( this , values ) ;
}
module . exports = ServiceRequest ;
2019-03-27 17:43:00 -04:00
} , { "object-assign" : 3 } ] , 18 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
/ * *
2019-03-27 17:43:00 -04:00
* @ fileoverview
2015-05-29 16:21:09 -04:00
* @ author Brandon Alexander - balexander @ willowgarage . com
* /
var assign = require ( 'object-assign' ) ;
/ * *
* A ServiceResponse is returned from the service call .
*
* @ constructor
* @ param values - object matching the fields defined in the . srv definition file
* /
function ServiceResponse ( values ) {
assign ( this , values ) ;
}
module . exports = ServiceResponse ;
2019-03-27 17:43:00 -04:00
} , { "object-assign" : 3 } ] , 19 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
/ * *
* Socket event handling utilities for handling events on either
* WebSocket and TCP sockets
2019-03-27 17:43:00 -04:00
*
* Note to anyone reviewing this code : these functions are called
* in the context of their parent object , unless bound
* @ fileOverview
* /
'use strict' ;
2015-05-29 16:21:09 -04:00
2019-03-27 17:43:00 -04:00
var decompressPng = require ( '../util/decompressPng' ) ;
var CBOR = require ( 'cbor-js' ) ;
var typedArrayTagger = require ( '../util/cborTypedArrayTags' ) ;
var BSON = null ;
if ( typeof bson !== 'undefined' ) {
BSON = bson ( ) . BSON ;
2015-05-29 16:21:09 -04:00
}
/ * *
* Events listeners for a WebSocket or TCP socket to a JavaScript
* ROS Client . Sets up Messages for a given topic to trigger an
* event on the ROS client .
2019-03-27 17:43:00 -04:00
*
* @ namespace SocketAdapter
* @ private
2015-05-29 16:21:09 -04:00
* /
function SocketAdapter ( client ) {
function handleMessage ( message ) {
if ( message . op === 'publish' ) {
client . emit ( message . topic , message . msg ) ;
} else if ( message . op === 'service_response' ) {
client . emit ( message . id , message ) ;
2019-03-27 17:43:00 -04:00
} else if ( message . op === 'call_service' ) {
client . emit ( message . service , message ) ;
} else if ( message . op === 'status' ) {
if ( message . id ) {
client . emit ( 'status:' + message . id , message ) ;
} else {
client . emit ( 'status' , message ) ;
}
}
}
function handlePng ( message , callback ) {
if ( message . op === 'png' ) {
decompressPng ( message . data , callback ) ;
} else {
callback ( message ) ;
}
}
function decodeBSON ( data , callback ) {
if ( ! BSON ) {
throw 'Cannot process BSON encoded message without BSON header.' ;
2015-05-29 16:21:09 -04:00
}
2019-03-27 17:43:00 -04:00
var reader = new FileReader ( ) ;
reader . onload = function ( ) {
var uint8Array = new Uint8Array ( this . result ) ;
var msg = BSON . deserialize ( uint8Array ) ;
callback ( msg ) ;
} ;
reader . readAsArrayBuffer ( data ) ;
2015-05-29 16:21:09 -04:00
}
return {
/ * *
* Emits a 'connection' event on WebSocket connection .
*
* @ param event - the argument to emit with the event .
2019-03-27 17:43:00 -04:00
* @ memberof SocketAdapter
2015-05-29 16:21:09 -04:00
* /
onopen : function onOpen ( event ) {
client . isConnected = true ;
client . emit ( 'connection' , event ) ;
} ,
/ * *
* Emits a 'close' event on WebSocket disconnection .
*
* @ param event - the argument to emit with the event .
2019-03-27 17:43:00 -04:00
* @ memberof SocketAdapter
2015-05-29 16:21:09 -04:00
* /
onclose : function onClose ( event ) {
client . isConnected = false ;
client . emit ( 'close' , event ) ;
} ,
/ * *
* Emits an 'error' event whenever there was an error .
*
* @ param event - the argument to emit with the event .
2019-03-27 17:43:00 -04:00
* @ memberof SocketAdapter
2015-05-29 16:21:09 -04:00
* /
onerror : function onError ( event ) {
client . emit ( 'error' , event ) ;
} ,
/ * *
* Parses message responses from rosbridge and sends to the appropriate
* topic , service , or param .
*
* @ param message - the raw JSON message from rosbridge .
2019-03-27 17:43:00 -04:00
* @ memberof SocketAdapter
2015-05-29 16:21:09 -04:00
* /
2019-03-27 17:43:00 -04:00
onmessage : function onMessage ( data ) {
if ( typeof Blob !== 'undefined' && data . data instanceof Blob ) {
decodeBSON ( data . data , function ( message ) {
handlePng ( message , handleMessage ) ;
} ) ;
} else if ( data . data instanceof ArrayBuffer ) {
var decoded = CBOR . decode ( data . data , typedArrayTagger ) ;
handleMessage ( decoded ) ;
2015-05-29 16:21:09 -04:00
} else {
2019-03-27 17:43:00 -04:00
var message = JSON . parse ( typeof data === 'string' ? data : data . data ) ;
handlePng ( message , handleMessage ) ;
2015-05-29 16:21:09 -04:00
}
}
} ;
}
module . exports = SocketAdapter ;
2019-03-27 17:43:00 -04:00
} , { "../util/cborTypedArrayTags" : 42 , "../util/decompressPng" : 45 , "cbor-js" : 1 } ] , 20 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
/ * *
2019-03-27 17:43:00 -04:00
* @ fileoverview
2015-05-29 16:21:09 -04:00
* @ author Brandon Alexander - baalexander @ gmail . com
* /
2019-03-27 17:43:00 -04:00
var EventEmitter2 = require ( 'eventemitter2' ) . EventEmitter2 ;
2015-05-29 16:21:09 -04:00
var Message = require ( './Message' ) ;
/ * *
* Publish and / or subscribe to a topic in ROS .
*
* Emits the following events :
* * 'warning' - if there are any warning during the Topic creation
* * 'message' - the message data from rosbridge
*
* @ constructor
* @ param options - object with following keys :
* * ros - the ROSLIB . Ros connection handle
* * name - the topic name , like / cmd _vel
* * messageType - the message type , like 'std_msgs/String'
2019-03-27 17:43:00 -04:00
* * compression - the type of compression to use , like 'png' or 'cbor'
2015-05-29 16:21:09 -04:00
* * throttle _rate - the rate ( in ms in between messages ) at which to throttle the topics
* * queue _size - the queue created at bridge side for re - publishing webtopics ( defaults to 100 )
* * latch - latch the topic when publishing
* * queue _length - the queue length at bridge side used when subscribing ( defaults to 0 , no queueing ) .
2019-03-27 17:43:00 -04:00
* * reconnect _on _close - the flag to enable resubscription and readvertisement on close event ( defaults to true ) .
2015-05-29 16:21:09 -04:00
* /
function Topic ( options ) {
options = options || { } ;
this . ros = options . ros ;
this . name = options . name ;
this . messageType = options . messageType ;
this . isAdvertised = false ;
this . compression = options . compression || 'none' ;
this . throttle _rate = options . throttle _rate || 0 ;
this . latch = options . latch || false ;
this . queue _size = options . queue _size || 100 ;
this . queue _length = options . queue _length || 0 ;
2019-03-27 17:43:00 -04:00
this . reconnect _on _close = options . reconnect _on _close !== undefined ? options . reconnect _on _close : true ;
2015-05-29 16:21:09 -04:00
// Check for valid compression types
if ( this . compression && this . compression !== 'png' &&
2019-03-27 17:43:00 -04:00
this . compression !== 'cbor' && this . compression !== 'none' ) {
2015-05-29 16:21:09 -04:00
this . emit ( 'warning' , this . compression +
' compression is not supported. No compression will be used.' ) ;
2019-03-27 17:43:00 -04:00
this . compression = 'none' ;
2015-05-29 16:21:09 -04:00
}
// Check if throttle rate is negative
if ( this . throttle _rate < 0 ) {
this . emit ( 'warning' , this . throttle _rate + ' is not allowed. Set to 0' ) ;
this . throttle _rate = 0 ;
}
var that = this ;
2019-03-27 17:43:00 -04:00
if ( this . reconnect _on _close ) {
this . callForSubscribeAndAdvertise = function ( message ) {
that . ros . callOnConnection ( message ) ;
that . waitForReconnect = false ;
that . reconnectFunc = function ( ) {
if ( ! that . waitForReconnect ) {
that . waitForReconnect = true ;
that . ros . callOnConnection ( message ) ;
that . ros . once ( 'connection' , function ( ) {
that . waitForReconnect = false ;
} ) ;
}
} ;
that . ros . on ( 'close' , that . reconnectFunc ) ;
} ;
}
else {
this . callForSubscribeAndAdvertise = this . ros . callOnConnection ;
}
2015-05-29 16:21:09 -04:00
this . _messageCallback = function ( data ) {
that . emit ( 'message' , new Message ( data ) ) ;
} ;
}
Topic . prototype . _ _proto _ _ = EventEmitter2 . prototype ;
/ * *
* Every time a message is published for the given topic , the callback
* will be called with the message object .
*
* @ param callback - function with the following params :
* * message - the published message
* /
Topic . prototype . subscribe = function ( callback ) {
if ( typeof callback === 'function' ) {
this . on ( 'message' , callback ) ;
}
if ( this . subscribeId ) { return ; }
this . ros . on ( this . name , this . _messageCallback ) ;
this . subscribeId = 'subscribe:' + this . name + ':' + ( ++ this . ros . idCounter ) ;
2019-03-27 17:43:00 -04:00
this . callForSubscribeAndAdvertise ( {
2015-05-29 16:21:09 -04:00
op : 'subscribe' ,
id : this . subscribeId ,
type : this . messageType ,
topic : this . name ,
compression : this . compression ,
throttle _rate : this . throttle _rate ,
queue _length : this . queue _length
} ) ;
} ;
/ * *
* Unregisters as a subscriber for the topic . Unsubscribing stop remove
* all subscribe callbacks . To remove a call back , you must explicitly
* pass the callback function in .
*
* @ param callback - the optional callback to unregister , if
* * provided and other listeners are registered the topic won ' t
* * unsubscribe , just stop emitting to the passed listener
* /
Topic . prototype . unsubscribe = function ( callback ) {
if ( callback ) {
this . off ( 'message' , callback ) ;
// If there is any other callbacks still subscribed don't unsubscribe
if ( this . listeners ( 'message' ) . length ) { return ; }
}
if ( ! this . subscribeId ) { return ; }
// Note: Don't call this.removeAllListeners, allow client to handle that themselves
this . ros . off ( this . name , this . _messageCallback ) ;
2019-03-27 17:43:00 -04:00
if ( this . reconnect _on _close ) {
this . ros . off ( 'close' , this . reconnectFunc ) ;
}
2015-05-29 16:21:09 -04:00
this . emit ( 'unsubscribe' ) ;
this . ros . callOnConnection ( {
op : 'unsubscribe' ,
id : this . subscribeId ,
topic : this . name
} ) ;
this . subscribeId = null ;
} ;
2019-03-27 17:43:00 -04:00
2015-05-29 16:21:09 -04:00
/ * *
* Registers as a publisher for the topic .
* /
Topic . prototype . advertise = function ( ) {
if ( this . isAdvertised ) {
return ;
}
this . advertiseId = 'advertise:' + this . name + ':' + ( ++ this . ros . idCounter ) ;
2019-03-27 17:43:00 -04:00
this . callForSubscribeAndAdvertise ( {
2015-05-29 16:21:09 -04:00
op : 'advertise' ,
id : this . advertiseId ,
type : this . messageType ,
topic : this . name ,
latch : this . latch ,
queue _size : this . queue _size
} ) ;
this . isAdvertised = true ;
2019-03-27 17:43:00 -04:00
if ( ! this . reconnect _on _close ) {
var that = this ;
this . ros . on ( 'close' , function ( ) {
that . isAdvertised = false ;
} ) ;
}
2015-05-29 16:21:09 -04:00
} ;
/ * *
* Unregisters as a publisher for the topic .
* /
Topic . prototype . unadvertise = function ( ) {
if ( ! this . isAdvertised ) {
return ;
}
2019-03-27 17:43:00 -04:00
if ( this . reconnect _on _close ) {
this . ros . off ( 'close' , this . reconnectFunc ) ;
}
2015-05-29 16:21:09 -04:00
this . emit ( 'unadvertise' ) ;
this . ros . callOnConnection ( {
op : 'unadvertise' ,
id : this . advertiseId ,
topic : this . name
} ) ;
this . isAdvertised = false ;
} ;
/ * *
* Publish the message .
*
* @ param message - A ROSLIB . Message object .
* /
Topic . prototype . publish = function ( message ) {
if ( ! this . isAdvertised ) {
this . advertise ( ) ;
}
this . ros . idCounter ++ ;
var call = {
op : 'publish' ,
id : 'publish:' + this . name + ':' + this . ros . idCounter ,
topic : this . name ,
msg : message ,
latch : this . latch
} ;
this . ros . callOnConnection ( call ) ;
} ;
module . exports = Topic ;
2019-03-27 17:43:00 -04:00
} , { "./Message" : 13 , "eventemitter2" : 2 } ] , 21 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
var mixin = require ( '../mixin' ) ;
var core = module . exports = {
Ros : require ( './Ros' ) ,
Topic : require ( './Topic' ) ,
Message : require ( './Message' ) ,
Param : require ( './Param' ) ,
Service : require ( './Service' ) ,
ServiceRequest : require ( './ServiceRequest' ) ,
ServiceResponse : require ( './ServiceResponse' )
} ;
mixin ( core . Ros , [ 'Param' , 'Service' , 'Topic' ] , core ) ;
2019-03-27 17:43:00 -04:00
} , { "../mixin" : 27 , "./Message" : 13 , "./Param" : 14 , "./Ros" : 15 , "./Service" : 16 , "./ServiceRequest" : 17 , "./ServiceResponse" : 18 , "./Topic" : 20 } ] , 22 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
/ * *
2019-03-27 17:43:00 -04:00
* @ fileoverview
2015-05-29 16:21:09 -04:00
* @ author David Gossow - dgossow @ willowgarage . com
* /
var Vector3 = require ( './Vector3' ) ;
var Quaternion = require ( './Quaternion' ) ;
/ * *
* A Pose in 3 D space . Values are copied into this object .
*
* @ constructor
* @ param options - object with following keys :
* * position - the Vector3 describing the position
* * orientation - the ROSLIB . Quaternion describing the orientation
* /
function Pose ( options ) {
options = options || { } ;
// copy the values into this object if they exist
this . position = new Vector3 ( options . position ) ;
this . orientation = new Quaternion ( options . orientation ) ;
}
/ * *
* Apply a transform against this pose .
*
* @ param tf the transform
* /
Pose . prototype . applyTransform = function ( tf ) {
this . position . multiplyQuaternion ( tf . rotation ) ;
this . position . add ( tf . translation ) ;
var tmp = tf . rotation . clone ( ) ;
tmp . multiply ( this . orientation ) ;
this . orientation = tmp ;
} ;
/ * *
* Clone a copy of this pose .
*
* @ returns the cloned pose
* /
Pose . prototype . clone = function ( ) {
return new Pose ( this ) ;
} ;
2019-03-27 17:43:00 -04:00
/ * *
* Multiplies this pose with another pose without altering this pose .
*
* @ returns Result of multiplication .
* /
Pose . prototype . multiply = function ( pose ) {
var p = pose . clone ( ) ;
p . applyTransform ( { rotation : this . orientation , translation : this . position } ) ;
return p ;
} ;
/ * *
* Computes the inverse of this pose .
*
* @ returns Inverse of pose .
* /
Pose . prototype . getInverse = function ( ) {
var inverse = this . clone ( ) ;
inverse . orientation . invert ( ) ;
inverse . position . multiplyQuaternion ( inverse . orientation ) ;
inverse . position . x *= - 1 ;
inverse . position . y *= - 1 ;
inverse . position . z *= - 1 ;
return inverse ;
} ;
2015-05-29 16:21:09 -04:00
module . exports = Pose ;
2019-03-27 17:43:00 -04:00
} , { "./Quaternion" : 23 , "./Vector3" : 25 } ] , 23 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
/ * *
2019-03-27 17:43:00 -04:00
* @ fileoverview
2015-05-29 16:21:09 -04:00
* @ author David Gossow - dgossow @ willowgarage . com
* /
/ * *
* A Quaternion .
*
* @ constructor
* @ param options - object with following keys :
* * x - the x value
* * y - the y value
* * z - the z value
* * w - the w value
* /
function Quaternion ( options ) {
options = options || { } ;
this . x = options . x || 0 ;
this . y = options . y || 0 ;
this . z = options . z || 0 ;
this . w = ( typeof options . w === 'number' ) ? options . w : 1 ;
}
/ * *
* Perform a conjugation on this quaternion .
* /
Quaternion . prototype . conjugate = function ( ) {
this . x *= - 1 ;
this . y *= - 1 ;
this . z *= - 1 ;
} ;
/ * *
* Return the norm of this quaternion .
* /
Quaternion . prototype . norm = function ( ) {
return Math . sqrt ( this . x * this . x + this . y * this . y + this . z * this . z + this . w * this . w ) ;
} ;
/ * *
* Perform a normalization on this quaternion .
* /
Quaternion . prototype . normalize = function ( ) {
var l = Math . sqrt ( this . x * this . x + this . y * this . y + this . z * this . z + this . w * this . w ) ;
if ( l === 0 ) {
this . x = 0 ;
this . y = 0 ;
this . z = 0 ;
this . w = 1 ;
} else {
l = 1 / l ;
this . x = this . x * l ;
this . y = this . y * l ;
this . z = this . z * l ;
this . w = this . w * l ;
}
} ;
/ * *
* Convert this quaternion into its inverse .
* /
Quaternion . prototype . invert = function ( ) {
this . conjugate ( ) ;
this . normalize ( ) ;
} ;
/ * *
* Set the values of this quaternion to the product of itself and the given quaternion .
*
* @ param q the quaternion to multiply with
* /
Quaternion . prototype . multiply = function ( q ) {
var newX = this . x * q . w + this . y * q . z - this . z * q . y + this . w * q . x ;
var newY = - this . x * q . z + this . y * q . w + this . z * q . x + this . w * q . y ;
var newZ = this . x * q . y - this . y * q . x + this . z * q . w + this . w * q . z ;
var newW = - this . x * q . x - this . y * q . y - this . z * q . z + this . w * q . w ;
this . x = newX ;
this . y = newY ;
this . z = newZ ;
this . w = newW ;
} ;
/ * *
* Clone a copy of this quaternion .
*
* @ returns the cloned quaternion
* /
Quaternion . prototype . clone = function ( ) {
return new Quaternion ( this ) ;
} ;
module . exports = Quaternion ;
2019-03-27 17:43:00 -04:00
} , { } ] , 24 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
/ * *
2019-03-27 17:43:00 -04:00
* @ fileoverview
2015-05-29 16:21:09 -04:00
* @ author David Gossow - dgossow @ willowgarage . com
* /
var Vector3 = require ( './Vector3' ) ;
var Quaternion = require ( './Quaternion' ) ;
/ * *
* A Transform in 3 - space . Values are copied into this object .
*
* @ constructor
* @ param options - object with following keys :
* * translation - the Vector3 describing the translation
* * rotation - the ROSLIB . Quaternion describing the rotation
* /
function Transform ( options ) {
options = options || { } ;
// Copy the values into this object if they exist
this . translation = new Vector3 ( options . translation ) ;
this . rotation = new Quaternion ( options . rotation ) ;
}
/ * *
* Clone a copy of this transform .
*
* @ returns the cloned transform
* /
Transform . prototype . clone = function ( ) {
return new Transform ( this ) ;
} ;
module . exports = Transform ;
2019-03-27 17:43:00 -04:00
} , { "./Quaternion" : 23 , "./Vector3" : 25 } ] , 25 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
/ * *
2019-03-27 17:43:00 -04:00
* @ fileoverview
2015-05-29 16:21:09 -04:00
* @ author David Gossow - dgossow @ willowgarage . com
* /
/ * *
* A 3 D vector .
*
* @ constructor
* @ param options - object with following keys :
* * x - the x value
* * y - the y value
* * z - the z value
* /
function Vector3 ( options ) {
options = options || { } ;
this . x = options . x || 0 ;
this . y = options . y || 0 ;
this . z = options . z || 0 ;
}
/ * *
* Set the values of this vector to the sum of itself and the given vector .
*
* @ param v the vector to add with
* /
Vector3 . prototype . add = function ( v ) {
this . x += v . x ;
this . y += v . y ;
this . z += v . z ;
} ;
/ * *
* Set the values of this vector to the difference of itself and the given vector .
*
* @ param v the vector to subtract with
* /
Vector3 . prototype . subtract = function ( v ) {
this . x -= v . x ;
this . y -= v . y ;
this . z -= v . z ;
} ;
/ * *
* Multiply the given Quaternion with this vector .
*
* @ param q - the quaternion to multiply with
* /
Vector3 . prototype . multiplyQuaternion = function ( q ) {
var ix = q . w * this . x + q . y * this . z - q . z * this . y ;
var iy = q . w * this . y + q . z * this . x - q . x * this . z ;
var iz = q . w * this . z + q . x * this . y - q . y * this . x ;
var iw = - q . x * this . x - q . y * this . y - q . z * this . z ;
this . x = ix * q . w + iw * - q . x + iy * - q . z - iz * - q . y ;
this . y = iy * q . w + iw * - q . y + iz * - q . x - ix * - q . z ;
this . z = iz * q . w + iw * - q . z + ix * - q . y - iy * - q . x ;
} ;
/ * *
* Clone a copy of this vector .
*
* @ returns the cloned vector
* /
Vector3 . prototype . clone = function ( ) {
return new Vector3 ( this ) ;
} ;
module . exports = Vector3 ;
2019-03-27 17:43:00 -04:00
} , { } ] , 26 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
module . exports = {
Pose : require ( './Pose' ) ,
Quaternion : require ( './Quaternion' ) ,
Transform : require ( './Transform' ) ,
Vector3 : require ( './Vector3' )
} ;
2019-03-27 17:43:00 -04:00
} , { "./Pose" : 22 , "./Quaternion" : 23 , "./Transform" : 24 , "./Vector3" : 25 } ] , 27 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
/ * *
* Mixin a feature to the core / Ros prototype .
* For example , mixin ( Ros , [ 'Topic' ] , { Topic : < Topic > } )
* will add a topic bound to any Ros instances so a user
* can call ` var topic = ros.Topic({name: '/foo'}); `
*
* @ author Graeme Yeates - github . com / megawac
* /
module . exports = function ( Ros , classes , features ) {
classes . forEach ( function ( className ) {
var Class = features [ className ] ;
Ros . prototype [ className ] = function ( options ) {
options . ros = this ;
return new Class ( options ) ;
} ;
} ) ;
} ;
2019-03-27 17:43:00 -04:00
} , { } ] , 28 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
/ * *
2019-03-27 17:43:00 -04:00
* @ fileoverview
2015-05-29 16:21:09 -04:00
* @ author David Gossow - dgossow @ willowgarage . com
* /
var ActionClient = require ( '../actionlib/ActionClient' ) ;
var Goal = require ( '../actionlib/Goal' ) ;
var Service = require ( '../core/Service.js' ) ;
var ServiceRequest = require ( '../core/ServiceRequest.js' ) ;
var Transform = require ( '../math/Transform' ) ;
/ * *
* A TF Client that listens to TFs from tf2 _web _republisher .
*
* @ constructor
* @ param options - object with following keys :
* * ros - the ROSLIB . Ros connection handle
* * fixedFrame - the fixed frame , like / base _link
* * angularThres - the angular threshold for the TF republisher
* * transThres - the translation threshold for the TF republisher
* * rate - the rate for the TF republisher
* * updateDelay - the time ( in ms ) to wait after a new subscription
* to update the TF republisher ' s list of TFs
* * topicTimeout - the timeout parameter for the TF republisher
2019-03-27 17:43:00 -04:00
* * serverName ( optional ) - the name of the tf2 _web _republisher server
* * repubServiceName ( optional ) - the name of the republish _tfs service ( non groovy compatibility mode only )
* default : '/republish_tfs'
2015-05-29 16:21:09 -04:00
* /
function TFClient ( options ) {
options = options || { } ;
this . ros = options . ros ;
this . fixedFrame = options . fixedFrame || '/base_link' ;
this . angularThres = options . angularThres || 2.0 ;
this . transThres = options . transThres || 0.01 ;
this . rate = options . rate || 10.0 ;
this . updateDelay = options . updateDelay || 50 ;
var seconds = options . topicTimeout || 2.0 ;
var secs = Math . floor ( seconds ) ;
var nsecs = Math . floor ( ( seconds - secs ) * 1000000000 ) ;
this . topicTimeout = {
secs : secs ,
nsecs : nsecs
} ;
2019-03-27 17:43:00 -04:00
this . serverName = options . serverName || '/tf2_web_republisher' ;
this . repubServiceName = options . repubServiceName || '/republish_tfs' ;
2015-05-29 16:21:09 -04:00
this . currentGoal = false ;
this . currentTopic = false ;
this . frameInfos = { } ;
this . republisherUpdateRequested = false ;
// Create an Action client
this . actionClient = this . ros . ActionClient ( {
2019-03-27 17:43:00 -04:00
serverName : this . serverName ,
actionName : 'tf2_web_republisher/TFSubscriptionAction' ,
omitStatus : true ,
omitResult : true
2015-05-29 16:21:09 -04:00
} ) ;
// Create a Service client
this . serviceClient = this . ros . Service ( {
2019-03-27 17:43:00 -04:00
name : this . repubServiceName ,
2015-05-29 16:21:09 -04:00
serviceType : 'tf2_web_republisher/RepublishTFs'
} ) ;
}
/ * *
* Process the incoming TF message and send them out using the callback
* functions .
*
* @ param tf - the TF message from the server
* /
TFClient . prototype . processTFArray = function ( tf ) {
var that = this ;
tf . transforms . forEach ( function ( transform ) {
var frameID = transform . child _frame _id ;
if ( frameID [ 0 ] === '/' )
{
frameID = frameID . substring ( 1 ) ;
}
var info = this . frameInfos [ frameID ] ;
if ( info ) {
info . transform = new Transform ( {
translation : transform . transform . translation ,
rotation : transform . transform . rotation
} ) ;
info . cbs . forEach ( function ( cb ) {
cb ( info . transform ) ;
} ) ;
}
} , this ) ;
} ;
/ * *
* Create and send a new goal ( or service request ) to the tf2 _web _republisher
* based on the current list of TFs .
* /
TFClient . prototype . updateGoal = function ( ) {
var goalMessage = {
source _frames : Object . keys ( this . frameInfos ) ,
target _frame : this . fixedFrame ,
angular _thres : this . angularThres ,
trans _thres : this . transThres ,
rate : this . rate
} ;
// if we're running in groovy compatibility mode (the default)
// then use the action interface to tf2_web_republisher
if ( this . ros . groovyCompatibility ) {
if ( this . currentGoal ) {
this . currentGoal . cancel ( ) ;
}
this . currentGoal = new Goal ( {
actionClient : this . actionClient ,
goalMessage : goalMessage
} ) ;
this . currentGoal . on ( 'feedback' , this . processTFArray . bind ( this ) ) ;
this . currentGoal . send ( ) ;
}
else {
// otherwise, use the service interface
// The service interface has the same parameters as the action,
// plus the timeout
goalMessage . timeout = this . topicTimeout ;
var request = new ServiceRequest ( goalMessage ) ;
this . serviceClient . callService ( request , this . processResponse . bind ( this ) ) ;
}
this . republisherUpdateRequested = false ;
} ;
/ * *
* Process the service response and subscribe to the tf republisher
* topic
*
* @ param response the service response containing the topic name
* /
TFClient . prototype . processResponse = function ( response ) {
// if we subscribed to a topic before, unsubscribe so
// the republisher stops publishing it
if ( this . currentTopic ) {
this . currentTopic . unsubscribe ( ) ;
}
this . currentTopic = this . ros . Topic ( {
name : response . topic _name ,
messageType : 'tf2_web_republisher/TFArray'
} ) ;
this . currentTopic . subscribe ( this . processTFArray . bind ( this ) ) ;
} ;
/ * *
* Subscribe to the given TF frame .
*
* @ param frameID - the TF frame to subscribe to
* @ param callback - function with params :
* * transform - the transform data
* /
TFClient . prototype . subscribe = function ( frameID , callback ) {
// remove leading slash, if it's there
if ( frameID [ 0 ] === '/' )
{
frameID = frameID . substring ( 1 ) ;
}
// if there is no callback registered for the given frame, create emtpy callback list
if ( ! this . frameInfos [ frameID ] ) {
this . frameInfos [ frameID ] = {
cbs : [ ]
} ;
if ( ! this . republisherUpdateRequested ) {
setTimeout ( this . updateGoal . bind ( this ) , this . updateDelay ) ;
this . republisherUpdateRequested = true ;
}
}
// if we already have a transform, call back immediately
else if ( this . frameInfos [ frameID ] . transform ) {
callback ( this . frameInfos [ frameID ] . transform ) ;
}
this . frameInfos [ frameID ] . cbs . push ( callback ) ;
} ;
/ * *
* Unsubscribe from the given TF frame .
*
* @ param frameID - the TF frame to unsubscribe from
* @ param callback - the callback function to remove
* /
TFClient . prototype . unsubscribe = function ( frameID , callback ) {
// remove leading slash, if it's there
if ( frameID [ 0 ] === '/' )
{
frameID = frameID . substring ( 1 ) ;
}
var info = this . frameInfos [ frameID ] ;
for ( var cbs = info && info . cbs || [ ] , idx = cbs . length ; idx -- ; ) {
if ( cbs [ idx ] === callback ) {
cbs . splice ( idx , 1 ) ;
}
}
if ( ! callback || cbs . length === 0 ) {
delete this . frameInfos [ frameID ] ;
}
} ;
2019-03-27 17:43:00 -04:00
/ * *
* Unsubscribe and unadvertise all topics associated with this TFClient .
* /
TFClient . prototype . dispose = function ( ) {
this . actionClient . dispose ( ) ;
if ( this . currentTopic ) {
this . currentTopic . unsubscribe ( ) ;
}
} ;
2015-05-29 16:21:09 -04:00
module . exports = TFClient ;
2019-03-27 17:43:00 -04:00
} , { "../actionlib/ActionClient" : 8 , "../actionlib/Goal" : 10 , "../core/Service.js" : 16 , "../core/ServiceRequest.js" : 17 , "../math/Transform" : 24 } ] , 29 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
var Ros = require ( '../core/Ros' ) ;
var mixin = require ( '../mixin' ) ;
var tf = module . exports = {
TFClient : require ( './TFClient' )
} ;
mixin ( Ros , [ 'TFClient' ] , tf ) ;
2019-03-27 17:43:00 -04:00
} , { "../core/Ros" : 15 , "../mixin" : 27 , "./TFClient" : 28 } ] , 30 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
/ * *
2019-03-27 17:43:00 -04:00
* @ fileOverview
2015-05-29 16:21:09 -04:00
* @ author Benjamin Pitzer - ben . pitzer @ gmail . com
* @ author Russell Toris - rctoris @ wpi . edu
* /
var Vector3 = require ( '../math/Vector3' ) ;
var UrdfTypes = require ( './UrdfTypes' ) ;
/ * *
* A Box element in a URDF .
*
* @ constructor
* @ param options - object with following keys :
* * xml - the XML element to parse
* /
function UrdfBox ( options ) {
this . dimension = null ;
this . type = UrdfTypes . URDF _BOX ;
// Parse the xml string
var xyz = options . xml . getAttribute ( 'size' ) . split ( ' ' ) ;
this . dimension = new Vector3 ( {
x : parseFloat ( xyz [ 0 ] ) ,
y : parseFloat ( xyz [ 1 ] ) ,
z : parseFloat ( xyz [ 2 ] )
} ) ;
}
module . exports = UrdfBox ;
2019-03-27 17:43:00 -04:00
} , { "../math/Vector3" : 25 , "./UrdfTypes" : 39 } ] , 31 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
/ * *
2019-03-27 17:43:00 -04:00
* @ fileOverview
2015-05-29 16:21:09 -04:00
* @ author Benjamin Pitzer - ben . pitzer @ gmail . com
* @ author Russell Toris - rctoris @ wpi . edu
* /
/ * *
* A Color element in a URDF .
*
* @ constructor
* @ param options - object with following keys :
* * xml - the XML element to parse
* /
function UrdfColor ( options ) {
// Parse the xml string
var rgba = options . xml . getAttribute ( 'rgba' ) . split ( ' ' ) ;
this . r = parseFloat ( rgba [ 0 ] ) ;
this . g = parseFloat ( rgba [ 1 ] ) ;
this . b = parseFloat ( rgba [ 2 ] ) ;
this . a = parseFloat ( rgba [ 3 ] ) ;
}
module . exports = UrdfColor ;
2019-03-27 17:43:00 -04:00
} , { } ] , 32 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
/ * *
2019-03-27 17:43:00 -04:00
* @ fileOverview
2015-05-29 16:21:09 -04:00
* @ author Benjamin Pitzer - ben . pitzer @ gmail . com
* @ author Russell Toris - rctoris @ wpi . edu
* /
var UrdfTypes = require ( './UrdfTypes' ) ;
/ * *
* A Cylinder element in a URDF .
*
* @ constructor
* @ param options - object with following keys :
* * xml - the XML element to parse
* /
function UrdfCylinder ( options ) {
this . type = UrdfTypes . URDF _CYLINDER ;
this . length = parseFloat ( options . xml . getAttribute ( 'length' ) ) ;
this . radius = parseFloat ( options . xml . getAttribute ( 'radius' ) ) ;
}
module . exports = UrdfCylinder ;
2019-03-27 17:43:00 -04:00
} , { "./UrdfTypes" : 39 } ] , 33 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
/ * *
2019-03-27 17:43:00 -04:00
* @ fileOverview
2015-05-29 16:21:09 -04:00
* @ author David V . Lu ! ! davidvlu @ gmail . com
* /
2019-03-27 17:43:00 -04:00
var Pose = require ( '../math/Pose' ) ;
var Vector3 = require ( '../math/Vector3' ) ;
var Quaternion = require ( '../math/Quaternion' ) ;
2015-05-29 16:21:09 -04:00
/ * *
* A Joint element in a URDF .
*
* @ constructor
* @ param options - object with following keys :
* * xml - the XML element to parse
* /
function UrdfJoint ( options ) {
this . name = options . xml . getAttribute ( 'name' ) ;
this . type = options . xml . getAttribute ( 'type' ) ;
2019-03-27 17:43:00 -04:00
var parents = options . xml . getElementsByTagName ( 'parent' ) ;
if ( parents . length > 0 ) {
this . parent = parents [ 0 ] . getAttribute ( 'link' ) ;
}
var children = options . xml . getElementsByTagName ( 'child' ) ;
if ( children . length > 0 ) {
this . child = children [ 0 ] . getAttribute ( 'link' ) ;
}
2015-05-29 16:21:09 -04:00
var limits = options . xml . getElementsByTagName ( 'limit' ) ;
if ( limits . length > 0 ) {
this . minval = parseFloat ( limits [ 0 ] . getAttribute ( 'lower' ) ) ;
this . maxval = parseFloat ( limits [ 0 ] . getAttribute ( 'upper' ) ) ;
}
2019-03-27 17:43:00 -04:00
// Origin
var origins = options . xml . getElementsByTagName ( 'origin' ) ;
if ( origins . length === 0 ) {
// use the identity as the default
this . origin = new Pose ( ) ;
} else {
// Check the XYZ
var xyz = origins [ 0 ] . getAttribute ( 'xyz' ) ;
var position = new Vector3 ( ) ;
if ( xyz ) {
xyz = xyz . split ( ' ' ) ;
position = new Vector3 ( {
x : parseFloat ( xyz [ 0 ] ) ,
y : parseFloat ( xyz [ 1 ] ) ,
z : parseFloat ( xyz [ 2 ] )
} ) ;
}
// Check the RPY
var rpy = origins [ 0 ] . getAttribute ( 'rpy' ) ;
var orientation = new Quaternion ( ) ;
if ( rpy ) {
rpy = rpy . split ( ' ' ) ;
// Convert from RPY
var roll = parseFloat ( rpy [ 0 ] ) ;
var pitch = parseFloat ( rpy [ 1 ] ) ;
var yaw = parseFloat ( rpy [ 2 ] ) ;
var phi = roll / 2.0 ;
var the = pitch / 2.0 ;
var psi = yaw / 2.0 ;
var x = Math . sin ( phi ) * Math . cos ( the ) * Math . cos ( psi ) - Math . cos ( phi ) * Math . sin ( the )
* Math . sin ( psi ) ;
var y = Math . cos ( phi ) * Math . sin ( the ) * Math . cos ( psi ) + Math . sin ( phi ) * Math . cos ( the )
* Math . sin ( psi ) ;
var z = Math . cos ( phi ) * Math . cos ( the ) * Math . sin ( psi ) - Math . sin ( phi ) * Math . sin ( the )
* Math . cos ( psi ) ;
var w = Math . cos ( phi ) * Math . cos ( the ) * Math . cos ( psi ) + Math . sin ( phi ) * Math . sin ( the )
* Math . sin ( psi ) ;
orientation = new Quaternion ( {
x : x ,
y : y ,
z : z ,
w : w
} ) ;
orientation . normalize ( ) ;
}
this . origin = new Pose ( {
position : position ,
orientation : orientation
} ) ;
}
2015-05-29 16:21:09 -04:00
}
module . exports = UrdfJoint ;
2019-03-27 17:43:00 -04:00
} , { "../math/Pose" : 22 , "../math/Quaternion" : 23 , "../math/Vector3" : 25 } ] , 34 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
/ * *
2019-03-27 17:43:00 -04:00
* @ fileOverview
2015-05-29 16:21:09 -04:00
* @ author Benjamin Pitzer - ben . pitzer @ gmail . com
* @ author Russell Toris - rctoris @ wpi . edu
* /
var UrdfVisual = require ( './UrdfVisual' ) ;
/ * *
* A Link element in a URDF .
*
* @ constructor
* @ param options - object with following keys :
* * xml - the XML element to parse
* /
function UrdfLink ( options ) {
this . name = options . xml . getAttribute ( 'name' ) ;
this . visuals = [ ] ;
var visuals = options . xml . getElementsByTagName ( 'visual' ) ;
for ( var i = 0 ; i < visuals . length ; i ++ ) {
this . visuals . push ( new UrdfVisual ( {
xml : visuals [ i ]
} ) ) ;
}
}
module . exports = UrdfLink ;
2019-03-27 17:43:00 -04:00
} , { "./UrdfVisual" : 40 } ] , 35 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
/ * *
2019-03-27 17:43:00 -04:00
* @ fileOverview
2015-05-29 16:21:09 -04:00
* @ author Benjamin Pitzer - ben . pitzer @ gmail . com
* @ author Russell Toris - rctoris @ wpi . edu
* /
var UrdfColor = require ( './UrdfColor' ) ;
/ * *
* A Material element in a URDF .
*
* @ constructor
* @ param options - object with following keys :
* * xml - the XML element to parse
* /
function UrdfMaterial ( options ) {
this . textureFilename = null ;
this . color = null ;
this . name = options . xml . getAttribute ( 'name' ) ;
// Texture
var textures = options . xml . getElementsByTagName ( 'texture' ) ;
if ( textures . length > 0 ) {
this . textureFilename = textures [ 0 ] . getAttribute ( 'filename' ) ;
}
// Color
var colors = options . xml . getElementsByTagName ( 'color' ) ;
if ( colors . length > 0 ) {
// Parse the RBGA string
this . color = new UrdfColor ( {
xml : colors [ 0 ]
} ) ;
}
}
UrdfMaterial . prototype . isLink = function ( ) {
return this . color === null && this . textureFilename === null ;
} ;
var assign = require ( 'object-assign' ) ;
UrdfMaterial . prototype . assign = function ( obj ) {
return assign ( this , obj ) ;
} ;
module . exports = UrdfMaterial ;
2019-03-27 17:43:00 -04:00
} , { "./UrdfColor" : 31 , "object-assign" : 3 } ] , 36 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
/ * *
2019-03-27 17:43:00 -04:00
* @ fileOverview
2015-05-29 16:21:09 -04:00
* @ author Benjamin Pitzer - ben . pitzer @ gmail . com
* @ author Russell Toris - rctoris @ wpi . edu
* /
var Vector3 = require ( '../math/Vector3' ) ;
var UrdfTypes = require ( './UrdfTypes' ) ;
/ * *
* A Mesh element in a URDF .
*
* @ constructor
* @ param options - object with following keys :
* * xml - the XML element to parse
* /
function UrdfMesh ( options ) {
this . scale = null ;
this . type = UrdfTypes . URDF _MESH ;
this . filename = options . xml . getAttribute ( 'filename' ) ;
// Check for a scale
var scale = options . xml . getAttribute ( 'scale' ) ;
if ( scale ) {
// Get the XYZ
var xyz = scale . split ( ' ' ) ;
this . scale = new Vector3 ( {
x : parseFloat ( xyz [ 0 ] ) ,
y : parseFloat ( xyz [ 1 ] ) ,
z : parseFloat ( xyz [ 2 ] )
} ) ;
}
}
module . exports = UrdfMesh ;
2019-03-27 17:43:00 -04:00
} , { "../math/Vector3" : 25 , "./UrdfTypes" : 39 } ] , 37 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
/ * *
2019-03-27 17:43:00 -04:00
* @ fileOverview
2015-05-29 16:21:09 -04:00
* @ author Benjamin Pitzer - ben . pitzer @ gmail . com
* @ author Russell Toris - rctoris @ wpi . edu
* /
var UrdfMaterial = require ( './UrdfMaterial' ) ;
var UrdfLink = require ( './UrdfLink' ) ;
var UrdfJoint = require ( './UrdfJoint' ) ;
2019-03-27 17:43:00 -04:00
var DOMParser = require ( 'xmldom' ) . DOMParser ;
2015-05-29 16:21:09 -04:00
// See https://developer.mozilla.org/docs/XPathResult#Constants
var XPATH _FIRST _ORDERED _NODE _TYPE = 9 ;
/ * *
* A URDF Model can be used to parse a given URDF into the appropriate elements .
*
* @ constructor
* @ param options - object with following keys :
* * xml - the XML element to parse
* * string - the XML element to parse as a string
* /
function UrdfModel ( options ) {
options = options || { } ;
var xmlDoc = options . xml ;
var string = options . string ;
this . materials = { } ;
this . links = { } ;
this . joints = { } ;
// Check if we are using a string or an XML element
if ( string ) {
// Parse the string
var parser = new DOMParser ( ) ;
xmlDoc = parser . parseFromString ( string , 'text/xml' ) ;
}
// Initialize the model with the given XML node.
// Get the robot tag
2019-03-27 17:43:00 -04:00
var robotXml = xmlDoc . documentElement ;
2015-05-29 16:21:09 -04:00
// Get the robot name
this . name = robotXml . getAttribute ( 'name' ) ;
// Parse all the visual elements we need
for ( var nodes = robotXml . childNodes , i = 0 ; i < nodes . length ; i ++ ) {
var node = nodes [ i ] ;
if ( node . tagName === 'material' ) {
var material = new UrdfMaterial ( {
xml : node
} ) ;
// Make sure this is unique
if ( this . materials [ material . name ] !== void 0 ) {
if ( this . materials [ material . name ] . isLink ( ) ) {
this . materials [ material . name ] . assign ( material ) ;
} else {
console . warn ( 'Material ' + material . name + 'is not unique.' ) ;
}
} else {
this . materials [ material . name ] = material ;
}
} else if ( node . tagName === 'link' ) {
var link = new UrdfLink ( {
xml : node
} ) ;
// Make sure this is unique
if ( this . links [ link . name ] !== void 0 ) {
console . warn ( 'Link ' + link . name + ' is not unique.' ) ;
} else {
// Check for a material
for ( var j = 0 ; j < link . visuals . length ; j ++ )
{
var mat = link . visuals [ j ] . material ;
if ( mat !== null ) {
if ( this . materials [ mat . name ] !== void 0 ) {
link . visuals [ j ] . material = this . materials [ mat . name ] ;
} else {
this . materials [ mat . name ] = mat ;
}
}
}
// Add the link
this . links [ link . name ] = link ;
}
} else if ( node . tagName === 'joint' ) {
var joint = new UrdfJoint ( {
xml : node
} ) ;
this . joints [ joint . name ] = joint ;
}
}
}
module . exports = UrdfModel ;
2019-03-27 17:43:00 -04:00
} , { "./UrdfJoint" : 33 , "./UrdfLink" : 34 , "./UrdfMaterial" : 35 , "xmldom" : 46 } ] , 38 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
/ * *
2019-03-27 17:43:00 -04:00
* @ fileOverview
2015-05-29 16:21:09 -04:00
* @ author Benjamin Pitzer - ben . pitzer @ gmail . com
* @ author Russell Toris - rctoris @ wpi . edu
* /
var UrdfTypes = require ( './UrdfTypes' ) ;
/ * *
* A Sphere element in a URDF .
*
* @ constructor
* @ param options - object with following keys :
* * xml - the XML element to parse
* /
function UrdfSphere ( options ) {
this . type = UrdfTypes . URDF _SPHERE ;
this . radius = parseFloat ( options . xml . getAttribute ( 'radius' ) ) ;
}
module . exports = UrdfSphere ;
2019-03-27 17:43:00 -04:00
} , { "./UrdfTypes" : 39 } ] , 39 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
module . exports = {
URDF _SPHERE : 0 ,
URDF _BOX : 1 ,
URDF _CYLINDER : 2 ,
URDF _MESH : 3
} ;
2019-03-27 17:43:00 -04:00
} , { } ] , 40 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
/ * *
2019-03-27 17:43:00 -04:00
* @ fileOverview
2015-05-29 16:21:09 -04:00
* @ author Benjamin Pitzer - ben . pitzer @ gmail . com
* @ author Russell Toris - rctoris @ wpi . edu
* /
var Pose = require ( '../math/Pose' ) ;
var Vector3 = require ( '../math/Vector3' ) ;
var Quaternion = require ( '../math/Quaternion' ) ;
var UrdfCylinder = require ( './UrdfCylinder' ) ;
var UrdfBox = require ( './UrdfBox' ) ;
var UrdfMaterial = require ( './UrdfMaterial' ) ;
var UrdfMesh = require ( './UrdfMesh' ) ;
var UrdfSphere = require ( './UrdfSphere' ) ;
/ * *
* A Visual element in a URDF .
*
* @ constructor
* @ param options - object with following keys :
* * xml - the XML element to parse
* /
function UrdfVisual ( options ) {
var xml = options . xml ;
this . origin = null ;
this . geometry = null ;
this . material = null ;
// Origin
var origins = xml . getElementsByTagName ( 'origin' ) ;
if ( origins . length === 0 ) {
// use the identity as the default
this . origin = new Pose ( ) ;
} else {
// Check the XYZ
var xyz = origins [ 0 ] . getAttribute ( 'xyz' ) ;
var position = new Vector3 ( ) ;
if ( xyz ) {
xyz = xyz . split ( ' ' ) ;
position = new Vector3 ( {
x : parseFloat ( xyz [ 0 ] ) ,
y : parseFloat ( xyz [ 1 ] ) ,
z : parseFloat ( xyz [ 2 ] )
} ) ;
}
// Check the RPY
var rpy = origins [ 0 ] . getAttribute ( 'rpy' ) ;
var orientation = new Quaternion ( ) ;
if ( rpy ) {
rpy = rpy . split ( ' ' ) ;
// Convert from RPY
var roll = parseFloat ( rpy [ 0 ] ) ;
var pitch = parseFloat ( rpy [ 1 ] ) ;
var yaw = parseFloat ( rpy [ 2 ] ) ;
var phi = roll / 2.0 ;
var the = pitch / 2.0 ;
var psi = yaw / 2.0 ;
var x = Math . sin ( phi ) * Math . cos ( the ) * Math . cos ( psi ) - Math . cos ( phi ) * Math . sin ( the )
* Math . sin ( psi ) ;
var y = Math . cos ( phi ) * Math . sin ( the ) * Math . cos ( psi ) + Math . sin ( phi ) * Math . cos ( the )
* Math . sin ( psi ) ;
var z = Math . cos ( phi ) * Math . cos ( the ) * Math . sin ( psi ) - Math . sin ( phi ) * Math . sin ( the )
* Math . cos ( psi ) ;
var w = Math . cos ( phi ) * Math . cos ( the ) * Math . cos ( psi ) + Math . sin ( phi ) * Math . sin ( the )
* Math . sin ( psi ) ;
orientation = new Quaternion ( {
x : x ,
y : y ,
z : z ,
w : w
} ) ;
orientation . normalize ( ) ;
}
this . origin = new Pose ( {
position : position ,
orientation : orientation
} ) ;
}
// Geometry
var geoms = xml . getElementsByTagName ( 'geometry' ) ;
if ( geoms . length > 0 ) {
var geom = geoms [ 0 ] ;
var shape = null ;
// Check for the shape
for ( var i = 0 ; i < geom . childNodes . length ; i ++ ) {
var node = geom . childNodes [ i ] ;
if ( node . nodeType === 1 ) {
shape = node ;
break ;
}
}
// Check the type
var type = shape . nodeName ;
if ( type === 'sphere' ) {
this . geometry = new UrdfSphere ( {
xml : shape
} ) ;
} else if ( type === 'box' ) {
this . geometry = new UrdfBox ( {
xml : shape
} ) ;
} else if ( type === 'cylinder' ) {
this . geometry = new UrdfCylinder ( {
xml : shape
} ) ;
} else if ( type === 'mesh' ) {
this . geometry = new UrdfMesh ( {
xml : shape
} ) ;
} else {
console . warn ( 'Unknown geometry type ' + type ) ;
}
}
// Material
var materials = xml . getElementsByTagName ( 'material' ) ;
if ( materials . length > 0 ) {
this . material = new UrdfMaterial ( {
xml : materials [ 0 ]
} ) ;
}
}
module . exports = UrdfVisual ;
2019-03-27 17:43:00 -04:00
} , { "../math/Pose" : 22 , "../math/Quaternion" : 23 , "../math/Vector3" : 25 , "./UrdfBox" : 30 , "./UrdfCylinder" : 32 , "./UrdfMaterial" : 35 , "./UrdfMesh" : 36 , "./UrdfSphere" : 38 } ] , 41 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
module . exports = require ( 'object-assign' ) ( {
UrdfBox : require ( './UrdfBox' ) ,
UrdfColor : require ( './UrdfColor' ) ,
UrdfCylinder : require ( './UrdfCylinder' ) ,
UrdfLink : require ( './UrdfLink' ) ,
UrdfMaterial : require ( './UrdfMaterial' ) ,
UrdfMesh : require ( './UrdfMesh' ) ,
UrdfModel : require ( './UrdfModel' ) ,
UrdfSphere : require ( './UrdfSphere' ) ,
UrdfVisual : require ( './UrdfVisual' )
} , require ( './UrdfTypes' ) ) ;
2019-03-27 17:43:00 -04:00
} , { "./UrdfBox" : 30 , "./UrdfColor" : 31 , "./UrdfCylinder" : 32 , "./UrdfLink" : 34 , "./UrdfMaterial" : 35 , "./UrdfMesh" : 36 , "./UrdfModel" : 37 , "./UrdfSphere" : 38 , "./UrdfTypes" : 39 , "./UrdfVisual" : 40 , "object-assign" : 3 } ] , 42 : [ function ( require , module , exports ) {
'use strict' ;
var UPPER32 = Math . pow ( 2 , 32 ) ;
var warnedPrecision = false ;
function warnPrecision ( ) {
if ( ! warnedPrecision ) {
warnedPrecision = true ;
console . warn ( 'CBOR 64-bit integer array values may lose precision. No further warnings.' ) ;
}
}
/ * *
* Unpacks 64 - bit unsigned integer from byte array .
* @ param { Uint8Array } bytes
* /
function decodeUint64LE ( bytes ) {
warnPrecision ( ) ;
var byteLen = bytes . byteLength ;
var offset = bytes . byteOffset ;
var arrLen = byteLen / 8 ;
var buffer = bytes . buffer . slice ( offset , offset + byteLen ) ;
var uint32View = new Uint32Array ( buffer ) ;
var arr = new Array ( arrLen ) ;
for ( var i = 0 ; i < arrLen ; i ++ ) {
var si = i * 2 ;
var lo = uint32View [ si ] ;
var hi = uint32View [ si + 1 ] ;
arr [ i ] = lo + UPPER32 * hi ;
}
return arr ;
}
/ * *
* Unpacks 64 - bit signed integer from byte array .
* @ param { Uint8Array } bytes
* /
function decodeInt64LE ( bytes ) {
warnPrecision ( ) ;
var byteLen = bytes . byteLength ;
var offset = bytes . byteOffset ;
var arrLen = byteLen / 8 ;
var buffer = bytes . buffer . slice ( offset , offset + byteLen ) ;
var uint32View = new Uint32Array ( buffer ) ;
var int32View = new Int32Array ( buffer ) ;
var arr = new Array ( arrLen ) ;
for ( var i = 0 ; i < arrLen ; i ++ ) {
var si = i * 2 ;
var lo = uint32View [ si ] ;
var hi = int32View [ si + 1 ] ;
arr [ i ] = lo + UPPER32 * hi ;
}
return arr ;
}
/ * *
* Unpacks typed array from byte array .
* @ param { Uint8Array } bytes
* @ param { type } ArrayType - desired output array type
* /
function decodeNativeArray ( bytes , ArrayType ) {
var byteLen = bytes . byteLength ;
var offset = bytes . byteOffset ;
var buffer = bytes . buffer . slice ( offset , offset + byteLen ) ;
return new ArrayType ( buffer ) ;
}
/ * *
* Support a subset of draft CBOR typed array tags :
* < https : //tools.ietf.org/html/draft-ietf-cbor-array-tags-00>
* Only support little - endian tags for now .
* /
var nativeArrayTypes = {
64 : Uint8Array ,
69 : Uint16Array ,
70 : Uint32Array ,
72 : Int8Array ,
77 : Int16Array ,
78 : Int32Array ,
85 : Float32Array ,
86 : Float64Array
2015-05-29 16:21:09 -04:00
} ;
2019-03-27 17:43:00 -04:00
/ * *
* We can also decode 64 - bit integer arrays , since ROS has these types .
* /
var conversionArrayTypes = {
71 : decodeUint64LE ,
79 : decodeInt64LE
} ;
/ * *
* Handles CBOR typed array tags during decoding .
* @ param { Uint8Array } data
* @ param { Number } tag
* /
function cborTypedArrayTagger ( data , tag ) {
if ( tag in nativeArrayTypes ) {
var arrayType = nativeArrayTypes [ tag ] ;
return decodeNativeArray ( data , arrayType ) ;
}
if ( tag in conversionArrayTypes ) {
return conversionArrayTypes [ tag ] ( data ) ;
}
return data ;
}
if ( typeof module !== 'undefined' && module . exports ) {
module . exports = cborTypedArrayTagger ;
}
} , { } ] , 43 : [ function ( require , module , exports ) {
module . exports = typeof window !== 'undefined' ? window . WebSocket : WebSocket ;
} , { } ] , 44 : [ function ( require , module , exports ) {
2015-05-29 16:21:09 -04:00
/* global document */
module . exports = function Canvas ( ) {
return document . createElement ( 'canvas' ) ;
} ;
2019-03-27 17:43:00 -04:00
} , { } ] , 45 : [ function ( require , module , exports ) {
/ * *
* @ fileOverview
* @ author Graeme Yeates - github . com / megawac
* /
'use strict' ;
var Canvas = require ( 'canvas' ) ;
var Image = Canvas . Image || window . Image ;
/ * *
* If a message was compressed as a PNG image ( a compression hack since
* gzipping over WebSockets * is not supported yet ) , this function places the
* "image" in a canvas element then decodes the * "image" as a Base64 string .
*
* @ private
* @ param data - object containing the PNG data .
* @ param callback - function with params :
* * data - the uncompressed data
* /
function decompressPng ( data , callback ) {
// Uncompresses the data before sending it through (use image/canvas to do so).
var image = new Image ( ) ;
// When the image loads, extracts the raw data (JSON message).
image . onload = function ( ) {
// Creates a local canvas to draw on.
var canvas = new Canvas ( ) ;
var context = canvas . getContext ( '2d' ) ;
// Sets width and height.
canvas . width = image . width ;
canvas . height = image . height ;
// Prevents anti-aliasing and loosing data
context . imageSmoothingEnabled = false ;
context . webkitImageSmoothingEnabled = false ;
context . mozImageSmoothingEnabled = false ;
// Puts the data into the image.
context . drawImage ( image , 0 , 0 ) ;
// Grabs the raw, uncompressed data.
var imageData = context . getImageData ( 0 , 0 , image . width , image . height ) . data ;
// Constructs the JSON.
var jsonData = '' ;
for ( var i = 0 ; i < imageData . length ; i += 4 ) {
// RGB
jsonData += String . fromCharCode ( imageData [ i ] , imageData [ i + 1 ] , imageData [ i + 2 ] ) ;
}
callback ( JSON . parse ( jsonData ) ) ;
} ;
// Sends the image data to load.
image . src = 'data:image/png;base64,' + data ;
}
module . exports = decompressPng ;
} , { "canvas" : 44 } ] , 46 : [ function ( require , module , exports ) {
exports . DOMImplementation = window . DOMImplementation ;
exports . XMLSerializer = window . XMLSerializer ;
exports . DOMParser = window . DOMParser ;
} , { } ] , 47 : [ function ( require , module , exports ) {
var work = require ( 'webworkify' ) ;
var workerSocketImpl = require ( './workerSocketImpl' ) ;
function WorkerSocket ( uri ) {
this . socket _ = work ( workerSocketImpl ) ;
this . socket _ . addEventListener ( 'message' , this . handleWorkerMessage _ . bind ( this ) ) ;
this . socket _ . postMessage ( {
uri : uri ,
} ) ;
}
WorkerSocket . prototype . handleWorkerMessage _ = function ( ev ) {
var data = ev . data ;
if ( data instanceof ArrayBuffer || typeof data === 'string' ) {
// binary or JSON message from rosbridge
this . onmessage ( ev ) ;
} else {
// control message from the wrapped WebSocket
var type = data . type ;
if ( type === 'close' ) {
this . onclose ( null ) ;
} else if ( type === 'open' ) {
this . onopen ( null ) ;
} else if ( type === 'error' ) {
this . onerror ( null ) ;
} else {
throw 'Unknown message from workersocket' ;
}
}
} ;
WorkerSocket . prototype . send = function ( data ) {
this . socket _ . postMessage ( data ) ;
} ;
WorkerSocket . prototype . close = function ( ) {
this . socket _ . postMessage ( {
close : true
} ) ;
} ;
module . exports = WorkerSocket ;
} , { "./workerSocketImpl" : 48 , "webworkify" : 5 } ] , 48 : [ function ( require , module , exports ) {
var WebSocket = WebSocket || require ( 'ws' ) ;
module . exports = function ( self ) {
var socket = null ;
function handleSocketMessage ( ev ) {
var data = ev . data ;
if ( data instanceof ArrayBuffer ) {
// binary message, transfer for speed
self . postMessage ( data , [ data ] ) ;
} else {
// JSON message, copy string
self . postMessage ( data ) ;
}
}
function handleSocketControl ( ev ) {
self . postMessage ( { type : ev . type } ) ;
}
self . addEventListener ( 'message' , function ( ev ) {
var data = ev . data ;
if ( typeof data === 'string' ) {
// JSON message from ROSLIB
socket . send ( data ) ;
} else {
// control message
if ( data . hasOwnProperty ( 'close' ) ) {
socket . close ( ) ;
socket = null ;
} else if ( data . hasOwnProperty ( 'uri' ) ) {
var uri = data . uri ;
socket = new WebSocket ( uri ) ;
socket . binaryType = 'arraybuffer' ;
socket . onmessage = handleSocketMessage ;
socket . onclose = handleSocketControl ;
socket . onopen = handleSocketControl ;
socket . onerror = handleSocketControl ;
} else {
throw 'Unknown message to WorkerSocket' ;
}
}
} ) ;
} ;
} , { "ws" : 43 } ] } , { } , [ 7 ] ) ;