@jesec/flood 0.0.0-master.83e789c → 0.0.0-master.84305da

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (440) hide show
  1. package/CHANGELOG.md +710 -103
  2. package/README.md +126 -46
  3. package/SECURITY.md +27 -0
  4. package/dist/assets/icon_128x128.png +0 -0
  5. package/dist/assets/icon_192x192.png +0 -0
  6. package/dist/assets/icon_256x256.png +0 -0
  7. package/dist/assets/icon_384x384.png +0 -0
  8. package/dist/assets/icon_512x512.png +0 -0
  9. package/dist/assets/icon_96x96.png +0 -0
  10. package/dist/assets/icon_maskable.png +0 -0
  11. package/dist/assets/icon_maskable_180x180.png +0 -0
  12. package/dist/assets/index.html +1 -1
  13. package/dist/assets/manifest.json +35 -7
  14. package/dist/assets/static/css/main.968c780bfc4b52a705a5.css +2 -0
  15. package/dist/assets/static/css/main.968c780bfc4b52a705a5.css.map +1 -0
  16. package/dist/assets/static/js/179.43c61c39.chunk.js +2 -0
  17. package/dist/assets/static/js/179.43c61c39.chunk.js.map +1 -0
  18. package/dist/assets/static/js/525.57b74c72.chunk.js +2 -0
  19. package/dist/assets/static/js/525.57b74c72.chunk.js.map +1 -0
  20. package/dist/assets/static/js/579.c74a7ebb.chunk.js +2 -0
  21. package/dist/assets/static/js/579.c74a7ebb.chunk.js.map +1 -0
  22. package/dist/assets/static/js/704.2754d905.chunk.js +2 -0
  23. package/dist/assets/static/js/704.2754d905.chunk.js.map +1 -0
  24. package/dist/assets/static/js/flag0.390f4d80.chunk.js +2 -0
  25. package/dist/assets/static/js/flag0.390f4d80.chunk.js.map +1 -0
  26. package/dist/assets/static/js/flag1.c2493006.chunk.js +1 -0
  27. package/dist/assets/static/js/flag2.55e1234c.chunk.js +1 -0
  28. package/dist/assets/static/js/flag3.f007a894.chunk.js +1 -0
  29. package/dist/assets/static/js/i18n0.ec6ce9de.chunk.js +2 -0
  30. package/dist/assets/static/js/i18n0.ec6ce9de.chunk.js.map +1 -0
  31. package/dist/assets/static/js/i18n1.024a1e0a.chunk.js +2 -0
  32. package/dist/assets/static/js/i18n1.024a1e0a.chunk.js.map +1 -0
  33. package/dist/assets/static/js/i18n10.b180a8fe.chunk.js +2 -0
  34. package/dist/assets/static/js/i18n10.b180a8fe.chunk.js.map +1 -0
  35. package/dist/assets/static/js/i18n11.cc9e4457.chunk.js +2 -0
  36. package/dist/assets/static/js/i18n11.cc9e4457.chunk.js.map +1 -0
  37. package/dist/assets/static/js/i18n12.434bfc84.chunk.js +2 -0
  38. package/dist/assets/static/js/i18n12.434bfc84.chunk.js.map +1 -0
  39. package/dist/assets/static/js/i18n13.4e1bcc7d.chunk.js +2 -0
  40. package/dist/assets/static/js/i18n13.4e1bcc7d.chunk.js.map +1 -0
  41. package/dist/assets/static/js/i18n14.bd0e0339.chunk.js +2 -0
  42. package/dist/assets/static/js/i18n14.bd0e0339.chunk.js.map +1 -0
  43. package/dist/assets/static/js/i18n15.9bccd290.chunk.js +2 -0
  44. package/dist/assets/static/js/i18n15.9bccd290.chunk.js.map +1 -0
  45. package/dist/assets/static/js/i18n16.72597f50.chunk.js +2 -0
  46. package/dist/assets/static/js/i18n16.72597f50.chunk.js.map +1 -0
  47. package/dist/assets/static/js/i18n17.a512a8ea.chunk.js +2 -0
  48. package/dist/assets/static/js/i18n17.a512a8ea.chunk.js.map +1 -0
  49. package/dist/assets/static/js/i18n18.7f743233.chunk.js +2 -0
  50. package/dist/assets/static/js/i18n18.7f743233.chunk.js.map +1 -0
  51. package/dist/assets/static/js/i18n19.39cd469a.chunk.js +2 -0
  52. package/dist/assets/static/js/i18n19.39cd469a.chunk.js.map +1 -0
  53. package/dist/assets/static/js/i18n2.79e0d92e.chunk.js +2 -0
  54. package/dist/assets/static/js/i18n2.79e0d92e.chunk.js.map +1 -0
  55. package/dist/assets/static/js/i18n20.3abdb6e8.chunk.js +2 -0
  56. package/dist/assets/static/js/i18n20.3abdb6e8.chunk.js.map +1 -0
  57. package/dist/assets/static/js/i18n21.50abaf1d.chunk.js +2 -0
  58. package/dist/assets/static/js/i18n21.50abaf1d.chunk.js.map +1 -0
  59. package/dist/assets/static/js/i18n22.1b255305.chunk.js +2 -0
  60. package/dist/assets/static/js/i18n22.1b255305.chunk.js.map +1 -0
  61. package/dist/assets/static/js/i18n23.bed06736.chunk.js +2 -0
  62. package/dist/assets/static/js/i18n23.bed06736.chunk.js.map +1 -0
  63. package/dist/assets/static/js/i18n24.3c9dd350.chunk.js +2 -0
  64. package/dist/assets/static/js/i18n24.3c9dd350.chunk.js.map +1 -0
  65. package/dist/assets/static/js/i18n25.bd8904ad.chunk.js +2 -0
  66. package/dist/assets/static/js/i18n25.bd8904ad.chunk.js.map +1 -0
  67. package/dist/assets/static/js/i18n26.6b4d29ff.chunk.js +2 -0
  68. package/dist/assets/static/js/i18n26.6b4d29ff.chunk.js.map +1 -0
  69. package/dist/assets/static/js/i18n27.aef61718.chunk.js +2 -0
  70. package/dist/assets/static/js/i18n27.aef61718.chunk.js.map +1 -0
  71. package/dist/assets/static/js/i18n28.c7adecad.chunk.js +2 -0
  72. package/dist/assets/static/js/i18n28.c7adecad.chunk.js.map +1 -0
  73. package/dist/assets/static/js/i18n3.0dd26c81.chunk.js +2 -0
  74. package/dist/assets/static/js/i18n3.0dd26c81.chunk.js.map +1 -0
  75. package/dist/assets/static/js/i18n4.aa48660a.chunk.js +2 -0
  76. package/dist/assets/static/js/i18n4.aa48660a.chunk.js.map +1 -0
  77. package/dist/assets/static/js/i18n5.5d0467c6.chunk.js +2 -0
  78. package/dist/assets/static/js/i18n5.5d0467c6.chunk.js.map +1 -0
  79. package/dist/assets/static/js/i18n6.95586fce.chunk.js +2 -0
  80. package/dist/assets/static/js/i18n6.95586fce.chunk.js.map +1 -0
  81. package/dist/assets/static/js/i18n8.c41df595.chunk.js +2 -0
  82. package/dist/assets/static/js/i18n8.c41df595.chunk.js.map +1 -0
  83. package/dist/assets/static/js/i18n9.7a446f59.chunk.js +2 -0
  84. package/dist/assets/static/js/i18n9.7a446f59.chunk.js.map +1 -0
  85. package/dist/assets/static/js/main.8378636b.js +2 -0
  86. package/dist/assets/static/js/main.8378636b.js.map +1 -0
  87. package/dist/assets/static/media/ad.1b24595d.png +0 -0
  88. package/dist/assets/static/media/ae.4dd8f55e.png +0 -0
  89. package/dist/assets/static/media/af.4ce660eb.png +0 -0
  90. package/dist/assets/static/media/ag.fd9409e4.png +0 -0
  91. package/dist/assets/static/media/al.a297aacf.png +0 -0
  92. package/dist/assets/static/media/am.c84ee0cf.png +0 -0
  93. package/dist/assets/static/media/ao.a7c9214e.png +0 -0
  94. package/dist/assets/static/media/ar.7e57ef92.png +0 -0
  95. package/dist/assets/static/media/at.5aa9728a.png +0 -0
  96. package/dist/assets/static/media/au.155b51d8.png +0 -0
  97. package/dist/assets/static/media/az.63afef5b.png +0 -0
  98. package/dist/assets/static/media/ba.5ce8f273.png +0 -0
  99. package/dist/assets/static/media/bb.f369fc62.png +0 -0
  100. package/dist/assets/static/media/bd.516278fc.png +0 -0
  101. package/dist/assets/static/media/be.08ec4a8d.png +0 -0
  102. package/dist/assets/static/media/bf.50bfcb31.png +0 -0
  103. package/dist/assets/static/media/bg.d9346b96.png +0 -0
  104. package/dist/assets/static/media/bh.f06d5914.png +0 -0
  105. package/dist/assets/static/media/bi.4923e3a3.png +0 -0
  106. package/dist/assets/static/media/bj.019fa79b.png +0 -0
  107. package/dist/assets/static/media/bn.077671e2.png +0 -0
  108. package/dist/assets/static/media/bo.8fb15fc6.png +0 -0
  109. package/dist/assets/static/media/br.ec051f0c.png +0 -0
  110. package/dist/assets/static/media/bs.a74a126f.png +0 -0
  111. package/dist/assets/static/media/bt.4217b804.png +0 -0
  112. package/dist/assets/static/media/bw.21fe1567.png +0 -0
  113. package/dist/assets/static/media/by.d247fe16.png +0 -0
  114. package/dist/assets/static/media/bz.98ec59f6.png +0 -0
  115. package/dist/assets/static/media/ca.25743e11.png +0 -0
  116. package/dist/assets/static/media/cd.a5bfda53.png +0 -0
  117. package/dist/assets/static/media/cf.de7d5d92.png +0 -0
  118. package/dist/assets/static/media/cg.a47b626b.png +0 -0
  119. package/dist/assets/static/media/ch.445f47a1.png +0 -0
  120. package/dist/assets/static/media/ci.a6009c5b.png +0 -0
  121. package/dist/assets/static/media/cl.de1d715e.png +0 -0
  122. package/dist/assets/static/media/cm.3ce8a86a.png +0 -0
  123. package/dist/assets/static/media/cn.e6a26073.png +0 -0
  124. package/dist/assets/static/media/co.e9244faa.png +0 -0
  125. package/dist/assets/static/media/cr.c895e035.png +0 -0
  126. package/dist/assets/static/media/cu.e486c055.png +0 -0
  127. package/dist/assets/static/media/cv.a9585acf.png +0 -0
  128. package/dist/assets/static/media/cw.df13039d.png +0 -0
  129. package/dist/assets/static/media/cy.b31f43a9.png +0 -0
  130. package/dist/assets/static/media/cz.8ec5948b.png +0 -0
  131. package/dist/assets/static/media/de.d12f391a.png +0 -0
  132. package/dist/assets/static/media/dj.154c3580.png +0 -0
  133. package/dist/assets/static/media/dk.da382fe2.png +0 -0
  134. package/dist/assets/static/media/dm.f452e6cd.png +0 -0
  135. package/dist/assets/static/media/do.c6bd7637.png +0 -0
  136. package/dist/assets/static/media/dz.672a69c0.png +0 -0
  137. package/dist/assets/static/media/ec.349d9bd7.png +0 -0
  138. package/dist/assets/static/media/ee.2396205f.png +0 -0
  139. package/dist/assets/static/media/eg.ccbf3f45.png +0 -0
  140. package/dist/assets/static/media/eh.af65674a.png +0 -0
  141. package/dist/assets/static/media/er.21afb638.png +0 -0
  142. package/dist/assets/static/media/es.2a6eaee4.png +0 -0
  143. package/dist/assets/static/media/et.8beb65c8.png +0 -0
  144. package/dist/assets/static/media/fi.331f70fd.png +0 -0
  145. package/dist/assets/static/media/fj.7724d800.png +0 -0
  146. package/dist/assets/static/media/fm.eeaf71e9.png +0 -0
  147. package/dist/assets/static/media/fr.5d5ab008.png +0 -0
  148. package/dist/assets/static/media/ga.77ed474c.png +0 -0
  149. package/dist/assets/static/media/gb.e00065bf.png +0 -0
  150. package/dist/assets/static/media/gd.b4522267.png +0 -0
  151. package/dist/assets/static/media/ge.91a7654d.png +0 -0
  152. package/dist/assets/static/media/gh.4759f92f.png +0 -0
  153. package/dist/assets/static/media/gm.81cd9f75.png +0 -0
  154. package/dist/assets/static/media/gn.9f3d376e.png +0 -0
  155. package/dist/assets/static/media/gq.e8ad58be.png +0 -0
  156. package/dist/assets/static/media/gr.26f3ac0b.png +0 -0
  157. package/dist/assets/static/media/gt.9d81c52e.png +0 -0
  158. package/dist/assets/static/media/gw.dc906982.png +0 -0
  159. package/dist/assets/static/media/gy.a4f62b6c.png +0 -0
  160. package/dist/assets/static/media/hk.56555c3f.png +0 -0
  161. package/dist/assets/static/media/hn.64ee6aad.png +0 -0
  162. package/dist/assets/static/media/hr.93ebecd3.png +0 -0
  163. package/dist/assets/static/media/ht.42ca1596.png +0 -0
  164. package/dist/assets/static/media/hu.bb30f05d.png +0 -0
  165. package/dist/assets/static/media/id.2cb49f2d.png +0 -0
  166. package/dist/assets/static/media/ie.b4dd1f19.png +0 -0
  167. package/dist/assets/static/media/il.cd1d1faf.png +0 -0
  168. package/dist/assets/static/media/in.2df03847.png +0 -0
  169. package/dist/assets/static/media/iq.a9b670ab.png +0 -0
  170. package/dist/assets/static/media/ir.9a3de085.png +0 -0
  171. package/dist/assets/static/media/is.d88f4fc9.png +0 -0
  172. package/dist/assets/static/media/it.b73713e3.png +0 -0
  173. package/dist/assets/static/media/je.0353f56a.png +0 -0
  174. package/dist/assets/static/media/jm.20330ef4.png +0 -0
  175. package/dist/assets/static/media/jo.eb66f1d1.png +0 -0
  176. package/dist/assets/static/media/jp.63e382ae.png +0 -0
  177. package/dist/assets/static/media/ke.ab2e43b8.png +0 -0
  178. package/dist/assets/static/media/kg.2c47c2af.png +0 -0
  179. package/dist/assets/static/media/kh.4732c810.png +0 -0
  180. package/dist/assets/static/media/ki.5fba09fd.png +0 -0
  181. package/dist/assets/static/media/km.7bbed3e9.png +0 -0
  182. package/dist/assets/static/media/kn.a9595a16.png +0 -0
  183. package/dist/assets/static/media/kp.8a4dc30a.png +0 -0
  184. package/dist/assets/static/media/kr.5273be1d.png +0 -0
  185. package/dist/assets/static/media/ks.99f78645.png +0 -0
  186. package/dist/assets/static/media/kw.af3521bc.png +0 -0
  187. package/dist/assets/static/media/kz.ea47ef79.png +0 -0
  188. package/dist/assets/static/media/la.78a598d7.png +0 -0
  189. package/dist/assets/static/media/lb.7a7c15a9.png +0 -0
  190. package/dist/assets/static/media/lc.6083a4ff.png +0 -0
  191. package/dist/assets/static/media/li.61c564a4.png +0 -0
  192. package/dist/assets/static/media/lk.6fa85802.png +0 -0
  193. package/dist/assets/static/media/lr.8063f7db.png +0 -0
  194. package/dist/assets/static/media/ls.901ddb71.png +0 -0
  195. package/dist/assets/static/media/lt.9209ace3.png +0 -0
  196. package/dist/assets/static/media/lu.c9872bc1.png +0 -0
  197. package/dist/assets/static/media/lv.7bcacf0a.png +0 -0
  198. package/dist/assets/static/media/ly.2830aa63.png +0 -0
  199. package/dist/assets/static/media/ma.ce5f697b.png +0 -0
  200. package/dist/assets/static/media/mc.4bd5d57a.png +0 -0
  201. package/dist/assets/static/media/md.fb4b5bdf.png +0 -0
  202. package/dist/assets/static/media/me.1f1d1772.png +0 -0
  203. package/dist/assets/static/media/mg.89101bd2.png +0 -0
  204. package/dist/assets/static/media/mh.ff11dff7.png +0 -0
  205. package/dist/assets/static/media/mk.8420e604.png +0 -0
  206. package/dist/assets/static/media/ml.4db47c66.png +0 -0
  207. package/dist/assets/static/media/mm.8e4ac30a.png +0 -0
  208. package/dist/assets/static/media/mn.dc1daa04.png +0 -0
  209. package/dist/assets/static/media/mr.7cbca6d0.png +0 -0
  210. package/dist/assets/static/media/mt.28a4b863.png +0 -0
  211. package/dist/assets/static/media/mu.d93db6c7.png +0 -0
  212. package/dist/assets/static/media/mv.7d026bf1.png +0 -0
  213. package/dist/assets/static/media/mw.960cd4fb.png +0 -0
  214. package/dist/assets/static/media/mx.39b78eb2.png +0 -0
  215. package/dist/assets/static/media/my.916a8392.png +0 -0
  216. package/dist/assets/static/media/mz.facb4ea3.png +0 -0
  217. package/dist/assets/static/media/na.472666a9.png +0 -0
  218. package/dist/assets/static/media/ne.d774701f.png +0 -0
  219. package/dist/assets/static/media/ng.7b06a49f.png +0 -0
  220. package/dist/assets/static/media/ni.7140131c.png +0 -0
  221. package/dist/assets/static/media/nl.4c04aa96.png +0 -0
  222. package/dist/assets/static/media/no.c19eb00d.png +0 -0
  223. package/dist/assets/static/media/np.54fb4f2f.png +0 -0
  224. package/dist/assets/static/media/nr.7527cc38.png +0 -0
  225. package/dist/assets/static/media/nz.738be05b.png +0 -0
  226. package/dist/assets/static/media/om.b25e0a17.png +0 -0
  227. package/dist/assets/static/media/pa.b28a9059.png +0 -0
  228. package/dist/assets/static/media/pe.c1fc1d96.png +0 -0
  229. package/dist/assets/static/media/pg.380115db.png +0 -0
  230. package/dist/assets/static/media/ph.02199ddc.png +0 -0
  231. package/dist/assets/static/media/pk.094f9517.png +0 -0
  232. package/dist/assets/static/media/pl.41521283.png +0 -0
  233. package/dist/assets/static/media/pt.1f82dc04.png +0 -0
  234. package/dist/assets/static/media/pw.a26c2316.png +0 -0
  235. package/dist/assets/static/media/py.926c65ed.png +0 -0
  236. package/dist/assets/static/media/qa.c6a3c20e.png +0 -0
  237. package/dist/assets/static/media/ro.a36876c9.png +0 -0
  238. package/dist/assets/static/media/rs.c6629de8.png +0 -0
  239. package/dist/assets/static/media/ru.a9b948c1.png +0 -0
  240. package/dist/assets/static/media/rw.e8aecba0.png +0 -0
  241. package/dist/assets/static/media/sa.859049c8.png +0 -0
  242. package/dist/assets/static/media/sb.4ad27b27.png +0 -0
  243. package/dist/assets/static/media/sc.3293efde.png +0 -0
  244. package/dist/assets/static/media/sd.19c94faa.png +0 -0
  245. package/dist/assets/static/media/se.195b3f93.png +0 -0
  246. package/dist/assets/static/media/sg.19d81907.png +0 -0
  247. package/dist/assets/static/media/si.367c5443.png +0 -0
  248. package/dist/assets/static/media/sk.4e5b8a39.png +0 -0
  249. package/dist/assets/static/media/sl.4b174b1c.png +0 -0
  250. package/dist/assets/static/media/sm.2cba3dac.png +0 -0
  251. package/dist/assets/static/media/sn.a4c1041d.png +0 -0
  252. package/dist/assets/static/media/so.b455e3bf.png +0 -0
  253. package/dist/assets/static/media/sr.5adc1c00.png +0 -0
  254. package/dist/assets/static/media/st.5ae44155.png +0 -0
  255. package/dist/assets/static/media/sv.43aa6cdf.png +0 -0
  256. package/dist/assets/static/media/sy.0fbd24f7.png +0 -0
  257. package/dist/assets/static/media/sz.ff204912.png +0 -0
  258. package/dist/assets/static/media/td.c7aa2a4e.png +0 -0
  259. package/dist/assets/static/media/tg.857c3bec.png +0 -0
  260. package/dist/assets/static/media/th.683600c7.png +0 -0
  261. package/dist/assets/static/media/tj.d20c5570.png +0 -0
  262. package/dist/assets/static/media/tl.5edd8ea7.png +0 -0
  263. package/dist/assets/static/media/tm.15960215.png +0 -0
  264. package/dist/assets/static/media/tn.40df718e.png +0 -0
  265. package/dist/assets/static/media/to.c3b054df.png +0 -0
  266. package/dist/assets/static/media/tr.adeace6d.png +0 -0
  267. package/dist/assets/static/media/tt.839bd7f1.png +0 -0
  268. package/dist/assets/static/media/tv.628cae3e.png +0 -0
  269. package/dist/assets/static/media/tw.4e885914.png +0 -0
  270. package/dist/assets/static/media/tz.b2f0dc37.png +0 -0
  271. package/dist/assets/static/media/ua.6b103313.png +0 -0
  272. package/dist/assets/static/media/ug.c84042fc.png +0 -0
  273. package/dist/assets/static/media/us.8523c31d.png +0 -0
  274. package/dist/assets/static/media/uy.a943f85e.png +0 -0
  275. package/dist/assets/static/media/uz.25552673.png +0 -0
  276. package/dist/assets/static/media/va.a29e1b53.png +0 -0
  277. package/dist/assets/static/media/vc.7480bd37.png +0 -0
  278. package/dist/assets/static/media/ve.fd4273c2.png +0 -0
  279. package/dist/assets/static/media/vn.7d2eff1b.png +0 -0
  280. package/dist/assets/static/media/vu.48b64cf3.png +0 -0
  281. package/dist/assets/static/media/ws.f3d9202f.png +0 -0
  282. package/dist/assets/static/media/ye.311a0e50.png +0 -0
  283. package/dist/assets/static/media/za.090a856f.png +0 -0
  284. package/dist/assets/static/media/zm.8371e197.png +0 -0
  285. package/dist/assets/static/media/zw.a6809447.png +0 -0
  286. package/dist/index.js +131685 -0
  287. package/package.json +222 -151
  288. package/dist/assets/android-chrome-192x192.png +0 -0
  289. package/dist/assets/android-chrome-512x512.png +0 -0
  290. package/dist/assets/apple-touch-icon.png +0 -0
  291. package/dist/assets/asset-manifest.json +0 -57
  292. package/dist/assets/browserconfig.xml +0 -9
  293. package/dist/assets/favicon-16x16.png +0 -0
  294. package/dist/assets/favicon-32x32.png +0 -0
  295. package/dist/assets/mstile-144x144.png +0 -0
  296. package/dist/assets/mstile-150x150.png +0 -0
  297. package/dist/assets/mstile-310x150.png +0 -0
  298. package/dist/assets/mstile-310x310.png +0 -0
  299. package/dist/assets/mstile-70x70.png +0 -0
  300. package/dist/assets/static/css/main.e5c088b6b6f679087a82.css +0 -1
  301. package/dist/assets/static/js/0.0a556a75.chunk.js +0 -1
  302. package/dist/assets/static/js/1.14dd2d0c.chunk.js +0 -1
  303. package/dist/assets/static/js/10.d4eef924.chunk.js +0 -1
  304. package/dist/assets/static/js/11.53cd515d.chunk.js +0 -1
  305. package/dist/assets/static/js/12.ce0f8a4e.chunk.js +0 -1
  306. package/dist/assets/static/js/13.9ca96920.chunk.js +0 -1
  307. package/dist/assets/static/js/14.588e3d0c.chunk.js +0 -1
  308. package/dist/assets/static/js/15.f28d64ab.chunk.js +0 -1
  309. package/dist/assets/static/js/16.53dd87df.chunk.js +0 -1
  310. package/dist/assets/static/js/17.b764e125.chunk.js +0 -1
  311. package/dist/assets/static/js/18.9b7e5575.chunk.js +0 -1
  312. package/dist/assets/static/js/2.8fafb9ff.chunk.js +0 -1
  313. package/dist/assets/static/js/20.64809e35.chunk.js +0 -1
  314. package/dist/assets/static/js/21.f3058669.chunk.js +0 -1
  315. package/dist/assets/static/js/22.dcfb4883.chunk.js +0 -1
  316. package/dist/assets/static/js/23.840a4201.chunk.js +0 -1
  317. package/dist/assets/static/js/24.0a173a0d.chunk.js +0 -1
  318. package/dist/assets/static/js/25.e4c2217e.chunk.js +0 -1
  319. package/dist/assets/static/js/26.5f03f1a3.chunk.js +0 -1
  320. package/dist/assets/static/js/27.5127408d.chunk.js +0 -1
  321. package/dist/assets/static/js/28.ebac4379.chunk.js +0 -1
  322. package/dist/assets/static/js/29.de46849d.chunk.js +0 -1
  323. package/dist/assets/static/js/3.c219b8a8.chunk.js +0 -1
  324. package/dist/assets/static/js/30.ff543e93.chunk.js +0 -1
  325. package/dist/assets/static/js/31.1f1ad44f.chunk.js +0 -1
  326. package/dist/assets/static/js/32.b4c28098.chunk.js +0 -1
  327. package/dist/assets/static/js/33.3febffaf.chunk.js +0 -1
  328. package/dist/assets/static/js/34.2e764e96.chunk.js +0 -1
  329. package/dist/assets/static/js/35.92c40bb9.chunk.js +0 -1
  330. package/dist/assets/static/js/36.27afe215.chunk.js +0 -1
  331. package/dist/assets/static/js/37.6d94e34b.chunk.js +0 -1
  332. package/dist/assets/static/js/38.107b5aa9.chunk.js +0 -1
  333. package/dist/assets/static/js/39.112b724b.chunk.js +0 -1
  334. package/dist/assets/static/js/4.19d26f13.chunk.js +0 -1
  335. package/dist/assets/static/js/40.44aa79f5.chunk.js +0 -1
  336. package/dist/assets/static/js/41.fb69cc30.chunk.js +0 -1
  337. package/dist/assets/static/js/42.906cc1ff.chunk.js +0 -1
  338. package/dist/assets/static/js/43.135e1560.chunk.js +0 -1
  339. package/dist/assets/static/js/44.a3d23bab.chunk.js +0 -1
  340. package/dist/assets/static/js/45.f025dffe.chunk.js +0 -1
  341. package/dist/assets/static/js/46.3ea25c9e.chunk.js +0 -1
  342. package/dist/assets/static/js/47.5a213255.chunk.js +0 -1
  343. package/dist/assets/static/js/48.ce4bfe23.chunk.js +0 -1
  344. package/dist/assets/static/js/49.857650de.chunk.js +0 -1
  345. package/dist/assets/static/js/5.dc5232a2.chunk.js +0 -1
  346. package/dist/assets/static/js/50.2a5fd558.chunk.js +0 -1
  347. package/dist/assets/static/js/6.210f5d48.chunk.js +0 -1
  348. package/dist/assets/static/js/7.29af7904.chunk.js +0 -1
  349. package/dist/assets/static/js/8.efcd70d8.chunk.js +0 -1
  350. package/dist/assets/static/js/9.23e24017.chunk.js +0 -1
  351. package/dist/assets/static/js/main.c8ce60de.js +0 -1
  352. package/dist/assets/static/media/ABOUT.d02918c9.md +0 -13
  353. package/dist/assets/static/media/Roboto-500.64e69384.woff +0 -0
  354. package/dist/assets/static/media/Roboto-500.7f8f0146.eot +0 -0
  355. package/dist/assets/static/media/Roboto-500.916656a2.ttf +0 -0
  356. package/dist/assets/static/media/Roboto-500.abd255e8.svg +0 -305
  357. package/dist/assets/static/media/Roboto-700.8d11d1e1.ttf +0 -0
  358. package/dist/assets/static/media/Roboto-700.9c9c164e.svg +0 -310
  359. package/dist/assets/static/media/Roboto-700.c65552c8.eot +0 -0
  360. package/dist/assets/static/media/Roboto-700.ee82bda2.woff +0 -0
  361. package/dist/assets/static/media/Roboto-700italic.1dc5bfed.eot +0 -0
  362. package/dist/assets/static/media/Roboto-700italic.686da014.woff +0 -0
  363. package/dist/assets/static/media/Roboto-700italic.896656dc.ttf +0 -0
  364. package/dist/assets/static/media/Roboto-700italic.cacb9681.svg +0 -325
  365. package/dist/assets/static/media/Roboto-italic.09ed2f27.svg +0 -323
  366. package/dist/assets/static/media/Roboto-italic.c1421604.woff +0 -0
  367. package/dist/assets/static/media/Roboto-italic.c38ecad2.ttf +0 -0
  368. package/dist/assets/static/media/Roboto-italic.f7677a07.eot +0 -0
  369. package/dist/assets/static/media/Roboto-regular.5107f918.eot +0 -0
  370. package/dist/assets/static/media/Roboto-regular.6a307cf2.woff +0 -0
  371. package/dist/assets/static/media/Roboto-regular.81dc9b21.ttf +0 -0
  372. package/dist/assets/static/media/Roboto-regular.bcf2ba9e.svg +0 -308
  373. package/dist/config.js +0 -173
  374. package/dist/server/app.js +0 -79
  375. package/dist/server/bin/enforce-prerequisites.js +0 -55
  376. package/dist/server/bin/migrations/fix-is-admin-flag.js +0 -41
  377. package/dist/server/bin/migrations/per-user-rtorrent-instances.js +0 -67
  378. package/dist/server/bin/migrations/run.js +0 -10
  379. package/dist/server/bin/start.js +0 -18
  380. package/dist/server/bin/web-server.js +0 -94
  381. package/dist/server/config/passport.js +0 -32
  382. package/dist/server/constants/clientGatewayServiceEvents.js +0 -15
  383. package/dist/server/constants/diskUsageServiceEvents.js +0 -8
  384. package/dist/server/constants/fileListPropMap.js +0 -29
  385. package/dist/server/constants/historyServiceEvents.js +0 -18
  386. package/dist/server/constants/notificationServiceEvents.js +0 -8
  387. package/dist/server/constants/taxonomyServiceEvents.js +0 -8
  388. package/dist/server/constants/torrentListPropMap.js +0 -200
  389. package/dist/server/constants/torrentServiceEvents.js +0 -8
  390. package/dist/server/constants/transferSummaryPropMap.js +0 -28
  391. package/dist/server/middleware/appendUserServices.js +0 -10
  392. package/dist/server/middleware/booleanCoerce.js +0 -9
  393. package/dist/server/middleware/clientActivityStream.js +0 -124
  394. package/dist/server/middleware/eventStream.js +0 -25
  395. package/dist/server/middleware/requireAdmin.js +0 -8
  396. package/dist/server/models/ClientRequest.js +0 -310
  397. package/dist/server/models/Feed.js +0 -65
  398. package/dist/server/models/Filesystem.js +0 -44
  399. package/dist/server/models/HistoryEra.js +0 -168
  400. package/dist/server/models/ServerEvent.js +0 -27
  401. package/dist/server/models/TemporaryStorage.js +0 -20
  402. package/dist/server/models/Users.js +0 -160
  403. package/dist/server/models/client.js +0 -363
  404. package/dist/server/models/settings.js +0 -119
  405. package/dist/server/routes/api.js +0 -69
  406. package/dist/server/routes/auth.js +0 -184
  407. package/dist/server/routes/client.js +0 -101
  408. package/dist/server/services/BaseService.js +0 -24
  409. package/dist/server/services/clientGatewayService.js +0 -220
  410. package/dist/server/services/clientRequestManager.js +0 -76
  411. package/dist/server/services/diskUsageService.js +0 -133
  412. package/dist/server/services/feedService.js +0 -290
  413. package/dist/server/services/historyService.js +0 -181
  414. package/dist/server/services/index.js +0 -108
  415. package/dist/server/services/notificationService.js +0 -109
  416. package/dist/server/services/taxonomyService.js +0 -107
  417. package/dist/server/services/torrentService.js +0 -235
  418. package/dist/server/util/ajaxUtil.js +0 -19
  419. package/dist/server/util/clientResponseUtil.js +0 -99
  420. package/dist/server/util/fileUtil.js +0 -45
  421. package/dist/server/util/mediainfo.js +0 -34
  422. package/dist/server/util/methodCallUtil.js +0 -22
  423. package/dist/server/util/numberUtils.js +0 -7
  424. package/dist/server/util/rTorrentDeserializer.js +0 -104
  425. package/dist/server/util/rTorrentPropMap.js +0 -13
  426. package/dist/server/util/scgiUtil.js +0 -36
  427. package/dist/server/util/torrentFileUtil.js +0 -23
  428. package/dist/shared/config/paths.js +0 -41
  429. package/dist/shared/constants/clientSettingsMap.js +0 -53
  430. package/dist/shared/constants/diffActionTypes.js +0 -6
  431. package/dist/shared/constants/historySnapshotTypes.js +0 -11
  432. package/dist/shared/constants/serverEventTypes.js +0 -18
  433. package/dist/shared/constants/torrentFilePropsMap.js +0 -6
  434. package/dist/shared/constants/torrentPeerPropsMap.js +0 -32
  435. package/dist/shared/constants/torrentStatusMap.js +0 -17
  436. package/dist/shared/constants/torrentTrackerPropsMap.js +0 -6
  437. package/dist/shared/util/formatUtil.js +0 -33
  438. package/dist/shared/util/objectUtil.js +0 -56
  439. package/dist/shared/util/regEx.js +0 -7
  440. /package/dist/assets/{safari-pinned-tab.svg → icon.svg} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"static/js/179.43c61c39.chunk.js","mappings":"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","sources":["client/src/javascript/util/userPreferences.ts","client/src/javascript/components/modals/ModalActions.tsx","client/src/javascript/components/modals/add-torrents-modal/AddTorrentsActions.tsx","client/src/javascript/components/general/filesystem/FilesystemBrowser.tsx","client/src/javascript/components/general/form-elements/FilesystemBrowserTextbox.tsx","client/src/javascript/components/general/form-elements/TagSelect.tsx","client/src/javascript/components/general/form-elements/TextboxRepeater.tsx","client/src/javascript/components/modals/add-torrents-modal/AddTorrentsByCreation.tsx","client/src/javascript/components/general/form-elements/FileDropzone.tsx","client/src/javascript/components/modals/add-torrents-modal/AddTorrentsByFile.tsx","client/src/javascript/components/modals/add-torrents-modal/AddTorrentsByURL.tsx","client/src/javascript/components/modals/ModalTabs.tsx","client/src/javascript/components/modals/Modal.tsx","client/src/javascript/components/modals/add-torrents-modal/AddTorrentsModal.tsx","client/src/javascript/components/modals/confirm-modal/ConfirmModal.tsx","client/src/javascript/stores/FeedStore.ts","client/src/javascript/actions/FeedActions.ts","shared/util/regEx.ts","client/src/javascript/util/validators.ts","client/src/javascript/components/modals/feeds-modal/DownloadRuleForm.tsx","client/src/javascript/components/modals/ModalFormSectionHeader.tsx","client/src/javascript/components/modals/feeds-modal/DownloadRuleList.tsx","client/src/javascript/components/modals/feeds-modal/DownloadRulesTab.tsx","client/src/javascript/components/modals/feeds-modal/FeedForm.tsx","client/src/javascript/components/modals/feeds-modal/FeedItems.tsx","client/src/javascript/components/modals/feeds-modal/FeedItemsForm.tsx","client/src/javascript/components/modals/feeds-modal/FeedList.tsx","client/src/javascript/components/modals/feeds-modal/FeedsTab.tsx","client/src/javascript/components/modals/feeds-modal/FeedsModal.tsx","shared/types/TorrentTracker.ts","client/src/javascript/components/modals/generate-magnet-modal/GenerateMagnetModal.tsx","client/src/javascript/components/modals/move-torrents-modal/MoveTorrentsModal.tsx","client/src/javascript/components/modals/remove-torrents-modal/RemoveTorrentsModal.tsx","client/src/javascript/components/modals/set-tags-modal/SetTagsModal.tsx","client/src/javascript/components/modals/set-trackers-modal/SetTrackersModal.tsx","client/src/javascript/components/modals/settings-modal/AboutTab.tsx","client/src/ABOUT.md","client/src/javascript/components/modals/settings-modal/AuthTab.tsx","client/src/javascript/components/modals/settings-modal/SettingsUtils.tsx","client/src/javascript/components/modals/settings-modal/BandwidthTab.tsx","client/src/javascript/components/modals/settings-modal/ConnectivityTab.tsx","client/src/javascript/components/general/SortableListItem.tsx","client/src/javascript/components/general/SortableList.tsx","client/src/javascript/components/modals/settings-modal/lists/MountPointsList.tsx","client/src/javascript/components/modals/settings-modal/DiskUsageTab.tsx","client/src/javascript/components/modals/settings-modal/ResourcesTab.tsx","client/src/javascript/components/general/ToggleList.tsx","client/src/javascript/components/modals/settings-modal/lists/MiscUISettingsList.tsx","client/src/javascript/components/modals/settings-modal/lists/TorrentContextMenuActionsList.tsx","client/src/javascript/components/modals/settings-modal/lists/TorrentListColumnsList.tsx","client/src/javascript/components/modals/settings-modal/UITab.tsx","client/src/javascript/components/modals/settings-modal/SettingsModal.tsx","client/src/javascript/components/modals/torrent-details-modal/TorrentMediainfo.tsx","client/src/javascript/util/selectionTree.ts","client/src/javascript/components/general/filesystem/DirectoryFileList.tsx","client/src/javascript/components/general/filesystem/DirectoryTreeNode.tsx","client/src/javascript/components/general/filesystem/DirectoryTree.tsx","client/src/javascript/components/modals/torrent-details-modal/TorrentContents.tsx","client/src/javascript/components/general/LinkedText.tsx","client/src/javascript/components/modals/torrent-details-modal/TorrentGeneralInfo.tsx","client/src/javascript/components/modals/torrent-details-modal/TorrentHeading.tsx","client/src/javascript/components/modals/torrent-details-modal/TorrentPeers.tsx","client/src/javascript/components/modals/torrent-details-modal/TorrentTrackers.tsx","client/src/javascript/components/modals/torrent-details-modal/TorrentDetailsModal.tsx","client/src/javascript/components/modals/Modals.tsx"],"sourcesContent":["import SettingActions from '@client/actions/SettingActions';\nimport SettingStore from '@client/stores/SettingStore';\n\nimport type {FloodSettings} from '@shared/types/FloodSettings';\nimport type {TorrentProperties} from '@shared/types/Torrent';\n\nexport const saveAddTorrentsUserPreferences = ({\n start,\n destination,\n tags,\n tab,\n}: {\n start?: FloodSettings['startTorrentsOnLoad'];\n destination?: string;\n tags?: TorrentProperties['tags'];\n tab?: FloodSettings['UITorrentsAddTab'];\n}): void => {\n const changedSettings: Partial<FloodSettings> = {};\n\n if (start != null) {\n changedSettings.startTorrentsOnLoad = start;\n }\n\n if (destination != null && destination !== '') {\n if (changedSettings.torrentDestinations == null) {\n changedSettings.torrentDestinations = SettingStore.floodSettings.torrentDestinations || {};\n }\n\n if (typeof tags?.[0] === 'string') {\n changedSettings.torrentDestinations[tags[0]] = destination;\n } else {\n changedSettings.torrentDestinations[''] = destination;\n }\n }\n\n if (tab != null) {\n changedSettings.UITorrentsAddTab = tab;\n }\n\n SettingActions.saveSettings(changedSettings);\n};\n\nexport const saveDeleteTorrentsUserPreferences = ({deleteData}: {deleteData?: boolean}): void => {\n if (deleteData != null) {\n SettingActions.saveSetting('deleteTorrentData', deleteData);\n }\n};\n","import {FC} from 'react';\n\nimport {Button, Checkbox} from '@client/ui';\nimport UIStore from '@client/stores/UIStore';\n\nimport type {ModalAction} from '@client/stores/UIStore';\n\ninterface ModalActionsProps {\n actions: Array<ModalAction>;\n}\n\nconst ModalActions: FC<ModalActionsProps> = (props: ModalActionsProps) => {\n const {actions} = props;\n\n const buttons = actions.map((action, index) => {\n let dismissIfNeeded = () => {\n // do nothing by default.\n };\n\n if (action.triggerDismiss) {\n dismissIfNeeded = () => {\n UIStore.setActiveModal(null);\n };\n }\n\n if (action.type === 'checkbox') {\n return (\n <Checkbox\n defaultChecked={action.checked}\n id={action.id}\n key={index}\n onClick={(event) => {\n if (action.clickHandler != null) {\n action.clickHandler(event);\n }\n dismissIfNeeded();\n }}\n >\n {action.content}\n </Checkbox>\n );\n }\n\n return (\n <Button\n isLoading={action.isLoading}\n onClick={(event) => {\n if (action.clickHandler != null) {\n action.clickHandler(event);\n }\n dismissIfNeeded();\n }}\n priority={action.type}\n key={index}\n type={action.submit ? 'submit' : 'button'}\n >\n {action.content}\n </Button>\n );\n });\n\n const buttonsGroup = <div className=\"modal__button-group\">{buttons}</div>;\n\n return <div className=\"modal__actions\">{buttonsGroup}</div>;\n};\n\nexport default ModalActions;\n","import React, {FC} from 'react';\nimport {useLingui} from '@lingui/react';\n\nimport ModalActions from '../ModalActions';\nimport SettingStore from '../../../stores/SettingStore';\n\ninterface AddTorrentsActionsProps {\n isAddingTorrents: boolean;\n onAddTorrentsClick: (event: React.MouseEvent<HTMLButtonElement>) => void;\n}\n\nconst AddTorrentsActions: FC<AddTorrentsActionsProps> = ({\n isAddingTorrents,\n onAddTorrentsClick,\n}: AddTorrentsActionsProps) => {\n const {i18n} = useLingui();\n return (\n <ModalActions\n actions={[\n {\n checked: Boolean(SettingStore.floodSettings.startTorrentsOnLoad),\n clickHandler: null,\n content: i18n._('torrents.add.start.label'),\n id: 'start',\n triggerDismiss: false,\n type: 'checkbox',\n },\n {\n clickHandler: null,\n content: i18n._('button.cancel'),\n triggerDismiss: true,\n type: 'tertiary',\n },\n {\n clickHandler: onAddTorrentsClick,\n content: i18n._('torrents.add.button.add'),\n isLoading: isAddingTorrents,\n submit: true,\n triggerDismiss: false,\n type: 'primary',\n },\n ]}\n />\n );\n};\n\nexport default AddTorrentsActions;\n","import {css} from '@client/styled-system/css';\nimport {FC, memo, ReactNodeArray, useEffect, useRef, useState} from 'react';\nimport {sort} from 'fast-sort';\nimport {Trans} from '@lingui/react';\nimport {useKey} from 'react-use';\n\nimport {Arrow, File, FolderClosedOutlined, FolderClosedSolid, FolderOpenSolid} from '@client/ui/icons';\nimport FloodActions from '@client/actions/FloodActions';\nimport termMatch from '@client/util/termMatch';\n\nconst foregroundColor = '#5E728C';\nconst borderColor = '#dde2e8'; // lighten(0.43, foregroundColor)\nconst hoverColor = '#374c66'; // saturate(0.1, darken(0.15, foregroundColor))\nconst hoverBackground = 'rgba(94, 114, 140, 0.1)'; // rgba(foregroundColor, 0.1)\n\nconst itemPaddingStyle = css.raw({padding: '3px 9px'});\n\nconst headerStyle = css.raw({\n borderBottom: `1px solid ${borderColor}`,\n marginBottom: '3px',\n paddingBottom: '3px',\n opacity: 0.75,\n _last: {\n marginBottom: 0,\n },\n});\n\nconst baseListItemStyle = css.raw({\n transition: 'color 0.25s',\n whiteSpace: 'nowrap',\n '& button': {\n width: '100%',\n height: '100%',\n textAlign: 'left',\n _disabled: {\n pointerEvents: 'none',\n },\n ...itemPaddingStyle,\n },\n});\n\nconst listItemStyle = css({\n opacity: 0.5,\n ...baseListItemStyle,\n});\n\nconst listItemSelectableActiveStyle = css.raw({\n color: hoverColor,\n background: hoverBackground,\n '& button:focus': {\n outline: 'none',\n WebkitTapHighlightColor: 'transparent',\n },\n});\n\nconst listItemSelectableStyle = css({\n opacity: 1,\n cursor: 'pointer',\n transition: 'background 0.25s, color 0.25s',\n userSelect: 'none',\n _hover: listItemSelectableActiveStyle,\n _focusWithin: listItemSelectableActiveStyle,\n ...baseListItemStyle,\n});\n\nconst MESSAGES = {\n EACCES: 'filesystem.error.eacces',\n ENOENT: 'filesystem.error.enoent',\n};\n\ninterface FilesystemBrowserProps {\n selectable?: 'files' | 'directories';\n directory: string;\n onItemSelection?: (newDestination: string, shouldKeepOpen?: boolean) => void;\n onYieldFocus?: () => void;\n}\n\nconst FilesystemBrowser: FC<FilesystemBrowserProps> = memo(\n ({directory, selectable, onItemSelection, onYieldFocus}: FilesystemBrowserProps) => {\n const [cursor, setCursor] = useState<number | null>(null);\n const [errorResponse, setErrorResponse] = useState<{data?: NodeJS.ErrnoException} | null>(null);\n const [separator, setSeparator] = useState<string>(directory.includes('/') ? '/' : '\\\\');\n const [directories, setDirectories] = useState<string[] | null>(null);\n const [files, setFiles] = useState<string[] | null>(null);\n\n const listRef = useRef<HTMLUListElement>(null);\n\n const lastSegmentIndex = directory.lastIndexOf(separator) + 1;\n const currentDirectory = lastSegmentIndex > 0 ? directory.substr(0, lastSegmentIndex) : directory;\n const lastSegment = directory.substr(lastSegmentIndex);\n\n useEffect(() => {\n if (!currentDirectory) {\n return;\n }\n\n setCursor(null);\n setDirectories(null);\n setFiles(null);\n\n FloodActions.fetchDirectoryList(currentDirectory)\n .then(({files: fetchedFiles, directories: fetchedDirectories, separator: fetchedSeparator}) => {\n setDirectories(fetchedDirectories);\n setFiles(fetchedFiles);\n setSeparator(fetchedSeparator);\n setErrorResponse(null);\n })\n .catch(({response}) => {\n setErrorResponse(response);\n });\n }, [currentDirectory]);\n\n useEffect(() => {\n if (listRef.current != null && cursor != null) {\n const element = (listRef.current.children[cursor] as HTMLLIElement)?.children[0] as HTMLDivElement;\n if (element?.tabIndex === 0) {\n element.focus();\n } else {\n setCursor(\n Array.from(listRef.current.children).findIndex((e) => (e.children[0] as HTMLDivElement).tabIndex === 0),\n );\n }\n }\n }, [cursor]);\n\n useKey('ArrowUp', (e) => {\n e.preventDefault();\n setCursor((prevCursor) => {\n if (prevCursor == null || prevCursor - 1 < 0) {\n onYieldFocus?.();\n return null;\n }\n\n return prevCursor - 1;\n });\n });\n\n useKey('ArrowDown', (e) => {\n e.preventDefault();\n setCursor((prevCursor) => {\n if (prevCursor != null) {\n return prevCursor + 1;\n }\n return 0;\n });\n });\n\n let errorMessage: string | null = null;\n let listItems: ReactNodeArray = [];\n\n if ((directories == null && selectable === 'directories') || (files == null && selectable === 'files')) {\n errorMessage = 'filesystem.fetching';\n }\n\n if (errorResponse && errorResponse.data && errorResponse.data.code) {\n errorMessage = MESSAGES[errorResponse.data.code as keyof typeof MESSAGES] || 'filesystem.error.unknown';\n }\n\n if (!directory) {\n errorMessage = 'filesystem.error.no.input';\n } else {\n const parentDirectory = `${currentDirectory.split(separator).slice(0, -2).join(separator)}${separator}`;\n const parentDirectoryElement = (\n <li\n className={`${listItemSelectableStyle} ${css({\n '@media (max-width: 720px)': headerStyle,\n })}`}\n key={parentDirectory}\n >\n <button type=\"button\" onClick={() => onItemSelection?.(parentDirectory, true)}>\n <Arrow className={css({transform: 'scale(0.75) rotate(180deg)'})} />\n ..\n </button>\n </li>\n );\n\n const isDirectorySelectable = selectable !== 'files';\n const directoryMatched = lastSegment ? termMatch(directories, (subDirectory) => subDirectory, lastSegment) : [];\n\n const inputDirectoryElement =\n !directoryMatched.includes(lastSegment) && selectable === 'directories' && lastSegment && !errorMessage\n ? (() => {\n const inputDestination = `${currentDirectory}${lastSegment}${separator}`;\n return [\n <li\n className={`${listItemSelectableStyle} ${css({\n '@media (max-width: 720px)': {display: 'none'},\n })}`}\n style={{fontWeight: 'bold'}}\n key={inputDestination}\n >\n <button type=\"button\" onClick={() => onItemSelection?.(inputDestination, false)}>\n <FolderClosedOutlined />\n <span style={{whiteSpace: 'pre-wrap'}}>{lastSegment}</span>\n <em style={{fontWeight: 'lighter'}}>\n {' - '}\n <Trans id=\"filesystem.error.enoent\" />\n </em>\n </button>\n </li>,\n ];\n })()\n : [];\n\n const directoryList: ReactNodeArray =\n (directories?.length &&\n sort(directories.slice())\n .desc((subDirectory) => directoryMatched.includes(subDirectory))\n .map((subDirectory) => {\n const destination = `${currentDirectory}${subDirectory}${separator}`;\n return (\n <li\n className={isDirectorySelectable ? listItemSelectableStyle : listItemStyle}\n style={directoryMatched.includes(subDirectory) ? {fontWeight: 'bold'} : undefined}\n key={destination}\n >\n <button\n type=\"button\"\n disabled={!isDirectorySelectable}\n tabIndex={isDirectorySelectable ? 0 : -1}\n onClick={isDirectorySelectable ? () => onItemSelection?.(destination, true) : undefined}\n >\n <FolderClosedSolid />\n {subDirectory}\n </button>\n </li>\n );\n })) ||\n [];\n\n const isFileSelectable = selectable !== 'directories';\n const fileMatched = lastSegment ? termMatch(files, (file) => file, lastSegment) : [];\n const fileList: ReactNodeArray =\n (files?.length &&\n sort(files.slice())\n .desc((file) => fileMatched.includes(file))\n .map((file) => {\n const destination = `${currentDirectory}${file}`;\n return (\n <li\n className={isFileSelectable ? listItemSelectableStyle : listItemStyle}\n style={fileMatched.includes(file) ? {fontWeight: 'bold'} : undefined}\n key={destination}\n >\n <button\n type=\"button\"\n disabled={!isFileSelectable}\n tabIndex={isFileSelectable ? 0 : -1}\n onClick={isFileSelectable ? () => onItemSelection?.(destination, false) : undefined}\n >\n <File />\n {file}\n </button>\n </li>\n );\n })) ||\n [];\n\n if (directoryList.length === 0 && fileList.length === 0 && !errorMessage) {\n errorMessage = 'filesystem.empty.directory';\n }\n\n listItems = [parentDirectoryElement, ...inputDirectoryElement, ...directoryList, ...fileList];\n }\n\n return (\n <div\n className={css({\n color: foregroundColor,\n listStyle: 'none',\n padding: '3px 0px',\n '& .icon': {\n fill: 'currentColor',\n height: '14px',\n width: '14px',\n marginRight: '5px',\n marginTop: '-3px',\n verticalAlign: 'middle',\n },\n })}\n >\n {currentDirectory && (\n <li\n className={`${listItemStyle} ${css(headerStyle, itemPaddingStyle, {\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-all',\n '& .icon': {\n transform: 'scale(0.9)',\n marginTop: '-2px !important',\n },\n '@media (max-width: 720px)': {\n display: 'none',\n },\n })}`}\n >\n <FolderOpenSolid />\n {currentDirectory}\n </li>\n )}\n <ul ref={listRef}>{listItems}</ul>\n {errorMessage && (\n <div className={`${listItemStyle} ${css(itemPaddingStyle)}`} style={{opacity: 1}}>\n <em>\n <Trans id={errorMessage} />\n </em>\n </div>\n )}\n </div>\n );\n },\n);\n\nexport default FilesystemBrowser;\n","import debounce from 'lodash/debounce';\nimport {forwardRef, MutableRefObject, ReactElement, ReactNode, useEffect, useRef, useState} from 'react';\nimport {Trans, useLingui} from '@lingui/react';\nimport {useEnsuredForwardedRef} from 'react-use';\n\nimport {Checkbox, ContextMenu, FormElementAddon, FormRow, FormRowGroup, Portal, Textbox} from '@client/ui';\nimport {Search} from '@client/ui/icons';\nimport SettingStore from '@client/stores/SettingStore';\n\nimport FilesystemBrowser from '../filesystem/FilesystemBrowser';\n\ninterface FilesystemBrowserTextboxProps {\n id: string;\n label?: ReactNode;\n selectable?: 'directories' | 'files';\n suggested?: string;\n showBasePathToggle?: boolean;\n showCompletedToggle?: boolean;\n showSequentialToggle?: boolean;\n onChange?: (destination: string) => void;\n}\n\nconst FilesystemBrowserTextbox = forwardRef<HTMLInputElement, FilesystemBrowserTextboxProps>(\n (\n {\n id,\n label,\n selectable,\n suggested,\n showBasePathToggle = false,\n showCompletedToggle = false,\n showSequentialToggle = false,\n onChange,\n }: FilesystemBrowserTextboxProps,\n ref,\n ) => {\n const [destination, setDestination] = useState<string>(\n suggested ||\n SettingStore.floodSettings.torrentDestinations?.[''] ||\n SettingStore.clientSettings?.directoryDefault ||\n '',\n );\n const [isDirectoryListOpen, setIsDirectoryListOpen] = useState<boolean>(false);\n\n const formRowRef = useRef<HTMLDivElement>(null);\n const textboxRef = useEnsuredForwardedRef(ref as MutableRefObject<HTMLInputElement>);\n\n const {i18n} = useLingui();\n\n useEffect(() => {\n const closeDirectoryList = (): void => {\n setIsDirectoryListOpen(false);\n };\n\n const handleDocumentClick = (e: Event): void => {\n if (!formRowRef.current?.contains(e.target as unknown as Node)) {\n closeDirectoryList();\n }\n };\n\n document.addEventListener('click', handleDocumentClick);\n window.addEventListener('resize', closeDirectoryList);\n\n return () => {\n document.removeEventListener('click', handleDocumentClick);\n window.removeEventListener('resize', closeDirectoryList);\n };\n }, []);\n\n const toggles: Array<ReactElement> = [];\n if (showBasePathToggle) {\n toggles.push(\n <Checkbox grow={false} id=\"isBasePath\" key=\"isBasePath\">\n <Trans id=\"torrents.destination.base_path\" />\n </Checkbox>,\n );\n }\n if (showCompletedToggle) {\n toggles.push(\n <Checkbox grow={false} id=\"isCompleted\" key=\"isCompleted\">\n <Trans id=\"torrents.destination.completed\" />\n </Checkbox>,\n );\n }\n if (showSequentialToggle) {\n // TODO: this is getting bloated. toggles can be moved to their own elements...\n toggles.push(\n <Checkbox grow={false} id=\"isSequential\" key=\"isSequential\">\n <Trans id=\"torrents.destination.sequential\" />\n </Checkbox>,\n );\n }\n\n return (\n <FormRowGroup ref={formRowRef}>\n <FormRow>\n <Textbox\n autoComplete={isDirectoryListOpen ? 'off' : undefined}\n addonPlacement=\"after\"\n defaultValue={destination}\n id={id}\n label={label}\n onChange={debounce(\n () => {\n if (textboxRef.current == null) {\n return;\n }\n\n const newDestination = textboxRef.current.value;\n\n if (onChange) {\n onChange(newDestination);\n }\n\n setDestination(newDestination);\n },\n 100,\n {leading: true},\n )}\n onClick={(event) => event.nativeEvent.stopImmediatePropagation()}\n placeholder={i18n._('torrents.add.destination.placeholder')}\n ref={textboxRef}\n >\n <FormElementAddon\n onClick={() => {\n if (textboxRef.current != null) {\n setDestination(textboxRef.current.value);\n }\n setIsDirectoryListOpen(!isDirectoryListOpen);\n }}\n >\n <Search />\n </FormElementAddon>\n <Portal>\n <ContextMenu\n isIn={isDirectoryListOpen}\n onClick={(event) => event.nativeEvent.stopImmediatePropagation()}\n overlayProps={{isInteractive: false}}\n padding={false}\n triggerRef={textboxRef}\n >\n <FilesystemBrowser\n directory={destination}\n selectable={selectable}\n onItemSelection={(newDestination: string, shouldKeepOpen = true) => {\n if (textboxRef.current != null) {\n textboxRef.current.value = newDestination;\n }\n\n setIsDirectoryListOpen(shouldKeepOpen);\n setDestination(newDestination);\n }}\n onYieldFocus={() => {\n textboxRef.current?.focus();\n }}\n />\n </ContextMenu>\n </Portal>\n </Textbox>\n </FormRow>\n {toggles.length > 0 ? <FormRow>{toggles}</FormRow> : null}\n </FormRowGroup>\n );\n },\n);\n\nexport default FilesystemBrowserTextbox;\n","import classnames from 'classnames';\nimport {FC, ReactElement, ReactNode, useEffect, useRef, useState} from 'react';\nimport {sort} from 'fast-sort';\nimport {Trans} from '@lingui/react';\nimport {useKeyPressEvent} from 'react-use';\n\nimport {ContextMenu, FormElementAddon, FormRowItem, Portal, SelectItem, Textbox} from '@client/ui';\nimport {Chevron} from '@client/ui/icons';\nimport SettingStore from '@client/stores/SettingStore';\nimport TorrentFilterStore from '@client/stores/TorrentFilterStore';\n\nimport type {TorrentProperties} from '@shared/types/Torrent';\n\ninterface TagSelectProps {\n id?: string;\n label?: ReactNode;\n defaultValue?: TorrentProperties['tags'];\n placeholder?: string;\n onTagSelected?: (tags: TorrentProperties['tags']) => void;\n}\n\nconst TagSelect: FC<TagSelectProps> = ({\n defaultValue,\n placeholder,\n id = 'tags',\n label,\n onTagSelected,\n}: TagSelectProps) => {\n const [isOpen, setIsOpen] = useState<boolean>(false);\n const [selectedTags, setSelectedTags] = useState<Array<string>>(defaultValue ?? []);\n const formRowRef = useRef<HTMLDivElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n const textboxRef = useRef<HTMLInputElement>(null);\n\n const classes = classnames('select form__element', {\n 'select--is-open': isOpen,\n });\n\n useKeyPressEvent('Escape', (e) => {\n e.preventDefault();\n setIsOpen(false);\n });\n\n useEffect(() => {\n const handleDocumentClick = (e: Event) => {\n if (!formRowRef.current?.contains(e.target as unknown as Node)) {\n setIsOpen(false);\n }\n };\n\n document.addEventListener('click', handleDocumentClick);\n\n return () => {\n document.removeEventListener('click', handleDocumentClick);\n };\n }, []);\n\n useEffect(() => {\n if (textboxRef.current != null) {\n textboxRef.current.value = selectedTags.join();\n }\n if (onTagSelected) {\n onTagSelected(selectedTags);\n }\n }, [selectedTags, onTagSelected]);\n\n return (\n <FormRowItem ref={formRowRef}>\n <div className={classes}>\n <Textbox\n autoComplete={isOpen ? 'off' : undefined}\n id={id || 'tags'}\n addonPlacement=\"after\"\n defaultValue={defaultValue}\n label={label}\n onChange={() => {\n if (textboxRef.current != null) {\n let selectedTagsArray = textboxRef.current.value\n .split(',')\n .map((tag) => tag.trim())\n .filter((tag) => tag.length > 0);\n\n if (textboxRef.current.value.trimEnd().endsWith(',')) {\n // Ensures that the trailing ',' does not get removed automatically.\n selectedTagsArray.push('');\n\n // Deduplicate\n selectedTagsArray = [...new Set(selectedTagsArray)];\n }\n\n setSelectedTags(selectedTagsArray);\n }\n }}\n placeholder={placeholder}\n ref={textboxRef}\n >\n <FormElementAddon\n onClick={() => {\n setIsOpen(!isOpen);\n }}\n className=\"select__indicator\"\n >\n <Chevron />\n </FormElementAddon>\n <Portal>\n <ContextMenu\n isIn={isOpen}\n onClick={(event) => {\n if (SettingStore.floodSettings.UITagSelectorMode !== 'single') {\n event.nativeEvent.stopImmediatePropagation();\n }\n }}\n overlayProps={{isInteractive: false}}\n ref={menuRef}\n triggerRef={textboxRef}\n >\n {[\n ...new Set([\n 'untagged',\n ...sort(Object.keys(TorrentFilterStore.taxonomy.tagCounts)).asc(),\n ...selectedTags,\n ]),\n ].reduce((accumulator: Array<ReactElement>, tag) => {\n if (tag === '') {\n return accumulator;\n }\n\n accumulator.push(\n <SelectItem\n id={tag}\n key={tag}\n isSelected={selectedTags.includes(tag)}\n onClick={() => {\n if (tag === 'untagged') {\n setSelectedTags([]);\n } else if (selectedTags.includes(tag)) {\n setSelectedTags(selectedTags.filter((key) => key !== tag && key !== ''));\n } else {\n setSelectedTags([...selectedTags.filter((key) => key !== ''), tag]);\n }\n }}\n >\n {tag === 'untagged' ? <Trans id=\"filter.untagged\" /> : tag}\n </SelectItem>,\n );\n return accumulator;\n }, [])}\n </ContextMenu>\n </Portal>\n </Textbox>\n </div>\n </FormRowItem>\n );\n};\n\nexport default TagSelect;\n","import {FC, ReactNode, useRef, useState} from 'react';\n\nimport {AddMini, RemoveMini} from '@client/ui/icons';\nimport {FormElementAddon, FormRow, FormRowGroup, Textbox} from '@client/ui';\n\nexport const getTextArray = (formData: Record<string, string | undefined>, id: string): string[] =>\n Object.keys(formData).reduce((accumulator: Array<string>, formItemKey: string) => {\n if (formItemKey.startsWith(id)) {\n const text = formData[formItemKey];\n if (text != null) {\n accumulator.push(text);\n }\n }\n return accumulator;\n }, []);\n\ntype Textboxes = Array<{id: number; value: string}>;\n\ninterface TextboxRepeaterProps {\n defaultValues?: Textboxes;\n id: number | string;\n label?: ReactNode;\n placeholder?: string;\n}\n\nconst TextboxRepeater: FC<TextboxRepeaterProps> = ({defaultValues, id, label, placeholder}: TextboxRepeaterProps) => {\n const idCounter = useRef<number>(0);\n const [textboxes, setTextboxes] = useState<Textboxes>(defaultValues ?? [{id: 0, value: ''}]);\n\n return (\n <FormRowGroup>\n {textboxes.map((textbox, index) => {\n let removeButton = null;\n\n if (index > 0) {\n removeButton = (\n <FormElementAddon\n onClick={() => {\n const newTextboxes = textboxes.slice();\n newTextboxes.splice(index, 1);\n setTextboxes(newTextboxes);\n }}\n >\n <RemoveMini />\n </FormElementAddon>\n );\n }\n\n return (\n <FormRow key={textbox.id}>\n <Textbox\n addonPlacement=\"after\"\n id={`${id}-${textbox.id}`}\n defaultValue={textbox.value}\n label={index === 0 && label}\n placeholder={placeholder}\n wrapperClassName=\"textbox-repeater\"\n >\n <FormElementAddon\n onClick={() => {\n idCounter.current += 1;\n\n const newTextboxes = textboxes.slice();\n newTextboxes.splice(index + 1, 0, {\n id: idCounter.current,\n value: '',\n });\n setTextboxes(newTextboxes);\n }}\n >\n <AddMini />\n </FormElementAddon>\n {removeButton}\n </Textbox>\n </FormRow>\n );\n })}\n </FormRowGroup>\n );\n};\n\nexport default TextboxRepeater;\n","import {FC, useRef, useState} from 'react';\nimport {useLingui} from '@lingui/react';\n\nimport {Checkbox, Form, FormHandle, FormRow, Textbox} from '@client/ui';\nimport {saveAddTorrentsUserPreferences} from '@client/util/userPreferences';\nimport TorrentActions from '@client/actions/TorrentActions';\nimport UIStore from '@client/stores/UIStore';\n\nimport AddTorrentsActions from './AddTorrentsActions';\nimport FilesystemBrowserTextbox from '../../general/form-elements/FilesystemBrowserTextbox';\nimport TagSelect from '../../general/form-elements/TagSelect';\nimport TextboxRepeater, {getTextArray} from '../../general/form-elements/TextboxRepeater';\n\ntype AddTorrentsByCreationFormData = {\n [trackers: string]: string;\n} & {\n name: string;\n sourcePath: string;\n comment: string;\n infoSource: string;\n isPrivate: boolean;\n start: boolean;\n tags: string;\n};\n\nconst AddTorrentsByCreation: FC = () => {\n const formRef = useRef<FormHandle>(null);\n const {i18n} = useLingui();\n const [isCreatingTorrents, setIsCreatingTorrents] = useState<boolean>(false);\n\n return (\n <Form className=\"inverse\" ref={formRef}>\n <FilesystemBrowserTextbox id=\"sourcePath\" label={i18n._('torrents.create.source.path.label')} />\n <TextboxRepeater\n id=\"trackers\"\n label={i18n._('torrents.create.trackers.label')}\n placeholder={i18n._('torrents.create.tracker.input.placeholder')}\n defaultValues={[{id: 0, value: ''}]}\n />\n <FormRow>\n <Textbox\n id=\"name\"\n label={i18n._('torrents.create.base.name.label')}\n placeholder={i18n._('torrents.create.base.name.input.placeholder')}\n />\n </FormRow>\n <FormRow>\n <Textbox\n id=\"comment\"\n label={i18n._('torrents.create.comment.label')}\n placeholder={i18n._('torrents.create.comment.input.placeholder')}\n />\n </FormRow>\n <FormRow>\n <Textbox\n id=\"infoSource\"\n label={i18n._('torrents.create.info.source.label')}\n placeholder={i18n._('torrents.create.info.source.input.placeholder')}\n />\n </FormRow>\n <FormRow>\n <Checkbox grow={false} id=\"isPrivate\">\n {i18n._('torrents.create.is.private.label')}\n </Checkbox>\n </FormRow>\n <FormRow>\n <TagSelect\n id=\"tags\"\n label={i18n._('torrents.add.tags')}\n placeholder={i18n._('torrents.create.tags.input.placeholder')}\n />\n </FormRow>\n <AddTorrentsActions\n onAddTorrentsClick={() => {\n if (formRef.current == null) {\n return;\n }\n\n const formData = formRef.current.getFormData() as Partial<AddTorrentsByCreationFormData>;\n setIsCreatingTorrents(true);\n\n if (formData.sourcePath == null) {\n return;\n }\n\n TorrentActions.createTorrent({\n name: formData.name,\n sourcePath: formData.sourcePath,\n trackers: getTextArray(formData, 'trackers'),\n comment: formData.comment,\n infoSource: formData.infoSource,\n isPrivate: formData.isPrivate || false,\n start: formData.start || false,\n tags: formData.tags != null ? formData.tags.split(',') : undefined,\n }).then(() => {\n UIStore.setActiveModal(null);\n });\n\n saveAddTorrentsUserPreferences({\n start: formData.start,\n destination: formData.sourcePath,\n tab: 'by-creation',\n });\n }}\n isAddingTorrents={isCreatingTorrents}\n />\n </Form>\n );\n};\n\nexport default AddTorrentsByCreation;\n","import Dropzone from 'react-dropzone';\nimport {FC, useEffect, useState} from 'react';\nimport {Trans} from '@lingui/react';\n\nimport {Close, File, Files} from '@client/ui/icons';\nimport {FormRowItem} from '@client/ui';\n\nexport type ProcessedFiles = Array<{name: string; data: string}>;\n\ninterface FileDropzoneProps {\n initialFiles?: ProcessedFiles;\n onFilesChanged: (files: ProcessedFiles) => void;\n}\n\nconst FileDropzone: FC<FileDropzoneProps> = ({initialFiles, onFilesChanged}: FileDropzoneProps) => {\n const [files, setFiles] = useState<ProcessedFiles>(initialFiles ?? []);\n\n useEffect(() => {\n onFilesChanged(files);\n }, [files, onFilesChanged]);\n\n return (\n <FormRowItem>\n <span className=\"form__element__label\">\n <Trans id=\"torrents.add.torrents.label\" />\n </span>\n {files.length > 0 ? (\n <div\n onClick={(event) => {\n event.stopPropagation();\n }}\n role=\"none\"\n >\n <ul className=\"dropzone__selected-files interactive-list\">\n {files.map((file, index) => (\n <li className=\"dropzone__selected-files__file interactive-list__item\" key={file.name} title={file.name}>\n <span className=\"interactive-list__icon\">\n <File />\n </span>\n <span className=\"interactive-list__label\">{file.name}</span>\n <button\n className=\"interactive-list__icon interactive-list__icon--action interactive-list__icon--action--warning\"\n type=\"button\"\n onClick={() => {\n const newArray = files.slice();\n newArray.splice(index, 1);\n setFiles(newArray);\n }}\n >\n <Close />\n </button>\n </li>\n ))}\n </ul>\n </div>\n ) : null}\n <Dropzone\n onDrop={(addedFiles: Array<File>) => {\n const processedFiles: ProcessedFiles = [];\n addedFiles.forEach((file) => {\n const reader = new FileReader();\n reader.onload = (e) => {\n if (e.target?.result != null && typeof e.target.result === 'string') {\n processedFiles.push({\n name: file.name,\n data: e.target.result.split('base64,')[1],\n });\n }\n if (processedFiles.length === addedFiles.length) {\n setFiles(files.concat(processedFiles));\n }\n };\n reader.readAsDataURL(file);\n });\n }}\n >\n {({getRootProps, getInputProps, isDragActive}) => (\n <div\n {...getRootProps()}\n className={`form__dropzone dropzone interactive-list ${isDragActive ? 'dropzone--is-dragging' : ''}`}\n >\n <input {...getInputProps()} />\n <div className=\"dropzone__copy\">\n <div className=\"dropzone__icon\">\n <Files />\n </div>\n <Trans id=\"torrents.add.tab.file.drop\" />{' '}\n <span className=\"dropzone__browse-button\">\n <Trans id=\"torrents.add.tab.file.browse\" />\n </span>\n .\n </div>\n </div>\n )}\n </Dropzone>\n </FormRowItem>\n );\n};\n\nexport default FileDropzone;\n","import {FC, useRef, useState} from 'react';\nimport {useLingui} from '@lingui/react';\n\nimport {Form, FormHandle, FormRow} from '@client/ui';\nimport {saveAddTorrentsUserPreferences} from '@client/util/userPreferences';\nimport SettingStore from '@client/stores/SettingStore';\nimport TorrentActions from '@client/actions/TorrentActions';\nimport UIStore from '@client/stores/UIStore';\n\nimport AddTorrentsActions from './AddTorrentsActions';\nimport FileDropzone from '../../general/form-elements/FileDropzone';\nimport FilesystemBrowserTextbox from '../../general/form-elements/FilesystemBrowserTextbox';\nimport TagSelect from '../../general/form-elements/TagSelect';\n\nimport type {ProcessedFiles} from '../../general/form-elements/FileDropzone';\n\ninterface AddTorrentsByFileFormData {\n destination: string;\n start: boolean;\n tags: string;\n isBasePath: boolean;\n isCompleted: boolean;\n isSequential: boolean;\n}\n\nconst AddTorrentsByFile: FC = () => {\n const filesRef = useRef<ProcessedFiles>([]);\n const formRef = useRef<FormHandle>(null);\n const textboxRef = useRef<HTMLInputElement>(null);\n const [isAddingTorrents, setIsAddingTorrents] = useState<boolean>(false);\n\n const {i18n} = useLingui();\n\n return (\n <Form className=\"inverse\" ref={formRef}>\n <FormRow>\n <FileDropzone\n initialFiles={\n (UIStore.activeModal?.id === 'add-torrents' &&\n UIStore.activeModal?.tab === 'by-file' &&\n UIStore.activeModal?.files) ||\n []\n }\n onFilesChanged={(files) => {\n filesRef.current = files;\n }}\n />\n </FormRow>\n <FormRow>\n <TagSelect\n label={i18n._('torrents.add.tags')}\n id=\"tags\"\n onTagSelected={(tags) => {\n if (textboxRef.current != null) {\n const suggestedPath = SettingStore.floodSettings.torrentDestinations?.[tags[0]];\n if (typeof suggestedPath === 'string' && textboxRef.current != null) {\n textboxRef.current.value = suggestedPath;\n textboxRef.current.dispatchEvent(new Event('input', {bubbles: true}));\n }\n }\n }}\n />\n </FormRow>\n <FilesystemBrowserTextbox\n id=\"destination\"\n label={i18n._('torrents.add.destination.label')}\n ref={textboxRef}\n selectable=\"directories\"\n showBasePathToggle\n showCompletedToggle\n showSequentialToggle\n />\n <AddTorrentsActions\n onAddTorrentsClick={() => {\n if (formRef.current == null) {\n return;\n }\n\n const formData = formRef.current?.getFormData();\n setIsAddingTorrents(true);\n\n const {destination, start, tags, isBasePath, isCompleted, isSequential} =\n formData as Partial<AddTorrentsByFileFormData>;\n\n const filesData: Array<string> = [];\n filesRef.current.forEach((file) => {\n filesData.push(file.data);\n });\n\n if (filesData.length === 0 || destination == null) {\n setIsAddingTorrents(false);\n return;\n }\n\n const tagsArray = tags != null ? tags.split(',').filter((tag) => tag.length > 0) : undefined;\n\n TorrentActions.addTorrentsByFiles({\n files: filesData as [string, ...string[]],\n destination,\n tags: tagsArray,\n isBasePath,\n isCompleted,\n isSequential,\n start,\n }).then(() => {\n UIStore.setActiveModal(null);\n });\n\n saveAddTorrentsUserPreferences({\n start,\n destination,\n tags: tagsArray,\n tab: 'by-file',\n });\n }}\n isAddingTorrents={isAddingTorrents}\n />\n </Form>\n );\n};\n\nexport default AddTorrentsByFile;\n","import {FC, useRef, useState} from 'react';\nimport {useLingui} from '@lingui/react';\n\nimport {css} from '@client/styled-system/css';\nimport ConfigStore from '@client/stores/ConfigStore';\nimport {Form, FormHandle, FormRow} from '@client/ui';\nimport {saveAddTorrentsUserPreferences} from '@client/util/userPreferences';\nimport SettingStore from '@client/stores/SettingStore';\nimport TorrentActions from '@client/actions/TorrentActions';\nimport UIStore from '@client/stores/UIStore';\n\nimport AddTorrentsActions from './AddTorrentsActions';\nimport FilesystemBrowserTextbox from '../../general/form-elements/FilesystemBrowserTextbox';\nimport TagSelect from '../../general/form-elements/TagSelect';\nimport TextboxRepeater, {getTextArray} from '../../general/form-elements/TextboxRepeater';\n\ntype AddTorrentsByURLFormData = {\n [urls: string]: string;\n} & {\n [cookies: string]: string;\n} & {\n destination: string;\n isBasePath: boolean;\n isCompleted: boolean;\n isSequential: boolean;\n start: boolean;\n tags: string;\n};\n\nconst AddTorrentsByURL: FC = () => {\n const formRef = useRef<FormHandle>(null);\n const textboxRef = useRef<HTMLInputElement>(null);\n const [isAddingTorrents, setIsAddingTorrents] = useState<boolean>(false);\n\n const {i18n} = useLingui();\n\n return (\n <Form className=\"inverse\" ref={formRef}>\n <TextboxRepeater\n id=\"urls\"\n label={\n <div>\n {i18n._('torrents.add.torrents.label')}\n {typeof navigator.registerProtocolHandler === 'function' && (\n <button\n className={css({\n float: 'right',\n _focus: {\n outline: 'none',\n WebkitTapHighlightColor: 'transparent',\n },\n _focusVisible: {\n outline: 'dashed',\n },\n })}\n type=\"button\"\n onClick={() => {\n if (typeof navigator.registerProtocolHandler === 'function') {\n navigator.registerProtocolHandler('magnet', `${ConfigStore.baseURI}?action=add-urls&url=%s`);\n }\n }}\n >\n <em className={css({fontSize: '0.8em'})}>{i18n._('torrents.add.tab.url.register.magnet.handler')}</em>\n </button>\n )}\n </div>\n }\n placeholder={i18n._('torrents.add.tab.url.input.placeholder')}\n defaultValues={\n (UIStore.activeModal?.id === 'add-torrents' &&\n UIStore.activeModal?.tab === 'by-url' &&\n UIStore.activeModal?.urls) || [{id: 0, value: ''}]\n }\n />\n <TextboxRepeater\n id=\"cookies\"\n label={i18n._('torrents.add.cookies.label')}\n placeholder={i18n._('torrents.add.cookies.input.placeholder')}\n />\n <FormRow>\n <TagSelect\n id=\"tags\"\n label={i18n._('torrents.add.tags')}\n onTagSelected={(tags) => {\n if (textboxRef.current != null) {\n const suggestedPath = SettingStore.floodSettings.torrentDestinations?.[tags[0]];\n if (typeof suggestedPath === 'string' && textboxRef.current != null) {\n textboxRef.current.value = suggestedPath;\n textboxRef.current.dispatchEvent(new Event('input', {bubbles: true}));\n }\n }\n }}\n />\n </FormRow>\n <FilesystemBrowserTextbox\n id=\"destination\"\n label={i18n._('torrents.add.destination.label')}\n ref={textboxRef}\n selectable=\"directories\"\n showBasePathToggle\n showCompletedToggle\n showSequentialToggle\n />\n <AddTorrentsActions\n onAddTorrentsClick={() => {\n if (formRef.current == null) {\n return;\n }\n\n const formData = formRef.current.getFormData() as Partial<AddTorrentsByURLFormData>;\n setIsAddingTorrents(true);\n\n const urls = getTextArray(formData, 'urls').filter((url) => url !== '');\n\n if (urls.length === 0 || formData.destination == null) {\n setIsAddingTorrents(false);\n return;\n }\n\n const cookies = getTextArray(formData, 'cookies');\n\n // TODO: handle multiple domain names\n const firstDomain = urls[0].startsWith('http') && urls[0].split('/')[2];\n const processedCookies = firstDomain\n ? {\n [firstDomain]: cookies,\n }\n : undefined;\n\n const tags = formData.tags != null ? formData.tags.split(',').filter((tag) => tag.length > 0) : undefined;\n\n TorrentActions.addTorrentsByUrls({\n urls: urls as [string, ...string[]],\n cookies: processedCookies,\n destination: formData.destination,\n isBasePath: formData.isBasePath,\n isCompleted: formData.isCompleted,\n isSequential: formData.isSequential,\n start: formData.start,\n tags,\n }).then(() => {\n UIStore.setActiveModal(null);\n });\n\n saveAddTorrentsUserPreferences({\n start: formData.start,\n destination: formData.destination,\n tags,\n tab: 'by-url',\n });\n }}\n isAddingTorrents={isAddingTorrents}\n />\n </Form>\n );\n};\n\nexport default AddTorrentsByURL;\n","import classnames from 'classnames';\nimport {FC, ReactNode} from 'react';\n\nimport {css} from '@client/styled-system/css';\n\nexport interface Tab {\n id?: string;\n label: ReactNode;\n\n content: FC<any>;\n props?: Record<string, unknown>;\n modalContentClasses?: string;\n}\n\ninterface ModalTabsProps {\n activeTabId: string | null;\n tabs?: Record<string, Tab>;\n onTabChange: (tab: Tab) => void;\n}\n\nconst ModalTabs: FC<ModalTabsProps> = ({activeTabId, tabs = {}, onTabChange}: ModalTabsProps) => {\n return (\n <ul className=\"modal__tabs\">\n {Object.keys(tabs).map((tabId) => {\n const currentTab = tabs[tabId];\n\n currentTab.id = tabId;\n\n const classes = classnames('modal__tab', {\n 'is-active': tabId === activeTabId,\n });\n\n return (\n <li className={classes} key={tabId}>\n <button\n className={css({\n _focus: {\n outline: 'none',\n WebkitTapHighlightColor: 'transparent',\n },\n _focusVisible: {\n outline: 'dashed',\n },\n })}\n type=\"button\"\n onClick={() => {\n if (onTabChange) {\n onTabChange(currentTab);\n }\n }}\n >\n {currentTab.label}\n </button>\n </li>\n );\n })}\n </ul>\n );\n};\n\nexport default ModalTabs;\n","import classnames from 'classnames';\nimport {FC, ReactNode, useState} from 'react';\n\nimport ModalActions from './ModalActions';\nimport ModalTabs from './ModalTabs';\n\nimport type {ModalAction} from '../../stores/UIStore';\nimport type {Tab} from './ModalTabs';\n\ninterface ModalProps {\n heading: ReactNode;\n content?: ReactNode;\n className?: string | null;\n alignment?: 'left' | 'center';\n size?: 'medium' | 'large';\n orientation?: 'horizontal' | 'vertical';\n tabsInBody?: boolean;\n inverse?: boolean;\n actions?: Array<ModalAction>;\n tabs?: Record<string, Tab>;\n initialTabId?: string;\n}\n\nconst Modal: FC<ModalProps> = ({\n alignment = 'left',\n size = 'medium',\n orientation = 'horizontal',\n tabsInBody = false,\n inverse = true,\n initialTabId,\n className = null,\n content,\n heading,\n tabs,\n actions,\n}: ModalProps) => {\n const contentWrapperClasses = classnames(\n 'modal__content__wrapper',\n `modal--align-${alignment}`,\n `modal--size-${size}`,\n {\n 'modal--horizontal': orientation === 'horizontal',\n 'modal--vertical': orientation === 'vertical',\n 'modal--tabs-in-header': !tabsInBody,\n 'modal--tabs-in-body': tabsInBody,\n inverse,\n },\n className,\n );\n let modalBody = content;\n const modalHeader = heading;\n const headerClasses = classnames('modal__header', {\n 'has-tabs': tabs,\n });\n\n let bodyTabs;\n let footer;\n let headerTabs;\n\n const [activeTabId, setActiveTabId] = useState<string>(initialTabId ?? Object.keys(tabs || {})[0]);\n if (tabs) {\n const activeTab = tabs[activeTabId];\n const contentClasses = classnames('modal__content', activeTab.modalContentClasses);\n\n const ModalContentComponent = activeTab.content;\n const modalContentData = activeTab.props;\n\n const modalTabs = (\n <ModalTabs\n activeTabId={activeTabId}\n key=\"modal-tabs\"\n onTabChange={(tab) => {\n if (tab.id != null) {\n setActiveTabId(tab.id);\n }\n }}\n tabs={tabs}\n />\n );\n\n if (tabsInBody) {\n bodyTabs = modalTabs;\n } else {\n headerTabs = modalTabs;\n }\n\n modalBody = [\n bodyTabs,\n <div className={contentClasses} key=\"modal-content\">\n <ModalContentComponent {...modalContentData} />\n </div>,\n ];\n }\n\n if (actions) {\n footer = (\n <div className=\"modal__footer\">\n <ModalActions actions={actions} />\n </div>\n );\n }\n\n return (\n <div className={contentWrapperClasses}>\n <div className={headerClasses}>\n {modalHeader}\n {headerTabs}\n </div>\n <div className=\"modal__body\">\n {modalBody}\n {footer}\n </div>\n </div>\n );\n};\n\nexport default Modal;\n","import {FC} from 'react';\nimport {useLingui} from '@lingui/react';\n\nimport AddTorrentsByCreation from './AddTorrentsByCreation';\nimport AddTorrentsByFile from './AddTorrentsByFile';\nimport AddTorrentsByURL from './AddTorrentsByURL';\nimport Modal from '../Modal';\nimport SettingStore from '../../../stores/SettingStore';\nimport UIStore from '../../../stores/UIStore';\n\nconst AddTorrentsModal: FC = () => {\n const {i18n} = useLingui();\n\n const tabs = {\n 'by-url': {\n content: AddTorrentsByURL,\n label: i18n._('torrents.add.tab.url.title'),\n },\n 'by-file': {\n content: AddTorrentsByFile,\n label: i18n._('torrents.add.tab.file.title'),\n },\n 'by-creation': {\n content: AddTorrentsByCreation,\n label: i18n._('torrents.add.tab.create.title'),\n },\n };\n\n if (UIStore.activeModal?.id !== 'add-torrents') {\n return null;\n }\n\n return (\n <Modal\n heading={i18n._('torrents.add.heading')}\n tabs={tabs}\n initialTabId={UIStore.activeModal.tab ?? SettingStore.floodSettings.UITorrentsAddTab ?? 'by-url'}\n />\n );\n};\n\nexport default AddTorrentsModal;\n","import {FC} from 'react';\nimport {observer} from 'mobx-react-lite';\n\nimport Modal from '../Modal';\nimport UIStore from '../../../stores/UIStore';\n\nconst ConfirmModal: FC = observer(() => {\n if (UIStore.activeModal?.id !== 'confirm') {\n return null;\n }\n\n const {actions, content, heading} = UIStore.activeModal || {};\n\n return <Modal actions={actions} content={<div className=\"modal__content\">{content}</div>} heading={heading} />;\n});\n\nexport default ConfirmModal;\n","import {makeAutoObservable} from 'mobx';\n\nimport type {Feed, Rule, Item} from '@shared/types/Feed';\n\nclass FeedStore {\n feeds: Array<Feed> = [];\n rules: Array<Rule> = [];\n items: Array<Item> = [];\n\n constructor() {\n makeAutoObservable(this);\n }\n\n setFeeds(feeds: Array<Feed>): void {\n if (feeds == null) {\n this.feeds = [];\n return;\n }\n\n this.feeds = [...feeds].sort((a, b) => a.label.localeCompare(b.label));\n }\n\n setRules(rules: Array<Rule>): void {\n if (rules == null) {\n this.rules = [];\n return;\n }\n\n this.rules = [...rules].sort((a, b) => a.label.localeCompare(b.label));\n }\n\n handleFeedMonitorsFetchSuccess(feedMonitors: {feeds: Array<Feed>; rules: Array<Rule>}): void {\n this.setFeeds(feedMonitors.feeds);\n this.setRules(feedMonitors.rules);\n }\n\n handleItemsFetchSuccess(items: Array<Item>): void {\n this.items = items;\n }\n}\n\nexport default new FeedStore();\n","import axios from 'axios';\n\nimport ConfigStore from '@client/stores/ConfigStore';\nimport FeedStore from '@client/stores/FeedStore';\n\nimport type {Feed, Item, Rule} from '@shared/types/Feed';\nimport type {AddFeedOptions, AddRuleOptions, ModifyFeedOptions} from '@shared/types/api/feed-monitor';\n\nconst {baseURI} = ConfigStore;\n\nconst FeedActions = {\n addFeed: (options: AddFeedOptions) =>\n axios.put(`${baseURI}api/feed-monitor/feeds`, options).then(() => FeedActions.fetchFeedMonitors()),\n\n modifyFeed: (id: string, options: ModifyFeedOptions) =>\n axios.patch(`${baseURI}api/feed-monitor/feeds/${id}`, options).then(() => FeedActions.fetchFeedMonitors()),\n\n addRule: (options: AddRuleOptions) =>\n axios.put(`${baseURI}api/feed-monitor/rules`, options).then(() => FeedActions.fetchFeedMonitors()),\n\n fetchFeedMonitors: () =>\n axios.get<{feeds: Array<Feed>; rules: Array<Rule>}>(`${baseURI}api/feed-monitor`).then(\n ({data}) => {\n FeedStore.handleFeedMonitorsFetchSuccess(data);\n },\n () => {\n // do nothing.\n },\n ),\n\n fetchItems: ({id, search}: {id: string; search: string}) =>\n axios\n .get<Item[]>(`${baseURI}api/feed-monitor/feeds/${id}/items`, {\n params: {\n search,\n },\n })\n .then(\n ({data}) => {\n FeedStore.handleItemsFetchSuccess(data);\n },\n () => {\n // do nothing.\n },\n ),\n\n removeFeedMonitor: (id: string) =>\n axios.delete(`${baseURI}api/feed-monitor/${id}`).then(\n () => FeedActions.fetchFeedMonitors(),\n () => {\n // do nothing.\n },\n ),\n} as const;\n\nexport default FeedActions;\n","export const url = /^(?:https?|ftp):\\/\\/.{1,}\\.{1}.{1,}/;\nexport const cdata = /<!\\[CDATA\\[(.*?)\\]\\]>/;\nexport const noComma = /^[^,]+$/;\n","import {url as matchURL} from '@shared/util/regEx';\n\nexport const isNotEmpty = (value: string | undefined): value is string => value != null && value !== '';\n\nexport const isRegExValid = (regExToCheck: string): boolean => {\n try {\n new RegExp(regExToCheck);\n } catch {\n return false;\n }\n\n return true;\n};\n\nexport const isURLValid = (url: string | undefined): url is string =>\n url != null && url !== '' && url.match(matchURL) !== null;\n\nexport const isPositiveInteger = (value: number | string | undefined): boolean => {\n if (value === null || value === '') return false;\n\n const number = parseInt(`${value}`, 10);\n\n return !Number.isNaN(number) && number > 0;\n};\n","import {FC} from 'react';\nimport {Trans, useLingui} from '@lingui/react';\n\nimport {\n Button,\n Checkbox,\n FormElementAddon,\n FormRow,\n FormRowGroup,\n FormRowItem,\n Select,\n SelectItem,\n Textbox,\n} from '@client/ui';\nimport {CheckmarkThick} from '@client/ui/icons';\nimport FeedStore from '@client/stores/FeedStore';\n\nimport type {AddRuleOptions} from '@shared/types/api/feed-monitor';\n\nimport FilesystemBrowserTextbox from '../../general/form-elements/FilesystemBrowserTextbox';\nimport TagSelect from '../../general/form-elements/TagSelect';\n\ninterface DownloadRuleFormProps {\n rule: AddRuleOptions;\n isSubmitting: boolean;\n isPatternMatched: boolean;\n onCancel: () => void;\n}\n\nconst DownloadRuleForm: FC<DownloadRuleFormProps> = ({\n rule,\n isSubmitting,\n isPatternMatched,\n onCancel,\n}: DownloadRuleFormProps) => {\n const {feeds} = FeedStore;\n const {i18n} = useLingui();\n\n return (\n <FormRowGroup>\n <FormRow>\n <Textbox id=\"label\" label={i18n._('feeds.label')} defaultValue={rule.label} />\n <Select\n disabled={!feeds.length}\n id=\"feedID\"\n label={i18n._('feeds.applicable.feed')}\n defaultID={rule.feedIDs?.[0]}\n >\n {feeds.length === 0\n ? [\n <SelectItem key=\"empty\" id=\"placeholder\" isPlaceholder>\n <em>\n <Trans id=\"feeds.no.feeds.available\" />\n </em>\n </SelectItem>,\n ]\n : feeds.reduce(\n (feedOptions, feed) =>\n feedOptions.concat(\n <SelectItem key={feed._id} id={`${feed._id}`}>\n {feed.label}\n </SelectItem>,\n ),\n [\n <SelectItem key=\"select-feed\" id=\"placeholder\" isPlaceholder>\n <em>\n <Trans id=\"feeds.select.feed\" />\n </em>\n </SelectItem>,\n ],\n )}\n </Select>\n </FormRow>\n <FormRow>\n <Textbox\n id=\"match\"\n label={i18n._('feeds.match.pattern')}\n placeholder={i18n._('feeds.regEx')}\n defaultValue={rule.match}\n width=\"three-eighths\"\n />\n <Textbox\n id=\"exclude\"\n label={i18n._('feeds.exclude.pattern')}\n placeholder={i18n._('feeds.regEx')}\n defaultValue={rule.exclude}\n width=\"three-eighths\"\n />\n </FormRow>\n <FormRow>\n <Textbox\n addonPlacement=\"after\"\n id=\"check\"\n label={i18n._('feeds.test.match')}\n placeholder={i18n._('feeds.check')}\n >\n {isPatternMatched && (\n <FormElementAddon>\n <CheckmarkThick />\n </FormElementAddon>\n )}\n </Textbox>\n </FormRow>\n <FormRow>\n <FormRowItem>\n <FilesystemBrowserTextbox\n id=\"destination\"\n label={i18n._('feeds.torrent.destination')}\n selectable=\"directories\"\n suggested={rule.destination}\n showBasePathToggle\n />\n </FormRowItem>\n <TagSelect\n id=\"tags\"\n label={i18n._('feeds.apply.tags')}\n placeholder={i18n._('feeds.tags')}\n defaultValue={rule.tags}\n />\n </FormRow>\n <FormRow align=\"end\" justify=\"end\">\n <br />\n <Checkbox id=\"startOnLoad\" defaultChecked={rule.startOnLoad} matchTextboxHeight>\n <Trans id=\"feeds.start.on.load\" />\n </Checkbox>\n <Button onClick={onCancel}>\n <Trans id=\"button.cancel\" />\n </Button>\n <Button type=\"submit\" isLoading={isSubmitting}>\n <Trans id=\"button.save.feed\" />\n </Button>\n </FormRow>\n </FormRowGroup>\n );\n};\n\nexport default DownloadRuleForm;\n","import {FC, ReactNode} from 'react';\n\ninterface ModalFormSectionHeaderProps {\n children: ReactNode;\n}\n\nconst ModalFormSectionHeader: FC<ModalFormSectionHeaderProps> = ({children}: ModalFormSectionHeaderProps) => (\n <h2 className=\"h4\">{children}</h2>\n);\n\nexport default ModalFormSectionHeader;\n","import {FC} from 'react';\nimport {observer} from 'mobx-react-lite';\nimport {Trans} from '@lingui/react';\n\nimport {Close, Edit} from '@client/ui/icons';\n\nimport {Rule} from '@shared/types/Feed';\n\nimport FeedStore from '@client/stores/FeedStore';\n\ninterface DownloadRuleListProps {\n currentRule: Rule | null;\n onSelect: (rule: Rule) => void;\n onRemove: (rule: Rule) => void;\n}\n\nconst DownloadRuleList: FC<DownloadRuleListProps> = observer(\n ({currentRule, onSelect, onRemove}: DownloadRuleListProps) => {\n const {rules} = FeedStore;\n\n if (rules.length === 0) {\n return (\n <ul className=\"interactive-list\">\n <li className=\"interactive-list__item\">\n <Trans id=\"feeds.no.rules.defined\" />\n </li>\n </ul>\n );\n }\n\n return (\n <ul className=\"interactive-list\">\n {rules.map((rule) => {\n const matchedCount = rule.count || 0;\n let excludeNode = null;\n let tags = null;\n\n if (rule.exclude) {\n excludeNode = (\n <li\n className=\"interactive-list__detail-list__item\n interactive-list__detail interactive-list__detail--tertiary\"\n >\n <Trans id=\"feeds.exclude\" />\n {': '}\n {rule.exclude}\n </li>\n );\n }\n\n if (rule.tags && rule.tags.length > 0) {\n const tagNodes = rule.tags.map((tag) => (\n <span className=\"tag\" key={tag}>\n {tag}\n </span>\n ));\n\n tags = (\n <li className=\"interactive-list__detail-list__item interactive-list__detail interactive-list__detail--tertiary\">\n <Trans id=\"feeds.tags\" />\n {': '}\n {tagNodes}\n </li>\n );\n }\n\n return (\n <li className=\"interactive-list__item interactive-list__item--stacked-content\" key={rule._id}>\n <div className=\"interactive-list__label\">\n <ul className=\"interactive-list__detail-list\">\n <li\n className=\"interactive-list__detail-list__item\n interactive-list__detail--primary\"\n >\n {rule.label}\n </li>\n <li\n className=\"interactive-list__detail-list__item\n interactive-list__detail-list__item--overflow\n interactive-list__detail interactive-list__detail--secondary\"\n >\n <Trans id=\"feeds.match.count\" values={{count: matchedCount}} />\n </li>\n {rule === currentRule && (\n <li\n className=\"interactive-list__detail-list__item\n interactive-list__detail--primary\"\n >\n Modifying\n </li>\n )}\n </ul>\n <ul className=\"interactive-list__detail-list\">\n <li\n className=\"interactive-list__detail-list__item\n interactive-list__detail interactive-list__detail--tertiary\"\n style={{\n maxWidth: '50%',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n <Trans id=\"feeds.match\" />\n {': '}\n {rule.match}\n </li>\n <div style={{width: '100%'}} />\n {excludeNode}\n {tags}\n </ul>\n </div>\n <button\n className=\"interactive-list__icon interactive-list__icon--action\"\n type=\"button\"\n onClick={() => onSelect(rule)}\n >\n <Edit />\n </button>\n <button\n className=\"interactive-list__icon interactive-list__icon--action interactive-list__icon--action--warning\"\n type=\"button\"\n onClick={() => onRemove(rule)}\n >\n <Close />\n </button>\n </li>\n );\n })}\n </ul>\n );\n },\n);\n\nexport default DownloadRuleList;\n","import {FC, ReactElement, useRef, useState} from 'react';\nimport {Trans, useLingui} from '@lingui/react';\n\nimport {Button, Form, FormHandle, FormError, FormRow, FormRowItem} from '@client/ui';\nimport FeedActions from '@client/actions/FeedActions';\nimport {isNotEmpty, isRegExValid} from '@client/util/validators';\n\nimport type {AddRuleOptions} from '@shared/types/api/feed-monitor';\nimport type {Rule} from '@shared/types/Feed';\n\nimport DownloadRuleForm from './DownloadRuleForm';\nimport ModalFormSectionHeader from '../ModalFormSectionHeader';\nimport DownloadRuleList from './DownloadRuleList';\n\nconst initialRule: AddRuleOptions = {\n label: '',\n feedIDs: [],\n match: '',\n exclude: '',\n tags: [],\n destination: '',\n startOnLoad: false,\n};\n\nconst validatedFields = {\n destination: {\n isValid: isNotEmpty,\n error: 'feeds.validation.must.specify.destination',\n },\n feedID: {\n isValid: (value: string | undefined) => isNotEmpty(value) && value !== 'placeholder',\n error: 'feeds.validation.must.select.feed',\n },\n label: {\n isValid: isNotEmpty,\n error: 'feeds.validation.must.specify.label',\n },\n match: {\n isValid: (value: string | undefined) => isNotEmpty(value) && isRegExValid(value),\n error: 'feeds.validation.invalid.regular.expression',\n },\n exclude: {\n isValid: (value: string | undefined) => {\n if (isNotEmpty(value)) {\n return isRegExValid(value);\n }\n\n return true;\n },\n error: 'feeds.validation.invalid.regular.expression',\n },\n} as const;\n\ntype ValidatedField = keyof typeof validatedFields;\n\nconst validateField = (validatedField: ValidatedField, value: string | undefined): string | undefined =>\n validatedFields[validatedField]?.isValid(value) ? undefined : validatedFields[validatedField]?.error;\n\ninterface RuleFormData {\n check: string;\n exclude: string;\n destination: string;\n field: string;\n feedID: string;\n label: string;\n match: string;\n tags: string;\n isBasePath: boolean;\n startOnLoad: boolean;\n}\n\nconst DownloadRulesTab: FC = () => {\n const formRef = useRef<FormHandle>(null);\n const {i18n} = useLingui();\n\n const [currentRule, setCurrentRule] = useState<Rule | null>(null);\n const [errors, setErrors] = useState<Record<string, string | undefined>>({});\n const [isEditing, setIsEditing] = useState<boolean>(false);\n const [isSubmitting, setIsSubmitting] = useState<boolean>(false);\n const [isFormChanged, setIsFormChanged] = useState<boolean>(false);\n const [isPatternMatched, setIsPatternMatched] = useState<boolean>(false);\n\n return (\n <Form\n className=\"inverse\"\n onChange={({event, formData}) => {\n const validatedField = (event.target as HTMLInputElement).name as ValidatedField;\n const ruleFormData = formData as Partial<RuleFormData>;\n\n setErrors({\n ...errors,\n [validatedField]: validateField(validatedField, ruleFormData[validatedField]),\n });\n\n setIsPatternMatched(\n (() => {\n const {check, match = '', exclude = ''} = ruleFormData;\n\n if (isNotEmpty(check) && isRegExValid(match) && isRegExValid(exclude)) {\n const isMatched = new RegExp(match, 'gi').test(check);\n const isExcluded = exclude !== '' && new RegExp(exclude, 'gi').test(check);\n return isMatched && !isExcluded;\n }\n\n return false;\n })(),\n );\n\n setIsFormChanged(true);\n }}\n onSubmit={async () => {\n if (formRef.current == null) {\n return;\n }\n\n const formData = formRef.current.getFormData() as Partial<RuleFormData>;\n\n const currentErrors = Object.keys(validatedFields).reduce((memo, key) => {\n const validatedField = key as ValidatedField;\n\n return {\n ...memo,\n [validatedField]: validateField(validatedField, formData[validatedField]),\n };\n }, {} as Record<string, string | undefined>);\n setErrors(currentErrors);\n\n const isFormValid = Object.keys(currentErrors).every((key) => currentErrors[key] === undefined);\n\n if (isFormChanged && isFormValid) {\n setIsSubmitting(true);\n\n if (currentRule?._id != null) {\n await FeedActions.removeFeedMonitor(currentRule._id);\n }\n\n await FeedActions.addRule({\n label: formData.label ?? initialRule.label,\n feedIDs: [formData.feedID ?? ''],\n field: formData.field,\n match: formData.match ?? initialRule.match,\n exclude: formData.exclude ?? initialRule.exclude,\n destination: formData.destination ?? initialRule.destination,\n tags: formData.tags?.split(',') ?? initialRule.tags,\n startOnLoad: formData.startOnLoad ?? initialRule.startOnLoad,\n isBasePath: formData.isBasePath ?? false,\n }).then(\n () => {\n formRef.current?.resetForm();\n setErrors({});\n setCurrentRule(null);\n setIsEditing(false);\n },\n () => {\n setErrors({backend: 'general.error.unknown'});\n },\n );\n\n setIsSubmitting(false);\n }\n }}\n ref={formRef}\n >\n <ModalFormSectionHeader>\n <Trans id=\"feeds.existing.rules\" />\n </ModalFormSectionHeader>\n {Object.keys(errors).reduce((memo: Array<ReactElement>, key) => {\n if (errors[key as ValidatedField] != null) {\n memo.push(\n <FormRow key={`error-${key}`}>\n <FormError>{i18n._(errors?.[key as ValidatedField] as string)}</FormError>\n </FormRow>,\n );\n }\n\n return memo;\n }, [])}\n <FormRow>\n <FormRowItem>\n <DownloadRuleList\n currentRule={currentRule}\n onSelect={(rule) => {\n setCurrentRule(rule);\n setIsEditing(true);\n }}\n onRemove={(rule) => {\n if (rule._id != null) {\n FeedActions.removeFeedMonitor(rule._id);\n }\n\n if (rule === currentRule) {\n setCurrentRule(null);\n setIsEditing(false);\n }\n }}\n />\n </FormRowItem>\n </FormRow>\n {isEditing ? (\n <DownloadRuleForm\n key={currentRule?._id || 'initial'}\n rule={currentRule ?? initialRule}\n isPatternMatched={isPatternMatched}\n isSubmitting={isSubmitting}\n onCancel={() => {\n setCurrentRule(null);\n setIsEditing(false);\n }}\n />\n ) : (\n <FormRow align=\"end\" justify=\"end\">\n <br />\n <Button\n onClick={() => {\n setIsEditing(true);\n }}\n >\n <Trans id=\"button.new\" />\n </Button>\n </FormRow>\n )}\n </Form>\n );\n};\n\nexport default DownloadRulesTab;\n","import {FC} from 'react';\nimport {Trans, useLingui} from '@lingui/react';\n\nimport {Button, FormRow, FormRowGroup, Select, SelectItem, Textbox} from '@client/ui';\n\nimport type {Feed} from '@shared/types/Feed';\n\ninterface FeedFormProps {\n currentFeed: Feed | null;\n defaultFeed: Pick<Feed, 'interval' | 'label' | 'url'>;\n intervalMultipliers: Readonly<Array<{message: string; value: number}>>;\n isSubmitting: boolean;\n onCancel: () => void;\n}\n\nconst FeedForm: FC<FeedFormProps> = ({\n currentFeed,\n defaultFeed,\n intervalMultipliers,\n isSubmitting,\n onCancel,\n}: FeedFormProps) => {\n const {i18n} = useLingui();\n const feedInterval = currentFeed?.interval ?? defaultFeed.interval;\n\n let defaultIntervalTextValue = feedInterval;\n let defaultIntervalMultiplier = 1;\n\n intervalMultipliers.forEach((interval) => {\n const intervalMultiplier = interval.value;\n\n if (feedInterval % intervalMultiplier === 0) {\n defaultIntervalTextValue = feedInterval / intervalMultiplier;\n defaultIntervalMultiplier = intervalMultiplier;\n }\n });\n\n return (\n <FormRowGroup>\n <FormRow>\n <Textbox\n id=\"label\"\n label={i18n._('feeds.label')}\n placeholder={i18n._('feeds.label')}\n defaultValue={currentFeed?.label ?? defaultFeed.label}\n />\n <Textbox\n id=\"interval\"\n label={i18n._('feeds.select.interval')}\n placeholder={i18n._('feeds.interval')}\n defaultValue={defaultIntervalTextValue}\n width=\"one-eighth\"\n />\n <Select labelOffset defaultID={defaultIntervalMultiplier} id=\"intervalMultiplier\" width=\"one-eighth\">\n {intervalMultipliers.map((interval) => (\n <SelectItem key={interval.value} id={interval.value}>\n {i18n._(interval.message)}\n </SelectItem>\n ))}\n </Select>\n </FormRow>\n <FormRow>\n <Textbox\n id=\"url\"\n label={i18n._('feeds.url')}\n placeholder={i18n._('feeds.url')}\n defaultValue={currentFeed?.url ?? defaultFeed?.url}\n />\n <Button labelOffset onClick={onCancel}>\n <Trans id=\"button.cancel\" />\n </Button>\n <Button labelOffset type=\"submit\" isLoading={isSubmitting}>\n <Trans id=\"button.save.feed\" />\n </Button>\n </FormRow>\n </FormRowGroup>\n );\n};\n\nexport default FeedForm;\n","import {FC, ReactElement} from 'react';\nimport {observer} from 'mobx-react-lite';\nimport {Trans} from '@lingui/react';\n\nimport {Checkbox, FormRow} from '@client/ui';\n\nimport FeedStore from '@client/stores/FeedStore';\n\ninterface FeedItemsProps {\n selectedFeedID: string;\n}\n\nconst FeedItems: FC<FeedItemsProps> = observer(({selectedFeedID}: FeedItemsProps) => {\n const {items} = FeedStore;\n\n const itemElements: Array<ReactElement> = [];\n if (selectedFeedID) {\n const titleOccurrences: Record<string, number> = {};\n items.forEach((item, index) => {\n let {title} = item;\n const occurrence = titleOccurrences[title];\n\n if (occurrence == null) {\n titleOccurrences[title] = 2;\n } else {\n title = `${title} #${occurrence}`;\n titleOccurrences[title] += 1;\n }\n\n itemElements.push(\n <li className=\"interactive-list__item interactive-list__item--stacked-content feed-list__feed\" key={title}>\n <div className=\"interactive-list__label feed-list__feed-label\">{title}</div>\n <Checkbox id={`${index}`} />\n </li>,\n );\n });\n }\n\n return (\n <FormRow>\n {itemElements.length === 0 ? (\n <ul className=\"interactive-list\">\n <li className=\"interactive-list__item\">\n <div className=\"interactive-list__label\">\n <Trans id=\"feeds.no.items.matching\" />\n </div>\n </li>\n </ul>\n ) : (\n <ul className=\"interactive-list feed-list\">{itemElements}</ul>\n )}\n </FormRow>\n );\n});\n\nexport default FeedItems;\n","import {FC, useRef, useState} from 'react';\nimport {observer} from 'mobx-react-lite';\nimport {Trans, useLingui} from '@lingui/react';\n\nimport {Button, Form, FormHandle, FormRow, Select, SelectItem, Textbox} from '@client/ui';\nimport FeedActions from '@client/actions/FeedActions';\nimport FeedStore from '@client/stores/FeedStore';\nimport UIStore from '@client/stores/UIStore';\n\nimport FeedItems from './FeedItems';\nimport ModalFormSectionHeader from '../ModalFormSectionHeader';\n\nconst FeedItemsForm: FC = observer(() => {\n const {i18n} = useLingui();\n const manualAddingFormRef = useRef<FormHandle>(null);\n const [selectedFeedID, setSelectedFeedID] = useState<string | null>(null);\n\n const {feeds} = FeedStore;\n\n if (selectedFeedID != null) {\n if (!feeds.some((feed) => feed._id === selectedFeedID)) {\n setSelectedFeedID(null);\n }\n }\n\n return (\n <Form\n className=\"inverse\"\n onChange={({event, formData}) => {\n const feedBrowseForm = formData as {feedID: string; search: string};\n if ((event.target as HTMLInputElement).type !== 'checkbox') {\n setSelectedFeedID(feedBrowseForm.feedID);\n FeedActions.fetchItems({\n id: feedBrowseForm.feedID,\n search: feedBrowseForm.search,\n });\n }\n }}\n onSubmit={() => {\n if (manualAddingFormRef.current == null) {\n return;\n }\n\n const formData = manualAddingFormRef.current.getFormData();\n\n // TODO: Properly handle array of array of URLs\n const torrentsToDownload = FeedStore.items\n .filter((_item, index) => formData[index])\n .map((item, index) => ({id: index, value: item.urls[0]}));\n\n UIStore.setActiveModal({\n id: 'add-torrents',\n tab: 'by-url',\n urls: torrentsToDownload,\n });\n }}\n ref={manualAddingFormRef}\n >\n <ModalFormSectionHeader>\n <Trans id=\"feeds.browse.feeds\" />\n </ModalFormSectionHeader>\n <FormRow>\n <Select\n disabled={!feeds.length}\n grow={false}\n id=\"feedID\"\n label={i18n._('feeds.select.feed')}\n width=\"three-eighths\"\n >\n {!feeds.length\n ? [\n <SelectItem key=\"empty\" id=\"placeholder\" isPlaceholder>\n <em>\n <Trans id=\"feeds.no.feeds.available\" />\n </em>\n </SelectItem>,\n ]\n : feeds.reduce(\n (feedOptions, feed) => {\n if (feed._id == null) {\n return feedOptions;\n }\n\n return feedOptions.concat(\n <SelectItem key={feed._id} id={feed._id}>\n {feed.label}\n </SelectItem>,\n );\n },\n [\n <SelectItem key=\"select-feed\" id=\"placeholder\" isPlaceholder>\n <em>\n <Trans id=\"feeds.select.feed\" />\n </em>\n </SelectItem>,\n ],\n )}\n </Select>\n {selectedFeedID && (\n <Textbox id=\"search\" label={i18n._('feeds.search.term')} placeholder={i18n._('feeds.search')} />\n )}\n {selectedFeedID && (\n <Button key=\"button\" type=\"submit\" labelOffset>\n <Trans id=\"button.download\" />\n </Button>\n )}\n </FormRow>\n {selectedFeedID && <FeedItems selectedFeedID={selectedFeedID} />}\n </Form>\n );\n});\n\nexport default FeedItemsForm;\n","import {FC} from 'react';\nimport {observer} from 'mobx-react-lite';\nimport {Trans, useLingui} from '@lingui/react';\n\nimport {Close, Edit} from '@client/ui/icons';\nimport FeedStore from '@client/stores/FeedStore';\n\nimport type {Feed} from '@shared/types/Feed';\n\ninterface FeedListProps {\n currentFeed: Feed | null;\n intervalMultipliers: Readonly<Array<{message: string; value: number}>>;\n onSelect: (feed: Feed) => void;\n onRemove: (feed: Feed) => void;\n}\n\nconst FeedList: FC<FeedListProps> = observer(\n ({currentFeed, intervalMultipliers, onSelect, onRemove}: FeedListProps) => {\n const {feeds} = FeedStore;\n const {i18n} = useLingui();\n\n if (feeds.length === 0) {\n return (\n <ul className=\"interactive-list\">\n <li className=\"interactive-list__item\">\n <Trans id=\"feeds.no.feeds.defined\" />\n </li>\n </ul>\n );\n }\n\n return (\n <ul className=\"interactive-list feed-list\">\n {feeds.map((feed) => {\n const matchedCount = feed.count || 0;\n\n let intervalText = `${feed.interval}`;\n let intervalMultiplierMessage = intervalMultipliers[0].message;\n\n intervalMultipliers.forEach((interval) => {\n if (feed.interval % interval.value === 0) {\n intervalText = `${feed.interval / interval.value}`;\n intervalMultiplierMessage = interval.message;\n }\n });\n\n return (\n <li\n className=\"interactive-list__item interactive-list__item--stacked-content feed-list__feed\"\n key={feed._id}\n >\n <div className=\"interactive-list__label\">\n <ul className=\"interactive-list__detail-list\">\n <li\n className=\"interactive-list__detail-list__item\n interactive-list__detail--primary\"\n >\n {feed.label}\n </li>\n <li\n className=\"interactive-list__detail-list__item\n interactive-list__detail-list__item--overflow\n interactive-list__detail interactive-list__detail--secondary\"\n >\n <Trans id=\"feeds.match.count\" values={{count: matchedCount}} />\n </li>\n {feed === currentFeed && (\n <li\n className=\"interactive-list__detail-list__item\n interactive-list__detail--primary\"\n >\n Modifying\n </li>\n )}\n </ul>\n <ul className=\"interactive-list__detail-list\">\n <li\n className=\"interactive-list__detail-list__item\n interactive-list__detail interactive-list__detail--tertiary\"\n >\n {`${intervalText} ${i18n._(intervalMultiplierMessage)}`}\n </li>\n <li\n className=\"interactive-list__detail-list__item\n interactive-list__detail-list__item--overflow\n interactive-list__detail interactive-list__detail--tertiary\"\n >\n <a href={feed.url} rel=\"noopener noreferrer\" target=\"_blank\">\n {feed.url}\n </a>\n </li>\n </ul>\n </div>\n <button\n className=\"interactive-list__icon interactive-list__icon--action\"\n type=\"button\"\n onClick={() => onSelect(feed)}\n >\n <Edit />\n </button>\n <button\n className=\"interactive-list__icon interactive-list__icon--action interactive-list__icon--action--warning\"\n type=\"button\"\n onClick={() => onRemove(feed)}\n >\n <Close />\n </button>\n </li>\n );\n })}\n </ul>\n );\n },\n);\n\nexport default FeedList;\n","import {FC, ReactElement, useRef, useState} from 'react';\nimport {Trans, useLingui} from '@lingui/react';\n\nimport {Button, Form, FormHandle, FormError, FormRow, FormRowItem} from '@client/ui';\nimport FeedActions from '@client/actions/FeedActions';\nimport {isNotEmpty, isPositiveInteger, isURLValid} from '@client/util/validators';\n\nimport type {AddFeedOptions} from '@shared/types/api/feed-monitor';\nimport type {Feed} from '@shared/types/Feed';\n\nimport FeedForm from './FeedForm';\nimport FeedItemsForm from './FeedItemsForm';\nimport FeedList from './FeedList';\nimport ModalFormSectionHeader from '../ModalFormSectionHeader';\n\nconst validatedFields = {\n url: {\n isValid: isURLValid,\n error: 'feeds.validation.must.specify.valid.feed.url',\n },\n label: {\n isValid: isNotEmpty,\n error: 'feeds.validation.must.specify.label',\n },\n interval: {\n isValid: isPositiveInteger,\n error: 'feeds.validation.interval.not.positive',\n },\n} as const;\n\ntype ValidatedField = keyof typeof validatedFields;\n\nconst validateField = (validatedField: ValidatedField, value: string | undefined): string | undefined =>\n validatedFields[validatedField]?.isValid(value) ? undefined : validatedFields[validatedField]?.error;\n\ninterface FeedFormData {\n url: string;\n label: string;\n interval: string;\n intervalMultiplier: string;\n}\n\nconst INTERVAL_MULTIPLIERS = [\n {\n message: 'feeds.time.min',\n value: 1,\n },\n {\n message: 'feeds.time.hr',\n value: 60,\n },\n {\n message: 'feeds.time.day',\n value: 1440,\n },\n] as const;\n\nconst defaultFeed: AddFeedOptions = {\n label: '',\n interval: 5,\n url: '',\n};\n\nconst FeedsTab: FC = () => {\n const formRef = useRef<FormHandle>(null);\n const {i18n} = useLingui();\n const [currentFeed, setCurrentFeed] = useState<Feed | null>(null);\n const [errors, setErrors] = useState<Record<string, string | undefined>>({});\n const [isEditing, setIsEditing] = useState<boolean>(false);\n const [isSubmitting, setIsSubmitting] = useState<boolean>(false);\n\n return (\n <div>\n <Form\n className=\"inverse\"\n onChange={({event, formData}) => {\n const validatedField = (event.target as HTMLInputElement).name as ValidatedField;\n const feedForm = formData as unknown as FeedFormData;\n\n setErrors({\n ...errors,\n [validatedField]: validateField(validatedField, feedForm[validatedField]),\n });\n }}\n onSubmit={async () => {\n const feedForm = formRef.current?.getFormData() as unknown as FeedFormData;\n if (formRef.current == null || feedForm == null) {\n return;\n }\n\n setIsSubmitting(true);\n\n const currentErrors = Object.keys(validatedFields).reduce((memo, key) => {\n const validatedField = key as ValidatedField;\n\n return {\n ...memo,\n [validatedField]: validateField(validatedField, feedForm[validatedField]),\n };\n }, {} as Record<string, string | undefined>);\n setErrors(currentErrors);\n\n const isFormValid = Object.keys(currentErrors).every((key) => currentErrors[key] === undefined);\n\n if (isFormValid) {\n const feed: AddFeedOptions = {\n label: feedForm.label,\n url: feedForm.url,\n interval: Number(feedForm.interval) * Number(feedForm.intervalMultiplier),\n };\n\n let success = true;\n try {\n if (currentFeed === null) {\n await FeedActions.addFeed(feed);\n } else if (currentFeed?._id != null) {\n await FeedActions.modifyFeed(currentFeed._id, feed);\n }\n } catch {\n success = false;\n }\n\n if (success) {\n formRef.current.resetForm();\n setErrors({});\n setCurrentFeed(null);\n setIsEditing(false);\n } else {\n setErrors({backend: 'general.error.unknown'});\n }\n }\n\n setIsSubmitting(false);\n }}\n ref={formRef}\n >\n <ModalFormSectionHeader>\n <Trans id=\"feeds.existing.feeds\" />\n </ModalFormSectionHeader>\n {Object.keys(errors).reduce((memo: Array<ReactElement>, key) => {\n if (errors[key as ValidatedField] != null) {\n memo.push(\n <FormRow key={`error-${key}`}>\n <FormError>{i18n._(errors?.[key as ValidatedField] as string)}</FormError>\n </FormRow>,\n );\n }\n\n return memo;\n }, [])}\n <FormRow>\n <FormRowItem>\n <FeedList\n currentFeed={currentFeed}\n intervalMultipliers={INTERVAL_MULTIPLIERS}\n onSelect={(feed) => {\n setCurrentFeed(feed);\n setIsEditing(true);\n }}\n onRemove={(feed) => {\n if (feed === currentFeed) {\n if (isEditing) {\n setErrors({});\n setIsEditing(false);\n }\n\n setCurrentFeed(null);\n }\n\n if (feed._id != null) {\n FeedActions.removeFeedMonitor(feed._id);\n }\n }}\n />\n </FormRowItem>\n </FormRow>\n {isEditing ? (\n <FeedForm\n currentFeed={currentFeed}\n defaultFeed={defaultFeed}\n key={currentFeed?._id || 'initial'}\n intervalMultipliers={INTERVAL_MULTIPLIERS}\n isSubmitting={isSubmitting}\n onCancel={() => {\n setErrors({});\n setIsEditing(false);\n setCurrentFeed(null);\n }}\n />\n ) : (\n <FormRow>\n <FormRowItem width=\"auto\" />\n <Button\n onClick={() => {\n setIsEditing(true);\n }}\n >\n <Trans id=\"button.new\" />\n </Button>\n </FormRow>\n )}\n </Form>\n <FeedItemsForm />\n </div>\n );\n};\n\nexport default FeedsTab;\n","import {FC, useEffect} from 'react';\nimport {useLingui} from '@lingui/react';\n\nimport DownloadRulesTab from './DownloadRulesTab';\nimport FeedActions from '../../../actions/FeedActions';\nimport FeedsTab from './FeedsTab';\nimport Modal from '../Modal';\n\nconst FeedsModal: FC = () => {\n const {i18n} = useLingui();\n\n useEffect(() => {\n FeedActions.fetchFeedMonitors();\n }, []);\n\n const tabs = {\n feeds: {\n content: FeedsTab,\n label: i18n._('feeds.tabs.feeds'),\n },\n downloadRules: {\n content: DownloadRulesTab,\n label: i18n._('feeds.tabs.download.rules'),\n },\n };\n\n return <Modal heading={i18n._('feeds.tabs.heading')} orientation=\"horizontal\" size=\"large\" tabs={tabs} />;\n};\n\nexport default FeedsModal;\n","export enum TorrentTrackerType {\n HTTP = 1,\n UDP = 2,\n DHT = 3,\n}\n\nexport interface TorrentTracker {\n url: string;\n type: TorrentTrackerType;\n}\n","import {FC, useEffect, useRef, useState} from 'react';\nimport {useLingui} from '@lingui/react';\n\nimport {CheckmarkThick, Clipboard} from '@client/ui/icons';\nimport {Form, FormElementAddon, FormError, FormRow, Textbox} from '@client/ui';\nimport TorrentActions from '@client/actions/TorrentActions';\nimport TorrentStore from '@client/stores/TorrentStore';\n\nimport {TorrentTrackerType} from '@shared/types/TorrentTracker';\n\nimport Modal from '../Modal';\n\nconst generateMagnet = (hash: string, trackers?: Array<string>): string => {\n let result = `magnet:?xt=urn:btih:${hash}`;\n\n if (trackers?.length) {\n trackers.forEach((tracker) => {\n result = `${result}&tr=${encodeURI(tracker)}`;\n });\n }\n\n return result;\n};\n\nconst GenerateMagnetModal: FC = () => {\n const magnetTextboxRef = useRef<HTMLInputElement>(null);\n const magnetTrackersTextboxRef = useRef<HTMLInputElement>(null);\n const {i18n} = useLingui();\n\n const [isMagnetCopied, setIsMagnetCopied] = useState<boolean>(false);\n const [isMagnetTrackersCopied, setIsMagnetTrackersCopied] = useState<boolean>(false);\n const [trackerState, setTrackerState] = useState<{\n isLoadingTrackers: boolean;\n magnetTrackersLink: string;\n }>({\n isLoadingTrackers: true,\n magnetTrackersLink: '',\n });\n\n useEffect(() => {\n TorrentActions.fetchTorrentTrackers(TorrentStore.selectedTorrents[0]).then((trackers) => {\n if (trackers != null) {\n setTrackerState({\n isLoadingTrackers: false,\n magnetTrackersLink: generateMagnet(\n TorrentStore.selectedTorrents[0],\n trackers.filter((tracker) => tracker.type !== TorrentTrackerType.DHT).map((tracker) => tracker.url),\n ),\n });\n }\n });\n }, []);\n\n const magnetLink = generateMagnet(TorrentStore.selectedTorrents[0]);\n\n return (\n <Modal\n heading={i18n._('torrents.generate.magnet.heading')}\n content={\n <div className=\"modal__content inverse\">\n <Form>\n {TorrentStore.torrents[TorrentStore.selectedTorrents[0]]?.isPrivate ? (\n <FormRow>\n <FormError>{i18n._('torrents.generate.magnet.private.torrent')}</FormError>\n </FormRow>\n ) : null}\n <FormRow>\n <Textbox\n id=\"magnet\"\n ref={magnetTextboxRef}\n addonPlacement=\"after\"\n label={i18n._('torrents.generate.magnet.magnet')}\n defaultValue={magnetLink}\n readOnly\n >\n <FormElementAddon\n onClick={() => {\n if (typeof navigator.clipboard?.writeText === 'function') {\n navigator.clipboard.writeText(magnetLink).then(() => {\n setIsMagnetCopied(true);\n });\n } else if (magnetTextboxRef.current != null) {\n magnetTextboxRef.current?.select();\n document.execCommand('copy');\n setIsMagnetCopied(true);\n }\n }}\n >\n {isMagnetCopied ? <CheckmarkThick /> : <Clipboard />}\n </FormElementAddon>\n </Textbox>\n </FormRow>\n <FormRow>\n {trackerState.isLoadingTrackers ? (\n <Textbox\n id=\"loading\"\n label={i18n._('torrents.generate.magnet.magnet.with.trackers')}\n placeholder={i18n._('torrents.generate.magnet.loading.trackers')}\n disabled\n />\n ) : (\n <Textbox\n id=\"magnet-trackers\"\n ref={magnetTrackersTextboxRef}\n addonPlacement=\"after\"\n label={i18n._('torrents.generate.magnet.magnet.with.trackers')}\n defaultValue={trackerState.magnetTrackersLink}\n readOnly\n >\n <FormElementAddon\n onClick={() => {\n if (typeof navigator.clipboard?.writeText === 'function') {\n navigator.clipboard.writeText(trackerState.magnetTrackersLink).then(() => {\n setIsMagnetTrackersCopied(true);\n });\n } else if (magnetTrackersTextboxRef.current != null) {\n magnetTrackersTextboxRef.current?.select();\n document.execCommand('copy');\n setIsMagnetTrackersCopied(true);\n }\n }}\n >\n {isMagnetTrackersCopied ? <CheckmarkThick /> : <Clipboard />}\n </FormElementAddon>\n </Textbox>\n )}\n </FormRow>\n </Form>\n </div>\n }\n actions={[\n {\n clickHandler: null,\n content: i18n._('button.close'),\n triggerDismiss: true,\n type: 'tertiary',\n },\n ]}\n />\n );\n};\n\nexport default GenerateMagnetModal;\n","import {FC, useState} from 'react';\nimport {useLingui} from '@lingui/react';\n\nimport {Form} from '@client/ui';\nimport TorrentActions from '@client/actions/TorrentActions';\nimport TorrentStore from '@client/stores/TorrentStore';\nimport UIStore from '@client/stores/UIStore';\n\nimport FilesystemBrowserTextbox from '../../general/form-elements/FilesystemBrowserTextbox';\nimport Modal from '../Modal';\nimport ModalActions from '../ModalActions';\n\nconst getSuggestedPath = (sources: Array<string>): string | undefined => {\n let commonPath = '';\n\n for (let i = 0; i < sources[0].length; i += 1) {\n for (let j = 1; j < sources.length; j += 1) {\n if (sources[0][i] !== sources[j][i]) {\n commonPath = sources[0].slice(0, i);\n }\n }\n }\n\n for (let i = commonPath.length - 1; i >= 0; i -= 1) {\n if (commonPath[i] === '/') {\n return commonPath.slice(0, i + 1);\n }\n }\n\n // Fallback to default download location.\n return undefined;\n};\n\nconst MoveTorrents: FC = () => {\n const {i18n} = useLingui();\n const [isSettingDownloadPath, setIsSettingDownloadPath] = useState<boolean>(false);\n\n return (\n <Modal\n heading={i18n._('torrents.move.heading')}\n content={\n <div className=\"modal__content\">\n <Form\n className=\"inverse\"\n onSubmit={({formData}) => {\n const hashes = TorrentStore.selectedTorrents;\n if (hashes.length > 0) {\n setIsSettingDownloadPath(true);\n TorrentActions.moveTorrents({\n hashes,\n destination: formData.destination as string,\n isBasePath: formData.isBasePath as boolean,\n moveFiles: formData.moveFiles as boolean,\n isCheckHash: formData.isCheckHash as boolean,\n }).then(() => {\n UIStore.setActiveModal(null);\n setIsSettingDownloadPath(false);\n });\n }\n }}\n >\n <FilesystemBrowserTextbox\n id=\"destination\"\n selectable=\"directories\"\n suggested={getSuggestedPath(\n TorrentStore.selectedTorrents.map((hash: string) => TorrentStore.torrents[hash].directory),\n )}\n showBasePathToggle\n />\n <ModalActions\n actions={[\n {\n checked: true,\n content: i18n._('torrents.move.data.label'),\n id: 'moveFiles',\n type: 'checkbox',\n },\n {\n checked: false,\n content: i18n._('torrents.move.check_hash.label'),\n id: 'isCheckHash',\n type: 'checkbox',\n },\n {\n content: i18n._('button.cancel'),\n triggerDismiss: true,\n type: 'tertiary',\n },\n {\n content: i18n._('torrents.move.button.set.location'),\n isLoading: isSettingDownloadPath,\n submit: true,\n type: 'primary',\n },\n ]}\n />\n </Form>\n </div>\n }\n />\n );\n};\n\nexport default MoveTorrents;\n","import {FC, useState} from 'react';\nimport {Trans, useLingui} from '@lingui/react';\n\nimport {Form, FormRow} from '@client/ui';\nimport {saveDeleteTorrentsUserPreferences} from '@client/util/userPreferences';\nimport SettingStore from '@client/stores/SettingStore';\nimport TorrentActions from '@client/actions/TorrentActions';\nimport TorrentStore from '@client/stores/TorrentStore';\nimport UIStore from '@client/stores/UIStore';\n\nimport Modal from '../Modal';\nimport ModalActions from '../ModalActions';\n\nconst RemoveTorrentsModal: FC = () => {\n const {i18n} = useLingui();\n const [isRemoving, setIsRemoving] = useState<boolean>(false);\n const {selectedTorrents} = TorrentStore;\n\n if (selectedTorrents.length === 0) {\n return (\n <Modal\n heading={i18n._('torrents.remove')}\n content={\n <div className=\"modal__content inverse\">\n <Form>\n <FormRow>\n <Trans id=\"torrents.remove.error.no.torrents.selected\" />\n </FormRow>\n </Form>\n </div>\n }\n actions={[\n {\n clickHandler: null,\n content: i18n._('button.ok'),\n triggerDismiss: true,\n type: 'primary',\n },\n ]}\n />\n );\n }\n\n return (\n <Modal\n heading={i18n._('torrents.remove')}\n content={\n <div className=\"modal__content\">\n <Form\n className=\"inverse\"\n onSubmit={({formData}) => {\n setIsRemoving(true);\n\n const deleteData = formData.deleteData as boolean;\n\n TorrentActions.deleteTorrents({\n hashes: TorrentStore.selectedTorrents,\n deleteData,\n }).then(() => {\n setIsRemoving(false);\n saveDeleteTorrentsUserPreferences({deleteData});\n UIStore.setActiveModal(null);\n });\n }}\n >\n <FormRow>\n <Trans id=\"torrents.remove.are.you.sure\" values={{count: selectedTorrents.length}} />\n </FormRow>\n <ModalActions\n actions={[\n {\n checked: SettingStore.floodSettings.deleteTorrentData,\n content: i18n._('torrents.remove.delete.data'),\n id: 'deleteData',\n type: 'checkbox',\n },\n {\n content: i18n._('button.no'),\n triggerDismiss: true,\n type: 'tertiary',\n },\n {\n content: i18n._('button.yes'),\n isLoading: isRemoving,\n submit: true,\n type: 'primary',\n },\n ]}\n />\n </Form>\n </div>\n }\n />\n );\n};\n\nexport default RemoveTorrentsModal;\n","import {FC, useRef, useState} from 'react';\nimport {useLingui} from '@lingui/react';\n\nimport {Form, FormHandle, FormRow} from '@client/ui';\nimport TorrentActions from '@client/actions/TorrentActions';\nimport TorrentStore from '@client/stores/TorrentStore';\n\nimport Modal from '../Modal';\nimport TagSelect from '../../general/form-elements/TagSelect';\n\nconst SetTagsModal: FC = () => {\n const formRef = useRef<FormHandle>(null);\n const {i18n} = useLingui();\n const [isSettingTags, setIsSettingTags] = useState<boolean>(false);\n\n return (\n <Modal\n heading={i18n._('torrents.set.tags.heading')}\n content={\n <div className=\"modal__content inverse\">\n <Form ref={formRef}>\n <FormRow>\n <TagSelect\n defaultValue={TorrentStore.selectedTorrents\n .map((hash: string) => TorrentStore.torrents[hash].tags)[0]\n .slice()}\n id=\"tags\"\n placeholder={i18n._('torrents.set.tags.enter.tags')}\n />\n </FormRow>\n </Form>\n </div>\n }\n actions={[\n {\n content: i18n._('button.cancel'),\n clickHandler: null,\n triggerDismiss: true,\n type: 'tertiary',\n },\n {\n content: i18n._('torrents.set.tags.button.set'),\n clickHandler: () => {\n if (formRef.current == null) {\n return;\n }\n\n const {selectedTorrents} = TorrentStore;\n const formData = formRef.current.getFormData() as {tags: string};\n const tags = formData.tags ? formData.tags.split(',').filter((tag) => !!tag) : [];\n\n setIsSettingTags(true);\n\n if (selectedTorrents?.length > 0) {\n TorrentActions.setTags({\n hashes: selectedTorrents as [string, ...string[]],\n tags,\n });\n }\n },\n isLoading: isSettingTags,\n triggerDismiss: false,\n type: 'primary',\n },\n ]}\n />\n );\n};\n\nexport default SetTagsModal;\n","import {FC, useEffect, useRef, useState} from 'react';\nimport {useLingui} from '@lingui/react';\n\nimport {Form, FormHandle, FormRow, Textbox} from '@client/ui';\nimport TorrentActions from '@client/actions/TorrentActions';\nimport TorrentStore from '@client/stores/TorrentStore';\nimport UIStore from '@client/stores/UIStore';\n\nimport {TorrentTrackerType} from '@shared/types/TorrentTracker';\n\nimport Modal from '../Modal';\nimport TextboxRepeater, {getTextArray} from '../../general/form-elements/TextboxRepeater';\n\nconst SetTrackersModal: FC = () => {\n const formRef = useRef<FormHandle>(null);\n const {i18n} = useLingui();\n const [isSettingTrackers, setIsSettingTrackers] = useState<boolean>(false);\n const [trackerState, setTrackerState] = useState<{\n isLoadingTrackers: boolean;\n trackerURLs: Array<string>;\n }>({\n isLoadingTrackers: true,\n trackerURLs: [],\n });\n\n useEffect(() => {\n TorrentActions.fetchTorrentTrackers(TorrentStore.selectedTorrents[0]).then((trackers) => {\n if (trackers != null) {\n setTrackerState({\n isLoadingTrackers: false,\n trackerURLs: trackers\n .filter((tracker) => tracker.type !== TorrentTrackerType.DHT)\n .map((tracker) => tracker.url),\n });\n }\n });\n }, []);\n\n return (\n <Modal\n heading={i18n._('torrents.set.trackers.heading')}\n content={\n <div className=\"modal__content inverse\">\n <Form ref={formRef}>\n {trackerState.isLoadingTrackers ? (\n <FormRow>\n <Textbox id=\"loading\" placeholder={i18n._('torrents.set.trackers.loading.trackers')} disabled />\n </FormRow>\n ) : (\n <TextboxRepeater\n id=\"trackers\"\n placeholder={i18n._('torrents.set.trackers.enter.tracker')}\n defaultValues={\n trackerState.trackerURLs.length === 0\n ? undefined\n : trackerState.trackerURLs.map((url, index) => ({\n id: index,\n value: url,\n }))\n }\n />\n )}\n </Form>\n </div>\n }\n actions={[\n {\n clickHandler: null,\n content: i18n._('button.cancel'),\n triggerDismiss: true,\n type: 'tertiary',\n },\n {\n clickHandler: () => {\n if (formRef.current == null || isSettingTrackers || trackerState.isLoadingTrackers) {\n return;\n }\n\n setIsSettingTrackers(true);\n\n const formData = formRef.current.getFormData() as Record<string, string>;\n const trackers = getTextArray(formData, 'trackers').filter((tracker) => tracker !== '');\n\n TorrentActions.setTrackers({\n hashes: TorrentStore.selectedTorrents,\n trackers,\n }).then(() => {\n setIsSettingTrackers(false);\n UIStore.setActiveModal(null);\n });\n },\n content: i18n._('torrents.set.trackers.button.set'),\n isLoading: isSettingTrackers || trackerState.isLoadingTrackers,\n triggerDismiss: false,\n type: 'primary',\n },\n ]}\n />\n );\n};\n\nexport default SetTrackersModal;\n","import {FC, Suspense} from 'react';\n\nimport Markdown from 'react-markdown';\n\nimport packageJSON from '../../../../../../package.json';\n\nimport AboutMarkdown from '../../../../ABOUT.md';\n\nconst FLOOD_PROJECT_URL = 'https://github.com/jesec/flood';\n\nconst versioned = AboutMarkdown.replaceAll('<FloodVersion />', packageJSON.version).replaceAll(\n '<CommitBadge />',\n packageJSON.version.length > 8\n ? // If user is on a rolling build, display latest version of rolling build.\n `![${FLOOD_PROJECT_URL}](\"https://img.shields.io/npm/v/@jesec/flood?label=HEAD\" \"Latest version of rolling build\")`\n : // If user is on a released build, display commits to project made since user's version.\n `![${FLOOD_PROJECT_URL}](https://img.shields.io/github/commits-since/jesec/flood/v${packageJSON.version} \"Commits since user's version\")`,\n);\n\nconst AboutTab: FC = () => (\n <Suspense fallback={null}>\n <Markdown>{versioned}</Markdown>\n </Suspense>\n);\n\nexport default AboutTab;\n","export default \"# Flood <FloodVersion />\\n\\n[![Latest release badge](https://img.shields.io/npm/v/flood?label=Latest%20Release)](https://www.npmjs.com/flood) <CommitBadge />\\n\\n[![Github Actions build status badge](https://github.com/jesec/flood/actions/workflows/build.yml/badge.svg)](https://github.com/jesec/flood/actions/workflows/build.yml) [![Crowdin](https://badges.crowdin.net/flood/localized.svg)](https://crowdin.com/project/flood) [![Discord server badge](https://img.shields.io/discord/418267176873623553.svg?style=flat-square)](https://discord.gg/Z7yR5Uf)\\n\\nFlood is a monitoring service for various torrent clients. It's a Node.js service that communicates with your favorite torrent client and serves a decent web UI for administration. This project is based on the [original Flood project](https://github.com/Flood-UI/flood).\\n\\n#### Feedback\\n\\nIf you have a specific issue or bug, please file a [GitHub issue](https://github.com/jesec/flood/issues). Please join the [Flood Discord server](https://discord.gg/Z7yR5Uf) to discuss feature requests and implementation details.\\n\\n#### More Information\\n\\nCheck out the [Wiki](https://github.com/jesec/flood/wiki) for more information.\\n\";","import classnames from 'classnames';\nimport {CSSTransition, TransitionGroup} from 'react-transition-group';\nimport {FC, useEffect, useRef, useState} from 'react';\nimport {observer} from 'mobx-react-lite';\nimport {Trans, useLingui} from '@lingui/react';\n\nimport {Button, Checkbox, Form, FormHandle, FormError, FormRowItem, FormRow, LoadingRing, Textbox} from '@client/ui';\nimport {Close} from '@client/ui/icons';\nimport AuthActions from '@client/actions/AuthActions';\nimport AuthStore from '@client/stores/AuthStore';\n\nimport {AccessLevel} from '@shared/schema/constants/Auth';\n\nimport type {Credentials} from '@shared/schema/Auth';\nimport type {ClientConnectionSettings} from '@shared/schema/ClientConnectionSettings';\n\nimport ClientConnectionSettingsForm from '../../general/connection-settings/ClientConnectionSettingsForm';\nimport ModalFormSectionHeader from '../ModalFormSectionHeader';\n\ninterface AuthTabFormData {\n username: string;\n password: string;\n isAdmin: boolean;\n}\n\nconst AuthTab: FC = observer(() => {\n const formRef = useRef<FormHandle>(null);\n const clientConnectionSettingsRef = useRef<ClientConnectionSettings | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [isUserListFetched, setIsUserListFetched] = useState<boolean>(false);\n const [isSubmitting, setIsSubmitting] = useState<boolean>(false);\n const {i18n} = useLingui();\n\n useEffect(() => {\n if (AuthStore.currentUser.isAdmin) {\n AuthActions.fetchUsers().then(() => {\n setIsUserListFetched(true);\n });\n }\n }, []);\n\n if (!AuthStore.currentUser.isAdmin) {\n return (\n <Form>\n <ModalFormSectionHeader>\n <Trans id=\"auth.user.accounts\" />\n </ModalFormSectionHeader>\n <FormRow>\n <FormError>\n <Trans id=\"auth.message.not.admin\" />\n </FormError>\n </FormRow>\n </Form>\n );\n }\n\n const isLoading = !isUserListFetched && AuthStore.users.length === 0;\n const interactiveListClasses = classnames('interactive-list', {\n 'interactive-list--loading': isLoading,\n });\n\n return (\n <Form\n onSubmit={() => {\n if (formRef.current == null || clientConnectionSettingsRef.current == null) {\n return;\n }\n\n const formData = formRef.current.getFormData() as Partial<AuthTabFormData>;\n\n if (formData.username == null || formData.username === '') {\n setError('auth.error.username.empty');\n } else if (formData.password == null || formData.password === '') {\n setError('auth.error.password.empty');\n } else {\n setIsSubmitting(true);\n\n const connectionSettings = clientConnectionSettingsRef.current;\n if (connectionSettings == null) {\n setError('connection.settings.error.empty');\n setIsSubmitting(false);\n return;\n }\n\n AuthActions.createUser({\n username: formData.username,\n password: formData.password,\n client: connectionSettings,\n level: formData.isAdmin === true ? AccessLevel.ADMINISTRATOR : AccessLevel.USER,\n })\n .then(\n () => {\n if (formRef.current != null) {\n formRef.current.resetForm();\n }\n setError(null);\n setIsSubmitting(false);\n },\n () => {\n setError('general.error.unknown');\n setIsSubmitting(false);\n },\n )\n .then(AuthActions.fetchUsers);\n }\n }}\n ref={formRef}\n >\n <ModalFormSectionHeader>\n <Trans id=\"auth.user.accounts\" />\n </ModalFormSectionHeader>\n <FormRow>\n <FormRowItem>\n <ul className={interactiveListClasses}>\n <TransitionGroup>\n {isLoading && (\n <CSSTransition classNames=\"interactive-list__loading-indicator\" timeout={{enter: 250, exit: 250}}>\n <div className=\"interactive-list__loading-indicator\" key=\"loading-indicator\">\n <LoadingRing />\n </div>\n </CSSTransition>\n )}\n </TransitionGroup>\n {AuthStore.users\n .slice()\n .sort((a: Credentials, b: Credentials) => a.username.localeCompare(b.username))\n .map((user: Credentials) => {\n const isCurrentUser = user.username === AuthStore.currentUser.username;\n let badge = null;\n let removeIcon = null;\n\n if (!isCurrentUser) {\n removeIcon = (\n <button\n className=\"interactive-list__icon interactive-list__icon--action interactive-list__icon--action--warning\"\n type=\"button\"\n onClick={() => AuthActions.deleteUser(user.username).then(AuthActions.fetchUsers)}\n >\n <Close />\n </button>\n );\n } else {\n badge = (\n <span className=\"interactive-list__label__tag tag\">\n <Trans id=\"auth.current.user\" />\n </span>\n );\n }\n\n const classes = classnames('interactive-list__item', {\n 'interactive-list__item--disabled': isCurrentUser,\n });\n\n return (\n <li className={classes} key={user.username}>\n <span className=\"interactive-list__label\">\n <div className=\"interactive-list__label__text\">{user.username}</div>\n {badge}\n </span>\n {removeIcon}\n </li>\n );\n })}\n </ul>\n </FormRowItem>\n </FormRow>\n <ModalFormSectionHeader>\n <Trans id=\"auth.add.user\" />\n </ModalFormSectionHeader>\n {error && (\n <FormRow>\n <FormError>{i18n._(error)}</FormError>\n </FormRow>\n )}\n <FormRow>\n <Textbox\n id=\"username\"\n label={<Trans id=\"auth.username\" />}\n placeholder={i18n._('auth.username')}\n autoComplete=\"username\"\n />\n <Textbox\n id=\"password\"\n label={<Trans id=\"auth.password\" />}\n placeholder={i18n._('auth.password')}\n autoComplete=\"new-password\"\n />\n <Checkbox grow={false} id=\"isAdmin\" labelOffset matchTextboxHeight>\n <Trans id=\"auth.admin\" />\n </Checkbox>\n </FormRow>\n <ClientConnectionSettingsForm\n onSettingsChange={(settings) => {\n clientConnectionSettingsRef.current = settings;\n }}\n />\n <p />\n <FormRow justify=\"end\">\n <Button isLoading={isSubmitting} priority=\"primary\" type=\"submit\">\n <Trans id=\"button.add\" />\n </Button>\n </FormRow>\n </Form>\n );\n});\n\nexport default AuthTab;\n","import {FormEvent} from 'react';\n\nimport type {ClientSetting, ClientSettings} from '@shared/types/ClientSettings';\n\nimport SettingStore from '../../../stores/SettingStore';\n\nexport const getChangedClientSetting = <T extends ClientSetting>(\n changedClientSettings: Partial<ClientSettings>,\n property: T,\n): ClientSettings[T] | undefined => {\n if (changedClientSettings[property] != null) {\n return changedClientSettings[property] as ClientSettings[T];\n }\n\n return SettingStore.clientSettings?.[property];\n};\n\nexport const handleClientSettingChange = (event: FormEvent<HTMLFormElement> | Event): Partial<ClientSettings> => {\n const inputElement = event.target as HTMLInputElement;\n const property = inputElement.name as ClientSetting;\n const {value, type, checked} = inputElement;\n\n let changedClientSetting: Partial<ClientSettings> = {};\n if (type === 'checkbox') {\n changedClientSetting = {[property]: checked};\n } else {\n changedClientSetting = {[property]: value};\n }\n\n return changedClientSetting;\n};\n","import {FC, FormEvent, useState} from 'react';\nimport {Trans} from '@lingui/react';\n\nimport {Form, FormRow, Textbox} from '@client/ui';\nimport SettingStore from '@client/stores/SettingStore';\n\nimport {FloodSettings} from '@shared/types/FloodSettings';\nimport {ClientSettings} from '@shared/types/ClientSettings';\n\nimport {getChangedClientSetting, handleClientSettingChange} from './SettingsUtils';\nimport ModalFormSectionHeader from '../ModalFormSectionHeader';\n\nconst processSpeedsForDisplay = (speeds: number[]): string | undefined => {\n if (!speeds || speeds.length === 0) {\n return undefined;\n }\n\n return speeds.join(', ');\n};\n\nconst processSpeedsForSave = (speeds = ''): number[] => {\n if (speeds === '') {\n return [];\n }\n\n return speeds\n .replace(/\\s/g, '')\n .split(',')\n .map((speed) => Number(speed));\n};\n\ninterface BandwidthTabProps {\n onSettingsChange: (changeSettings: Partial<FloodSettings>) => void;\n onClientSettingsChange: (changeSettings: Partial<ClientSettings>) => void;\n}\n\nconst BandwidthTab: FC<BandwidthTabProps> = ({onSettingsChange, onClientSettingsChange}: BandwidthTabProps) => {\n const [changedClientSettings, setChangedClientSettings] = useState<Partial<ClientSettings>>({});\n\n return (\n <Form\n onChange={({event, formData}: {event: Event | FormEvent<HTMLFormElement>; formData: Record<string, unknown>}) => {\n const inputElement = event.target as HTMLInputElement;\n\n if (inputElement.name === 'dropdownPresetDownload' || inputElement.name === 'dropdownPresetUpload') {\n onSettingsChange({\n speedLimits: {\n download: processSpeedsForSave(formData.dropdownPresetDownload as string),\n upload: processSpeedsForSave(formData.dropdownPresetUpload as string),\n },\n });\n\n return;\n }\n\n const newChangedClientSettings = {\n ...changedClientSettings,\n ...handleClientSettingChange(event),\n };\n\n setChangedClientSettings(newChangedClientSettings);\n onClientSettingsChange(newChangedClientSettings);\n }}\n >\n <ModalFormSectionHeader>\n <Trans id=\"settings.bandwidth.transferrate.heading\" />\n </ModalFormSectionHeader>\n <FormRow>\n <Textbox\n defaultValue={\n SettingStore.floodSettings.speedLimits != null\n ? processSpeedsForDisplay(SettingStore.floodSettings.speedLimits.download)\n : 0\n }\n label={<Trans id=\"settings.bandwidth.transferrate.dropdown.preset.download.label\" />}\n id=\"dropdownPresetDownload\"\n />\n </FormRow>\n <FormRow>\n <Textbox\n defaultValue={\n SettingStore.floodSettings.speedLimits != null\n ? processSpeedsForDisplay(SettingStore.floodSettings.speedLimits.upload)\n : 0\n }\n label={<Trans id=\"settings.bandwidth.transferrate.dropdown.preset.upload.label\" />}\n id=\"dropdownPresetUpload\"\n />\n </FormRow>\n <FormRow>\n <Textbox\n defaultValue={getChangedClientSetting(changedClientSettings, 'throttleGlobalDownSpeed')}\n label={\n <div>\n <Trans id=\"settings.bandwidth.transferrate.global.throttle.download\" /> <em className=\"unit\">(B/s)</em>\n </div>\n }\n id=\"throttleGlobalDownSpeed\"\n />\n <Textbox\n defaultValue={getChangedClientSetting(changedClientSettings, 'throttleGlobalUpSpeed')}\n label={\n <div>\n <Trans id=\"settings.bandwidth.transferrate.global.throttle.upload\" /> <em className=\"unit\">(B/s)</em>\n </div>\n }\n id=\"throttleGlobalUpSpeed\"\n />\n </FormRow>\n <ModalFormSectionHeader>\n <Trans id=\"settings.bandwidth.slots.heading\" />\n </ModalFormSectionHeader>\n <FormRow>\n <Textbox\n defaultValue={getChangedClientSetting(changedClientSettings, 'throttleMaxUploads')}\n label={<Trans id=\"settings.bandwidth.slots.upload.label\" />}\n id=\"throttleMaxUploads\"\n />\n <Textbox\n defaultValue={getChangedClientSetting(changedClientSettings, 'throttleMaxUploadsGlobal')}\n label={<Trans id=\"settings.bandwidth.slots.upload.global.label\" />}\n id=\"throttleMaxUploadsGlobal\"\n />\n </FormRow>\n <FormRow>\n <Textbox\n defaultValue={getChangedClientSetting(changedClientSettings, 'throttleMaxDownloads')}\n label={<Trans id=\"settings.bandwidth.slots.download.label\" />}\n id=\"throttleMaxDownloads\"\n />\n <Textbox\n defaultValue={getChangedClientSetting(changedClientSettings, 'throttleMaxDownloadsGlobal')}\n label={<Trans id=\"settings.bandwidth.slots.download.global.label\" />}\n id=\"throttleMaxDownloadsGlobal\"\n />\n </FormRow>\n </Form>\n );\n};\n\nexport default BandwidthTab;\n","import {FC, useState} from 'react';\nimport {Trans} from '@lingui/react';\n\nimport {Checkbox, Form, FormRow, Textbox} from '@client/ui';\n\nimport {ClientSettings} from '@shared/types/ClientSettings';\n\nimport {getChangedClientSetting, handleClientSettingChange} from './SettingsUtils';\nimport ModalFormSectionHeader from '../ModalFormSectionHeader';\n\ninterface ConnectivityTabProps {\n onClientSettingsChange: (changeSettings: Partial<ClientSettings>) => void;\n}\n\nconst ConnectivityTab: FC<ConnectivityTabProps> = ({onClientSettingsChange}: ConnectivityTabProps) => {\n const [changedClientSettings, setChangedClientSettings] = useState<Partial<ClientSettings>>({});\n\n return (\n <Form\n onChange={({event}) => {\n const newChangedClientSettings = {\n ...changedClientSettings,\n ...handleClientSettingChange(event),\n };\n\n setChangedClientSettings(newChangedClientSettings);\n onClientSettingsChange(newChangedClientSettings);\n }}\n >\n <ModalFormSectionHeader>\n <Trans id=\"settings.connectivity.incoming.heading\" />\n </ModalFormSectionHeader>\n <FormRow>\n <Textbox\n defaultValue={getChangedClientSetting(changedClientSettings, 'networkPortRange')}\n id=\"networkPortRange\"\n label={<Trans id=\"settings.connectivity.port.range.label\" />}\n width=\"one-quarter\"\n />\n <Checkbox\n defaultChecked={getChangedClientSetting(changedClientSettings, 'networkPortRandom')}\n grow={false}\n id=\"networkPortRandom\"\n labelOffset\n matchTextboxHeight\n >\n <Trans id=\"settings.connectivity.port.randomize.label\" />\n </Checkbox>\n <Checkbox\n defaultChecked={getChangedClientSetting(changedClientSettings, 'networkPortOpen')}\n grow={false}\n id=\"networkPortOpen\"\n labelOffset\n matchTextboxHeight\n >\n <Trans id=\"settings.connectivity.port.open.label\" />\n </Checkbox>\n </FormRow>\n <FormRow>\n <Textbox\n defaultValue={getChangedClientSetting(changedClientSettings, 'networkLocalAddress')}\n id=\"networkLocalAddress\"\n label={<Trans id=\"settings.connectivity.ip.hostname.label\" />}\n />\n <Textbox\n defaultValue={getChangedClientSetting(changedClientSettings, 'networkHttpMaxOpen')}\n id=\"networkHttpMaxOpen\"\n label={<Trans id=\"settings.connectivity.max.http.connections\" />}\n />\n </FormRow>\n <ModalFormSectionHeader>\n <Trans id=\"settings.connectivity.dpd.heading\" />\n </ModalFormSectionHeader>\n <FormRow>\n <Textbox\n defaultValue={getChangedClientSetting(changedClientSettings, 'dhtPort')}\n id=\"dhtPort\"\n label={<Trans id=\"settings.connectivity.dht.port.label\" />}\n width=\"one-quarter\"\n />\n <Checkbox\n defaultChecked={getChangedClientSetting(changedClientSettings, 'dht')}\n grow={false}\n id=\"dht\"\n labelOffset\n matchTextboxHeight\n >\n <Trans id=\"settings.connectivity.dht.label\" />\n </Checkbox>\n <Checkbox\n defaultChecked={getChangedClientSetting(changedClientSettings, 'protocolPex')}\n grow={false}\n id=\"protocolPex\"\n labelOffset\n matchTextboxHeight\n >\n <Trans id=\"settings.connectivity.peer.exchange.label\" />\n </Checkbox>\n </FormRow>\n <ModalFormSectionHeader>\n <Trans id=\"settings.connectivity.peers.heading\" />\n </ModalFormSectionHeader>\n <FormRow>\n <Textbox\n defaultValue={getChangedClientSetting(changedClientSettings, 'throttleMinPeersNormal')}\n id=\"throttleMinPeersNormal\"\n label={<Trans id=\"settings.connectivity.peers.min.label\" />}\n />\n <Textbox\n defaultValue={getChangedClientSetting(changedClientSettings, 'throttleMaxPeersNormal')}\n id=\"throttleMaxPeersNormal\"\n label={<Trans id=\"settings.connectivity.peers.max.label\" />}\n />\n </FormRow>\n <FormRow>\n <Textbox\n defaultValue={getChangedClientSetting(changedClientSettings, 'throttleMinPeersSeed')}\n id=\"throttleMinPeersSeed\"\n label={<Trans id=\"settings.connectivity.peers.seeding.min.label\" />}\n />\n <Textbox\n defaultValue={getChangedClientSetting(changedClientSettings, 'throttleMaxPeersSeed')}\n id=\"throttleMaxPeersSeed\"\n label={<Trans id=\"settings.connectivity.peers.seeding.max.label\" />}\n />\n </FormRow>\n <FormRow>\n <Textbox\n defaultValue={getChangedClientSetting(changedClientSettings, 'trackersNumWant')}\n id=\"trackersNumWant\"\n label={<Trans id=\"settings.connectivity.peers.desired.label\" />}\n width=\"one-half\"\n />\n </FormRow>\n </Form>\n );\n};\n\nexport default ConnectivityTab;\n","import classnames from 'classnames';\nimport {CSS} from '@dnd-kit/utilities';\nimport {FC, ReactNode} from 'react';\nimport {useSortable} from '@dnd-kit/sortable';\n\nimport {Lock} from '@client/ui/icons';\n\ninterface SortableListItemProps {\n children?: ReactNode;\n id: string;\n disabled?: boolean;\n}\n\nconst SortableListItem: FC<SortableListItemProps> = (props: SortableListItemProps) => {\n const {children, id, disabled} = props;\n const {attributes, setNodeRef, listeners, transform, transition, isDragging} = useSortable({id, disabled});\n\n const style = {\n transform: CSS.Transform.toString(transform),\n transition,\n };\n\n return (\n <div\n className={classnames('sortable-list__item', {\n 'sortable-list__item--is-dragging': isDragging,\n 'sortable-list__item--is-locked': disabled,\n })}\n ref={setNodeRef}\n style={style}\n {...attributes}\n {...listeners}\n >\n {disabled ? <Lock /> : null}\n {children}\n </div>\n );\n};\n\nexport default SortableListItem;\n","import {arrayMove, SortableContext, verticalListSortingStrategy} from '@dnd-kit/sortable';\nimport classnames from 'classnames';\nimport {DndContext, KeyboardSensor, MouseSensor, TouchSensor, useSensor} from '@dnd-kit/core';\nimport {FC, MouseEvent, ReactNode, useState} from 'react';\nimport {restrictToParentElement, restrictToVerticalAxis} from '@dnd-kit/modifiers';\nimport {css} from '@client/styled-system/css';\n\nimport SortableListItem from './SortableListItem';\n\ninterface SortableListProps {\n className: string;\n lockedIDs: Array<string>;\n items: string[];\n renderItem: (id: string, index: number) => ReactNode;\n onMouseDown?: (event: MouseEvent) => void;\n onDrop?: (items: this['items']) => void;\n}\n\nconst SortableList: FC<SortableListProps> = ({\n className,\n items,\n lockedIDs,\n renderItem,\n onMouseDown,\n onDrop,\n}: SortableListProps) => {\n const [currentItems, setCurrentItems] = useState(items);\n const classes = classnames('sortable-list', className);\n\n const keyboardSensor = useSensor(KeyboardSensor);\n const mouseSensor = useSensor(MouseSensor, {activationConstraint: {distance: 10}});\n const touchSensor = useSensor(TouchSensor, {activationConstraint: {distance: 10}});\n\n return (\n <div\n className={css({width: '100%', touchAction: 'none'})}\n role=\"none\"\n onMouseDown={(event) => {\n if (onMouseDown) {\n onMouseDown(event);\n }\n }}\n >\n <DndContext\n sensors={[keyboardSensor, mouseSensor, touchSensor]}\n onDragEnd={({active, over}) => {\n if (over == null) {\n return;\n }\n\n if (active.id === over.id) {\n return;\n }\n\n const newItems = arrayMove(\n items,\n items.findIndex((id) => id === active.id),\n items.findIndex((id) => id === over.id),\n );\n\n setCurrentItems(newItems);\n\n if (onDrop) {\n onDrop(newItems);\n }\n }}\n modifiers={[restrictToVerticalAxis, restrictToParentElement]}\n autoScroll={false}\n >\n <SortableContext items={currentItems} strategy={verticalListSortingStrategy}>\n <ul className={classes}>\n {currentItems.map((id, index) => {\n return (\n <SortableListItem id={id} disabled={lockedIDs.includes(id)} key={id}>\n {renderItem(id, index)}\n </SortableListItem>\n );\n })}\n </ul>\n </SortableContext>\n </DndContext>\n </div>\n );\n};\n\nexport default SortableList;\n","import {FC, useState} from 'react';\nimport {Trans} from '@lingui/react';\n\nimport {Checkbox} from '@client/ui';\nimport DiskUsageStore from '@client/stores/DiskUsageStore';\nimport SettingStore from '@client/stores/SettingStore';\nimport SortableList from '@client/components/general/SortableList';\n\nimport type {FloodSettings} from '@shared/types/FloodSettings';\n\ninterface MountPointsListProps {\n onSettingsChange: (changedSettings: Partial<FloodSettings>) => void;\n}\n\nconst MountPointsList: FC<MountPointsListProps> = ({onSettingsChange}: MountPointsListProps) => {\n const [diskItems, setDiskItems] = useState(\n (() => {\n const {mountPoints} = SettingStore.floodSettings;\n const disks = Object.assign(\n {},\n ...DiskUsageStore.disks.map((disk) => ({\n [disk.target]: disk,\n })),\n );\n\n return mountPoints\n .filter((target) => target in disks)\n .map((target) => ({\n id: target,\n visible: true,\n }))\n .concat(\n Object.keys(disks)\n .filter((target) => !mountPoints.includes(target))\n .map((target) => ({\n id: target,\n visible: false,\n })),\n );\n })(),\n );\n\n const diskItemVisiblity = diskItems.reduce((memo, {id, visible}) => {\n memo[id] = visible;\n return memo;\n }, {} as Record<string, boolean>);\n\n return (\n <SortableList\n className=\"sortable-list--disks\"\n items={diskItems.map(({id}) => id)}\n lockedIDs={[]}\n onDrop={(items) => {\n setDiskItems(items.map((id) => ({id, visible: diskItemVisiblity[id]})));\n }}\n renderItem={(id) => {\n const checkbox = (\n <span className=\"sortable-list__content sortable-list__content--secondary\">\n <Checkbox\n defaultChecked={diskItemVisiblity[id]}\n id={id}\n onClick={(event) => {\n diskItemVisiblity[id] = (event.target as HTMLInputElement).checked;\n\n const newItems = diskItems.map((disk) => {\n if (disk.id === id) {\n return {...disk, visible: (event.target as HTMLInputElement).checked};\n }\n return disk;\n });\n\n onSettingsChange({\n mountPoints: newItems.filter((newItem) => newItem.visible).map((newItem) => newItem.id),\n });\n setDiskItems(newItems);\n }}\n >\n <Trans id=\"settings.diskusage.show\" />\n </Checkbox>\n </span>\n );\n\n const content = (\n <div className=\"sortable-list__content sortable-list__content__wrapper\">\n <span className=\"sortable-list__content sortable-list__content--primary\">\n <div>{id}</div>\n </span>\n {checkbox}\n </div>\n );\n\n return content;\n }}\n />\n );\n};\n\nexport default MountPointsList;\n","import {FC} from 'react';\nimport {Trans} from '@lingui/react';\n\nimport {Form, FormRow} from '@client/ui';\n\nimport type {FloodSettings} from '@shared/types/FloodSettings';\n\nimport ModalFormSectionHeader from '../ModalFormSectionHeader';\nimport MountPointsList from './lists/MountPointsList';\n\ninterface DiskUsageTabProps {\n onSettingsChange: (changedSettings: Partial<FloodSettings>) => void;\n}\n\nconst DiskUsageTab: FC<DiskUsageTabProps> = ({onSettingsChange}: DiskUsageTabProps) => (\n <Form>\n <ModalFormSectionHeader>\n <Trans id=\"settings.diskusage.mount.points\" />\n </ModalFormSectionHeader>\n <FormRow>\n <MountPointsList onSettingsChange={onSettingsChange} />\n </FormRow>\n </Form>\n);\n\nexport default DiskUsageTab;\n","import {FC, useState} from 'react';\nimport {Trans} from '@lingui/react';\n\nimport {Checkbox, Form, FormRow, Textbox} from '@client/ui';\n\nimport {ClientSettings} from '@shared/types/ClientSettings';\n\nimport {getChangedClientSetting, handleClientSettingChange} from './SettingsUtils';\nimport ModalFormSectionHeader from '../ModalFormSectionHeader';\n\ninterface ResourcesTabProps {\n onClientSettingsChange: (changeSettings: Partial<ClientSettings>) => void;\n}\n\nconst ResourcesTab: FC<ResourcesTabProps> = ({onClientSettingsChange}: ResourcesTabProps) => {\n const [changedClientSettings, setChangedClientSettings] = useState<Partial<ClientSettings>>({});\n\n return (\n <Form\n onChange={({event}) => {\n const newChangedClientSettings = {\n ...changedClientSettings,\n ...handleClientSettingChange(event),\n };\n\n setChangedClientSettings(newChangedClientSettings);\n onClientSettingsChange(newChangedClientSettings);\n }}\n >\n <ModalFormSectionHeader>\n <Trans id=\"settings.resources.disk.heading\" />\n </ModalFormSectionHeader>\n <FormRow>\n <Textbox\n defaultValue={getChangedClientSetting(changedClientSettings, 'directoryDefault')}\n id=\"directoryDefault\"\n label={<Trans id=\"settings.resources.disk.download.location.label\" />}\n />\n </FormRow>\n <FormRow>\n <Textbox\n defaultValue={getChangedClientSetting(changedClientSettings, 'networkMaxOpenFiles')}\n id=\"networkMaxOpenFiles\"\n label={<Trans id=\"settings.resources.max.open.files\" />}\n width=\"one-half\"\n />\n <Checkbox\n defaultChecked={getChangedClientSetting(changedClientSettings, 'piecesHashOnCompletion')}\n grow={false}\n id=\"piecesHashOnCompletion\"\n labelOffset\n matchTextboxHeight\n >\n <Trans id=\"settings.resources.disk.check.hash.label\" />\n </Checkbox>\n </FormRow>\n <ModalFormSectionHeader>\n <Trans id=\"settings.resources.memory.heading\" />\n </ModalFormSectionHeader>\n <FormRow>\n <Textbox\n defaultValue={getChangedClientSetting(changedClientSettings, 'piecesMemoryMax')}\n id=\"piecesMemoryMax\"\n label={\n <div>\n <Trans id=\"settings.resources.memory.max.label\" /> <em className=\"unit\">(MB)</em>\n </div>\n }\n width=\"one-half\"\n />\n </FormRow>\n </Form>\n );\n};\n\nexport default ResourcesTab;\n","import classnames from 'classnames';\nimport {FC} from 'react';\nimport {Trans} from '@lingui/react';\n\nimport {css} from '@client/styled-system/css';\nimport {Checkbox} from '@client/ui';\nimport {Lock} from '@client/ui/icons';\n\ninterface ToggleListProps {\n className?: string;\n checkboxLabel?: string;\n items: Array<{\n id?: string;\n label: string;\n isLocked?: boolean;\n defaultChecked: boolean;\n onClick?: (checked: boolean) => void;\n }>;\n}\n\nconst ToggleList: FC<ToggleListProps> = ({className, checkboxLabel, items}: ToggleListProps) => (\n <div className={css({width: '100%'})} role=\"none\">\n <ul\n className={classnames(\n 'sortable-list',\n className,\n css({\n '& .sortable-list__item': {\n cursor: 'default',\n },\n }),\n )}\n >\n {items.map((item) => {\n const {id, label, isLocked = false, defaultChecked, onClick} = item;\n return (\n <li\n className={classnames('sortable-list__item', {\n 'sortable-list__item--is-locked': isLocked,\n })}\n key={id || label}\n >\n {isLocked ? <Lock /> : null}\n <div className=\"sortable-list__content sortable-list__content__wrapper\">\n <span className=\"sortable-list__content sortable-list__content--primary\">\n <Trans id={label} />\n </span>\n {isLocked ? null : (\n <span className=\"sortable-list__content sortable-list__content--secondary\">\n <Checkbox\n defaultChecked={defaultChecked}\n id={id}\n onClick={(event) => onClick?.((event.target as HTMLInputElement).checked)}\n >\n {checkboxLabel && <Trans id={checkboxLabel} />}\n </Checkbox>\n </span>\n )}\n </div>\n </li>\n );\n })}\n </ul>\n </div>\n);\n\nexport default ToggleList;\n","import {FC, useRef} from 'react';\n\nimport SettingStore from '@client/stores/SettingStore';\nimport ToggleList from '@client/components/general/ToggleList';\n\nimport type {FloodSettings} from '@shared/types/FloodSettings';\n\ninterface MiscUISettingsListProps {\n onSettingsChange: (changedSettings: Partial<FloodSettings>) => void;\n}\n\nconst MiscUISettingsList: FC<MiscUISettingsListProps> = ({onSettingsChange}: MiscUISettingsListProps) => {\n const changedUIPageTitleSpeedEnabledRef = useRef<FloodSettings['UIPageTitleSpeedEnabled']>(\n SettingStore.floodSettings.UIPageTitleSpeedEnabled,\n );\n\n return (\n <ToggleList\n items={[\n {\n label: 'settings.ui.page.title.speed',\n defaultChecked: changedUIPageTitleSpeedEnabledRef.current,\n onClick: () => {\n changedUIPageTitleSpeedEnabledRef.current = !changedUIPageTitleSpeedEnabledRef.current;\n onSettingsChange({UIPageTitleSpeedEnabled: changedUIPageTitleSpeedEnabledRef.current});\n },\n },\n ]}\n />\n );\n};\n\nexport default MiscUISettingsList;\n","import {FC, useRef} from 'react';\n\nimport SettingStore from '@client/stores/SettingStore';\nimport ToggleList from '@client/components/general/ToggleList';\nimport TorrentContextMenuActions from '@client/constants/TorrentContextMenuActions';\n\nimport defaultFloodSettings from '@shared/constants/defaultFloodSettings';\n\nimport type {TorrentContextMenuAction} from '@client/constants/TorrentContextMenuActions';\n\nimport type {FloodSettings} from '@shared/types/FloodSettings';\n\ninterface TorrentContextMenuActionsListProps {\n onSettingsChange: (changedSettings: Partial<FloodSettings>) => void;\n}\n\nconst TorrentContextMenuActionsList: FC<TorrentContextMenuActionsListProps> = ({\n onSettingsChange,\n}: TorrentContextMenuActionsListProps) => {\n const changedTorrentContextMenuActionsRef = useRef<FloodSettings['torrentContextMenuActions']>(\n defaultFloodSettings.torrentContextMenuActions.map(({id, visible: defaultVisible}) => ({\n id,\n visible:\n SettingStore.floodSettings.torrentContextMenuActions.find((setting) => setting.id === id)?.visible ??\n defaultVisible,\n })),\n );\n\n return (\n <ToggleList\n checkboxLabel=\"settings.ui.torrent.context.menu.items.show\"\n items={Object.keys(TorrentContextMenuActions).map((action) => ({\n label: TorrentContextMenuActions[action as TorrentContextMenuAction],\n isLocked: action === 'start' || action === 'stop' || action === 'setTaxonomy' || action === 'torrentDetails',\n defaultChecked: changedTorrentContextMenuActionsRef.current.some(\n (setting) => setting.id === action && setting.visible,\n ),\n onClick: () => {\n const currentSetting = changedTorrentContextMenuActionsRef.current.find((setting) => setting.id === action);\n if (currentSetting != null) {\n currentSetting.visible = !currentSetting.visible;\n }\n onSettingsChange({torrentContextMenuActions: changedTorrentContextMenuActionsRef.current});\n },\n }))}\n />\n );\n};\n\nexport default TorrentContextMenuActionsList;\n","import {FC, useRef, useState} from 'react';\nimport {Trans} from '@lingui/react';\n\nimport {Checkbox} from '@client/ui';\nimport {Error} from '@client/ui/icons';\nimport SettingStore from '@client/stores/SettingStore';\nimport TorrentListColumns from '@client/constants/TorrentListColumns';\n\nimport type {FloodSettings} from '@shared/types/FloodSettings';\nimport type {TorrentListColumn} from '@client/constants/TorrentListColumns';\n\nimport SortableList from '../../../general/SortableList';\nimport Tooltip, {TooltipHandle} from '../../../general/Tooltip';\n\ninterface TorrentListColumnsListProps {\n torrentListViewSize: FloodSettings['torrentListViewSize'];\n onSettingsChange: (changedSettings: Partial<FloodSettings>) => void;\n}\n\nconst TorrentListColumnsList: FC<TorrentListColumnsListProps> = ({\n torrentListViewSize,\n onSettingsChange,\n}: TorrentListColumnsListProps) => {\n const tooltipRef = useRef<TooltipHandle>(null);\n\n const [torrentListColumns, setTorrentListColumns] = useState([\n ...SettingStore.floodSettings.torrentListColumns.filter((column) => TorrentListColumns[column.id] != null).slice(),\n ...Object.keys(TorrentListColumns)\n .filter((key) => SettingStore.floodSettings.torrentListColumns.every((column) => column.id !== key))\n .map((newColumn) => ({\n id: newColumn,\n visible: false,\n })),\n ]);\n\n const torrentListColumnVisiblity = torrentListColumns.reduce((memo, {id, visible}) => {\n memo[id] = visible;\n return memo;\n }, {} as Record<string, boolean>);\n\n const lockedIDs =\n torrentListViewSize === 'expanded' ? ['name', 'eta', 'downRate', 'percentComplete', 'downTotal', 'upRate'] : [];\n\n return (\n <SortableList\n className=\"sortable-list--torrent-details\"\n items={torrentListColumns.map(({id}) => id)}\n lockedIDs={lockedIDs}\n onMouseDown={(): void => {\n tooltipRef.current?.dismissTooltip();\n }}\n onDrop={(items) => {\n const newItems = items.map((id) => ({id, visible: torrentListColumnVisiblity[id]}));\n onSettingsChange({torrentListColumns: newItems as FloodSettings['torrentListColumns']});\n setTorrentListColumns(newItems);\n }}\n renderItem={(id, index) => {\n let checkbox = null;\n let warning = null;\n\n if (!lockedIDs.includes(id)) {\n checkbox = (\n <span className=\"sortable-list__content sortable-list__content--secondary\">\n <Checkbox\n defaultChecked={torrentListColumnVisiblity[id]}\n id={id}\n onClick={(event) => {\n torrentListColumnVisiblity[id] = (event.target as HTMLInputElement).checked;\n\n const changedTorrentListColumns = torrentListColumns.map((column) => ({\n id: column.id,\n visible: column.id === id ? (event.target as HTMLInputElement).checked : column.visible,\n }));\n\n setTorrentListColumns(changedTorrentListColumns);\n onSettingsChange({\n torrentListColumns: changedTorrentListColumns as FloodSettings['torrentListColumns'],\n });\n }}\n >\n <Trans id=\"settings.ui.torrent.details.enabled\" />\n </Checkbox>\n </span>\n );\n }\n\n if (id === 'tags' && torrentListViewSize === 'expanded' && index < torrentListColumns.length - 1) {\n const tooltipContent = <Trans id=\"settings.ui.torrent.details.tags.placement\" />;\n\n warning = (\n <Tooltip\n className=\"tooltip tooltip--is-error\"\n content={tooltipContent}\n offset={-5}\n ref={tooltipRef}\n width={200}\n wrapperClassName=\"sortable-list__content sortable-list__content--secondary tooltip__wrapper\"\n wrapText\n >\n <Error />\n </Tooltip>\n );\n }\n\n const content = (\n <div className=\"sortable-list__content sortable-list__content__wrapper\">\n {warning}\n <span className=\"sortable-list__content sortable-list__content--primary\">\n <Trans id={TorrentListColumns[id as TorrentListColumn]} />\n </span>\n {checkbox}\n </div>\n );\n\n return content;\n }}\n />\n );\n};\n\nexport default TorrentListColumnsList;\n","import {FC, useState} from 'react';\nimport {Trans, useLingui} from '@lingui/react';\n\nimport {Form, FormRow, Select, SelectItem, Radio} from '@client/ui';\nimport Languages from '@client/constants/Languages';\nimport SettingStore from '@client/stores/SettingStore';\n\nimport type {Language} from '@client/constants/Languages';\n\nimport type {FloodSettings} from '@shared/types/FloodSettings';\n\nimport ModalFormSectionHeader from '../ModalFormSectionHeader';\nimport MiscUISettingsList from './lists/MiscUISettingsList';\nimport TorrentContextMenuActionsList from './lists/TorrentContextMenuActionsList';\nimport TorrentListColumnsList from './lists/TorrentListColumnsList';\n\ninterface UITabProps {\n onSettingsChange: (changeSettings: Partial<FloodSettings>) => void;\n}\n\nconst UITab: FC<UITabProps> = ({onSettingsChange}: UITabProps) => {\n const {i18n} = useLingui();\n const [torrentListViewSize, setTorrentListViewSize] = useState(SettingStore.floodSettings.torrentListViewSize);\n const [selectedLanguage, setSelectedLanguage] = useState(SettingStore.floodSettings.language);\n const [UITagSelectorMode, setUITagSelectorMode] = useState(SettingStore.floodSettings.UITagSelectorMode);\n\n return (\n <Form\n onChange={({event, formData}) => {\n const inputElement = event.target as HTMLInputElement;\n\n if (inputElement.type === 'radio') {\n setTorrentListViewSize(formData['ui-torrent-size'] as FloodSettings['torrentListViewSize']);\n setUITagSelectorMode(formData['ui-tag-selector-mode'] as FloodSettings['UITagSelectorMode']);\n onSettingsChange({\n torrentListViewSize,\n UITagSelectorMode,\n });\n }\n\n if (inputElement.name === 'language') {\n const newSelectedLanguage = formData.language as FloodSettings['language'];\n setSelectedLanguage(newSelectedLanguage);\n onSettingsChange({\n language: newSelectedLanguage,\n });\n }\n }}\n >\n <ModalFormSectionHeader key=\"locale-header\">\n <Trans id=\"settings.ui.language\" />\n </ModalFormSectionHeader>\n <FormRow key=\"locale-selection\">\n <Select defaultID={selectedLanguage} id=\"language\">\n {Object.keys(Languages).map((languageID) => (\n <SelectItem key={languageID} id={languageID}>\n {languageID === 'auto' ? i18n._(Languages[languageID].id) : (Languages[languageID as Language] as string)}\n </SelectItem>\n ))}\n </Select>\n </FormRow>\n <ModalFormSectionHeader>\n <Trans id=\"settings.ui.tag.selector.mode\" />\n </ModalFormSectionHeader>\n <FormRow>\n <Radio defaultChecked={UITagSelectorMode === 'single'} groupID=\"ui-tag-selector-mode\" id=\"single\" width=\"auto\">\n <Trans id=\"settings.ui.tag.selector.mode.single\" />\n </Radio>\n <Radio defaultChecked={UITagSelectorMode === 'multi'} groupID=\"ui-tag-selector-mode\" id=\"multi\" width=\"auto\">\n <Trans id=\"settings.ui.tag.selector.mode.multi\" />\n </Radio>\n </FormRow>\n <ModalFormSectionHeader>\n <Trans id=\"settings.ui.torrent.list\" />\n </ModalFormSectionHeader>\n <FormRow>\n <Radio defaultChecked={torrentListViewSize === 'expanded'} groupID=\"ui-torrent-size\" id=\"expanded\" width=\"auto\">\n <Trans id=\"settings.ui.torrent.size.expanded\" />\n </Radio>\n <Radio\n defaultChecked={torrentListViewSize === 'condensed'}\n groupID=\"ui-torrent-size\"\n id=\"condensed\"\n width=\"auto\"\n >\n <Trans id=\"settings.ui.torrent.size.condensed\" />\n </Radio>\n </FormRow>\n <ModalFormSectionHeader>\n <Trans id=\"settings.ui.displayed.details\" />\n </ModalFormSectionHeader>\n <FormRow>\n <TorrentListColumnsList torrentListViewSize={torrentListViewSize} onSettingsChange={onSettingsChange} />\n </FormRow>\n <ModalFormSectionHeader>\n <Trans id=\"settings.ui.displayed.context.menu.items\" />\n </ModalFormSectionHeader>\n <FormRow>\n <TorrentContextMenuActionsList onSettingsChange={onSettingsChange} />\n </FormRow>\n <ModalFormSectionHeader>\n <Trans id=\"settings.ui.misc\" />\n </ModalFormSectionHeader>\n <FormRow>\n <MiscUISettingsList onSettingsChange={onSettingsChange} />\n </FormRow>\n </Form>\n );\n};\n\nexport default UITab;\n","import {FC, useState} from 'react';\nimport {observer} from 'mobx-react-lite';\nimport {useLingui} from '@lingui/react';\n\nimport type {ClientSettings} from '@shared/types/ClientSettings';\nimport type {FloodSettings} from '@shared/types/FloodSettings';\n\nimport AboutTab from './AboutTab';\nimport AuthTab from './AuthTab';\nimport BandwidthTab from './BandwidthTab';\nimport ConfigStore from '../../../stores/ConfigStore';\nimport ConnectivityTab from './ConnectivityTab';\nimport ClientActions from '../../../actions/ClientActions';\nimport DiskUsageTab from './DiskUsageTab';\nimport Modal from '../Modal';\nimport ResourcesTab from './ResourcesTab';\nimport SettingActions from '../../../actions/SettingActions';\nimport UITab from './UITab';\nimport UIStore from '../../../stores/UIStore';\n\nconst SettingsModal: FC = observer(() => {\n const {i18n} = useLingui();\n\n const [changedClientSettings, setChangedClientSettings] = useState<Partial<ClientSettings>>({});\n const [changedFloodSettings, setChangedFloodSettings] = useState<Partial<FloodSettings>>({});\n const [isSavingSettings, setSavingSettings] = useState<boolean>(false);\n\n const handleClientSettingsChange = (changedSettings: Partial<ClientSettings>) => {\n setChangedClientSettings({\n ...changedClientSettings,\n ...changedSettings,\n });\n };\n\n const handleFloodSettingsChange = (changedSettings: Partial<FloodSettings>) => {\n setChangedFloodSettings({\n ...changedFloodSettings,\n ...changedSettings,\n });\n };\n\n const tabs = {\n bandwidth: {\n content: BandwidthTab,\n props: {\n onClientSettingsChange: handleClientSettingsChange,\n onSettingsChange: handleFloodSettingsChange,\n },\n label: i18n._('settings.tabs.bandwidth'),\n },\n connectivity: {\n content: ConnectivityTab,\n props: {\n onClientSettingsChange: handleClientSettingsChange,\n },\n label: i18n._('settings.tabs.connectivity'),\n },\n resources: {\n content: ResourcesTab,\n props: {\n onClientSettingsChange: handleClientSettingsChange,\n },\n label: i18n._('settings.tabs.resources'),\n },\n ...(ConfigStore.authMethod !== 'none'\n ? {\n authentication: {\n content: AuthTab,\n label: i18n._('settings.tabs.authentication'),\n },\n }\n : {}),\n ui: {\n content: UITab,\n label: i18n._('settings.tabs.userinterface'),\n props: {\n onSettingsChange: handleFloodSettingsChange,\n },\n },\n diskusage: {\n content: DiskUsageTab,\n label: i18n._('settings.tabs.diskusage'),\n props: {\n onSettingsChange: handleFloodSettingsChange,\n },\n },\n about: {\n content: AboutTab,\n label: i18n._('settings.tabs.about'),\n },\n };\n\n return (\n <Modal\n actions={[\n {\n clickHandler: null,\n content: i18n._('button.cancel'),\n triggerDismiss: true,\n type: 'tertiary',\n },\n {\n clickHandler: () => {\n setSavingSettings(true);\n Promise.all([\n SettingActions.saveSettings(changedFloodSettings, {\n alert: true,\n }),\n ClientActions.saveSettings(changedClientSettings, {\n alert: true,\n }),\n ]).then(() => {\n setSavingSettings(false);\n UIStore.setActiveModal(null);\n });\n },\n isLoading: isSavingSettings,\n content: i18n._('button.save'),\n triggerDismiss: false,\n type: 'primary',\n },\n ]}\n size=\"large\"\n heading={i18n._('settings.tabs.heading')}\n orientation={ConfigStore.isSmallScreen ? 'horizontal' : 'vertical'}\n tabs={tabs}\n />\n );\n});\n\nexport default SettingsModal;\n","import axios, {CancelTokenSource} from 'axios';\nimport {FC, useEffect, useRef, useState} from 'react';\nimport {Trans, useLingui} from '@lingui/react';\n\nimport {Button} from '@client/ui';\nimport {Checkmark, Clipboard} from '@client/ui/icons';\nimport TorrentActions from '@client/actions/TorrentActions';\nimport UIStore from '@client/stores/UIStore';\n\nimport Tooltip from '../../general/Tooltip';\n\nconst TorrentMediainfo: FC = () => {\n const {i18n} = useLingui();\n const cancelToken = useRef<CancelTokenSource>(axios.CancelToken.source());\n const clipboardRef = useRef<HTMLInputElement>(null);\n const [mediainfo, setMediainfo] = useState<string | null>(null);\n const [fetchMediainfoError, setFetchMediainfoError] = useState<Error | null>(null);\n const [isFetchingMediainfo, setIsFetchingMediainfo] = useState<boolean>(true);\n const [isCopiedToClipboard, setIsCopiedToClipboard] = useState<boolean>(false);\n\n useEffect(() => {\n const {current: currentCancelToken} = cancelToken;\n\n if (UIStore.activeModal?.id === 'torrent-details') {\n TorrentActions.fetchMediainfo(UIStore.activeModal?.hash, cancelToken.current.token).then(\n (fetchedMediainfo) => {\n setMediainfo(fetchedMediainfo.output);\n setIsFetchingMediainfo(false);\n },\n (error) => {\n if (!axios.isCancel(error)) {\n setFetchMediainfoError(error.response.data);\n setIsFetchingMediainfo(false);\n }\n },\n );\n }\n\n return () => {\n currentCancelToken.cancel();\n };\n }, []);\n\n let headingMessageId = 'mediainfo.heading';\n if (isFetchingMediainfo) {\n headingMessageId = 'mediainfo.fetching';\n } else if (fetchMediainfoError) {\n headingMessageId = 'mediainfo.execError';\n }\n\n return (\n <div className=\"torrent-details__section mediainfo modal__content--nested-scroll__content\">\n <div className=\"mediainfo__toolbar\">\n <div className=\"mediainfo__toolbar__item\">\n <span className=\"torrent-details__table__heading--tertiary\">\n <Trans id={headingMessageId} />\n </span>\n </div>\n {mediainfo && (\n <Tooltip\n content={i18n._(isCopiedToClipboard ? 'general.clipboard.copied' : 'general.clipboard.copy')}\n wrapperClassName=\"tooltip__wrapper mediainfo__toolbar__item\"\n >\n <Button\n priority=\"tertiary\"\n onClick={() => {\n if (mediainfo != null) {\n if (typeof navigator.clipboard?.writeText === 'function') {\n navigator.clipboard.writeText(mediainfo).then(() => {\n setIsCopiedToClipboard(true);\n });\n } else if (clipboardRef.current != null) {\n clipboardRef.current.value = mediainfo;\n clipboardRef.current.select();\n document.execCommand('copy');\n setIsCopiedToClipboard(true);\n }\n }\n }}\n >\n {isCopiedToClipboard ? <Checkmark /> : <Clipboard />}\n </Button>\n </Tooltip>\n )}\n </div>\n <input ref={clipboardRef} style={{width: '0.1px', height: '1px', position: 'absolute', right: 0}} />\n {fetchMediainfoError ? (\n <pre className=\"mediainfo__output mediainfo__output--error\">{fetchMediainfoError.message}</pre>\n ) : (\n <pre className=\"mediainfo__output\">{mediainfo}</pre>\n )}\n </div>\n );\n};\n\nexport default TorrentMediainfo;\n","import type {TorrentContent, TorrentContentSelection, TorrentContentSelectionTree} from '@shared/types/TorrentContent';\n\nconst selectAll = (tree: TorrentContentSelectionTree, isSelected: boolean): TorrentContentSelectionTree => ({\n ...tree,\n ...(tree.directories != null\n ? {\n directories: Object.assign(\n {},\n ...Object.keys(tree.directories).map((directory) =>\n tree.directories != null\n ? {\n [directory]: selectAll(tree.directories[directory], isSelected),\n }\n : {},\n ),\n ),\n }\n : {}),\n ...(tree.files != null\n ? {\n files: Object.assign(\n {},\n ...Object.keys(tree.files).map((file) =>\n tree.files != null\n ? {\n [file]: {\n ...tree.files[file],\n isSelected,\n },\n }\n : {},\n ),\n ),\n }\n : {}),\n isSelected,\n});\n\nconst applySelection = (\n tree: TorrentContentSelectionTree,\n item: TorrentContentSelection,\n recursiveDepth = 0,\n): TorrentContentSelectionTree => {\n const {depth, path, select, type} = item;\n const currentPath = path[recursiveDepth];\n\n // Change happens\n if (recursiveDepth === depth - 1) {\n if (type === 'file' && tree.files?.[currentPath] != null) {\n const files = {\n ...tree.files,\n [currentPath]: {\n ...tree.files[currentPath],\n isSelected: select,\n },\n };\n\n return {\n ...tree,\n files,\n isSelected:\n Object.values(files).every(({isSelected}) => isSelected) &&\n (tree.directories != null ? Object.values(tree.directories).every(({isSelected}) => isSelected) : true),\n };\n }\n\n if (type === 'directory' && tree.directories != null) {\n const directories = {\n ...tree.directories,\n [currentPath]: selectAll(tree.directories[currentPath], select),\n };\n\n return {\n ...tree,\n directories,\n isSelected:\n Object.values(directories).every(({isSelected}) => isSelected) &&\n (tree.files != null ? Object.values(tree.files).every(({isSelected}) => isSelected) : true),\n };\n }\n\n return tree;\n }\n\n // Recursive call till we reach the target\n if (tree.directories != null) {\n const selectionSubTree = tree.directories;\n Object.keys(selectionSubTree).forEach((directory) => {\n if (directory === currentPath) {\n selectionSubTree[directory] = applySelection(selectionSubTree[directory], item, recursiveDepth + 1);\n }\n });\n return {\n ...tree,\n directories: selectionSubTree,\n isSelected: Object.values(selectionSubTree).every(({isSelected}) => isSelected),\n };\n }\n\n return tree;\n};\n\nconst getSelectedItems = (tree: TorrentContentSelectionTree): number[] => {\n const indices: number[] = [];\n\n if (tree.files != null) {\n const {files} = tree;\n Object.keys(files).forEach((fileName) => {\n const file = files[fileName];\n\n if (file.isSelected) {\n indices.push(file.index);\n }\n });\n }\n\n if (tree.directories != null) {\n const {directories} = tree;\n Object.keys(directories).forEach((directoryName) => {\n indices.push(...getSelectedItems(directories[directoryName]));\n });\n }\n\n return indices;\n};\n\nconst getSelectionTree = (contents: Array<TorrentContent>, isSelected = false): TorrentContentSelectionTree => {\n const tree: TorrentContentSelectionTree = {isSelected};\n\n contents.forEach((content) => {\n const pathComponents = content.path.split('/');\n let currentDirectory = tree;\n\n while (pathComponents.length - 1) {\n const pathComponent = pathComponents.shift() as string;\n\n if (currentDirectory.directories == null) {\n currentDirectory.directories = {};\n }\n\n if (currentDirectory.directories[pathComponent] == null) {\n currentDirectory.directories[pathComponent] = {isSelected};\n }\n\n currentDirectory = currentDirectory.directories[pathComponent];\n }\n\n if (currentDirectory.files == null) {\n currentDirectory.files = {};\n }\n\n currentDirectory.files[content.filename] = {...content, isSelected};\n });\n\n return tree;\n};\n\nconst selectionTree = {\n selectAll,\n applySelection,\n getSelectedItems,\n getSelectionTree,\n};\n\nexport default selectionTree;\n","import classnames from 'classnames';\nimport {FC, ReactText, useRef, useState} from 'react';\n\nimport {Checkbox} from '@client/ui';\nimport {Checkmark, Clipboard, File as FileIcon} from '@client/ui/icons';\nimport ConfigStore from '@client/stores/ConfigStore';\nimport TorrentActions from '@client/actions/TorrentActions';\n\nimport type {TorrentContentSelection, TorrentContentSelectionTree} from '@shared/types/TorrentContent';\nimport type {TorrentProperties} from '@shared/types/Torrent';\n\nimport PriorityMeter from '../PriorityMeter';\nimport Size from '../Size';\n\ninterface DirectoryFilesProps {\n depth: number;\n hash: TorrentProperties['hash'];\n items: TorrentContentSelectionTree['files'];\n path: Array<string>;\n onItemSelect: (selection: TorrentContentSelection) => void;\n}\n\nconst DirectoryFiles: FC<DirectoryFilesProps> = ({depth, items, hash, path, onItemSelect}: DirectoryFilesProps) => {\n const [copiedToClipboard, setCopiedToClipboard] = useState<number | null>(null);\n const contentPermalinks = useRef<Record<number, string | null>>({});\n\n if (items == null) {\n return null;\n }\n\n const files = Object.values(items)\n .sort((a, b) => a.filename.localeCompare(b.filename))\n .map((file) => {\n const isSelected = (items && items[file.filename] && items[file.filename].isSelected) || false;\n const classes = classnames(\n 'directory-tree__node file',\n 'directory-tree__node--file directory-tree__node--selectable',\n {\n 'directory-tree__node--selected': isSelected,\n },\n );\n\n return (\n <div className={classes} key={file.filename} title={file.filename}>\n <div className=\"file__label file__detail\">\n <div className=\"file__checkbox directory-tree__checkbox\">\n <div className=\"directory-tree__checkbox__item directory-tree__checkbox__item--checkbox\">\n <Checkbox\n checked={isSelected}\n id={`${file.index}`}\n onClick={() =>\n onItemSelect({\n type: 'file',\n depth,\n path: [...path, file.filename],\n select: !isSelected,\n })\n }\n />\n </div>\n <div className=\"directory-tree__checkbox__item directory-tree__checkbox__item--icon\">\n <FileIcon />\n </div>\n </div>\n <div className=\"file__name\">\n {/* TODO: Add a WebAssembly decoding player if the feature is popular */}\n <a\n href={`${ConfigStore.baseURI}api/torrents/${hash}/contents/${file.index}/data`}\n style={{textDecoration: 'none'}}\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n {file.filename}\n </a>\n </div>\n </div>\n <div className=\"file__detail file__detail--secondary\">\n <Size value={file.sizeBytes} precision={1} />\n </div>\n <div className=\"file__detail file__detail--secondary\">{Math.trunc(file.percentComplete)}%</div>\n <div\n className=\"file__detail file__detail--secondary\n file__detail--priority\"\n >\n <PriorityMeter\n key={`${file.index}-${file.filename}`}\n level={file.priority}\n id={file.index}\n maxLevel={2}\n onChange={(fileIndex: ReactText, priorityLevel: number) =>\n TorrentActions.setFilePriority(hash, {\n indices: [Number(fileIndex)],\n priority: priorityLevel,\n })\n }\n priorityType=\"file\"\n />\n </div>\n {typeof navigator.clipboard?.writeText === 'function' && (\n <button\n className=\"file__detail file__detail--secondary file__detail--clipboard\"\n type=\"button\"\n onClick={() => {\n const copy = (link: string): void => {\n if (link !== '') {\n if (typeof navigator.share === 'function') {\n navigator\n .share({\n title: file.filename,\n url: link,\n })\n .then(() => setCopiedToClipboard(file.index));\n } else {\n navigator.clipboard.writeText(link).then(() => setCopiedToClipboard(file.index));\n }\n }\n };\n // Safari does not support async operations inside \"user gesture\" handler.\n // Otherwise the write to clipboard will be rejected for \"security reasons\".\n // As such, we cache the token, so next click can be synchronous. Incompatible\n // morons make everyone's life hard.\n const link = contentPermalinks.current[file.index];\n if (link != null) {\n copy(link);\n } else {\n contentPermalinks.current[file.index] = '';\n TorrentActions.getTorrentContentsDataPermalink(hash, [file.index]).then(\n (url) => {\n contentPermalinks.current[file.index] = url;\n copy(url);\n },\n () => {\n contentPermalinks.current[file.index] = null;\n },\n );\n }\n }}\n >\n {copiedToClipboard === file.index ? <Checkmark /> : <Clipboard />}\n </button>\n )}\n </div>\n );\n });\n\n return <div className=\"directory-tree__node directory-tree__node--file-list\">{files}</div>;\n};\n\nexport default DirectoryFiles;\n","import classnames from 'classnames';\nimport {FC, useState} from 'react';\n\nimport {css} from '@client/styled-system/css';\nimport {Checkbox} from '@client/ui';\nimport {FolderClosedSolid, FolderOpenSolid} from '@client/ui/icons';\n\nimport type {TorrentContentSelection, TorrentContentSelectionTree} from '@shared/types/TorrentContent';\nimport type {TorrentProperties} from '@shared/types/Torrent';\n\n// TODO: Fix this circular dependency\nimport DirectoryTree from './DirectoryTree';\n\ninterface DirectoryTreeNodeProps {\n id: string;\n depth: number;\n hash: TorrentProperties['hash'];\n path: Array<string>;\n directoryName: string;\n itemsTree: TorrentContentSelectionTree;\n isSelected: boolean;\n onItemSelect: (selection: TorrentContentSelection) => void;\n}\n\nconst DirectoryTreeNode: FC<DirectoryTreeNodeProps> = ({\n depth,\n directoryName,\n id,\n itemsTree,\n hash,\n path,\n isSelected,\n onItemSelect,\n}: DirectoryTreeNodeProps) => {\n const [expanded, setExpanded] = useState<boolean>(false);\n const currentPath = [...path, directoryName];\n\n return (\n <div\n className={classnames('directory-tree__branch', `directory-tree__branch--depth-${depth}`, {\n 'directory-tree__node--selected': isSelected,\n })}\n >\n <button\n className={classnames(\n 'directory-tree__node',\n 'directory-tree__node--selectable directory-tree__node--directory',\n css({\n width: '100%',\n textAlign: 'left',\n _focus: {\n outline: 'none',\n WebkitTapHighlightColor: 'transparent',\n },\n _focusVisible: {\n outline: 'dashed',\n },\n }),\n {\n 'is-expanded': expanded,\n },\n )}\n type=\"button\"\n onClick={() => setExpanded(!expanded)}\n title={directoryName}\n >\n <div className=\"file__label\">\n <div className=\"file__checkbox directory-tree__checkbox\">\n <div\n className=\"directory-tree__checkbox__item\n directory-tree__checkbox__item--checkbox\"\n >\n <Checkbox\n checked={isSelected}\n id={id}\n onClick={() =>\n onItemSelect({\n type: 'directory',\n depth,\n path: currentPath,\n select: !isSelected,\n })\n }\n />\n </div>\n <div\n className=\"directory-tree__checkbox__item\n directory-tree__checkbox__item--icon\"\n >\n {expanded ? <FolderOpenSolid /> : <FolderClosedSolid />}\n </div>\n </div>\n <div className=\"file__name\">{directoryName}</div>\n </div>\n </button>\n {expanded ? (\n <div className=\"directory-tree__node directory-tree__node--group\">\n <DirectoryTree\n depth={depth}\n hash={hash}\n key={`${expanded}-${depth}`}\n onItemSelect={onItemSelect}\n path={currentPath}\n itemsTree={itemsTree}\n />\n </div>\n ) : null}\n </div>\n );\n};\n\nexport default DirectoryTreeNode;\n","import {FC, ReactNode} from 'react';\n\nimport type {TorrentContentSelection, TorrentContentSelectionTree} from '@shared/types/TorrentContent';\nimport type {TorrentProperties} from '@shared/types/Torrent';\n\nimport DirectoryFileList from './DirectoryFileList';\n// TODO: Fix this circular dependency\nimport DirectoryTreeNode from './DirectoryTreeNode';\n\ninterface DirectoryTreeProps {\n depth: number;\n path: Array<string>;\n hash: TorrentProperties['hash'];\n itemsTree: TorrentContentSelectionTree;\n onItemSelect: (selection: TorrentContentSelection) => void;\n}\n\nconst DirectoryTree: FC<DirectoryTreeProps> = (props: DirectoryTreeProps) => {\n const {depth = 0, itemsTree, hash, path, onItemSelect} = props;\n const {files, directories} = itemsTree;\n const childDepth = depth + 1;\n\n const directoryNodes: Array<ReactNode> =\n directories != null\n ? Object.keys(directories)\n .sort((a, b) => a.localeCompare(b))\n .map((directoryName, index): ReactNode => {\n const subSelectedItems = itemsTree.directories && itemsTree.directories[directoryName];\n\n const id = `${index}${childDepth}${directoryName}`;\n const isSelected = (subSelectedItems && subSelectedItems.isSelected) || false;\n\n if (subSelectedItems == null) {\n return null;\n }\n\n return (\n <DirectoryTreeNode\n depth={childDepth}\n directoryName={directoryName}\n hash={hash}\n id={id}\n isSelected={isSelected}\n key={id}\n itemsTree={subSelectedItems}\n onItemSelect={onItemSelect}\n path={path}\n />\n );\n })\n : [];\n\n const fileList: ReactNode =\n files != null && Object.keys(files).length > 0 ? (\n <DirectoryFileList\n depth={childDepth}\n hash={hash}\n key={`files-${childDepth}`}\n onItemSelect={onItemSelect}\n path={path}\n items={itemsTree.files}\n />\n ) : null;\n\n return <div className=\"directory-tree__tree\">{directoryNodes.concat(fileList)}</div>;\n};\n\nexport default DirectoryTree;\n","import classnames from 'classnames';\nimport {observer} from 'mobx-react-lite';\nimport {FC, useEffect, useState} from 'react';\nimport {Trans, useLingui} from '@lingui/react';\n\nimport {Button, Checkbox, Form, FormRow, FormRowItem, Select, SelectItem} from '@client/ui';\nimport ConfigStore from '@client/stores/ConfigStore';\nimport {Disk} from '@client/ui/icons';\nimport selectionTree from '@client/util/selectionTree';\nimport TorrentActions from '@client/actions/TorrentActions';\nimport TorrentStore from '@client/stores/TorrentStore';\nimport UIStore from '@client/stores/UIStore';\n\nimport type {TorrentContent, TorrentContentSelection, TorrentContentSelectionTree} from '@shared/types/TorrentContent';\n\nimport DirectoryTree from '../../general/filesystem/DirectoryTree';\n\nconst TorrentContents: FC = observer(() => {\n const [contents, setContents] = useState<TorrentContent[]>([]);\n const [itemsTree, setItemsTree] = useState<TorrentContentSelectionTree>({});\n const [selectedIndices, setSelectedIndices] = useState<number[]>([]);\n const {i18n} = useLingui();\n\n useEffect(() => {\n if (UIStore.activeModal?.id === 'torrent-details') {\n TorrentActions.fetchTorrentContents(UIStore.activeModal?.hash).then((fetchedContents) => {\n if (fetchedContents != null) {\n setContents(fetchedContents);\n setItemsTree(selectionTree.getSelectionTree(fetchedContents));\n }\n });\n }\n }, []);\n\n if (UIStore.activeModal?.id !== 'torrent-details') {\n return null;\n }\n\n const {hash} = UIStore.activeModal;\n\n let directoryHeadingIconContent = null;\n let fileDetailContent = null;\n\n let allSelected = false;\n if (contents?.length > 0) {\n allSelected = selectedIndices.length >= contents.length;\n directoryHeadingIconContent = (\n <div className=\"file__checkbox directory-tree__checkbox\">\n <div\n className=\"directory-tree__checkbox__item\n directory-tree__checkbox__item--checkbox\"\n >\n <FormRow>\n <Checkbox\n checked={allSelected}\n id=\"select-all\"\n onClick={() => {\n // select or deselect all\n const newItemsTree = selectionTree.getSelectionTree(contents, selectedIndices.length < contents.length);\n\n setItemsTree(newItemsTree);\n setSelectedIndices(selectionTree.getSelectedItems(newItemsTree));\n }}\n />\n </FormRow>\n </div>\n <div\n className=\"directory-tree__checkbox__item\n directory-tree__checkbox__item--icon\"\n >\n <Disk />\n </div>\n </div>\n );\n fileDetailContent = (\n <DirectoryTree\n depth={0}\n onItemSelect={(selectedItem: TorrentContentSelection) => {\n const newItemsTree = selectionTree.applySelection(itemsTree, selectedItem);\n setItemsTree(newItemsTree);\n setSelectedIndices(selectionTree.getSelectedItems(newItemsTree));\n }}\n hash={hash}\n path={[]}\n itemsTree={itemsTree}\n />\n );\n } else {\n directoryHeadingIconContent = <Disk />;\n fileDetailContent = (\n <div className=\"directory-tree__node directory-tree__node--file\">\n <Trans id=\"torrents.details.files.loading\" />\n </div>\n );\n }\n\n const directoryHeadingClasses = classnames(\n 'directory-tree__node',\n 'directory-tree__parent-directory torrent-details__section__heading',\n {\n 'directory-tree__node--selected': allSelected,\n },\n );\n\n const directoryHeading = (\n <div className={directoryHeadingClasses}>\n <div className=\"file__label\">\n {directoryHeadingIconContent}\n <div className=\"file__name\">{TorrentStore.torrents?.[hash].directory}</div>\n </div>\n </div>\n );\n\n const wrapperClasses = classnames('inverse directory-tree__wrapper', {\n 'directory-tree__wrapper--toolbar-visible': selectedIndices.length > 0,\n });\n\n return (\n <Form\n className={wrapperClasses}\n onChange={({event}) => {\n if (event.target != null && (event.target as HTMLInputElement).name === 'file-priority') {\n const inputElement = event.target as HTMLInputElement;\n if (inputElement.value) {\n TorrentActions.setFilePriority(hash, {\n indices: selectedIndices,\n priority: Number(inputElement.value),\n });\n }\n }\n }}\n >\n <div className=\"directory-tree__selection-toolbar\">\n <FormRow align=\"center\">\n <FormRowItem width=\"one-quarter\" grow={false} shrink={false}>\n <Trans\n id=\"torrents.details.selected.files\"\n values={{\n count: selectedIndices.length,\n countElement: (\n <span className=\"directory-tree__selection-toolbar__item-count\">{selectedIndices.length}</span>\n ),\n }}\n />\n </FormRowItem>\n <Button\n onClick={(event) => {\n event.preventDefault();\n const {baseURI} = ConfigStore;\n const link = document.createElement('a');\n\n link.download = '';\n link.href = `${baseURI}api/torrents/${hash}/contents/${selectedIndices.join(',')}/data`;\n link.style.display = 'none';\n\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n }}\n grow={false}\n shrink={false}\n >\n <Trans\n id=\"torrents.details.files.download.file\"\n values={{\n count: selectedIndices.length,\n }}\n />\n </Button>\n <Select id=\"file-priority\" persistentPlaceholder shrink={false} defaultID=\"\">\n <SelectItem id={-1} isPlaceholder>\n <Trans id=\"torrents.details.selected.files.set.priority\" />\n </SelectItem>\n <SelectItem id={0}>{i18n._('priority.dont.download')}</SelectItem>\n <SelectItem id={1}>{i18n._('priority.normal')}</SelectItem>\n <SelectItem id={2}>{i18n._('priority.high')}</SelectItem>\n </Select>\n </FormRow>\n </div>\n <div className=\"directory-tree torrent-details__section torrent-details__section--file-tree modal__content--nested-scroll__content\">\n {directoryHeading}\n {fileDetailContent}\n </div>\n </Form>\n );\n});\n\nexport default TorrentContents;\n","import {FC} from 'react';\n\ninterface LinkedTextProps {\n text: string;\n className?: string;\n}\n\nfunction isValidHttpUrl(s: string) {\n let url;\n\n try {\n url = new URL(s);\n } catch {\n return false;\n }\n\n return url.protocol === 'http:' || url.protocol === 'https:';\n}\n\nconst LinkedText: FC<LinkedTextProps> = ({text, className}: LinkedTextProps) => {\n const nodes = text.split(/([ \\n])/).map((s, index) => {\n if (s === '\\n') {\n return <br key={index} />;\n }\n if (isValidHttpUrl(s)) {\n return (\n <a href={s.trimEnd()} target=\"_blank\" rel=\"noopener noreferrer\" key={index}>\n {s}\n </a>\n );\n }\n return s;\n });\n\n return <span className={className}>{nodes}</span>;\n};\n\nexport default LinkedText;\n","import {FC} from 'react';\nimport {observer} from 'mobx-react-lite';\nimport {Trans, useLingui} from '@lingui/react';\n\nimport type {TorrentProperties} from '@shared/types/Torrent';\n\nimport LinkedText from '../../general/LinkedText';\nimport Size from '../../general/Size';\nimport TorrentStore from '../../../stores/TorrentStore';\nimport UIStore from '../../../stores/UIStore';\n\nconst getTags = (tags: TorrentProperties['tags']) =>\n tags.map((tag) => (\n <span className=\"tag\" key={tag}>\n {tag}\n </span>\n ));\n\nconst TorrentGeneralInfo: FC = observer(() => {\n const {i18n} = useLingui();\n\n if (UIStore.activeModal?.id !== 'torrent-details') {\n return null;\n }\n\n const torrent = TorrentStore.torrents[UIStore.activeModal.hash];\n if (torrent == null) {\n return null;\n }\n\n const VALUE_NOT_AVAILABLE = (\n <span className=\"not-available\">\n <Trans id=\"torrents.details.general.none\" />\n </span>\n );\n\n return (\n <div className=\"torrent-details__section torrent-details__section--general\">\n <table className=\"torrent-details__table table\">\n <tbody>\n <tr className=\"torrent-details__table__heading\">\n <td className=\"torrent-details__table__heading--tertiary\" colSpan={2}>\n <Trans id=\"torrents.details.general.heading.general\" />\n </td>\n </tr>\n <tr className=\"torrent-details__detail torrent-details__detail--dateAdded\">\n <td className=\"torrent-details__detail__label\">\n <Trans id=\"torrents.details.general.date.added\" />\n </td>\n <td className=\"torrent-details__detail__value\">\n {torrent.dateAdded > 0\n ? i18n.date(new Date(torrent.dateAdded * 1000), {\n year: 'numeric',\n month: 'long',\n day: '2-digit',\n hour: 'numeric',\n minute: 'numeric',\n })\n : VALUE_NOT_AVAILABLE}\n </td>\n </tr>\n <tr className=\"torrent-details__detail torrent-details__detail--location\">\n <td className=\"torrent-details__detail__label\">\n <Trans id=\"torrents.details.general.location\" />\n </td>\n <td className=\"torrent-details__detail__value\">{torrent.directory}</td>\n </tr>\n <tr className=\"torrent-details__detail torrent-details__detail--tags\">\n <td className=\"torrent-details__detail__label\">\n <Trans id=\"torrents.details.general.tags\" />\n </td>\n <td className=\"torrent-details__detail__value\">\n {torrent.tags.length ? getTags(torrent.tags) : VALUE_NOT_AVAILABLE}\n </td>\n </tr>\n <tr className=\"torrent-details__table__heading\">\n <td className=\"torrent-details__table__heading--tertiary\" colSpan={2}>\n <Trans id=\"torrents.details.general.heading.transfer\" />\n </td>\n </tr>\n <tr className=\"torrent-details__detail torrent-details__detail--dateFinished\">\n <td className=\"torrent-details__detail__label\">\n <Trans id=\"torrents.details.general.date.finished\" />\n </td>\n <td className=\"torrent-details__detail__value\">\n {torrent.dateFinished > 0\n ? i18n.date(new Date(torrent.dateFinished * 1000), {\n year: 'numeric',\n month: 'long',\n day: '2-digit',\n hour: 'numeric',\n minute: 'numeric',\n })\n : VALUE_NOT_AVAILABLE}\n </td>\n </tr>\n <tr className=\"torrent-details__detail torrent-details__detail--downloaded\">\n <td className=\"torrent-details__detail__label\">\n <Trans id=\"torrents.details.general.downloaded\" />\n </td>\n <td className=\"torrent-details__detail__value\">\n {i18n.number(torrent.percentComplete)}\n <em className=\"unit\">%</em>\n </td>\n </tr>\n <tr className=\"torrent-details__detail torrent-details__detail--peers\">\n <td className=\"torrent-details__detail__label\">\n <Trans id=\"torrents.details.general.peers\" />\n </td>\n <td className=\"torrent-details__detail__value\">\n <Trans\n id=\"torrents.details.general.connected\"\n values={{\n connectedCount: torrent.peersConnected,\n connected: i18n.number(torrent.peersConnected),\n total: i18n.number(torrent.peersTotal),\n }}\n />\n </td>\n </tr>\n <tr className=\"torrent-details__detail torrent-details__detail--seeds\">\n <td className=\"torrent-details__detail__label\">\n <Trans id=\"torrents.details.general.seeds\" />\n </td>\n <td className=\"torrent-details__detail__value\">\n <Trans\n id=\"torrents.details.general.connected\"\n values={{\n connectedCount: torrent.seedsConnected,\n connected: i18n.number(torrent.seedsConnected),\n total: i18n.number(torrent.seedsTotal),\n }}\n />\n </td>\n </tr>\n <tr className=\"torrent-details__detail torrent-details__detail--dateActive\">\n <td className=\"torrent-details__detail__label\">\n <Trans id=\"torrents.details.general.date.active\" />\n </td>\n <td className=\"torrent-details__detail__value\">\n {(() => {\n if (torrent.dateActive === 0) {\n return VALUE_NOT_AVAILABLE;\n }\n\n if (torrent.dateActive === -1) {\n return i18n._('torrents.details.general.date.active.now');\n }\n\n return i18n.date(new Date(torrent.dateActive * 1000), {\n year: 'numeric',\n month: 'long',\n day: '2-digit',\n hour: 'numeric',\n minute: 'numeric',\n });\n })()}\n </td>\n </tr>\n <tr className=\"torrent-details__table__heading\">\n <td className=\"torrent-details__table__heading--tertiary\" colSpan={2}>\n <Trans id=\"torrents.details.general.heading.torrent\" />\n </td>\n </tr>\n <tr className=\"torrent-details__detail torrent-details__detail--created\">\n <td className=\"torrent-details__detail__label\">\n <Trans id=\"torrents.details.general.date.created\" />\n </td>\n <td className=\"torrent-details__detail__value\">\n {torrent.dateCreated > 0\n ? i18n.date(new Date(torrent.dateCreated * 1000), {\n year: 'numeric',\n month: 'long',\n day: '2-digit',\n hour: 'numeric',\n minute: 'numeric',\n })\n : VALUE_NOT_AVAILABLE}\n </td>\n </tr>\n <tr className=\"torrent-details__detail torrent-details__detail--hash\">\n <td className=\"torrent-details__detail__label\">\n <Trans id=\"torrents.details.general.hash\" />\n </td>\n <td className=\"torrent-details__detail__value\">{torrent.hash}</td>\n </tr>\n <tr className=\"torrent-details__detail torrent-details__detail--size\">\n <td className=\"torrent-details__detail__label\">\n <Trans id=\"torrents.details.general.size\" />\n </td>\n <td className=\"torrent-details__detail__value\">\n <Size value={torrent.sizeBytes} />\n </td>\n </tr>\n <tr className=\"torrent-details__detail torrent-details__detail--type\">\n <td className=\"torrent-details__detail__label\">\n <Trans id=\"torrents.details.general.type\" />\n </td>\n <td className=\"torrent-details__detail__value\">\n {torrent.isPrivate\n ? i18n._('torrents.details.general.type.private')\n : i18n._('torrents.details.general.type.public')}\n </td>\n </tr>\n <tr className=\"torrent-details__detail torrent-details__detail--comment\">\n <td className=\"torrent-details__detail__label\">\n <Trans id=\"torrents.details.general.comment\" />\n </td>\n <td className=\"torrent-details__detail__value\">\n {torrent.comment ? <LinkedText text={torrent.comment.trim()} /> : VALUE_NOT_AVAILABLE}\n </td>\n </tr>\n <tr className=\"torrent-details__table__heading\">\n <td className=\"torrent-details__table__heading--tertiary\" colSpan={2}>\n <Trans id=\"torrents.details.general.heading.tracker\" />\n </td>\n </tr>\n <tr className=\"torrent-details__detail torrent-details__detail--tracker-message\">\n <td className=\"torrent-details__detail__label\">\n <Trans id=\"torrents.details.general.tracker.message\" />\n </td>\n <td className=\"torrent-details__detail__value\">\n {torrent.message ? torrent.message : VALUE_NOT_AVAILABLE}\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n );\n});\n\nexport default TorrentGeneralInfo;\n","import classnames from 'classnames';\nimport {computed} from 'mobx';\nimport {FC, useEffect, useState} from 'react';\nimport {observer} from 'mobx-react-lite';\nimport {Trans, useLingui} from '@lingui/react';\n\nimport {Clock, DownloadThick, Ratio, Start, Stop, UploadThick} from '@client/ui/icons';\nimport TorrentActions from '@client/actions/TorrentActions';\nimport {torrentStatusClasses, torrentStatusEffective} from '@client/util/torrentStatus';\nimport TorrentStore from '@client/stores/TorrentStore';\nimport UIStore from '@client/stores/UIStore';\n\nimport Duration from '../../general/Duration';\nimport PriorityMeter from '../../general/PriorityMeter';\nimport ProgressBar from '../../general/ProgressBar';\nimport Size from '../../general/Size';\n\nconst TorrentHeading: FC = observer(() => {\n const {i18n} = useLingui();\n const torrent =\n UIStore.activeModal?.id === 'torrent-details' ? TorrentStore.torrents[UIStore.activeModal.hash] : undefined;\n const [torrentStatus, setTorrentStatus] = useState<'start' | 'stop'>('stop');\n\n useEffect(() => {\n if (torrent?.status.includes('stopped')) {\n setTorrentStatus('stop');\n } else {\n setTorrentStatus('start');\n }\n }, [torrent?.status]);\n\n if (torrent == null) {\n return null;\n }\n\n const torrentClasses = torrentStatusClasses(\n {\n status: torrent.status,\n upRate: torrent.upRate,\n downRate: torrent.downRate,\n },\n 'torrent-details__header',\n );\n\n return (\n <div className={torrentClasses}>\n <h1 className=\"torrent-details__heading torrent-details--name\">{torrent.name}</h1>\n <div className=\"torrent-details__sub-heading\">\n <ul className=\"torrent-details__sub-heading__secondary\">\n <li className=\"torrent-details__sub-heading__tertiary torrent-details__sub-heading__tertiary--download\">\n <DownloadThick />\n <Size value={torrent.downRate} isSpeed />\n &nbsp;&mdash;&nbsp;\n <Size value={torrent.bytesDone} />\n </li>\n <li className=\"torrent-details__sub-heading__tertiary torrent-details__sub-heading__tertiary--upload\">\n <UploadThick />\n <Size value={torrent.upRate} isSpeed />\n &nbsp;&mdash;&nbsp;\n <Size value={torrent.upTotal} />\n </li>\n <li className=\"torrent-details__sub-heading__tertiary\">\n <Ratio />\n {i18n.number(torrent.ratio)}\n </li>\n <li className=\"torrent-details__sub-heading__tertiary\">\n <Clock />\n <Duration value={torrent.eta} />\n </li>\n </ul>\n <ul className=\"torrent-details__sub-heading__secondary\">\n <li className=\"torrent-details__sub-heading__tertiary\" key=\"priority-meter\">\n <PriorityMeter\n id={torrent.hash}\n level={torrent.priority}\n maxLevel={3}\n priorityType=\"torrent\"\n onChange={(hash, level) => {\n TorrentActions.setPriority({\n hashes: [`${hash}`],\n priority: level,\n });\n }}\n />\n </li>\n <li className=\"torrent-details__sub-heading__tertiary\" key=\"start\">\n <button\n className={classnames('torrent-details__action', {\n 'is-active': torrentStatus === 'start',\n })}\n type=\"button\"\n onClick={() => {\n setTorrentStatus('start');\n TorrentActions.startTorrents({\n hashes: [torrent.hash],\n });\n }}\n >\n <Start />\n <Trans id=\"torrents.details.actions.start\" />\n </button>\n </li>\n <li className=\"torrent-details__sub-heading__tertiary\" key=\"stop\">\n <button\n className={classnames('torrent-details__action', {\n 'is-active': torrentStatus === 'stop',\n })}\n type=\"button\"\n onClick={() => {\n setTorrentStatus('stop');\n TorrentActions.stopTorrents({\n hashes: [torrent.hash],\n });\n }}\n >\n <Stop />\n <Trans id=\"torrents.details.actions.stop\" />\n </button>\n </li>\n </ul>\n </div>\n <ProgressBar\n percent={computed(() => Math.ceil(torrent.percentComplete)).get()}\n status={computed(() => torrentStatusEffective(torrent.status)).get()}\n />\n </div>\n );\n});\n\nexport default TorrentHeading;\n","import {FC, Suspense, useEffect, useState} from 'react';\nimport {Trans} from '@lingui/react';\nimport {useInterval} from 'react-use';\n\nimport {css} from '@client/styled-system/css';\nimport {CheckmarkThick, CountryFlag, Lock, Spinner} from '@client/ui/icons';\nimport ConfigStore from '@client/stores/ConfigStore';\nimport TorrentActions from '@client/actions/TorrentActions';\nimport UIStore from '@client/stores/UIStore';\n\nimport type {TorrentPeer} from '@shared/types/TorrentPeer';\n\nimport Badge from '../../general/Badge';\nimport Size from '../../general/Size';\n\nconst TorrentPeers: FC = () => {\n const [peers, setPeers] = useState<Array<TorrentPeer>>([]);\n const [pollingDelay, setPollingDelay] = useState<number | null>(null);\n\n const fetchPeers = () => {\n setPollingDelay(null);\n if (UIStore.activeModal?.id === 'torrent-details') {\n TorrentActions.fetchTorrentPeers(UIStore.activeModal?.hash).then((data) => {\n if (data != null) {\n setPeers(data);\n }\n });\n }\n setPollingDelay(ConfigStore.pollInterval);\n };\n\n useEffect(() => fetchPeers(), []);\n useInterval(() => fetchPeers(), pollingDelay);\n\n return (\n <div className=\"torrent-details__section torrent-details__section--peers\">\n <table\n className={`torrent-details__table table ${css({\n '& td': {\n maxWidth: '140px',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n },\n })}`}\n >\n <thead className=\"torrent-details__table__heading\">\n <tr>\n <th className=\"torrent-details__table__heading--primary\">\n <Trans id=\"torrents.details.peers\" />\n <Badge>{peers.length}</Badge>\n </th>\n <th className=\"torrent-details__table__heading--secondary\">DL</th>\n <th className=\"torrent-details__table__heading--secondary\">UL</th>\n <th className=\"torrent-details__table__heading--secondary\">%</th>\n <th className=\"torrent-details__table__heading--secondary\">Client</th>\n <th className=\"torrent-details__table__heading--secondary\">Enc</th>\n <th className=\"torrent-details__table__heading--secondary\">In</th>\n </tr>\n </thead>\n <tbody>\n {peers.map((peer) => {\n const {country: countryCode} = peer;\n const encryptedIcon = peer.isEncrypted ? <Lock /> : null;\n const incomingIcon = peer.isIncoming ? <CheckmarkThick /> : null;\n\n return (\n <tr key={peer.address}>\n <td>\n <span className=\"peers-list__flag\">\n <Suspense fallback={<Spinner />}>\n <CountryFlag countryCode={countryCode} />\n </Suspense>\n <span className=\"peers-list__flag__text\">{countryCode}</span>\n </span>\n {peer.address}\n </td>\n <td>\n <Size value={peer.downloadRate} isSpeed />\n </td>\n <td>\n <Size value={peer.uploadRate} isSpeed />\n </td>\n <td>{`${Math.ceil(peer.completedPercent)}%`}</td>\n <td>{peer.clientVersion}</td>\n <td className=\"peers-list__encryption\">{encryptedIcon}</td>\n <td className=\"peers-list__incoming\">{incomingIcon}</td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n );\n};\n\nexport default TorrentPeers;\n","import {FC, useEffect, useState} from 'react';\nimport {Trans} from '@lingui/react';\n\nimport type {TorrentTracker} from '@shared/types/TorrentTracker';\n\nimport Badge from '../../general/Badge';\nimport TorrentActions from '../../../actions/TorrentActions';\nimport UIStore from '../../../stores/UIStore';\n\nconst TorrentTrackers: FC = () => {\n const [trackers, setTrackers] = useState<Array<TorrentTracker>>([]);\n\n const trackerCount = trackers.length;\n const trackerTypes = ['http', 'udp', 'dht'];\n\n const trackerDetails = trackers.map((tracker) => (\n <tr key={tracker.url}>\n <td className=\"torrent-details__trackers--url\">{tracker.url}</td>\n <td>{trackerTypes[tracker.type - 1]}</td>\n </tr>\n ));\n\n useEffect(() => {\n if (UIStore.activeModal?.id === 'torrent-details') {\n TorrentActions.fetchTorrentTrackers(UIStore.activeModal?.hash).then((data) => {\n if (data != null) {\n setTrackers(data);\n }\n });\n }\n }, []);\n\n return (\n <div className=\"torrent-details__trackers torrent-details__section\">\n <table className=\"torrent-details__table table\">\n <thead className=\"torrent-details__table__heading\">\n <tr>\n <th className=\"torrent-details__table__heading--primary\">\n <Trans id=\"torrents.details.trackers\" />\n <Badge>{trackerCount}</Badge>\n </th>\n <th className=\"torrent-details__table__heading--secondary\">\n <Trans id=\"torrents.details.trackers.type\" />\n </th>\n </tr>\n </thead>\n <tbody>{trackerDetails}</tbody>\n </table>\n </div>\n );\n};\n\nexport default TorrentTrackers;\n","import {FC} from 'react';\nimport {observer} from 'mobx-react-lite';\nimport {useLingui} from '@lingui/react';\n\nimport ConfigStore from '@client/stores/ConfigStore';\n\nimport Modal from '../Modal';\nimport TorrentMediainfo from './TorrentMediainfo';\nimport TorrentContents from './TorrentContents';\nimport TorrentGeneralInfo from './TorrentGeneralInfo';\nimport TorrentHeading from './TorrentHeading';\nimport TorrentPeers from './TorrentPeers';\nimport TorrentTrackers from './TorrentTrackers';\n\nconst TorrentDetailsModal: FC = observer(() => {\n const {i18n} = useLingui();\n const {isSmallScreen} = ConfigStore;\n\n const tabs = {\n 'torrent-details': {\n content: TorrentGeneralInfo,\n label: i18n._('torrents.details.details'),\n },\n 'torrent-contents': {\n content: TorrentContents,\n label: i18n._('torrents.details.files'),\n modalContentClasses: 'modal__content--nested-scroll',\n },\n 'torrent-peers': {\n content: TorrentPeers,\n label: i18n._('torrents.details.peers'),\n },\n 'torrent-trackers': {\n content: TorrentTrackers,\n label: i18n._('torrents.details.trackers'),\n },\n 'torrent-mediainfo': {\n content: TorrentMediainfo,\n label: i18n._('torrents.details.mediainfo'),\n modalContentClasses: 'modal__content--nested-scroll',\n },\n };\n\n return (\n <Modal\n heading={<TorrentHeading key=\"torrent-heading\" />}\n size=\"large\"\n tabs={tabs}\n orientation={isSmallScreen ? 'horizontal' : 'vertical'}\n tabsInBody={!isSmallScreen}\n />\n );\n});\n\nexport default TorrentDetailsModal;\n","import {CSSTransition, TransitionGroup} from 'react-transition-group';\nimport React, {FC} from 'react';\nimport {observer} from 'mobx-react-lite';\nimport {useKeyPressEvent} from 'react-use';\n\nimport AddTorrentsModal from './add-torrents-modal/AddTorrentsModal';\nimport ConfirmModal from './confirm-modal/ConfirmModal';\nimport FeedsModal from './feeds-modal/FeedsModal';\nimport GenerateMagnetModal from './generate-magnet-modal/GenerateMagnetModal';\nimport MoveTorrentsModal from './move-torrents-modal/MoveTorrentsModal';\nimport RemoveTorrentsModal from './remove-torrents-modal/RemoveTorrentsModal';\nimport SetTagsModal from './set-tags-modal/SetTagsModal';\nimport SetTrackersModal from './set-trackers-modal/SetTrackersModal';\nimport SettingsModal from './settings-modal/SettingsModal';\nimport TorrentDetailsModal from './torrent-details-modal/TorrentDetailsModal';\nimport UIStore from '../../stores/UIStore';\n\nimport type {Modal} from '../../stores/UIStore';\n\nconst createModal = (id: Modal['id']): React.ReactNode => {\n switch (id) {\n case 'add-torrents':\n return <AddTorrentsModal />;\n case 'confirm':\n return <ConfirmModal />;\n case 'feeds':\n return <FeedsModal />;\n case 'generate-magnet':\n return <GenerateMagnetModal />;\n case 'move-torrents':\n return <MoveTorrentsModal />;\n case 'remove-torrents':\n return <RemoveTorrentsModal />;\n case 'set-taxonomy':\n return <SetTagsModal />;\n case 'set-trackers':\n return <SetTrackersModal />;\n case 'settings':\n return <SettingsModal />;\n case 'torrent-details':\n return <TorrentDetailsModal />;\n default:\n return null;\n }\n};\n\nconst Modals: FC = observer(() => {\n const {id} = UIStore.activeModal || {};\n\n useKeyPressEvent('Escape', () => UIStore.setActiveModal(null));\n\n let modal;\n if (id != null) {\n modal = (\n <CSSTransition key={id} classNames=\"modal__animation\" timeout={{enter: 500, exit: 500}}>\n <div className=\"modal\">\n <div\n className=\"modal__overlay\"\n role=\"none\"\n onClick={() => {\n UIStore.setActiveModal(null);\n }}\n />\n {createModal(id)}\n </div>\n </CSSTransition>\n );\n }\n\n return <TransitionGroup>{modal}</TransitionGroup>;\n});\n\nexport default Modals;\n"],"names":["saveAddTorrentsUserPreferences","start","destination","tags","tab","changedSettings","startTorrentsOnLoad","torrentDestinations","SettingStore","floodSettings","UITorrentsAddTab","SettingActions","saveSettings","props","actions","buttons","map","action","index","dismissIfNeeded","triggerDismiss","UIStore","setActiveModal","type","_jsx","Checkbox","defaultChecked","checked","id","onClick","event","clickHandler","children","content","Button","isLoading","priority","submit","buttonsGroup","className","AddTorrentsActions","isAddingTorrents","onAddTorrentsClick","i18n","useLingui","ModalActions","Boolean","_","itemPaddingStyle","css","raw","padding","headerStyle","borderBottom","marginBottom","paddingBottom","opacity","_last","baseListItemStyle","transition","whiteSpace","width","height","textAlign","_disabled","pointerEvents","listItemStyle","listItemSelectableActiveStyle","color","background","outline","WebkitTapHighlightColor","listItemSelectableStyle","cursor","userSelect","_hover","_focusWithin","MESSAGES","EACCES","ENOENT","memo","directory","selectable","onItemSelection","onYieldFocus","setCursor","useState","errorResponse","setErrorResponse","separator","setSeparator","includes","directories","setDirectories","files","setFiles","listRef","useRef","lastSegmentIndex","lastIndexOf","currentDirectory","substr","lastSegment","useEffect","FloodActions","fetchDirectoryList","then","fetchedFiles","fetchedDirectories","fetchedSeparator","catch","response","current","element","tabIndex","focus","Array","from","findIndex","e","useKey","preventDefault","prevCursor","errorMessage","listItems","data","code","parentDirectory","split","slice","join","parentDirectoryElement","_jsxs","Arrow","transform","isDirectorySelectable","directoryMatched","termMatch","subDirectory","inputDirectoryElement","inputDestination","display","style","fontWeight","FolderClosedOutlined","Trans","directoryList","length","sort","desc","undefined","disabled","FolderClosedSolid","isFileSelectable","fileMatched","file","fileList","File","listStyle","fill","marginRight","marginTop","verticalAlign","wordBreak","FolderOpenSolid","ref","forwardRef","label","suggested","showBasePathToggle","showCompletedToggle","showSequentialToggle","onChange","setDestination","clientSettings","directoryDefault","isDirectoryListOpen","setIsDirectoryListOpen","formRowRef","textboxRef","useEnsuredForwardedRef","closeDirectoryList","handleDocumentClick","contains","target","document","addEventListener","window","removeEventListener","toggles","push","grow","FormRowGroup","FormRow","Textbox","autoComplete","addonPlacement","defaultValue","debounce","newDestination","value","leading","nativeEvent","stopImmediatePropagation","placeholder","FormElementAddon","Search","Portal","ContextMenu","isIn","overlayProps","isInteractive","triggerRef","FilesystemBrowser","shouldKeepOpen","TagSelect","onTagSelected","isOpen","setIsOpen","selectedTags","setSelectedTags","menuRef","classes","classnames","useKeyPressEvent","FormRowItem","selectedTagsArray","tag","trim","filter","trimEnd","endsWith","Set","Chevron","UITagSelectorMode","Object","keys","TorrentFilterStore","taxonomy","tagCounts","asc","reduce","accumulator","SelectItem","isSelected","key","getTextArray","formData","formItemKey","startsWith","text","TextboxRepeater","defaultValues","idCounter","textboxes","setTextboxes","textbox","removeButton","newTextboxes","splice","RemoveMini","wrapperClassName","AddMini","AddTorrentsByCreation","formRef","isCreatingTorrents","setIsCreatingTorrents","Form","FilesystemBrowserTextbox","getFormData","sourcePath","TorrentActions","createTorrent","name","trackers","comment","infoSource","isPrivate","FileDropzone","initialFiles","onFilesChanged","stopPropagation","role","title","newArray","Close","Dropzone","onDrop","addedFiles","processedFiles","forEach","reader","FileReader","onload","result","concat","readAsDataURL","getRootProps","getInputProps","isDragActive","Files","AddTorrentsByFile","filesRef","setIsAddingTorrents","activeModal","suggestedPath","dispatchEvent","Event","bubbles","isBasePath","isCompleted","isSequential","filesData","tagsArray","addTorrentsByFiles","AddTorrentsByURL","navigator","registerProtocolHandler","float","_focus","_focusVisible","ConfigStore","baseURI","fontSize","urls","url","cookies","firstDomain","processedCookies","addTorrentsByUrls","ModalTabs","activeTabId","tabs","onTabChange","tabId","currentTab","Modal","alignment","size","orientation","tabsInBody","inverse","initialTabId","heading","contentWrapperClasses","modalBody","modalHeader","headerClasses","bodyTabs","footer","headerTabs","setActiveTabId","activeTab","contentClasses","modalContentClasses","ModalContentComponent","modalContentData","modalTabs","AddTorrentsModal","observer","feeds","rules","items","constructor","makeAutoObservable","this","setFeeds","a","b","localeCompare","setRules","handleFeedMonitorsFetchSuccess","feedMonitors","handleItemsFetchSuccess","FeedActions","addFeed","options","axios","put","fetchFeedMonitors","modifyFeed","patch","addRule","get","FeedStore","fetchItems","search","params","removeFeedMonitor","delete","isNotEmpty","isRegExValid","regExToCheck","RegExp","DownloadRuleForm","rule","isSubmitting","isPatternMatched","onCancel","Select","defaultID","feedIDs","isPlaceholder","feedOptions","feed","_id","match","exclude","CheckmarkThick","align","justify","startOnLoad","matchTextboxHeight","ModalFormSectionHeader","currentRule","onSelect","onRemove","matchedCount","count","excludeNode","tagNodes","values","maxWidth","overflow","textOverflow","Edit","initialRule","validatedFields","isValid","error","feedID","validateField","validatedField","DownloadRulesTab","setCurrentRule","errors","setErrors","isEditing","setIsEditing","setIsSubmitting","isFormChanged","setIsFormChanged","setIsPatternMatched","ruleFormData","check","isMatched","test","isExcluded","onSubmit","async","currentErrors","isFormValid","every","field","resetForm","backend","FormError","DownloadRuleList","FeedForm","currentFeed","defaultFeed","intervalMultipliers","feedInterval","interval","defaultIntervalTextValue","defaultIntervalMultiplier","intervalMultiplier","labelOffset","message","selectedFeedID","itemElements","titleOccurrences","item","occurrence","manualAddingFormRef","setSelectedFeedID","some","feedBrowseForm","torrentsToDownload","_item","FeedItems","intervalText","intervalMultiplierMessage","href","rel","matchURL","number","parseInt","Number","isNaN","INTERVAL_MULTIPLIERS","FeedsTab","setCurrentFeed","feedForm","success","FeedList","FeedItemsForm","FeedsModal","downloadRules","TorrentTrackerType","generateMagnet","hash","tracker","encodeURI","GenerateMagnetModal","magnetTextboxRef","magnetTrackersTextboxRef","isMagnetCopied","setIsMagnetCopied","isMagnetTrackersCopied","setIsMagnetTrackersCopied","trackerState","setTrackerState","isLoadingTrackers","magnetTrackersLink","fetchTorrentTrackers","TorrentStore","selectedTorrents","DHT","magnetLink","torrents","readOnly","clipboard","writeText","select","execCommand","Clipboard","getSuggestedPath","sources","commonPath","i","j","MoveTorrents","isSettingDownloadPath","setIsSettingDownloadPath","hashes","moveTorrents","moveFiles","isCheckHash","RemoveTorrentsModal","isRemoving","setIsRemoving","deleteData","deleteTorrents","saveDeleteTorrentsUserPreferences","saveSetting","deleteTorrentData","SetTagsModal","isSettingTags","setIsSettingTags","setTags","SetTrackersModal","isSettingTrackers","setIsSettingTrackers","trackerURLs","setTrackers","FLOOD_PROJECT_URL","versioned","replaceAll","packageJSON","AboutTab","Suspense","fallback","Markdown","clientConnectionSettingsRef","setError","isUserListFetched","setIsUserListFetched","AuthStore","currentUser","isAdmin","AuthActions","fetchUsers","users","interactiveListClasses","username","password","connectionSettings","createUser","client","level","AccessLevel","ADMINISTRATOR","USER","TransitionGroup","CSSTransition","classNames","timeout","enter","exit","LoadingRing","user","isCurrentUser","badge","removeIcon","deleteUser","ClientConnectionSettingsForm","onSettingsChange","settings","getChangedClientSetting","changedClientSettings","property","handleClientSettingChange","inputElement","changedClientSetting","processSpeedsForDisplay","speeds","processSpeedsForSave","replace","speed","BandwidthTab","onClientSettingsChange","setChangedClientSettings","speedLimits","download","dropdownPresetDownload","upload","dropdownPresetUpload","newChangedClientSettings","ConnectivityTab","attributes","setNodeRef","listeners","isDragging","useSortable","CSS","Transform","toString","Lock","SortableList","lockedIDs","renderItem","onMouseDown","currentItems","setCurrentItems","keyboardSensor","useSensor","KeyboardSensor","mouseSensor","MouseSensor","activationConstraint","distance","touchSensor","TouchSensor","touchAction","DndContext","sensors","onDragEnd","active","over","newItems","arrayMove","modifiers","restrictToVerticalAxis","restrictToParentElement","autoScroll","SortableContext","strategy","verticalListSortingStrategy","SortableListItem","MountPointsList","diskItems","setDiskItems","mountPoints","disks","assign","DiskUsageStore","disk","visible","diskItemVisiblity","checkbox","newItem","DiskUsageTab","ResourcesTab","ToggleList","checkboxLabel","isLocked","MiscUISettingsList","changedUIPageTitleSpeedEnabledRef","UIPageTitleSpeedEnabled","TorrentContextMenuActionsList","changedTorrentContextMenuActionsRef","defaultFloodSettings","torrentContextMenuActions","defaultVisible","find","setting","TorrentContextMenuActions","currentSetting","TorrentListColumnsList","torrentListViewSize","tooltipRef","torrentListColumns","setTorrentListColumns","column","TorrentListColumns","newColumn","torrentListColumnVisiblity","dismissTooltip","warning","changedTorrentListColumns","tooltipContent","Tooltip","offset","wrapText","Error","UITab","setTorrentListViewSize","selectedLanguage","setSelectedLanguage","language","setUITagSelectorMode","newSelectedLanguage","Languages","languageID","Radio","groupID","changedFloodSettings","setChangedFloodSettings","isSavingSettings","setSavingSettings","handleClientSettingsChange","handleFloodSettingsChange","bandwidth","connectivity","resources","authMethod","authentication","AuthTab","ui","diskusage","about","Promise","all","alert","ClientActions","isSmallScreen","TorrentMediainfo","cancelToken","CancelToken","source","clipboardRef","mediainfo","setMediainfo","fetchMediainfoError","setFetchMediainfoError","isFetchingMediainfo","setIsFetchingMediainfo","isCopiedToClipboard","setIsCopiedToClipboard","currentCancelToken","fetchMediainfo","token","fetchedMediainfo","output","isCancel","cancel","headingMessageId","Checkmark","position","right","selectAll","tree","applySelection","recursiveDepth","depth","path","currentPath","selectionSubTree","getSelectedItems","indices","fileName","directoryName","getSelectionTree","contents","pathComponents","pathComponent","shift","filename","DirectoryFiles","onItemSelect","copiedToClipboard","setCopiedToClipboard","contentPermalinks","FileIcon","textDecoration","Size","sizeBytes","precision","Math","trunc","percentComplete","PriorityMeter","maxLevel","fileIndex","priorityLevel","setFilePriority","priorityType","copy","link","share","getTorrentContentsDataPermalink","DirectoryTreeNode","itemsTree","expanded","setExpanded","DirectoryTree","childDepth","directoryNodes","subSelectedItems","DirectoryFileList","TorrentContents","setContents","setItemsTree","selectedIndices","setSelectedIndices","fetchTorrentContents","fetchedContents","selectionTree","directoryHeadingIconContent","fileDetailContent","allSelected","newItemsTree","Disk","selectedItem","directoryHeadingClasses","directoryHeading","wrapperClasses","shrink","countElement","createElement","body","appendChild","click","removeChild","persistentPlaceholder","LinkedText","nodes","s","URL","protocol","isValidHttpUrl","torrent","VALUE_NOT_AVAILABLE","colSpan","dateAdded","date","Date","year","month","day","hour","minute","dateFinished","connectedCount","peersConnected","connected","total","peersTotal","seedsConnected","seedsTotal","dateActive","dateCreated","torrentStatus","setTorrentStatus","status","torrentClasses","torrentStatusClasses","upRate","downRate","DownloadThick","isSpeed","bytesDone","UploadThick","upTotal","Ratio","ratio","Clock","Duration","eta","setPriority","startTorrents","Start","stopTorrents","Stop","ProgressBar","percent","computed","ceil","torrentStatusEffective","TorrentPeers","peers","setPeers","pollingDelay","setPollingDelay","fetchPeers","fetchTorrentPeers","pollInterval","useInterval","Badge","peer","country","countryCode","encryptedIcon","isEncrypted","incomingIcon","isIncoming","Spinner","CountryFlag","address","downloadRate","uploadRate","completedPercent","clientVersion","TorrentTrackers","trackerCount","trackerTypes","trackerDetails","TorrentGeneralInfo","TorrentHeading","createModal","ConfirmModal","MoveTorrentsModal","SettingsModal","TorrentDetailsModal","modal"],"sourceRoot":""}