{"version":3,"sources":["components/WebGLBanner.png","images/clipboard.png","serviceWorker.ts","utils.ts","connection.ts","components/AppGlobalMessage.tsx","components/WebGLBanner.tsx","types.ts","components/Header.tsx","components/Login.tsx","components/Note.tsx","components/Column.tsx","components/Participants.tsx","components/StatusParticipant.tsx","components/StatusHost.tsx","components/Link.tsx","components/Room.tsx","App.tsx","index.tsx"],"names":["module","exports","Boolean","window","location","hostname","match","getSetLocalStorage","key","init","res","localStorage","getItem","setItem","trimBase64Padding","s","replace","Connection","baseUrl","clientId","secret","connectionStateChangeListeners","messageListeners","connected","this","rawCommand","name","eventSource","EventSource","eventsUrl","onerror","err","console","error","onopen","forEach","x","onmessage","evt","parsed","JSON","parse","data","event","callback","push","nickname","dataCommand","roomName","roomId","state","noteId","text","mood","hasFinished","finished","payload","Error","randomID","length","Uint8Array","crypto","getRandomValues","btoa","String","fromCharCode","apply","command","a","fetch","method","mode","headers","body","stringify","then","status","json","catch","e","title","children","className","onNotDisplayable","canvasRef","useRef","animationRef","useEffect","notDisplayable","image","Image","src","logo","onload","canvas","current","setAttribute","width","toString","height","program","gl","getContext","log","vertexShader","fragmentShader","createProgram","attachShader","linkProgram","getProgramParameter","LINK_STATUS","getProgramInfoLog","deleteProgram","createShader","VERTEX_SHADER","vertexShaderSource","FRAGMENT_SHADER","fragmentShaderSource","positionAttributeLocation","getAttribLocation","canvasResolutionUniformLocation","getUniformLocation","imageResolutionUniformLocation","timeUniformLocation","positionBuffer","createBuffer","bindBuffer","ARRAY_BUFFER","y","x1","x2","y1","y2","bufferData","Float32Array","STATIC_DRAW","setRectangle","texture","createTexture","bindTexture","TEXTURE_2D","texParameteri","TEXTURE_WRAP_S","CLAMP_TO_EDGE","TEXTURE_WRAP_T","TEXTURE_MIN_FILTER","NEAREST","TEXTURE_MAG_FILTER","texImage2D","RGBA","UNSIGNED_BYTE","requestAnimationFrame","drawScene","now","skipRender","viewport","clearColor","clear","COLOR_BUFFER_BIT","useProgram","enableVertexAttribArray","vertexAttribPointer","FLOAT","uniform2f","uniform1f","drawArrays","TRIANGLES","render","animate","cancelAnimationFrame","ref","type","source","shader","shaderSource","compileShader","getShaderParameter","COMPILE_STATUS","getShaderInfoLog","deleteShader","RoomState","Mood","banner","useState","webGLDisabled","setWebGLDisabled","onNameSet","setName","handleSetName","trimmedName","trim","placeholder","onChange","target","value","onKeyDown","data-test-id","onClick","note","author","editable","onNoteSave","tabIndex","textareaRef","editedText","setEditedText","isCreate","isInEditMode","textarea","focus","setSelectionRange","textAreaFocus","handleEdit","handleDelete","id","handleCancelEdition","handleSave","saveBadge","fn","keyCode","metaKey","ctrlKey","container","icon","notes","participants","rest","noteComponents","filter","n","map","authorId","get","participantNames","hostId","userId","size","Array","from","badgesArr","finishedWriting","flagComponent","hasFinishedToBtnLabel","false","true","onHasFinishedWriting","setHasFinished","showHasFinishedBtn","t","RUNNING","disableHasFinishedBtn","WAITING_FOR_PARTICIPANTS","REVIEWING","stateDescription","disabled","nextHasFinished","nextButton","testId","onStateTransition","btn","descr","link","clicked","setClicked","setTimeout","clearTimeout","navigator","clipboard","writeText","ClipboardImg","moodIcons","POSITIVE","NEGATIVE","CONFUSED","room","nameById","nameToIDs","Map","p","ids","undefined","set","index","idToName","participantById","notesByMood","moodToNotes","isHost","isWaiting","isRunning","isReviewing","toLowerCase","Date","fileName","document","createElement","appendChild","style","cssText","blob","Blob","url","URL","createObjectURL","href","download","click","revokeObjectURL","remove","triggerDownload","date","formattedDate","toISOString","split","exportFileName","resNotes","content","buildExportData","handleExport","connection","useReducer","reducer","initialState","dispatch","onMessage","message","Object","values","flat","history","replaceState","onConnectionStateChange","start","connect","searchParams","readRoomIdFromURL","identified","joinRoom","createRoom","identify","handleNameSet","saveNote","handleNoteSave","setRoomState","handleRoomStateIncrement","setFinishedWriting","handleFinishedWriting","mainComponent","action","updatedParticipants","updatedIndex","findIndex","noteIndex","ReactDOM","StrictMode","getElementById","serviceWorker","ready","registration","unregister"],"mappings":"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","file":"static/js/main.5e444b1f.chunk.js","sourcesContent":["module.exports = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAB4AAAAIXCAYAAAB9+UOaAAABg2lDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV9TiyL1A+wg4pChOlkQFXHUKhShQqgVWnUwufQLmjQkKS6OgmvBwY/FqoOLs64OroIg+AHi5Oik6CIl/i8ptIjx4Lgf7+497t4BQr3MNKtjHNB020wl4mImuyp2viIEAf0AemVmGXOSlITv+LpHgK93MZ7lf+7P0aPmLAYEROJZZpg28Qbx9KZtcN4njrCirBKfE4+ZdEHiR64rHr9xLrgs8MyImU7NE0eIxUIbK23MiqZGPEUcVTWd8oWMxyrnLc5aucqa9+QvDOf0lWWu0xxGAotYggQRCqoooQwbMVp1UiykaD/u4x9y/RK5FHKVwMixgAo0yK4f/A9+d2vlJye8pHAcCL04zscI0LkLNGqO833sOI0TIPgMXOktf6UOzHySXmtp0SOgbxu4uG5pyh5wuQMMPhmyKbtSkKaQzwPvZ/RNWWDgFuhe83pr7uP0AUhTV8kb4OAQGC1Q9rrPu7vae/v3TLO/H8aVcmKfeOK0AAAABmJLR0QAJgAlACS1RwEBAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH5AUCEBMHwEXDjgAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAABwrSURBVHja7Ny9b1RXAsbhYzw2Bo9DEGYVYksO4kMChSZCWheWZtuVKJDSREpDmSKdqxUusVK5S7Glm0hpolDwB8QKBZGsbYigsryWTECLkQMx+AvCFlusNrIt7J07nnnneUqQfX3PPffcM/Ozp+fihfNvCwAAAAAAAAAd74ghAAAAAAAAAMggAAMAAAAAAACEEIABAAAAAAAAQgjAAAAAAAAAACEEYAAAAAAAAIAQAjAAAAAAAABACAEYAAAAAAAAIIQADAAAAAAAABBCAAYAAAAAAAAIIQADAAAAAAAAhBCAAQAAAAAAAEIIwAAAAAAAAAAhBGAAAAAAAACAEAIwAAAAAAAAQAgBGAAAAAAAACCEAAwAAAAAAAAQQgAGAAAAAAAACCEAAwAAAAAAAIQQgAEAAAAAAABCCMAAAAAAAAAAIQRgAAAAAAAAgBACMAAAAAAAAEAIARgAAAAAAAAghAAMAAAAAAAAEEIABgAAAAAAAAghAAMAAAAAAACEEIABAAAAAAAAQgjAAAAAAAAAACEEYAAAAAAAAIAQAjAAAAAAAABACAEYAAAAAAAAIIQADAAAAAAAABBCAAYAAAAAAAAIIQADAAAAAAAAhBCAAQAAAAAAAEIIwAAAAAAAAAAhBGAAAAAAAACAEAIwAAAAAAAAQAgBGAAAAAAAACCEAAwAAAAAAAAQQgAGAAAAAAAACCEAAwAAAAAAAIQQgAEAAAAAAABCCMAAAAAAAAAAIQRgAAAAAAAAgBACMAAAAAAAAEAIARgAAAAAAAAghAAMAAAAAAAAEEIABgAAAAAAAAghAAMAAAAAAACEEIABAAAAAAAAQgjAAAAAAAAAACEEYAAAAAAAAIAQAjAAAAAAAABACAEYAAAAAAAAIIQADAAAAAAAABBCAAYAAAAAAAAIIQADAAAAAAAAhBCAAQAAAAAAAEIIwAAAAAAAAAAhBGAAAAAAAACAEAIwAAAAAAAAQAgBGAAAAAAAACCEAAwAAAAAAAAQQgAGAAAAAAAACCEAAwAAAAAAAIQQgAEAAAAAAABCCMAAAAAAAAAAIQRgAAAAAAAAgBACMAAAAAAAAEAIARgAAAAAAAAghAAMAAAAAAAAEEIABgAAAAAAAAghAAMAAAAAAACEEIABAAAAAAAAQgjAAAAAAAAAACEEYAAAAAAAAIAQAjAAAAAAAABACAEYAAAAAAAAIIQADAAAAAAAABBCAAYAAAAAAAAIIQADAAAAAAAAhBCAAQAAAAAAAEIIwAAAAAAAAAAhBGAAAAAAAACAEAIwAAAAAAAAQAgBGAAAAAAAACCEAAwAAAAAAAAQQgAGAAAAAAAACCEAAwAAAAAAAIQQgAEAAAAAAABCCMAAAAAAAAAAIQRgAAAAAAAAgBACMAAAAAAAAEAIARgAAAAAAAAghAAMAAAAAAAAEEIABgAAAAAAAAghAAMAAAAAAACEEIABAAAAAAAAQgjAAAAAAAAAACEEYAAAAAAAAIAQAjAAAAAAAABACAEYAAAAAAAAIIQADAAAAAAAABBCAAYAAAAAAAAIIQADAAAAAAAAhBCAAQAAAAAAAEIIwAAAAAAAAAAhBGAAAAAAAACAEAIwAAAAAAAAQAgBGAAAAAAAACCEAAwAAAAAAAAQQgAGAAAAAAAACCEAAwAAAAAAAIQQgAEAAAAAAABCCMAAAAAAAAAA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\"","module.exports = \"data:image/png;base64,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bbp/fyBH/KgPTWA6gHUDn21eB0vgQAIEgAB8KDcfUzYB8AbgAAqUUEyAABCAx5D0QxshAASgyB49H0iAABCAD+XmY8omAATgAAqUUEyAABCAx5D0QxshAASgyB49H0iAABCAD+XmY8omAATgAAqUUEyAABCAx5D0QxshAASgyB49H0iAABCAD+XmY8omAATgAAqUUEyAABCAx5D0QxshAASgyB49H0iAABCAD+XmY8omAATgAAqUUEyAABCAx5D0QxshAASgyB49H0iAABCAD+XmY8omAATgAAqUUEyAABCAx5D0QxshAASgyB49H0iAABCAD+XmY8omAATgAAqUUEyAABCAx5D0QxshAASgyB49H0iAABCAD+XmY8omAATgAAqUUEyAABCAx5D0QxshAASgyB49H0iAABCAD+XmY8omAATgAAqUUEyAABCAx5D0QxshAASgyB49H0iAABCAD+XmY8omAATgAAqUUEyAABCAx5D0QxshAASgyB49H0iAABCAD+XmY8omAATgAAqUUEyAABCAx5D0QxshAASgyB49H0iAABCAD+XmY8omAATgAAqUUEyAABCAx5D0QxshAASgyB49H0iAABCAD+XmY8omAATgAAqUUEyAABCAx5D0QxshAASgyB49H0iAABCAD+XmY8omAATgAAqUUEyAABCAx5D0QxshAASgyB49H0iAABCAD+XmY8omAATgAAqUUEyAABCAx5D0QxshAGEBWC9g528BsJaO9fP/5eefvi//rPv/UGYp+wcmQAAIwHQGDizBbP8EgAD8QJb4UR+YwHT5Le376+w1fOoLeJ1//fz6/NX3zwfySsk/OIEpBOsXsL6A6wBe91+fv/r++cEs8eM+MAEC4FcA0xlYQ7B8PgHwK4APZJaSf2AC0+VfN/D6Ai7D90Lv9fmr758fyBE/6kMTIADeAExn4AIIqzUQAG8APpRbyv5BCUyXf93A6wu4Ct4rfdfnr75/fhBD/JgPToAAeAMwnYErMCzWQQC8Afhgdin9ByQwXf51A68v4CJ0L/Vcn7/6/vkB/PAjPjwBAuANwHQGLgGxVgsB8Abgw/ml/L+YwHT51w28voBrwL3Wb33+6vvnL7LDP/6ABAiANwDTGbgGxVI9BMAbgAcwTAt/IYHp8q8beH0Bl2B7sdf6/NX3z1/ghn/0IQkQAG8ApjNwEYyVmgiANwAP4Zg2/mQC0+VfN/D6Aq6A9mqf9fmr758/yQz/2IMSIADeAExn4CocC3URAG8AHsQyrfyJBKbLv27g9QVcgOzlHuvzV98/f4IX/pGHJUAAvAGYzsBlQD69NgLgDcDDeKadP5jAdPnXDby+gJ8O2Ov91eevvn/+ICv87Q9MgAB4AzCdgeuQfHJ9BMAbgAcyTUt/IIHp8q8beH0BPxmun9Bbff7q++cPcMLf+tAECIA3ANMZ+ARQPrVGAuANwEO5pq3fmcB0+dcNvL6AnwrWT+mrPn/1/fM7GeFve3ACBMAbgOkMfAosn1gnAfAG4MFs09rvSGC6/OsGXl/AT4TqJ/VUn7/6/vkdfPC3PDwBAuANwHQGPgmYT6uVAHgD8HC+ae+/JDBd/nUDry/gpwH10/qpz199//wXNvivAwkQAG8ApjPwadB8Ur0EwBuAAOO0+B8SmC7/uoHXF/CTYPqJvdTnr75//gMX/FeRBAiANwDTGfhEcD6lZgLgDUCEc9r8jQSmy79u4PUF/BSQfmof9fmr75/fYIK/HEqAAITfAKwB4Px2AmtxIgAh0mn1VxMgAASgTSHdzxIgAN+m+/dXieAvphKYDmDdwGeb18ESOJAAASAAKdoebJYAeANwAAVKKCZAAAjAQSamSiIABKDIHj0fSIAAEIAUbQ82SwAIwAEUKKGYAAEgAAeZmCqJABCAInv0fCABAkAAUrQ92CwBIAAHUKCEYgIEgAAcZGKqJAJAAIrs0fOBBAgAAUjR9mCzBIAAHECBEooJEAACcJCJqZIIAAEoskfPBxIgAAQgRduDzRIAAnAABUooJkAACMBBJqZKIgAEoMgePR9IgAAQgBRtDzZLAAjAARQooZgAASAAB5mYKokAEIAie/R8IAECQABStD3YLAEgAAdQoIRiAgSAABxkYqokAkAAiuzR84EECAABSNH2YLMEgAAcQIESigkQAAJwkImpkggAASiyR88HEiAABCBF24PNEgACcAAFSigmQAAIwEEmpkoiAASgyB49H0iAABCAFG0PNksACMABFCihmAABIAAHmZgqiQAQgCJ79HwgAQJAAFK0PdgsASAAB1CghGICBIAAHGRiqiQCQACK7NHzgQQIAAFI0fZgswSAABxAgRKKCRAAAnCQiamSCAABKLJHzwcSIAAEIEXbg80SAAJwAAVKKCZAAAjAQSamSiIABKDIHj0fSIAAEIAUbQ82SwAIwAEUKKGYAAEgAAeZmCqJABCAInv0fCABAkAAUrQ92CwBIAAHUKCEYgIEgAAcZGKqJAIQFoD1Anb+FgBr6Vg//19+/un78s+6/xTpNPurCRAAAjCdgQNLMNs/ASAAv0oFfzGTwHT5Le376+w1fOoLeJ1//fz6/NX3T4ZyGv3NBKYQrF/A+gKuA3jdf33+6vvnN6ngv8gkQAD8CmA6A2sIls8nAH4FkCGdRn81genyrxt4fQGX4Xuh9/r81ffPrxLBX0wlQAC8AZjOwAUQVmsgAN4ApGin2f+XwHT51w28voCr4L3Sd33+6vvn/9HAX8glQAC8AZjOwBUYFusgAN4A5Iin4X9LYLr86wZeX8BF6F7quT5/9f3zbyTwvyQTIADeAExn4BIQa7UQAG8AktTT9L8SmC7/uoHXF3ANuNf6rc9fff/8iwL+h2wCBMAbgOkMXINiqR4C4A1Alnwa/2cC0+VfN/D6Ai7B9mKv9fmr7x8MlAAB8AZgOgMXwVipiQB4AwCB7QSmy79u4PUFXAHt1T7r81ffP2306f4rAQIwzKC+gNfzVz+/Pn8EAATrCRAAAjCdgTqEl/0TAL8CqAOw3v90+dcNvL6Al/Bz9rf1+E13z9fzr++fOvz0P/z26wJawCC8/RXc2gDWz58AQGA9gamF1y9gfQGvAVA/vz5/9f1Th5/+vQGYClB9AdcBvO6/Pn8EAALrCUwBWL+A9QW8BmD9/Pr81fdPHX769wZgKkD1BVwH8Lr/+vwRAAisJzAFYP0C1hfwGoD18+vzV98/dfjp3xuAqQDVF3AdwOv+6/NHACCwnsAUgPULWF/AawDWz6/PX33/1OGnf28ApgJUX8B1AK/7r88fAYDAegJTANYvYH0BrwFYP78+f/X9U4ef/r0BmApQfQHXAbzuvz5/BAAC6wlMAVi/gPUFvAZg/fz6/NX3Tx1++vcGYCpA9QVcB/C6//r8EQAIrCcwBWD9Aq4XsPMlsExgLUD1/VOHn/69AZgK0HL5OlsC6wQIwPb/N0gAlMAUgHUDXy9g50tgmQABIAAQvE2AAAzfgiyXr7MlsE6AABCALf6cTgAIwJoDzo8mQAAIAARvEyAABCCKH22vEyAABGCLP6cTAAKw5oDzowkQAAIAwdsECAABiOJH2+sECAAB2OLP6QSAAKw54PxoAgSAAEDwNgECQACi+NH2OgECQAC2+HM6ASAAaw44P5oAASAAELxNgAAQgCh+tL1OgAAQgC3+nE4ACMCaA86PJkAACAAEbxMgAAQgih9trxMgAARgiz+nEwACsOaA86MJEAACAMHbBAgAAYjiR9vrBAgAAdjiz+kEgACsOeD8aAIEgABA8DYBAkAAovjR9joBAkAAtvhzOgEgAGsOOD+aAAEgABC8TYAAEIAofrS9ToAAEIAt/pxOAAjAmgPOjyZAAAgABG8TIAAEIIofba8TIAAEYIs/pxMAArDmgPOjCRAAAgDB2wQIAAGI4kfb6wQIAAHY4s/pBIAArDng/GgCBIAAQPA2AQJAAKL40fY6AQJAALb4czoBIABrDjg/mgABIAAQvE2AABCAKH60vU6AABCALf6cTgAIwJoDzo8mQAAIAARvEyAABCCKH22vEyAABGCLP6cTAAKw5oDzowkQAAIAwdsECAABiOJH2+sECAAB2OLP6QQgLADrBez8LQAIwE/ff/l59+fA/CNgPAECQACmM3BgCWb7JwA7+H+Jx4HZj+NP+9MhXNr3hQtYX8AHFuB0/tf91+evvn/gTwLTBVi/gPUFvAZg/fz6/NX3D/xJgAD4FcB0BuoQXvZPAPwKAALbCUyXf93A6wt4CT9nf1uP33T3fD3/+v5po0/3XwlML2H9Aq438Pr5O397/+rzV98/ECgBAjCUoPoCJgAEYDkDBAAA6wkQAAIwnYElAOpn1wWUANTxp//p8q9fwPoCrgN43X99/ur7B/4kQAC8AZjOwBqC5fMJgP8rAAhsJzBd/nUDry/gMnwv9F6fv/r+aaNP918JEIBhBvUFvJ6/+vn1+SMAIFhPgAAQgOkM1CG87J8A+BVAHYD1/qfLv27g9QW8hJ+z/T8EVN8/dfjpf/jt92sB1y8gAdj+CqouAfX5q+8fAJSANwBDCaov4DqA1/3X548AAGA9AQJAAKYzsIZg+XwC4N8BqAOw3v90+dcNvL6Ay/C90Ht9/ur7pw4//Q+//X4twPoFrC/gCxAs11Cfv/r+AUAJeAMwlKD6Ai7D90Lv9fkjAABYT4AAEIDpDFwAYbUGAuDfAagDsN7/dPnXDby+gKvgvdJ3ff7q+6cOP/0Pv/1+LcH6Bawv4CsgrNZRn7/6/gFACXgDMJSg+gKugvdK3/X5IwAAWE+AABCA6QxcgWGxDgLg3wGoA7De/3T51w28voCL0L3Uc33+6vunDj/9D7/9fi3C+gWsL+BLMCzWUp+/+v4BQAl4AzCUoPoCLkL3Us/1+SMAAFhPgAAQgOkMXAJirRYC4N8BqAOw3v90+dcNvL6Aa8C91m99/ur7pw4//Q+//X4tw/oFrC/ga0Cs1VOfv/r+AUAJeAMwlKD1Ana+BJYJrIWLAABgPQECQACWDHB2OAEC8G26f+vw0/8Qfl+Xv27g4d2vdQms4ZffPwAogeklJAAoIIFuAt4AeAMAwdsECMDwLUh39etcAt+nu8cbyH/Kx5Y+Tp8nML2E3gDAgAS6CXgD4A3AnIDxAgiANwBdAul8mgABIABx/s7bJwAEYAoBh3cTIAAEYE7AeAEEgAB0CaTzaQIEgADE+TtvnwAQgCkEHN5NgAAQgDkB4wUQAALQJZDOpwkQAAIQ5++8fQJAAKYQcHg3AQJAAOYEjBdAAAhAl0A6nyZAAAhAnL/z9gkAAZhCwOHdBAgAAZgTMF4AASAAXQLpfJoAASAAcf7O2ycABGAKAYd3EyAABGBOwHgBBIAAdAmk82kCBIAAxPk7b58AEIApBBzeTYAAEIA5AeMFEAAC0CWQzqcJEAACEOfvvH0CQACmEHB4NwECQADmBIwXQAAIQJdAOp8mQAAIQJy/8/YJAAGYQsDh3QQIAAGYEzBeAAEgAF0C6XyaAAEgAHH+ztsnAARgCgGHdxMgAARgTsB4AQSAAHQJpPNpAgSAAMT5O2+fABCAKQQc3k2AABCAOQHjBRAAAtAlkM6nCRAAAhDn77x9AkAAphBweDcBAkAA5gSMF0AACECXQDqfJkAACECcv/P2CQABmELA4d0ECAABmBMwXgABIABdAul8mgABIABx/s7bJwAEYAoBh3cTIAAEYE7AeAEEYCgA6wXo/PkCnt6/+vP/5eefvi//HMg/jj/tTxfQ8vJ9nX3gAqqBgJmB0QzYPwBYT2C6fFxA30BJmBlYzYD9U8ef/gnA6NvHauk5F3DNwP/OAAEAwHoCBIAATGcAjAjJagYIQB1/+p8ufxfQ8l8tf+eaPfsHAOsJEABvAKYzAMRAvJoBAlDHn/6ny98FtPxXy9+5Zs/+AcB6AgTAG4DpDAAxEK9mgADU8af/6fJ3AS3/1fJ3rtmzfwCwngAB8AZgOgNADMSrGSAAdfzpf7r8XUDLf7X8nWv27B8ArCdAALwBmM4AEAPxagYIQB1/+p8ufxfQ8l8tf+eaPfsHAOsJEABvAKYzAMRAvJoBAlDHn/6ny98FtPxXy9+5Zs/+AcB6AgTAG4DpDAAxEK9mgADU8af/6fJ3AS3/1fJ3rtmzfwCwngAB8AZgOgNADMSrGSAAdQo7Ym0AAAViSURBVPzpf7r8XUDLf7X8nWv27B8ArCdAALwBmM4AEAPxagYIQB1/+p8ufxfQ8l8tf+eaPfsHAOsJEABvAKYzAMRAvJoBAlDHn/6ny98FtPxXy9+5Zs/+AcB6AgTAG4DpDAAxEK9mgADU8af/6fJ3AS3/1fJ3rtmzfwCwngAB8AZgOgNADMSrGSAAdfzpf7r8XUDLf7X8nWv27B8ArCdAALwBmM4AEAPxagYIQB1/+p8ufxfQ8l8tf+eaPfsHAOsJEABvAKYzAMRAvJoBAlDHn/6ny98FtPxXy9+5Zs/+AcB6AmkBWC8A5//0XQYyqM7AAQmt8y/fPwH42QKuLmB9m/3lDBCAPH/nARAAAuBbuBkwA4MZIABz/uULIACDi7/81uFs33rNwI0ZIAB5/s4DIAAEwLc/M2AGBjNAAOb8yxdAAAYX3zewG9/APAfPYTkDBCDP33kABIAA+PZnBszAYAYIwJx/+QIIwODiL791ONu3XjNwYwYIQJ6/8wAIAAHw7c8MmIHBDBCAOf/yBRCAwcX3DezGNzDPwXNYzgAByPN3HgABIAC+/ZkBMzCYAQIw51++AAIwuPjLbx3O9q3XDNyYAQKQ5+88AAJAAHz7MwNmYDADBGDOv3wBBGBw8X0Du/ENzHPwHJYzQADy/J0HQAAIgG9/ZsAMDGaAAMz5ly+AAAwu/vJbh7N96zUDN2aAAOT5Ow+AABAA3/7MgBkYzAABmPMvXwABGFx838BufAPzHDyH5QwQgDx/5wEQAALg258ZMAODGSAAc/7lCyAAg4u//NbhbN96zcCNGSAAef7OAyAABMC3PzNgBgYzQADm/MsXQAAGF983sBvfwDwHz2E5AwQgz995AASAAPj2ZwbMwGAGCMCcf/kCCMDg4i+/dTjbt14zcGMGCECev/MACAAB8O3PDJiBwQwQgDn/8gUQgMHF9w3sxjcwz8FzWM4AAcjzdx4AASAAvv2ZATMwmAECMOdfvgACMLj4y28dzvat1wzcmAECkOfvPAACQAB8+zMDZmAwAwRgzr98AQRgcPF9A7vxDcxz8ByWM0AA8vydB0AACIBvf2bADAxmgADM+ZcvgAAMLv7yW4ezfes1AzdmgADk+TsPYCoABy6A/r99k4EMzEBzBuYAUsA2ARe/efE9d8/dDJiBLX2cPk/AErAEzIAZMAPNGZgDSAHbBFz85sX33D13M2AGtvRx+jwBS8ASMANmwAw0Z2AOIAVsE3Dxmxffc/fczYAZ2NLH6fMELAFLwAyYATPQnIE5gBSwTcDFb158z91zNwNmYEsfp88TsAQsATNgBsxAcwbmAFLANgEXv3nxPXfP3QyYgS19nD5PwBKwBMyAGTADzRmYA0gB2wRc/ObF99w9dzNgBrb0cfo8AUvAEjADZsAMNGdgDiAFbBNw8ZsX33P33M2AGdjSx+nzBCwBS8AMmAEz0JyBOYAUsE3AxW9efM/dczcDZmBLH6fPE7AELAEzYAbMQHMG5gBSwDYBF7958T13z90MmIEtfZw+T8ASsATMgBkwA80ZmANIAdsEXPzmxffcPXczYAa29HH6PAFLwBIwA2bADDRnYA4gBWwTcPGbF99z99zNgBnY0sfp8wQsAUvADJgBM9CcgTmAFLBNwMVvXnzP3XM3A2ZgSx+nzxOwBCwBM2AGzEBzBuYAUsA2ARe/efE9d8/dDJiBLX2cPk/AErAEzIAZMAPNGZgDSAHbBFz85sX33D13M2AGtvRx+jwBS8ASMANmwAw0Z2AOIAVsE3Dxmxffc/fczYAZ2NLH6fMELAFLwAyYATPQnIE5gBSwTcDFb158z91zNwNmYEuf8en/A0qPf3W0DVV4AAAAAElFTkSuQmCC\"","// This optional code is used to register a service worker.\n// register() is not called by default.\n\n// This lets the app load faster on subsequent visits in production, and gives\n// it offline capabilities. However, it also means that developers (and users)\n// will only see deployed updates on subsequent visits to a page, after all the\n// existing tabs open on the page have been closed, since previously cached\n// resources are updated in the background.\n\n// To learn more about the benefits of this model and instructions on how to\n// opt-in, read https://bit.ly/CRA-PWA\n\nconst isLocalhost = Boolean(\n window.location.hostname === 'localhost' ||\n // [::1] is the IPv6 localhost address.\n window.location.hostname === '[::1]' ||\n // 127.0.0.0/8 are considered localhost for IPv4.\n window.location.hostname.match(\n /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\n )\n);\n\ntype Config = {\n onSuccess?: (registration: ServiceWorkerRegistration) => void;\n onUpdate?: (registration: ServiceWorkerRegistration) => void;\n};\n\nexport function register(config?: Config) {\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\n // The URL constructor is available in all browsers that support SW.\n const publicUrl = new URL(\n process.env.PUBLIC_URL,\n window.location.href\n );\n if (publicUrl.origin !== window.location.origin) {\n // Our service worker won't work if PUBLIC_URL is on a different origin\n // from what our page is served on. This might happen if a CDN is used to\n // serve assets; see https://github.com/facebook/create-react-app/issues/2374\n return;\n }\n\n window.addEventListener('load', () => {\n const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;\n\n if (isLocalhost) {\n // This is running on localhost. Let's check if a service worker still exists or not.\n checkValidServiceWorker(swUrl, config);\n\n // Add some additional logging to localhost, pointing developers to the\n // service worker/PWA documentation.\n navigator.serviceWorker.ready.then(() => {\n console.log(\n 'This web app is being served cache-first by a service ' +\n 'worker. To learn more, visit https://bit.ly/CRA-PWA'\n );\n });\n } else {\n // Is not localhost. Just register service worker\n registerValidSW(swUrl, config);\n }\n });\n }\n}\n\nfunction registerValidSW(swUrl: string, config?: Config) {\n navigator.serviceWorker\n .register(swUrl)\n .then(registration => {\n registration.onupdatefound = () => {\n const installingWorker = registration.installing;\n if (installingWorker == null) {\n return;\n }\n installingWorker.onstatechange = () => {\n if (installingWorker.state === 'installed') {\n if (navigator.serviceWorker.controller) {\n // At this point, the updated precached content has been fetched,\n // but the previous service worker will still serve the older\n // content until all client tabs are closed.\n console.log(\n 'New content is available and will be used when all ' +\n 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'\n );\n\n // Execute callback\n if (config && config.onUpdate) {\n config.onUpdate(registration);\n }\n } else {\n // At this point, everything has been precached.\n // It's the perfect time to display a\n // \"Content is cached for offline use.\" message.\n console.log('Content is cached for offline use.');\n\n // Execute callback\n if (config && config.onSuccess) {\n config.onSuccess(registration);\n }\n }\n }\n };\n };\n })\n .catch(error => {\n console.error('Error during service worker registration:', error);\n });\n}\n\nfunction checkValidServiceWorker(swUrl: string, config?: Config) {\n // Check if the service worker can be found. If it can't reload the page.\n fetch(swUrl, {\n headers: { 'Service-Worker': 'script' }\n })\n .then(response => {\n // Ensure service worker exists, and that we really are getting a JS file.\n const contentType = response.headers.get('content-type');\n if (\n response.status === 404 ||\n (contentType != null && contentType.indexOf('javascript') === -1)\n ) {\n // No service worker found. Probably a different app. Reload the page.\n navigator.serviceWorker.ready.then(registration => {\n registration.unregister().then(() => {\n window.location.reload();\n });\n });\n } else {\n // Service worker found. Proceed as normal.\n registerValidSW(swUrl, config);\n }\n })\n .catch(() => {\n console.log(\n 'No internet connection found. App is running in offline mode.'\n );\n });\n}\n\nexport function unregister() {\n if ('serviceWorker' in navigator) {\n navigator.serviceWorker.ready\n .then(registration => {\n registration.unregister();\n })\n .catch(error => {\n console.error(error.message);\n });\n }\n}\n","export const getSetLocalStorage = (key: string, init: (() => any)): any => {\n let res = localStorage.getItem(key)\n if (res !== null) return res\n res = init()\n if (res !== null) localStorage.setItem(key, res)\n return res\n}\n\nexport function trimBase64Padding(s: string): string {\n return s.replace(/=+$/, '');\n}\n","import { Mood, RoomState } from './types';\nimport { trimBase64Padding } from './utils';\n\nconst CLIENT_ID_LEN = 16;\nconst SECRET_LEN = 64;\n\ntype ConnectionStateChangeCallback = (connected: boolean) => void;\n\ntype Message = {name: string} & Record\ntype MessageCallback = (message: Message) => void;\n\nexport class Connection {\n baseUrl: string\n clientId: string\n secret: string\n\n connectionStateChangeListeners: ConnectionStateChangeCallback[] = [];\n messageListeners: MessageCallback[] = [];\n\n connected = false // EventSource\n\n constructor(baseUrl: string, clientId: string, secret: string) {\n this.baseUrl = baseUrl;\n this.clientId = clientId;\n this.secret = secret;\n }\n\n async start(): Promise {\n if (this.connected) {\n return;\n }\n\n const res = await rawCommand(this.baseUrl, {name: 'hello', clientId: this.clientId, secret: this.secret})\n\n // console.log('Connection up, events URL: ' + res.eventsUrl)\n\n const eventSource = new EventSource(res.eventsUrl);\n eventSource.onerror = (err) => {\n console.error('Event source error', err);\n }\n // maybe useless (just for logging)\n eventSource.onopen = () => {\n // Lost connection but can ignore\n // console.log('Event source connected');\n this.connected = true;\n this.connectionStateChangeListeners.forEach(x => x(true));\n }\n\n eventSource.onmessage = (evt) => {\n // console.log(\"Event received\")\n // console.log(evt)\n\n const parsed = JSON.parse(evt.data);\n\n if (parsed.event === 'keep-alive') {\n return;\n }\n\n this.messageListeners.forEach(x => x(parsed));\n }\n }\n\n onConnectionStateChange(callback: (connected: boolean) => void) {\n this.connectionStateChangeListeners.push(callback);\n }\n\n onMessage(callback: (msg: Message) => void) {\n this.messageListeners.push(callback);\n }\n\n // API\n\n async identify(nickname: string): Promise {\n return this.dataCommand({name: 'identify', nickname: nickname})\n }\n\n async createRoom() {\n // TODO(abustany): What do we do for the room name?\n return this.dataCommand({name: 'create-room', roomName: \"name\"})\n }\n\n async joinRoom(roomId: string) {\n return this.dataCommand({name: 'join-room', roomId: roomId})\n }\n\n async setRoomState(state: RoomState) {\n return this.dataCommand({name: 'set-state', state: state})\n }\n\n async saveNote(noteId: number, text: string, mood: Mood) {\n return this.dataCommand({name: 'save-note', noteId, text, mood})\n }\n\n async setFinishedWriting(hasFinished: boolean) {\n return this.dataCommand({name: 'set-finished-writing', finished: hasFinished})\n }\n\n // END OF API\n\n async dataCommand(payload: unknown): Promise {\n if (!this.connected) {\n throw Error('Cannot send data command on disconnected connection');\n }\n\n return rawCommand(this.baseUrl, {name: 'data', clientId: this.clientId, secret: this.secret, payload: payload})\n }\n}\n\nfunction randomID(length: number) {\n const data = new Uint8Array(length);\n window.crypto.getRandomValues(data);\n return trimBase64Padding(btoa(String.fromCharCode.apply(null, data as unknown as number[])).replace(/\\+/g, '-').replace(/\\//g, '_'));\n}\n\nexport function generateClientId(): string {\n return randomID(CLIENT_ID_LEN)\n}\n\nexport function generateSecret(): string {\n return randomID(SECRET_LEN)\n}\n\nasync function rawCommand(baseUrl: string, command: unknown): Promise {\n return fetch(`${baseUrl}/command`, {\n method: 'POST',\n mode: 'same-origin',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(command),\n }).then(res => {\n if (res.status !== 200) {\n throw new Error('Unexpected status code: ' + res.status);\n }\n\n return res.json()\n }).catch(e => {\n console.error('API command error: ', e);\n throw e;\n });\n}\n\ninterface HelloResponse {\n eventsUrl: string;\n}\n","import React from 'react';\n\nimport './AppGlobalMessage.scss'\n\ninterface Props {\n title: string\n}\n\nexport default function({title, children}: React.PropsWithChildren) {\n return
\n

{ title }

\n { children }\n
\n}\n","import React, { useEffect, useRef } from 'react';\n\nimport logo from './WebGLBanner.png';\nimport './WebGLBanner.scss';\n\ninterface Props {\n onNotDisplayable: () => void;\n}\n\nexport default function({onNotDisplayable}: Props) {\n const canvasRef = useRef(null)\n const animationRef = useRef(null)\n\n useEffect((): () => void => {\n animate(canvasRef, animationRef, onNotDisplayable)\n\n // The ref value 'animationRef.current' will likely have changed by the time this effect cleanup function runs. If this ref points to a node rendered by React, copy 'animationRef.current' to a variable inside the effect, and use that variable in the cleanup function.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n return () => { animationRef.current && cancelAnimationFrame(animationRef.current) }\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n return \n}\n\nfunction animate(\n canvasRef: React.MutableRefObject,\n animationRef: React.MutableRefObject,\n notDisplayable: () => void\n): void {\n const image = new Image();\n image.src = logo;\n image.onload = () => {\n render(canvasRef, animationRef, image, notDisplayable);\n }\n}\n\nfunction render(\n canvasRef: React.MutableRefObject,\n animationRef: React.MutableRefObject,\n image: HTMLImageElement,\n notDisplayable: () => void\n): void {\n const canvas = canvasRef.current\n // Component has been unmounted already\n if (!canvas) return\n\n canvas.setAttribute('width', image.width.toString());\n canvas.setAttribute('height', image.height.toString());\n\n let gl = canvas.getContext('webgl');\n if (!gl) {\n console.log(\"WebGL unavailable\")\n notDisplayable()\n return\n }\n\n let program: WebGLProgram\n try {\n program = createProgram(\n gl,\n createShader(gl, gl.VERTEX_SHADER, vertexShaderSource),\n createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource),\n );\n } catch(err) {\n console.log(err)\n notDisplayable()\n return\n }\n\n const positionAttributeLocation = gl.getAttribLocation(program, 'a_position');\n const canvasResolutionUniformLocation = gl.getUniformLocation(program, 'u_vertexResolution');\n const imageResolutionUniformLocation = gl.getUniformLocation(program, 'u_imageResolution');\n const timeUniformLocation = gl.getUniformLocation(program, 'iTime');\n\n // Rectangle with the same size as the image in positionBuffer\n const positionBuffer = gl.createBuffer();\n gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);\n setRectangle(gl, 0, 0, image.width, image.height);\n\n // Upload image into texture\n const texture = gl.createTexture();\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);\n\n animationRef.current = requestAnimationFrame(drawScene);\n let skipRender = false;\n\n function drawScene(now: number): void {\n if (skipRender) {\n skipRender = false;\n animationRef.current = requestAnimationFrame(drawScene);\n return;\n }\n\n now *= 0.001;\n gl = gl as WebGLRenderingContext\n\n gl.viewport(0, 0, image.width, image.height);\n gl.clearColor(0.149, 0.145, 0.141, 1);\n gl.clear(gl.COLOR_BUFFER_BIT);\n\n gl.useProgram(program);\n\n // Bind attributes to buffers\n gl.enableVertexAttribArray(positionAttributeLocation);\n gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);\n gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);\n\n gl.uniform2f(canvasResolutionUniformLocation, image.width, image.height);\n gl.uniform2f(imageResolutionUniformLocation, image.width, image.height);\n gl.uniform1f(timeUniformLocation, now);\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n\n skipRender = true;\n animationRef.current = requestAnimationFrame(drawScene);\n }\n\n}\n\nfunction createShader(gl: WebGLRenderingContext, type: number, source: string): WebGLShader {\n let shader = gl.createShader(type);\n if (!shader) {\n throw new Error(\"Failed to create shader\")\n }\n shader = shader as WebGLShader\n\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);\n if (success) {\n return shader;\n }\n\n console.log(gl.getShaderInfoLog(shader));\n gl.deleteShader(shader);\n throw new Error(\"Failed to get shader params\")\n}\n\nfunction createProgram(gl: WebGLRenderingContext, vertexShader: WebGLShader, fragmentShader: WebGLShader): WebGLProgram {\n const program = gl.createProgram();\n if (!program) {\n throw new Error(\"Failed to create program\")\n }\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n gl.linkProgram(program);\n const success = gl.getProgramParameter(program, gl.LINK_STATUS);\n if (success) {\n return program;\n }\n\n console.log(gl.getProgramInfoLog(program));\n gl.deleteProgram(program);\n throw new Error(\"Failed to get program parameter\")\n}\n\nfunction setRectangle(gl: WebGLRenderingContext, x: number, y: number, width: number, height: number): void {\n const x1 = x;\n const x2 = x + width;\n const y1 = y;\n const y2 = y + height;\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([\n x1, y1,\n x2, y1,\n x1, y2,\n x1, y2,\n x2, y1,\n x2, y2,\n ]), gl.STATIC_DRAW);\n}\n\nconst vertexShaderSource = `\nattribute vec2 a_position;\nuniform vec2 u_vertexResolution;\n\nattribute vec2 a_texCoord;\n\nvoid main() {\n vec2 clipSpace = (a_position / u_vertexResolution)*2.0-1.0;\n gl_Position = vec4(clipSpace*vec2(1, -1), 0, 1);\n}\n`;\n\nconst fragmentShaderSource = `\nprecision mediump float;\n\n// Copied from https://www.shadertoy.com/view/ldXGW4\n\nuniform vec2 u_imageResolution;\nuniform float iTime; // shader playback time (in seconds)\nuniform sampler2D u_image;\n\n// change these values to 0.0 to turn off individual effects\nfloat vertJerkOpt = 1.0;\nfloat vertMovementOpt = 1.0;\nfloat bottomStaticOpt = 1.0;\nfloat scalinesOpt = 1.0;\nfloat rgbOffsetOpt = 0.3; // down from 1.0\nfloat horzFuzzOpt = 0.5; // down from 1.0\n\n// Noise generation functions borrowed from:\n// https://github.com/ashima/webgl-noise/blob/master/src/noise2D.glsl\n\nvec3 mod289(vec3 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\n\nvec2 mod289(vec2 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\n\nvec3 permute(vec3 x) {\n return mod289(((x*34.0)+1.0)*x);\n}\n\nfloat snoise(vec2 v)\n {\n const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0\n 0.366025403784439, // 0.5*(sqrt(3.0)-1.0)\n -0.577350269189626, // -1.0 + 2.0 * C.x\n 0.024390243902439); // 1.0 / 41.0\n// First corner\n vec2 i = floor(v + dot(v, C.yy) );\n vec2 x0 = v - i + dot(i, C.xx);\n\n// Other corners\n vec2 i1;\n //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0\n //i1.y = 1.0 - i1.x;\n i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n // x0 = x0 - 0.0 + 0.0 * C.xx ;\n // x1 = x0 - i1 + 1.0 * C.xx ;\n // x2 = x0 - 1.0 + 2.0 * C.xx ;\n vec4 x12 = x0.xyxy + C.xxzz;\n x12.xy -= i1;\n\n// Permutations\n i = mod289(i); // Avoid truncation effects in permutation\n vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 ))\n\t\t+ i.x + vec3(0.0, i1.x, 1.0 ));\n\n vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0);\n m = m*m ;\n m = m*m ;\n\n// Gradients: 41 points uniformly over a line, mapped onto a diamond.\n// The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287)\n\n vec3 x = 2.0 * fract(p * C.www) - 1.0;\n vec3 h = abs(x) - 0.5;\n vec3 ox = floor(x + 0.5);\n vec3 a0 = x - ox;\n\n// Normalise gradients implicitly by scaling m\n// Approximation of: m *= inversesqrt( a0*a0 + h*h );\n m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );\n\n// Compute final noise value at P\n vec3 g;\n g.x = a0.x * x0.x + h.x * x0.y;\n g.yz = a0.yz * x12.xz + h.yz * x12.yw;\n return 130.0 * dot(m, g);\n}\n\nfloat staticV(vec2 uv) {\n float staticHeight = snoise(vec2(9.0,iTime*1.2+3.0))*0.3+5.0;\n float staticAmount = snoise(vec2(1.0,iTime*1.2-6.0))*0.1+0.3;\n float staticStrength = snoise(vec2(-9.75,iTime*0.6-3.0))*2.0+2.0;\n\treturn (1.0-step(snoise(vec2(5.0*pow(iTime,2.0)+pow(uv.x*7.0,1.2),pow((mod(iTime,100.0)+100.0)*uv.y*0.3+3.0,staticHeight))),staticAmount))*staticStrength;\n}\n\n\nvoid mainImage( out vec4 fragColor, in vec2 fragCoord )\n{\n\tvec2 uv = fragCoord.xy/u_imageResolution.xy;\n\n\tfloat jerkOffset = (1.0-step(snoise(vec2(iTime*1.3,5.0)),0.8))*0.05;\n\n\tfloat fuzzOffset = snoise(vec2(iTime*15.0,uv.y*80.0))*0.003;\n\tfloat largeFuzzOffset = snoise(vec2(iTime*1.0,uv.y*25.0))*0.004;\n\n float vertMovementOn = (1.0-step(snoise(vec2(iTime*0.2,8.0)),0.4))*vertMovementOpt;\n float vertJerk = (1.0-step(snoise(vec2(iTime*1.5,5.0)),0.6))*vertJerkOpt;\n float vertJerk2 = (1.0-step(snoise(vec2(iTime*5.5,5.0)),0.2))*vertJerkOpt;\n float yOffset = abs(sin(iTime)*4.0)*vertMovementOn+vertJerk*vertJerk2*0.3;\n float y = mod(uv.y+yOffset,1.0);\n\n\n\tfloat xOffset = (fuzzOffset + largeFuzzOffset) * horzFuzzOpt;\n\n float staticVal = 0.0;\n\n for (float y = -1.0; y <= 1.0; y += 1.0) {\n float maxDist = 5.0/200.0;\n float dist = y/200.0;\n \tstaticVal += staticV(vec2(uv.x,uv.y+dist))*(maxDist-abs(dist))*1.5;\n }\n\n staticVal *= bottomStaticOpt;\n\n\tfloat red \t= texture2D(\tu_image, \tvec2(uv.x + xOffset -0.01*rgbOffsetOpt,y)).r+staticVal;\n\tfloat green = \ttexture2D(\tu_image, \tvec2(uv.x + xOffset,\t y)).g+staticVal;\n\tfloat blue \t=\ttexture2D(\tu_image, \tvec2(uv.x + xOffset +0.01*rgbOffsetOpt,y)).b+staticVal;\n\n\tvec3 color = vec3(red,green,blue);\n\tfloat scanline = sin(uv.y*800.0)*0.04*scalinesOpt;\n\tcolor -= scanline;\n\n\tfragColor = vec4(color,1.0);\n}\n\nvoid fadeToBackground(in vec2 fragCoord) {\n\tvec2 uv = fragCoord.xy/u_imageResolution.xy;\n vec3 background = vec3(.149, .145, .141);\n float factor = -uv.y*2.0;\n vec3 faded = vec3(1.0, 1.0, 1.0)*factor; // varies between 1 and 0\n gl_FragColor = gl_FragColor * vec4(faded, 1.0) + vec4(background, 1.0) * vec4(1.0-faded, 1.0);\n}\n\nvoid main() {\n mainImage(gl_FragColor, gl_FragCoord.xy*vec2(1, -1));\n fadeToBackground(gl_FragCoord.xy*vec2(1, -1));\n}\n`;\n","export interface Participant {\n clientId: string;\n name: string;\n finishedWriting?: boolean;\n};\n\nexport enum RoomState {\n WAITING_FOR_PARTICIPANTS = 1,\n RUNNING = 2,\n REVIEWING = 3\n}\n\nexport interface Room {\n state: RoomState;\n participants: Participant[];\n notes: Note[];\n hostId: string;\n}\n\nexport enum Mood {\n POSITIVE = 1,\n NEGATIVE = 2,\n CONFUSED = 3\n}\n\nexport interface Note {\n authorId: string;\n id: number;\n text: string;\n mood: Mood;\n}\n\nexport interface State {\n error?: string;\n connected: boolean;\n name?: string;\n identified: boolean;\n roomId?: string;\n room?: Room;\n}\n\nexport type Action = {\n type: 'connectionStatus';\n payload: boolean; // connected or not\n} | {\n type: 'connectionError';\n payload: string; // error message\n} | {\n type: 'name';\n payload: string; // name\n} | {\n type: 'identifyReceived';\n payload: boolean; // identified or not\n} | {\n type: 'roomIdSetFromURL';\n payload: string; // room ID\n} | {\n type: 'roomReceive';\n payload: Room; // the current room state\n} | {\n type: 'roomParticipantAdd';\n payload: Participant;\n} | {\n type: 'roomParticipantRemoved';\n payload: Participant;\n} | {\n type: 'roomParticipantUpdated';\n payload: Participant;\n} | {\n type: 'hostChange';\n payload: string; // host clientId\n} | {\n type: 'roomStateChanged';\n payload: RoomState;\n} | {\n type: 'noteCreated';\n payload: Note;\n} | {\n type: 'noteUpdated';\n payload: {noteId: number, text: string}\n}\n","import React, { useState } from 'react';\n\nimport WebGLBanner from './WebGLBanner'\nimport './Header.scss'\n\ninterface Props {\n name?: string;\n}\n\nexport default function({name}: Props) {\n const [webGLDisabled, setWebGLDisabled] = useState(false)\n\n let banner;\n if (name || webGLDisabled) {\n banner =
\n

Goretro

\n
\n } else {\n banner = { setWebGLDisabled(true) }}/>\n }\n\n return
{ banner }
\n}\n","import React, { useState } from 'react';\n\nimport './Login.scss'\n\nconst nameLocalStorageKey: string = \"nickname\"\n\ninterface LoginProps {\n onNameSet: (name: string) => void;\n}\n\nexport default function({onNameSet}: LoginProps) {\n const [name, setName] = useState(\n localStorage.getItem(nameLocalStorageKey) || \"\"\n );\n\n const handleSetName = () => {\n if (name) {\n const trimmedName = name.trim()\n localStorage.setItem(nameLocalStorageKey, trimmedName)\n onNameSet(trimmedName);\n }\n }\n\n return
\n setName(e.target.value)}\n value={name}\n onKeyDown={(e) => { e.key === 'Enter' && handleSetName() }}\n data-test-id=\"login-nickname\"\n />\n\n \n
\n}\n","import React, { useState, useRef, useEffect } from 'react';\n\nimport * as types from '../types';\n\nimport './Note.scss'\n\ninterface Props {\n note?: types.Note;\n author?: string;\n editable: boolean;\n onNoteSave: (text: string, id?: number) => void;\n tabIndex?: number\n}\n\n// If `note` is present, behaves as an Note that can be edited or deleted.\n// Otherwise, behaves as a Note creator that gets empty after edition.\n// `note` is not meant to change over the lifetime.\nexport default function({note, author, editable, onNoteSave, tabIndex}: Props) {\n const textareaRef = useRef(null);\n const [editedText, setEditedText] = useState(\"\")\n const isCreate = !note\n const isInEditMode = editedText !== \"\" || isCreate\n\n useEffect(() => {\n if (!isCreate && isInEditMode) textAreaFocus(textareaRef.current)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [editedText])\n\n author = author || \"Unknown author\"\n\n // Callbacks\n\n const handleEdit = () => {\n setEditedText(note!.text)\n }\n\n const handleDelete = () => {\n onNoteSave(\"\", note?.id)\n setEditedText(\"\")\n }\n\n const handleCancelEdition = () => {\n setEditedText(\"\")\n }\n\n const handleSave = () => {\n onNoteSave(editedText!, note?.id)\n setEditedText(\"\")\n if (isCreate) {\n textareaRef.current?.focus()\n }\n }\n\n // Badges\n\n const editBadge = () => \n const authorBadge = () => { author }\n const saveBadge = () => \n const cancelBadge = () => \n const deleteBadge = () => \n\n // Logic\n\n const text = isInEditMode ? editedText : note?.text\n\n const badges = () => {\n if (!editable) {\n return authorBadge()\n } else {\n if (isCreate) {\n return saveBadge()\n }\n if (isInEditMode) {\n // reversed because of the float:right.\n return [saveBadge(), cancelBadge(), deleteBadge()]\n } else {\n return editBadge()\n }\n }\n }\n\n const container = () => {\n if (isInEditMode) {\n return setEditedText(e.target.value) }\n value={ text }\n ref={ textareaRef }\n onKeyDown={ onMetaEnter(handleSave) }\n placeholder=\"…\"\n tabIndex={tabIndex}\n data-test-id=\"noteeditor-text\"\n />\n } else {\n return
{ text }
\n }\n }\n\n // Render!\n\n return
\n { container() }\n { badges() }\n
\n}\n\nfunction onMetaEnter(fn: (e: React.KeyboardEvent) => any) {\n return (e: React.KeyboardEvent) => {\n if (e.keyCode === 13 && (e.metaKey || e.ctrlKey)) fn(e)\n }\n}\n\nfunction textAreaFocus(textarea: HTMLTextAreaElement | null) {\n if (!textarea) return\n textarea.focus()\n textarea.setSelectionRange(textarea.value.length,textarea.value.length);\n}\n\n// ✎\n// …\n// ✓\n// ✕␘\n// ⏎ ↵ 💾\n// ␡⌫🗑\n","import React from 'react';\n\nimport Note from './Note'\nimport './Column.scss'\nimport * as types from '../types';\n\ninterface Props {\n editable: boolean;\n icon: string;\n notes: types.Note[];\n participants: Map;\n onNoteSave: (text: string, id?: number) => void;\n tabIndex: number;\n}\n\nexport default function({editable, icon, notes, participants, onNoteSave, tabIndex, ...rest}: Props) {\n const noteComponents = notes.filter((n) => n.text !== \"\").map((n) => )\n\n if (editable) {\n noteComponents.push()\n }\n\n return
\n

