{"version":3,"sources":["api/index.js","providers/UUIDProvider.jsx","api/websocket.js","views/Home/Home.jsx","api/queries.js","static/audio/notification_xperia.mp3","views/Messenger/Chat.jsx","static/audio/call_ringtone.mp3","views/Messenger/Call.jsx","views/Messenger/RTC.jsx","views/Messenger/Compose.jsx","utils/tools.js","views/Messenger/MessagesWindow.jsx","views/Messenger/ChatWindow.jsx","views/Messenger/Messenger.jsx","router/routes.js","router/Router.jsx","components/Preloader/Preloader.jsx","App.jsx","reportWebVitals.js","themes/chakraTheme.js","index.js"],"names":["socketUrl","get","endpoint","params","a","queryString","queryArray","queryEntries","Object","entries","key","value","push","length","join","fetch","then","res","json","data","catch","UUIDContext","createContext","UUIDProvider","children","useState","v4","UUID","username","setUsername","connected","setConnected","toast","useToast","event","setEvent","contextValue","connectToMainSocket","name","socket","uuid","RWS","connectMain","onopen","onmessage","e","JSON","parse","type","payload","title","description","message","status","isClosable","close","Provider","Home","setName","useContext","connecting","setConnecting","blurred","setBlurred","history","useHistory","useEffect","MessengerRoute","className","Form","onSubmit","preventDefault","Group","Control","onBlur","onChange","target","isInvalid","placeholder","Button","variant","disabled","getMessages","chatId","lastDate","Chat","chat","activeChat","onClick","onReceive","tempMessage","msgEvent","chatUser","users","find","user","last_message","lastMessage","setLastMessage","unread","setUnread","socketRef","useRef","notificationTone","Audio","RingTone","id","fireRead","current","send","stringify","sender","document","hasFocus","play","window","addEventListener","removeEventListener","width","height","margin","flexGrow","maxW","base","sm","lg","xl","fontSize","fontWeight","text","defaultMessage","lastMsgSender","attachment","audio","getLastMessage","borderRadius","display","justifyContent","textAlign","alignItems","color","Call","answerCall","terminateCall","call","requestCall","endCall","remoteStream","toggleMute","receiver","buttons","Icon","FaPhoneSlash","background","condition","FaPhone","caller","postButtons","FaTimes","FaVideo","video","mute","setMute","connectedButtons","FaMicrophoneSlash","FaMicrophone","FaVideoSlash","mediaRef","srcObject","visibility","d","flexDir","padding","peer","getCallerText","marginTop","map","index","rounded","colorScheme","marginInline","size","as","src","autoPlay","position","top","left","minHeight","minWidth","objectFit","zIndex","ref","transform","RTC","closeChatWindow","onSend","isCall","changeActiveChat","peerConnection","MediaStream","localStream","createPeerConnection","RTCPeerConnection","iceServers","urls","credential","ontrack","addTrack","track","onicecandidate","candidate","oniceconnectionstatechange","iceConnectionState","onconnectionstatechange","connectionState","setCall","createLocalStream","callType","constraints","autoGainControl","noiseSuppression","echoCancellation","channelCount","exact","latency","sampleRate","sampleSize","volume","navigator","mediaDevices","getUserMedia","addMyStream","getTracks","forEach","callRingtone","Ringtone","callTimeout","createRTCOffer","createOffer","offer","setLocalDescription","setTimeout","pause","currentTime","stop","MAX_AWAIT_TIME","answerOffer","clearTimeout","setRemoteDescription","RTCSessionDescription","sdpOffer","createAnswer","answer","sdp","replace","acceptAnswer","notified","end","removeTrack","includes","addIceCandidate","RTCIceCandidate","icons","style","maxWidth","CSSTransition","in","timeout","classNames","unmountOnExit","kind","foundTrack","enabled","Compose","openPicker","setOpenPicker","fileInputRef","composeInputRef","setMessage","recordStream","mediaRecorder","discardRecordFlag","chunks","setChunks","isRecording","setIsRecording","readAsB64","file","callback","reader","FileReader","onload","result","onerror","duration","readAsDataURL","stopRecord","state","blob","Blob","hash","BiMicrophone","onMouseDown","stream","MediaRecorder","mimeType","ondataavailable","start","Wave","fromStream","stroke","colors","onMouseUp","onMouseLeave","BiUnlink","click","BiWinkTongue","onEmojiClick","_","emoji","insert","selectionStart","emojifiedMessage","slice","focus","files","match","marginRight","onTouchStart","onTouchEnd","onTouchCancel","toObjectUrl","b64Data","contentType","byteChars","atob","byteNums","Array","i","charCodeAt","byteArray","Uint8Array","URL","createObjectURL","MessagesWindow","messages","fetchMessages","containerRef","firstLoad","scrollHeight","clientHeight","scrollTop","loadMoreMsgs","getMsgDate","date","Date","msgDate","toLocaleTimeString","split","time","dayTime","filter","idx","arr","localTime","past","getTime","toLocaleDateString","pending","trackColor","isIndeterminate","alt","controls","created","seen","ChatWindow","closeCurrent","Messenger","chats","setChats","currentChat","setCurrentChat","setIsCall","fetchOld","setFetchOld","setMessages","setTempMessage","setMsgEvent","oldFlag","fetchChats","response","isArray","msgs","HomeRoute","len","newMessages","findIndex","pendingMessage","c","Routes","path","Component","withRouter","location","TransitionGroup","Preloader","loading","setLoading","hypeDynos","App","reportWebVitals","onPerfEntry","Function","getCLS","getFID","getFCP","getLCP","getTTFB","breakPoints","createBreakpoints","md","theme","extendTheme","styles","global","h1","h2","h3","h4","h5","h6","ReactDOM","render","StrictMode","chakraTheme","getElementById"],"mappings":"yRACaA,EAAY,oDAEZC,EAAG,uCAAG,WAAOC,EAAUC,GAAjB,6BAAAC,EAAA,sDAKf,GAHIC,EAAc,GAGdF,EAAQ,CAGR,IAFIG,EAAa,GACbC,EAAeC,OAAOC,QAAQN,GAClC,MAA2BI,EAA3B,qCAAYG,EAAZ,MAAiBC,EAAjB,OAAkDL,EAAWM,KAAX,UAAmBF,EAAnB,YAA0BC,IACxEL,EAAWO,OAAS,IAAGR,EAAW,WAAOC,EAAWQ,KAAK,OATlD,yBAYRC,MAAM,GAAD,OAfO,6CAeP,OAAcb,GAAd,OAAyBG,IAC5BW,MAAK,SAAAC,GAAG,OAAIA,EAAIC,UAChBF,MAAK,SAAAG,GAAI,OAAIA,KACbC,OAAM,kBAAM,SAfN,2CAAH,wD,gBCGHC,EAAcC,0BA2DZC,MAzDf,YAAmC,IAAZC,EAAW,EAAXA,SAAW,EAGfC,mBAASC,eAAjBC,EAHuB,sBAMEF,mBAAS,IANX,mBAMvBG,EANuB,KAMbC,EANa,OASIJ,oBAAS,GATb,mBASvBK,EATuB,KASZC,EATY,KAYxBC,EAAQC,cAZgB,EAeJR,mBAAS,IAfL,mBAevBS,EAfuB,KAehBC,EAfgB,KA0CxBC,EAAe,CACjBT,OACAO,QACAJ,YACAF,WACAS,oBA7BwB,SAACC,GACzBT,EAAYS,GAEZ,IAAMC,EC1BqB,SAACC,EAAMZ,GAEtC,OADe,IAAIa,IAAJ,UAAWzC,EAAX,iBAA6BwC,EAA7B,YAAqCZ,IDyBjCc,CAAYf,EAAMW,GACjCC,EAAOI,OAAS,kBAAMZ,GAAa,IAEnCQ,EAAOK,UAAY,SAACC,GAChB,IAAM1B,EAAO2B,KAAKC,MAAMF,EAAE1B,MAER,cAAdA,EAAK6B,MAAwB7B,EAAK8B,QAAQT,OAASb,GACnDK,EAAM,CACFkB,MAAO,UACPC,YAAahC,EAAK8B,QAAQG,QAC1BC,OAAQ,QACRC,YAAY,IAEhBvB,GAAa,GAEbQ,EAAOgB,SAENpB,EAAShB,MAYtB,OACI,cAACE,EAAYmC,SAAb,CAAsB7C,MAAOyB,EAA7B,SACKZ,KEHEiC,MAnDf,WAAgB,MAGYhC,mBAAS,IAHrB,mBAGLa,EAHK,KAGCoB,EAHD,OAM6BC,qBAAWtC,GAA7CgB,EANK,EAMLA,oBAAqBP,EANhB,EAMgBA,UANhB,EASwBL,oBAAS,GATjC,mBASLmC,EATK,KASOC,EATP,OAYkBpC,oBAAS,GAZ3B,mBAYLqC,EAZK,KAYIC,EAZJ,KA0BNC,EAAUC,cAOhB,OANAC,qBAAU,WAEFpC,GAAWkC,EAAQpD,KAAKuD,MAC7B,CAACrC,IAIA,8BACI,yBAAQsC,UAAU,cAAlB,UACI,4DACA,gEACA,eAACC,EAAA,EAAD,CAAMC,SAvBG,SAACzB,GAClBA,EAAE0B,iBAEGjC,IAELuB,GAAc,GACdxB,EAAoBC,KAiBZ,UACI,cAAC+B,EAAA,EAAKG,MAAN,UACI,cAACH,EAAA,EAAKI,QAAN,CAAcC,OAAQ,kBAAMX,GAAW,IAAOY,SAAU,SAAC9B,GAAD,OAAOa,EAAQb,EAAE+B,OAAOjE,QAAQkE,UAAWf,IAAYxB,EAAMwC,YAAY,wBAErI,cAACT,EAAA,EAAKG,MAAN,UACI,cAACO,EAAA,EAAD,CAAQ/B,KAAK,SAASgC,QAAQ,UAAUC,SAAUrB,EAAlD,6B,gBC7CXsB,EAAc,SAACC,EAAQC,GAAT,OAAsBnF,EAAI,cAAD,OAAekF,EAAf,aAAkC,CAACC,c,4CCJxE,MAA0B,gDCsH1BC,MA/Gf,YAA8E,IAA/DC,EAA8D,EAA9DA,KAAMC,EAAwD,EAAxDA,WAAYC,EAA4C,EAA5CA,QAASC,EAAmC,EAAnCA,UAAWC,EAAwB,EAAxBA,YAAaC,EAAW,EAAXA,SAGvDhE,EAAQgC,qBAAWtC,GAAnBM,KAIDiE,EAAWN,EAAKO,MAAMC,MAAK,SAAAC,GAAI,OAAIA,EAAKvD,OAASb,KAPkB,EAUnCF,mBAAS6D,EAAKU,cAVqB,mBAUlEC,EAVkE,KAUrDC,EAVqD,OAa7CzE,mBAAS6D,EAAKa,QAb+B,mBAalEA,EAbkE,KAa1DC,EAb0D,KAgBnEC,EAAYC,iBAAO,MAGnBC,EAAmBD,iBAAO,IAAIE,MAAMC,IAG1CvC,qBAAU,WACiB,aAAX,OAARyB,QAAQ,IAARA,OAAA,EAAAA,EAAU3C,OAAsB2C,EAAS1C,QAAQqC,OAASA,EAAKoB,KAC3DpB,EAAKoB,MAAL,OAAYnB,QAAZ,IAAYA,OAAZ,EAAYA,EAAYmB,KACxBN,EAAUD,EAAS,GAEvBD,EAAeP,EAAS1C,YAE7B,CAAC0C,IAGJ,IAAMgB,EAAW,WACb,GAAIrB,EAAKoB,MAAL,OAAYnB,QAAZ,IAAYA,OAAZ,EAAYA,EAAYmB,IAAI,CAC5B,IAAMvF,EAAO,CAAC6B,KAAM,OAAQC,QAAS,CAACT,KAAMb,IAC5C0E,EAAUO,QAAQC,KAAK/D,KAAKgE,UAAU3F,IACtCiF,EAAU,KAwDlB,OAnDAlC,qBAAU,WJxCqB,IAACiB,EIsD5B,OAbAkB,EAAUO,SJzCkBzB,EIyCYG,EAAKoB,GJxClC,IAAIjE,IAAJ,UAAWzC,EAAX,iBAA6BmF,KIyCxCkB,EAAUO,QAAQhE,UAAY,SAACC,GAC3B,IAAM1B,EAAO2B,KAAKC,MAAMF,EAAE1B,MAC1BsE,EAAUtE,GACQ,YAAdA,EAAK6B,MAAsB7B,EAAK8B,QAAQ8D,OAAOvE,OAASb,IACnDqF,SAASC,WAITN,IAFDJ,EAAiBK,QAAQM,SAM9B,kBAAMb,EAAUO,QAAQrD,WAChC,IAGHW,qBAAU,WAGN,OAFAiD,OAAOC,iBAAiB,QAAST,GAE1B,WACHQ,OAAOE,oBAAoB,QAASV,MAEzC,CAACA,IAEJzC,qBAAU,WAIN,GAAMwB,EAAYtC,SAAWkC,EAAKoB,MAAL,OAAYnB,QAAZ,IAAYA,OAAZ,EAAYA,EAAYmB,KAA4B,QAArBhB,EAAY1C,KAAxE,CACA,IAAM7B,EAAO,CAAC6B,KAAM0C,EAAY1C,KAAMC,QAASyC,EAAYtC,SAC3DiD,EAAUO,QAAQC,KAAK/D,KAAKgE,UAAU3F,OACvC,CAACuE,IAGJxB,qBAAU,WACNyC,MACD,CAACpB,IAcA,qBAAKnB,UAAS,eAAUkB,EAAKoB,MAAL,OAAYnB,QAAZ,IAAYA,OAAZ,EAAYA,EAAYmB,IAAK,SAAW,IAAMlB,QAASA,EAA/E,SACI,sBAAKpB,UAAU,4BAAf,UACI,cAAC,IAAD,CAAQkD,MAAM,OAAOC,OAAO,SAC5B,eAAC,IAAD,CAAKC,OAAO,SAASC,SAAU,EAAGC,KAAM,CAACC,KAAM,MAAOC,GAAI,MAAOC,GAAI,MAAOC,GAAI,OAAhF,UACI,cAAC,IAAD,CAASC,SAAU,GAAIC,WAAW,MAAlC,SAAyCpC,EAAShE,WAClD,oBAAIwC,UAAU,OAAd,SACI,cAAC,IAAD,CAAO6D,KAjBJ,SAAC7E,GACpB,IAAM8E,EAAc,gCAA4BtC,EAAShE,SAArC,MACpB,IAAKwB,EAAS,OAAO8E,EACrB,IAAMC,EAAgB/E,EAAQ2D,OAAOvE,OAASb,EAAO,MAAQiE,EAAShE,SACtE,OAAIwB,EAAQ6E,KAAa7E,EAAQ6E,KAC7B7E,EAAQgF,WAAkB,GAAN,OAAUD,EAAV,uBACpB/E,EAAQiF,MAAa,GAAN,OAAUF,EAAV,yBACZD,EAUsBI,CAAerC,UAIhCE,EAAS,GACT,cAAC,IAAD,CAAKoC,aAAa,MAAMjB,MAAM,OAAOC,OAAO,OAAOiB,QAAQ,OAAOC,eAAe,SAASC,UAAU,SAASC,WAAW,SAASvE,UAAU,UAAUwE,MAAM,QAAQZ,WAAW,OAAOD,SAAU,GAA/L,SAAoM5B,U,iBC/GzM,MAA0B,0C,kBCyH1B0C,MArHf,YAA4G,IAA7FC,EAA4F,EAA5FA,WAAYC,EAAgF,EAAhFA,cAAeC,EAAiE,EAAjEA,KAAMC,EAA2D,EAA3DA,YAAaC,EAA8C,EAA9CA,QAASC,EAAqC,EAArCA,aAAcC,EAAuB,EAAvBA,WAAYC,EAAW,EAAXA,SAGtFC,EAAU,CACZ,CAACC,KAAMC,IAAcC,WAAY,MAAOjE,QAAS,kBAAM0D,KAAWQ,WAAW,GAC7E,CAACH,KAAMI,IAASF,WAAY,WAAYjE,QAAS,kBAAMsD,KAAcY,YAAW,OAACV,QAAD,IAACA,OAAD,EAACA,EAAMY,UAIrFC,EAAc,CAChB,CAACN,KAAMO,IAASL,WAAY,aAAcjE,QAASuD,GACnD,CAACQ,KAAMQ,IAASN,WAAY,WAAYjE,QAAS,kBAAMyD,EAAY,WACnE,CAACM,KAAMI,IAASF,WAAY,WAAYjE,QAAS,kBAAMyD,EAAY,YAZgC,EAgB/ExH,mBAAS,CAAC4G,OAAO,EAAO2B,OAAO,IAhBgD,mBAgBhGC,EAhBgG,KAgB1FC,EAhB0F,KA8BvGhG,qBAAU,WAEe,eAAb,OAAJ8E,QAAI,IAAJA,OAAA,EAAAA,EAAM3F,SAAwB6G,EAAQ,CAAC7B,OAAO,EAAO2B,OAAO,MACjE,CAAChB,IAGJ,IAAMmB,EAAmB,CACrB,CAACZ,KAAMU,EAAK5B,MAAQ+B,IAAoBC,IAAcZ,WAAY,aAAcjE,QAlB5D,WACpB4D,EAAW,SACXc,EAAQ,2BAAID,GAAL,IAAW5B,OAAQ4B,EAAK5B,UAgB2EqB,WAAW,GACrH,CAACH,KAAMU,EAAKD,MAAQM,IAAeP,IAASN,WAAY,aAAcjE,QAblD,WACpB4D,EAAW,SACXc,EAAQ,2BAAID,GAAL,IAAWD,OAAQC,EAAKD,UAWiEN,UAA0B,WAAX,OAAJV,QAAI,IAAJA,OAAA,EAAAA,EAAMhG,OACjH,CAACuG,KAAMC,IAAcC,WAAY,MAAOjE,QAAS,kBAAM0D,KAAWQ,WAAW,IAa3Ea,EAAWjE,iBAAO,MAOxB,OAJApC,qBAAU,WACe,eAAb,OAAJ8E,QAAI,IAAJA,OAAA,EAAAA,EAAM3F,UAAwBkH,EAAS3D,QAAQ4D,UAAYrB,KAChE,CAACH,IAGA,eAAC,IAAD,CAAK5E,UAAU,cAAcqF,WAA6B,eAAb,OAAJT,QAAI,IAAJA,OAAA,EAAAA,EAAM3F,QAAyB,kBAAoB,OAA5F,UACI,eAAC,IAAD,CAAKoH,WAA2B,WAAX,OAAJzB,QAAI,IAAJA,OAAA,EAAAA,EAAMhG,OAAqC,eAAb,OAAJgG,QAAI,IAAJA,OAAA,EAAAA,EAAM3F,QAAyB,UAAY,SAAUqH,EAAE,OAAOC,QAAQ,SAAShC,WAAW,SAArI,UACI,cAAC,IAAD,CAAQrB,MAAM,QAAQC,OAAO,UAC7B,cAAC,IAAD,CAAMQ,SAAU,GAAIC,WAAY,IAAKY,MAAM,QAAQgC,QAAQ,OAA3D,SAEyB,WAAb,OAAJ5B,QAAI,IAAJA,OAAA,EAAAA,EAAM3F,QACN,aAvBE,WAClB,GAAK2F,EACL,MAAmB,cAAhBA,EAAK3F,OAAwB,OAAOgG,QAAP,IAAOA,OAAP,EAAOA,EAAUzH,SAC7B,mBAAhBoH,EAAK3F,OAAoC,eACzC2F,EAAKY,OAAc,WAAN,cAAkBP,QAAlB,IAAkBA,OAAlB,EAAkBA,EAAUzH,UACxC,UAAUoH,EAAK6B,KAAf,eAAwC,UAAd7B,EAAKhG,KAAmB,QAAU,GAA5D,kBAmBW8H,QAKS,gBAAb,OAAJ9B,QAAI,IAAJA,OAAA,EAAAA,EAAM3F,SACN,cAAC,IAAD,CAAKqH,EAAE,OAAOjC,eAAe,SAASE,WAAW,SAASoC,UAAU,QAApE,SAEQzB,EAAQ0B,KAAI,WAAyCC,GAAzC,IAAE1B,EAAF,EAAEA,KAAME,EAAR,EAAQA,WAAYjE,EAApB,EAAoBA,QAApB,SAA6BkE,WAErC,cAAC,IAAD,CAAQd,MAAM,QAAQsC,QAAQ,OAAOC,YAAa1B,EAAY2B,aAAa,OAAO9D,MAAM,OAAOC,OAAO,OAAO/B,QAASA,EAAtH,SACI,cAAC+D,EAAD,CAAM8B,KAAM,MADoHJ,QAQ/H,WAAb,OAAJjC,QAAI,IAAJA,OAAA,EAAAA,EAAM3F,SACN,cAAC,IAAD,CAAKqH,EAAE,OAAOjC,eAAe,SAASE,WAAW,SAASoC,UAAU,QAApE,SAEQlB,EAAYmB,KAAI,WAA8BC,GAA9B,IAAE1B,EAAF,EAAEA,KAAME,EAAR,EAAQA,WAAYjE,EAApB,EAAoBA,QAApB,OACZ,cAAC,IAAD,CAAQoD,MAAM,QAAQsC,QAAQ,OAAOC,YAAa1B,EAAY2B,aAAa,OAAO9D,MAAM,OAAOC,OAAO,OAAO/B,QAASA,EAAtH,SACI,cAAC+D,EAAD,CAAM8B,KAAM,MADoHJ,QAQ/H,eAAb,OAAJjC,QAAI,IAAJA,OAAA,EAAAA,EAAM3F,SACN,cAAC,IAAD,CAAKqH,EAAE,OAAOjC,eAAe,SAASE,WAAW,SAASoC,UAAU,QAApE,SAEQZ,EAAiBa,KAAI,WAAyCC,GAAzC,IAAE1B,EAAF,EAAEA,KAAME,EAAR,EAAQA,WAAYjE,EAApB,EAAoBA,QAApB,SAA6BkE,WAE9C,cAAC,IAAD,CAAQd,MAAM,QAAQsC,QAAQ,OAAOC,YAAa1B,EAAY2B,aAAa,OAAO9D,MAAM,OAAOC,OAAO,OAAO/B,QAASA,EAAtH,SACI,cAAC+D,EAAD,CAAM8B,KAAM,MADoHJ,QAQ/H,eAAb,OAAJjC,QAAI,IAAJA,OAAA,EAAAA,EAAM3F,SACN,cAAC,IAAD,CAAKiI,GAAG,QAAQC,IAAKpC,EAAcqC,UAAQ,EAACC,SAAS,QAAQC,IAAK,EAAGC,KAAM,EAAGC,UAAU,OAAOC,SAAS,OAAOC,UAAU,QAAQC,QAAS,EAAGC,IAAK,SAAApH,GAAM,OAAI2F,EAAS3D,QAAUhC,GAAQqH,UAAU,yB,OCqHlMC,MA/Nf,YAA6F,IAA/EC,EAA8E,EAA9EA,gBAAiBxG,EAA6D,EAA7DA,SAAUyG,EAAmD,EAAnDA,OAAQC,EAA2C,EAA3CA,OAAQ/G,EAAmC,EAAnCA,KAAMgH,EAA6B,EAA7BA,iBAAkBjD,EAAW,EAAXA,SAGvEkD,EAAiBjG,iBAAO,MAGxB6C,EAAe7C,iBAAO,IAAIkG,aAG1BC,EAAcnG,iBAAO,MAT6D,EAYzD3C,qBAAWtC,GAAnCO,EAZiF,EAYjFA,SAAgBY,EAZiE,EAYvEb,KAGX+K,EAAuB,WACzBH,EAAe3F,QAAU,IAAI+F,kBAAkB,CAC3CC,WAAY,CACR,CACIC,KAAM,wBACNjL,SAAU,SACVkL,WAAY,mBAEhB,CACID,KAAM,mCAMlBN,EAAe3F,QAAQmG,QAAU,SAAClK,GAC9BsG,EAAavC,QAAQoG,SAASnK,EAAEoK,MAAO9D,EAAavC,UAIxD2F,EAAe3F,QAAQsG,eAAiB,SAACrK,GACrCuJ,EAAO,CAACrF,OAAQ,CAACvE,QAAO,UAAaK,EAAEsK,WAAY,QAIvDZ,EAAe3F,QAAQwG,2BAA6B,SAACvK,GACb,iBAAhCA,EAAE+B,OAAOyI,oBAAuCnE,KAIxDqD,EAAe3F,QAAQ0G,wBAA0B,WACE,cAA3Cf,EAAe3F,QAAQ2G,iBACvBC,GAAQ,SAAAxE,GAAI,kCAASA,GAAT,IAAe3F,OAAQ,mBAMzCoK,EAAiB,uCAAG,WAAOC,GAAP,eAAAtN,EAAA,6DAEhBuN,EAAc,CAChBtF,MAAO,CACHuF,iBAAiB,EACjBC,kBAAkB,EAClBC,kBAAkB,EAClBC,aAAc,CAACC,MAAO,GACtBC,QAAS,EACTC,WAAY,KACZC,WAAY,GACZC,OAAQ,GAEZpE,MAAoB,UAAb0D,GAbW,SAeMW,UAAUC,aAAaC,aAAaZ,GAf1C,OAetBlB,EAAY7F,QAfU,kDAAH,sDAmBjB4H,EAAc,WAChB/B,EAAY7F,QAAQ6H,YAAYC,SAAQ,SAAAzB,GAAK,OAAIV,EAAe3F,QAAQoG,SAASC,EAAOR,EAAY7F,aAzEhB,EAsFhEnF,mBAAS,MAtFuD,mBAsFjFuH,EAtFiF,KAsF3EwE,EAtF2E,KAyFlFmB,EAAerI,iBAAO,IAAIE,MAAMoI,IAGhCC,EAAcvI,iBAAO,MAGrBwI,EAAc,uCAAG,WAAOpB,GAAP,eAAAtN,EAAA,6DACnBsM,IADmB,SAEbe,EAAkBC,GAFL,cAGnBc,IAHmB,SAICjC,EAAe3F,QAAQmI,cAJxB,cAIbC,EAJa,gBAKbzC,EAAe3F,QAAQqI,oBAAoBD,GAL9B,OAMnB5C,EAAO,CAACrF,OAAQ,CAACvE,OAAMZ,YAAWoN,QAAOtB,WAAUrE,SAAUA,EAAS7G,MAAO,OAE7EmM,EAAa/H,QAAQM,OACrBsG,EAAQ,CAACnK,OAAQ,aAAcL,KAAM0K,EAAU7C,KAAMjJ,EAAUgI,QAAQ,IAEvEiF,EAAYjI,QAAUsI,YAAW,WAC7B1B,EAAQ,MACRmB,EAAa/H,QAAQuI,QACrBR,EAAa/H,QAAQwI,YAAc,EAEnC3C,EAAY7F,QAAQ6H,YAAYC,SAAQ,SAAAzB,GAAK,OAAIA,EAAMoC,YACxDC,MAjBgB,4CAAH,sDAqBdC,EAAW,uCAAG,4BAAAnP,EAAA,6DAEhBoP,aAAaX,EAAYjI,SACzB4G,EAAQ,2BAAIxE,GAAL,IAAW3F,OAAQ,oBAHV,SAIVkJ,EAAe3F,QAAQ6I,qBAAqB,IAAIC,sBAAsB1G,EAAK2G,WAJjE,uBAKKpD,EAAe3F,QAAQgJ,eAL5B,cAKVC,EALU,QAMTC,IAAMD,EAAOC,IAAIC,QAAQ,iBAAkB,sDANlC,UAOVxD,EAAe3F,QAAQqI,oBAAoBY,GAPjC,QAQhBzD,EAAO,CAACrF,OAAQ,CAACvE,OAAMZ,YAAWiO,SAAQxG,SAAUA,EAAS7G,MAAO,OARpD,4CAAH,qDAYXwN,EAAY,uCAAG,WAAOH,GAAP,SAAAzP,EAAA,6DACjBoP,aAAaX,EAAYjI,SACzB4G,EAAQ,2BAAIxE,GAAL,IAAW3F,OAAQ,oBAFT,SAGXkJ,EAAe3F,QAAQ6I,qBAAqB,IAAIC,sBAAsBG,IAH3D,2CAAH,sDAYZ3G,EAAU,SAAC+G,GAAc,IAAD,IAE1BT,aAAaX,EAAYjI,SAEzB4G,EAAQ,2BAAIxE,GAAL,IAAW3F,OAAQ,WAE1BsL,EAAa/H,QAAQuI,QACrBR,EAAa/H,QAAQwI,YAAc,EACnC,UAAA7C,EAAe3F,eAAf,SAAwBrD,QACxBgJ,EAAe3F,QAAU,KAGpBqJ,GACD7D,EAAO,CAACrF,OAAQ,CAACvE,QAAO0N,KAAK,EAAM7G,SAAQ,OAAEA,QAAF,IAAEA,OAAF,EAAEA,EAAU7G,KAAM8C,KAAI,OAAEA,QAAF,IAAEA,OAAF,EAAEA,EAAMoB,IAAK,OAGlF,UAAA+F,EAAY7F,eAAZ,SAAqB6H,YAAYC,SAAQ,SAAAzB,GAAK,OAAIA,EAAMoC,UACxD5C,EAAY7F,QAAU,KAEtBuC,EAAavC,QAAQ6H,YAAYC,SAAQ,SAAAzB,GAAK,OAAI9D,EAAavC,QAAQuJ,YAAYlD,OAIvF/I,qBAAU,WAEN,IAAY,OAARyB,QAAQ,IAARA,OAAA,EAAAA,EAAU1C,QAAQ8D,SAAUpB,EAAS1C,QAAQ8D,OAAOvE,OAASA,EAAM,CAAC,IAAD,EACnE,GAAImD,EAAS1C,QAAQoG,WAAa7G,EAAM,CACpC,GAAImD,EAAS1C,QAAQ+L,MAAO,CAExB,GAAIhG,GAAQ,CAAC,aAAc,aAAaoH,SAASpH,EAAK3F,QAAS,OAC/DiJ,GAAkB3G,EAAS1C,QAAQkC,QACnCuH,IACAe,EAAkB9H,EAAS1C,QAAQyK,UAAU1M,KAAKwN,GAClDhB,EAAQ,CAACnK,OAAQ,aAAcL,KAAM2C,EAAS1C,QAAQyK,SAAU7C,KAAMlF,EAAS1C,QAAQ8D,OAAOnF,SAAU+N,SAAUhK,EAAS1C,QAAQ+L,QACnIL,EAAa/H,QAAQM,OACrB2H,EAAYjI,QAAUsI,YAAW,WAC7B1B,EAAQ,MACRmB,EAAa/H,QAAQuI,QACrBR,EAAa/H,QAAQwI,YAAc,IACpCE,MAEH3J,EAAS1C,QAAQ4M,QAAQG,EAAarK,EAAS1C,QAAQ4M,QACvDlK,EAAS1C,QAAQiN,MAAQvK,EAAS1C,QAAQkC,UAAlB,OAA6BG,QAA7B,IAA6BA,OAA7B,EAA6BA,EAAMoB,KAAIwC,GAAQ,GAE3EvD,EAAS1C,QAAQkK,YAAW,UAAAZ,EAAe3F,eAAf,SAAwByJ,gBAAgB,IAAIC,gBAAgB3K,EAAS1C,QAAQkK,gBAElH,CAACxH,IAEJzB,qBAAU,WAEM,IAAD,GADXmI,EAAOrD,GACFA,KACD,UAAAuD,EAAe3F,eAAf,SAAwBrD,QACxBgJ,EAAe3F,QAAU,MAER,eAAb,OAAJoC,QAAI,IAAJA,OAAA,EAAAA,EAAM3F,UACNsL,EAAa/H,QAAQuI,QACrBR,EAAa/H,QAAQwI,YAAc,KAExC,CAACpG,IAGJ,IAAMuH,EAAQ,CACV,CAAChH,KAAMI,IAASnE,QAAS,kBAAMsJ,EAAe,WAC9C,CAACvF,KAAMQ,IAASvE,QAAS,kBAAMsJ,EAAe,WAC9C,CAACvF,KAAMO,IAAStE,QAAS2G,IAG7B,OACI,sBAAK/H,UAAU,mDAAmDoM,MAAO,CAACC,SAAU,SAApF,UAEQF,EAAMvF,KAAI,WAAkBC,GAAlB,IAAE1B,EAAF,EAAEA,KAAM/D,EAAR,EAAQA,QAAR,OACN,cAAC,IAAD,CAAwBA,QAASA,EAASR,QAAQ,QAAQkG,QAAQ,OAAOC,YAAY,YAAYE,KAAK,KAAtG,SACI,cAAC9B,EAAD,CAAM8B,KAAM,MADCJ,MAKzB,cAACyF,EAAA,EAAD,CAAeC,GAAa,OAAT3H,EAAe4H,QAAS,IAAKC,WAAW,OAAOC,eAAa,EAA/E,SACI,cAAC,EAAD,CAAM9H,KAAMA,EAAMC,YAAa6F,EAAgB5F,QAASA,EAASH,cAlFvD,WAClByE,EAAQ,OAiF+F1E,WAAYyG,EAAapG,aAAcA,EAAavC,QAASwC,WA5IhJ,SAAC2H,GACrB,IAAMC,EAAavE,EAAY7F,QAAQ6H,YAAY3I,MAAK,SAAAmH,GAAK,OAAIA,EAAM8D,OAASA,KAChFC,EAAWC,SAAWD,EAAWC,SA0IgK5H,SAAUA,U,mDCzCpM6H,MAjLf,YAAkC,IAAhB9E,EAAe,EAAfA,OAAQ5J,EAAO,EAAPA,KAAO,EAGOf,oBAAS,GAHhB,mBAGtB0P,EAHsB,KAGVC,EAHU,KAMvBC,EAAe/K,iBAAO,MAGtBgL,EAAkBhL,iBAAO,MAGzBtE,EAAQC,cAZe,EAeCR,mBAAS,IAfV,mBAetB2B,EAfsB,KAebmO,EAfa,KAkBvBC,EAAelL,iBAAO,MAGtBmL,EAAgBnL,iBAAO,MAGvBoL,EAAoBpL,kBAAO,GAxBJ,EA2BD7E,mBAAS,IA3BR,mBA2BtBkQ,EA3BsB,KA2BdC,EA3Bc,OA8BSnQ,oBAAS,GA9BlB,mBA8BtBoQ,EA9BsB,KA8BTC,EA9BS,KAiCvBC,EAAY,SAACC,EAAMC,GACrB,IAAMC,EAAS,IAAIC,WACnBD,EAAOE,OAAS,SAACvP,GAAD,OAAOoP,EAASpP,EAAE+B,OAAOyN,OAAOtC,QAAQ,mBAAoB,MAC5EmC,EAAOI,QAAU,WACbtQ,EAAM,CACFkB,MAAO,UACPC,YAAa,iCACbE,OAAQ,QACRkP,SAAU,IACVjP,YAAY,KAGpB4O,EAAOM,cAAcR,IA4BnBS,EAAa,WACVhB,EAAc7K,SAA2C,aAAhC6K,EAAc7K,QAAQ8L,QACpDjB,EAAc7K,QAAQyI,OACtByC,GAAe,GACfN,EAAa5K,QAAQ6H,YAAYC,SAAQ,SAAAzB,GAAK,OAAIA,EAAMoC,YAS5DnL,qBAAU,WAEN,GAAIyN,EAAO9Q,SAAW6Q,EAAkB9K,QAAS,CAC7C,IAAM+L,EAAO,IAAIC,KAAKjB,EAAQ,CAAC3O,KAAM,eACrC+O,EAAUY,GAAM,SAACN,GACbjG,EAAO,CAACrF,OAAQ,CAACvE,QAAO6F,MAAOgK,EAAQQ,KAAMnR,gBAC7CkQ,EAAU,UAGnB,CAACD,IAGJ,IAuBMpB,EAAQ,CACV,CAAChH,KAAMuJ,IAAcC,YAzEL,WAChBrB,EAAkB9K,SAAU,EAC5BkL,GAAe,GACfzD,UAAUC,aAAaC,aAAa,CAChClG,OAAO,IAEVrH,MAAK,SAACgS,GACHxB,EAAa5K,QAAUoM,EACvBvB,EAAc7K,QAAU,IAAIqM,cAAczB,EAAa5K,QAAS,CAACsM,SAAU,eAC3EzB,EAAc7K,QAAQuM,gBAAkB,SAACtQ,GACjCA,EAAE1B,KAAKkK,KAAO,GAAGuG,EAAU,GAAD,mBAAKD,GAAL,CAAa9O,EAAE1B,SAEjDsQ,EAAc7K,QAAQwM,SACX,IAAIC,KACVC,WAAW9B,EAAa5K,QAAS,yBAA0B,CAC5D5D,KAAM,QACNuQ,OAAQ,EACRC,OAAQ,CAAC,QAAS,QAAS,cAGlCpS,OAAM,kBAAM0Q,GAAe,OAqDmB2B,UAAWhB,EAAYiB,aAzCpD,WAClBhC,EAAkB9K,SAAU,EAC5B6L,MAwCA,CAAClJ,KAAMoK,IAAUnO,QAAS,kBAAM6L,EAAazK,QAAQgN,UACrD,CAACrK,KAAMsK,IAAcrO,QAAS,kBAAM4L,GAAeD,MAsBvD,OACI,sBAAK/M,UAAU,UAAf,UACI,cAAC,IAAD,CAAKqH,SAAS,WAAWC,IAAI,QAAQC,KAAK,OAAOI,OAAQ,GAAIrH,OAAQ,kBAAM0M,GAAc,IAAQ5I,QAAS2I,EAAa,QAAU,OAAjI,SACI,cAAC,IAAD,CAAa2C,aArBA,SAACC,EAAGC,GACzB,IAAMC,EAAS3C,EAAgB1K,QAAQsN,eACjCC,EAAgB,UAAM/Q,EAAQgR,MAAM,EAAGH,IAAvB,OAAiCD,EAAMA,OAAvC,OAA+C5Q,EAAQgR,MAAMH,EAAQ7Q,EAAQvC,SACnG0Q,EAAW4C,GACX/C,GAAc,GACdE,EAAgB1K,QAAQyN,aAkBpB,uBAAOrR,KAAK,OAAOwN,MAAO,CAAChI,QAAS,QAASwD,IAAK,SAAApH,GAAM,OAAIyM,EAAazK,QAAUhC,GAAQD,SArD/E,SAAC9B,GACjB,IAAMmP,EAAOnP,EAAE+B,OAAO0P,MAAM,GAC5B,GAAKtC,EAAL,CAEIA,EAAKhP,KAAKuR,MADK,eAEfxC,EAAUC,GAAM,SAACK,GACbjG,EAAO,CAACrF,OAAQ,CAACvE,QAAO4F,WAAYiK,EAAQQ,KAAMnR,gBAElD2P,EAAazK,QAAQjG,MAAQ,QAIjCqB,EAAM,CACFkB,MAAO,qBACPC,YAAa,2CACbE,OAAQ,QACRkP,SAAU,IACVjP,YAAY,QAqChB,sBAAKc,UAAU,qEAAqEoM,MAAO,CAACC,SAAU,QAAS+D,YAAa,QAA5H,UAEQjE,EAAMvF,KAAI,WAAwDC,GAAxD,IAAE1B,EAAF,EAAEA,KAAM/D,EAAR,EAAQA,QAASuN,EAAjB,EAAiBA,YAAaU,EAA9B,EAA8BA,UAAWC,EAAzC,EAAyCA,aAAzC,OACN,cAAC,IAAD,CAAYpI,GAAG,SAAqB9F,QAASA,EAAS2F,YAAY,YAAYnG,QAAQ,QAAQkG,QAAQ,OAAOG,KAAK,KAAK0H,YAAaA,EAAaU,UAAWA,EAAWgB,aAAc1B,EAAa2B,WAAYjB,EAAWC,aAAcA,EAAciB,cAAejB,EAApQ,SACI,cAACnK,EAAD,CAAM8B,KAAM,MADaJ,MAMjC4G,GACA,cAAC,IAAD,CAAKpG,SAAS,WAAWC,IAAI,QAAQC,KAAK,IAAIvH,UAAU,aAAawG,QAAQ,OAAOtD,MAAM,cAAcC,OAAO,cAAcgB,aAAa,OAA1I,SACI,wBAAQ7B,GAAG,yBAAyBY,MAAM,QAAQC,OAAO,cAIrE,uBAAMnD,UAAU,4BAA4BE,SA9B/B,SAACzB,GAClBA,EAAE0B,iBAEGnB,IACLgJ,EAAO,CAACrF,OAAQ,CAACvE,QAAOyF,KAAM7E,EAASyP,KAAMnR,gBAC7C6P,EAAW,IACXD,EAAgB1K,QAAQyN,UAwBpB,UACI,cAAC,IAAD,CAAO1T,MAAOyC,EAASuB,SAAU,SAAA9B,GAAC,OAAI0O,EAAW1O,EAAE+B,OAAOjE,QAAQmE,YAAY,cAAckH,IAAK,SAAApH,GAAM,OAAI0M,EAAgB1K,QAAUhC,KACrI,cAAC,IAAD,CAAY5B,KAAK,SAASmI,YAAY,YAAYD,QAAQ,OAAOG,KAAK,KAAtE,SACI,cAAC,IAAD,CAAQA,KAAM,cCjLrBuJ,EAAc,SAACC,EAASC,GAGjC,IAFA,IAAMC,EAAYC,KAAKH,GACjBI,EAAW,IAAIC,MAAMH,EAAUlU,QAC5BsU,EAAI,EAAGA,EAAIF,EAASpU,OAAQsU,IACjCF,EAASE,GAAKJ,EAAUK,WAAWD,GAEvC,IAAME,EAAY,IAAIC,WAAWL,GAC3BtC,EAAO,IAAIC,KAAK,CAACyC,GAAY,CAACrS,KAAM8R,IAE1C,OADYS,IAAIC,gBAAgB7C,I,SC4GrB8C,MA/Gf,YAAgE,IAAvCC,EAAsC,EAAtCA,SAAUlT,EAA4B,EAA5BA,KAAMmT,EAAsB,EAAtBA,cAAerQ,EAAO,EAAPA,KAG9CsQ,EAAetP,iBAAO,MAGtBuP,EAAYvP,kBAAO,GAEzBpC,qBAAU,WAEF0R,EAAahP,QAAQkP,aAAeF,EAAahP,QAAQmP,cAAgBF,EAAUjP,UACnFgP,EAAahP,QAAQoP,UAAYJ,EAAahP,QAAQkP,aACtDD,EAAUjP,SAAU,GAEe,IAAnCgP,EAAahP,QAAQoP,YACzBJ,EAAahP,QAAQoP,UAAYJ,EAAahP,QAAQkP,gBACvD,CAACJ,IAGJ,IAAMO,EAAe,SAACpT,GAES,IAAvBA,EAAE+B,OAAOoR,WAAoBH,EAAUjP,SACvC+O,KAKFO,EAAa,SAACC,GAChBA,EAAOA,GAAQ,IAAIC,KACnB,IAAMC,EAAU,IAAID,KAAKD,GAFA,EAGHE,EAAQC,qBAAqBC,MAAM,KAHhC,mBAGpBC,EAHoB,KAGdC,EAHc,KAIzBD,EAAOA,EAAKD,MAAM,KAAKG,QAAO,SAAC3C,EAAG4C,EAAKC,GAAT,OAAiBD,IAAQC,EAAI/V,OAAS,KAAGC,KAAK,KAC5E,IAAM+V,EAAS,UAAML,EAAN,YAAcC,GACvBK,IAAQ,IAAIV,MAAOW,UAAYV,EAAQU,WAAhC,MACb,OAAID,EAAO,EAAUD,EACjBC,GAAQ,GAAKA,EAAO,EAAS,gBAAN,OAAuBD,GACtCR,EAAQW,sBAWxB,OARA9S,qBAAU,WACN2R,EAAUjP,SAAU,IACrB,CAACtB,IAEJpB,qBAAU,WACN0R,EAAahP,QAAQQ,iBAAiB,SAAU6O,KACjD,IAGC,qBAAK7R,UAAU,kBAAkB4H,IAAK,SAAApH,GAAM,OAAIgR,EAAahP,QAAUhC,GAAvE,SAEQ8Q,EAAS1K,KAAI,SAAC5H,EAASuT,EAAKC,GAAf,OACT,sBACIxS,UAAS,6EAEHhB,EAAQ2D,OAAOvE,OAASA,EAAO,OAAS,GAFrC,yCAGHY,EAAQ6T,QAAU,UAAY,GAH3B,8BADb,UASQ7T,EAAQ6E,KACR,qBAAK7D,UAAU,OAAf,SACI,cAAC,IAAD,CAAO6D,KAAM7E,EAAQ6E,SAGzB,qCAEI7E,EAAQgF,aAEJhF,EAAQ6T,QACR,cAAC,IAAD,CAAKvM,EAAE,OAAO/B,WAAW,SAASF,eAAe,SAASmD,UAAU,QAApE,SACI,cAAC,IAAD,CAAkBsL,WAAW,cAAc7L,KAAM,EAAG8L,iBAAe,MAGvE,qBAAK5L,IAAKqJ,EAAYxR,EAAQgF,WAAY,WAAYgP,IAAI,MAI9DhU,EAAQiF,QAEJjF,EAAQ6T,QACR,cAAC,IAAD,CAAKvM,EAAE,OAAO/B,WAAW,SAASF,eAAe,SAASmD,UAAU,QAApE,SACI,cAAC,IAAD,CAAkBsL,WAAW,cAAc7L,KAAM,EAAG8L,iBAAe,MAGvE,uBAAO5L,IAAKqJ,EAAYxR,EAAQiF,MAAO,cAAegP,UAAQ,SAMpEjU,EAAQ6T,SAAW7T,EAAQ2D,OAAOvE,OAASA,GAAQmU,IAAQC,EAAI/V,OAAS,GAC1E,sBAAKuD,UAAU,cAAf,UACI,sBAAMA,UAAU,OAAhB,SACK8R,EAAW9S,EAAQkU,WAGpBlU,EAAQmU,KACR,cAAC,IAAD,CAAelM,KAAM,GAAIzC,MAAM,sBAE/B,cAAC,IAAD,CAAeyC,KAAM,GAAIzC,MAAM,cA3CtCxF,EAAQyP,YCjCtB2E,MAvBf,YAAgH,IAA3FlS,EAA0F,EAA1FA,KAAMoQ,EAAoF,EAApFA,SAAU+B,EAA0E,EAA1EA,aAAcrL,EAA4D,EAA5DA,OAAQuJ,EAAoD,EAApDA,cAAehQ,EAAqC,EAArCA,SAAU0G,EAA2B,EAA3BA,OAAQC,EAAmB,EAAnBA,iBAGjF3K,EAAQgC,qBAAWtC,GAAnBM,KAGDiE,EAAQ,OAAGN,QAAH,IAAGA,OAAH,EAAGA,EAAMO,MAAMC,MAAK,SAAAC,GAAI,OAAIA,EAAKvD,OAASb,KAExD,OACI,sBAAKyC,UAAU,cAAf,UACI,sBAAKA,UAAU,UAAf,UACI,sBAAKA,UAAU,4BAAf,UACI,cAAC,IAAD,CAAQkD,MAAM,OAAOC,OAAO,SAC5B,cAAC,IAAD,CAASC,OAAO,SAASO,SAAU,GAAIC,WAAW,MAAlD,gBAAyDpC,QAAzD,IAAyDA,OAAzD,EAAyDA,EAAUhE,cAEvE,cAAC,EAAD,CAAKuK,gBAAiBsL,EAAc9R,SAAUA,EAAUyG,OAAQA,EAAQC,OAAQA,EAAQ/G,KAAMA,EAAMgH,iBAAkBA,EAAkBjD,SAAUzD,OAEtJ,cAAC,EAAD,CAAgB8P,SAAUA,EAAUlT,KAAMb,EAAMgU,cAAeA,EAAerQ,KAAMA,IACpF,cAAC,EAAD,CAAS8G,OAAQA,EAAQ5J,KAAMb,QC4I5B+V,MA5Jf,WAAqB,MAGSjW,mBAAS,IAHlB,mBAGVkW,EAHU,KAGHC,EAHG,OAMqBnW,mBAAS,MAN9B,mBAMVoW,EANU,KAMGC,EANH,OAcWrW,oBAAS,GAdpB,mBAcV4K,EAdU,KAcF0L,EAdE,OAiBgBpU,qBAAWtC,GAArCS,EAjBU,EAiBVA,UAAWH,EAjBD,EAiBCA,KAAMO,EAjBP,EAiBOA,MAjBP,EAoBeT,oBAAS,GApBxB,mBAoBVuW,EApBU,KAoBAC,EApBA,OAuBexW,mBAAS,IAvBxB,mBAuBViU,EAvBU,KAuBAwC,EAvBA,OA0BqBzW,mBAAS,IA1B9B,mBA0BViE,EA1BU,KA0BGyS,EA1BH,OA6Be1W,mBAAS,MA7BxB,mBA6BVkE,EA7BU,KA6BAyS,EA7BA,KAgCXC,EAAU/R,kBAAO,GAGjBgS,EAAU,uCAAG,4BAAAlY,EAAA,sEV1CWH,EAAI,mBAAoB,CAACuC,KU2CnBb,IADjB,OACT4W,EADS,OAEXrD,MAAMsD,QAAQD,IAAWX,EAASW,GAFvB,2CAAH,qDAKhBrU,qBAAU,WACNoU,MACD,IAEHpU,qBAAU,WAEDyT,EAAM7R,MAAK,SAAAR,GAAI,OAAIA,EAAKoB,MAAL,OAAYmR,QAAZ,IAAYA,OAAZ,EAAYA,EAAanR,QAAKoR,EAAe,QACtE,CAACH,EAAOE,IAGX,IAAMlC,EAAa,uCAAG,4CAAAvV,EAAA,yDAAOgF,EAAP,+BAAkB,KAC/ByS,EADa,wDAEbzS,GAAU8S,EAAY,IACvBO,EAAO,GACPrT,IAAUqT,EAAI,YAAO/C,IAJP,SAKKxQ,EAAY2S,EAAYnR,GAAItB,GALjC,OAKZmT,EALY,OAMlBN,GAAY,GACR/C,MAAMsD,QAAQD,IAAWL,EAAY,GAAD,mBAAKK,GAAL,YAAkBE,KAPxC,4CAAH,qDAWbzU,EAAUC,cAEhBC,qBAAU,WAEDpC,GAAWkC,EAAQpD,KAAK8X,MAC9B,CAAC5W,IAEJoC,qBAAU,WAEa,WAAfhC,EAAMc,MAAoC,WAAfd,EAAMc,OACjCsV,IACAF,EAAYlW,MAEjB,CAACA,IAGJ,IAAMuD,EAAY,SAACvD,GAAD,OAAWkW,EAAYlW,IA6DzC,OAlDAgC,qBAAU,WAEF2T,EACAlC,IAECuC,EAAY,MAClB,CAACL,IAEJ3T,qBAAU,WAEN,GAAImU,EAAQzR,QACRyR,EAAQzR,SAAU,MADtB,CAKA,IACM+R,EAAMjD,EAAS7U,OACjB8X,EAFQ,IAEKjD,EAASiD,EAAM,GAAG5R,OAAOvE,OAASb,GAC/CuW,EAAYxC,EAAStB,MAAMuE,EAHnB,GAG8BA,OAE3C,CAACjD,IAEJxR,qBAAU,WACN,GAAuB,UAAX,OAARyB,QAAQ,IAARA,OAAA,EAAAA,EAAU3C,OAAmB2C,EAAS1C,QAAQ8D,OAAOvE,OAASb,EAAM,CACpE,IAAMiX,EAAW,YAAOlD,GACxBkD,EAAYlK,SAAQ,SAAAtL,GAAO,OAAIA,EAAQmU,MAAO,KAC9CW,EAAYU,GAGhB,GAAuB,aAAX,OAARjT,QAAQ,IAARA,OAAA,EAAAA,EAAU3C,MAAoB,CAE9B,GAAI2C,EAAS1C,QAAQqC,QAAjB,OAA0BuS,QAA1B,IAA0BA,OAA1B,EAA0BA,EAAanR,IAAI,OAC/C,IAAMkS,EAAW,YAAOlD,GAClBiB,EAAMiC,EAAYC,WAAU,SAAAzV,GAAO,OAAIA,EAAQyP,OAASlN,EAAS1C,QAAQ4P,QAC/E,IAAa,IAAT8D,EAEA,YADAuB,EAAY,GAAD,mBAAKU,GAAL,CAAkBjT,EAAS1C,WAG1C2V,EAAYjC,GAAOhR,EAAS1C,QAC5BiV,EAAYU,MAEjB,CAACjT,IAEJzB,qBAAU,WACwB,IAAD,EAAzB8T,GAAYtC,EAAS,KACrBC,EAAa,UAACD,EAAS,UAAV,aAAC,EAAa4B,SAC3Be,EAAQzR,SAAU,KAEvB,CAACoR,EAAUtC,IAGV,qBAAKtR,UAAU,YAAf,SACI,sBAAKA,UAAU,mBAAf,UACI,qBAAKA,UAAU,kBAAf,SAEQuT,EAAM3M,KAAI,SAAA1F,GAAI,OACV,cAAC,EAAD,CAAoBA,KAAMA,EAAMC,WAAYsS,EAAarS,QAAS,kBAAMsS,EAAexS,IAAOG,UAAWA,EAAWC,YAAaA,EAAaC,SAAUA,GAA7IL,EAAKoB,SAI5B,qBAAKtC,UAAU,SAASoM,MAAO,CAACzE,OAAQ8L,GAAexL,EAAS,GAAK,EAAG7D,QAASqP,GAAexL,EAAS,QAAU,QAAnH,SACI,cAAC,EAAD,CAAYqJ,SAAUA,EAAUpQ,KAAMuS,EAAaJ,aAAc,kBAAMK,EAAe,OAAO1L,OArE9F,SAAChJ,GAA+B,IAAtBJ,EAAqB,uDAAd,UAE5B,GADAmV,EAAe,CAAC/U,UAASJ,SACZ,YAATA,EAAoB,CACpB,IAAM8V,EAAc,2BAAO1V,GAAP,IAAgB6T,SAAS,IAC7CiB,EAAY,GAAD,mBAAKxC,GAAL,CAAeoD,OAiE2FnD,cAAe,kBAAMsC,GAAY,IAAOtS,SAAUA,EAAU0G,OAAQ0L,EAAWzL,iBA5InL,SAAC5F,GACtBoR,EAAeH,EAAM7R,MAAK,SAAAiT,GAAC,OAAIA,EAAErS,KAAOA,iBCfnCgS,GAAY,IACZvU,GAAiB,aAQf6U,GALA,CACX,CAACC,KAAMP,GAAWQ,UAAWzV,GAC7B,CAACwV,KAAM9U,GAAgB+U,UAAWxB,ICcvByB,oBApBf,YAA6B,IAAZC,EAAW,EAAXA,SACb,OACI,cAACC,EAAA,EAAD,CAAiBjV,UAAU,kBAA3B,SACI,cAACsM,EAAA,EAAD,CAAkCG,WAAW,QAAQD,QAAS,IAA9D,SACI,cAAC,IAAD,CAAQwI,SAAUA,EAAlB,SAEQJ,GAAOhO,KAAI,gBAAEiO,EAAF,EAAEA,KAAMC,EAAR,EAAQA,UAAR,OACP,cAAC,IAAD,CAAOD,KAAMA,EAAMjL,OAAK,EAAxB,SACI,qBAAK5J,UAAU,QAAf,SACI,cAAC8U,EAAD,OAFsBD,SAJ1BG,EAAS1Y,U,yBC6B1B4Y,OAhCf,YAAgC,IAAZ9X,EAAW,EAAXA,SAAW,EAGGC,oBAAS,GAHZ,mBAGpB8X,EAHoB,KAGXC,EAHW,KAMrBC,EAAS,uCAAG,sBAAArZ,EAAA,sEbJSH,EAAI,mBaIb,OAEduZ,GAAW,GAFG,2CAAH,qDASf,OAJAtV,qBAAU,WACNuV,MACD,IAGC,mCAEQF,EACA,cAAC,IAAD,CAAK7O,EAAE,OAAOjC,eAAe,SAASE,WAAW,SAASpB,OAAO,QAAQD,MAAM,OAAOmE,SAAS,QAAQC,IAAK,EAAGC,KAAM,EAAGlC,WAAW,qBAAnI,SACI,eAAC,IAAD,CAAKiB,EAAE,OAAO/B,WAAW,SAASgC,QAAQ,SAA1C,UACI,cAAC,IAAD,CAAkBU,KAAM,GAAI8L,iBAAe,IAC3C,cAAC,IAAD,CAAMvO,MAAM,OAAOgC,QAAQ,YAA3B,8CAIRpJ,KCRDkY,OAdf,WACE,OACE,qBAAKtV,UAAU,MAAf,SACE,cAAC,KAAD,UACE,cAAC,EAAD,UACE,cAAC,GAAD,UACE,cAAC,GAAD,aCFGuV,GAZS,SAAAC,GAClBA,GAAeA,aAAuBC,UACxC,8BAAqB7Y,MAAK,YAAkD,IAA/C8Y,EAA8C,EAA9CA,OAAQC,EAAsC,EAAtCA,OAAQC,EAA8B,EAA9BA,OAAQC,EAAsB,EAAtBA,OAAQC,EAAc,EAAdA,QAC3DJ,EAAOF,GACPG,EAAOH,GACPI,EAAOJ,GACPK,EAAOL,GACPM,EAAQN,O,oBCHRO,GAAcC,aAAkB,CAClCxS,GAAI,QACJyS,GAAI,QACJxS,GAAI,QACJC,GAAI,WA6BOwS,GAFDC,aAAY,CAACJ,eAAaK,OAvBzB,CACXC,OAAQ,CACJC,GAAI,CACA3S,SAAU,OAEd4S,GAAI,CACA5S,SAAU,SAEd6S,GAAI,CACA7S,SAAU,UAEd8S,GAAI,CACA9S,SAAU,OAEd+S,GAAI,CACA/S,SAAU,UAEdgT,GAAI,CACAhT,SAAU,c,UCvBtBiT,IAASC,OACP,cAAC,IAAMC,WAAP,UACE,cAAC,KAAD,CAAgBZ,MAAOa,GAAvB,SACE,cAAC,GAAD,QAGJnU,SAASoU,eAAe,SAM1BzB,O","file":"static/js/main.18d17e54.chunk.js","sourcesContent":["export const baseUrl = 'https://direct-messages-api.herokuapp.com';\nexport const socketUrl = 'wss://direct-messages-api.herokuapp.com/websocket';\n\nexport const get = async (endpoint, params) => {\n //Query search paramters string\n let queryString = '';\n\n //Construct query string from paramters object\n if (params) {\n let queryArray = [];\n let queryEntries = Object.entries(params);\n for (const [key, value] of queryEntries) value && queryArray.push(`${key}=${value}`);\n if (queryArray.length > 0) queryString = `?${queryArray.join('&')}`;\n }\n\n return fetch(`${baseUrl}${endpoint}${queryString}`)\n .then(res => res.json())\n .then(data => data)\n .catch(() => null)\n}","import React, {createContext, useState} from 'react';\nimport {v4} from 'uuid';\nimport {connectToMainSocket as connectMain} from 'api/websocket';\nimport {useToast} from '@chakra-ui/react';\n\n\nexport const UUIDContext = createContext();\n\nfunction UUIDProvider({children}) {\n \n //current uuid, automatically generated every time the app starts\n const [UUID] = useState(v4());\n\n //username inserted\n const [username, setUsername] = useState('');\n\n //connection status\n const [connected, setConnected] = useState(false);\n\n //toaster for user friendly messages\n const toast = useToast();\n\n //event of other users creation and deletion\n const [event, setEvent] = useState({});\n\n //function to connect to the main websocket\n const connectToMainSocket = (name) => {\n setUsername(name);\n //Connect using the name and UUID\n const socket = connectMain(UUID, name);\n socket.onopen = () => setConnected(true);\n //Listen to user creation and deletion real time events\n socket.onmessage = (e) => {\n const data = JSON.parse(e.data);\n //Check if the message is an error message and also for current user\n if (data.type === 'exception' && data.payload.uuid === UUID) {\n toast({\n title: 'Whoops!',\n description: data.payload.message,\n status: 'error',\n isClosable: true\n })\n setConnected(false);\n //Close the socket so that user can retry with another name\n socket.close();\n }\n else setEvent(data);\n }\n }\n\n const contextValue = {\n UUID,\n event,\n connected,\n username,\n connectToMainSocket\n }\n\n return (\n \n {children}\n \n )\n}\n\nexport default UUIDProvider\n","import RWS from 'reconnecting-websocket';\nimport {socketUrl} from './index';\n\nexport const connectToMainSocket = (uuid, username) => {\n const socket = new RWS(`${socketUrl}/main/${uuid}/${username}`);\n return socket;\n}\n\nexport const connectToChatSocket = (chatId) => {\n const socket = new RWS(`${socketUrl}/chat/${chatId}`);\n return socket;\n}","import React, {useState, useContext, useEffect} from 'react';\nimport {Form, Button} from 'react-bootstrap';\nimport {UUIDContext} from 'providers/UUIDProvider';\nimport {useHistory} from 'react-router-dom';\nimport {MessengerRoute} from 'router/routes';\n\nfunction Home() {\n\n //the name the user will be using\n const [name, setName] = useState('');\n\n //function for connecting to main socket\n const {connectToMainSocket, connected} = useContext(UUIDContext);\n\n //websocket connecting status\n const [connecting, setConnecting] = useState(false);\n\n //blurred status for input\n const [blurred, setBlurred] = useState(false);\n\n //function to handle submission\n const handleSubmit = (e) => {\n e.preventDefault();\n //User must enter a name\n if (!name) return;\n //Connect to the main socket\n setConnecting(true);\n connectToMainSocket(name);\n }\n\n //history object\n\n const history = useHistory();\n useEffect(() => {\n //If the user is already connected redirect to messenger\n if (connected) history.push(MessengerRoute);\n }, [connected])\n\n\n return (\n
\n
\n

Welcome To Direct Messages

\n

Your Place To Make New Friends

\n
\n \n setBlurred(true)} onChange={(e) => setName(e.target.value)} isInvalid={blurred && !name} placeholder=\"Enter your name..\" />\n \n \n \n \n
\n
\n
\n )\n}\n\nexport default Home\n","import {get} from './index';\n\nexport const getChats = (uuid) => get('/websocket/chats', {uuid});\n\nexport const getMessages = (chatId, lastDate) => get(`/websocket/${chatId}/messages`, {lastDate});\n\nexport const hypeDynos = () => get('/websocket/hype');","export default __webpack_public_path__ + \"static/media/notification_xperia.309dd561.mp3\";","import React, {useContext, useEffect, useState, useRef, useCallback} from 'react';\nimport {UUIDContext} from 'providers/UUIDProvider';\nimport {Avatar, Heading, Box} from \"@chakra-ui/react\";\nimport {connectToChatSocket} from 'api/websocket';\nimport Emoji from 'react-emoji-render';\nimport RingTone from 'static/audio/notification_xperia.mp3';\n\nfunction Chat({chat, activeChat, onClick, onReceive, tempMessage, msgEvent}) {\n\n //current user uuid\n const {UUID} = useContext(UUIDContext);\n\n //The connected user on chat is the one with an id different from\n //the current user\n const chatUser = chat.users.find(user => user.uuid !== UUID);\n\n //last message sent in chat\n const [lastMessage, setLastMessage] = useState(chat.last_message); \n\n //No of unread messages in this chat\n const [unread, setUnread] = useState(chat.unread);\n\n //socket ref\n const socketRef = useRef(null);\n\n //notification ringtone\n const notificationTone = useRef(new Audio(RingTone));\n\n //listening to msg events\n useEffect(() => {\n if (msgEvent?.type === 'message' && msgEvent.payload.chat === chat.id) {\n if (chat.id !== activeChat?.id) {\n setUnread(unread + 1);\n }\n setLastMessage(msgEvent.payload);\n }\n }, [msgEvent])\n\n //function to fire read message event\n const fireRead = () => {\n if (chat.id === activeChat?.id) {\n const data = {type: 'read', payload: {uuid: UUID}};\n socketRef.current.send(JSON.stringify(data));\n setUnread(0);\n }\n }\n\n //connect to corresponding socket\n useEffect(() => {\n socketRef.current = connectToChatSocket(chat.id);\n socketRef.current.onmessage = (e) => {\n const data = JSON.parse(e.data);\n onReceive(data);\n if (data.type === 'message' && data.payload.sender.uuid !== UUID) {\n if (!document.hasFocus()) {\n //play notification when user is on another tab\n notificationTone.current.play();\n }\n else fireRead();\n }\n } \n\n return () => socketRef.current.close();\n }, [])\n\n //message listener to window focus for firing read event\n useEffect(() => {\n window.addEventListener('focus', fireRead);\n \n return () => {\n window.removeEventListener('focus', fireRead);\n }\n }, [fireRead])\n\n useEffect(() => {\n //when this changes it means that the user did input\n //a message and submitted it to send in the chat\n //RTC events shall fire without depending on what chat is active\n if ((!tempMessage.message || chat.id !== activeChat?.id) && tempMessage.type !== 'rtc') return;\n const data = {type: tempMessage.type, payload: tempMessage.message};\n socketRef.current.send(JSON.stringify(data));\n }, [tempMessage])\n\n //mark messages as read once it becomes the active chat\n useEffect(() => {\n fireRead();\n }, [activeChat])\n\n //function to get last message preview\n const getLastMessage = (message) => {\n const defaultMessage = `You can now chat with ${chatUser.username}..`;\n if (!message) return defaultMessage;\n const lastMsgSender = message.sender.uuid === UUID ? 'You' : chatUser.username;\n if (message.text) return message.text;\n if (message.attachment) return `${lastMsgSender} sent an attachment`;\n if (message.audio) return `${lastMsgSender} sent a voice message`;\n return defaultMessage;\n }\n\n return (\n
\n
\n \n \n {chatUser.username}\n
\n \n
\n
\n {\n unread > 0 &&\n {unread}\n }\n
\n
\n )\n}\n\nexport default Chat\n","export default __webpack_public_path__ + \"static/media/call_ringtone.2bc59d93.mp3\";","import React, {useEffect, useRef, useState} from 'react';\nimport {Avatar, Box, Text, Button} from \"@chakra-ui/react\";\nimport {FaMicrophoneSlash, FaVideoSlash, FaPhoneSlash, FaPhone, FaTimes, FaMicrophone, FaVideo} from 'react-icons/fa';\n\nfunction Call({answerCall, terminateCall, call, requestCall, endCall, remoteStream, toggleMute, receiver}) {\n\n //call ringing buttons\n const buttons = [\n {Icon: FaPhoneSlash, background: 'red', onClick: () => endCall(), condition: true},\n {Icon: FaPhone, background: 'whatsapp', onClick: () => answerCall(), condition: !call?.caller}\n ]\n\n //ended call buttons\n const postButtons = [\n {Icon: FaTimes, background: 'blackAlpha', onClick: terminateCall},\n {Icon: FaVideo, background: 'whatsapp', onClick: () => requestCall('video')},\n {Icon: FaPhone, background: 'whatsapp', onClick: () => requestCall('audio')}\n ]\n\n //mute configurations\n const [mute, setMute] = useState({audio: false, video: false});\n\n //function to toggle mic mute\n const toggleAudioMute = () => {\n toggleMute('audio');\n setMute({...mute, audio: !mute.audio});\n }\n\n //function to toggle camera\n const toggleVideoMute = () => {\n toggleMute('video');\n setMute({...mute, video: !mute.video});\n }\n\n useEffect(() => {\n //resetting mute status\n if (call?.status !== 'connected') setMute({audio: false, video: false});\n }, [call])\n\n //connected buttons\n const connectedButtons = [\n {Icon: mute.audio ? FaMicrophoneSlash : FaMicrophone, background: 'blackAlpha', onClick: toggleAudioMute, condition: true},\n {Icon: mute.video ? FaVideoSlash : FaVideo, background: 'blackAlpha', onClick: toggleVideoMute, condition: call?.type === 'video'},\n {Icon: FaPhoneSlash, background: 'red', onClick: () => endCall(), condition: true}\n ]\n\n //function to get caller text\n const getCallerText = () => {\n if (!call) return;\n if(call.status === 'connected') return receiver?.username;\n if (call.status === 'rtc-connecting') return 'Connecting..';\n if (call.caller) return `Calling ${receiver?.username}`;\n else return `${call.peer} is ${call.type === 'video' ? 'video' : ''} calling you..`;\n }\n\n //reference for media container that will be streaming\n const mediaRef = useRef(null);\n \n //setting the stream on the video\n useEffect(() => {\n if (call?.status === 'connected') mediaRef.current.srcObject = remoteStream;\n }, [call])\n\n return (\n \n \n \n \n {\n call?.status === 'ended' ?\n 'Call ended' :\n getCallerText()\n }\n \n \n {\n call?.status === 'connecting' &&\n \n {\n buttons.map(({Icon, background, onClick, condition}, index) => (\n condition &&\n \n ))\n }\n \n }\n {\n call?.status === 'ended' &&\n \n {\n postButtons.map(({Icon, background, onClick}, index) => (\n \n ))\n }\n \n }\n {\n call?.status === 'connected' &&\n \n {\n connectedButtons.map(({Icon, background, onClick, condition}, index) => (\n condition &&\n \n ))\n }\n \n }\n {\n call?.status === 'connected' &&\n mediaRef.current = target} transform=\"rotateY(-180deg)\"/>\n }\n \n )\n}\n\nexport default Call\n","import React, {useState, useEffect, useRef, useContext} from 'react'\nimport {FaPhone, FaVideo, FaTimes} from 'react-icons/fa';\nimport {IconButton} from \"@chakra-ui/react\";\nimport Ringtone from 'static/audio/call_ringtone.mp3';\nimport {UUIDContext} from 'providers/UUIDProvider';\nimport Call from './Call';\nimport {CSSTransition} from 'react-transition-group';\nimport 'adapterjs';\n\nfunction RTC({closeChatWindow, msgEvent, onSend, isCall, chat, changeActiveChat, receiver}) {\n\n //current peer connection\n const peerConnection = useRef(null);\n\n //remote stream\n const remoteStream = useRef(new MediaStream());\n\n //local stream\n const localStream = useRef(null);\n\n //username of the current user\n const {username, UUID: uuid} = useContext(UUIDContext);\n\n //creating a peer connection\n const createPeerConnection = () => {\n peerConnection.current = new RTCPeerConnection({\n iceServers: [\n {\n urls: 'turn:numb.viagenie.ca',\n username: 'muazkh',\n credential: 'webrtc@live.com'\n },\n {\n urls: 'stun:stun.l.google.com:19302'\n }\n ]\n })\n \n //Track event\n peerConnection.current.ontrack = (e) => {\n remoteStream.current.addTrack(e.track, remoteStream.current);\n }\n\n //Tickling ice\n peerConnection.current.onicecandidate = (e) => {\n onSend({sender: {uuid}, 'candidate': e.candidate}, 'rtc');\n }\n \n //Disconnecting ice notifications\n peerConnection.current.oniceconnectionstatechange = (e) => {\n if (e.target.iceConnectionState === 'disconnected') endCall();\n }\n\n //Connection established\n peerConnection.current.onconnectionstatechange = () => {\n if (peerConnection.current.connectionState === 'connected') {\n setCall(call => ({...call, status: 'connected'}));\n }\n }\n }\n\n //creating a local stream\n const createLocalStream = async (callType) => {\n //Fetch the user media\n const constraints = {\n audio: {\n autoGainControl: false,\n noiseSuppression: false,\n echoCancellation: false,\n channelCount: {exact: 2},\n latency: 0,\n sampleRate: 48000,\n sampleSize: 16,\n volume: 1.0\n },\n video: callType === 'video'\n }\n localStream.current = await navigator.mediaDevices.getUserMedia(constraints);\n }\n\n //function to add local tracks\n const addMyStream = () => {\n localStream.current.getTracks().forEach(track => peerConnection.current.addTrack(track, localStream.current));\n }\n\n //function to mute tracks\n const toggleMuteTrack = (kind) => {\n const foundTrack = localStream.current.getTracks().find(track => track.kind === kind);\n foundTrack.enabled = !foundTrack.enabled;\n }\n\n //await time to answer call\n const MAX_AWAIT_TIME = 15;\n\n //call status\n const [call, setCall] = useState(null);\n\n //ringtone\n const callRingtone = useRef(new Audio(Ringtone));\n\n //call timeout\n const callTimeout = useRef(null);\n\n //creating rtc offer and sending it\n const createRTCOffer = async (callType) => {\n createPeerConnection();\n await createLocalStream(callType);\n addMyStream();\n const offer = await peerConnection.current.createOffer();\n await peerConnection.current.setLocalDescription(offer);\n onSend({sender: {uuid, username}, offer, callType, receiver: receiver.uuid}, 'rtc');\n //Activating ringtone after sending the call offer and update the call status\n callRingtone.current.play();\n setCall({status: 'connecting', type: callType, peer: username, caller: true})\n //He will not be requesting that forever\n callTimeout.current = setTimeout(() => {\n setCall(null);\n callRingtone.current.pause();\n callRingtone.current.currentTime = 0;\n //Remove the user media devices\n localStream.current.getTracks().forEach(track => track.stop());\n }, MAX_AWAIT_TIME * 1000)\n }\n\n //creating rtc answer and responding with it\n const answerOffer = async () => {\n //Now we need to clear the timeout that is gonna close the call\n clearTimeout(callTimeout.current);\n setCall({...call, status: 'rtc-connecting'});\n await peerConnection.current.setRemoteDescription(new RTCSessionDescription(call.sdpOffer));\n const answer = await peerConnection.current.createAnswer();\n answer.sdp = answer.sdp.replace('useinbandfec=1', 'useinbandfec=1; stereo=1; maxaveragebitrate=510000');\n await peerConnection.current.setLocalDescription(answer);\n onSend({sender: {uuid, username}, answer, receiver: receiver.uuid}, 'rtc');\n }\n\n //accepting answers\n const acceptAnswer = async (answer) => {\n clearTimeout(callTimeout.current);\n setCall({...call, status: 'rtc-connecting'});\n await peerConnection.current.setRemoteDescription(new RTCSessionDescription(answer));\n }\n\n //terminate the call\n const terminateCall = () => {\n setCall(null);\n }\n\n //end the call\n const endCall = (notified) => {\n //Clear call timeout here too\n clearTimeout(callTimeout.current);\n //Indicate that the call is ended\n setCall({...call, status: 'ended'});\n //stop the ringtone in case user is still ringing\n callRingtone.current.pause();\n callRingtone.current.currentTime = 0;\n peerConnection.current?.close();\n peerConnection.current = null;\n // notify the other user if not notified\n //Typicall we call with notified = true from the side ending the call\n if (!notified) {\n onSend({sender: {uuid}, end: true, receiver: receiver?.uuid, chat: chat?.id}, 'rtc');\n }\n //Remove the user media devices\n localStream.current?.getTracks().forEach(track => track.stop());\n localStream.current = null;\n //Empty remote stream to add further tracks on future calls\n remoteStream.current.getTracks().forEach(track => remoteStream.current.removeTrack(track));\n }\n\n //listening to message events\n useEffect(() => {\n //We only need to listen to the other peer\n if (msgEvent?.payload.sender && msgEvent.payload.sender.uuid !== uuid) {\n if (msgEvent.payload.receiver === uuid) {\n if (msgEvent.payload.offer) {\n //Ignore if on another call\n if (call && ['connecting', 'connected'].includes(call.status)) return;\n changeActiveChat(+msgEvent.payload.chatId);\n createPeerConnection();\n createLocalStream(msgEvent.payload.callType).then(addMyStream);\n setCall({status: 'connecting', type: msgEvent.payload.callType, peer: msgEvent.payload.sender.username, sdpOffer: msgEvent.payload.offer});\n callRingtone.current.play();\n callTimeout.current = setTimeout(() => {\n setCall(null);\n callRingtone.current.pause();\n callRingtone.current.currentTime = 0;\n }, MAX_AWAIT_TIME * 1000)\n }\n if (msgEvent.payload.answer) acceptAnswer(msgEvent.payload.answer);\n if (msgEvent.payload.end && +msgEvent.payload.chatId === chat?.id) endCall(true);\n }\n if (msgEvent.payload.candidate) peerConnection.current?.addIceCandidate(new RTCIceCandidate(msgEvent.payload.candidate));\n }\n }, [msgEvent])\n\n useEffect(() => {\n isCall(call);\n if (!call) {\n peerConnection.current?.close();\n peerConnection.current = null;\n }\n if (call?.status === 'connected') {\n callRingtone.current.pause();\n callRingtone.current.currentTime = 0;\n }\n }, [call])\n\n //rtc functioning icons\n const icons = [\n {Icon: FaPhone, onClick: () => createRTCOffer('audio')},\n {Icon: FaVideo, onClick: () => createRTCOffer('video')},\n {Icon: FaTimes, onClick: closeChatWindow}\n ]\n \n return (\n
\n {\n icons.map(({Icon, onClick}, index) => (\n \n \n \n ))\n }\n \n \n \n
\n )\n}\n\nexport default RTC\n","import React, {useState, useRef, useEffect} from 'react';\nimport {v4} from 'uuid';\nimport EmojiPicker from 'emoji-picker-react';\nimport {Input, Box, IconButton} from \"@chakra-ui/react\";\nimport {BiWinkTongue, BiMicrophone, BiUnlink, BiSend} from 'react-icons/bi';\nimport {useToast} from '@chakra-ui/react';\nimport Wave from 'wave-visualizer';\n\nfunction Compose({onSend, uuid}) {\n\n //open emoji picker status\n const [openPicker, setOpenPicker] = useState(false);\n\n //input of type file to allow users to attach videos and images\n const fileInputRef = useRef(null);\n\n //compose input ref used to type message\n const composeInputRef = useRef(null);\n\n //messages toaster\n const toast = useToast();\n\n //current message value that is being typed\n const [message, setMessage] = useState('');\n\n //recording stream\n const recordStream = useRef(null);\n\n //media recorder\n const mediaRecorder = useRef(null);\n\n //indicates if the record shall be discarded\n const discardRecordFlag = useRef(false);\n\n //chunks recorded\n const [chunks, setChunks] = useState([]);\n\n //recording status\n const [isRecording, setIsRecording] = useState(false);\n\n //function for reading file data as base64\n const readAsB64 = (file, callback) => {\n const reader = new FileReader();\n reader.onload = (e) => callback(e.target.result.replace(/^data:.+;base64,/, ''));\n reader.onerror = () => {\n toast({\n title: \"Whoops!\",\n description: \"Failed to read the file data..\",\n status: \"error\",\n duration: 3000,\n isClosable: false\n })\n }\n reader.readAsDataURL(file);\n }\n\n //function to start recording\n const startRecord = () => {\n discardRecordFlag.current = false;\n setIsRecording(true);\n navigator.mediaDevices.getUserMedia({\n audio: true\n })\n .then((stream) => {\n recordStream.current = stream;\n mediaRecorder.current = new MediaRecorder(recordStream.current, {mimeType: 'audio/webm'});\n mediaRecorder.current.ondataavailable = (e) => {\n if (e.data.size > 0) setChunks([...chunks, e.data]);\n }\n mediaRecorder.current.start();\n let wave = new Wave();\n wave.fromStream(recordStream.current, 'record-wave-visualizer', {\n type: 'shine',\n stroke: 1,\n colors: ['white', 'white', 'white']\n });\n })\n .catch(() => setIsRecording(false))\n }\n\n //function to stop recording\n const stopRecord = () => {\n if (!mediaRecorder.current || mediaRecorder.current.state === 'inactive') return;\n mediaRecorder.current.stop();\n setIsRecording(false);\n recordStream.current.getTracks().forEach(track => track.stop());\n }\n\n //function to discard record\n const discardRecord = () => {\n discardRecordFlag.current = true;\n stopRecord();\n }\n \n useEffect(() => {\n //sending chunks in chat when ready\n if (chunks.length && !discardRecordFlag.current) {\n const blob = new Blob(chunks, {type: 'audio/webm'});\n readAsB64(blob, (result) => {\n onSend({sender: {uuid}, audio: result, hash: v4()});\n setChunks([]);\n })\n }\n }, [chunks])\n\n //function for handling media change\n const handleMedia = (e) => {\n const file = e.target.files[0];\n if (!file) return;\n const validTypes = /image|video/;\n if (file.type.match(validTypes)) {\n readAsB64(file, (result) => {\n onSend({sender: {uuid}, attachment: result, hash: v4()});\n //Reset the input\n fileInputRef.current.value = null;\n })\n }\n else {\n toast({\n title: \"Unsupported Media!\",\n description: \"Only images and videos can be attached..\",\n status: \"error\",\n duration: 3000,\n isClosable: false\n })\n }\n }\n\n //functioning icons\n const icons = [\n {Icon: BiMicrophone, onMouseDown: startRecord, onMouseUp: stopRecord, onMouseLeave: discardRecord},\n {Icon: BiUnlink, onClick: () => fileInputRef.current.click()},\n {Icon: BiWinkTongue, onClick: () => setOpenPicker(!openPicker)}\n ]\n\n //function to handle emoji click\n const handleEmojiClick = (_, emoji) => {\n const insert = composeInputRef.current.selectionStart;\n const emojifiedMessage = `${message.slice(0, insert)}${emoji.emoji}${message.slice(insert, message.length)}`;\n setMessage(emojifiedMessage);\n setOpenPicker(false);\n composeInputRef.current.focus();\n }\n\n //function to handle compose submissionc\n const handleSubmit = (e) => {\n e.preventDefault();\n //Do not compose emtpy messages\n if (!message) return;\n onSend({sender: {uuid}, text: message, hash: v4()});\n setMessage('');\n composeInputRef.current.focus();\n }\n\n return (\n
\n setOpenPicker(false)} display={openPicker ? 'block' : 'none'}>\n \n \n fileInputRef.current = target} onChange={handleMedia}/>\n
\n {\n icons.map(({Icon, onClick, onMouseDown, onMouseUp, onMouseLeave}, index) => (\n \n \n \n ))\n }\n {\n isRecording &&\n \n \n \n }\n
\n
\n setMessage(e.target.value)} placeholder=\"Type here..\" ref={target => composeInputRef.current = target} />\n \n \n \n
\n
\n )\n}\n\nexport default Compose\n","//Convert a base64 data string to a URL to be used with images for eg\nexport const toObjectUrl = (b64Data, contentType) => {\n const byteChars = atob(b64Data);\n const byteNums = new Array(byteChars.length)\n for (let i = 0; i < byteNums.length; i++) {\n byteNums[i] = byteChars.charCodeAt(i);\n }\n const byteArray = new Uint8Array(byteNums);\n const blob = new Blob([byteArray], {type: contentType});\n const url = URL.createObjectURL(blob);\n return url;\n}","import React, {useEffect, useRef} from 'react';\nimport Emoji from 'react-emoji-render';\nimport {FaCheckDouble} from 'react-icons/fa';\nimport {toObjectUrl} from 'utils/tools';\nimport {CircularProgress, Box} from '@chakra-ui/react';\n\nfunction MessagesWindow({messages, uuid, fetchMessages, chat}) {\n\n //messages container ref\n const containerRef = useRef(null);\n\n //first load ref\n const firstLoad = useRef(true);\n\n useEffect(() => {\n //do not do that if the user is intending to fetch older messages\n if (containerRef.current.scrollHeight > containerRef.current.clientHeight && firstLoad.current) {\n containerRef.current.scrollTop = containerRef.current.scrollHeight;\n firstLoad.current = false;\n }\n if (containerRef.current.scrollTop === 0) return;\n containerRef.current.scrollTop = containerRef.current.scrollHeight;\n }, [messages])\n\n //fetch more messages by scrolling to the very top\n const loadMoreMsgs = (e) => {\n //Fetching older messages\n if (e.target.scrollTop === 0 && !firstLoad.current) {\n fetchMessages();\n }\n }\n\n //function to get message send date\n const getMsgDate = (date) => {\n date = date || new Date();\n const msgDate = new Date(date);\n let [time, dayTime] = msgDate.toLocaleTimeString().split(' ');\n time = time.split(':').filter((_, idx, arr) => idx !== arr.length - 1).join(':');\n const localTime = `${time} ${dayTime}`;\n const past = (new Date().getTime() - msgDate.getTime()) / (1000 * 60 * 60 * 24);\n if (past < 1) return localTime;\n if (past >= 1 && past < 2) return `Yesterday at ${localTime}`;\n else return msgDate.toLocaleDateString();\n }\n\n useEffect(() => {\n firstLoad.current = true;\n }, [chat])\n\n useEffect(() => {\n containerRef.current.addEventListener('scroll', loadMoreMsgs);\n }, [])\n\n return (\n
containerRef.current = target}>\n {\n messages.map((message, idx, arr) => (\n \n {\n message.text ?\n
\n \n
\n :\n <>\n {\n message.attachment &&\n (\n message.pending ?\n \n \n \n :\n \"\"\n )\n }\n {\n message.audio &&\n (\n message.pending ?\n \n \n \n :\n
\n ))\n }\n \n )\n}\n\nexport default MessagesWindow\n","import React, {useContext} from 'react';\nimport {Avatar, Heading} from '@chakra-ui/react';\nimport {UUIDContext} from 'providers/UUIDProvider';\nimport RTC from './RTC';\nimport Compose from './Compose';\nimport MessagesWindow from './MessagesWindow';\n\nfunction ChatWindow({chat, messages, closeCurrent, onSend, fetchMessages, msgEvent, isCall, changeActiveChat}) {\n\n //UUID\n const {UUID} = useContext(UUIDContext);\n\n //connected user on chat\n const chatUser = chat?.users.find(user => user.uuid !== UUID);\n\n return (\n
\n
\n
\n \n {chatUser?.username}\n
\n \n
\n \n \n
\n )\n}\n\nexport default ChatWindow\n","import React, {useState, useEffect, useContext, useRef} from 'react';\nimport {getChats} from 'api/queries';\nimport Chat from './Chat';\nimport {UUIDContext} from 'providers/UUIDProvider';\nimport {useHistory} from 'react-router-dom';\nimport {HomeRoute} from 'router/routes';\nimport {getMessages} from 'api/queries';\nimport ChatWindow from './ChatWindow';\n\nfunction Messenger() {\n\n //current chats\n const [chats, setChats] = useState([]);\n\n //current active chat\n const [currentChat, setCurrentChat] = useState(null);\n\n //function to change active chat using id\n const changeActiveChat = (id) => {\n setCurrentChat(chats.find(c => c.id === id));\n }\n\n //indicate if there is a call running\n const [isCall, setIsCall] = useState(false);\n\n //connected status and uuid for user\n const {connected, UUID, event} = useContext(UUIDContext);\n\n //last date for fetching older messages\n const [fetchOld, setFetchOld] = useState(false);\n\n //active chat messages\n const [messages, setMessages] = useState([]);\n\n //temp message to send in socket\n const [tempMessage, setTempMessage] = useState({});\n\n //new received message\n const [msgEvent, setMsgEvent] = useState(null);\n\n //flag ref for fetching old messages\n const oldFlag = useRef(false);\n\n //function to fetch chats\n const fetchChats = async () => {\n const response = await getChats(UUID);\n if (Array.isArray(response)) setChats(response);\n }\n\n useEffect(() => {\n fetchChats();\n }, [])\n\n useEffect(() => {\n //Check if the current chat is deleted or still there\n if (!chats.find(chat => chat.id === currentChat?.id)) setCurrentChat(null);\n }, [chats, currentChat])\n\n //function to fetch messages\n const fetchMessages = async (lastDate = null) => {\n if (!currentChat) return;\n if (!lastDate) setMessages([]);\n let msgs = [];\n if (lastDate) msgs = [...messages]; \n const response = await getMessages(currentChat.id, lastDate);\n setFetchOld(false);\n if (Array.isArray(response)) setMessages([...response, ...msgs]);\n }\n \n //history objet\n const history = useHistory();\n\n useEffect(() => {\n //User must be connected to be on messenger\n if (!connected) history.push(HomeRoute);\n }, [connected])\n\n useEffect(() => {\n //listen to new connecting/disconnecting users\n if (event.type === 'create' || event.type === 'delete') {\n fetchChats();\n setMsgEvent(event);\n }\n }, [event])\n\n //callback for receiving messages\n const onReceive = (event) => setMsgEvent(event);\n\n //call back for sending messages\n const onSend = (message, type = 'message') => {\n setTempMessage({message, type});\n if (type === 'message') {\n const pendingMessage = {...message, pending: true};\n setMessages([...messages, pendingMessage]);\n }\n }\n\n useEffect(() => {\n //when the active chat changes fetch it's messages\n if (currentChat) {\n fetchMessages();\n }\n else setMessages([]);\n }, [currentChat])\n\n useEffect(() => {\n //Verify first that the user isn't intending to fetch more messages\n if (oldFlag.current) {\n oldFlag.current = false;\n return;\n }\n //messages should never exceed 20, show more upon scrolling up\n const max = 20;\n const len = messages.length;\n if (len > max && messages[len - 1].sender.uuid === UUID) {\n setMessages(messages.slice(len - max, len));\n }\n }, [messages])\n\n useEffect(() => {\n if (msgEvent?.type === 'read' && msgEvent.payload.sender.uuid !== UUID) {\n const newMessages = [...messages];\n newMessages.forEach(message => message.seen = true);\n setMessages(newMessages);\n }\n\n if (msgEvent?.type === 'message') {\n //Make sure it's a message in the activeChat\n if (msgEvent.payload.chat !== currentChat?.id) return;\n const newMessages = [...messages];\n const idx = newMessages.findIndex(message => message.hash === msgEvent.payload.hash);\n if (idx === -1) {\n setMessages([...newMessages, msgEvent.payload]);\n return;\n }\n newMessages[idx] = msgEvent.payload;\n setMessages(newMessages);\n }\n }, [msgEvent])\n\n useEffect(() => {\n if (fetchOld && messages[0]) {\n fetchMessages(messages[0]?.created);\n oldFlag.current = true;\n }\n }, [fetchOld, messages])\n\n return (\n
\n
\n
\n {\n chats.map(chat => (\n setCurrentChat(chat)} onReceive={onReceive} tempMessage={tempMessage} msgEvent={msgEvent}/>\n ))\n }\n
\n
\n setCurrentChat(null)} onSend={onSend} fetchMessages={() => setFetchOld(true)} msgEvent={msgEvent} isCall={setIsCall} changeActiveChat={changeActiveChat}/>\n
\n
\n
\n )\n}\n\nexport default Messenger\n","import Home from 'views/Home/Home';\nimport Messenger from 'views/Messenger/Messenger';\n\n//Routes Literal Paths\nexport const HomeRoute = '/';\nexport const MessengerRoute = '/messenger';\n\n//Routes Objects\nconst Routes = [\n {path: HomeRoute, Component: Home},\n {path: MessengerRoute, Component: Messenger}\n]\n\nexport default Routes;","import {Route, Switch, withRouter} from 'react-router-dom';\nimport {TransitionGroup, CSSTransition} from 'react-transition-group';\nimport Routes from './routes';\n\nfunction Router({location}) {\n return (\n \n \n \n {\n Routes.map(({path, Component}) => (\n \n
\n \n
\n
\n ))\n }\n
\n
\n
\n )\n}\n\nexport default withRouter(Router)\n","import React, {useState, useEffect} from 'react';\nimport {hypeDynos as hype} from 'api/queries';\nimport {Box, CircularProgress, Text} from '@chakra-ui/react';\n\nfunction Preloader({children}) {\n\n //loading status\n const [loading, setLoading] = useState(true);\n\n //function to hype dynos\n const hypeDynos = async () => {\n await hype();\n setLoading(false);\n }\n\n useEffect(() => {\n hypeDynos();\n }, [])\n\n return (\n <>\n {\n loading ?\n \n \n \n Initializing the project...\n \n \n :\n children\n }\n \n )\n}\n\nexport default Preloader\n","import React from 'react';\nimport Router from 'router/Router';\nimport 'bootstrap/dist/css/bootstrap.min.css';\nimport 'styles/css/main.css';\nimport {BrowserRouter} from 'react-router-dom';\nimport UUIDProvider from 'providers/UUIDProvider';\nimport Preloader from 'components/Preloader/Preloader';\n\nfunction App() {\n return (\n
\n \n \n \n \n \n \n \n
\n );\n}\n\nexport default App;\n","const reportWebVitals = onPerfEntry => {\n if (onPerfEntry && onPerfEntry instanceof Function) {\n import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {\n getCLS(onPerfEntry);\n getFID(onPerfEntry);\n getFCP(onPerfEntry);\n getLCP(onPerfEntry);\n getTTFB(onPerfEntry);\n });\n }\n};\n\nexport default reportWebVitals;\n","import {extendTheme} from \"@chakra-ui/react\";\nimport {createBreakpoints} from \"@chakra-ui/theme-tools\";\n\n//responsive breakpoints\nconst breakPoints = createBreakpoints({\n sm: \"576px\",\n md: \"768px\",\n lg: \"992px\",\n xl: \"1200px\"\n})\n\n//global styles\nconst styles = {\n global: {\n h1: {\n fontSize: \"2em\"\n },\n h2: {\n fontSize: \"1.5em\"\n },\n h3: {\n fontSize: \"1.15em\"\n },\n h4: {\n fontSize: '1em'\n },\n h5: {\n fontSize: '0.85em'\n },\n h6: {\n fontSize: '0.75em'\n }\n }\n}\n\nconst theme = extendTheme({breakPoints, styles});\n\nexport default theme;","import React from 'react';\nimport ReactDOM from 'react-dom';\nimport App from './App';\nimport reportWebVitals from './reportWebVitals';\nimport chakraTheme from 'themes/chakraTheme';\nimport {ChakraProvider} from \"@chakra-ui/react\";\n\nReactDOM.render(\n \n \n \n \n ,\n document.getElementById('root')\n);\n\n// If you want to start measuring performance in your app, pass a function\n// to log results (for example: reportWebVitals(console.log))\n// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals\nreportWebVitals();\n"],"sourceRoot":""}