From b70254cc5647f92bde6a1850f074ecae42d329cd Mon Sep 17 00:00:00 2001 From: Yun Feng Date: Sun, 16 Oct 2022 17:30:58 +1100 Subject: [PATCH 01/40] feat: add rrweb web-extension package --- .vscode/rrweb-monorepo.code-workspace | 4 + packages/web-extension/package.json | 45 + packages/web-extension/src/assets/icon128.png | Bin 0 -> 9279 bytes packages/web-extension/src/assets/icon16.png | Bin 0 -> 3733 bytes packages/web-extension/src/assets/icon48.png | Bin 0 -> 4862 bytes .../web-extension/src/background/index.ts | 86 + .../src/components/CircleButton.tsx | 33 + .../src/components/SidebarWithHeader.tsx | 290 ++ packages/web-extension/src/content/index.ts | 167 + packages/web-extension/src/manifest.json | 28 + packages/web-extension/src/options/App.tsx | 38 + .../src/options/RRWebVersion.tsx | 312 ++ packages/web-extension/src/options/index.html | 8 + packages/web-extension/src/options/index.tsx | 22 + packages/web-extension/src/pages/App.tsx | 37 + packages/web-extension/src/pages/Player.tsx | 69 + .../web-extension/src/pages/SessionList.tsx | 64 + packages/web-extension/src/pages/index.html | 8 + packages/web-extension/src/pages/index.tsx | 22 + packages/web-extension/src/popup/App.tsx | 155 + packages/web-extension/src/popup/Timer.tsx | 25 + packages/web-extension/src/popup/index.tsx | 15 + packages/web-extension/src/popup/popup.html | 8 + packages/web-extension/src/types.ts | 71 + packages/web-extension/src/utils/channel.ts | 184 + packages/web-extension/src/utils/index.ts | 75 + packages/web-extension/tsconfig.json | 23 + packages/web-extension/vite.config.ts | 47 + yarn.lock | 4232 ++++++++++++++++- 29 files changed, 5943 insertions(+), 125 deletions(-) create mode 100644 packages/web-extension/package.json create mode 100644 packages/web-extension/src/assets/icon128.png create mode 100644 packages/web-extension/src/assets/icon16.png create mode 100644 packages/web-extension/src/assets/icon48.png create mode 100644 packages/web-extension/src/background/index.ts create mode 100644 packages/web-extension/src/components/CircleButton.tsx create mode 100644 packages/web-extension/src/components/SidebarWithHeader.tsx create mode 100644 packages/web-extension/src/content/index.ts create mode 100644 packages/web-extension/src/manifest.json create mode 100644 packages/web-extension/src/options/App.tsx create mode 100644 packages/web-extension/src/options/RRWebVersion.tsx create mode 100644 packages/web-extension/src/options/index.html create mode 100644 packages/web-extension/src/options/index.tsx create mode 100644 packages/web-extension/src/pages/App.tsx create mode 100644 packages/web-extension/src/pages/Player.tsx create mode 100644 packages/web-extension/src/pages/SessionList.tsx create mode 100644 packages/web-extension/src/pages/index.html create mode 100644 packages/web-extension/src/pages/index.tsx create mode 100644 packages/web-extension/src/popup/App.tsx create mode 100644 packages/web-extension/src/popup/Timer.tsx create mode 100644 packages/web-extension/src/popup/index.tsx create mode 100644 packages/web-extension/src/popup/popup.html create mode 100644 packages/web-extension/src/types.ts create mode 100644 packages/web-extension/src/utils/channel.ts create mode 100644 packages/web-extension/src/utils/index.ts create mode 100644 packages/web-extension/tsconfig.json create mode 100644 packages/web-extension/vite.config.ts diff --git a/.vscode/rrweb-monorepo.code-workspace b/.vscode/rrweb-monorepo.code-workspace index 896a62e5d9..0ef18ad4d8 100644 --- a/.vscode/rrweb-monorepo.code-workspace +++ b/.vscode/rrweb-monorepo.code-workspace @@ -23,6 +23,10 @@ { "name": "rrweb-snapshot (package)", "path": "../packages/rrweb-snapshot" + }, + { + "name": "web-extension (package)", + "path": "../packages/web-extension" } ], "settings": { diff --git a/packages/web-extension/package.json b/packages/web-extension/package.json new file mode 100644 index 0000000000..a48f4dff2a --- /dev/null +++ b/packages/web-extension/package.json @@ -0,0 +1,45 @@ +{ + "name": "web-extension", + "version": "0.2.0", + "description": "The web extension of rrweb which helps to run rrweb on any website out of box", + "author": "Yanzhen Yu, Yun Feng", + "scripts": { + "dev:chrome": "cross-env TARGET_BROWSER=chrome vite dev", + "dev:firefox": "cross-env TARGET_BROWSER=firefox vite dev", + "build:chrome": "cross-env TARGET_BROWSER=chrome vite build", + "build:firefox": "cross-env TARGET_BROWSER=firefox vite build", + "pack:chrome": "cross-env TARGET_BROWSER=chrome ZIP=true vite build", + "pack:firefox": "cross-env TARGET_BROWSER=firefox ZIP=true vite build", + "test": "jest", + "check-types": "tsc -noEmit", + "prepublish": "npm run pack:chrome && npm run pack:firefox" + }, + "devDependencies": { + "@types/react-dom": "^18.0.6", + "@types/webextension-polyfill": "^0.9.1", + "@vitejs/plugin-react": "^2.1.0", + "cross-env": "^7.0.3", + "jest": "^29.0.3", + "rrweb": "^2.0.0-alpha.3", + "rrweb-player": "^1.0.0-alpha.3", + "ts-jest": "^29.0.1", + "type-fest": "^2.19.0", + "typescript": "^4.8.3", + "vite": "^3.1.2", + "vite-plugin-web-extension": "^1.4.4", + "vite-plugin-zip": "^1.0.1", + "webextension-polyfill": "^0.10.0" + }, + "dependencies": { + "@chakra-ui/react": "^2.3.4", + "@emotion/react": "^11.10.4", + "@emotion/styled": "^11.10.4", + "framer-motion": "^7.3.6", + "mitt": "^3.0.0", + "nanoid": "^4.0.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-icons": "^4.4.0", + "react-router-dom": "^6.4.1" + } +} diff --git a/packages/web-extension/src/assets/icon128.png b/packages/web-extension/src/assets/icon128.png new file mode 100644 index 0000000000000000000000000000000000000000..c053fb110dcffdd2fffc8688ec5b23f728a99e54 GIT binary patch literal 9279 zcmZvgbyQT*xA+k&tc#q`L>DR7z61l%cz0 z_>J%V)_dPS-d*e5bJpGa-nH+(`|h*%CsIRAo{X557ytl}DJsCVuru=CpuoqTlPWtR z002@6+m|mj6kon%(r|UMvURWo02CsV^$85Lzdy`2(qgU$fV5X_*`)>j8 zDHD%)+uORku7|3fOgRJqDl!+CWKJrQ5!3X-&<3Wp7#_4 zA6y}jkA6PydDC$CjG1i`s*%*>H4Hr@c$d;HN*P0miZx0Io7e9{hqR8+EmSRtPgMkC znYbxhcOEIof{Ff#sJhi8reYZfO?H*&Py;fv{+rBZ=c1vFRjzk`a%14MoFA4zs|G>r zP^rAQ2UZHf=E-M8-j^ZAy+YPRFA|jea+x?KbP^c9g!L!)lcR$hNZ?;WrRk+HzazR^ z4)B7cqgu=tK$4--qPd>0cMB$Z=_6zjj z{W^>iIb3ykYfukn@OvBqaG)T3Bt>iwOT(=Vs;+42q*;9G6AYwLkYc3(5U>b{fE5=Z z!P6odq?k|zz)^S~-heM&F2xZd+@N<7XffbR@)zQY(vCQm5*Y|P*Sci?72gCuz~%oM z=!O3JBjj-XE64WT`3=)`)*ES7nePe&;`|c?+>z2fQfBOYX*M6|mOGn;8Gu!oYS@~} zyqhz_(k_uY5q+q9=ys^u*WJjkEr~h#PjFy)0oD98o099Grr`9qUVuHE$vpnb4|D*6 z`3F~TRsu%r=qzS_G+VxUb5nTR^!VoB`Nwzn*@%@M%N>^dz7f+JQX6tqkWJZUJT8b3 z^k-k%$;-~UtqUBGU~F8GG%_Qp3HkkE=l(mOXw)PQ{yUI8%CN?qU#z}0dq96Wx5>a; z?1hH>1$khIx?ak6zY^LKh7z8rPLOoM4n5iLq#kXSuY+Ge_#^?8xTLWWXp!KRoj*II z$ertaFaM6ngg{}6g{l4dc1gg&3qD?6=Rcw}??A{~2Ip(x0JKBe!FV1Bbt#vvqxE^& zc_s|7M78ByvWa7Ede33mFEdE=03X9d7#hS*L7v!+`^f*HF`9}OPldouiijQOC(5px z!2x8{tyWF&1aP{{E`m24tei`4OyIe)wF%;pV)P=AfDp>a*bvhHl2@Tn?qP6|ON-#4 z3WYP(DDWq~w*Z6TQ7ZE5%$5Vh7UH#drE+JGn1QE%Kx0AkatvVc0sBAHQF&#bh3rBN z^B|h6KV-iB@^TkTk5rTU@auAe%AMOVY)@``RC|Nv1U4JlDRs?GZ+f0(5f+qA?DN;wqP<~bwCfzEt1@>nuk5?TS{$uJ&{0g3} z{ETfM%*cjdmV^Wr+h}k-HTlR+oWq}7`>{4=4Bn!$neSI@r&UoZG2vw=zWw~tmIt+Ln6hF+)BJa21IFw`@YHuS5wG&E{ZvllNm zcXxwj3>SDpR5ZMpotd?q^{t<)zjm*8H};_Nh;rv}kKJ_NGHcaqeX?M@ zP}EA`?z9m=YxO)@P=(jwSM}^0{r4Tybd~5Two%T>xpL3f`$-ZnB^4y)16u+*F#b66 zs9~l))2ME_5CQy-Zw=wT#h&2`#)rTXwFq^G+{7bQ)s}?UB@+TkX`5JWa*e}(SRyjESobN zNjHD(@Y>veVDRiSGPID&9=>v>3Oz+_b!_&q#&$^%08Pgh@w9K{<8wxEL)@?VL?6e0#lWvc0(W zW+h==bJHcMbST>DnN{{V)C=Eh_(*K)^4HIWa@00*8nJk9@x@|Wdz-vb+{5Tap{ts> zPvq0qAJj{Dz6lR`);X2rlrm0N{n$_FYLQ$DY`YUk;pWU}$T;OkJ(Z$z7Fiab`yd|T z&rd-@O2kFxKr%+GL}~ zrogPEKl?*LziRZ{gY#z+OaZnx3%D7$wlZ${K4x}i9;?@dsKN(|S?2PwS$t<&wbHe` zEzDsb6VqzNivo>Dnym({cQ$99w?ve;c z8TIa}qYL$m&kujM3%1kv1!6b?;!yI{G6!7W*vw_+Jd4%We+*`Gb$vPdV!~|HY;wUN z`rKFh>^k#vCjASX7R46d;{k75?-($*X6$Fn#KXdTMS3$|m&j(f+UY-&N!QSo#NA5; z%*D-nkmChpiK8I_1NJxAFf!1*c%!uXF+?_9Ha~x=^qn@1s=wY7xe&ua2!fhVFgpaJ%QBHk`SHh7G;uJKt?D^j1BNSs%&1yGV^k z*eOjYL0N=pym)@sQy|!le>V;5IC{#N*2D5H(UfS7^rz>&t^H&-iTu)?=?uMz%w{?;#DU&@;sn7bu; zj;}ys<=;IK6gPBHLH{0Gn^-%JBhO@)_!X$-S9`9rUfMrIow1+I;Cp4LtfD;k=|BKI zf}bPqAM3H#P8?kHp zHg2N5U(~v69d4*<|ZL6)JVWS(Pg(f$ru2yX?^zp*XIpMj|zWqE;py@^K z7Wtgy*}GOx2H!^))u)>C1#NNOaR{;Rfk#F58132dBWu=?vbL z02fFLz{9S9*dYO=`=7NOkR5>YU)MnZK)5Xc_y6mtVdsB`0(Shn=f7uAF6e(WkhwVj zyZ)yt+A)glU;sqU3a{J%021nd0|-dZd;|c{@F>Eib-aMPS>*9hUH|?rPbm@1z|d2C z=~3WQYN=JIwBn~na!MSuyls*9lR30qMojSpzwatW*DNokc< zf4syogyC@HBb)R=3`f@J3&`D@Ws&9((SXhU?OVsXh2xFvg-DdAMs-9i@ zzPB0ERZBS!oYkOkN@f#npOlY7@qxvCLnK=Tt&6hzzN41H$la(|Q->1clI zTk@?}5Zv9O9~vRHPvPyH9$~Bp0hj1S4s<6KdS0Ew0#nxy-vpm?u1RRHfa64i>u?rv zB_Z%XOMQ_FlP@?^JD#OZ;ZtzVH>o?`h}wMwu;~z0R~0y=u81cz%I*+=b`W4x(7ojt z7ErslAaGHK1+@~(-mZd#{KOSOQPO|T9hZ;DVnR()<6g{KfgCcxc;r^UqBu-bg!F#6 zZ|H>km%;y3Q&GOCfy0L%v4RnwDHG{B|LT`q zPD*r&g9f>x&G5?nft$h4v?C~9lq$hH4Itoi)udJY6+C7zI+`j0hgFfLa)d=}Vl55G zi!+L*ld`|J&rY2{Vh{hLDBmePDiq=-A34yeO0`ASKI)$FPsti5zS7nv8PkL{>OCwH zv*kAbj2Ub%uV_K2WRWKf7wKw}Lp4LKBpPb=MpdD9gLa83^(@c(#PXzk^(0_CQtmPN@Dqb%AUV*|_r8Yzyk z2?gZbutyp;(T7Z%kGNf$I5}EQXZyEKG6aZ9AGBubNs-mi%QYHk_vSEZk9m69rRQ7ZOocjV+sKA%^ zMNvnWw{4v8KP$H2bz+Wc`G|p$lE{cNFR^x+R(*-sFH{M>#gTWbC%ZB&@K#UEUvEhR z$g%?@S4ig8Ed7EcE$qJba-J>t2wecT(2eA}c`xRc79qBMfcTl_Mk2X%)P7h%JErmg zB}C70kkEkZRi+5LIRwigUV#@@IdxJ?`$I(f%$C?)Kj^h3$nO*en*Yr-0DC^~F929s_eW?|R_xJDC0WFxPQEKMp8vZbl&hbyzJ;k#=M<2b3-weeC=JtA`8vlFfwi$_vG&Y?cxNXjWVk;em6A1&@;N z!_Fd=+7)k!I919(uB?KC+^4H?G)h=QHC%n9###zw^568_yOZq|=e}L(jL%|OB~g7( zS)O;;PYUTFm3nk3##=fssDz}U$NYqSR=L6I&}8(`qz`tsBR*ZMg;AN|Gkwfthp^4)-iE92`T~s~$?v65n(Pzxp zAr}jatdYf18Lw_87zLu^r+Skd{1^;0$asLvjl!&)D#nZ{hLGH!5C$i#rR73OQ;LXvS+atTxxRNSH&$r&oTaU4(h&Q_|^H^NeArL&-v%xgoY;|fCH=&0en$et zc!i=)ukH1JWBvuN6V-jsw|ZvF=DMIKdaN@!l4Kx1drrlN(nEcuv;C}!(RE8xcpCIa zjRY!G2?ff~SHvo*e|`-9_;lo@5-}k9qwx5s1byq0Rd^3mwve$6w>ah9yb<$;ah*CF zJ!T)4zCK~kEkDL^5K^cwk!7Bd0@W5|ZthT<-z2axfN*3&(W@rLCU*s%!9X{1$rfwd zMq!cVga zpPwc}eCr>uB%XYi)F3?gX$fj?Pyy^#*U{oS+dIl(%AX|2$Bs*j!}OOBm24Rxu~QOEX!V&9UmaH*}!!qfrDSzb)Ngvs;8QbCx^R>2f44B zI4dVa+{_Sux`W~PEb=z;;^aPFC=Zjam)e^3+6*o)pWmV~V)rWONivF>*J0Z%I14~H z^~je*4%|&B*6JAC5c1s}on8@BUiOJl&TJ19D_5;aZWa2LQ`ol{EE)*_H2ah z8_0Hk+GYi2d=J5*`GWmoBX9H7hS1)3HY(5iRHdS9M~RT~4_6zI@ug@g-zkKF#BYey z2qSRpvAa()G$zQfdVCIBhQaB&$NFEDUC*+^)-#(;fIBqt==y~HOiggUBa^ajcz5$# z0f4_S;A%v8FSD7=Uc#s(OUP&QXj-`fwLb?1A8x}bJ6sybnD=u`PQ9?j=S?qR4P95; z`){ODOJqo^UGzc}D3!^>4uW@3$*qPZt$RV?KFK zMMenapIuY3@O1oy%#)(>9|O2Y8EIKBortjeq{9505?@DQL&&eSz8Dv<<@B*UlwmSe ztUSk%1)M|64A!5H9B8x!kGWnT<|6yWx#54JToT;{ry67ax_tBCS!yi^e~j!E06Zg* zt*6}k;gT4*W{j;U4STblq(}R{9%Cy-&u#dh6quqNtEW130^1Xe{KL)BO-St73}YD; zCA~fGlKag5XDQ8>+9GDZaGouAb!-vp)JrkofsYDchfAunAqRtR_yap6g=FCGUfiI! z^&)8Fx3}SNdx@(J4IQ=*@_6ex`);S(vq7yM(jPoCdxZe$e1Re=M~p;`6N=AgD`a8Q zyQ{RDQ@dFcq!YRG0;=#%Y%RY}$9mjlGTGm#lY4ygw#sPw-b4k7Vfz|s6wp8y3`SH^ z-fhcN$T+zRIJuj61gM8ai1DgIr)~AuZPD=hEzGG4_-IoT?5dT_bwgR?AN0EYs79=+ zAM4>J;019?r^Gn6ex$!Dq)3=)!ren&3P&|E8}lk920AZ!S5_ohILDdf&~hPQgE_>1 z(EY0$&#P&s0=w~x@Z+Bm`j~Imb?xI%PDjf2Q*C(H^Bv52tctca*SzC_ch8<90-cOF zM(>Vh=@(LW!aNZN(t?1)`dM)5M8q9;(7kWBb}{gR)$~H7n!s!1X~Htb7Hm=ylHzWa zy?4I{G`*>2aoAek^cWfBkE>vPLWeEdOFULPB(0aejl9c!>a#ZZ2;`qKE%g56le^Ax zF>MVUf0nwk{SqlEkq=;4?H(T=`%Qf*x3$WgXweYd>!d>;ewX91TII5HKe1liAe??( z!zD{llE$;`&$DJv5cw8FsugKdU?k?C=XAcKcRg#LYV3HT%sA4-IMTwFXl)Z65v;HKI`!gTgNW( zUSaO~V25;|EQ7V%Z%`N_{B8nP85kb_MH{E&nEv-N!{Y4m$n+xZ`=E|$49V0sE%Gcz zeTjdzS1+f5CVgcVZGxs$$WcFUIIJ9R!i6=YNgQtBd=ri}mISKm+ zJDq&l<1`Q2b!&N=TZe~up@?LBt{{|rjRXYp%jFk!&chl1?e7G%xXm^=z;`0GHE|r& z%XQm?6rSS4eF8ZcEKSJm@;SeCh*P0lZYP6&+7tC>4o3oLsvxL24k&&3Pyin8-7FL} z-LH`0C17G5OR-F?-NQH{b5(%F3z&`e4eJ&UYG7q16Us#Xtd>I;Wx6KCr~q{P_Fu)W!dZqQDhwBOaiO{y{-lIL#GfEheJ87Yxx-2^LH z3J+H#xTUsQWZjrB86i9reXXQY_0w}DjApKM6irWDOaX6C|j1R^t10 z!$42?Tpe(@+jRgB4ZjZHI=M#pjb8{TTNYo znBzW5hiZ!HPoDQr#}f!A6!zuWU)namMUaCW9*Ln~PL)0vf^fk|Y@y^}?P}Wkv9!`X^+Ck1$ zI40~A*Q+}r`R@e>(5{4nX>T6)ATmD9jwA=*H7}80>7^go*43K%OmJ>ipLN|=VHrM{_>SrCR%aoZDxo`2&$E0~0 zlazpZ_m#_mJuH0^*7v=NWsz>vRLeoE-+#EV6E2%vJK?TQ2Gsp)WN@0jq5(WF5`S|_ zAssS=$g+{)Pb#VPT3=Hgu#gc(}XyLyYKOu8Vp{r7ov7qKz`mhz%!A=9AZM}bG^h1n%l+_S>#VT z+zXSCi$HOHIizG7wyk=or2s5f>g5lcBbOS_X_~Yg^w8AIiay!L5|rwPue`i{Jh7XJ zn5rK+F8ExHIssB{v4S2_zH=pMqLs=lID4f5q(42sq$4`OSQAz6*-()QKT8NE@QtyN z`~*c=W<=g4EN}1wpNWLQk4Z&L)=&>8)PQxFH5__48uaUJljo=C7|Mil?6xal4lf+n z3~a5R5#H`WP>}j6_ zzfwztitT5_vRw4>0xO;3zvSuB8x8-ZpZxk_5A14g{??q)WNRnUxI%B zsNWQTga@m_h&j*ewiR6G>A68S)3`v^J=R|zU#n_eRO3*){G_E4oLx{&{Mp)~m>+n6 zMJiWRiJ{o*7?wT2&hz0d#+zBAKCXTK<)XFPj z3|n{IXLq6{D$BU2n)KLW%&vU6sh7OD#Qi-ewdjSu*gtwF>hELhXuRY8HSsNCL`!rr zs)gps{>*=|-8^IiFf?H#MM*oi0t;7Xf0$(#OFjArS0Opv$;DFGG8Ryu+$*LU#QP7f z%1Ib;s0KA+h`id#oW}2dtHg ro{s8a<&Kto>e@`CSVR5~LvJLhCi7h4RjW?_adkymHF%|rY4HC8+r^Qs literal 0 HcmV?d00001 diff --git a/packages/web-extension/src/assets/icon16.png b/packages/web-extension/src/assets/icon16.png new file mode 100644 index 0000000000000000000000000000000000000000..26a6bdd0185253e58d398f7b4293e31596b564b3 GIT binary patch literal 3733 zcmV;G4r=j4Tx07!|IR|i;A$rhelQX#Ye0#ZV6f=CS@C4?40dJ#k=BmqK+F%U%TWl_Pk ziv?`xs)%Bz*%3R7VDF0s1!Y|<*p)XapzFT!z4^Ym^WT5Y{O8QMGxy#BK>Z|FEY3wW z0LT*+NMb_*7-N%D7^J6w3=9DkI0APrFJH`xj*bAZ47PtS?`{A@)?RgxY5lYRzZOlt zAfE>S5)E-WKcANe@gV^4N}gC!002?On@=ea%P_1!TLJ@wc%ckuDsZI?rz`M2xlMd5 z8{!rK$f{hfBohF&cE~ddd6`f{tq)=+5nm_*K%D`xZ(iOcKE!Dd+dvyJ#4>$m`VTsp zf747K(&Tb8hp=KU@Y7Bs5kwXPCEJIg`R=SQX-4 zQF>$)#99!45c1{r5Tn#AX=sAN9yR3UvtiDFF2qiJZeTdXh7bpfaw8*@e0qj3m;*6f zA!w1XfD;d~9>fa;`9X0?o6V9*u}WWPU513sQu61y61iWQuLshc1eQ|&b(Vmm)W_6{ zv*ME=rb28{C`^omSPf#w{G7OOrOoK#EOz9ejYJwNi{Ap`Sb-=cK%tKnW=Mi#mG-51 z`GfPtHfISrkxG1^AS*spksqvu$Cbwq=Yq8hM685C9YOxsh{3t=1%W||xntb|Q9_(j z=YzN)AXYIJr;2lCJ+DzB{Mi8N!}xZ*EmoN{)9*X@`uI+ z$a@8#5b|G#SjE)=WXO99KB$w&u1GSmkxi9y6bVkj|~Xp0-*zPL9Y0k8hBI^#^-b8sHt?Fml_9fU`O z>x53i?TNymT!@h&6pE-|V5DpZ&9c$UYyo z;Xhkq3$cUPIqVd60XvG-0|s^iYrtBuV=_Fnx}L~a*Pyppc|18#NB9qagHKkL$$Y08 zryi#-ioOCtk?b7}*ptLlCBn?C0tO3y5d;j5i03$h;q2t>41nzWqIiA1iIIOd5Z%`A z+`K;k@HsIsFmU8M7j^=G{T^`pH-6`AnDEn~0>Jr3o>Wq(;BeW60N)boaHr`5V_*(! z;C!5cJMaenAP9tkC=d^l!2}q67F_2NFa=Bpb3h3w1Ixf_upVpzTft7S2OI$P;3zl+ z&Voyz9b5-@;p*uEFF+r72RdVvIVI|_9KnRDdYmuf!szOB0b1!(Eo^CGSkybu3Ipb-oS_5?2i zhcK3qNti+?A(Rug6Aly3z`fK(ct<1>b&1wQ54abTiP^+y#Kpu7#J$9m#17(PVn2yQ z(kI!Id`M9wE~$W2LRv@KO*%okLh2%YAgho~$j;o4m9mtwjnYK9OzEP0rfO2HsXo+rYBqHabuG1)dWL$B`bI@X#Z1LhB}PT4 zGFxS>%089zDi2jYs%oj)sj^j5Ri&y+RClPJRK2bGhDM`V(fnyCv;x`^S~cx7?E&qB z8ePp%jibg_o26EvR;PAF?WHqrMd@nZ|Hs+W;Bd7OfYQG zu-ai)hP~GtuIH~O&@0v3t9M=RlRiT~NIyq^xqiL=eFNOU&LGBMior&MGX}lGwTF8T z=M66%eqi_=L)6gDFxGII;a0;|!+s-UqYxvp(K@5kM!m+m#{S0H#;c5v8~2#dO?*v+ zCaX+Nm^^3bFj$OS##%-TqtDdPG}KgTy2Z53^s||@S%TSIv%O~b&8g;0^9=J<=FR4P z7A6*BET&u3SlqFsSTZfMEZ10`vwUx5ZIxuTz^dM=+gi_>V_j@rV|~wtX5(iw*`~_o znk~_mX`5ra!M5EFwR5w}va7JWY>(Qz+Y9YC*msN|jPM*G8c{Xkrh}>j%c0Pr#^Ir( zu49DbT*rFHmm@7kri@%Z^4!R8PHs-QPTQRBj?x+xHfrvurctk*?VNee70%aOXfDAn zvs@ZnUb))43S2k3-g2Y6jd5Gx*6jAx-NRktUhCfDVd0VHQR#7$sm+XLE@qzhBzOjR z&hk9!`O(YWtHA4k*I(Wa-Z|d8yt_wRj~0yHHu|xTnGe@zi%+L7!#B-$vu~%LsUO#` z%I}fCxj)~3yZyVG7t+42`mk43(^Wo2wETXAlNK8 zGq@(WFT^cmTFA*zLTGsC^3aeVrpV_;`^k)q!me>V@HmiG4@ijL9#HpA%&EZn6f>ke_YVG)#JKS-BL?Z zZ;ZDdUo`&01cM2=6OK((pU9nfFpZFwl(sAF3pa{e#qCe$q*tc*@z}gIycc|b{wjWt zz(=q`@GQe8V?{=HrcdU|%$_X2tn#d0AzQd!_$oUzdsFuNoT!`~IRm*#xqI`-d1-l# zA}vvlsAZDzq@qb3Vta9kxO1}C*t8H|C|uaK$Ys&G zMc+#Kr5DSb%F4^WEaok~`0J=&*Zw-NBx6b2Qun1Bml2nVmfcwHw|wUc%@xHf9Ys_ho(7`s)<|6?-cUD;HJ1-@xB+ zWuyPb+D%5A$~Jx4EZlr+OURbGDyypUt;DT`Tc2)A+;;9a=5N*84YrqU|GGo8qjP8M z&X#JA>grvFyO!3VHPV`%-Ko3V_XO@~sCB5_vR8L+**>sOy6^e^wEZ^@gdb==$UInk z$nsF-Vfx|HI;3uDU0;1xeP=^*Lq}s+V{?;t)8QkIM|K=FJz8;0=h)KY)Z_Dy51c4I z(SK5WviDTxsmIL|o9~_;d-_^SOiSCD@H6Mn2A@5Bj&<(Dd7tw~FL+&OyvV#*f64t) zU8`H`;oseUKiuZtR(ILsazndkdsD~gj^kJSuAI6Wc=hZx&b3R|Bd>SdNVsw9X6nt( zTl`zyw{vg5x>I=P^WE9^2=_|wYuqn?VECZw58FTXcDi>Sdl>kz^-xKBm=iZV(HUF%9Y4h^XU;cl!_Kof9dL?-^ z@OtqZ{Wm+_y1s4hkM4i)F7Msv_oW~7KkWR-{CMtD(x+#ir+guOS^L%YYty&zZ}$fB z1_s1j30M9rfWeApWB~Ab2LQBW0O;_1MjfX(|H%uYIJ3$T_)l1IMwAzK0BYg?drU9< zySWL#zHRXM1@+Za0f?pn5bp_47nh+rcvh32D`kZU&jFhwzozG0BmJgNoGw=04e|g00;mC0U7`W000010000!0UH1X00001 z0000+0Vn_i0000100IC2hiL!=000010000^000000000;000010000;0000100N)_ z00aO40096101%)900aO40096101yBG002j3r40Z8010qNS#tmY3ljhU3ljkVnw%H_ z00D(bL_t(Y4ZYN{OT$1E$MJ8~S<*p7M2!e;V%!A5c65uVlMdCtK-AgUMFeqka1z8# zaC6d0#3cd2L6AC$TdRT~h0|Y42sRuSq%z033ax;>1+!&=Nl)58hmR(Bs0wU^0++GC?S*8&OCrt| zESCiCtCAgGYXUo=!11BL%Csb9?4z><4Fnz|vH$2T5?ELl_-?Z2CvTiPkR-ZBFOak) zy@>mA?m+U3VPBFN%m)G!fxw^}kkdR1VzB5+j`xQhgy>H@1JfrChF zWz%@>9r#4xEEZVu<##7a0{dG6aZSQ(zx>|wyd~g;eWTFQ!DrZyEy1s)YD%<00000NkvXXu0mjflqm7v literal 0 HcmV?d00001 diff --git a/packages/web-extension/src/assets/icon48.png b/packages/web-extension/src/assets/icon48.png new file mode 100644 index 0000000000000000000000000000000000000000..31d04fa38a0d0443345960fe9d802cdacc410c20 GIT binary patch literal 4862 zcmYM1byO43+sC&7j!prUoQ#l836<`WW>P~YDGGx0Xrx0L>28&7#?%1=WrRpK$Ur(| zAoc3|{?6~c=X~$?d!FZW&$-WE_uLo*eGMw|JLCWWfJ#eK)#$H_{uAwuzdJaE8v_7P z$~&v57-*@ea2j~HIXJu80|1&a>E>XV@c>i4r4ghF05Vc`3)7_HhR7cxYOw&Dxv)zj$A+fg>oJyCzSGa{b>^?)aA1wysF7V&lB?t>Z z#Y?EUAWlsRfMsCRv{M1yLZlksDy;~iqy#d`fP92S;NM~s69ILUEx{stF9E6(HePR? zFB`9WnDkJb1z-R@)hjuLf=uuM1hB825BoceVPDSUd$eCgYZWa)L=nD4l#cxFWt0^H z`||C2NI{krCIGhD>I0Mk(Cm$sAoqJ`pz@x^j+YM32U5%f*1Op(K;<#cw6lsVVi@s2 zhd(rO?}ESUa*VBcNJQ1y2_Gs`-&~LLY&X6hetof*k}1G;{FJ1|B?BsHcHc3p)lxR~ zvptM)#m3P8*-eZEZ7}WO&lB2`aY1LNu+QvLYd;&G;zEQm`pB2IGMGqOaGVDhR~phk zQZ$Q5%nIU^To=MXQ_qf}AURWdrJXaBqE)XAce0L*7&1D zMEXgY-&y!k?|nxy*<@{GA*X=6Nis+6oBs5E8hltYg=%et5}VT1RP?9zeUeb6*mlG` z$WS@g2p`_Y$!R9WR1xc0l77xC#NwZWees_M!w=R! z^KV@fE;!Hgo+|Mu4`_lPiI0PYVw5n7c6?%4PH`+ts5WVK;K!>vxmDdcPj~jk9kRz{ zY!Mm}TM_!7cVa%brxX;k63G<>)rm82Dy)NA!?Iuc0(Oah6p4R`V*!BY82>z74jO4> zc{V-RX8+{rMd@Yh?TdZMH1C_d$}hNV z493cHv@9!F+ELVpPswiI^aehN{XulY8}uA)QI8OR*wm4aHJ>bOh50>{HPASv2@Zd3 zmN9^=xKqJiArgxMDJ5^SQB9>{jJZF5s|DSl2%;mVOpM0Mge`BcZBvG9pBMWEcE=H^%JfH?7cP6Sm>NO``t&_=W7hHMb(w}T_P-sxD0s)mA{Po zzJ8b;qpuz}dbUCTTFBzfuKL!9@do#?+)NBg@mwsV%C;lx-g=0b*nOrqWwy7oh;w4n z?S8@-&Elj!;gO7682|bt8M=y9$~oYNC4+}R{Br8SyHh*lBNW5OFP8f?rz%}E*Xo6I zlw>EwBA_VIjJH}@%6yPCh86~D1{}J3T+LSlO79gjp-R)noEkHYamMsws4(4_R1EbB z!cHMZb&Pj96{%?m6|M>~QMS;S(UVi^Q2uo{khA8k9u~J|>p}iRHD5=VckeC-FC3!4 z6S?*%=zDj=F*X6z!wUnJQ=-kzSjhrp|_CQ zk=z09gx|3qGE6AxGtVhAD>AF_R@*6)Q=2!+E0b61hILzA7XGpSZ9^3snSR4EyhhBp zM7hLpwOqZ2$J#T^A;L%S^xQ?a>Q#-xg1={aEV(< zL6MI$L-YG)*_r7X`ogK-fF(A1N_=;Bj}EU zWW1EFsOxCm%v1Bo?n#yp_>a6J0zYPJe606UMjqjSDgiTvDb~_M;s@8Rn zD346nht>m`c$g4^<(A{Hx%yI=xKN|uBrLxX>1O{T{aG`*dZBvOVmKRN?P`q(9FBBY zb(EMcA6(BC8qILdL3DmQomh)Hg`91><;67m)**8!;g78xqdiC z+@zJ0@F(F$t2=isyHS;4(=uQv@0wIcV0_m2npmg=lm8&-&3S_msxr=8}}$YP@I;6l1z}wm12xs zo795im~%={Mxu?UO#~zK%mO=LpzP$kaX6C0%0-=IJhVx1M4Cf4LI2?nJ2OiD!Z5-* z0$S`$DaYgbZBUGGSBOh3`L`iwEJL&Sub?KcQ2$SuB=9WHtGnK+!Rogq=rqyU@eE1K{&BdtYXheA5mvUle(zSO*&a4^*+ z)y0eqzTyu`LTl71?+bq6MX0I!ls{e{{FX1+Q+rrz1F>wgIpu#K8DM;Jo?DsACQH<= z)gEw!^>g-1xGQ9sSZSYfP+F|TW*6`(rp>cqa_vXzIdnN?=S=hJ^db`U;*@KVzd8Bp zZXj&K5@vY%RC^^YTrFFzxOk$<+n8A|(2UjUVpbA)$IasC_4iHBa)sPa+4c53;u3)l zM}kLBjvT#)sNZ#aQhVv+au@M(L)K!1ovuu4_cX044N^o5Wb-GmvpS+T*gCewMjR<8dnRJ;k8S}8+RwSN$ zh_P3I{Ud8*!%Iel>1K6n4etk(!L9|$naV5SwH|&Zx|wQAa6-tEU>`W~XNwWY7$86; zz-)?IL@&DAmt6PF=&9!n-VdA+oI^g>!De*u*HjkgHs5>Ll%T!u^1uV2=Yof#8_Qe)Zq^HrU*1ma!iO0UZK26G>`Y5BUx9eZb2O_$Qt z5gbnP*oUwH?4iNWr+=2m!b&ciL^5T4u!rc0Tna}j9hf1eofN}pu;;Q+@hun@kzQ4DnaLqcCTpxYr zG}~TnIs6*JSzcJqw|ctubQt^MkLITdqy+7~=W`;#wx@-^Xl4~oygPi@18$wx{WhE{ z=}huVf4ccjq`*Pw+In-^i(g1lkh-o#Iv*X5z^{Uv zPZD;v{JH(4_Wci7E~OtVbf8}BChZ3A3-8V231u9|3fmXh3*TMiu?ok63M3@($@!0y z=igiR-3T`hZ`{CGk(pl!gnWv1cm~+_2Lqa(0XFuL>TDG<*8>#AGL3_Dr;lN;)YF)K z04~ed0lFd=o$X|3)QkO7lHWg!fzjna+C4G@=FB2FU$fK#0sA+k!@wM_o^pIyc(CzJ zM;yn>RXd5esrkO=xrj;IPKU;R7te-0`H{g)6eB>MmS53M9_JNj#6?wU_L0RRey ze*yxsb8i6vB)eLwN+!O*of+%OoA$TB`#lb2uPW&p_B;gMh7~s_QD`BG!=Qtqe6f`+ zG>0GbrRR4IH_Go)ROf_oF&QTN)pCZ}>iaN8YH#Wde7Ki!_Nku!+~9iXIxi3@E5Vu= zFgKm&Id}F6hr?}mJs6fa!kwcU8<%**^9b-xw$SN$;X3%jDd{nTs64wh{1 z6(#86C!mwnc1sIiR@)W5C23W?ilOp75%f z)V4F}*;B#Z^i1{WF4>zNI)ZD4QC$Kl$TN|NUN~7CXu!?!d~dr8&0lFwRtK;KL4tj- zdv;o&PBmnRTMhYRT`B3a-z`1*!#dw7^=N93K2FqHOGD8s1|iyfsICG|^dfbgQ_<;f zweFk)vO08Nr)h{RwY!(8tB~k@s63E@e`S*S_imFG8WLSF=1>opm*YXd0?T|o*oyP_ znSt7J(sJ~D2|fMk7Y@qZ1VrWh2Uqkef+7^D>kuYLmfwdva@jy#ht)m_Q$vBN94ZnhrR`~!MUF(Hir7YG{B13L8NC0?`E*CH{%3Y3Cy>Ps;&UI$Axg2&TYt)H)oRx3=0;;%yI3!j zvHRP#B4dgky7V1}JaR84s)s~&--L79TWX!S&u8a7|Fyy(HF_0rbS9}CLb6em4ZZE8 z_xFx}7*Bi{0(g)CPnDELbz^9In=?KFC_IJC%J|L9mFat&?e-$ZF1&e{{;+lP`U zkf7*LvMT1WNiSxUim2iAK?rXfS1I_GN4Dos9=&~hLKg$ { + const recorderVersions = await fetchPackageVersions('rrweb'); + const playerVersions = await fetchPackageVersions('rrweb-player'); + // Use the latest version. + const defaultRecorderVersion = recorderVersions[0]; + const defaultPlayerVersion = playerVersions[0]; + // assign default value to settings of this extension + const result = + ((await Browser.storage.sync.get(SyncDataKey.settings)) as SyncData) || + undefined; + const defaultSettings: Settings = { + recorderURL: getRecorderURL(defaultRecorderVersion), + recorderVersion: defaultRecorderVersion, + playerURL: getPlayerURL(defaultPlayerVersion), + playerVersion: defaultPlayerVersion, + }; + let settings = defaultSettings; + if (result && result.settings) { + setDefaultSettings(result.settings, defaultSettings); + settings = result.settings; + } + await Browser.storage.sync.set({ + settings, + } as SyncData); + void fetchSourceCode(settings); +})(); + +Browser.storage.onChanged.addListener((changes, area) => { + if (area === 'sync' && changes.settings) { + const newValue = changes.settings.newValue as Settings; + void fetchSourceCode(newValue); + } +}); + +/** + * Update existed settings with new settings. + * Set new setting values if these properties don't exist in older versions. + */ +function setDefaultSettings( + existedSettings: Record, + newSettings: Record, +) { + for (const i in newSettings) { + // settings[i] contains key-value settings + if ( + typeof newSettings[i] === 'object' && + !(newSettings[i] instanceof Array) && + Object.keys(newSettings[i] as Record).length > 0 + ) { + if (existedSettings[i]) { + setDefaultSettings( + existedSettings[i] as Record, + newSettings[i] as Record, + ); + } else { + // settings[i] contains several setting items but these have not been set before + existedSettings[i] = newSettings[i]; + } + } else if (existedSettings[i] === undefined) { + // settings[i] is a single setting item and it has not been set before + existedSettings[i] = newSettings[i]; + } + } +} + +/** + * Fetch rrweb source code from recorder URL and player URL. + */ +async function fetchSourceCode(settings: Settings) { + if (settings.recorderURL) { + const code = await (await fetch(settings.recorderURL)).text(); + await Browser.storage.local.set({ + recorder_code: code, + }); + } + if (settings.playerURL) { + const code = await (await fetch(settings.playerURL)).text(); + await Browser.storage.local.set({ + player_code: code, + }); + } +} diff --git a/packages/web-extension/src/components/CircleButton.tsx b/packages/web-extension/src/components/CircleButton.tsx new file mode 100644 index 0000000000..abbb68e576 --- /dev/null +++ b/packages/web-extension/src/components/CircleButton.tsx @@ -0,0 +1,33 @@ +import { Button, ButtonProps } from '@chakra-ui/react'; + +interface CircleButtonProps extends ButtonProps { + diameter: number; + onClick?: () => void; + children?: React.ReactNode; + title?: string; +} + +export function CircleButton({ + diameter, + onClick, + children, + title, + ...rest +}: CircleButtonProps) { + return ( + + ); +} diff --git a/packages/web-extension/src/components/SidebarWithHeader.tsx b/packages/web-extension/src/components/SidebarWithHeader.tsx new file mode 100644 index 0000000000..ba8470a5b6 --- /dev/null +++ b/packages/web-extension/src/components/SidebarWithHeader.tsx @@ -0,0 +1,290 @@ +import { ReactNode } from 'react'; +import { + IconButton, + Box, + CloseButton, + Flex, + HStack, + Icon, + Image, + useColorModeValue, + Link, + Drawer, + DrawerContent, + useDisclosure, + BoxProps, + FlexProps, + Heading, + Stack, + Text, + Popover, + PopoverTrigger, + PopoverContent, +} from '@chakra-ui/react'; +import { FiChevronRight, FiMenu } from 'react-icons/fi'; +import type { IconType } from 'react-icons'; +import Browser from 'webextension-polyfill'; + +export interface SideBarItem { + label: string; + icon: IconType; + href: string; +} + +export interface HeadBarItem { + label: string; + subLabel?: string; + children?: Array; + href?: string; +} + +export default function SidebarWithHeader({ + children, + title, + headBarItems, + sideBarItems, +}: { + title?: string; + sideBarItems: SideBarItem[]; + headBarItems: SideBarItem[]; + children: ReactNode; +}) { + const { isOpen, onOpen, onClose } = useDisclosure(); + return ( + + onClose} + display={{ base: 'none', md: 'block' }} + title={title} + /> + + + + + + + + + + + {children} + + ); +} + +interface SidebarProps extends BoxProps { + onClose: () => void; + title?: string; + sideBarItems: SideBarItem[]; +} + +const SidebarContent = ({ + onClose, + sideBarItems, + title, + ...rest +}: SidebarProps) => { + return ( + + + + RRWeb Logo + + {title && ( + + {title} + + )} + + + {sideBarItems.map((link) => ( + + {link.label} + + ))} + + ); +}; + +interface NavItemProps extends FlexProps { + icon: IconType; + href: string; + children: string; +} +const NavItem = ({ icon, href, children, ...rest }: NavItemProps) => { + return ( + + + <> + {icon && } + {children} + + + + ); +}; + +interface MobileProps extends FlexProps { + onOpen: () => void; +} +const MobileNav = ({ onOpen, ...rest }: MobileProps) => { + return ( + + } + /> + + + {rest.children && rest.children} + + + ); +}; + +const DesktopNav = ({ headBarItems }: { headBarItems: HeadBarItem[] }) => { + const linkColor = useColorModeValue('gray.600', 'gray.200'); + const linkHoverColor = useColorModeValue('gray.800', 'white'); + const popoverContentBgColor = useColorModeValue('white', 'gray.800'); + + return ( + + {headBarItems.map((navItem) => ( + + + + + {navItem.label} + + + + {navItem.children && ( + + + {navItem.children.map((child) => ( + + ))} + + + )} + + + ))} + + ); +}; + +const DesktopSubNav = ({ label, href, subLabel }: HeadBarItem) => { + return ( + + + + + {label} + + {subLabel} + + + + + + + ); +}; diff --git a/packages/web-extension/src/content/index.ts b/packages/web-extension/src/content/index.ts new file mode 100644 index 0000000000..b0aa66acff --- /dev/null +++ b/packages/web-extension/src/content/index.ts @@ -0,0 +1,167 @@ +import Browser from 'webextension-polyfill'; +import { nanoid } from 'nanoid'; +import type { eventWithTime } from 'rrweb/typings/types'; +import { + LocalData, + LocalDataKey, + RecorderStatus, + ServiceName, + Session, + StartRecordResponse, + StopRecordResponse, + SyncData, + SyncDataKey, +} from '../types'; +import Channel from '../utils/channel'; + +const channel = new Channel(); + +void (async () => { + let storedEvents: eventWithTime[] = []; + let startResponseCb: ((response: StartRecordResponse) => void) | undefined = + undefined; + // The callback function to remove the recorder from the page. + let clearRecorderCb: (() => void) | undefined = undefined; + channel.provide(ServiceName.StartRecord, async () => { + clearRecorderCb = await startRecord(); + window.postMessage({ message: 'start-record' }); + return new Promise((resolve) => { + startResponseCb = (response) => { + resolve(response); + }; + }); + }); + let stopResponseCb: ((response: StopRecordResponse) => void) | undefined = + undefined; + channel.provide(ServiceName.StopRecord, () => { + window.postMessage({ message: 'stop-record' }); + return new Promise((resolve) => { + stopResponseCb = (response: StopRecordResponse) => { + resolve(response); + }; + }); + }); + + window.addEventListener('message', (event) => { + const data = event.data as + | StartRecordResponse + | StopRecordResponse + | HeartBreathMessage; + if (data.message === 'start-record-response' && startResponseCb) + startResponseCb(data); + else if (data.message === 'stop-record-response' && stopResponseCb) { + stopResponseCb(data); + void saveEvents(storedEvents.concat(data.events)); + clearRecorderCb?.(); + clearRecorderCb = undefined; + storedEvents = []; + } else if (data.message === 'heart-beat') { + const events = data.events; + void Browser.storage.local.set({ + [LocalDataKey.bufferedEvents]: storedEvents.concat(events), + }); + } + }); + + const localData = (await Browser.storage.local.get()) as LocalData; + if (localData?.recorder_status?.status === RecorderStatus.RECORDING) { + clearRecorderCb = await startRecord(); + storedEvents = localData.buffered_events || []; + } +})(); + +async function startRecord() { + const data = await Browser.storage.local.get('recorder_code'); + const recorderCode = data['recorder_code'] as string | undefined; + if (!recorderCode || recorderCode.length === 0) return; + + const scriptEl = document.createElement('script'); + try { + const uniqueVariablePrefix = '__rrweb_extension_unique_prefix_'; + const events = `${uniqueVariablePrefix}events`; + const stopFn = `${uniqueVariablePrefix}stopFn`; + const setIntervalId = `${uniqueVariablePrefix}setIntervalId`; + const record = `${uniqueVariablePrefix}record`; + scriptEl.textContent = ` + ${recorderCode} + var ${events} = []; + var ${stopFn} = null; + var ${setIntervalId} = null; + + function ${record}() { + ${events} = []; + let recorder; + try { + recorder = rrwebRecord; + } catch (e) { + recorder = rrweb.record; + } + ${stopFn} = recorder({ + emit: (event) => { + ${events}.push(event); + }, + }); + } + + window.addEventListener('message', (event) => { + const data = event.data; + if (data.message === 'stop-record') { + if (${stopFn}) ${stopFn}(); + clearInterval(${setIntervalId}); + window.postMessage({ + message: 'stop-record-response', + events: ${events}, + endTimestamp: Date.now(), + }); + } + }); + + window.postMessage({ + message: 'start-record-response', + startTimestamp: Date.now(), + }); + ${record}(); + + ${setIntervalId} = setInterval(() => { + window.postMessage({ + message: 'heart-beat', + events: ${events}, + }); + }, 50); + `; + document.documentElement.appendChild(scriptEl); + return () => { + document.documentElement.removeChild(scriptEl); + }; + } catch (e) { + document.documentElement.removeChild(scriptEl); + } +} + +async function saveEvents(events: eventWithTime[]) { + const recorderSettings = (await Browser.storage.sync.get( + SyncDataKey.settings, + )) as SyncData; + const { recorderVersion, recorderURL } = recorderSettings.settings; + const newSession: Session = { + id: nanoid(), + name: document.title, + tags: [], + events, + createTimestamp: Date.now(), + modifyTimestamp: Date.now(), + recorderVersion, + recorderURL, + }; + const data = (await Browser.storage.local.get( + LocalDataKey.sessions, + )) as LocalData; + if (!data.sessions) data.sessions = {}; + data.sessions[newSession.id] = newSession; + await Browser.storage.local.set(data); +} + +type HeartBreathMessage = { + message: 'heart-beat'; + events: eventWithTime[]; +}; diff --git a/packages/web-extension/src/manifest.json b/packages/web-extension/src/manifest.json new file mode 100644 index 0000000000..fa3920cb83 --- /dev/null +++ b/packages/web-extension/src/manifest.json @@ -0,0 +1,28 @@ +{ + "manifest_version": 2, + "name": "rrweb", + "background": { + "persistent": false, + "scripts": ["background/index.ts"] + }, + "browser_action": { + "default_title": "rrweb extension", + "default_popup": "popup/popup.html", + "browser_style": false + }, + "content_scripts": [ + { + "matches": [""], + "js": ["content/index.ts"], + "run_at": "document_idle" + } + ], + "options_page": "options/index.html", + "icons": { + "16": "assets/icon16.png", + "48": "assets/icon48.png", + "128": "assets/icon128.png" + }, + "permissions": ["activeTab", "tabs", "storage", "unlimitedStorage"], + "content_security_policy": "script-src-elem 'self' http://localhost:3000 'self'; script-src 'self' http://localhost:3000 'unsafe-eval' object-src 'self'" +} diff --git a/packages/web-extension/src/options/App.tsx b/packages/web-extension/src/options/App.tsx new file mode 100644 index 0000000000..78bdc1a58e --- /dev/null +++ b/packages/web-extension/src/options/App.tsx @@ -0,0 +1,38 @@ +import { Route, Routes } from 'react-router-dom'; +import SidebarWithHeader from '../components/SidebarWithHeader'; +import { FiTarget, FiList, FiSettings } from 'react-icons/fi'; +import RRWebVersion from './RRWebVersion'; +import { Box } from '@chakra-ui/react'; + +export default function App() { + return ( + + + + } /> + + + + ); +} diff --git a/packages/web-extension/src/options/RRWebVersion.tsx b/packages/web-extension/src/options/RRWebVersion.tsx new file mode 100644 index 0000000000..9161742c4c --- /dev/null +++ b/packages/web-extension/src/options/RRWebVersion.tsx @@ -0,0 +1,312 @@ +import { useEffect, useState } from 'react'; +import Browser from 'webextension-polyfill'; +import { + Button, + Flex, + FormControl, + FormHelperText, + FormLabel, + Input, + InputGroup, + InputRightElement, + Select, + useToast, +} from '@chakra-ui/react'; +import { + fetchPackageVersions, + getRecorderURL, + verifyPlayerURL, + verifyRecorderURL, +} from '../utils'; +import { SyncData, SyncDataKey } from '../types'; +import { getPlayerURL } from '../utils/index'; + +export default function RRWebVersion() { + const toast = useToast(); + const [recorderVersion, setRecorderVersion] = useState(''); + const [recorderVersions, setRecorderVersions] = useState([]); + const [recorderURL, setRecorderURL] = useState(''); + const [recorderValidURL, setRecorderValidURL] = useState(''); + const [playerVersion, setPlayerVersion] = useState(''); + const [playerVersions, setPlayerVersions] = useState([]); + const [playerURL, setPlayerURL] = useState(''); + const [playerValidURL, setPlayerValidURL] = useState(''); + + useEffect(() => { + void fetchPackageVersions('rrweb').then((versions) => { + setRecorderVersions(versions); + }); + void fetchPackageVersions('rrweb-player').then((versions) => { + setPlayerVersions(versions); + }); + void Browser.storage.sync.get(SyncDataKey.settings).then((data) => { + const syncData = data as SyncData; + if (!syncData.settings) return; + const { recorderVersion, recorderURL, playerURL, playerVersion } = + syncData.settings; + setRecorderVersion(recorderVersion); + setRecorderURL(recorderURL); + setRecorderValidURL(recorderURL); + setPlayerVersion(playerVersion); + setPlayerURL(playerURL); + setPlayerValidURL(playerURL); + }); + }, []); + + return ( + + + + RRWeb Recorder Version + + + {recorderVersion !== '' && recorderVersion !== 'custom' && ( + <> + The extension will load Recorder script with v{recorderVersion} + from jsDelivr. + + )} + + + + Recorder URL + + setRecorderURL(event.target.value)} + /> + + + + + + + {(recorderVersion === '' || recorderVersion === 'custom') && ( + <> + The extension will load Recorder script from {recorderValidURL} + + )} + + + + + + RRWeb Player Version + + + {playerVersion !== '' && playerVersion !== 'custom' && ( + <> + The extension will load Player script with v{playerVersion} from + jsDelivr. + + )} + + + + Player URL + + setPlayerURL(event.target.value)} + /> + + + + + + + {(playerVersion === '' || playerVersion === 'custom') && ( + <>The extension will load Player script from {playerValidURL} + )} + + + + + ); +} diff --git a/packages/web-extension/src/options/index.html b/packages/web-extension/src/options/index.html new file mode 100644 index 0000000000..18065c296c --- /dev/null +++ b/packages/web-extension/src/options/index.html @@ -0,0 +1,8 @@ + + + + +
+ + + diff --git a/packages/web-extension/src/options/index.tsx b/packages/web-extension/src/options/index.tsx new file mode 100644 index 0000000000..0114523911 --- /dev/null +++ b/packages/web-extension/src/options/index.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import { ChakraProvider } from '@chakra-ui/react'; +import * as ReactDOM from 'react-dom/client'; +import { createHashRouter, RouterProvider } from 'react-router-dom'; +import App from './App'; + +const rootElement = document.getElementById('root'); +const router = createHashRouter([ + { + path: '/*', + element: , + }, +]); + +rootElement && + ReactDOM.createRoot(rootElement).render( + + + + + , + ); diff --git a/packages/web-extension/src/pages/App.tsx b/packages/web-extension/src/pages/App.tsx new file mode 100644 index 0000000000..66d1ba2b52 --- /dev/null +++ b/packages/web-extension/src/pages/App.tsx @@ -0,0 +1,37 @@ +import { Route, Routes } from 'react-router-dom'; +import SidebarWithHeader from '../components/SidebarWithHeader'; +import { SessionList } from './SessionList'; +import { FiList, FiSettings } from 'react-icons/fi'; +import Player from './Player'; + +export default function App() { + return ( + + + } /> + } /> + + + ); +} diff --git a/packages/web-extension/src/pages/Player.tsx b/packages/web-extension/src/pages/Player.tsx new file mode 100644 index 0000000000..f73fcd2262 --- /dev/null +++ b/packages/web-extension/src/pages/Player.tsx @@ -0,0 +1,69 @@ +import { useRef, useEffect, useState } from 'react'; +import { useParams } from 'react-router-dom'; +import Browser from 'webextension-polyfill'; +import type rrwebPlayer from 'rrweb-player'; +import { RRwebPlayerOptions } from 'rrweb-player'; +import { LocalData } from '../types'; +import { + Box, + Breadcrumb, + BreadcrumbItem, + BreadcrumbLink, + Center, +} from '@chakra-ui/react'; + +export default function Player() { + const playerElRef = useRef(null); + const playerRef = useRef(null); + const { sessionId } = useParams(); + const [sessionName, setSessionName] = useState(''); + + useEffect(() => { + void Browser.storage.local.get().then((data) => { + if (!playerElRef.current || !sessionId) return; + const localData = data as LocalData; + const session = localData.sessions[sessionId]; + if (!session) return; + setSessionName(session.name); + + eval(localData.player_code + 'window.rrwebPlayer = rrwebPlayer;'); + + const Player = ( + window as Window & + typeof globalThis & { + rrwebPlayer: new (options: RRwebPlayerOptions) => rrwebPlayer; + } + ).rrwebPlayer; + if (!Player) return; + + const linkEl = document.createElement('link'); + linkEl.href = + 'https://cdn.jsdelivr.net/npm/rrweb-player@1.0.0-alpha.1/dist/style.css'; + linkEl.rel = 'stylesheet'; + document.head.appendChild(linkEl); + playerRef.current = new Player({ + target: playerElRef.current as HTMLElement, + props: { + events: session.events, + autoPlay: true, + }, + }); + }); + }, []); + + return ( + <> + + + Sessions + + + {sessionName} + + +
+ +
+ + ); +} diff --git a/packages/web-extension/src/pages/SessionList.tsx b/packages/web-extension/src/pages/SessionList.tsx new file mode 100644 index 0000000000..36076c2fc1 --- /dev/null +++ b/packages/web-extension/src/pages/SessionList.tsx @@ -0,0 +1,64 @@ +import { useEffect, useState } from 'react'; +import { + Table, + Thead, + Tbody, + Tr, + Th, + Td, + TableContainer, +} from '@chakra-ui/react'; +import { LocalData, LocalDataKey, Session } from '../types'; +import Browser from 'webextension-polyfill'; +import { useNavigate } from 'react-router-dom'; + +export function SessionList() { + const [sessions, setSessions] = useState([]); + const navigate = useNavigate(); + + useEffect(() => { + const getSessions = (sessions?: LocalData['sessions']) => { + if (!sessions) return; + const sessionArray = []; + for (const id in sessions) sessionArray.push(sessions[id]); + setSessions(sessionArray); + }; + void Browser.storage.local + .get(LocalDataKey.sessions) + .then((data) => getSessions((data as LocalData).sessions)); + Browser.storage.onChanged.addListener((changes, area) => { + if (area === 'local' && changes.sessions) + getSessions(changes.sessions.newValue as LocalData['sessions']); + }); + }, []); + + return ( + + + + + + + + + + + {sessions.map((session) => { + return ( + { + navigate(`/session/${session.id}`); + }} + _hover={{ cursor: 'pointer' }} + > + + + + + ); + })} + +
NameCreated TimeRRWEB Version
{session.name}{new Date(session.createTimestamp).toLocaleString()}{session.recorderVersion}
+
+ ); +} diff --git a/packages/web-extension/src/pages/index.html b/packages/web-extension/src/pages/index.html new file mode 100644 index 0000000000..18065c296c --- /dev/null +++ b/packages/web-extension/src/pages/index.html @@ -0,0 +1,8 @@ + + + + +
+ + + diff --git a/packages/web-extension/src/pages/index.tsx b/packages/web-extension/src/pages/index.tsx new file mode 100644 index 0000000000..0114523911 --- /dev/null +++ b/packages/web-extension/src/pages/index.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import { ChakraProvider } from '@chakra-ui/react'; +import * as ReactDOM from 'react-dom/client'; +import { createHashRouter, RouterProvider } from 'react-router-dom'; +import App from './App'; + +const rootElement = document.getElementById('root'); +const router = createHashRouter([ + { + path: '/*', + element: , + }, +]); + +rootElement && + ReactDOM.createRoot(rootElement).render( + + + + + , + ); diff --git a/packages/web-extension/src/popup/App.tsx b/packages/web-extension/src/popup/App.tsx new file mode 100644 index 0000000000..221375ebef --- /dev/null +++ b/packages/web-extension/src/popup/App.tsx @@ -0,0 +1,155 @@ +import { useState, useEffect } from 'react'; +import { Box, Flex, IconButton, Spacer, Stack, Text } from '@chakra-ui/react'; +import { FiSettings, FiList } from 'react-icons/fi'; +import Channel from '../utils/channel'; +import { + LocalData, + LocalDataKey, + RecorderStatus, + ServiceName, + StartRecordResponse, +} from '../types'; +import Browser from 'webextension-polyfill'; +import { CircleButton } from '../components/CircleButton'; +import { Timer } from './Timer'; +const RECORD_BUTTON_SIZE = 3; + +const channel = new Channel(); + +export function App() { + const [recording, setRecording] = useState(false); + const [errorMessage, setErrorMessage] = useState(''); + const [startTime, setStartTime] = useState(0); + + useEffect(() => { + void Browser.storage.local.get(LocalDataKey.recorderStatus).then((data) => { + const localData = data as LocalData; + if (!localData || !localData.recorder_status) return; + const { status, startTimestamp } = localData.recorder_status; + if (status === RecorderStatus.RECORDING) { + setRecording(true); + setStartTime(startTimestamp || 0); + } + }); + }, []); + + return ( + + + + RRWeb Recorder + + + + { + void Browser.tabs.create({ url: '/pages/index.html#/' }); + }} + size="xs" + icon={} + aria-label={'Session List'} + title="Session List" + > + { + void Browser.tabs.create({ url: '/options/index.html' }); + }} + size="xs" + icon={} + aria-label={'Settings button'} + title="Settings" + > + + + {recording && startTime && ( + + )} + + { + if (recording) { + // stop recording + setErrorMessage(''); + void channel.getCurrentTabId().then((tabId) => { + if (tabId === -1) return; + void channel + .requestToTab(tabId, ServiceName.StopRecord, {}) + .then(async (res) => { + if (res) { + setRecording(false); + await Browser.storage.local.set({ + [LocalDataKey.recorderStatus]: { + status: RecorderStatus.IDLE, + }, + }); + } + }) + .catch((error: Error) => { + setErrorMessage(error.message); + }); + }); + } else { + // start recording + void channel.getCurrentTabId().then((tabId) => { + if (tabId === -1) return; + void channel + .requestToTab(tabId, ServiceName.StartRecord, {}) + .then(async (res: StartRecordResponse | undefined) => { + if (res) { + setRecording(true); + setStartTime(res.startTimestamp); + await Browser.storage.local.set({ + [LocalDataKey.recorderStatus]: { + status: RecorderStatus.RECORDING, + startTimestamp: res.startTimestamp, + }, + }); + } + }) + .catch((error: Error) => { + setErrorMessage(error.message); + }); + }); + } + }} + > + + + {/* // TODO add pause function */} + {/* {recording && ( + + + + + + )} */} + + {errorMessage !== '' && ( + + {errorMessage} +
+ Maybe refresh your current tab. +
+ )} +
+ ); +} diff --git a/packages/web-extension/src/popup/Timer.tsx b/packages/web-extension/src/popup/Timer.tsx new file mode 100644 index 0000000000..066e2c6421 --- /dev/null +++ b/packages/web-extension/src/popup/Timer.tsx @@ -0,0 +1,25 @@ +import { useEffect, useState } from 'react'; +import { Stat, StatNumber } from '@chakra-ui/react'; +import { formatTime } from '../utils'; + +export function Timer({ + startTime, + ticking, +}: { + startTime: number; + ticking: boolean; +}) { + const [time, setTime] = useState(0); + useEffect(() => { + if (!ticking) return; + const interval = setInterval(() => { + setTime(Date.now() - startTime); + }, 100); + return () => clearInterval(interval); + }, [startTime, ticking]); + return ( + + {formatTime(time)} + + ); +} diff --git a/packages/web-extension/src/popup/index.tsx b/packages/web-extension/src/popup/index.tsx new file mode 100644 index 0000000000..d93c01a2b0 --- /dev/null +++ b/packages/web-extension/src/popup/index.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import { ChakraProvider } from '@chakra-ui/react'; +import * as ReactDOM from 'react-dom/client'; +import { App } from './App'; + +const rootElement = document.getElementById('root'); + +rootElement && + ReactDOM.createRoot(rootElement).render( + + + + + , + ); diff --git a/packages/web-extension/src/popup/popup.html b/packages/web-extension/src/popup/popup.html new file mode 100644 index 0000000000..18065c296c --- /dev/null +++ b/packages/web-extension/src/popup/popup.html @@ -0,0 +1,8 @@ + + + + +
+ + + diff --git a/packages/web-extension/src/types.ts b/packages/web-extension/src/types.ts new file mode 100644 index 0000000000..adf86bac77 --- /dev/null +++ b/packages/web-extension/src/types.ts @@ -0,0 +1,71 @@ +import type { eventWithTime } from 'rrweb/typings/types'; + +export enum SyncDataKey { + settings = 'settings', +} + +export type SyncData = { + [SyncDataKey.settings]: Settings; +}; + +export type Settings = { + recorderURL: string; + recorderVersion: string; + playerURL: string; + playerVersion: string; +}; + +export enum LocalDataKey { + recorderCode = 'recorder_code', + playerCode = 'player_code', + sessions = 'sessions', + recorderStatus = 'recorder_status', + bufferedEvents = 'buffered_events', +} + +export type LocalData = { + [LocalDataKey.recorderCode]: string; + [LocalDataKey.playerCode]: string; + [LocalDataKey.sessions]: Record; + [LocalDataKey.recorderStatus]: { + status: RecorderStatus; + startTimestamp?: number; + duration?: number; + }; + [LocalDataKey.bufferedEvents]: eventWithTime[]; +}; + +export enum RecorderStatus { + IDLE = 'IDLE', + RECORDING = 'RECORDING', + PAUSED = 'PAUSED', +} + +export type Session = { + id: string; + name: string; + tags: string[]; + events: eventWithTime[]; + createTimestamp: number; + modifyTimestamp: number; + recorderVersion: string; + recorderURL: string; +}; + +export enum ServiceName { + StartRecord = 'start-record', + StopRecord = 'stop-record', + PauseRecord = 'pause-record', + ResumeRecord = 'resume-record', +} + +export type StartRecordResponse = { + message: 'start-record-response'; + startTimestamp: number; +}; + +export type StopRecordResponse = { + message: 'stop-record-response'; + events: eventWithTime[]; + endTimestamp: number; +}; diff --git a/packages/web-extension/src/utils/channel.ts b/packages/web-extension/src/utils/channel.ts new file mode 100644 index 0000000000..88a01ab5bf --- /dev/null +++ b/packages/web-extension/src/utils/channel.ts @@ -0,0 +1,184 @@ +import mitt from 'mitt'; +import Browser, { Runtime } from 'webextension-polyfill'; + +export type Message = EventType | ServiceType; +export type EventType = { + type: 'event'; + event: string; + detail: unknown; +}; +export type ServiceType = { + type: 'service'; + service: string; + params: unknown; +}; + +/** + * Channel for inter-context communication. + * + * A chrome extension typically contains 4 types of context: background, popup, options and content scripts. + * Communication between these contexts relies on + * chrome.runtime.sendMessage and chrome.tabs.sendMessage. + * + * This Class provides two communication model: + * * request/response + * * event trigger/listen + * based on chrome.runtime.sendMessage and chrome.tabs.sendMessage. + */ +class Channel { + private services = new Map< + string, + (params: unknown, sender: Runtime.MessageSender) => Promise + >(); + private emitter = mitt(); + constructor() { + /** + * Register massage listener. + */ + Browser.runtime.onMessage.addListener( + ((message: string, sender: Runtime.MessageSender) => { + const parsed = JSON.parse(message) as Message | null | undefined; + if (!parsed || !parsed.type) { + console.error(`Bad message: ${message}`); + return; + } + switch (parsed.type) { + case 'event': + this.emitter.emit(parsed.event, { detail: parsed.detail, sender }); + break; + case 'service': { + const server = this.services.get(parsed.service); + if (!server) break; + return server(parsed.params, sender); + } + default: + console.error( + `Unknown message type: ${(parsed as { type: string }).type}`, + ); + break; + } + return; + }).bind(this), + ); + } + + /** + * Provide a service. + * + * @param serviceName - the name of the service, acts like a URL + * @param serveFunction - a function to provide the service when a consumer request this service. + * @returns a function to remove the service + */ + public provide( + serviceName: string, + serveFunction: ( + params: unknown, + sender: Runtime.MessageSender, + ) => Promise, + ): () => void { + this.services.set(serviceName, serveFunction); + return () => { + this.services.delete(serviceName); + }; + } + + /** + * Send a request and get a response. + * + * @param service - service name to request + * @param params - request parameters + * @returns service data + */ + public request( + serviceName: string, + params: Record | unknown, + ) { + const message = JSON.stringify({ + type: 'service', + service: serviceName, + params, + }); + return Browser.runtime.sendMessage(message); + } + + /** + * Send a request to the specified tab and get a response. + * + * @param tabId - tab id + * @param service - service name to request + * @param params - request parameters + * @returns service data + */ + public requestToTab( + tabId: number, + serviceName: string, + params: Record | unknown, + ) { + if (!Browser.tabs || !Browser.tabs.sendMessage) + return Promise.reject('Can not send message to tabs in current context!'); + const message = JSON.stringify({ + type: 'service', + service: serviceName, + params, + }); + return Browser.tabs.sendMessage(tabId, message); + } + + /** + * Add an event handler. + * + * @param eventName - event name + * @param handler - event handler, accepts two arguments: + * detail: event detail + * source: source of the event, chrome.runtime.MessageSender object + * @returns a function to remove the handler + */ + public on(event: string, handler: (detail: unknown) => unknown) { + return this.emitter.on(event, handler); + } + + /** + * Emit an event. + * + * @param event - event name + * @param detail - event detail + */ + public emit(eventName: string, detail: unknown) { + const message = JSON.stringify({ type: 'event', eventName, detail }); + void Browser.runtime.sendMessage(message); + } + + /** + * Emit an event to specified tabs. + * + * @param tabIds - tab ids + * @param event - event name + * @param detail - event detail + */ + public emitToTabs( + tabIds: number | number[], + eventName: string, + detail: unknown, + ) { + if (!Browser.tabs || !Browser.tabs.sendMessage) + return Promise.reject('Can not send message to tabs in current context!'); + + // If tabIds is a number, wrap it up with an array. + if (typeof tabIds === 'number') { + tabIds = [tabIds]; + } + + const message = JSON.stringify({ type: 'event', eventName, detail }); + tabIds.forEach((tabId) => void Browser.tabs.sendMessage(tabId, message)); + } + + public async getCurrentTabId() { + const tabs = await Browser.tabs.query({ + active: true, + currentWindow: true, + }); + return tabs[0].id || -1; + } +} + +export default Channel; diff --git a/packages/web-extension/src/utils/index.ts b/packages/web-extension/src/utils/index.ts new file mode 100644 index 0000000000..6f320a65a9 --- /dev/null +++ b/packages/web-extension/src/utils/index.ts @@ -0,0 +1,75 @@ +import { PackageJson } from 'type-fest'; + +const SECOND = 1000; +const MINUTE = 60 * SECOND; +const HOUR = 60 * MINUTE; + +export async function fetchPackageVersions(packageName: string) { + type Meta = { + name: string; + author: string; + versions: Record; + }; + const meta = (await ( + await fetch(`https://registry.npmjs.org/${packageName}`) + ).json()) as Meta; + const versions = []; + for (const version in meta.versions) versions.push(version); + return versions.reverse(); +} + +export function getRecorderURL(version: string) { + return `https://cdn.jsdelivr.net/npm/rrweb@${version}/dist/record/rrweb-record.min.js`; +} + +export function getPlayerURL(version: string) { + return `https://cdn.jsdelivr.net/npm/rrweb-player@${version}/dist/index.js`; +} + +export async function verifyRecorderURL(url: string) { + try { + const res = await fetch(url); + if (!res.ok) return false; + const text = await res.text(); + return text.includes('rrwebRecord') || text.includes('record'); + } catch (e) { + return false; + } +} + +export async function verifyPlayerURL(url: string) { + try { + const res = await fetch(url); + if (!res.ok) return false; + const text = await res.text(); + return text.includes('rrwebPlayer'); + } catch (e) { + return false; + } +} + +export function formatTime(ms: number): string { + if (ms <= 0) { + return '00:00'; + } + const hour = Math.floor(ms / HOUR); + ms = ms % HOUR; + const minute = Math.floor(ms / MINUTE); + ms = ms % MINUTE; + const second = Math.floor(ms / SECOND); + if (hour) { + return `${padZero(hour)}:${padZero(minute)}:${padZero(second)}`; + } + return `${padZero(minute)}:${padZero(second)}`; +} + +function padZero(num: number, len = 2): string { + let str = String(num); + const threshold = Math.pow(10, len - 1); + if (num < threshold) { + while (String(threshold).length > str.length) { + str = `0${num}`; + } + } + return str; +} diff --git a/packages/web-extension/tsconfig.json b/packages/web-extension/tsconfig.json new file mode 100644 index 0000000000..cbca7830d1 --- /dev/null +++ b/packages/web-extension/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "module": "ESNext", + "target": "es2016", + "lib": ["DOM", "ESNext"], + "strict": true, + "esModuleInterop": true, + "incremental": false, + "skipLibCheck": true, + "moduleResolution": "node", + "resolveJsonModule": true, + "noUnusedLocals": true, + "strictNullChecks": true, + "forceConsistentCasingInFileNames": true, + "paths": { + "~/*": ["src/*"] + }, + "jsx": "react-jsx" + }, + "exclude": ["dist", "node_modules"], + "references": [] +} diff --git a/packages/web-extension/vite.config.ts b/packages/web-extension/vite.config.ts new file mode 100644 index 0000000000..32e44d1184 --- /dev/null +++ b/packages/web-extension/vite.config.ts @@ -0,0 +1,47 @@ +import { defineConfig } from 'vite'; +import webExtension, { readJsonFile } from 'vite-plugin-web-extension'; +import zip from 'vite-plugin-zip'; +import * as path from 'path'; +import type { PackageJson } from 'type-fest'; +import react from '@vitejs/plugin-react'; + +export default defineConfig({ + root: 'src', + // Configure our outputs - nothing special, this is normal vite config + build: { + outDir: path.resolve( + __dirname, + 'dist', + process.env.TARGET_BROWSER as string, + ), + emptyOutDir: true, + }, + // Add the webExtension plugin + plugins: [ + react(), + webExtension({ + // A function to generate manifest file dynamically. + manifest: () => { + const packageJson = readJsonFile('package.json') as PackageJson; + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return { + ...readJsonFile('./src/manifest.json'), + version: packageJson.version, + author: packageJson.author, + }; + }, + assets: 'assets', + browser: process.env.TARGET_BROWSER, + webExtConfig: { + startUrl: ['github.com/rrweb-io/rrweb'], + watchIgnored: ['*.md', '*.log'], + }, + additionalInputs: ['pages/index.html'], + }), + process.env.ZIP === 'true' && + zip({ + dir: 'dist', + outputName: process.env.TARGET_BROWSER, + }), + ], +}); diff --git a/yarn.lock b/yarn.lock index b2f2d2feaa..92c6afd8f3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,14 @@ # yarn lockfile v1 +"@ampproject/remapping@^2.1.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" + integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== + dependencies: + "@jridgewell/gen-mapping" "^0.1.0" + "@jridgewell/trace-mapping" "^0.3.9" + "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.0.0-beta.35", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.14.5": version "7.14.5" resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz" @@ -16,6 +24,13 @@ dependencies: "@babel/highlight" "^7.16.7" +"@babel/code-frame@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" + integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== + dependencies: + "@babel/highlight" "^7.18.6" + "@babel/compat-data@^7.15.0": version "7.15.0" resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz" @@ -26,6 +41,11 @@ resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.4.tgz" integrity sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q== +"@babel/compat-data@^7.19.3": + version "7.19.4" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.19.4.tgz#95c86de137bf0317f3a570e1b6e996b427299747" + integrity sha512-CHIGpJcUQ5lU9KrPHTjBMhVwQG6CQjxfg36fGXl3qk/Gik1WwWachaXFuo0uCWJT/mStOKtcbFJCaVLihC1CMw== + "@babel/core@^7.1.0", "@babel/core@^7.7.2", "@babel/core@^7.7.5", "@babel/core@^7.8.0": version "7.15.5" resolved "https://registry.npmjs.org/@babel/core/-/core-7.15.5.tgz" @@ -47,6 +67,27 @@ semver "^6.3.0" source-map "^0.5.0" +"@babel/core@^7.11.6", "@babel/core@^7.18.13": + version "7.19.3" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.19.3.tgz#2519f62a51458f43b682d61583c3810e7dcee64c" + integrity sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ== + dependencies: + "@ampproject/remapping" "^2.1.0" + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.19.3" + "@babel/helper-compilation-targets" "^7.19.3" + "@babel/helper-module-transforms" "^7.19.0" + "@babel/helpers" "^7.19.0" + "@babel/parser" "^7.19.3" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.19.3" + "@babel/types" "^7.19.3" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.1" + semver "^6.3.0" + "@babel/core@^7.12.3": version "7.16.7" resolved "https://registry.npmjs.org/@babel/core/-/core-7.16.7.tgz" @@ -86,6 +127,22 @@ jsesc "^2.5.1" source-map "^0.5.0" +"@babel/generator@^7.19.3", "@babel/generator@^7.19.4": + version "7.19.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.19.5.tgz#da3f4b301c8086717eee9cab14da91b1fa5dcca7" + integrity sha512-DxbNz9Lz4aMZ99qPpO1raTbcrI1ZeYh+9NR9qhfkQIbFtVEqotHojEBxHzmxhVONkGt6VyrqVQcgpefMy9pqcg== + dependencies: + "@babel/types" "^7.19.4" + "@jridgewell/gen-mapping" "^0.3.2" + jsesc "^2.5.1" + +"@babel/helper-annotate-as-pure@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz#eaa49f6f80d5a33f9a5dd2276e6d6e451be0a6bb" + integrity sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA== + dependencies: + "@babel/types" "^7.18.6" + "@babel/helper-compilation-targets@^7.15.4": version "7.15.4" resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz" @@ -106,6 +163,16 @@ browserslist "^4.17.5" semver "^6.3.0" +"@babel/helper-compilation-targets@^7.19.3": + version "7.19.3" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz#a10a04588125675d7c7ae299af86fa1b2ee038ca" + integrity sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg== + dependencies: + "@babel/compat-data" "^7.19.3" + "@babel/helper-validator-option" "^7.18.6" + browserslist "^4.21.3" + semver "^6.3.0" + "@babel/helper-environment-visitor@^7.16.7": version "7.16.7" resolved "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz" @@ -113,6 +180,11 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-environment-visitor@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" + integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== + "@babel/helper-function-name@^7.15.4": version "7.15.4" resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz" @@ -131,6 +203,14 @@ "@babel/template" "^7.16.7" "@babel/types" "^7.16.7" +"@babel/helper-function-name@^7.19.0": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c" + integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w== + dependencies: + "@babel/template" "^7.18.10" + "@babel/types" "^7.19.0" + "@babel/helper-get-function-arity@^7.15.4": version "7.15.4" resolved "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz" @@ -159,6 +239,13 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-hoist-variables@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" + integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== + dependencies: + "@babel/types" "^7.18.6" + "@babel/helper-member-expression-to-functions@^7.15.4": version "7.15.4" resolved "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz" @@ -180,6 +267,13 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-module-imports@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" + integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== + dependencies: + "@babel/types" "^7.18.6" + "@babel/helper-module-transforms@^7.15.4": version "7.15.7" resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.7.tgz" @@ -208,6 +302,20 @@ "@babel/traverse" "^7.16.7" "@babel/types" "^7.16.7" +"@babel/helper-module-transforms@^7.19.0": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz#309b230f04e22c58c6a2c0c0c7e50b216d350c30" + integrity sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-simple-access" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-validator-identifier" "^7.18.6" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.19.0" + "@babel/types" "^7.19.0" + "@babel/helper-optimise-call-expression@^7.15.4": version "7.15.4" resolved "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz" @@ -220,6 +328,11 @@ resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz" integrity sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ== +"@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.19.0": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz#4796bb14961521f0f8715990bee2fb6e51ce21bf" + integrity sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw== + "@babel/helper-replace-supers@^7.15.4": version "7.15.4" resolved "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz" @@ -244,6 +357,13 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-simple-access@^7.18.6": + version "7.19.4" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.19.4.tgz#be553f4951ac6352df2567f7daa19a0ee15668e7" + integrity sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg== + dependencies: + "@babel/types" "^7.19.4" + "@babel/helper-split-export-declaration@^7.15.4": version "7.15.4" resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz" @@ -258,6 +378,18 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-split-export-declaration@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" + integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-string-parser@^7.19.4": + version "7.19.4" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63" + integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw== + "@babel/helper-validator-identifier@^7.14.5": version "7.14.8" resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.8.tgz" @@ -273,6 +405,11 @@ resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz" integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== +"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" + integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== + "@babel/helper-validator-option@^7.14.5": version "7.14.5" resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz" @@ -283,6 +420,11 @@ resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz" integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== +"@babel/helper-validator-option@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" + integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== + "@babel/helpers@^7.15.4": version "7.15.4" resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz" @@ -301,6 +443,15 @@ "@babel/traverse" "^7.16.7" "@babel/types" "^7.16.7" +"@babel/helpers@^7.19.0": + version "7.19.4" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.19.4.tgz#42154945f87b8148df7203a25c31ba9a73be46c5" + integrity sha512-G+z3aOx2nfDHwX/kyVii5fJq+bgscg89/dJNWpYeKeBv3v9xX8EIabmx1k6u9LS04H7nROFVRVK+e3k0VHp+sw== + dependencies: + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.19.4" + "@babel/types" "^7.19.4" + "@babel/highlight@^7.14.5": version "7.14.5" resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz" @@ -319,6 +470,15 @@ chalk "^2.0.0" js-tokens "^4.0.0" +"@babel/highlight@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" + integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== + dependencies: + "@babel/helper-validator-identifier" "^7.18.6" + chalk "^2.0.0" + js-tokens "^4.0.0" + "@babel/parser@^7.1.0", "@babel/parser@^7.15.4", "@babel/parser@^7.15.5", "@babel/parser@^7.7.2": version "7.15.7" resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.15.7.tgz" @@ -329,6 +489,11 @@ resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.16.7.tgz" integrity sha512-sR4eaSrnM7BV7QPzGfEX5paG/6wrZM3I0HDzfIAK06ESvo9oy3xBuVBxE3MbQaKNhvg8g/ixjMWo2CGpzpHsDA== +"@babel/parser@^7.18.10", "@babel/parser@^7.19.3", "@babel/parser@^7.19.4": + version "7.19.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.19.4.tgz#03c4339d2b8971eb3beca5252bafd9b9f79db3dc" + integrity sha512-qpVT7gtuOLjWeDTKLkJ6sryqLliBaFpAtGeqw5cs5giLldvh+Ch0plqnUMKoVAUS6ZEueQQiZV+p5pxtPitEsA== + "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" resolved "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz" @@ -364,6 +529,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" +"@babel/plugin-syntax-jsx@^7.17.12", "@babel/plugin-syntax-jsx@^7.18.6", "@babel/plugin-syntax-jsx@^7.7.2": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz#a8feef63b010150abd97f1649ec296e849943ca0" + integrity sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": version "7.10.4" resolved "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz" @@ -420,6 +592,52 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" +"@babel/plugin-transform-react-jsx-development@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz#dbe5c972811e49c7405b630e4d0d2e1380c0ddc5" + integrity sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA== + dependencies: + "@babel/plugin-transform-react-jsx" "^7.18.6" + +"@babel/plugin-transform-react-jsx-self@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.18.6.tgz#3849401bab7ae8ffa1e3e5687c94a753fc75bda7" + integrity sha512-A0LQGx4+4Jv7u/tWzoJF7alZwnBDQd6cGLh9P+Ttk4dpiL+J5p7NSNv/9tlEFFJDq3kjxOavWmbm6t0Gk+A3Ig== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-react-jsx-source@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.18.6.tgz#06e9ae8a14d2bc19ce6e3c447d842032a50598fc" + integrity sha512-utZmlASneDfdaMh0m/WausbjUjEdGrQJz0vFK93d7wD3xf5wBtX219+q6IlCNZeguIcxS2f/CvLZrlLSvSHQXw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-react-jsx@^7.18.10", "@babel/plugin-transform-react-jsx@^7.18.6": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.19.0.tgz#b3cbb7c3a00b92ec8ae1027910e331ba5c500eb9" + integrity sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-plugin-utils" "^7.19.0" + "@babel/plugin-syntax-jsx" "^7.18.6" + "@babel/types" "^7.19.0" + +"@babel/runtime@7.13.9": + version "7.13.9" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.9.tgz#97dbe2116e2630c489f22e0656decd60aaa1fcee" + integrity sha512-aY2kU+xgJ3dJ1eU6FMB9EH8dIe8dmusF1xEku52joLvw6eAFN0AI+WxCLDnpev2LEejWBAy2sBvBOBAjI3zmvA== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/runtime@^7.0.0", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3": + version "7.19.4" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.19.4.tgz#a42f814502ee467d55b38dd1c256f53a7b885c78" + integrity sha512-EXpLCrk55f+cYqmHsSR+yD/0gAIMxxA9QK9lnQWzhMCvt+YmoBN7Zx94s++Kv0+unHk39vxNO8t+CMA2WSS3wA== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/template@^7.15.4", "@babel/template@^7.3.3": version "7.15.4" resolved "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz" @@ -438,6 +656,15 @@ "@babel/parser" "^7.16.7" "@babel/types" "^7.16.7" +"@babel/template@^7.18.10": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71" + integrity sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/parser" "^7.18.10" + "@babel/types" "^7.18.10" + "@babel/traverse@^7.1.0", "@babel/traverse@^7.15.4", "@babel/traverse@^7.7.2": version "7.15.4" resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz" @@ -469,6 +696,22 @@ debug "^4.1.0" globals "^11.1.0" +"@babel/traverse@^7.19.0", "@babel/traverse@^7.19.3", "@babel/traverse@^7.19.4": + version "7.19.4" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.19.4.tgz#f117820e18b1e59448a6c1fa9d0ff08f7ac459a8" + integrity sha512-w3K1i+V5u2aJUOXBFFC5pveFLmtq1s3qcdDNC2qRI6WPBQIDaKFqXxDEqDO/h1dQ3HjsZoZMyIy6jGLq0xtw+g== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.19.4" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.19.0" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/parser" "^7.19.4" + "@babel/types" "^7.19.4" + debug "^4.1.0" + globals "^11.1.0" + "@babel/types@^7.0.0", "@babel/types@^7.15.4", "@babel/types@^7.15.6", "@babel/types@^7.3.0", "@babel/types@^7.3.3": version "7.15.6" resolved "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz" @@ -485,11 +728,748 @@ "@babel/helper-validator-identifier" "^7.16.7" to-fast-properties "^2.0.0" +"@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.19.0", "@babel/types@^7.19.3", "@babel/types@^7.19.4": + version "7.19.4" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.19.4.tgz#0dd5c91c573a202d600490a35b33246fed8a41c7" + integrity sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw== + dependencies: + "@babel/helper-string-parser" "^7.19.4" + "@babel/helper-validator-identifier" "^7.19.1" + to-fast-properties "^2.0.0" + "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@chakra-ui/accordion@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/accordion/-/accordion-2.1.1.tgz#34a8ffe7eb5bd30f7e10db4ed61f80c53d8bfa18" + integrity sha512-5f4QBl/0EgU/9EVvzlj8ZU7SWwG6nUHCE9moGBCbgiIOVBEySxZ5Robsk6+T7sXmzQ41db04GcUE9NRKdalgIA== + dependencies: + "@chakra-ui/descendant" "3.0.10" + "@chakra-ui/icon" "3.0.11" + "@chakra-ui/react-context" "2.0.4" + "@chakra-ui/react-use-controllable-state" "2.0.5" + "@chakra-ui/react-use-merge-refs" "2.0.4" + "@chakra-ui/transition" "2.0.10" + +"@chakra-ui/alert@2.0.11": + version "2.0.11" + resolved "https://registry.yarnpkg.com/@chakra-ui/alert/-/alert-2.0.11.tgz#d792b0684ae7810befa3874af5bdd4aa115513a2" + integrity sha512-n40KHU3j1H6EbIdgptjEad92V7Fpv7YD++ZBjy2g1h4w9ay9nw4kGHib3gaIkBupLf52CfLqySEc8w0taoIlXQ== + dependencies: + "@chakra-ui/icon" "3.0.11" + "@chakra-ui/react-context" "2.0.4" + "@chakra-ui/spinner" "2.0.10" + +"@chakra-ui/anatomy@2.0.7": + version "2.0.7" + resolved "https://registry.yarnpkg.com/@chakra-ui/anatomy/-/anatomy-2.0.7.tgz#33e60c7c4d6e5f949f6f8308249dc571f84ead1e" + integrity sha512-vzcB2gcsGCxhrKbldQQV6LnBPys4eSSsH2UA2mLsT+J3WlXw0aodZw0eE/nH7yLxe4zaQ4Gnc0KjkFW4EWNKSg== + +"@chakra-ui/avatar@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/avatar/-/avatar-2.1.1.tgz#7482d7cda4736dfa9e4b4eefd5cbb8c5b1486c64" + integrity sha512-lTZPUq4Pefxgv3ndyJMxIHgFrXwdz2VZFCLF/aKcuGaUlB7TBYaCurQ7TNbME8j8VkJWNX+vKiVHPYvxsrITwQ== + dependencies: + "@chakra-ui/image" "2.0.11" + "@chakra-ui/react-children-utils" "2.0.2" + "@chakra-ui/react-context" "2.0.4" + +"@chakra-ui/breadcrumb@2.0.10": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@chakra-ui/breadcrumb/-/breadcrumb-2.0.10.tgz#2b01e7422e171d1de1a8ca8c8e2a774c8449701b" + integrity sha512-roKFA7nheq18eWNAdrHV6w8A9vZMSQTEEsbL6eU0lhUkolW9RlDjBl1bZvE7icFkNFXlJ33n8+0QAezLI+mMrQ== + dependencies: + "@chakra-ui/react-children-utils" "2.0.2" + "@chakra-ui/react-context" "2.0.4" + +"@chakra-ui/breakpoint-utils@2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@chakra-ui/breakpoint-utils/-/breakpoint-utils-2.0.4.tgz#6231eff8b20f4e3cbb4eb7c86d05c927679d905b" + integrity sha512-SUUEYnA/FCIKYDHMuEXcnBMwet+6RAAjQ+CqGD1hlwKPTfh7EK9fS8FoVAJa9KpRKAc/AawzPkgwvorzPj8NSg== + +"@chakra-ui/button@2.0.11": + version "2.0.11" + resolved "https://registry.yarnpkg.com/@chakra-ui/button/-/button-2.0.11.tgz#98e0aa1e35ea7e193bb50f9a4b5d0ea23202ace8" + integrity sha512-J6iMRITqxTxa0JexHUY9c7BXUrTZtSkl3jZ2hxiFybB4MQL8J2wZ24O846B6M+WTYqy7XVuHRuVURnH4czWesw== + dependencies: + "@chakra-ui/react-context" "2.0.4" + "@chakra-ui/react-use-merge-refs" "2.0.4" + "@chakra-ui/spinner" "2.0.10" + +"@chakra-ui/checkbox@2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/checkbox/-/checkbox-2.2.1.tgz#3e88337f4588bb8bbc37da0102653b35991d736d" + integrity sha512-soTeXEI+4UZSA4B4rRLpdh3cIW/gdhY6k0eXF4ZWExPb+dJ5Giv497S96vS4IGE7SJ7Ugw9kaWS+do2lSiPJew== + dependencies: + "@chakra-ui/form-control" "2.0.11" + "@chakra-ui/react-context" "2.0.4" + "@chakra-ui/react-types" "2.0.3" + "@chakra-ui/react-use-callback-ref" "2.0.4" + "@chakra-ui/react-use-controllable-state" "2.0.5" + "@chakra-ui/react-use-merge-refs" "2.0.4" + "@chakra-ui/react-use-safe-layout-effect" "2.0.2" + "@chakra-ui/react-use-update-effect" "2.0.4" + "@chakra-ui/visually-hidden" "2.0.11" + "@zag-js/focus-visible" "0.1.0" + +"@chakra-ui/clickable@2.0.10": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@chakra-ui/clickable/-/clickable-2.0.10.tgz#e89b7b3eaf9364753f6205e36fd5128b26a617d8" + integrity sha512-G6JdR6yAMlXpfjOJ70W2FL7aUwNuomiMFtkneeTpk7Q42bJ5iGHfYlbZEx5nJd8iB+UluXVM4xlhMv2MyytjGw== + dependencies: + "@chakra-ui/react-use-merge-refs" "2.0.4" + +"@chakra-ui/close-button@2.0.11": + version "2.0.11" + resolved "https://registry.yarnpkg.com/@chakra-ui/close-button/-/close-button-2.0.11.tgz#8b0679da42738229014d3807885d05fac0fdf448" + integrity sha512-9WF/nwwK9BldS89WQ5PtXK2nFS4r8QOgKls2BOwXfE+rGmOUZtOsu8ne/drXRjgkiBRETR6CxdyUjm7EPzXllw== + dependencies: + "@chakra-ui/icon" "3.0.11" + +"@chakra-ui/color-mode@2.1.9": + version "2.1.9" + resolved "https://registry.yarnpkg.com/@chakra-ui/color-mode/-/color-mode-2.1.9.tgz#d3a6f9ba9eee15d9e14cc96484e25d44cef1dbc1" + integrity sha512-0kx0I+AQon8oS23/X+qMtnhsv/1BUulyJvU56p3Uh8CRaBfgJ7Ly9CerShoUL+5kadu6hN1M9oty4cugaCwv2w== + dependencies: + "@chakra-ui/react-use-safe-layout-effect" "2.0.2" + +"@chakra-ui/control-box@2.0.10": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@chakra-ui/control-box/-/control-box-2.0.10.tgz#e8a849c9f0fa085da78ee15dda7e13e1734b983d" + integrity sha512-sHmZanFLEv4IDATl19ZTxq8Bi8PtjfvnsN6xF4k7JGSYUnk1YXUf1coyW7WKdcsczOASrMikfsLc3iEVAzx4Ng== + +"@chakra-ui/counter@2.0.10": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@chakra-ui/counter/-/counter-2.0.10.tgz#861f00db021235892dfe0407e739a259f1c233b2" + integrity sha512-MZK8UKUZp4nFMd+GlV/cq0NIARS7UdlubTuCx+wockw9j2JI5OHzsyK0XiWuJiq5psegSTzpbtT99QfAUm3Yiw== + dependencies: + "@chakra-ui/number-utils" "2.0.4" + "@chakra-ui/react-use-callback-ref" "2.0.4" + +"@chakra-ui/css-reset@2.0.8": + version "2.0.8" + resolved "https://registry.yarnpkg.com/@chakra-ui/css-reset/-/css-reset-2.0.8.tgz#093ce6b166b37f2dd14e63f246635c463a59c106" + integrity sha512-VuDD1rk1pFc+dItk4yUcstyoC9D2B35hatHDBtlPMqTczFAzpbgVJJYgEHANatXGfulM5SdckmYEIJ3Tac1Rtg== + +"@chakra-ui/descendant@3.0.10": + version "3.0.10" + resolved "https://registry.yarnpkg.com/@chakra-ui/descendant/-/descendant-3.0.10.tgz#e54c95270896c451f61b57d31719ee042f4e1827" + integrity sha512-MHH0Qdm0fGllGP2xgx4WOycmrpctyyEdGw6zxcfs2VqZNlrwmjG3Yb9eVY+Q7UmEv5rwAq6qRn7BhQxgSPn3Cg== + dependencies: + "@chakra-ui/react-context" "2.0.4" + "@chakra-ui/react-use-merge-refs" "2.0.4" + +"@chakra-ui/dom-utils@2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@chakra-ui/dom-utils/-/dom-utils-2.0.3.tgz#8a5498b107d3a42662f3502f7b8965cb73bf6a33" + integrity sha512-aeGlRmTxcv0cvW44DyeZHru1i68ZDQsXpfX2dnG1I1yBlT6GlVx1xYjCULis9mjhgvd2O3NfcYPRTkjNWTDUbA== + +"@chakra-ui/editable@2.0.12": + version "2.0.12" + resolved "https://registry.yarnpkg.com/@chakra-ui/editable/-/editable-2.0.12.tgz#935d100cdce18268c9bf716ec9192b4b46253ffb" + integrity sha512-37bDqm+j2JTN2XR443KRK9MmHHIQuS6fN+2TRuFgjfG8TomxxCJnhJ3GIfQSKh5Yjtnt4sXDmL4L0tyDpNrrrw== + dependencies: + "@chakra-ui/react-context" "2.0.4" + "@chakra-ui/react-types" "2.0.3" + "@chakra-ui/react-use-callback-ref" "2.0.4" + "@chakra-ui/react-use-controllable-state" "2.0.5" + "@chakra-ui/react-use-focus-on-pointer-down" "2.0.3" + "@chakra-ui/react-use-merge-refs" "2.0.4" + "@chakra-ui/react-use-safe-layout-effect" "2.0.2" + "@chakra-ui/react-use-update-effect" "2.0.4" + "@chakra-ui/shared-utils" "2.0.2" + +"@chakra-ui/event-utils@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@chakra-ui/event-utils/-/event-utils-2.0.5.tgz#23de21e319d1a70863953402d64cb4b0e6ce322f" + integrity sha512-VXoOAIsM0PFKDlhm+EZxkWlUXd5UFTb/LTux3y3A+S9G5fDxLRvpiLWByPUgTFTCDFcgTCF+YnQtdWJB4DLyxg== + +"@chakra-ui/focus-lock@2.0.12": + version "2.0.12" + resolved "https://registry.yarnpkg.com/@chakra-ui/focus-lock/-/focus-lock-2.0.12.tgz#11c0301a326249efe269c2dd0f54b11a67a04321" + integrity sha512-NvIP59A11ZNbxXZ3qwxSiQ5npjABkpSbTIjK0uZ9bZm5LMfepRnuuA19VsVlq31/BYV9nHFAy6xzIuG+Qf9xMA== + dependencies: + "@chakra-ui/dom-utils" "2.0.3" + react-focus-lock "^2.9.1" + +"@chakra-ui/form-control@2.0.11": + version "2.0.11" + resolved "https://registry.yarnpkg.com/@chakra-ui/form-control/-/form-control-2.0.11.tgz#fbfdddb02d1b5d2c67ffdc721c434ff16693e4bd" + integrity sha512-MVhIe0xY4Zn06IXRXFmS9tCa93snppK1SdUQb1P99Ipo424RrL5ykzLnJ8CAkQrhoVP3sxF7z3eOSzk8/iRfow== + dependencies: + "@chakra-ui/icon" "3.0.11" + "@chakra-ui/react-context" "2.0.4" + "@chakra-ui/react-types" "2.0.3" + "@chakra-ui/react-use-merge-refs" "2.0.4" + +"@chakra-ui/hooks@2.0.11": + version "2.0.11" + resolved "https://registry.yarnpkg.com/@chakra-ui/hooks/-/hooks-2.0.11.tgz#465ee4720c0e76900a4a4480c347d6c91bb4848e" + integrity sha512-mYN4u9lbjDjEr/VucrVcLGg/sIO6gA9ZprcT3n9CBGSWt3xih7fCOJmE+yRcCNbL7335AMrv7a/M5Q30aRArcA== + dependencies: + "@chakra-ui/react-utils" "2.0.8" + "@chakra-ui/utils" "2.0.11" + compute-scroll-into-view "1.0.14" + copy-to-clipboard "3.3.1" + +"@chakra-ui/icon@3.0.11": + version "3.0.11" + resolved "https://registry.yarnpkg.com/@chakra-ui/icon/-/icon-3.0.11.tgz#a51dda24bed2f2ed77b4136ada8f22d3249c9870" + integrity sha512-RG4jf/XmBdaxOYI5J5QstEtTCPoVlmrQ/XiWhvN0LTgAnmZIqVwFl3Uw+satArdStHAs0GmJZg/E/soFTWuFmw== + dependencies: + "@chakra-ui/shared-utils" "2.0.2" + +"@chakra-ui/image@2.0.11": + version "2.0.11" + resolved "https://registry.yarnpkg.com/@chakra-ui/image/-/image-2.0.11.tgz#eb880ecd2fce47f22ef50bbbba66cbb027c0304c" + integrity sha512-S6NqAprPcbHnck/J+2wg06r9SSol62v5A01O8Kke2PnAyjalMcS+6P59lDRO7wvPqsdxq4PPbSTZP6Dww2CvcA== + dependencies: + "@chakra-ui/react-use-safe-layout-effect" "2.0.2" + +"@chakra-ui/input@2.0.11": + version "2.0.11" + resolved "https://registry.yarnpkg.com/@chakra-ui/input/-/input-2.0.11.tgz#1d37093f2128f3148551b22c43f623256c856940" + integrity sha512-kaV0VCz6/yzoCKQnh/tMUVgh+Rp6EnM+WzJ37SVX1gDvErON2bmmVLU45BiRoWUcd50wOhDlpsNVUWP0sLlCDA== + dependencies: + "@chakra-ui/form-control" "2.0.11" + "@chakra-ui/object-utils" "2.0.4" + "@chakra-ui/react-children-utils" "2.0.2" + "@chakra-ui/react-context" "2.0.4" + "@chakra-ui/shared-utils" "2.0.2" + +"@chakra-ui/layout@2.1.8": + version "2.1.8" + resolved "https://registry.yarnpkg.com/@chakra-ui/layout/-/layout-2.1.8.tgz#5bab204e33079527e0756e2f3616718888b5f14d" + integrity sha512-pcNUNgMh+e4wepNOlCg5iDrxGg4VFBpqZPmSHoP4TyPN2ddEnDRLoMLaREMoX7gEVyTsqEFOFg+wa3JZK32H4A== + dependencies: + "@chakra-ui/breakpoint-utils" "2.0.4" + "@chakra-ui/icon" "3.0.11" + "@chakra-ui/object-utils" "2.0.4" + "@chakra-ui/react-children-utils" "2.0.2" + "@chakra-ui/react-context" "2.0.4" + "@chakra-ui/shared-utils" "2.0.2" + +"@chakra-ui/lazy-utils@2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/lazy-utils/-/lazy-utils-2.0.2.tgz#d85f9afc60c2434ba76376fd4b23a7a0a1341e14" + integrity sha512-MTxutBJZvqNNqrrS0722cI7qrnGu0yUQpIebmTxYwI+F3cOnPEKf5Ni+hrA8hKcw4XJhSY4npAPPYu1zJbOV4w== + +"@chakra-ui/live-region@2.0.10": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@chakra-ui/live-region/-/live-region-2.0.10.tgz#d33a784c85feed7ba96e2579553ca1d20c965171" + integrity sha512-eQ2ZIreR/plzi/KGszDYTi1TvIyGEBcPiWP52BQOS7xwpzb1vsoR1FgFAIELxAGJvKnMUs+9qVogfyRBX8PdOg== + +"@chakra-ui/media-query@3.2.7": + version "3.2.7" + resolved "https://registry.yarnpkg.com/@chakra-ui/media-query/-/media-query-3.2.7.tgz#ece5b2181136145305bf5e6ec82c696ef1d59a77" + integrity sha512-hbgm6JCe0kYU3PAhxASYYDopFQI26cW9kZnbp+5tRL1fykkVWNMPwoGC8FEZPur9JjXp7aoL6H4Jk7nrxY/XWw== + dependencies: + "@chakra-ui/breakpoint-utils" "2.0.4" + "@chakra-ui/react-env" "2.0.10" + +"@chakra-ui/menu@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/menu/-/menu-2.1.1.tgz#de2b6da5c1267513a7c4b2ae73eff6ea4848a326" + integrity sha512-9fpCyV3vufLV5Rvv/oYC3LyCIkNqh0bEdYFVOLiqCZ6mt6NLFxL2jgE25nROYfDXQuBkY0qPC9IopYU198G4nw== + dependencies: + "@chakra-ui/clickable" "2.0.10" + "@chakra-ui/descendant" "3.0.10" + "@chakra-ui/lazy-utils" "2.0.2" + "@chakra-ui/popper" "3.0.8" + "@chakra-ui/react-children-utils" "2.0.2" + "@chakra-ui/react-context" "2.0.4" + "@chakra-ui/react-use-animation-state" "2.0.5" + "@chakra-ui/react-use-controllable-state" "2.0.5" + "@chakra-ui/react-use-disclosure" "2.0.5" + "@chakra-ui/react-use-focus-effect" "2.0.5" + "@chakra-ui/react-use-merge-refs" "2.0.4" + "@chakra-ui/react-use-outside-click" "2.0.4" + "@chakra-ui/react-use-update-effect" "2.0.4" + "@chakra-ui/transition" "2.0.10" + +"@chakra-ui/modal@2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/modal/-/modal-2.2.1.tgz#2903d1e0a0a5ab308db2ce5e3f6382eed20e702a" + integrity sha512-+zfiUG/yZqUQ0wY7syoZg01cpBf54lbKUe7+ANEx558UQGbsI4bbcHSkY9l5lsprQ8teInvhjb6BekeCA0e7TA== + dependencies: + "@chakra-ui/close-button" "2.0.11" + "@chakra-ui/focus-lock" "2.0.12" + "@chakra-ui/portal" "2.0.10" + "@chakra-ui/react-context" "2.0.4" + "@chakra-ui/react-types" "2.0.3" + "@chakra-ui/react-use-merge-refs" "2.0.4" + "@chakra-ui/transition" "2.0.10" + aria-hidden "^1.1.1" + react-remove-scroll "^2.5.4" + +"@chakra-ui/number-input@2.0.12": + version "2.0.12" + resolved "https://registry.yarnpkg.com/@chakra-ui/number-input/-/number-input-2.0.12.tgz#90a8408e6abb2d021793888ef2119d01761d7614" + integrity sha512-3owLjl01sCYpTd3xbq//fJo9QJ0Q3PVYSx9JeOzlXnnTW8ws+yHPrqQzPe7G+tO4yOYynWuUT+NJ9oyCeAJIxA== + dependencies: + "@chakra-ui/counter" "2.0.10" + "@chakra-ui/form-control" "2.0.11" + "@chakra-ui/icon" "3.0.11" + "@chakra-ui/react-context" "2.0.4" + "@chakra-ui/react-types" "2.0.3" + "@chakra-ui/react-use-callback-ref" "2.0.4" + "@chakra-ui/react-use-event-listener" "2.0.4" + "@chakra-ui/react-use-interval" "2.0.2" + "@chakra-ui/react-use-merge-refs" "2.0.4" + "@chakra-ui/react-use-safe-layout-effect" "2.0.2" + "@chakra-ui/react-use-update-effect" "2.0.4" + +"@chakra-ui/number-utils@2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@chakra-ui/number-utils/-/number-utils-2.0.4.tgz#0331be05956f2c03125c073d35655e261e267cd4" + integrity sha512-MdYd29GboBoKaXY9jhbY0Wl+0NxG1t/fa32ZSIbU6VrfMsZuAMl4NEJsz7Xvhy50fummLdKn5J6HFS7o5iyIgw== + +"@chakra-ui/object-utils@2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@chakra-ui/object-utils/-/object-utils-2.0.4.tgz#d890ce285103a5e9b993f016a4fb38307aa55ac0" + integrity sha512-sY98L4v2wcjpwRX8GCXqT+WzpL0i5FHVxT1Okxw0360T2tGnZt7toAwpMfIOR3dzkemP9LfXMCyBmWR5Hi2zpQ== + +"@chakra-ui/pin-input@2.0.14": + version "2.0.14" + resolved "https://registry.yarnpkg.com/@chakra-ui/pin-input/-/pin-input-2.0.14.tgz#8b5a1817c508bf0c986c6855245b0dc516a14df8" + integrity sha512-gFNlTUjU1xIuOErR/d/HrNNh1mS0erjNJSt5C6RU/My4lShzgCczmwnil7TuEx3k7lPqHKLEf/CGeCxBSUjaGA== + dependencies: + "@chakra-ui/descendant" "3.0.10" + "@chakra-ui/react-children-utils" "2.0.2" + "@chakra-ui/react-context" "2.0.4" + "@chakra-ui/react-use-controllable-state" "2.0.5" + "@chakra-ui/react-use-merge-refs" "2.0.4" + +"@chakra-ui/popover@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/popover/-/popover-2.1.1.tgz#1b5e05e334ba5f9bce4bc5bcabfb92563393fc84" + integrity sha512-j09NsesfT+eaYITkITYJXDlRcPoOeQUM80neJZKOBgul2iHkVsEoii8dwS5Ip5ONeu4ane1b6zEOlYvYj2SrkA== + dependencies: + "@chakra-ui/close-button" "2.0.11" + "@chakra-ui/lazy-utils" "2.0.2" + "@chakra-ui/popper" "3.0.8" + "@chakra-ui/react-context" "2.0.4" + "@chakra-ui/react-types" "2.0.3" + "@chakra-ui/react-use-animation-state" "2.0.5" + "@chakra-ui/react-use-disclosure" "2.0.5" + "@chakra-ui/react-use-focus-effect" "2.0.5" + "@chakra-ui/react-use-focus-on-pointer-down" "2.0.3" + "@chakra-ui/react-use-merge-refs" "2.0.4" + +"@chakra-ui/popper@3.0.8": + version "3.0.8" + resolved "https://registry.yarnpkg.com/@chakra-ui/popper/-/popper-3.0.8.tgz#89b6984aee405316974dbb70ba451f85832bf44e" + integrity sha512-246eUwuCRsLpTPxn5T8D8T9/6ODqmmz6pRRJAjGnLlUB0gNHgjisBn0UDBic5Gbxcg0sqKvxOMY3uurbW5lXTA== + dependencies: + "@chakra-ui/react-types" "2.0.3" + "@chakra-ui/react-use-merge-refs" "2.0.4" + "@popperjs/core" "^2.9.3" + +"@chakra-ui/portal@2.0.10": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@chakra-ui/portal/-/portal-2.0.10.tgz#8ac21131cb0666a0bf6565468b3f7e799ef3bc8d" + integrity sha512-VRYvVAggIuqIZ3IQ6XZ1b5ujjjOUgPk9PPdc9jssUngZa7RG+5NXNhgoM8a5TsXv6aPEolBOlDNWuxzRQ4RSSg== + dependencies: + "@chakra-ui/react-context" "2.0.4" + "@chakra-ui/react-use-safe-layout-effect" "2.0.2" + +"@chakra-ui/progress@2.0.11": + version "2.0.11" + resolved "https://registry.yarnpkg.com/@chakra-ui/progress/-/progress-2.0.11.tgz#f17a08f6d5dd59334ad705501debcbc031e0843d" + integrity sha512-2OwxGxI6W757QpDB6b++B4b2+t0oBgaQdHnd4/y35n3+mOFj++Wg7XpW4/iDHn+x3LkM+X3NIgdBWQFlmGx+6w== + dependencies: + "@chakra-ui/react-context" "2.0.4" + +"@chakra-ui/provider@2.0.19": + version "2.0.19" + resolved "https://registry.yarnpkg.com/@chakra-ui/provider/-/provider-2.0.19.tgz#6364df6b1f5058f77c270030b122f6614cdb69c4" + integrity sha512-V+p0OePre0OgYmNxLbfiPWWbzaJ/EM2sfaRtD7E6ZA4TjUl2m4pWdC6OPMOiklu7EALfSgVk9X6Jh5pc+moH1g== + dependencies: + "@chakra-ui/css-reset" "2.0.8" + "@chakra-ui/portal" "2.0.10" + "@chakra-ui/react-env" "2.0.10" + "@chakra-ui/system" "2.2.12" + "@chakra-ui/utils" "2.0.11" + +"@chakra-ui/radio@2.0.12": + version "2.0.12" + resolved "https://registry.yarnpkg.com/@chakra-ui/radio/-/radio-2.0.12.tgz#d89eb463df0247a0e634cff1fb9ca755bcbab825" + integrity sha512-871hqAGQaufxyUzPP3aautPBIRZQmpi3fw5XPZ6SbY62dV61M4sjcttd46HfCf5SrAonoOADFQLMGQafznjhaA== + dependencies: + "@chakra-ui/form-control" "2.0.11" + "@chakra-ui/react-context" "2.0.4" + "@chakra-ui/react-types" "2.0.3" + "@chakra-ui/react-use-merge-refs" "2.0.4" + "@zag-js/focus-visible" "0.1.0" + +"@chakra-ui/react-children-utils@2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-children-utils/-/react-children-utils-2.0.2.tgz#8676ce88573ad1824989399db8a1ec7e51afc0d0" + integrity sha512-mRTGAZ3DBXB3hgVwS2DVJe3Nlc0qGvMN0PAo4tD/3fj2op2IwspLcYPAWC5D/rI2xj2JlwE6szAtbvxdAfLCNw== + +"@chakra-ui/react-context@2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-context/-/react-context-2.0.4.tgz#1b6ab260d44d9073c95b975b7d1643f011e65e02" + integrity sha512-eBITFkf7fLSiMZrSdhweK4fYr41WUNMEeIEOP2dCWolE7WgKxNYaYleC+iRGY0GeXkFM2KYywUtixjJe29NuVA== + +"@chakra-ui/react-env@2.0.10": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-env/-/react-env-2.0.10.tgz#2eaa4ba64a14ecd2d279c32d5edfef7a6b5de3e8" + integrity sha512-3Yab5EbFcCGYzEsoijy4eA3354Z/JoXyk9chYIuW7Uwd+K6g/R8C0mUSAHeTmfp6Fix9kzDgerO5MWNM87b8cA== + +"@chakra-ui/react-types@2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-types/-/react-types-2.0.3.tgz#dc454c4703b4de585e6461fd607304ede06fe595" + integrity sha512-1mJYOQldFTALE0Wr3j6tk/MYvgQIp6CKkJulNzZrI8QN+ox/bJOh8OVP4vhwqvfigdLTui0g0k8M9h+j2ub/Mw== + +"@chakra-ui/react-use-animation-state@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-animation-state/-/react-use-animation-state-2.0.5.tgz#f022baf0103c35aa494227b041422e7d2401b0d4" + integrity sha512-8gZIqZpMS5yTGlC+IqYoSrV13joiAYoeI0YR2t68WuDagcZ459OrjE57+gF04NLxfdV7eUgwqnpuv7IOLbJX/A== + dependencies: + "@chakra-ui/dom-utils" "2.0.3" + "@chakra-ui/react-use-event-listener" "2.0.4" + +"@chakra-ui/react-use-callback-ref@2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-callback-ref/-/react-use-callback-ref-2.0.4.tgz#5099ef1df4413af42e434945f541de99394ec96f" + integrity sha512-he7EQfwMA4mwiDDKvX7cHIJaboCqf7UD3KYHGUcIjsF4dSc2Y8X5Ze4w+hmVZoJWIe4DWUzb3ili2SUm8eTgPg== + +"@chakra-ui/react-use-controllable-state@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-controllable-state/-/react-use-controllable-state-2.0.5.tgz#5ef9f600ae134a2a37fe080fd6231bbed83544bb" + integrity sha512-JrZZpMX24CUyfDuyqDczw9Z9IMvjH8ujETHK0Zu4M0SIsX/q4EqOwwngUFL03I2gx/O38HfSdeX8hMu4zbTAGA== + dependencies: + "@chakra-ui/react-use-callback-ref" "2.0.4" + +"@chakra-ui/react-use-disclosure@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-disclosure/-/react-use-disclosure-2.0.5.tgz#bb52340f0e7d614cc95819bd21cffd050783f96c" + integrity sha512-kPLB9oxImASRhAbKfvfc03/lbAJbsXndEVRzd+nvvL+QZm2RRfnel3k6OIkWvGFOXXYOPE2+slLe8ZPwbTGg9g== + dependencies: + "@chakra-ui/react-use-callback-ref" "2.0.4" + +"@chakra-ui/react-use-event-listener@2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-event-listener/-/react-use-event-listener-2.0.4.tgz#3f893def57a7b10db6c355740dd1e82cd3216259" + integrity sha512-VqmalfKWMO8D21XuZO19WUtcP5xhbHXKzkggApTChZUN02UC5TC4pe0pYbDygoeUuNBhY+9lJKHeS08vYsljRg== + dependencies: + "@chakra-ui/react-use-callback-ref" "2.0.4" + +"@chakra-ui/react-use-focus-effect@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-focus-effect/-/react-use-focus-effect-2.0.5.tgz#b554277c38e84468b019e08a73579e9700e1003a" + integrity sha512-sbe1QnsXXfjukM+laxbKnT0UnMpHe/7kTzEPG/BYM6/ZDUUmrC1Nz+8l+3H/52iWIaruikDBdif/Xd37Yvu3Kg== + dependencies: + "@chakra-ui/dom-utils" "2.0.3" + "@chakra-ui/react-use-event-listener" "2.0.4" + "@chakra-ui/react-use-update-effect" "2.0.4" + +"@chakra-ui/react-use-focus-on-pointer-down@2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-focus-on-pointer-down/-/react-use-focus-on-pointer-down-2.0.3.tgz#8b605063c9e707a18b021fbcaed8919c8660d1ed" + integrity sha512-8cKmpv26JnblexNaekWxEDI7M+MZnJcp1PJUz6lByjfQ1m4YjFr1cdbdhG4moaqzzYs7vTmO/qL8KVq8ZLUwyQ== + dependencies: + "@chakra-ui/react-use-event-listener" "2.0.4" + +"@chakra-ui/react-use-interval@2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-interval/-/react-use-interval-2.0.2.tgz#6d1d5d5b5c5604ee2ea47f1e140e6eaf6e885df5" + integrity sha512-5U1c0pEB5n0Yri0E4RdFXWx2RVBZBBhD8Uu49dM33jkIguCbIPmZ+YgVry5DDzCHyz4RgDg4yZKOPK0PI8lEUg== + dependencies: + "@chakra-ui/react-use-callback-ref" "2.0.4" + +"@chakra-ui/react-use-latest-ref@2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-latest-ref/-/react-use-latest-ref-2.0.2.tgz#4895d3ae2dc93a660ed86aaec7021b729830d3d2" + integrity sha512-Ra/NMV+DSQ3n0AdKsyIqdgnFzls5UntabtIRfDXLrqmJ4tI0a1tDdop2qop0Ue87AcqD9P1KtQue4KPx7wCElw== + +"@chakra-ui/react-use-merge-refs@2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-merge-refs/-/react-use-merge-refs-2.0.4.tgz#c23f10fda1d3a6327a48708a8a7ad4b62ba918d3" + integrity sha512-aoWvtE5tDQNaLCiNUI6WV+MA2zVcCLR5mHSCISmowlTXyXOqOU5Fo9ZoUftzrmgCJpDu5x1jfUOivxuHUueb0g== + +"@chakra-ui/react-use-outside-click@2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-outside-click/-/react-use-outside-click-2.0.4.tgz#977d873cfedec615c8e3acd48fca7b094b464b6e" + integrity sha512-uerJKS8dqg2kHs1xozA5vcCqW0UInuwrfCPb+rDWBTpu7aEqxABMw9W3e4gfOABrAjhKz2I0a/bu2i8zbVwdLw== + dependencies: + "@chakra-ui/react-use-callback-ref" "2.0.4" + +"@chakra-ui/react-use-pan-event@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-pan-event/-/react-use-pan-event-2.0.5.tgz#9269d4b798d1447e18b00ee0b28fa52c5c8efb26" + integrity sha512-nhE3b85++EEmBD2v6m46TLoA4LehSCZ349P8kvEjw/RC0K6XDOZndaBucIeAlnpEENSSUpczFfMSOLxSHdu0oA== + dependencies: + "@chakra-ui/event-utils" "2.0.5" + "@chakra-ui/react-use-latest-ref" "2.0.2" + framesync "5.3.0" + +"@chakra-ui/react-use-previous@2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-previous/-/react-use-previous-2.0.2.tgz#1091ae8abc2082ab504e3742f8b1d75409ae7b27" + integrity sha512-ap/teLRPKopaHYD80fnf0TR/NpTWHJO5VdKg6sPyF1y5ediYLAzPT1G2OqMCj4QfJsYDctioT142URDYe0Nn7w== + +"@chakra-ui/react-use-safe-layout-effect@2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-safe-layout-effect/-/react-use-safe-layout-effect-2.0.2.tgz#31088eeb4b2a6910251683ddb15fb855d6127adf" + integrity sha512-gl5HDq9RVeDJiT8udtpx12KRV8JPLJHDIUX8f/yZcKpXow0C7FFGg5Yy5I9397NQog5ZjKMuOg+AUq9TLJxsyQ== + +"@chakra-ui/react-use-size@2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-size/-/react-use-size-2.0.4.tgz#3634782f8dab6aa2a37699188afa89251cbae8f3" + integrity sha512-W6rgTLuoSC4ovZtqYco8cG+yBadH3bhlg92T5lgpKDakSDr0mXcZdbGx6g0AOkgxXm0V1jWNGO1743wudtF7ew== + dependencies: + "@zag-js/element-size" "0.1.0" + +"@chakra-ui/react-use-timeout@2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-timeout/-/react-use-timeout-2.0.2.tgz#f1378de0d5e01f7aee60d5b9ec3205e1fc7d2fc4" + integrity sha512-n6zb3OmxtDmRMxYkDgILqKh15aDOa8jNLHBlqHzmlL6mEGNKmMFPW9j/KvpAqSgKjUTDRnnXcpneprTMKy/yrw== + dependencies: + "@chakra-ui/react-use-callback-ref" "2.0.4" + +"@chakra-ui/react-use-update-effect@2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-update-effect/-/react-use-update-effect-2.0.4.tgz#522bc58b943fffe540a91f7a096d42e4a91b9748" + integrity sha512-F/I9LVnGAQyvww+x7tQb47wCwjhMYjpxtM1dTg1U3oCEXY0yF1Ts3NJLUAlsr3nAW6epJIwWx61niC7KWpam1w== + +"@chakra-ui/react-utils@2.0.8": + version "2.0.8" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-utils/-/react-utils-2.0.8.tgz#1db4e920386f4afbf44fe9dd8aaaf6f22eefb371" + integrity sha512-OSHHBKZlJWTi2NZcPnBx1PyZvLQY+n5RPBtcri7/89EDdAwz2NdEhp2Dz1yQRctOSCF1kB/rnCYDP1U0oRk9RQ== + dependencies: + "@chakra-ui/utils" "2.0.11" + +"@chakra-ui/react@^2.3.4": + version "2.3.5" + resolved "https://registry.yarnpkg.com/@chakra-ui/react/-/react-2.3.5.tgz#0f11a6ede3e90e334bab604e7a2c56e0d0fa930e" + integrity sha512-bQDRV23M3IvF0+AorTvqJmG/4T6KKQIb+1XGA2RyxonoSHVt89HbN3qnygHJw06Sdgpclxdbr/1qZ4o8+SMbpA== + dependencies: + "@chakra-ui/accordion" "2.1.1" + "@chakra-ui/alert" "2.0.11" + "@chakra-ui/avatar" "2.1.1" + "@chakra-ui/breadcrumb" "2.0.10" + "@chakra-ui/button" "2.0.11" + "@chakra-ui/checkbox" "2.2.1" + "@chakra-ui/close-button" "2.0.11" + "@chakra-ui/control-box" "2.0.10" + "@chakra-ui/counter" "2.0.10" + "@chakra-ui/css-reset" "2.0.8" + "@chakra-ui/editable" "2.0.12" + "@chakra-ui/form-control" "2.0.11" + "@chakra-ui/hooks" "2.0.11" + "@chakra-ui/icon" "3.0.11" + "@chakra-ui/image" "2.0.11" + "@chakra-ui/input" "2.0.11" + "@chakra-ui/layout" "2.1.8" + "@chakra-ui/live-region" "2.0.10" + "@chakra-ui/media-query" "3.2.7" + "@chakra-ui/menu" "2.1.1" + "@chakra-ui/modal" "2.2.1" + "@chakra-ui/number-input" "2.0.12" + "@chakra-ui/pin-input" "2.0.14" + "@chakra-ui/popover" "2.1.1" + "@chakra-ui/popper" "3.0.8" + "@chakra-ui/portal" "2.0.10" + "@chakra-ui/progress" "2.0.11" + "@chakra-ui/provider" "2.0.19" + "@chakra-ui/radio" "2.0.12" + "@chakra-ui/react-env" "2.0.10" + "@chakra-ui/select" "2.0.12" + "@chakra-ui/skeleton" "2.0.17" + "@chakra-ui/slider" "2.0.12" + "@chakra-ui/spinner" "2.0.10" + "@chakra-ui/stat" "2.0.11" + "@chakra-ui/styled-system" "2.3.4" + "@chakra-ui/switch" "2.0.13" + "@chakra-ui/system" "2.2.12" + "@chakra-ui/table" "2.0.11" + "@chakra-ui/tabs" "2.1.3" + "@chakra-ui/tag" "2.0.11" + "@chakra-ui/textarea" "2.0.12" + "@chakra-ui/theme" "2.1.13" + "@chakra-ui/toast" "3.0.13" + "@chakra-ui/tooltip" "2.2.0" + "@chakra-ui/transition" "2.0.10" + "@chakra-ui/utils" "2.0.11" + "@chakra-ui/visually-hidden" "2.0.11" + +"@chakra-ui/select@2.0.12": + version "2.0.12" + resolved "https://registry.yarnpkg.com/@chakra-ui/select/-/select-2.0.12.tgz#9b485e6a28c9aa468bc1c0d8a78aabd985b0c370" + integrity sha512-NCDMb0w48GYCHmazVSQ7/ysEpbnri+Up6n+v7yytf6g43TPRkikvK5CsVgLnAEj0lIdCJhWXTcZer5wG5KOEgA== + dependencies: + "@chakra-ui/form-control" "2.0.11" + +"@chakra-ui/shared-utils@2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/shared-utils/-/shared-utils-2.0.2.tgz#1df08133194c12ac4df9302604ec37784c2bb026" + integrity sha512-wC58Fh6wCnFFQyiebVZ0NI7PFW9+Vch0QE6qN7iR+bLseOzQY9miYuzPJ1kMYiFd6QTOmPJkI39M3wHqrPYiOg== + +"@chakra-ui/skeleton@2.0.17": + version "2.0.17" + resolved "https://registry.yarnpkg.com/@chakra-ui/skeleton/-/skeleton-2.0.17.tgz#737e08f771980f5b73060dc6c940691e7759d044" + integrity sha512-dL7viXEKDEzmAJGbHMj+QbGl9PAd0VWztEcWcz5wOGfmAcJllA0lVh6NmG/yqLb6iXPCX4Y1Y0Yurm459TEYWg== + dependencies: + "@chakra-ui/media-query" "3.2.7" + "@chakra-ui/react-use-previous" "2.0.2" + +"@chakra-ui/slider@2.0.12": + version "2.0.12" + resolved "https://registry.yarnpkg.com/@chakra-ui/slider/-/slider-2.0.12.tgz#42fc5fe385c507276da29f4aa49a6408ee853978" + integrity sha512-Cna04J7e4+F3tJNb7tRNfPP+koicbDsKJBp+f1NpR32JbRzIfrf2Vdr4hfD5/uOfC4RGxnVInNZzZLGBelLtLw== + dependencies: + "@chakra-ui/number-utils" "2.0.4" + "@chakra-ui/react-context" "2.0.4" + "@chakra-ui/react-types" "2.0.3" + "@chakra-ui/react-use-callback-ref" "2.0.4" + "@chakra-ui/react-use-controllable-state" "2.0.5" + "@chakra-ui/react-use-latest-ref" "2.0.2" + "@chakra-ui/react-use-merge-refs" "2.0.4" + "@chakra-ui/react-use-pan-event" "2.0.5" + "@chakra-ui/react-use-size" "2.0.4" + "@chakra-ui/react-use-update-effect" "2.0.4" + +"@chakra-ui/spinner@2.0.10": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@chakra-ui/spinner/-/spinner-2.0.10.tgz#f8b1b6f1c8f45e3aeab44d5ab1f1debc71e52573" + integrity sha512-SwId1xPaaFAaEYrR9eHkQHAuB66CbxwjWaQonEjeEUSh9ecxkd5WbXlsQSyf2hVRIqXJg0m3HIYblcKUsQt9Rw== + +"@chakra-ui/stat@2.0.11": + version "2.0.11" + resolved "https://registry.yarnpkg.com/@chakra-ui/stat/-/stat-2.0.11.tgz#0c052aee68486a892e09e802bb569dc984e31eae" + integrity sha512-ZPFK2fKufDSHD8bp/KhO3jLgW/b3PzdG4zV+7iTO7OYjxm5pkBfBAeMqfXGx4cl51rtWUKzsY0HV4vLLjcSjHw== + dependencies: + "@chakra-ui/icon" "3.0.11" + "@chakra-ui/react-context" "2.0.4" + +"@chakra-ui/styled-system@2.3.4": + version "2.3.4" + resolved "https://registry.yarnpkg.com/@chakra-ui/styled-system/-/styled-system-2.3.4.tgz#6022c5a675b54a69b1d3c2d3e60258901dc7b82a" + integrity sha512-Lozbedu+GBj4EbHB/eGv475SFDLApsIEN9gNKiZJBJAE1HIhHn3Seh1iZQSrHC/Beq+D5cQq3Z+yPn3bXtFU7w== + dependencies: + csstype "^3.0.11" + lodash.mergewith "4.6.2" + +"@chakra-ui/switch@2.0.13": + version "2.0.13" + resolved "https://registry.yarnpkg.com/@chakra-ui/switch/-/switch-2.0.13.tgz#1736a501daaeedab295b166c176cd2fd990adac3" + integrity sha512-Ikj0L+SLLs/SnfGCiUChaldLIr/aizA1Q9D5+X6LtxpBnixFK/+fNXU+3juPDi9G1IFuNz2IAG51souO7C4nSQ== + dependencies: + "@chakra-ui/checkbox" "2.2.1" + +"@chakra-ui/system@2.2.12": + version "2.2.12" + resolved "https://registry.yarnpkg.com/@chakra-ui/system/-/system-2.2.12.tgz#6792afebbebb21e03a4cbf6c0de79739f230acfc" + integrity sha512-I7hFQswp8tG6ogjEMFs5TsCItdCYuNxpLAULgUrLdOlsQeNnHNQhlL4zpIfD+VzguhsNy5lisbegAMKjdghTYg== + dependencies: + "@chakra-ui/color-mode" "2.1.9" + "@chakra-ui/react-utils" "2.0.8" + "@chakra-ui/styled-system" "2.3.4" + "@chakra-ui/utils" "2.0.11" + react-fast-compare "3.2.0" + +"@chakra-ui/table@2.0.11": + version "2.0.11" + resolved "https://registry.yarnpkg.com/@chakra-ui/table/-/table-2.0.11.tgz#9bd25d5383c94982b89e792675bc1d1f667f81f3" + integrity sha512-zQTiqPKEgjdeO/PG0FByn0fH4sPF7dLJF+YszrIzDc6wvpD96iY6MYLeV+CSelbH1g0/uibcJ10PSaFStfGUZg== + dependencies: + "@chakra-ui/react-context" "2.0.4" + +"@chakra-ui/tabs@2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@chakra-ui/tabs/-/tabs-2.1.3.tgz#17f462c7798292142a78938ae2e66781fe79c6da" + integrity sha512-9gUcj49LMt5QQnfJHR/ctr9VPttJ97CtQWuH2Irjb3RXkq1TRrz6wjythPImNQUv1/DYyXp2jsUhoEQc4Oz14Q== + dependencies: + "@chakra-ui/clickable" "2.0.10" + "@chakra-ui/descendant" "3.0.10" + "@chakra-ui/lazy-utils" "2.0.2" + "@chakra-ui/react-children-utils" "2.0.2" + "@chakra-ui/react-context" "2.0.4" + "@chakra-ui/react-use-controllable-state" "2.0.5" + "@chakra-ui/react-use-merge-refs" "2.0.4" + "@chakra-ui/react-use-safe-layout-effect" "2.0.2" + +"@chakra-ui/tag@2.0.11": + version "2.0.11" + resolved "https://registry.yarnpkg.com/@chakra-ui/tag/-/tag-2.0.11.tgz#14702adf5d1456dbbb84ea7a4b314953b92c323f" + integrity sha512-iJJcX+4hl+6Se/8eCRzG+xxDwZfiYgc4Ly/8s93M0uW2GLb+ybbfSE2DjeKSyk3mQVeGzuxGkBfDHH2c2v26ew== + dependencies: + "@chakra-ui/icon" "3.0.11" + "@chakra-ui/react-context" "2.0.4" + +"@chakra-ui/textarea@2.0.12": + version "2.0.12" + resolved "https://registry.yarnpkg.com/@chakra-ui/textarea/-/textarea-2.0.12.tgz#469c1d64cb855b3b534dcd7fcc1d927e60da8da1" + integrity sha512-msR9YMynRXwZIqR6DgjQ2MogA/cW1syBx/R0v3es+9Zx8zlbuKdoLhYqajHteCup8dUzTeIH2Vs2vAwgq4wu5A== + dependencies: + "@chakra-ui/form-control" "2.0.11" + +"@chakra-ui/theme-tools@2.0.12": + version "2.0.12" + resolved "https://registry.yarnpkg.com/@chakra-ui/theme-tools/-/theme-tools-2.0.12.tgz#b29d9fb626d35e3b00f532c64f95ea261d8f6997" + integrity sha512-mnMlKSmXkCjHUJsKWmJbgBTGF2vnLaMLv1ihkBn5eQcCubMQrBLTiMAEFl5pZdzuHItU6QdnLGA10smcXbNl0g== + dependencies: + "@chakra-ui/anatomy" "2.0.7" + "@ctrl/tinycolor" "^3.4.0" + +"@chakra-ui/theme@2.1.13": + version "2.1.13" + resolved "https://registry.yarnpkg.com/@chakra-ui/theme/-/theme-2.1.13.tgz#51e76179048cf87c0cb551a619a49d183246550e" + integrity sha512-qbrrvn9JstyLFV2qyhwgnhwzVs4zSJ4PcS3ScL8kafXJazTRU6onbCcjEZ5mVCw6z8uEz3jcE8Y5KIhVzaB+Xw== + dependencies: + "@chakra-ui/anatomy" "2.0.7" + "@chakra-ui/theme-tools" "2.0.12" + +"@chakra-ui/toast@3.0.13": + version "3.0.13" + resolved "https://registry.yarnpkg.com/@chakra-ui/toast/-/toast-3.0.13.tgz#e23f6a9c6cc373a78f66f465625b9777d8277033" + integrity sha512-5GADso5l5Tv1PAL1iocEneLs6U7I8HHMHSMvWdPFSmmJJh0XCH3fboh0C9LiFNIcnEGJmn+A5yGc4vjedA0h2A== + dependencies: + "@chakra-ui/alert" "2.0.11" + "@chakra-ui/close-button" "2.0.11" + "@chakra-ui/portal" "2.0.10" + "@chakra-ui/react-use-timeout" "2.0.2" + "@chakra-ui/react-use-update-effect" "2.0.4" + "@chakra-ui/styled-system" "2.3.4" + "@chakra-ui/theme" "2.1.13" + +"@chakra-ui/tooltip@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/tooltip/-/tooltip-2.2.0.tgz#24e005f831cddf1c0e41dd246ed2771a97b8637c" + integrity sha512-oB97aQJBW+U3rRIt1ct7NaDRMnbW16JQ5ZBCl3BzN1VJWO3djiNuscpjVdZSceb+FdGSFo+GoDozp1ZwqdfFeQ== + dependencies: + "@chakra-ui/popper" "3.0.8" + "@chakra-ui/portal" "2.0.10" + "@chakra-ui/react-types" "2.0.3" + "@chakra-ui/react-use-disclosure" "2.0.5" + "@chakra-ui/react-use-event-listener" "2.0.4" + "@chakra-ui/react-use-merge-refs" "2.0.4" + +"@chakra-ui/transition@2.0.10": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@chakra-ui/transition/-/transition-2.0.10.tgz#a1ab786f4c2d0e41eb02dfd0f2f8f48a0bc9e35b" + integrity sha512-Tkkne8pIIY7f95TKt2aH+IAuQqzHmEt+ICPqvg74QbmIpKE5ptX0cd+P3swBANw4ACnJcCc2vWIaKmVBQ9clLw== + +"@chakra-ui/utils@2.0.11": + version "2.0.11" + resolved "https://registry.yarnpkg.com/@chakra-ui/utils/-/utils-2.0.11.tgz#8e773f900a8356bd10c48b59151a781dba1c7b70" + integrity sha512-4ZQdK6tbOuTrUCsAQBHWo7tw5/Q6pBV93ZbVpats61cSWMFGv32AIQw9/hA4un2zDeSWN9ZMVLNjAY2Dq/KQOA== + dependencies: + "@types/lodash.mergewith" "4.6.6" + css-box-model "1.2.1" + framesync "5.3.0" + lodash.mergewith "4.6.2" + +"@chakra-ui/visually-hidden@2.0.11": + version "2.0.11" + resolved "https://registry.yarnpkg.com/@chakra-ui/visually-hidden/-/visually-hidden-2.0.11.tgz#b2eb236e803451b39cdfcce3c5ab52e773c066a3" + integrity sha512-e+5amYvnsmEQdiWH4XMyvrtGTdwz//+48vwj5CsNWWcselzkwqodmciy5rIrT71/SCQDOtmgnL7ZWAUOffxfsQ== + "@cspotcode/source-map-support@^0.8.0": version "0.8.1" resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" @@ -497,6 +1477,181 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" +"@ctrl/tinycolor@^3.4.0": + version "3.4.1" + resolved "https://registry.yarnpkg.com/@ctrl/tinycolor/-/tinycolor-3.4.1.tgz#75b4c27948c81e88ccd3a8902047bcd797f38d32" + integrity sha512-ej5oVy6lykXsvieQtqZxCOaLT+xD4+QNarq78cIYISHmZXshCvROLudpQN3lfL8G0NL7plMSSK+zlyvCaIJ4Iw== + +"@devicefarmer/adbkit-logcat@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@devicefarmer/adbkit-logcat/-/adbkit-logcat-1.1.0.tgz#866d3406dc9f3791446adfe3ae622ffc48607db4" + integrity sha512-K90P5gUXM/w+yzLvJIRQ+tJooNU6ipUPPQkljtPJ0laR66TGtpt4Gqsjm0n9dPHK1W5KGgU1R5wnCd6RTSlPNA== + +"@devicefarmer/adbkit-monkey@~1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@devicefarmer/adbkit-monkey/-/adbkit-monkey-1.0.1.tgz#7d225e5fdbdad8d6772453390ecab3f1b0eb72b1" + integrity sha512-HilPrVrCosYWqSyjfpDtaaN1kJwdlBpS+IAflP3z+e7nsEgk3JGJf1Vg0NgHJooTf5HDfXSyZqMVg+5jvXCK0g== + dependencies: + async "~0.2.9" + +"@devicefarmer/adbkit@2.11.3": + version "2.11.3" + resolved "https://registry.yarnpkg.com/@devicefarmer/adbkit/-/adbkit-2.11.3.tgz#0ad981a20aada3e4eff4871218f633c85cf7f2db" + integrity sha512-rsgWREAvSRQjdP9/3GoAV6Tq+o97haywgbTfCgt5yUqiDpaaq3hlH9FTo9XsdG8x+Jd0VQ9nTC2IXsDu8JGRSA== + dependencies: + "@devicefarmer/adbkit-logcat" "^1.1.0" + "@devicefarmer/adbkit-monkey" "~1.0.1" + bluebird "~2.9.24" + commander "^2.3.0" + debug "~2.6.3" + node-forge "^0.10.0" + split "~0.3.3" + +"@emotion/babel-plugin@^11.10.0": + version "11.10.2" + resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.10.2.tgz#879db80ba622b3f6076917a1e6f648b1c7d008c7" + integrity sha512-xNQ57njWTFVfPAc3cjfuaPdsgLp5QOSuRsj9MA6ndEhH/AzuZM86qIQzt6rq+aGBwj3n5/TkLmU5lhAfdRmogA== + dependencies: + "@babel/helper-module-imports" "^7.16.7" + "@babel/plugin-syntax-jsx" "^7.17.12" + "@babel/runtime" "^7.18.3" + "@emotion/hash" "^0.9.0" + "@emotion/memoize" "^0.8.0" + "@emotion/serialize" "^1.1.0" + babel-plugin-macros "^3.1.0" + convert-source-map "^1.5.0" + escape-string-regexp "^4.0.0" + find-root "^1.1.0" + source-map "^0.5.7" + stylis "4.0.13" + +"@emotion/cache@^11.10.0": + version "11.10.3" + resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.10.3.tgz#c4f67904fad10c945fea5165c3a5a0583c164b87" + integrity sha512-Psmp/7ovAa8appWh3g51goxu/z3iVms7JXOreq136D8Bbn6dYraPnmL6mdM8GThEx9vwSn92Fz+mGSjBzN8UPQ== + dependencies: + "@emotion/memoize" "^0.8.0" + "@emotion/sheet" "^1.2.0" + "@emotion/utils" "^1.2.0" + "@emotion/weak-memoize" "^0.3.0" + stylis "4.0.13" + +"@emotion/hash@^0.9.0": + version "0.9.0" + resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.0.tgz#c5153d50401ee3c027a57a177bc269b16d889cb7" + integrity sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ== + +"@emotion/is-prop-valid@^0.8.2": + version "0.8.8" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a" + integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA== + dependencies: + "@emotion/memoize" "0.7.4" + +"@emotion/is-prop-valid@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz#7f2d35c97891669f7e276eb71c83376a5dc44c83" + integrity sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg== + dependencies: + "@emotion/memoize" "^0.8.0" + +"@emotion/memoize@0.7.4": + version "0.7.4" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb" + integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw== + +"@emotion/memoize@^0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.0.tgz#f580f9beb67176fa57aae70b08ed510e1b18980f" + integrity sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA== + +"@emotion/react@^11.10.4": + version "11.10.4" + resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.10.4.tgz#9dc6bccbda5d70ff68fdb204746c0e8b13a79199" + integrity sha512-j0AkMpr6BL8gldJZ6XQsQ8DnS9TxEQu1R+OGmDZiWjBAJtCcbt0tS3I/YffoqHXxH6MjgI7KdMbYKw3MEiU9eA== + dependencies: + "@babel/runtime" "^7.18.3" + "@emotion/babel-plugin" "^11.10.0" + "@emotion/cache" "^11.10.0" + "@emotion/serialize" "^1.1.0" + "@emotion/use-insertion-effect-with-fallbacks" "^1.0.0" + "@emotion/utils" "^1.2.0" + "@emotion/weak-memoize" "^0.3.0" + hoist-non-react-statics "^3.3.1" + +"@emotion/serialize@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.0.tgz#b1f97b1011b09346a40e9796c37a3397b4ea8ea8" + integrity sha512-F1ZZZW51T/fx+wKbVlwsfchr5q97iW8brAnXmsskz4d0hVB4O3M/SiA3SaeH06x02lSNzkkQv+n3AX3kCXKSFA== + dependencies: + "@emotion/hash" "^0.9.0" + "@emotion/memoize" "^0.8.0" + "@emotion/unitless" "^0.8.0" + "@emotion/utils" "^1.2.0" + csstype "^3.0.2" + +"@emotion/sheet@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.0.tgz#771b1987855839e214fc1741bde43089397f7be5" + integrity sha512-OiTkRgpxescko+M51tZsMq7Puu/KP55wMT8BgpcXVG2hqXc0Vo0mfymJ/Uj24Hp0i083ji/o0aLddh08UEjq8w== + +"@emotion/styled@^11.10.4": + version "11.10.4" + resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.10.4.tgz#e93f84a4d54003c2acbde178c3f97b421fce1cd4" + integrity sha512-pRl4R8Ez3UXvOPfc2bzIoV8u9P97UedgHS4FPX594ntwEuAMA114wlaHvOK24HB48uqfXiGlYIZYCxVJ1R1ttQ== + dependencies: + "@babel/runtime" "^7.18.3" + "@emotion/babel-plugin" "^11.10.0" + "@emotion/is-prop-valid" "^1.2.0" + "@emotion/serialize" "^1.1.0" + "@emotion/use-insertion-effect-with-fallbacks" "^1.0.0" + "@emotion/utils" "^1.2.0" + +"@emotion/unitless@^0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.0.tgz#a4a36e9cbdc6903737cd20d38033241e1b8833db" + integrity sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw== + +"@emotion/use-insertion-effect-with-fallbacks@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz#ffadaec35dbb7885bd54de3fa267ab2f860294df" + integrity sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A== + +"@emotion/utils@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.2.0.tgz#9716eaccbc6b5ded2ea5a90d65562609aab0f561" + integrity sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw== + +"@emotion/weak-memoize@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz#ea89004119dc42db2e1dba0f97d553f7372f6fcb" + integrity sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg== + +"@esbuild/android-arm@0.15.11": + version "0.15.11" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.15.11.tgz#bdd9c3e098183bdca97075aa4c3e0152ed3e10ee" + integrity sha512-PzMcQLazLBkwDEkrNPi9AbjFt6+3I7HKbiYF2XtWQ7wItrHvEOeO3T8Am434zAozWtVP7lrTue1bEfc2nYWeCA== + +"@esbuild/linux-loong64@0.15.11": + version "0.15.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.15.11.tgz#2f4f9a1083dcb4fc65233b6f59003c406abf32e5" + integrity sha512-geWp637tUhNmhL3Xgy4Bj703yXB9dqiLJe05lCUfjSFDrQf9C/8pArusyPUbUbPwlC/EAUjBw32sxuIl/11dZw== + +"@eslint/eslintrc@^1.2.1": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.3.tgz#2b044ab39fdfa75b4688184f9e573ce3c5b0ff95" + integrity sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.4.0" + globals "^13.15.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + "@eslint/eslintrc@^1.2.3": version "1.2.3" resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.3.tgz" @@ -586,6 +1741,18 @@ jest-util "^27.5.1" slash "^3.0.0" +"@jest/console@^29.2.0": + version "29.2.0" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.2.0.tgz#e906bdbfc83baf79590f05b515dad900b3b71fed" + integrity sha512-Xz1Wu+ZZxcB3RS8U3HdkFxlRJ7kLXI/by9X7d2/gvseIWPwYu/c1EsYy77cB5iyyHGOy3whS2HycjcuzIF4Jow== + dependencies: + "@jest/types" "^29.2.0" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^29.2.0" + jest-util "^29.2.0" + slash "^3.0.0" + "@jest/core@^27.2.4": version "27.2.4" resolved "https://registry.npmjs.org/@jest/core/-/core-27.2.4.tgz" @@ -654,6 +1821,40 @@ slash "^3.0.0" strip-ansi "^6.0.0" +"@jest/core@^29.2.0": + version "29.2.0" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.2.0.tgz#beed57c552be65d4e4ab2f4161d0abe8ea6bf3a8" + integrity sha512-+gyJ3bX+kGEW/eqt/0kI7fLjqiFr3AN8O+rlEl1fYRf7D8h4Sj4tBGo9YOSirvWgvemoH2EPRya35bgvcPFzHQ== + dependencies: + "@jest/console" "^29.2.0" + "@jest/reporters" "^29.2.0" + "@jest/test-result" "^29.2.0" + "@jest/transform" "^29.2.0" + "@jest/types" "^29.2.0" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + ci-info "^3.2.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-changed-files "^29.2.0" + jest-config "^29.2.0" + jest-haste-map "^29.2.0" + jest-message-util "^29.2.0" + jest-regex-util "^29.2.0" + jest-resolve "^29.2.0" + jest-resolve-dependencies "^29.2.0" + jest-runner "^29.2.0" + jest-runtime "^29.2.0" + jest-snapshot "^29.2.0" + jest-util "^29.2.0" + jest-validate "^29.2.0" + jest-watcher "^29.2.0" + micromatch "^4.0.4" + pretty-format "^29.2.0" + slash "^3.0.0" + strip-ansi "^6.0.0" + "@jest/environment@^27.2.4": version "27.2.4" resolved "https://registry.npmjs.org/@jest/environment/-/environment-27.2.4.tgz" @@ -674,6 +1875,31 @@ "@types/node" "*" jest-mock "^27.5.1" +"@jest/environment@^29.2.0": + version "29.2.0" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.2.0.tgz#7e5604e4ead098572056a962a970f3d79379fbd8" + integrity sha512-foaVv1QVPB31Mno3LlL58PxEQQOLZd9zQfCpyQQCQIpUAtdFP1INBjkphxrCfKT13VxpA0z5jFGIkmZk0DAg2Q== + dependencies: + "@jest/fake-timers" "^29.2.0" + "@jest/types" "^29.2.0" + "@types/node" "*" + jest-mock "^29.2.0" + +"@jest/expect-utils@^29.2.0": + version "29.2.0" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.2.0.tgz#3c0c472115d98211e7e0a0a8fa00719bf081987f" + integrity sha512-nz2IDF7nb1qmj9hx8Ja3MFab2q9Ml8QbOaaeJNyX5JQJHU8QUvEDiMctmhGEkk3Kzr8w8vAqz4hPk/ogJSrUhg== + dependencies: + jest-get-type "^29.2.0" + +"@jest/expect@^29.2.0": + version "29.2.0" + resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.2.0.tgz#25316d2ae930e7bb9df96cce7521053d377c4c0d" + integrity sha512-+3lxcYL9e0xPJGOR33utxxejn+Mulz40kY0oy0FVsmIESW87NZDJ7B1ovaIqeX0xIgPX4laS5SGlqD2uSoBMcw== + dependencies: + expect "^29.2.0" + jest-snapshot "^29.2.0" + "@jest/fake-timers@^27.2.4": version "27.2.4" resolved "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.2.4.tgz" @@ -698,6 +1924,18 @@ jest-mock "^27.5.1" jest-util "^27.5.1" +"@jest/fake-timers@^29.2.0": + version "29.2.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.2.0.tgz#e43635c1bd73b23886e80ca12307092ef2ee1929" + integrity sha512-mX0V0uQsgeSLTt0yTqanAhhpeUKMGd2uq+PSLAfO40h72bvfNNQ7pIEl9vIwNMFxRih1ENveEjSBsLjxGGDPSw== + dependencies: + "@jest/types" "^29.2.0" + "@sinonjs/fake-timers" "^9.1.2" + "@types/node" "*" + jest-message-util "^29.2.0" + jest-mock "^29.2.0" + jest-util "^29.2.0" + "@jest/globals@^27.2.4": version "27.2.4" resolved "https://registry.npmjs.org/@jest/globals/-/globals-27.2.4.tgz" @@ -716,6 +1954,16 @@ "@jest/types" "^27.5.1" expect "^27.5.1" +"@jest/globals@^29.2.0": + version "29.2.0" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.2.0.tgz#5cfc41c028efaf511624ba086d64113d5a8a92b3" + integrity sha512-JQxtEVNWiai1p3PIzAJZSyEqQdAJGvNKvinZDPfu0mhiYEVx6E+PiBuDWj1sVUW8hzu+R3DVqaWC9K2xcLRIAA== + dependencies: + "@jest/environment" "^29.2.0" + "@jest/expect" "^29.2.0" + "@jest/types" "^29.2.0" + jest-mock "^29.2.0" + "@jest/reporters@^27.2.4": version "27.2.4" resolved "https://registry.npmjs.org/@jest/reporters/-/reporters-27.2.4.tgz" @@ -777,6 +2025,43 @@ terminal-link "^2.0.0" v8-to-istanbul "^8.1.0" +"@jest/reporters@^29.2.0": + version "29.2.0" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.2.0.tgz#24cac16d997ec91a9c615db2621805ee485689e0" + integrity sha512-BXoAJatxTZ18U0cwD7C8qBo8V6vef8AXYRBZdhqE5DF9CmpqmhMfw9c7OUvYqMTnBBK9A0NgXGO4Lc9EJzdHvw== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^29.2.0" + "@jest/test-result" "^29.2.0" + "@jest/transform" "^29.2.0" + "@jest/types" "^29.2.0" + "@jridgewell/trace-mapping" "^0.3.15" + "@types/node" "*" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^5.1.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.1.3" + jest-message-util "^29.2.0" + jest-util "^29.2.0" + jest-worker "^29.2.0" + slash "^3.0.0" + string-length "^4.0.1" + strip-ansi "^6.0.0" + v8-to-istanbul "^9.0.1" + +"@jest/schemas@^29.0.0": + version "29.0.0" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.0.0.tgz#5f47f5994dd4ef067fb7b4188ceac45f77fe952a" + integrity sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA== + dependencies: + "@sinclair/typebox" "^0.24.1" + "@jest/source-map@^27.0.6": version "27.0.6" resolved "https://registry.npmjs.org/@jest/source-map/-/source-map-27.0.6.tgz" @@ -795,6 +2080,15 @@ graceful-fs "^4.2.9" source-map "^0.6.0" +"@jest/source-map@^29.2.0": + version "29.2.0" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.2.0.tgz#ab3420c46d42508dcc3dc1c6deee0b613c235744" + integrity sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ== + dependencies: + "@jridgewell/trace-mapping" "^0.3.15" + callsites "^3.0.0" + graceful-fs "^4.2.9" + "@jest/test-result@^27.2.4": version "27.2.4" resolved "https://registry.npmjs.org/@jest/test-result/-/test-result-27.2.4.tgz" @@ -815,6 +2109,16 @@ "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" +"@jest/test-result@^29.2.0": + version "29.2.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.2.0.tgz#3dcc7123b8f0fb5ba1f650ce17af45cce91a0323" + integrity sha512-l76EPJ6QqtzsCLS4aimJqWO53pxZ82o3aE+Brcmo1HJ/phb9+MR7gPhyDdN6VSGaLJCRVJBZgWEhAEz+qON0Fw== + dependencies: + "@jest/console" "^29.2.0" + "@jest/types" "^29.2.0" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + "@jest/test-sequencer@^27.2.4": version "27.2.4" resolved "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.2.4.tgz" @@ -835,6 +2139,16 @@ jest-haste-map "^27.5.1" jest-runtime "^27.5.1" +"@jest/test-sequencer@^29.2.0": + version "29.2.0" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.2.0.tgz#acd875533f7ad01cb22da59ff4047de18e9d64da" + integrity sha512-NCnjZcGnVdva6IDqF7TCuFsXs2F1tohiNF9sasSJNzD7VfN5ic9XgcS/oPDalGiPLxCmGKj4kewqqrKAqBACcQ== + dependencies: + "@jest/test-result" "^29.2.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.2.0" + slash "^3.0.0" + "@jest/transform@^27.2.4": version "27.2.4" resolved "https://registry.npmjs.org/@jest/transform/-/transform-27.2.4.tgz" @@ -877,6 +2191,27 @@ source-map "^0.6.1" write-file-atomic "^3.0.0" +"@jest/transform@^29.2.0": + version "29.2.0" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.2.0.tgz#1c55ca549f64810351df999265a29f8ead51be15" + integrity sha512-NXMujGHy+B4DAj4dGnVPD0SIXlR2Z/N8Gp9h3mF66kcIRult1WWqY3/CEIrJcKviNWaFPYhZjCG2L3fteWzcUw== + dependencies: + "@babel/core" "^7.11.6" + "@jest/types" "^29.2.0" + "@jridgewell/trace-mapping" "^0.3.15" + babel-plugin-istanbul "^6.1.1" + chalk "^4.0.0" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.1.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.2.0" + jest-regex-util "^29.2.0" + jest-util "^29.2.0" + micromatch "^4.0.4" + pirates "^4.0.4" + slash "^3.0.0" + write-file-atomic "^4.0.1" + "@jest/types@^27.2.4": version "27.2.4" resolved "https://registry.npmjs.org/@jest/types/-/types-27.2.4.tgz" @@ -899,7 +2234,27 @@ "@types/yargs" "^16.0.0" chalk "^4.0.0" -"@jridgewell/gen-mapping@^0.3.0": +"@jest/types@^29.2.0": + version "29.2.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.2.0.tgz#c0d1ef8bc1e4f4b358e7877e34157371e7881b0b" + integrity sha512-mfgpQz4Z2xGo37m6KD8xEpKelaVzvYVRijmLPePn9pxgaPEtX+SqIyPNzzoeCPXKYbB4L/wYSgXDL8o3Gop78Q== + dependencies: + "@jest/schemas" "^29.0.0" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + +"@jridgewell/gen-mapping@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" + integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== + dependencies: + "@jridgewell/set-array" "^1.0.0" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": version "0.3.2" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== @@ -908,12 +2263,12 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/resolve-uri@^3.0.3": +"@jridgewell/resolve-uri@3.1.0", "@jridgewell/resolve-uri@^3.0.3": version "3.1.0" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== -"@jridgewell/set-array@^1.0.1": +"@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": version "1.1.2" resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== @@ -926,7 +2281,7 @@ "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/sourcemap-codec@^1.4.10": +"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": version "1.4.14" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== @@ -939,6 +2294,14 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.15": + version "0.3.17" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" + integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== + dependencies: + "@jridgewell/resolve-uri" "3.1.0" + "@jridgewell/sourcemap-codec" "1.4.14" + "@jridgewell/trace-mapping@^0.3.9": version "0.3.14" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz#b231a081d8f66796e475ad588a1ef473112701ed" @@ -1618,6 +2981,11 @@ npmlog "^4.1.2" write-file-atomic "^3.0.3" +"@mdn/browser-compat-data@4.1.12": + version "4.1.12" + resolved "https://registry.yarnpkg.com/@mdn/browser-compat-data/-/browser-compat-data-4.1.12.tgz#d266138c24295440619ea562ce3f4ec22600e897" + integrity sha512-y3Ntio6hb5+m6asxcA3nnIN6URjAFMji2EZZVYGd2Ag5On4mmvPhMnXdiIScCMXgHjFX+5qXuKaojLLhJHZPAg== + "@mdn/browser-compat-data@^3.3.14": version "3.3.14" resolved "https://registry.yarnpkg.com/@mdn/browser-compat-data/-/browser-compat-data-3.3.14.tgz#b72a37c654e598f9ae6f8335faaee182bebc6b28" @@ -1663,6 +3031,59 @@ semver-match "0.1.1" upath "^2.0.1" +"@motionone/animation@^10.13.1": + version "10.14.0" + resolved "https://registry.yarnpkg.com/@motionone/animation/-/animation-10.14.0.tgz#2f2a3517183bb58d82e389aac777fe0850079de6" + integrity sha512-h+1sdyBP8vbxEBW5gPFDnj+m2DCqdlAuf2g6Iafb1lcMnqjsRXWlPw1AXgvUMXmreyhqmPbJqoNfIKdytampRQ== + dependencies: + "@motionone/easing" "^10.14.0" + "@motionone/types" "^10.14.0" + "@motionone/utils" "^10.14.0" + tslib "^2.3.1" + +"@motionone/dom@10.13.1": + version "10.13.1" + resolved "https://registry.yarnpkg.com/@motionone/dom/-/dom-10.13.1.tgz#fc29ea5d12538f21b211b3168e502cfc07a24882" + integrity sha512-zjfX+AGMIt/fIqd/SL1Lj93S6AiJsEA3oc5M9VkUr+Gz+juRmYN1vfvZd6MvEkSqEjwPQgcjN7rGZHrDB9APfQ== + dependencies: + "@motionone/animation" "^10.13.1" + "@motionone/generators" "^10.13.1" + "@motionone/types" "^10.13.0" + "@motionone/utils" "^10.13.1" + hey-listen "^1.0.8" + tslib "^2.3.1" + +"@motionone/easing@^10.14.0": + version "10.14.0" + resolved "https://registry.yarnpkg.com/@motionone/easing/-/easing-10.14.0.tgz#d8154b7f71491414f3cdee23bd3838d763fffd00" + integrity sha512-2vUBdH9uWTlRbuErhcsMmt1jvMTTqvGmn9fHq8FleFDXBlHFs5jZzHJT9iw+4kR1h6a4SZQuCf72b9ji92qNYA== + dependencies: + "@motionone/utils" "^10.14.0" + tslib "^2.3.1" + +"@motionone/generators@^10.13.1": + version "10.14.0" + resolved "https://registry.yarnpkg.com/@motionone/generators/-/generators-10.14.0.tgz#e05d9dd56da78a4b92db99185848a0f3db62242d" + integrity sha512-6kRHezoFfIjFN7pPpaxmkdZXD36tQNcyJe3nwVqwJ+ZfC0e3rFmszR8kp9DEVFs9QL/akWjuGPSLBI1tvz+Vjg== + dependencies: + "@motionone/types" "^10.14.0" + "@motionone/utils" "^10.14.0" + tslib "^2.3.1" + +"@motionone/types@^10.13.0", "@motionone/types@^10.14.0": + version "10.14.0" + resolved "https://registry.yarnpkg.com/@motionone/types/-/types-10.14.0.tgz#148c34f3270b175397e49c3058b33fab405c21e3" + integrity sha512-3bNWyYBHtVd27KncnJLhksMFQ5o2MSdk1cA/IZqsHtA9DnRM1SYgN01CTcJ8Iw8pCXF5Ocp34tyAjY7WRpOJJQ== + +"@motionone/utils@^10.13.1", "@motionone/utils@^10.14.0": + version "10.14.0" + resolved "https://registry.yarnpkg.com/@motionone/utils/-/utils-10.14.0.tgz#a19a3464ed35b08506747b062d035c7bc9bbe708" + integrity sha512-sLWBLPzRqkxmOTRzSaD3LFQXCPHvDzyHJ1a3VP9PRzBxyVd2pv51/gMOsdAcxQ9n+MIeGJnxzXBYplUHKj4jkw== + dependencies: + "@motionone/types" "^10.14.0" + hey-listen "^1.0.8" + tslib "^2.3.1" + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" @@ -1853,6 +3274,16 @@ resolved "https://registry.npmjs.org/@polka/url/-/url-0.5.0.tgz" integrity sha512-oZLYFEAzUKyi3SKnXvj32ZCEGH6RDnao7COuCVhDydMS9NrCSVXhM79VaKyP5+Zc33m0QXEd2DN3UkU7OsHcfw== +"@popperjs/core@^2.9.3": + version "2.11.6" + resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.6.tgz#cee20bd55e68a1720bdab363ecf0c821ded4cd45" + integrity sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw== + +"@remix-run/router@1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.0.2.tgz#1c17eadb2fa77f80a796ad5ea9bf108e6993ef06" + integrity sha512-GRSOFhJzjGN+d4sKHTMSvNeUPoZiDHWmRnXfzaxrqe7dE/Nzlc8BiMSJdLDESZlndM7jIUrZ/F4yWqVYlI0rwQ== + "@rollup/plugin-commonjs@^20.0.0": version "20.0.0" resolved "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-20.0.0.tgz" @@ -1936,6 +3367,16 @@ estree-walker "^2.0.1" picomatch "^2.2.2" +"@sinclair/typebox@^0.24.1": + version "0.24.46" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.46.tgz#57501b58023776dbbae9e25619146286440be34c" + integrity sha512-ng4ut1z2MCBhK/NwDVwIQp3pAUOCs/KNaW3cBxdFB2xTDrOuo1xuNmpr/9HHFhxqIvHrs1NTH3KJg6q+JSy1Kw== + +"@sindresorhus/is@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" + integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== + "@sinonjs/commons@^1.7.0": version "1.8.3" resolved "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz" @@ -1950,6 +3391,20 @@ dependencies: "@sinonjs/commons" "^1.7.0" +"@sinonjs/fake-timers@^9.1.2": + version "9.1.2" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz#4eaab737fab77332ab132d396a3c0d364bd0ea8c" + integrity sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw== + dependencies: + "@sinonjs/commons" "^1.7.0" + +"@szmarczak/http-timer@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" + integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== + dependencies: + defer-to-connect "^1.0.1" + "@tootallnate/once@1": version "1.1.2" resolved "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz" @@ -2055,7 +3510,7 @@ resolved "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz" integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== -"@types/graceful-fs@^4.1.2": +"@types/graceful-fs@^4.1.2", "@types/graceful-fs@^4.1.3": version "4.1.5" resolved "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz" integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== @@ -2128,6 +3583,18 @@ resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz" integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== +"@types/lodash.mergewith@4.6.6": + version "4.6.6" + resolved "https://registry.yarnpkg.com/@types/lodash.mergewith/-/lodash.mergewith-4.6.6.tgz#c4698f5b214a433ff35cb2c75ee6ec7f99d79f10" + integrity sha512-RY/8IaVENjG19rxTZu9Nukqh0W2UrYgmBj5sdns4hWRZaV8PqR7wIKHFKzvOTjo4zVRV7sVI+yFhAJql12Kfqg== + dependencies: + "@types/lodash" "*" + +"@types/lodash@*": + version "4.14.186" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.186.tgz#862e5514dd7bd66ada6c70ee5fce844b06c8ee97" + integrity sha512-eHcVlLXP0c2FlMPm56ITode2AgLMSa6aJ05JTTbYbI+7EMkCEE5qk2E41d5g2lCVTqRe0GnnRFurmlCsDODrPw== + "@types/minimatch@^3.0.3": version "3.0.5" resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz" @@ -2190,6 +3657,11 @@ resolved "https://registry.npmjs.org/@types/prettier/-/prettier-2.3.2.tgz" integrity sha512-eI5Yrz3Qv4KPUa/nSIAi0h+qX0XyewOliug5F2QAtuRg6Kjg6jfmxe1GIwoIRhZspD1A0RP8ANrPwvEXXtRFog== +"@types/prop-types@*": + version "15.7.5" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" + integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== + "@types/pug@^2.0.4": version "2.0.5" resolved "https://registry.npmjs.org/@types/pug/-/pug-2.0.5.tgz" @@ -2214,6 +3686,22 @@ resolved "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz" integrity sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ== +"@types/react-dom@^18.0.6": + version "18.0.6" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.6.tgz#36652900024842b74607a17786b6662dd1e103a1" + integrity sha512-/5OFZgfIPSwy+YuIBP/FgJnQnsxhZhjjrnxudMddeblOouIodEQ75X14Rr4wGSG/bknL+Omy9iWlLo1u/9GzAA== + dependencies: + "@types/react" "*" + +"@types/react@*": + version "18.0.21" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.21.tgz#b8209e9626bb00a34c76f55482697edd2b43cc67" + integrity sha512-7QUCOxvFgnD5Jk8ZKlUAhVcRj7GuJRjnjjiY/IUBWKgOlnvDvTMLD4RTF7NPyVmbRhNrbomZiOepg7M/2Kj1mA== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + "@types/resolve@1.17.1": version "1.17.1" resolved "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz" @@ -2228,6 +3716,11 @@ dependencies: "@types/node" "*" +"@types/scheduler@*": + version "0.16.2" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" + integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== + "@types/stack-utils@^2.0.0": version "2.0.1" resolved "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz" @@ -2245,6 +3738,11 @@ resolved "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.1.tgz" integrity sha512-Y0K95ThC3esLEYD6ZuqNek29lNX2EM1qxV8y2FTLUB0ff5wWrk7az+mLrnNFUnaXcgKye22+sFBRXOgpPILZNg== +"@types/webextension-polyfill@^0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@types/webextension-polyfill/-/webextension-polyfill-0.9.1.tgz#fcb5c352e2e461d0287774db89bc326b15b47844" + integrity sha512-6aNzPIhqKlAV9t06nwSH3/veAceYE2dS2RVFZI8V1+UXHqsFNB6cRwxNmheiBvEGRc45E/gyZNzH0xAYIC27KA== + "@types/yargs-parser@*": version "20.2.1" resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz" @@ -2257,7 +3755,14 @@ dependencies: "@types/yargs-parser" "*" -"@types/yauzl@^2.9.1": +"@types/yargs@^17.0.8": + version "17.0.13" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.13.tgz#34cced675ca1b1d51fcf4d34c3c6f0fa142a5c76" + integrity sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg== + dependencies: + "@types/yargs-parser" "*" + +"@types/yauzl@2.9.2", "@types/yauzl@^2.9.1": version "2.9.2" resolved "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz" integrity sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA== @@ -2470,6 +3975,19 @@ "@typescript-eslint/types" "5.30.4" eslint-visitor-keys "^3.3.0" +"@vitejs/plugin-react@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-2.1.0.tgz#4c99df15e71d2630601bd3018093bdc787d40e55" + integrity sha512-am6rPyyU3LzUYne3Gd9oj9c4Rzbq5hQnuGXSMT6Gujq45Il/+bunwq3lrB7wghLkiF45ygMwft37vgJ/NE8IAA== + dependencies: + "@babel/core" "^7.18.13" + "@babel/plugin-transform-react-jsx" "^7.18.10" + "@babel/plugin-transform-react-jsx-development" "^7.18.6" + "@babel/plugin-transform-react-jsx-self" "^7.18.6" + "@babel/plugin-transform-react-jsx-source" "^7.18.6" + magic-string "^0.26.2" + react-refresh "^0.14.0" + "@xstate/fsm@^1.4.0": version "1.6.1" resolved "https://registry.npmjs.org/@xstate/fsm/-/fsm-1.6.1.tgz" @@ -2484,6 +4002,16 @@ tslib "^2.3.1" upath2 "^3.1.12" +"@zag-js/element-size@0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@zag-js/element-size/-/element-size-0.1.0.tgz#dfdb3f66a70328d0c3149aae29b8f99c10590c22" + integrity sha512-QF8wp0+V8++z+FHXiIw93+zudtubYszOtYbNgK39fg3pi+nCZtuSm4L1jC5QZMatNZ83MfOzyNCfgUubapagJQ== + +"@zag-js/focus-visible@0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@zag-js/focus-visible/-/focus-visible-0.1.0.tgz#9777bbaff8316d0b3a14a9095631e1494f69dbc7" + integrity sha512-PeaBcTmdZWcFf7n1aM+oiOdZc+sy14qi0emPIeUuGMTjbP0xLGrZu43kdpHnWSXy7/r4Ubp/vlg50MCV8+9Isg== + JSONStream@^1.0.4: version "1.3.5" resolved "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz" @@ -2518,7 +4046,7 @@ acorn-globals@^6.0.0: acorn "^7.1.1" acorn-walk "^7.1.1" -acorn-jsx@^5.3.2: +acorn-jsx@^5.3.1, acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== @@ -2543,10 +4071,74 @@ acorn@^8.2.4, acorn@^8.4.1, acorn@^8.5.0, acorn@^8.7.1: resolved "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz" integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A== -add-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz" - integrity sha1-anmQQ3ynNtXhKI25K9MmbV9csqo= +acorn@^8.7.0, acorn@^8.8.0: + version "8.8.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" + integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== + +add-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz" + integrity sha1-anmQQ3ynNtXhKI25K9MmbV9csqo= + +addons-linter@4.14.0: + version "4.14.0" + resolved "https://registry.yarnpkg.com/addons-linter/-/addons-linter-4.14.0.tgz#e8a5b99665a7e7df3fda2da42d73593fea8db3f9" + integrity sha512-TH3/PMS4Dd0Jf3kXW7DLXseHZcD7ZbnfnQAztkrP4YC0HQKQVZJ+lGOuDOGUtVQDMwC/eEdvHvZoRnHDer5qkg== + dependencies: + "@mdn/browser-compat-data" "4.1.12" + addons-moz-compare "1.2.0" + addons-scanner-utils "6.3.0" + ajv "6.12.6" + ajv-merge-patch "4.1.0" + chalk "4.1.2" + cheerio "1.0.0-rc.10" + columnify "1.6.0" + common-tags "1.8.2" + deepmerge "4.2.2" + eslint "8.11.0" + eslint-plugin-no-unsanitized "4.0.1" + eslint-visitor-keys "3.3.0" + espree "9.3.1" + esprima "4.0.1" + fluent-syntax "0.13.0" + glob "7.2.0" + image-size "1.0.1" + is-mergeable-object "1.1.1" + jed "1.1.1" + os-locale "5.0.0" + pino "7.9.1" + postcss "8.4.12" + relaxed-json "1.0.3" + semver "7.3.5" + sha.js "2.4.11" + source-map-support "0.5.21" + tosource "1.0.0" + upath "2.0.1" + yargs "17.4.0" + yauzl "2.10.0" + +addons-moz-compare@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/addons-moz-compare/-/addons-moz-compare-1.2.0.tgz#d6246cbae224ab629cb7da397b2b9602938ea085" + integrity sha512-COG8qk2/dubPqabfcoJW4E7pm2EQDI43iMrHnhlobvq/uRMEzx/PYJ1KaUZ97Vgg44R3QdRG5CvDsTRbMUHcDw== + +addons-scanner-utils@6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/addons-scanner-utils/-/addons-scanner-utils-6.3.0.tgz#99596585a1e5d50f543e4f765cb3549bcf9d48db" + integrity sha512-sD4U7TX/NFDUYVheydrcpHH9xG3E0eVBFDn1RuUkGpqRyay3SsOU75Pl2lWAbCmeE0Mh9inU1Fwl7Mm1VRWkZw== + dependencies: + "@types/yauzl" "2.9.2" + common-tags "1.8.2" + first-chunk-stream "3.0.0" + strip-bom-stream "4.0.0" + upath "2.0.1" + yauzl "2.10.0" + +adm-zip@~0.5.x: + version "0.5.9" + resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.5.9.tgz#b33691028333821c0cf95c31374c5462f2905a83" + integrity sha512-s+3fXLkeeLjZ2kLjCBwQufpI5fuN+kIGBxu6530nVQZGVol0d7Y/M88/xw9HGGUcJjKf8LutN3VPRUBq6N7Ajg== agent-base@6, agent-base@^6.0.2: version "6.0.2" @@ -2579,7 +4171,15 @@ aggregate-error@^3.0.0: clean-stack "^2.0.0" indent-string "^4.0.0" -ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4, ajv@~6.12.6: +ajv-merge-patch@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ajv-merge-patch/-/ajv-merge-patch-4.1.0.tgz#cd580e5860ac53431d6aa901fa3d5e2eb2b74a6c" + integrity sha512-0mAYXMSauA8RZ7r+B4+EAOYcZEcO9OK5EiQCR7W7Cv4E44pJj56ZnkKLJ9/PAcOc0dT+LlV9fdDcq2TxVJfOYw== + dependencies: + fast-json-patch "^2.0.6" + json-merge-patch "^0.2.3" + +ajv@6.12.6, ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4, ajv@~6.12.6: version "6.12.6" resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -2589,11 +4189,28 @@ ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4, ajv@~6.12.6: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@^8.8.1: + version "8.11.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f" + integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + alphanum-sort@^1.0.0: version "1.0.2" resolved "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz" integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= +ansi-align@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" + integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w== + dependencies: + string-width "^4.1.0" + ansi-escapes@^4.2.1: version "4.3.2" resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz" @@ -2657,6 +4274,11 @@ ansi-styles@^6.1.0: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.1.0.tgz#87313c102b8118abd57371afab34618bf7350ed3" integrity sha512-VbqNsoz55SYGczauuup0MFUyXNQviSpFTj1RQtFzmQLk18qbVSpTFFGMT293rmDaQuKCT6InmbuEyUne4mTuxQ== +any-promise@^1.0.0, any-promise@^1.1.0, any-promise@~1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== + anymatch@^3.0.3, anymatch@~3.1.2: version "3.1.2" resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz" @@ -2700,6 +4322,13 @@ argparse@^2.0.1: resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== +aria-hidden@^1.1.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/aria-hidden/-/aria-hidden-1.2.1.tgz#ad8c1edbde360b454eb2bf717ea02da00bfee0f8" + integrity sha512-PN344VAf9j1EAi+jyVHOJ8XidQdPVssGco39eNcsGdM4wcsILtxrKLkbuiMfLWYROK1FjRQasMWCBttrhjnr6A== + dependencies: + tslib "^2.0.0" + arr-diff@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz" @@ -2788,6 +4417,16 @@ async-limiter@~1.0.0: resolved "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz" integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== +async@^3.2.0: + version "3.2.4" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" + integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== + +async@~0.2.9: + version "0.2.10" + resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" + integrity sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ== + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" @@ -2798,6 +4437,11 @@ at-least-node@^1.0.0: resolved "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz" integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== +atomic-sleep@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b" + integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ== + aws-sign2@~0.7.0: version "0.7.0" resolved "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz" @@ -2836,6 +4480,19 @@ babel-jest@^27.5.1: graceful-fs "^4.2.9" slash "^3.0.0" +babel-jest@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.2.0.tgz#088624f037da90e69a06073305276cbd111d68a8" + integrity sha512-c8FkrW1chgcbyBqOo7jFGpQYfVnb43JqjQGV+C2r94k2rZJOukYOZ6+csAqKE4ms+PHc+yevnONxs27jQIxylw== + dependencies: + "@jest/transform" "^29.2.0" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^29.2.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + slash "^3.0.0" + babel-plugin-istanbul@^6.0.0: version "6.0.0" resolved "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz" @@ -2878,6 +4535,25 @@ babel-plugin-jest-hoist@^27.5.1: "@types/babel__core" "^7.0.0" "@types/babel__traverse" "^7.0.6" +babel-plugin-jest-hoist@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.2.0.tgz#23ee99c37390a98cfddf3ef4a78674180d823094" + integrity sha512-TnspP2WNiR3GLfCsUNHqeXw0RoQ2f9U5hQ5L3XFpwuO8htQmSrhh8qsB6vi5Yi8+kuynN1yjDjQsPfkebmB6ZA== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.1.14" + "@types/babel__traverse" "^7.0.6" + +babel-plugin-macros@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz#9ef6dc74deb934b4db344dc973ee851d148c50c1" + integrity sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg== + dependencies: + "@babel/runtime" "^7.12.5" + cosmiconfig "^7.0.0" + resolve "^1.19.0" + babel-preset-current-node-syntax@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz" @@ -2912,6 +4588,14 @@ babel-preset-jest@^27.5.1: babel-plugin-jest-hoist "^27.5.1" babel-preset-current-node-syntax "^1.0.0" +babel-preset-jest@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.2.0.tgz#3048bea3a1af222e3505e4a767a974c95a7620dc" + integrity sha512-z9JmMJppMxNv8N7fNRHvhMg9cvIkMxQBXgFkane3yKVEvEOP+kB50lk8DFRvF9PGqbyXxlmebKWhuDORO8RgdA== + dependencies: + babel-plugin-jest-hoist "^29.2.0" + babel-preset-current-node-syntax "^1.0.0" + babel-runtime@^6.26.0: version "6.26.0" resolved "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz" @@ -2990,6 +4674,11 @@ bluebird@^3.5.2: resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== +bluebird@~2.9.24: + version "2.9.34" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.9.34.tgz#2f7b4ec80216328a9fddebdf69c8d4942feff7d8" + integrity sha512-ZDzCb87X7/IP1uzQ5eJZB+WoQRGTnKL5DHWvPw6kkMbQseouiQIrEi3P1UGE0D1k0N5/+aP/5GMCyHZ1xYJyHQ== + body-parser@1.19.0: version "1.19.0" resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz" @@ -3011,6 +4700,20 @@ boolbase@^1.0.0, boolbase@~1.0.0: resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz" integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= +boxen@^5.0.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" + integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ== + dependencies: + ansi-align "^3.0.0" + camelcase "^6.2.0" + chalk "^4.1.0" + cli-boxes "^2.2.1" + string-width "^4.2.2" + type-fest "^0.20.2" + widest-line "^3.1.0" + wrap-ansi "^7.0.0" + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" @@ -3069,7 +4772,7 @@ browserslist@^4.16.6: node-releases "^1.1.77" picocolors "^0.2.1" -browserslist@^4.16.8, browserslist@^4.21.4: +browserslist@^4.16.8, browserslist@^4.21.3, browserslist@^4.21.4: version "4.21.4" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== @@ -3109,6 +4812,11 @@ buffer-crc32@~0.2.3: resolved "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz" integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= +buffer-equal-constant-time@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" + integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA== + buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" @@ -3145,6 +4853,16 @@ builtins@^1.0.3: resolved "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz" integrity sha1-y5T662HIaWRR2zZTThQi+U8K7og= +bunyan@1.8.15: + version "1.8.15" + resolved "https://registry.yarnpkg.com/bunyan/-/bunyan-1.8.15.tgz#8ce34ca908a17d0776576ca1b2f6cbd916e93b46" + integrity sha512-0tECWShh6wUysgucJcBAoYegf3JJoZWibxdqhTm7OHPeT42qdjkZ29QCMcKwbgU1kiH+auSIasNRXMLWXafXig== + optionalDependencies: + dtrace-provider "~0.8" + moment "^2.19.3" + mv "~2" + safe-json-stringify "~1" + byline@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/byline/-/byline-5.0.0.tgz" @@ -3183,6 +4901,19 @@ cacache@^15.0.5, cacache@^15.2.0: tar "^6.0.2" unique-filename "^1.1.1" +cacheable-request@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" + integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^3.0.0" + lowercase-keys "^2.0.0" + normalize-url "^4.1.0" + responselike "^1.0.2" + call-bind@^1.0.0, call-bind@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz" @@ -3224,16 +4955,16 @@ camelcase-keys@^6.2.2: map-obj "^4.0.0" quick-lru "^4.0.1" +camelcase@6.2.0, camelcase@^6.2.0: + version "6.2.0" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz" + integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== + camelcase@^5.0.0, camelcase@^5.3.1: version "5.3.1" resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -camelcase@^6.2.0: - version "6.2.0" - resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz" - integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== - caniuse-api@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz" @@ -3254,6 +4985,14 @@ caseless@~0.12.0: resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= +chalk@4.1.2, chalk@^4.1.0: + version "4.1.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + chalk@^1.1.3: version "1.1.3" resolved "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz" @@ -3265,7 +5004,7 @@ chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.4.1: +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -3282,14 +5021,6 @@ chalk@^4.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^4.1.0: - version "4.1.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - chalk@^5.0.0, chalk@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.0.1.tgz#ca57d71e82bb534a296df63bbacc4a1c22b2a4b6" @@ -3305,6 +5036,11 @@ chardet@^0.7.0: resolved "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== +charenc@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" + integrity sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA== + cheerio-select@^1.5.0: version "1.5.0" resolved "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.5.0.tgz" @@ -3316,7 +5052,7 @@ cheerio-select@^1.5.0: domhandler "^4.2.0" domutils "^2.7.0" -cheerio@^1.0.0-rc.3: +cheerio@1.0.0-rc.10, cheerio@^1.0.0-rc.3: version "1.0.0-rc.10" resolved "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz" integrity sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw== @@ -3354,6 +5090,16 @@ chownr@^2.0.0: resolved "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz" integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== +chrome-launcher@0.15.0: + version "0.15.0" + resolved "https://registry.yarnpkg.com/chrome-launcher/-/chrome-launcher-0.15.0.tgz#5144a57aba0cf2f4cbe61dccefdde024fb3ca7fc" + integrity sha512-ZQqX5kb9H0+jy1OqLnWampfocrtSZaGl7Ny3F9GRha85o4odbL8x55paUzh51UC7cEmZ5obp3H2Mm70uC2PpRA== + dependencies: + "@types/node" "*" + escape-string-regexp "^4.0.0" + is-wsl "^2.2.0" + lighthouse-logger "^1.0.0" + ci-info@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz" @@ -3379,6 +5125,11 @@ clean-stack@^2.0.0: resolved "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz" integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== +cli-boxes@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" + integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== + cli-cursor@^3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz" @@ -3417,6 +5168,15 @@ cliui@^7.0.2: strip-ansi "^6.0.0" wrap-ansi "^7.0.0" +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" + clone-deep@^4.0.1: version "4.0.1" resolved "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz" @@ -3426,6 +5186,13 @@ clone-deep@^4.0.1: kind-of "^6.0.2" shallow-clone "^3.0.0" +clone-response@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.3.tgz#af2032aa47816399cf5f0a1d0db902f517abb8c3" + integrity sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA== + dependencies: + mimic-response "^1.0.0" + clone@^1.0.2: version "1.0.4" resolved "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz" @@ -3507,6 +5274,14 @@ colorette@^1.2.2: resolved "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz" integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== +columnify@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.6.0.tgz#6989531713c9008bb29735e61e37acf5bd553cf3" + integrity sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q== + dependencies: + strip-ansi "^6.0.1" + wcwidth "^1.0.0" + columnify@^1.5.4: version "1.5.4" resolved "https://registry.npmjs.org/columnify/-/columnify-1.5.4.tgz" @@ -3522,7 +5297,14 @@ combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -commander@^2.20.0: +commander@2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" + integrity sha512-bmkUukX8wAOjHdN26xj5c4ctEV22TQ7dQYhSmuckKhToXrkUn0iIaolHdIxYYqD55nhpSPA9zPQ1yP57GdXP2A== + dependencies: + graceful-readlink ">= 1.0.0" + +commander@^2.20.0, commander@^2.3.0, commander@^2.6.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== @@ -3542,6 +5324,11 @@ comment-json@^3.0.3: has-own-prop "^2.0.0" repeat-string "^1.6.1" +common-tags@1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.2.tgz#94ebb3c076d26032745fd54face7f688ef5ac9c6" + integrity sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA== + commondir@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz" @@ -3560,12 +5347,17 @@ compare-versions@^4.1.3: resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-4.1.3.tgz#8f7b8966aef7dc4282b45dfa6be98434fc18a1a4" integrity sha512-WQfnbDcrYnGr55UwbxKiQKASnTtNnaAWVi8jZyy8NTpVAXWACSne8lMD1iaIo9AiU6mnuLvSVshCzewVuWxHUg== +compute-scroll-into-view@1.0.14: + version "1.0.14" + resolved "https://registry.yarnpkg.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.14.tgz#80e3ebb25d6aa89f42e533956cb4b16a04cfe759" + integrity sha512-mKDjINe3tc6hGelUMNDzuhorIUZ7kS7BwyY0r2wQd2HOH2tRuJykiC06iSEX8y1TuhNzvz4GcJnK16mM2J1NMQ== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -concat-stream@^1.6.2: +concat-stream@^1.4.7, concat-stream@^1.6.2: version "1.6.2" resolved "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz" integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== @@ -3614,6 +5406,18 @@ config-chain@^1.1.12: ini "^1.3.4" proto-list "~1.2.1" +configstore@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96" + integrity sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA== + dependencies: + dot-prop "^5.2.0" + graceful-fs "^4.1.2" + make-dir "^3.0.0" + unique-string "^2.0.0" + write-file-atomic "^3.0.0" + xdg-basedir "^4.0.0" + console-clear@^1.1.0: version "1.1.1" resolved "https://registry.npmjs.org/console-clear/-/console-clear-1.1.1.tgz" @@ -3731,6 +5535,11 @@ convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: dependencies: safe-buffer "~5.1.1" +convert-source-map@^1.5.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" + integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== + cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz" @@ -3741,6 +5550,18 @@ cookie@0.4.0: resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz" integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== +copy-to-clipboard@3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz#115aa1a9998ffab6196f93076ad6da3b913662ae" + integrity sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw== + dependencies: + toggle-selection "^1.0.6" + +core-js@3.21.0: + version "3.21.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.21.0.tgz#f479dbfc3dffb035a0827602dd056839a774aa71" + integrity sha512-YUdI3fFu4TF/2WykQ2xzSiTQdldLB4KVuL9WeAy5XONZYt5Cun/fpQvctoKbCgvPhmzADeesTk/j2Rdx77AcKQ== + core-js@^2.4.0: version "2.6.12" resolved "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz" @@ -3794,6 +5615,13 @@ cross-env@^5.2.0: dependencies: cross-spawn "^6.0.5" +cross-env@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" + integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== + dependencies: + cross-spawn "^7.0.1" + cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz" @@ -3805,7 +5633,7 @@ cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^7.0.2, cross-spawn@^7.0.3: +cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -3814,6 +5642,23 @@ cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" +crypt@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" + integrity sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow== + +crypto-random-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" + integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== + +css-box-model@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/css-box-model/-/css-box-model-1.2.1.tgz#59951d3b81fd6b2074a62d49444415b0d2b4d7c1" + integrity sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw== + dependencies: + tiny-invariant "^1.0.6" + css-color-names@0.0.4, css-color-names@^0.0.4: version "0.0.4" resolved "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz" @@ -4000,6 +5845,11 @@ cssstyle@^2.3.0: dependencies: cssom "~0.3.6" +csstype@^3.0.11, csstype@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.1.tgz#841b532c45c758ee546a11d5bd7b7b473c8c30b9" + integrity sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw== + dargs@^7.0.0: version "7.0.0" resolved "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz" @@ -4031,7 +5881,12 @@ dateformat@^3.0.0: resolved "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz" integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== -debug@2.6.9, debug@^2.6.9: +debounce@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.0.tgz#44a540abc0ea9943018dc0eaa95cce87f65cd131" + integrity sha512-mYtLl1xfZLi1m4RtQYlZgJUNQjl4ZxVnHzIR8nLLgi4q1YT8o/WM+MK/f8yfcc9s5Ir5zRaPZyZU6xs1Syoocg== + +debug@2.6.9, debug@^2.6.9, debug@~2.6.3: version "2.6.9" resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== @@ -4072,6 +5927,11 @@ decamelize-keys@^1.1.0: decamelize "^1.1.0" map-obj "^1.0.0" +decamelize@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-5.0.0.tgz#88358157b010ef133febfd27c18994bd80c6215b" + integrity sha512-U75DcT5hrio3KNtvdULAWnLiAPbFUC4191ldxMmj4FA/mRuBnmDwU0boNfPyFRhnan+Jm+haLeSn3P0afcBn4w== + decamelize@^1.1.0, decamelize@^1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz" @@ -4087,11 +5947,30 @@ decode-uri-component@^0.2.0: resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" integrity sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og== +decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA== + dependencies: + mimic-response "^1.0.0" + dedent@^0.7.0: version "0.7.0" resolved "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz" integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= +deep-equal@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" + integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== + dependencies: + is-arguments "^1.0.4" + is-date-object "^1.0.1" + is-regex "^1.0.4" + object-is "^1.0.1" + object-keys "^1.1.1" + regexp.prototype.flags "^1.2.0" + deep-extend@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" @@ -4102,7 +5981,14 @@ deep-is@^0.1.3, deep-is@~0.1.3: resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= -deepmerge@^4.2.2: +deepcopy@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/deepcopy/-/deepcopy-2.1.0.tgz#2deb0dd52d079c2ecb7924b640a7c3abd4db1d6d" + integrity sha512-8cZeTb1ZKC3bdSCP6XOM1IsTczIO73fdqtwa2B0N15eAz7gmyhQo+mc5gnFuulsgN3vIQYmTgbmQVKalH1dKvQ== + dependencies: + type-detect "^4.0.8" + +deepmerge@4.2.2, deepmerge@^4.2.2: version "4.2.2" resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz" integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== @@ -4114,6 +6000,11 @@ defaults@^1.0.3: dependencies: clone "^1.0.2" +defer-to-connect@^1.0.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" + integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== + define-properties@^1.1.3: version "1.1.3" resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz" @@ -4161,6 +6052,11 @@ detect-newline@^3.0.0: resolved "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== +detect-node-es@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/detect-node-es/-/detect-node-es-1.1.0.tgz#163acdf643330caa0b4cd7c21e7ee7755d6fa493" + integrity sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ== + devtools-protocol@0.0.869402: version "0.0.869402" resolved "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.869402.tgz" @@ -4184,6 +6080,11 @@ diff-sequences@^27.5.1: resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz" integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ== +diff-sequences@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.2.0.tgz#4c55b5b40706c7b5d2c5c75999a50c56d214e8f6" + integrity sha512-413SY5JpYeSBZxmenGEmCVQ8mCgtFJF0w9PROdaS6z987XC2Pd2GOKqOITLtMftmyFZqgtCOb/QA7/Z3ZXfzIw== + diff@^3.1.0, diff@^3.2.0: version "3.5.0" resolved "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz" @@ -4280,11 +6181,33 @@ dot-prop@^6.0.1: dependencies: is-obj "^2.0.0" +dtrace-provider@~0.8: + version "0.8.8" + resolved "https://registry.yarnpkg.com/dtrace-provider/-/dtrace-provider-0.8.8.tgz#2996d5490c37e1347be263b423ed7b297fb0d97e" + integrity sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg== + dependencies: + nan "^2.14.0" + +duplexer3@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.5.tgz#0b5e4d7bad5de8901ea4440624c8e1d20099217e" + integrity sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA== + duplexer@^0.1.1: version "0.1.2" resolved "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz" integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== +duplexify@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-4.1.2.tgz#18b4f8d28289132fa0b9573c898d9f903f81c7b0" + integrity sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw== + dependencies: + end-of-stream "^1.4.1" + inherits "^2.0.3" + readable-stream "^3.1.1" + stream-shift "^1.0.0" + eastasianwidth@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" @@ -4298,6 +6221,13 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" +ecdsa-sig-formatter@1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" + integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== + dependencies: + safe-buffer "^5.0.1" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" @@ -4323,6 +6253,11 @@ electron-to-chromium@^1.4.251: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.254.tgz#c6203583890abf88dfc0be046cd72d3b48f8beb6" integrity sha512-Sh/7YsHqQYkA6ZHuHMy24e6TE4eX6KZVsZb9E/DvU1nQRIrH4BflO/4k+83tfdYvDl+MObvlqHPRICzEdC9c6Q== +emittery@^0.10.2: + version "0.10.2" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.10.2.tgz#902eec8aedb8c41938c46e9385e9db7e03182933" + integrity sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw== + emittery@^0.8.1: version "0.8.1" resolved "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz" @@ -4355,7 +6290,7 @@ encoding@^0.1.12: dependencies: iconv-lite "^0.6.2" -end-of-stream@^1.1.0, end-of-stream@^1.4.1: +end-of-stream@^1.1.0, end-of-stream@^1.4.1, end-of-stream@~1.4.1: version "1.4.4" resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== @@ -4461,11 +6396,21 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +es6-error@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" + integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== + es6-promise@^4.0.3: version "4.2.8" resolved "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz" integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== +es6-promisify@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-7.0.0.tgz#9a710008dd6a4ab75a89e280bad787bfb749927b" + integrity sha512-ginqzK3J90Rd4/Yz7qRrqUeIpe3TwSXTPPZtPne7tGBPeAaQiU8qt4fpKApnxHcq1AwtUdHVg5P77x/yrggG8Q== + es6-promisify@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz" @@ -4478,101 +6423,201 @@ esbuild-android-64@0.14.38: resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.14.38.tgz#5b94a1306df31d55055f64a62ff6b763a47b7f64" integrity sha512-aRFxR3scRKkbmNuGAK+Gee3+yFxkTJO/cx83Dkyzo4CnQl/2zVSurtG6+G86EQIZ+w+VYngVyK7P3HyTBKu3nw== +esbuild-android-64@0.15.11: + version "0.15.11" + resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.15.11.tgz#50402129c3e85bb06434e212374c5f693e4c5f01" + integrity sha512-rrwoXEiuI1kaw4k475NJpexs8GfJqQUKcD08VR8sKHmuW9RUuTR2VxcupVvHdiGh9ihxL9m3lpqB1kju92Ialw== + esbuild-android-arm64@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.38.tgz#78acc80773d16007de5219ccce544c036abd50b8" integrity sha512-L2NgQRWuHFI89IIZIlpAcINy9FvBk6xFVZ7xGdOwIm8VyhX1vNCEqUJO3DPSSy945Gzdg98cxtNt8Grv1CsyhA== +esbuild-android-arm64@0.15.11: + version "0.15.11" + resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.15.11.tgz#49bee35218ea2ccf1a0c5f187af77c1c0a5dee71" + integrity sha512-/hDubOg7BHOhUUsT8KUIU7GfZm5bihqssvqK5PfO4apag7YuObZRZSzViyEKcFn2tPeHx7RKbSBXvAopSHDZJQ== + esbuild-darwin-64@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.38.tgz#e02b1291f629ebdc2aa46fabfacc9aa28ff6aa46" integrity sha512-5JJvgXkX87Pd1Og0u/NJuO7TSqAikAcQQ74gyJ87bqWRVeouky84ICoV4sN6VV53aTW+NE87qLdGY4QA2S7KNA== +esbuild-darwin-64@0.15.11: + version "0.15.11" + resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.15.11.tgz#89a90c8cf6f0029ac4169bfedd012a0412c1575f" + integrity sha512-1DqHD0ms3AhiwkKnjRUzmiW7JnaJJr5FKrPiR7xuyMwnjDqvNWDdMq4rKSD9OC0piFNK6n0LghsglNMe2MwJtA== + esbuild-darwin-arm64@0.14.38: version "0.14.38" resolved "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.38.tgz" integrity sha512-eqF+OejMI3mC5Dlo9Kdq/Ilbki9sQBw3QlHW3wjLmsLh+quNfHmGMp3Ly1eWm981iGBMdbtSS9+LRvR2T8B3eQ== +esbuild-darwin-arm64@0.15.11: + version "0.15.11" + resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.11.tgz#556f4385c6de806cc81132dd7b8af00fe9d292df" + integrity sha512-OMzhxSbS0lwwrW40HHjRCeVIJTURdXFA8c3GU30MlHKuPCcvWNUIKVucVBtNpJySXmbkQMDJdJNrXzNDyvoqvQ== + esbuild-freebsd-64@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.38.tgz#790b8786729d4aac7be17648f9ea8e0e16475b5e" integrity sha512-epnPbhZUt93xV5cgeY36ZxPXDsQeO55DppzsIgWM8vgiG/Rz+qYDLmh5ts3e+Ln1wA9dQ+nZmVHw+RjaW3I5Ig== +esbuild-freebsd-64@0.15.11: + version "0.15.11" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.11.tgz#fd86fd1b3b65366048f35b996d9cdf3547384eee" + integrity sha512-8dKP26r0/Qyez8nTCwpq60QbuYKOeBygdgOAWGCRalunyeqWRoSZj9TQjPDnTTI9joxd3QYw3UhVZTKxO9QdRg== + esbuild-freebsd-arm64@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.38.tgz#b66340ab28c09c1098e6d9d8ff656db47d7211e6" integrity sha512-/9icXUYJWherhk+y5fjPI5yNUdFPtXHQlwP7/K/zg8t8lQdHVj20SqU9/udQmeUo5pDFHMYzcEFfJqgOVeKNNQ== +esbuild-freebsd-arm64@0.15.11: + version "0.15.11" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.11.tgz#d346bcacfe9779ebc1a11edac1bdedeff6dda3b1" + integrity sha512-aSGiODiukLGGnSg/O9+cGO2QxEacrdCtCawehkWYTt5VX1ni2b9KoxpHCT9h9Y6wGqNHmXFnB47RRJ8BIqZgmQ== + esbuild-linux-32@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.38.tgz#7927f950986fd39f0ff319e92839455912b67f70" integrity sha512-QfgfeNHRFvr2XeHFzP8kOZVnal3QvST3A0cgq32ZrHjSMFTdgXhMhmWdKzRXP/PKcfv3e2OW9tT9PpcjNvaq6g== +esbuild-linux-32@0.15.11: + version "0.15.11" + resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.15.11.tgz#64b50e774bf75af7dcc6a73ad509f2eb0ac4487b" + integrity sha512-lsrAfdyJBGx+6aHIQmgqUonEzKYeBnyfJPkT6N2dOf1RoXYYV1BkWB6G02tjsrz1d5wZzaTc3cF+TKmuTo/ZwA== + esbuild-linux-64@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.38.tgz#4893d07b229d9cfe34a2b3ce586399e73c3ac519" integrity sha512-uuZHNmqcs+Bj1qiW9k/HZU3FtIHmYiuxZ/6Aa+/KHb/pFKr7R3aVqvxlAudYI9Fw3St0VCPfv7QBpUITSmBR1Q== +esbuild-linux-64@0.15.11: + version "0.15.11" + resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.15.11.tgz#fba3a78b95769772863f8f6dc316abca55cf8416" + integrity sha512-Y2Rh+PcyVhQqXKBTacPCltINN3uIw2xC+dsvLANJ1SpK5NJUtxv8+rqWpjmBgaNWKQT1/uGpMmA9olALy9PLVA== + esbuild-linux-arm64@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.38.tgz#8442402e37d0b8ae946ac616784d9c1a2041056a" integrity sha512-HlMGZTEsBrXrivr64eZ/EO0NQM8H8DuSENRok9d+Jtvq8hOLzrxfsAT9U94K3KOGk2XgCmkaI2KD8hX7F97lvA== +esbuild-linux-arm64@0.15.11: + version "0.15.11" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.11.tgz#c0cb31980eee066bfd39a4593660a0ecebe926cb" + integrity sha512-uhcXiTwTmD4OpxJu3xC5TzAAw6Wzf9O1XGWL448EE9bqGjgV1j+oK3lIHAfsHnuIn8K4nDW8yjX0Sv5S++oRuw== + esbuild-linux-arm@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.38.tgz#d5dbf32d38b7f79be0ec6b5fb2f9251fd9066986" integrity sha512-FiFvQe8J3VKTDXG01JbvoVRXQ0x6UZwyrU4IaLBZeq39Bsbatd94Fuc3F1RGqPF5RbIWW7RvkVQjn79ejzysnA== +esbuild-linux-arm@0.15.11: + version "0.15.11" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.15.11.tgz#7824d20099977aa671016c7de7a5038c9870010f" + integrity sha512-TJllTVk5aSyqPFvvcHTvf6Wu1ZKhWpJ/qNmZO8LL/XeB+LXCclm7HQHNEIz6MT7IX8PmlC1BZYrOiw2sXSB95A== + esbuild-linux-mips64le@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.38.tgz#95081e42f698bbe35d8ccee0e3a237594b337eb5" integrity sha512-qd1dLf2v7QBiI5wwfil9j0HG/5YMFBAmMVmdeokbNAMbcg49p25t6IlJFXAeLzogv1AvgaXRXvgFNhScYEUXGQ== +esbuild-linux-mips64le@0.15.11: + version "0.15.11" + resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.11.tgz#10627331c90164e553429ed25e025184bba485b6" + integrity sha512-WD61y/R1M4BLe4gxXRypoQ0Ci+Vjf714QYzcPNkiYv5I8K8WDz2ZR8Bm6cqKxd6rD+e/rZgPDbhQ9PCf7TMHmA== + esbuild-linux-ppc64le@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.38.tgz#dceb0a1b186f5df679618882a7990bd422089b47" integrity sha512-mnbEm7o69gTl60jSuK+nn+pRsRHGtDPfzhrqEUXyCl7CTOCLtWN2bhK8bgsdp6J/2NyS/wHBjs1x8aBWwP2X9Q== +esbuild-linux-ppc64le@0.15.11: + version "0.15.11" + resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.11.tgz#be42679a36a5246b893fc8b898135ebacb5a0a14" + integrity sha512-JVleZS9oPVLTlBhPTWgOwxFWU/wMUdlBwTbGA4GF8c38sLbS13cupj+C8bLq929jU7EMWry4SaL+tKGIaTlqKg== + esbuild-linux-riscv64@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.38.tgz#61fb8edb75f475f9208c4a93ab2bfab63821afd2" integrity sha512-+p6YKYbuV72uikChRk14FSyNJZ4WfYkffj6Af0/Tw63/6TJX6TnIKE+6D3xtEc7DeDth1fjUOEqm+ApKFXbbVQ== +esbuild-linux-riscv64@0.15.11: + version "0.15.11" + resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.11.tgz#3ac2f328e3db73cbff833ada94314d8e79503e54" + integrity sha512-9aLIalZ2HFHIOZpmVU11sEAS9F8TnHw49daEjcgMpBXHFF57VuT9f9/9LKJhw781Gda0P9jDkuCWJ0tFbErvJw== + esbuild-linux-s390x@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.38.tgz#34c7126a4937406bf6a5e69100185fd702d12fe0" integrity sha512-0zUsiDkGJiMHxBQ7JDU8jbaanUY975CdOW1YDrurjrM0vWHfjv9tLQsW9GSyEb/heSK1L5gaweRjzfUVBFoybQ== +esbuild-linux-s390x@0.15.11: + version "0.15.11" + resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.11.tgz#e774e0df061b6847d86783bf3c8c4300a72e03ad" + integrity sha512-sZHtiXXOKsLI3XGBGoYO4qKBzJlb8xNsWmvFiwFMHFzA4AXgDP1KDp7Dawe9C2pavTRBDvl+Ok4n/DHQ59oaTg== + esbuild-netbsd-64@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.38.tgz#322ea9937d9e529183ee281c7996b93eb38a5d95" integrity sha512-cljBAApVwkpnJZfnRVThpRBGzCi+a+V9Ofb1fVkKhtrPLDYlHLrSYGtmnoTVWDQdU516qYI8+wOgcGZ4XIZh0Q== +esbuild-netbsd-64@0.15.11: + version "0.15.11" + resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.11.tgz#55e265fa4489e3f396b16c81f6f5a11d6ca2a9a4" + integrity sha512-hUC9yN06K9sg7ju4Vgu9ChAPdsEgtcrcLfyNT5IKwKyfpLvKUwCMZSdF+gRD3WpyZelgTQfJ+pDx5XFbXTlB0A== + esbuild-openbsd-64@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.38.tgz#1ca29bb7a2bf09592dcc26afdb45108f08a2cdbd" integrity sha512-CDswYr2PWPGEPpLDUO50mL3WO/07EMjnZDNKpmaxUPsrW+kVM3LoAqr/CE8UbzugpEiflYqJsGPLirThRB18IQ== +esbuild-openbsd-64@0.15.11: + version "0.15.11" + resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.11.tgz#bc04103ccfd8c2f2241e1add0b51a095955b73c4" + integrity sha512-0bBo9SQR4t66Wd91LGMAqmWorzO0TTzVjYiifwoFtel8luFeXuPThQnEm5ztN4g0fnvcp7AnUPPzS/Depf17wQ== + esbuild-sunos-64@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.38.tgz#c9446f7d8ebf45093e7bb0e7045506a88540019b" integrity sha512-2mfIoYW58gKcC3bck0j7lD3RZkqYA7MmujFYmSn9l6TiIcAMpuEvqksO+ntBgbLep/eyjpgdplF7b+4T9VJGOA== +esbuild-sunos-64@0.15.11: + version "0.15.11" + resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.15.11.tgz#ccd580305d31fde07b5c386da79c942aaf069013" + integrity sha512-EuBdTGlsMTjEl1sQnBX2jfygy7iR6CKfvOzi+gEOfhDqbHXsmY1dcpbVtcwHAg9/2yUZSfMJHMAgf1z8M4yyyw== + esbuild-windows-32@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.38.tgz#f8e9b4602fd0ccbd48e5c8d117ec0ba4040f2ad1" integrity sha512-L2BmEeFZATAvU+FJzJiRLFUP+d9RHN+QXpgaOrs2klshoAm1AE6Us4X6fS9k33Uy5SzScn2TpcgecbqJza1Hjw== +esbuild-windows-32@0.15.11: + version "0.15.11" + resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.15.11.tgz#40fe1d48f9b20a76f6db5109aaaf1511aed58c71" + integrity sha512-O0/Wo1Wk6dc0rZSxkvGpmTNIycEznHmkObTFz2VHBhjPsO4ZpCgfGxNkCpz4AdAIeMczpTXt/8d5vdJNKEGC+Q== + esbuild-windows-64@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.38.tgz#280f58e69f78535f470905ce3e43db1746518107" integrity sha512-Khy4wVmebnzue8aeSXLC+6clo/hRYeNIm0DyikoEqX+3w3rcvrhzpoix0S+MF9vzh6JFskkIGD7Zx47ODJNyCw== +esbuild-windows-64@0.15.11: + version "0.15.11" + resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.15.11.tgz#80c58b1ef2ff030c78e3a06e7a922776cc4cb687" + integrity sha512-x977Q4HhNjnHx00b4XLAnTtj5vfbdEvkxaQwC1Zh5AN8g5EX+izgZ6e5QgqJgpzyRNJqh4hkgIJF1pyy1be0mQ== + esbuild-windows-arm64@0.14.38: version "0.14.38" resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.38.tgz#d97e9ac0f95a4c236d9173fa9f86c983d6a53f54" integrity sha512-k3FGCNmHBkqdJXuJszdWciAH77PukEyDsdIryEHn9cKLQFxzhT39dSumeTuggaQcXY57UlmLGIkklWZo2qzHpw== +esbuild-windows-arm64@0.15.11: + version "0.15.11" + resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.11.tgz#018624023b5c3f0cca334cc99f5ef7134d396333" + integrity sha512-VwUHFACuBahrvntdcMKZteUZ9HaYrBRODoKe4tIWxguQRvvYoYb7iu5LrcRS/FQx8KPZNaa72zuqwVtHeXsITw== + esbuild@^0.14.38: version "0.14.38" resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.14.38.tgz" @@ -4599,11 +6644,44 @@ esbuild@^0.14.38: esbuild-windows-64 "0.14.38" esbuild-windows-arm64 "0.14.38" +esbuild@^0.15.9: + version "0.15.11" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.15.11.tgz#524d48612a9aa7edc1753c83459cb6fcae0cb66e" + integrity sha512-OgHGuhlfZ//mToxjte1D5iiiQgWfJ2GByVMwEC/IuoXsBGkuyK1+KrjYu0laSpnN/L1UmLUCv0s25vObdc1bVg== + optionalDependencies: + "@esbuild/android-arm" "0.15.11" + "@esbuild/linux-loong64" "0.15.11" + esbuild-android-64 "0.15.11" + esbuild-android-arm64 "0.15.11" + esbuild-darwin-64 "0.15.11" + esbuild-darwin-arm64 "0.15.11" + esbuild-freebsd-64 "0.15.11" + esbuild-freebsd-arm64 "0.15.11" + esbuild-linux-32 "0.15.11" + esbuild-linux-64 "0.15.11" + esbuild-linux-arm "0.15.11" + esbuild-linux-arm64 "0.15.11" + esbuild-linux-mips64le "0.15.11" + esbuild-linux-ppc64le "0.15.11" + esbuild-linux-riscv64 "0.15.11" + esbuild-linux-s390x "0.15.11" + esbuild-netbsd-64 "0.15.11" + esbuild-openbsd-64 "0.15.11" + esbuild-sunos-64 "0.15.11" + esbuild-windows-32 "0.15.11" + esbuild-windows-64 "0.15.11" + esbuild-windows-arm64 "0.15.11" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== +escape-goat@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675" + integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q== + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" @@ -4667,6 +6745,11 @@ eslint-plugin-jest@^26.5.3: dependencies: "@typescript-eslint/utils" "^5.10.0" +eslint-plugin-no-unsanitized@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-no-unsanitized/-/eslint-plugin-no-unsanitized-4.0.1.tgz#e2343265467ba2270ade478cbe07bbafeaea412d" + integrity sha512-y/lAMWnPPC7RYuUdxlEL/XiCL8FehN9h9s3Kjqbp/Kv0i9NZs+IXSC2kS546Fa4Bumwy31HlVS/OdWX0Kxb5Xg== + eslint-plugin-svelte3@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/eslint-plugin-svelte3/-/eslint-plugin-svelte3-4.0.0.tgz#3d4f3dcaec5761dac8bc697f81de3613b485b4e3" @@ -4703,15 +6786,56 @@ eslint-utils@^3.0.0: dependencies: eslint-visitor-keys "^2.0.0" +eslint-visitor-keys@3.3.0, eslint-visitor-keys@^3.0.0, eslint-visitor-keys@^3.3.0: + version "3.3.0" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz" + integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== + eslint-visitor-keys@^2.0.0: version "2.1.0" resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz" integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== -eslint-visitor-keys@^3.0.0, eslint-visitor-keys@^3.3.0: - version "3.3.0" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz" - integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== +eslint@8.11.0: + version "8.11.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.11.0.tgz#88b91cfba1356fc10bb9eb592958457dfe09fb37" + integrity sha512-/KRpd9mIRg2raGxHRGwW9ZywYNAClZrHjdueHcrVDuO3a6bj83eoTirCCk0M0yPwOjWYKHwRVRid+xK4F/GHgA== + dependencies: + "@eslint/eslintrc" "^1.2.1" + "@humanwhocodes/config-array" "^0.9.2" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.1.1" + eslint-utils "^3.0.0" + eslint-visitor-keys "^3.3.0" + espree "^9.3.1" + esquery "^1.4.0" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^6.0.1" + globals "^13.6.0" + ignore "^5.2.0" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.0.4" + natural-compare "^1.4.0" + optionator "^0.9.1" + regexpp "^3.2.0" + strip-ansi "^6.0.1" + strip-json-comments "^3.1.0" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" eslint@^8.15.0: version "8.15.0" @@ -4795,6 +6919,24 @@ eslint@^8.19.0: text-table "^0.2.0" v8-compile-cache "^2.0.3" +espree@9.3.1: + version "9.3.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.1.tgz#8793b4bc27ea4c778c19908e0719e7b8f4115bcd" + integrity sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ== + dependencies: + acorn "^8.7.0" + acorn-jsx "^5.3.1" + eslint-visitor-keys "^3.3.0" + +espree@^9.3.1, espree@^9.4.0: + version "9.4.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.4.0.tgz#cd4bc3d6e9336c433265fc0aa016fc1aaf182f8a" + integrity sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw== + dependencies: + acorn "^8.8.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.3.0" + espree@^9.3.2: version "9.3.2" resolved "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz" @@ -4804,7 +6946,7 @@ espree@^9.3.2: acorn-jsx "^5.3.2" eslint-visitor-keys "^3.3.0" -esprima@^4.0.0, esprima@^4.0.1: +esprima@4.0.1, esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== @@ -4863,6 +7005,21 @@ eventemitter3@^4.0.4: resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== +execa@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" + integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== + dependencies: + cross-spawn "^7.0.0" + get-stream "^5.0.0" + human-signals "^1.1.1" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.0" + onetime "^5.1.0" + signal-exit "^3.0.2" + strip-final-newline "^2.0.0" + execa@^5.0.0: version "5.1.1" resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz" @@ -4919,6 +7076,17 @@ expect@^27.5.1: jest-matcher-utils "^27.5.1" jest-message-util "^27.5.1" +expect@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-29.2.0.tgz#b90c6df52be7abfd9f206f273fbcf8b33d8f332d" + integrity sha512-03ClF3GWwUqd9Grgkr9ZSdaCJGMRA69PQ8jT7o+Bx100VlGiAFf9/8oIm9Qve7ZVJhuJxFftqFhviZJRxxNfvg== + dependencies: + "@jest/expect-utils" "^29.2.0" + jest-get-type "^29.2.0" + jest-matcher-utils "^29.2.0" + jest-message-util "^29.2.0" + jest-util "^29.2.0" + express@^4.16.4: version "4.17.1" resolved "https://registry.npmjs.org/express/-/express-4.17.1.tgz" @@ -5007,6 +7175,11 @@ extsprintf@^1.2.0: resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.0.tgz" integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + integrity sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w== + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" @@ -5034,7 +7207,14 @@ fast-glob@^3.2.9: merge2 "^1.3.0" micromatch "^4.0.4" -fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: +fast-json-patch@^2.0.6: + version "2.2.1" + resolved "https://registry.yarnpkg.com/fast-json-patch/-/fast-json-patch-2.2.1.tgz#18150d36c9ab65c7209e7d4eb113f4f8eaabe6d9" + integrity sha512-4j5uBaTnsYAV5ebkidvxiLUYOwjQ+JSFljeqfTxCrH9bDmlCQaOJFS84oDJ2rAXZq2yskmk3ORfoP9DCwqFNig== + dependencies: + fast-deep-equal "^2.0.1" + +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== @@ -5055,6 +7235,11 @@ fast-mhtml@^1.1.9: express "^4.16.4" filenamify "^2.1.0" +fast-redact@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-3.1.2.tgz#d58e69e9084ce9fa4c1a6fa98a3e1ecf5d7839aa" + integrity sha512-+0em+Iya9fKGfEQGcd62Yv6onjBmmhV1uh86XVfOU8VwAe6kaFdQCWI9s0/Nnugx5Vd9tdbZ7e6gE2tR9dzXdw== + fastparse@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz" @@ -5172,6 +7357,11 @@ find-cache-dir@^3.3.2: make-dir "^3.0.2" pkg-dir "^4.1.0" +find-root@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" + integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== + find-up@^2.0.0: version "2.1.0" resolved "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz" @@ -5195,6 +7385,22 @@ find-up@^5.0.0: locate-path "^6.0.0" path-exists "^4.0.0" +firefox-profile@4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/firefox-profile/-/firefox-profile-4.2.2.tgz#1c7c78d103e2fe4102154e0300dbc17124847db5" + integrity sha512-3kI17Xl9dL9AeRkpV1yahsJ+UbekkPtlQswKrIsTY1NLgxtEOR4R19rjGGz5+7/rP8Jt6fvxHk+Bai9R6Eai3w== + dependencies: + adm-zip "~0.5.x" + fs-extra "~9.0.1" + ini "~2.0.0" + minimist "^1.2.5" + xml2js "~0.4.23" + +first-chunk-stream@3.0.0, first-chunk-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-3.0.0.tgz#06972a66263505ed82b2c4db93c1b5e078a6576a" + integrity sha512-LNRvR4hr/S8cXXkIY5pTgVP7L3tq6LlYWcg9nWBuW7o1NMxKZo6oOVa/6GIekMGI0Iw7uC+HWimMe9u/VAeKqw== + flat-cache@^3.0.4: version "3.0.4" resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz" @@ -5208,6 +7414,18 @@ flatted@^3.1.0: resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.1.tgz" integrity sha512-OMQjaErSFHmHqZe+PSidH5n8j3O0F2DdnVh8JB4j4eUQ2k6KvB0qGfrKIhapvez5JerBbmWkaLYUYWISaESoXg== +fluent-syntax@0.13.0: + version "0.13.0" + resolved "https://registry.yarnpkg.com/fluent-syntax/-/fluent-syntax-0.13.0.tgz#417144d99cba94ff474c422b3e6623d5a842855a" + integrity sha512-0Bk1AsliuYB550zr4JV9AYhsETsD3ELXUQzdXGJfIc1Ni/ukAfBdQInDhVMYJUaT2QxoamNslwkYF7MlOrPUwg== + +focus-lock@^0.11.2: + version "0.11.3" + resolved "https://registry.yarnpkg.com/focus-lock/-/focus-lock-0.11.3.tgz#c094e8f109d780f56038abdeec79328fd56b627f" + integrity sha512-4n0pYcPTa/uI7Q66BZna61nRT7lDhnuJ9PJr6wiDjx4uStg491ks41y7uOG+s0umaaa+hulNKSldU9aTg9/yVg== + dependencies: + tslib "^2.0.3" + for-each@^0.3.3: version "0.3.3" resolved "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz" @@ -5255,6 +7473,34 @@ forwarded@0.2.0: resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz" integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== +framer-motion@^7.3.6: + version "7.5.3" + resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-7.5.3.tgz#a1de7d6c4abbf7333619d4a6c8df74c12240be43" + integrity sha512-VvANga9Z7bYtKMAsM/je81FwJDHfThOYywN04xVQ4OGdMVY09Bowx/q7nZd6XtytLuv6byc6GT1mYwag+SQ/nw== + dependencies: + "@motionone/dom" "10.13.1" + framesync "6.1.2" + hey-listen "^1.0.8" + popmotion "11.0.5" + style-value-types "5.1.2" + tslib "2.4.0" + optionalDependencies: + "@emotion/is-prop-valid" "^0.8.2" + +framesync@5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/framesync/-/framesync-5.3.0.tgz#0ecfc955e8f5a6ddc8fdb0cc024070947e1a0d9b" + integrity sha512-oc5m68HDO/tuK2blj7ZcdEBRx3p1PjrgHazL8GYEpvULhrtGIFbQArN6cQS2QhW8mitffaB+VYzMjDqBxxQeoA== + dependencies: + tslib "^2.1.0" + +framesync@6.1.2: + version "6.1.2" + resolved "https://registry.yarnpkg.com/framesync/-/framesync-6.1.2.tgz#755eff2fb5b8f3b4d2b266dd18121b300aefea27" + integrity sha512-jBTqhX6KaQVDyus8muwZbBeGGP0XgujBRbQ7gM7BRdS3CadCZIHiawyzYLnafYcvZIh5j8WE7cxZKFn7dXhu9g== + dependencies: + tslib "2.4.0" + fresh@0.5.2: version "0.5.2" resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" @@ -5265,6 +7511,16 @@ fs-constants@^1.0.0: resolved "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== +fs-extra@9.1.0, fs-extra@^9.1.0: + version "9.1.0" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz" + integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + fs-extra@^10.0.0: version "10.0.1" resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz" @@ -5274,15 +7530,15 @@ fs-extra@^10.0.0: jsonfile "^6.0.1" universalify "^2.0.0" -fs-extra@^9.1.0: - version "9.1.0" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz" - integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== +fs-extra@~9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.0.1.tgz#910da0062437ba4c39fedd863f1675ccfefcb9fc" + integrity sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ== dependencies: at-least-node "^1.0.0" graceful-fs "^4.2.0" jsonfile "^6.0.1" - universalify "^2.0.0" + universalify "^1.0.0" fs-minipass@^1.2.7: version "1.2.7" @@ -5318,6 +7574,23 @@ functional-red-black-tree@^1.0.1: resolved "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= +functions-have-names@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== + +fx-runner@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fx-runner/-/fx-runner-1.2.0.tgz#6fd6d0fc47b5c32c176aa22af2182227664a03fe" + integrity sha512-/zR9BmHF8h4OaVJ+fHHJBv/5FdPV9mjOAPIscQZbAijm7Aa15Ls/P8UBHD5OKU5jwu2niTxkkzzHKITE7oCMoQ== + dependencies: + commander "2.9.0" + shell-quote "1.7.3" + spawn-sync "1.0.15" + when "3.7.7" + which "1.2.4" + winreg "0.0.12" + gauge@~2.7.3: version "2.7.4" resolved "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz" @@ -5367,6 +7640,11 @@ get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: has "^1.0.3" has-symbols "^1.0.1" +get-nonce@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/get-nonce/-/get-nonce-1.0.1.tgz#fdf3f0278073820d2ce9426c18f07481b1e0cdf3" + integrity sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q== + get-package-type@^0.1.0: version "0.1.0" resolved "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz" @@ -5402,7 +7680,14 @@ get-stdin@~9.0.0: resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-9.0.0.tgz#3983ff82e03d56f1b2ea0d3e60325f39d703a575" integrity sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA== -get-stream@^5.1.0: +get-stream@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-stream@^5.0.0, get-stream@^5.1.0: version "5.2.0" resolved "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz" integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== @@ -5507,6 +7792,34 @@ glob-parent@^6.0.1: dependencies: is-glob "^4.0.3" +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + +glob@7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^6.0.1: + version "6.0.4" + resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22" + integrity sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A== + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: version "7.1.7" resolved "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz" @@ -5531,6 +7844,13 @@ glob@~7.2.0: once "^1.3.0" path-is-absolute "^1.0.0" +global-dirs@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.0.tgz#70a76fe84ea315ab37b1f5576cbde7d48ef72686" + integrity sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA== + dependencies: + ini "2.0.0" + globals@^11.1.0: version "11.12.0" resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz" @@ -5583,6 +7903,23 @@ glur@^1.1.2: resolved "https://registry.npmjs.org/glur/-/glur-1.1.2.tgz" integrity sha1-8g6jbbEDv8KSNDkh8fkeg8NGdok= +got@^9.6.0: + version "9.6.0" + resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" + integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== + dependencies: + "@sindresorhus/is" "^0.14.0" + "@szmarczak/http-timer" "^1.1.2" + cacheable-request "^6.0.0" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^4.1.0" + lowercase-keys "^1.0.1" + mimic-response "^1.0.1" + p-cancelable "^1.0.0" + to-readable-stream "^1.0.0" + url-parse-lax "^3.0.0" + graceful-fs@^4.1.11, graceful-fs@^4.1.2: version "4.2.6" resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz" @@ -5598,6 +7935,16 @@ graceful-fs@^4.2.9: resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz" integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + integrity sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w== + +growly@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" + integrity sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw== + handlebars@^4.7.6: version "4.7.7" resolved "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz" @@ -5687,6 +8034,11 @@ has-unicode@^2.0.0, has-unicode@^2.0.1: resolved "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz" integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= +has-yarn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77" + integrity sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw== + has@^1.0.0, has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" @@ -5699,6 +8051,18 @@ hex-color-regex@^1.1.0: resolved "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz" integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ== +hey-listen@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/hey-listen/-/hey-listen-1.0.8.tgz#8e59561ff724908de1aa924ed6ecc84a56a9aa68" + integrity sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q== + +hoist-non-react-statics@^3.3.1: + version "3.3.2" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== + dependencies: + react-is "^16.7.0" + hosted-git-info@^2.1.4: version "2.8.9" resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz" @@ -5743,7 +8107,7 @@ htmlparser2@^6.1.0: domutils "^2.5.2" entities "^2.0.0" -http-cache-semantics@^4.1.0: +http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz" integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== @@ -5804,6 +8168,11 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" +human-signals@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" + integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== + human-signals@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz" @@ -5869,6 +8238,18 @@ ignore@^5.1.8, ignore@^5.2.0, ignore@~5.2.0: resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz" integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== +image-size@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/image-size/-/image-size-1.0.1.tgz#86d6cfc2b1d19eab5d2b368d4b9194d9e48541c5" + integrity sha512-VAwkvNSNGClRw9mDHhc5Efax8PLlsOGcUTh0T/LIriC8vPA3U5PdqXWqkz406MoYHMKW8Uf9gWr05T/rYB44kQ== + dependencies: + queue "6.0.2" + +immediate@~3.0.5: + version "3.0.6" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" + integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== + import-cwd@^2.0.0: version "2.1.0" resolved "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz" @@ -5883,6 +8264,14 @@ import-cwd@^3.0.0: dependencies: import-from "^3.0.0" +import-fresh@3.3.0, import-fresh@^3.0.0, import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + import-fresh@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz" @@ -5891,14 +8280,6 @@ import-fresh@^2.0.0: caller-path "^2.0.0" resolve-from "^3.0.0" -import-fresh@^3.0.0, import-fresh@^3.2.1: - version "3.3.0" - resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - import-from@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz" @@ -5913,6 +8294,11 @@ import-from@^3.0.0: dependencies: resolve-from "^5.0.0" +import-lazy@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" + integrity sha512-m7ZEHgtw69qOGw+jwxXkHlrlIPdTGkyh66zXZ1ajZbxkDBNjSY/LGbmjc7h0s2ELsUDTAhFr55TrPSSqJGPG0A== + import-local@^3.0.2: version "3.0.2" resolved "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz" @@ -5949,7 +8335,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -5959,16 +8345,16 @@ inherits@2.0.3: resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= -ini@^1.3.2, ini@^1.3.4: - version "1.3.8" - resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" - integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== - -ini@~2.0.0: +ini@2.0.0, ini@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== +ini@^1.3.2, ini@^1.3.4, ini@~1.3.0: + version "1.3.8" + resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + init-package-json@^2.0.2: version "2.0.3" resolved "https://registry.npmjs.org/init-package-json/-/init-package-json-2.0.3.tgz" @@ -6032,6 +8418,18 @@ internal-slot@^1.0.3: has "^1.0.3" side-channel "^1.0.4" +invariant@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + +invert-kv@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-3.0.1.tgz#a93c7a3d4386a1dc8325b97da9bb1620c0282523" + integrity sha512-CYdFeFexxhv/Bcny+Q0BfOV+ltRlJcd4BBZBYFX/O0u4npJrgZtIcjokegtiSMAvlMTJ+Koq0GBCc//3bueQxw== + ip@^1.1.5: version "1.1.5" resolved "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz" @@ -6047,6 +8445,21 @@ is-absolute-url@^2.0.0: resolved "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz" integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY= +is-absolute@^0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-0.1.7.tgz#847491119fccb5fb436217cc737f7faad50f603f" + integrity sha512-Xi9/ZSn4NFapG8RP98iNPMOeaV3mXPisxKxzKtHVqr3g56j/fBn+yZmnxSVAA8lmZbl2J9b/a4kJvfU3hqQYgA== + dependencies: + is-relative "^0.1.0" + +is-arguments@^1.0.4: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" @@ -6076,7 +8489,7 @@ is-boolean-object@^1.1.0: dependencies: call-bind "^1.0.2" -is-buffer@^1.1.5: +is-buffer@^1.1.5, is-buffer@~1.1.6: version "1.1.6" resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== @@ -6131,6 +8544,13 @@ is-core-module@^2.2.0: dependencies: has "^1.0.3" +is-core-module@^2.9.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.10.0.tgz#9012ede0a91c69587e647514e1d5277019e728ed" + integrity sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg== + dependencies: + has "^1.0.3" + is-date-object@^1.0.1: version "1.0.4" resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz" @@ -6141,6 +8561,11 @@ is-directory@^0.3.1: resolved "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz" integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= +is-docker@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + is-dotfile@^1.0.0: version "1.0.3" resolved "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz" @@ -6204,6 +8629,14 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" +is-installed-globally@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520" + integrity sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ== + dependencies: + global-dirs "^3.0.0" + is-path-inside "^3.0.2" + is-interactive@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-2.0.0.tgz#40c57614593826da1100ade6059778d597f16e90" @@ -6214,6 +8647,11 @@ is-lambda@^1.0.1: resolved "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz" integrity sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU= +is-mergeable-object@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-mergeable-object/-/is-mergeable-object-1.1.1.tgz#faaa3ed1cfce87d6f7d2f5885e92cc30af3e2ebf" + integrity sha512-CPduJfuGg8h8vW74WOxHtHmtQutyQBzR+3MjQ6iDHIYdbOnm1YC7jv43SqCoU8OPGTJD4nibmiryA4kmogbGrA== + is-module@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz" @@ -6224,6 +8662,11 @@ is-negative-zero@^2.0.1: resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz" integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== +is-npm@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-5.0.0.tgz#43e8d65cc56e1b67f8d47262cf667099193f45a8" + integrity sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA== + is-number-object@^1.0.4: version "1.0.5" resolved "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz" @@ -6251,6 +8694,11 @@ is-obj@^2.0.0: resolved "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz" integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== +is-path-inside@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz" @@ -6295,6 +8743,14 @@ is-reference@^1.2.1: dependencies: "@types/estree" "*" +is-regex@^1.0.4, is-regex@^1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + is-regex@^1.1.3: version "1.1.3" resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz" @@ -6303,13 +8759,10 @@ is-regex@^1.1.3: call-bind "^1.0.2" has-symbols "^1.0.2" -is-regex@^1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" +is-relative@^0.1.0: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-0.1.3.tgz#905fee8ae86f45b3ec614bc3c15c869df0876e82" + integrity sha512-wBOr+rNM4gkAZqoLRJI4myw5WzzIdQosFAAbnvfXP5z1LyzgAI3ivOKehC5KfqlQJZoihVhirgtCBj378Eg8GA== is-resolvable@^1.0.0: version "1.1.0" @@ -6369,6 +8822,11 @@ is-unicode-supported@^1.1.0, is-unicode-supported@^1.2.0: resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-1.2.0.tgz#f4f54f34d8ebc84a46b93559a036763b6d3e1014" integrity sha512-wH+U77omcRzevfIG8dDhTS0V9zZyweakfD01FULl97+0EHiJTTZtJqxPSkIIo/SDPv/i07k/C9jAPY+jwLLeUQ== +is-utf8@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q== + is-weakref@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz" @@ -6376,11 +8834,28 @@ is-weakref@^1.0.1: dependencies: call-bind "^1.0.0" +is-wsl@^2.1.1, is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +is-yarn-global@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232" + integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw== + isarray@1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= +isexe@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-1.1.2.tgz#36f3e22e60750920f5e7241a476a8c6a42275ad0" + integrity sha512-d2eJzK691yZwPHcv1LbeAOa91yMJ9QmfTgSO1oXB65ezVhXQsxBac2vEB4bMVms9cGzaA99n6V2viHMq82VLDw== + isexe@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" @@ -6468,6 +8943,11 @@ istanbul-reports@^3.1.3: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" +jed@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/jed/-/jed-1.1.1.tgz#7a549bbd9ffe1585b0cd0a191e203055bee574b4" + integrity sha512-z35ZSEcXHxLW4yumw0dF6L464NT36vmx3wxJw8MDpraBcWuNVgUPZgPJKcu1HekNgwlMFNqol7i/IpSbjhqwqA== + jest-changed-files@^27.2.4: version "27.2.4" resolved "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.2.4.tgz" @@ -6486,6 +8966,14 @@ jest-changed-files@^27.5.1: execa "^5.0.0" throat "^6.0.1" +jest-changed-files@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.2.0.tgz#b6598daa9803ea6a4dce7968e20ab380ddbee289" + integrity sha512-qPVmLLyBmvF5HJrY7krDisx6Voi8DmlV3GZYX0aFNbaQsZeoz1hfxcCMbqDGuQCxU1dJy9eYc2xscE8QrCCYaA== + dependencies: + execa "^5.0.0" + p-limit "^3.1.0" + jest-circus@^27.2.4: version "27.2.4" resolved "https://registry.npmjs.org/jest-circus/-/jest-circus-27.2.4.tgz" @@ -6536,6 +9024,31 @@ jest-circus@^27.5.1: stack-utils "^2.0.3" throat "^6.0.1" +jest-circus@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.2.0.tgz#692ddf3b12a5ae6326f2f37b9d176c68777fcf4c" + integrity sha512-bpJRMe+VtvYlF3q8JNx+/cAo4FYvNCiR5s7Z0Scf8aC+KJ2ineSjZKtw1cIZbythlplkiro0My8nc65pfCqJ3A== + dependencies: + "@jest/environment" "^29.2.0" + "@jest/expect" "^29.2.0" + "@jest/test-result" "^29.2.0" + "@jest/types" "^29.2.0" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^0.7.0" + is-generator-fn "^2.0.0" + jest-each "^29.2.0" + jest-matcher-utils "^29.2.0" + jest-message-util "^29.2.0" + jest-runtime "^29.2.0" + jest-snapshot "^29.2.0" + jest-util "^29.2.0" + p-limit "^3.1.0" + pretty-format "^29.2.0" + slash "^3.0.0" + stack-utils "^2.0.3" + jest-cli@^27.2.4: version "27.2.4" resolved "https://registry.npmjs.org/jest-cli/-/jest-cli-27.2.4.tgz" @@ -6572,6 +9085,24 @@ jest-cli@^27.5.1: prompts "^2.0.1" yargs "^16.2.0" +jest-cli@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.2.0.tgz#c6ca40889d6671c38b1cf9119d3b653809f31a3a" + integrity sha512-/581TzbXeO+5kbtSlhXEthGiVJCC8AP0jgT0iZINAAMW+tTFj2uWU7z+HNUH5yIYdHV7AvRr0fWLrmHJGIruHg== + dependencies: + "@jest/core" "^29.2.0" + "@jest/test-result" "^29.2.0" + "@jest/types" "^29.2.0" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + import-local "^3.0.2" + jest-config "^29.2.0" + jest-util "^29.2.0" + jest-validate "^29.2.0" + prompts "^2.0.1" + yargs "^17.3.1" + jest-config@^27.2.4: version "27.2.4" resolved "https://registry.npmjs.org/jest-config/-/jest-config-27.2.4.tgz" @@ -6629,6 +9160,34 @@ jest-config@^27.5.1: slash "^3.0.0" strip-json-comments "^3.1.1" +jest-config@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.2.0.tgz#8823f35255f696444a882721e624d7ad352e208b" + integrity sha512-IkdCsrHIoxDPZAyFcdtQrCQ3uftLqns6Joj0tlbxiAQW4k/zTXmIygqWBmPNxO9FbFkDrhtYZiLHXjaJh9rS+Q== + dependencies: + "@babel/core" "^7.11.6" + "@jest/test-sequencer" "^29.2.0" + "@jest/types" "^29.2.0" + babel-jest "^29.2.0" + chalk "^4.0.0" + ci-info "^3.2.0" + deepmerge "^4.2.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-circus "^29.2.0" + jest-environment-node "^29.2.0" + jest-get-type "^29.2.0" + jest-regex-util "^29.2.0" + jest-resolve "^29.2.0" + jest-runner "^29.2.0" + jest-util "^29.2.0" + jest-validate "^29.2.0" + micromatch "^4.0.4" + parse-json "^5.2.0" + pretty-format "^29.2.0" + slash "^3.0.0" + strip-json-comments "^3.1.1" + jest-diff@^23.6.0: version "23.6.0" resolved "https://registry.npmjs.org/jest-diff/-/jest-diff-23.6.0.tgz" @@ -6659,6 +9218,16 @@ jest-diff@^27.5.1: jest-get-type "^27.5.1" pretty-format "^27.5.1" +jest-diff@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.2.0.tgz#b1e11ac1a1401fc4792ef8ba406b48f1ae7d2bc5" + integrity sha512-GsH07qQL+/D/GxlnU+sSg9GL3fBOcuTlmtr3qr2pnkiODCwubNN2/7slW4m3CvxDsEus/VEOfQKRFLyXsUlnZw== + dependencies: + chalk "^4.0.0" + diff-sequences "^29.2.0" + jest-get-type "^29.2.0" + pretty-format "^29.2.0" + jest-docblock@^27.0.6: version "27.0.6" resolved "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.0.6.tgz" @@ -6673,6 +9242,13 @@ jest-docblock@^27.5.1: dependencies: detect-newline "^3.0.0" +jest-docblock@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.2.0.tgz#307203e20b637d97cee04809efc1d43afc641e82" + integrity sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A== + dependencies: + detect-newline "^3.0.0" + jest-each@^27.2.4: version "27.2.4" resolved "https://registry.npmjs.org/jest-each/-/jest-each-27.2.4.tgz" @@ -6695,6 +9271,17 @@ jest-each@^27.5.1: jest-util "^27.5.1" pretty-format "^27.5.1" +jest-each@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.2.0.tgz#0f89c1233d65f22c7dba265ccd319611f1d662de" + integrity sha512-h4LeC3L/R7jIMfTdYowevPIssvcPYQ7Qzs+pCSYsJgPztIizXwKmnfhZXBA4WVqdmvMcpmseYEXb67JT7IJ2eg== + dependencies: + "@jest/types" "^29.2.0" + chalk "^4.0.0" + jest-get-type "^29.2.0" + jest-util "^29.2.0" + pretty-format "^29.2.0" + jest-environment-jsdom@^27.2.4: version "27.2.4" resolved "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.2.4.tgz" @@ -6745,6 +9332,18 @@ jest-environment-node@^27.5.1: jest-mock "^27.5.1" jest-util "^27.5.1" +jest-environment-node@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.2.0.tgz#49c39d4f9df64fc74da3725cbcaeee6da01a6dd6" + integrity sha512-b4qQGVStPMvtZG97Ac0rvnmSIjCZturFU7MQRMp4JDFl7zoaDLTtXmFjFP1tNmi9te6kR8d+Htbv3nYeoaIz6g== + dependencies: + "@jest/environment" "^29.2.0" + "@jest/fake-timers" "^29.2.0" + "@jest/types" "^29.2.0" + "@types/node" "*" + jest-mock "^29.2.0" + jest-util "^29.2.0" + jest-get-type@^22.1.0: version "22.4.3" resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-22.4.3.tgz" @@ -6760,6 +9359,11 @@ jest-get-type@^27.5.1: resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz" integrity sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw== +jest-get-type@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.2.0.tgz#726646f927ef61d583a3b3adb1ab13f3a5036408" + integrity sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA== + jest-haste-map@^27.2.4: version "27.2.4" resolved "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.2.4.tgz" @@ -6800,6 +9404,25 @@ jest-haste-map@^27.5.1: optionalDependencies: fsevents "^2.3.2" +jest-haste-map@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.2.0.tgz#2410f2ec93958e0bd894818de6c8056eb1b4d6fc" + integrity sha512-qu9lGFi7qJ8v37egS1phZZUJYiMyWnKwu83NlNT1qs50TbedIX2hFl+9ztsJ7U/ENaHwk1/Bs8fqOIQsScIRwg== + dependencies: + "@jest/types" "^29.2.0" + "@types/graceful-fs" "^4.1.3" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.9" + jest-regex-util "^29.2.0" + jest-util "^29.2.0" + jest-worker "^29.2.0" + micromatch "^4.0.4" + walker "^1.0.8" + optionalDependencies: + fsevents "^2.3.2" + jest-image-snapshot@^4.5.1: version "4.5.1" resolved "https://registry.npmjs.org/jest-image-snapshot/-/jest-image-snapshot-4.5.1.tgz" @@ -6878,6 +9501,14 @@ jest-leak-detector@^27.5.1: jest-get-type "^27.5.1" pretty-format "^27.5.1" +jest-leak-detector@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.2.0.tgz#7c0eace293cf05a130a09beb1b9318ecc2f77692" + integrity sha512-FXT9sCFdct42+oOqGIr/9kmUw3RbhvpkwidCBT5ySHHoWNGd3c9n7HXpFKjEz9UnUITRCGdn0q2s6Sxrq36kwg== + dependencies: + jest-get-type "^29.2.0" + pretty-format "^29.2.0" + jest-matcher-utils@^23.6.0: version "23.6.0" resolved "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-23.6.0.tgz" @@ -6907,6 +9538,16 @@ jest-matcher-utils@^27.2.4: jest-get-type "^27.0.6" pretty-format "^27.2.4" +jest-matcher-utils@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.2.0.tgz#d1d73add0e0efb0e316a50f296977505dc053e02" + integrity sha512-FcEfKZ4vm28yCdBsvC69EkrEhcfex+IYlRctNJXsRG9+WC3WxgBNORnECIgqUtj7o/h1d8o7xB/dFUiLi4bqtw== + dependencies: + chalk "^4.0.0" + jest-diff "^29.2.0" + jest-get-type "^29.2.0" + pretty-format "^29.2.0" + jest-message-util@^23.4.0: version "23.4.0" resolved "https://registry.npmjs.org/jest-message-util/-/jest-message-util-23.4.0.tgz" @@ -6948,6 +9589,21 @@ jest-message-util@^27.5.1: slash "^3.0.0" stack-utils "^2.0.3" +jest-message-util@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.2.0.tgz#cbd43fd9a20a8facd4267ac37556bc5c9a525ec0" + integrity sha512-arBfk5yMFMTnMB22GyG601xGSGthA02vWSewPaxoFo0F9wBqDOyxccPbCcYu8uibw3kduSHXdCOd1PsLSgdomg== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^29.2.0" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^29.2.0" + slash "^3.0.0" + stack-utils "^2.0.3" + jest-mock@^27.2.4: version "27.2.4" resolved "https://registry.npmjs.org/jest-mock/-/jest-mock-27.2.4.tgz" @@ -6964,6 +9620,15 @@ jest-mock@^27.5.1: "@jest/types" "^27.5.1" "@types/node" "*" +jest-mock@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.2.0.tgz#3531012881178f59f4b5fd1e243acc329d08d6a1" + integrity sha512-aiWGR0P8ivssIO17xkehLGFtCcef2ZwQFNPwEer1jQLHxPctDlIg3Hs6QMq1KpPz5dkCcgM7mwGif4a9IPznlg== + dependencies: + "@jest/types" "^29.2.0" + "@types/node" "*" + jest-util "^29.2.0" + jest-pnp-resolver@^1.2.2: version "1.2.2" resolved "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz" @@ -6979,6 +9644,11 @@ jest-regex-util@^27.5.1: resolved "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz" integrity sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg== +jest-regex-util@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.2.0.tgz#82ef3b587e8c303357728d0322d48bbfd2971f7b" + integrity sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA== + jest-resolve-dependencies@^27.2.4: version "27.2.4" resolved "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.2.4.tgz" @@ -6997,6 +9667,14 @@ jest-resolve-dependencies@^27.5.1: jest-regex-util "^27.5.1" jest-snapshot "^27.5.1" +jest-resolve-dependencies@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.2.0.tgz#a127b7d6b7df69d4eaf2c7c99f652f17ba0fed71" + integrity sha512-Cd0Z39sDntEnfR9PoUdFHUAGDvtKI0/7Wt73l3lt03A3yQ+A6Qi3XmBuqGjdFl2QbXaPa937oLhilG612P8HGQ== + dependencies: + jest-regex-util "^29.2.0" + jest-snapshot "^29.2.0" + jest-resolve@^23.6.0: version "23.6.0" resolved "https://registry.npmjs.org/jest-resolve/-/jest-resolve-23.6.0.tgz" @@ -7030,10 +9708,25 @@ jest-resolve@^27.5.1: "@jest/types" "^27.5.1" chalk "^4.0.0" graceful-fs "^4.2.9" - jest-haste-map "^27.5.1" + jest-haste-map "^27.5.1" + jest-pnp-resolver "^1.2.2" + jest-util "^27.5.1" + jest-validate "^27.5.1" + resolve "^1.20.0" + resolve.exports "^1.1.0" + slash "^3.0.0" + +jest-resolve@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.2.0.tgz#cb9f9770164382785cd68598a9fb0b7e4bb95a9f" + integrity sha512-f5c0ljNg2guDBCC7wi92vAhNuA0BtAG5vkY7Fob0c7sUMU1g87mTXqRmjrVFe2XvdwP5m5T/e5KJsCKu9hRvBA== + dependencies: + chalk "^4.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.2.0" jest-pnp-resolver "^1.2.2" - jest-util "^27.5.1" - jest-validate "^27.5.1" + jest-util "^29.2.0" + jest-validate "^29.2.0" resolve "^1.20.0" resolve.exports "^1.1.0" slash "^3.0.0" @@ -7093,6 +9786,33 @@ jest-runner@^27.5.1: source-map-support "^0.5.6" throat "^6.0.1" +jest-runner@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.2.0.tgz#d621e67a2d59d5bc302eca1f5348615ce166712c" + integrity sha512-VPBrCwl9fM2mc5yk6yZhNrgXzRJMD5jfLmntkMLlrVq4hQPWbRK998iJlR+DOGCO04TC9PPYLntOJ001Vnf28g== + dependencies: + "@jest/console" "^29.2.0" + "@jest/environment" "^29.2.0" + "@jest/test-result" "^29.2.0" + "@jest/transform" "^29.2.0" + "@jest/types" "^29.2.0" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.10.2" + graceful-fs "^4.2.9" + jest-docblock "^29.2.0" + jest-environment-node "^29.2.0" + jest-haste-map "^29.2.0" + jest-leak-detector "^29.2.0" + jest-message-util "^29.2.0" + jest-resolve "^29.2.0" + jest-runtime "^29.2.0" + jest-util "^29.2.0" + jest-watcher "^29.2.0" + jest-worker "^29.2.0" + p-limit "^3.1.0" + source-map-support "0.5.13" + jest-runtime@^27.2.4: version "27.2.4" resolved "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.2.4.tgz" @@ -7154,6 +9874,34 @@ jest-runtime@^27.5.1: slash "^3.0.0" strip-bom "^4.0.0" +jest-runtime@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.2.0.tgz#6b10d9539c1f7af32d06fccd7d16b6c9996c9cb2" + integrity sha512-+GDmzCrswQF+mvI0upTYMe/OPYnlRRNLLDHM9AFLp2y7zxWoDoYgb8DL3WwJ8d9m743AzrnvBV9JQHi/0ed7dg== + dependencies: + "@jest/environment" "^29.2.0" + "@jest/fake-timers" "^29.2.0" + "@jest/globals" "^29.2.0" + "@jest/source-map" "^29.2.0" + "@jest/test-result" "^29.2.0" + "@jest/transform" "^29.2.0" + "@jest/types" "^29.2.0" + "@types/node" "*" + chalk "^4.0.0" + cjs-module-lexer "^1.0.0" + collect-v8-coverage "^1.0.0" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-haste-map "^29.2.0" + jest-message-util "^29.2.0" + jest-mock "^29.2.0" + jest-regex-util "^29.2.0" + jest-resolve "^29.2.0" + jest-snapshot "^29.2.0" + jest-util "^29.2.0" + slash "^3.0.0" + strip-bom "^4.0.0" + jest-serializer@^27.0.6: version "27.0.6" resolved "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.0.6.tgz" @@ -7244,6 +9992,36 @@ jest-snapshot@^27.5.1: pretty-format "^27.5.1" semver "^7.3.2" +jest-snapshot@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.2.0.tgz#fb3d4e1d9df579f37d7c60072877ee99376b6090" + integrity sha512-YCKrOR0PLRXROmww73fHO9oeY4tL+LPQXWR3yml1+hKbQDR8j1VUrVzB65hKSJJgxBOr1vWx+hmz2by8JjAU5w== + dependencies: + "@babel/core" "^7.11.6" + "@babel/generator" "^7.7.2" + "@babel/plugin-syntax-jsx" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/traverse" "^7.7.2" + "@babel/types" "^7.3.3" + "@jest/expect-utils" "^29.2.0" + "@jest/transform" "^29.2.0" + "@jest/types" "^29.2.0" + "@types/babel__traverse" "^7.0.6" + "@types/prettier" "^2.1.5" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^29.2.0" + graceful-fs "^4.2.9" + jest-diff "^29.2.0" + jest-get-type "^29.2.0" + jest-haste-map "^29.2.0" + jest-matcher-utils "^29.2.0" + jest-message-util "^29.2.0" + jest-util "^29.2.0" + natural-compare "^1.4.0" + pretty-format "^29.2.0" + semver "^7.3.5" + jest-util@^27.0.0, jest-util@^27.2.4: version "27.2.4" resolved "https://registry.npmjs.org/jest-util/-/jest-util-27.2.4.tgz" @@ -7268,6 +10046,18 @@ jest-util@^27.5.1: graceful-fs "^4.2.9" picomatch "^2.2.3" +jest-util@^29.0.0, jest-util@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.2.0.tgz#797935697e83a5722aeba401ed6cd01264295566" + integrity sha512-8M1dx12ujkBbnhwytrezWY0Ut79hbflwodE+qZKjxSRz5qt4xDp6dQQJaOCFvCmE0QJqp9KyEK33lpPNjnhevw== + dependencies: + "@jest/types" "^29.2.0" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + jest-validate@^27.2.4: version "27.2.4" resolved "https://registry.npmjs.org/jest-validate/-/jest-validate-27.2.4.tgz" @@ -7292,6 +10082,18 @@ jest-validate@^27.5.1: leven "^3.1.0" pretty-format "^27.5.1" +jest-validate@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.2.0.tgz#e40faf33759365c12ead6a45165349d660d09ba4" + integrity sha512-4Vl51bPNeFeDok9aJiOnrC6tqJbOp4iMCYlewoC2ZzYJZ5+6pfr3KObAdx5wP8auHcg2MRaguiqj5OdScZa72g== + dependencies: + "@jest/types" "^29.2.0" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^29.2.0" + leven "^3.1.0" + pretty-format "^29.2.0" + jest-watcher@^27.2.4: version "27.2.4" resolved "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.2.4.tgz" @@ -7318,6 +10120,20 @@ jest-watcher@^27.5.1: jest-util "^27.5.1" string-length "^4.0.1" +jest-watcher@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.2.0.tgz#d0c58ff76d3dd22fff79f3f9cbeadaa749d2ca6e" + integrity sha512-bRh0JdUeN+cl9XfK7tMnXLm4Mv70hG2SZlqbkFe5CTs7oeCkbwlGBk/mEfEJ63mrxZ8LPbnfaMpfSmkhEQBEGA== + dependencies: + "@jest/test-result" "^29.2.0" + "@jest/types" "^29.2.0" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.10.2" + jest-util "^29.2.0" + string-length "^4.0.1" + jest-worker@^26.2.1: version "26.6.2" resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz" @@ -7345,6 +10161,16 @@ jest-worker@^27.5.1: merge-stream "^2.0.0" supports-color "^8.0.0" +jest-worker@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.2.0.tgz#b2bd1a81fc7a1ae79a500b05f5feb0d1c0b1a19e" + integrity sha512-mluOlMbRX1H59vGVzPcVg2ALfCausbBpxC8a2KWOzInhYHZibbHH8CB0C1JkmkpfurrkOYgF7FPmypuom1OM9A== + dependencies: + "@types/node" "*" + jest-util "^29.2.0" + merge-stream "^2.0.0" + supports-color "^8.0.0" + jest@^27.2.4: version "27.2.4" resolved "https://registry.npmjs.org/jest/-/jest-27.2.4.tgz" @@ -7363,6 +10189,16 @@ jest@^27.5.1: import-local "^3.0.2" jest-cli "^27.5.1" +jest@^29.0.3: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-29.2.0.tgz#e7997bc603f31e04edbbe87dd24cf6e7c432abac" + integrity sha512-6krPemKUXCEu5Fh3j6ZVoLMjpTQVm0OCU+7f3K/9gllX8wNIE6NSCQ6s0q2RDoiKLRaQlVRHyscjSPRPqCI0Fg== + dependencies: + "@jest/core" "^29.2.0" + "@jest/types" "^29.2.0" + import-local "^3.0.2" + jest-cli "^29.2.0" + jju@~1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/jju/-/jju-1.4.0.tgz#a3abe2718af241a2b2904f84a625970f389ae32a" @@ -7373,7 +10209,7 @@ joycon@^3.0.1: resolved "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz" integrity sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw== -js-tokens@^4.0.0: +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== @@ -7469,6 +10305,18 @@ jsesc@^2.5.1: resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + integrity sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ== + +json-merge-patch@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-merge-patch/-/json-merge-patch-0.2.3.tgz#fa2c6b5af87da77bae2966a589d52e23ed81fe40" + integrity sha512-mjd5eObNGOhWkKCztwVuF25KOzLj2T4TJaWXLBgCQPeoPRJrMxKNgjNBE8sPmXoWRT0WDlo4Itd/gTlFh29TFw== + dependencies: + deep-equal "^1.0.0" + json-parse-better-errors@^1.0.1: version "1.0.2" resolved "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz" @@ -7484,6 +10332,11 @@ json-schema-traverse@^0.4.1: resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + json-schema@0.2.3: version "0.2.3" resolved "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz" @@ -7513,6 +10366,11 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" +json5@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" + integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== + jsonc-parser@^3.0.0, jsonc-parser@~3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz" @@ -7532,6 +10390,22 @@ jsonparse@^1.2.0, jsonparse@^1.3.1: resolved "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz" integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= +jsonwebtoken@8.5.1: + version "8.5.1" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d" + integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w== + dependencies: + jws "^3.2.2" + lodash.includes "^4.3.0" + lodash.isboolean "^3.0.3" + lodash.isinteger "^4.0.4" + lodash.isnumber "^3.0.3" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.once "^4.0.0" + ms "^2.1.1" + semver "^5.6.0" + jsprim@^1.2.2: version "1.4.1" resolved "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz" @@ -7542,6 +10416,40 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" +jszip@^3.2.2: + version "3.10.1" + resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.10.1.tgz#34aee70eb18ea1faec2f589208a157d1feb091c2" + integrity sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g== + dependencies: + lie "~3.3.0" + pako "~1.0.2" + readable-stream "~2.3.6" + setimmediate "^1.0.5" + +jwa@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" + integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== + dependencies: + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.11" + safe-buffer "^5.0.1" + +jws@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" + integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== + dependencies: + jwa "^1.4.1" + safe-buffer "^5.0.1" + +keyv@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" + integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== + dependencies: + json-buffer "3.0.0" + kind-of@^3.0.2: version "3.2.2" resolved "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz" @@ -7559,6 +10467,20 @@ kleur@^3.0.0, kleur@^3.0.3: resolved "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== +latest-version@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face" + integrity sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA== + dependencies: + package-json "^6.3.0" + +lcid@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-3.1.1.tgz#9030ec479a058fc36b5e8243ebaac8b6ac582fd0" + integrity sha512-M6T051+5QCGLBQb8id3hdvIW8+zeFV2FyBGFS9IEK5H9Wt4MueD4bW1eWikpHgZp+5xR3l5c8pZUkQsIA0BFZg== + dependencies: + invert-kv "^3.0.0" + lerna@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/lerna/-/lerna-4.0.0.tgz" @@ -7625,6 +10547,21 @@ libnpmpublish@^4.0.0: semver "^7.1.3" ssri "^8.0.1" +lie@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a" + integrity sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ== + dependencies: + immediate "~3.0.5" + +lighthouse-logger@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/lighthouse-logger/-/lighthouse-logger-1.3.0.tgz#ba6303e739307c4eee18f08249524e7dafd510db" + integrity sha512-BbqAKApLb9ywUli+0a+PcV04SyJ/N1q/8qgCNe6U97KbPCS1BTksEuHFLYdvc8DltuhfxIUBqDZsC0bBGtl3lA== + dependencies: + debug "^2.6.9" + marky "^1.2.2" + lines-and-columns@^1.1.6: version "1.1.6" resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz" @@ -7718,11 +10655,41 @@ lodash.camelcase@^4.3.0: resolved "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz" integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= +lodash.includes@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" + integrity sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w== + +lodash.isboolean@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" + integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg== + +lodash.isinteger@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" + integrity sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA== + lodash.ismatch@^4.4.0: version "4.4.0" resolved "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz" integrity sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc= +lodash.isnumber@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" + integrity sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw== + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== + +lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw== + lodash.memoize@4.1.2, lodash.memoize@4.x, lodash.memoize@^4.1.2: version "4.1.2" resolved "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz" @@ -7733,6 +10700,16 @@ lodash.merge@^4.6.2: resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== +lodash.mergewith@4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55" + integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ== + +lodash.once@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== + lodash.template@^4.5.0: version "4.5.0" resolved "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz" @@ -7766,6 +10743,23 @@ log-symbols@^5.1.0: chalk "^5.0.0" is-unicode-supported "^1.1.0" +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" @@ -7780,6 +10774,13 @@ magic-string@^0.25.7: dependencies: sourcemap-codec "^1.4.4" +magic-string@^0.26.2: + version "0.26.7" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.26.7.tgz#caf7daf61b34e9982f8228c4527474dac8981d6f" + integrity sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow== + dependencies: + sourcemap-codec "^1.4.8" + make-dir@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz" @@ -7795,7 +10796,7 @@ make-dir@^3.0.0, make-dir@^3.0.2: dependencies: semver "^6.0.0" -make-error@1.x, make-error@^1.1.1: +make-error@1.x, make-error@^1.1.1, make-error@^1.3.2: version "1.3.6" resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== @@ -7843,6 +10844,13 @@ make-fetch-happen@^9.0.1: socks-proxy-agent "^5.0.0" ssri "^8.0.0" +makeerror@1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" + integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== + dependencies: + tmpl "1.0.5" + makeerror@1.0.x: version "1.0.11" resolved "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz" @@ -7850,6 +10858,13 @@ makeerror@1.0.x: dependencies: tmpl "1.0.x" +map-age-cleaner@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" + integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== + dependencies: + p-defer "^1.0.0" + map-obj@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz" @@ -7899,11 +10914,25 @@ markdownlint@^0.25.1, markdownlint@~0.25.1: dependencies: markdown-it "12.3.2" +marky@^1.2.2: + version "1.2.5" + resolved "https://registry.yarnpkg.com/marky/-/marky-1.2.5.tgz#55796b688cbd72390d2d399eaaf1832c9413e3c0" + integrity sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q== + math-random@^1.0.1: version "1.0.4" resolved "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz" integrity sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A== +md5@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/md5/-/md5-2.3.0.tgz#c3da9a6aae3a30b46b7b0c349b87b110dc3bda4f" + integrity sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g== + dependencies: + charenc "0.0.2" + crypt "0.0.2" + is-buffer "~1.1.6" + mdn-data@2.0.14: version "2.0.14" resolved "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz" @@ -7924,6 +10953,15 @@ media-typer@0.3.0: resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz" integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= +mem@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/mem/-/mem-5.1.1.tgz#7059b67bf9ac2c924c9f1cff7155a064394adfb3" + integrity sha512-qvwipnozMohxLXG1pOqoLiZKNkC4r4qqRucSoDwXowsNGDSULiqFTRUF05vcZWnwJSG22qTsynQhxbaMtnX9gw== + dependencies: + map-age-cleaner "^0.1.3" + mimic-fn "^2.1.0" + p-is-promise "^2.1.0" + meow@^7.0.0, meow@^7.1.1: version "7.1.1" resolved "https://registry.npmjs.org/meow/-/meow-7.1.1.tgz" @@ -8044,12 +11082,17 @@ mimic-fn@^2.1.0: resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +mimic-response@^1.0.0, mimic-response@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + min-indent@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz" integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== -minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: +"minimatch@2 || 3", minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -8173,6 +11216,11 @@ mkdirp-infer-owner@^2.0.0: infer-owner "^1.0.4" mkdirp "^1.0.3" +mkdirp@1.0.4, mkdirp@^1.0.3, mkdirp@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + mkdirp@^0.5.1, mkdirp@^0.5.4, mkdirp@^0.5.5, mkdirp@~0.5.1: version "0.5.5" resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz" @@ -8180,16 +11228,16 @@ mkdirp@^0.5.1, mkdirp@^0.5.4, mkdirp@^0.5.5, mkdirp@~0.5.1: dependencies: minimist "^1.2.5" -mkdirp@^1.0.3, mkdirp@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - modify-values@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz" integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw== +moment@^2.19.3: + version "2.29.4" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108" + integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w== + mri@^1.1.0: version "1.1.6" resolved "https://registry.npmjs.org/mri/-/mri-1.1.6.tgz" @@ -8215,7 +11263,7 @@ ms@^2.0.0, ms@^2.1.1: resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -multimatch@^5.0.0: +multimatch@5.0.0, multimatch@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz" integrity sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA== @@ -8231,11 +11279,49 @@ mute-stream@0.0.8, mute-stream@~0.0.4: resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== +mv@~2: + version "2.1.1" + resolved "https://registry.yarnpkg.com/mv/-/mv-2.1.1.tgz#ae6ce0d6f6d5e0a4f7d893798d03c1ea9559b6a2" + integrity sha512-at/ZndSy3xEGJ8i0ygALh8ru9qy7gWW1cmkaqBN29JmMlIvM//MEO9y1sk/avxuwnPcfhkejkLsuPxH81BrkSg== + dependencies: + mkdirp "~0.5.1" + ncp "~2.0.0" + rimraf "~2.4.0" + +mz@2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + +nan@^2.14.0: + version "2.17.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb" + integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ== + +nanoid@^3.3.1, nanoid@^3.3.4: + version "3.3.4" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" + integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== + +nanoid@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-4.0.0.tgz#6e144dee117609232c3f415c34b0e550e64999a5" + integrity sha512-IgBP8piMxe/gf73RTQx7hmnhwz0aaEXYakvqZyE302IXW3HyVNhdNGC+O2MwMAVhLEnvXlvKtGbtJf6wvHihCg== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= +ncp@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3" + integrity sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA== + negotiator@0.6.2, negotiator@^0.6.2: version "0.6.2" resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz" @@ -8258,6 +11344,11 @@ node-fetch@^2.6.1: dependencies: whatwg-url "^5.0.0" +node-forge@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" + integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== + node-gyp@^5.0.2: version "5.1.1" resolved "https://registry.npmjs.org/node-gyp/-/node-gyp-5.1.1.tgz" @@ -8301,6 +11392,18 @@ node-modules-regexp@^1.0.0: resolved "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz" integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= +node-notifier@9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-9.0.0.tgz#46c5bbecbb796d4a803f646cea5bc91403f2ff38" + integrity sha512-SkwNwGnMMlSPrcoeH4CSo9XyWe72acAHEJGDdPdB+CyBVHsIYaTQ4U/1wk3URsyzC75xZLg2vzU2YaALlqDF1Q== + dependencies: + growly "^1.3.0" + is-wsl "^2.2.0" + semver "^7.3.2" + shellwords "^0.1.1" + uuid "^8.3.0" + which "^2.0.2" + node-releases@^1.1.71: version "1.1.73" resolved "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz" @@ -8373,6 +11476,11 @@ normalize-url@^3.0.0: resolved "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz" integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== +normalize-url@^4.1.0: + version "4.5.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" + integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== + normalize-url@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" @@ -8466,7 +11574,7 @@ npm-registry-fetch@^9.0.0: minizlib "^2.0.0" npm-package-arg "^8.0.0" -npm-run-path@^4.0.1: +npm-run-path@^4.0.0, npm-run-path@^4.0.1: version "4.0.1" resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz" integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== @@ -8512,7 +11620,7 @@ oauth-sign@~0.9.0: resolved "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== -object-assign@^4.0.1, object-assign@^4.1.0: +object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= @@ -8527,6 +11635,14 @@ object-inspect@^1.9.0: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== +object-is@^1.0.1: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz" @@ -8577,6 +11693,11 @@ object.values@^1.1.0: define-properties "^1.1.3" es-abstract "^1.19.1" +on-exit-leak-free@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/on-exit-leak-free/-/on-exit-leak-free-0.2.0.tgz#b39c9e3bf7690d890f4861558b0d7b90a442d209" + integrity sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg== + on-finished@~2.3.0: version "2.3.0" resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz" @@ -8598,6 +11719,14 @@ onetime@^5.1.0, onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" +open@7.4.2: + version "7.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" + integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q== + dependencies: + is-docker "^2.0.0" + is-wsl "^2.1.1" + optionator@^0.8.1: version "0.8.3" resolved "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz" @@ -8647,6 +11776,20 @@ os-homedir@^1.0.0: resolved "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz" integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= +os-locale@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-5.0.0.tgz#6d26c1d95b6597c5d5317bf5fba37eccec3672e0" + integrity sha512-tqZcNEDAIZKBEPnHPlVDvKrp7NzgLi7jRmhKiUoa2NUmhl13FtkAGLUVR+ZsYvApBQdBfYm43A4tXXQ4IrYLBA== + dependencies: + execa "^4.0.0" + lcid "^3.0.0" + mem "^5.0.0" + +os-shim@^0.1.2: + version "0.1.3" + resolved "https://registry.yarnpkg.com/os-shim/-/os-shim-0.1.3.tgz#6b62c3791cf7909ea35ed46e17658bb417cb3917" + integrity sha512-jd0cvB8qQ5uVt0lvCIexBaROw1KyKm5sbulg2fWOHjETisuCzWyt+eTZKEMs8v6HwzoGs8xik26jg7eCM6pS+A== + os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz" @@ -8660,11 +11803,26 @@ osenv@^0.1.4: os-homedir "^1.0.0" os-tmpdir "^1.0.0" +p-cancelable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" + integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== + +p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + integrity sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw== + p-finally@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz" integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= +p-is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" + integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== + p-limit@^1.1.0: version "1.3.0" resolved "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz" @@ -8679,7 +11837,7 @@ p-limit@^2.2.0: dependencies: p-try "^2.0.0" -p-limit@^3.0.2: +p-limit@^3.0.2, p-limit@^3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== @@ -8761,6 +11919,16 @@ p-waterfall@^2.1.1: dependencies: p-reduce "^2.0.0" +package-json@^6.3.0: + version "6.5.0" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0" + integrity sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ== + dependencies: + got "^9.6.0" + registry-auth-token "^4.0.0" + registry-url "^5.0.0" + semver "^6.2.0" + pacote@^11.2.6: version "11.3.5" resolved "https://registry.npmjs.org/pacote/-/pacote-11.3.5.tgz" @@ -8786,6 +11954,11 @@ pacote@^11.2.6: ssri "^8.0.1" tar "^6.1.0" +pako@~1.0.2: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + parent-module@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" @@ -8803,15 +11976,7 @@ parse-glob@^3.0.4: is-extglob "^1.0.0" is-glob "^2.0.0" -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - -parse-json@^5.0.0, parse-json@^5.2.0: +parse-json@5.2.0, parse-json@^5.0.0, parse-json@^5.2.0: version "5.2.0" resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== @@ -8821,6 +11986,14 @@ parse-json@^5.0.0, parse-json@^5.2.0: json-parse-even-better-errors "^2.3.0" lines-and-columns "^1.1.6" +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz" + integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + parse-path@^4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/parse-path/-/parse-path-4.0.4.tgz#4bf424e6b743fb080831f03b536af9fc43f0ffea" @@ -8897,7 +12070,7 @@ path-key@^3.0.0, path-key@^3.1.0: resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== -path-parse@^1.0.6: +path-parse@^1.0.6, path-parse@^1.0.7: version "1.0.7" resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== @@ -8983,6 +12156,35 @@ pinkie@^2.0.0: resolved "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz" integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= +pino-abstract-transport@v0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/pino-abstract-transport/-/pino-abstract-transport-0.5.0.tgz#4b54348d8f73713bfd14e3dc44228739aa13d9c0" + integrity sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ== + dependencies: + duplexify "^4.1.2" + split2 "^4.0.0" + +pino-std-serializers@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pino-std-serializers/-/pino-std-serializers-4.0.0.tgz#1791ccd2539c091ae49ce9993205e2cd5dbba1e2" + integrity sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q== + +pino@7.9.1: + version "7.9.1" + resolved "https://registry.yarnpkg.com/pino/-/pino-7.9.1.tgz#7e6f401cac6e80b4eaee908ab90a05e48455cec2" + integrity sha512-28+D7c5orCoScdcWtiPXrCA9tdVosBWrYQgVtPdYTyiuTt6u/+rbEtpJR+dtVG8k1flhv0H2f0XSkgGm+TdjqQ== + dependencies: + fast-redact "^3.0.0" + on-exit-leak-free "^0.2.0" + pino-abstract-transport v0.5.0 + pino-std-serializers "^4.0.0" + process-warning "^1.0.0" + quick-format-unescaped "^4.0.3" + real-require "^0.1.0" + safe-stable-stringify "^2.1.0" + sonic-boom "^2.2.1" + thread-stream "^0.13.0" + pirates@^4.0.1: version "4.0.1" resolved "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz" @@ -9026,6 +12228,16 @@ pngjs@^4.0.1: resolved "https://registry.npmjs.org/pngjs/-/pngjs-4.0.1.tgz" integrity sha512-rf5+2/ioHeQxR6IxuYNYGFytUyG3lma/WW1nsmjeHlWwtb2aByla6dkVc8pmJ9nplzkTA0q2xx7mMWrOTqT4Gg== +popmotion@11.0.5: + version "11.0.5" + resolved "https://registry.yarnpkg.com/popmotion/-/popmotion-11.0.5.tgz#8e3e014421a0ffa30ecd722564fd2558954e1f7d" + integrity sha512-la8gPM1WYeFznb/JqF4GiTkRRPZsfaj2+kCxqQgr2MJylMmIKUwBfWW8Wa5fml/8gmtlD5yI01MP1QCZPWmppA== + dependencies: + framesync "6.1.2" + hey-listen "^1.0.8" + style-value-types "5.1.2" + tslib "2.4.0" + postcss-calc@^7.0.1: version "7.0.5" resolved "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.5.tgz" @@ -9383,6 +12595,15 @@ postcss@6.0.1: source-map "^0.5.6" supports-color "^3.2.3" +postcss@8.4.12: + version "8.4.12" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.12.tgz#1e7de78733b28970fa4743f7da6f3763648b1905" + integrity sha512-lg6eITwYe9v6Hr5CncVbK70SoioNQIq81nsaG86ev5hAidQvmOeETBqs7jm43K2F5/Ley3ytDtriImV6TpNiSg== + dependencies: + nanoid "^3.3.1" + picocolors "^1.0.0" + source-map-js "^1.0.2" + postcss@^6.0.1, postcss@^6.0.11: version "6.0.23" resolved "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz" @@ -9400,6 +12621,15 @@ postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.27: picocolors "^0.2.1" source-map "^0.6.1" +postcss@^8.4.16: + version "8.4.18" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.18.tgz#6d50046ea7d3d66a85e0e782074e7203bc7fbca2" + integrity sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA== + dependencies: + nanoid "^3.3.4" + picocolors "^1.0.0" + source-map-js "^1.0.2" + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" @@ -9410,6 +12640,11 @@ prelude-ls@~1.1.2: resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + integrity sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA== + preserve@^0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz" @@ -9447,11 +12682,25 @@ pretty-format@^27.5.1: ansi-styles "^5.0.0" react-is "^17.0.1" +pretty-format@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.2.0.tgz#1d4ea56fb46079b44efd9ed59c14f70f2950a61b" + integrity sha512-QCSUFdwOi924g24czhOH5eTkXxUCqlLGZBRCySlwDYHIXRJkdGyjJc9nZaqhlFBZws8dq5Dvk0lCilsmlfsPxw== + dependencies: + "@jest/schemas" "^29.0.0" + ansi-styles "^5.0.0" + react-is "^18.0.0" + process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== +process-warning@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/process-warning/-/process-warning-1.0.0.tgz#980a0b25dc38cd6034181be4b7726d89066b4616" + integrity sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q== + progress@^2.0.1: version "2.0.3" resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz" @@ -9470,6 +12719,13 @@ promise-retry@^2.0.1: err-code "^2.0.2" retry "^0.12.0" +promise-toolbox@0.20.0: + version "0.20.0" + resolved "https://registry.yarnpkg.com/promise-toolbox/-/promise-toolbox-0.20.0.tgz#af04d7338038c2362b8fb7c27546c57d893bf562" + integrity sha512-VXF6waqUheD19yOU7zxsXhw/HCKlXqXwUc4jM8mchtBqZFNA+GHA7dbJsQDLHP4IUpQuTLpCQRd0lCr5z4CqXQ== + dependencies: + make-error "^1.3.2" + promise.series@^0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/promise.series/-/promise.series-0.2.0.tgz" @@ -9490,6 +12746,15 @@ promzard@^0.3.0: dependencies: read "1" +prop-types@^15.6.2: + version "15.8.1" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.13.1" + proto-list@~1.2.1: version "1.2.4" resolved "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz" @@ -9536,6 +12801,13 @@ punycode@^2.1.0, punycode@^2.1.1: resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== +pupa@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.1.1.tgz#f5e8fd4afc2c5d97828faa523549ed8744a20d62" + integrity sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A== + dependencies: + escape-goat "^2.0.0" + puppeteer@^1.15.0: version "1.20.0" resolved "https://registry.npmjs.org/puppeteer/-/puppeteer-1.20.0.tgz" @@ -9605,6 +12877,18 @@ queue-microtask@^1.2.2: resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== +queue@6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/queue/-/queue-6.0.2.tgz#b91525283e2315c7553d2efa18d83e76432fed65" + integrity sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA== + dependencies: + inherits "~2.0.3" + +quick-format-unescaped@^4.0.3: + version "4.0.4" + resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz#93ef6dd8d3453cbc7970dd614fad4c5954d6b5a7" + integrity sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg== + quick-lru@^4.0.1: version "4.0.1" resolved "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz" @@ -9631,21 +12915,133 @@ range-parser@~1.2.1: resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -raw-body@2.4.0: - version "2.4.0" - resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz" - integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== +raw-body@2.4.0: + version "2.4.0" + resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz" + integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== + dependencies: + bytes "3.1.0" + http-errors "1.7.2" + iconv-lite "0.4.24" + unpipe "1.0.0" + +rc@1.2.8, rc@^1.2.8: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +react-clientside-effect@^1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/react-clientside-effect/-/react-clientside-effect-1.2.6.tgz#29f9b14e944a376b03fb650eed2a754dd128ea3a" + integrity sha512-XGGGRQAKY+q25Lz9a/4EPqom7WRjz3z9R2k4jhVKA/puQFH/5Nt27vFZYql4m4NVNdUvX8PS3O7r/Zzm7cjUlg== + dependencies: + "@babel/runtime" "^7.12.13" + +react-dom@^18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" + integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== dependencies: - bytes "3.1.0" - http-errors "1.7.2" - iconv-lite "0.4.24" - unpipe "1.0.0" + loose-envify "^1.1.0" + scheduler "^0.23.0" + +react-fast-compare@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb" + integrity sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA== + +react-focus-lock@^2.9.1: + version "2.9.1" + resolved "https://registry.yarnpkg.com/react-focus-lock/-/react-focus-lock-2.9.1.tgz#094cfc19b4f334122c73bb0bff65d77a0c92dd16" + integrity sha512-pSWOQrUmiKLkffPO6BpMXN7SNKXMsuOakl652IBuALAu1esk+IcpJyM+ALcYzPTTFz1rD0R54aB9A4HuP5t1Wg== + dependencies: + "@babel/runtime" "^7.0.0" + focus-lock "^0.11.2" + prop-types "^15.6.2" + react-clientside-effect "^1.2.6" + use-callback-ref "^1.3.0" + use-sidecar "^1.1.2" + +react-icons@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.6.0.tgz#f83eda179af5d02c047449a20b702c858653d397" + integrity sha512-rR/L9m9340yO8yv1QT1QurxWQvWpbNHqVX0fzMln2HEb9TEIrQRGsqiNFQfiv9/JEUbyHmHPlNTB2LWm2Ttz0g== + +react-is@^16.13.1, react-is@^16.7.0: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== react-is@^17.0.1: version "17.0.2" resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== +react-is@^18.0.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" + integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== + +react-refresh@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.0.tgz#4e02825378a5f227079554d4284889354e5f553e" + integrity sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ== + +react-remove-scroll-bar@^2.3.3: + version "2.3.4" + resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.4.tgz#53e272d7a5cb8242990c7f144c44d8bd8ab5afd9" + integrity sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A== + dependencies: + react-style-singleton "^2.2.1" + tslib "^2.0.0" + +react-remove-scroll@^2.5.4: + version "2.5.5" + resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz#1e31a1260df08887a8a0e46d09271b52b3a37e77" + integrity sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw== + dependencies: + react-remove-scroll-bar "^2.3.3" + react-style-singleton "^2.2.1" + tslib "^2.1.0" + use-callback-ref "^1.3.0" + use-sidecar "^1.1.2" + +react-router-dom@^6.4.1: + version "6.4.2" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.4.2.tgz#115b37d501d6d8ac870683694978c51c43e6c0d2" + integrity sha512-yM1kjoTkpfjgczPrcyWrp+OuQMyB1WleICiiGfstnQYo/S8hPEEnVjr/RdmlH6yKK4Tnj1UGXFSa7uwAtmDoLQ== + dependencies: + "@remix-run/router" "1.0.2" + react-router "6.4.2" + +react-router@6.4.2: + version "6.4.2" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.4.2.tgz#300628ee9ed81b8ef1597b5cb98b474efe9779b8" + integrity sha512-Rb0BAX9KHhVzT1OKhMvCDMw776aTYM0DtkxqUBP8dNBom3mPXlfNs76JNGK8wKJ1IZEY1+WGj+cvZxHVk/GiKw== + dependencies: + "@remix-run/router" "1.0.2" + +react-style-singleton@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/react-style-singleton/-/react-style-singleton-2.2.1.tgz#f99e420492b2d8f34d38308ff660b60d0b1205b4" + integrity sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g== + dependencies: + get-nonce "^1.0.0" + invariant "^2.2.4" + tslib "^2.0.0" + +react@^18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" + integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== + dependencies: + loose-envify "^1.1.0" + read-cache@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz" @@ -9777,6 +13173,11 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" +real-require@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/real-require/-/real-require-0.1.0.tgz#736ac214caa20632847b7ca8c1056a0767df9381" + integrity sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg== + realpath-native@^1.0.0: version "1.1.0" resolved "https://registry.npmjs.org/realpath-native/-/realpath-native-1.1.0.tgz" @@ -9797,6 +13198,11 @@ regenerator-runtime@^0.11.0: resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz" integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== +regenerator-runtime@^0.13.4: + version "0.13.10" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz#ed07b19616bcbec5da6274ebc75ae95634bfc2ee" + integrity sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw== + regex-cache@^0.4.2: version "0.4.4" resolved "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz" @@ -9804,11 +13210,42 @@ regex-cache@^0.4.2: dependencies: is-equal-shallow "^0.1.3" +regexp.prototype.flags@^1.2.0: + version "1.4.3" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" + integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + functions-have-names "^1.2.2" + regexpp@^3.2.0: version "3.2.0" resolved "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== +registry-auth-token@^4.0.0: + version "4.2.2" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.2.tgz#f02d49c3668884612ca031419491a13539e21fac" + integrity sha512-PC5ZysNb42zpFME6D/XlIgtNGdTl8bBOCw90xQLVMpzuuubJKYDWFAEuUNc+Cn8Z8724tg2SDhDRrkVEsqfDMg== + dependencies: + rc "1.2.8" + +registry-url@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-5.1.0.tgz#e98334b50d5434b81136b44ec638d9c2009c5009" + integrity sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw== + dependencies: + rc "^1.2.8" + +relaxed-json@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/relaxed-json/-/relaxed-json-1.0.3.tgz#eb2101ae0ee60e82267d95ed0ddf19a3604b8c1e" + integrity sha512-b7wGPo7o2KE/g7SqkJDDbav6zmrEeP4TK2VpITU72J/M949TLe/23y/ZHJo+pskcGM52xIfFoT9hydwmgr1AEg== + dependencies: + chalk "^2.4.2" + commander "^2.6.0" + remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz" @@ -9824,7 +13261,7 @@ repeat-string@^1.5.2, repeat-string@^1.6.1: resolved "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= -request@^2.88.0, request@^2.88.2: +request@2.88.2, request@^2.88.0, request@^2.88.2: version "2.88.2" resolved "https://registry.npmjs.org/request/-/request-2.88.2.tgz" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== @@ -9855,6 +13292,11 @@ require-directory@^2.1.1: resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + require-relative@^0.8.7: version "0.8.7" resolved "https://registry.npmjs.org/require-relative/-/require-relative-0.8.7.tgz" @@ -9900,6 +13342,15 @@ resolve@^1.1.7, resolve@^1.10.0, resolve@^1.16.1, resolve@^1.17.0, resolve@^1.19 is-core-module "^2.2.0" path-parse "^1.0.6" +resolve@^1.22.1: + version "1.22.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" + integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== + dependencies: + is-core-module "^2.9.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + resolve@~1.19.0: version "1.19.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c" @@ -9908,6 +13359,13 @@ resolve@~1.19.0: is-core-module "^2.1.0" path-parse "^1.0.6" +responselike@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + integrity sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ== + dependencies: + lowercase-keys "^1.0.0" + restore-cursor@^3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz" @@ -9958,6 +13416,13 @@ rimraf@^3.0.0, rimraf@^3.0.2: dependencies: glob "^7.1.3" +rimraf@~2.4.0: + version "2.4.5" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.4.5.tgz#ee710ce5d93a8fdb856fb5ea8ff0e2d75934b2da" + integrity sha512-J5xnxTyqaiw06JjMftq7L9ouA448dw/E7dKghkP9WpKNuwmARNNg+Gk8/u5ryb9N/Yo2+z3MCwuqFK/+qPOPfQ== + dependencies: + glob "^6.0.1" + rollup-plugin-css-only@^3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/rollup-plugin-css-only/-/rollup-plugin-css-only-3.1.0.tgz" @@ -10081,6 +13546,13 @@ rollup@^2.71.1: optionalDependencies: fsevents "~2.3.2" +rollup@~2.78.0: + version "2.78.1" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.78.1.tgz#52fe3934d9c83cb4f7c4cb5fb75d88591be8648f" + integrity sha512-VeeCgtGi4P+o9hIg+xz4qQpRl6R401LWEXBmxYKOV4zlF82lyhgh2hTZnheFUbANE8l2A41F458iwj2vEYaXJg== + optionalDependencies: + fsevents "~2.3.2" + run-async@^2.4.0: version "2.4.1" resolved "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz" @@ -10139,12 +13611,22 @@ safe-identifier@^0.4.1: resolved "https://registry.npmjs.org/safe-identifier/-/safe-identifier-0.4.2.tgz" integrity sha512-6pNbSMW6OhAi9j+N8V+U715yBQsaWJ7eyEUaOrawX+isg5ZxhUlV1NipNtgaKHmFGiABwt+ZF04Ii+3Xjkg+8w== +safe-json-stringify@~1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz#356e44bc98f1f93ce45df14bcd7c01cda86e0afd" + integrity sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg== + +safe-stable-stringify@^2.1.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.4.0.tgz#95fadb1bcf8057a1363e11052122f5da36a69215" + integrity sha512-eehKHKpab6E741ud7ZIMcXhKcP6TSIezPkNZhy5U8xC6+VvrRdUA2tMgxGxaGl4cz7c2Ew5+mg5+wNB16KQqrA== + "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sax@~1.2.4: +sax@>=0.6.0, sax@~1.2.4: version "1.2.4" resolved "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== @@ -10156,6 +13638,20 @@ saxes@^5.0.1: dependencies: xmlchars "^2.2.0" +scheduler@^0.23.0: + version "0.23.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" + integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== + dependencies: + loose-envify "^1.1.0" + +semver-diff@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b" + integrity sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg== + dependencies: + semver "^6.3.0" + semver-match@0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/semver-match/-/semver-match-0.1.1.tgz#e7ccb31f83fd4a0e377d66387afd8ca3a329b5fc" @@ -10175,7 +13671,7 @@ semver@7.3.5, semver@7.x, semver@^7.1.1, semver@^7.1.3, semver@^7.3.2, semver@^7 dependencies: lru-cache "^6.0.0" -semver@^6.0.0, semver@^6.3.0: +semver@^6.0.0, semver@^6.2.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== @@ -10228,11 +13724,24 @@ set-blocking@~2.0.0: resolved "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= +setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== + setprototypeof@1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz" integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== +sha.js@2.4.11: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + shallow-clone@^3.0.0: version "3.0.1" resolved "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz" @@ -10264,6 +13773,16 @@ shebang-regex@^3.0.0: resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== +shell-quote@1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.3.tgz#aa40edac170445b9a431e17bb62c0b881b9c4123" + integrity sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw== + +shellwords@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" + integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== + side-channel@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" @@ -10273,11 +13792,32 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" +sign-addon@3.11.0: + version "3.11.0" + resolved "https://registry.yarnpkg.com/sign-addon/-/sign-addon-3.11.0.tgz#8c4e688ae8053b8e24ab03aa59e651f1bf66a9fb" + integrity sha512-fcK2WzkMb8e8E9kvuccy+mrBTT81iR+1CowHLU594Elr4E9E9zZFr3itGlL0OoXcRouKmvt7rpXzoARu++tXRQ== + dependencies: + common-tags "1.8.2" + core-js "3.21.0" + deepcopy "2.1.0" + es6-error "4.1.1" + es6-promisify "7.0.0" + jsonwebtoken "8.5.1" + mz "2.7.0" + request "2.88.2" + source-map-support "0.5.21" + stream-to-promise "3.0.0" + signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3: version "3.0.3" resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz" integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== +signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + simple-peer-light@^9.10.0: version "9.10.0" resolved "https://registry.yarnpkg.com/simple-peer-light/-/simple-peer-light-9.10.0.tgz#6f3699b80e4b6d3a9374a865e1a8e497aa623afb" @@ -10353,6 +13893,13 @@ socks@^2.3.3: ip "^1.1.5" smart-buffer "^4.1.0" +sonic-boom@^2.2.1: + version "2.8.0" + resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-2.8.0.tgz#c1def62a77425090e6ad7516aad8eb402e047611" + integrity sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg== + dependencies: + atomic-sleep "^1.0.0" + sort-keys@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz" @@ -10367,7 +13914,28 @@ sort-keys@^4.0.0: dependencies: is-plain-obj "^2.0.0" -source-map-support@^0.5.6, source-map-support@~0.5.20: +source-map-js@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + +source-map-support@0.5.13: + version "0.5.13" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" + integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-support@0.5.20: + version "0.5.20" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.20.tgz#12166089f8f5e5e8c56926b377633392dd2cb6c9" + integrity sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-support@0.5.21, source-map-support@^0.5.6, source-map-support@~0.5.20: version "0.5.21" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== @@ -10375,7 +13943,7 @@ source-map-support@^0.5.6, source-map-support@~0.5.20: buffer-from "^1.0.0" source-map "^0.6.0" -source-map@^0.5.0, source-map@^0.5.6: +source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7: version "0.5.7" resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= @@ -10390,7 +13958,7 @@ source-map@^0.7.3: resolved "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz" integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== -sourcemap-codec@^1.4.4: +sourcemap-codec@^1.4.4, sourcemap-codec@^1.4.8: version "1.4.8" resolved "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz" integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== @@ -10400,6 +13968,14 @@ spawn-command@^0.0.2-1: resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2-1.tgz#62f5e9466981c1b796dc5929937e11c9c6921bd0" integrity sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A= +spawn-sync@1.0.15: + version "1.0.15" + resolved "https://registry.yarnpkg.com/spawn-sync/-/spawn-sync-1.0.15.tgz#b00799557eb7fb0c8376c29d44e8a1ea67e57476" + integrity sha512-9DWBgrgYZzNghseho0JOuh+5fg9u6QWhAWa51QC7+U5rCheZ/j1DrEZnyE0RBBRqZ9uEXGPgSSM0nky6burpVw== + dependencies: + concat-stream "^1.4.7" + os-shim "^0.1.2" + spdx-correct@^3.0.0: version "3.1.1" resolved "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz" @@ -10438,6 +14014,11 @@ split2@^3.0.0: dependencies: readable-stream "^3.0.0" +split2@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/split2/-/split2-4.1.0.tgz#101907a24370f85bb782f08adaabe4e281ecf809" + integrity sha512-VBiJxFkxiXRlUIeyMQi8s4hgvKCSjtknJv/LVYbrgALPwf5zSKmEwV9Lst25AkvMDnvxODugjdl6KZgwKM1WYQ== + split@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/split/-/split-1.0.1.tgz" @@ -10445,6 +14026,13 @@ split@^1.0.0: dependencies: through "2" +split@~0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f" + integrity sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA== + dependencies: + through "2" + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" @@ -10501,6 +14089,27 @@ stack-utils@^2.0.3: resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= +stream-shift@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" + integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== + +stream-to-array@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/stream-to-array/-/stream-to-array-2.3.0.tgz#bbf6b39f5f43ec30bc71babcb37557acecf34353" + integrity sha512-UsZtOYEn4tWU2RGLOXr/o/xjRBftZRlG3dEWoaHr8j4GuypJ3isitGbVyjQKAuMu+xbiop8q224TjiZWc4XTZA== + dependencies: + any-promise "^1.1.0" + +stream-to-promise@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/stream-to-promise/-/stream-to-promise-3.0.0.tgz#8934d66dcbc9189394e8b33200da3bb9611db774" + integrity sha512-h+7wLeFiYegOdgTfTxjRsrT7/Op7grnKEIHWgaO1RTHwcwk7xRreMr3S8XpDfDMesSxzgM2V4CxNCFAGo6ssnA== + dependencies: + any-promise "~1.3.0" + end-of-stream "~1.4.1" + stream-to-array "~2.3.0" + strict-uri-encode@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" @@ -10536,6 +14145,15 @@ string-width@^1.0.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" +string-width@^4.0.0, string-width@^4.2.2, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + string-width@^4.1.0, string-width@^4.2.0: version "4.2.2" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz" @@ -10612,16 +14230,31 @@ strip-ansi@^7.0.1: dependencies: ansi-regex "^6.0.1" -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= +strip-bom-buf@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom-buf/-/strip-bom-buf-2.0.0.tgz#ff9c223937f8e7154b77e9de9bde094186885c15" + integrity sha512-gLFNHucd6gzb8jMsl5QmZ3QgnUJmp7qn4uUSHNwEXumAp7YizoGYw19ZUVfuq4aBOQUtyn2k8X/CwzWB73W2lQ== + dependencies: + is-utf8 "^0.2.1" + +strip-bom-stream@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-bom-stream/-/strip-bom-stream-4.0.0.tgz#4d21a651e723ef743a0a8b0d4534471805330cbb" + integrity sha512-0ApK3iAkHv6WbgLICw/J4nhwHeDZsBxIIsOD+gHgZICL6SeJ0S9f/WZqemka9cjkTyMN5geId6e8U5WGFAn3cQ== + dependencies: + first-chunk-stream "^3.0.0" + strip-bom-buf "^2.0.0" -strip-bom@^4.0.0: +strip-bom@4.0.0, strip-bom@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz" integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + strip-final-newline@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz" @@ -10634,11 +14267,16 @@ strip-indent@^3.0.0: dependencies: min-indent "^1.0.0" -strip-json-comments@^3.1.0, strip-json-comments@^3.1.1, strip-json-comments@~3.1.1: +strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1, strip-json-comments@~3.1.1: version "3.1.1" resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== + strip-outer@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz" @@ -10660,6 +14298,14 @@ style-inject@^0.3.0: resolved "https://registry.npmjs.org/style-inject/-/style-inject-0.3.0.tgz" integrity sha512-IezA2qp+vcdlhJaVm5SOdPPTUu0FCEqfNSli2vRuSIBbu5Nq5UvygTk/VzeCqfLz2Atj3dVII5QBKGZRZ0edzw== +style-value-types@5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/style-value-types/-/style-value-types-5.1.2.tgz#6be66b237bd546048a764883528072ed95713b62" + integrity sha512-Vs9fNreYF9j6W2VvuDTP7kepALi7sk0xtk2Tu8Yxi9UoajJdEVpNpCov0HsLTqXvNGKX+Uv09pkozVITi1jf3Q== + dependencies: + hey-listen "^1.0.8" + tslib "2.4.0" + stylehacks@^4.0.0: version "4.0.3" resolved "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz" @@ -10669,6 +14315,11 @@ stylehacks@^4.0.0: postcss "^7.0.0" postcss-selector-parser "^3.0.0" +stylis@4.0.13: + version "4.0.13" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.13.tgz#f5db332e376d13cc84ecfe5dace9a2a51d954c91" + integrity sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag== + supports-color@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz" @@ -10710,6 +14361,11 @@ supports-hyperlinks@^2.0.0: has-flag "^4.0.0" supports-color "^7.0.0" +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + svelte-check@^1.4.0: version "1.6.0" resolved "https://registry.npmjs.org/svelte-check/-/svelte-check-1.6.0.tgz" @@ -10863,6 +14519,27 @@ text-table@^0.2.0: resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= +thenify-all@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== + dependencies: + thenify ">= 3.1.0 < 4" + +"thenify@>= 3.1.0 < 4": + version "3.3.1" + resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" + integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== + dependencies: + any-promise "^1.0.0" + +thread-stream@^0.13.0: + version "0.13.2" + resolved "https://registry.yarnpkg.com/thread-stream/-/thread-stream-0.13.2.tgz#de8ea87584baee625c631947ec73494aa86131c8" + integrity sha512-woZFt0cLFkPdhsa+IGpRo1jiSouaHxMIljzTgt30CMjBWoUYbbcHqnunW5Yv+BXko9H05MVIcxMipI3Jblallw== + dependencies: + real-require "^0.1.0" + throat@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz" @@ -10893,11 +14570,23 @@ timsort@^0.3.0: resolved "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz" integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= +tiny-invariant@^1.0.6: + version "1.3.1" + resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.1.tgz#8560808c916ef02ecfd55e66090df23a4b7aa642" + integrity sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw== + tinydate@^1.0.0: version "1.3.0" resolved "https://registry.npmjs.org/tinydate/-/tinydate-1.3.0.tgz" integrity sha512-7cR8rLy2QhYHpsBDBVYnnWXm8uRTr38RoZakFSW7Bs7PzfMPNZthuMLkwqZv7MTu8lhQ91cOFYS5a7iFj2oR3w== +tmp@0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" + tmp@^0.0.33: version "0.0.33" resolved "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz" @@ -10905,7 +14594,7 @@ tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" -tmpl@1.0.x: +tmpl@1.0.5, tmpl@1.0.x: version "1.0.5" resolved "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz" integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== @@ -10920,6 +14609,11 @@ to-fast-properties@^2.0.0: resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz" integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= +to-readable-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" + integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== + to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" @@ -10927,11 +14621,21 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" +toggle-selection@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32" + integrity sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ== + toidentifier@1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz" integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== +tosource@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/tosource/-/tosource-1.0.0.tgz#42d88dd116618bcf00d6106dd5446f3427902ff1" + integrity sha512-N6g8eQ1eerw6Y1pBhdgkubWIiPFwXa2POSUrlL8jth5CyyEWNWzoGKRkO3CaO7Jx27hlJP54muB3btIAbx4MPg== + tough-cookie@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz" @@ -11011,6 +14715,20 @@ ts-jest@^27.1.3: semver "7.x" yargs-parser "20.x" +ts-jest@^29.0.1: + version "29.0.3" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.0.3.tgz#63ea93c5401ab73595440733cefdba31fcf9cb77" + integrity sha512-Ibygvmuyq1qp/z3yTh9QTwVVAbFdDy/+4BtIQR2sp6baF2SJU/8CKK/hhnGIDY2L90Az2jIqTwZPnN2p+BweiQ== + dependencies: + bs-logger "0.x" + fast-json-stable-stringify "2.x" + jest-util "^29.0.0" + json5 "^2.2.1" + lodash.memoize "4.x" + make-error "1.x" + semver "7.x" + yargs-parser "^21.0.1" + ts-node@^10.9.1: version "10.9.1" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" @@ -11044,6 +14762,11 @@ ts-node@^7.0.1: source-map-support "^0.5.6" yn "^2.0.0" +tslib@2.4.0, tslib@^2.0.3, tslib@^2.1.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" + integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== + tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: version "1.14.1" resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" @@ -11054,11 +14777,6 @@ tslib@^2.0.0, tslib@^2.2.0: resolved "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz" integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg== -tslib@^2.1.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" - integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== - tslib@^2.3.1: version "2.3.1" resolved "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz" @@ -11181,7 +14899,7 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" -type-detect@4.0.8: +type-detect@4.0.8, type-detect@^4.0.8: version "4.0.8" resolved "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== @@ -11226,6 +14944,11 @@ type-fest@^1.0.2: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1" integrity sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA== +type-fest@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" + integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== + type-is@~1.6.17, type-is@~1.6.18: version "1.6.18" resolved "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz" @@ -11251,6 +14974,11 @@ typescript@*, typescript@^4.7.3: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235" integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ== +typescript@^4.8.3: + version "4.8.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.4.tgz#c464abca159669597be5f96b8943500b238e60e6" + integrity sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ== + uc.micro@^1.0.1, uc.micro@^1.0.5: version "1.0.6" resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" @@ -11313,6 +15041,13 @@ unique-slug@^2.0.0: dependencies: imurmurhash "^0.1.4" +unique-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" + integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg== + dependencies: + crypto-random-string "^2.0.0" + universal-user-agent@^6.0.0: version "6.0.0" resolved "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz" @@ -11323,6 +15058,11 @@ universalify@^0.1.2: resolved "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== +universalify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-1.0.0.tgz#b61a1da173e8435b2fe3c67d29b9adf8594bd16d" + integrity sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug== + universalify@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz" @@ -11347,7 +15087,7 @@ upath2@^3.1.12: path-strip-sep "^1.0.10" tslib "^2.3.1" -upath@^2.0.1: +upath@2.0.1, upath@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/upath/-/upath-2.0.1.tgz" integrity sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w== @@ -11360,6 +15100,26 @@ update-browserslist-db@^1.0.9: escalade "^3.1.1" picocolors "^1.0.0" +update-notifier@5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-5.1.0.tgz#4ab0d7c7f36a231dd7316cf7729313f0214d9ad9" + integrity sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw== + dependencies: + boxen "^5.0.0" + chalk "^4.1.0" + configstore "^5.0.1" + has-yarn "^2.1.0" + import-lazy "^2.1.0" + is-ci "^2.0.0" + is-installed-globally "^0.4.0" + is-npm "^5.0.0" + is-yarn-global "^0.3.0" + latest-version "^5.1.0" + pupa "^2.1.1" + semver "^7.3.4" + semver-diff "^3.1.1" + xdg-basedir "^4.0.0" + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" @@ -11367,6 +15127,28 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + integrity sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ== + dependencies: + prepend-http "^2.0.0" + +use-callback-ref@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/use-callback-ref/-/use-callback-ref-1.3.0.tgz#772199899b9c9a50526fedc4993fc7fa1f7e32d5" + integrity sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w== + dependencies: + tslib "^2.0.0" + +use-sidecar@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.1.2.tgz#2f43126ba2d7d7e117aa5855e5d8f0276dfe73c2" + integrity sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw== + dependencies: + detect-node-es "^1.1.0" + tslib "^2.0.0" + util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" @@ -11410,6 +15192,11 @@ uuid@^3.3.2: resolved "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== +uuid@^8.3.0: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + v8-compile-cache-lib@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" @@ -11429,6 +15216,15 @@ v8-to-istanbul@^8.1.0: convert-source-map "^1.6.0" source-map "^0.7.3" +v8-to-istanbul@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz#b6f994b0b5d4ef255e17a0d17dc444a9f5132fa4" + integrity sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w== + dependencies: + "@jridgewell/trace-mapping" "^0.3.12" + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" + validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: version "3.0.4" resolved "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz" @@ -11463,6 +15259,34 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" +vite-plugin-web-extension@^1.4.4: + version "1.4.4" + resolved "https://registry.yarnpkg.com/vite-plugin-web-extension/-/vite-plugin-web-extension-1.4.4.tgz#942c6605623c312cd20b86d9b640a192bff892a0" + integrity sha512-X1MGWdYI45Gcp8W+Yc2aq+k/nHWBQ6bMDgGbGn05JVIREsxtpZa7Bh4KKAEV32d9zTnz6aiaSXyAi8usexbyyg== + dependencies: + ajv "^8.8.1" + md5 "^2.3.0" + web-ext "^6.5.0" + +vite-plugin-zip@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/vite-plugin-zip/-/vite-plugin-zip-1.0.1.tgz#a72ad7f29ddc873f7d6f3917397fd008a6badaa3" + integrity sha512-DdQQGq8eSLwMHtFmzwKZ/h59qaeSNsSFM6TKiUsHl2Cx2D1KD0iJD9OQP7rLOSEZCPoUoUvW45G2nJNcr0qlEg== + dependencies: + yazl "^2.5.1" + +vite@^3.1.2: + version "3.1.8" + resolved "https://registry.yarnpkg.com/vite/-/vite-3.1.8.tgz#fa29144167d19b773baffd65b3972ea4c12359c9" + integrity sha512-m7jJe3nufUbuOfotkntGFupinL/fmuTNuQmiVE7cH2IZMuf4UbfbGYMUT3jVWgGYuRVLY9j8NnrRqgw5rr5QTg== + dependencies: + esbuild "^0.15.9" + postcss "^8.4.16" + resolve "^1.22.1" + rollup "~2.78.0" + optionalDependencies: + fsevents "~2.3.2" + w3c-hr-time@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz" @@ -11484,6 +15308,21 @@ walker@^1.0.7: dependencies: makeerror "1.0.x" +walker@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" + integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== + dependencies: + makeerror "1.0.12" + +watchpack@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.1.1.tgz#e99630550fca07df9f90a06056987baa40a689c7" + integrity sha512-Oo7LXCmc1eE1AjyuSBmtC3+Wy4HcV8PxWh2kP6fOl8yTlNS7r0K9l1ao2lrrUza7V39Y3D/BbJgY8VeSlc5JKw== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + wcwidth@^1.0.0, wcwidth@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz" @@ -11491,6 +15330,47 @@ wcwidth@^1.0.0, wcwidth@^1.0.1: dependencies: defaults "^1.0.3" +web-ext@^6.5.0: + version "6.8.0" + resolved "https://registry.yarnpkg.com/web-ext/-/web-ext-6.8.0.tgz#bc8d1ee478a0a1444f48159e80d492f7bf2fb9fc" + integrity sha512-qZ3a4YVs0Vdqet44QRZEcNUQznkrfhsAkSOnZp57O4T4A9Bo3pamePSBeRqdPdJv9GF8ntKG84o3eV0MrEvLbw== + dependencies: + "@babel/runtime" "7.13.9" + "@devicefarmer/adbkit" "2.11.3" + addons-linter "4.14.0" + bunyan "1.8.15" + camelcase "6.2.0" + chrome-launcher "0.15.0" + debounce "1.2.0" + decamelize "5.0.0" + es6-error "4.1.1" + firefox-profile "4.2.2" + fs-extra "9.1.0" + fx-runner "1.2.0" + import-fresh "3.3.0" + mkdirp "1.0.4" + multimatch "5.0.0" + mz "2.7.0" + node-notifier "9.0.0" + open "7.4.2" + parse-json "5.2.0" + promise-toolbox "0.20.0" + sign-addon "3.11.0" + source-map-support "0.5.20" + strip-bom "4.0.0" + strip-json-comments "3.1.1" + tmp "0.2.1" + update-notifier "5.1.0" + watchpack "2.1.1" + ws "7.4.6" + yargs "16.2.0" + zip-dir "2.0.0" + +webextension-polyfill@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/webextension-polyfill/-/webextension-polyfill-0.10.0.tgz#ccb28101c910ba8cf955f7e6a263e662d744dbb8" + integrity sha512-c5s35LgVa5tFaHhrZDnr3FpQpjj1BB+RXhLTYUxGqBVN460HkbM8TBtEqdXWbpTKfzwCcjAZVF7zXCYSKtcp9g== + webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz" @@ -11535,6 +15415,11 @@ whatwg-url@^8.0.0, whatwg-url@^8.4.0, whatwg-url@^8.5.0: tr46 "^2.1.0" webidl-conversions "^6.1.0" +when@3.7.7: + version "3.7.7" + resolved "https://registry.yarnpkg.com/when/-/when-3.7.7.tgz#aba03fc3bb736d6c88b091d013d8a8e590d84718" + integrity sha512-9lFZp/KHoqH6bPKjbWqa+3Dg/K/r2v0X/3/G2x4DBGchVS2QX2VXL3cZV994WQVnTM1/PD71Az25nAzryEUugw== + which-boxed-primitive@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz" @@ -11546,6 +15431,14 @@ which-boxed-primitive@^1.0.2: is-string "^1.0.5" is-symbol "^1.0.3" +which@1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/which/-/which-1.2.4.tgz#1557f96080604e5b11b3599eb9f45b50a9efd722" + integrity sha512-zDRAqDSBudazdfM9zpiI30Fu9ve47htYXcGi3ln0wfKu2a7SmrT6F3VDoYONu//48V8Vz4TdCRNPjtvyRO3yBA== + dependencies: + is-absolute "^0.1.7" + isexe "^1.1.1" + which@^1.2.9, which@^1.3.1: version "1.3.1" resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz" @@ -11567,6 +15460,18 @@ wide-align@^1.1.0: dependencies: string-width "^1.0.2 || 2" +widest-line@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" + integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== + dependencies: + string-width "^4.0.0" + +winreg@0.0.12: + version "0.0.12" + resolved "https://registry.yarnpkg.com/winreg/-/winreg-0.0.12.tgz#07105554ba1a9d08979251d129475bffae3006b7" + integrity sha512-typ/+JRmi7RqP1NanzFULK36vczznSNN8kWVA9vIqXyv8GhghUlwhGp1Xj3Nms1FsPcNnsQrJOR10N58/nQ9hQ== + word-wrap@^1.2.3, word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz" @@ -11619,6 +15524,14 @@ write-file-atomic@^3.0.0, write-file-atomic@^3.0.3: signal-exit "^3.0.2" typedarray-to-buffer "^3.1.5" +write-file-atomic@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" + integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== + dependencies: + imurmurhash "^0.1.4" + signal-exit "^3.0.7" + write-json-file@^3.2.0: version "3.2.0" resolved "https://registry.npmjs.org/write-json-file/-/write-json-file-3.2.0.tgz" @@ -11652,6 +15565,11 @@ write-pkg@^4.0.0: type-fest "^0.4.1" write-json-file "^3.2.0" +ws@7.4.6: + version "7.4.6" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" + integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== + ws@^6.1.0: version "6.2.2" resolved "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz" @@ -11674,11 +15592,29 @@ ws@^7.4.6: resolved "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz" integrity sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w== +xdg-basedir@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" + integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== + xml-name-validator@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz" integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== +xml2js@~0.4.23: + version "0.4.23" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" + integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== + dependencies: + sax ">=0.6.0" + xmlbuilder "~11.0.0" + +xmlbuilder@~11.0.0: + version "11.0.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" + integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== + xmlchars@^2.2.0: version "2.2.0" resolved "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz" @@ -11727,7 +15663,12 @@ yargs-parser@^18.1.3: camelcase "^5.0.0" decamelize "^1.2.0" -yargs@^16.2.0: +yargs-parser@^21.0.0, yargs-parser@^21.0.1: + version "21.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + +yargs@16.2.0, yargs@^16.2.0: version "16.2.0" resolved "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz" integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== @@ -11740,7 +15681,33 @@ yargs@^16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" -yauzl@^2.10.0: +yargs@17.4.0: + version "17.4.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.4.0.tgz#9fc9efc96bd3aa2c1240446af28499f0e7593d00" + integrity sha512-WJudfrk81yWFSOkZYpAZx4Nt7V4xp7S/uJkX0CnxovMCt1wCE8LNftPpNuF9X/u9gN5nsD7ycYtRcDf2pL3UiA== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.0.0" + +yargs@^17.3.1: + version "17.6.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.6.0.tgz#e134900fc1f218bc230192bdec06a0a5f973e46c" + integrity sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g== + dependencies: + cliui "^8.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.0.0" + +yauzl@2.10.0, yauzl@^2.10.0: version "2.10.0" resolved "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz" integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk= @@ -11748,6 +15715,13 @@ yauzl@^2.10.0: buffer-crc32 "~0.2.3" fd-slicer "~1.1.0" +yazl@^2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/yazl/-/yazl-2.5.1.tgz#a3d65d3dd659a5b0937850e8609f22fffa2b5c35" + integrity sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw== + dependencies: + buffer-crc32 "~0.2.3" + yn@3.1.1: version "3.1.1" resolved "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz" @@ -11762,3 +15736,11 @@ yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +zip-dir@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/zip-dir/-/zip-dir-2.0.0.tgz#c5df6e15c8f9efeb4e320377028c9f5c8277c932" + integrity sha512-uhlsJZWz26FLYXOD6WVuq+fIcZ3aBPGo/cFdiLlv3KNwpa52IF3ISV8fLhQLiqVu5No3VhlqlgthN6gehil1Dg== + dependencies: + async "^3.2.0" + jszip "^3.2.2" From be295bdddb5bac34af87b3ebc09be38cb8282bee Mon Sep 17 00:00:00 2001 From: Yun Feng Date: Mon, 17 Oct 2022 19:34:01 +1100 Subject: [PATCH 02/40] refactor: make the extension suitable for manifest v3 --- packages/web-extension/package.json | 14 +- .../web-extension/src/background/index.ts | 39 +-- packages/web-extension/src/content/index.ts | 167 ++++------ packages/web-extension/src/content/inject.ts | 59 ++++ packages/web-extension/src/manifest.json | 83 +++-- packages/web-extension/src/options/App.tsx | 13 +- .../src/options/RRWebVersion.tsx | 312 ------------------ packages/web-extension/src/pages/Player.tsx | 16 +- packages/web-extension/src/types.ts | 32 +- packages/web-extension/src/utils/index.ts | 46 --- packages/web-extension/vite.config.ts | 30 +- yarn.lock | 7 +- 12 files changed, 238 insertions(+), 580 deletions(-) create mode 100644 packages/web-extension/src/content/inject.ts delete mode 100644 packages/web-extension/src/options/RRWebVersion.tsx diff --git a/packages/web-extension/package.json b/packages/web-extension/package.json index a48f4dff2a..8809fa9016 100644 --- a/packages/web-extension/package.json +++ b/packages/web-extension/package.json @@ -1,8 +1,10 @@ { "name": "web-extension", - "version": "0.2.0", + "version": "2.0.0", "description": "The web extension of rrweb which helps to run rrweb on any website out of box", "author": "Yanzhen Yu, Yun Feng", + "license": "MIT", + "private": true, "scripts": { "dev:chrome": "cross-env TARGET_BROWSER=chrome vite dev", "dev:firefox": "cross-env TARGET_BROWSER=firefox vite dev", @@ -20,12 +22,10 @@ "@vitejs/plugin-react": "^2.1.0", "cross-env": "^7.0.3", "jest": "^29.0.3", - "rrweb": "^2.0.0-alpha.3", - "rrweb-player": "^1.0.0-alpha.3", "ts-jest": "^29.0.1", "type-fest": "^2.19.0", - "typescript": "^4.8.3", - "vite": "^3.1.2", + "typescript": "^4.7.3", + "vite": "^3.1.8", "vite-plugin-web-extension": "^1.4.4", "vite-plugin-zip": "^1.0.1", "webextension-polyfill": "^0.10.0" @@ -40,6 +40,8 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-icons": "^4.4.0", - "react-router-dom": "^6.4.1" + "react-router-dom": "^6.4.1", + "rrweb": "^2.0.0-alpha.3", + "rrweb-player": "^1.0.0-alpha.3" } } diff --git a/packages/web-extension/src/background/index.ts b/packages/web-extension/src/background/index.ts index ee82a357e2..2205573772 100644 --- a/packages/web-extension/src/background/index.ts +++ b/packages/web-extension/src/background/index.ts @@ -1,23 +1,12 @@ import Browser from 'webextension-polyfill'; import { Settings, SyncData, SyncDataKey } from '../types'; -import { fetchPackageVersions, getPlayerURL, getRecorderURL } from '../utils'; void (async () => { - const recorderVersions = await fetchPackageVersions('rrweb'); - const playerVersions = await fetchPackageVersions('rrweb-player'); - // Use the latest version. - const defaultRecorderVersion = recorderVersions[0]; - const defaultPlayerVersion = playerVersions[0]; // assign default value to settings of this extension const result = ((await Browser.storage.sync.get(SyncDataKey.settings)) as SyncData) || undefined; - const defaultSettings: Settings = { - recorderURL: getRecorderURL(defaultRecorderVersion), - recorderVersion: defaultRecorderVersion, - playerURL: getPlayerURL(defaultPlayerVersion), - playerVersion: defaultPlayerVersion, - }; + const defaultSettings: Settings = {}; let settings = defaultSettings; if (result && result.settings) { setDefaultSettings(result.settings, defaultSettings); @@ -26,16 +15,8 @@ void (async () => { await Browser.storage.sync.set({ settings, } as SyncData); - void fetchSourceCode(settings); })(); -Browser.storage.onChanged.addListener((changes, area) => { - if (area === 'sync' && changes.settings) { - const newValue = changes.settings.newValue as Settings; - void fetchSourceCode(newValue); - } -}); - /** * Update existed settings with new settings. * Set new setting values if these properties don't exist in older versions. @@ -66,21 +47,3 @@ function setDefaultSettings( } } } - -/** - * Fetch rrweb source code from recorder URL and player URL. - */ -async function fetchSourceCode(settings: Settings) { - if (settings.recorderURL) { - const code = await (await fetch(settings.recorderURL)).text(); - await Browser.storage.local.set({ - recorder_code: code, - }); - } - if (settings.playerURL) { - const code = await (await fetch(settings.playerURL)).text(); - await Browser.storage.local.set({ - player_code: code, - }); - } -} diff --git a/packages/web-extension/src/content/index.ts b/packages/web-extension/src/content/index.ts index b0aa66acff..e0f2afb6d5 100644 --- a/packages/web-extension/src/content/index.ts +++ b/packages/web-extension/src/content/index.ts @@ -7,10 +7,10 @@ import { RecorderStatus, ServiceName, Session, - StartRecordResponse, - StopRecordResponse, - SyncData, - SyncDataKey, + RecordStartedMessage, + RecordStoppedMessage, + HeartBreathMessage, + MessageName, } from '../types'; import Channel from '../utils/channel'; @@ -18,131 +18,86 @@ const channel = new Channel(); void (async () => { let storedEvents: eventWithTime[] = []; - let startResponseCb: ((response: StartRecordResponse) => void) | undefined = - undefined; + let startResponseCb: + | ((response: RecordStartedMessage) => void) + | undefined = undefined; // The callback function to remove the recorder from the page. let clearRecorderCb: (() => void) | undefined = undefined; channel.provide(ServiceName.StartRecord, async () => { - clearRecorderCb = await startRecord(); - window.postMessage({ message: 'start-record' }); + clearRecorderCb = startRecord(); return new Promise((resolve) => { startResponseCb = (response) => { resolve(response); }; }); }); - let stopResponseCb: ((response: StopRecordResponse) => void) | undefined = - undefined; + let stopResponseCb: + | ((response: RecordStoppedMessage) => void) + | undefined = undefined; channel.provide(ServiceName.StopRecord, () => { - window.postMessage({ message: 'stop-record' }); + window.postMessage({ message: MessageName.StopRecord }); return new Promise((resolve) => { - stopResponseCb = (response: StopRecordResponse) => { + stopResponseCb = (response: RecordStoppedMessage) => { resolve(response); }; }); }); - window.addEventListener('message', (event) => { - const data = event.data as - | StartRecordResponse - | StopRecordResponse - | HeartBreathMessage; - if (data.message === 'start-record-response' && startResponseCb) - startResponseCb(data); - else if (data.message === 'stop-record-response' && stopResponseCb) { - stopResponseCb(data); - void saveEvents(storedEvents.concat(data.events)); - clearRecorderCb?.(); - clearRecorderCb = undefined; - storedEvents = []; - } else if (data.message === 'heart-beat') { - const events = data.events; - void Browser.storage.local.set({ - [LocalDataKey.bufferedEvents]: storedEvents.concat(events), - }); - } - }); + window.addEventListener( + 'message', + (event: { + data: + | RecordStartedMessage + | RecordStoppedMessage + | HeartBreathMessage + | { + message: MessageName; + }; + }) => { + if (event.data.message === MessageName.RecordScriptReady) + window.postMessage({ message: MessageName.StartRecord }); + else if ( + event.data.message === MessageName.RecordStarted && + startResponseCb + ) + startResponseCb(event.data as RecordStartedMessage); + else if ( + event.data.message === MessageName.RecordStopped && + stopResponseCb + ) { + const data = event.data as RecordStoppedMessage; + stopResponseCb(data); + void saveEvents(storedEvents.concat(data.events)); + clearRecorderCb?.(); + clearRecorderCb = undefined; + storedEvents = []; + } else if (event.data.message === MessageName.HeartBeat) { + void Browser.storage.local.set({ + [LocalDataKey.bufferedEvents]: storedEvents.concat( + (event.data as HeartBreathMessage).events, + ), + }); + } + }, + ); const localData = (await Browser.storage.local.get()) as LocalData; if (localData?.recorder_status?.status === RecorderStatus.RECORDING) { - clearRecorderCb = await startRecord(); + clearRecorderCb = startRecord(); storedEvents = localData.buffered_events || []; } })(); -async function startRecord() { - const data = await Browser.storage.local.get('recorder_code'); - const recorderCode = data['recorder_code'] as string | undefined; - if (!recorderCode || recorderCode.length === 0) return; - +function startRecord() { const scriptEl = document.createElement('script'); - try { - const uniqueVariablePrefix = '__rrweb_extension_unique_prefix_'; - const events = `${uniqueVariablePrefix}events`; - const stopFn = `${uniqueVariablePrefix}stopFn`; - const setIntervalId = `${uniqueVariablePrefix}setIntervalId`; - const record = `${uniqueVariablePrefix}record`; - scriptEl.textContent = ` - ${recorderCode} - var ${events} = []; - var ${stopFn} = null; - var ${setIntervalId} = null; - - function ${record}() { - ${events} = []; - let recorder; - try { - recorder = rrwebRecord; - } catch (e) { - recorder = rrweb.record; - } - ${stopFn} = recorder({ - emit: (event) => { - ${events}.push(event); - }, - }); - } - - window.addEventListener('message', (event) => { - const data = event.data; - if (data.message === 'stop-record') { - if (${stopFn}) ${stopFn}(); - clearInterval(${setIntervalId}); - window.postMessage({ - message: 'stop-record-response', - events: ${events}, - endTimestamp: Date.now(), - }); - } - }); - - window.postMessage({ - message: 'start-record-response', - startTimestamp: Date.now(), - }); - ${record}(); - - ${setIntervalId} = setInterval(() => { - window.postMessage({ - message: 'heart-beat', - events: ${events}, - }); - }, 50); - `; - document.documentElement.appendChild(scriptEl); - return () => { - document.documentElement.removeChild(scriptEl); - }; - } catch (e) { + scriptEl.src = Browser.runtime.getURL('content/inject.js'); + document.documentElement.appendChild(scriptEl); + return () => { document.documentElement.removeChild(scriptEl); - } + }; } async function saveEvents(events: eventWithTime[]) { - const recorderSettings = (await Browser.storage.sync.get( - SyncDataKey.settings, - )) as SyncData; - const { recorderVersion, recorderURL } = recorderSettings.settings; const newSession: Session = { id: nanoid(), name: document.title, @@ -150,8 +105,9 @@ async function saveEvents(events: eventWithTime[]) { events, createTimestamp: Date.now(), modifyTimestamp: Date.now(), - recorderVersion, - recorderURL, + recorderVersion: ((Browser.runtime.getManifest() as unknown) as { + recorder_version: string; + }).recorder_version, }; const data = (await Browser.storage.local.get( LocalDataKey.sessions, @@ -160,8 +116,3 @@ async function saveEvents(events: eventWithTime[]) { data.sessions[newSession.id] = newSession; await Browser.storage.local.set(data); } - -type HeartBreathMessage = { - message: 'heart-beat'; - events: eventWithTime[]; -}; diff --git a/packages/web-extension/src/content/inject.ts b/packages/web-extension/src/content/inject.ts new file mode 100644 index 0000000000..7ceabec51f --- /dev/null +++ b/packages/web-extension/src/content/inject.ts @@ -0,0 +1,59 @@ +import { record } from 'rrweb'; +import { eventWithTime, recordOptions } from 'rrweb/typings/types'; +import { MessageName, RecordStartedMessage } from '../types'; + +const events: eventWithTime[] = []; +let stopFn: (() => void) | null = null; +let setIntervalId: number | null = null; + +function startRecord(config: recordOptions) { + events.length = 0; + stopFn = + record({ + emit: (event) => { + events.push(event); + }, + ...config, + }) || null; + window.postMessage({ + message: MessageName.RecordStarted, + startTimestamp: Date.now(), + } as RecordStartedMessage); + setIntervalId = (setInterval(() => { + window.postMessage({ + message: MessageName.HeartBeat, + events, + }); + }, 50) as unknown) as number; +} + +window.addEventListener( + 'message', + (event: { + data: { + message: MessageName; + config?: recordOptions; + }; + }) => { + const data = event.data; + const eventHandler = { + [MessageName.StartRecord]: () => { + startRecord(data.config || {}); + }, + [MessageName.StopRecord]: () => { + if (stopFn) stopFn(); + if (setIntervalId) clearInterval(setIntervalId); + window.postMessage({ + message: MessageName.RecordStopped, + events, + endTimestamp: Date.now(), + }); + }, + } as Record void>; + if (eventHandler[data.message]) eventHandler[data.message](); + }, +); + +window.postMessage({ + message: MessageName.RecordScriptReady, +}); diff --git a/packages/web-extension/src/manifest.json b/packages/web-extension/src/manifest.json index fa3920cb83..3c7baaff45 100644 --- a/packages/web-extension/src/manifest.json +++ b/packages/web-extension/src/manifest.json @@ -1,28 +1,63 @@ { - "manifest_version": 2, - "name": "rrweb", - "background": { - "persistent": false, - "scripts": ["background/index.ts"] - }, - "browser_action": { - "default_title": "rrweb extension", - "default_popup": "popup/popup.html", - "browser_style": false - }, - "content_scripts": [ - { - "matches": [""], - "js": ["content/index.ts"], - "run_at": "document_idle" + "common": { + "name": "rrweb", + "content_scripts": [ + { + "matches": [""], + "js": ["content/index.ts"], + "run_at": "document_idle" + } + ], + "options_ui": { + "page": "options/index.html", + "open_in_tab": true, + "chrome_style": false + }, + "icons": { + "16": "assets/icon16.png", + "48": "assets/icon48.png", + "128": "assets/icon128.png" } - ], - "options_page": "options/index.html", - "icons": { - "16": "assets/icon16.png", - "48": "assets/icon48.png", - "128": "assets/icon128.png" }, - "permissions": ["activeTab", "tabs", "storage", "unlimitedStorage"], - "content_security_policy": "script-src-elem 'self' http://localhost:3000 'self'; script-src 'self' http://localhost:3000 'unsafe-eval' object-src 'self'" + "v2": { + "common": { + "manifest_version": 2, + "background": { + "persistent": false, + "scripts": ["background/index.ts"] + }, + "browser_action": { + "default_title": "rrweb extension", + "default_popup": "popup/popup.html", + "browser_style": false + }, + "permissions": ["activeTab", "tabs", "storage", "unlimitedStorage"], + "web_accessible_resources": ["**/*.js"] + }, + "chrome": {}, + "firefox": {} + }, + "v3": { + "common": { + "manifest_version": 3, + "background": { + "service_worker": "background/index.ts", + "type": "module" + }, + "action": { + "default_title": "rrweb extension", + "default_popup": "popup/popup.html", + "browser_style": false + }, + "permissions": ["activeTab", "tabs", "storage", "unlimitedStorage"], + "web_accessible_resources": [ + { + "resources": ["**/*.js"], + "matches": [""] + } + ] + }, + "chrome": {}, + "firefox": {} + } } diff --git a/packages/web-extension/src/options/App.tsx b/packages/web-extension/src/options/App.tsx index 78bdc1a58e..80e1f1ca40 100644 --- a/packages/web-extension/src/options/App.tsx +++ b/packages/web-extension/src/options/App.tsx @@ -1,7 +1,6 @@ import { Route, Routes } from 'react-router-dom'; import SidebarWithHeader from '../components/SidebarWithHeader'; -import { FiTarget, FiList, FiSettings } from 'react-icons/fi'; -import RRWebVersion from './RRWebVersion'; +import { FiList, FiSettings } from 'react-icons/fi'; import { Box } from '@chakra-ui/react'; export default function App() { @@ -20,17 +19,11 @@ export default function App() { href: '#', }, ]} - sideBarItems={[ - { - label: 'rrweb versions', - icon: FiTarget, - href: `#`, - }, - ]} + sideBarItems={[]} > - } /> + } /> diff --git a/packages/web-extension/src/options/RRWebVersion.tsx b/packages/web-extension/src/options/RRWebVersion.tsx deleted file mode 100644 index 9161742c4c..0000000000 --- a/packages/web-extension/src/options/RRWebVersion.tsx +++ /dev/null @@ -1,312 +0,0 @@ -import { useEffect, useState } from 'react'; -import Browser from 'webextension-polyfill'; -import { - Button, - Flex, - FormControl, - FormHelperText, - FormLabel, - Input, - InputGroup, - InputRightElement, - Select, - useToast, -} from '@chakra-ui/react'; -import { - fetchPackageVersions, - getRecorderURL, - verifyPlayerURL, - verifyRecorderURL, -} from '../utils'; -import { SyncData, SyncDataKey } from '../types'; -import { getPlayerURL } from '../utils/index'; - -export default function RRWebVersion() { - const toast = useToast(); - const [recorderVersion, setRecorderVersion] = useState(''); - const [recorderVersions, setRecorderVersions] = useState([]); - const [recorderURL, setRecorderURL] = useState(''); - const [recorderValidURL, setRecorderValidURL] = useState(''); - const [playerVersion, setPlayerVersion] = useState(''); - const [playerVersions, setPlayerVersions] = useState([]); - const [playerURL, setPlayerURL] = useState(''); - const [playerValidURL, setPlayerValidURL] = useState(''); - - useEffect(() => { - void fetchPackageVersions('rrweb').then((versions) => { - setRecorderVersions(versions); - }); - void fetchPackageVersions('rrweb-player').then((versions) => { - setPlayerVersions(versions); - }); - void Browser.storage.sync.get(SyncDataKey.settings).then((data) => { - const syncData = data as SyncData; - if (!syncData.settings) return; - const { recorderVersion, recorderURL, playerURL, playerVersion } = - syncData.settings; - setRecorderVersion(recorderVersion); - setRecorderURL(recorderURL); - setRecorderValidURL(recorderURL); - setPlayerVersion(playerVersion); - setPlayerURL(playerURL); - setPlayerValidURL(playerURL); - }); - }, []); - - return ( - - - - RRWeb Recorder Version - - - {recorderVersion !== '' && recorderVersion !== 'custom' && ( - <> - The extension will load Recorder script with v{recorderVersion} - from jsDelivr. - - )} - - - - Recorder URL - - setRecorderURL(event.target.value)} - /> - - - - - - - {(recorderVersion === '' || recorderVersion === 'custom') && ( - <> - The extension will load Recorder script from {recorderValidURL} - - )} - - - - - - RRWeb Player Version - - - {playerVersion !== '' && playerVersion !== 'custom' && ( - <> - The extension will load Player script with v{playerVersion} from - jsDelivr. - - )} - - - - Player URL - - setPlayerURL(event.target.value)} - /> - - - - - - - {(playerVersion === '' || playerVersion === 'custom') && ( - <>The extension will load Player script from {playerValidURL} - )} - - - - - ); -} diff --git a/packages/web-extension/src/pages/Player.tsx b/packages/web-extension/src/pages/Player.tsx index f73fcd2262..8339e1a520 100644 --- a/packages/web-extension/src/pages/Player.tsx +++ b/packages/web-extension/src/pages/Player.tsx @@ -2,7 +2,7 @@ import { useRef, useEffect, useState } from 'react'; import { useParams } from 'react-router-dom'; import Browser from 'webextension-polyfill'; import type rrwebPlayer from 'rrweb-player'; -import { RRwebPlayerOptions } from 'rrweb-player'; +import Replayer from 'rrweb-player'; import { LocalData } from '../types'; import { Box, @@ -26,22 +26,12 @@ export default function Player() { if (!session) return; setSessionName(session.name); - eval(localData.player_code + 'window.rrwebPlayer = rrwebPlayer;'); - - const Player = ( - window as Window & - typeof globalThis & { - rrwebPlayer: new (options: RRwebPlayerOptions) => rrwebPlayer; - } - ).rrwebPlayer; - if (!Player) return; - const linkEl = document.createElement('link'); linkEl.href = - 'https://cdn.jsdelivr.net/npm/rrweb-player@1.0.0-alpha.1/dist/style.css'; + 'https://cdn.jsdelivr.net/npm/rrweb-player@1.0.0-alpha.3/dist/style.css'; linkEl.rel = 'stylesheet'; document.head.appendChild(linkEl); - playerRef.current = new Player({ + playerRef.current = new Replayer({ target: playerElRef.current as HTMLElement, props: { events: session.events, diff --git a/packages/web-extension/src/types.ts b/packages/web-extension/src/types.ts index adf86bac77..94cfe18561 100644 --- a/packages/web-extension/src/types.ts +++ b/packages/web-extension/src/types.ts @@ -9,23 +9,16 @@ export type SyncData = { }; export type Settings = { - recorderURL: string; - recorderVersion: string; - playerURL: string; - playerVersion: string; + // }; export enum LocalDataKey { - recorderCode = 'recorder_code', - playerCode = 'player_code', sessions = 'sessions', recorderStatus = 'recorder_status', bufferedEvents = 'buffered_events', } export type LocalData = { - [LocalDataKey.recorderCode]: string; - [LocalDataKey.playerCode]: string; [LocalDataKey.sessions]: Record; [LocalDataKey.recorderStatus]: { status: RecorderStatus; @@ -49,7 +42,6 @@ export type Session = { createTimestamp: number; modifyTimestamp: number; recorderVersion: string; - recorderURL: string; }; export enum ServiceName { @@ -59,13 +51,27 @@ export enum ServiceName { ResumeRecord = 'resume-record', } -export type StartRecordResponse = { - message: 'start-record-response'; +export enum MessageName { + RecordScriptReady = 'rrweb-extension-record-script-ready', + StartRecord = 'rrweb-extension-start-record', + RecordStarted = 'rrweb-extension-record-started', + HeartBeat = 'rrweb-extension-heart-beat', + StopRecord = 'rrweb-extension-stop-record', + RecordStopped = 'rrweb-extension-record-stopped', +} + +export type RecordStartedMessage = { + message: MessageName.RecordStarted; startTimestamp: number; }; -export type StopRecordResponse = { - message: 'stop-record-response'; +export type RecordStoppedMessage = { + message: MessageName.RecordStopped; events: eventWithTime[]; endTimestamp: number; }; + +export type HeartBreathMessage = { + message: MessageName.HeartBeat; + events: eventWithTime[]; +}; diff --git a/packages/web-extension/src/utils/index.ts b/packages/web-extension/src/utils/index.ts index 6f320a65a9..a2a6d22452 100644 --- a/packages/web-extension/src/utils/index.ts +++ b/packages/web-extension/src/utils/index.ts @@ -1,53 +1,7 @@ -import { PackageJson } from 'type-fest'; - const SECOND = 1000; const MINUTE = 60 * SECOND; const HOUR = 60 * MINUTE; -export async function fetchPackageVersions(packageName: string) { - type Meta = { - name: string; - author: string; - versions: Record; - }; - const meta = (await ( - await fetch(`https://registry.npmjs.org/${packageName}`) - ).json()) as Meta; - const versions = []; - for (const version in meta.versions) versions.push(version); - return versions.reverse(); -} - -export function getRecorderURL(version: string) { - return `https://cdn.jsdelivr.net/npm/rrweb@${version}/dist/record/rrweb-record.min.js`; -} - -export function getPlayerURL(version: string) { - return `https://cdn.jsdelivr.net/npm/rrweb-player@${version}/dist/index.js`; -} - -export async function verifyRecorderURL(url: string) { - try { - const res = await fetch(url); - if (!res.ok) return false; - const text = await res.text(); - return text.includes('rrwebRecord') || text.includes('record'); - } catch (e) { - return false; - } -} - -export async function verifyPlayerURL(url: string) { - try { - const res = await fetch(url); - if (!res.ok) return false; - const text = await res.text(); - return text.includes('rrwebPlayer'); - } catch (e) { - return false; - } -} - export function formatTime(ms: number): string { if (ms <= 0) { return '00:00'; diff --git a/packages/web-extension/vite.config.ts b/packages/web-extension/vite.config.ts index 32e44d1184..8b0812402c 100644 --- a/packages/web-extension/vite.config.ts +++ b/packages/web-extension/vite.config.ts @@ -23,12 +23,34 @@ export default defineConfig({ // A function to generate manifest file dynamically. manifest: () => { const packageJson = readJsonFile('package.json') as PackageJson; - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return { - ...readJsonFile('./src/manifest.json'), + const isProduction = process.env.NODE_ENV === 'production'; + type ManifestBase = { + common: Record; + chrome: Record; + firefox: Record; + }; + const originalManifest = readJsonFile('./src/manifest.json') as { + common: Record; + v2: ManifestBase; + v3: ManifestBase; + }; + const ManifestVersion = + process.env.TARGET_BROWSER === 'chrome' && isProduction ? 'v3' : 'v2'; + const BrowserName = + process.env.TARGET_BROWSER === 'chrome' ? 'chrome' : 'firefox'; + const commonManifest = originalManifest.common; + const manifest = { version: packageJson.version, author: packageJson.author, + recorder_version: packageJson.dependencies?.rrweb?.replace('^', ''), + ...commonManifest, }; + Object.assign( + manifest, + originalManifest[ManifestVersion].common, + originalManifest[ManifestVersion][BrowserName], + ); + return manifest; }, assets: 'assets', browser: process.env.TARGET_BROWSER, @@ -36,7 +58,7 @@ export default defineConfig({ startUrl: ['github.com/rrweb-io/rrweb'], watchIgnored: ['*.md', '*.log'], }, - additionalInputs: ['pages/index.html'], + additionalInputs: ['pages/index.html', 'content/inject.ts'], }), process.env.ZIP === 'true' && zip({ diff --git a/yarn.lock b/yarn.lock index 92c6afd8f3..738cfa28ab 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14974,11 +14974,6 @@ typescript@*, typescript@^4.7.3: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235" integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ== -typescript@^4.8.3: - version "4.8.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.4.tgz#c464abca159669597be5f96b8943500b238e60e6" - integrity sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ== - uc.micro@^1.0.1, uc.micro@^1.0.5: version "1.0.6" resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" @@ -15275,7 +15270,7 @@ vite-plugin-zip@^1.0.1: dependencies: yazl "^2.5.1" -vite@^3.1.2: +vite@^3.1.8: version "3.1.8" resolved "https://registry.yarnpkg.com/vite/-/vite-3.1.8.tgz#fa29144167d19b773baffd65b3972ea4c12359c9" integrity sha512-m7jJe3nufUbuOfotkntGFupinL/fmuTNuQmiVE7cH2IZMuf4UbfbGYMUT3jVWgGYuRVLY9j8NnrRqgw5rr5QTg== From 6d7ae5d88ae8ed0cfca7dc59f183fb69935148e3 Mon Sep 17 00:00:00 2001 From: Yun Feng Date: Mon, 31 Oct 2022 18:44:11 +1100 Subject: [PATCH 03/40] update tsconfig.json --- packages/web-extension/tsconfig.json | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/packages/web-extension/tsconfig.json b/packages/web-extension/tsconfig.json index cbca7830d1..608eb134c5 100644 --- a/packages/web-extension/tsconfig.json +++ b/packages/web-extension/tsconfig.json @@ -3,7 +3,10 @@ "baseUrl": ".", "module": "ESNext", "target": "es2016", - "lib": ["DOM", "ESNext"], + "lib": [ + "DOM", + "ESNext" + ], "strict": true, "esModuleInterop": true, "incremental": false, @@ -14,10 +17,22 @@ "strictNullChecks": true, "forceConsistentCasingInFileNames": true, "paths": { - "~/*": ["src/*"] + "~/*": [ + "src/*" + ] }, "jsx": "react-jsx" }, - "exclude": ["dist", "node_modules"], - "references": [] + "exclude": [ + "dist", + "node_modules" + ], + "references": [ + { + "path": "../rrweb" + }, + { + "path": "../rrweb-player" + } + ] } From c99b049d056152602b026db97d8776bb95548cc8 Mon Sep 17 00:00:00 2001 From: Yun Feng Date: Mon, 31 Oct 2022 18:56:13 +1100 Subject: [PATCH 04/40] use version_name rather than recorder_version in manifest.json --- packages/web-extension/src/content/index.ts | 4 +--- packages/web-extension/vite.config.ts | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/web-extension/src/content/index.ts b/packages/web-extension/src/content/index.ts index e0f2afb6d5..98343a9c56 100644 --- a/packages/web-extension/src/content/index.ts +++ b/packages/web-extension/src/content/index.ts @@ -105,9 +105,7 @@ async function saveEvents(events: eventWithTime[]) { events, createTimestamp: Date.now(), modifyTimestamp: Date.now(), - recorderVersion: ((Browser.runtime.getManifest() as unknown) as { - recorder_version: string; - }).recorder_version, + recorderVersion: Browser.runtime.getManifest().version_name || 'unknown', }; const data = (await Browser.storage.local.get( LocalDataKey.sessions, diff --git a/packages/web-extension/vite.config.ts b/packages/web-extension/vite.config.ts index 8b0812402c..1afea8f191 100644 --- a/packages/web-extension/vite.config.ts +++ b/packages/web-extension/vite.config.ts @@ -42,7 +42,7 @@ export default defineConfig({ const manifest = { version: packageJson.version, author: packageJson.author, - recorder_version: packageJson.dependencies?.rrweb?.replace('^', ''), + version_name: packageJson.dependencies?.rrweb?.replace('^', ''), ...commonManifest, }; Object.assign( From e87d539f18250a6504267ce7218c08595981ae9d Mon Sep 17 00:00:00 2001 From: Mark-Fenng Date: Tue, 1 Nov 2022 14:19:33 +1100 Subject: [PATCH 05/40] update manifest.json --- packages/web-extension/src/manifest.json | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/web-extension/src/manifest.json b/packages/web-extension/src/manifest.json index 3c7baaff45..70f7426008 100644 --- a/packages/web-extension/src/manifest.json +++ b/packages/web-extension/src/manifest.json @@ -8,11 +8,6 @@ "run_at": "document_idle" } ], - "options_ui": { - "page": "options/index.html", - "open_in_tab": true, - "chrome_style": false - }, "icons": { "16": "assets/icon16.png", "48": "assets/icon48.png", @@ -31,6 +26,11 @@ "default_popup": "popup/popup.html", "browser_style": false }, + "options_ui": { + "page": "options/index.html", + "open_in_tab": true, + "chrome_style": false + }, "permissions": ["activeTab", "tabs", "storage", "unlimitedStorage"], "web_accessible_resources": ["**/*.js"] }, @@ -49,6 +49,10 @@ "default_popup": "popup/popup.html", "browser_style": false }, + "options_ui": { + "page": "options/index.html", + "open_in_tab": true + }, "permissions": ["activeTab", "tabs", "storage", "unlimitedStorage"], "web_accessible_resources": [ { From 579d5b8f64f2fa452a58345bcce4ec87f4e529b3 Mon Sep 17 00:00:00 2001 From: Mark-Fenng Date: Tue, 1 Nov 2022 21:42:57 +1100 Subject: [PATCH 06/40] enable to keep recording after changing tabs --- .../web-extension/src/background/index.ts | 93 ++++++++++++++++++- packages/web-extension/src/content/index.ts | 26 +++++- packages/web-extension/src/popup/App.tsx | 22 +++-- packages/web-extension/src/types.ts | 3 + 4 files changed, 131 insertions(+), 13 deletions(-) diff --git a/packages/web-extension/src/background/index.ts b/packages/web-extension/src/background/index.ts index 2205573772..1c4fcf4b92 100644 --- a/packages/web-extension/src/background/index.ts +++ b/packages/web-extension/src/background/index.ts @@ -1,5 +1,19 @@ import Browser from 'webextension-polyfill'; -import { Settings, SyncData, SyncDataKey } from '../types'; +import type { eventWithTime } from 'rrweb/typings/types'; +import Channel from '../utils/channel'; +import { + LocalData, + LocalDataKey, + RecorderStatus, + RecordStartedMessage, + RecordStoppedMessage, + ServiceName, + Settings, + SyncData, + SyncDataKey, +} from '../types'; + +const channel = new Channel(); void (async () => { // assign default value to settings of this extension @@ -15,6 +29,83 @@ void (async () => { await Browser.storage.sync.set({ settings, } as SyncData); + + // Resume recording after change to a new tab. + const resumeRecording = async ( + newTabId: number, + events: eventWithTime[], + duration: number | undefined, + ) => { + const startResponse = (await channel.requestToTab( + newTabId, + ServiceName.ResumeRecord, + { events }, + )) as RecordStartedMessage; + if (!startResponse) return; + await Browser.storage.local.set({ + [LocalDataKey.recorderStatus]: { + status: RecorderStatus.RECORDING, + activeTabId: newTabId, + startTimestamp: startResponse.startTimestamp - (duration || 0), + }, + }); + }; + + Browser.tabs.onActivated.addListener((activeInfo) => { + void Browser.storage.local + .get(LocalDataKey.recorderStatus) + .then(async (data) => { + const localData = data as LocalData; + if (!localData || !localData.recorder_status) return; + const { + status, + startTimestamp, + activeTabId, + } = localData.recorder_status; + if ( + status !== RecorderStatus.RECORDING || + activeTabId === activeInfo.tabId + ) + return; + + const stopResponse = (await channel.requestToTab( + activeTabId, + ServiceName.PauseRecord, + {}, + )) as RecordStoppedMessage; + if (!stopResponse) return; + const duration = startTimestamp + ? stopResponse.endTimestamp - startTimestamp + : undefined; + await Browser.storage.local.set({ + [LocalDataKey.recorderStatus]: { + status: RecorderStatus.PausedSwitch, + duration, + }, + }); + await resumeRecording(activeInfo.tabId, stopResponse.events, duration); + }) + .catch(() => { + // the extension can't access to the tab + }); + }); + + Browser.tabs.onUpdated.addListener(function (tabId, info) { + if (info.status !== 'complete') return; + void Browser.storage.local + .get() + .then((data) => { + const localData = data as LocalData; + if (!localData || !localData.recorder_status) return; + const { status, activeTabId, duration } = localData.recorder_status; + if (status !== RecorderStatus.PausedSwitch || activeTabId === tabId) + return; + return resumeRecording(tabId, localData.buffered_events, duration); + }) + .catch(() => { + // the extension can't access to the tab + }); + }); })(); /** diff --git a/packages/web-extension/src/content/index.ts b/packages/web-extension/src/content/index.ts index 98343a9c56..5deb8ff191 100644 --- a/packages/web-extension/src/content/index.ts +++ b/packages/web-extension/src/content/index.ts @@ -31,6 +31,15 @@ void (async () => { }; }); }); + channel.provide(ServiceName.ResumeRecord, async (params) => { + storedEvents = (params as { events: eventWithTime[] }).events; + clearRecorderCb = startRecord(); + return new Promise((resolve) => { + startResponseCb = (response) => { + resolve(response); + }; + }); + }); let stopResponseCb: | ((response: RecordStoppedMessage) => void) | undefined = undefined; @@ -38,6 +47,18 @@ void (async () => { window.postMessage({ message: MessageName.StopRecord }); return new Promise((resolve) => { stopResponseCb = (response: RecordStoppedMessage) => { + stopResponseCb = undefined; + void saveEvents(response.events); + storedEvents = []; + resolve(response); + }; + }); + }); + channel.provide(ServiceName.PauseRecord, () => { + window.postMessage({ message: MessageName.StopRecord }); + return new Promise((resolve) => { + stopResponseCb = (response: RecordStoppedMessage) => { + stopResponseCb = undefined; resolve(response); }; }); @@ -66,11 +87,10 @@ void (async () => { stopResponseCb ) { const data = event.data as RecordStoppedMessage; - stopResponseCb(data); - void saveEvents(storedEvents.concat(data.events)); + data.events = storedEvents.concat(data.events); clearRecorderCb?.(); clearRecorderCb = undefined; - storedEvents = []; + stopResponseCb(data); } else if (event.data.message === MessageName.HeartBeat) { void Browser.storage.local.set({ [LocalDataKey.bufferedEvents]: storedEvents.concat( diff --git a/packages/web-extension/src/popup/App.tsx b/packages/web-extension/src/popup/App.tsx index 221375ebef..7168ca3aab 100644 --- a/packages/web-extension/src/popup/App.tsx +++ b/packages/web-extension/src/popup/App.tsx @@ -7,7 +7,7 @@ import { LocalDataKey, RecorderStatus, ServiceName, - StartRecordResponse, + RecordStartedMessage, } from '../types'; import Browser from 'webextension-polyfill'; import { CircleButton } from '../components/CircleButton'; @@ -79,10 +79,12 @@ export function App() { .then(async (res) => { if (res) { setRecording(false); + const status: LocalData[LocalDataKey.recorderStatus] = { + status: RecorderStatus.IDLE, + activeTabId: tabId, + }; await Browser.storage.local.set({ - [LocalDataKey.recorderStatus]: { - status: RecorderStatus.IDLE, - }, + [LocalDataKey.recorderStatus]: status, }); } }) @@ -96,15 +98,17 @@ export function App() { if (tabId === -1) return; void channel .requestToTab(tabId, ServiceName.StartRecord, {}) - .then(async (res: StartRecordResponse | undefined) => { + .then(async (res: RecordStartedMessage | undefined) => { if (res) { setRecording(true); setStartTime(res.startTimestamp); + const status: LocalData[LocalDataKey.recorderStatus] = { + status: RecorderStatus.RECORDING, + activeTabId: tabId, + startTimestamp: res.startTimestamp, + }; await Browser.storage.local.set({ - [LocalDataKey.recorderStatus]: { - status: RecorderStatus.RECORDING, - startTimestamp: res.startTimestamp, - }, + [LocalDataKey.recorderStatus]: status, }); } }) diff --git a/packages/web-extension/src/types.ts b/packages/web-extension/src/types.ts index 94cfe18561..7e535dcc1a 100644 --- a/packages/web-extension/src/types.ts +++ b/packages/web-extension/src/types.ts @@ -22,6 +22,7 @@ export type LocalData = { [LocalDataKey.sessions]: Record; [LocalDataKey.recorderStatus]: { status: RecorderStatus; + activeTabId: number; startTimestamp?: number; duration?: number; }; @@ -32,6 +33,8 @@ export enum RecorderStatus { IDLE = 'IDLE', RECORDING = 'RECORDING', PAUSED = 'PAUSED', + // when user change the tab, the recorder will be paused during the tab change + PausedSwitch = 'PAUSED_SWITCH', } export type Session = { From 8739a6fb4ba201a6c36805756a7e40b715695251 Mon Sep 17 00:00:00 2001 From: Mark-Fenng Date: Wed, 2 Nov 2022 18:01:12 +1100 Subject: [PATCH 07/40] enable to record between tabs and urls --- .../web-extension/src/background/index.ts | 107 +++++++++++------- packages/web-extension/src/content/index.ts | 18 ++- packages/web-extension/src/popup/App.tsx | 4 +- packages/web-extension/src/types.ts | 3 +- 4 files changed, 88 insertions(+), 44 deletions(-) diff --git a/packages/web-extension/src/background/index.ts b/packages/web-extension/src/background/index.ts index 1c4fcf4b92..6bf8e7e5d3 100644 --- a/packages/web-extension/src/background/index.ts +++ b/packages/web-extension/src/background/index.ts @@ -34,20 +34,25 @@ void (async () => { const resumeRecording = async ( newTabId: number, events: eventWithTime[], - duration: number | undefined, + startTimestamp: number, + pausedTimestamp: number | undefined, ) => { const startResponse = (await channel.requestToTab( newTabId, ServiceName.ResumeRecord, - { events }, + { events, pausedTimestamp }, )) as RecordStartedMessage; if (!startResponse) return; + const pausedTime = pausedTimestamp + ? startResponse.startTimestamp - pausedTimestamp + : 0; + const statusData: LocalData[LocalDataKey.recorderStatus] = { + status: RecorderStatus.RECORDING, + activeTabId: newTabId, + startTimestamp: startTimestamp + pausedTime, + }; await Browser.storage.local.set({ - [LocalDataKey.recorderStatus]: { - status: RecorderStatus.RECORDING, - activeTabId: newTabId, - startTimestamp: startResponse.startTimestamp - (duration || 0), - }, + [LocalDataKey.recorderStatus]: statusData, }); }; @@ -56,34 +61,47 @@ void (async () => { .get(LocalDataKey.recorderStatus) .then(async (data) => { const localData = data as LocalData; - if (!localData || !localData.recorder_status) return; - const { - status, - startTimestamp, - activeTabId, - } = localData.recorder_status; - if ( - status !== RecorderStatus.RECORDING || - activeTabId === activeInfo.tabId - ) - return; + if (!localData || !localData[LocalDataKey.recorderStatus]) return; + let { status, pausedTimestamp } = localData[ + LocalDataKey.recorderStatus + ]; + const { startTimestamp, activeTabId } = localData[ + LocalDataKey.recorderStatus + ]; + let bufferedEvents: eventWithTime[] | undefined; - const stopResponse = (await channel.requestToTab( - activeTabId, - ServiceName.PauseRecord, - {}, - )) as RecordStoppedMessage; - if (!stopResponse) return; - const duration = startTimestamp - ? stopResponse.endTimestamp - startTimestamp - : undefined; - await Browser.storage.local.set({ - [LocalDataKey.recorderStatus]: { + if (status === RecorderStatus.RECORDING) { + const stopResponse = (await channel.requestToTab( + activeTabId, + ServiceName.PauseRecord, + {}, + )) as RecordStoppedMessage; + if (!stopResponse) return; + const statusData: LocalData[LocalDataKey.recorderStatus] = { status: RecorderStatus.PausedSwitch, - duration, - }, - }); - await resumeRecording(activeInfo.tabId, stopResponse.events, duration); + activeTabId: activeInfo.tabId, + startTimestamp, + pausedTimestamp: stopResponse.endTimestamp, + }; + await Browser.storage.local.set({ + [LocalDataKey.recorderStatus]: statusData, + }); + status = RecorderStatus.PausedSwitch; + pausedTimestamp = stopResponse.endTimestamp; + bufferedEvents = stopResponse.events; + } + if (status === RecorderStatus.PausedSwitch) { + if (!bufferedEvents) + bufferedEvents = ((await Browser.storage.local.get( + LocalDataKey.bufferedEvents, + )) as LocalData)[LocalDataKey.bufferedEvents]; + await resumeRecording( + activeInfo.tabId, + bufferedEvents, + startTimestamp || bufferedEvents[0].timestamp, + pausedTimestamp, + ); + } }) .catch(() => { // the extension can't access to the tab @@ -93,14 +111,27 @@ void (async () => { Browser.tabs.onUpdated.addListener(function (tabId, info) { if (info.status !== 'complete') return; void Browser.storage.local - .get() - .then((data) => { + .get(LocalDataKey.recorderStatus) + .then(async (data) => { const localData = data as LocalData; - if (!localData || !localData.recorder_status) return; - const { status, activeTabId, duration } = localData.recorder_status; + if (!localData || !localData[LocalDataKey.recorderStatus]) return; + const { + status, + activeTabId, + startTimestamp, + pausedTimestamp, + } = localData[LocalDataKey.recorderStatus]; if (status !== RecorderStatus.PausedSwitch || activeTabId === tabId) return; - return resumeRecording(tabId, localData.buffered_events, duration); + const bufferedEvents = ((await Browser.storage.local.get( + LocalDataKey.bufferedEvents, + )) as LocalData)[LocalDataKey.bufferedEvents]; + await resumeRecording( + tabId, + bufferedEvents, + startTimestamp || bufferedEvents[0].timestamp, + pausedTimestamp, + ); }) .catch(() => { // the extension can't access to the tab diff --git a/packages/web-extension/src/content/index.ts b/packages/web-extension/src/content/index.ts index 5deb8ff191..2a959f8efd 100644 --- a/packages/web-extension/src/content/index.ts +++ b/packages/web-extension/src/content/index.ts @@ -32,10 +32,19 @@ void (async () => { }); }); channel.provide(ServiceName.ResumeRecord, async (params) => { - storedEvents = (params as { events: eventWithTime[] }).events; + const { events, pausedTimestamp } = params as { + events: eventWithTime[]; + pausedTimestamp: number; + }; + storedEvents = events; clearRecorderCb = startRecord(); return new Promise((resolve) => { startResponseCb = (response) => { + const pausedTime = response.startTimestamp - pausedTimestamp; + // Decrease the time spent in the pause state and make them look like a continuous recording. + storedEvents.forEach((event) => { + event.timestamp += pausedTime; + }); resolve(response); }; }); @@ -102,9 +111,12 @@ void (async () => { ); const localData = (await Browser.storage.local.get()) as LocalData; - if (localData?.recorder_status?.status === RecorderStatus.RECORDING) { + if ( + localData?.[LocalDataKey.recorderStatus]?.status === + RecorderStatus.RECORDING + ) { clearRecorderCb = startRecord(); - storedEvents = localData.buffered_events || []; + storedEvents = localData[LocalDataKey.bufferedEvents] || []; } })(); diff --git a/packages/web-extension/src/popup/App.tsx b/packages/web-extension/src/popup/App.tsx index 7168ca3aab..354566b658 100644 --- a/packages/web-extension/src/popup/App.tsx +++ b/packages/web-extension/src/popup/App.tsx @@ -24,8 +24,8 @@ export function App() { useEffect(() => { void Browser.storage.local.get(LocalDataKey.recorderStatus).then((data) => { const localData = data as LocalData; - if (!localData || !localData.recorder_status) return; - const { status, startTimestamp } = localData.recorder_status; + if (!localData || !localData[LocalDataKey.recorderStatus]) return; + const { status, startTimestamp } = localData[LocalDataKey.recorderStatus]; if (status === RecorderStatus.RECORDING) { setRecording(true); setStartTime(startTimestamp || 0); diff --git a/packages/web-extension/src/types.ts b/packages/web-extension/src/types.ts index 7e535dcc1a..793a064d91 100644 --- a/packages/web-extension/src/types.ts +++ b/packages/web-extension/src/types.ts @@ -24,7 +24,8 @@ export type LocalData = { status: RecorderStatus; activeTabId: number; startTimestamp?: number; - duration?: number; + // the timestamp when the recording is paused + pausedTimestamp?: number; }; [LocalDataKey.bufferedEvents]: eventWithTime[]; }; From 6fd4f2ad9d87cfe034e52b02c6670138f7522d1c Mon Sep 17 00:00:00 2001 From: Mark-Fenng Date: Wed, 2 Nov 2022 18:06:29 +1100 Subject: [PATCH 08/40] fix CI error --- packages/web-extension/package.json | 3 - yarn.lock | 779 ++-------------------------- 2 files changed, 29 insertions(+), 753 deletions(-) diff --git a/packages/web-extension/package.json b/packages/web-extension/package.json index 8809fa9016..8d2b63a948 100644 --- a/packages/web-extension/package.json +++ b/packages/web-extension/package.json @@ -12,7 +12,6 @@ "build:firefox": "cross-env TARGET_BROWSER=firefox vite build", "pack:chrome": "cross-env TARGET_BROWSER=chrome ZIP=true vite build", "pack:firefox": "cross-env TARGET_BROWSER=firefox ZIP=true vite build", - "test": "jest", "check-types": "tsc -noEmit", "prepublish": "npm run pack:chrome && npm run pack:firefox" }, @@ -21,8 +20,6 @@ "@types/webextension-polyfill": "^0.9.1", "@vitejs/plugin-react": "^2.1.0", "cross-env": "^7.0.3", - "jest": "^29.0.3", - "ts-jest": "^29.0.1", "type-fest": "^2.19.0", "typescript": "^4.7.3", "vite": "^3.1.8", diff --git a/yarn.lock b/yarn.lock index 738cfa28ab..33e2867eba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -67,27 +67,6 @@ semver "^6.3.0" source-map "^0.5.0" -"@babel/core@^7.11.6", "@babel/core@^7.18.13": - version "7.19.3" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.19.3.tgz#2519f62a51458f43b682d61583c3810e7dcee64c" - integrity sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ== - dependencies: - "@ampproject/remapping" "^2.1.0" - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.19.3" - "@babel/helper-compilation-targets" "^7.19.3" - "@babel/helper-module-transforms" "^7.19.0" - "@babel/helpers" "^7.19.0" - "@babel/parser" "^7.19.3" - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.19.3" - "@babel/types" "^7.19.3" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.1" - semver "^6.3.0" - "@babel/core@^7.12.3": version "7.16.7" resolved "https://registry.npmjs.org/@babel/core/-/core-7.16.7.tgz" @@ -109,6 +88,27 @@ semver "^6.3.0" source-map "^0.5.0" +"@babel/core@^7.18.13": + version "7.19.3" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.19.3.tgz#2519f62a51458f43b682d61583c3810e7dcee64c" + integrity sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ== + dependencies: + "@ampproject/remapping" "^2.1.0" + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.19.3" + "@babel/helper-compilation-targets" "^7.19.3" + "@babel/helper-module-transforms" "^7.19.0" + "@babel/helpers" "^7.19.0" + "@babel/parser" "^7.19.3" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.19.3" + "@babel/types" "^7.19.3" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.1" + semver "^6.3.0" + "@babel/generator@^7.15.4", "@babel/generator@^7.7.2": version "7.15.4" resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.15.4.tgz" @@ -529,7 +529,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-jsx@^7.17.12", "@babel/plugin-syntax-jsx@^7.18.6", "@babel/plugin-syntax-jsx@^7.7.2": +"@babel/plugin-syntax-jsx@^7.17.12", "@babel/plugin-syntax-jsx@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz#a8feef63b010150abd97f1649ec296e849943ca0" integrity sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q== @@ -1741,18 +1741,6 @@ jest-util "^27.5.1" slash "^3.0.0" -"@jest/console@^29.2.0": - version "29.2.0" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.2.0.tgz#e906bdbfc83baf79590f05b515dad900b3b71fed" - integrity sha512-Xz1Wu+ZZxcB3RS8U3HdkFxlRJ7kLXI/by9X7d2/gvseIWPwYu/c1EsYy77cB5iyyHGOy3whS2HycjcuzIF4Jow== - dependencies: - "@jest/types" "^29.2.0" - "@types/node" "*" - chalk "^4.0.0" - jest-message-util "^29.2.0" - jest-util "^29.2.0" - slash "^3.0.0" - "@jest/core@^27.2.4": version "27.2.4" resolved "https://registry.npmjs.org/@jest/core/-/core-27.2.4.tgz" @@ -1821,40 +1809,6 @@ slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/core@^29.2.0": - version "29.2.0" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.2.0.tgz#beed57c552be65d4e4ab2f4161d0abe8ea6bf3a8" - integrity sha512-+gyJ3bX+kGEW/eqt/0kI7fLjqiFr3AN8O+rlEl1fYRf7D8h4Sj4tBGo9YOSirvWgvemoH2EPRya35bgvcPFzHQ== - dependencies: - "@jest/console" "^29.2.0" - "@jest/reporters" "^29.2.0" - "@jest/test-result" "^29.2.0" - "@jest/transform" "^29.2.0" - "@jest/types" "^29.2.0" - "@types/node" "*" - ansi-escapes "^4.2.1" - chalk "^4.0.0" - ci-info "^3.2.0" - exit "^0.1.2" - graceful-fs "^4.2.9" - jest-changed-files "^29.2.0" - jest-config "^29.2.0" - jest-haste-map "^29.2.0" - jest-message-util "^29.2.0" - jest-regex-util "^29.2.0" - jest-resolve "^29.2.0" - jest-resolve-dependencies "^29.2.0" - jest-runner "^29.2.0" - jest-runtime "^29.2.0" - jest-snapshot "^29.2.0" - jest-util "^29.2.0" - jest-validate "^29.2.0" - jest-watcher "^29.2.0" - micromatch "^4.0.4" - pretty-format "^29.2.0" - slash "^3.0.0" - strip-ansi "^6.0.0" - "@jest/environment@^27.2.4": version "27.2.4" resolved "https://registry.npmjs.org/@jest/environment/-/environment-27.2.4.tgz" @@ -1875,31 +1829,6 @@ "@types/node" "*" jest-mock "^27.5.1" -"@jest/environment@^29.2.0": - version "29.2.0" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.2.0.tgz#7e5604e4ead098572056a962a970f3d79379fbd8" - integrity sha512-foaVv1QVPB31Mno3LlL58PxEQQOLZd9zQfCpyQQCQIpUAtdFP1INBjkphxrCfKT13VxpA0z5jFGIkmZk0DAg2Q== - dependencies: - "@jest/fake-timers" "^29.2.0" - "@jest/types" "^29.2.0" - "@types/node" "*" - jest-mock "^29.2.0" - -"@jest/expect-utils@^29.2.0": - version "29.2.0" - resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.2.0.tgz#3c0c472115d98211e7e0a0a8fa00719bf081987f" - integrity sha512-nz2IDF7nb1qmj9hx8Ja3MFab2q9Ml8QbOaaeJNyX5JQJHU8QUvEDiMctmhGEkk3Kzr8w8vAqz4hPk/ogJSrUhg== - dependencies: - jest-get-type "^29.2.0" - -"@jest/expect@^29.2.0": - version "29.2.0" - resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.2.0.tgz#25316d2ae930e7bb9df96cce7521053d377c4c0d" - integrity sha512-+3lxcYL9e0xPJGOR33utxxejn+Mulz40kY0oy0FVsmIESW87NZDJ7B1ovaIqeX0xIgPX4laS5SGlqD2uSoBMcw== - dependencies: - expect "^29.2.0" - jest-snapshot "^29.2.0" - "@jest/fake-timers@^27.2.4": version "27.2.4" resolved "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.2.4.tgz" @@ -1924,18 +1853,6 @@ jest-mock "^27.5.1" jest-util "^27.5.1" -"@jest/fake-timers@^29.2.0": - version "29.2.0" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.2.0.tgz#e43635c1bd73b23886e80ca12307092ef2ee1929" - integrity sha512-mX0V0uQsgeSLTt0yTqanAhhpeUKMGd2uq+PSLAfO40h72bvfNNQ7pIEl9vIwNMFxRih1ENveEjSBsLjxGGDPSw== - dependencies: - "@jest/types" "^29.2.0" - "@sinonjs/fake-timers" "^9.1.2" - "@types/node" "*" - jest-message-util "^29.2.0" - jest-mock "^29.2.0" - jest-util "^29.2.0" - "@jest/globals@^27.2.4": version "27.2.4" resolved "https://registry.npmjs.org/@jest/globals/-/globals-27.2.4.tgz" @@ -1954,16 +1871,6 @@ "@jest/types" "^27.5.1" expect "^27.5.1" -"@jest/globals@^29.2.0": - version "29.2.0" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.2.0.tgz#5cfc41c028efaf511624ba086d64113d5a8a92b3" - integrity sha512-JQxtEVNWiai1p3PIzAJZSyEqQdAJGvNKvinZDPfu0mhiYEVx6E+PiBuDWj1sVUW8hzu+R3DVqaWC9K2xcLRIAA== - dependencies: - "@jest/environment" "^29.2.0" - "@jest/expect" "^29.2.0" - "@jest/types" "^29.2.0" - jest-mock "^29.2.0" - "@jest/reporters@^27.2.4": version "27.2.4" resolved "https://registry.npmjs.org/@jest/reporters/-/reporters-27.2.4.tgz" @@ -2025,43 +1932,6 @@ terminal-link "^2.0.0" v8-to-istanbul "^8.1.0" -"@jest/reporters@^29.2.0": - version "29.2.0" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.2.0.tgz#24cac16d997ec91a9c615db2621805ee485689e0" - integrity sha512-BXoAJatxTZ18U0cwD7C8qBo8V6vef8AXYRBZdhqE5DF9CmpqmhMfw9c7OUvYqMTnBBK9A0NgXGO4Lc9EJzdHvw== - dependencies: - "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^29.2.0" - "@jest/test-result" "^29.2.0" - "@jest/transform" "^29.2.0" - "@jest/types" "^29.2.0" - "@jridgewell/trace-mapping" "^0.3.15" - "@types/node" "*" - chalk "^4.0.0" - collect-v8-coverage "^1.0.0" - exit "^0.1.2" - glob "^7.1.3" - graceful-fs "^4.2.9" - istanbul-lib-coverage "^3.0.0" - istanbul-lib-instrument "^5.1.0" - istanbul-lib-report "^3.0.0" - istanbul-lib-source-maps "^4.0.0" - istanbul-reports "^3.1.3" - jest-message-util "^29.2.0" - jest-util "^29.2.0" - jest-worker "^29.2.0" - slash "^3.0.0" - string-length "^4.0.1" - strip-ansi "^6.0.0" - v8-to-istanbul "^9.0.1" - -"@jest/schemas@^29.0.0": - version "29.0.0" - resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.0.0.tgz#5f47f5994dd4ef067fb7b4188ceac45f77fe952a" - integrity sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA== - dependencies: - "@sinclair/typebox" "^0.24.1" - "@jest/source-map@^27.0.6": version "27.0.6" resolved "https://registry.npmjs.org/@jest/source-map/-/source-map-27.0.6.tgz" @@ -2080,15 +1950,6 @@ graceful-fs "^4.2.9" source-map "^0.6.0" -"@jest/source-map@^29.2.0": - version "29.2.0" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.2.0.tgz#ab3420c46d42508dcc3dc1c6deee0b613c235744" - integrity sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ== - dependencies: - "@jridgewell/trace-mapping" "^0.3.15" - callsites "^3.0.0" - graceful-fs "^4.2.9" - "@jest/test-result@^27.2.4": version "27.2.4" resolved "https://registry.npmjs.org/@jest/test-result/-/test-result-27.2.4.tgz" @@ -2109,16 +1970,6 @@ "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-result@^29.2.0": - version "29.2.0" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.2.0.tgz#3dcc7123b8f0fb5ba1f650ce17af45cce91a0323" - integrity sha512-l76EPJ6QqtzsCLS4aimJqWO53pxZ82o3aE+Brcmo1HJ/phb9+MR7gPhyDdN6VSGaLJCRVJBZgWEhAEz+qON0Fw== - dependencies: - "@jest/console" "^29.2.0" - "@jest/types" "^29.2.0" - "@types/istanbul-lib-coverage" "^2.0.0" - collect-v8-coverage "^1.0.0" - "@jest/test-sequencer@^27.2.4": version "27.2.4" resolved "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.2.4.tgz" @@ -2139,16 +1990,6 @@ jest-haste-map "^27.5.1" jest-runtime "^27.5.1" -"@jest/test-sequencer@^29.2.0": - version "29.2.0" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.2.0.tgz#acd875533f7ad01cb22da59ff4047de18e9d64da" - integrity sha512-NCnjZcGnVdva6IDqF7TCuFsXs2F1tohiNF9sasSJNzD7VfN5ic9XgcS/oPDalGiPLxCmGKj4kewqqrKAqBACcQ== - dependencies: - "@jest/test-result" "^29.2.0" - graceful-fs "^4.2.9" - jest-haste-map "^29.2.0" - slash "^3.0.0" - "@jest/transform@^27.2.4": version "27.2.4" resolved "https://registry.npmjs.org/@jest/transform/-/transform-27.2.4.tgz" @@ -2191,27 +2032,6 @@ source-map "^0.6.1" write-file-atomic "^3.0.0" -"@jest/transform@^29.2.0": - version "29.2.0" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.2.0.tgz#1c55ca549f64810351df999265a29f8ead51be15" - integrity sha512-NXMujGHy+B4DAj4dGnVPD0SIXlR2Z/N8Gp9h3mF66kcIRult1WWqY3/CEIrJcKviNWaFPYhZjCG2L3fteWzcUw== - dependencies: - "@babel/core" "^7.11.6" - "@jest/types" "^29.2.0" - "@jridgewell/trace-mapping" "^0.3.15" - babel-plugin-istanbul "^6.1.1" - chalk "^4.0.0" - convert-source-map "^1.4.0" - fast-json-stable-stringify "^2.1.0" - graceful-fs "^4.2.9" - jest-haste-map "^29.2.0" - jest-regex-util "^29.2.0" - jest-util "^29.2.0" - micromatch "^4.0.4" - pirates "^4.0.4" - slash "^3.0.0" - write-file-atomic "^4.0.1" - "@jest/types@^27.2.4": version "27.2.4" resolved "https://registry.npmjs.org/@jest/types/-/types-27.2.4.tgz" @@ -2234,18 +2054,6 @@ "@types/yargs" "^16.0.0" chalk "^4.0.0" -"@jest/types@^29.2.0": - version "29.2.0" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.2.0.tgz#c0d1ef8bc1e4f4b358e7877e34157371e7881b0b" - integrity sha512-mfgpQz4Z2xGo37m6KD8xEpKelaVzvYVRijmLPePn9pxgaPEtX+SqIyPNzzoeCPXKYbB4L/wYSgXDL8o3Gop78Q== - dependencies: - "@jest/schemas" "^29.0.0" - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^17.0.8" - chalk "^4.0.0" - "@jridgewell/gen-mapping@^0.1.0": version "0.1.1" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" @@ -2263,7 +2071,7 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/resolve-uri@3.1.0", "@jridgewell/resolve-uri@^3.0.3": +"@jridgewell/resolve-uri@^3.0.3": version "3.1.0" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== @@ -2281,7 +2089,7 @@ "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": +"@jridgewell/sourcemap-codec@^1.4.10": version "1.4.14" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== @@ -2294,14 +2102,6 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.15": - version "0.3.17" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" - integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== - dependencies: - "@jridgewell/resolve-uri" "3.1.0" - "@jridgewell/sourcemap-codec" "1.4.14" - "@jridgewell/trace-mapping@^0.3.9": version "0.3.14" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz#b231a081d8f66796e475ad588a1ef473112701ed" @@ -3367,11 +3167,6 @@ estree-walker "^2.0.1" picomatch "^2.2.2" -"@sinclair/typebox@^0.24.1": - version "0.24.46" - resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.46.tgz#57501b58023776dbbae9e25619146286440be34c" - integrity sha512-ng4ut1z2MCBhK/NwDVwIQp3pAUOCs/KNaW3cBxdFB2xTDrOuo1xuNmpr/9HHFhxqIvHrs1NTH3KJg6q+JSy1Kw== - "@sindresorhus/is@^0.14.0": version "0.14.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" @@ -3391,13 +3186,6 @@ dependencies: "@sinonjs/commons" "^1.7.0" -"@sinonjs/fake-timers@^9.1.2": - version "9.1.2" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz#4eaab737fab77332ab132d396a3c0d364bd0ea8c" - integrity sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw== - dependencies: - "@sinonjs/commons" "^1.7.0" - "@szmarczak/http-timer@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" @@ -3510,7 +3298,7 @@ resolved "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz" integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== -"@types/graceful-fs@^4.1.2", "@types/graceful-fs@^4.1.3": +"@types/graceful-fs@^4.1.2": version "4.1.5" resolved "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz" integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== @@ -3755,13 +3543,6 @@ dependencies: "@types/yargs-parser" "*" -"@types/yargs@^17.0.8": - version "17.0.13" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.13.tgz#34cced675ca1b1d51fcf4d34c3c6f0fa142a5c76" - integrity sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg== - dependencies: - "@types/yargs-parser" "*" - "@types/yauzl@2.9.2", "@types/yauzl@^2.9.1": version "2.9.2" resolved "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz" @@ -4480,19 +4261,6 @@ babel-jest@^27.5.1: graceful-fs "^4.2.9" slash "^3.0.0" -babel-jest@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.2.0.tgz#088624f037da90e69a06073305276cbd111d68a8" - integrity sha512-c8FkrW1chgcbyBqOo7jFGpQYfVnb43JqjQGV+C2r94k2rZJOukYOZ6+csAqKE4ms+PHc+yevnONxs27jQIxylw== - dependencies: - "@jest/transform" "^29.2.0" - "@types/babel__core" "^7.1.14" - babel-plugin-istanbul "^6.1.1" - babel-preset-jest "^29.2.0" - chalk "^4.0.0" - graceful-fs "^4.2.9" - slash "^3.0.0" - babel-plugin-istanbul@^6.0.0: version "6.0.0" resolved "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz" @@ -4535,16 +4303,6 @@ babel-plugin-jest-hoist@^27.5.1: "@types/babel__core" "^7.0.0" "@types/babel__traverse" "^7.0.6" -babel-plugin-jest-hoist@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.2.0.tgz#23ee99c37390a98cfddf3ef4a78674180d823094" - integrity sha512-TnspP2WNiR3GLfCsUNHqeXw0RoQ2f9U5hQ5L3XFpwuO8htQmSrhh8qsB6vi5Yi8+kuynN1yjDjQsPfkebmB6ZA== - dependencies: - "@babel/template" "^7.3.3" - "@babel/types" "^7.3.3" - "@types/babel__core" "^7.1.14" - "@types/babel__traverse" "^7.0.6" - babel-plugin-macros@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz#9ef6dc74deb934b4db344dc973ee851d148c50c1" @@ -4588,14 +4346,6 @@ babel-preset-jest@^27.5.1: babel-plugin-jest-hoist "^27.5.1" babel-preset-current-node-syntax "^1.0.0" -babel-preset-jest@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.2.0.tgz#3048bea3a1af222e3505e4a767a974c95a7620dc" - integrity sha512-z9JmMJppMxNv8N7fNRHvhMg9cvIkMxQBXgFkane3yKVEvEOP+kB50lk8DFRvF9PGqbyXxlmebKWhuDORO8RgdA== - dependencies: - babel-plugin-jest-hoist "^29.2.0" - babel-preset-current-node-syntax "^1.0.0" - babel-runtime@^6.26.0: version "6.26.0" resolved "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz" @@ -5168,15 +4918,6 @@ cliui@^7.0.2: strip-ansi "^6.0.0" wrap-ansi "^7.0.0" -cliui@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" - integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.1" - wrap-ansi "^7.0.0" - clone-deep@^4.0.1: version "4.0.1" resolved "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz" @@ -6080,11 +5821,6 @@ diff-sequences@^27.5.1: resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz" integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ== -diff-sequences@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.2.0.tgz#4c55b5b40706c7b5d2c5c75999a50c56d214e8f6" - integrity sha512-413SY5JpYeSBZxmenGEmCVQ8mCgtFJF0w9PROdaS6z987XC2Pd2GOKqOITLtMftmyFZqgtCOb/QA7/Z3ZXfzIw== - diff@^3.1.0, diff@^3.2.0: version "3.5.0" resolved "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz" @@ -6253,11 +5989,6 @@ electron-to-chromium@^1.4.251: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.254.tgz#c6203583890abf88dfc0be046cd72d3b48f8beb6" integrity sha512-Sh/7YsHqQYkA6ZHuHMy24e6TE4eX6KZVsZb9E/DvU1nQRIrH4BflO/4k+83tfdYvDl+MObvlqHPRICzEdC9c6Q== -emittery@^0.10.2: - version "0.10.2" - resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.10.2.tgz#902eec8aedb8c41938c46e9385e9db7e03182933" - integrity sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw== - emittery@^0.8.1: version "0.8.1" resolved "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz" @@ -7076,17 +6807,6 @@ expect@^27.5.1: jest-matcher-utils "^27.5.1" jest-message-util "^27.5.1" -expect@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-29.2.0.tgz#b90c6df52be7abfd9f206f273fbcf8b33d8f332d" - integrity sha512-03ClF3GWwUqd9Grgkr9ZSdaCJGMRA69PQ8jT7o+Bx100VlGiAFf9/8oIm9Qve7ZVJhuJxFftqFhviZJRxxNfvg== - dependencies: - "@jest/expect-utils" "^29.2.0" - jest-get-type "^29.2.0" - jest-matcher-utils "^29.2.0" - jest-message-util "^29.2.0" - jest-util "^29.2.0" - express@^4.16.4: version "4.17.1" resolved "https://registry.npmjs.org/express/-/express-4.17.1.tgz" @@ -7214,7 +6934,7 @@ fast-json-patch@^2.0.6: dependencies: fast-deep-equal "^2.0.1" -fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== @@ -8966,14 +8686,6 @@ jest-changed-files@^27.5.1: execa "^5.0.0" throat "^6.0.1" -jest-changed-files@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.2.0.tgz#b6598daa9803ea6a4dce7968e20ab380ddbee289" - integrity sha512-qPVmLLyBmvF5HJrY7krDisx6Voi8DmlV3GZYX0aFNbaQsZeoz1hfxcCMbqDGuQCxU1dJy9eYc2xscE8QrCCYaA== - dependencies: - execa "^5.0.0" - p-limit "^3.1.0" - jest-circus@^27.2.4: version "27.2.4" resolved "https://registry.npmjs.org/jest-circus/-/jest-circus-27.2.4.tgz" @@ -9024,31 +8736,6 @@ jest-circus@^27.5.1: stack-utils "^2.0.3" throat "^6.0.1" -jest-circus@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.2.0.tgz#692ddf3b12a5ae6326f2f37b9d176c68777fcf4c" - integrity sha512-bpJRMe+VtvYlF3q8JNx+/cAo4FYvNCiR5s7Z0Scf8aC+KJ2ineSjZKtw1cIZbythlplkiro0My8nc65pfCqJ3A== - dependencies: - "@jest/environment" "^29.2.0" - "@jest/expect" "^29.2.0" - "@jest/test-result" "^29.2.0" - "@jest/types" "^29.2.0" - "@types/node" "*" - chalk "^4.0.0" - co "^4.6.0" - dedent "^0.7.0" - is-generator-fn "^2.0.0" - jest-each "^29.2.0" - jest-matcher-utils "^29.2.0" - jest-message-util "^29.2.0" - jest-runtime "^29.2.0" - jest-snapshot "^29.2.0" - jest-util "^29.2.0" - p-limit "^3.1.0" - pretty-format "^29.2.0" - slash "^3.0.0" - stack-utils "^2.0.3" - jest-cli@^27.2.4: version "27.2.4" resolved "https://registry.npmjs.org/jest-cli/-/jest-cli-27.2.4.tgz" @@ -9085,24 +8772,6 @@ jest-cli@^27.5.1: prompts "^2.0.1" yargs "^16.2.0" -jest-cli@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.2.0.tgz#c6ca40889d6671c38b1cf9119d3b653809f31a3a" - integrity sha512-/581TzbXeO+5kbtSlhXEthGiVJCC8AP0jgT0iZINAAMW+tTFj2uWU7z+HNUH5yIYdHV7AvRr0fWLrmHJGIruHg== - dependencies: - "@jest/core" "^29.2.0" - "@jest/test-result" "^29.2.0" - "@jest/types" "^29.2.0" - chalk "^4.0.0" - exit "^0.1.2" - graceful-fs "^4.2.9" - import-local "^3.0.2" - jest-config "^29.2.0" - jest-util "^29.2.0" - jest-validate "^29.2.0" - prompts "^2.0.1" - yargs "^17.3.1" - jest-config@^27.2.4: version "27.2.4" resolved "https://registry.npmjs.org/jest-config/-/jest-config-27.2.4.tgz" @@ -9160,34 +8829,6 @@ jest-config@^27.5.1: slash "^3.0.0" strip-json-comments "^3.1.1" -jest-config@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.2.0.tgz#8823f35255f696444a882721e624d7ad352e208b" - integrity sha512-IkdCsrHIoxDPZAyFcdtQrCQ3uftLqns6Joj0tlbxiAQW4k/zTXmIygqWBmPNxO9FbFkDrhtYZiLHXjaJh9rS+Q== - dependencies: - "@babel/core" "^7.11.6" - "@jest/test-sequencer" "^29.2.0" - "@jest/types" "^29.2.0" - babel-jest "^29.2.0" - chalk "^4.0.0" - ci-info "^3.2.0" - deepmerge "^4.2.2" - glob "^7.1.3" - graceful-fs "^4.2.9" - jest-circus "^29.2.0" - jest-environment-node "^29.2.0" - jest-get-type "^29.2.0" - jest-regex-util "^29.2.0" - jest-resolve "^29.2.0" - jest-runner "^29.2.0" - jest-util "^29.2.0" - jest-validate "^29.2.0" - micromatch "^4.0.4" - parse-json "^5.2.0" - pretty-format "^29.2.0" - slash "^3.0.0" - strip-json-comments "^3.1.1" - jest-diff@^23.6.0: version "23.6.0" resolved "https://registry.npmjs.org/jest-diff/-/jest-diff-23.6.0.tgz" @@ -9218,16 +8859,6 @@ jest-diff@^27.5.1: jest-get-type "^27.5.1" pretty-format "^27.5.1" -jest-diff@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.2.0.tgz#b1e11ac1a1401fc4792ef8ba406b48f1ae7d2bc5" - integrity sha512-GsH07qQL+/D/GxlnU+sSg9GL3fBOcuTlmtr3qr2pnkiODCwubNN2/7slW4m3CvxDsEus/VEOfQKRFLyXsUlnZw== - dependencies: - chalk "^4.0.0" - diff-sequences "^29.2.0" - jest-get-type "^29.2.0" - pretty-format "^29.2.0" - jest-docblock@^27.0.6: version "27.0.6" resolved "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.0.6.tgz" @@ -9242,13 +8873,6 @@ jest-docblock@^27.5.1: dependencies: detect-newline "^3.0.0" -jest-docblock@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.2.0.tgz#307203e20b637d97cee04809efc1d43afc641e82" - integrity sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A== - dependencies: - detect-newline "^3.0.0" - jest-each@^27.2.4: version "27.2.4" resolved "https://registry.npmjs.org/jest-each/-/jest-each-27.2.4.tgz" @@ -9271,17 +8895,6 @@ jest-each@^27.5.1: jest-util "^27.5.1" pretty-format "^27.5.1" -jest-each@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.2.0.tgz#0f89c1233d65f22c7dba265ccd319611f1d662de" - integrity sha512-h4LeC3L/R7jIMfTdYowevPIssvcPYQ7Qzs+pCSYsJgPztIizXwKmnfhZXBA4WVqdmvMcpmseYEXb67JT7IJ2eg== - dependencies: - "@jest/types" "^29.2.0" - chalk "^4.0.0" - jest-get-type "^29.2.0" - jest-util "^29.2.0" - pretty-format "^29.2.0" - jest-environment-jsdom@^27.2.4: version "27.2.4" resolved "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.2.4.tgz" @@ -9332,18 +8945,6 @@ jest-environment-node@^27.5.1: jest-mock "^27.5.1" jest-util "^27.5.1" -jest-environment-node@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.2.0.tgz#49c39d4f9df64fc74da3725cbcaeee6da01a6dd6" - integrity sha512-b4qQGVStPMvtZG97Ac0rvnmSIjCZturFU7MQRMp4JDFl7zoaDLTtXmFjFP1tNmi9te6kR8d+Htbv3nYeoaIz6g== - dependencies: - "@jest/environment" "^29.2.0" - "@jest/fake-timers" "^29.2.0" - "@jest/types" "^29.2.0" - "@types/node" "*" - jest-mock "^29.2.0" - jest-util "^29.2.0" - jest-get-type@^22.1.0: version "22.4.3" resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-22.4.3.tgz" @@ -9359,11 +8960,6 @@ jest-get-type@^27.5.1: resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz" integrity sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw== -jest-get-type@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.2.0.tgz#726646f927ef61d583a3b3adb1ab13f3a5036408" - integrity sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA== - jest-haste-map@^27.2.4: version "27.2.4" resolved "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.2.4.tgz" @@ -9404,25 +9000,6 @@ jest-haste-map@^27.5.1: optionalDependencies: fsevents "^2.3.2" -jest-haste-map@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.2.0.tgz#2410f2ec93958e0bd894818de6c8056eb1b4d6fc" - integrity sha512-qu9lGFi7qJ8v37egS1phZZUJYiMyWnKwu83NlNT1qs50TbedIX2hFl+9ztsJ7U/ENaHwk1/Bs8fqOIQsScIRwg== - dependencies: - "@jest/types" "^29.2.0" - "@types/graceful-fs" "^4.1.3" - "@types/node" "*" - anymatch "^3.0.3" - fb-watchman "^2.0.0" - graceful-fs "^4.2.9" - jest-regex-util "^29.2.0" - jest-util "^29.2.0" - jest-worker "^29.2.0" - micromatch "^4.0.4" - walker "^1.0.8" - optionalDependencies: - fsevents "^2.3.2" - jest-image-snapshot@^4.5.1: version "4.5.1" resolved "https://registry.npmjs.org/jest-image-snapshot/-/jest-image-snapshot-4.5.1.tgz" @@ -9501,14 +9078,6 @@ jest-leak-detector@^27.5.1: jest-get-type "^27.5.1" pretty-format "^27.5.1" -jest-leak-detector@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.2.0.tgz#7c0eace293cf05a130a09beb1b9318ecc2f77692" - integrity sha512-FXT9sCFdct42+oOqGIr/9kmUw3RbhvpkwidCBT5ySHHoWNGd3c9n7HXpFKjEz9UnUITRCGdn0q2s6Sxrq36kwg== - dependencies: - jest-get-type "^29.2.0" - pretty-format "^29.2.0" - jest-matcher-utils@^23.6.0: version "23.6.0" resolved "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-23.6.0.tgz" @@ -9538,16 +9107,6 @@ jest-matcher-utils@^27.2.4: jest-get-type "^27.0.6" pretty-format "^27.2.4" -jest-matcher-utils@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.2.0.tgz#d1d73add0e0efb0e316a50f296977505dc053e02" - integrity sha512-FcEfKZ4vm28yCdBsvC69EkrEhcfex+IYlRctNJXsRG9+WC3WxgBNORnECIgqUtj7o/h1d8o7xB/dFUiLi4bqtw== - dependencies: - chalk "^4.0.0" - jest-diff "^29.2.0" - jest-get-type "^29.2.0" - pretty-format "^29.2.0" - jest-message-util@^23.4.0: version "23.4.0" resolved "https://registry.npmjs.org/jest-message-util/-/jest-message-util-23.4.0.tgz" @@ -9589,21 +9148,6 @@ jest-message-util@^27.5.1: slash "^3.0.0" stack-utils "^2.0.3" -jest-message-util@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.2.0.tgz#cbd43fd9a20a8facd4267ac37556bc5c9a525ec0" - integrity sha512-arBfk5yMFMTnMB22GyG601xGSGthA02vWSewPaxoFo0F9wBqDOyxccPbCcYu8uibw3kduSHXdCOd1PsLSgdomg== - dependencies: - "@babel/code-frame" "^7.12.13" - "@jest/types" "^29.2.0" - "@types/stack-utils" "^2.0.0" - chalk "^4.0.0" - graceful-fs "^4.2.9" - micromatch "^4.0.4" - pretty-format "^29.2.0" - slash "^3.0.0" - stack-utils "^2.0.3" - jest-mock@^27.2.4: version "27.2.4" resolved "https://registry.npmjs.org/jest-mock/-/jest-mock-27.2.4.tgz" @@ -9620,15 +9164,6 @@ jest-mock@^27.5.1: "@jest/types" "^27.5.1" "@types/node" "*" -jest-mock@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.2.0.tgz#3531012881178f59f4b5fd1e243acc329d08d6a1" - integrity sha512-aiWGR0P8ivssIO17xkehLGFtCcef2ZwQFNPwEer1jQLHxPctDlIg3Hs6QMq1KpPz5dkCcgM7mwGif4a9IPznlg== - dependencies: - "@jest/types" "^29.2.0" - "@types/node" "*" - jest-util "^29.2.0" - jest-pnp-resolver@^1.2.2: version "1.2.2" resolved "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz" @@ -9644,11 +9179,6 @@ jest-regex-util@^27.5.1: resolved "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz" integrity sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg== -jest-regex-util@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.2.0.tgz#82ef3b587e8c303357728d0322d48bbfd2971f7b" - integrity sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA== - jest-resolve-dependencies@^27.2.4: version "27.2.4" resolved "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.2.4.tgz" @@ -9667,14 +9197,6 @@ jest-resolve-dependencies@^27.5.1: jest-regex-util "^27.5.1" jest-snapshot "^27.5.1" -jest-resolve-dependencies@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.2.0.tgz#a127b7d6b7df69d4eaf2c7c99f652f17ba0fed71" - integrity sha512-Cd0Z39sDntEnfR9PoUdFHUAGDvtKI0/7Wt73l3lt03A3yQ+A6Qi3XmBuqGjdFl2QbXaPa937oLhilG612P8HGQ== - dependencies: - jest-regex-util "^29.2.0" - jest-snapshot "^29.2.0" - jest-resolve@^23.6.0: version "23.6.0" resolved "https://registry.npmjs.org/jest-resolve/-/jest-resolve-23.6.0.tgz" @@ -9716,21 +9238,6 @@ jest-resolve@^27.5.1: resolve.exports "^1.1.0" slash "^3.0.0" -jest-resolve@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.2.0.tgz#cb9f9770164382785cd68598a9fb0b7e4bb95a9f" - integrity sha512-f5c0ljNg2guDBCC7wi92vAhNuA0BtAG5vkY7Fob0c7sUMU1g87mTXqRmjrVFe2XvdwP5m5T/e5KJsCKu9hRvBA== - dependencies: - chalk "^4.0.0" - graceful-fs "^4.2.9" - jest-haste-map "^29.2.0" - jest-pnp-resolver "^1.2.2" - jest-util "^29.2.0" - jest-validate "^29.2.0" - resolve "^1.20.0" - resolve.exports "^1.1.0" - slash "^3.0.0" - jest-runner@^27.2.4: version "27.2.4" resolved "https://registry.npmjs.org/jest-runner/-/jest-runner-27.2.4.tgz" @@ -9786,33 +9293,6 @@ jest-runner@^27.5.1: source-map-support "^0.5.6" throat "^6.0.1" -jest-runner@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.2.0.tgz#d621e67a2d59d5bc302eca1f5348615ce166712c" - integrity sha512-VPBrCwl9fM2mc5yk6yZhNrgXzRJMD5jfLmntkMLlrVq4hQPWbRK998iJlR+DOGCO04TC9PPYLntOJ001Vnf28g== - dependencies: - "@jest/console" "^29.2.0" - "@jest/environment" "^29.2.0" - "@jest/test-result" "^29.2.0" - "@jest/transform" "^29.2.0" - "@jest/types" "^29.2.0" - "@types/node" "*" - chalk "^4.0.0" - emittery "^0.10.2" - graceful-fs "^4.2.9" - jest-docblock "^29.2.0" - jest-environment-node "^29.2.0" - jest-haste-map "^29.2.0" - jest-leak-detector "^29.2.0" - jest-message-util "^29.2.0" - jest-resolve "^29.2.0" - jest-runtime "^29.2.0" - jest-util "^29.2.0" - jest-watcher "^29.2.0" - jest-worker "^29.2.0" - p-limit "^3.1.0" - source-map-support "0.5.13" - jest-runtime@^27.2.4: version "27.2.4" resolved "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.2.4.tgz" @@ -9874,34 +9354,6 @@ jest-runtime@^27.5.1: slash "^3.0.0" strip-bom "^4.0.0" -jest-runtime@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.2.0.tgz#6b10d9539c1f7af32d06fccd7d16b6c9996c9cb2" - integrity sha512-+GDmzCrswQF+mvI0upTYMe/OPYnlRRNLLDHM9AFLp2y7zxWoDoYgb8DL3WwJ8d9m743AzrnvBV9JQHi/0ed7dg== - dependencies: - "@jest/environment" "^29.2.0" - "@jest/fake-timers" "^29.2.0" - "@jest/globals" "^29.2.0" - "@jest/source-map" "^29.2.0" - "@jest/test-result" "^29.2.0" - "@jest/transform" "^29.2.0" - "@jest/types" "^29.2.0" - "@types/node" "*" - chalk "^4.0.0" - cjs-module-lexer "^1.0.0" - collect-v8-coverage "^1.0.0" - glob "^7.1.3" - graceful-fs "^4.2.9" - jest-haste-map "^29.2.0" - jest-message-util "^29.2.0" - jest-mock "^29.2.0" - jest-regex-util "^29.2.0" - jest-resolve "^29.2.0" - jest-snapshot "^29.2.0" - jest-util "^29.2.0" - slash "^3.0.0" - strip-bom "^4.0.0" - jest-serializer@^27.0.6: version "27.0.6" resolved "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.0.6.tgz" @@ -9992,36 +9444,6 @@ jest-snapshot@^27.5.1: pretty-format "^27.5.1" semver "^7.3.2" -jest-snapshot@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.2.0.tgz#fb3d4e1d9df579f37d7c60072877ee99376b6090" - integrity sha512-YCKrOR0PLRXROmww73fHO9oeY4tL+LPQXWR3yml1+hKbQDR8j1VUrVzB65hKSJJgxBOr1vWx+hmz2by8JjAU5w== - dependencies: - "@babel/core" "^7.11.6" - "@babel/generator" "^7.7.2" - "@babel/plugin-syntax-jsx" "^7.7.2" - "@babel/plugin-syntax-typescript" "^7.7.2" - "@babel/traverse" "^7.7.2" - "@babel/types" "^7.3.3" - "@jest/expect-utils" "^29.2.0" - "@jest/transform" "^29.2.0" - "@jest/types" "^29.2.0" - "@types/babel__traverse" "^7.0.6" - "@types/prettier" "^2.1.5" - babel-preset-current-node-syntax "^1.0.0" - chalk "^4.0.0" - expect "^29.2.0" - graceful-fs "^4.2.9" - jest-diff "^29.2.0" - jest-get-type "^29.2.0" - jest-haste-map "^29.2.0" - jest-matcher-utils "^29.2.0" - jest-message-util "^29.2.0" - jest-util "^29.2.0" - natural-compare "^1.4.0" - pretty-format "^29.2.0" - semver "^7.3.5" - jest-util@^27.0.0, jest-util@^27.2.4: version "27.2.4" resolved "https://registry.npmjs.org/jest-util/-/jest-util-27.2.4.tgz" @@ -10046,18 +9468,6 @@ jest-util@^27.5.1: graceful-fs "^4.2.9" picomatch "^2.2.3" -jest-util@^29.0.0, jest-util@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.2.0.tgz#797935697e83a5722aeba401ed6cd01264295566" - integrity sha512-8M1dx12ujkBbnhwytrezWY0Ut79hbflwodE+qZKjxSRz5qt4xDp6dQQJaOCFvCmE0QJqp9KyEK33lpPNjnhevw== - dependencies: - "@jest/types" "^29.2.0" - "@types/node" "*" - chalk "^4.0.0" - ci-info "^3.2.0" - graceful-fs "^4.2.9" - picomatch "^2.2.3" - jest-validate@^27.2.4: version "27.2.4" resolved "https://registry.npmjs.org/jest-validate/-/jest-validate-27.2.4.tgz" @@ -10082,18 +9492,6 @@ jest-validate@^27.5.1: leven "^3.1.0" pretty-format "^27.5.1" -jest-validate@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.2.0.tgz#e40faf33759365c12ead6a45165349d660d09ba4" - integrity sha512-4Vl51bPNeFeDok9aJiOnrC6tqJbOp4iMCYlewoC2ZzYJZ5+6pfr3KObAdx5wP8auHcg2MRaguiqj5OdScZa72g== - dependencies: - "@jest/types" "^29.2.0" - camelcase "^6.2.0" - chalk "^4.0.0" - jest-get-type "^29.2.0" - leven "^3.1.0" - pretty-format "^29.2.0" - jest-watcher@^27.2.4: version "27.2.4" resolved "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.2.4.tgz" @@ -10120,20 +9518,6 @@ jest-watcher@^27.5.1: jest-util "^27.5.1" string-length "^4.0.1" -jest-watcher@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.2.0.tgz#d0c58ff76d3dd22fff79f3f9cbeadaa749d2ca6e" - integrity sha512-bRh0JdUeN+cl9XfK7tMnXLm4Mv70hG2SZlqbkFe5CTs7oeCkbwlGBk/mEfEJ63mrxZ8LPbnfaMpfSmkhEQBEGA== - dependencies: - "@jest/test-result" "^29.2.0" - "@jest/types" "^29.2.0" - "@types/node" "*" - ansi-escapes "^4.2.1" - chalk "^4.0.0" - emittery "^0.10.2" - jest-util "^29.2.0" - string-length "^4.0.1" - jest-worker@^26.2.1: version "26.6.2" resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz" @@ -10161,16 +9545,6 @@ jest-worker@^27.5.1: merge-stream "^2.0.0" supports-color "^8.0.0" -jest-worker@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.2.0.tgz#b2bd1a81fc7a1ae79a500b05f5feb0d1c0b1a19e" - integrity sha512-mluOlMbRX1H59vGVzPcVg2ALfCausbBpxC8a2KWOzInhYHZibbHH8CB0C1JkmkpfurrkOYgF7FPmypuom1OM9A== - dependencies: - "@types/node" "*" - jest-util "^29.2.0" - merge-stream "^2.0.0" - supports-color "^8.0.0" - jest@^27.2.4: version "27.2.4" resolved "https://registry.npmjs.org/jest/-/jest-27.2.4.tgz" @@ -10189,16 +9563,6 @@ jest@^27.5.1: import-local "^3.0.2" jest-cli "^27.5.1" -jest@^29.0.3: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest/-/jest-29.2.0.tgz#e7997bc603f31e04edbbe87dd24cf6e7c432abac" - integrity sha512-6krPemKUXCEu5Fh3j6ZVoLMjpTQVm0OCU+7f3K/9gllX8wNIE6NSCQ6s0q2RDoiKLRaQlVRHyscjSPRPqCI0Fg== - dependencies: - "@jest/core" "^29.2.0" - "@jest/types" "^29.2.0" - import-local "^3.0.2" - jest-cli "^29.2.0" - jju@~1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/jju/-/jju-1.4.0.tgz#a3abe2718af241a2b2904f84a625970f389ae32a" @@ -10844,13 +10208,6 @@ make-fetch-happen@^9.0.1: socks-proxy-agent "^5.0.0" ssri "^8.0.0" -makeerror@1.0.12: - version "1.0.12" - resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" - integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== - dependencies: - tmpl "1.0.5" - makeerror@1.0.x: version "1.0.11" resolved "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz" @@ -11837,7 +11194,7 @@ p-limit@^2.2.0: dependencies: p-try "^2.0.0" -p-limit@^3.0.2, p-limit@^3.1.0: +p-limit@^3.0.2: version "3.1.0" resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== @@ -12682,15 +12039,6 @@ pretty-format@^27.5.1: ansi-styles "^5.0.0" react-is "^17.0.1" -pretty-format@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.2.0.tgz#1d4ea56fb46079b44efd9ed59c14f70f2950a61b" - integrity sha512-QCSUFdwOi924g24czhOH5eTkXxUCqlLGZBRCySlwDYHIXRJkdGyjJc9nZaqhlFBZws8dq5Dvk0lCilsmlfsPxw== - dependencies: - "@jest/schemas" "^29.0.0" - ansi-styles "^5.0.0" - react-is "^18.0.0" - process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" @@ -12982,11 +12330,6 @@ react-is@^17.0.1: resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== -react-is@^18.0.0: - version "18.2.0" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" - integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== - react-refresh@^0.14.0: version "0.14.0" resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.0.tgz#4e02825378a5f227079554d4284889354e5f553e" @@ -13813,11 +13156,6 @@ signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3: resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz" integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== -signal-exit@^3.0.7: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - simple-peer-light@^9.10.0: version "9.10.0" resolved "https://registry.yarnpkg.com/simple-peer-light/-/simple-peer-light-9.10.0.tgz#6f3699b80e4b6d3a9374a865e1a8e497aa623afb" @@ -13919,14 +13257,6 @@ source-map-js@^1.0.2: resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== -source-map-support@0.5.13: - version "0.5.13" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" - integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - source-map-support@0.5.20: version "0.5.20" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.20.tgz#12166089f8f5e5e8c56926b377633392dd2cb6c9" @@ -14594,7 +13924,7 @@ tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" -tmpl@1.0.5, tmpl@1.0.x: +tmpl@1.0.x: version "1.0.5" resolved "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz" integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== @@ -14715,20 +14045,6 @@ ts-jest@^27.1.3: semver "7.x" yargs-parser "20.x" -ts-jest@^29.0.1: - version "29.0.3" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.0.3.tgz#63ea93c5401ab73595440733cefdba31fcf9cb77" - integrity sha512-Ibygvmuyq1qp/z3yTh9QTwVVAbFdDy/+4BtIQR2sp6baF2SJU/8CKK/hhnGIDY2L90Az2jIqTwZPnN2p+BweiQ== - dependencies: - bs-logger "0.x" - fast-json-stable-stringify "2.x" - jest-util "^29.0.0" - json5 "^2.2.1" - lodash.memoize "4.x" - make-error "1.x" - semver "7.x" - yargs-parser "^21.0.1" - ts-node@^10.9.1: version "10.9.1" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" @@ -15211,15 +14527,6 @@ v8-to-istanbul@^8.1.0: convert-source-map "^1.6.0" source-map "^0.7.3" -v8-to-istanbul@^9.0.1: - version "9.0.1" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz#b6f994b0b5d4ef255e17a0d17dc444a9f5132fa4" - integrity sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w== - dependencies: - "@jridgewell/trace-mapping" "^0.3.12" - "@types/istanbul-lib-coverage" "^2.0.1" - convert-source-map "^1.6.0" - validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: version "3.0.4" resolved "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz" @@ -15303,13 +14610,6 @@ walker@^1.0.7: dependencies: makeerror "1.0.x" -walker@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" - integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== - dependencies: - makeerror "1.0.12" - watchpack@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.1.1.tgz#e99630550fca07df9f90a06056987baa40a689c7" @@ -15519,14 +14819,6 @@ write-file-atomic@^3.0.0, write-file-atomic@^3.0.3: signal-exit "^3.0.2" typedarray-to-buffer "^3.1.5" -write-file-atomic@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" - integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== - dependencies: - imurmurhash "^0.1.4" - signal-exit "^3.0.7" - write-json-file@^3.2.0: version "3.2.0" resolved "https://registry.npmjs.org/write-json-file/-/write-json-file-3.2.0.tgz" @@ -15658,7 +14950,7 @@ yargs-parser@^18.1.3: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^21.0.0, yargs-parser@^21.0.1: +yargs-parser@^21.0.0: version "21.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== @@ -15689,19 +14981,6 @@ yargs@17.4.0: y18n "^5.0.5" yargs-parser "^21.0.0" -yargs@^17.3.1: - version "17.6.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.6.0.tgz#e134900fc1f218bc230192bdec06a0a5f973e46c" - integrity sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g== - dependencies: - cliui "^8.0.1" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.3" - y18n "^5.0.5" - yargs-parser "^21.0.0" - yauzl@2.10.0, yauzl@^2.10.0: version "2.10.0" resolved "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz" From 3209471e750ea1b3b2878b4ba9ddbd5b2f2c38fa Mon Sep 17 00:00:00 2001 From: Mark-Fenng Date: Wed, 2 Nov 2022 18:49:23 +1100 Subject: [PATCH 09/40] try to fix CI error --- .github/workflows/style-check.yml | 2 +- .travis.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/style-check.yml b/.github/workflows/style-check.yml index 50498ee960..79320836dc 100644 --- a/.github/workflows/style-check.yml +++ b/.github/workflows/style-check.yml @@ -20,7 +20,7 @@ jobs: - name: Install Dependencies run: yarn - name: Build Packages - run: yarn build:all + run: NODE_OPTIONS='--max-old-space-size=4096' yarn build:all - name: Eslint Check run: yarn turbo run lint - name: Save Code Linting Report JSON diff --git a/.travis.yml b/.travis.yml index b122c43a8f..4d5d7f9ba9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,6 @@ install: - yarn script: - - yarn build:all + - NODE_OPTIONS='--max-old-space-size=4096' yarn build:all - yarn turbo run check-types - xvfb-run --server-args="-screen 0 1920x1080x24" yarn test From f134ddcbf20a1946a3ae383d1799ec91b029b0e6 Mon Sep 17 00:00:00 2001 From: Mark-Fenng Date: Thu, 3 Nov 2022 16:12:28 +1100 Subject: [PATCH 10/40] feat: add pause and resume buttons --- .../web-extension/src/background/index.ts | 93 ++------ packages/web-extension/src/content/index.ts | 6 +- packages/web-extension/src/content/inject.ts | 2 +- packages/web-extension/src/popup/App.tsx | 215 +++++++++++------- packages/web-extension/src/popup/Timer.tsx | 2 +- packages/web-extension/src/utils/index.ts | 81 +++++++ 6 files changed, 242 insertions(+), 157 deletions(-) diff --git a/packages/web-extension/src/background/index.ts b/packages/web-extension/src/background/index.ts index 6bf8e7e5d3..a5337d92d0 100644 --- a/packages/web-extension/src/background/index.ts +++ b/packages/web-extension/src/background/index.ts @@ -5,13 +5,11 @@ import { LocalData, LocalDataKey, RecorderStatus, - RecordStartedMessage, - RecordStoppedMessage, - ServiceName, Settings, SyncData, SyncDataKey, } from '../types'; +import { pauseRecording, resumeRecording } from '../utils'; const channel = new Channel(); @@ -30,84 +28,42 @@ void (async () => { settings, } as SyncData); - // Resume recording after change to a new tab. - const resumeRecording = async ( - newTabId: number, - events: eventWithTime[], - startTimestamp: number, - pausedTimestamp: number | undefined, - ) => { - const startResponse = (await channel.requestToTab( - newTabId, - ServiceName.ResumeRecord, - { events, pausedTimestamp }, - )) as RecordStartedMessage; - if (!startResponse) return; - const pausedTime = pausedTimestamp - ? startResponse.startTimestamp - pausedTimestamp - : 0; - const statusData: LocalData[LocalDataKey.recorderStatus] = { - status: RecorderStatus.RECORDING, - activeTabId: newTabId, - startTimestamp: startTimestamp + pausedTime, - }; - await Browser.storage.local.set({ - [LocalDataKey.recorderStatus]: statusData, - }); - }; - + // When tab is changed during the recording process, pause recording in the old tab and start a new one in the new tab. Browser.tabs.onActivated.addListener((activeInfo) => { void Browser.storage.local .get(LocalDataKey.recorderStatus) .then(async (data) => { const localData = data as LocalData; if (!localData || !localData[LocalDataKey.recorderStatus]) return; - let { status, pausedTimestamp } = localData[ - LocalDataKey.recorderStatus - ]; - const { startTimestamp, activeTabId } = localData[ - LocalDataKey.recorderStatus - ]; + let statusData = localData[LocalDataKey.recorderStatus]; + let { status } = statusData; let bufferedEvents: eventWithTime[] | undefined; if (status === RecorderStatus.RECORDING) { - const stopResponse = (await channel.requestToTab( - activeTabId, - ServiceName.PauseRecord, - {}, - )) as RecordStoppedMessage; - if (!stopResponse) return; - const statusData: LocalData[LocalDataKey.recorderStatus] = { - status: RecorderStatus.PausedSwitch, - activeTabId: activeInfo.tabId, - startTimestamp, - pausedTimestamp: stopResponse.endTimestamp, - }; - await Browser.storage.local.set({ - [LocalDataKey.recorderStatus]: statusData, - }); - status = RecorderStatus.PausedSwitch; - pausedTimestamp = stopResponse.endTimestamp; - bufferedEvents = stopResponse.events; + const result = await pauseRecording( + channel, + RecorderStatus.PausedSwitch, + statusData, + ); + if (!result) return; + statusData = result.status; + status = statusData.status; + bufferedEvents = result.bufferedEvents; } - if (status === RecorderStatus.PausedSwitch) { - if (!bufferedEvents) - bufferedEvents = ((await Browser.storage.local.get( - LocalDataKey.bufferedEvents, - )) as LocalData)[LocalDataKey.bufferedEvents]; + if (status === RecorderStatus.PausedSwitch) await resumeRecording( + channel, activeInfo.tabId, + statusData, bufferedEvents, - startTimestamp || bufferedEvents[0].timestamp, - pausedTimestamp, ); - } }) .catch(() => { // the extension can't access to the tab }); }); + // If the recording can't start on an invalid tab, resume it when the tab content is updated. Browser.tabs.onUpdated.addListener(function (tabId, info) { if (info.status !== 'complete') return; void Browser.storage.local @@ -115,22 +71,13 @@ void (async () => { .then(async (data) => { const localData = data as LocalData; if (!localData || !localData[LocalDataKey.recorderStatus]) return; - const { - status, - activeTabId, - startTimestamp, - pausedTimestamp, - } = localData[LocalDataKey.recorderStatus]; + const { status, activeTabId } = localData[LocalDataKey.recorderStatus]; if (status !== RecorderStatus.PausedSwitch || activeTabId === tabId) return; - const bufferedEvents = ((await Browser.storage.local.get( - LocalDataKey.bufferedEvents, - )) as LocalData)[LocalDataKey.bufferedEvents]; await resumeRecording( + channel, tabId, - bufferedEvents, - startTimestamp || bufferedEvents[0].timestamp, - pausedTimestamp, + localData[LocalDataKey.recorderStatus], ); }) .catch(() => { diff --git a/packages/web-extension/src/content/index.ts b/packages/web-extension/src/content/index.ts index 2a959f8efd..d38b9c44bd 100644 --- a/packages/web-extension/src/content/index.ts +++ b/packages/web-extension/src/content/index.ts @@ -100,13 +100,15 @@ void (async () => { clearRecorderCb?.(); clearRecorderCb = undefined; stopResponseCb(data); - } else if (event.data.message === MessageName.HeartBeat) { + void Browser.storage.local.set({ + [LocalDataKey.bufferedEvents]: storedEvents.concat(data.events), + }); + } else if (event.data.message === MessageName.HeartBeat) void Browser.storage.local.set({ [LocalDataKey.bufferedEvents]: storedEvents.concat( (event.data as HeartBreathMessage).events, ), }); - } }, ); diff --git a/packages/web-extension/src/content/inject.ts b/packages/web-extension/src/content/inject.ts index 7ceabec51f..11e80dea9f 100644 --- a/packages/web-extension/src/content/inject.ts +++ b/packages/web-extension/src/content/inject.ts @@ -24,7 +24,7 @@ function startRecord(config: recordOptions) { message: MessageName.HeartBeat, events, }); - }, 50) as unknown) as number; + }, 500) as unknown) as number; } window.addEventListener( diff --git a/packages/web-extension/src/popup/App.tsx b/packages/web-extension/src/popup/App.tsx index 354566b658..daac6705e1 100644 --- a/packages/web-extension/src/popup/App.tsx +++ b/packages/web-extension/src/popup/App.tsx @@ -1,6 +1,6 @@ import { useState, useEffect } from 'react'; import { Box, Flex, IconButton, Spacer, Stack, Text } from '@chakra-ui/react'; -import { FiSettings, FiList } from 'react-icons/fi'; +import { FiSettings, FiList, FiPause, FiPlay } from 'react-icons/fi'; import Channel from '../utils/channel'; import { LocalData, @@ -12,12 +12,13 @@ import { import Browser from 'webextension-polyfill'; import { CircleButton } from '../components/CircleButton'; import { Timer } from './Timer'; +import { pauseRecording, resumeRecording } from '../utils'; const RECORD_BUTTON_SIZE = 3; const channel = new Channel(); export function App() { - const [recording, setRecording] = useState(false); + const [status, setStatus] = useState(RecorderStatus.IDLE); const [errorMessage, setErrorMessage] = useState(''); const [startTime, setStartTime] = useState(0); @@ -25,11 +26,13 @@ export function App() { void Browser.storage.local.get(LocalDataKey.recorderStatus).then((data) => { const localData = data as LocalData; if (!localData || !localData[LocalDataKey.recorderStatus]) return; - const { status, startTimestamp } = localData[LocalDataKey.recorderStatus]; - if (status === RecorderStatus.RECORDING) { - setRecording(true); - setStartTime(startTimestamp || 0); - } + const { status, startTimestamp, pausedTimestamp } = localData[ + LocalDataKey.recorderStatus + ]; + setStatus(status); + if (startTimestamp && pausedTimestamp) + setStartTime(Date.now() - pausedTimestamp + startTimestamp || 0); + else if (startTimestamp) setStartTime(startTimestamp); }); }, []); @@ -61,75 +64,114 @@ export function App() { > - {recording && startTime && ( - + {status !== RecorderStatus.IDLE && startTime && ( + )} - { - if (recording) { - // stop recording - setErrorMessage(''); - void channel.getCurrentTabId().then((tabId) => { - if (tabId === -1) return; - void channel - .requestToTab(tabId, ServiceName.StopRecord, {}) - .then(async (res) => { - if (res) { - setRecording(false); - const status: LocalData[LocalDataKey.recorderStatus] = { - status: RecorderStatus.IDLE, - activeTabId: tabId, - }; - await Browser.storage.local.set({ - [LocalDataKey.recorderStatus]: status, - }); - } - }) - .catch((error: Error) => { - setErrorMessage(error.message); - }); - }); - } else { - // start recording - void channel.getCurrentTabId().then((tabId) => { - if (tabId === -1) return; - void channel - .requestToTab(tabId, ServiceName.StartRecord, {}) - .then(async (res: RecordStartedMessage | undefined) => { - if (res) { - setRecording(true); - setStartTime(res.startTimestamp); - const status: LocalData[LocalDataKey.recorderStatus] = { - status: RecorderStatus.RECORDING, - activeTabId: tabId, - startTimestamp: res.startTimestamp, - }; - await Browser.storage.local.set({ - [LocalDataKey.recorderStatus]: status, - }); - } - }) - .catch((error: Error) => { - setErrorMessage(error.message); - }); - }); + {[RecorderStatus.IDLE, RecorderStatus.RECORDING].includes(status) && ( + - - - {/* // TODO add pause function */} - {/* {recording && ( - + onClick={() => { + if (status === RecorderStatus.RECORDING) { + // stop recording + setErrorMessage(''); + void channel.getCurrentTabId().then((tabId) => { + if (tabId === -1) return; + void channel + .requestToTab(tabId, ServiceName.StopRecord, {}) + .then(async (res) => { + if (res) { + setStatus(RecorderStatus.IDLE); + const status: LocalData[LocalDataKey.recorderStatus] = { + status: RecorderStatus.IDLE, + activeTabId: tabId, + }; + await Browser.storage.local.set({ + [LocalDataKey.recorderStatus]: status, + }); + } + }) + .catch((error: Error) => { + setErrorMessage(error.message); + }); + }); + } else { + // start recording + void channel.getCurrentTabId().then((tabId) => { + if (tabId === -1) return; + void channel + .requestToTab(tabId, ServiceName.StartRecord, {}) + .then(async (res: RecordStartedMessage | undefined) => { + if (res) { + setStatus(RecorderStatus.RECORDING); + setStartTime(res.startTimestamp); + const status: LocalData[LocalDataKey.recorderStatus] = { + status: RecorderStatus.RECORDING, + activeTabId: tabId, + startTimestamp: res.startTimestamp, + }; + await Browser.storage.local.set({ + [LocalDataKey.recorderStatus]: status, + }); + } + }) + .catch((error: Error) => { + setErrorMessage(error.message); + }); + }); + } + }} + > + + + )} + {status !== RecorderStatus.IDLE && ( + { + if (status === RecorderStatus.RECORDING) { + void pauseRecording(channel, RecorderStatus.PAUSED).then( + (result) => { + if (!result) return; + setStatus(result?.status.status); + }, + ); + } else { + void channel.getCurrentTabId().then((tabId) => { + if (tabId === -1) return; + resumeRecording(channel, tabId) + .then((statusData) => { + if (!statusData) return; + setStatus(statusData.status); + if (statusData.startTimestamp) + setStartTime(statusData.startTimestamp); + }) + .catch((error: Error) => { + setErrorMessage(error.message); + }); + }); + } + }} + > - + {[RecorderStatus.PAUSED, RecorderStatus.PausedSwitch].includes( + status, + ) && ( + + )} + {status === RecorderStatus.RECORDING && ( + + )} - )} */} + )} {errorMessage !== '' && ( diff --git a/packages/web-extension/src/popup/Timer.tsx b/packages/web-extension/src/popup/Timer.tsx index 066e2c6421..f965f10dad 100644 --- a/packages/web-extension/src/popup/Timer.tsx +++ b/packages/web-extension/src/popup/Timer.tsx @@ -9,7 +9,7 @@ export function Timer({ startTime: number; ticking: boolean; }) { - const [time, setTime] = useState(0); + const [time, setTime] = useState(Date.now() - startTime); useEffect(() => { if (!ticking) return; const interval = setInterval(() => { diff --git a/packages/web-extension/src/utils/index.ts b/packages/web-extension/src/utils/index.ts index a2a6d22452..ad3494f8e3 100644 --- a/packages/web-extension/src/utils/index.ts +++ b/packages/web-extension/src/utils/index.ts @@ -1,3 +1,15 @@ +import Browser from 'webextension-polyfill'; +import type { eventWithTime } from 'rrweb/typings/types'; +import { + LocalData, + LocalDataKey, + RecorderStatus, + RecordStartedMessage, + RecordStoppedMessage, + ServiceName, +} from '../types'; +import type Channel from './channel'; + const SECOND = 1000; const MINUTE = 60 * SECOND; const HOUR = 60 * MINUTE; @@ -27,3 +39,72 @@ function padZero(num: number, len = 2): string { } return str; } + +// Pause recording. +export async function pauseRecording( + channel: Channel, + newStatus: RecorderStatus, + status?: LocalData[LocalDataKey.recorderStatus], +) { + if (!status) + status = (await Browser.storage.local.get(LocalDataKey.recorderStatus))[ + LocalDataKey.recorderStatus + ] as LocalData[LocalDataKey.recorderStatus]; + const { startTimestamp, activeTabId } = status; + const stopResponse = (await channel.requestToTab( + activeTabId, + ServiceName.PauseRecord, + {}, + )) as RecordStoppedMessage; + if (!stopResponse) return; + const statusData: LocalData[LocalDataKey.recorderStatus] = { + status: newStatus, + activeTabId, + startTimestamp, + pausedTimestamp: stopResponse.endTimestamp, + }; + await Browser.storage.local.set({ + [LocalDataKey.recorderStatus]: statusData, + }); + return { + status: statusData, + bufferedEvents: stopResponse.events, + }; +} + +// Resume recording after change to a new tab. +export async function resumeRecording( + channel: Channel, + newTabId: number, + status?: LocalData[LocalDataKey.recorderStatus], + bufferedEvents?: eventWithTime[], +) { + if (!status) + status = (await Browser.storage.local.get(LocalDataKey.recorderStatus))[ + LocalDataKey.recorderStatus + ] as LocalData[LocalDataKey.recorderStatus]; + if (!bufferedEvents) + bufferedEvents = ((await Browser.storage.local.get( + LocalDataKey.bufferedEvents, + )) as LocalData)[LocalDataKey.bufferedEvents]; + const { startTimestamp, pausedTimestamp } = status; + const startResponse = (await channel.requestToTab( + newTabId, + ServiceName.ResumeRecord, + { events: bufferedEvents, pausedTimestamp }, + )) as RecordStartedMessage; + if (!startResponse) return; + const pausedTime = pausedTimestamp + ? startResponse.startTimestamp - pausedTimestamp + : 0; + const statusData: LocalData[LocalDataKey.recorderStatus] = { + status: RecorderStatus.RECORDING, + activeTabId: newTabId, + startTimestamp: + (startTimestamp || bufferedEvents[0].timestamp) + pausedTime, + }; + await Browser.storage.local.set({ + [LocalDataKey.recorderStatus]: statusData, + }); + return statusData; +} From ab0b588b3b6f950ed67ebda56e58f9b7dd566b46 Mon Sep 17 00:00:00 2001 From: Mark-Fenng Date: Thu, 3 Nov 2022 17:06:48 +1100 Subject: [PATCH 11/40] feat: add a link to new session after recording --- packages/web-extension/src/content/index.ts | 22 +++++---- packages/web-extension/src/popup/App.tsx | 51 ++++++++++++++++----- packages/web-extension/src/types.ts | 1 + 3 files changed, 54 insertions(+), 20 deletions(-) diff --git a/packages/web-extension/src/content/index.ts b/packages/web-extension/src/content/index.ts index d38b9c44bd..9fcb41c6a6 100644 --- a/packages/web-extension/src/content/index.ts +++ b/packages/web-extension/src/content/index.ts @@ -57,7 +57,9 @@ void (async () => { return new Promise((resolve) => { stopResponseCb = (response: RecordStoppedMessage) => { stopResponseCb = undefined; - void saveEvents(response.events); + const session = saveEvents(response.events); + session.events = []; + response.session = session; storedEvents = []; resolve(response); }; @@ -131,7 +133,7 @@ function startRecord() { }; } -async function saveEvents(events: eventWithTime[]) { +function saveEvents(events: eventWithTime[]) { const newSession: Session = { id: nanoid(), name: document.title, @@ -141,10 +143,14 @@ async function saveEvents(events: eventWithTime[]) { modifyTimestamp: Date.now(), recorderVersion: Browser.runtime.getManifest().version_name || 'unknown', }; - const data = (await Browser.storage.local.get( - LocalDataKey.sessions, - )) as LocalData; - if (!data.sessions) data.sessions = {}; - data.sessions[newSession.id] = newSession; - await Browser.storage.local.set(data); + void Browser.storage.local.get(LocalDataKey.sessions).then((res) => { + const data = res as LocalData; + if (!data.sessions) data.sessions = {}; + data.sessions[newSession.id] = newSession; + void Browser.storage.local.set(data); + }); + + return { + ...newSession, + }; } diff --git a/packages/web-extension/src/popup/App.tsx b/packages/web-extension/src/popup/App.tsx index daac6705e1..1b57372ab1 100644 --- a/packages/web-extension/src/popup/App.tsx +++ b/packages/web-extension/src/popup/App.tsx @@ -1,5 +1,13 @@ import { useState, useEffect } from 'react'; -import { Box, Flex, IconButton, Spacer, Stack, Text } from '@chakra-ui/react'; +import { + Box, + Flex, + IconButton, + Link, + Spacer, + Stack, + Text, +} from '@chakra-ui/react'; import { FiSettings, FiList, FiPause, FiPlay } from 'react-icons/fi'; import Channel from '../utils/channel'; import { @@ -8,6 +16,8 @@ import { RecorderStatus, ServiceName, RecordStartedMessage, + RecordStoppedMessage, + Session, } from '../types'; import Browser from 'webextension-polyfill'; import { CircleButton } from '../components/CircleButton'; @@ -21,6 +31,7 @@ export function App() { const [status, setStatus] = useState(RecorderStatus.IDLE); const [errorMessage, setErrorMessage] = useState(''); const [startTime, setStartTime] = useState(0); + const [newSession, setNewSession] = useState(null); useEffect(() => { void Browser.storage.local.get(LocalDataKey.recorderStatus).then((data) => { @@ -55,7 +66,7 @@ export function App() { > { - void Browser.tabs.create({ url: '/options/index.html' }); + void Browser.runtime.openOptionsPage(); }} size="xs" icon={} @@ -87,16 +98,19 @@ export function App() { if (tabId === -1) return; void channel .requestToTab(tabId, ServiceName.StopRecord, {}) - .then(async (res) => { - if (res) { - setStatus(RecorderStatus.IDLE); - const status: LocalData[LocalDataKey.recorderStatus] = { - status: RecorderStatus.IDLE, - activeTabId: tabId, - }; - await Browser.storage.local.set({ - [LocalDataKey.recorderStatus]: status, - }); + .then(async (res: RecordStoppedMessage) => { + if (!res) return; + + setStatus(RecorderStatus.IDLE); + const status: LocalData[LocalDataKey.recorderStatus] = { + status: RecorderStatus.IDLE, + activeTabId: tabId, + }; + await Browser.storage.local.set({ + [LocalDataKey.recorderStatus]: status, + }); + if (res.session) { + setNewSession(res.session); } }) .catch((error: Error) => { @@ -202,6 +216,19 @@ export function App() { )} + {newSession && ( + + New Session: + + {newSession.name} + + + )} {errorMessage !== '' && ( {errorMessage} diff --git a/packages/web-extension/src/types.ts b/packages/web-extension/src/types.ts index 793a064d91..30c7247777 100644 --- a/packages/web-extension/src/types.ts +++ b/packages/web-extension/src/types.ts @@ -73,6 +73,7 @@ export type RecordStoppedMessage = { message: MessageName.RecordStopped; events: eventWithTime[]; endTimestamp: number; + session?: Session; }; export type HeartBreathMessage = { From 0d633e547d3910db1fa06dd968db151916246494 Mon Sep 17 00:00:00 2001 From: Mark-Fenng Date: Sat, 5 Nov 2022 14:01:47 +1100 Subject: [PATCH 12/40] improve session list --- packages/web-extension/package.json | 1 + .../web-extension/src/pages/SessionList.tsx | 196 +++++++++++++++--- yarn.lock | 12 ++ 3 files changed, 182 insertions(+), 27 deletions(-) diff --git a/packages/web-extension/package.json b/packages/web-extension/package.json index 8d2b63a948..238d091c6d 100644 --- a/packages/web-extension/package.json +++ b/packages/web-extension/package.json @@ -31,6 +31,7 @@ "@chakra-ui/react": "^2.3.4", "@emotion/react": "^11.10.4", "@emotion/styled": "^11.10.4", + "@tanstack/react-table": "^8.5.22", "framer-motion": "^7.3.6", "mitt": "^3.0.0", "nanoid": "^4.0.0", diff --git a/packages/web-extension/src/pages/SessionList.tsx b/packages/web-extension/src/pages/SessionList.tsx index 36076c2fc1..00e81007a8 100644 --- a/packages/web-extension/src/pages/SessionList.tsx +++ b/packages/web-extension/src/pages/SessionList.tsx @@ -1,5 +1,6 @@ -import { useEffect, useState } from 'react'; +import { useEffect, useMemo, useState } from 'react'; import { + chakra, Table, Thead, Tbody, @@ -7,14 +8,85 @@ import { Th, Td, TableContainer, + Flex, + Checkbox, + Button, + Spacer, } from '@chakra-ui/react'; +import { + createColumnHelper, + useReactTable, + flexRender, + getCoreRowModel, + SortingState, + getSortedRowModel, +} from '@tanstack/react-table'; +import { VscTriangleDown, VscTriangleUp } from 'react-icons/vsc'; import { LocalData, LocalDataKey, Session } from '../types'; import Browser from 'webextension-polyfill'; import { useNavigate } from 'react-router-dom'; +const columnHelper = createColumnHelper(); + export function SessionList() { const [sessions, setSessions] = useState([]); const navigate = useNavigate(); + const [sorting, setSorting] = useState([ + { + id: 'createTimestamp', + desc: true, + }, + ]); + const [rowSelection, setRowSelection] = useState({}); + + const columns = useMemo( + () => [ + columnHelper.display({ + id: 'select', + header: ({ table }) => ( + + ), + cell: ({ row }) => ( + + ), + }), + columnHelper.accessor((row) => row.name, { + cell: (info) => info.getValue(), + header: 'Name', + }), + columnHelper.accessor((row) => row.createTimestamp, { + id: 'createTimestamp', + cell: (info) => new Date(info.getValue()).toLocaleString(), + header: 'Created Time', + sortDescFirst: true, + }), + columnHelper.accessor((row) => row.recorderVersion, { + cell: (info) => info.getValue(), + header: 'RRWEB Version', + }), + ], + [], + ); + const table = useReactTable({ + columns, + data: sessions, + getCoreRowModel: getCoreRowModel(), + onRowSelectionChange: setRowSelection, + onSortingChange: setSorting, + getSortedRowModel: getSortedRowModel(), + state: { + sorting, + rowSelection, + }, + }); useEffect(() => { const getSessions = (sessions?: LocalData['sessions']) => { @@ -33,32 +105,102 @@ export function SessionList() { }, []); return ( - - - - - - - - - - - {sessions.map((session) => { - return ( - { - navigate(`/session/${session.id}`); - }} - _hover={{ cursor: 'pointer' }} - > - - - + <> + +
NameCreated TimeRRWEB Version
{session.name}{new Date(session.createTimestamp).toLocaleString()}{session.recorderVersion}
+ + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => { + const meta = header.column.columnDef.meta as + | { + isNumeric: boolean; + } + | undefined; + return ( + + ); + })} + + ))} + + + {table.getRowModel().rows.map((row) => ( + + {row.getVisibleCells().map((cell, index) => { + const meta = cell.column.columnDef.meta as + | { + isNumeric: boolean; + } + | undefined; + return ( + + ); + })} - ); - })} - -
+ + {flexRender( + header.column.columnDef.header, + header.getContext(), + )} + + {{ + asc: ( + + ), + desc: ( + + ), + }[header.column.getIsSorted() as string] ?? null} + + +
{ + if (index !== 0) + navigate(`/session/${row.original.id}`); + }} + > + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} +
-
+ ))} + + + + + + + + ); } diff --git a/yarn.lock b/yarn.lock index 33e2867eba..8574f36cc1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3193,6 +3193,18 @@ dependencies: defer-to-connect "^1.0.1" +"@tanstack/react-table@^8.5.22": + version "8.5.22" + resolved "https://registry.yarnpkg.com/@tanstack/react-table/-/react-table-8.5.22.tgz#8a5250ac6437ca7c16e683cde65a065c0f573e24" + integrity sha512-01XaxQTxcI+w7g+i/YRblxdAikM9G7L1S7LwqaiD/gkKmNUs+g2BXw4GfIcuzzE75Q5t0BXlyqM7MyxxBuvQXA== + dependencies: + "@tanstack/table-core" "8.5.22" + +"@tanstack/table-core@8.5.22": + version "8.5.22" + resolved "https://registry.yarnpkg.com/@tanstack/table-core/-/table-core-8.5.22.tgz#ba381db5f7f47558aba6e75cc94ee32a691defeb" + integrity sha512-D3wDbVXl3Bi5PdGfle6DijhLzZxrvMyZsE1dSHH0xBsqEbu7Pkxn5EEd6CA9tGsCgXIEP1s4Yfy1cZ9xnMz1sQ== + "@tootallnate/once@1": version "1.1.2" resolved "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz" From 824645708c7faa4807ed97ac378f07f3a87446a6 Mon Sep 17 00:00:00 2001 From: Mark-Fenng Date: Sat, 5 Nov 2022 16:28:53 +1100 Subject: [PATCH 13/40] refactor: migrate session storage from chrome local storage to indexedDB --- packages/web-extension/package.json | 1 + packages/web-extension/src/content/index.ts | 19 +---- packages/web-extension/src/pages/Player.tsx | 54 +++++++----- .../web-extension/src/pages/SessionList.tsx | 63 +++++++------- packages/web-extension/src/popup/App.tsx | 9 +- packages/web-extension/src/popup/Timer.tsx | 2 +- packages/web-extension/src/types.ts | 7 +- packages/web-extension/src/utils/channel.ts | 12 +-- packages/web-extension/src/utils/index.ts | 84 +++++++++++++++++++ yarn.lock | 5 ++ 10 files changed, 173 insertions(+), 83 deletions(-) diff --git a/packages/web-extension/package.json b/packages/web-extension/package.json index 238d091c6d..497a314d45 100644 --- a/packages/web-extension/package.json +++ b/packages/web-extension/package.json @@ -33,6 +33,7 @@ "@emotion/styled": "^11.10.4", "@tanstack/react-table": "^8.5.22", "framer-motion": "^7.3.6", + "idb": "^7.1.1", "mitt": "^3.0.0", "nanoid": "^4.0.0", "react": "^18.2.0", diff --git a/packages/web-extension/src/content/index.ts b/packages/web-extension/src/content/index.ts index 9fcb41c6a6..e168461ebd 100644 --- a/packages/web-extension/src/content/index.ts +++ b/packages/web-extension/src/content/index.ts @@ -57,9 +57,8 @@ void (async () => { return new Promise((resolve) => { stopResponseCb = (response: RecordStoppedMessage) => { stopResponseCb = undefined; - const session = saveEvents(response.events); - session.events = []; - response.session = session; + const newSession = generateSession(); + response.session = newSession; storedEvents = []; resolve(response); }; @@ -133,24 +132,14 @@ function startRecord() { }; } -function saveEvents(events: eventWithTime[]) { +function generateSession() { const newSession: Session = { id: nanoid(), name: document.title, tags: [], - events, createTimestamp: Date.now(), modifyTimestamp: Date.now(), recorderVersion: Browser.runtime.getManifest().version_name || 'unknown', }; - void Browser.storage.local.get(LocalDataKey.sessions).then((res) => { - const data = res as LocalData; - if (!data.sessions) data.sessions = {}; - data.sessions[newSession.id] = newSession; - void Browser.storage.local.set(data); - }); - - return { - ...newSession, - }; + return newSession; } diff --git a/packages/web-extension/src/pages/Player.tsx b/packages/web-extension/src/pages/Player.tsx index 8339e1a520..abc4057dc2 100644 --- a/packages/web-extension/src/pages/Player.tsx +++ b/packages/web-extension/src/pages/Player.tsx @@ -1,9 +1,7 @@ import { useRef, useEffect, useState } from 'react'; import { useParams } from 'react-router-dom'; -import Browser from 'webextension-polyfill'; -import type rrwebPlayer from 'rrweb-player'; +import rrwebPlayer from 'rrweb-player'; import Replayer from 'rrweb-player'; -import { LocalData } from '../types'; import { Box, Breadcrumb, @@ -11,6 +9,7 @@ import { BreadcrumbLink, Center, } from '@chakra-ui/react'; +import { getEvents, getSession } from '../utils'; export default function Player() { const playerElRef = useRef(null); @@ -19,27 +18,38 @@ export default function Player() { const [sessionName, setSessionName] = useState(''); useEffect(() => { - void Browser.storage.local.get().then((data) => { - if (!playerElRef.current || !sessionId) return; - const localData = data as LocalData; - const session = localData.sessions[sessionId]; - if (!session) return; - setSessionName(session.name); + if (!sessionId) return; + getSession(sessionId) + .then((session) => { + setSessionName(session.name); + }) + .catch((err) => { + console.error(err); + }); + getEvents(sessionId) + .then((events) => { + if (!playerElRef.current || !sessionId) return; - const linkEl = document.createElement('link'); - linkEl.href = - 'https://cdn.jsdelivr.net/npm/rrweb-player@1.0.0-alpha.3/dist/style.css'; - linkEl.rel = 'stylesheet'; - document.head.appendChild(linkEl); - playerRef.current = new Replayer({ - target: playerElRef.current as HTMLElement, - props: { - events: session.events, - autoPlay: true, - }, + const linkEl = document.createElement('link'); + linkEl.href = + 'https://cdn.jsdelivr.net/npm/rrweb-player@1.0.0-alpha.3/dist/style.css'; + linkEl.rel = 'stylesheet'; + document.head.appendChild(linkEl); + playerRef.current = new Replayer({ + target: playerElRef.current as HTMLElement, + props: { + events, + autoPlay: true, + }, + }); + }) + .catch((err) => { + console.error(err); }); - }); - }, []); + return () => { + playerRef.current?.pause(); + }; + }, [sessionId]); return ( <> diff --git a/packages/web-extension/src/pages/SessionList.tsx b/packages/web-extension/src/pages/SessionList.tsx index 00e81007a8..14e27a4411 100644 --- a/packages/web-extension/src/pages/SessionList.tsx +++ b/packages/web-extension/src/pages/SessionList.tsx @@ -22,11 +22,13 @@ import { getSortedRowModel, } from '@tanstack/react-table'; import { VscTriangleDown, VscTriangleUp } from 'react-icons/vsc'; -import { LocalData, LocalDataKey, Session } from '../types'; -import Browser from 'webextension-polyfill'; import { useNavigate } from 'react-router-dom'; +import { Session, EventName } from '../types'; +import Channel from '../utils/channel'; +import { deleteSessions, getAllSessions } from '../utils'; const columnHelper = createColumnHelper(); +const channel = new Channel(); export function SessionList() { const [sessions, setSessions] = useState([]); @@ -88,19 +90,15 @@ export function SessionList() { }, }); + const updateSessions = async () => { + const sessions = await getAllSessions(); + setSessions(sessions); + }; + useEffect(() => { - const getSessions = (sessions?: LocalData['sessions']) => { - if (!sessions) return; - const sessionArray = []; - for (const id in sessions) sessionArray.push(sessions[id]); - setSessions(sessionArray); - }; - void Browser.storage.local - .get(LocalDataKey.sessions) - .then((data) => getSessions((data as LocalData).sessions)); - Browser.storage.onChanged.addListener((changes, area) => { - if (area === 'local' && changes.sessions) - getSessions(changes.sessions.newValue as LocalData['sessions']); + void updateSessions(); + channel.on(EventName.SessionUpdated, () => { + void updateSessions(); }); }, []); @@ -179,27 +177,26 @@ export function SessionList() { - + }} + > + Delete + + )} ); diff --git a/packages/web-extension/src/popup/App.tsx b/packages/web-extension/src/popup/App.tsx index 1b57372ab1..f9fa04de26 100644 --- a/packages/web-extension/src/popup/App.tsx +++ b/packages/web-extension/src/popup/App.tsx @@ -18,11 +18,12 @@ import { RecordStartedMessage, RecordStoppedMessage, Session, + EventName, } from '../types'; import Browser from 'webextension-polyfill'; import { CircleButton } from '../components/CircleButton'; import { Timer } from './Timer'; -import { pauseRecording, resumeRecording } from '../utils'; +import { pauseRecording, resumeRecording, saveSession } from '../utils'; const RECORD_BUTTON_SIZE = 3; const channel = new Channel(); @@ -111,6 +112,12 @@ export function App() { }); if (res.session) { setNewSession(res.session); + await saveSession(res.session, res.events).catch( + (e) => { + setErrorMessage((e as { message: string }).message); + }, + ); + channel.emit(EventName.SessionUpdated, {}); } }) .catch((error: Error) => { diff --git a/packages/web-extension/src/popup/Timer.tsx b/packages/web-extension/src/popup/Timer.tsx index f965f10dad..2ffdf0962a 100644 --- a/packages/web-extension/src/popup/Timer.tsx +++ b/packages/web-extension/src/popup/Timer.tsx @@ -18,7 +18,7 @@ export function Timer({ return () => clearInterval(interval); }, [startTime, ticking]); return ( - + {formatTime(time)} ); diff --git a/packages/web-extension/src/types.ts b/packages/web-extension/src/types.ts index 30c7247777..0229063ab4 100644 --- a/packages/web-extension/src/types.ts +++ b/packages/web-extension/src/types.ts @@ -13,13 +13,11 @@ export type Settings = { }; export enum LocalDataKey { - sessions = 'sessions', recorderStatus = 'recorder_status', bufferedEvents = 'buffered_events', } export type LocalData = { - [LocalDataKey.sessions]: Record; [LocalDataKey.recorderStatus]: { status: RecorderStatus; activeTabId: number; @@ -42,7 +40,6 @@ export type Session = { id: string; name: string; tags: string[]; - events: eventWithTime[]; createTimestamp: number; modifyTimestamp: number; recorderVersion: string; @@ -55,6 +52,10 @@ export enum ServiceName { ResumeRecord = 'resume-record', } +export enum EventName { + SessionUpdated = 'session-updated', +} + export enum MessageName { RecordScriptReady = 'rrweb-extension-record-script-ready', StartRecord = 'rrweb-extension-start-record', diff --git a/packages/web-extension/src/utils/channel.ts b/packages/web-extension/src/utils/channel.ts index 88a01ab5bf..a1c0ea8eb7 100644 --- a/packages/web-extension/src/utils/channel.ts +++ b/packages/web-extension/src/utils/channel.ts @@ -143,8 +143,8 @@ class Channel { * @param event - event name * @param detail - event detail */ - public emit(eventName: string, detail: unknown) { - const message = JSON.stringify({ type: 'event', eventName, detail }); + public emit(event: string, detail: unknown) { + const message = JSON.stringify({ type: 'event', event, detail }); void Browser.runtime.sendMessage(message); } @@ -155,11 +155,7 @@ class Channel { * @param event - event name * @param detail - event detail */ - public emitToTabs( - tabIds: number | number[], - eventName: string, - detail: unknown, - ) { + public emitToTabs(tabIds: number | number[], event: string, detail: unknown) { if (!Browser.tabs || !Browser.tabs.sendMessage) return Promise.reject('Can not send message to tabs in current context!'); @@ -168,7 +164,7 @@ class Channel { tabIds = [tabIds]; } - const message = JSON.stringify({ type: 'event', eventName, detail }); + const message = JSON.stringify({ type: 'event', event, detail }); tabIds.forEach((tabId) => void Browser.tabs.sendMessage(tabId, message)); } diff --git a/packages/web-extension/src/utils/index.ts b/packages/web-extension/src/utils/index.ts index ad3494f8e3..9d8e8493e7 100644 --- a/packages/web-extension/src/utils/index.ts +++ b/packages/web-extension/src/utils/index.ts @@ -1,5 +1,6 @@ import Browser from 'webextension-polyfill'; import type { eventWithTime } from 'rrweb/typings/types'; +import { openDB } from 'idb'; import { LocalData, LocalDataKey, @@ -7,6 +8,7 @@ import { RecordStartedMessage, RecordStoppedMessage, ServiceName, + Session, } from '../types'; import type Channel from './channel'; @@ -108,3 +110,85 @@ export async function resumeRecording( }); return statusData; } + +const EventStoreName = 'events'; +type EventData = { + id: string; + events: eventWithTime[]; +}; + +export async function getEventStore() { + return openDB(EventStoreName, 1, { + upgrade(db) { + db.createObjectStore(EventStoreName, { + keyPath: 'id', + autoIncrement: false, + }); + }, + }); +} + +export async function getEvents(id: string) { + const db = await getEventStore(); + const data = (await db.get(EventStoreName, id)) as EventData; + return data.events; +} + +const SessionStoreName = 'sessions'; +export async function getSessionStore() { + return openDB(SessionStoreName, 1, { + upgrade(db) { + // Create a store of objects + db.createObjectStore(SessionStoreName, { + // The 'id' property of the object will be the key. + keyPath: 'id', + // If it isn't explicitly set, create a value by auto incrementing. + autoIncrement: false, + }); + }, + }); +} + +export async function saveSession(session: Session, events: eventWithTime[]) { + const eventStore = await getEventStore(); + await eventStore.put(EventStoreName, { id: session.id, events }); + const store = await getSessionStore(); + await store.add(SessionStoreName, session); +} + +export async function getSession(id: string) { + const store = await getSessionStore(); + return store.get(SessionStoreName, id) as Promise; +} + +export async function getAllSessions() { + const store = await getSessionStore(); + return store.getAll(SessionStoreName) as Promise; +} + +export async function deleteSession(id: string) { + const eventStore = await getEventStore(); + const sessionStore = await getSessionStore(); + await Promise.all([ + eventStore.delete(EventStoreName, id), + sessionStore.delete(SessionStoreName, id), + ]); +} + +export async function deleteSessions(ids: string[]) { + const eventStore = await getEventStore(); + const sessionStore = await getSessionStore(); + const eventTransition = eventStore.transaction(EventStoreName, 'readwrite'); + const sessionTransition = sessionStore.transaction( + SessionStoreName, + 'readwrite', + ); + const promises = []; + for (const id of ids) { + promises.push(eventTransition.store.delete(id)); + promises.push(sessionTransition.store.delete(id)); + } + await Promise.all(promises).then(() => { + return Promise.all([eventTransition.done, sessionTransition.done]); + }); +} diff --git a/yarn.lock b/yarn.lock index 8574f36cc1..311decedcc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7936,6 +7936,11 @@ icss-replace-symbols@1.1.0, icss-replace-symbols@^1.1.0: resolved "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz" integrity sha1-Bupvg2ead0njhs/h/oEq5dsiPe0= +idb@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/idb/-/idb-7.1.1.tgz#d910ded866d32c7ced9befc5bfdf36f572ced72b" + integrity sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ== + identity-obj-proxy@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz" From 5fe51f17b6602c19686d694a7f3bb4540339fa46 Mon Sep 17 00:00:00 2001 From: Mark-Fenng Date: Sat, 5 Nov 2022 18:31:56 +1100 Subject: [PATCH 14/40] feat: add pagination to session list --- .../web-extension/src/pages/SessionList.tsx | 153 +++++++++++++++--- packages/web-extension/src/utils/index.ts | 3 +- 2 files changed, 136 insertions(+), 20 deletions(-) diff --git a/packages/web-extension/src/pages/SessionList.tsx b/packages/web-extension/src/pages/SessionList.tsx index 14e27a4411..3ab8b60847 100644 --- a/packages/web-extension/src/pages/SessionList.tsx +++ b/packages/web-extension/src/pages/SessionList.tsx @@ -7,11 +7,16 @@ import { Tr, Th, Td, + Text, TableContainer, Flex, Checkbox, Button, Spacer, + IconButton, + Select, + Input, + Divider, } from '@chakra-ui/react'; import { createColumnHelper, @@ -20,12 +25,19 @@ import { getCoreRowModel, SortingState, getSortedRowModel, + PaginationState, } from '@tanstack/react-table'; import { VscTriangleDown, VscTriangleUp } from 'react-icons/vsc'; import { useNavigate } from 'react-router-dom'; import { Session, EventName } from '../types'; import Channel from '../utils/channel'; import { deleteSessions, getAllSessions } from '../utils'; +import { + FiChevronLeft, + FiChevronRight, + FiChevronsLeft, + FiChevronsRight, +} from 'react-icons/fi'; const columnHelper = createColumnHelper(); const channel = new Channel(); @@ -41,6 +53,33 @@ export function SessionList() { ]); const [rowSelection, setRowSelection] = useState({}); + const [{ pageIndex, pageSize }, setPagination] = useState({ + pageIndex: 0, + pageSize: 10, + }); + + const fetchDataOptions = { + pageIndex, + pageSize, + }; + + const fetchData = (options: { pageIndex: number; pageSize: number }) => { + return { + rows: sessions.slice( + options.pageIndex * options.pageSize, + (options.pageIndex + 1) * options.pageSize, + ), + pageCount: Math.ceil(sessions.length / options.pageSize), + }; + }; + const pagination = useMemo( + () => ({ + pageIndex, + pageSize, + }), + [pageIndex, pageSize], + ); + const columns = useMemo( () => [ columnHelper.display({ @@ -79,15 +118,19 @@ export function SessionList() { ); const table = useReactTable({ columns, - data: sessions, + data: fetchData(fetchDataOptions).rows, getCoreRowModel: getCoreRowModel(), + onPaginationChange: setPagination, onRowSelectionChange: setRowSelection, onSortingChange: setSorting, getSortedRowModel: getSortedRowModel(), state: { + pagination, sorting, rowSelection, }, + manualPagination: true, + pageCount: fetchData(fetchDataOptions).pageCount, }); const updateSessions = async () => { @@ -176,27 +219,99 @@ export function SessionList() { + + + table.setPageIndex(0)} + disabled={!table.getCanPreviousPage()} + > + + + table.previousPage()} + disabled={!table.getCanPreviousPage()} + > + + + + + Page + + {`${ + table.getState().pagination.pageIndex + 1 + } of ${table.getPageCount()}`} + + + + + Go to page: + { + const page = e.target.value ? Number(e.target.value) - 1 : 0; + table.setPageIndex(page); + }} + /> + + + table.nextPage()} + disabled={!table.getCanNextPage()} + > + + + table.setPageIndex(table.getPageCount() - 1)} + disabled={!table.getCanNextPage()} + > + + + + - {Object.keys(rowSelection).length > 0 && ( - + )} + ); diff --git a/packages/web-extension/src/utils/index.ts b/packages/web-extension/src/utils/index.ts index 9d8e8493e7..9f9cd43cc4 100644 --- a/packages/web-extension/src/utils/index.ts +++ b/packages/web-extension/src/utils/index.ts @@ -163,7 +163,8 @@ export async function getSession(id: string) { export async function getAllSessions() { const store = await getSessionStore(); - return store.getAll(SessionStoreName) as Promise; + const sessions = (await store.getAll(SessionStoreName)) as Session[]; + return sessions.sort((a, b) => b.createTimestamp - a.createTimestamp); } export async function deleteSession(id: string) { From 1266dae532ea994134d35259e48be9db59b7294f Mon Sep 17 00:00:00 2001 From: Mark-Fenng Date: Sat, 5 Nov 2022 19:00:13 +1100 Subject: [PATCH 15/40] fix: multiple recorders are started after pausing and resuming process --- packages/web-extension/src/content/inject.ts | 52 ++++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/packages/web-extension/src/content/inject.ts b/packages/web-extension/src/content/inject.ts index 11e80dea9f..2862033a6b 100644 --- a/packages/web-extension/src/content/inject.ts +++ b/packages/web-extension/src/content/inject.ts @@ -27,32 +27,32 @@ function startRecord(config: recordOptions) { }, 500) as unknown) as number; } -window.addEventListener( - 'message', - (event: { - data: { - message: MessageName; - config?: recordOptions; - }; - }) => { - const data = event.data; - const eventHandler = { - [MessageName.StartRecord]: () => { - startRecord(data.config || {}); - }, - [MessageName.StopRecord]: () => { - if (stopFn) stopFn(); - if (setIntervalId) clearInterval(setIntervalId); - window.postMessage({ - message: MessageName.RecordStopped, - events, - endTimestamp: Date.now(), - }); - }, - } as Record void>; - if (eventHandler[data.message]) eventHandler[data.message](); - }, -); +const messageHandler = (event: { + data: { + message: MessageName; + config?: recordOptions; + }; +}) => { + const data = event.data; + const eventHandler = { + [MessageName.StartRecord]: () => { + startRecord(data.config || {}); + }, + [MessageName.StopRecord]: () => { + if (stopFn) stopFn(); + if (setIntervalId) clearInterval(setIntervalId); + window.postMessage({ + message: MessageName.RecordStopped, + events, + endTimestamp: Date.now(), + }); + window.removeEventListener('message', messageHandler); + }, + } as Record void>; + if (eventHandler[data.message]) eventHandler[data.message](); +}; + +window.addEventListener('message', messageHandler); window.postMessage({ message: MessageName.RecordScriptReady, From 6186f6a848772d8db79039904bd75ac275f10d2a Mon Sep 17 00:00:00 2001 From: Mark-Fenng Date: Sat, 5 Nov 2022 19:42:24 +1100 Subject: [PATCH 16/40] fix: can't stop recording on firefox browser --- packages/web-extension/src/content/index.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/web-extension/src/content/index.ts b/packages/web-extension/src/content/index.ts index e168461ebd..c9a9355bd5 100644 --- a/packages/web-extension/src/content/index.ts +++ b/packages/web-extension/src/content/index.ts @@ -97,12 +97,16 @@ void (async () => { stopResponseCb ) { const data = event.data as RecordStoppedMessage; - data.events = storedEvents.concat(data.events); + // On firefox, the event.data is immutable, so we need to clone it to avoid errors. + const newData = { + ...data, + }; + newData.events = storedEvents.concat(data.events); clearRecorderCb?.(); clearRecorderCb = undefined; - stopResponseCb(data); + stopResponseCb(newData); void Browser.storage.local.set({ - [LocalDataKey.bufferedEvents]: storedEvents.concat(data.events), + [LocalDataKey.bufferedEvents]: newData.events, }); } else if (event.data.message === MessageName.HeartBeat) void Browser.storage.local.set({ From 5340919b62f9f91dec3c300e02229a49c6289a33 Mon Sep 17 00:00:00 2001 From: Mark-Fenng Date: Sat, 5 Nov 2022 20:11:29 +1100 Subject: [PATCH 17/40] update type import of 'eventWithTime' --- packages/rrweb-player/src/utils.ts | 2 +- packages/rrweb/tsconfig.json | 16 +++++++++++----- packages/web-extension/package.json | 1 + packages/web-extension/src/background/index.ts | 2 +- packages/web-extension/src/content/index.ts | 2 +- packages/web-extension/src/content/inject.ts | 3 ++- packages/web-extension/src/types.ts | 2 +- packages/web-extension/src/utils/index.ts | 2 +- 8 files changed, 19 insertions(+), 11 deletions(-) diff --git a/packages/rrweb-player/src/utils.ts b/packages/rrweb-player/src/utils.ts index 796d18106c..2a3f29219c 100644 --- a/packages/rrweb-player/src/utils.ts +++ b/packages/rrweb-player/src/utils.ts @@ -16,7 +16,7 @@ declare global { } import { EventType, IncrementalSource } from 'rrweb'; -import type { eventWithTime } from 'rrweb/typings/types'; +import type { eventWithTime } from '@rrweb/types'; export function inlineCss(cssObj: Record): string { let style = ''; diff --git a/packages/rrweb/tsconfig.json b/packages/rrweb/tsconfig.json index 268d008f66..fb1b407ad6 100644 --- a/packages/rrweb/tsconfig.json +++ b/packages/rrweb/tsconfig.json @@ -9,7 +9,10 @@ "preserveConstEnums": true, "rootDir": "src", "outDir": "build", - "lib": ["es6", "dom"], + "lib": [ + "es6", + "dom" + ], "downlevelIteration": true, "importsNotUsedAsValues": "error", "strictBindCallApply": true, @@ -17,16 +20,19 @@ }, "references": [ { - "path": "../rrdom" + "path": "../types" }, { - "path": "../rrweb-snapshot" + "path": "../rrdom" }, { - "path": "../types" + "path": "../rrweb-snapshot" } ], - "exclude": ["test", "scripts"], + "exclude": [ + "test", + "scripts" + ], "include": [ "src", "node_modules/@types/css-font-loading-module/index.d.ts", diff --git a/packages/web-extension/package.json b/packages/web-extension/package.json index 497a314d45..0fde20903b 100644 --- a/packages/web-extension/package.json +++ b/packages/web-extension/package.json @@ -16,6 +16,7 @@ "prepublish": "npm run pack:chrome && npm run pack:firefox" }, "devDependencies": { + "@rrweb/types": "^2.0.0-alpha.3", "@types/react-dom": "^18.0.6", "@types/webextension-polyfill": "^0.9.1", "@vitejs/plugin-react": "^2.1.0", diff --git a/packages/web-extension/src/background/index.ts b/packages/web-extension/src/background/index.ts index a5337d92d0..750a42ccc0 100644 --- a/packages/web-extension/src/background/index.ts +++ b/packages/web-extension/src/background/index.ts @@ -1,5 +1,5 @@ import Browser from 'webextension-polyfill'; -import type { eventWithTime } from 'rrweb/typings/types'; +import type { eventWithTime } from '@rrweb/types'; import Channel from '../utils/channel'; import { LocalData, diff --git a/packages/web-extension/src/content/index.ts b/packages/web-extension/src/content/index.ts index c9a9355bd5..eb927f55cd 100644 --- a/packages/web-extension/src/content/index.ts +++ b/packages/web-extension/src/content/index.ts @@ -1,6 +1,6 @@ import Browser from 'webextension-polyfill'; import { nanoid } from 'nanoid'; -import type { eventWithTime } from 'rrweb/typings/types'; +import type { eventWithTime } from '@rrweb/types'; import { LocalData, LocalDataKey, diff --git a/packages/web-extension/src/content/inject.ts b/packages/web-extension/src/content/inject.ts index 2862033a6b..6fd2cc1772 100644 --- a/packages/web-extension/src/content/inject.ts +++ b/packages/web-extension/src/content/inject.ts @@ -1,5 +1,6 @@ import { record } from 'rrweb'; -import { eventWithTime, recordOptions } from 'rrweb/typings/types'; +import type { recordOptions } from 'rrweb/typings/types'; +import type { eventWithTime } from '@rrweb/types'; import { MessageName, RecordStartedMessage } from '../types'; const events: eventWithTime[] = []; diff --git a/packages/web-extension/src/types.ts b/packages/web-extension/src/types.ts index 0229063ab4..d65f69ba64 100644 --- a/packages/web-extension/src/types.ts +++ b/packages/web-extension/src/types.ts @@ -1,4 +1,4 @@ -import type { eventWithTime } from 'rrweb/typings/types'; +import type { eventWithTime } from '@rrweb/types'; export enum SyncDataKey { settings = 'settings', diff --git a/packages/web-extension/src/utils/index.ts b/packages/web-extension/src/utils/index.ts index 9f9cd43cc4..90eb32024f 100644 --- a/packages/web-extension/src/utils/index.ts +++ b/packages/web-extension/src/utils/index.ts @@ -1,5 +1,5 @@ import Browser from 'webextension-polyfill'; -import type { eventWithTime } from 'rrweb/typings/types'; +import type { eventWithTime } from '@rrweb/types'; import { openDB } from 'idb'; import { LocalData, From 9670fd3a4eaba201c3291288b322910f532802da Mon Sep 17 00:00:00 2001 From: Mark-Fenng Date: Sat, 5 Nov 2022 20:43:19 +1100 Subject: [PATCH 18/40] fix CI error --- .github/workflows/ci-cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 6f98b26d8a..580f49faef 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -24,7 +24,7 @@ jobs: run: yarn - name: Build Project - run: yarn build:all + run: NODE_OPTIONS='--max-old-space-size=4096' yarn build:all - name: Check types run: yarn turbo run check-types From 196082bf34c0cea571bbbc95ebadd3e676476716 Mon Sep 17 00:00:00 2001 From: Mark-Fenng Date: Sat, 5 Nov 2022 21:14:25 +1100 Subject: [PATCH 19/40] doc: add readme --- packages/web-extension/README.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 packages/web-extension/README.md diff --git a/packages/web-extension/README.md b/packages/web-extension/README.md new file mode 100644 index 0000000000..5acb7b6cc9 --- /dev/null +++ b/packages/web-extension/README.md @@ -0,0 +1,32 @@ +

+ +

+ +# rrweb extension + +The package web-extension provides a browser extension for recording and replaying web pages. + +## Installation + +``` +yarn install +``` + +## Build + +```bash +# build for chrome +yarn build:chrome + +# build for firefox +yarn build:firefox +``` + +## Development + +```bash +# start a development chrome browser +yarn dev:chrome +# start a development firefox browser +yarn dev:firefox +``` From c0126c95fa5596ed4783c6049481e1dc7a277f86 Mon Sep 17 00:00:00 2001 From: MF Date: Sat, 12 Nov 2022 08:24:52 +0800 Subject: [PATCH 20/40] Apply suggestions from Justin's code review Co-authored-by: Justin Halsall --- packages/web-extension/src/content/index.ts | 6 +++--- packages/web-extension/src/pages/Player.tsx | 2 +- packages/web-extension/src/types.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/web-extension/src/content/index.ts b/packages/web-extension/src/content/index.ts index eb927f55cd..bfea9549c9 100644 --- a/packages/web-extension/src/content/index.ts +++ b/packages/web-extension/src/content/index.ts @@ -9,7 +9,7 @@ import { Session, RecordStartedMessage, RecordStoppedMessage, - HeartBreathMessage, + HeartBeatMessage, MessageName, } from '../types'; import Channel from '../utils/channel'; @@ -80,7 +80,7 @@ void (async () => { data: | RecordStartedMessage | RecordStoppedMessage - | HeartBreathMessage + | HeartBeatMessage | { message: MessageName; }; @@ -111,7 +111,7 @@ void (async () => { } else if (event.data.message === MessageName.HeartBeat) void Browser.storage.local.set({ [LocalDataKey.bufferedEvents]: storedEvents.concat( - (event.data as HeartBreathMessage).events, + (event.data as HeartBeatMessage).events, ), }); }, diff --git a/packages/web-extension/src/pages/Player.tsx b/packages/web-extension/src/pages/Player.tsx index abc4057dc2..8471601258 100644 --- a/packages/web-extension/src/pages/Player.tsx +++ b/packages/web-extension/src/pages/Player.tsx @@ -32,7 +32,7 @@ export default function Player() { const linkEl = document.createElement('link'); linkEl.href = - 'https://cdn.jsdelivr.net/npm/rrweb-player@1.0.0-alpha.3/dist/style.css'; + 'https://cdn.jsdelivr.net/npm/rrweb-player@latest/dist/style.css'; linkEl.rel = 'stylesheet'; document.head.appendChild(linkEl); playerRef.current = new Replayer({ diff --git a/packages/web-extension/src/types.ts b/packages/web-extension/src/types.ts index d65f69ba64..14c426d57d 100644 --- a/packages/web-extension/src/types.ts +++ b/packages/web-extension/src/types.ts @@ -77,7 +77,7 @@ export type RecordStoppedMessage = { session?: Session; }; -export type HeartBreathMessage = { +export type HeartBeatMessage = { message: MessageName.HeartBeat; events: eventWithTime[]; }; From 2d35e10f0f70a549855c09a5bf5e2ca54d40ff0b Mon Sep 17 00:00:00 2001 From: Mark-Fenng Date: Sat, 12 Nov 2022 23:27:25 +1100 Subject: [PATCH 21/40] refactor: make use of webNavigation API to implement recording consistent during page navigation --- .../web-extension/src/background/index.ts | 56 ++++++++++++++++++- packages/web-extension/src/content/index.ts | 31 ++++++---- packages/web-extension/src/content/inject.ts | 8 --- packages/web-extension/src/manifest.json | 16 +++++- packages/web-extension/src/pages/Player.tsx | 3 +- packages/web-extension/src/types.ts | 6 +- 6 files changed, 90 insertions(+), 30 deletions(-) diff --git a/packages/web-extension/src/background/index.ts b/packages/web-extension/src/background/index.ts index 750a42ccc0..0ed836c0fe 100644 --- a/packages/web-extension/src/background/index.ts +++ b/packages/web-extension/src/background/index.ts @@ -5,6 +5,7 @@ import { LocalData, LocalDataKey, RecorderStatus, + ServiceName, Settings, SyncData, SyncDataKey, @@ -30,7 +31,7 @@ void (async () => { // When tab is changed during the recording process, pause recording in the old tab and start a new one in the new tab. Browser.tabs.onActivated.addListener((activeInfo) => { - void Browser.storage.local + Browser.storage.local .get(LocalDataKey.recorderStatus) .then(async (data) => { const localData = data as LocalData; @@ -66,7 +67,7 @@ void (async () => { // If the recording can't start on an invalid tab, resume it when the tab content is updated. Browser.tabs.onUpdated.addListener(function (tabId, info) { if (info.status !== 'complete') return; - void Browser.storage.local + Browser.storage.local .get(LocalDataKey.recorderStatus) .then(async (data) => { const localData = data as LocalData; @@ -84,6 +85,57 @@ void (async () => { // the extension can't access to the tab }); }); + + // When page in the current tab is reloaded (navigated), inform the content script in the tab to store events into LocalStorage temporarily. + Browser.webNavigation.onBeforeNavigate.addListener((details) => { + if (details.parentFrameId !== -1) return; + const { tabId } = details; + Browser.storage.local + .get(LocalDataKey.recorderStatus) + .then(async (data) => { + const localData = data as LocalData; + if (!localData || !localData[LocalDataKey.recorderStatus]) return; + const { status, activeTabId } = localData[LocalDataKey.recorderStatus]; + if (status !== RecorderStatus.RECORDING || activeTabId !== tabId) + return; + await channel.requestToTab(tabId, ServiceName.CacheEvents, {}); + }) + .catch((err) => { + console.error(err); + }); + }); + + /** + * When the current tab is closed, the recording events will be lost because this event is fired after it is closed. + * This event listener is just used to make sure the recording status is updated. + */ + Browser.tabs.onRemoved.addListener((tabId) => { + Browser.storage.local + .get(LocalDataKey.recorderStatus) + .then(async (data) => { + const localData = data as LocalData; + if (!localData || !localData[LocalDataKey.recorderStatus]) return; + const { status, activeTabId, startTimestamp } = localData[ + LocalDataKey.recorderStatus + ]; + if (activeTabId !== tabId || status !== RecorderStatus.RECORDING) + return; + + // Update the recording status to make it resumable after users switch to other tabs. + const statusData: LocalData[LocalDataKey.recorderStatus] = { + status: RecorderStatus.PausedSwitch, + activeTabId, + startTimestamp, + pausedTimestamp: Date.now(), + }; + await Browser.storage.local.set({ + [LocalDataKey.recorderStatus]: statusData, + }); + }) + .catch((err) => { + console.error(err); + }); + }); })(); /** diff --git a/packages/web-extension/src/content/index.ts b/packages/web-extension/src/content/index.ts index bfea9549c9..0a64f27848 100644 --- a/packages/web-extension/src/content/index.ts +++ b/packages/web-extension/src/content/index.ts @@ -9,7 +9,6 @@ import { Session, RecordStartedMessage, RecordStoppedMessage, - HeartBeatMessage, MessageName, } from '../types'; import Channel from '../utils/channel'; @@ -61,6 +60,10 @@ void (async () => { response.session = newSession; storedEvents = []; resolve(response); + // clear cache + void Browser.storage.local.set({ + [LocalDataKey.bufferedEvents]: [], + }); }; }); }); @@ -70,6 +73,21 @@ void (async () => { stopResponseCb = (response: RecordStoppedMessage) => { stopResponseCb = undefined; resolve(response); + void Browser.storage.local.set({ + [LocalDataKey.bufferedEvents]: response.events, + }); + }; + }); + }); + channel.provide(ServiceName.CacheEvents, () => { + window.postMessage({ message: MessageName.StopRecord }); + return new Promise((resolve) => { + stopResponseCb = (response: RecordStoppedMessage) => { + stopResponseCb = undefined; + resolve(response); + void Browser.storage.local.set({ + [LocalDataKey.bufferedEvents]: response.events, + }); }; }); }); @@ -80,7 +98,6 @@ void (async () => { data: | RecordStartedMessage | RecordStoppedMessage - | HeartBeatMessage | { message: MessageName; }; @@ -105,15 +122,7 @@ void (async () => { clearRecorderCb?.(); clearRecorderCb = undefined; stopResponseCb(newData); - void Browser.storage.local.set({ - [LocalDataKey.bufferedEvents]: newData.events, - }); - } else if (event.data.message === MessageName.HeartBeat) - void Browser.storage.local.set({ - [LocalDataKey.bufferedEvents]: storedEvents.concat( - (event.data as HeartBeatMessage).events, - ), - }); + } }, ); diff --git a/packages/web-extension/src/content/inject.ts b/packages/web-extension/src/content/inject.ts index 6fd2cc1772..0b1b8c9b75 100644 --- a/packages/web-extension/src/content/inject.ts +++ b/packages/web-extension/src/content/inject.ts @@ -5,7 +5,6 @@ import { MessageName, RecordStartedMessage } from '../types'; const events: eventWithTime[] = []; let stopFn: (() => void) | null = null; -let setIntervalId: number | null = null; function startRecord(config: recordOptions) { events.length = 0; @@ -20,12 +19,6 @@ function startRecord(config: recordOptions) { message: MessageName.RecordStarted, startTimestamp: Date.now(), } as RecordStartedMessage); - setIntervalId = (setInterval(() => { - window.postMessage({ - message: MessageName.HeartBeat, - events, - }); - }, 500) as unknown) as number; } const messageHandler = (event: { @@ -41,7 +34,6 @@ const messageHandler = (event: { }, [MessageName.StopRecord]: () => { if (stopFn) stopFn(); - if (setIntervalId) clearInterval(setIntervalId); window.postMessage({ message: MessageName.RecordStopped, events, diff --git a/packages/web-extension/src/manifest.json b/packages/web-extension/src/manifest.json index 70f7426008..6c25c1995b 100644 --- a/packages/web-extension/src/manifest.json +++ b/packages/web-extension/src/manifest.json @@ -31,7 +31,13 @@ "open_in_tab": true, "chrome_style": false }, - "permissions": ["activeTab", "tabs", "storage", "unlimitedStorage"], + "permissions": [ + "activeTab", + "tabs", + "storage", + "unlimitedStorage", + "webNavigation" + ], "web_accessible_resources": ["**/*.js"] }, "chrome": {}, @@ -53,7 +59,13 @@ "page": "options/index.html", "open_in_tab": true }, - "permissions": ["activeTab", "tabs", "storage", "unlimitedStorage"], + "permissions": [ + "activeTab", + "tabs", + "storage", + "unlimitedStorage", + "webNavigation" + ], "web_accessible_resources": [ { "resources": ["**/*.js"], diff --git a/packages/web-extension/src/pages/Player.tsx b/packages/web-extension/src/pages/Player.tsx index 8471601258..59a2332f36 100644 --- a/packages/web-extension/src/pages/Player.tsx +++ b/packages/web-extension/src/pages/Player.tsx @@ -1,6 +1,5 @@ import { useRef, useEffect, useState } from 'react'; import { useParams } from 'react-router-dom'; -import rrwebPlayer from 'rrweb-player'; import Replayer from 'rrweb-player'; import { Box, @@ -13,7 +12,7 @@ import { getEvents, getSession } from '../utils'; export default function Player() { const playerElRef = useRef(null); - const playerRef = useRef(null); + const playerRef = useRef(null); const { sessionId } = useParams(); const [sessionName, setSessionName] = useState(''); diff --git a/packages/web-extension/src/types.ts b/packages/web-extension/src/types.ts index 14c426d57d..71df172bd6 100644 --- a/packages/web-extension/src/types.ts +++ b/packages/web-extension/src/types.ts @@ -50,6 +50,7 @@ export enum ServiceName { StopRecord = 'stop-record', PauseRecord = 'pause-record', ResumeRecord = 'resume-record', + CacheEvents = 'cache-events', } export enum EventName { @@ -76,8 +77,3 @@ export type RecordStoppedMessage = { endTimestamp: number; session?: Session; }; - -export type HeartBeatMessage = { - message: MessageName.HeartBeat; - events: eventWithTime[]; -}; From 2fbd399d34afd5ec68f267c38dfcc815b792ded7 Mon Sep 17 00:00:00 2001 From: Mark-Fenng Date: Sun, 13 Nov 2022 00:22:56 +1100 Subject: [PATCH 22/40] fix firefox compatibility issue and add title to pages --- packages/web-extension/src/manifest.json | 9 ++++++++- packages/web-extension/src/options/index.html | 1 + packages/web-extension/src/pages/index.html | 1 + 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/web-extension/src/manifest.json b/packages/web-extension/src/manifest.json index 6c25c1995b..7b6f0049bd 100644 --- a/packages/web-extension/src/manifest.json +++ b/packages/web-extension/src/manifest.json @@ -41,7 +41,14 @@ "web_accessible_resources": ["**/*.js"] }, "chrome": {}, - "firefox": {} + "firefox": { + "browser_specific_settings": { + "gecko": { + "id": "rrweb@rrweb.io", + "strict_min_version": "42.0" + } + } + } }, "v3": { "common": { diff --git a/packages/web-extension/src/options/index.html b/packages/web-extension/src/options/index.html index 18065c296c..8734726ce5 100644 --- a/packages/web-extension/src/options/index.html +++ b/packages/web-extension/src/options/index.html @@ -1,5 +1,6 @@ +rrweb settings
diff --git a/packages/web-extension/src/pages/index.html b/packages/web-extension/src/pages/index.html index 18065c296c..bac6dabc6f 100644 --- a/packages/web-extension/src/pages/index.html +++ b/packages/web-extension/src/pages/index.html @@ -1,5 +1,6 @@ +rrweb
From 4a5672755e2e8d7c6f30006e0099ed746b5a49ee Mon Sep 17 00:00:00 2001 From: Mark-Fenng Date: Sun, 13 Nov 2022 11:48:38 +1100 Subject: [PATCH 23/40] add mouseleave listener to enhance the recording liability --- packages/web-extension/src/content/index.ts | 8 ++++++++ packages/web-extension/src/content/inject.ts | 10 ++++++++++ packages/web-extension/src/types.ts | 10 +++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/packages/web-extension/src/content/index.ts b/packages/web-extension/src/content/index.ts index 0a64f27848..e9ced0df16 100644 --- a/packages/web-extension/src/content/index.ts +++ b/packages/web-extension/src/content/index.ts @@ -10,6 +10,7 @@ import { RecordStartedMessage, RecordStoppedMessage, MessageName, + CacheEventsMessage, } from '../types'; import Channel from '../utils/channel'; @@ -98,6 +99,7 @@ void (async () => { data: | RecordStartedMessage | RecordStoppedMessage + | CacheEventsMessage | { message: MessageName; }; @@ -122,6 +124,12 @@ void (async () => { clearRecorderCb?.(); clearRecorderCb = undefined; stopResponseCb(newData); + } else if (event.data.message === MessageName.CacheEvents) { + void Browser.storage.local.set({ + [LocalDataKey.bufferedEvents]: storedEvents.concat( + (event.data as CacheEventsMessage).events, + ), + }); } }, ); diff --git a/packages/web-extension/src/content/inject.ts b/packages/web-extension/src/content/inject.ts index 0b1b8c9b75..30d0a916b0 100644 --- a/packages/web-extension/src/content/inject.ts +++ b/packages/web-extension/src/content/inject.ts @@ -6,6 +6,14 @@ import { MessageName, RecordStartedMessage } from '../types'; const events: eventWithTime[] = []; let stopFn: (() => void) | null = null; +// When mouse leaves the page, cache the stored events in case the tab is closed or changed. This is a backup mechanism in case the events are not cached before page unloaded. +const mouseLeaveHandler = () => { + window.postMessage({ + message: MessageName.CacheEvents, + events, + }); +}; + function startRecord(config: recordOptions) { events.length = 0; stopFn = @@ -19,6 +27,7 @@ function startRecord(config: recordOptions) { message: MessageName.RecordStarted, startTimestamp: Date.now(), } as RecordStartedMessage); + document.addEventListener('mouseleave', mouseLeaveHandler); } const messageHandler = (event: { @@ -40,6 +49,7 @@ const messageHandler = (event: { endTimestamp: Date.now(), }); window.removeEventListener('message', messageHandler); + document.removeEventListener('mouseleave', mouseLeaveHandler); }, } as Record void>; if (eventHandler[data.message]) eventHandler[data.message](); diff --git a/packages/web-extension/src/types.ts b/packages/web-extension/src/types.ts index 71df172bd6..9d0a7d22d5 100644 --- a/packages/web-extension/src/types.ts +++ b/packages/web-extension/src/types.ts @@ -45,6 +45,7 @@ export type Session = { recorderVersion: string; }; +// all service names for channel export enum ServiceName { StartRecord = 'start-record', StopRecord = 'stop-record', @@ -53,17 +54,19 @@ export enum ServiceName { CacheEvents = 'cache-events', } +// all event names for channel export enum EventName { SessionUpdated = 'session-updated', } +// all message names for postMessage API export enum MessageName { RecordScriptReady = 'rrweb-extension-record-script-ready', StartRecord = 'rrweb-extension-start-record', RecordStarted = 'rrweb-extension-record-started', - HeartBeat = 'rrweb-extension-heart-beat', StopRecord = 'rrweb-extension-stop-record', RecordStopped = 'rrweb-extension-record-stopped', + CacheEvents = 'rrweb-extension-cache-event', } export type RecordStartedMessage = { @@ -77,3 +80,8 @@ export type RecordStoppedMessage = { endTimestamp: number; session?: Session; }; + +export type CacheEventsMessage = { + message: MessageName.CacheEvents; + events: eventWithTime[]; +}; From 6abfb40adfba063f14d722db20173e3e38dc3259 Mon Sep 17 00:00:00 2001 From: Mark-Fenng Date: Sun, 13 Nov 2022 13:13:47 +1100 Subject: [PATCH 24/40] fix firefox compatibility issue and improve the experience of recording resume after closing tabs --- packages/web-extension/src/background/index.ts | 15 ++++++++++++++- packages/web-extension/src/content/inject.ts | 7 +++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/packages/web-extension/src/background/index.ts b/packages/web-extension/src/background/index.ts index 0ed836c0fe..1e25035eb3 100644 --- a/packages/web-extension/src/background/index.ts +++ b/packages/web-extension/src/background/index.ts @@ -45,7 +45,20 @@ void (async () => { channel, RecorderStatus.PausedSwitch, statusData, - ); + ).catch(async () => { + /** + * This error happen when the old tab is closed. + * In this case, the recording process would be stopped through Browser.tabs.onRemoved API. + * So we just read the new status here. + */ + const localData = (await Browser.storage.local.get( + LocalDataKey.recorderStatus, + )) as LocalData; + return { + status: localData[LocalDataKey.recorderStatus], + bufferedEvents, + }; + }); if (!result) return; statusData = result.status; status = statusData.status; diff --git a/packages/web-extension/src/content/inject.ts b/packages/web-extension/src/content/inject.ts index 30d0a916b0..2acd6176a8 100644 --- a/packages/web-extension/src/content/inject.ts +++ b/packages/web-extension/src/content/inject.ts @@ -27,7 +27,7 @@ function startRecord(config: recordOptions) { message: MessageName.RecordStarted, startTimestamp: Date.now(), } as RecordStartedMessage); - document.addEventListener('mouseleave', mouseLeaveHandler); + document.documentElement.addEventListener('mouseleave', mouseLeaveHandler); } const messageHandler = (event: { @@ -49,7 +49,10 @@ const messageHandler = (event: { endTimestamp: Date.now(), }); window.removeEventListener('message', messageHandler); - document.removeEventListener('mouseleave', mouseLeaveHandler); + document.documentElement.removeEventListener( + 'mouseleave', + mouseLeaveHandler, + ); }, } as Record void>; if (eventHandler[data.message]) eventHandler[data.message](); From da99bc2df87b735eb8634573be65c4aa30b26bd5 Mon Sep 17 00:00:00 2001 From: Mark-Fenng Date: Sun, 13 Nov 2022 13:17:29 +1100 Subject: [PATCH 25/40] update tsconfig --- packages/web-extension/tsconfig.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/web-extension/tsconfig.json b/packages/web-extension/tsconfig.json index 608eb134c5..999bfaa228 100644 --- a/packages/web-extension/tsconfig.json +++ b/packages/web-extension/tsconfig.json @@ -33,6 +33,9 @@ }, { "path": "../rrweb-player" + }, + { + "path": "../types" } ] } From d65135ce5bc1d3967071ee6009b35010c63c32c5 Mon Sep 17 00:00:00 2001 From: Yun Feng Date: Thu, 17 Nov 2022 17:23:30 +1100 Subject: [PATCH 26/40] upgrade vite-plugin-web-extension config to fix some bugs on facebook web page --- packages/web-extension/package.json | 2 +- packages/web-extension/src/content/index.ts | 1 + packages/web-extension/vite.config.ts | 23 ++++++++++++++++++++- yarn.lock | 8 +++---- 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/packages/web-extension/package.json b/packages/web-extension/package.json index 0fde20903b..c23173eda9 100644 --- a/packages/web-extension/package.json +++ b/packages/web-extension/package.json @@ -24,7 +24,7 @@ "type-fest": "^2.19.0", "typescript": "^4.7.3", "vite": "^3.1.8", - "vite-plugin-web-extension": "^1.4.4", + "vite-plugin-web-extension": "^1.4.5", "vite-plugin-zip": "^1.0.1", "webextension-polyfill": "^0.10.0" }, diff --git a/packages/web-extension/src/content/index.ts b/packages/web-extension/src/content/index.ts index e9ced0df16..7bf4cbf767 100644 --- a/packages/web-extension/src/content/index.ts +++ b/packages/web-extension/src/content/index.ts @@ -147,6 +147,7 @@ void (async () => { function startRecord() { const scriptEl = document.createElement('script'); scriptEl.src = Browser.runtime.getURL('content/inject.js'); + scriptEl.type = 'module'; document.documentElement.appendChild(scriptEl); return () => { document.documentElement.removeChild(scriptEl); diff --git a/packages/web-extension/vite.config.ts b/packages/web-extension/vite.config.ts index 1afea8f191..c0a4378f28 100644 --- a/packages/web-extension/vite.config.ts +++ b/packages/web-extension/vite.config.ts @@ -1,10 +1,28 @@ -import { defineConfig } from 'vite'; +import { defineConfig, LibraryOptions, PluginOption } from 'vite'; import webExtension, { readJsonFile } from 'vite-plugin-web-extension'; import zip from 'vite-plugin-zip'; import * as path from 'path'; import type { PackageJson } from 'type-fest'; import react from '@vitejs/plugin-react'; +function useEsmFormat(entriesToUseEsm: string[]): PluginOption { + return { + name: 'use-esm-format', + config(config) { + const shouldUseEsm = entriesToUseEsm.includes( + (config.build?.lib as LibraryOptions)?.entry, + ); + if (shouldUseEsm) { + config.build ??= {}; + // @ts-expect-error: lib needs to be an object, forcing it. + config.build.lib ||= {}; + // @ts-expect-error: lib is an object + config.build.lib.formats = ['es']; + } + }, + }; +} + export default defineConfig({ root: 'src', // Configure our outputs - nothing special, this is normal vite config @@ -60,6 +78,9 @@ export default defineConfig({ }, additionalInputs: ['pages/index.html', 'content/inject.ts'], }), + // https://github.com/aklinker1/vite-plugin-web-extension/issues/50#issuecomment-1317922947 + // transfer inject.ts to esm format to avoid error + useEsmFormat([path.resolve(__dirname, 'src/content/inject.ts')]), process.env.ZIP === 'true' && zip({ dir: 'dist', diff --git a/yarn.lock b/yarn.lock index 0b7d33b23c..5e039b09da 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14814,10 +14814,10 @@ vite-plugin-dts@^1.6.6: kolorist "^1.6.0" ts-morph "^16.0.0" -vite-plugin-web-extension@^1.4.4: - version "1.4.4" - resolved "https://registry.yarnpkg.com/vite-plugin-web-extension/-/vite-plugin-web-extension-1.4.4.tgz#942c6605623c312cd20b86d9b640a192bff892a0" - integrity sha512-X1MGWdYI45Gcp8W+Yc2aq+k/nHWBQ6bMDgGbGn05JVIREsxtpZa7Bh4KKAEV32d9zTnz6aiaSXyAi8usexbyyg== +vite-plugin-web-extension@^1.4.5: + version "1.4.5" + resolved "https://registry.yarnpkg.com/vite-plugin-web-extension/-/vite-plugin-web-extension-1.4.5.tgz#ed52701557c2c54c347a7ae0b85d804bf9c042d8" + integrity sha512-P8+x4XbkFjEfW0fa0HhY6UjU43K6QoEw9PyIXh5yeSsEotj8I1zXw+cWtQoPIsTy03mDswcHaigHOQAQgPGsoA== dependencies: ajv "^8.8.1" md5 "^2.3.0" From f08f334baa58ec0ffab2193e58b364c8712bd1bc Mon Sep 17 00:00:00 2001 From: Yun Feng Date: Thu, 17 Nov 2022 17:25:32 +1100 Subject: [PATCH 27/40] update import links --- packages/web-extension/src/background/index.ts | 6 +++--- packages/web-extension/src/content/index.ts | 4 ++-- packages/web-extension/src/content/inject.ts | 2 +- packages/web-extension/src/options/App.tsx | 2 +- packages/web-extension/src/pages/App.tsx | 2 +- packages/web-extension/src/pages/Player.tsx | 2 +- packages/web-extension/src/pages/SessionList.tsx | 6 +++--- packages/web-extension/src/popup/App.tsx | 8 ++++---- packages/web-extension/src/popup/Timer.tsx | 2 +- packages/web-extension/src/utils/index.ts | 2 +- packages/web-extension/vite.config.ts | 5 +++++ 11 files changed, 23 insertions(+), 18 deletions(-) diff --git a/packages/web-extension/src/background/index.ts b/packages/web-extension/src/background/index.ts index 1e25035eb3..67750ff6a9 100644 --- a/packages/web-extension/src/background/index.ts +++ b/packages/web-extension/src/background/index.ts @@ -1,6 +1,6 @@ import Browser from 'webextension-polyfill'; import type { eventWithTime } from '@rrweb/types'; -import Channel from '../utils/channel'; +import Channel from '~/utils/channel'; import { LocalData, LocalDataKey, @@ -9,8 +9,8 @@ import { Settings, SyncData, SyncDataKey, -} from '../types'; -import { pauseRecording, resumeRecording } from '../utils'; +} from '~/types'; +import { pauseRecording, resumeRecording } from '~/utils'; const channel = new Channel(); diff --git a/packages/web-extension/src/content/index.ts b/packages/web-extension/src/content/index.ts index 7bf4cbf767..c78ba710f1 100644 --- a/packages/web-extension/src/content/index.ts +++ b/packages/web-extension/src/content/index.ts @@ -11,8 +11,8 @@ import { RecordStoppedMessage, MessageName, CacheEventsMessage, -} from '../types'; -import Channel from '../utils/channel'; +} from '~/types'; +import Channel from '~/utils/channel'; const channel = new Channel(); diff --git a/packages/web-extension/src/content/inject.ts b/packages/web-extension/src/content/inject.ts index 2acd6176a8..5dab7e5480 100644 --- a/packages/web-extension/src/content/inject.ts +++ b/packages/web-extension/src/content/inject.ts @@ -1,7 +1,7 @@ import { record } from 'rrweb'; import type { recordOptions } from 'rrweb/typings/types'; import type { eventWithTime } from '@rrweb/types'; -import { MessageName, RecordStartedMessage } from '../types'; +import { MessageName, RecordStartedMessage } from '~/types'; const events: eventWithTime[] = []; let stopFn: (() => void) | null = null; diff --git a/packages/web-extension/src/options/App.tsx b/packages/web-extension/src/options/App.tsx index 80e1f1ca40..5d93e6153d 100644 --- a/packages/web-extension/src/options/App.tsx +++ b/packages/web-extension/src/options/App.tsx @@ -1,5 +1,5 @@ import { Route, Routes } from 'react-router-dom'; -import SidebarWithHeader from '../components/SidebarWithHeader'; +import SidebarWithHeader from '~/components/SidebarWithHeader'; import { FiList, FiSettings } from 'react-icons/fi'; import { Box } from '@chakra-ui/react'; diff --git a/packages/web-extension/src/pages/App.tsx b/packages/web-extension/src/pages/App.tsx index 66d1ba2b52..9a352a95a4 100644 --- a/packages/web-extension/src/pages/App.tsx +++ b/packages/web-extension/src/pages/App.tsx @@ -1,5 +1,5 @@ import { Route, Routes } from 'react-router-dom'; -import SidebarWithHeader from '../components/SidebarWithHeader'; +import SidebarWithHeader from '~/components/SidebarWithHeader'; import { SessionList } from './SessionList'; import { FiList, FiSettings } from 'react-icons/fi'; import Player from './Player'; diff --git a/packages/web-extension/src/pages/Player.tsx b/packages/web-extension/src/pages/Player.tsx index 59a2332f36..34ef5dab10 100644 --- a/packages/web-extension/src/pages/Player.tsx +++ b/packages/web-extension/src/pages/Player.tsx @@ -8,7 +8,7 @@ import { BreadcrumbLink, Center, } from '@chakra-ui/react'; -import { getEvents, getSession } from '../utils'; +import { getEvents, getSession } from '~/utils'; export default function Player() { const playerElRef = useRef(null); diff --git a/packages/web-extension/src/pages/SessionList.tsx b/packages/web-extension/src/pages/SessionList.tsx index 3ab8b60847..e359b9656e 100644 --- a/packages/web-extension/src/pages/SessionList.tsx +++ b/packages/web-extension/src/pages/SessionList.tsx @@ -29,9 +29,9 @@ import { } from '@tanstack/react-table'; import { VscTriangleDown, VscTriangleUp } from 'react-icons/vsc'; import { useNavigate } from 'react-router-dom'; -import { Session, EventName } from '../types'; -import Channel from '../utils/channel'; -import { deleteSessions, getAllSessions } from '../utils'; +import { Session, EventName } from '~/types'; +import Channel from '~/utils/channel'; +import { deleteSessions, getAllSessions } from '~/utils'; import { FiChevronLeft, FiChevronRight, diff --git a/packages/web-extension/src/popup/App.tsx b/packages/web-extension/src/popup/App.tsx index f9fa04de26..2b35fcb7c8 100644 --- a/packages/web-extension/src/popup/App.tsx +++ b/packages/web-extension/src/popup/App.tsx @@ -9,7 +9,7 @@ import { Text, } from '@chakra-ui/react'; import { FiSettings, FiList, FiPause, FiPlay } from 'react-icons/fi'; -import Channel from '../utils/channel'; +import Channel from '~/utils/channel'; import { LocalData, LocalDataKey, @@ -19,11 +19,11 @@ import { RecordStoppedMessage, Session, EventName, -} from '../types'; +} from '~/types'; import Browser from 'webextension-polyfill'; -import { CircleButton } from '../components/CircleButton'; +import { CircleButton } from '~/components/CircleButton'; import { Timer } from './Timer'; -import { pauseRecording, resumeRecording, saveSession } from '../utils'; +import { pauseRecording, resumeRecording, saveSession } from '~/utils'; const RECORD_BUTTON_SIZE = 3; const channel = new Channel(); diff --git a/packages/web-extension/src/popup/Timer.tsx b/packages/web-extension/src/popup/Timer.tsx index 2ffdf0962a..d8732e2e9b 100644 --- a/packages/web-extension/src/popup/Timer.tsx +++ b/packages/web-extension/src/popup/Timer.tsx @@ -1,6 +1,6 @@ import { useEffect, useState } from 'react'; import { Stat, StatNumber } from '@chakra-ui/react'; -import { formatTime } from '../utils'; +import { formatTime } from '~/utils'; export function Timer({ startTime, diff --git a/packages/web-extension/src/utils/index.ts b/packages/web-extension/src/utils/index.ts index 90eb32024f..9e27e89b67 100644 --- a/packages/web-extension/src/utils/index.ts +++ b/packages/web-extension/src/utils/index.ts @@ -9,7 +9,7 @@ import { RecordStoppedMessage, ServiceName, Session, -} from '../types'; +} from '~/types'; import type Channel from './channel'; const SECOND = 1000; diff --git a/packages/web-extension/vite.config.ts b/packages/web-extension/vite.config.ts index c0a4378f28..c6081ef3ba 100644 --- a/packages/web-extension/vite.config.ts +++ b/packages/web-extension/vite.config.ts @@ -87,4 +87,9 @@ export default defineConfig({ outputName: process.env.TARGET_BROWSER, }), ], + resolve: { + alias: { + '~': path.resolve(__dirname, './src'), + }, + }, }); From 46140be721eec388427031567bde0821ec34dadf Mon Sep 17 00:00:00 2001 From: Yun Feng Date: Fri, 18 Nov 2022 00:38:08 +1100 Subject: [PATCH 28/40] refactor: cross tab recording mechanism apply Justin's suggestion --- packages/web-extension/package.json | 2 +- .../web-extension/src/background/index.ts | 20 -------- packages/web-extension/src/content/index.ts | 49 ++++++++----------- packages/web-extension/src/content/inject.ts | 17 ++----- packages/web-extension/src/manifest.json | 17 +------ packages/web-extension/src/types.ts | 9 ++-- packages/web-extension/src/utils/index.ts | 6 +++ packages/web-extension/vite.config.ts | 27 +++++++--- 8 files changed, 57 insertions(+), 90 deletions(-) diff --git a/packages/web-extension/package.json b/packages/web-extension/package.json index c23173eda9..1dd7c3b617 100644 --- a/packages/web-extension/package.json +++ b/packages/web-extension/package.json @@ -2,7 +2,7 @@ "name": "web-extension", "version": "2.0.0", "description": "The web extension of rrweb which helps to run rrweb on any website out of box", - "author": "Yanzhen Yu, Yun Feng", + "author": "rrweb-io", "license": "MIT", "private": true, "scripts": { diff --git a/packages/web-extension/src/background/index.ts b/packages/web-extension/src/background/index.ts index 67750ff6a9..85eac0169b 100644 --- a/packages/web-extension/src/background/index.ts +++ b/packages/web-extension/src/background/index.ts @@ -5,7 +5,6 @@ import { LocalData, LocalDataKey, RecorderStatus, - ServiceName, Settings, SyncData, SyncDataKey, @@ -99,25 +98,6 @@ void (async () => { }); }); - // When page in the current tab is reloaded (navigated), inform the content script in the tab to store events into LocalStorage temporarily. - Browser.webNavigation.onBeforeNavigate.addListener((details) => { - if (details.parentFrameId !== -1) return; - const { tabId } = details; - Browser.storage.local - .get(LocalDataKey.recorderStatus) - .then(async (data) => { - const localData = data as LocalData; - if (!localData || !localData[LocalDataKey.recorderStatus]) return; - const { status, activeTabId } = localData[LocalDataKey.recorderStatus]; - if (status !== RecorderStatus.RECORDING || activeTabId !== tabId) - return; - await channel.requestToTab(tabId, ServiceName.CacheEvents, {}); - }) - .catch((err) => { - console.error(err); - }); - }); - /** * When the current tab is closed, the recording events will be lost because this event is fired after it is closed. * This event listener is just used to make sure the recording status is updated. diff --git a/packages/web-extension/src/content/index.ts b/packages/web-extension/src/content/index.ts index c78ba710f1..6ce59ae281 100644 --- a/packages/web-extension/src/content/index.ts +++ b/packages/web-extension/src/content/index.ts @@ -10,14 +10,15 @@ import { RecordStartedMessage, RecordStoppedMessage, MessageName, - CacheEventsMessage, + EmitEventMessage, } from '~/types'; import Channel from '~/utils/channel'; const channel = new Channel(); void (async () => { - let storedEvents: eventWithTime[] = []; + let bufferedEvents: eventWithTime[] = []; + let newEvents: eventWithTime[] = []; let startResponseCb: | ((response: RecordStartedMessage) => void) | undefined = undefined; @@ -36,13 +37,13 @@ void (async () => { events: eventWithTime[]; pausedTimestamp: number; }; - storedEvents = events; + bufferedEvents = events; clearRecorderCb = startRecord(); return new Promise((resolve) => { startResponseCb = (response) => { const pausedTime = response.startTimestamp - pausedTimestamp; // Decrease the time spent in the pause state and make them look like a continuous recording. - storedEvents.forEach((event) => { + bufferedEvents.forEach((event) => { event.timestamp += pausedTime; }); resolve(response); @@ -59,7 +60,8 @@ void (async () => { stopResponseCb = undefined; const newSession = generateSession(); response.session = newSession; - storedEvents = []; + bufferedEvents = []; + newEvents = []; resolve(response); // clear cache void Browser.storage.local.set({ @@ -73,18 +75,8 @@ void (async () => { return new Promise((resolve) => { stopResponseCb = (response: RecordStoppedMessage) => { stopResponseCb = undefined; - resolve(response); - void Browser.storage.local.set({ - [LocalDataKey.bufferedEvents]: response.events, - }); - }; - }); - }); - channel.provide(ServiceName.CacheEvents, () => { - window.postMessage({ message: MessageName.StopRecord }); - return new Promise((resolve) => { - stopResponseCb = (response: RecordStoppedMessage) => { - stopResponseCb = undefined; + bufferedEvents = []; + newEvents = []; resolve(response); void Browser.storage.local.set({ [LocalDataKey.bufferedEvents]: response.events, @@ -99,7 +91,7 @@ void (async () => { data: | RecordStartedMessage | RecordStoppedMessage - | CacheEventsMessage + | EmitEventMessage | { message: MessageName; }; @@ -120,17 +112,12 @@ void (async () => { const newData = { ...data, }; - newData.events = storedEvents.concat(data.events); + newData.events = bufferedEvents.concat(data.events); clearRecorderCb?.(); clearRecorderCb = undefined; stopResponseCb(newData); - } else if (event.data.message === MessageName.CacheEvents) { - void Browser.storage.local.set({ - [LocalDataKey.bufferedEvents]: storedEvents.concat( - (event.data as CacheEventsMessage).events, - ), - }); - } + } else if (event.data.message === MessageName.EmitEvent) + newEvents.push((event.data as EmitEventMessage).event); }, ); @@ -140,14 +127,20 @@ void (async () => { RecorderStatus.RECORDING ) { clearRecorderCb = startRecord(); - storedEvents = localData[LocalDataKey.bufferedEvents] || []; + bufferedEvents = localData[LocalDataKey.bufferedEvents] || []; } + + // Before unload pages, cache the new events in the local storage. + window.addEventListener('beforeunload', () => { + void Browser.storage.local.set({ + [LocalDataKey.bufferedEvents]: bufferedEvents.concat(newEvents), + }); + }); })(); function startRecord() { const scriptEl = document.createElement('script'); scriptEl.src = Browser.runtime.getURL('content/inject.js'); - scriptEl.type = 'module'; document.documentElement.appendChild(scriptEl); return () => { document.documentElement.removeChild(scriptEl); diff --git a/packages/web-extension/src/content/inject.ts b/packages/web-extension/src/content/inject.ts index 5dab7e5480..d204082176 100644 --- a/packages/web-extension/src/content/inject.ts +++ b/packages/web-extension/src/content/inject.ts @@ -6,20 +6,16 @@ import { MessageName, RecordStartedMessage } from '~/types'; const events: eventWithTime[] = []; let stopFn: (() => void) | null = null; -// When mouse leaves the page, cache the stored events in case the tab is closed or changed. This is a backup mechanism in case the events are not cached before page unloaded. -const mouseLeaveHandler = () => { - window.postMessage({ - message: MessageName.CacheEvents, - events, - }); -}; - function startRecord(config: recordOptions) { events.length = 0; stopFn = record({ emit: (event) => { events.push(event); + window.postMessage({ + message: MessageName.EmitEvent, + event, + }); }, ...config, }) || null; @@ -27,7 +23,6 @@ function startRecord(config: recordOptions) { message: MessageName.RecordStarted, startTimestamp: Date.now(), } as RecordStartedMessage); - document.documentElement.addEventListener('mouseleave', mouseLeaveHandler); } const messageHandler = (event: { @@ -49,10 +44,6 @@ const messageHandler = (event: { endTimestamp: Date.now(), }); window.removeEventListener('message', messageHandler); - document.documentElement.removeEventListener( - 'mouseleave', - mouseLeaveHandler, - ); }, } as Record void>; if (eventHandler[data.message]) eventHandler[data.message](); diff --git a/packages/web-extension/src/manifest.json b/packages/web-extension/src/manifest.json index 7b6f0049bd..608b06b348 100644 --- a/packages/web-extension/src/manifest.json +++ b/packages/web-extension/src/manifest.json @@ -12,7 +12,8 @@ "16": "assets/icon16.png", "48": "assets/icon48.png", "128": "assets/icon128.png" - } + }, + "permissions": ["activeTab", "tabs", "storage", "unlimitedStorage"] }, "v2": { "common": { @@ -31,13 +32,6 @@ "open_in_tab": true, "chrome_style": false }, - "permissions": [ - "activeTab", - "tabs", - "storage", - "unlimitedStorage", - "webNavigation" - ], "web_accessible_resources": ["**/*.js"] }, "chrome": {}, @@ -66,13 +60,6 @@ "page": "options/index.html", "open_in_tab": true }, - "permissions": [ - "activeTab", - "tabs", - "storage", - "unlimitedStorage", - "webNavigation" - ], "web_accessible_resources": [ { "resources": ["**/*.js"], diff --git a/packages/web-extension/src/types.ts b/packages/web-extension/src/types.ts index 9d0a7d22d5..f0dae57e43 100644 --- a/packages/web-extension/src/types.ts +++ b/packages/web-extension/src/types.ts @@ -51,7 +51,6 @@ export enum ServiceName { StopRecord = 'stop-record', PauseRecord = 'pause-record', ResumeRecord = 'resume-record', - CacheEvents = 'cache-events', } // all event names for channel @@ -66,7 +65,7 @@ export enum MessageName { RecordStarted = 'rrweb-extension-record-started', StopRecord = 'rrweb-extension-stop-record', RecordStopped = 'rrweb-extension-record-stopped', - CacheEvents = 'rrweb-extension-cache-event', + EmitEvent = 'rrweb-extension-emit-event', } export type RecordStartedMessage = { @@ -81,7 +80,7 @@ export type RecordStoppedMessage = { session?: Session; }; -export type CacheEventsMessage = { - message: MessageName.CacheEvents; - events: eventWithTime[]; +export type EmitEventMessage = { + message: MessageName.EmitEvent; + event: eventWithTime; }; diff --git a/packages/web-extension/src/utils/index.ts b/packages/web-extension/src/utils/index.ts index 9e27e89b67..0d8cb22707 100644 --- a/packages/web-extension/src/utils/index.ts +++ b/packages/web-extension/src/utils/index.ts @@ -12,6 +12,10 @@ import { } from '~/types'; import type Channel from './channel'; +export function isFirefox(): boolean { + return window.navigator.userAgent.toLowerCase().indexOf('firefox') > -1; +} + const SECOND = 1000; const MINUTE = 60 * SECOND; const HOUR = 60 * MINUTE; @@ -90,6 +94,8 @@ export async function resumeRecording( LocalDataKey.bufferedEvents, )) as LocalData)[LocalDataKey.bufferedEvents]; const { startTimestamp, pausedTimestamp } = status; + // On Firefox, the new tab is not communicable immediately after it is created. + if (isFirefox()) await new Promise((r) => setTimeout(r, 50)); const startResponse = (await channel.requestToTab( newTabId, ServiceName.ResumeRecord, diff --git a/packages/web-extension/vite.config.ts b/packages/web-extension/vite.config.ts index c6081ef3ba..d46a8a0d43 100644 --- a/packages/web-extension/vite.config.ts +++ b/packages/web-extension/vite.config.ts @@ -1,23 +1,31 @@ -import { defineConfig, LibraryOptions, PluginOption } from 'vite'; +import { + defineConfig, + LibraryFormats, + LibraryOptions, + PluginOption, +} from 'vite'; import webExtension, { readJsonFile } from 'vite-plugin-web-extension'; import zip from 'vite-plugin-zip'; import * as path from 'path'; import type { PackageJson } from 'type-fest'; import react from '@vitejs/plugin-react'; -function useEsmFormat(entriesToUseEsm: string[]): PluginOption { +function useSpecialFormat( + entriesToUse: string[], + format: LibraryFormats, +): PluginOption { return { - name: 'use-esm-format', + name: 'use-special-format', config(config) { - const shouldUseEsm = entriesToUseEsm.includes( + const shouldUse = entriesToUse.includes( (config.build?.lib as LibraryOptions)?.entry, ); - if (shouldUseEsm) { + if (shouldUse) { config.build ??= {}; // @ts-expect-error: lib needs to be an object, forcing it. config.build.lib ||= {}; // @ts-expect-error: lib is an object - config.build.lib.formats = ['es']; + config.build.lib.formats = [format]; } }, }; @@ -79,8 +87,11 @@ export default defineConfig({ additionalInputs: ['pages/index.html', 'content/inject.ts'], }), // https://github.com/aklinker1/vite-plugin-web-extension/issues/50#issuecomment-1317922947 - // transfer inject.ts to esm format to avoid error - useEsmFormat([path.resolve(__dirname, 'src/content/inject.ts')]), + // transfer inject.ts to iife format to avoid error + useSpecialFormat( + [path.resolve(__dirname, 'src/content/inject.ts')], + 'iife', + ), process.env.ZIP === 'true' && zip({ dir: 'dist', From 36248e231fae77ef2b3316b63c91595a621da9c0 Mon Sep 17 00:00:00 2001 From: Yun Feng Date: Thu, 1 Dec 2022 18:18:07 +1100 Subject: [PATCH 29/40] refactor: slipt util/index.ts into multiple files --- packages/web-extension/package.json | 6 +- .../web-extension/src/background/index.ts | 2 +- packages/web-extension/src/pages/Player.tsx | 2 +- .../web-extension/src/pages/SessionList.tsx | 2 +- packages/web-extension/src/popup/App.tsx | 3 +- packages/web-extension/src/utils/index.ts | 172 +----------------- packages/web-extension/src/utils/recording.ts | 88 +++++++++ packages/web-extension/src/utils/storage.ts | 90 +++++++++ 8 files changed, 190 insertions(+), 175 deletions(-) create mode 100644 packages/web-extension/src/utils/recording.ts create mode 100644 packages/web-extension/src/utils/storage.ts diff --git a/packages/web-extension/package.json b/packages/web-extension/package.json index 1dd7c3b617..1e23bfb7d9 100644 --- a/packages/web-extension/package.json +++ b/packages/web-extension/package.json @@ -16,7 +16,7 @@ "prepublish": "npm run pack:chrome && npm run pack:firefox" }, "devDependencies": { - "@rrweb/types": "^2.0.0-alpha.3", + "@rrweb/types": "^2.0.0-alpha.4", "@types/react-dom": "^18.0.6", "@types/webextension-polyfill": "^0.9.1", "@vitejs/plugin-react": "^2.1.0", @@ -41,7 +41,7 @@ "react-dom": "^18.2.0", "react-icons": "^4.4.0", "react-router-dom": "^6.4.1", - "rrweb": "^2.0.0-alpha.3", - "rrweb-player": "^1.0.0-alpha.3" + "rrweb": "^2.0.0-alpha.4", + "rrweb-player": "^1.0.0-alpha.4" } } diff --git a/packages/web-extension/src/background/index.ts b/packages/web-extension/src/background/index.ts index 85eac0169b..073f82b862 100644 --- a/packages/web-extension/src/background/index.ts +++ b/packages/web-extension/src/background/index.ts @@ -9,7 +9,7 @@ import { SyncData, SyncDataKey, } from '~/types'; -import { pauseRecording, resumeRecording } from '~/utils'; +import { pauseRecording, resumeRecording } from '~/utils/recording'; const channel = new Channel(); diff --git a/packages/web-extension/src/pages/Player.tsx b/packages/web-extension/src/pages/Player.tsx index 34ef5dab10..b9744a8fa4 100644 --- a/packages/web-extension/src/pages/Player.tsx +++ b/packages/web-extension/src/pages/Player.tsx @@ -8,7 +8,7 @@ import { BreadcrumbLink, Center, } from '@chakra-ui/react'; -import { getEvents, getSession } from '~/utils'; +import { getEvents, getSession } from '~/utils/storage'; export default function Player() { const playerElRef = useRef(null); diff --git a/packages/web-extension/src/pages/SessionList.tsx b/packages/web-extension/src/pages/SessionList.tsx index e359b9656e..8aead1834f 100644 --- a/packages/web-extension/src/pages/SessionList.tsx +++ b/packages/web-extension/src/pages/SessionList.tsx @@ -31,7 +31,7 @@ import { VscTriangleDown, VscTriangleUp } from 'react-icons/vsc'; import { useNavigate } from 'react-router-dom'; import { Session, EventName } from '~/types'; import Channel from '~/utils/channel'; -import { deleteSessions, getAllSessions } from '~/utils'; +import { deleteSessions, getAllSessions } from '~/utils/storage'; import { FiChevronLeft, FiChevronRight, diff --git a/packages/web-extension/src/popup/App.tsx b/packages/web-extension/src/popup/App.tsx index 2b35fcb7c8..a6bed7b3f2 100644 --- a/packages/web-extension/src/popup/App.tsx +++ b/packages/web-extension/src/popup/App.tsx @@ -23,7 +23,8 @@ import { import Browser from 'webextension-polyfill'; import { CircleButton } from '~/components/CircleButton'; import { Timer } from './Timer'; -import { pauseRecording, resumeRecording, saveSession } from '~/utils'; +import { pauseRecording, resumeRecording } from '~/utils/recording'; +import { saveSession } from '~/utils/storage'; const RECORD_BUTTON_SIZE = 3; const channel = new Channel(); diff --git a/packages/web-extension/src/utils/index.ts b/packages/web-extension/src/utils/index.ts index 0d8cb22707..de1e69bf81 100644 --- a/packages/web-extension/src/utils/index.ts +++ b/packages/web-extension/src/utils/index.ts @@ -1,21 +1,11 @@ -import Browser from 'webextension-polyfill'; -import type { eventWithTime } from '@rrweb/types'; -import { openDB } from 'idb'; -import { - LocalData, - LocalDataKey, - RecorderStatus, - RecordStartedMessage, - RecordStoppedMessage, - ServiceName, - Session, -} from '~/types'; -import type Channel from './channel'; - export function isFirefox(): boolean { return window.navigator.userAgent.toLowerCase().indexOf('firefox') > -1; } +export function isInIFrame(): boolean { + return window.parent !== window; +} + const SECOND = 1000; const MINUTE = 60 * SECOND; const HOUR = 60 * MINUTE; @@ -45,157 +35,3 @@ function padZero(num: number, len = 2): string { } return str; } - -// Pause recording. -export async function pauseRecording( - channel: Channel, - newStatus: RecorderStatus, - status?: LocalData[LocalDataKey.recorderStatus], -) { - if (!status) - status = (await Browser.storage.local.get(LocalDataKey.recorderStatus))[ - LocalDataKey.recorderStatus - ] as LocalData[LocalDataKey.recorderStatus]; - const { startTimestamp, activeTabId } = status; - const stopResponse = (await channel.requestToTab( - activeTabId, - ServiceName.PauseRecord, - {}, - )) as RecordStoppedMessage; - if (!stopResponse) return; - const statusData: LocalData[LocalDataKey.recorderStatus] = { - status: newStatus, - activeTabId, - startTimestamp, - pausedTimestamp: stopResponse.endTimestamp, - }; - await Browser.storage.local.set({ - [LocalDataKey.recorderStatus]: statusData, - }); - return { - status: statusData, - bufferedEvents: stopResponse.events, - }; -} - -// Resume recording after change to a new tab. -export async function resumeRecording( - channel: Channel, - newTabId: number, - status?: LocalData[LocalDataKey.recorderStatus], - bufferedEvents?: eventWithTime[], -) { - if (!status) - status = (await Browser.storage.local.get(LocalDataKey.recorderStatus))[ - LocalDataKey.recorderStatus - ] as LocalData[LocalDataKey.recorderStatus]; - if (!bufferedEvents) - bufferedEvents = ((await Browser.storage.local.get( - LocalDataKey.bufferedEvents, - )) as LocalData)[LocalDataKey.bufferedEvents]; - const { startTimestamp, pausedTimestamp } = status; - // On Firefox, the new tab is not communicable immediately after it is created. - if (isFirefox()) await new Promise((r) => setTimeout(r, 50)); - const startResponse = (await channel.requestToTab( - newTabId, - ServiceName.ResumeRecord, - { events: bufferedEvents, pausedTimestamp }, - )) as RecordStartedMessage; - if (!startResponse) return; - const pausedTime = pausedTimestamp - ? startResponse.startTimestamp - pausedTimestamp - : 0; - const statusData: LocalData[LocalDataKey.recorderStatus] = { - status: RecorderStatus.RECORDING, - activeTabId: newTabId, - startTimestamp: - (startTimestamp || bufferedEvents[0].timestamp) + pausedTime, - }; - await Browser.storage.local.set({ - [LocalDataKey.recorderStatus]: statusData, - }); - return statusData; -} - -const EventStoreName = 'events'; -type EventData = { - id: string; - events: eventWithTime[]; -}; - -export async function getEventStore() { - return openDB(EventStoreName, 1, { - upgrade(db) { - db.createObjectStore(EventStoreName, { - keyPath: 'id', - autoIncrement: false, - }); - }, - }); -} - -export async function getEvents(id: string) { - const db = await getEventStore(); - const data = (await db.get(EventStoreName, id)) as EventData; - return data.events; -} - -const SessionStoreName = 'sessions'; -export async function getSessionStore() { - return openDB(SessionStoreName, 1, { - upgrade(db) { - // Create a store of objects - db.createObjectStore(SessionStoreName, { - // The 'id' property of the object will be the key. - keyPath: 'id', - // If it isn't explicitly set, create a value by auto incrementing. - autoIncrement: false, - }); - }, - }); -} - -export async function saveSession(session: Session, events: eventWithTime[]) { - const eventStore = await getEventStore(); - await eventStore.put(EventStoreName, { id: session.id, events }); - const store = await getSessionStore(); - await store.add(SessionStoreName, session); -} - -export async function getSession(id: string) { - const store = await getSessionStore(); - return store.get(SessionStoreName, id) as Promise; -} - -export async function getAllSessions() { - const store = await getSessionStore(); - const sessions = (await store.getAll(SessionStoreName)) as Session[]; - return sessions.sort((a, b) => b.createTimestamp - a.createTimestamp); -} - -export async function deleteSession(id: string) { - const eventStore = await getEventStore(); - const sessionStore = await getSessionStore(); - await Promise.all([ - eventStore.delete(EventStoreName, id), - sessionStore.delete(SessionStoreName, id), - ]); -} - -export async function deleteSessions(ids: string[]) { - const eventStore = await getEventStore(); - const sessionStore = await getSessionStore(); - const eventTransition = eventStore.transaction(EventStoreName, 'readwrite'); - const sessionTransition = sessionStore.transaction( - SessionStoreName, - 'readwrite', - ); - const promises = []; - for (const id of ids) { - promises.push(eventTransition.store.delete(id)); - promises.push(sessionTransition.store.delete(id)); - } - await Promise.all(promises).then(() => { - return Promise.all([eventTransition.done, sessionTransition.done]); - }); -} diff --git a/packages/web-extension/src/utils/recording.ts b/packages/web-extension/src/utils/recording.ts new file mode 100644 index 0000000000..8c28239ec4 --- /dev/null +++ b/packages/web-extension/src/utils/recording.ts @@ -0,0 +1,88 @@ +import Browser from 'webextension-polyfill'; +import type { eventWithTime } from '@rrweb/types'; + +import { + LocalData, + LocalDataKey, + RecorderStatus, + RecordStartedMessage, + RecordStoppedMessage, + ServiceName, +} from '~/types'; +import type Channel from './channel'; +import { isFirefox } from '.'; + +/** + * Some commonly used functions for session recording. + */ + +// Pause recording. +export async function pauseRecording( + channel: Channel, + newStatus: RecorderStatus, + status?: LocalData[LocalDataKey.recorderStatus], +) { + if (!status) + status = (await Browser.storage.local.get(LocalDataKey.recorderStatus))[ + LocalDataKey.recorderStatus + ] as LocalData[LocalDataKey.recorderStatus]; + const { startTimestamp, activeTabId } = status; + const stopResponse = (await channel.requestToTab( + activeTabId, + ServiceName.PauseRecord, + {}, + )) as RecordStoppedMessage; + if (!stopResponse) return; + const statusData: LocalData[LocalDataKey.recorderStatus] = { + status: newStatus, + activeTabId, + startTimestamp, + pausedTimestamp: stopResponse.endTimestamp, + }; + await Browser.storage.local.set({ + [LocalDataKey.recorderStatus]: statusData, + }); + return { + status: statusData, + bufferedEvents: stopResponse.events, + }; +} + +// Resume recording after change to a new tab. +export async function resumeRecording( + channel: Channel, + newTabId: number, + status?: LocalData[LocalDataKey.recorderStatus], + bufferedEvents?: eventWithTime[], +) { + if (!status) + status = (await Browser.storage.local.get(LocalDataKey.recorderStatus))[ + LocalDataKey.recorderStatus + ] as LocalData[LocalDataKey.recorderStatus]; + if (!bufferedEvents) + bufferedEvents = ((await Browser.storage.local.get( + LocalDataKey.bufferedEvents, + )) as LocalData)[LocalDataKey.bufferedEvents]; + const { startTimestamp, pausedTimestamp } = status; + // On Firefox, the new tab is not communicable immediately after it is created. + if (isFirefox()) await new Promise((r) => setTimeout(r, 50)); + const startResponse = (await channel.requestToTab( + newTabId, + ServiceName.ResumeRecord, + { events: bufferedEvents, pausedTimestamp }, + )) as RecordStartedMessage; + if (!startResponse) return; + const pausedTime = pausedTimestamp + ? startResponse.startTimestamp - pausedTimestamp + : 0; + const statusData: LocalData[LocalDataKey.recorderStatus] = { + status: RecorderStatus.RECORDING, + activeTabId: newTabId, + startTimestamp: + (startTimestamp || bufferedEvents[0].timestamp) + pausedTime, + }; + await Browser.storage.local.set({ + [LocalDataKey.recorderStatus]: statusData, + }); + return statusData; +} diff --git a/packages/web-extension/src/utils/storage.ts b/packages/web-extension/src/utils/storage.ts new file mode 100644 index 0000000000..9c52c38a05 --- /dev/null +++ b/packages/web-extension/src/utils/storage.ts @@ -0,0 +1,90 @@ +import { openDB } from 'idb'; +import { eventWithTime } from '@rrweb/types'; +import { Session } from '~/types'; + +/** + * Storage related functions with indexedDB. + */ + +const EventStoreName = 'events'; +type EventData = { + id: string; + events: eventWithTime[]; +}; + +export async function getEventStore() { + return openDB(EventStoreName, 1, { + upgrade(db) { + db.createObjectStore(EventStoreName, { + keyPath: 'id', + autoIncrement: false, + }); + }, + }); +} + +export async function getEvents(id: string) { + const db = await getEventStore(); + const data = (await db.get(EventStoreName, id)) as EventData; + return data.events; +} + +const SessionStoreName = 'sessions'; +export async function getSessionStore() { + return openDB(SessionStoreName, 1, { + upgrade(db) { + // Create a store of objects + db.createObjectStore(SessionStoreName, { + // The 'id' property of the object will be the key. + keyPath: 'id', + // If it isn't explicitly set, create a value by auto incrementing. + autoIncrement: false, + }); + }, + }); +} + +export async function saveSession(session: Session, events: eventWithTime[]) { + const eventStore = await getEventStore(); + await eventStore.put(EventStoreName, { id: session.id, events }); + const store = await getSessionStore(); + await store.add(SessionStoreName, session); +} + +export async function getSession(id: string) { + const store = await getSessionStore(); + return store.get(SessionStoreName, id) as Promise; +} + +export async function getAllSessions() { + const store = await getSessionStore(); + const sessions = (await store.getAll(SessionStoreName)) as Session[]; + return sessions.sort((a, b) => b.createTimestamp - a.createTimestamp); +} + +export async function deleteSession(id: string) { + const eventStore = await getEventStore(); + const sessionStore = await getSessionStore(); + await Promise.all([ + eventStore.delete(EventStoreName, id), + sessionStore.delete(SessionStoreName, id), + ]); +} + +export async function deleteSessions(ids: string[]) { + const eventStore = await getEventStore(); + const sessionStore = await getSessionStore(); + const eventTransition = eventStore.transaction(EventStoreName, 'readwrite'); + const sessionTransition = sessionStore.transaction( + SessionStoreName, + 'readwrite', + ); + const promises = []; + for (const id of ids) { + promises.push(eventTransition.store.delete(id)); + promises.push(sessionTransition.store.delete(id)); + } + await Promise.all(promises).then(() => { + return Promise.all([eventTransition.done, sessionTransition.done]); + }); +} From d978ab6e0934771508ed7e07feb02122d3cf7bc0 Mon Sep 17 00:00:00 2001 From: Yun Feng Date: Fri, 2 Dec 2022 20:42:24 +1100 Subject: [PATCH 30/40] implement cross-origin iframe recording --- packages/web-extension/src/content/index.ts | 82 ++++++++++++++++---- packages/web-extension/src/content/inject.ts | 36 ++++++--- packages/web-extension/src/manifest.json | 1 + packages/web-extension/src/utils/index.ts | 11 ++- 4 files changed, 101 insertions(+), 29 deletions(-) diff --git a/packages/web-extension/src/content/index.ts b/packages/web-extension/src/content/index.ts index 6ce59ae281..4b36ae2706 100644 --- a/packages/web-extension/src/content/index.ts +++ b/packages/web-extension/src/content/index.ts @@ -1,4 +1,4 @@ -import Browser from 'webextension-polyfill'; +import Browser, { Storage } from 'webextension-polyfill'; import { nanoid } from 'nanoid'; import type { eventWithTime } from '@rrweb/types'; import { @@ -13,19 +13,46 @@ import { EmitEventMessage, } from '~/types'; import Channel from '~/utils/channel'; +import { isInCrossOriginIFrame } from '~/utils'; const channel = new Channel(); -void (async () => { +void (() => { + window.addEventListener( + 'message', + ( + event: MessageEvent<{ + message: MessageName; + }>, + ) => { + if (event.source !== window) return; + if (event.data.message === MessageName.RecordScriptReady) + window.postMessage( + { + message: MessageName.StartRecord, + config: { + recordCrossOriginIframes: true, + }, + }, + location.origin, + ); + }, + ); + if (isInCrossOriginIFrame()) { + void initCrossOriginIframe(); + } else { + void initMainPage(); + } +})(); + +async function initMainPage() { let bufferedEvents: eventWithTime[] = []; let newEvents: eventWithTime[] = []; let startResponseCb: | ((response: RecordStartedMessage) => void) | undefined = undefined; - // The callback function to remove the recorder from the page. - let clearRecorderCb: (() => void) | undefined = undefined; channel.provide(ServiceName.StartRecord, async () => { - clearRecorderCb = startRecord(); + startRecord(); return new Promise((resolve) => { startResponseCb = (response) => { resolve(response); @@ -38,7 +65,7 @@ void (async () => { pausedTimestamp: number; }; bufferedEvents = events; - clearRecorderCb = startRecord(); + startRecord(); return new Promise((resolve) => { startResponseCb = (response) => { const pausedTime = response.startTimestamp - pausedTimestamp; @@ -87,17 +114,17 @@ void (async () => { window.addEventListener( 'message', - (event: { - data: + ( + event: MessageEvent< | RecordStartedMessage | RecordStoppedMessage | EmitEventMessage | { message: MessageName; - }; - }) => { - if (event.data.message === MessageName.RecordScriptReady) - window.postMessage({ message: MessageName.StartRecord }); + } + >, + ) => { + if (event.source !== window) return; else if ( event.data.message === MessageName.RecordStarted && startResponseCb @@ -113,8 +140,6 @@ void (async () => { ...data, }; newData.events = bufferedEvents.concat(data.events); - clearRecorderCb?.(); - clearRecorderCb = undefined; stopResponseCb(newData); } else if (event.data.message === MessageName.EmitEvent) newEvents.push((event.data as EmitEventMessage).event); @@ -126,7 +151,7 @@ void (async () => { localData?.[LocalDataKey.recorderStatus]?.status === RecorderStatus.RECORDING ) { - clearRecorderCb = startRecord(); + startRecord(); bufferedEvents = localData[LocalDataKey.bufferedEvents] || []; } @@ -136,13 +161,36 @@ void (async () => { [LocalDataKey.bufferedEvents]: bufferedEvents.concat(newEvents), }); }); -})(); +} + +async function initCrossOriginIframe() { + Browser.storage.local.onChanged.addListener((change) => { + if (change[LocalDataKey.recorderStatus]) { + const statusChange = change[ + LocalDataKey.recorderStatus + ] as Storage.StorageChange; + const newStatus = statusChange.newValue as LocalData[LocalDataKey.recorderStatus]; + if (newStatus.status === RecorderStatus.RECORDING) startRecord(); + else + window.postMessage( + { message: MessageName.StopRecord }, + location.origin, + ); + } + }); + const localData = (await Browser.storage.local.get()) as LocalData; + if ( + localData?.[LocalDataKey.recorderStatus]?.status === + RecorderStatus.RECORDING + ) + startRecord(); +} function startRecord() { const scriptEl = document.createElement('script'); scriptEl.src = Browser.runtime.getURL('content/inject.js'); document.documentElement.appendChild(scriptEl); - return () => { + scriptEl.onload = () => { document.documentElement.removeChild(scriptEl); }; } diff --git a/packages/web-extension/src/content/inject.ts b/packages/web-extension/src/content/inject.ts index d204082176..0f2d7d3f67 100644 --- a/packages/web-extension/src/content/inject.ts +++ b/packages/web-extension/src/content/inject.ts @@ -2,6 +2,11 @@ import { record } from 'rrweb'; import type { recordOptions } from 'rrweb/typings/types'; import type { eventWithTime } from '@rrweb/types'; import { MessageName, RecordStartedMessage } from '~/types'; +import { isInCrossOriginIFrame } from '~/utils'; + +/** + * This script is injected into both main page and cross-origin IFrames through