desktopCapture-p2p/bower_components/kurento-utils/js/kurento-utils.map

1 line
210 KiB
Plaintext
Executable File

{"version":3,"sources":["../node_modules/browser-pack/_prelude.js","../node_modules/freeice/stun.json","../node_modules/freeice/turn.json","../lib/WebRtcPeer.js","../lib/browser.js","../lib/index.js","../node_modules/events/events.js","../node_modules/freeice/index.js","../node_modules/hark/hark.js","../node_modules/inherits/inherits_browser.js","../node_modules/merge/merge.js","../node_modules/normalice/index.js","../node_modules/sdp-transform/lib/grammar.js","../node_modules/sdp-transform/lib/index.js","../node_modules/sdp-transform/lib/parser.js","../node_modules/sdp-transform/lib/writer.js","../node_modules/sdp-translator/lib/array-equals.js","../node_modules/sdp-translator/lib/index.js","../node_modules/sdp-translator/lib/interop.js","../node_modules/sdp-translator/lib/transform.js","../node_modules/ua-parser-js/src/ua-parser.js","../node_modules/uuid/rng-browser.js","../node_modules/uuid/uuid.js","../node_modules/wildemitter/wildemitter.js"],"names":["noop","error","logger","trackStop","track","stop","streamStop","stream","getTracks","forEach","bufferizeCandidates","pc","onerror","candidatesQueue","addEventListener","this","signalingState","length","entry","shift","addIceCandidate","candidate","callback","Error","remoteDescription","push","removeFIDFromOffer","sdp","n","indexOf","slice","getSimulcastInfo","videoStream","videoTracks","getVideoTracks","warn","lines","id","join","WebRtcPeer","mode","options","setRemoteVideo","remoteVideo","pause","getRemoteStreams","srcObject","debug","load","mangleSdpToAddSimulcast","answer","simulcast","browser","name","RTCSessionDescription","type","start","localVideo","self","showLocalVideo","addStream","audioStream","parser","getBrowser","major","getMedia","constraints","undefined","MEDIA_CONSTRAINTS","navigator","mediaDevices","getUserMedia","then","catch","super_","call","Function","bind","dataChannel","mediaConstraints","connectionConstraints","peerConnection","sendSource","dataChannelConfig","useDataChannels","dataChannels","guid","uuid","v4","configuration","recursive","iceServers","freeice","onicecandidate","on","oncandidategatheringdone","multistream","interop","sdpTranslator","Interop","candidatesQueueOut","candidategatheringdone","Object","defineProperties","get","value","writable","currentFrame","readyState","HAVE_CURRENT_DATA","canvas","document","createElement","width","videoWidth","height","videoHeight","getContext","drawImage","RTCPeerConnection","dcId","dcOptions","createDataChannel","onopen","onclose","onmessage","onbufferedamountlow","event","EventEmitter","listenerCount","cand","usePlanB","candidateToUnifiedPlan","emit","onaddstream","onnegotiationneeded","listener","iceCandidate","candidateToPlanB","RTCIceCandidate","generateOffer","offerAudio","offerVideo","audio","video","browserDependantConstraints","offerToReceiveAudio","offerToReceiveVideo","JSON","stringify","createOffer","offer","setLocalDescription","localDescription","toUnifiedPlan","dumpSDP","processAnswer","getLocalSessionDescriptor","getRemoteSessionDescriptor","muted","send","data","sdpAnswer","planBAnswer","toPlanB","setRemoteDescription","processOffer","sdpOffer","planBOffer","createAnswer","setTimeout","getScreenConstraints","constraints_","unshift","apply","removeAllListeners","window","cancelChooseDesktopMedia","createEnableDescriptor","method","enumerable","streams","getLocalStreams","i","tracks","j","enabled","set","trackSetEnable","WebRtcPeerRecvonly","WebRtcPeerSendonly","WebRtcPeerSendrecv","harkUtils","hark","require","inherits","UAParser","Logger","console","framerate","ua","userAgent","description","prototype","audioEnabled","videoEnabled","getLocalStream","index","getRemoteStream","dispose","dc","close","err","exports","module","_events","_maxListeners","isFunction","arg","isNumber","isObject","isUndefined","defaultMaxListeners","setMaxListeners","isNaN","TypeError","er","handler","len","args","listeners","arguments","context","Array","addListener","m","newListener","warned","trace","once","g","removeListener","fired","list","position","splice","key","evlistener","emitter","normalice","opts","getServers","count","idx","out","input","concat","servers","Math","random","map","url","String","selected","stun","turn","stunCount","turnCount","getMaxVolume","analyser","fftBins","maxVolume","Infinity","getFloatFrequencyData","ii","WildEmitter","audioContextType","AudioContext","webkitAudioContext","audioContext","harker","smoothing","interval","threshold","play","history","running","sourceNode","createAnalyser","fftSize","smoothingTimeConstant","Float32Array","jquery","HTMLAudioElement","HTMLVideoElement","createMediaElementSource","createMediaStreamSource","connect","destination","speaking","setThreshold","t","setInterval","speakingHistory","looper","currentVolume","create","ctor","superCtor","constructor","configurable","TempCtor","isNode","merge_recursive","base","extend","typeOf","merge","clone","argv","result","size","item","sitem","Public","toString","toLowerCase","output","protocols","protocol","parts","trim","split","username","credential","urls","grammar","v","reg","o","names","format","s","u","e","p","z","r","c","b","a","rate","address","subtype","config","sessionConfig","str","raddr","tcptype","generation","keys","obj","writer","write","parse","parseFmtpConfig","parsePayloads","parseRemoteCandidates","toIntIfInt","Number","attachProperties","match","location","rawName","parseReg","content","needsBlank","keyLocation","validLine","RegExp","test","session","media","filter","l","rtp","fmtp","fmtpReducer","acc","expr","reduce","candidates","component","ip","port","formatRegExp","formatStr","replace","x","makeLine","defaultOuterOrder","defaultInnerOrder","version","mLine","payloads","outerOrder","innerOrder","el","arrayEquals","array","cache","mlB2UMap","mlU2BMap","addSetupAttr","uLine","setup","transform","sdpMLineIndex","sdpMid","getFirstSendingIndexFromAnswer","isArray","direction","desc","every","mid","rewrite","codec","type2bl","types","rtcpMux","sources","ssrc","msid","ssrcGroups","bundleOnly","groups","some","group","mids","msidSemantic","semantic","token","resStr","hasBundle","sort","mustBeBundle","cached","iceUfrag","icePwd","fingerprint","recvonlySsrcs","mid2ul","bIdx","uIdx","sources2ul","rtcpFb","bLine","hash","ssrc2group","ssrcGroup","ssrcs","ssrc2ml","related","done","source","attribute","MODEL","NAME","TYPE","VENDOR","VERSION","MOBILE","TABLET","util","regexes","extensions","margedRegexes","has","str1","str2","lowerize","mapper","rgx","arrays","k","q","matches","regex","props","exec","maps","oldsafari","1.0","1.2","1.3","2.0","2.0.2","2.0.3","2.0.4","?","device","amazon","model","Fire Phone","sprint","Evo Shift 4G","vendor","HTC","Sprint","os","windows","ME","NT 3.11","NT 4.0","2000","XP","Vista","7","8","8.1","10","RT","cpu","engine","uastring","getResult","rgxmap","getCPU","architecture","getDevice","getEngine","getOS","getUA","setUA","BROWSER","MAJOR","CPU","ARCHITECTURE","DEVICE","CONSOLE","SMARTTV","WEARABLE","EMBEDDED","ENGINE","OS","define","amd","$","jQuery","Zepto","prop","rng","crypto","global","msCrypto","getRandomValues","_rnds8","Uint8Array","_rnds","buf","offset","oct","_hexToByte","unparse","bth","_byteToHex","v1","clockseq","_clockseq","msecs","Date","getTime","nsecs","_lastNSecs","dt","_lastMSecs","tl","tmh","node","_nodeId","rnds","_rng","substr","_seedBytes","mixin","isWildEmitter","groupName","fn","callbacks","hasGroup","func","_groupName","off","releaseGroup","handlers","specialCallbacks","getWildcardCallbacks","eventName"],"mappings":"AAAA;AGkCA,QAASA,MAAKC,GACNA,GACAC,OAAOD,MAAMA,GAErB,QAASE,WAAUC,GACfA,EAAMC,MAAQD,EAAMC,OAExB,QAASC,YAAWC,GAChBA,EAAOC,YAAYC,QAAQN,WAQ/B,QAASO,qBAAoBC,EAAIC,GAC7B,GAAIC,KASJ,OARAF,GAAGG,iBAAiB,uBAAwB,WACxC,GAA4B,WAAxBC,KAAKC,eACL,KAAOH,EAAgBI,QAAQ,CAC3B,GAAIC,GAAQL,EAAgBM,OAC5BR,GAAGS,gBAAgBF,EAAMG,UAAWH,EAAMI,SAAUJ,EAAMI,aAI/D,SAAUD,EAAWC,GAExB,OADAA,EAAWA,GAAYV,EACfD,EAAGK,gBACX,IAAK,SACDM,EAAS,GAAIC,OAAM,mCACnB,MACJ,KAAK,SACD,GAAIZ,EAAGa,kBAAmB,CACtBb,EAAGS,gBAAgBC,EAAWC,EAAUA,EACxC,OAER,QACIT,EAAgBY,MACZJ,UAAWA,EACXC,SAAUA,MAK1B,QAASI,oBAAmBC,GACxB,GAAIC,GAAID,EAAIE,QAAQ,mBACpB,OAAID,GAAI,EACGD,EAAIG,MAAM,EAAGF,GAEbD,EAGf,QAASI,kBAAiBC,GACtB,GAAIC,GAAcD,EAAYE,gBAC9B,KAAKD,EAAYhB,OAEb,MADAf,QAAOiC,KAAK,iDACL,EAEX,IAAIC,IACI,6BACA,yBACA,4BACA,iBAAmBJ,EAAYK,GAAK,IAAMJ,EAAY,GAAGI,GACzD,oBAAsBL,EAAYK,GAClC,kBAAoBJ,EAAY,GAAGI,GACnC,4BACA,iBAAmBL,EAAYK,GAAK,IAAMJ,EAAY,GAAGI,GACzD,oBAAsBL,EAAYK,GAClC,kBAAoBJ,EAAY,GAAGI,GACnC,4BACA,iBAAmBL,EAAYK,GAAK,IAAMJ,EAAY,GAAGI,GACzD,oBAAsBL,EAAYK,GAClC,kBAAoBJ,EAAY,GAAGI,GAG3C,OADAD,GAAMX,KAAK,IACJW,EAAME,KAAK,MAEtB,QAASC,YAAWC,EAAMC,EAASnB,GA+K/B,QAASoB,KACL,GAAIC,EAAa,CACbA,EAAYC,OACZ,IAAIrC,GAASI,EAAGkC,mBAAmB,EACnCF,GAAYG,UAAYvC,EACxBL,OAAO6C,MAAM,iBAAkBxC,GAC/BoC,EAAYK,QAmEpB,QAASC,GAAwBC,GAY7B,MAXIC,KACqB,WAAjBC,QAAQC,MAAsC,aAAjBD,QAAQC,MACrCnD,OAAO6C,MAAM,yBACbG,EAAS,GAAII,wBACTC,KAAQL,EAAOK,KACf5B,IAAOD,mBAAmBwB,EAAOvB,KAAOI,iBAAiBC,MAG7D9B,OAAOiC,KAAK,mDAGbe,EAEX,QAASM,KACqB,WAAtB7C,EAAGK,gBACHM,EAAS,oJAETU,GAAeyB,GACfC,EAAKC,iBAEL3B,GACArB,EAAGiD,UAAU5B,GAEb6B,GACAlD,EAAGiD,UAAUC,EAEjB,IAAIT,GAAUU,OAAOC,YACR,cAATvB,GAAyC,WAAjBY,EAAQC,MAAsC,aAAjBD,EAAQC,MAA0C,KAAlBD,EAAQY,QAC7FxB,EAAO,YAEXlB,IAGA,QAAS2C,GAASC,OACMC,KAAhBD,IACAA,EAAcE,mBAElBC,UAAUC,aAAaC,aAAaL,GAAaM,KAAK,SAAUjE,GAC5DyB,EAAczB,EACdiD,MACDiB,MAAMnD,GAhSjB,KAAMP,eAAgBwB,aAClB,MAAO,IAAIA,YAAWC,EAAMC,EAASnB,EAEzCiB,YAAWmC,OAAOC,KAAK5D,MACnB0B,YAAmBmC,YACnBtD,EAAWmB,EACXA,MAAU0B,IAEd1B,EAAUA,MACVnB,GAAYA,GAAYtB,MAAM6E,KAAK9D,KACnC,IAWI+D,GAXApB,EAAO3C,KACP0C,EAAahB,EAAQgB,WACrBd,EAAcF,EAAQE,YACtBX,EAAcS,EAAQT,YACtB6B,EAAcpB,EAAQoB,YACtBkB,EAAmBtC,EAAQsC,iBAE3BpE,GADwB8B,EAAQuC,sBAC3BvC,EAAQwC,gBACbC,EAAazC,EAAQyC,YAAc,SACnCC,EAAoB1C,EAAQ0C,kBAC5BC,EAAkB3C,EAAQ4C,eAAgB,EAE1CC,EAAOC,KAAKC,KACZC,EAAgBC,WAAYC,WAAYC,WAAanD,EAAQgD,eAC7DI,EAAiBpD,EAAQoD,cACzBA,IACA9E,KAAK+E,GAAG,eAAgBD,EAC5B,IAAIE,GAA2BtD,EAAQsD,wBACnCA,IACAhF,KAAK+E,GAAG,yBAA0BC,EAEtC,IAAI5C,GAAYV,EAAQU,UACpB6C,EAAcvD,EAAQuD,YACtBC,EAAU,GAAIC,eAAcC,QAC5BC,KACAC,GAAyB,CAwC7B,IAvCAC,OAAOC,iBAAiBxF,MACpBkE,gBACIuB,IAAK,WACD,MAAO7F,KAGf0B,IACIoE,MAAOhE,EAAQJ,IAAMiD,EACrBoB,UAAU,GAEd/D,aACI6D,IAAK,WACD,MAAO7D,KAGfc,YACI+C,IAAK,WACD,MAAO/C,KAGfqB,aACI0B,IAAK,WACD,MAAO1B,KAGf6B,cACIH,IAAK,WACD,GAAK7D,EAAL,CAEA,GAAIA,EAAYiE,WAAajE,EAAYkE,kBACrC,KAAM,IAAItF,OAAM,iCACpB,IAAIuF,GAASC,SAASC,cAAc,SAIpC,OAHAF,GAAOG,MAAQtE,EAAYuE,WAC3BJ,EAAOK,OAASxE,EAAYyE,YAC5BN,EAAOO,WAAW,MAAMC,UAAU3E,EAAa,EAAG,GAC3CmE,QAIdnG,IACDA,EAAK,GAAI4G,mBAAkB9B,GACvBL,IAAoBN,GAAa,CACjC,GAAI0C,GAAO,cAAgB9D,EAAKrB,GAC5BoF,MAAYtD,EACZgB,KACAqC,EAAOrC,EAAkB9C,IAAMmF,EAC/BC,EAAYtC,EAAkB1C,SAElCqC,EAAcnE,EAAG+G,kBAAkBF,EAAMC,GACrCtC,IACAL,EAAY6C,OAASxC,EAAkBwC,OACvC7C,EAAY8C,QAAUzC,EAAkByC,QACxC9C,EAAY+C,UAAY1C,EAAkB0C,UAC1C/C,EAAYgD,oBAAsB3C,EAAkB2C,oBACpDhD,EAAYlE,QAAUuE,EAAkBvE,SAAWZ,MAI/DW,EAAGG,iBAAiB,eAAgB,SAAUiH,GAC1C,GAAI1G,GAAY0G,EAAM1G,SACtB,IAAI2G,aAAaC,cAAcvE,EAAM,iBAAmBsE,aAAaC,cAAcvE,EAAM,0BACrF,GAAIrC,EAAW,CACX,GAAI6G,EAEAA,GADAlC,GAAemC,SACRlC,EAAQmC,uBAAuB/G,GAE/BA,EAEXqC,EAAK2E,KAAK,eAAgBH,GAC1B7B,GAAyB,MACjBA,KACR3C,EAAK2E,KAAK,0BACVhC,GAAyB,OAErBA,KACRD,EAAmB3E,KAAKJ,GACnBA,IACDgF,GAAyB,MAGrC1F,EAAG2H,YAAc7F,EAAQ6F,YACzB3H,EAAG4H,oBAAsB9F,EAAQ8F,oBACjCxH,KAAK+E,GAAG,cAAe,SAAUiC,EAAOS,GACpC,GAAc,iBAAVT,GAAsC,2BAAVA,EAC5B,KAAO3B,EAAmBnF,QAAQ,CAC9B,GAAII,GAAY+E,EAAmBjF,SAC9BE,IAAyB,2BAAV0G,IAChBS,EAASnH,KAKzB,IAAID,GAAkBV,oBAAoBC,EAC1CI,MAAKK,gBAAkB,SAAUqH,EAAcnH,GAC3C,GAAID,EAEAA,GADA2E,GAAemC,SACHlC,EAAQyC,iBAAiBD,GAEzB,GAAIE,iBAAgBF,GAEpCvI,OAAO6C,MAAM,gCAAiC0F,GAC9CnH,GAAYA,GAAYtB,MAAM6E,KAAK9D,MACnCK,EAAgBC,EAAWC,IAE/BP,KAAK6H,cAAgB,SAAUtH,GAC3BA,EAAWA,EAASuD,KAAK9D,KACzB,IAAI8H,IAAa,EACbC,GAAa,CACb/D,KACA8D,EAA+C,iBAA3B9D,GAAiBgE,OAAsBhE,EAAiBgE,MAC5ED,EAA+C,iBAA3B/D,GAAiBiE,OAAsBjE,EAAiBiE,MAEhF,IAAIC,IACIC,oBAA8B,aAAT1G,GAAuBqG,EAC5CM,oBAA8B,aAAT3G,GAAuBsG,GAEhD5E,EAAc+E,CAClB/I,QAAO6C,MAAM,gBAAkBqG,KAAKC,UAAUnF,IAC9CvD,EAAG2I,YAAYpF,GAAaM,KAAK,SAAU+E,GAGvC,MAFArJ,QAAO6C,MAAM,qBACbwG,EAAQtG,EAAwBsG,GACzB5I,EAAG6I,oBAAoBD,KAC/B/E,KAAK,WACJ,GAAIiF,GAAmB9I,EAAG8I,gBAC1BvJ,QAAO6C,MAAM,wBAAyB0G,EAAiB9H,KACnDqE,GAAemC,WACfsB,EAAmBxD,EAAQyD,cAAcD,GACzCvJ,OAAO6C,MAAM,gCAAiC4G,QAAQF,KAE1DnI,EAAS,KAAMmI,EAAiB9H,IAAK+B,EAAKkG,cAAc/E,KAAKnB,MAC9De,MAAMnD,IAEbP,KAAK8I,0BAA4B,WAC7B,MAAOlJ,GAAG8I,kBAEd1I,KAAK+I,2BAA6B,WAC9B,MAAOnJ,GAAGa,mBAWdT,KAAK4C,eAAiB,WAClBF,EAAWX,UAAYd,EACvByB,EAAWsG,OAAQ,GAEvBhJ,KAAKiJ,KAAO,SAAUC,GACdnF,GAA0C,SAA3BA,EAAY8B,WAC3B9B,EAAYkF,KAAKC,GAEjB/J,OAAOiC,KAAK,mEAGpBpB,KAAK6I,cAAgB,SAAUM,EAAW5I,GACtCA,GAAYA,GAAYtB,MAAM6E,KAAK9D,KACnC,IAAImC,GAAS,GAAII,wBACTC,KAAM,SACN5B,IAAKuI,GAEb,IAAIlE,GAAemC,SAAU,CACzB,GAAIgC,GAAclE,EAAQmE,QAAQlH,EAClChD,QAAO6C,MAAM,gBAAiB4G,QAAQQ,IACtCjH,EAASiH,EAGb,GADAjK,OAAO6C,MAAM,mDACa,WAAtBpC,EAAGK,eACH,MAAOM,GAAS,2BAEpBX,GAAG0J,qBAAqBnH,EAAQ,WAC5BR,IACApB,KACDA,IAEPP,KAAKuJ,aAAe,SAAUC,EAAUjJ,GACpCA,EAAWA,EAASuD,KAAK9D,KACzB,IAAIwI,GAAQ,GAAIjG,wBACRC,KAAM,QACN5B,IAAK4I,GAEb,IAAIvE,GAAemC,SAAU,CACzB,GAAIqC,GAAavE,EAAQmE,QAAQb,EACjCrJ,QAAO6C,MAAM,eAAgB4G,QAAQa,IACrCjB,EAAQiB,EAGZ,GADAtK,OAAO6C,MAAM,kDACa,WAAtBpC,EAAGK,eACH,MAAOM,GAAS,2BAEpBX,GAAG0J,qBAAqBd,GAAO/E,KAAK,WAChC,MAAO9B,OACR8B,KAAK,WACJ,MAAO7D,GAAG8J,iBACXjG,KAAK,SAAUtB,GAGd,MAFAA,GAASD,EAAwBC,GACjChD,OAAO6C,MAAM,sBACNpC,EAAG6I,oBAAoBtG,KAC/BsB,KAAK,WACJ,GAAIiF,GAAmB9I,EAAG8I,gBACtBzD,IAAemC,WACfsB,EAAmBxD,EAAQyD,cAAcD,GACzCvJ,OAAO6C,MAAM,iCAAkC4G,QAAQF,KAE3DvJ,OAAO6C,MAAM,wBAAyB0G,EAAiB9H,KACvDL,EAAS,KAAMmI,EAAiB9H,OACjC8C,MAAMnD,IAmCA,aAATkB,GAAwBR,GAAgB6B,EAsBxC6G,WAAWlH,EAAO,GAZC,WAAf0B,EACAjB,EAASc,GAET4F,qBAAqBzF,EAAY,SAAUjF,EAAO2K,GAC9C,GAAI3K,EACA,MAAOqB,GAASrB,EACpBiE,cAAea,GACfb,YAAY2G,QAAQD,GACpB3G,EAASyB,UAAUoF,UAAM3G,GAAWD,eACrCoB,GAKXvE,KAAK+E,GAAG,WAAY,WACZrC,IACAA,EAAWb,QACXa,EAAWX,UAAY,KACvBW,EAAWT,OACXS,EAAWsG,OAAQ,GAEnBpH,IACAA,EAAYC,QACZD,EAAYG,UAAY,KACxBH,EAAYK,QAEhBU,EAAKqH,yBACmC5G,KAApC6G,OAAOC,0BACPD,OAAOC,yBAAyB3F,KAK5C,QAAS4F,wBAAuB3H,GAC5B,GAAI4H,GAAS,MAAQ5H,EAAO,QAC5B,QACI6H,YAAY,EACZ5E,IAAK,WACD,GAAKzF,KAAKkE,eAAV,CAEA,GAAIoG,GAAUtK,KAAKkE,eAAeqG,iBAClC,IAAKD,EAAQpK,OAAb,CAEA,IAAK,GAAWV,GAAPgL,EAAI,EAAWhL,EAAS8K,EAAQE,GAAIA,IAEzC,IAAK,GAAWnL,GADZoL,EAASjL,EAAO4K,KACXM,EAAI,EAAUrL,EAAQoL,EAAOC,GAAIA,IACtC,IAAKrL,EAAMsL,QACP,OAAO,CAEnB,QAAO,KAEXC,IAAK,SAAUlF,GACX,QAASmF,GAAexL,GACpBA,EAAMsL,QAAUjF,EAEpB1F,KAAKkE,eAAeqG,kBAAkB7K,QAAQ,SAAUF,GACpDA,EAAO4K,KAAU1K,QAAQmL,OAiDzC,QAASC,oBAAmBpJ,EAASnB,GACjC,KAAMP,eAAgB8K,qBAClB,MAAO,IAAIA,oBAAmBpJ,EAASnB,EAE3CuK,oBAAmBnH,OAAOC,KAAK5D,KAAM,WAAY0B,EAASnB,GAG9D,QAASwK,oBAAmBrJ,EAASnB,GACjC,KAAMP,eAAgB+K,qBAClB,MAAO,IAAIA,oBAAmBrJ,EAASnB,EAE3CwK,oBAAmBpH,OAAOC,KAAK5D,KAAM,WAAY0B,EAASnB,GAG9D,QAASyK,oBAAmBtJ,EAASnB,GACjC,KAAMP,eAAgBgL,qBAClB,MAAO,IAAIA,oBAAmBtJ,EAASnB,EAE3CyK,oBAAmBrH,OAAOC,KAAK5D,KAAM,WAAY0B,EAASnB,GAG9D,QAAS0K,WAAUzL,EAAQkC,GACvB,MAAOwJ,MAAK1L,EAAQkC,GAlhBxB,GAAImD,SAAUsG,QAAQ,WAClBC,SAAWD,QAAQ,YACnBE,SAAWF,QAAQ,gBACnB3G,KAAO2G,QAAQ,QACfD,KAAOC,QAAQ,QACflE,aAAekE,QAAQ,UAAUlE,aACjCtC,UAAYwG,QAAQ,SAASxG,UAAUb,SAAKV,IAAW,GACvD+B,cAAgBgG,QAAQ,kBACxBhM,OAAS8K,OAAOqB,QAAUC,OAC9B,KACIJ,QAAQ,8BACV,MAAOjM,GAC+B,mBAAzB0K,wBACPzK,OAAOiC,KAAK,mCACZwI,qBAAuB,SAA8BzF,EAAY5D,GAC7DA,EAAS,GAAIC,OAAM,qDAI/B,GAAI6C,oBACI2E,OAAO,EACPC,OACI/B,MAAO,IACPsF,UAAW,KAGnBC,GAAKxB,QAAUA,OAAO3G,UAAY2G,OAAO3G,UAAUoI,UAAY,GAC/D3I,OAAS,GAAIsI,UAASI,IACtBpJ,QAAUU,OAAOC,aACjBoE,UAAW,CACM,YAAjB/E,QAAQC,MAAsC,aAAjBD,QAAQC,OACrCnD,OAAO6C,MAAMK,QAAQC,KAAO,qBAC5B8E,UAAW,EAYf,IAAIwB,SAAU,SAAU+C,GACpB,WAA2B,KAAhBA,GAA+C,OAAhBA,EAC/B,GAEJ,SAAWA,EAAYnJ,KAAO,OAASmJ,EAAY/K,IAmY9DwK,UAAS5J,WAAYyF,cA6BrB1B,OAAOC,iBAAiBhE,WAAWoK,WAC/BjB,SACIN,YAAY,EACZ5E,IAAK,WACD,MAAOzF,MAAK6L,cAAgB7L,KAAK8L,cAErClB,IAAK,SAAUlF,GACX1F,KAAK6L,aAAe7L,KAAK8L,aAAepG,IAGhDmG,aAAgB1B,uBAAuB,SACvC2B,aAAgB3B,uBAAuB,WAE3C3I,WAAWoK,UAAUG,eAAiB,SAAUC,GAC5C,GAAIhM,KAAKkE,eACL,MAAOlE,MAAKkE,eAAeqG,kBAAkByB,GAAS,IAG9DxK,WAAWoK,UAAUK,gBAAkB,SAAUD,GAC7C,GAAIhM,KAAKkE,eACL,MAAOlE,MAAKkE,eAAepC,mBAAmBkK,GAAS,IAG/DxK,WAAWoK,UAAUM,QAAU,WAC3B/M,OAAO6C,MAAM,uBACb,IAAIpC,GAAKI,KAAKkE,eACViI,EAAKnM,KAAK+D,WACd,KACI,GAAIoI,EAAI,CACJ,GAA0B,WAAtBA,EAAGlM,eACH,MACJkM,GAAGC,QAEP,GAAIxM,EAAI,CACJ,GAA0B,WAAtBA,EAAGK,eACH,MACJL,GAAG2K,kBAAkB7K,QAAQH,YAC7BK,EAAGwM,SAET,MAAOC,GACLlN,OAAOiC,KAAK,mCAAqCiL,GAErDrM,KAAKsH,KAAK,aAQd8D,SAASN,mBAAoBtJ,YAO7B4J,SAASL,mBAAoBvJ,YAO7B4J,SAASJ,mBAAoBxJ,YAI7B8K,QAAQ3M,oBAAsBA,oBAC9B2M,QAAQxB,mBAAqBA,mBAC7BwB,QAAQvB,mBAAqBA,mBAC7BuB,QAAQtB,mBAAqBA,mBAC7BsB,QAAQpB,KAAOD;;ACxhBXhB,OAAOlK,mBACPwM,OAAOD,QAAUnB,QAAQ;;ACD7B,GAAI3J,YAAa2J,QAAQ,eACzBmB,SAAQ9K,WAAaA;;ACoBrB,QAASyF,gBACPjH,KAAKwM,QAAUxM,KAAKwM,YACpBxM,KAAKyM,cAAgBzM,KAAKyM,mBAAiBrJ,GAwQ7C,QAASsJ,YAAWC,GAClB,MAAsB,kBAARA,GAGhB,QAASC,UAASD,GAChB,MAAsB,gBAARA,GAGhB,QAASE,UAASF,GAChB,MAAsB,gBAARA,IAA4B,OAARA,EAGpC,QAASG,aAAYH,GACnB,WAAe,KAARA,EAnRTJ,OAAOD,QAAUrF,aAGjBA,aAAaA,aAAeA,aAE5BA,aAAa2E,UAAUY,YAAUpJ,GACjC6D,aAAa2E,UAAUa,kBAAgBrJ,GAIvC6D,aAAa8F,oBAAsB,GAInC9F,aAAa2E,UAAUoB,gBAAkB,SAASnM,GAChD,IAAK+L,SAAS/L,IAAMA,EAAI,GAAKoM,MAAMpM,GACjC,KAAMqM,WAAU,8BAElB,OADAlN,MAAKyM,cAAgB5L,EACdb,MAGTiH,aAAa2E,UAAUtE,KAAO,SAAS9E,GACrC,GAAI2K,GAAIC,EAASC,EAAKC,EAAM9C,EAAG+C,CAM/B,IAJKvN,KAAKwM,UACRxM,KAAKwM,YAGM,UAAThK,KACGxC,KAAKwM,QAAQtN,OACb2N,SAAS7M,KAAKwM,QAAQtN,SAAWc,KAAKwM,QAAQtN,MAAMgB,QAAS,CAEhE,IADAiN,EAAKK,UAAU,aACGhN,OAChB,KAAM2M,EAGN,IAAId,GAAM,GAAI7L,OAAM,yCAA2C2M,EAAK,IAEpE,MADAd,GAAIoB,QAAUN,EACRd,EAOZ,GAFAe,EAAUpN,KAAKwM,QAAQhK,GAEnBsK,YAAYM,GACd,OAAO,CAET,IAAIV,WAAWU,GACb,OAAQI,UAAUtN,QAEhB,IAAK,GACHkN,EAAQxJ,KAAK5D,KACb,MACF,KAAK,GACHoN,EAAQxJ,KAAK5D,KAAMwN,UAAU,GAC7B,MACF,KAAK,GACHJ,EAAQxJ,KAAK5D,KAAMwN,UAAU,GAAIA,UAAU,GAC3C,MAEF,SACEF,EAAOI,MAAM9B,UAAU7K,MAAM6C,KAAK4J,UAAW,GAC7CJ,EAAQrD,MAAM/J,KAAMsN,OAEnB,IAAIT,SAASO,GAIlB,IAHAE,EAAOI,MAAM9B,UAAU7K,MAAM6C,KAAK4J,UAAW,GAC7CD,EAAYH,EAAQrM,QACpBsM,EAAME,EAAUrN,OACXsK,EAAI,EAAGA,EAAI6C,EAAK7C,IACnB+C,EAAU/C,GAAGT,MAAM/J,KAAMsN,EAG7B,QAAO,GAGTrG,aAAa2E,UAAU+B,YAAc,SAASnL,EAAMiF,GAClD,GAAImG,EAEJ,KAAKlB,WAAWjF,GACd,KAAMyF,WAAU,8BA2ClB,OAzCKlN,MAAKwM,UACRxM,KAAKwM,YAIHxM,KAAKwM,QAAQqB,aACf7N,KAAKsH,KAAK,cAAe9E,EACfkK,WAAWjF,EAASA,UACpBA,EAASA,SAAWA,GAE3BzH,KAAKwM,QAAQhK,GAGTqK,SAAS7M,KAAKwM,QAAQhK,IAE7BxC,KAAKwM,QAAQhK,GAAM9B,KAAK+G,GAGxBzH,KAAKwM,QAAQhK,IAASxC,KAAKwM,QAAQhK,GAAOiF,GAN1CzH,KAAKwM,QAAQhK,GAAQiF,EASnBoF,SAAS7M,KAAKwM,QAAQhK,MAAWxC,KAAKwM,QAAQhK,GAAMsL,SAIpDF,EAHGd,YAAY9M,KAAKyM,eAGhBxF,aAAa8F,oBAFb/M,KAAKyM,gBAKFmB,EAAI,GAAK5N,KAAKwM,QAAQhK,GAAMtC,OAAS0N,IAC5C5N,KAAKwM,QAAQhK,GAAMsL,QAAS,EAC5BvC,QAAQrM,MAAM,mIAGAc,KAAKwM,QAAQhK,GAAMtC,QACJ,kBAAlBqL,SAAQwC,OAEjBxC,QAAQwC,SAKP/N,MAGTiH,aAAa2E,UAAU7G,GAAKkC,aAAa2E,UAAU+B,YAEnD1G,aAAa2E,UAAUoC,KAAO,SAASxL,EAAMiF,GAM3C,QAASwG,KACPjO,KAAKkO,eAAe1L,EAAMyL,GAErBE,IACHA,GAAQ,EACR1G,EAASsC,MAAM/J,KAAMwN,YAVzB,IAAKd,WAAWjF,GACd,KAAMyF,WAAU,8BAElB,IAAIiB,IAAQ,CAcZ,OAHAF,GAAExG,SAAWA,EACbzH,KAAK+E,GAAGvC,EAAMyL,GAEPjO,MAITiH,aAAa2E,UAAUsC,eAAiB,SAAS1L,EAAMiF,GACrD,GAAI2G,GAAMC,EAAUnO,EAAQsK,CAE5B,KAAKkC,WAAWjF,GACd,KAAMyF,WAAU,8BAElB,KAAKlN,KAAKwM,UAAYxM,KAAKwM,QAAQhK,GACjC,MAAOxC,KAMT,IAJAoO,EAAOpO,KAAKwM,QAAQhK,GACpBtC,EAASkO,EAAKlO,OACdmO,GAAY,EAERD,IAAS3G,GACRiF,WAAW0B,EAAK3G,WAAa2G,EAAK3G,WAAaA,QAC3CzH,MAAKwM,QAAQhK,GAChBxC,KAAKwM,QAAQ0B,gBACflO,KAAKsH,KAAK,iBAAkB9E,EAAMiF,OAE/B,IAAIoF,SAASuB,GAAO,CACzB,IAAK5D,EAAItK,EAAQsK,KAAM,GACrB,GAAI4D,EAAK5D,KAAO/C,GACX2G,EAAK5D,GAAG/C,UAAY2G,EAAK5D,GAAG/C,WAAaA,EAAW,CACvD4G,EAAW7D,CACX,OAIJ,GAAI6D,EAAW,EACb,MAAOrO,KAEW,KAAhBoO,EAAKlO,QACPkO,EAAKlO,OAAS,QACPF,MAAKwM,QAAQhK,IAEpB4L,EAAKE,OAAOD,EAAU,GAGpBrO,KAAKwM,QAAQ0B,gBACflO,KAAKsH,KAAK,iBAAkB9E,EAAMiF,GAGtC,MAAOzH,OAGTiH,aAAa2E,UAAU5B,mBAAqB,SAASxH,GACnD,GAAI+L,GAAKhB,CAET,KAAKvN,KAAKwM,QACR,MAAOxM,KAGT,KAAKA,KAAKwM,QAAQ0B,eAKhB,MAJyB,KAArBV,UAAUtN,OACZF,KAAKwM,WACExM,KAAKwM,QAAQhK,UACbxC,MAAKwM,QAAQhK,GACfxC,IAIT,IAAyB,IAArBwN,UAAUtN,OAAc,CAC1B,IAAKqO,IAAOvO,MAAKwM,QACH,mBAAR+B,GACJvO,KAAKgK,mBAAmBuE,EAI1B,OAFAvO,MAAKgK,mBAAmB,kBACxBhK,KAAKwM,WACExM,KAKT,GAFAuN,EAAYvN,KAAKwM,QAAQhK,GAErBkK,WAAWa,GACbvN,KAAKkO,eAAe1L,EAAM+K,OACrB,IAAIA,EAET,KAAOA,EAAUrN,QACfF,KAAKkO,eAAe1L,EAAM+K,EAAUA,EAAUrN,OAAS,GAI3D,cAFOF,MAAKwM,QAAQhK,GAEbxC,MAGTiH,aAAa2E,UAAU2B,UAAY,SAAS/K,GAQ1C,MANKxC,MAAKwM,SAAYxM,KAAKwM,QAAQhK,GAE1BkK,WAAW1M,KAAKwM,QAAQhK,KACxBxC,KAAKwM,QAAQhK,IAEdxC,KAAKwM,QAAQhK,GAAMzB,YAI7BkG,aAAa2E,UAAU1E,cAAgB,SAAS1E,GAC9C,GAAIxC,KAAKwM,QAAS,CAChB,GAAIgC,GAAaxO,KAAKwM,QAAQhK,EAE9B,IAAIkK,WAAW8B,GACb,MAAO,EACJ,IAAIA,EACP,MAAOA,GAAWtO,OAEtB,MAAO,IAGT+G,aAAaC,cAAgB,SAASuH,EAASjM,GAC7C,MAAOiM,GAAQvH,cAAc1E;;AC3R/B,YAEA,IAAIkM,WAAYvD,QAAQ,aA8DpBtG,QAAU0H,OAAOD,QAAU,SAASqC,GAWtC,QAASC,GAAWpM,EAAMqM,GAKxB,IAJA,GAEIC,GAFAC,KACAC,KAAWC,OAAOC,EAAQ1M,IAGvBwM,EAAM9O,QAAU6O,EAAI7O,OAAS2O,GAClCC,EAAOK,KAAKC,SAAWJ,EAAM9O,OAAU,EACvC6O,EAAMA,EAAIE,OAAOD,EAAMV,OAAOQ,EAAK,GAGrC,OAAOC,GAAIM,IAAI,SAASC,GAEpB,MAAoB,gBAARA,IAAyBA,YAAeC,QAGzCb,UAAUlM,EAAO,IAAM8M,GAFvBA,IAtBjB,GAOIE,GAPAN,GACFO,MAAOd,OAAYc,MAAQtE,QAAQ,eACnCuE,MAAOf,OAAYe,MAAQvE,QAAQ,gBAGjCwE,GAAahB,OAAYgB,WAAa,EACtCC,GAAajB,OAAYiB,WAAa,CA8B1C,OANAJ,MAAcP,OAAOL,EAAW,OAAQe,IAEpCC,IACFJ,EAAWA,EAASP,OAAOL,EAAW,OAAQgB,KAGzCJ;;ANvGT;;ACAA;;AMEA,QAASK,cAAcC,EAAUC,GAC/B,GAAIC,IAAaC,EAAAA,CACjBH,GAASI,sBAAsBH,EAE/B,KAAI,GAAIvF,GAAE,EAAG2F,EAAGJ,EAAQ7P,OAAQsK,EAAI2F,EAAI3F,IAClCuF,EAAQvF,GAAKwF,GAAaD,EAAQvF,GAAK,IACzCwF,EAAYD,EAAQvF,GAIxB,OAAOwF,GAZT,GAAII,aAAcjF,QAAQ,eAgBtBkF,iBAAmBpG,OAAOqG,cAAgBrG,OAAOsG,mBAEjDC,aAAe,IACnBjE,QAAOD,QAAU,SAAS9M,EAAQkC,GAChC,GAAI+O,GAAS,GAAIL,YAIjB,KAAKC,iBAAkB,MAAOI,EAG9B,IAAI/O,GAAUA,MACVgP,EAAahP,EAAQgP,WAAa,GAClCC,EAAYjP,EAAQiP,UAAY,GAChCC,EAAYlP,EAAQkP,UACpBC,EAAOnP,EAAQmP,KACfC,EAAUpP,EAAQoP,SAAW,GAC7BC,GAAU,CAGTP,gBACHA,aAAe,GAAIH,kBAErB,IAAIW,GAAYjB,EAASD,CAEzBA,GAAWU,aAAaS,iBACxBnB,EAASoB,QAAU,IACnBpB,EAASqB,sBAAwBT,EACjCX,EAAU,GAAIqB,cAAatB,EAASoB,SAEhC1R,EAAO6R,SAAQ7R,EAASA,EAAO,IAC/BA,YAAkB8R,mBAAoB9R,YAAkB+R,mBAE1DP,EAAaR,aAAagB,yBAAyBhS,OAC/B,KAATqR,IAAsBA,GAAO,GACxCD,EAAYA,IAAc,KAG1BI,EAAaR,aAAaiB,wBAAwBjS,GAClDoR,EAAYA,IAAc,IAG5BI,EAAWU,QAAQ5B,GACfe,GAAMf,EAAS4B,QAAQlB,aAAamB,aAExClB,EAAOmB,UAAW,EAElBnB,EAAOoB,aAAe,SAASC,GAC7BlB,EAAYkB,GAGdrB,EAAOsB,YAAc,SAASvH,GAC5BmG,EAAWnG,GAGbiG,EAAOnR,KAAO,WACZyR,GAAU,EACVN,EAAOnJ,KAAK,iBAAkB,IAAKsJ,GAC/BH,EAAOmB,WACTnB,EAAOmB,UAAW,EAClBnB,EAAOnJ,KAAK,sBAGhBmJ,EAAOuB,kBACP,KAAK,GAAIxH,GAAI,EAAGA,EAAIsG,EAAStG,IACzBiG,EAAOuB,gBAAgBtR,KAAK,EAKhC,IAAIuR,GAAS,WACXtI,WAAW,WAGT,GAAIoH,EAAJ,CAIA,GAAImB,GAAgBrC,aAAaC,EAAUC,EAE3CU,GAAOnJ,KAAK,gBAAiB4K,EAAetB,EAE5C,IAAIE,GAAU,CACd,IAAIoB,EAAgBtB,IAAcH,EAAOmB,SAAU,CAEjD,IAAK,GAAIpH,GAAIiG,EAAOuB,gBAAgB9R,OAAS,EAAGsK,EAAIiG,EAAOuB,gBAAgB9R,OAAQsK,IACjFsG,GAAWL,EAAOuB,gBAAgBxH,EAEhCsG,IAAW,IACbL,EAAOmB,UAAW,EAClBnB,EAAOnJ,KAAK,iBAET,IAAI4K,EAAgBtB,GAAaH,EAAOmB,SAAU,CACvD,IAAK,GAAIpH,GAAI,EAAGA,EAAIiG,EAAOuB,gBAAgB9R,OAAQsK,IACjDsG,GAAWL,EAAOuB,gBAAgBxH,EAErB,IAAXsG,IACFL,EAAOmB,UAAW,EAClBnB,EAAOnJ,KAAK,qBAGhBmJ,EAAOuB,gBAAgB5R,QACvBqQ,EAAOuB,gBAAgBtR,KAAK,GAAKwR,EAAgBtB,IAEjDqB,MACCtB,GAKL,OAHAsB,KAGOxB;;AC9HoB,kBAAlBlL,QAAO4M,OAEhB5F,OAAOD,QAAU,SAAkB8F,EAAMC,GACvCD,EAAKzO,OAAS0O,EACdD,EAAKxG,UAAYrG,OAAO4M,OAAOE,EAAUzG,WACvC0G,aACE5M,MAAO0M,EACP/H,YAAY,EACZ1E,UAAU,EACV4M,cAAc,MAMpBhG,OAAOD,QAAU,SAAkB8F,EAAMC,GACvCD,EAAKzO,OAAS0O,CACd,IAAIG,GAAW,YACfA,GAAS5G,UAAYyG,EAAUzG,UAC/BwG,EAAKxG,UAAY,GAAI4G,GACrBJ,EAAKxG,UAAU0G,YAAcF;;;;CCXhC,SAAUK,GAsEV,QAASC,GAAgBC,EAAMC,GAE9B,GAAqB,WAAjBC,EAAOF,GAEV,MAAOC,EAER,KAAK,GAAIrE,KAAOqE,GAEW,WAAtBC,EAAOF,EAAKpE,KAA8C,WAAxBsE,EAAOD,EAAOrE,IAEnDoE,EAAKpE,GAAOmE,EAAgBC,EAAKpE,GAAMqE,EAAOrE,IAI9CoE,EAAKpE,GAAOqE,EAAOrE,EAMrB,OAAOoE,GAYR,QAASG,GAAMC,EAAOpO,EAAWqO,GAEhC,GAAIC,GAASD,EAAK,GACjBE,EAAOF,EAAK9S,QAET6S,GAA4B,WAAnBF,EAAOI,MAEnBA,KAED,KAAK,GAAIjH,GAAM,EAAEA,EAAMkH,IAAOlH,EAAO,CAEpC,GAAImH,GAAOH,EAAKhH,EAIhB,IAAa,WAFL6G,EAAOM,GAIf,IAAK,GAAI5E,KAAO4E,GAAM,CAErB,GAAIC,GAAQL,EAAQM,EAAON,MAAMI,EAAK5E,IAAQ4E,EAAK5E,EAIlD0E,GAAO1E,GAFJ5J,EAEW+N,EAAgBO,EAAO1E,GAAM6E,GAI7BA,GAQjB,MAAOH,GAYR,QAASJ,GAAO7D,GAEf,SAAYsE,SAAS1P,KAAKoL,GAAOjO,MAAM,GAAI,GAAGwS,cA9I/C,GAAIF,GAAS,SAASN,GAErB,MAAOD,IAAgB,IAAVC,GAAgB,EAAOvF,WAWrC6F,GAAO1O,UAAY,SAASoO,GAE3B,MAAOD,IAAgB,IAAVC,GAAgB,EAAMvF,YAUpC6F,EAAON,MAAQ,SAAS/D,GAEvB,GAEChD,GAAOkH,EAFJM,EAASxE,EACZxM,EAAOqQ,EAAO7D,EAGf,IAAa,UAATxM,EAKH,IAHAgR,KACAN,EAAOlE,EAAM9O,OAER8L,EAAM,EAAEA,EAAMkH,IAAOlH,EAEzBwH,EAAOxH,GAASqH,EAAON,MAAM/D,EAAMhD,QAE9B,IAAa,WAATxJ,EAAmB,CAE7BgR,IAEA,KAAKxH,IAASgD,GAEbwE,EAAOxH,GAASqH,EAAON,MAAM/D,EAAMhD,IAIrC,MAAOwH,IAgGJf,EAEHlG,OAAOD,QAAU+G,EAIjBpJ,OAAiB,MAAIoJ,GAIF,gBAAX9G,SAAuBA,QAAoC,gBAAnBA,QAAOD,SAAwBC,OAAOD;;AChKxF,GAAImH,YACF,QACA,QAGFlH,QAAOD,QAAU,SAAS0C,GACxB,GACI0E,GACAC,EAFArE,GAAON,OAAaM,KAAON,EAG3BwE,IAGJ,OAAkB,gBAAPlE,IAAuBA,YAAeC,SAKjDD,EAAMA,EAAIsE,QAGVF,EAAWD,UAAUA,UAAU3S,QAAQwO,EAAIvO,MAAM,EAAG,OAMpDuO,EAAMA,EAAIvO,MAAM,GAChB4S,EAAQrE,EAAIuE,MAAM,KAElBL,EAAOM,SAAW9E,EAAM8E,SACxBN,EAAOO,WAAa/E,EAAM+E,WAEtBJ,EAAMzT,OAAS,IACjBoP,EAAMqE,EAAM,GACZA,EAAQA,EAAM,GAAGE,MAAM,KAGvBL,EAAOM,SAAWH,EAAM,GACxBH,EAAOO,YAAc/E,OAAa+E,YAAcJ,EAAM,IAAM,IAG9DH,EAAOlE,IAAMoE,EAAWpE,EACxBkE,EAAOQ,MAASR,EAAOlE,KAEhBkE,GAtBExE,GATAA;;AC3BX,GAAIiF,SAAU1H,OAAOD,SACnB4H,IACI5R,KAAM,UACN6R,IAAK,YAETC,IAEE9R,KAAM,SACN6R,IAAK,wCACLE,OAAQ,WAAY,YAAa,iBAAkB,UAAW,QAAS,WACvEC,OAAQ,wBAGVC,IAAMjS,KAAM,SACZkI,IAAMlI,KAAM,gBACZkS,IAAMlS,KAAM,QACZmS,IAAMnS,KAAM,UACZoS,IAAMpS,KAAM,UACZqS,IAAMrS,KAAM,cACZsS,IAAMtS,KAAM,YAEZwP,IACExP,KAAM,SACN6R,IAAK,eACLE,OAAQ,QAAS,QACjBC,OAAQ,UAEVO,IACIvS,KAAM,aACN6R,IAAK,mBACLE,OAAQ,UAAW,MACnBC,OAAQ,eAEZQ,IACIpU,KAAM,YACNyT,IAAK,4BACLE,OAAQ,OAAQ,SAChBC,OAAQ,UAEZ1G,IAGIuG,IAAK,mCACLE,OAAQ,OAAQ,OAAQ,WAAY,YACpCC,OAAQ,gBAEZS,IAEIrU,KAAM,MACNyT,IAAK,wDACLE,OAAQ,UAAW,QAAS,OAAQ,YACpCC,OAAQ,SAAUF,GAChB,MAAQA,GAAU,SAChB,qBACAA,EAAEY,KACF,kBACA,kBAMJtU,KAAM,OACNyT,IAAK,wBACLE,OAAQ,UAAW,UACnBC,OAAQ,eAGNhS,KAAM,UACN6R,IAAK,gBACLG,OAAQ,eAGVhS,KAAM,OACN6R,IAAK,sCACLE,OAAQ,OAAQ,UAAW,QAAS,WACpCC,OAAQ,SAAUF,GAChB,MAAqB,OAAbA,EAAEa,QACR,qBACA,aAIJvU,KAAM,eACNyT,IAAK,kCACLE,OAAQ,UAAW,SACnBC,OAAQ,0BAGR5T,KAAM,SACNyT,IAAK,6CACLE,OAAQ,UAAW,OAAQ,WAC3BC,OAAQ,SAAUF,GAChB,MAAqB,OAAbA,EAAEc,QACR,mBACA,mBAKJxU,KAAM,MACNyT,IAAK,sCACLE,OAAQ,QAAS,MAAO,UACxBC,OAAQ,SAAUF,GAChB,MAAoB,OAAZA,EAAEe,OACR,kBACA,kBAKJzU,KAAM,SACNyT,IAAK,0CACLE,OAAQ,KAAM,QAAS,SAAU,iBACjCC,OAAQ,SAAUF,GAChB,MAA2B,OAAnBA,EAAEgB,cACR,qBACA,qBAIJ9S,KAAM,QACN6R,IAAK,eACLG,OAAQ,aAGRhS,KAAM,MACN6R,IAAK,gBACLG,OAAQ,WAGRhS,KAAM,OACN6R,IAAK,aACLG,OAAQ,YAGRhS,KAAM,QACN6R,IAAK,eACLG,OAAQ,aAGRhS,KAAM,WACN6R,IAAK,kBACLG,OAAQ,gBAGRhS,KAAM,YACN6R,IAAK,2CAGL7R,KAAM,UACN6R,IAAK,gBAGL7R,KAAM,WACN6R,IAAK,mBACLG,OAAQ,iBAGRhS,KAAM,SACN6R,IAAK,iBACLG,OAAQ,eAGRhS,KAAM,cACN6R,IAAK,2BACLE,OAAQ,OAAQ,QAChBC,OAAQ,sBAQR5T,KAAK,aACLyT,IAAK,iIACLE,OAAQ,aAAc,YAAa,YAAa,WAAY,KAAM,OAAQ,OAAQ,QAAS,QAAS,UAAW,cAC/GC,OAAQ,SAAUF,GAChB,GAAIiB,GAAM,oCAUV,OARAA,IAAmB,MAAXjB,EAAEkB,MAAiB,qBAAuB,OAGlDD,GAAqB,MAAbjB,EAAEmB,QAAmB,cAAgB,KAEzB,MAAhBnB,EAAEoB,aACJH,GAAO,kBAEFA,KAIT/S,KAAM,kBACN6R,IAAK,yBAGL7R,KAAM,mBACN6R,IAAK,0BACLG,OAAQ,yBAGRhS,KAAM,aACN6R,IAAK,qBACLG,OAAQ,mBAGR5T,KAAM,QACNyT,IAAK,4BACLE,OAAQ,KAAM,YAAa,SAC3BC,OAAQ,kBAGR5T,KAAM,aACNyT,IAAK,yBACLE,OAAQ,YAAa,SACrBC,OAAQ,qBAGRhS,KAAM,eACN6R,IAAK,gCACLE,OAAQ,WAAY,SACpBC,OAAQ,yBAGR5T,KAAM,SACNyT,IAAK,oBACLE,OAAQ,OAAQ,QAChBC,OAAQ,gBAGRhS,KAAM,UACN6R,IAAK,gBAGL7R,KAAM,YACN6R,IAAK,kBAGLzT,KAAM,UACN2T,OAAQ,WAMd9O,QAAOkQ,KAAKxB,SAASvU,QAAQ,SAAU6O,GAC1B0F,QAAQ1F,GACd7O,QAAQ,SAAUgW,GAChBA,EAAIvB,MACPuB,EAAIvB,IAAM,QAEPuB,EAAIpB,SACPoB,EAAIpB,OAAS;;AC7PnB,GAAIvR,QAASoI,QAAQ,YACjBwK,OAASxK,QAAQ,WAErBmB,SAAQsJ,MAAQD,OAChBrJ,QAAQuJ,MAAQ9S,OAAO8S,MACvBvJ,QAAQwJ,gBAAkB/S,OAAO+S,gBACjCxJ,QAAQyJ,cAAgBhT,OAAOgT,cAC/BzJ,QAAQ0J,sBAAwBjT,OAAOiT;;ACPvC,GAAIC,YAAa,SAAU/B,GACzB,MAAO3E,QAAO2G,OAAOhC,MAAQA,EAAIgC,OAAOhC,GAAKA,GAG3CiC,iBAAmB,SAAUC,EAAOC,EAAUhC,EAAOiC,GACvD,GAAIA,IAAYjC,EACdgC,EAASC,GAAWL,WAAWG,EAAM,QAGrC,KAAK,GAAI5L,GAAI,EAAGA,EAAI6J,EAAMnU,OAAQsK,GAAK,EACnB,MAAd4L,EAAM5L,EAAE,KACV6L,EAAShC,EAAM7J,IAAMyL,WAAWG,EAAM5L,EAAE,MAM5C+L,SAAW,SAAUb,EAAKW,EAAUG,GACtC,GAAIC,GAAaf,EAAIpT,MAAQoT,EAAIrB,KAC7BqB,GAAIhV,OAAS2V,EAASX,EAAIhV,MAC5B2V,EAASX,EAAIhV,SAEN+V,IAAeJ,EAASX,EAAIpT,QACnC+T,EAASX,EAAIpT,SAEf,IAAIoU,GAAchB,EAAIhV,QAEpB+V,EAAaJ,EAASX,EAAIpT,MAAQ+T,CAEpCF,kBAAiBK,EAAQJ,MAAMV,EAAIvB,KAAMuC,EAAahB,EAAIrB,MAAOqB,EAAIpT,MAEjEoT,EAAIhV,MACN2V,EAASX,EAAIhV,MAAMA,KAAKgW,IAIxBzC,QAAU9I,QAAQ,aAClBwL,UAAYC,OAAOhL,UAAUiL,KAAK/S,KAAK,gBAE3CwI,SAAQuJ,MAAQ,SAAUjV,GACxB,GAAIkW,MACAC,KACAV,EAAWS,CAoBf,OAjBAlW,GAAIiT,MAAM,gBAAgBmD,OAAOL,WAAWjX,QAAQ,SAAUuX,GAC5D,GAAIzU,GAAOyU,EAAE,GACTT,EAAUS,EAAElW,MAAM,EACT,OAATyB,IACFuU,EAAMrW,MAAMwW,OAASC,UACrBd,EAAWU,EAAMA,EAAM7W,OAAO,GAGhC,KAAK,GAAIwK,GAAI,EAAGA,GAAKuJ,QAAQzR,QAAatC,OAAQwK,GAAK,EAAG,CACxD,GAAIgL,GAAMzB,QAAQzR,GAAMkI,EACxB,IAAIgL,EAAIvB,IAAI0C,KAAKL,GACf,MAAOD,UAASb,EAAKW,EAAUG,MAKrCM,EAAQC,MAAQA,EACTD,EAGT,IAAIM,aAAc,SAAUC,EAAKC,GAC/B,GAAI/C,GAAI+C,EAAKzD,MAAM,IAInB,OAHiB,KAAbU,EAAErU,SACJmX,EAAI9C,EAAE,IAAM0B,WAAW1B,EAAE,KAEpB8C,EAGT/K,SAAQwJ,gBAAkB,SAAUT,GAClC,MAAOA,GAAIxB,MAAM,SAAS0D,OAAOH,iBAGnC9K,QAAQyJ,cAAgB,SAAUV,GAChC,MAAOA,GAAIxB,MAAM,KAAKxE,IAAI6G,SAG5B5J,QAAQ0J,sBAAwB,SAAUX,GAGxC,IAAK,GAFDmC,MACA7D,EAAQ0B,EAAIxB,MAAM,KAAKxE,IAAI4G,YACtBzL,EAAI,EAAGA,EAAImJ,EAAMzT,OAAQsK,GAAK,EACrCgN,EAAW9W,MACT+W,UAAW9D,EAAMnJ,GACjBkN,GAAI/D,EAAMnJ,EAAI,GACdmN,KAAMhE,EAAMnJ,EAAI,IAGpB,OAAOgN;;AC3FT,GAAIvD,SAAU9I,QAAQ,aAGlByM,aAAe,WACftD,OAAS,SAAUuD,GACrB,GAAIrN,GAAI,EACJ8C,EAAOE,UACPH,EAAMC,EAAKpN,MACf,OAAO2X,GAAUC,QAAQF,aAAc,SAAUG,GAC/C,GAAIvN,GAAK6C,EACP,MAAO0K,EAET,IAAIpL,GAAMW,EAAK9C,EAEf,QADAA,GAAK,EACGuN,GACN,IAAK,KACH,MAAO,GACT,KAAK,KACH,MAAOxI,QAAO5C,EAChB,KAAK,KACH,MAAOuJ,QAAOvJ,EAChB,KAAK,KACH,MAAO,OAMXqL,SAAW,SAAUxV,EAAMkT,EAAKW,GAClC,GAAIhB,GAAMK,EAAIpB,iBAAkBzQ,UAC7B6R,EAAIpB,OAAOoB,EAAIhV,KAAO2V,EAAWA,EAASX,EAAIpT,OAC/CoT,EAAIpB,OAEFhH,GAAQ9K,EAAO,IAAM6S,EACzB,IAAIK,EAAIrB,MACN,IAAK,GAAI7J,GAAI,EAAGA,EAAIkL,EAAIrB,MAAMnU,OAAQsK,GAAK,EAAG,CAC5C,GAAI3J,GAAI6U,EAAIrB,MAAM7J,EACdkL,GAAIpT,KACNgL,EAAK5M,KAAK2V,EAASX,EAAIpT,MAAMzB,IAG7ByM,EAAK5M,KAAK2V,EAASX,EAAIrB,MAAM7J,SAKjC8C,GAAK5M,KAAK2V,EAASX,EAAIpT,MAEzB,OAAOgS,QAAOvK,MAAM,KAAMuD,IAKxB2K,mBACF,IAAK,IAAK,IAAK,IACf,IAAK,IAAK,IAAK,IACf,IAAK,IAAK,IAAK,IAAK,KAElBC,mBAAqB,IAAK,IAAK,IAAK,IAGxC3L,QAAOD,QAAU,SAAUwK,EAASnI,GAClCA,EAAOA,MAEgB,MAAnBmI,EAAQqB,UACVrB,EAAQqB,QAAU,GAEA,MAAhBrB,EAAQxU,OACVwU,EAAQxU,KAAO,KAEjBwU,EAAQC,MAAMrX,QAAQ,SAAU0Y,GACR,MAAlBA,EAAMC,WACRD,EAAMC,SAAW,KAIrB,IAAIC,GAAa3J,EAAK2J,YAAcL,kBAChCM,EAAa5J,EAAK4J,YAAcL,kBAChCtX,IAkCJ,OA/BA0X,GAAW5Y,QAAQ,SAAU8C,GAC3ByR,QAAQzR,GAAM9C,QAAQ,SAAUgW,GAC1BA,EAAIpT,OAAQwU,IAAgC,MAArBA,EAAQpB,EAAIpT,MACrC1B,EAAIF,KAAKsX,SAASxV,EAAMkT,EAAKoB,IAEtBpB,EAAIhV,OAAQoW,IAAgC,MAArBA,EAAQpB,EAAIhV,OAC1CoW,EAAQpB,EAAIhV,MAAMhB,QAAQ,SAAU8Y,GAClC5X,EAAIF,KAAKsX,SAASxV,EAAMkT,EAAK8C,UAOrC1B,EAAQC,MAAMrX,QAAQ,SAAU0Y,GAC9BxX,EAAIF,KAAKsX,SAAS,IAAK/D,QAAQrG,EAAE,GAAIwK,IAErCG,EAAW7Y,QAAQ,SAAU8C,GAC3ByR,QAAQzR,GAAM9C,QAAQ,SAAUgW,GAC1BA,EAAIpT,OAAQ8V,IAA4B,MAAnBA,EAAM1C,EAAIpT,MACjC1B,EAAIF,KAAKsX,SAASxV,EAAMkT,EAAK0C,IAEtB1C,EAAIhV,OAAQ0X,IAA4B,MAAnBA,EAAM1C,EAAIhV,OACtC0X,EAAM1C,EAAIhV,MAAMhB,QAAQ,SAAU8Y,GAChC5X,EAAIF,KAAKsX,SAASxV,EAAMkT,EAAK8C,YAOhC5X,EAAIW,KAAK,QAAU;;ACjG5BgL,OAAOD,QAAU,QAASmM,GAAYC,GAElC,IAAKA,EACD,OAAO,CAGX,IAAI1Y,KAAKE,QAAUwY,EAAMxY,OACrB,OAAO,CAEX,KAAK,GAAIsK,GAAI,EAAGyM,EAAIjX,KAAKE,OAAQsK,EAAIyM,EAAGzM,IAEpC,GAAIxK,KAAKwK,YAAckD,QAASgL,EAAMlO,YAAckD,QAEhD,IAAK+K,EAAY1O,MAAM/J,KAAKwK,IAAKkO,EAAMlO,KACnC,OAAO,MACR,IAAIxK,KAAKwK,IAAMkO,EAAMlO,GAGxB,OAAO,CAGf,QAAO;;ACrBX8B,QAAQlH,QAAU+F,QAAQ;;ACG1B,YAKA,SAAS/F,WASLpF,KAAK2Y,OACDC,YACAC,aA4QR,QAASC,cAAaC,OACS,KAAhBA,EAAMC,QAIG,WAAhBD,EAAMC,MACFD,EAAMC,MAAQ,UACK,YAAhBD,EAAMC,QACbD,EAAMC,MAAQ,WAlStB,GAAIC,WAAY9N,QAAQ,eACpBsN,YAActN,QAAQ,iBAiB1BoB,QAAOD,QAAUlH,QAKjBA,QAAQwG,UAAUvE,uBAAyB,SAAS/G,GAChD,GAAI6G,GAAO,GAAIS,iBAAgBtH,EAK/B,OAHA6G,GAAK+R,cAAgBlZ,KAAK2Y,MAAMC,SAASzR,EAAK+R,eAGvC/R,GAMX/B,QAAQwG,UAAUjE,iBAAmB,SAASrH,GAC1C,GAAI6G,GAAO,GAAIS,iBAAgBtH,EAE/B,IAAqC,IAAjC6G,EAAKgS,OAAOrY,QAAQ,SACtBqG,EAAKgS,OAAS,YACT,CAAA,GAAqC,IAAjChS,EAAKgS,OAAOrY,QAAQ,SAG7B,KAAM,IAAIN,OAAM,kBAAoB2G,EAAKgS,OAAS,eAFlDhS,GAAKgS,OAAS,QAOhB,MAFAhS,GAAK+R,cAAgBlZ,KAAK2Y,MAAME,SAAS1R,EAAK+R,eAEvC/R,GAWX/B,QAAQwG,UAAUwN,+BAAiC,SAAS5W,GACxD,IAAKxC,KAAK2Y,MAAMxW,OACZ,MAAO,KAGX,IAAI2U,GAAUmC,UAAUpD,MAAM7V,KAAK2Y,MAAMxW,OACzC,IAAI2U,GAAWA,EAAQC,OAASrJ,MAAM2L,QAAQvC,EAAQC,OAClD,IAAK,GAAIvM,GAAI,EAAGA,EAAIsM,EAAQC,MAAM7W,OAAQsK,IACtC,GAAIsM,EAAQC,MAAMvM,GAAGhI,MAAQA,KACvBsU,EAAQC,MAAMvM,GAAG8O,WACgB,aAA/BxC,EAAQC,MAAMvM,GAAG8O,WACc,aAA/BxC,EAAQC,MAAMvM,GAAG8O,WACrB,MAAO9O,EAKnB,OAAO,OAWXpF,QAAQwG,UAAUvC,QAAU,SAASkQ,GACjC,GAAI5W,GAAO3C,IAGX,IAAoB,gBAATuZ,IAA8B,OAATA,GACR,gBAAbA,GAAK3Y,IAEZ,MADA2K,SAAQnK,KAAK,mDACNmY,CAIX,IAAIzC,GAAUmC,UAAUpD,MAAM0D,EAAK3Y,IAGnC,QAA6B,KAAlBkW,EAAQC,QACdrJ,MAAM2L,QAAQvC,EAAQC,QAAmC,IAAzBD,EAAQC,MAAM7W,OAE/C,MADAqL,SAAQnK,KAAK,iCACNmY,CAKX,IAAIzC,EAAQC,MAAM7W,QAAU,GAAK4W,EAAQC,MAAMyC,MAAM,SAAS5L,GACtD,OAAsD,KAA9C,QAAS,QAAS,QAAQ9M,QAAQ8M,EAAE6L,OAGhD,MADAlO,SAAQnK,KAAK,qDACNmY,CAQX,KAAK,GAFD3Y,GAAM2Y,EAAK3Y,IACX8Y,GAAU,EACLlP,EAAI,EAAGA,EAAIsM,EAAQC,MAAM7W,OAAQsK,IAAK,CAC/BsM,EAAQC,MAAMvM,GACpB0M,IAAIxX,QAAQ,SAASwX,GACvB,GAAkB,SAAdA,EAAIyC,MACR,CACID,GAAU,CACV,IAAIlR,GAAQyQ,UAAUpD,MAAMlT,EAAKgW,MAAMnQ,MACvC0O,GAAIyC,MAAQnR,EAAMuO,MAAMvM,GAAG0M,IAAI,GAAGyC,SAI1CD,IACA9Y,EAAMqY,UAAUrD,MAAMkB,IAK1B9W,KAAK2Y,MAAMY,EAAK/W,MAAQ5B,CAKxB,IAAImW,GAAQD,EAAQC,KACpBD,GAAQC,QAKR,IAAI6C,MAIAC,IAEJ9C,GAAMrX,QAAQ,SAASqZ,GAEnB,IAA8B,gBAAlBA,GAAMe,SACI,aAAlBf,EAAMe,UACc,aAApBf,EAAMO,UACN,KAAM,IAAI9Y,OAAM,sFAWpB,QALmC,KAAxBoZ,EAAQb,EAAMvW,OACa,aAAlCoX,EAAQb,EAAMvW,MAAM8W,YACpBM,EAAQb,EAAMvW,MAAQuW,GAGtBA,EAAMrF,UAAYkG,EAAQb,EAAMvW,MAAMkR,SACxC,KAAM,IAAIlT,OAAM,oHAKlB,IAAIuY,EAAMV,UAAYuB,EAAQb,EAAMvW,MAAM6V,SACxC,KAAM,IAAI7X,OAAM,sHAQtBuW,EAAMrX,QAAQ,SAASqZ,GACnB,GAAmB,gBAAfA,EAAMvW,KAGN,MAFAsU,GAAQC,MAAMrW,KAAKqY,OACnBc,GAAMnZ,KAAKqY,EAAMU,IAKQ,iBAAlBV,GAAMgB,SACbxU,OAAOkQ,KAAKsD,EAAMgB,SAASra,QAAQ,SAASsa,GACG,gBAAhCJ,GAAQb,EAAMvW,MAAMuX,UAC3BH,EAAQb,EAAMvW,MAAMuX,YAGxBH,EAAQb,EAAMvW,MAAMuX,QAAQC,GACxBjB,EAAMgB,QAAQC,OAEQ,KAAfjB,EAAMkB,OAObL,EAAQb,EAAMvW,MAAMuX,QAAQC,GAAMC,KAC9BlB,EAAMkB,YAQU,KAArBlB,EAAMmB,YACTxM,MAAM2L,QAAQN,EAAMmB,kBAGsB,KAAnCN,EAAQb,EAAMvW,MAAM0X,YACtBxM,MAAM2L,QAAQO,EAAQb,EAAMvW,MAAM0X,cACvCN,EAAQb,EAAMvW,MAAM0X,eAGxBN,EAAQb,EAAMvW,MAAM0X,WAChBN,EAAQb,EAAMvW,MAAM0X,WAAWjL,OAC3B8J,EAAMmB,aAGdN,EAAQb,EAAMvW,QAAUuW,IAExBA,EAAMU,IAAMV,EAAMvW,WAGXuW,GAAMoB,iBAGNpB,GAAMkB,KAEhBlB,EAAMvW,MAAQuU,EAAM,GAAGvU,MACzBqX,EAAM/P,QAAQiP,EAAMvW,MAEpBsU,EAAQC,MAAMjN,QAAQiP,KAEtBc,EAAMnZ,KAAKqY,EAAMvW,MAEjBsU,EAAQC,MAAMrW,KAAKqY,WAKQ,KAAnBjC,EAAQsD,QAEjBtD,EAAQsD,OAAOC,KAAK,SAASC,GAChC,GAAmB,WAAfA,EAAM9X,KAEN,MADA8X,GAAMC,KAAOV,EAAMtY,KAAK,MACjB,IAMVuV,EAAQ0D,cACJC,SAAU,MACVC,MAAO,IAGX,IAAIC,GAAS1B,UAAUrD,MAAMkB,EAE7B,OAAO,IAAIvU,wBACPC,KAAM+W,EAAK/W,KACX5B,IAAK+Z,KA2BbvV,QAAQwG,UAAUjD,cAAgB,SAAS4Q,GACvC,GAAI5W,GAAO3C,IAGX,IAAoB,gBAATuZ,IAA8B,OAATA,GACR,gBAAbA,GAAK3Y,IAEZ,MADA2K,SAAQnK,KAAK,mDACNmY,CAGX,IAAIzC,GAAUmC,UAAUpD,MAAM0D,EAAK3Y,IAGnC,QAA6B,KAAlBkW,EAAQC,QACdrJ,MAAM2L,QAAQvC,EAAQC,QAAmC,IAAzBD,EAAQC,MAAM7W,OAE/C,MADAqL,SAAQnK,KAAK,iCACNmY,CAKX,IAAIzC,EAAQC,MAAM7W,OAAS,IAAM4W,EAAQC,MAAMyC,MAAM,SAAS5L,GACtD,OAAsD,KAA9C,QAAS,QAAS,QAAQ9M,QAAQ8M,EAAE6L,OAGhD,MADAlO,SAAQnK,KAAK,+CACNmY,CAIX,IAAIgB,KACJzD,GAAQC,MAAMrX,QAAQ,SAASkO,GAC3B2M,EAAK7Z,KAAKkN,EAAE6L,MAGhB,IAAImB,IAAY,CAShB,QAR8B,KAAnB9D,EAAQsD,QACf1M,MAAM2L,QAAQvC,EAAQsD,UACtBQ,EAAY9D,EAAQsD,OAAOZ,MAAM,SAASvL,GACtC,MAAkB,WAAXA,EAAEzL,MACLiW,YAAY1O,MAAMkE,EAAEsM,KAAKM,QAASN,EAAKM,aAI9CD,EAAW,CACZ,GAAIE,IAAe,CAQnB,IANAhE,EAAQC,MAAMrX,QAAQ,SAASkO,GACP,aAAhBA,EAAE0L,YACFwB,GAAe,KAInBA,EACA,KAAM,IAAIta,OAAM,mFA8BxB,GAAIgC,EACJ,IAAkB,WAAd+W,EAAK/W,KACLA,EAAO,YACJ,CAAA,GAAkB,UAAd+W,EAAK/W,KAGZ,KAAM,IAAIhC,OAAM,SAAW+Y,EAAK/W,KAAO,mBAFvCA,GAAO,SAKX,GAAIuY,OAC4B,KAArB/a,KAAK2Y,MAAMnW,KAClBuY,EAAS9B,UAAUpD,MAAM7V,KAAK2Y,MAAMnW,IAGxC,IAaIgV,GACAwD,EACAC,EACAC,EAhBAC,GACAnT,SACAC,UAKAmT,KACAC,EAAO,EACPC,EAAO,EAEPC,KAMAlD,KACAmD,KACAtE,IAwPJ,IAtPAJ,EAAQC,MAAMrX,QAAQ,SAAS+b,GAC3B,IAA8B,gBAAlBA,GAAM3B,SACI,aAAlB2B,EAAM3B,UACc,aAApB2B,EAAMnC,UACN,KAAM,IAAI9Y,OAAM,4FAIpB,IAAmB,gBAAfib,EAAMjZ,KAEN,YADA4Y,EAAOK,EAAMhC,KAAOgC,EAMxB,IAAI1B,GAAU0B,EAAM1B,QAChBG,EAAauB,EAAMvB,WACnBvC,EAAO8D,EAAM9D,IAWjB,QAR+B,KAApB8D,EAAMjE,aAETA,MADqB,KAAdA,EACMA,EAAWvI,OAAOwM,EAAMjE,YAExBiE,EAAMjE,gBAIH,KAAZwD,OAAsD,KAAlBS,EAAMT,UAA6BA,GAAYS,EAAMT,SACjG,KAAM,IAAIxa,OAAM,uFACsBwa,EAAW,qBACZS,EAAMT,SAQ/C,QAJ6B,KAAlBS,EAAMT,WACTA,EAAWS,EAAMT,cAGH,KAAVC,OAAkD,KAAhBQ,EAAMR,QAA2BA,GAAUQ,EAAMR,OAC3F,KAAM,IAAIza,OAAM,mFACoBya,EAAS,mBACVQ,EAAMR,OAQ7C,QAJ2B,KAAhBQ,EAAMR,SACTA,EAASQ,EAAMR,YAGI,KAAfC,OAA4D,KAArBO,EAAMP,cACpDA,EAAY1Y,MAAQiZ,EAAMP,YAAY1Y,MAAQ0Y,EAAYQ,MAAQD,EAAMP,YAAYQ,MACrF,KAAM,IAAIlb,OAAM,6FACyB6H,KAAKC,UAAU4S,GAAe,wBAC/B7S,KAAKC,UAAUmT,EAAMP,kBAIjC,KAArBO,EAAMP,cACTA,EAAcO,EAAMP,aAG5B7C,EAASoD,EAAMjZ,MAAQiZ,EAAMpD,SAC7BmD,EAAOC,EAAMjZ,MAAQiZ,EAAMD,OAC3BtE,EAAIuE,EAAMjZ,MAAQiZ,EAAMvE,GAGxB,IAAIyE,UACsB,KAAfzB,GAA8BxM,MAAM2L,QAAQa,IACnDA,EAAWxa,QAAQ,SAAUkc,OAGM,KAApBA,EAAUC,OACjBnO,MAAM2L,QAAQuC,EAAUC,QACxBD,EAAUC,MAAMnc,QAAQ,SAAUsa,OACE,KAArB2B,EAAW3B,KAClB2B,EAAW3B,OAGf2B,EAAW3B,GAAMtZ,KAAKkb,MAOtC,IAAIE,KAEJ,IAAuB,gBAAZ/B,SAIA0B,GAAM1B,cACN0B,GAAMvB,iBACNuB,GAAMjE,iBACNiE,GAAMT,eACNS,GAAMR,aACNQ,GAAMP,kBACNO,GAAM9D,WACN8D,GAAMhC,IAGblU,OAAOkQ,KAAKsE,GAASra,QAAQ,SAASsa,GAMlC,GAAIjB,EAOJ,IAAgB,UAAZQ,EAAK/W,OAQAuX,EAAQC,GAAMC,KAIf,YAHAkB,EAAcM,EAAMjZ,MAAMwX,GAAQD,EAAQC,QAOlB,KAArB2B,EAAW3B,IAClBtM,MAAM2L,QAAQsC,EAAW3B,KACzB2B,EAAW3B,GAAMK,KAAK,SAAUuB,GAG5B,MAAOA,GAAUC,MAAMxB,KAAK,SAAU0B,GAClC,GAAgC,gBAArBD,GAAQC,GAEf,MADAhD,GAAQ+C,EAAQC,IACT,MAMF,gBAAVhD,IAEPA,EAAMgB,QAAQC,GAAQD,EAAQC,SACvBD,GAAQC,GAAMC,OAGrBlB,EAAQxT,OAAO4M,OAAOsJ,GACtBK,EAAQ9B,GAAQjB,MAEkB,KAAvBgB,EAAQC,GAAMC,OAMrBlB,EAAMkB,KAAOF,EAAQC,GAAMC,WACpBF,GAAQC,GAAMC,MAIzBlB,EAAMgB,WACNhB,EAAMgB,QAAQC,GAAQD,EAAQC,GAC9BjB,EAAMmB,WAAayB,EAAW3B,OAIR,KAAXe,OACiB,KAAjBA,EAAOhE,OACdrJ,MAAM2L,QAAQ0B,EAAOhE,QAErBgE,EAAOhE,MAAMrX,QAAQ,SAAUkO,GACF,gBAAdA,GAAEmM,SACTxU,OAAOkQ,KAAK7H,EAAEmM,SAASra,QAAQ,SAAU6U,GACjCA,IAAMyF,IACNjB,EAAMU,IAAM7L,EAAE6L,aAOT,KAAdV,EAAMU,MAebV,EAAMU,KAAOgC,EAAMjZ,KAAM,IAAKwX,GAAMzY,KAAK,KAI7CwX,EAAMvB,WAAaA,EACnBuB,EAAMiC,SAAWA,EACjBjC,EAAMkC,OAASA,EACflC,EAAMmC,YAAcA,EACpBnC,EAAMpB,KAAOA,EAEbyD,EAAOrC,EAAMU,KAAOV,EACpBwC,EAAWD,GAAQvC,EAAMgB,QAEzBpX,EAAKgW,MAAME,SAASyC,GAAQD,MACa,KAA9B1Y,EAAKgW,MAAMC,SAASyC,KAC7B1Y,EAAKgW,MAAMC,SAASyC,GAAQC,GAE9BA,WAGL,CACL,GAAIvC,GAAQ0C,CAEZ1C,GAAMvB,WAAaA,EACnBuB,EAAMiC,SAAWA,EACjBjC,EAAMkC,OAASA,EACflC,EAAMmC,YAAcA,EACpBnC,EAAMpB,KAAOA,EAEbyD,EAAOrC,EAAMU,KAAOV,EAEpBpW,EAAKgW,MAAME,SAASyC,GAAQD,MACa,KAA9B1Y,EAAKgW,MAAMC,SAASyC,KAC7B1Y,EAAKgW,MAAMC,SAASyC,GAAQC,GAIhCD,MAKJvE,EAAQC,SACRwD,KAEkB,WAAdhB,EAAK/W,KAcL,IAAK,GAAIgI,GAAI,EAAGA,EAAIuQ,EAAOhE,MAAM7W,OAAQsK,IAAK,CAC1C,GAAIuO,GAAQgC,EAAOhE,MAAMvM,SAElBuO,GAAMkB,WACNlB,GAAMgB,cACNhB,GAAMmB,eAEgB,KAAlBqB,EAAW/Q,GACfuO,EAAMO,WACgB,aAApBP,EAAMO,UAEgB,aAApBP,EAAMO,YACXP,EAAMO,UAAY,YAFlBP,EAAMO,UAAY,WAIjBP,EAAMO,WACgB,aAApBP,EAAMO,UAEgB,aAApBP,EAAMO,YACXP,EAAMO,UAAY,YAFlBP,EAAMO,UAAY,WAKxBP,EAAMgB,QAAUwB,EAAW/Q,GAC3BuO,EAAMvB,WAAaA,EACnBuB,EAAMiC,SAAWA,EACjBjC,EAAMkC,OAASA,EACflC,EAAMmC,YAAcA,EAEpBnC,EAAM7B,IAAMA,EAAI6B,EAAMvW,MACtBuW,EAAMV,SAAWA,EAASU,EAAMvW,MAChCuW,EAAMyC,OAASA,EAAOzC,EAAMvW,MAE5BsU,EAAQC,MAAMrW,KAAKqY,GAEM,gBAAdA,GAAMU,KAEbc,EAAK7Z,KAAKqY,EAAMU,cAaF,KAAXsB,OACiB,KAAjBA,EAAOhE,OACdrJ,MAAM2L,QAAQ0B,EAAOhE,QACrBgE,EAAOhE,MAAMrX,QAAQ,SAASqZ,GAC1BwB,EAAK7Z,KAAKqY,EAAMU,SACiB,KAAtB2B,EAAOrC,EAAMU,KACpB3C,EAAQC,MAAMrW,KAAK0a,EAAOrC,EAAMU,aAEzBV,GAAMkB,WACNlB,GAAMgB,cACNhB,GAAMmB,WAERnB,EAAMO,WACgB,aAApBP,EAAMO,YACTP,EAAMO,UAAY,YAEjBP,EAAMO,WACgB,aAApBP,EAAMO,YACTP,EAAMO,UAAY,YAGtBR,aAAcC,GACdjC,EAAQC,MAAMrW,KAAKqY,MAM/BxT,OAAOkQ,KAAK2F,GAAQ1b,QAAQ,SAAS+Z,GACjC,IAA2B,IAAvBc,EAAKzZ,QAAQ2Y,GAEb,GADAc,EAAK7Z,KAAK+Y,GACoB,aAA1B2B,EAAO3B,GAAKH,UAA0B,CAMtC,GAAI0C,IAAO,CAEXlF,GAAQC,MAAMsD,KAAK,SAAUtB,GACzB,IAAyB,aAApBA,EAAMO,WACa,aAApBP,EAAMO,YACNP,EAAMvW,OAAS4Y,EAAO3B,GAAKjX,KAS3B,MAPA+C,QAAOkQ,KAAK2F,EAAO3B,GAAKM,SAASra,QAC7B,SAAUsa,GACVjB,EAAMgB,QAAQC,GACVoB,EAAO3B,GAAKM,QAAQC,KAG5BgC,GAAO,GACA,IAIVA,GACDlF,EAAQC,MAAMrW,KAAK0a,EAAO3B,QAG9B3C,GAAQC,MAAMrW,KAAK0a,EAAO3B,OAWzC,QAAS,SAAS/Z,QAAQ,SAAU8C,GACjC,GAAKsU,GAAYA,EAAQC,OAAUrJ,MAAM2L,QAAQvC,EAAQC,OAAzD,CAGA,GAAIjI,GAAM,IACV,IAAIvJ,OAAOkQ,KAAK0F,EAAc3Y,IAAOtC,OAAS,GAE9B,QADZ4O,EAAMnM,EAAKyW,+BAA+B5W,IAMtC,IAAK,GAAIgI,GAAI,EAAGA,EAAIsM,EAAQC,MAAM7W,OAAQsK,IACtC,GAAIsM,EAAQC,MAAMvM,GAAGhI,OAASA,EAAM,CAChCsM,EAAMtE,CACN,OAMhB,GAAIsE,GAAOgI,EAAQC,MAAM7W,OAAS4O,EAAK,CACnC,GAAIsJ,GAAQtB,EAAQC,MAAMjI,EAC1BvJ,QAAOkQ,KAAK0F,EAAc3Y,IAAO9C,QAAQ,SAASsa,GAC1C5B,EAAM2B,SAAW3B,EAAM2B,QAAQC,IAC/BzO,QAAQnK,KAAK,+BAEZgX,EAAM2B,UACP3B,EAAM2B,YAGV3B,EAAM2B,QAAQC,GAAQmB,EAAc3Y,GAAMwX,aAKxB,KAAnBlD,EAAQsD,QAEjBtD,EAAQsD,OAAOC,KAAK,SAASC,GAChC,GAAmB,WAAfA,EAAM9X,KAEN,MADA8X,GAAMC,KAAOA,EAAKhZ,KAAK,MAChB,IAMVuV,EAAQ0D,cACJC,SAAU,MACVC,MAAO,IAGX,IAAIC,GAAS1B,UAAUrD,MAAMkB,EAM7B,OAFA9W,MAAK2Y,MAAMY,EAAK/W,MAAQmY,EAEjB,GAAIpY,wBACPC,KAAM+W,EAAK/W,KACX5B,IAAK+Z;;AC/1Bb,GAAI1B,WAAY9N,QAAQ,gBAExBmB,SAAQsJ,MAAQ,SAASkB,EAASnI,GAgDhC,WA9CuB,KAAZmI,OACkB,KAAlBA,EAAQC,OACfrJ,MAAM2L,QAAQvC,EAAQC,QAExBD,EAAQC,MAAMrX,QAAQ,SAAU0Y,OAED,KAAlBA,EAAM2B,SACuB,IAAtCxU,OAAOkQ,KAAK2C,EAAM2B,SAAS7Z,SACzBkY,EAAMyD,SACNtW,OAAOkQ,KAAK2C,EAAM2B,SAASra,QAAQ,SAAUsa,GAC3C,GAAIiC,GAAS7D,EAAM2B,QAAQC,EAC3BzU,QAAOkQ,KAAKwG,GAAQvc,QAAQ,SAAUwc,GACpC9D,EAAMyD,MAAMnb,MACVY,GAAI0Y,EACJkC,UAAWA,EACXxW,MAAOuW,EAAOC,eAIb9D,GAAM2B,aAIe,KAArB3B,EAAM8B,YACfxM,MAAM2L,QAAQjB,EAAM8B,aAClB9B,EAAM8B,WAAWxa,QAAQ,SAAUkc,OACF,KAApBA,EAAUC,OACjBnO,MAAM2L,QAAQuC,EAAUC,SAC1BD,EAAUC,MAAQD,EAAUC,MAAMta,KAAK,cAQ5B,KAAZuV,OACmB,KAAnBA,EAAQsD,QAA0B1M,MAAM2L,QAAQvC,EAAQsD,SAEjEtD,EAAQsD,OAAO1a,QAAQ,SAAUuO,OACT,KAAXA,EAAEsM,MAAwB7M,MAAM2L,QAAQpL,EAAEsM,QACnDtM,EAAEsM,KAAOtM,EAAEsM,KAAKhZ,KAAK,QAKpB0X,UAAUrD,MAAMkB,EAASnI,IAGlCrC,QAAQuJ,MAAQ,SAASjV,GACvB,GAAIkW,GAAUmC,UAAUpD,MAAMjV,EAwC9B,YAtCuB,KAAZkW,OAAoD,KAAlBA,EAAQC,OACjDrJ,MAAM2L,QAAQvC,EAAQC,QAExBD,EAAQC,MAAMrX,QAAQ,SAAU0Y,OAEH,KAAhBA,EAAMyD,OAAyBnO,MAAM2L,QAAQjB,EAAMyD,SAC5DzD,EAAM2B,WACN3B,EAAMyD,MAAMnc,QAAQ,SAAUsa,GACvB5B,EAAM2B,QAAQC,EAAK1Y,MACxB8W,EAAM2B,QAAQC,EAAK1Y,QACrB8W,EAAM2B,QAAQC,EAAK1Y,IAAI0Y,EAAKkC,WAAalC,EAAKtU,cAGvC0S,GAAMyD,WAIiB,KAArBzD,EAAM8B,YACfxM,MAAM2L,QAAQjB,EAAM8B,aAClB9B,EAAM8B,WAAWxa,QAAQ,SAAUkc,GACF,gBAApBA,GAAUC,QACnBD,EAAUC,MAAQD,EAAUC,MAAMhI,MAAM,cAO7B,KAAZiD,OACmB,KAAnBA,EAAQsD,QAA0B1M,MAAM2L,QAAQvC,EAAQsD,SAEjEtD,EAAQsD,OAAO1a,QAAQ,SAAUuO,GACT,gBAAXA,GAAEsM,OACXtM,EAAEsM,KAAOtM,EAAEsM,KAAK1G,MAAM,QAKrBiD;;CCpGT,SAAW7M,EAAQ7G,GAEf,YAOA,IAQI+Y,GAAc,QACdC,EAAc,OACdC,EAAc,OACdC,EAAc,SACdC,EAAc,UAGdC,EAAc,SACdC,EAAc,SAWdC,GACA9J,OAAS,SAAU+J,EAASC,GACxB,GAAIC,KACJ,KAAK,GAAIrS,KAAKmS,GACNC,EAAWpS,IAAMoS,EAAWpS,GAAGtK,OAAS,GAAM,EAC9C2c,EAAcrS,GAAKoS,EAAWpS,GAAGyE,OAAO0N,EAAQnS,IAEhDqS,EAAcrS,GAAKmS,EAAQnS,EAGnC,OAAOqS,IAEXC,IAAM,SAAUC,EAAMC,GACpB,MAAoB,gBAATD,KACkD,IAApDC,EAAKzJ,cAAczS,QAAQic,EAAKxJ,gBAK3C0J,SAAW,SAAU5H,GACjB,MAAOA,GAAI9B,eAEftQ,MAAQ,SAAUkV,GACd,MA5CU,gBA4CG,GAAyBA,EAAQL,QAAQ,WAAW,IAAIjE,MAAM,KAAK,OA3D5F,IA6DQD,KAAO,SAAUyB,GACf,MAAOA,GAAIyC,QAAQ,qCAAsC,MAU3DoF,GAEAC,IAAM,SAAU1R,EAAI2R,GAYhB,IATA,GAAW1S,GAAG2S,EAAG3I,EAAG4I,EAAGC,EAASnH,EAA5B5L,EAAI,EASDA,EAAI4S,EAAOld,SAAWqd,GAAS,CAElC,GAAIC,GAAQJ,EAAO5S,GACfiT,EAAQL,EAAO5S,EAAI,EAIvB,KAHAE,EAAI2S,EAAI,EAGD3S,EAAI8S,EAAMtd,SAAWqd,GAIxB,GAFAA,EAAUC,EAAM9S,KAAKgT,KAAKjS,GAGtB,IAAKiJ,EAAI,EAAGA,EAAI+I,EAAMvd,OAAQwU,IAC1B0B,EAAQmH,IAAUF,GAClBC,EAAIG,EAAM/I,GAtFhB,gBAwFiB4I,IAAkBA,EAAEpd,OAAS,EACpB,GAAZod,EAAEpd,OA3FhB,kBA4FyBod,GAAE,GAETtd,KAAKsd,EAAE,IAAMA,EAAE,GAAG1Z,KAAK5D,KAAMoW,GAG7BpW,KAAKsd,EAAE,IAAMA,EAAE,GAEA,GAAZA,EAAEpd,OAnGvB,kBAqGyBod,GAAE,IAAsBA,EAAE,GAAGI,MAAQJ,EAAE,GAAGzG,KAKjD7W,KAAKsd,EAAE,IAAMlH,EAAQA,EAAM0B,QAAQwF,EAAE,GAAIA,EAAE,QAtHnF,GAmHwCtd,KAAKsd,EAAE,IAAMlH,EAAQkH,EAAE,GAAG1Z,KAAK5D,KAAMoW,EAAOkH,EAAE,QAnHtF,GAwHuD,GAAZA,EAAEpd,SACLF,KAAKsd,EAAE,IAAMlH,EAAQkH,EAAE,GAAG1Z,KAAK5D,KAAMoW,EAAM0B,QAAQwF,EAAE,GAAIA,EAAE,SAzHnG,IA4HgCtd,KAAKsd,GAAKlH,OA5H1C,EAiIgB5L,IAAK,IAMb6K,IAAM,SAAUA,EAAKhG,GAEjB,IAAK,GAAI7E,KAAK6E,GAEV,GA7HM,gBA6HKA,GAAI7E,IAAmB6E,EAAI7E,GAAGtK,OAAS,GAC9C,IAAK,GAAIwK,GAAI,EAAGA,EAAI2E,EAAI7E,GAAGtK,OAAQwK,IAC/B,GAAIgS,EAAKI,IAAIzN,EAAI7E,GAAGE,GAAI2K,GACpB,MAnIN,MAmIc7K,MA9IpC,GA8IiEA,MAG1C,IAAIkS,EAAKI,IAAIzN,EAAI7E,GAAI6K,GACxB,MAvIE,MAuIM7K,MAlJ5B,GAkJyDA,CAG7C,OAAO6K,KAUXsI,GAEAtb,SACIub,WACIzF,SACI0F,MAAU,KACVC,IAAU,KACVC,IAAU,KACVC,MAAU,OACVC,QAAU,OACVC,QAAU,OACVC,QAAU,OACVC,IAAU,OAKtBC,QACIC,QACIC,OACIC,cAAgB,KAAM,QAG9BC,QACIF,OACIG,eAAiB,UAErBC,QACIC,IAAc,MACdC,OAAc,YAK1BC,IACIC,SACI5G,SACI6G,GAAc,OACdC,UAAc,SACdC,SAAc,QACdC,KAAc,SACdC,IAAe,SAAU,UACzBC,MAAc,SACdC,EAAc,SACdC,EAAc,SACdC,IAAc,SACdC,IAAe,SAAU,WACzBC,GAAc,UAY1B/C,GAEAta,UAGI,6BACA,8CACA,+BACA,6BACI+Z,EAAMG,IAEV,8BACKH,EAAM,cAAeG,IAE1B,yBACKH,EAAM,SAAUG,IAGrB,uBACA,gEAIA,6DAEA,4BAGA,wBACA,8HAEIH,EAAMG,IAEV,+CACKH,EAAM,MAAOG,IAElB,6BACIH,EAAMG,IAEV,6BACKH,EAAM,UAAWG,IAEtB,0BACKH,EAAM,UAAWG,IAEtB,+DAEKH,EAAM,aAAcG,IAEzB,iCACKH,EAAM,KAAM,KAAMG,IAEvB,kCACKH,EAAM,UAAWG,IAEtB,qBACIH,EAAMG,IAEV,mCACIH,EAAMG,IAEV,oCACIA,GAAUH,EAAM,kBAEpB,uBACIG,GAAUH,EAAM,cAEpB,sCACIG,GAAUH,EAAM,qBAEpB,kCACKA,EAAM,OAAQ,cAAeG,IAElC,6CACKH,EAAM,mBAAoB,SAAUG,IAEzC,+DACIA,GAAUH,EAAM,qBAEpB,iEAEIA,EAAMG,IAEV,0BACKH,EAAM,WAAYG,IAEvB,2CACKH,EAAM,UAAWG,IAEtB,yBACKH,EAAM,eAAgBG,IAE3B,uBACIA,GAAUH,EAAM,aAEpB,gDACIG,GAAUH,EAAM,mBAEpB,mDACIG,EAASH,IAEb,sEACKA,EAAM,OAAQG,IAEnB,kDACIH,GAAOG,EAASW,EAAO7H,IAAKsI,EAAKtb,QAAQub,UAAUzF,WAEvD,0BACA,+BACIiE,EAAMG,IAGV,uCACKH,EAAM,YAAaG,IACxB,cACA,gGAEA,2EAEA,0CAGA,8EAEA,wBACA,4BACA,iCACA,6BACIH,EAAMG,IAkHdoD,MAEI,mDAxbU,eAybS,WAEnB,kBA3bU,eA4bSjD,EAAKO,YAExB,4BA9bU,eA+bS,UAGnB,kCAlcU,eAmcS,SAEnB,6CArcU,eAscS,OAAQ,GAAIP,EAAKO,YAEpC,oBAxcU,eAycS,WAEnB,iHA3cU,eA6cSP,EAAKO,YAG5BoB,SAEI,8CACIlC,EAAOG,GAASD,EAAMI,KAE1B,qCACIN,GAAQG,EAAQ,UAAWD,EAAMI,KAErC,uBACKN,EAAO,aAAcG,EAAQ,WAElC,yBACA,oBACA,kBACA,uBACA,+BACA,qCACIA,EAAQH,GAAQE,EAAMI,KAE1B,wCACIN,GAAQG,EAAQ,WAAYD,EAAMI,KACtC,sDACKN,EAAOe,EAAO7H,IAAKsI,EAAKU,OAAOC,OAAOC,QAASjC,EAAQ,WAAYD,EAAMG,KAE9E,oCACIL,EAAOG,GAASD,EAAMG,KAC1B,2BACIL,GAAQG,EAAQ,UAAWD,EAAMG,KAErC,2BACA,oGAEA,qBACA,mBACIF,EAAQH,GAAQE,EAAMG,KAC1B,oBACIL,GAAQG,EAAQ,eAAgBD,EAAMG,KAE1C,8EACIL,GAAQG,EAAQ,SAAUD,EAAMI,KAEpC,mCACA,gCACKH,EAAQ,SAAUH,EAAO,kBAAmBE,EAAMI,KACvD,gDACIN,GAAQG,EAAQ,SAAUD,EAAMG,KAEpC,cACA,6BACIF,EAAQH,GAAQE,EAhgBV,aAkgBV,iCACIF,GAAQG,EAAQ,WAAYD,EAngBtB,aAqgBV,oCACIF,GAAQG,EAAQ,SAAUD,EAtgBpB,aAwgBV,sBACKC,EAAQY,EAAO7H,IAAKsI,EAAKU,OAAOI,OAAOE,SAAUxC,EAAOe,EAAO7H,IAAKsI,EAAKU,OAAOI,OAAOF,QAASlC,EAAMG,KAE3G,8CACIF,EAAQH,GAAQE,EAAMI,KAE1B,qCACA,gBACA,8EAEIH,GAASH,EAAO,KAAM,MAAOE,EAAMG,KAEvC,gBACIL,GAAQG,EAAQ,QAASD,EAAMI,KAEnC,4BACA,iBACIN,GAAQG,EAAQ,WAAYD,EAAMG,KAEtC,kCACIF,EAAQH,GAAQE,EAAMG,KAE1B,oCACIL,GAAQG,EAAQ,cAAeD,EA/hBzB,aAgiBV,wBACKF,EAAO,MAAO,MAAOG,EAAQ,cAAeD,EAAMG,KAGvD,kFACA,mBACA,uBACA,gBACIL,GAAQG,EAAQ,aAAcD,EAAMG,KACxC,iDACIL,GAAQG,EAAQ,aAAcD,EAAMI,KAExC,4DACKH,EAAQI,EAAK9I,OAAQuI,EAAOO,EAAK9I,OAAQyI,EA1iBpC,aA4iBV,yBACKF,EAAO,IAAK,YAAaG,EAAQ,YAAaD,EA7iBzC,aA+iBV,yBACIF,GAAQG,EAAQ,UAAWD,EAhjBrB,aAkjBV,8EACA,kBACKC,EAAQ,WAAYH,GAAQE,EAAMI,KACvC,yBACIH,GAASD,EAtjBH,WAsjBmBF,IAC7B,qDACA,oCACA,qBACKG,EAAQ,WAAYH,GAAQE,EAAMG,KAEvC,gBACIL,GAAQG,EAAQ,YAAaD,EAAMG,KAEvC,oCACA,8BACKF,EAAQ,SAAUH,GAAQE,EAAMG,KAErC,sCACIL,GAAQG,EAAQ,SAAUD,EAAMI,KAEpC,sCACIN,GAAQG,EAAQ,OAAQD,EAAMI,KAClC,mDACKH,EAAQ,MAAOH,GAAQE,EAAMI,KAClC,sBACIH,EAAQH,GAAQE,EA3kBV,aA4kBV,iBACA,sBACA,qCACIF,GAAQG,EAAQ,OAAQD,EAAMG,KAElC,qCACIL,GAAQG,EAAQ,WAAYD,EAAMI,KAEtC,wBACIH,EAAQH,GAAQE,EAAMG,KAE1B,8BACIF,EAAQH,GAAQE,EAvlBV,cAylBV,2CACIC,EAAQH,GAAQE,EAAMG,KAE1B,YACKL,EAAO,eAAgBG,EAAQ,YAEpC,6BACIH,GAAQG,EAAQ,WAAYD,EAhmBtB,cAkmBV,6BACIF,GAAQG,EAAQ,WAAYD,EAAMI,KAEtC,oCACIN,GAAQG,EAAQ,WAAYD,EAAMG,KAEtC,gCACA,qDACA,8EACA,kEACKL,EAAO,KAAM,MAAOG,EAAQ,WAAYD,EAAMG,KACnD,8DACIL,EAAO,KAAM,MAAOG,EAAQ,WAAYD,EAAMI,KAClD,uCACIN,GAAQG,EAAQ,UAAWD,EAAMI,KAErC,8BACIN,GAAQG,EAAQ,YAAaD,EAAMG,KAEvC,2CACIL,GAAQG,EAAQ,QAASD,EAAMI,KAEnC,6CACIN,GAAQG,EAAQ,SAAUD,EAAMI,KAEpC,8CACIN,GAAQG,EAAQ,YAAaD,EAAMI,KAEvC,mEACKH,EAAQ,kBAAmBH,GAAQE,EAAMI,KAE9C,4CACIN,GAAQG,EAAQ,aAAcD,EAAMI,KAExC,gDACKH,EAAQ,OAAQH,GAAQE,EAAMI,KAEnC,8CACIN,GAAQG,EAAQ,UAAWD,EAAMG,KAErC,yCACIL,GAAQG,EAAQ,UAAWD,EAAMI,KAErC,8CACIN,GAAQG,EAAQ,SAAUD,EAAMI,KAEpC,8CACA,8DACKH,EAAQ,gBAAiBH,GAAQE,EAAMI,KAE5C,uCACIN,GAAQG,EAAQ,aAAcD,EAAMI,KAExC,8CACIN,GAAQG,EAAQ,aAAcD,EAAMI,KAExC,gFACKH,EAAQ,SAAUH,GAAQE,EAAMG,KAErC,mDACKF,EAAQ,SAAUH,GAAQE,EAAMG,KAErC,6DACIL,GAAQG,EAAQ,YAAaD,EAAMI,KAEvC,0DACIH,EAAQH,GAAQE,EAAMI,KAE1B,8CACIN,GAAQG,EAAQ,cAAeD,EAAMI,KAEzC,uDACIH,EAAQH,GAAQE,EAAMI,KAE1B,wCACIN,GAAQG,EAAQ,UAAWD,EAAMI,KAErC,+BACIN,GAAQG,EAAQ,WAAYD,EAAMI,KAEtC,4CACIH,EAAQH,GAAQE,EAAMI,KAE1B,uBACA,mCACKJ,EAAMK,EAAKO,UAAWX,EAAQH,IAEnC,6BACIA,GAAQG,EAAQ,aAuDxBsD,SAEI,gCACIrD,GAAUH,EAAM,cAEpB,uBACA,+DACA,0CACA,iCACIA,EAAMG,IAEV,4BACIA,EAASH,IAGjB0C,KAGI,sCACI1C,EAAMG,IACV,+BACA,kDACA,uDACIH,GAAOG,EAASW,EAAO7H,IAAKsI,EAAKmB,GAAGC,QAAQ5G,WAChD,0CACKiE,EAAM,YAAaG,EAASW,EAAO7H,IAAKsI,EAAKmB,GAAGC,QAAQ5G,WAG7D,kBACKiE,EAAM,cAAeG,IAC1B,gCACA,0BACA,qFAEA,yBACIH,EAAMG,IACV,uDACKH,EAAM,WAAYG,IACvB,mBACIH,IACJ,yCACKA,EAAM,cAAeG,IAG1B,iDAGA,yBACA,6BACA,0JAGA,6BACA,wBACIH,EAAMG,IAEV,iCACKH,EAAM,eAAgBG,IAG3B,6BACKH,EAAM,WAAYG,IAGvB,oDACIH,EAAMG,IAEV,oBACIH,EAAMG,IAEV,uBACA,uDACKA,EAAS,KAAM,MAAOH,EAAM,SAEjC,iCACA,oCACKA,EAAM,WAAYG,EAAS,KAAM,OAGtC,wCACA,qCACA,+DAEA,yBACIH,EAAMG,KAwBdlR,EAAW,SAAUwU,EAAUjD,GAO/B,GALwB,gBAAbiD,KACPjD,EAAaiD,EACbA,MA53BZ,MA+3Bc7f,eAAgBqL,IAClB,MAAO,IAAIA,GAASwU,EAAUjD,GAAYkD,WAG9C,IAAIrU,GAAKoU,IAAc5V,GAAUA,EAAO3G,WAAa2G,EAAO3G,UAAUoI,UAAazB,EAAO3G,UAAUoI,UAz3BtF,IA03BVqU,EAASnD,EAAaF,EAAK9J,OAAO+J,EAASC,GAAcD,CAuD7D,OAhDA3c,MAAKgD,WAAa,WACd,GAAIX,IAAYC,SA54B5B,GA44B6C6V,YA54B7C,GA+4BY,OAFA+E,GAAOC,IAAIvZ,KAAKvB,EAASoJ,EAAIsU,EAAO1d,SACpCA,EAAQY,MAAQyZ,EAAKzZ,MAAMZ,EAAQ8V,SAC5B9V,GAEXrC,KAAKggB,OAAS,WACV,GAAIL,IAAQM,iBAl5BxB,GAo5BY,OADA/C,GAAOC,IAAIvZ,KAAK+b,EAAKlU,EAAIsU,EAAOJ,KACzBA,GAEX3f,KAAKkgB,UAAY,WACb,GAAI7B,IAAWM,WAv5B3B,GAu5B8CJ,UAv5B9C,GAu5BgE/b,SAv5BhE,GAy5BY,OADA0a,GAAOC,IAAIvZ,KAAKya,EAAQ5S,EAAIsU,EAAO1B,QAC5BA,GAEXre,KAAKmgB,UAAY,WACb,GAAIP,IAAWtd,SA55B3B,GA45B4C6V,YA55B5C,GA85BY,OADA+E,GAAOC,IAAIvZ,KAAKgc,EAAQnU,EAAIsU,EAAOH,QAC5BA,GAEX5f,KAAKogB,MAAQ,WACT,GAAItB,IAAOxc,SAj6BvB,GAi6BwC6V,YAj6BxC,GAm6BY,OADA+E,GAAOC,IAAIvZ,KAAKkb,EAAIrT,EAAIsU,EAAOjB,IACxBA,GAEX9e,KAAK8f,UAAY,WACb,OACIrU,GAAUzL,KAAKqgB,QACfhe,QAAUrC,KAAKgD,aACf4c,OAAU5f,KAAKmgB,YACfrB,GAAU9e,KAAKogB,QACf/B,OAAUre,KAAKkgB,YACfP,IAAU3f,KAAKggB,WAGvBhgB,KAAKqgB,MAAQ,WACT,MAAO5U,IAEXzL,KAAKsgB,MAAQ,SAAUT,GAOnB,MANApU,GAAKoU,EAME7f,MAEJA,KAGXqL,GAASkR,QAr7BS,SAs7BlBlR,EAASkV,SACLnE,KAAUA,EACVoE,MAj7Bc,QAk7BdjE,QAAUA,GAEdlR,EAASoV,KACLC,aA/6Bc,gBAi7BlBrV,EAASsV,QACLxE,MAAUA,EACVG,OAAUA,EACVD,KAAUA,EACVuE,QAp7Bc,UAq7BdpE,OAAUA,EACVqE,QAn7Bc,UAo7BdpE,OAAUA,EACVqE,SAp7Bc,WAq7BdC,SAp7Bc,YAs7BlB1V,EAAS2V,QACL5E,KAAUA,EACVG,QAAUA,GAEdlR,EAAS4V,IACL7E,KAAUA,EACVG,QAAUA,GA38BI,mBAq9BR,UAr9BQ,mBAu9BHhQ,SAAyBA,OAAOD,UACvCA,QAAUC,OAAOD,QAAUjB,GA+B/BiB,QAAQjB,SAAWA,GAx/BL,kBA2/BJ,SAA0B6V,OAAOC,IACvCD,OAAO,WACH,MAAO7V,KAEJpB,IAEPA,EAAOoB,SAAWA,EAS1B,IAAI+V,GAAInX,IAAWA,EAAOoX,QAAUpX,EAAOqX,MAC3C,QA1gCkB,KA0gCPF,EAAkB,CACzB,GAAIre,GAAS,GAAIsI,EACjB+V,GAAE3V,GAAK1I,EAAO+c,YACdsB,EAAE3V,GAAGhG,IAAM,WACP,MAAO1C,GAAOsd,SAElBe,EAAE3V,GAAGb,IAAM,SAAUiV,GACjB9c,EAAOud,MAAMT,EACb,IAAI5M,GAASlQ,EAAO+c,WACpB,KAAK,GAAIyB,KAAQtO,GACbmO,EAAE3V,GAAG8V,GAAQtO,EAAOsO,MAKf,gBAAXtX,QAAsBA,OAASjK;;;AC9iCzC,GAAIwhB,KAEAC,OAASC,OAAOD,QAAUC,OAAOC,QACrC,IAAIF,QAAUA,OAAOG,gBAAiB,CAGpC,GAAIC,QAAS,GAAIC,YAAW,GAC5BN,KAAM,WAEJ,MADAC,QAAOG,gBAAgBC,QAChBA,QAIX,IAAKL,IAAK,CAKR,GAAKO,OAAQ,GAAIrU,OAAM,GACvB8T,KAAM,WACJ,IAAK,GAAW5M,GAAPpK,EAAI,EAAMA,EAAI,GAAIA,IACN,IAAV,EAAJA,KAAiBoK,EAAoB,WAAhBzF,KAAKC,UAC/B2S,MAAMvX,GAAKoK,MAAY,EAAJpK,IAAa,GAAK,GAGvC,OAAOuX,QAIXxV,OAAOD,QAAUkV;;;;ACXjB,QAAS3L,OAAMtB,EAAGyN,EAAKC,GACrB,GAAIzX,GAAKwX,GAAOC,GAAW,EAAG9R,EAAK,CAUnC,KARA6R,EAAMA,MACNzN,EAAEhB,cAAcuE,QAAQ,eAAgB,SAASoK,GAC3C/R,EAAK,KACP6R,EAAIxX,EAAI2F,KAAQgS,WAAWD,MAKxB/R,EAAK,IACV6R,EAAIxX,EAAI2F,KAAQ,CAGlB,OAAO6R,GAIT,QAASI,SAAQJ,EAAKC,GACpB,GAAIzX,GAAIyX,GAAU,EAAGI,EAAMC,UAC3B,OAAQD,GAAIL,EAAIxX,MAAQ6X,EAAIL,EAAIxX,MACxB6X,EAAIL,EAAIxX,MAAQ6X,EAAIL,EAAIxX,MAAQ,IAChC6X,EAAIL,EAAIxX,MAAQ6X,EAAIL,EAAIxX,MAAQ,IAChC6X,EAAIL,EAAIxX,MAAQ6X,EAAIL,EAAIxX,MAAQ,IAChC6X,EAAIL,EAAIxX,MAAQ6X,EAAIL,EAAIxX,MAAQ,IAChC6X,EAAIL,EAAIxX,MAAQ6X,EAAIL,EAAIxX,MACxB6X,EAAIL,EAAIxX,MAAQ6X,EAAIL,EAAIxX,MACxB6X,EAAIL,EAAIxX,MAAQ6X,EAAIL,EAAIxX,MAwBlC,QAAS+X,IAAG7gB,EAASsgB,EAAKC,GACxB,GAAIzX,GAAIwX,GAAOC,GAAU,EACrBnN,EAAIkN,KAERtgB,GAAUA,KAEV,IAAI8gB,OAAgCpf,KAArB1B,EAAQ8gB,SAAyB9gB,EAAQ8gB,SAAWC,UAM/DC,MAA0Btf,KAAlB1B,EAAQghB,MAAsBhhB,EAAQghB,OAAQ,GAAIC,OAAOC,UAIjEC,MAA0Bzf,KAAlB1B,EAAQmhB,MAAsBnhB,EAAQmhB,MAAQC,WAAa,EAGnEC,EAAML,EAAQM,YAAeH,EAAQC,YAAY,GAcrD,IAXIC,EAAK,OAA0B3f,KAArB1B,EAAQ8gB,WACpBA,EAAWA,EAAW,EAAI,QAKvBO,EAAK,GAAKL,EAAQM,iBAAiC5f,KAAlB1B,EAAQmhB,QAC5CA,EAAQ,GAINA,GAAS,IACX,KAAM,IAAIriB,OAAM,kDAGlBwiB,YAAaN,EACbI,WAAaD,EACbJ,UAAYD,EAGZE,GAAS,WAGT,IAAIO,IAA4B,KAAb,UAARP,GAA6BG,GAAS,UACjD/N,GAAEtK,KAAOyY,IAAO,GAAK,IACrBnO,EAAEtK,KAAOyY,IAAO,GAAK,IACrBnO,EAAEtK,KAAOyY,IAAO,EAAI,IACpBnO,EAAEtK,KAAY,IAALyY,CAGT,IAAIC,GAAOR,EAAQ,WAAc,IAAS,SAC1C5N,GAAEtK,KAAO0Y,IAAQ,EAAI,IACrBpO,EAAEtK,KAAa,IAAN0Y,EAGTpO,EAAEtK,KAAO0Y,IAAQ,GAAK,GAAM,GAC5BpO,EAAEtK,KAAO0Y,IAAQ,GAAK,IAGtBpO,EAAEtK,KAAOgY,IAAa,EAAI,IAG1B1N,EAAEtK,KAAkB,IAAXgY,CAIT,KAAK,GADDW,GAAOzhB,EAAQyhB,MAAQC,QAClBviB,EAAI,EAAGA,EAAI,EAAGA,IACrBiU,EAAEtK,EAAI3J,GAAKsiB,EAAKtiB,EAGlB,OAAOmhB,IAAYI,QAAQtN,GAM7B,QAASrQ,IAAG/C,EAASsgB,EAAKC,GAExB,GAAIzX,GAAIwX,GAAOC,GAAU,CAEF,iBAAb,KACRD,EAAiB,UAAXtgB,EAAsB,GAAIgM,OAAM,IAAM,KAC5ChM,EAAU,MAEZA,EAAUA,KAEV,IAAI2hB,GAAO3hB,EAAQ0N,SAAW1N,EAAQ8f,KAAO8B,OAO7C,IAJAD,EAAK,GAAgB,GAAVA,EAAK,GAAa,GAC7BA,EAAK,GAAgB,GAAVA,EAAK,GAAa,IAGzBrB,EACF,IAAK,GAAI7R,GAAK,EAAGA,EAAK,GAAIA,IACxB6R,EAAIxX,EAAI2F,GAAMkT,EAAKlT,EAIvB,OAAO6R,IAAOI,QAAQiB,GA/JxB,IAAK,GALDC,MAAOnY,QAAQ,SAGfmX,cACAH,cACK3X,EAAI,EAAGA,EAAI,IAAKA,IACvB8X,WAAW9X,IAAMA,EAAI,KAAO8I,SAAS,IAAIiQ,OAAO,GAChDpB,WAAWG,WAAW9X,IAAMA,CAyC9B,IAAIgZ,YAAaF,OAGbF,SACc,EAAhBI,WAAW,GACXA,WAAW,GAAIA,WAAW,GAAIA,WAAW,GAAIA,WAAW,GAAIA,WAAW,IAIrEf,UAAmD,OAAtCe,WAAW,IAAM,EAAIA,WAAW,IAG7CR,WAAa,EAAGF,WAAa,EA4G7Bte,KAAOC,EACXD,MAAK+d,GAAKA,GACV/d,KAAKC,GAAKA,GACVD,KAAKqR,MAAQA,MACbrR,KAAK4d,QAAUA,QAEf7V,OAAOD,QAAU9H;;AChKjB,QAAS4L,gBAFT7D,OAAOD,QAAU8D,YAIjBA,YAAYqT,MAAQ,SAAUnR,GAC1B,GAAI1G,GAAY0G,EAAY1G,WAAa0G,CAEzC1G,GAAU8X,eAAe,EAGzB9X,EAAU7G,GAAK,SAAUiC,EAAO2c,EAAWC,GACvC5jB,KAAK6jB,UAAY7jB,KAAK6jB,aACtB,IAAIC,GAAiC,IAArBtW,UAAUtN,OACtBoa,EAAQwJ,EAAWtW,UAAU,OAAKpK,GAClC2gB,EAAOD,EAAWtW,UAAU,GAAKA,UAAU,EAG/C,OAFAuW,GAAKC,WAAa1J,GACjBta,KAAK6jB,UAAU7c,GAAShH,KAAK6jB,UAAU7c,QAActG,KAAKqjB,GACpD/jB,MAKX4L,EAAUoC,KAAO,SAAUhH,EAAO2c,EAAWC,GAKzC,QAAS7e,KACLpC,EAAKshB,IAAIjd,EAAOjC,GAChBgf,EAAKha,MAAM/J,KAAMwN,WANrB,GAAI7K,GAAO3C,KACP8jB,EAAiC,IAArBtW,UAAUtN,OACtBoa,EAAQwJ,EAAWtW,UAAU,OAAKpK,GAClC2gB,EAAOD,EAAWtW,UAAU,GAAKA,UAAU,EAM/C,OADAxN,MAAK+E,GAAGiC,EAAOsT,EAAOvV,GACf/E,MAIX4L,EAAUsY,aAAe,SAAUP,GAC/B3jB,KAAK6jB,UAAY7jB,KAAK6jB,aACtB,IAAI1Q,GAAM3I,EAAG6C,EAAK8W,CAClB,KAAKhR,IAAQnT,MAAK6jB,UAEd,IADAM,EAAWnkB,KAAK6jB,UAAU1Q,GACrB3I,EAAI,EAAG6C,EAAM8W,EAASjkB,OAAQsK,EAAI6C,EAAK7C,IACpC2Z,EAAS3Z,GAAGwZ,aAAeL,IAG3BQ,EAAS7V,OAAO9D,EAAG,GACnBA,IACA6C,IAIZ,OAAOrN,OAKX4L,EAAUqY,IAAM,SAAUjd,EAAO4c,GAC7B5jB,KAAK6jB,UAAY7jB,KAAK6jB,aACtB,IACIrZ,GADAqZ,EAAY7jB,KAAK6jB,UAAU7c,EAG/B,OAAK6c,GAGoB,IAArBrW,UAAUtN,cACHF,MAAK6jB,UAAU7c,GACfhH,OAIXwK,EAAIqZ,EAAU/iB,QAAQ8iB,GACtBC,EAAUvV,OAAO9D,EAAG,GACK,IAArBqZ,EAAU3jB,cACHF,MAAK6jB,UAAU7c,GAEnBhH,MAdgBA,MAmB3B4L,EAAUtE,KAAO,SAAUN,GACvBhH,KAAK6jB,UAAY7jB,KAAK6jB,aACtB,IAGIrZ,GACA6C,EAEAE,EANAD,KAAUvM,MAAM6C,KAAK4J,UAAW,GAChCqW,EAAY7jB,KAAK6jB,UAAU7c,GAC3Bod,EAAmBpkB,KAAKqkB,qBAAqBrd,EAMjD,IAAI6c,EAEA,IADAtW,EAAYsW,EAAU9iB,QACjByJ,EAAI,EAAG6C,EAAME,EAAUrN,OAAQsK,EAAI6C,GAC/BE,EAAU/C,KAD4BA,EAI3C+C,EAAU/C,GAAGT,MAAM/J,KAAMsN,EAIjC,IAAI8W,EAGA,IAFA/W,EAAM+W,EAAiBlkB,OACvBqN,EAAY6W,EAAiBrjB,QACxByJ,EAAI,EAAG6C,EAAME,EAAUrN,OAAQsK,EAAI6C,GAC/BE,EAAU/C,KAD4BA,EAI3C+C,EAAU/C,GAAGT,MAAM/J,MAAOgH,GAAOiI,OAAO3B,GAIhD,OAAOtN,OAIX4L,EAAUyY,qBAAuB,SAAUC,GACvCtkB,KAAK6jB,UAAY7jB,KAAK6jB,aACtB,IAAI1Q,GACAU,EACAZ,IAEJ,KAAKE,IAAQnT,MAAK6jB,UACdhQ,EAAQV,EAAKU,MAAM,MACN,MAATV,GAAkC,IAAjBU,EAAM3T,QAAgBokB,EAAUvjB,MAAM,EAAG8S,EAAM,GAAG3T,UAAY2T,EAAM,MACrFZ,EAASA,EAAOhE,OAAOjP,KAAK6jB,UAAU1Q,IAG9C,OAAOF,KAKf7C,YAAYqT,MAAMrT","file":"bundle.js","sourcesContent":["(function(){function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}return e})()","module.exports=[\"stun.l.google.com:19302\",\"stun1.l.google.com:19302\",\"stun2.l.google.com:19302\",\"stun3.l.google.com:19302\",\"stun4.l.google.com:19302\",\"stun.ekiga.net\",\"stun.ideasip.com\",\"stun.schlund.de\",\"stun.stunprotocol.org:3478\",\"stun.voiparound.com\",\"stun.voipbuster.com\",\"stun.voipstunt.com\",\"stun.voxgratia.org\",\"stun.services.mozilla.com\"]","module.exports=[]","var freeice = require('freeice');\nvar inherits = require('inherits');\nvar UAParser = require('ua-parser-js');\nvar uuid = require('uuid');\nvar hark = require('hark');\nvar EventEmitter = require('events').EventEmitter;\nvar recursive = require('merge').recursive.bind(undefined, true);\nvar sdpTranslator = require('sdp-translator');\nvar logger = window.Logger || console;\ntry {\n require('kurento-browser-extensions');\n} catch (error) {\n if (typeof getScreenConstraints === 'undefined') {\n logger.warn('screen sharing is not available');\n getScreenConstraints = function getScreenConstraints(sendSource, callback) {\n callback(new Error('This library is not enabled for screen sharing'));\n };\n }\n}\nvar MEDIA_CONSTRAINTS = {\n audio: true,\n video: {\n width: 640,\n framerate: 15\n }\n };\nvar ua = window && window.navigator ? window.navigator.userAgent : '';\nvar parser = new UAParser(ua);\nvar browser = parser.getBrowser();\nvar usePlanB = false;\nif (browser.name === 'Chrome' || browser.name === 'Chromium') {\n logger.debug(browser.name + ': using SDP PlanB');\n usePlanB = true;\n}\nfunction noop(error) {\n if (error)\n logger.error(error);\n}\nfunction trackStop(track) {\n track.stop && track.stop();\n}\nfunction streamStop(stream) {\n stream.getTracks().forEach(trackStop);\n}\nvar dumpSDP = function (description) {\n if (typeof description === 'undefined' || description === null) {\n return '';\n }\n return 'type: ' + description.type + '\\r\\n' + description.sdp;\n};\nfunction bufferizeCandidates(pc, onerror) {\n var candidatesQueue = [];\n pc.addEventListener('signalingstatechange', function () {\n if (this.signalingState === 'stable') {\n while (candidatesQueue.length) {\n var entry = candidatesQueue.shift();\n pc.addIceCandidate(entry.candidate, entry.callback, entry.callback);\n }\n }\n });\n return function (candidate, callback) {\n callback = callback || onerror;\n switch (pc.signalingState) {\n case 'closed':\n callback(new Error('PeerConnection object is closed'));\n break;\n case 'stable':\n if (pc.remoteDescription) {\n pc.addIceCandidate(candidate, callback, callback);\n break;\n }\n default:\n candidatesQueue.push({\n candidate: candidate,\n callback: callback\n });\n }\n };\n}\nfunction removeFIDFromOffer(sdp) {\n var n = sdp.indexOf('a=ssrc-group:FID');\n if (n > 0) {\n return sdp.slice(0, n);\n } else {\n return sdp;\n }\n}\nfunction getSimulcastInfo(videoStream) {\n var videoTracks = videoStream.getVideoTracks();\n if (!videoTracks.length) {\n logger.warn('No video tracks available in the video stream');\n return '';\n }\n var lines = [\n 'a=x-google-flag:conference',\n 'a=ssrc-group:SIM 1 2 3',\n 'a=ssrc:1 cname:localVideo',\n 'a=ssrc:1 msid:' + videoStream.id + ' ' + videoTracks[0].id,\n 'a=ssrc:1 mslabel:' + videoStream.id,\n 'a=ssrc:1 label:' + videoTracks[0].id,\n 'a=ssrc:2 cname:localVideo',\n 'a=ssrc:2 msid:' + videoStream.id + ' ' + videoTracks[0].id,\n 'a=ssrc:2 mslabel:' + videoStream.id,\n 'a=ssrc:2 label:' + videoTracks[0].id,\n 'a=ssrc:3 cname:localVideo',\n 'a=ssrc:3 msid:' + videoStream.id + ' ' + videoTracks[0].id,\n 'a=ssrc:3 mslabel:' + videoStream.id,\n 'a=ssrc:3 label:' + videoTracks[0].id\n ];\n lines.push('');\n return lines.join('\\n');\n}\nfunction WebRtcPeer(mode, options, callback) {\n if (!(this instanceof WebRtcPeer)) {\n return new WebRtcPeer(mode, options, callback);\n }\n WebRtcPeer.super_.call(this);\n if (options instanceof Function) {\n callback = options;\n options = undefined;\n }\n options = options || {};\n callback = (callback || noop).bind(this);\n var self = this;\n var localVideo = options.localVideo;\n var remoteVideo = options.remoteVideo;\n var videoStream = options.videoStream;\n var audioStream = options.audioStream;\n var mediaConstraints = options.mediaConstraints;\n var connectionConstraints = options.connectionConstraints;\n var pc = options.peerConnection;\n var sendSource = options.sendSource || 'webcam';\n var dataChannelConfig = options.dataChannelConfig;\n var useDataChannels = options.dataChannels || false;\n var dataChannel;\n var guid = uuid.v4();\n var configuration = recursive({ iceServers: freeice() }, options.configuration);\n var onicecandidate = options.onicecandidate;\n if (onicecandidate)\n this.on('icecandidate', onicecandidate);\n var oncandidategatheringdone = options.oncandidategatheringdone;\n if (oncandidategatheringdone) {\n this.on('candidategatheringdone', oncandidategatheringdone);\n }\n var simulcast = options.simulcast;\n var multistream = options.multistream;\n var interop = new sdpTranslator.Interop();\n var candidatesQueueOut = [];\n var candidategatheringdone = false;\n Object.defineProperties(this, {\n 'peerConnection': {\n get: function () {\n return pc;\n }\n },\n 'id': {\n value: options.id || guid,\n writable: false\n },\n 'remoteVideo': {\n get: function () {\n return remoteVideo;\n }\n },\n 'localVideo': {\n get: function () {\n return localVideo;\n }\n },\n 'dataChannel': {\n get: function () {\n return dataChannel;\n }\n },\n 'currentFrame': {\n get: function () {\n if (!remoteVideo)\n return;\n if (remoteVideo.readyState < remoteVideo.HAVE_CURRENT_DATA)\n throw new Error('No video stream data available');\n var canvas = document.createElement('canvas');\n canvas.width = remoteVideo.videoWidth;\n canvas.height = remoteVideo.videoHeight;\n canvas.getContext('2d').drawImage(remoteVideo, 0, 0);\n return canvas;\n }\n }\n });\n if (!pc) {\n pc = new RTCPeerConnection(configuration);\n if (useDataChannels && !dataChannel) {\n var dcId = 'WebRtcPeer-' + self.id;\n var dcOptions = undefined;\n if (dataChannelConfig) {\n dcId = dataChannelConfig.id || dcId;\n dcOptions = dataChannelConfig.options;\n }\n dataChannel = pc.createDataChannel(dcId, dcOptions);\n if (dataChannelConfig) {\n dataChannel.onopen = dataChannelConfig.onopen;\n dataChannel.onclose = dataChannelConfig.onclose;\n dataChannel.onmessage = dataChannelConfig.onmessage;\n dataChannel.onbufferedamountlow = dataChannelConfig.onbufferedamountlow;\n dataChannel.onerror = dataChannelConfig.onerror || noop;\n }\n }\n }\n pc.addEventListener('icecandidate', function (event) {\n var candidate = event.candidate;\n if (EventEmitter.listenerCount(self, 'icecandidate') || EventEmitter.listenerCount(self, 'candidategatheringdone')) {\n if (candidate) {\n var cand;\n if (multistream && usePlanB) {\n cand = interop.candidateToUnifiedPlan(candidate);\n } else {\n cand = candidate;\n }\n self.emit('icecandidate', cand);\n candidategatheringdone = false;\n } else if (!candidategatheringdone) {\n self.emit('candidategatheringdone');\n candidategatheringdone = true;\n }\n } else if (!candidategatheringdone) {\n candidatesQueueOut.push(candidate);\n if (!candidate)\n candidategatheringdone = true;\n }\n });\n pc.onaddstream = options.onaddstream;\n pc.onnegotiationneeded = options.onnegotiationneeded;\n this.on('newListener', function (event, listener) {\n if (event === 'icecandidate' || event === 'candidategatheringdone') {\n while (candidatesQueueOut.length) {\n var candidate = candidatesQueueOut.shift();\n if (!candidate === (event === 'candidategatheringdone')) {\n listener(candidate);\n }\n }\n }\n });\n var addIceCandidate = bufferizeCandidates(pc);\n this.addIceCandidate = function (iceCandidate, callback) {\n var candidate;\n if (multistream && usePlanB) {\n candidate = interop.candidateToPlanB(iceCandidate);\n } else {\n candidate = new RTCIceCandidate(iceCandidate);\n }\n logger.debug('Remote ICE candidate received', iceCandidate);\n callback = (callback || noop).bind(this);\n addIceCandidate(candidate, callback);\n };\n this.generateOffer = function (callback) {\n callback = callback.bind(this);\n var offerAudio = true;\n var offerVideo = true;\n if (mediaConstraints) {\n offerAudio = typeof mediaConstraints.audio === 'boolean' ? mediaConstraints.audio : true;\n offerVideo = typeof mediaConstraints.video === 'boolean' ? mediaConstraints.video : true;\n }\n var browserDependantConstraints = {\n offerToReceiveAudio: mode !== 'sendonly' && offerAudio,\n offerToReceiveVideo: mode !== 'sendonly' && offerVideo\n };\n var constraints = browserDependantConstraints;\n logger.debug('constraints: ' + JSON.stringify(constraints));\n pc.createOffer(constraints).then(function (offer) {\n logger.debug('Created SDP offer');\n offer = mangleSdpToAddSimulcast(offer);\n return pc.setLocalDescription(offer);\n }).then(function () {\n var localDescription = pc.localDescription;\n logger.debug('Local description set', localDescription.sdp);\n if (multistream && usePlanB) {\n localDescription = interop.toUnifiedPlan(localDescription);\n logger.debug('offer::origPlanB->UnifiedPlan', dumpSDP(localDescription));\n }\n callback(null, localDescription.sdp, self.processAnswer.bind(self));\n }).catch(callback);\n };\n this.getLocalSessionDescriptor = function () {\n return pc.localDescription;\n };\n this.getRemoteSessionDescriptor = function () {\n return pc.remoteDescription;\n };\n function setRemoteVideo() {\n if (remoteVideo) {\n remoteVideo.pause();\n var stream = pc.getRemoteStreams()[0];\n remoteVideo.srcObject = stream;\n logger.debug('Remote stream:', stream);\n remoteVideo.load();\n }\n }\n this.showLocalVideo = function () {\n localVideo.srcObject = videoStream;\n localVideo.muted = true;\n };\n this.send = function (data) {\n if (dataChannel && dataChannel.readyState === 'open') {\n dataChannel.send(data);\n } else {\n logger.warn('Trying to send data over a non-existing or closed data channel');\n }\n };\n this.processAnswer = function (sdpAnswer, callback) {\n callback = (callback || noop).bind(this);\n var answer = new RTCSessionDescription({\n type: 'answer',\n sdp: sdpAnswer\n });\n if (multistream && usePlanB) {\n var planBAnswer = interop.toPlanB(answer);\n logger.debug('asnwer::planB', dumpSDP(planBAnswer));\n answer = planBAnswer;\n }\n logger.debug('SDP answer received, setting remote description');\n if (pc.signalingState === 'closed') {\n return callback('PeerConnection is closed');\n }\n pc.setRemoteDescription(answer, function () {\n setRemoteVideo();\n callback();\n }, callback);\n };\n this.processOffer = function (sdpOffer, callback) {\n callback = callback.bind(this);\n var offer = new RTCSessionDescription({\n type: 'offer',\n sdp: sdpOffer\n });\n if (multistream && usePlanB) {\n var planBOffer = interop.toPlanB(offer);\n logger.debug('offer::planB', dumpSDP(planBOffer));\n offer = planBOffer;\n }\n logger.debug('SDP offer received, setting remote description');\n if (pc.signalingState === 'closed') {\n return callback('PeerConnection is closed');\n }\n pc.setRemoteDescription(offer).then(function () {\n return setRemoteVideo();\n }).then(function () {\n return pc.createAnswer();\n }).then(function (answer) {\n answer = mangleSdpToAddSimulcast(answer);\n logger.debug('Created SDP answer');\n return pc.setLocalDescription(answer);\n }).then(function () {\n var localDescription = pc.localDescription;\n if (multistream && usePlanB) {\n localDescription = interop.toUnifiedPlan(localDescription);\n logger.debug('answer::origPlanB->UnifiedPlan', dumpSDP(localDescription));\n }\n logger.debug('Local description set', localDescription.sdp);\n callback(null, localDescription.sdp);\n }).catch(callback);\n };\n function mangleSdpToAddSimulcast(answer) {\n if (simulcast) {\n if (browser.name === 'Chrome' || browser.name === 'Chromium') {\n logger.debug('Adding multicast info');\n answer = new RTCSessionDescription({\n 'type': answer.type,\n 'sdp': removeFIDFromOffer(answer.sdp) + getSimulcastInfo(videoStream)\n });\n } else {\n logger.warn('Simulcast is only available in Chrome browser.');\n }\n }\n return answer;\n }\n function start() {\n if (pc.signalingState === 'closed') {\n callback('The peer connection object is in \"closed\" state. This is most likely due to an invocation of the dispose method before accepting in the dialogue');\n }\n if (videoStream && localVideo) {\n self.showLocalVideo();\n }\n if (videoStream) {\n pc.addStream(videoStream);\n }\n if (audioStream) {\n pc.addStream(audioStream);\n }\n var browser = parser.getBrowser();\n if (mode === 'sendonly' && (browser.name === 'Chrome' || browser.name === 'Chromium') && browser.major === 39) {\n mode = 'sendrecv';\n }\n callback();\n }\n if (mode !== 'recvonly' && !videoStream && !audioStream) {\n function getMedia(constraints) {\n if (constraints === undefined) {\n constraints = MEDIA_CONSTRAINTS;\n }\n navigator.mediaDevices.getUserMedia(constraints).then(function (stream) {\n videoStream = stream;\n start();\n }).catch(callback);\n }\n if (sendSource === 'webcam') {\n getMedia(mediaConstraints);\n } else {\n getScreenConstraints(sendSource, function (error, constraints_) {\n if (error)\n return callback(error);\n constraints = [mediaConstraints];\n constraints.unshift(constraints_);\n getMedia(recursive.apply(undefined, constraints));\n }, guid);\n }\n } else {\n setTimeout(start, 0);\n }\n this.on('_dispose', function () {\n if (localVideo) {\n localVideo.pause();\n localVideo.srcObject = null;\n localVideo.load();\n localVideo.muted = false;\n }\n if (remoteVideo) {\n remoteVideo.pause();\n remoteVideo.srcObject = null;\n remoteVideo.load();\n }\n self.removeAllListeners();\n if (window.cancelChooseDesktopMedia !== undefined) {\n window.cancelChooseDesktopMedia(guid);\n }\n });\n}\ninherits(WebRtcPeer, EventEmitter);\nfunction createEnableDescriptor(type) {\n var method = 'get' + type + 'Tracks';\n return {\n enumerable: true,\n get: function () {\n if (!this.peerConnection)\n return;\n var streams = this.peerConnection.getLocalStreams();\n if (!streams.length)\n return;\n for (var i = 0, stream; stream = streams[i]; i++) {\n var tracks = stream[method]();\n for (var j = 0, track; track = tracks[j]; j++)\n if (!track.enabled)\n return false;\n }\n return true;\n },\n set: function (value) {\n function trackSetEnable(track) {\n track.enabled = value;\n }\n this.peerConnection.getLocalStreams().forEach(function (stream) {\n stream[method]().forEach(trackSetEnable);\n });\n }\n };\n}\nObject.defineProperties(WebRtcPeer.prototype, {\n 'enabled': {\n enumerable: true,\n get: function () {\n return this.audioEnabled && this.videoEnabled;\n },\n set: function (value) {\n this.audioEnabled = this.videoEnabled = value;\n }\n },\n 'audioEnabled': createEnableDescriptor('Audio'),\n 'videoEnabled': createEnableDescriptor('Video')\n});\nWebRtcPeer.prototype.getLocalStream = function (index) {\n if (this.peerConnection) {\n return this.peerConnection.getLocalStreams()[index || 0];\n }\n};\nWebRtcPeer.prototype.getRemoteStream = function (index) {\n if (this.peerConnection) {\n return this.peerConnection.getRemoteStreams()[index || 0];\n }\n};\nWebRtcPeer.prototype.dispose = function () {\n logger.debug('Disposing WebRtcPeer');\n var pc = this.peerConnection;\n var dc = this.dataChannel;\n try {\n if (dc) {\n if (dc.signalingState === 'closed')\n return;\n dc.close();\n }\n if (pc) {\n if (pc.signalingState === 'closed')\n return;\n pc.getLocalStreams().forEach(streamStop);\n pc.close();\n }\n } catch (err) {\n logger.warn('Exception disposing webrtc peer ' + err);\n }\n this.emit('_dispose');\n};\nfunction WebRtcPeerRecvonly(options, callback) {\n if (!(this instanceof WebRtcPeerRecvonly)) {\n return new WebRtcPeerRecvonly(options, callback);\n }\n WebRtcPeerRecvonly.super_.call(this, 'recvonly', options, callback);\n}\ninherits(WebRtcPeerRecvonly, WebRtcPeer);\nfunction WebRtcPeerSendonly(options, callback) {\n if (!(this instanceof WebRtcPeerSendonly)) {\n return new WebRtcPeerSendonly(options, callback);\n }\n WebRtcPeerSendonly.super_.call(this, 'sendonly', options, callback);\n}\ninherits(WebRtcPeerSendonly, WebRtcPeer);\nfunction WebRtcPeerSendrecv(options, callback) {\n if (!(this instanceof WebRtcPeerSendrecv)) {\n return new WebRtcPeerSendrecv(options, callback);\n }\n WebRtcPeerSendrecv.super_.call(this, 'sendrecv', options, callback);\n}\ninherits(WebRtcPeerSendrecv, WebRtcPeer);\nfunction harkUtils(stream, options) {\n return hark(stream, options);\n}\nexports.bufferizeCandidates = bufferizeCandidates;\nexports.WebRtcPeerRecvonly = WebRtcPeerRecvonly;\nexports.WebRtcPeerSendonly = WebRtcPeerSendonly;\nexports.WebRtcPeerSendrecv = WebRtcPeerSendrecv;\nexports.hark = harkUtils;","if (window.addEventListener)\n module.exports = require('./index');","var WebRtcPeer = require('./WebRtcPeer');\nexports.WebRtcPeer = WebRtcPeer;","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nfunction EventEmitter() {\n this._events = this._events || {};\n this._maxListeners = this._maxListeners || undefined;\n}\nmodule.exports = EventEmitter;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nEventEmitter.defaultMaxListeners = 10;\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function(n) {\n if (!isNumber(n) || n < 0 || isNaN(n))\n throw TypeError('n must be a positive number');\n this._maxListeners = n;\n return this;\n};\n\nEventEmitter.prototype.emit = function(type) {\n var er, handler, len, args, i, listeners;\n\n if (!this._events)\n this._events = {};\n\n // If there is no 'error' event listener then throw.\n if (type === 'error') {\n if (!this._events.error ||\n (isObject(this._events.error) && !this._events.error.length)) {\n er = arguments[1];\n if (er instanceof Error) {\n throw er; // Unhandled 'error' event\n } else {\n // At least give some kind of context to the user\n var err = new Error('Uncaught, unspecified \"error\" event. (' + er + ')');\n err.context = er;\n throw err;\n }\n }\n }\n\n handler = this._events[type];\n\n if (isUndefined(handler))\n return false;\n\n if (isFunction(handler)) {\n switch (arguments.length) {\n // fast cases\n case 1:\n handler.call(this);\n break;\n case 2:\n handler.call(this, arguments[1]);\n break;\n case 3:\n handler.call(this, arguments[1], arguments[2]);\n break;\n // slower\n default:\n args = Array.prototype.slice.call(arguments, 1);\n handler.apply(this, args);\n }\n } else if (isObject(handler)) {\n args = Array.prototype.slice.call(arguments, 1);\n listeners = handler.slice();\n len = listeners.length;\n for (i = 0; i < len; i++)\n listeners[i].apply(this, args);\n }\n\n return true;\n};\n\nEventEmitter.prototype.addListener = function(type, listener) {\n var m;\n\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n if (!this._events)\n this._events = {};\n\n // To avoid recursion in the case that type === \"newListener\"! Before\n // adding it to the listeners, first emit \"newListener\".\n if (this._events.newListener)\n this.emit('newListener', type,\n isFunction(listener.listener) ?\n listener.listener : listener);\n\n if (!this._events[type])\n // Optimize the case of one listener. Don't need the extra array object.\n this._events[type] = listener;\n else if (isObject(this._events[type]))\n // If we've already got an array, just append.\n this._events[type].push(listener);\n else\n // Adding the second element, need to change to array.\n this._events[type] = [this._events[type], listener];\n\n // Check for listener leak\n if (isObject(this._events[type]) && !this._events[type].warned) {\n if (!isUndefined(this._maxListeners)) {\n m = this._maxListeners;\n } else {\n m = EventEmitter.defaultMaxListeners;\n }\n\n if (m && m > 0 && this._events[type].length > m) {\n this._events[type].warned = true;\n console.error('(node) warning: possible EventEmitter memory ' +\n 'leak detected. %d listeners added. ' +\n 'Use emitter.setMaxListeners() to increase limit.',\n this._events[type].length);\n if (typeof console.trace === 'function') {\n // not supported in IE 10\n console.trace();\n }\n }\n }\n\n return this;\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.once = function(type, listener) {\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n var fired = false;\n\n function g() {\n this.removeListener(type, g);\n\n if (!fired) {\n fired = true;\n listener.apply(this, arguments);\n }\n }\n\n g.listener = listener;\n this.on(type, g);\n\n return this;\n};\n\n// emits a 'removeListener' event iff the listener was removed\nEventEmitter.prototype.removeListener = function(type, listener) {\n var list, position, length, i;\n\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n if (!this._events || !this._events[type])\n return this;\n\n list = this._events[type];\n length = list.length;\n position = -1;\n\n if (list === listener ||\n (isFunction(list.listener) && list.listener === listener)) {\n delete this._events[type];\n if (this._events.removeListener)\n this.emit('removeListener', type, listener);\n\n } else if (isObject(list)) {\n for (i = length; i-- > 0;) {\n if (list[i] === listener ||\n (list[i].listener && list[i].listener === listener)) {\n position = i;\n break;\n }\n }\n\n if (position < 0)\n return this;\n\n if (list.length === 1) {\n list.length = 0;\n delete this._events[type];\n } else {\n list.splice(position, 1);\n }\n\n if (this._events.removeListener)\n this.emit('removeListener', type, listener);\n }\n\n return this;\n};\n\nEventEmitter.prototype.removeAllListeners = function(type) {\n var key, listeners;\n\n if (!this._events)\n return this;\n\n // not listening for removeListener, no need to emit\n if (!this._events.removeListener) {\n if (arguments.length === 0)\n this._events = {};\n else if (this._events[type])\n delete this._events[type];\n return this;\n }\n\n // emit removeListener for all listeners on all events\n if (arguments.length === 0) {\n for (key in this._events) {\n if (key === 'removeListener') continue;\n this.removeAllListeners(key);\n }\n this.removeAllListeners('removeListener');\n this._events = {};\n return this;\n }\n\n listeners = this._events[type];\n\n if (isFunction(listeners)) {\n this.removeListener(type, listeners);\n } else if (listeners) {\n // LIFO order\n while (listeners.length)\n this.removeListener(type, listeners[listeners.length - 1]);\n }\n delete this._events[type];\n\n return this;\n};\n\nEventEmitter.prototype.listeners = function(type) {\n var ret;\n if (!this._events || !this._events[type])\n ret = [];\n else if (isFunction(this._events[type]))\n ret = [this._events[type]];\n else\n ret = this._events[type].slice();\n return ret;\n};\n\nEventEmitter.prototype.listenerCount = function(type) {\n if (this._events) {\n var evlistener = this._events[type];\n\n if (isFunction(evlistener))\n return 1;\n else if (evlistener)\n return evlistener.length;\n }\n return 0;\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n return emitter.listenerCount(type);\n};\n\nfunction isFunction(arg) {\n return typeof arg === 'function';\n}\n\nfunction isNumber(arg) {\n return typeof arg === 'number';\n}\n\nfunction isObject(arg) {\n return typeof arg === 'object' && arg !== null;\n}\n\nfunction isUndefined(arg) {\n return arg === void 0;\n}\n","/* jshint node: true */\n'use strict';\n\nvar normalice = require('normalice');\n\n/**\n # freeice\n\n The `freeice` module is a simple way of getting random STUN or TURN server\n for your WebRTC application. The list of servers (just STUN at this stage)\n were sourced from this [gist](https://gist.github.com/zziuni/3741933).\n\n ## Example Use\n\n The following demonstrates how you can use `freeice` with\n [rtc-quickconnect](https://github.com/rtc-io/rtc-quickconnect):\n\n <<< examples/quickconnect.js\n\n As the `freeice` module generates ice servers in a list compliant with the\n WebRTC spec you will be able to use it with raw `RTCPeerConnection`\n constructors and other WebRTC libraries.\n\n ## Hey, don't use my STUN/TURN server!\n\n If for some reason your free STUN or TURN server ends up in the\n list of servers ([stun](https://github.com/DamonOehlman/freeice/blob/master/stun.json) or\n [turn](https://github.com/DamonOehlman/freeice/blob/master/turn.json))\n that is used in this module, you can feel\n free to open an issue on this repository and those servers will be removed\n within 24 hours (or sooner). This is the quickest and probably the most\n polite way to have something removed (and provides us some visibility\n if someone opens a pull request requesting that a server is added).\n\n ## Please add my server!\n\n If you have a server that you wish to add to the list, that's awesome! I'm\n sure I speak on behalf of a whole pile of WebRTC developers who say thanks.\n To get it into the list, feel free to either open a pull request or if you\n find that process a bit daunting then just create an issue requesting\n the addition of the server (make sure you provide all the details, and if\n you have a Terms of Service then including that in the PR/issue would be\n awesome).\n\n ## I know of a free server, can I add it?\n\n Sure, if you do your homework and make sure it is ok to use (I'm currently\n in the process of reviewing the terms of those STUN servers included from\n the original list). If it's ok to go, then please see the previous entry\n for how to add it.\n\n ## Current List of Servers\n\n * current as at the time of last `README.md` file generation\n\n ### STUN\n\n <<< stun.json\n\n ### TURN\n\n <<< turn.json\n\n**/\n\nvar freeice = module.exports = function(opts) {\n // if a list of servers has been provided, then use it instead of defaults\n var servers = {\n stun: (opts || {}).stun || require('./stun.json'),\n turn: (opts || {}).turn || require('./turn.json')\n };\n\n var stunCount = (opts || {}).stunCount || 2;\n var turnCount = (opts || {}).turnCount || 0;\n var selected;\n\n function getServers(type, count) {\n var out = [];\n var input = [].concat(servers[type]);\n var idx;\n\n while (input.length && out.length < count) {\n idx = (Math.random() * input.length) | 0;\n out = out.concat(input.splice(idx, 1));\n }\n\n return out.map(function(url) {\n //If it's a not a string, don't try to \"normalice\" it otherwise using type:url will screw it up\n if ((typeof url !== 'string') && (! (url instanceof String))) {\n return url;\n } else {\n return normalice(type + ':' + url);\n }\n });\n }\n\n // add stun servers\n selected = [].concat(getServers('stun', stunCount));\n\n if (turnCount) {\n selected = selected.concat(getServers('turn', turnCount));\n }\n\n return selected;\n};\n","var WildEmitter = require('wildemitter');\n\nfunction getMaxVolume (analyser, fftBins) {\n var maxVolume = -Infinity;\n analyser.getFloatFrequencyData(fftBins);\n\n for(var i=4, ii=fftBins.length; i < ii; i++) {\n if (fftBins[i] > maxVolume && fftBins[i] < 0) {\n maxVolume = fftBins[i];\n }\n };\n\n return maxVolume;\n}\n\n\nvar audioContextType = window.AudioContext || window.webkitAudioContext;\n// use a single audio context due to hardware limits\nvar audioContext = null;\nmodule.exports = function(stream, options) {\n var harker = new WildEmitter();\n\n\n // make it not break in non-supported browsers\n if (!audioContextType) return harker;\n\n //Config\n var options = options || {},\n smoothing = (options.smoothing || 0.1),\n interval = (options.interval || 50),\n threshold = options.threshold,\n play = options.play,\n history = options.history || 10,\n running = true;\n\n //Setup Audio Context\n if (!audioContext) {\n audioContext = new audioContextType();\n }\n var sourceNode, fftBins, analyser;\n\n analyser = audioContext.createAnalyser();\n analyser.fftSize = 512;\n analyser.smoothingTimeConstant = smoothing;\n fftBins = new Float32Array(analyser.fftSize);\n\n if (stream.jquery) stream = stream[0];\n if (stream instanceof HTMLAudioElement || stream instanceof HTMLVideoElement) {\n //Audio Tag\n sourceNode = audioContext.createMediaElementSource(stream);\n if (typeof play === 'undefined') play = true;\n threshold = threshold || -50;\n } else {\n //WebRTC Stream\n sourceNode = audioContext.createMediaStreamSource(stream);\n threshold = threshold || -50;\n }\n\n sourceNode.connect(analyser);\n if (play) analyser.connect(audioContext.destination);\n\n harker.speaking = false;\n\n harker.setThreshold = function(t) {\n threshold = t;\n };\n\n harker.setInterval = function(i) {\n interval = i;\n };\n \n harker.stop = function() {\n running = false;\n harker.emit('volume_change', -100, threshold);\n if (harker.speaking) {\n harker.speaking = false;\n harker.emit('stopped_speaking');\n }\n };\n harker.speakingHistory = [];\n for (var i = 0; i < history; i++) {\n harker.speakingHistory.push(0);\n }\n\n // Poll the analyser node to determine if speaking\n // and emit events if changed\n var looper = function() {\n setTimeout(function() {\n \n //check if stop has been called\n if(!running) {\n return;\n }\n \n var currentVolume = getMaxVolume(analyser, fftBins);\n\n harker.emit('volume_change', currentVolume, threshold);\n\n var history = 0;\n if (currentVolume > threshold && !harker.speaking) {\n // trigger quickly, short history\n for (var i = harker.speakingHistory.length - 3; i < harker.speakingHistory.length; i++) {\n history += harker.speakingHistory[i];\n }\n if (history >= 2) {\n harker.speaking = true;\n harker.emit('speaking');\n }\n } else if (currentVolume < threshold && harker.speaking) {\n for (var i = 0; i < harker.speakingHistory.length; i++) {\n history += harker.speakingHistory[i];\n }\n if (history == 0) {\n harker.speaking = false;\n harker.emit('stopped_speaking');\n }\n }\n harker.speakingHistory.shift();\n harker.speakingHistory.push(0 + (currentVolume > threshold));\n\n looper();\n }, interval);\n };\n looper();\n\n\n return harker;\n}\n","if (typeof Object.create === 'function') {\n // implementation from standard node.js 'util' module\n module.exports = function inherits(ctor, superCtor) {\n ctor.super_ = superCtor\n ctor.prototype = Object.create(superCtor.prototype, {\n constructor: {\n value: ctor,\n enumerable: false,\n writable: true,\n configurable: true\n }\n });\n };\n} else {\n // old school shim for old browsers\n module.exports = function inherits(ctor, superCtor) {\n ctor.super_ = superCtor\n var TempCtor = function () {}\n TempCtor.prototype = superCtor.prototype\n ctor.prototype = new TempCtor()\n ctor.prototype.constructor = ctor\n }\n}\n","/*!\r\n * @name JavaScript/NodeJS Merge v1.2.0\r\n * @author yeikos\r\n * @repository https://github.com/yeikos/js.merge\r\n\r\n * Copyright 2014 yeikos - MIT license\r\n * https://raw.github.com/yeikos/js.merge/master/LICENSE\r\n */\r\n\r\n;(function(isNode) {\r\n\r\n\t/**\r\n\t * Merge one or more objects \r\n\t * @param bool? clone\r\n\t * @param mixed,... arguments\r\n\t * @return object\r\n\t */\r\n\r\n\tvar Public = function(clone) {\r\n\r\n\t\treturn merge(clone === true, false, arguments);\r\n\r\n\t}, publicName = 'merge';\r\n\r\n\t/**\r\n\t * Merge two or more objects recursively \r\n\t * @param bool? clone\r\n\t * @param mixed,... arguments\r\n\t * @return object\r\n\t */\r\n\r\n\tPublic.recursive = function(clone) {\r\n\r\n\t\treturn merge(clone === true, true, arguments);\r\n\r\n\t};\r\n\r\n\t/**\r\n\t * Clone the input removing any reference\r\n\t * @param mixed input\r\n\t * @return mixed\r\n\t */\r\n\r\n\tPublic.clone = function(input) {\r\n\r\n\t\tvar output = input,\r\n\t\t\ttype = typeOf(input),\r\n\t\t\tindex, size;\r\n\r\n\t\tif (type === 'array') {\r\n\r\n\t\t\toutput = [];\r\n\t\t\tsize = input.length;\r\n\r\n\t\t\tfor (index=0;index<size;++index)\r\n\r\n\t\t\t\toutput[index] = Public.clone(input[index]);\r\n\r\n\t\t} else if (type === 'object') {\r\n\r\n\t\t\toutput = {};\r\n\r\n\t\t\tfor (index in input)\r\n\r\n\t\t\t\toutput[index] = Public.clone(input[index]);\r\n\r\n\t\t}\r\n\r\n\t\treturn output;\r\n\r\n\t};\r\n\r\n\t/**\r\n\t * Merge two objects recursively\r\n\t * @param mixed input\r\n\t * @param mixed extend\r\n\t * @return mixed\r\n\t */\r\n\r\n\tfunction merge_recursive(base, extend) {\r\n\r\n\t\tif (typeOf(base) !== 'object')\r\n\r\n\t\t\treturn extend;\r\n\r\n\t\tfor (var key in extend) {\r\n\r\n\t\t\tif (typeOf(base[key]) === 'object' && typeOf(extend[key]) === 'object') {\r\n\r\n\t\t\t\tbase[key] = merge_recursive(base[key], extend[key]);\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tbase[key] = extend[key];\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t\treturn base;\r\n\r\n\t}\r\n\r\n\t/**\r\n\t * Merge two or more objects\r\n\t * @param bool clone\r\n\t * @param bool recursive\r\n\t * @param array argv\r\n\t * @return object\r\n\t */\r\n\r\n\tfunction merge(clone, recursive, argv) {\r\n\r\n\t\tvar result = argv[0],\r\n\t\t\tsize = argv.length;\r\n\r\n\t\tif (clone || typeOf(result) !== 'object')\r\n\r\n\t\t\tresult = {};\r\n\r\n\t\tfor (var index=0;index<size;++index) {\r\n\r\n\t\t\tvar item = argv[index],\r\n\r\n\t\t\t\ttype = typeOf(item);\r\n\r\n\t\t\tif (type !== 'object') continue;\r\n\r\n\t\t\tfor (var key in item) {\r\n\r\n\t\t\t\tvar sitem = clone ? Public.clone(item[key]) : item[key];\r\n\r\n\t\t\t\tif (recursive) {\r\n\r\n\t\t\t\t\tresult[key] = merge_recursive(result[key], sitem);\r\n\r\n\t\t\t\t} else {\r\n\r\n\t\t\t\t\tresult[key] = sitem;\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t\treturn result;\r\n\r\n\t}\r\n\r\n\t/**\r\n\t * Get type of variable\r\n\t * @param mixed input\r\n\t * @return string\r\n\t *\r\n\t * @see http://jsperf.com/typeofvar\r\n\t */\r\n\r\n\tfunction typeOf(input) {\r\n\r\n\t\treturn ({}).toString.call(input).slice(8, -1).toLowerCase();\r\n\r\n\t}\r\n\r\n\tif (isNode) {\r\n\r\n\t\tmodule.exports = Public;\r\n\r\n\t} else {\r\n\r\n\t\twindow[publicName] = Public;\r\n\r\n\t}\r\n\r\n})(typeof module === 'object' && module && typeof module.exports === 'object' && module.exports);","/**\n # normalice\n\n Normalize an ice server configuration object (or plain old string) into a format\n that is usable in all browsers supporting WebRTC. Primarily this module is designed\n to help with the transition of the `url` attribute of the configuration object to\n the `urls` attribute.\n\n ## Example Usage\n\n <<< examples/simple.js\n\n**/\n\nvar protocols = [\n 'stun:',\n 'turn:'\n];\n\nmodule.exports = function(input) {\n var url = (input || {}).url || input;\n var protocol;\n var parts;\n var output = {};\n\n // if we don't have a string url, then allow the input to passthrough\n if (typeof url != 'string' && (! (url instanceof String))) {\n return input;\n }\n\n // trim the url string, and convert to an array\n url = url.trim();\n\n // if the protocol is not known, then passthrough\n protocol = protocols[protocols.indexOf(url.slice(0, 5))];\n if (! protocol) {\n return input;\n }\n\n // now let's attack the remaining url parts\n url = url.slice(5);\n parts = url.split('@');\n\n output.username = input.username;\n output.credential = input.credential;\n // if we have an authentication part, then set the credentials\n if (parts.length > 1) {\n url = parts[1];\n parts = parts[0].split(':');\n\n // add the output credential and username\n output.username = parts[0];\n output.credential = (input || {}).credential || parts[1] || '';\n }\n\n output.url = protocol + url;\n output.urls = [ output.url ];\n\n return output;\n};\n","var grammar = module.exports = {\n v: [{\n name: 'version',\n reg: /^(\\d*)$/\n }],\n o: [{ //o=- 20518 0 IN IP4 203.0.113.1\n // NB: sessionId will be a String in most cases because it is huge\n name: 'origin',\n reg: /^(\\S*) (\\d*) (\\d*) (\\S*) IP(\\d) (\\S*)/,\n names: ['username', 'sessionId', 'sessionVersion', 'netType', 'ipVer', 'address'],\n format: \"%s %s %d %s IP%d %s\"\n }],\n // default parsing of these only (though some of these feel outdated)\n s: [{ name: 'name' }],\n i: [{ name: 'description' }],\n u: [{ name: 'uri' }],\n e: [{ name: 'email' }],\n p: [{ name: 'phone' }],\n z: [{ name: 'timezones' }], // TODO: this one can actually be parsed properly..\n r: [{ name: 'repeats' }], // TODO: this one can also be parsed properly\n //k: [{}], // outdated thing ignored\n t: [{ //t=0 0\n name: 'timing',\n reg: /^(\\d*) (\\d*)/,\n names: ['start', 'stop'],\n format: \"%d %d\"\n }],\n c: [{ //c=IN IP4 10.47.197.26\n name: 'connection',\n reg: /^IN IP(\\d) (\\S*)/,\n names: ['version', 'ip'],\n format: \"IN IP%d %s\"\n }],\n b: [{ //b=AS:4000\n push: 'bandwidth',\n reg: /^(TIAS|AS|CT|RR|RS):(\\d*)/,\n names: ['type', 'limit'],\n format: \"%s:%s\"\n }],\n m: [{ //m=video 51744 RTP/AVP 126 97 98 34 31\n // NB: special - pushes to session\n // TODO: rtp/fmtp should be filtered by the payloads found here?\n reg: /^(\\w*) (\\d*) ([\\w\\/]*)(?: (.*))?/,\n names: ['type', 'port', 'protocol', 'payloads'],\n format: \"%s %d %s %s\"\n }],\n a: [\n { //a=rtpmap:110 opus/48000/2\n push: 'rtp',\n reg: /^rtpmap:(\\d*) ([\\w\\-]*)(?:\\s*\\/(\\d*)(?:\\s*\\/(\\S*))?)?/,\n names: ['payload', 'codec', 'rate', 'encoding'],\n format: function (o) {\n return (o.encoding) ?\n \"rtpmap:%d %s/%s/%s\":\n o.rate ?\n \"rtpmap:%d %s/%s\":\n \"rtpmap:%d %s\";\n }\n },\n {\n //a=fmtp:108 profile-level-id=24;object=23;bitrate=64000\n //a=fmtp:111 minptime=10; useinbandfec=1\n push: 'fmtp',\n reg: /^fmtp:(\\d*) ([\\S| ]*)/,\n names: ['payload', 'config'],\n format: \"fmtp:%d %s\"\n },\n { //a=control:streamid=0\n name: 'control',\n reg: /^control:(.*)/,\n format: \"control:%s\"\n },\n { //a=rtcp:65179 IN IP4 193.84.77.194\n name: 'rtcp',\n reg: /^rtcp:(\\d*)(?: (\\S*) IP(\\d) (\\S*))?/,\n names: ['port', 'netType', 'ipVer', 'address'],\n format: function (o) {\n return (o.address != null) ?\n \"rtcp:%d %s IP%d %s\":\n \"rtcp:%d\";\n }\n },\n { //a=rtcp-fb:98 trr-int 100\n push: 'rtcpFbTrrInt',\n reg: /^rtcp-fb:(\\*|\\d*) trr-int (\\d*)/,\n names: ['payload', 'value'],\n format: \"rtcp-fb:%d trr-int %d\"\n },\n { //a=rtcp-fb:98 nack rpsi\n push: 'rtcpFb',\n reg: /^rtcp-fb:(\\*|\\d*) ([\\w-_]*)(?: ([\\w-_]*))?/,\n names: ['payload', 'type', 'subtype'],\n format: function (o) {\n return (o.subtype != null) ?\n \"rtcp-fb:%s %s %s\":\n \"rtcp-fb:%s %s\";\n }\n },\n { //a=extmap:2 urn:ietf:params:rtp-hdrext:toffset\n //a=extmap:1/recvonly URI-gps-string\n push: 'ext',\n reg: /^extmap:([\\w_\\/]*) (\\S*)(?: (\\S*))?/,\n names: ['value', 'uri', 'config'], // value may include \"/direction\" suffix\n format: function (o) {\n return (o.config != null) ?\n \"extmap:%s %s %s\":\n \"extmap:%s %s\";\n }\n },\n {\n //a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR|2^20|1:32\n push: 'crypto',\n reg: /^crypto:(\\d*) ([\\w_]*) (\\S*)(?: (\\S*))?/,\n names: ['id', 'suite', 'config', 'sessionConfig'],\n format: function (o) {\n return (o.sessionConfig != null) ?\n \"crypto:%d %s %s %s\":\n \"crypto:%d %s %s\";\n }\n },\n { //a=setup:actpass\n name: 'setup',\n reg: /^setup:(\\w*)/,\n format: \"setup:%s\"\n },\n { //a=mid:1\n name: 'mid',\n reg: /^mid:([^\\s]*)/,\n format: \"mid:%s\"\n },\n { //a=msid:0c8b064d-d807-43b4-b434-f92a889d8587 98178685-d409-46e0-8e16-7ef0db0db64a\n name: 'msid',\n reg: /^msid:(.*)/,\n format: \"msid:%s\"\n },\n { //a=ptime:20\n name: 'ptime',\n reg: /^ptime:(\\d*)/,\n format: \"ptime:%d\"\n },\n { //a=maxptime:60\n name: 'maxptime',\n reg: /^maxptime:(\\d*)/,\n format: \"maxptime:%d\"\n },\n { //a=sendrecv\n name: 'direction',\n reg: /^(sendrecv|recvonly|sendonly|inactive)/\n },\n { //a=ice-lite\n name: 'icelite',\n reg: /^(ice-lite)/\n },\n { //a=ice-ufrag:F7gI\n name: 'iceUfrag',\n reg: /^ice-ufrag:(\\S*)/,\n format: \"ice-ufrag:%s\"\n },\n { //a=ice-pwd:x9cml/YzichV2+XlhiMu8g\n name: 'icePwd',\n reg: /^ice-pwd:(\\S*)/,\n format: \"ice-pwd:%s\"\n },\n { //a=fingerprint:SHA-1 00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33\n name: 'fingerprint',\n reg: /^fingerprint:(\\S*) (\\S*)/,\n names: ['type', 'hash'],\n format: \"fingerprint:%s %s\"\n },\n {\n //a=candidate:0 1 UDP 2113667327 203.0.113.1 54400 typ host\n //a=candidate:1162875081 1 udp 2113937151 192.168.34.75 60017 typ host generation 0\n //a=candidate:3289912957 2 udp 1845501695 193.84.77.194 60017 typ srflx raddr 192.168.34.75 rport 60017 generation 0\n //a=candidate:229815620 1 tcp 1518280447 192.168.150.19 60017 typ host tcptype active generation 0\n //a=candidate:3289912957 2 tcp 1845501695 193.84.77.194 60017 typ srflx raddr 192.168.34.75 rport 60017 tcptype passive generation 0\n push:'candidates',\n reg: /^candidate:(\\S*) (\\d*) (\\S*) (\\d*) (\\S*) (\\d*) typ (\\S*)(?: raddr (\\S*) rport (\\d*))?(?: tcptype (\\S*))?(?: generation (\\d*))?/,\n names: ['foundation', 'component', 'transport', 'priority', 'ip', 'port', 'type', 'raddr', 'rport', 'tcptype', 'generation'],\n format: function (o) {\n var str = \"candidate:%s %d %s %d %s %d typ %s\";\n\n str += (o.raddr != null) ? \" raddr %s rport %d\" : \"%v%v\";\n\n // NB: candidate has three optional chunks, so %void middles one if it's missing\n str += (o.tcptype != null) ? \" tcptype %s\" : \"%v\";\n\n if (o.generation != null) {\n str += \" generation %d\";\n }\n return str;\n }\n },\n { //a=end-of-candidates (keep after the candidates line for readability)\n name: 'endOfCandidates',\n reg: /^(end-of-candidates)/\n },\n { //a=remote-candidates:1 203.0.113.1 54400 2 203.0.113.1 54401 ...\n name: 'remoteCandidates',\n reg: /^remote-candidates:(.*)/,\n format: \"remote-candidates:%s\"\n },\n { //a=ice-options:google-ice\n name: 'iceOptions',\n reg: /^ice-options:(\\S*)/,\n format: \"ice-options:%s\"\n },\n { //a=ssrc:2566107569 cname:t9YU8M1UxTF8Y1A1\n push: \"ssrcs\",\n reg: /^ssrc:(\\d*) ([\\w_]*):(.*)/,\n names: ['id', 'attribute', 'value'],\n format: \"ssrc:%d %s:%s\"\n },\n { //a=ssrc-group:FEC 1 2\n push: \"ssrcGroups\",\n reg: /^ssrc-group:(\\w*) (.*)/,\n names: ['semantics', 'ssrcs'],\n format: \"ssrc-group:%s %s\"\n },\n { //a=msid-semantic: WMS Jvlam5X3SX1OP6pn20zWogvaKJz5Hjf9OnlV\n name: \"msidSemantic\",\n reg: /^msid-semantic:\\s?(\\w*) (\\S*)/,\n names: ['semantic', 'token'],\n format: \"msid-semantic: %s %s\" // space after \":\" is not accidental\n },\n { //a=group:BUNDLE audio video\n push: 'groups',\n reg: /^group:(\\w*) (.*)/,\n names: ['type', 'mids'],\n format: \"group:%s %s\"\n },\n { //a=rtcp-mux\n name: 'rtcpMux',\n reg: /^(rtcp-mux)/\n },\n { //a=rtcp-rsize\n name: 'rtcpRsize',\n reg: /^(rtcp-rsize)/\n },\n { // any a= that we don't understand is kepts verbatim on media.invalid\n push: 'invalid',\n names: [\"value\"]\n }\n ]\n};\n\n// set sensible defaults to avoid polluting the grammar with boring details\nObject.keys(grammar).forEach(function (key) {\n var objs = grammar[key];\n objs.forEach(function (obj) {\n if (!obj.reg) {\n obj.reg = /(.*)/;\n }\n if (!obj.format) {\n obj.format = \"%s\";\n }\n });\n});\n","var parser = require('./parser');\nvar writer = require('./writer');\n\nexports.write = writer;\nexports.parse = parser.parse;\nexports.parseFmtpConfig = parser.parseFmtpConfig;\nexports.parsePayloads = parser.parsePayloads;\nexports.parseRemoteCandidates = parser.parseRemoteCandidates;\n","var toIntIfInt = function (v) {\n return String(Number(v)) === v ? Number(v) : v;\n};\n\nvar attachProperties = function (match, location, names, rawName) {\n if (rawName && !names) {\n location[rawName] = toIntIfInt(match[1]);\n }\n else {\n for (var i = 0; i < names.length; i += 1) {\n if (match[i+1] != null) {\n location[names[i]] = toIntIfInt(match[i+1]);\n }\n }\n }\n};\n\nvar parseReg = function (obj, location, content) {\n var needsBlank = obj.name && obj.names;\n if (obj.push && !location[obj.push]) {\n location[obj.push] = [];\n }\n else if (needsBlank && !location[obj.name]) {\n location[obj.name] = {};\n }\n var keyLocation = obj.push ?\n {} : // blank object that will be pushed\n needsBlank ? location[obj.name] : location; // otherwise, named location or root\n\n attachProperties(content.match(obj.reg), keyLocation, obj.names, obj.name);\n\n if (obj.push) {\n location[obj.push].push(keyLocation);\n }\n};\n\nvar grammar = require('./grammar');\nvar validLine = RegExp.prototype.test.bind(/^([a-z])=(.*)/);\n\nexports.parse = function (sdp) {\n var session = {}\n , media = []\n , location = session; // points at where properties go under (one of the above)\n\n // parse lines we understand\n sdp.split(/(\\r\\n|\\r|\\n)/).filter(validLine).forEach(function (l) {\n var type = l[0];\n var content = l.slice(2);\n if (type === 'm') {\n media.push({rtp: [], fmtp: []});\n location = media[media.length-1]; // point at latest media line\n }\n\n for (var j = 0; j < (grammar[type] || []).length; j += 1) {\n var obj = grammar[type][j];\n if (obj.reg.test(content)) {\n return parseReg(obj, location, content);\n }\n }\n });\n\n session.media = media; // link it up\n return session;\n};\n\nvar fmtpReducer = function (acc, expr) {\n var s = expr.split('=');\n if (s.length === 2) {\n acc[s[0]] = toIntIfInt(s[1]);\n }\n return acc;\n};\n\nexports.parseFmtpConfig = function (str) {\n return str.split(/\\;\\s?/).reduce(fmtpReducer, {});\n};\n\nexports.parsePayloads = function (str) {\n return str.split(' ').map(Number);\n};\n\nexports.parseRemoteCandidates = function (str) {\n var candidates = [];\n var parts = str.split(' ').map(toIntIfInt);\n for (var i = 0; i < parts.length; i += 3) {\n candidates.push({\n component: parts[i],\n ip: parts[i + 1],\n port: parts[i + 2]\n });\n }\n return candidates;\n};\n","var grammar = require('./grammar');\n\n// customized util.format - discards excess arguments and can void middle ones\nvar formatRegExp = /%[sdv%]/g;\nvar format = function (formatStr) {\n var i = 1;\n var args = arguments;\n var len = args.length;\n return formatStr.replace(formatRegExp, function (x) {\n if (i >= len) {\n return x; // missing argument\n }\n var arg = args[i];\n i += 1;\n switch (x) {\n case '%%':\n return '%';\n case '%s':\n return String(arg);\n case '%d':\n return Number(arg);\n case '%v':\n return '';\n }\n });\n // NB: we discard excess arguments - they are typically undefined from makeLine\n};\n\nvar makeLine = function (type, obj, location) {\n var str = obj.format instanceof Function ?\n (obj.format(obj.push ? location : location[obj.name])) :\n obj.format;\n\n var args = [type + '=' + str];\n if (obj.names) {\n for (var i = 0; i < obj.names.length; i += 1) {\n var n = obj.names[i];\n if (obj.name) {\n args.push(location[obj.name][n]);\n }\n else { // for mLine and push attributes\n args.push(location[obj.names[i]]);\n }\n }\n }\n else {\n args.push(location[obj.name]);\n }\n return format.apply(null, args);\n};\n\n// RFC specified order\n// TODO: extend this with all the rest\nvar defaultOuterOrder = [\n 'v', 'o', 's', 'i',\n 'u', 'e', 'p', 'c',\n 'b', 't', 'r', 'z', 'a'\n];\nvar defaultInnerOrder = ['i', 'c', 'b', 'a'];\n\n\nmodule.exports = function (session, opts) {\n opts = opts || {};\n // ensure certain properties exist\n if (session.version == null) {\n session.version = 0; // \"v=0\" must be there (only defined version atm)\n }\n if (session.name == null) {\n session.name = \" \"; // \"s= \" must be there if no meaningful name set\n }\n session.media.forEach(function (mLine) {\n if (mLine.payloads == null) {\n mLine.payloads = \"\";\n }\n });\n\n var outerOrder = opts.outerOrder || defaultOuterOrder;\n var innerOrder = opts.innerOrder || defaultInnerOrder;\n var sdp = [];\n\n // loop through outerOrder for matching properties on session\n outerOrder.forEach(function (type) {\n grammar[type].forEach(function (obj) {\n if (obj.name in session && session[obj.name] != null) {\n sdp.push(makeLine(type, obj, session));\n }\n else if (obj.push in session && session[obj.push] != null) {\n session[obj.push].forEach(function (el) {\n sdp.push(makeLine(type, obj, el));\n });\n }\n });\n });\n\n // then for each media line, follow the innerOrder\n session.media.forEach(function (mLine) {\n sdp.push(makeLine('m', grammar.m[0], mLine));\n\n innerOrder.forEach(function (type) {\n grammar[type].forEach(function (obj) {\n if (obj.name in mLine && mLine[obj.name] != null) {\n sdp.push(makeLine(type, obj, mLine));\n }\n else if (obj.push in mLine && mLine[obj.push] != null) {\n mLine[obj.push].forEach(function (el) {\n sdp.push(makeLine(type, obj, el));\n });\n }\n });\n });\n });\n\n return sdp.join('\\r\\n') + '\\r\\n';\n};\n","/* Copyright @ 2015 Atlassian Pty Ltd\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nmodule.exports = function arrayEquals(array) {\n // if the other array is a falsy value, return\n if (!array)\n return false;\n\n // compare lengths - can save a lot of time\n if (this.length != array.length)\n return false;\n\n for (var i = 0, l = this.length; i < l; i++) {\n // Check if we have nested arrays\n if (this[i] instanceof Array && array[i] instanceof Array) {\n // recurse into the nested arrays\n if (!arrayEquals.apply(this[i], [array[i]]))\n return false;\n } else if (this[i] != array[i]) {\n // Warning - two different object instances will never be equal:\n // {x:20} != {x:20}\n return false;\n }\n }\n return true;\n};\n\n","/* Copyright @ 2015 Atlassian Pty Ltd\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexports.Interop = require('./interop');\n","/* Copyright @ 2015 Atlassian Pty Ltd\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/* global RTCSessionDescription */\n/* global RTCIceCandidate */\n/* jshint -W097 */\n\"use strict\";\n\nvar transform = require('./transform');\nvar arrayEquals = require('./array-equals');\n\nfunction Interop() {\n\n /**\n * This map holds the most recent Unified Plan offer/answer SDP that was\n * converted to Plan B, with the SDP type ('offer' or 'answer') as keys and\n * the SDP string as values.\n *\n * @type {{}}\n */\n this.cache = {\n mlB2UMap : {},\n mlU2BMap : {}\n };\n}\n\nmodule.exports = Interop;\n\n/**\n * Changes the candidate args to match with the related Unified Plan\n */\nInterop.prototype.candidateToUnifiedPlan = function(candidate) {\n var cand = new RTCIceCandidate(candidate);\n\n cand.sdpMLineIndex = this.cache.mlB2UMap[cand.sdpMLineIndex];\n /* TODO: change sdpMid to (audio|video)-SSRC */\n\n return cand;\n};\n\n/**\n * Changes the candidate args to match with the related Plan B\n */\nInterop.prototype.candidateToPlanB = function(candidate) {\n var cand = new RTCIceCandidate(candidate);\n\n if (cand.sdpMid.indexOf('audio') === 0) {\n cand.sdpMid = 'audio';\n } else if (cand.sdpMid.indexOf('video') === 0) {\n cand.sdpMid = 'video';\n } else {\n throw new Error('candidate with ' + cand.sdpMid + ' not allowed');\n }\n\n cand.sdpMLineIndex = this.cache.mlU2BMap[cand.sdpMLineIndex];\n\n return cand;\n};\n\n/**\n * Returns the index of the first m-line with the given media type and with a\n * direction which allows sending, in the last Unified Plan description with\n * type \"answer\" converted to Plan B. Returns {null} if there is no saved\n * answer, or if none of its m-lines with the given type allow sending.\n * @param type the media type (\"audio\" or \"video\").\n * @returns {*}\n */\nInterop.prototype.getFirstSendingIndexFromAnswer = function(type) {\n if (!this.cache.answer) {\n return null;\n }\n\n var session = transform.parse(this.cache.answer);\n if (session && session.media && Array.isArray(session.media)){\n for (var i = 0; i < session.media.length; i++) {\n if (session.media[i].type == type &&\n (!session.media[i].direction /* default to sendrecv */ ||\n session.media[i].direction === 'sendrecv' ||\n session.media[i].direction === 'sendonly')){\n return i;\n }\n }\n }\n\n return null;\n};\n\n/**\n * This method transforms a Unified Plan SDP to an equivalent Plan B SDP. A\n * PeerConnection wrapper transforms the SDP to Plan B before passing it to the\n * application.\n *\n * @param desc\n * @returns {*}\n */\nInterop.prototype.toPlanB = function(desc) {\n var self = this;\n //#region Preliminary input validation.\n\n if (typeof desc !== 'object' || desc === null ||\n typeof desc.sdp !== 'string') {\n console.warn('An empty description was passed as an argument.');\n return desc;\n }\n\n // Objectify the SDP for easier manipulation.\n var session = transform.parse(desc.sdp);\n\n // If the SDP contains no media, there's nothing to transform.\n if (typeof session.media === 'undefined' ||\n !Array.isArray(session.media) || session.media.length === 0) {\n console.warn('The description has no media.');\n return desc;\n }\n\n // Try some heuristics to \"make sure\" this is a Unified Plan SDP. Plan B\n // SDP has a video, an audio and a data \"channel\" at most.\n if (session.media.length <= 3 && session.media.every(function(m) {\n return ['video', 'audio', 'data'].indexOf(m.mid) !== -1;\n })) {\n console.warn('This description does not look like Unified Plan.');\n return desc;\n }\n\n //#endregion\n\n // HACK https://bugzilla.mozilla.org/show_bug.cgi?id=1113443\n var sdp = desc.sdp;\n var rewrite = false;\n for (var i = 0; i < session.media.length; i++) {\n var uLine = session.media[i];\n uLine.rtp.forEach(function(rtp) {\n if (rtp.codec === 'NULL')\n {\n rewrite = true;\n var offer = transform.parse(self.cache.offer);\n rtp.codec = offer.media[i].rtp[0].codec;\n }\n });\n }\n if (rewrite) {\n sdp = transform.write(session);\n }\n\n // Unified Plan SDP is our \"precious\". Cache it for later use in the Plan B\n // -> Unified Plan transformation.\n this.cache[desc.type] = sdp;\n\n //#region Convert from Unified Plan to Plan B.\n\n // We rebuild the session.media array.\n var media = session.media;\n session.media = [];\n\n // Associative array that maps channel types to channel objects for fast\n // access to channel objects by their type, e.g. type2bl['audio']->channel\n // obj.\n var type2bl = {};\n\n // Used to build the group:BUNDLE value after the channels construction\n // loop.\n var types = [];\n\n media.forEach(function(uLine) {\n // rtcp-mux is required in the Plan B SDP.\n if ((typeof uLine.rtcpMux !== 'string' ||\n uLine.rtcpMux !== 'rtcp-mux') &&\n uLine.direction !== 'inactive') {\n throw new Error('Cannot convert to Plan B because m-lines ' +\n 'without the rtcp-mux attribute were found.');\n }\n\n // If we don't have a channel for this uLine.type OR the selected is\n // inactive, then select this uLine as the channel basis.\n if (typeof type2bl[uLine.type] === 'undefined' ||\n type2bl[uLine.type].direction === 'inactive') {\n type2bl[uLine.type] = uLine;\n }\n\n if (uLine.protocol != type2bl[uLine.type].protocol) {\n throw new Error('Cannot convert to Plan B because m-lines ' +\n 'have different protocols and this library does not have ' +\n 'support for that');\n }\n\n if (uLine.payloads != type2bl[uLine.type].payloads) {\n throw new Error('Cannot convert to Plan B because m-lines ' +\n 'have different payloads and this library does not have ' +\n 'support for that');\n }\n\n });\n\n // Implode the Unified Plan m-lines/tracks into Plan B channels.\n media.forEach(function(uLine) {\n if (uLine.type === 'application') {\n session.media.push(uLine);\n types.push(uLine.mid);\n return;\n }\n\n // Add sources to the channel and handle a=msid.\n if (typeof uLine.sources === 'object') {\n Object.keys(uLine.sources).forEach(function(ssrc) {\n if (typeof type2bl[uLine.type].sources !== 'object')\n type2bl[uLine.type].sources = {};\n\n // Assign the sources to the channel.\n type2bl[uLine.type].sources[ssrc] =\n uLine.sources[ssrc];\n\n if (typeof uLine.msid !== 'undefined') {\n // In Plan B the msid is an SSRC attribute. Also, we don't\n // care about the obsolete label and mslabel attributes.\n //\n // Note that it is not guaranteed that the uLine will\n // have an msid. recvonly channels in particular don't have\n // one.\n type2bl[uLine.type].sources[ssrc].msid =\n uLine.msid;\n }\n // NOTE ssrcs in ssrc groups will share msids, as\n // draft-uberti-rtcweb-plan-00 mandates.\n });\n }\n\n // Add ssrc groups to the channel.\n if (typeof uLine.ssrcGroups !== 'undefined' &&\n Array.isArray(uLine.ssrcGroups)) {\n\n // Create the ssrcGroups array, if it's not defined.\n if (typeof type2bl[uLine.type].ssrcGroups === 'undefined' ||\n !Array.isArray(type2bl[uLine.type].ssrcGroups)) {\n type2bl[uLine.type].ssrcGroups = [];\n }\n\n type2bl[uLine.type].ssrcGroups =\n type2bl[uLine.type].ssrcGroups.concat(\n uLine.ssrcGroups);\n }\n\n if (type2bl[uLine.type] === uLine) {\n // Plan B mids are in ['audio', 'video', 'data']\n uLine.mid = uLine.type;\n\n // Plan B doesn't support/need the bundle-only attribute.\n delete uLine.bundleOnly;\n\n // In Plan B the msid is an SSRC attribute.\n delete uLine.msid;\n\n\t if (uLine.type == media[0].type) {\n\t types.unshift(uLine.type);\n\t // Add the channel to the new media array.\n\t session.media.unshift(uLine);\n\t } else {\n\t types.push(uLine.type);\n\t // Add the channel to the new media array.\n\t session.media.push(uLine);\n\t }\n }\n });\n\n if (typeof session.groups !== 'undefined') {\n // We regenerate the BUNDLE group with the new mids.\n session.groups.some(function(group) {\n\t if (group.type === 'BUNDLE') {\n\t group.mids = types.join(' ');\n\t return true;\n\t }\n });\n }\n\n // msid semantic\n session.msidSemantic = {\n semantic: 'WMS',\n token: '*'\n };\n\n var resStr = transform.write(session);\n\n return new RTCSessionDescription({\n type: desc.type,\n sdp: resStr\n });\n\n //#endregion\n};\n\n/* follow rules defined in RFC4145 */\nfunction addSetupAttr(uLine) {\n if (typeof uLine.setup === 'undefined') {\n return;\n }\n\n if (uLine.setup === \"active\") {\n uLine.setup = \"passive\";\n } else if (uLine.setup === \"passive\") {\n uLine.setup = \"active\";\n }\n}\n\n/**\n * This method transforms a Plan B SDP to an equivalent Unified Plan SDP. A\n * PeerConnection wrapper transforms the SDP to Unified Plan before passing it\n * to FF.\n *\n * @param desc\n * @returns {*}\n */\nInterop.prototype.toUnifiedPlan = function(desc) {\n var self = this;\n //#region Preliminary input validation.\n\n if (typeof desc !== 'object' || desc === null ||\n typeof desc.sdp !== 'string') {\n console.warn('An empty description was passed as an argument.');\n return desc;\n }\n\n var session = transform.parse(desc.sdp);\n\n // If the SDP contains no media, there's nothing to transform.\n if (typeof session.media === 'undefined' ||\n !Array.isArray(session.media) || session.media.length === 0) {\n console.warn('The description has no media.');\n return desc;\n }\n\n // Try some heuristics to \"make sure\" this is a Plan B SDP. Plan B SDP has\n // a video, an audio and a data \"channel\" at most.\n if (session.media.length > 3 || !session.media.every(function(m) {\n return ['video', 'audio', 'data'].indexOf(m.mid) !== -1;\n })) {\n console.warn('This description does not look like Plan B.');\n return desc;\n }\n\n // Make sure this Plan B SDP can be converted to a Unified Plan SDP.\n var mids = [];\n session.media.forEach(function(m) {\n mids.push(m.mid);\n });\n\n var hasBundle = false;\n if (typeof session.groups !== 'undefined' &&\n Array.isArray(session.groups)) {\n hasBundle = session.groups.every(function(g) {\n return g.type !== 'BUNDLE' ||\n arrayEquals.apply(g.mids.sort(), [mids.sort()]);\n });\n }\n\n if (!hasBundle) {\n var mustBeBundle = false;\n\n session.media.forEach(function(m) {\n if (m.direction !== 'inactive') {\n mustBeBundle = true;\n }\n });\n\n if (mustBeBundle) {\n throw new Error(\"Cannot convert to Unified Plan because m-lines that\" +\n \" are not bundled were found.\");\n }\n }\n\n //#endregion\n\n\n //#region Convert from Plan B to Unified Plan.\n\n // Unfortunately, a Plan B offer/answer doesn't have enough information to\n // rebuild an equivalent Unified Plan offer/answer.\n //\n // For example, if this is a local answer (in Unified Plan style) that we\n // convert to Plan B prior to handing it over to the application (the\n // PeerConnection wrapper called us, for instance, after a successful\n // createAnswer), we want to remember the m-line at which we've seen the\n // (local) SSRC. That's because when the application wants to do call the\n // SLD method, forcing us to do the inverse transformation (from Plan B to\n // Unified Plan), we need to know to which m-line to assign the (local)\n // SSRC. We also need to know all the other m-lines that the original\n // answer had and include them in the transformed answer as well.\n //\n // Another example is if this is a remote offer that we convert to Plan B\n // prior to giving it to the application, we want to remember the mid at\n // which we've seen the (remote) SSRC.\n //\n // In the iteration that follows, we use the cached Unified Plan (if it\n // exists) to assign mids to ssrcs.\n\n var type;\n if (desc.type === 'answer') {\n type = 'offer';\n } else if (desc.type === 'offer') {\n type = 'answer';\n } else {\n throw new Error(\"Type '\" + desc.type + \"' not supported.\");\n }\n\n var cached;\n if (typeof this.cache[type] !== 'undefined') {\n cached = transform.parse(this.cache[type]);\n }\n\n var recvonlySsrcs = {\n audio: {},\n video: {}\n };\n\n // A helper map that sends mids to m-line objects. We use it later to\n // rebuild the Unified Plan style session.media array.\n var mid2ul = {};\n var bIdx = 0;\n var uIdx = 0;\n\n var sources2ul = {};\n\n var candidates;\n var iceUfrag;\n var icePwd;\n var fingerprint;\n var payloads = {};\n var rtcpFb = {};\n var rtp = {};\n\n session.media.forEach(function(bLine) {\n if ((typeof bLine.rtcpMux !== 'string' ||\n bLine.rtcpMux !== 'rtcp-mux') &&\n bLine.direction !== 'inactive') {\n throw new Error(\"Cannot convert to Unified Plan because m-lines \" +\n \"without the rtcp-mux attribute were found.\");\n }\n\n if (bLine.type === 'application') {\n mid2ul[bLine.mid] = bLine;\n return;\n }\n\n // With rtcp-mux and bundle all the channels should have the same ICE\n // stuff.\n var sources = bLine.sources;\n var ssrcGroups = bLine.ssrcGroups;\n var port = bLine.port;\n\n /* Chrome adds different candidates even using bundle, so we concat the candidates list */\n if (typeof bLine.candidates != 'undefined') {\n if (typeof candidates != 'undefined') {\n candidates = candidates.concat(bLine.candidates);\n } else {\n candidates = bLine.candidates;\n }\n }\n\n if ((typeof iceUfrag != 'undefined') && (typeof bLine.iceUfrag != 'undefined') && (iceUfrag != bLine.iceUfrag)) {\n throw new Error(\"Only BUNDLE supported, iceUfrag must be the same for all m-lines.\\n\" +\n \"\\tLast iceUfrag: \" + iceUfrag + \"\\n\" +\n \"\\tNew iceUfrag: \" + bLine.iceUfrag\n );\n }\n\n if (typeof bLine.iceUfrag != 'undefined') {\n iceUfrag = bLine.iceUfrag;\n }\n\n if ((typeof icePwd != 'undefined') && (typeof bLine.icePwd != 'undefined') && (icePwd != bLine.icePwd)) {\n throw new Error(\"Only BUNDLE supported, icePwd must be the same for all m-lines.\\n\" +\n \"\\tLast icePwd: \" + icePwd + \"\\n\" +\n \"\\tNew icePwd: \" + bLine.icePwd\n );\n }\n\n if (typeof bLine.icePwd != 'undefined') {\n icePwd = bLine.icePwd;\n }\n\n if ((typeof fingerprint != 'undefined') && (typeof bLine.fingerprint != 'undefined') &&\n (fingerprint.type != bLine.fingerprint.type || fingerprint.hash != bLine.fingerprint.hash)) {\n throw new Error(\"Only BUNDLE supported, fingerprint must be the same for all m-lines.\\n\" +\n \"\\tLast fingerprint: \" + JSON.stringify(fingerprint) + \"\\n\" +\n \"\\tNew fingerprint: \" + JSON.stringify(bLine.fingerprint)\n );\n }\n\n if (typeof bLine.fingerprint != 'undefined') {\n fingerprint = bLine.fingerprint;\n }\n\n payloads[bLine.type] = bLine.payloads;\n rtcpFb[bLine.type] = bLine.rtcpFb;\n rtp[bLine.type] = bLine.rtp;\n\n // inverted ssrc group map\n var ssrc2group = {};\n if (typeof ssrcGroups !== 'undefined' && Array.isArray(ssrcGroups)) {\n ssrcGroups.forEach(function (ssrcGroup) {\n // XXX This might brake if an SSRC is in more than one group\n // for some reason.\n if (typeof ssrcGroup.ssrcs !== 'undefined' &&\n Array.isArray(ssrcGroup.ssrcs)) {\n ssrcGroup.ssrcs.forEach(function (ssrc) {\n if (typeof ssrc2group[ssrc] === 'undefined') {\n ssrc2group[ssrc] = [];\n }\n\n ssrc2group[ssrc].push(ssrcGroup);\n });\n }\n });\n }\n\n // ssrc to m-line index.\n var ssrc2ml = {};\n\n if (typeof sources === 'object') {\n\n // We'll use the \"bLine\" object as a prototype for each new \"mLine\"\n // that we create, but first we need to clean it up a bit.\n delete bLine.sources;\n delete bLine.ssrcGroups;\n delete bLine.candidates;\n delete bLine.iceUfrag;\n delete bLine.icePwd;\n delete bLine.fingerprint;\n delete bLine.port;\n delete bLine.mid;\n\n // Explode the Plan B channel sources with one m-line per source.\n Object.keys(sources).forEach(function(ssrc) {\n\n // The (unified) m-line for this SSRC. We either create it from\n // scratch or, if it's a grouped SSRC, we re-use a related\n // mline. In other words, if the source is grouped with another\n // source, put the two together in the same m-line.\n var uLine;\n\n // We assume here that we are the answerer in the O/A, so any\n // offers which we translate come from the remote side, while\n // answers are local. So the check below is to make that we\n // handle receive-only SSRCs in a special way only if they come\n // from the remote side.\n if (desc.type==='offer') {\n // We want to detect SSRCs which are used by a remote peer\n // in an m-line with direction=recvonly (i.e. they are\n // being used for RTCP only).\n // This information would have gotten lost if the remote\n // peer used Unified Plan and their local description was\n // translated to Plan B. So we use the lack of an MSID\n // attribute to deduce a \"receive only\" SSRC.\n if (!sources[ssrc].msid) {\n recvonlySsrcs[bLine.type][ssrc] = sources[ssrc];\n // Receive-only SSRCs must not create new m-lines. We\n // will assign them to an existing m-line later.\n return;\n }\n }\n\n if (typeof ssrc2group[ssrc] !== 'undefined' &&\n Array.isArray(ssrc2group[ssrc])) {\n ssrc2group[ssrc].some(function (ssrcGroup) {\n // ssrcGroup.ssrcs *is* an Array, no need to check\n // again here.\n return ssrcGroup.ssrcs.some(function (related) {\n if (typeof ssrc2ml[related] === 'object') {\n uLine = ssrc2ml[related];\n return true;\n }\n });\n });\n }\n\n if (typeof uLine === 'object') {\n // the m-line already exists. Just add the source.\n uLine.sources[ssrc] = sources[ssrc];\n delete sources[ssrc].msid;\n } else {\n // Use the \"bLine\" as a prototype for the \"uLine\".\n uLine = Object.create(bLine);\n ssrc2ml[ssrc] = uLine;\n\n if (typeof sources[ssrc].msid !== 'undefined') {\n // Assign the msid of the source to the m-line. Note\n // that it is not guaranteed that the source will have\n // msid. In particular \"recvonly\" sources don't have an\n // msid. Note that \"recvonly\" is a term only defined\n // for m-lines.\n uLine.msid = sources[ssrc].msid;\n delete sources[ssrc].msid;\n }\n\n // We assign one SSRC per media line.\n uLine.sources = {};\n uLine.sources[ssrc] = sources[ssrc];\n uLine.ssrcGroups = ssrc2group[ssrc];\n\n // Use the cached Unified Plan SDP (if it exists) to assign\n // SSRCs to mids.\n if (typeof cached !== 'undefined' &&\n typeof cached.media !== 'undefined' &&\n Array.isArray(cached.media)) {\n\n cached.media.forEach(function (m) {\n if (typeof m.sources === 'object') {\n Object.keys(m.sources).forEach(function (s) {\n if (s === ssrc) {\n uLine.mid = m.mid;\n }\n });\n }\n });\n }\n\n if (typeof uLine.mid === 'undefined') {\n\n // If this is an SSRC that we see for the first time\n // assign it a new mid. This is typically the case when\n // this method is called to transform a remote\n // description for the first time or when there is a\n // new SSRC in the remote description because a new\n // peer has joined the conference. Local SSRCs should\n // have already been added to the map in the toPlanB\n // method.\n //\n // Because FF generates answers in Unified Plan style,\n // we MUST already have a cached answer with all the\n // local SSRCs mapped to some m-line/mid.\n\n uLine.mid = [bLine.type, '-', ssrc].join('');\n }\n\n // Include the candidates in the 1st media line.\n uLine.candidates = candidates;\n uLine.iceUfrag = iceUfrag;\n uLine.icePwd = icePwd;\n uLine.fingerprint = fingerprint;\n uLine.port = port;\n\n mid2ul[uLine.mid] = uLine;\n sources2ul[uIdx] = uLine.sources;\n\n self.cache.mlU2BMap[uIdx] = bIdx;\n if (typeof self.cache.mlB2UMap[bIdx] === 'undefined') {\n self.cache.mlB2UMap[bIdx] = uIdx;\n }\n uIdx++;\n }\n });\n } else {\n var uLine = bLine;\n\n uLine.candidates = candidates;\n uLine.iceUfrag = iceUfrag;\n uLine.icePwd = icePwd;\n uLine.fingerprint = fingerprint;\n uLine.port = port;\n\n mid2ul[uLine.mid] = uLine;\n\n self.cache.mlU2BMap[uIdx] = bIdx;\n if (typeof self.cache.mlB2UMap[bIdx] === 'undefined') {\n self.cache.mlB2UMap[bIdx] = uIdx;\n }\n }\n\n bIdx++;\n });\n\n // Rebuild the media array in the right order and add the missing mLines\n // (missing from the Plan B SDP).\n session.media = [];\n mids = []; // reuse\n\n if (desc.type === 'answer') {\n\n // The media lines in the answer must match the media lines in the\n // offer. The order is important too. Here we assume that Firefox is\n // the answerer, so we merely have to use the reconstructed (unified)\n // answer to update the cached (unified) answer accordingly.\n //\n // In the general case, one would have to use the cached (unified)\n // offer to find the m-lines that are missing from the reconstructed\n // answer, potentially grabbing them from the cached (unified) answer.\n // One has to be careful with this approach because inactive m-lines do\n // not always have an mid, making it tricky (impossible?) to find where\n // exactly and which m-lines are missing from the reconstructed answer.\n\n for (var i = 0; i < cached.media.length; i++) {\n var uLine = cached.media[i];\n\n delete uLine.msid;\n delete uLine.sources;\n delete uLine.ssrcGroups;\n\n if (typeof sources2ul[i] === 'undefined') {\n if (!uLine.direction\n || uLine.direction === 'sendrecv')\n uLine.direction = 'recvonly';\n else if (uLine.direction === 'sendonly')\n uLine.direction = 'inactive';\n } else {\n if (!uLine.direction\n || uLine.direction === 'sendrecv')\n uLine.direction = 'sendrecv';\n else if (uLine.direction === 'recvonly')\n uLine.direction = 'sendonly';\n }\n\n uLine.sources = sources2ul[i];\n uLine.candidates = candidates;\n uLine.iceUfrag = iceUfrag;\n uLine.icePwd = icePwd;\n uLine.fingerprint = fingerprint;\n\n uLine.rtp = rtp[uLine.type];\n uLine.payloads = payloads[uLine.type];\n uLine.rtcpFb = rtcpFb[uLine.type];\n\n session.media.push(uLine);\n\n if (typeof uLine.mid === 'string') {\n // inactive lines don't/may not have an mid.\n mids.push(uLine.mid);\n }\n }\n } else {\n\n // SDP offer/answer (and the JSEP spec) forbids removing an m-section\n // under any circumstances. If we are no longer interested in sending a\n // track, we just remove the msid and ssrc attributes and set it to\n // either a=recvonly (as the reofferer, we must use recvonly if the\n // other side was previously sending on the m-section, but we can also\n // leave the possibility open if it wasn't previously in use), or\n // a=inactive.\n\n if (typeof cached !== 'undefined' &&\n typeof cached.media !== 'undefined' &&\n Array.isArray(cached.media)) {\n cached.media.forEach(function(uLine) {\n mids.push(uLine.mid);\n if (typeof mid2ul[uLine.mid] !== 'undefined') {\n session.media.push(mid2ul[uLine.mid]);\n } else {\n delete uLine.msid;\n delete uLine.sources;\n delete uLine.ssrcGroups;\n\n if (!uLine.direction\n || uLine.direction === 'sendrecv') {\n uLine.direction = 'sendonly';\n }\n if (!uLine.direction\n || uLine.direction === 'recvonly') {\n uLine.direction = 'inactive';\n }\n\n addSetupAttr (uLine);\n session.media.push(uLine);\n }\n });\n }\n\n // Add all the remaining (new) m-lines of the transformed SDP.\n Object.keys(mid2ul).forEach(function(mid) {\n if (mids.indexOf(mid) === -1) {\n mids.push(mid);\n if (mid2ul[mid].direction === 'recvonly') {\n // This is a remote recvonly channel. Add its SSRC to the\n // appropriate sendrecv or sendonly channel.\n // TODO(gp) what if we don't have sendrecv/sendonly\n // channel?\n\n var done = false;\n\n session.media.some(function (uLine) {\n if ((uLine.direction === 'sendrecv' ||\n uLine.direction === 'sendonly') &&\n uLine.type === mid2ul[mid].type) {\n // mid2ul[mid] shouldn't have any ssrc-groups\n Object.keys(mid2ul[mid].sources).forEach(\n function (ssrc) {\n uLine.sources[ssrc] =\n mid2ul[mid].sources[ssrc];\n });\n\n done = true;\n return true;\n }\n });\n\n if (!done) {\n session.media.push(mid2ul[mid]);\n }\n } else {\n session.media.push(mid2ul[mid]);\n }\n }\n });\n }\n\n // After we have constructed the Plan Unified m-lines we can figure out\n // where (in which m-line) to place the 'recvonly SSRCs'.\n // Note: we assume here that we are the answerer in the O/A, so any offers\n // which we translate come from the remote side, while answers are local\n // (and so our last local description is cached as an 'answer').\n [\"audio\", \"video\"].forEach(function (type) {\n if (!session || !session.media || !Array.isArray(session.media))\n return;\n\n var idx = null;\n if (Object.keys(recvonlySsrcs[type]).length > 0) {\n idx = self.getFirstSendingIndexFromAnswer(type);\n if (idx === null){\n // If this is the first offer we receive, we don't have a\n // cached answer. Assume that we will be sending media using\n // the first m-line for each media type.\n\n for (var i = 0; i < session.media.length; i++) {\n if (session.media[i].type === type) {\n idx = i;\n break;\n }\n }\n }\n }\n\n if (idx && session.media.length > idx) {\n var mLine = session.media[idx];\n Object.keys(recvonlySsrcs[type]).forEach(function(ssrc) {\n if (mLine.sources && mLine.sources[ssrc]) {\n console.warn(\"Replacing an existing SSRC.\");\n }\n if (!mLine.sources) {\n mLine.sources = {};\n }\n\n mLine.sources[ssrc] = recvonlySsrcs[type][ssrc];\n });\n }\n });\n\n if (typeof session.groups !== 'undefined') {\n // We regenerate the BUNDLE group (since we regenerated the mids)\n session.groups.some(function(group) {\n\t if (group.type === 'BUNDLE') {\n\t group.mids = mids.join(' ');\n\t return true;\n\t }\n });\n }\n\n // msid semantic\n session.msidSemantic = {\n semantic: 'WMS',\n token: '*'\n };\n\n var resStr = transform.write(session);\n\n // Cache the transformed SDP (Unified Plan) for later re-use in this\n // function.\n this.cache[desc.type] = resStr;\n\n return new RTCSessionDescription({\n type: desc.type,\n sdp: resStr\n });\n\n //#endregion\n};\n","/* Copyright @ 2015 Atlassian Pty Ltd\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nvar transform = require('sdp-transform');\n\nexports.write = function(session, opts) {\n\n if (typeof session !== 'undefined' &&\n typeof session.media !== 'undefined' &&\n Array.isArray(session.media)) {\n\n session.media.forEach(function (mLine) {\n // expand sources to ssrcs\n if (typeof mLine.sources !== 'undefined' &&\n Object.keys(mLine.sources).length !== 0) {\n mLine.ssrcs = [];\n Object.keys(mLine.sources).forEach(function (ssrc) {\n var source = mLine.sources[ssrc];\n Object.keys(source).forEach(function (attribute) {\n mLine.ssrcs.push({\n id: ssrc,\n attribute: attribute,\n value: source[attribute]\n });\n });\n });\n delete mLine.sources;\n }\n\n // join ssrcs in ssrc groups\n if (typeof mLine.ssrcGroups !== 'undefined' &&\n Array.isArray(mLine.ssrcGroups)) {\n mLine.ssrcGroups.forEach(function (ssrcGroup) {\n if (typeof ssrcGroup.ssrcs !== 'undefined' &&\n Array.isArray(ssrcGroup.ssrcs)) {\n ssrcGroup.ssrcs = ssrcGroup.ssrcs.join(' ');\n }\n });\n }\n });\n }\n\n // join group mids\n if (typeof session !== 'undefined' &&\n typeof session.groups !== 'undefined' && Array.isArray(session.groups)) {\n\n session.groups.forEach(function (g) {\n if (typeof g.mids !== 'undefined' && Array.isArray(g.mids)) {\n g.mids = g.mids.join(' ');\n }\n });\n }\n\n return transform.write(session, opts);\n};\n\nexports.parse = function(sdp) {\n var session = transform.parse(sdp);\n\n if (typeof session !== 'undefined' && typeof session.media !== 'undefined' &&\n Array.isArray(session.media)) {\n\n session.media.forEach(function (mLine) {\n // group sources attributes by ssrc\n if (typeof mLine.ssrcs !== 'undefined' && Array.isArray(mLine.ssrcs)) {\n mLine.sources = {};\n mLine.ssrcs.forEach(function (ssrc) {\n if (!mLine.sources[ssrc.id])\n mLine.sources[ssrc.id] = {};\n mLine.sources[ssrc.id][ssrc.attribute] = ssrc.value;\n });\n\n delete mLine.ssrcs;\n }\n\n // split ssrcs in ssrc groups\n if (typeof mLine.ssrcGroups !== 'undefined' &&\n Array.isArray(mLine.ssrcGroups)) {\n mLine.ssrcGroups.forEach(function (ssrcGroup) {\n if (typeof ssrcGroup.ssrcs === 'string') {\n ssrcGroup.ssrcs = ssrcGroup.ssrcs.split(' ');\n }\n });\n }\n });\n }\n // split group mids\n if (typeof session !== 'undefined' &&\n typeof session.groups !== 'undefined' && Array.isArray(session.groups)) {\n\n session.groups.forEach(function (g) {\n if (typeof g.mids === 'string') {\n g.mids = g.mids.split(' ');\n }\n });\n }\n\n return session;\n};\n\n","/**\n * UAParser.js v0.7.17\n * Lightweight JavaScript-based User-Agent string parser\n * https://github.com/faisalman/ua-parser-js\n *\n * Copyright © 2012-2016 Faisal Salman <fyzlman@gmail.com>\n * Dual licensed under GPLv2 & MIT\n */\n\n(function (window, undefined) {\n\n 'use strict';\n\n //////////////\n // Constants\n /////////////\n\n\n var LIBVERSION = '0.7.17',\n EMPTY = '',\n UNKNOWN = '?',\n FUNC_TYPE = 'function',\n UNDEF_TYPE = 'undefined',\n OBJ_TYPE = 'object',\n STR_TYPE = 'string',\n MAJOR = 'major', // deprecated\n MODEL = 'model',\n NAME = 'name',\n TYPE = 'type',\n VENDOR = 'vendor',\n VERSION = 'version',\n ARCHITECTURE= 'architecture',\n CONSOLE = 'console',\n MOBILE = 'mobile',\n TABLET = 'tablet',\n SMARTTV = 'smarttv',\n WEARABLE = 'wearable',\n EMBEDDED = 'embedded';\n\n\n ///////////\n // Helper\n //////////\n\n\n var util = {\n extend : function (regexes, extensions) {\n var margedRegexes = {};\n for (var i in regexes) {\n if (extensions[i] && extensions[i].length % 2 === 0) {\n margedRegexes[i] = extensions[i].concat(regexes[i]);\n } else {\n margedRegexes[i] = regexes[i];\n }\n }\n return margedRegexes;\n },\n has : function (str1, str2) {\n if (typeof str1 === \"string\") {\n return str2.toLowerCase().indexOf(str1.toLowerCase()) !== -1;\n } else {\n return false;\n }\n },\n lowerize : function (str) {\n return str.toLowerCase();\n },\n major : function (version) {\n return typeof(version) === STR_TYPE ? version.replace(/[^\\d\\.]/g,'').split(\".\")[0] : undefined;\n },\n trim : function (str) {\n return str.replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g, '');\n }\n };\n\n\n ///////////////\n // Map helper\n //////////////\n\n\n var mapper = {\n\n rgx : function (ua, arrays) {\n\n //var result = {},\n var i = 0, j, k, p, q, matches, match;//, args = arguments;\n\n /*// construct object barebones\n for (p = 0; p < args[1].length; p++) {\n q = args[1][p];\n result[typeof q === OBJ_TYPE ? q[0] : q] = undefined;\n }*/\n\n // loop through all regexes maps\n while (i < arrays.length && !matches) {\n\n var regex = arrays[i], // even sequence (0,2,4,..)\n props = arrays[i + 1]; // odd sequence (1,3,5,..)\n j = k = 0;\n\n // try matching uastring with regexes\n while (j < regex.length && !matches) {\n\n matches = regex[j++].exec(ua);\n\n if (!!matches) {\n for (p = 0; p < props.length; p++) {\n match = matches[++k];\n q = props[p];\n // check if given property is actually array\n if (typeof q === OBJ_TYPE && q.length > 0) {\n if (q.length == 2) {\n if (typeof q[1] == FUNC_TYPE) {\n // assign modified match\n this[q[0]] = q[1].call(this, match);\n } else {\n // assign given value, ignore regex match\n this[q[0]] = q[1];\n }\n } else if (q.length == 3) {\n // check whether function or regex\n if (typeof q[1] === FUNC_TYPE && !(q[1].exec && q[1].test)) {\n // call function (usually string mapper)\n this[q[0]] = match ? q[1].call(this, match, q[2]) : undefined;\n } else {\n // sanitize match using given regex\n this[q[0]] = match ? match.replace(q[1], q[2]) : undefined;\n }\n } else if (q.length == 4) {\n this[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined;\n }\n } else {\n this[q] = match ? match : undefined;\n }\n }\n }\n }\n i += 2;\n }\n // console.log(this);\n //return this;\n },\n\n str : function (str, map) {\n\n for (var i in map) {\n // check if array\n if (typeof map[i] === OBJ_TYPE && map[i].length > 0) {\n for (var j = 0; j < map[i].length; j++) {\n if (util.has(map[i][j], str)) {\n return (i === UNKNOWN) ? undefined : i;\n }\n }\n } else if (util.has(map[i], str)) {\n return (i === UNKNOWN) ? undefined : i;\n }\n }\n return str;\n }\n };\n\n\n ///////////////\n // String map\n //////////////\n\n\n var maps = {\n\n browser : {\n oldsafari : {\n version : {\n '1.0' : '/8',\n '1.2' : '/1',\n '1.3' : '/3',\n '2.0' : '/412',\n '2.0.2' : '/416',\n '2.0.3' : '/417',\n '2.0.4' : '/419',\n '?' : '/'\n }\n }\n },\n\n device : {\n amazon : {\n model : {\n 'Fire Phone' : ['SD', 'KF']\n }\n },\n sprint : {\n model : {\n 'Evo Shift 4G' : '7373KT'\n },\n vendor : {\n 'HTC' : 'APA',\n 'Sprint' : 'Sprint'\n }\n }\n },\n\n os : {\n windows : {\n version : {\n 'ME' : '4.90',\n 'NT 3.11' : 'NT3.51',\n 'NT 4.0' : 'NT4.0',\n '2000' : 'NT 5.0',\n 'XP' : ['NT 5.1', 'NT 5.2'],\n 'Vista' : 'NT 6.0',\n '7' : 'NT 6.1',\n '8' : 'NT 6.2',\n '8.1' : 'NT 6.3',\n '10' : ['NT 6.4', 'NT 10.0'],\n 'RT' : 'ARM'\n }\n }\n }\n };\n\n\n //////////////\n // Regex map\n /////////////\n\n\n var regexes = {\n\n browser : [[\n\n // Presto based\n /(opera\\smini)\\/([\\w\\.-]+)/i, // Opera Mini\n /(opera\\s[mobiletab]+).+version\\/([\\w\\.-]+)/i, // Opera Mobi/Tablet\n /(opera).+version\\/([\\w\\.]+)/i, // Opera > 9.80\n /(opera)[\\/\\s]+([\\w\\.]+)/i // Opera < 9.80\n ], [NAME, VERSION], [\n\n /(opios)[\\/\\s]+([\\w\\.]+)/i // Opera mini on iphone >= 8.0\n ], [[NAME, 'Opera Mini'], VERSION], [\n\n /\\s(opr)\\/([\\w\\.]+)/i // Opera Webkit\n ], [[NAME, 'Opera'], VERSION], [\n\n // Mixed\n /(kindle)\\/([\\w\\.]+)/i, // Kindle\n /(lunascape|maxthon|netfront|jasmine|blazer)[\\/\\s]?([\\w\\.]+)*/i,\n // Lunascape/Maxthon/Netfront/Jasmine/Blazer\n\n // Trident based\n /(avant\\s|iemobile|slim|baidu)(?:browser)?[\\/\\s]?([\\w\\.]*)/i,\n // Avant/IEMobile/SlimBrowser/Baidu\n /(?:ms|\\()(ie)\\s([\\w\\.]+)/i, // Internet Explorer\n\n // Webkit/KHTML based\n /(rekonq)\\/([\\w\\.]+)*/i, // Rekonq\n /(chromium|flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser)\\/([\\w\\.-]+)/i\n // Chromium/Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser\n ], [NAME, VERSION], [\n\n /(trident).+rv[:\\s]([\\w\\.]+).+like\\sgecko/i // IE11\n ], [[NAME, 'IE'], VERSION], [\n\n /(edge)\\/((\\d+)?[\\w\\.]+)/i // Microsoft Edge\n ], [NAME, VERSION], [\n\n /(yabrowser)\\/([\\w\\.]+)/i // Yandex\n ], [[NAME, 'Yandex'], VERSION], [\n\n /(puffin)\\/([\\w\\.]+)/i // Puffin\n ], [[NAME, 'Puffin'], VERSION], [\n\n /((?:[\\s\\/])uc?\\s?browser|(?:juc.+)ucweb)[\\/\\s]?([\\w\\.]+)/i\n // UCBrowser\n ], [[NAME, 'UCBrowser'], VERSION], [\n\n /(comodo_dragon)\\/([\\w\\.]+)/i // Comodo Dragon\n ], [[NAME, /_/g, ' '], VERSION], [\n\n /(micromessenger)\\/([\\w\\.]+)/i // WeChat\n ], [[NAME, 'WeChat'], VERSION], [\n\n /(QQ)\\/([\\d\\.]+)/i // QQ, aka ShouQ\n ], [NAME, VERSION], [\n\n /m?(qqbrowser)[\\/\\s]?([\\w\\.]+)/i // QQBrowser\n ], [NAME, VERSION], [\n\n /xiaomi\\/miuibrowser\\/([\\w\\.]+)/i // MIUI Browser\n ], [VERSION, [NAME, 'MIUI Browser']], [\n\n /;fbav\\/([\\w\\.]+);/i // Facebook App for iOS & Android\n ], [VERSION, [NAME, 'Facebook']], [\n\n /headlesschrome(?:\\/([\\w\\.]+)|\\s)/i // Chrome Headless\n ], [VERSION, [NAME, 'Chrome Headless']], [\n\n /\\swv\\).+(chrome)\\/([\\w\\.]+)/i // Chrome WebView\n ], [[NAME, /(.+)/, '$1 WebView'], VERSION], [\n\n /((?:oculus|samsung)browser)\\/([\\w\\.]+)/i\n ], [[NAME, /(.+(?:g|us))(.+)/, '$1 $2'], VERSION], [ // Oculus / Samsung Browser\n\n /android.+version\\/([\\w\\.]+)\\s+(?:mobile\\s?safari|safari)*/i // Android Browser\n ], [VERSION, [NAME, 'Android Browser']], [\n\n /(chrome|omniweb|arora|[tizenoka]{5}\\s?browser)\\/v?([\\w\\.]+)/i\n // Chrome/OmniWeb/Arora/Tizen/Nokia\n ], [NAME, VERSION], [\n\n /(dolfin)\\/([\\w\\.]+)/i // Dolphin\n ], [[NAME, 'Dolphin'], VERSION], [\n\n /((?:android.+)crmo|crios)\\/([\\w\\.]+)/i // Chrome for Android/iOS\n ], [[NAME, 'Chrome'], VERSION], [\n\n /(coast)\\/([\\w\\.]+)/i // Opera Coast\n ], [[NAME, 'Opera Coast'], VERSION], [\n\n /fxios\\/([\\w\\.-]+)/i // Firefox for iOS\n ], [VERSION, [NAME, 'Firefox']], [\n\n /version\\/([\\w\\.]+).+?mobile\\/\\w+\\s(safari)/i // Mobile Safari\n ], [VERSION, [NAME, 'Mobile Safari']], [\n\n /version\\/([\\w\\.]+).+?(mobile\\s?safari|safari)/i // Safari & Safari Mobile\n ], [VERSION, NAME], [\n\n /webkit.+?(gsa)\\/([\\w\\.]+).+?(mobile\\s?safari|safari)(\\/[\\w\\.]+)/i // Google Search Appliance on iOS\n ], [[NAME, 'GSA'], VERSION], [\n\n /webkit.+?(mobile\\s?safari|safari)(\\/[\\w\\.]+)/i // Safari < 3.0\n ], [NAME, [VERSION, mapper.str, maps.browser.oldsafari.version]], [\n\n /(konqueror)\\/([\\w\\.]+)/i, // Konqueror\n /(webkit|khtml)\\/([\\w\\.]+)/i\n ], [NAME, VERSION], [\n\n // Gecko based\n /(navigator|netscape)\\/([\\w\\.-]+)/i // Netscape\n ], [[NAME, 'Netscape'], VERSION], [\n /(swiftfox)/i, // Swiftfox\n /(icedragon|iceweasel|camino|chimera|fennec|maemo\\sbrowser|minimo|conkeror)[\\/\\s]?([\\w\\.\\+]+)/i,\n // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror\n /(firefox|seamonkey|k-meleon|icecat|iceape|firebird|phoenix)\\/([\\w\\.-]+)/i,\n // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix\n /(mozilla)\\/([\\w\\.]+).+rv\\:.+gecko\\/\\d+/i, // Mozilla\n\n // Other\n /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir)[\\/\\s]?([\\w\\.]+)/i,\n // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Sleipnir\n /(links)\\s\\(([\\w\\.]+)/i, // Links\n /(gobrowser)\\/?([\\w\\.]+)*/i, // GoBrowser\n /(ice\\s?browser)\\/v?([\\w\\._]+)/i, // ICE Browser\n /(mosaic)[\\/\\s]([\\w\\.]+)/i // Mosaic\n ], [NAME, VERSION]\n\n /* /////////////////////\n // Media players BEGIN\n ////////////////////////\n\n , [\n\n /(apple(?:coremedia|))\\/((\\d+)[\\w\\._]+)/i, // Generic Apple CoreMedia\n /(coremedia) v((\\d+)[\\w\\._]+)/i\n ], [NAME, VERSION], [\n\n /(aqualung|lyssna|bsplayer)\\/((\\d+)?[\\w\\.-]+)/i // Aqualung/Lyssna/BSPlayer\n ], [NAME, VERSION], [\n\n /(ares|ossproxy)\\s((\\d+)[\\w\\.-]+)/i // Ares/OSSProxy\n ], [NAME, VERSION], [\n\n /(audacious|audimusicstream|amarok|bass|core|dalvik|gnomemplayer|music on console|nsplayer|psp-internetradioplayer|videos)\\/((\\d+)[\\w\\.-]+)/i,\n // Audacious/AudiMusicStream/Amarok/BASS/OpenCORE/Dalvik/GnomeMplayer/MoC\n // NSPlayer/PSP-InternetRadioPlayer/Videos\n /(clementine|music player daemon)\\s((\\d+)[\\w\\.-]+)/i, // Clementine/MPD\n /(lg player|nexplayer)\\s((\\d+)[\\d\\.]+)/i,\n /player\\/(nexplayer|lg player)\\s((\\d+)[\\w\\.-]+)/i // NexPlayer/LG Player\n ], [NAME, VERSION], [\n /(nexplayer)\\s((\\d+)[\\w\\.-]+)/i // Nexplayer\n ], [NAME, VERSION], [\n\n /(flrp)\\/((\\d+)[\\w\\.-]+)/i // Flip Player\n ], [[NAME, 'Flip Player'], VERSION], [\n\n /(fstream|nativehost|queryseekspider|ia-archiver|facebookexternalhit)/i\n // FStream/NativeHost/QuerySeekSpider/IA Archiver/facebookexternalhit\n ], [NAME], [\n\n /(gstreamer) souphttpsrc (?:\\([^\\)]+\\)){0,1} libsoup\\/((\\d+)[\\w\\.-]+)/i\n // Gstreamer\n ], [NAME, VERSION], [\n\n /(htc streaming player)\\s[\\w_]+\\s\\/\\s((\\d+)[\\d\\.]+)/i, // HTC Streaming Player\n /(java|python-urllib|python-requests|wget|libcurl)\\/((\\d+)[\\w\\.-_]+)/i,\n // Java/urllib/requests/wget/cURL\n /(lavf)((\\d+)[\\d\\.]+)/i // Lavf (FFMPEG)\n ], [NAME, VERSION], [\n\n /(htc_one_s)\\/((\\d+)[\\d\\.]+)/i // HTC One S\n ], [[NAME, /_/g, ' '], VERSION], [\n\n /(mplayer)(?:\\s|\\/)(?:(?:sherpya-){0,1}svn)(?:-|\\s)(r\\d+(?:-\\d+[\\w\\.-]+){0,1})/i\n // MPlayer SVN\n ], [NAME, VERSION], [\n\n /(mplayer)(?:\\s|\\/|[unkow-]+)((\\d+)[\\w\\.-]+)/i // MPlayer\n ], [NAME, VERSION], [\n\n /(mplayer)/i, // MPlayer (no other info)\n /(yourmuze)/i, // YourMuze\n /(media player classic|nero showtime)/i // Media Player Classic/Nero ShowTime\n ], [NAME], [\n\n /(nero (?:home|scout))\\/((\\d+)[\\w\\.-]+)/i // Nero Home/Nero Scout\n ], [NAME, VERSION], [\n\n /(nokia\\d+)\\/((\\d+)[\\w\\.-]+)/i // Nokia\n ], [NAME, VERSION], [\n\n /\\s(songbird)\\/((\\d+)[\\w\\.-]+)/i // Songbird/Philips-Songbird\n ], [NAME, VERSION], [\n\n /(winamp)3 version ((\\d+)[\\w\\.-]+)/i, // Winamp\n /(winamp)\\s((\\d+)[\\w\\.-]+)/i,\n /(winamp)mpeg\\/((\\d+)[\\w\\.-]+)/i\n ], [NAME, VERSION], [\n\n /(ocms-bot|tapinradio|tunein radio|unknown|winamp|inlight radio)/i // OCMS-bot/tap in radio/tunein/unknown/winamp (no other info)\n // inlight radio\n ], [NAME], [\n\n /(quicktime|rma|radioapp|radioclientapplication|soundtap|totem|stagefright|streamium)\\/((\\d+)[\\w\\.-]+)/i\n // QuickTime/RealMedia/RadioApp/RadioClientApplication/\n // SoundTap/Totem/Stagefright/Streamium\n ], [NAME, VERSION], [\n\n /(smp)((\\d+)[\\d\\.]+)/i // SMP\n ], [NAME, VERSION], [\n\n /(vlc) media player - version ((\\d+)[\\w\\.]+)/i, // VLC Videolan\n /(vlc)\\/((\\d+)[\\w\\.-]+)/i,\n /(xbmc|gvfs|xine|xmms|irapp)\\/((\\d+)[\\w\\.-]+)/i, // XBMC/gvfs/Xine/XMMS/irapp\n /(foobar2000)\\/((\\d+)[\\d\\.]+)/i, // Foobar2000\n /(itunes)\\/((\\d+)[\\d\\.]+)/i // iTunes\n ], [NAME, VERSION], [\n\n /(wmplayer)\\/((\\d+)[\\w\\.-]+)/i, // Windows Media Player\n /(windows-media-player)\\/((\\d+)[\\w\\.-]+)/i\n ], [[NAME, /-/g, ' '], VERSION], [\n\n /windows\\/((\\d+)[\\w\\.-]+) upnp\\/[\\d\\.]+ dlnadoc\\/[\\d\\.]+ (home media server)/i\n // Windows Media Server\n ], [VERSION, [NAME, 'Windows']], [\n\n /(com\\.riseupradioalarm)\\/((\\d+)[\\d\\.]*)/i // RiseUP Radio Alarm\n ], [NAME, VERSION], [\n\n /(rad.io)\\s((\\d+)[\\d\\.]+)/i, // Rad.io\n /(radio.(?:de|at|fr))\\s((\\d+)[\\d\\.]+)/i\n ], [[NAME, 'rad.io'], VERSION]\n\n //////////////////////\n // Media players END\n ////////////////////*/\n\n ],\n\n cpu : [[\n\n /(?:(amd|x(?:(?:86|64)[_-])?|wow|win)64)[;\\)]/i // AMD64\n ], [[ARCHITECTURE, 'amd64']], [\n\n /(ia32(?=;))/i // IA32 (quicktime)\n ], [[ARCHITECTURE, util.lowerize]], [\n\n /((?:i[346]|x)86)[;\\)]/i // IA32\n ], [[ARCHITECTURE, 'ia32']], [\n\n // PocketPC mistakenly identified as PowerPC\n /windows\\s(ce|mobile);\\sppc;/i\n ], [[ARCHITECTURE, 'arm']], [\n\n /((?:ppc|powerpc)(?:64)?)(?:\\smac|;|\\))/i // PowerPC\n ], [[ARCHITECTURE, /ower/, '', util.lowerize]], [\n\n /(sun4\\w)[;\\)]/i // SPARC\n ], [[ARCHITECTURE, 'sparc']], [\n\n /((?:avr32|ia64(?=;))|68k(?=\\))|arm(?:64|(?=v\\d+;))|(?=atmel\\s)avr|(?:irix|mips|sparc)(?:64)?(?=;)|pa-risc)/i\n // IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC\n ], [[ARCHITECTURE, util.lowerize]]\n ],\n\n device : [[\n\n /\\((ipad|playbook);[\\w\\s\\);-]+(rim|apple)/i // iPad/PlayBook\n ], [MODEL, VENDOR, [TYPE, TABLET]], [\n\n /applecoremedia\\/[\\w\\.]+ \\((ipad)/ // iPad\n ], [MODEL, [VENDOR, 'Apple'], [TYPE, TABLET]], [\n\n /(apple\\s{0,1}tv)/i // Apple TV\n ], [[MODEL, 'Apple TV'], [VENDOR, 'Apple']], [\n\n /(archos)\\s(gamepad2?)/i, // Archos\n /(hp).+(touchpad)/i, // HP TouchPad\n /(hp).+(tablet)/i, // HP Tablet\n /(kindle)\\/([\\w\\.]+)/i, // Kindle\n /\\s(nook)[\\w\\s]+build\\/(\\w+)/i, // Nook\n /(dell)\\s(strea[kpr\\s\\d]*[\\dko])/i // Dell Streak\n ], [VENDOR, MODEL, [TYPE, TABLET]], [\n\n /(kf[A-z]+)\\sbuild\\/[\\w\\.]+.*silk\\//i // Kindle Fire HD\n ], [MODEL, [VENDOR, 'Amazon'], [TYPE, TABLET]], [\n /(sd|kf)[0349hijorstuw]+\\sbuild\\/[\\w\\.]+.*silk\\//i // Fire Phone\n ], [[MODEL, mapper.str, maps.device.amazon.model], [VENDOR, 'Amazon'], [TYPE, MOBILE]], [\n\n /\\((ip[honed|\\s\\w*]+);.+(apple)/i // iPod/iPhone\n ], [MODEL, VENDOR, [TYPE, MOBILE]], [\n /\\((ip[honed|\\s\\w*]+);/i // iPod/iPhone\n ], [MODEL, [VENDOR, 'Apple'], [TYPE, MOBILE]], [\n\n /(blackberry)[\\s-]?(\\w+)/i, // BlackBerry\n /(blackberry|benq|palm(?=\\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron)[\\s_-]?([\\w-]+)*/i,\n // BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron\n /(hp)\\s([\\w\\s]+\\w)/i, // HP iPAQ\n /(asus)-?(\\w+)/i // Asus\n ], [VENDOR, MODEL, [TYPE, MOBILE]], [\n /\\(bb10;\\s(\\w+)/i // BlackBerry 10\n ], [MODEL, [VENDOR, 'BlackBerry'], [TYPE, MOBILE]], [\n // Asus Tablets\n /android.+(transfo[prime\\s]{4,10}\\s\\w+|eeepc|slider\\s\\w+|nexus 7|padfone)/i\n ], [MODEL, [VENDOR, 'Asus'], [TYPE, TABLET]], [\n\n /(sony)\\s(tablet\\s[ps])\\sbuild\\//i, // Sony\n /(sony)?(?:sgp.+)\\sbuild\\//i\n ], [[VENDOR, 'Sony'], [MODEL, 'Xperia Tablet'], [TYPE, TABLET]], [\n /android.+\\s([c-g]\\d{4}|so[-l]\\w+)\\sbuild\\//i\n ], [MODEL, [VENDOR, 'Sony'], [TYPE, MOBILE]], [\n\n /\\s(ouya)\\s/i, // Ouya\n /(nintendo)\\s([wids3u]+)/i // Nintendo\n ], [VENDOR, MODEL, [TYPE, CONSOLE]], [\n\n /android.+;\\s(shield)\\sbuild/i // Nvidia\n ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, CONSOLE]], [\n\n /(playstation\\s[34portablevi]+)/i // Playstation\n ], [MODEL, [VENDOR, 'Sony'], [TYPE, CONSOLE]], [\n\n /(sprint\\s(\\w+))/i // Sprint Phones\n ], [[VENDOR, mapper.str, maps.device.sprint.vendor], [MODEL, mapper.str, maps.device.sprint.model], [TYPE, MOBILE]], [\n\n /(lenovo)\\s?(S(?:5000|6000)+(?:[-][\\w+]))/i // Lenovo tablets\n ], [VENDOR, MODEL, [TYPE, TABLET]], [\n\n /(htc)[;_\\s-]+([\\w\\s]+(?=\\))|\\w+)*/i, // HTC\n /(zte)-(\\w+)*/i, // ZTE\n /(alcatel|geeksphone|lenovo|nexian|panasonic|(?=;\\s)sony)[_\\s-]?([\\w-]+)*/i\n // Alcatel/GeeksPhone/Lenovo/Nexian/Panasonic/Sony\n ], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [\n\n /(nexus\\s9)/i // HTC Nexus 9\n ], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [\n\n /d\\/huawei([\\w\\s-]+)[;\\)]/i,\n /(nexus\\s6p)/i // Huawei\n ], [MODEL, [VENDOR, 'Huawei'], [TYPE, MOBILE]], [\n\n /(microsoft);\\s(lumia[\\s\\w]+)/i // Microsoft Lumia\n ], [VENDOR, MODEL, [TYPE, MOBILE]], [\n\n /[\\s\\(;](xbox(?:\\sone)?)[\\s\\);]/i // Microsoft Xbox\n ], [MODEL, [VENDOR, 'Microsoft'], [TYPE, CONSOLE]], [\n /(kin\\.[onetw]{3})/i // Microsoft Kin\n ], [[MODEL, /\\./g, ' '], [VENDOR, 'Microsoft'], [TYPE, MOBILE]], [\n\n // Motorola\n /\\s(milestone|droid(?:[2-4x]|\\s(?:bionic|x2|pro|razr))?(:?\\s4g)?)[\\w\\s]+build\\//i,\n /mot[\\s-]?(\\w+)*/i,\n /(XT\\d{3,4}) build\\//i,\n /(nexus\\s6)/i\n ], [MODEL, [VENDOR, 'Motorola'], [TYPE, MOBILE]], [\n /android.+\\s(mz60\\d|xoom[\\s2]{0,2})\\sbuild\\//i\n ], [MODEL, [VENDOR, 'Motorola'], [TYPE, TABLET]], [\n\n /hbbtv\\/\\d+\\.\\d+\\.\\d+\\s+\\([\\w\\s]*;\\s*(\\w[^;]*);([^;]*)/i // HbbTV devices\n ], [[VENDOR, util.trim], [MODEL, util.trim], [TYPE, SMARTTV]], [\n\n /hbbtv.+maple;(\\d+)/i\n ], [[MODEL, /^/, 'SmartTV'], [VENDOR, 'Samsung'], [TYPE, SMARTTV]], [\n\n /\\(dtv[\\);].+(aquos)/i // Sharp\n ], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [\n\n /android.+((sch-i[89]0\\d|shw-m380s|gt-p\\d{4}|gt-n\\d+|sgh-t8[56]9|nexus 10))/i,\n /((SM-T\\w+))/i\n ], [[VENDOR, 'Samsung'], MODEL, [TYPE, TABLET]], [ // Samsung\n /smart-tv.+(samsung)/i\n ], [VENDOR, [TYPE, SMARTTV], MODEL], [\n /((s[cgp]h-\\w+|gt-\\w+|galaxy\\snexus|sm-\\w[\\w\\d]+))/i,\n /(sam[sung]*)[\\s-]*(\\w+-?[\\w-]*)*/i,\n /sec-((sgh\\w+))/i\n ], [[VENDOR, 'Samsung'], MODEL, [TYPE, MOBILE]], [\n\n /sie-(\\w+)*/i // Siemens\n ], [MODEL, [VENDOR, 'Siemens'], [TYPE, MOBILE]], [\n\n /(maemo|nokia).*(n900|lumia\\s\\d+)/i, // Nokia\n /(nokia)[\\s_-]?([\\w-]+)*/i\n ], [[VENDOR, 'Nokia'], MODEL, [TYPE, MOBILE]], [\n\n /android\\s3\\.[\\s\\w;-]{10}(a\\d{3})/i // Acer\n ], [MODEL, [VENDOR, 'Acer'], [TYPE, TABLET]], [\n\n /android.+([vl]k\\-?\\d{3})\\s+build/i // LG Tablet\n ], [MODEL, [VENDOR, 'LG'], [TYPE, TABLET]], [\n /android\\s3\\.[\\s\\w;-]{10}(lg?)-([06cv9]{3,4})/i // LG Tablet\n ], [[VENDOR, 'LG'], MODEL, [TYPE, TABLET]], [\n /(lg) netcast\\.tv/i // LG SmartTV\n ], [VENDOR, MODEL, [TYPE, SMARTTV]], [\n /(nexus\\s[45])/i, // LG\n /lg[e;\\s\\/-]+(\\w+)*/i,\n /android.+lg(\\-?[\\d\\w]+)\\s+build/i\n ], [MODEL, [VENDOR, 'LG'], [TYPE, MOBILE]], [\n\n /android.+(ideatab[a-z0-9\\-\\s]+)/i // Lenovo\n ], [MODEL, [VENDOR, 'Lenovo'], [TYPE, TABLET]], [\n\n /linux;.+((jolla));/i // Jolla\n ], [VENDOR, MODEL, [TYPE, MOBILE]], [\n\n /((pebble))app\\/[\\d\\.]+\\s/i // Pebble\n ], [VENDOR, MODEL, [TYPE, WEARABLE]], [\n\n /android.+;\\s(oppo)\\s?([\\w\\s]+)\\sbuild/i // OPPO\n ], [VENDOR, MODEL, [TYPE, MOBILE]], [\n\n /crkey/i // Google Chromecast\n ], [[MODEL, 'Chromecast'], [VENDOR, 'Google']], [\n\n /android.+;\\s(glass)\\s\\d/i // Google Glass\n ], [MODEL, [VENDOR, 'Google'], [TYPE, WEARABLE]], [\n\n /android.+;\\s(pixel c)\\s/i // Google Pixel C\n ], [MODEL, [VENDOR, 'Google'], [TYPE, TABLET]], [\n\n /android.+;\\s(pixel xl|pixel)\\s/i // Google Pixel\n ], [MODEL, [VENDOR, 'Google'], [TYPE, MOBILE]], [\n\n /android.+(\\w+)\\s+build\\/hm\\1/i, // Xiaomi Hongmi 'numeric' models\n /android.+(hm[\\s\\-_]*note?[\\s_]*(?:\\d\\w)?)\\s+build/i, // Xiaomi Hongmi\n /android.+(mi[\\s\\-_]*(?:one|one[\\s_]plus|note lte)?[\\s_]*(?:\\d\\w)?)\\s+build/i, // Xiaomi Mi\n /android.+(redmi[\\s\\-_]*(?:note)?(?:[\\s_]*[\\w\\s]+)?)\\s+build/i // Redmi Phones\n ], [[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, MOBILE]], [\n /android.+(mi[\\s\\-_]*(?:pad)?(?:[\\s_]*[\\w\\s]+)?)\\s+build/i // Mi Pad tablets\n ],[[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, TABLET]], [\n /android.+;\\s(m[1-5]\\snote)\\sbuild/i // Meizu Tablet\n ], [MODEL, [VENDOR, 'Meizu'], [TYPE, TABLET]], [\n\n /android.+a000(1)\\s+build/i // OnePlus\n ], [MODEL, [VENDOR, 'OnePlus'], [TYPE, MOBILE]], [\n\n /android.+[;\\/]\\s*(RCT[\\d\\w]+)\\s+build/i // RCA Tablets\n ], [MODEL, [VENDOR, 'RCA'], [TYPE, TABLET]], [\n\n /android.+[;\\/]\\s*(Venue[\\d\\s]*)\\s+build/i // Dell Venue Tablets\n ], [MODEL, [VENDOR, 'Dell'], [TYPE, TABLET]], [\n\n /android.+[;\\/]\\s*(Q[T|M][\\d\\w]+)\\s+build/i // Verizon Tablet\n ], [MODEL, [VENDOR, 'Verizon'], [TYPE, TABLET]], [\n\n /android.+[;\\/]\\s+(Barnes[&\\s]+Noble\\s+|BN[RT])(V?.*)\\s+build/i // Barnes & Noble Tablet\n ], [[VENDOR, 'Barnes & Noble'], MODEL, [TYPE, TABLET]], [\n\n /android.+[;\\/]\\s+(TM\\d{3}.*\\b)\\s+build/i // Barnes & Noble Tablet\n ], [MODEL, [VENDOR, 'NuVision'], [TYPE, TABLET]], [\n\n /android.+[;\\/]\\s*(zte)?.+(k\\d{2})\\s+build/i // ZTE K Series Tablet\n ], [[VENDOR, 'ZTE'], MODEL, [TYPE, TABLET]], [\n\n /android.+[;\\/]\\s*(gen\\d{3})\\s+build.*49h/i // Swiss GEN Mobile\n ], [MODEL, [VENDOR, 'Swiss'], [TYPE, MOBILE]], [\n\n /android.+[;\\/]\\s*(zur\\d{3})\\s+build/i // Swiss ZUR Tablet\n ], [MODEL, [VENDOR, 'Swiss'], [TYPE, TABLET]], [\n\n /android.+[;\\/]\\s*((Zeki)?TB.*\\b)\\s+build/i // Zeki Tablets\n ], [MODEL, [VENDOR, 'Zeki'], [TYPE, TABLET]], [\n\n /(android).+[;\\/]\\s+([YR]\\d{2}x?.*)\\s+build/i,\n /android.+[;\\/]\\s+(Dragon[\\-\\s]+Touch\\s+|DT)(.+)\\s+build/i // Dragon Touch Tablet\n ], [[VENDOR, 'Dragon Touch'], MODEL, [TYPE, TABLET]], [\n\n /android.+[;\\/]\\s*(NS-?.+)\\s+build/i // Insignia Tablets\n ], [MODEL, [VENDOR, 'Insignia'], [TYPE, TABLET]], [\n\n /android.+[;\\/]\\s*((NX|Next)-?.+)\\s+build/i // NextBook Tablets\n ], [MODEL, [VENDOR, 'NextBook'], [TYPE, TABLET]], [\n\n /android.+[;\\/]\\s*(Xtreme\\_?)?(V(1[045]|2[015]|30|40|60|7[05]|90))\\s+build/i\n ], [[VENDOR, 'Voice'], MODEL, [TYPE, MOBILE]], [ // Voice Xtreme Phones\n\n /android.+[;\\/]\\s*(LVTEL\\-?)?(V1[12])\\s+build/i // LvTel Phones\n ], [[VENDOR, 'LvTel'], MODEL, [TYPE, MOBILE]], [\n\n /android.+[;\\/]\\s*(V(100MD|700NA|7011|917G).*\\b)\\s+build/i // Envizen Tablets\n ], [MODEL, [VENDOR, 'Envizen'], [TYPE, TABLET]], [\n\n /android.+[;\\/]\\s*(Le[\\s\\-]+Pan)[\\s\\-]+(.*\\b)\\s+build/i // Le Pan Tablets\n ], [VENDOR, MODEL, [TYPE, TABLET]], [\n\n /android.+[;\\/]\\s*(Trio[\\s\\-]*.*)\\s+build/i // MachSpeed Tablets\n ], [MODEL, [VENDOR, 'MachSpeed'], [TYPE, TABLET]], [\n\n /android.+[;\\/]\\s*(Trinity)[\\-\\s]*(T\\d{3})\\s+build/i // Trinity Tablets\n ], [VENDOR, MODEL, [TYPE, TABLET]], [\n\n /android.+[;\\/]\\s*TU_(1491)\\s+build/i // Rotor Tablets\n ], [MODEL, [VENDOR, 'Rotor'], [TYPE, TABLET]], [\n\n /android.+(KS(.+))\\s+build/i // Amazon Kindle Tablets\n ], [MODEL, [VENDOR, 'Amazon'], [TYPE, TABLET]], [\n\n /android.+(Gigaset)[\\s\\-]+(Q.+)\\s+build/i // Gigaset Tablets\n ], [VENDOR, MODEL, [TYPE, TABLET]], [\n\n /\\s(tablet|tab)[;\\/]/i, // Unidentifiable Tablet\n /\\s(mobile)(?:[;\\/]|\\ssafari)/i // Unidentifiable Mobile\n ], [[TYPE, util.lowerize], VENDOR, MODEL], [\n\n /(android.+)[;\\/].+build/i // Generic Android Device\n ], [MODEL, [VENDOR, 'Generic']]\n\n\n /*//////////////////////////\n // TODO: move to string map\n ////////////////////////////\n\n /(C6603)/i // Sony Xperia Z C6603\n ], [[MODEL, 'Xperia Z C6603'], [VENDOR, 'Sony'], [TYPE, MOBILE]], [\n /(C6903)/i // Sony Xperia Z 1\n ], [[MODEL, 'Xperia Z 1'], [VENDOR, 'Sony'], [TYPE, MOBILE]], [\n\n /(SM-G900[F|H])/i // Samsung Galaxy S5\n ], [[MODEL, 'Galaxy S5'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [\n /(SM-G7102)/i // Samsung Galaxy Grand 2\n ], [[MODEL, 'Galaxy Grand 2'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [\n /(SM-G530H)/i // Samsung Galaxy Grand Prime\n ], [[MODEL, 'Galaxy Grand Prime'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [\n /(SM-G313HZ)/i // Samsung Galaxy V\n ], [[MODEL, 'Galaxy V'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [\n /(SM-T805)/i // Samsung Galaxy Tab S 10.5\n ], [[MODEL, 'Galaxy Tab S 10.5'], [VENDOR, 'Samsung'], [TYPE, TABLET]], [\n /(SM-G800F)/i // Samsung Galaxy S5 Mini\n ], [[MODEL, 'Galaxy S5 Mini'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [\n /(SM-T311)/i // Samsung Galaxy Tab 3 8.0\n ], [[MODEL, 'Galaxy Tab 3 8.0'], [VENDOR, 'Samsung'], [TYPE, TABLET]], [\n\n /(T3C)/i // Advan Vandroid T3C\n ], [MODEL, [VENDOR, 'Advan'], [TYPE, TABLET]], [\n /(ADVAN T1J\\+)/i // Advan Vandroid T1J+\n ], [[MODEL, 'Vandroid T1J+'], [VENDOR, 'Advan'], [TYPE, TABLET]], [\n /(ADVAN S4A)/i // Advan Vandroid S4A\n ], [[MODEL, 'Vandroid S4A'], [VENDOR, 'Advan'], [TYPE, MOBILE]], [\n\n /(V972M)/i // ZTE V972M\n ], [MODEL, [VENDOR, 'ZTE'], [TYPE, MOBILE]], [\n\n /(i-mobile)\\s(IQ\\s[\\d\\.]+)/i // i-mobile IQ\n ], [VENDOR, MODEL, [TYPE, MOBILE]], [\n /(IQ6.3)/i // i-mobile IQ IQ 6.3\n ], [[MODEL, 'IQ 6.3'], [VENDOR, 'i-mobile'], [TYPE, MOBILE]], [\n /(i-mobile)\\s(i-style\\s[\\d\\.]+)/i // i-mobile i-STYLE\n ], [VENDOR, MODEL, [TYPE, MOBILE]], [\n /(i-STYLE2.1)/i // i-mobile i-STYLE 2.1\n ], [[MODEL, 'i-STYLE 2.1'], [VENDOR, 'i-mobile'], [TYPE, MOBILE]], [\n\n /(mobiistar touch LAI 512)/i // mobiistar touch LAI 512\n ], [[MODEL, 'Touch LAI 512'], [VENDOR, 'mobiistar'], [TYPE, MOBILE]], [\n\n /////////////\n // END TODO\n ///////////*/\n\n ],\n\n engine : [[\n\n /windows.+\\sedge\\/([\\w\\.]+)/i // EdgeHTML\n ], [VERSION, [NAME, 'EdgeHTML']], [\n\n /(presto)\\/([\\w\\.]+)/i, // Presto\n /(webkit|trident|netfront|netsurf|amaya|lynx|w3m)\\/([\\w\\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m\n /(khtml|tasman|links)[\\/\\s]\\(?([\\w\\.]+)/i, // KHTML/Tasman/Links\n /(icab)[\\/\\s]([23]\\.[\\d\\.]+)/i // iCab\n ], [NAME, VERSION], [\n\n /rv\\:([\\w\\.]+).*(gecko)/i // Gecko\n ], [VERSION, NAME]\n ],\n\n os : [[\n\n // Windows based\n /microsoft\\s(windows)\\s(vista|xp)/i // Windows (iTunes)\n ], [NAME, VERSION], [\n /(windows)\\snt\\s6\\.2;\\s(arm)/i, // Windows RT\n /(windows\\sphone(?:\\sos)*)[\\s\\/]?([\\d\\.\\s]+\\w)*/i, // Windows Phone\n /(windows\\smobile|windows)[\\s\\/]?([ntce\\d\\.\\s]+\\w)/i\n ], [NAME, [VERSION, mapper.str, maps.os.windows.version]], [\n /(win(?=3|9|n)|win\\s9x\\s)([nt\\d\\.]+)/i\n ], [[NAME, 'Windows'], [VERSION, mapper.str, maps.os.windows.version]], [\n\n // Mobile/Embedded OS\n /\\((bb)(10);/i // BlackBerry 10\n ], [[NAME, 'BlackBerry'], VERSION], [\n /(blackberry)\\w*\\/?([\\w\\.]+)*/i, // Blackberry\n /(tizen)[\\/\\s]([\\w\\.]+)/i, // Tizen\n /(android|webos|palm\\sos|qnx|bada|rim\\stablet\\sos|meego|contiki)[\\/\\s-]?([\\w\\.]+)*/i,\n // Android/WebOS/Palm/QNX/Bada/RIM/MeeGo/Contiki\n /linux;.+(sailfish);/i // Sailfish OS\n ], [NAME, VERSION], [\n /(symbian\\s?os|symbos|s60(?=;))[\\/\\s-]?([\\w\\.]+)*/i // Symbian\n ], [[NAME, 'Symbian'], VERSION], [\n /\\((series40);/i // Series 40\n ], [NAME], [\n /mozilla.+\\(mobile;.+gecko.+firefox/i // Firefox OS\n ], [[NAME, 'Firefox OS'], VERSION], [\n\n // Console\n /(nintendo|playstation)\\s([wids34portablevu]+)/i, // Nintendo/Playstation\n\n // GNU/Linux based\n /(mint)[\\/\\s\\(]?(\\w+)*/i, // Mint\n /(mageia|vectorlinux)[;\\s]/i, // Mageia/VectorLinux\n /(joli|[kxln]?ubuntu|debian|[open]*suse|gentoo|(?=\\s)arch|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk|linpus)[\\/\\s-]?(?!chrom)([\\w\\.-]+)*/i,\n // Joli/Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware\n // Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus\n /(hurd|linux)\\s?([\\w\\.]+)*/i, // Hurd/Linux\n /(gnu)\\s?([\\w\\.]+)*/i // GNU\n ], [NAME, VERSION], [\n\n /(cros)\\s[\\w]+\\s([\\w\\.]+\\w)/i // Chromium OS\n ], [[NAME, 'Chromium OS'], VERSION],[\n\n // Solaris\n /(sunos)\\s?([\\w\\.]+\\d)*/i // Solaris\n ], [[NAME, 'Solaris'], VERSION], [\n\n // BSD based\n /\\s([frentopc-]{0,4}bsd|dragonfly)\\s?([\\w\\.]+)*/i // FreeBSD/NetBSD/OpenBSD/PC-BSD/DragonFly\n ], [NAME, VERSION],[\n\n /(haiku)\\s(\\w+)/i // Haiku\n ], [NAME, VERSION],[\n\n /cfnetwork\\/.+darwin/i,\n /ip[honead]+(?:.*os\\s([\\w]+)\\slike\\smac|;\\sopera)/i // iOS\n ], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [\n\n /(mac\\sos\\sx)\\s?([\\w\\s\\.]+\\w)*/i,\n /(macintosh|mac(?=_powerpc)\\s)/i // Mac OS\n ], [[NAME, 'Mac OS'], [VERSION, /_/g, '.']], [\n\n // Other\n /((?:open)?solaris)[\\/\\s-]?([\\w\\.]+)*/i, // Solaris\n /(aix)\\s((\\d)(?=\\.|\\)|\\s)[\\w\\.]*)*/i, // AIX\n /(plan\\s9|minix|beos|os\\/2|amigaos|morphos|risc\\sos|openvms)/i,\n // Plan9/Minix/BeOS/OS2/AmigaOS/MorphOS/RISCOS/OpenVMS\n /(unix)\\s?([\\w\\.]+)*/i // UNIX\n ], [NAME, VERSION]\n ]\n };\n\n\n /////////////////\n // Constructor\n ////////////////\n /*\n var Browser = function (name, version) {\n this[NAME] = name;\n this[VERSION] = version;\n };\n var CPU = function (arch) {\n this[ARCHITECTURE] = arch;\n };\n var Device = function (vendor, model, type) {\n this[VENDOR] = vendor;\n this[MODEL] = model;\n this[TYPE] = type;\n };\n var Engine = Browser;\n var OS = Browser;\n */\n var UAParser = function (uastring, extensions) {\n\n if (typeof uastring === 'object') {\n extensions = uastring;\n uastring = undefined;\n }\n\n if (!(this instanceof UAParser)) {\n return new UAParser(uastring, extensions).getResult();\n }\n\n var ua = uastring || ((window && window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : EMPTY);\n var rgxmap = extensions ? util.extend(regexes, extensions) : regexes;\n //var browser = new Browser();\n //var cpu = new CPU();\n //var device = new Device();\n //var engine = new Engine();\n //var os = new OS();\n\n this.getBrowser = function () {\n var browser = { name: undefined, version: undefined };\n mapper.rgx.call(browser, ua, rgxmap.browser);\n browser.major = util.major(browser.version); // deprecated\n return browser;\n };\n this.getCPU = function () {\n var cpu = { architecture: undefined };\n mapper.rgx.call(cpu, ua, rgxmap.cpu);\n return cpu;\n };\n this.getDevice = function () {\n var device = { vendor: undefined, model: undefined, type: undefined };\n mapper.rgx.call(device, ua, rgxmap.device);\n return device;\n };\n this.getEngine = function () {\n var engine = { name: undefined, version: undefined };\n mapper.rgx.call(engine, ua, rgxmap.engine);\n return engine;\n };\n this.getOS = function () {\n var os = { name: undefined, version: undefined };\n mapper.rgx.call(os, ua, rgxmap.os);\n return os;\n };\n this.getResult = function () {\n return {\n ua : this.getUA(),\n browser : this.getBrowser(),\n engine : this.getEngine(),\n os : this.getOS(),\n device : this.getDevice(),\n cpu : this.getCPU()\n };\n };\n this.getUA = function () {\n return ua;\n };\n this.setUA = function (uastring) {\n ua = uastring;\n //browser = new Browser();\n //cpu = new CPU();\n //device = new Device();\n //engine = new Engine();\n //os = new OS();\n return this;\n };\n return this;\n };\n\n UAParser.VERSION = LIBVERSION;\n UAParser.BROWSER = {\n NAME : NAME,\n MAJOR : MAJOR, // deprecated\n VERSION : VERSION\n };\n UAParser.CPU = {\n ARCHITECTURE : ARCHITECTURE\n };\n UAParser.DEVICE = {\n MODEL : MODEL,\n VENDOR : VENDOR,\n TYPE : TYPE,\n CONSOLE : CONSOLE,\n MOBILE : MOBILE,\n SMARTTV : SMARTTV,\n TABLET : TABLET,\n WEARABLE: WEARABLE,\n EMBEDDED: EMBEDDED\n };\n UAParser.ENGINE = {\n NAME : NAME,\n VERSION : VERSION\n };\n UAParser.OS = {\n NAME : NAME,\n VERSION : VERSION\n };\n //UAParser.Utils = util;\n\n ///////////\n // Export\n //////////\n\n\n // check js environment\n if (typeof(exports) !== UNDEF_TYPE) {\n // nodejs env\n if (typeof module !== UNDEF_TYPE && module.exports) {\n exports = module.exports = UAParser;\n }\n // TODO: test!!!!!!!!\n /*\n if (require && require.main === module && process) {\n // cli\n var jsonize = function (arr) {\n var res = [];\n for (var i in arr) {\n res.push(new UAParser(arr[i]).getResult());\n }\n process.stdout.write(JSON.stringify(res, null, 2) + '\\n');\n };\n if (process.stdin.isTTY) {\n // via args\n jsonize(process.argv.slice(2));\n } else {\n // via pipe\n var str = '';\n process.stdin.on('readable', function() {\n var read = process.stdin.read();\n if (read !== null) {\n str += read;\n }\n });\n process.stdin.on('end', function () {\n jsonize(str.replace(/\\n$/, '').split('\\n'));\n });\n }\n }\n */\n exports.UAParser = UAParser;\n } else {\n // requirejs env (optional)\n if (typeof(define) === FUNC_TYPE && define.amd) {\n define(function () {\n return UAParser;\n });\n } else if (window) {\n // browser env\n window.UAParser = UAParser;\n }\n }\n\n // jQuery/Zepto specific (optional)\n // Note:\n // In AMD env the global scope should be kept clean, but jQuery is an exception.\n // jQuery always exports to global scope, unless jQuery.noConflict(true) is used,\n // and we should catch that.\n var $ = window && (window.jQuery || window.Zepto);\n if (typeof $ !== UNDEF_TYPE) {\n var parser = new UAParser();\n $.ua = parser.getResult();\n $.ua.get = function () {\n return parser.getUA();\n };\n $.ua.set = function (uastring) {\n parser.setUA(uastring);\n var result = parser.getResult();\n for (var prop in result) {\n $.ua[prop] = result[prop];\n }\n };\n }\n\n})(typeof window === 'object' ? window : this);\n","\nvar rng;\n\nvar crypto = global.crypto || global.msCrypto; // for IE 11\nif (crypto && crypto.getRandomValues) {\n // WHATWG crypto-based RNG - http://wiki.whatwg.org/wiki/Crypto\n // Moderately fast, high quality\n var _rnds8 = new Uint8Array(16);\n rng = function whatwgRNG() {\n crypto.getRandomValues(_rnds8);\n return _rnds8;\n };\n}\n\nif (!rng) {\n // Math.random()-based (RNG)\n //\n // If all else fails, use Math.random(). It's fast, but is of unspecified\n // quality.\n var _rnds = new Array(16);\n rng = function() {\n for (var i = 0, r; i < 16; i++) {\n if ((i & 0x03) === 0) r = Math.random() * 0x100000000;\n _rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;\n }\n\n return _rnds;\n };\n}\n\nmodule.exports = rng;\n\n","// uuid.js\n//\n// Copyright (c) 2010-2012 Robert Kieffer\n// MIT License - http://opensource.org/licenses/mit-license.php\n\n// Unique ID creation requires a high quality random # generator. We feature\n// detect to determine the best RNG source, normalizing to a function that\n// returns 128-bits of randomness, since that's what's usually required\nvar _rng = require('./rng');\n\n// Maps for number <-> hex string conversion\nvar _byteToHex = [];\nvar _hexToByte = {};\nfor (var i = 0; i < 256; i++) {\n _byteToHex[i] = (i + 0x100).toString(16).substr(1);\n _hexToByte[_byteToHex[i]] = i;\n}\n\n// **`parse()` - Parse a UUID into it's component bytes**\nfunction parse(s, buf, offset) {\n var i = (buf && offset) || 0, ii = 0;\n\n buf = buf || [];\n s.toLowerCase().replace(/[0-9a-f]{2}/g, function(oct) {\n if (ii < 16) { // Don't overflow!\n buf[i + ii++] = _hexToByte[oct];\n }\n });\n\n // Zero out remaining bytes if string was short\n while (ii < 16) {\n buf[i + ii++] = 0;\n }\n\n return buf;\n}\n\n// **`unparse()` - Convert UUID byte array (ala parse()) into a string**\nfunction unparse(buf, offset) {\n var i = offset || 0, bth = _byteToHex;\n return bth[buf[i++]] + bth[buf[i++]] +\n bth[buf[i++]] + bth[buf[i++]] + '-' +\n bth[buf[i++]] + bth[buf[i++]] + '-' +\n bth[buf[i++]] + bth[buf[i++]] + '-' +\n bth[buf[i++]] + bth[buf[i++]] + '-' +\n bth[buf[i++]] + bth[buf[i++]] +\n bth[buf[i++]] + bth[buf[i++]] +\n bth[buf[i++]] + bth[buf[i++]];\n}\n\n// **`v1()` - Generate time-based UUID**\n//\n// Inspired by https://github.com/LiosK/UUID.js\n// and http://docs.python.org/library/uuid.html\n\n// random #'s we need to init node and clockseq\nvar _seedBytes = _rng();\n\n// Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)\nvar _nodeId = [\n _seedBytes[0] | 0x01,\n _seedBytes[1], _seedBytes[2], _seedBytes[3], _seedBytes[4], _seedBytes[5]\n];\n\n// Per 4.2.2, randomize (14 bit) clockseq\nvar _clockseq = (_seedBytes[6] << 8 | _seedBytes[7]) & 0x3fff;\n\n// Previous uuid creation time\nvar _lastMSecs = 0, _lastNSecs = 0;\n\n// See https://github.com/broofa/node-uuid for API details\nfunction v1(options, buf, offset) {\n var i = buf && offset || 0;\n var b = buf || [];\n\n options = options || {};\n\n var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq;\n\n // UUID timestamps are 100 nano-second units since the Gregorian epoch,\n // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so\n // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'\n // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.\n var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime();\n\n // Per 4.2.1.2, use count of uuid's generated during the current clock\n // cycle to simulate higher resolution clock\n var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1;\n\n // Time since last uuid creation (in msecs)\n var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000;\n\n // Per 4.2.1.2, Bump clockseq on clock regression\n if (dt < 0 && options.clockseq === undefined) {\n clockseq = clockseq + 1 & 0x3fff;\n }\n\n // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new\n // time interval\n if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) {\n nsecs = 0;\n }\n\n // Per 4.2.1.2 Throw error if too many uuids are requested\n if (nsecs >= 10000) {\n throw new Error('uuid.v1(): Can\\'t create more than 10M uuids/sec');\n }\n\n _lastMSecs = msecs;\n _lastNSecs = nsecs;\n _clockseq = clockseq;\n\n // Per 4.1.4 - Convert from unix epoch to Gregorian epoch\n msecs += 12219292800000;\n\n // `time_low`\n var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;\n b[i++] = tl >>> 24 & 0xff;\n b[i++] = tl >>> 16 & 0xff;\n b[i++] = tl >>> 8 & 0xff;\n b[i++] = tl & 0xff;\n\n // `time_mid`\n var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff;\n b[i++] = tmh >>> 8 & 0xff;\n b[i++] = tmh & 0xff;\n\n // `time_high_and_version`\n b[i++] = tmh >>> 24 & 0xf | 0x10; // include version\n b[i++] = tmh >>> 16 & 0xff;\n\n // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)\n b[i++] = clockseq >>> 8 | 0x80;\n\n // `clock_seq_low`\n b[i++] = clockseq & 0xff;\n\n // `node`\n var node = options.node || _nodeId;\n for (var n = 0; n < 6; n++) {\n b[i + n] = node[n];\n }\n\n return buf ? buf : unparse(b);\n}\n\n// **`v4()` - Generate random UUID**\n\n// See https://github.com/broofa/node-uuid for API details\nfunction v4(options, buf, offset) {\n // Deprecated - 'format' argument, as supported in v1.2\n var i = buf && offset || 0;\n\n if (typeof(options) == 'string') {\n buf = options == 'binary' ? new Array(16) : null;\n options = null;\n }\n options = options || {};\n\n var rnds = options.random || (options.rng || _rng)();\n\n // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n rnds[6] = (rnds[6] & 0x0f) | 0x40;\n rnds[8] = (rnds[8] & 0x3f) | 0x80;\n\n // Copy bytes to buffer, if provided\n if (buf) {\n for (var ii = 0; ii < 16; ii++) {\n buf[i + ii] = rnds[ii];\n }\n }\n\n return buf || unparse(rnds);\n}\n\n// Export public API\nvar uuid = v4;\nuuid.v1 = v1;\nuuid.v4 = v4;\nuuid.parse = parse;\nuuid.unparse = unparse;\n\nmodule.exports = uuid;\n","/*\r\nWildEmitter.js is a slim little event emitter by @henrikjoreteg largely based\r\non @visionmedia's Emitter from UI Kit.\r\n\r\nWhy? I wanted it standalone.\r\n\r\nI also wanted support for wildcard emitters like this:\r\n\r\nemitter.on('*', function (eventName, other, event, payloads) {\r\n\r\n});\r\n\r\nemitter.on('somenamespace*', function (eventName, payloads) {\r\n\r\n});\r\n\r\nPlease note that callbacks triggered by wildcard registered events also get\r\nthe event name as the first argument.\r\n*/\r\n\r\nmodule.exports = WildEmitter;\r\n\r\nfunction WildEmitter() { }\r\n\r\nWildEmitter.mixin = function (constructor) {\r\n var prototype = constructor.prototype || constructor;\r\n\r\n prototype.isWildEmitter= true;\r\n\r\n // Listen on the given `event` with `fn`. Store a group name if present.\r\n prototype.on = function (event, groupName, fn) {\r\n this.callbacks = this.callbacks || {};\r\n var hasGroup = (arguments.length === 3),\r\n group = hasGroup ? arguments[1] : undefined,\r\n func = hasGroup ? arguments[2] : arguments[1];\r\n func._groupName = group;\r\n (this.callbacks[event] = this.callbacks[event] || []).push(func);\r\n return this;\r\n };\r\n\r\n // Adds an `event` listener that will be invoked a single\r\n // time then automatically removed.\r\n prototype.once = function (event, groupName, fn) {\r\n var self = this,\r\n hasGroup = (arguments.length === 3),\r\n group = hasGroup ? arguments[1] : undefined,\r\n func = hasGroup ? arguments[2] : arguments[1];\r\n function on() {\r\n self.off(event, on);\r\n func.apply(this, arguments);\r\n }\r\n this.on(event, group, on);\r\n return this;\r\n };\r\n\r\n // Unbinds an entire group\r\n prototype.releaseGroup = function (groupName) {\r\n this.callbacks = this.callbacks || {};\r\n var item, i, len, handlers;\r\n for (item in this.callbacks) {\r\n handlers = this.callbacks[item];\r\n for (i = 0, len = handlers.length; i < len; i++) {\r\n if (handlers[i]._groupName === groupName) {\r\n //console.log('removing');\r\n // remove it and shorten the array we're looping through\r\n handlers.splice(i, 1);\r\n i--;\r\n len--;\r\n }\r\n }\r\n }\r\n return this;\r\n };\r\n\r\n // Remove the given callback for `event` or all\r\n // registered callbacks.\r\n prototype.off = function (event, fn) {\r\n this.callbacks = this.callbacks || {};\r\n var callbacks = this.callbacks[event],\r\n i;\r\n\r\n if (!callbacks) return this;\r\n\r\n // remove all handlers\r\n if (arguments.length === 1) {\r\n delete this.callbacks[event];\r\n return this;\r\n }\r\n\r\n // remove specific handler\r\n i = callbacks.indexOf(fn);\r\n callbacks.splice(i, 1);\r\n if (callbacks.length === 0) {\r\n delete this.callbacks[event];\r\n }\r\n return this;\r\n };\r\n\r\n /// Emit `event` with the given args.\r\n // also calls any `*` handlers\r\n prototype.emit = function (event) {\r\n this.callbacks = this.callbacks || {};\r\n var args = [].slice.call(arguments, 1),\r\n callbacks = this.callbacks[event],\r\n specialCallbacks = this.getWildcardCallbacks(event),\r\n i,\r\n len,\r\n item,\r\n listeners;\r\n\r\n if (callbacks) {\r\n listeners = callbacks.slice();\r\n for (i = 0, len = listeners.length; i < len; ++i) {\r\n if (!listeners[i]) {\r\n break;\r\n }\r\n listeners[i].apply(this, args);\r\n }\r\n }\r\n\r\n if (specialCallbacks) {\r\n len = specialCallbacks.length;\r\n listeners = specialCallbacks.slice();\r\n for (i = 0, len = listeners.length; i < len; ++i) {\r\n if (!listeners[i]) {\r\n break;\r\n }\r\n listeners[i].apply(this, [event].concat(args));\r\n }\r\n }\r\n\r\n return this;\r\n };\r\n\r\n // Helper for for finding special wildcard event handlers that match the event\r\n prototype.getWildcardCallbacks = function (eventName) {\r\n this.callbacks = this.callbacks || {};\r\n var item,\r\n split,\r\n result = [];\r\n\r\n for (item in this.callbacks) {\r\n split = item.split('*');\r\n if (item === '*' || (split.length === 2 && eventName.slice(0, split[0].length) === split[0])) {\r\n result = result.concat(this.callbacks[item]);\r\n }\r\n }\r\n return result;\r\n };\r\n\r\n};\r\n\r\nWildEmitter.mixin(WildEmitter);\r\n"]}