{icon}

\n\n { noteComponents }\n
\n}\n","import React from 'react';\n\nimport './Participants.scss'\nimport * as t from '../types';\n\ninterface Props {\n participants: Map\n participantNames: Map\n hostId: string\n userId: string\n}\n\nexport default function({participants, participantNames, hostId, userId}: Props){\n return
\n

Online ({ participants.size })

\n
    { Array.from(participantNames).map(([id, name]) => {\n let badgesArr = []\n if (participants.get(id)?.finishedWriting) badgesArr.push(flagComponent('READY'))\n if (id === userId) badgesArr.push(flagComponent('YOU'))\n if (id === hostId) badgesArr.push(flagComponent('HOST'))\n\n return
  • {name}{badgesArr}
  • \n })}
\n
\n}\n\nfunction flagComponent(text: string) {\n return \n {text}\n \n}\n","import React, { useState } from 'react';\n\nimport * as t from '../types'\n\nimport './StatusParticipant.scss'\n\nfunction stateDescription(state: t.RoomState, hasFinished: boolean) {\n switch(state) {\n case t.RoomState.WAITING_FOR_PARTICIPANTS:\n return \"Waiting for the host to press start...\"\n case t.RoomState.RUNNING:\n if (hasFinished) {\n return \"Waiting for other participants to be ready...\"\n } else {\n return \"Notes will be shared and reviewed in the next stage.\"\n }\n case t.RoomState.REVIEWING:\n return \"Review & Action Points\"\n }\n}\n\nconst hasFinishedToBtnLabel: {[key: string]: string} = {\n false: \"I'm done!\",\n true: \"Back to editing\"\n}\n\ninterface Props {\n state: t.RoomState\n onHasFinishedWriting?: (ready: boolean) => void;\n}\nexport default function({state, onHasFinishedWriting}: Props) {\n const [hasFinished, setHasFinished] = useState(false)\n const showHasFinishedBtn = state === t.RoomState.RUNNING && onHasFinishedWriting\n const disableHasFinishedBtn = !onHasFinishedWriting\n\n const handleHasFinished = () => {\n const nextHasFinished = !hasFinished\n setHasFinished(nextHasFinished)\n if (onHasFinishedWriting) onHasFinishedWriting(nextHasFinished)\n }\n\n return
\n
{ stateDescription(state, hasFinished) }
\n { showHasFinishedBtn && }\n
\n}\n/*

*/\n","import React from 'react';\n\nimport * as t from '../types'\n\nimport './StatusHost.scss'\n\nconst stateDescription = {\n [t.RoomState.WAITING_FOR_PARTICIPANTS]: \"Press start when everyone is ready.\",\n [t.RoomState.RUNNING]: \"Give participants time to write notes.\",\n [t.RoomState.REVIEWING]: null,\n}\n\nconst nextButton = {\n [t.RoomState.WAITING_FOR_PARTICIPANTS]: {text: \"Start!\", testId: \"room-start\"},\n [t.RoomState.RUNNING]: {text: \"Close & Review\", testId: \"room-close\"},\n [t.RoomState.REVIEWING]: null,\n}\n\ninterface Props {\n state: t.RoomState\n onStateTransition: () => void;\n}\nexport default function({state, onStateTransition}: Props) {\n const btn = nextButton[state]\n const descr = stateDescription[state]\n\n if (!descr && !btn) return null\n return
\n

Host Controls

\n { btn && }\n { descr &&
{ descr }
}\n
\n}\n","import React, { useState, useEffect } from 'react';\n\nimport './Link.scss'\nimport ClipboardImg from '../images/clipboard.png'\n\ninterface Props {\n link: string\n}\nexport default function({link}: Props) {\n const [clicked, setClicked] = useState(false)\n useEffect(() => {\n if (clicked) {\n const id = setTimeout(() => { setClicked(false) }, 1500)\n return () => clearTimeout(id)\n }\n }, [clicked])\n\n const handleCopy = () => {\n navigator.clipboard.writeText(link)\n setClicked(true)\n }\n\n return
\n

Invite participants!

\n
\n
\n { !clicked && }\n { clicked && Copied! }\n
\n\n {link}\n
\n
\n}\n","import React, { useState } from 'react';\n\nimport * as t from '../types';\n\nimport Column from './Column'\nimport Participants from './Participants'\nimport StatusParticipant from './StatusParticipant'\nimport StatusHost from './StatusHost'\nimport Link from './Link'\n\nimport './Room.scss'\n\nconst moodIcons = {\n [t.Mood.POSITIVE]: \"👍\",\n [t.Mood.NEGATIVE]: \"👎\",\n [t.Mood.CONFUSED]: \"🤔\",\n}\n\ninterface Props {\n room: t.Room;\n userId: string;\n link: string;\n onNoteSave: (mood: t.Mood, text: string, id?: number) => void;\n onStateTransition: () => void;\n onHasFinishedWriting: (hasFinished: boolean) => void;\n}\n\nexport default function({room, userId, link, onNoteSave, onStateTransition, onHasFinishedWriting}: Props) {\n // Refactor nameById and participantById into a same ExtendedParticipant.\n const [hasFinished, setHasFinished] = useState(false)\n\n const nameById = idToName(room.participants)\n const participantById = new Map(room.participants.map(p => [p.clientId, p]))\n\n const notesByMood = moodToNotes(room.notes)\n const isHost = userId === room.hostId\n const isWaiting = room.state === t.RoomState.WAITING_FOR_PARTICIPANTS\n const isRunning = room.state === t.RoomState.RUNNING\n const isReviewing = room.state === t.RoomState.REVIEWING\n const handleHasFinishedWriting = (hasFinished: boolean) => {\n setHasFinished(hasFinished)\n onHasFinishedWriting(hasFinished)\n }\n\n return
\n { !isWaiting &&
\n { [t.Mood.POSITIVE, t.Mood.NEGATIVE, t.Mood.CONFUSED].map((mood, index) =>\n onNoteSave(mood, text, id) }\n data-test-id={ \"room-column-\" + t.Mood[mood].toLowerCase() }\n tabIndex={index + 1}\n />\n ) }\n
}\n\n
\n
\n \n { isWaiting && }\n
\n\n
\n { isReviewing && }\n \n
\n\n
\n { isHost && }\n
\n
\n
\n}\n\nfunction moodToNotes(notes: t.Note[]): { [key: number]: t.Note[] } {\n const notesByMood: { [key: number]: t.Note[] } = {\n [t.Mood.POSITIVE]: [],\n [t.Mood.NEGATIVE]: [],\n [t.Mood.CONFUSED]: [],\n }\n for (const note of notes) {\n notesByMood[note.mood].push(note)\n }\n return notesByMood\n}\n\n// Return a mapping of ID the corresponding participant name PLUS a number if needed to make the name unique.\n// e.g. { AH13ubga71ef901: \"Joe (1)\", 9nd16vf00shBBs: \"Joe (2)\"}\nfunction idToName(participants: t.Participant[]): Map {\n const nameToIDs = new Map()\n participants.forEach(p => {\n let ids = nameToIDs.get(p.name)\n if (ids === undefined) {\n ids = []\n nameToIDs.set(p.name, ids)\n }\n ids.push(p.clientId)\n })\n\n const res = new Map()\n nameToIDs.forEach((ids, name: string) => {\n if (ids.length > 1) {\n ids.forEach((id, index) => {\n res.set(id, `${name} (${index + 1})`)\n })\n } else {\n res.set(ids[0], name)\n }\n })\n\n return res\n}\n\n// Export\n\nfunction handleExport(notes: t.Note[], participants: Map) {\n const now = new Date()\n triggerDownload(\n exportFileName(now),\n JSON.stringify(buildExportData(notes, participants, now), null, 2)\n )\n}\n\nfunction triggerDownload(fileName: string, data: string) {\n const a = document.createElement(\"a\");\n document.body.appendChild(a);\n a.style.cssText = \"display: none;\";\n\n const blob = new Blob([data], {type: \"octet/stream\"})\n const url = window.URL.createObjectURL(blob)\n\n a.href = url;\n a.download = fileName;\n a.click();\n window.URL.revokeObjectURL(url);\n a.remove();\n}\n\nfunction exportFileName(date: Date): string {\n const formattedDate = date.toISOString().split(\"T\")[0]\n return `${formattedDate}-retrospective.json`\n}\n\nfunction buildExportData(notes: t.Note[], participants: Map, date: Date): any {\n const resNotes: any[] = []\n\n notes.forEach(n => {\n resNotes.push({\n mood: moodIcons[n.mood],\n content: n.text,\n author: participants.get(n.authorId),\n })\n })\n\n return {\n date: date.toISOString(),\n notes: resNotes,\n }\n}\n","import React, { useReducer, useEffect, Dispatch } from 'react';\n\nimport { Connection } from './connection';\nimport * as types from './types';\n\nimport AppGlobalMessage from './components/AppGlobalMessage';\nimport Header from './components/Header';\nimport Login from './components/Login';\nimport Room from './components/Room';\n\nimport './App.scss'\n\ninterface Props {\n connection: Connection\n}\n\nexport default function({connection}: Props) {\n const [state, dispatch] = useReducer(reducer, initialState)\n\n useEffect(() => {\n connect(connection, dispatch)\n readRoomIdFromURL(dispatch)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n useEffect(() => {\n if (state.identified) {\n if (state.roomId) {\n connection.joinRoom(state.roomId)\n } else {\n connection.createRoom()\n }\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [state.identified, state.roomId])\n\n return (\n
\n
\n\n
\n { mainComponent(connection, state, dispatch) }\n
\n
\n );\n}\n\nfunction mainComponent(connection: Connection, state: types.State, dispatch: Dispatch) {\n if (state.error) {\n return { state.error }\n }\n\n if (!state.name) {\n return handleNameSet(connection, dispatch, name) }/>\n }\n\n if (!state.room) {\n return \n }\n\n return { handleNoteSave(connection, state, dispatch, mood, text, id) }}\n onStateTransition={() => { handleRoomStateIncrement(connection, state) }}\n onHasFinishedWriting={(hasFinished) => { handleFinishedWriting(connection, hasFinished)} }\n />\n}\n\nfunction handleNameSet(connection: Connection, dispatch: Dispatch, name: string): void {\n dispatch({type: 'name', payload: name})\n connection.identify(name).then(() => {\n dispatch({type: 'identifyReceived', payload: true})\n })\n}\n\nfunction handleRoomStateIncrement(connection: Connection, state: types.State): void {\n connection.setRoomState(state.room!.state + 1)\n}\n\nfunction handleNoteSave(connection: Connection, state: types.State, dispatch: Dispatch, mood: types.Mood, text: string, id?: number): void {\n if (id !== undefined) {\n dispatch({type: 'noteUpdated', payload: {noteId: id, text: text}})\n connection.saveNote(id, text, mood)\n } else {\n const note = {\n authorId: connection.clientId,\n id: id || state.room!.notes.length,\n text: text,\n mood: mood,\n }\n dispatch({type: 'noteCreated', payload: note})\n connection.saveNote(note.id, note.text, note.mood)\n }\n}\n\nfunction handleFinishedWriting(connection: Connection, hasFinished: boolean) {\n connection.setFinishedWriting(hasFinished)\n}\n\n// Connect the EventSource to the State via Actions.\nfunction connect(connection: Connection, dispatch: Dispatch): void {\n connection.onMessage((message) => {\n switch (message.event) {\n case \"state-changed\":\n dispatch({type: 'roomStateChanged', payload: message.payload})\n break\n case \"current-state\":\n // TODO(charles): change when BE changes.\n const room = message.payload\n room.notes = restructureRoomNotes(room.notes)\n // Change URL\n writeRoomIdInURL(message.payload.id)\n dispatch({type: 'roomReceive', payload: room})\n break\n case \"participant-added\":\n dispatch({type: 'roomParticipantAdd', payload: message.payload})\n break\n case \"participant-removed\":\n dispatch({type: 'roomParticipantRemoved', payload: message.payload})\n break\n case \"participant-updated\":\n dispatch({type: 'roomParticipantUpdated', payload: message.payload})\n break\n case \"host-changed\":\n dispatch({type: 'hostChange', payload: message.payload})\n break\n }\n });\n\n connection.onConnectionStateChange((connected) => {\n dispatch({type: 'connectionStatus', payload: connected})\n });\n\n connection.start().then(() => {\n // Connected\n }).catch((err) => {\n dispatch({type: 'connectionError', payload: err.toString()})\n })\n}\n\n// URL\n\nconst ROOMID_PARAM = `id`\n\nfunction writeRoomIdInURL(roomId: string) {\n window.history.replaceState(null, document.title, `/?${ROOMID_PARAM}=${roomId}`);\n}\n\nfunction readRoomIdFromURL(dispatch: Dispatch): void {\n const roomId = (new URL(window.location.toString())).searchParams.get(ROOMID_PARAM)\n if (!roomId) {\n return\n }\n dispatch({type: 'roomIdSetFromURL', payload: roomId})\n}\n\n// State\n\nconst initialState: types.State = {\n connected: false,\n identified: false,\n}\n\n// // Go to Room:\n// const initialState: types.State = {\n// connected: false,\n// identified: false,\n// name: \"Charles\",\n// room: {\n// state: 2,\n// hostId: \"111\",\n// notes: [\n// {authorId: \"111\", id: 1, text: \"Lorem ipsum, or lipsum as it is sometimes known, is dummy text used in laying out print, graphic or web designs. The passage is attributed to an unknown typesetter in the 15th century who is thought to have scrambled parts of Cicero's De Finibus Bonorum. Lorem ipsum, or lips\", mood: 2},\n// {authorId: \"111\", id: 2, text: \"Lorem ipsum, or lipsum as it is sometimes known, is dummy text used in laying out print, graphic or web designs. The passage is attributed to an unknown typesetter in the 15th century who is thought to have scrambled parts of Cicero's De Finibus Bonorum.\", mood: 2},\n// ],\n// participants: [\n// {name: \"Charles\", clientId: \"111\"}\n// ]\n// }\n// }\n\nfunction reducer(state: types.State, action: types.Action): types.State {\n switch (action.type) {\n case 'connectionStatus':\n return {...state, connected: action.payload}\n case 'connectionError':\n return {...state, error: action.payload}\n case 'name':\n return {...state, name: action.payload}\n case 'identifyReceived':\n return {...state, identified: action.payload}\n\n case 'roomIdSetFromURL':\n return {...state, roomId: action.payload}\n case 'roomReceive':\n return {...state, room: action.payload}\n case 'roomParticipantAdd':\n return {\n ...state,\n room: {\n ...state.room!,\n participants: [\n ...state.room!.participants,\n action.payload,\n ]\n }\n }\n case 'roomParticipantRemoved':\n return {\n ...state,\n room: {\n ...state.room!,\n participants: state.room!.participants.filter((p) => p.clientId !== action.payload.clientId),\n }\n }\n case 'roomParticipantUpdated':\n const updatedParticipants = [...state.room!.participants]\n const updatedIndex = updatedParticipants.findIndex((p) => p.clientId === action.payload.clientId)\n updatedParticipants[updatedIndex] = action.payload\n return {\n ...state,\n room: {\n ...state.room!,\n participants: updatedParticipants\n }\n }\n case 'roomStateChanged':\n return {...state, room: {...state.room!, state: action.payload}}\n case 'hostChange':\n return {...state, room: {...state.room!, hostId: action.payload}}\n case 'noteCreated':\n return {\n ...state,\n room: {\n ...state.room!,\n notes: [\n ...state.room!.notes,\n action.payload,\n ]\n }\n }\n case 'noteUpdated':\n const {noteId, text} = action.payload\n const notes = [...state.room!.notes] // copy\n const noteIndex = notes.findIndex((n: types.Note) => n.id === noteId)!\n notes[noteIndex] = {\n ...notes[noteIndex],\n text: text,\n }\n return {\n ...state,\n room: {\n ...state.room!,\n notes: notes,\n }\n }\n default:\n throw new Error(`Unknown action ${action}`);\n }\n}\n\nfunction restructureRoomNotes(notes: {[clientId: string]: types.Note[]}): types.Note[] {\n return Object.values(notes).flat();\n}\n","import React from 'react';\nimport ReactDOM from 'react-dom';\nimport * as serviceWorker from './serviceWorker';\n\nimport { Connection, generateClientId, generateSecret } from './connection';\nimport { getSetLocalStorage, trimBase64Padding } from './utils'\nimport './index.scss';\nimport App from './App';\n\n// the ID/secret generation functions already generate unpadded values, but we\n// might still have some old padded values in the local storage.\nconst clientId = trimBase64Padding(getSetLocalStorage(\"clientId\", generateClientId))\nconst secret = trimBase64Padding(getSetLocalStorage(\"secret\", generateSecret))\nconst connection = new Connection('/api', clientId, secret);\n\nReactDOM.render(\n \n \n ,\n document.getElementById('root')\n);\n\n// If you want your app to work offline and load faster, you can change\n// unregister() to register() below. Note this comes with some pitfalls.\n// Learn more about service workers: https://bit.ly/CRA-PWA\nserviceWorker.unregister();\n"],"sourceRoot":""}