emailengine-app 1.14.8 → 2.60.1

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 (2139) hide show
  1. package/.env.development +49 -0
  2. package/.env.example +82 -0
  3. package/.env.production +87 -0
  4. package/.eslintignore +1 -0
  5. package/.github/workflows/deploy.yml +104 -0
  6. package/.github/workflows/release.yaml +107 -0
  7. package/.github/workflows/test.yml +82 -0
  8. package/.ncurc.js +19 -5
  9. package/.prettierignore +44 -0
  10. package/CHANGELOG.md +1110 -0
  11. package/DOCKER_DEPLOYMENT.md +495 -0
  12. package/Dockerfile +53 -6
  13. package/Dockerfile-legacy +18 -0
  14. package/Fluid-Attacks-Results.csv +1 -0
  15. package/Gruntfile.js +46 -5
  16. package/LICENSE_EMAILENGINE.txt +110 -0
  17. package/README.md +72 -344
  18. package/app.json +40 -0
  19. package/bin/emailengine.js +283 -38
  20. package/config/default.toml +9 -11
  21. package/config/test.toml +45 -0
  22. package/copy-static-files.sh +34 -0
  23. package/data/google-crawlers.json +797 -0
  24. package/docker-compose.yml +103 -31
  25. package/encrypt.js +85 -10
  26. package/eslint.config.js +110 -0
  27. package/examples/auth-server.js +121 -69
  28. package/examples/grafana-dashboard.json +2375 -0
  29. package/help.txt +84 -0
  30. package/install.sh +426 -0
  31. package/lib/account.js +2348 -124
  32. package/lib/add-trackers.js +119 -0
  33. package/lib/api-routes/bull-board-routes.js +60 -0
  34. package/lib/api-routes/chat-routes.js +519 -0
  35. package/lib/api-routes/template-routes.js +490 -0
  36. package/lib/append-list.js +9 -2
  37. package/lib/arf-detect.js +200 -0
  38. package/lib/autodetect-imap-settings.js +781 -0
  39. package/lib/bounce-detect.js +280 -37
  40. package/lib/capa.js +97 -0
  41. package/lib/consts.js +210 -1
  42. package/lib/db.js +227 -8
  43. package/lib/document-store.js +54 -0
  44. package/lib/email-client/base-client.js +3677 -0
  45. package/lib/email-client/gmail-client.js +2796 -0
  46. package/lib/email-client/imap/mailbox.js +3721 -0
  47. package/lib/email-client/imap/subconnection.js +269 -0
  48. package/lib/email-client/imap-client.js +2628 -0
  49. package/lib/email-client/outlook-client.js +3805 -0
  50. package/lib/encrypt.js +85 -14
  51. package/lib/es.js +784 -0
  52. package/lib/feature-flags.js +42 -0
  53. package/lib/gateway.js +271 -0
  54. package/lib/generate-text-preview.js +56 -0
  55. package/lib/get-raw-email.js +302 -42
  56. package/lib/get-secret.js +23 -67
  57. package/lib/headers-rewriter.js +33 -0
  58. package/lib/imapproxy/imap-core/index.js +4 -0
  59. package/lib/imapproxy/imap-core/lib/commands/append.js +187 -0
  60. package/lib/imapproxy/imap-core/lib/commands/authenticate-plain.js +145 -0
  61. package/lib/imapproxy/imap-core/lib/commands/capability.js +13 -0
  62. package/lib/imapproxy/imap-core/lib/commands/check.js +10 -0
  63. package/lib/imapproxy/imap-core/lib/commands/close.js +44 -0
  64. package/lib/imapproxy/imap-core/lib/commands/compress.js +102 -0
  65. package/lib/imapproxy/imap-core/lib/commands/copy.js +109 -0
  66. package/lib/imapproxy/imap-core/lib/commands/create.js +93 -0
  67. package/lib/imapproxy/imap-core/lib/commands/delete.js +84 -0
  68. package/lib/imapproxy/imap-core/lib/commands/enable.js +36 -0
  69. package/lib/imapproxy/imap-core/lib/commands/expunge.js +68 -0
  70. package/lib/imapproxy/imap-core/lib/commands/fetch.js +385 -0
  71. package/lib/imapproxy/imap-core/lib/commands/getquota.js +85 -0
  72. package/lib/imapproxy/imap-core/lib/commands/getquotaroot.js +111 -0
  73. package/lib/imapproxy/imap-core/lib/commands/id.js +111 -0
  74. package/lib/imapproxy/imap-core/lib/commands/idle.js +45 -0
  75. package/lib/imapproxy/imap-core/lib/commands/list.js +218 -0
  76. package/lib/imapproxy/imap-core/lib/commands/login.js +135 -0
  77. package/lib/imapproxy/imap-core/lib/commands/logout.js +26 -0
  78. package/lib/imapproxy/imap-core/lib/commands/lsub.js +102 -0
  79. package/lib/imapproxy/imap-core/lib/commands/move.js +106 -0
  80. package/lib/imapproxy/imap-core/lib/commands/namespace.js +14 -0
  81. package/lib/imapproxy/imap-core/lib/commands/noop.js +10 -0
  82. package/lib/imapproxy/imap-core/lib/commands/rename.js +102 -0
  83. package/lib/imapproxy/imap-core/lib/commands/search.js +306 -0
  84. package/lib/imapproxy/imap-core/lib/commands/select.js +248 -0
  85. package/lib/imapproxy/imap-core/lib/commands/setquota.js +24 -0
  86. package/lib/imapproxy/imap-core/lib/commands/starttls.js +100 -0
  87. package/lib/imapproxy/imap-core/lib/commands/status.js +149 -0
  88. package/lib/imapproxy/imap-core/lib/commands/store.js +208 -0
  89. package/lib/imapproxy/imap-core/lib/commands/subscribe.js +69 -0
  90. package/lib/imapproxy/imap-core/lib/commands/uid-expunge.js +71 -0
  91. package/lib/imapproxy/imap-core/lib/commands/uid-store.js +170 -0
  92. package/lib/imapproxy/imap-core/lib/commands/unselect.js +14 -0
  93. package/lib/imapproxy/imap-core/lib/commands/unsubscribe.js +69 -0
  94. package/lib/imapproxy/imap-core/lib/handler/README.md +146 -0
  95. package/lib/imapproxy/imap-core/lib/handler/imap-compile-stream.js +252 -0
  96. package/lib/imapproxy/imap-core/lib/handler/imap-compiler.js +134 -0
  97. package/lib/imapproxy/imap-core/lib/handler/imap-formal-syntax.js +147 -0
  98. package/lib/imapproxy/imap-core/lib/handler/imap-handler.js +11 -0
  99. package/lib/imapproxy/imap-core/lib/handler/imap-parser.js +678 -0
  100. package/lib/imapproxy/imap-core/lib/imap-command.js +381 -0
  101. package/lib/imapproxy/imap-core/lib/imap-composer.js +71 -0
  102. package/lib/imapproxy/imap-core/lib/imap-connection.js +929 -0
  103. package/lib/imapproxy/imap-core/lib/imap-server.js +426 -0
  104. package/lib/imapproxy/imap-core/lib/imap-stream.js +172 -0
  105. package/lib/imapproxy/imap-core/lib/imap-tools.js +789 -0
  106. package/lib/imapproxy/imap-core/lib/indexer/body-structure.js +295 -0
  107. package/lib/imapproxy/imap-core/lib/indexer/create-envelope.js +103 -0
  108. package/lib/imapproxy/imap-core/lib/indexer/indexer.js +904 -0
  109. package/lib/imapproxy/imap-core/lib/indexer/parse-mime-tree.js +340 -0
  110. package/lib/imapproxy/imap-core/lib/length-limiter.js +76 -0
  111. package/lib/imapproxy/imap-core/lib/parse-date.js +225 -0
  112. package/lib/imapproxy/imap-core/lib/search.js +330 -0
  113. package/lib/imapproxy/imap-core/lib/tls-options.js +69 -0
  114. package/lib/imapproxy/imap-core/memory-notifier.js +129 -0
  115. package/lib/imapproxy/imap-core/test/client.js +46 -0
  116. package/lib/imapproxy/imap-core/test/fixtures/append.eml +1196 -0
  117. package/lib/imapproxy/imap-core/test/fixtures/chunks.js +44 -0
  118. package/lib/imapproxy/imap-core/test/fixtures/fix1.eml +6 -0
  119. package/lib/imapproxy/imap-core/test/fixtures/fix2.eml +599 -0
  120. package/lib/imapproxy/imap-core/test/fixtures/fix3.eml +32 -0
  121. package/lib/imapproxy/imap-core/test/fixtures/fix4.eml +6 -0
  122. package/lib/imapproxy/imap-core/test/fixtures/mimetorture.eml +599 -0
  123. package/lib/imapproxy/imap-core/test/fixtures/mimetorture.js +2740 -0
  124. package/lib/imapproxy/imap-core/test/fixtures/mimetorture.json +1411 -0
  125. package/lib/imapproxy/imap-core/test/fixtures/mimetree.js +85 -0
  126. package/lib/imapproxy/imap-core/test/fixtures/nodemailer.eml +582 -0
  127. package/lib/imapproxy/imap-core/test/fixtures/ryan_finnie_mime_torture.eml +599 -0
  128. package/lib/imapproxy/imap-core/test/fixtures/simple.eml +42 -0
  129. package/lib/imapproxy/imap-core/test/fixtures/simple.json +164 -0
  130. package/lib/imapproxy/imap-core/test/imap-compile-stream-test.js +671 -0
  131. package/lib/imapproxy/imap-core/test/imap-compiler-test.js +272 -0
  132. package/lib/imapproxy/imap-core/test/imap-indexer-test.js +236 -0
  133. package/lib/imapproxy/imap-core/test/imap-parser-test.js +922 -0
  134. package/lib/imapproxy/imap-core/test/memory-notifier.js +129 -0
  135. package/lib/imapproxy/imap-core/test/prepare.sh +74 -0
  136. package/lib/imapproxy/imap-core/test/protocol-test.js +1756 -0
  137. package/lib/imapproxy/imap-core/test/search-test.js +1356 -0
  138. package/lib/imapproxy/imap-core/test/test-client.js +152 -0
  139. package/lib/imapproxy/imap-core/test/test-server.js +623 -0
  140. package/lib/imapproxy/imap-core/test/tools-test.js +22 -0
  141. package/lib/imapproxy/imap-server.js +577 -0
  142. package/lib/lists.js +92 -0
  143. package/lib/llm-pre-process.js +141 -0
  144. package/lib/logger.js +43 -4
  145. package/lib/lua/ee-get-idempotency.lua +74 -0
  146. package/lib/lua/ee-list-add.lua +34 -0
  147. package/lib/lua/ee-list-remove.lua +37 -0
  148. package/lib/lua/h-incrby-exists.lua +28 -0
  149. package/lib/lua/h-push.lua +32 -0
  150. package/lib/lua/h-set-bigger.lua +40 -0
  151. package/lib/lua/h-set-exists.lua +29 -0
  152. package/lib/lua/h-set-new.lua +29 -0
  153. package/lib/lua/h-update-bigger.lua +45 -0
  154. package/lib/lua/s-list-accounts.lua +64 -14
  155. package/lib/lua/z-expunge.lua +86 -10
  156. package/lib/lua/z-get-by-uid.lua +28 -5
  157. package/lib/lua/z-get-mailbox-id.lua +24 -2
  158. package/lib/lua/z-get-mailbox-path.lua +16 -0
  159. package/lib/lua/z-get.lua +27 -4
  160. package/lib/lua/z-set.lua +24 -2
  161. package/lib/metrics-collector.js +209 -0
  162. package/lib/oauth/gmail.js +663 -0
  163. package/lib/oauth/mail-ru.js +310 -0
  164. package/lib/oauth/outlook.js +541 -0
  165. package/lib/oauth/pubsub/google.js +247 -0
  166. package/lib/oauth2-apps.js +1420 -0
  167. package/lib/outbox.js +140 -0
  168. package/lib/payload-examples-documents.json +404 -0
  169. package/lib/payload-examples-webhooks.json +266 -0
  170. package/lib/pre-process.js +193 -0
  171. package/lib/rate-limit.js +32 -0
  172. package/lib/reconnection-manager.js +106 -0
  173. package/lib/redis-scan-delete.js +82 -0
  174. package/lib/redis-url.js +78 -0
  175. package/lib/rewrite-text-nodes.js +267 -0
  176. package/lib/routes-ui.js +10247 -0
  177. package/lib/schemas.js +1576 -187
  178. package/lib/settings.js +263 -12
  179. package/lib/sub-script.js +109 -0
  180. package/lib/templates.js +240 -0
  181. package/lib/threads.js +155 -0
  182. package/lib/tokens.js +353 -0
  183. package/lib/tools.js +1773 -41
  184. package/lib/translations.js +33 -0
  185. package/lib/webhooks.js +605 -0
  186. package/list-generate.js +96 -0
  187. package/package.json +130 -54
  188. package/render.yaml +44 -0
  189. package/sbom.json +1 -0
  190. package/scan.js +14 -2
  191. package/scripts/README.md +50 -0
  192. package/scripts/refresh-test-tokens.js +180 -0
  193. package/server.js +2902 -376
  194. package/setup-production.sh +201 -0
  195. package/static/{bootstrap-4.6.0-dist → bootstrap-4.6.2-dist}/css/bootstrap-grid.css +3 -3
  196. package/static/bootstrap-4.6.2-dist/css/bootstrap-grid.css.map +1 -0
  197. package/static/{bootstrap-4.6.0-dist → bootstrap-4.6.2-dist}/css/bootstrap-grid.min.css +3 -3
  198. package/static/{bootstrap-4.6.0-dist → bootstrap-4.6.2-dist}/css/bootstrap-grid.min.css.map +1 -1
  199. package/static/{bootstrap-4.6.0-dist → bootstrap-4.6.2-dist}/css/bootstrap-reboot.css +3 -3
  200. package/static/bootstrap-4.6.2-dist/css/bootstrap-reboot.css.map +1 -0
  201. package/static/{bootstrap-4.6.0-dist → bootstrap-4.6.2-dist}/css/bootstrap-reboot.min.css +3 -3
  202. package/static/bootstrap-4.6.2-dist/css/bootstrap-reboot.min.css.map +1 -0
  203. package/static/{bootstrap-4.6.0-dist → bootstrap-4.6.2-dist}/css/bootstrap.css +60 -26
  204. package/static/bootstrap-4.6.2-dist/css/bootstrap.css.map +1 -0
  205. package/static/bootstrap-4.6.2-dist/css/bootstrap.min.css +7 -0
  206. package/static/bootstrap-4.6.2-dist/css/bootstrap.min.css.map +1 -0
  207. package/static/bootstrap-4.6.2-dist/js/bootstrap.bundle.js +7155 -0
  208. package/static/bootstrap-4.6.2-dist/js/bootstrap.bundle.js.map +784 -0
  209. package/static/bootstrap-4.6.2-dist/js/bootstrap.bundle.min.js +7 -0
  210. package/static/bootstrap-4.6.2-dist/js/bootstrap.bundle.min.js.map +959 -0
  211. package/static/{bootstrap-4.6.0-dist → bootstrap-4.6.2-dist}/js/bootstrap.js +792 -868
  212. package/static/bootstrap-4.6.2-dist/js/bootstrap.js.map +1 -0
  213. package/static/bootstrap-4.6.2-dist/js/bootstrap.min.js +7 -0
  214. package/static/bootstrap-4.6.2-dist/js/bootstrap.min.js.map +1 -0
  215. package/static/css/app.css +146 -0
  216. package/static/css/arena.css +777 -0
  217. package/static/css/default.min.css +9 -0
  218. package/static/css/highlight.min.css +9 -0
  219. package/static/css/sb-admin-2.min.css +10 -0
  220. package/static/emailengine.ico +0 -0
  221. package/static/favicon/android-chrome-192x192.png +0 -0
  222. package/static/favicon/android-chrome-512x512.png +0 -0
  223. package/static/favicon/apple-touch-icon.png +0 -0
  224. package/static/favicon/favicon-16x16.png +0 -0
  225. package/static/favicon/favicon-32x32.png +0 -0
  226. package/static/favicon/favicon.ico +0 -0
  227. package/static/favicon.ico +0 -0
  228. package/static/fonts/nunito/OFL.txt +93 -0
  229. package/static/fonts/nunito/XRXV3I6Li01BKofINeaBTMnFcQ.woff2 +0 -0
  230. package/static/fonts/nunito-font.css +66 -0
  231. package/static/front/EmailEngine_logo_horiz.png +0 -0
  232. package/static/front/EmailEngine_logo_vert.png +0 -0
  233. package/static/front/index.html +57 -0
  234. package/static/front/logo.png +0 -0
  235. package/static/imap-capabilities-1.csv +71 -0
  236. package/static/index.html +30 -713
  237. package/static/js/ace/README.txt +1 -0
  238. package/static/js/ace/ace.js +23 -0
  239. package/static/js/ace/ext-language_tools.js +8 -0
  240. package/static/js/ace/ext-searchbox.js +8 -0
  241. package/static/js/ace/mode-handlebars.js +8 -0
  242. package/static/js/ace/mode-html.js +8 -0
  243. package/static/js/ace/mode-javascript.js +8 -0
  244. package/static/js/ace/mode-json.js +8 -0
  245. package/static/js/ace/mode-markdown.js +8 -0
  246. package/static/js/ace/snippets/javascript.js +8 -0
  247. package/static/js/ace/snippets/markdown.js +8 -0
  248. package/static/js/ace/theme-kuroir.js +8 -0
  249. package/static/js/ace/theme-xcode.js +8 -0
  250. package/static/js/ace/worker-html.js +1 -0
  251. package/static/js/ace/worker-javascript.js +1 -0
  252. package/static/js/ace/worker-json.js +1 -0
  253. package/static/js/app.js +526 -0
  254. package/static/js/bootstrap-autocomplete.min.js +1 -0
  255. package/static/js/clipboard.min.js +517 -0
  256. package/static/js/ee-client.js +1977 -0
  257. package/static/js/evaluation-worker.js +47 -0
  258. package/static/js/highlight.min.js +1173 -0
  259. package/static/js/jquery-3.6.0.min.js +2 -0
  260. package/static/js/sb-admin-2.min.js +7 -0
  261. package/static/licenses.html +6606 -50
  262. package/static/logo/EmailEngine_logo_horiz.png +0 -0
  263. package/static/logo/EmailEngine_logo_vert.png +0 -0
  264. package/static/logo.png +0 -0
  265. package/static/logo_transparent.png +0 -0
  266. package/static/logo_transparent_small.png +0 -0
  267. package/static/logo_wide.png +0 -0
  268. package/static/preview/header-template.png +0 -0
  269. package/static/preview/render.png +0 -0
  270. package/static/preview/translation.png +0 -0
  271. package/static/providers/google_dark.png +0 -0
  272. package/static/providers/google_dark_edited.png +0 -0
  273. package/static/providers/google_light.png +0 -0
  274. package/static/providers/ms_dark.svg +1 -0
  275. package/static/providers/ms_light.svg +1 -0
  276. package/static/robots.txt +4 -0
  277. package/static/undraw_profile.svg +38 -0
  278. package/static/vendor/fontawesome-free/LICENSE.txt +34 -0
  279. package/static/vendor/fontawesome-free/attribution.js +3 -0
  280. package/static/vendor/fontawesome-free/css/all.css +4619 -0
  281. package/static/vendor/fontawesome-free/css/all.min.css +5 -0
  282. package/static/vendor/fontawesome-free/css/brands.css +15 -0
  283. package/static/vendor/fontawesome-free/css/brands.min.css +5 -0
  284. package/static/vendor/fontawesome-free/css/fontawesome.css +4585 -0
  285. package/static/vendor/fontawesome-free/css/fontawesome.min.css +5 -0
  286. package/static/vendor/fontawesome-free/css/regular.css +15 -0
  287. package/static/vendor/fontawesome-free/css/regular.min.css +5 -0
  288. package/static/vendor/fontawesome-free/css/solid.css +16 -0
  289. package/static/vendor/fontawesome-free/css/solid.min.css +5 -0
  290. package/static/vendor/fontawesome-free/css/svg-with-js.css +371 -0
  291. package/static/vendor/fontawesome-free/css/svg-with-js.min.css +5 -0
  292. package/static/vendor/fontawesome-free/css/v4-shims.css +2172 -0
  293. package/static/vendor/fontawesome-free/css/v4-shims.min.css +5 -0
  294. package/static/vendor/fontawesome-free/js/all.js +4467 -0
  295. package/static/vendor/fontawesome-free/js/all.min.js +5 -0
  296. package/static/vendor/fontawesome-free/js/brands.js +586 -0
  297. package/static/vendor/fontawesome-free/js/brands.min.js +5 -0
  298. package/static/vendor/fontawesome-free/js/conflict-detection.js +998 -0
  299. package/static/vendor/fontawesome-free/js/conflict-detection.min.js +5 -0
  300. package/static/vendor/fontawesome-free/js/fontawesome.js +2483 -0
  301. package/static/vendor/fontawesome-free/js/fontawesome.min.js +5 -0
  302. package/static/vendor/fontawesome-free/js/regular.js +280 -0
  303. package/static/vendor/fontawesome-free/js/regular.min.js +5 -0
  304. package/static/vendor/fontawesome-free/js/solid.js +1130 -0
  305. package/static/vendor/fontawesome-free/js/solid.min.js +5 -0
  306. package/static/vendor/fontawesome-free/js/v4-shims.js +68 -0
  307. package/static/vendor/fontawesome-free/js/v4-shims.min.js +5 -0
  308. package/static/vendor/fontawesome-free/less/_animated.less +19 -0
  309. package/static/vendor/fontawesome-free/less/_bordered-pulled.less +16 -0
  310. package/static/vendor/fontawesome-free/less/_core.less +12 -0
  311. package/static/vendor/fontawesome-free/less/_fixed-width.less +6 -0
  312. package/static/vendor/fontawesome-free/less/_icons.less +1462 -0
  313. package/static/vendor/fontawesome-free/less/_larger.less +27 -0
  314. package/static/vendor/fontawesome-free/less/_list.less +18 -0
  315. package/static/vendor/fontawesome-free/less/_mixins.less +56 -0
  316. package/static/vendor/fontawesome-free/less/_rotated-flipped.less +24 -0
  317. package/static/vendor/fontawesome-free/less/_screen-reader.less +5 -0
  318. package/static/vendor/fontawesome-free/less/_shims.less +2066 -0
  319. package/static/vendor/fontawesome-free/less/_stacked.less +22 -0
  320. package/static/vendor/fontawesome-free/less/_variables.less +1474 -0
  321. package/static/vendor/fontawesome-free/less/brands.less +23 -0
  322. package/static/vendor/fontawesome-free/less/fontawesome.less +16 -0
  323. package/static/vendor/fontawesome-free/less/regular.less +23 -0
  324. package/static/vendor/fontawesome-free/less/solid.less +24 -0
  325. package/static/vendor/fontawesome-free/less/v4-shims.less +6 -0
  326. package/static/vendor/fontawesome-free/metadata/categories.yml +2572 -0
  327. package/static/vendor/fontawesome-free/metadata/icons.yml +21783 -0
  328. package/static/vendor/fontawesome-free/metadata/shims.yml +298 -0
  329. package/static/vendor/fontawesome-free/metadata/sponsors.yml +744 -0
  330. package/static/vendor/fontawesome-free/package.json +58 -0
  331. package/static/vendor/fontawesome-free/scss/_animated.scss +20 -0
  332. package/static/vendor/fontawesome-free/scss/_bordered-pulled.scss +20 -0
  333. package/static/vendor/fontawesome-free/scss/_core.scss +21 -0
  334. package/static/vendor/fontawesome-free/scss/_fixed-width.scss +6 -0
  335. package/static/vendor/fontawesome-free/scss/_icons.scss +1462 -0
  336. package/static/vendor/fontawesome-free/scss/_larger.scss +23 -0
  337. package/static/vendor/fontawesome-free/scss/_list.scss +18 -0
  338. package/static/vendor/fontawesome-free/scss/_mixins.scss +56 -0
  339. package/static/vendor/fontawesome-free/scss/_rotated-flipped.scss +24 -0
  340. package/static/vendor/fontawesome-free/scss/_screen-reader.scss +5 -0
  341. package/static/vendor/fontawesome-free/scss/_shims.scss +2066 -0
  342. package/static/vendor/fontawesome-free/scss/_stacked.scss +31 -0
  343. package/static/vendor/fontawesome-free/scss/_variables.scss +1479 -0
  344. package/static/vendor/fontawesome-free/scss/brands.scss +23 -0
  345. package/static/vendor/fontawesome-free/scss/fontawesome.scss +16 -0
  346. package/static/vendor/fontawesome-free/scss/regular.scss +23 -0
  347. package/static/vendor/fontawesome-free/scss/solid.scss +24 -0
  348. package/static/vendor/fontawesome-free/scss/v4-shims.scss +6 -0
  349. package/static/vendor/fontawesome-free/sprites/brands.svg +1381 -0
  350. package/static/vendor/fontawesome-free/sprites/regular.svg +463 -0
  351. package/static/vendor/fontawesome-free/sprites/solid.svg +3013 -0
  352. package/static/vendor/fontawesome-free/svgs/brands/500px.svg +1 -0
  353. package/static/vendor/fontawesome-free/svgs/brands/accessible-icon.svg +1 -0
  354. package/static/vendor/fontawesome-free/svgs/brands/accusoft.svg +1 -0
  355. package/static/vendor/fontawesome-free/svgs/brands/acquisitions-incorporated.svg +1 -0
  356. package/static/vendor/fontawesome-free/svgs/brands/adn.svg +1 -0
  357. package/static/vendor/fontawesome-free/svgs/brands/adversal.svg +1 -0
  358. package/static/vendor/fontawesome-free/svgs/brands/affiliatetheme.svg +1 -0
  359. package/static/vendor/fontawesome-free/svgs/brands/airbnb.svg +1 -0
  360. package/static/vendor/fontawesome-free/svgs/brands/algolia.svg +1 -0
  361. package/static/vendor/fontawesome-free/svgs/brands/alipay.svg +1 -0
  362. package/static/vendor/fontawesome-free/svgs/brands/amazon-pay.svg +1 -0
  363. package/static/vendor/fontawesome-free/svgs/brands/amazon.svg +1 -0
  364. package/static/vendor/fontawesome-free/svgs/brands/amilia.svg +1 -0
  365. package/static/vendor/fontawesome-free/svgs/brands/android.svg +1 -0
  366. package/static/vendor/fontawesome-free/svgs/brands/angellist.svg +1 -0
  367. package/static/vendor/fontawesome-free/svgs/brands/angrycreative.svg +1 -0
  368. package/static/vendor/fontawesome-free/svgs/brands/angular.svg +1 -0
  369. package/static/vendor/fontawesome-free/svgs/brands/app-store-ios.svg +1 -0
  370. package/static/vendor/fontawesome-free/svgs/brands/app-store.svg +1 -0
  371. package/static/vendor/fontawesome-free/svgs/brands/apper.svg +1 -0
  372. package/static/vendor/fontawesome-free/svgs/brands/apple-pay.svg +1 -0
  373. package/static/vendor/fontawesome-free/svgs/brands/apple.svg +1 -0
  374. package/static/vendor/fontawesome-free/svgs/brands/artstation.svg +1 -0
  375. package/static/vendor/fontawesome-free/svgs/brands/asymmetrik.svg +1 -0
  376. package/static/vendor/fontawesome-free/svgs/brands/atlassian.svg +1 -0
  377. package/static/vendor/fontawesome-free/svgs/brands/audible.svg +1 -0
  378. package/static/vendor/fontawesome-free/svgs/brands/autoprefixer.svg +1 -0
  379. package/static/vendor/fontawesome-free/svgs/brands/avianex.svg +1 -0
  380. package/static/vendor/fontawesome-free/svgs/brands/aviato.svg +1 -0
  381. package/static/vendor/fontawesome-free/svgs/brands/aws.svg +1 -0
  382. package/static/vendor/fontawesome-free/svgs/brands/bandcamp.svg +1 -0
  383. package/static/vendor/fontawesome-free/svgs/brands/battle-net.svg +1 -0
  384. package/static/vendor/fontawesome-free/svgs/brands/behance-square.svg +1 -0
  385. package/static/vendor/fontawesome-free/svgs/brands/behance.svg +1 -0
  386. package/static/vendor/fontawesome-free/svgs/brands/bimobject.svg +1 -0
  387. package/static/vendor/fontawesome-free/svgs/brands/bitbucket.svg +1 -0
  388. package/static/vendor/fontawesome-free/svgs/brands/bitcoin.svg +1 -0
  389. package/static/vendor/fontawesome-free/svgs/brands/bity.svg +1 -0
  390. package/static/vendor/fontawesome-free/svgs/brands/black-tie.svg +1 -0
  391. package/static/vendor/fontawesome-free/svgs/brands/blackberry.svg +1 -0
  392. package/static/vendor/fontawesome-free/svgs/brands/blogger-b.svg +1 -0
  393. package/static/vendor/fontawesome-free/svgs/brands/blogger.svg +1 -0
  394. package/static/vendor/fontawesome-free/svgs/brands/bluetooth-b.svg +1 -0
  395. package/static/vendor/fontawesome-free/svgs/brands/bluetooth.svg +1 -0
  396. package/static/vendor/fontawesome-free/svgs/brands/bootstrap.svg +1 -0
  397. package/static/vendor/fontawesome-free/svgs/brands/btc.svg +1 -0
  398. package/static/vendor/fontawesome-free/svgs/brands/buffer.svg +1 -0
  399. package/static/vendor/fontawesome-free/svgs/brands/buromobelexperte.svg +1 -0
  400. package/static/vendor/fontawesome-free/svgs/brands/buy-n-large.svg +1 -0
  401. package/static/vendor/fontawesome-free/svgs/brands/buysellads.svg +1 -0
  402. package/static/vendor/fontawesome-free/svgs/brands/canadian-maple-leaf.svg +1 -0
  403. package/static/vendor/fontawesome-free/svgs/brands/cc-amazon-pay.svg +1 -0
  404. package/static/vendor/fontawesome-free/svgs/brands/cc-amex.svg +1 -0
  405. package/static/vendor/fontawesome-free/svgs/brands/cc-apple-pay.svg +1 -0
  406. package/static/vendor/fontawesome-free/svgs/brands/cc-diners-club.svg +1 -0
  407. package/static/vendor/fontawesome-free/svgs/brands/cc-discover.svg +1 -0
  408. package/static/vendor/fontawesome-free/svgs/brands/cc-jcb.svg +1 -0
  409. package/static/vendor/fontawesome-free/svgs/brands/cc-mastercard.svg +1 -0
  410. package/static/vendor/fontawesome-free/svgs/brands/cc-paypal.svg +1 -0
  411. package/static/vendor/fontawesome-free/svgs/brands/cc-stripe.svg +1 -0
  412. package/static/vendor/fontawesome-free/svgs/brands/cc-visa.svg +1 -0
  413. package/static/vendor/fontawesome-free/svgs/brands/centercode.svg +1 -0
  414. package/static/vendor/fontawesome-free/svgs/brands/centos.svg +1 -0
  415. package/static/vendor/fontawesome-free/svgs/brands/chrome.svg +1 -0
  416. package/static/vendor/fontawesome-free/svgs/brands/chromecast.svg +1 -0
  417. package/static/vendor/fontawesome-free/svgs/brands/cloudflare.svg +1 -0
  418. package/static/vendor/fontawesome-free/svgs/brands/cloudscale.svg +1 -0
  419. package/static/vendor/fontawesome-free/svgs/brands/cloudsmith.svg +1 -0
  420. package/static/vendor/fontawesome-free/svgs/brands/cloudversify.svg +1 -0
  421. package/static/vendor/fontawesome-free/svgs/brands/codepen.svg +1 -0
  422. package/static/vendor/fontawesome-free/svgs/brands/codiepie.svg +1 -0
  423. package/static/vendor/fontawesome-free/svgs/brands/confluence.svg +1 -0
  424. package/static/vendor/fontawesome-free/svgs/brands/connectdevelop.svg +1 -0
  425. package/static/vendor/fontawesome-free/svgs/brands/contao.svg +1 -0
  426. package/static/vendor/fontawesome-free/svgs/brands/cotton-bureau.svg +1 -0
  427. package/static/vendor/fontawesome-free/svgs/brands/cpanel.svg +1 -0
  428. package/static/vendor/fontawesome-free/svgs/brands/creative-commons-by.svg +1 -0
  429. package/static/vendor/fontawesome-free/svgs/brands/creative-commons-nc-eu.svg +1 -0
  430. package/static/vendor/fontawesome-free/svgs/brands/creative-commons-nc-jp.svg +1 -0
  431. package/static/vendor/fontawesome-free/svgs/brands/creative-commons-nc.svg +1 -0
  432. package/static/vendor/fontawesome-free/svgs/brands/creative-commons-nd.svg +1 -0
  433. package/static/vendor/fontawesome-free/svgs/brands/creative-commons-pd-alt.svg +1 -0
  434. package/static/vendor/fontawesome-free/svgs/brands/creative-commons-pd.svg +1 -0
  435. package/static/vendor/fontawesome-free/svgs/brands/creative-commons-remix.svg +1 -0
  436. package/static/vendor/fontawesome-free/svgs/brands/creative-commons-sa.svg +1 -0
  437. package/static/vendor/fontawesome-free/svgs/brands/creative-commons-sampling-plus.svg +1 -0
  438. package/static/vendor/fontawesome-free/svgs/brands/creative-commons-sampling.svg +1 -0
  439. package/static/vendor/fontawesome-free/svgs/brands/creative-commons-share.svg +1 -0
  440. package/static/vendor/fontawesome-free/svgs/brands/creative-commons-zero.svg +1 -0
  441. package/static/vendor/fontawesome-free/svgs/brands/creative-commons.svg +1 -0
  442. package/static/vendor/fontawesome-free/svgs/brands/critical-role.svg +1 -0
  443. package/static/vendor/fontawesome-free/svgs/brands/css3-alt.svg +1 -0
  444. package/static/vendor/fontawesome-free/svgs/brands/css3.svg +1 -0
  445. package/static/vendor/fontawesome-free/svgs/brands/cuttlefish.svg +1 -0
  446. package/static/vendor/fontawesome-free/svgs/brands/d-and-d-beyond.svg +1 -0
  447. package/static/vendor/fontawesome-free/svgs/brands/d-and-d.svg +1 -0
  448. package/static/vendor/fontawesome-free/svgs/brands/dailymotion.svg +1 -0
  449. package/static/vendor/fontawesome-free/svgs/brands/dashcube.svg +1 -0
  450. package/static/vendor/fontawesome-free/svgs/brands/deezer.svg +1 -0
  451. package/static/vendor/fontawesome-free/svgs/brands/delicious.svg +1 -0
  452. package/static/vendor/fontawesome-free/svgs/brands/deploydog.svg +1 -0
  453. package/static/vendor/fontawesome-free/svgs/brands/deskpro.svg +1 -0
  454. package/static/vendor/fontawesome-free/svgs/brands/dev.svg +1 -0
  455. package/static/vendor/fontawesome-free/svgs/brands/deviantart.svg +1 -0
  456. package/static/vendor/fontawesome-free/svgs/brands/dhl.svg +1 -0
  457. package/static/vendor/fontawesome-free/svgs/brands/diaspora.svg +1 -0
  458. package/static/vendor/fontawesome-free/svgs/brands/digg.svg +1 -0
  459. package/static/vendor/fontawesome-free/svgs/brands/digital-ocean.svg +1 -0
  460. package/static/vendor/fontawesome-free/svgs/brands/discord.svg +1 -0
  461. package/static/vendor/fontawesome-free/svgs/brands/discourse.svg +1 -0
  462. package/static/vendor/fontawesome-free/svgs/brands/dochub.svg +1 -0
  463. package/static/vendor/fontawesome-free/svgs/brands/docker.svg +1 -0
  464. package/static/vendor/fontawesome-free/svgs/brands/draft2digital.svg +1 -0
  465. package/static/vendor/fontawesome-free/svgs/brands/dribbble-square.svg +1 -0
  466. package/static/vendor/fontawesome-free/svgs/brands/dribbble.svg +1 -0
  467. package/static/vendor/fontawesome-free/svgs/brands/dropbox.svg +1 -0
  468. package/static/vendor/fontawesome-free/svgs/brands/drupal.svg +1 -0
  469. package/static/vendor/fontawesome-free/svgs/brands/dyalog.svg +1 -0
  470. package/static/vendor/fontawesome-free/svgs/brands/earlybirds.svg +1 -0
  471. package/static/vendor/fontawesome-free/svgs/brands/ebay.svg +1 -0
  472. package/static/vendor/fontawesome-free/svgs/brands/edge-legacy.svg +1 -0
  473. package/static/vendor/fontawesome-free/svgs/brands/edge.svg +1 -0
  474. package/static/vendor/fontawesome-free/svgs/brands/elementor.svg +1 -0
  475. package/static/vendor/fontawesome-free/svgs/brands/ello.svg +1 -0
  476. package/static/vendor/fontawesome-free/svgs/brands/ember.svg +1 -0
  477. package/static/vendor/fontawesome-free/svgs/brands/empire.svg +1 -0
  478. package/static/vendor/fontawesome-free/svgs/brands/envira.svg +1 -0
  479. package/static/vendor/fontawesome-free/svgs/brands/erlang.svg +1 -0
  480. package/static/vendor/fontawesome-free/svgs/brands/ethereum.svg +1 -0
  481. package/static/vendor/fontawesome-free/svgs/brands/etsy.svg +1 -0
  482. package/static/vendor/fontawesome-free/svgs/brands/evernote.svg +1 -0
  483. package/static/vendor/fontawesome-free/svgs/brands/expeditedssl.svg +1 -0
  484. package/static/vendor/fontawesome-free/svgs/brands/facebook-f.svg +1 -0
  485. package/static/vendor/fontawesome-free/svgs/brands/facebook-messenger.svg +1 -0
  486. package/static/vendor/fontawesome-free/svgs/brands/facebook-square.svg +1 -0
  487. package/static/vendor/fontawesome-free/svgs/brands/facebook.svg +1 -0
  488. package/static/vendor/fontawesome-free/svgs/brands/fantasy-flight-games.svg +1 -0
  489. package/static/vendor/fontawesome-free/svgs/brands/fedex.svg +1 -0
  490. package/static/vendor/fontawesome-free/svgs/brands/fedora.svg +1 -0
  491. package/static/vendor/fontawesome-free/svgs/brands/figma.svg +1 -0
  492. package/static/vendor/fontawesome-free/svgs/brands/firefox-browser.svg +1 -0
  493. package/static/vendor/fontawesome-free/svgs/brands/firefox.svg +1 -0
  494. package/static/vendor/fontawesome-free/svgs/brands/first-order-alt.svg +1 -0
  495. package/static/vendor/fontawesome-free/svgs/brands/first-order.svg +1 -0
  496. package/static/vendor/fontawesome-free/svgs/brands/firstdraft.svg +1 -0
  497. package/static/vendor/fontawesome-free/svgs/brands/flickr.svg +1 -0
  498. package/static/vendor/fontawesome-free/svgs/brands/flipboard.svg +1 -0
  499. package/static/vendor/fontawesome-free/svgs/brands/fly.svg +1 -0
  500. package/static/vendor/fontawesome-free/svgs/brands/font-awesome-alt.svg +1 -0
  501. package/static/vendor/fontawesome-free/svgs/brands/font-awesome-flag.svg +1 -0
  502. package/static/vendor/fontawesome-free/svgs/brands/font-awesome-logo-full.svg +1 -0
  503. package/static/vendor/fontawesome-free/svgs/brands/font-awesome.svg +1 -0
  504. package/static/vendor/fontawesome-free/svgs/brands/fonticons-fi.svg +1 -0
  505. package/static/vendor/fontawesome-free/svgs/brands/fonticons.svg +1 -0
  506. package/static/vendor/fontawesome-free/svgs/brands/fort-awesome-alt.svg +1 -0
  507. package/static/vendor/fontawesome-free/svgs/brands/fort-awesome.svg +1 -0
  508. package/static/vendor/fontawesome-free/svgs/brands/forumbee.svg +1 -0
  509. package/static/vendor/fontawesome-free/svgs/brands/foursquare.svg +1 -0
  510. package/static/vendor/fontawesome-free/svgs/brands/free-code-camp.svg +1 -0
  511. package/static/vendor/fontawesome-free/svgs/brands/freebsd.svg +1 -0
  512. package/static/vendor/fontawesome-free/svgs/brands/fulcrum.svg +1 -0
  513. package/static/vendor/fontawesome-free/svgs/brands/galactic-republic.svg +1 -0
  514. package/static/vendor/fontawesome-free/svgs/brands/galactic-senate.svg +1 -0
  515. package/static/vendor/fontawesome-free/svgs/brands/get-pocket.svg +1 -0
  516. package/static/vendor/fontawesome-free/svgs/brands/gg-circle.svg +1 -0
  517. package/static/vendor/fontawesome-free/svgs/brands/gg.svg +1 -0
  518. package/static/vendor/fontawesome-free/svgs/brands/git-alt.svg +1 -0
  519. package/static/vendor/fontawesome-free/svgs/brands/git-square.svg +1 -0
  520. package/static/vendor/fontawesome-free/svgs/brands/git.svg +1 -0
  521. package/static/vendor/fontawesome-free/svgs/brands/github-alt.svg +1 -0
  522. package/static/vendor/fontawesome-free/svgs/brands/github-square.svg +1 -0
  523. package/static/vendor/fontawesome-free/svgs/brands/github.svg +1 -0
  524. package/static/vendor/fontawesome-free/svgs/brands/gitkraken.svg +1 -0
  525. package/static/vendor/fontawesome-free/svgs/brands/gitlab.svg +1 -0
  526. package/static/vendor/fontawesome-free/svgs/brands/gitter.svg +1 -0
  527. package/static/vendor/fontawesome-free/svgs/brands/glide-g.svg +1 -0
  528. package/static/vendor/fontawesome-free/svgs/brands/glide.svg +1 -0
  529. package/static/vendor/fontawesome-free/svgs/brands/gofore.svg +1 -0
  530. package/static/vendor/fontawesome-free/svgs/brands/goodreads-g.svg +1 -0
  531. package/static/vendor/fontawesome-free/svgs/brands/goodreads.svg +1 -0
  532. package/static/vendor/fontawesome-free/svgs/brands/google-drive.svg +1 -0
  533. package/static/vendor/fontawesome-free/svgs/brands/google-pay.svg +1 -0
  534. package/static/vendor/fontawesome-free/svgs/brands/google-play.svg +1 -0
  535. package/static/vendor/fontawesome-free/svgs/brands/google-plus-g.svg +1 -0
  536. package/static/vendor/fontawesome-free/svgs/brands/google-plus-square.svg +1 -0
  537. package/static/vendor/fontawesome-free/svgs/brands/google-plus.svg +1 -0
  538. package/static/vendor/fontawesome-free/svgs/brands/google-wallet.svg +1 -0
  539. package/static/vendor/fontawesome-free/svgs/brands/google.svg +1 -0
  540. package/static/vendor/fontawesome-free/svgs/brands/gratipay.svg +1 -0
  541. package/static/vendor/fontawesome-free/svgs/brands/grav.svg +1 -0
  542. package/static/vendor/fontawesome-free/svgs/brands/gripfire.svg +1 -0
  543. package/static/vendor/fontawesome-free/svgs/brands/grunt.svg +1 -0
  544. package/static/vendor/fontawesome-free/svgs/brands/guilded.svg +1 -0
  545. package/static/vendor/fontawesome-free/svgs/brands/gulp.svg +1 -0
  546. package/static/vendor/fontawesome-free/svgs/brands/hacker-news-square.svg +1 -0
  547. package/static/vendor/fontawesome-free/svgs/brands/hacker-news.svg +1 -0
  548. package/static/vendor/fontawesome-free/svgs/brands/hackerrank.svg +1 -0
  549. package/static/vendor/fontawesome-free/svgs/brands/hips.svg +1 -0
  550. package/static/vendor/fontawesome-free/svgs/brands/hire-a-helper.svg +1 -0
  551. package/static/vendor/fontawesome-free/svgs/brands/hive.svg +1 -0
  552. package/static/vendor/fontawesome-free/svgs/brands/hooli.svg +1 -0
  553. package/static/vendor/fontawesome-free/svgs/brands/hornbill.svg +1 -0
  554. package/static/vendor/fontawesome-free/svgs/brands/hotjar.svg +1 -0
  555. package/static/vendor/fontawesome-free/svgs/brands/houzz.svg +1 -0
  556. package/static/vendor/fontawesome-free/svgs/brands/html5.svg +1 -0
  557. package/static/vendor/fontawesome-free/svgs/brands/hubspot.svg +1 -0
  558. package/static/vendor/fontawesome-free/svgs/brands/ideal.svg +1 -0
  559. package/static/vendor/fontawesome-free/svgs/brands/imdb.svg +1 -0
  560. package/static/vendor/fontawesome-free/svgs/brands/innosoft.svg +1 -0
  561. package/static/vendor/fontawesome-free/svgs/brands/instagram-square.svg +1 -0
  562. package/static/vendor/fontawesome-free/svgs/brands/instagram.svg +1 -0
  563. package/static/vendor/fontawesome-free/svgs/brands/instalod.svg +1 -0
  564. package/static/vendor/fontawesome-free/svgs/brands/intercom.svg +1 -0
  565. package/static/vendor/fontawesome-free/svgs/brands/internet-explorer.svg +1 -0
  566. package/static/vendor/fontawesome-free/svgs/brands/invision.svg +1 -0
  567. package/static/vendor/fontawesome-free/svgs/brands/ioxhost.svg +1 -0
  568. package/static/vendor/fontawesome-free/svgs/brands/itch-io.svg +1 -0
  569. package/static/vendor/fontawesome-free/svgs/brands/itunes-note.svg +1 -0
  570. package/static/vendor/fontawesome-free/svgs/brands/itunes.svg +1 -0
  571. package/static/vendor/fontawesome-free/svgs/brands/java.svg +1 -0
  572. package/static/vendor/fontawesome-free/svgs/brands/jedi-order.svg +1 -0
  573. package/static/vendor/fontawesome-free/svgs/brands/jenkins.svg +1 -0
  574. package/static/vendor/fontawesome-free/svgs/brands/jira.svg +1 -0
  575. package/static/vendor/fontawesome-free/svgs/brands/joget.svg +1 -0
  576. package/static/vendor/fontawesome-free/svgs/brands/joomla.svg +1 -0
  577. package/static/vendor/fontawesome-free/svgs/brands/js-square.svg +1 -0
  578. package/static/vendor/fontawesome-free/svgs/brands/js.svg +1 -0
  579. package/static/vendor/fontawesome-free/svgs/brands/jsfiddle.svg +1 -0
  580. package/static/vendor/fontawesome-free/svgs/brands/kaggle.svg +1 -0
  581. package/static/vendor/fontawesome-free/svgs/brands/keybase.svg +1 -0
  582. package/static/vendor/fontawesome-free/svgs/brands/keycdn.svg +1 -0
  583. package/static/vendor/fontawesome-free/svgs/brands/kickstarter-k.svg +1 -0
  584. package/static/vendor/fontawesome-free/svgs/brands/kickstarter.svg +1 -0
  585. package/static/vendor/fontawesome-free/svgs/brands/korvue.svg +1 -0
  586. package/static/vendor/fontawesome-free/svgs/brands/laravel.svg +1 -0
  587. package/static/vendor/fontawesome-free/svgs/brands/lastfm-square.svg +1 -0
  588. package/static/vendor/fontawesome-free/svgs/brands/lastfm.svg +1 -0
  589. package/static/vendor/fontawesome-free/svgs/brands/leanpub.svg +1 -0
  590. package/static/vendor/fontawesome-free/svgs/brands/less.svg +1 -0
  591. package/static/vendor/fontawesome-free/svgs/brands/line.svg +1 -0
  592. package/static/vendor/fontawesome-free/svgs/brands/linkedin-in.svg +1 -0
  593. package/static/vendor/fontawesome-free/svgs/brands/linkedin.svg +1 -0
  594. package/static/vendor/fontawesome-free/svgs/brands/linode.svg +1 -0
  595. package/static/vendor/fontawesome-free/svgs/brands/linux.svg +1 -0
  596. package/static/vendor/fontawesome-free/svgs/brands/lyft.svg +1 -0
  597. package/static/vendor/fontawesome-free/svgs/brands/magento.svg +1 -0
  598. package/static/vendor/fontawesome-free/svgs/brands/mailchimp.svg +1 -0
  599. package/static/vendor/fontawesome-free/svgs/brands/mandalorian.svg +1 -0
  600. package/static/vendor/fontawesome-free/svgs/brands/markdown.svg +1 -0
  601. package/static/vendor/fontawesome-free/svgs/brands/mastodon.svg +1 -0
  602. package/static/vendor/fontawesome-free/svgs/brands/maxcdn.svg +1 -0
  603. package/static/vendor/fontawesome-free/svgs/brands/mdb.svg +1 -0
  604. package/static/vendor/fontawesome-free/svgs/brands/medapps.svg +1 -0
  605. package/static/vendor/fontawesome-free/svgs/brands/medium-m.svg +1 -0
  606. package/static/vendor/fontawesome-free/svgs/brands/medium.svg +1 -0
  607. package/static/vendor/fontawesome-free/svgs/brands/medrt.svg +1 -0
  608. package/static/vendor/fontawesome-free/svgs/brands/meetup.svg +1 -0
  609. package/static/vendor/fontawesome-free/svgs/brands/megaport.svg +1 -0
  610. package/static/vendor/fontawesome-free/svgs/brands/mendeley.svg +1 -0
  611. package/static/vendor/fontawesome-free/svgs/brands/microblog.svg +1 -0
  612. package/static/vendor/fontawesome-free/svgs/brands/microsoft.svg +1 -0
  613. package/static/vendor/fontawesome-free/svgs/brands/mix.svg +1 -0
  614. package/static/vendor/fontawesome-free/svgs/brands/mixcloud.svg +1 -0
  615. package/static/vendor/fontawesome-free/svgs/brands/mixer.svg +1 -0
  616. package/static/vendor/fontawesome-free/svgs/brands/mizuni.svg +1 -0
  617. package/static/vendor/fontawesome-free/svgs/brands/modx.svg +1 -0
  618. package/static/vendor/fontawesome-free/svgs/brands/monero.svg +1 -0
  619. package/static/vendor/fontawesome-free/svgs/brands/napster.svg +1 -0
  620. package/static/vendor/fontawesome-free/svgs/brands/neos.svg +1 -0
  621. package/static/vendor/fontawesome-free/svgs/brands/nimblr.svg +1 -0
  622. package/static/vendor/fontawesome-free/svgs/brands/node-js.svg +1 -0
  623. package/static/vendor/fontawesome-free/svgs/brands/node.svg +1 -0
  624. package/static/vendor/fontawesome-free/svgs/brands/npm.svg +1 -0
  625. package/static/vendor/fontawesome-free/svgs/brands/ns8.svg +1 -0
  626. package/static/vendor/fontawesome-free/svgs/brands/nutritionix.svg +1 -0
  627. package/static/vendor/fontawesome-free/svgs/brands/octopus-deploy.svg +1 -0
  628. package/static/vendor/fontawesome-free/svgs/brands/odnoklassniki-square.svg +1 -0
  629. package/static/vendor/fontawesome-free/svgs/brands/odnoklassniki.svg +1 -0
  630. package/static/vendor/fontawesome-free/svgs/brands/old-republic.svg +1 -0
  631. package/static/vendor/fontawesome-free/svgs/brands/opencart.svg +1 -0
  632. package/static/vendor/fontawesome-free/svgs/brands/openid.svg +1 -0
  633. package/static/vendor/fontawesome-free/svgs/brands/opera.svg +1 -0
  634. package/static/vendor/fontawesome-free/svgs/brands/optin-monster.svg +1 -0
  635. package/static/vendor/fontawesome-free/svgs/brands/orcid.svg +1 -0
  636. package/static/vendor/fontawesome-free/svgs/brands/osi.svg +1 -0
  637. package/static/vendor/fontawesome-free/svgs/brands/page4.svg +1 -0
  638. package/static/vendor/fontawesome-free/svgs/brands/pagelines.svg +1 -0
  639. package/static/vendor/fontawesome-free/svgs/brands/palfed.svg +1 -0
  640. package/static/vendor/fontawesome-free/svgs/brands/patreon.svg +1 -0
  641. package/static/vendor/fontawesome-free/svgs/brands/paypal.svg +1 -0
  642. package/static/vendor/fontawesome-free/svgs/brands/penny-arcade.svg +1 -0
  643. package/static/vendor/fontawesome-free/svgs/brands/perbyte.svg +1 -0
  644. package/static/vendor/fontawesome-free/svgs/brands/periscope.svg +1 -0
  645. package/static/vendor/fontawesome-free/svgs/brands/phabricator.svg +1 -0
  646. package/static/vendor/fontawesome-free/svgs/brands/phoenix-framework.svg +1 -0
  647. package/static/vendor/fontawesome-free/svgs/brands/phoenix-squadron.svg +1 -0
  648. package/static/vendor/fontawesome-free/svgs/brands/php.svg +1 -0
  649. package/static/vendor/fontawesome-free/svgs/brands/pied-piper-alt.svg +1 -0
  650. package/static/vendor/fontawesome-free/svgs/brands/pied-piper-hat.svg +1 -0
  651. package/static/vendor/fontawesome-free/svgs/brands/pied-piper-pp.svg +1 -0
  652. package/static/vendor/fontawesome-free/svgs/brands/pied-piper-square.svg +1 -0
  653. package/static/vendor/fontawesome-free/svgs/brands/pied-piper.svg +1 -0
  654. package/static/vendor/fontawesome-free/svgs/brands/pinterest-p.svg +1 -0
  655. package/static/vendor/fontawesome-free/svgs/brands/pinterest-square.svg +1 -0
  656. package/static/vendor/fontawesome-free/svgs/brands/pinterest.svg +1 -0
  657. package/static/vendor/fontawesome-free/svgs/brands/playstation.svg +1 -0
  658. package/static/vendor/fontawesome-free/svgs/brands/product-hunt.svg +1 -0
  659. package/static/vendor/fontawesome-free/svgs/brands/pushed.svg +1 -0
  660. package/static/vendor/fontawesome-free/svgs/brands/python.svg +1 -0
  661. package/static/vendor/fontawesome-free/svgs/brands/qq.svg +1 -0
  662. package/static/vendor/fontawesome-free/svgs/brands/quinscape.svg +1 -0
  663. package/static/vendor/fontawesome-free/svgs/brands/quora.svg +1 -0
  664. package/static/vendor/fontawesome-free/svgs/brands/r-project.svg +1 -0
  665. package/static/vendor/fontawesome-free/svgs/brands/raspberry-pi.svg +1 -0
  666. package/static/vendor/fontawesome-free/svgs/brands/ravelry.svg +1 -0
  667. package/static/vendor/fontawesome-free/svgs/brands/react.svg +1 -0
  668. package/static/vendor/fontawesome-free/svgs/brands/reacteurope.svg +1 -0
  669. package/static/vendor/fontawesome-free/svgs/brands/readme.svg +1 -0
  670. package/static/vendor/fontawesome-free/svgs/brands/rebel.svg +1 -0
  671. package/static/vendor/fontawesome-free/svgs/brands/red-river.svg +1 -0
  672. package/static/vendor/fontawesome-free/svgs/brands/reddit-alien.svg +1 -0
  673. package/static/vendor/fontawesome-free/svgs/brands/reddit-square.svg +1 -0
  674. package/static/vendor/fontawesome-free/svgs/brands/reddit.svg +1 -0
  675. package/static/vendor/fontawesome-free/svgs/brands/redhat.svg +1 -0
  676. package/static/vendor/fontawesome-free/svgs/brands/renren.svg +1 -0
  677. package/static/vendor/fontawesome-free/svgs/brands/replyd.svg +1 -0
  678. package/static/vendor/fontawesome-free/svgs/brands/researchgate.svg +1 -0
  679. package/static/vendor/fontawesome-free/svgs/brands/resolving.svg +1 -0
  680. package/static/vendor/fontawesome-free/svgs/brands/rev.svg +1 -0
  681. package/static/vendor/fontawesome-free/svgs/brands/rocketchat.svg +1 -0
  682. package/static/vendor/fontawesome-free/svgs/brands/rockrms.svg +1 -0
  683. package/static/vendor/fontawesome-free/svgs/brands/rust.svg +1 -0
  684. package/static/vendor/fontawesome-free/svgs/brands/safari.svg +1 -0
  685. package/static/vendor/fontawesome-free/svgs/brands/salesforce.svg +1 -0
  686. package/static/vendor/fontawesome-free/svgs/brands/sass.svg +1 -0
  687. package/static/vendor/fontawesome-free/svgs/brands/schlix.svg +1 -0
  688. package/static/vendor/fontawesome-free/svgs/brands/scribd.svg +1 -0
  689. package/static/vendor/fontawesome-free/svgs/brands/searchengin.svg +1 -0
  690. package/static/vendor/fontawesome-free/svgs/brands/sellcast.svg +1 -0
  691. package/static/vendor/fontawesome-free/svgs/brands/sellsy.svg +1 -0
  692. package/static/vendor/fontawesome-free/svgs/brands/servicestack.svg +1 -0
  693. package/static/vendor/fontawesome-free/svgs/brands/shirtsinbulk.svg +1 -0
  694. package/static/vendor/fontawesome-free/svgs/brands/shopify.svg +1 -0
  695. package/static/vendor/fontawesome-free/svgs/brands/shopware.svg +1 -0
  696. package/static/vendor/fontawesome-free/svgs/brands/simplybuilt.svg +1 -0
  697. package/static/vendor/fontawesome-free/svgs/brands/sistrix.svg +1 -0
  698. package/static/vendor/fontawesome-free/svgs/brands/sith.svg +1 -0
  699. package/static/vendor/fontawesome-free/svgs/brands/sketch.svg +1 -0
  700. package/static/vendor/fontawesome-free/svgs/brands/skyatlas.svg +1 -0
  701. package/static/vendor/fontawesome-free/svgs/brands/skype.svg +1 -0
  702. package/static/vendor/fontawesome-free/svgs/brands/slack-hash.svg +1 -0
  703. package/static/vendor/fontawesome-free/svgs/brands/slack.svg +1 -0
  704. package/static/vendor/fontawesome-free/svgs/brands/slideshare.svg +1 -0
  705. package/static/vendor/fontawesome-free/svgs/brands/snapchat-ghost.svg +1 -0
  706. package/static/vendor/fontawesome-free/svgs/brands/snapchat-square.svg +1 -0
  707. package/static/vendor/fontawesome-free/svgs/brands/snapchat.svg +1 -0
  708. package/static/vendor/fontawesome-free/svgs/brands/soundcloud.svg +1 -0
  709. package/static/vendor/fontawesome-free/svgs/brands/sourcetree.svg +1 -0
  710. package/static/vendor/fontawesome-free/svgs/brands/speakap.svg +1 -0
  711. package/static/vendor/fontawesome-free/svgs/brands/speaker-deck.svg +1 -0
  712. package/static/vendor/fontawesome-free/svgs/brands/spotify.svg +1 -0
  713. package/static/vendor/fontawesome-free/svgs/brands/squarespace.svg +1 -0
  714. package/static/vendor/fontawesome-free/svgs/brands/stack-exchange.svg +1 -0
  715. package/static/vendor/fontawesome-free/svgs/brands/stack-overflow.svg +1 -0
  716. package/static/vendor/fontawesome-free/svgs/brands/stackpath.svg +1 -0
  717. package/static/vendor/fontawesome-free/svgs/brands/staylinked.svg +1 -0
  718. package/static/vendor/fontawesome-free/svgs/brands/steam-square.svg +1 -0
  719. package/static/vendor/fontawesome-free/svgs/brands/steam-symbol.svg +1 -0
  720. package/static/vendor/fontawesome-free/svgs/brands/steam.svg +1 -0
  721. package/static/vendor/fontawesome-free/svgs/brands/sticker-mule.svg +1 -0
  722. package/static/vendor/fontawesome-free/svgs/brands/strava.svg +1 -0
  723. package/static/vendor/fontawesome-free/svgs/brands/stripe-s.svg +1 -0
  724. package/static/vendor/fontawesome-free/svgs/brands/stripe.svg +1 -0
  725. package/static/vendor/fontawesome-free/svgs/brands/studiovinari.svg +1 -0
  726. package/static/vendor/fontawesome-free/svgs/brands/stumbleupon-circle.svg +1 -0
  727. package/static/vendor/fontawesome-free/svgs/brands/stumbleupon.svg +1 -0
  728. package/static/vendor/fontawesome-free/svgs/brands/superpowers.svg +1 -0
  729. package/static/vendor/fontawesome-free/svgs/brands/supple.svg +1 -0
  730. package/static/vendor/fontawesome-free/svgs/brands/suse.svg +1 -0
  731. package/static/vendor/fontawesome-free/svgs/brands/swift.svg +1 -0
  732. package/static/vendor/fontawesome-free/svgs/brands/symfony.svg +1 -0
  733. package/static/vendor/fontawesome-free/svgs/brands/teamspeak.svg +1 -0
  734. package/static/vendor/fontawesome-free/svgs/brands/telegram-plane.svg +1 -0
  735. package/static/vendor/fontawesome-free/svgs/brands/telegram.svg +1 -0
  736. package/static/vendor/fontawesome-free/svgs/brands/tencent-weibo.svg +1 -0
  737. package/static/vendor/fontawesome-free/svgs/brands/the-red-yeti.svg +1 -0
  738. package/static/vendor/fontawesome-free/svgs/brands/themeco.svg +1 -0
  739. package/static/vendor/fontawesome-free/svgs/brands/themeisle.svg +1 -0
  740. package/static/vendor/fontawesome-free/svgs/brands/think-peaks.svg +1 -0
  741. package/static/vendor/fontawesome-free/svgs/brands/tiktok.svg +1 -0
  742. package/static/vendor/fontawesome-free/svgs/brands/trade-federation.svg +1 -0
  743. package/static/vendor/fontawesome-free/svgs/brands/trello.svg +1 -0
  744. package/static/vendor/fontawesome-free/svgs/brands/tripadvisor.svg +1 -0
  745. package/static/vendor/fontawesome-free/svgs/brands/tumblr-square.svg +1 -0
  746. package/static/vendor/fontawesome-free/svgs/brands/tumblr.svg +1 -0
  747. package/static/vendor/fontawesome-free/svgs/brands/twitch.svg +1 -0
  748. package/static/vendor/fontawesome-free/svgs/brands/twitter-square.svg +1 -0
  749. package/static/vendor/fontawesome-free/svgs/brands/twitter.svg +1 -0
  750. package/static/vendor/fontawesome-free/svgs/brands/typo3.svg +1 -0
  751. package/static/vendor/fontawesome-free/svgs/brands/uber.svg +1 -0
  752. package/static/vendor/fontawesome-free/svgs/brands/ubuntu.svg +1 -0
  753. package/static/vendor/fontawesome-free/svgs/brands/uikit.svg +1 -0
  754. package/static/vendor/fontawesome-free/svgs/brands/umbraco.svg +1 -0
  755. package/static/vendor/fontawesome-free/svgs/brands/uncharted.svg +1 -0
  756. package/static/vendor/fontawesome-free/svgs/brands/uniregistry.svg +1 -0
  757. package/static/vendor/fontawesome-free/svgs/brands/unity.svg +1 -0
  758. package/static/vendor/fontawesome-free/svgs/brands/unsplash.svg +1 -0
  759. package/static/vendor/fontawesome-free/svgs/brands/untappd.svg +1 -0
  760. package/static/vendor/fontawesome-free/svgs/brands/ups.svg +1 -0
  761. package/static/vendor/fontawesome-free/svgs/brands/usb.svg +1 -0
  762. package/static/vendor/fontawesome-free/svgs/brands/usps.svg +1 -0
  763. package/static/vendor/fontawesome-free/svgs/brands/ussunnah.svg +1 -0
  764. package/static/vendor/fontawesome-free/svgs/brands/vaadin.svg +1 -0
  765. package/static/vendor/fontawesome-free/svgs/brands/viacoin.svg +1 -0
  766. package/static/vendor/fontawesome-free/svgs/brands/viadeo-square.svg +1 -0
  767. package/static/vendor/fontawesome-free/svgs/brands/viadeo.svg +1 -0
  768. package/static/vendor/fontawesome-free/svgs/brands/viber.svg +1 -0
  769. package/static/vendor/fontawesome-free/svgs/brands/vimeo-square.svg +1 -0
  770. package/static/vendor/fontawesome-free/svgs/brands/vimeo-v.svg +1 -0
  771. package/static/vendor/fontawesome-free/svgs/brands/vimeo.svg +1 -0
  772. package/static/vendor/fontawesome-free/svgs/brands/vine.svg +1 -0
  773. package/static/vendor/fontawesome-free/svgs/brands/vk.svg +1 -0
  774. package/static/vendor/fontawesome-free/svgs/brands/vnv.svg +1 -0
  775. package/static/vendor/fontawesome-free/svgs/brands/vuejs.svg +1 -0
  776. package/static/vendor/fontawesome-free/svgs/brands/watchman-monitoring.svg +1 -0
  777. package/static/vendor/fontawesome-free/svgs/brands/waze.svg +1 -0
  778. package/static/vendor/fontawesome-free/svgs/brands/weebly.svg +1 -0
  779. package/static/vendor/fontawesome-free/svgs/brands/weibo.svg +1 -0
  780. package/static/vendor/fontawesome-free/svgs/brands/weixin.svg +1 -0
  781. package/static/vendor/fontawesome-free/svgs/brands/whatsapp-square.svg +1 -0
  782. package/static/vendor/fontawesome-free/svgs/brands/whatsapp.svg +1 -0
  783. package/static/vendor/fontawesome-free/svgs/brands/whmcs.svg +1 -0
  784. package/static/vendor/fontawesome-free/svgs/brands/wikipedia-w.svg +1 -0
  785. package/static/vendor/fontawesome-free/svgs/brands/windows.svg +1 -0
  786. package/static/vendor/fontawesome-free/svgs/brands/wix.svg +1 -0
  787. package/static/vendor/fontawesome-free/svgs/brands/wizards-of-the-coast.svg +1 -0
  788. package/static/vendor/fontawesome-free/svgs/brands/wodu.svg +1 -0
  789. package/static/vendor/fontawesome-free/svgs/brands/wolf-pack-battalion.svg +1 -0
  790. package/static/vendor/fontawesome-free/svgs/brands/wordpress-simple.svg +1 -0
  791. package/static/vendor/fontawesome-free/svgs/brands/wordpress.svg +1 -0
  792. package/static/vendor/fontawesome-free/svgs/brands/wpbeginner.svg +1 -0
  793. package/static/vendor/fontawesome-free/svgs/brands/wpexplorer.svg +1 -0
  794. package/static/vendor/fontawesome-free/svgs/brands/wpforms.svg +1 -0
  795. package/static/vendor/fontawesome-free/svgs/brands/wpressr.svg +1 -0
  796. package/static/vendor/fontawesome-free/svgs/brands/xbox.svg +1 -0
  797. package/static/vendor/fontawesome-free/svgs/brands/xing-square.svg +1 -0
  798. package/static/vendor/fontawesome-free/svgs/brands/xing.svg +1 -0
  799. package/static/vendor/fontawesome-free/svgs/brands/y-combinator.svg +1 -0
  800. package/static/vendor/fontawesome-free/svgs/brands/yahoo.svg +1 -0
  801. package/static/vendor/fontawesome-free/svgs/brands/yammer.svg +1 -0
  802. package/static/vendor/fontawesome-free/svgs/brands/yandex-international.svg +1 -0
  803. package/static/vendor/fontawesome-free/svgs/brands/yandex.svg +1 -0
  804. package/static/vendor/fontawesome-free/svgs/brands/yarn.svg +1 -0
  805. package/static/vendor/fontawesome-free/svgs/brands/yelp.svg +1 -0
  806. package/static/vendor/fontawesome-free/svgs/brands/yoast.svg +1 -0
  807. package/static/vendor/fontawesome-free/svgs/brands/youtube-square.svg +1 -0
  808. package/static/vendor/fontawesome-free/svgs/brands/youtube.svg +1 -0
  809. package/static/vendor/fontawesome-free/svgs/brands/zhihu.svg +1 -0
  810. package/static/vendor/fontawesome-free/svgs/regular/address-book.svg +1 -0
  811. package/static/vendor/fontawesome-free/svgs/regular/address-card.svg +1 -0
  812. package/static/vendor/fontawesome-free/svgs/regular/angry.svg +1 -0
  813. package/static/vendor/fontawesome-free/svgs/regular/arrow-alt-circle-down.svg +1 -0
  814. package/static/vendor/fontawesome-free/svgs/regular/arrow-alt-circle-left.svg +1 -0
  815. package/static/vendor/fontawesome-free/svgs/regular/arrow-alt-circle-right.svg +1 -0
  816. package/static/vendor/fontawesome-free/svgs/regular/arrow-alt-circle-up.svg +1 -0
  817. package/static/vendor/fontawesome-free/svgs/regular/bell-slash.svg +1 -0
  818. package/static/vendor/fontawesome-free/svgs/regular/bell.svg +1 -0
  819. package/static/vendor/fontawesome-free/svgs/regular/bookmark.svg +1 -0
  820. package/static/vendor/fontawesome-free/svgs/regular/building.svg +1 -0
  821. package/static/vendor/fontawesome-free/svgs/regular/calendar-alt.svg +1 -0
  822. package/static/vendor/fontawesome-free/svgs/regular/calendar-check.svg +1 -0
  823. package/static/vendor/fontawesome-free/svgs/regular/calendar-minus.svg +1 -0
  824. package/static/vendor/fontawesome-free/svgs/regular/calendar-plus.svg +1 -0
  825. package/static/vendor/fontawesome-free/svgs/regular/calendar-times.svg +1 -0
  826. package/static/vendor/fontawesome-free/svgs/regular/calendar.svg +1 -0
  827. package/static/vendor/fontawesome-free/svgs/regular/caret-square-down.svg +1 -0
  828. package/static/vendor/fontawesome-free/svgs/regular/caret-square-left.svg +1 -0
  829. package/static/vendor/fontawesome-free/svgs/regular/caret-square-right.svg +1 -0
  830. package/static/vendor/fontawesome-free/svgs/regular/caret-square-up.svg +1 -0
  831. package/static/vendor/fontawesome-free/svgs/regular/chart-bar.svg +1 -0
  832. package/static/vendor/fontawesome-free/svgs/regular/check-circle.svg +1 -0
  833. package/static/vendor/fontawesome-free/svgs/regular/check-square.svg +1 -0
  834. package/static/vendor/fontawesome-free/svgs/regular/circle.svg +1 -0
  835. package/static/vendor/fontawesome-free/svgs/regular/clipboard.svg +1 -0
  836. package/static/vendor/fontawesome-free/svgs/regular/clock.svg +1 -0
  837. package/static/vendor/fontawesome-free/svgs/regular/clone.svg +1 -0
  838. package/static/vendor/fontawesome-free/svgs/regular/closed-captioning.svg +1 -0
  839. package/static/vendor/fontawesome-free/svgs/regular/comment-alt.svg +1 -0
  840. package/static/vendor/fontawesome-free/svgs/regular/comment-dots.svg +1 -0
  841. package/static/vendor/fontawesome-free/svgs/regular/comment.svg +1 -0
  842. package/static/vendor/fontawesome-free/svgs/regular/comments.svg +1 -0
  843. package/static/vendor/fontawesome-free/svgs/regular/compass.svg +1 -0
  844. package/static/vendor/fontawesome-free/svgs/regular/copy.svg +1 -0
  845. package/static/vendor/fontawesome-free/svgs/regular/copyright.svg +1 -0
  846. package/static/vendor/fontawesome-free/svgs/regular/credit-card.svg +1 -0
  847. package/static/vendor/fontawesome-free/svgs/regular/dizzy.svg +1 -0
  848. package/static/vendor/fontawesome-free/svgs/regular/dot-circle.svg +1 -0
  849. package/static/vendor/fontawesome-free/svgs/regular/edit.svg +1 -0
  850. package/static/vendor/fontawesome-free/svgs/regular/envelope-open.svg +1 -0
  851. package/static/vendor/fontawesome-free/svgs/regular/envelope.svg +1 -0
  852. package/static/vendor/fontawesome-free/svgs/regular/eye-slash.svg +1 -0
  853. package/static/vendor/fontawesome-free/svgs/regular/eye.svg +1 -0
  854. package/static/vendor/fontawesome-free/svgs/regular/file-alt.svg +1 -0
  855. package/static/vendor/fontawesome-free/svgs/regular/file-archive.svg +1 -0
  856. package/static/vendor/fontawesome-free/svgs/regular/file-audio.svg +1 -0
  857. package/static/vendor/fontawesome-free/svgs/regular/file-code.svg +1 -0
  858. package/static/vendor/fontawesome-free/svgs/regular/file-excel.svg +1 -0
  859. package/static/vendor/fontawesome-free/svgs/regular/file-image.svg +1 -0
  860. package/static/vendor/fontawesome-free/svgs/regular/file-pdf.svg +1 -0
  861. package/static/vendor/fontawesome-free/svgs/regular/file-powerpoint.svg +1 -0
  862. package/static/vendor/fontawesome-free/svgs/regular/file-video.svg +1 -0
  863. package/static/vendor/fontawesome-free/svgs/regular/file-word.svg +1 -0
  864. package/static/vendor/fontawesome-free/svgs/regular/file.svg +1 -0
  865. package/static/vendor/fontawesome-free/svgs/regular/flag.svg +1 -0
  866. package/static/vendor/fontawesome-free/svgs/regular/flushed.svg +1 -0
  867. package/static/vendor/fontawesome-free/svgs/regular/folder-open.svg +1 -0
  868. package/static/vendor/fontawesome-free/svgs/regular/folder.svg +1 -0
  869. package/static/vendor/fontawesome-free/svgs/regular/font-awesome-logo-full.svg +1 -0
  870. package/static/vendor/fontawesome-free/svgs/regular/frown-open.svg +1 -0
  871. package/static/vendor/fontawesome-free/svgs/regular/frown.svg +1 -0
  872. package/static/vendor/fontawesome-free/svgs/regular/futbol.svg +1 -0
  873. package/static/vendor/fontawesome-free/svgs/regular/gem.svg +1 -0
  874. package/static/vendor/fontawesome-free/svgs/regular/grimace.svg +1 -0
  875. package/static/vendor/fontawesome-free/svgs/regular/grin-alt.svg +1 -0
  876. package/static/vendor/fontawesome-free/svgs/regular/grin-beam-sweat.svg +1 -0
  877. package/static/vendor/fontawesome-free/svgs/regular/grin-beam.svg +1 -0
  878. package/static/vendor/fontawesome-free/svgs/regular/grin-hearts.svg +1 -0
  879. package/static/vendor/fontawesome-free/svgs/regular/grin-squint-tears.svg +1 -0
  880. package/static/vendor/fontawesome-free/svgs/regular/grin-squint.svg +1 -0
  881. package/static/vendor/fontawesome-free/svgs/regular/grin-stars.svg +1 -0
  882. package/static/vendor/fontawesome-free/svgs/regular/grin-tears.svg +1 -0
  883. package/static/vendor/fontawesome-free/svgs/regular/grin-tongue-squint.svg +1 -0
  884. package/static/vendor/fontawesome-free/svgs/regular/grin-tongue-wink.svg +1 -0
  885. package/static/vendor/fontawesome-free/svgs/regular/grin-tongue.svg +1 -0
  886. package/static/vendor/fontawesome-free/svgs/regular/grin-wink.svg +1 -0
  887. package/static/vendor/fontawesome-free/svgs/regular/grin.svg +1 -0
  888. package/static/vendor/fontawesome-free/svgs/regular/hand-lizard.svg +1 -0
  889. package/static/vendor/fontawesome-free/svgs/regular/hand-paper.svg +1 -0
  890. package/static/vendor/fontawesome-free/svgs/regular/hand-peace.svg +1 -0
  891. package/static/vendor/fontawesome-free/svgs/regular/hand-point-down.svg +1 -0
  892. package/static/vendor/fontawesome-free/svgs/regular/hand-point-left.svg +1 -0
  893. package/static/vendor/fontawesome-free/svgs/regular/hand-point-right.svg +1 -0
  894. package/static/vendor/fontawesome-free/svgs/regular/hand-point-up.svg +1 -0
  895. package/static/vendor/fontawesome-free/svgs/regular/hand-pointer.svg +1 -0
  896. package/static/vendor/fontawesome-free/svgs/regular/hand-rock.svg +1 -0
  897. package/static/vendor/fontawesome-free/svgs/regular/hand-scissors.svg +1 -0
  898. package/static/vendor/fontawesome-free/svgs/regular/hand-spock.svg +1 -0
  899. package/static/vendor/fontawesome-free/svgs/regular/handshake.svg +1 -0
  900. package/static/vendor/fontawesome-free/svgs/regular/hdd.svg +1 -0
  901. package/static/vendor/fontawesome-free/svgs/regular/heart.svg +1 -0
  902. package/static/vendor/fontawesome-free/svgs/regular/hospital.svg +1 -0
  903. package/static/vendor/fontawesome-free/svgs/regular/hourglass.svg +1 -0
  904. package/static/vendor/fontawesome-free/svgs/regular/id-badge.svg +1 -0
  905. package/static/vendor/fontawesome-free/svgs/regular/id-card.svg +1 -0
  906. package/static/vendor/fontawesome-free/svgs/regular/image.svg +1 -0
  907. package/static/vendor/fontawesome-free/svgs/regular/images.svg +1 -0
  908. package/static/vendor/fontawesome-free/svgs/regular/keyboard.svg +1 -0
  909. package/static/vendor/fontawesome-free/svgs/regular/kiss-beam.svg +1 -0
  910. package/static/vendor/fontawesome-free/svgs/regular/kiss-wink-heart.svg +1 -0
  911. package/static/vendor/fontawesome-free/svgs/regular/kiss.svg +1 -0
  912. package/static/vendor/fontawesome-free/svgs/regular/laugh-beam.svg +1 -0
  913. package/static/vendor/fontawesome-free/svgs/regular/laugh-squint.svg +1 -0
  914. package/static/vendor/fontawesome-free/svgs/regular/laugh-wink.svg +1 -0
  915. package/static/vendor/fontawesome-free/svgs/regular/laugh.svg +1 -0
  916. package/static/vendor/fontawesome-free/svgs/regular/lemon.svg +1 -0
  917. package/static/vendor/fontawesome-free/svgs/regular/life-ring.svg +1 -0
  918. package/static/vendor/fontawesome-free/svgs/regular/lightbulb.svg +1 -0
  919. package/static/vendor/fontawesome-free/svgs/regular/list-alt.svg +1 -0
  920. package/static/vendor/fontawesome-free/svgs/regular/map.svg +1 -0
  921. package/static/vendor/fontawesome-free/svgs/regular/meh-blank.svg +1 -0
  922. package/static/vendor/fontawesome-free/svgs/regular/meh-rolling-eyes.svg +1 -0
  923. package/static/vendor/fontawesome-free/svgs/regular/meh.svg +1 -0
  924. package/static/vendor/fontawesome-free/svgs/regular/minus-square.svg +1 -0
  925. package/static/vendor/fontawesome-free/svgs/regular/money-bill-alt.svg +1 -0
  926. package/static/vendor/fontawesome-free/svgs/regular/moon.svg +1 -0
  927. package/static/vendor/fontawesome-free/svgs/regular/newspaper.svg +1 -0
  928. package/static/vendor/fontawesome-free/svgs/regular/object-group.svg +1 -0
  929. package/static/vendor/fontawesome-free/svgs/regular/object-ungroup.svg +1 -0
  930. package/static/vendor/fontawesome-free/svgs/regular/paper-plane.svg +1 -0
  931. package/static/vendor/fontawesome-free/svgs/regular/pause-circle.svg +1 -0
  932. package/static/vendor/fontawesome-free/svgs/regular/play-circle.svg +1 -0
  933. package/static/vendor/fontawesome-free/svgs/regular/plus-square.svg +1 -0
  934. package/static/vendor/fontawesome-free/svgs/regular/question-circle.svg +1 -0
  935. package/static/vendor/fontawesome-free/svgs/regular/registered.svg +1 -0
  936. package/static/vendor/fontawesome-free/svgs/regular/sad-cry.svg +1 -0
  937. package/static/vendor/fontawesome-free/svgs/regular/sad-tear.svg +1 -0
  938. package/static/vendor/fontawesome-free/svgs/regular/save.svg +1 -0
  939. package/static/vendor/fontawesome-free/svgs/regular/share-square.svg +1 -0
  940. package/static/vendor/fontawesome-free/svgs/regular/smile-beam.svg +1 -0
  941. package/static/vendor/fontawesome-free/svgs/regular/smile-wink.svg +1 -0
  942. package/static/vendor/fontawesome-free/svgs/regular/smile.svg +1 -0
  943. package/static/vendor/fontawesome-free/svgs/regular/snowflake.svg +1 -0
  944. package/static/vendor/fontawesome-free/svgs/regular/square.svg +1 -0
  945. package/static/vendor/fontawesome-free/svgs/regular/star-half.svg +1 -0
  946. package/static/vendor/fontawesome-free/svgs/regular/star.svg +1 -0
  947. package/static/vendor/fontawesome-free/svgs/regular/sticky-note.svg +1 -0
  948. package/static/vendor/fontawesome-free/svgs/regular/stop-circle.svg +1 -0
  949. package/static/vendor/fontawesome-free/svgs/regular/sun.svg +1 -0
  950. package/static/vendor/fontawesome-free/svgs/regular/surprise.svg +1 -0
  951. package/static/vendor/fontawesome-free/svgs/regular/thumbs-down.svg +1 -0
  952. package/static/vendor/fontawesome-free/svgs/regular/thumbs-up.svg +1 -0
  953. package/static/vendor/fontawesome-free/svgs/regular/times-circle.svg +1 -0
  954. package/static/vendor/fontawesome-free/svgs/regular/tired.svg +1 -0
  955. package/static/vendor/fontawesome-free/svgs/regular/trash-alt.svg +1 -0
  956. package/static/vendor/fontawesome-free/svgs/regular/user-circle.svg +1 -0
  957. package/static/vendor/fontawesome-free/svgs/regular/user.svg +1 -0
  958. package/static/vendor/fontawesome-free/svgs/regular/window-close.svg +1 -0
  959. package/static/vendor/fontawesome-free/svgs/regular/window-maximize.svg +1 -0
  960. package/static/vendor/fontawesome-free/svgs/regular/window-minimize.svg +1 -0
  961. package/static/vendor/fontawesome-free/svgs/regular/window-restore.svg +1 -0
  962. package/static/vendor/fontawesome-free/svgs/solid/ad.svg +1 -0
  963. package/static/vendor/fontawesome-free/svgs/solid/address-book.svg +1 -0
  964. package/static/vendor/fontawesome-free/svgs/solid/address-card.svg +1 -0
  965. package/static/vendor/fontawesome-free/svgs/solid/adjust.svg +1 -0
  966. package/static/vendor/fontawesome-free/svgs/solid/air-freshener.svg +1 -0
  967. package/static/vendor/fontawesome-free/svgs/solid/align-center.svg +1 -0
  968. package/static/vendor/fontawesome-free/svgs/solid/align-justify.svg +1 -0
  969. package/static/vendor/fontawesome-free/svgs/solid/align-left.svg +1 -0
  970. package/static/vendor/fontawesome-free/svgs/solid/align-right.svg +1 -0
  971. package/static/vendor/fontawesome-free/svgs/solid/allergies.svg +1 -0
  972. package/static/vendor/fontawesome-free/svgs/solid/ambulance.svg +1 -0
  973. package/static/vendor/fontawesome-free/svgs/solid/american-sign-language-interpreting.svg +1 -0
  974. package/static/vendor/fontawesome-free/svgs/solid/anchor.svg +1 -0
  975. package/static/vendor/fontawesome-free/svgs/solid/angle-double-down.svg +1 -0
  976. package/static/vendor/fontawesome-free/svgs/solid/angle-double-left.svg +1 -0
  977. package/static/vendor/fontawesome-free/svgs/solid/angle-double-right.svg +1 -0
  978. package/static/vendor/fontawesome-free/svgs/solid/angle-double-up.svg +1 -0
  979. package/static/vendor/fontawesome-free/svgs/solid/angle-down.svg +1 -0
  980. package/static/vendor/fontawesome-free/svgs/solid/angle-left.svg +1 -0
  981. package/static/vendor/fontawesome-free/svgs/solid/angle-right.svg +1 -0
  982. package/static/vendor/fontawesome-free/svgs/solid/angle-up.svg +1 -0
  983. package/static/vendor/fontawesome-free/svgs/solid/angry.svg +1 -0
  984. package/static/vendor/fontawesome-free/svgs/solid/ankh.svg +1 -0
  985. package/static/vendor/fontawesome-free/svgs/solid/apple-alt.svg +1 -0
  986. package/static/vendor/fontawesome-free/svgs/solid/archive.svg +1 -0
  987. package/static/vendor/fontawesome-free/svgs/solid/archway.svg +1 -0
  988. package/static/vendor/fontawesome-free/svgs/solid/arrow-alt-circle-down.svg +1 -0
  989. package/static/vendor/fontawesome-free/svgs/solid/arrow-alt-circle-left.svg +1 -0
  990. package/static/vendor/fontawesome-free/svgs/solid/arrow-alt-circle-right.svg +1 -0
  991. package/static/vendor/fontawesome-free/svgs/solid/arrow-alt-circle-up.svg +1 -0
  992. package/static/vendor/fontawesome-free/svgs/solid/arrow-circle-down.svg +1 -0
  993. package/static/vendor/fontawesome-free/svgs/solid/arrow-circle-left.svg +1 -0
  994. package/static/vendor/fontawesome-free/svgs/solid/arrow-circle-right.svg +1 -0
  995. package/static/vendor/fontawesome-free/svgs/solid/arrow-circle-up.svg +1 -0
  996. package/static/vendor/fontawesome-free/svgs/solid/arrow-down.svg +1 -0
  997. package/static/vendor/fontawesome-free/svgs/solid/arrow-left.svg +1 -0
  998. package/static/vendor/fontawesome-free/svgs/solid/arrow-right.svg +1 -0
  999. package/static/vendor/fontawesome-free/svgs/solid/arrow-up.svg +1 -0
  1000. package/static/vendor/fontawesome-free/svgs/solid/arrows-alt-h.svg +1 -0
  1001. package/static/vendor/fontawesome-free/svgs/solid/arrows-alt-v.svg +1 -0
  1002. package/static/vendor/fontawesome-free/svgs/solid/arrows-alt.svg +1 -0
  1003. package/static/vendor/fontawesome-free/svgs/solid/assistive-listening-systems.svg +1 -0
  1004. package/static/vendor/fontawesome-free/svgs/solid/asterisk.svg +1 -0
  1005. package/static/vendor/fontawesome-free/svgs/solid/at.svg +1 -0
  1006. package/static/vendor/fontawesome-free/svgs/solid/atlas.svg +1 -0
  1007. package/static/vendor/fontawesome-free/svgs/solid/atom.svg +1 -0
  1008. package/static/vendor/fontawesome-free/svgs/solid/audio-description.svg +1 -0
  1009. package/static/vendor/fontawesome-free/svgs/solid/award.svg +1 -0
  1010. package/static/vendor/fontawesome-free/svgs/solid/baby-carriage.svg +1 -0
  1011. package/static/vendor/fontawesome-free/svgs/solid/baby.svg +1 -0
  1012. package/static/vendor/fontawesome-free/svgs/solid/backspace.svg +1 -0
  1013. package/static/vendor/fontawesome-free/svgs/solid/backward.svg +1 -0
  1014. package/static/vendor/fontawesome-free/svgs/solid/bacon.svg +1 -0
  1015. package/static/vendor/fontawesome-free/svgs/solid/bacteria.svg +1 -0
  1016. package/static/vendor/fontawesome-free/svgs/solid/bacterium.svg +1 -0
  1017. package/static/vendor/fontawesome-free/svgs/solid/bahai.svg +1 -0
  1018. package/static/vendor/fontawesome-free/svgs/solid/balance-scale-left.svg +1 -0
  1019. package/static/vendor/fontawesome-free/svgs/solid/balance-scale-right.svg +1 -0
  1020. package/static/vendor/fontawesome-free/svgs/solid/balance-scale.svg +1 -0
  1021. package/static/vendor/fontawesome-free/svgs/solid/ban.svg +1 -0
  1022. package/static/vendor/fontawesome-free/svgs/solid/band-aid.svg +1 -0
  1023. package/static/vendor/fontawesome-free/svgs/solid/barcode.svg +1 -0
  1024. package/static/vendor/fontawesome-free/svgs/solid/bars.svg +1 -0
  1025. package/static/vendor/fontawesome-free/svgs/solid/baseball-ball.svg +1 -0
  1026. package/static/vendor/fontawesome-free/svgs/solid/basketball-ball.svg +1 -0
  1027. package/static/vendor/fontawesome-free/svgs/solid/bath.svg +1 -0
  1028. package/static/vendor/fontawesome-free/svgs/solid/battery-empty.svg +1 -0
  1029. package/static/vendor/fontawesome-free/svgs/solid/battery-full.svg +1 -0
  1030. package/static/vendor/fontawesome-free/svgs/solid/battery-half.svg +1 -0
  1031. package/static/vendor/fontawesome-free/svgs/solid/battery-quarter.svg +1 -0
  1032. package/static/vendor/fontawesome-free/svgs/solid/battery-three-quarters.svg +1 -0
  1033. package/static/vendor/fontawesome-free/svgs/solid/bed.svg +1 -0
  1034. package/static/vendor/fontawesome-free/svgs/solid/beer.svg +1 -0
  1035. package/static/vendor/fontawesome-free/svgs/solid/bell-slash.svg +1 -0
  1036. package/static/vendor/fontawesome-free/svgs/solid/bell.svg +1 -0
  1037. package/static/vendor/fontawesome-free/svgs/solid/bezier-curve.svg +1 -0
  1038. package/static/vendor/fontawesome-free/svgs/solid/bible.svg +1 -0
  1039. package/static/vendor/fontawesome-free/svgs/solid/bicycle.svg +1 -0
  1040. package/static/vendor/fontawesome-free/svgs/solid/biking.svg +1 -0
  1041. package/static/vendor/fontawesome-free/svgs/solid/binoculars.svg +1 -0
  1042. package/static/vendor/fontawesome-free/svgs/solid/biohazard.svg +1 -0
  1043. package/static/vendor/fontawesome-free/svgs/solid/birthday-cake.svg +1 -0
  1044. package/static/vendor/fontawesome-free/svgs/solid/blender-phone.svg +1 -0
  1045. package/static/vendor/fontawesome-free/svgs/solid/blender.svg +1 -0
  1046. package/static/vendor/fontawesome-free/svgs/solid/blind.svg +1 -0
  1047. package/static/vendor/fontawesome-free/svgs/solid/blog.svg +1 -0
  1048. package/static/vendor/fontawesome-free/svgs/solid/bold.svg +1 -0
  1049. package/static/vendor/fontawesome-free/svgs/solid/bolt.svg +1 -0
  1050. package/static/vendor/fontawesome-free/svgs/solid/bomb.svg +1 -0
  1051. package/static/vendor/fontawesome-free/svgs/solid/bone.svg +1 -0
  1052. package/static/vendor/fontawesome-free/svgs/solid/bong.svg +1 -0
  1053. package/static/vendor/fontawesome-free/svgs/solid/book-dead.svg +1 -0
  1054. package/static/vendor/fontawesome-free/svgs/solid/book-medical.svg +1 -0
  1055. package/static/vendor/fontawesome-free/svgs/solid/book-open.svg +1 -0
  1056. package/static/vendor/fontawesome-free/svgs/solid/book-reader.svg +1 -0
  1057. package/static/vendor/fontawesome-free/svgs/solid/book.svg +1 -0
  1058. package/static/vendor/fontawesome-free/svgs/solid/bookmark.svg +1 -0
  1059. package/static/vendor/fontawesome-free/svgs/solid/border-all.svg +1 -0
  1060. package/static/vendor/fontawesome-free/svgs/solid/border-none.svg +1 -0
  1061. package/static/vendor/fontawesome-free/svgs/solid/border-style.svg +1 -0
  1062. package/static/vendor/fontawesome-free/svgs/solid/bowling-ball.svg +1 -0
  1063. package/static/vendor/fontawesome-free/svgs/solid/box-open.svg +1 -0
  1064. package/static/vendor/fontawesome-free/svgs/solid/box-tissue.svg +1 -0
  1065. package/static/vendor/fontawesome-free/svgs/solid/box.svg +1 -0
  1066. package/static/vendor/fontawesome-free/svgs/solid/boxes.svg +1 -0
  1067. package/static/vendor/fontawesome-free/svgs/solid/braille.svg +1 -0
  1068. package/static/vendor/fontawesome-free/svgs/solid/brain.svg +1 -0
  1069. package/static/vendor/fontawesome-free/svgs/solid/bread-slice.svg +1 -0
  1070. package/static/vendor/fontawesome-free/svgs/solid/briefcase-medical.svg +1 -0
  1071. package/static/vendor/fontawesome-free/svgs/solid/briefcase.svg +1 -0
  1072. package/static/vendor/fontawesome-free/svgs/solid/broadcast-tower.svg +1 -0
  1073. package/static/vendor/fontawesome-free/svgs/solid/broom.svg +1 -0
  1074. package/static/vendor/fontawesome-free/svgs/solid/brush.svg +1 -0
  1075. package/static/vendor/fontawesome-free/svgs/solid/bug.svg +1 -0
  1076. package/static/vendor/fontawesome-free/svgs/solid/building.svg +1 -0
  1077. package/static/vendor/fontawesome-free/svgs/solid/bullhorn.svg +1 -0
  1078. package/static/vendor/fontawesome-free/svgs/solid/bullseye.svg +1 -0
  1079. package/static/vendor/fontawesome-free/svgs/solid/burn.svg +1 -0
  1080. package/static/vendor/fontawesome-free/svgs/solid/bus-alt.svg +1 -0
  1081. package/static/vendor/fontawesome-free/svgs/solid/bus.svg +1 -0
  1082. package/static/vendor/fontawesome-free/svgs/solid/business-time.svg +1 -0
  1083. package/static/vendor/fontawesome-free/svgs/solid/calculator.svg +1 -0
  1084. package/static/vendor/fontawesome-free/svgs/solid/calendar-alt.svg +1 -0
  1085. package/static/vendor/fontawesome-free/svgs/solid/calendar-check.svg +1 -0
  1086. package/static/vendor/fontawesome-free/svgs/solid/calendar-day.svg +1 -0
  1087. package/static/vendor/fontawesome-free/svgs/solid/calendar-minus.svg +1 -0
  1088. package/static/vendor/fontawesome-free/svgs/solid/calendar-plus.svg +1 -0
  1089. package/static/vendor/fontawesome-free/svgs/solid/calendar-times.svg +1 -0
  1090. package/static/vendor/fontawesome-free/svgs/solid/calendar-week.svg +1 -0
  1091. package/static/vendor/fontawesome-free/svgs/solid/calendar.svg +1 -0
  1092. package/static/vendor/fontawesome-free/svgs/solid/camera-retro.svg +1 -0
  1093. package/static/vendor/fontawesome-free/svgs/solid/camera.svg +1 -0
  1094. package/static/vendor/fontawesome-free/svgs/solid/campground.svg +1 -0
  1095. package/static/vendor/fontawesome-free/svgs/solid/candy-cane.svg +1 -0
  1096. package/static/vendor/fontawesome-free/svgs/solid/cannabis.svg +1 -0
  1097. package/static/vendor/fontawesome-free/svgs/solid/capsules.svg +1 -0
  1098. package/static/vendor/fontawesome-free/svgs/solid/car-alt.svg +1 -0
  1099. package/static/vendor/fontawesome-free/svgs/solid/car-battery.svg +1 -0
  1100. package/static/vendor/fontawesome-free/svgs/solid/car-crash.svg +1 -0
  1101. package/static/vendor/fontawesome-free/svgs/solid/car-side.svg +1 -0
  1102. package/static/vendor/fontawesome-free/svgs/solid/car.svg +1 -0
  1103. package/static/vendor/fontawesome-free/svgs/solid/caravan.svg +1 -0
  1104. package/static/vendor/fontawesome-free/svgs/solid/caret-down.svg +1 -0
  1105. package/static/vendor/fontawesome-free/svgs/solid/caret-left.svg +1 -0
  1106. package/static/vendor/fontawesome-free/svgs/solid/caret-right.svg +1 -0
  1107. package/static/vendor/fontawesome-free/svgs/solid/caret-square-down.svg +1 -0
  1108. package/static/vendor/fontawesome-free/svgs/solid/caret-square-left.svg +1 -0
  1109. package/static/vendor/fontawesome-free/svgs/solid/caret-square-right.svg +1 -0
  1110. package/static/vendor/fontawesome-free/svgs/solid/caret-square-up.svg +1 -0
  1111. package/static/vendor/fontawesome-free/svgs/solid/caret-up.svg +1 -0
  1112. package/static/vendor/fontawesome-free/svgs/solid/carrot.svg +1 -0
  1113. package/static/vendor/fontawesome-free/svgs/solid/cart-arrow-down.svg +1 -0
  1114. package/static/vendor/fontawesome-free/svgs/solid/cart-plus.svg +1 -0
  1115. package/static/vendor/fontawesome-free/svgs/solid/cash-register.svg +1 -0
  1116. package/static/vendor/fontawesome-free/svgs/solid/cat.svg +1 -0
  1117. package/static/vendor/fontawesome-free/svgs/solid/certificate.svg +1 -0
  1118. package/static/vendor/fontawesome-free/svgs/solid/chair.svg +1 -0
  1119. package/static/vendor/fontawesome-free/svgs/solid/chalkboard-teacher.svg +1 -0
  1120. package/static/vendor/fontawesome-free/svgs/solid/chalkboard.svg +1 -0
  1121. package/static/vendor/fontawesome-free/svgs/solid/charging-station.svg +1 -0
  1122. package/static/vendor/fontawesome-free/svgs/solid/chart-area.svg +1 -0
  1123. package/static/vendor/fontawesome-free/svgs/solid/chart-bar.svg +1 -0
  1124. package/static/vendor/fontawesome-free/svgs/solid/chart-line.svg +1 -0
  1125. package/static/vendor/fontawesome-free/svgs/solid/chart-pie.svg +1 -0
  1126. package/static/vendor/fontawesome-free/svgs/solid/check-circle.svg +1 -0
  1127. package/static/vendor/fontawesome-free/svgs/solid/check-double.svg +1 -0
  1128. package/static/vendor/fontawesome-free/svgs/solid/check-square.svg +1 -0
  1129. package/static/vendor/fontawesome-free/svgs/solid/check.svg +1 -0
  1130. package/static/vendor/fontawesome-free/svgs/solid/cheese.svg +1 -0
  1131. package/static/vendor/fontawesome-free/svgs/solid/chess-bishop.svg +1 -0
  1132. package/static/vendor/fontawesome-free/svgs/solid/chess-board.svg +1 -0
  1133. package/static/vendor/fontawesome-free/svgs/solid/chess-king.svg +1 -0
  1134. package/static/vendor/fontawesome-free/svgs/solid/chess-knight.svg +1 -0
  1135. package/static/vendor/fontawesome-free/svgs/solid/chess-pawn.svg +1 -0
  1136. package/static/vendor/fontawesome-free/svgs/solid/chess-queen.svg +1 -0
  1137. package/static/vendor/fontawesome-free/svgs/solid/chess-rook.svg +1 -0
  1138. package/static/vendor/fontawesome-free/svgs/solid/chess.svg +1 -0
  1139. package/static/vendor/fontawesome-free/svgs/solid/chevron-circle-down.svg +1 -0
  1140. package/static/vendor/fontawesome-free/svgs/solid/chevron-circle-left.svg +1 -0
  1141. package/static/vendor/fontawesome-free/svgs/solid/chevron-circle-right.svg +1 -0
  1142. package/static/vendor/fontawesome-free/svgs/solid/chevron-circle-up.svg +1 -0
  1143. package/static/vendor/fontawesome-free/svgs/solid/chevron-down.svg +1 -0
  1144. package/static/vendor/fontawesome-free/svgs/solid/chevron-left.svg +1 -0
  1145. package/static/vendor/fontawesome-free/svgs/solid/chevron-right.svg +1 -0
  1146. package/static/vendor/fontawesome-free/svgs/solid/chevron-up.svg +1 -0
  1147. package/static/vendor/fontawesome-free/svgs/solid/child.svg +1 -0
  1148. package/static/vendor/fontawesome-free/svgs/solid/church.svg +1 -0
  1149. package/static/vendor/fontawesome-free/svgs/solid/circle-notch.svg +1 -0
  1150. package/static/vendor/fontawesome-free/svgs/solid/circle.svg +1 -0
  1151. package/static/vendor/fontawesome-free/svgs/solid/city.svg +1 -0
  1152. package/static/vendor/fontawesome-free/svgs/solid/clinic-medical.svg +1 -0
  1153. package/static/vendor/fontawesome-free/svgs/solid/clipboard-check.svg +1 -0
  1154. package/static/vendor/fontawesome-free/svgs/solid/clipboard-list.svg +1 -0
  1155. package/static/vendor/fontawesome-free/svgs/solid/clipboard.svg +1 -0
  1156. package/static/vendor/fontawesome-free/svgs/solid/clock.svg +1 -0
  1157. package/static/vendor/fontawesome-free/svgs/solid/clone.svg +1 -0
  1158. package/static/vendor/fontawesome-free/svgs/solid/closed-captioning.svg +1 -0
  1159. package/static/vendor/fontawesome-free/svgs/solid/cloud-download-alt.svg +1 -0
  1160. package/static/vendor/fontawesome-free/svgs/solid/cloud-meatball.svg +1 -0
  1161. package/static/vendor/fontawesome-free/svgs/solid/cloud-moon-rain.svg +1 -0
  1162. package/static/vendor/fontawesome-free/svgs/solid/cloud-moon.svg +1 -0
  1163. package/static/vendor/fontawesome-free/svgs/solid/cloud-rain.svg +1 -0
  1164. package/static/vendor/fontawesome-free/svgs/solid/cloud-showers-heavy.svg +1 -0
  1165. package/static/vendor/fontawesome-free/svgs/solid/cloud-sun-rain.svg +1 -0
  1166. package/static/vendor/fontawesome-free/svgs/solid/cloud-sun.svg +1 -0
  1167. package/static/vendor/fontawesome-free/svgs/solid/cloud-upload-alt.svg +1 -0
  1168. package/static/vendor/fontawesome-free/svgs/solid/cloud.svg +1 -0
  1169. package/static/vendor/fontawesome-free/svgs/solid/cocktail.svg +1 -0
  1170. package/static/vendor/fontawesome-free/svgs/solid/code-branch.svg +1 -0
  1171. package/static/vendor/fontawesome-free/svgs/solid/code.svg +1 -0
  1172. package/static/vendor/fontawesome-free/svgs/solid/coffee.svg +1 -0
  1173. package/static/vendor/fontawesome-free/svgs/solid/cog.svg +1 -0
  1174. package/static/vendor/fontawesome-free/svgs/solid/cogs.svg +1 -0
  1175. package/static/vendor/fontawesome-free/svgs/solid/coins.svg +1 -0
  1176. package/static/vendor/fontawesome-free/svgs/solid/columns.svg +1 -0
  1177. package/static/vendor/fontawesome-free/svgs/solid/comment-alt.svg +1 -0
  1178. package/static/vendor/fontawesome-free/svgs/solid/comment-dollar.svg +1 -0
  1179. package/static/vendor/fontawesome-free/svgs/solid/comment-dots.svg +1 -0
  1180. package/static/vendor/fontawesome-free/svgs/solid/comment-medical.svg +1 -0
  1181. package/static/vendor/fontawesome-free/svgs/solid/comment-slash.svg +1 -0
  1182. package/static/vendor/fontawesome-free/svgs/solid/comment.svg +1 -0
  1183. package/static/vendor/fontawesome-free/svgs/solid/comments-dollar.svg +1 -0
  1184. package/static/vendor/fontawesome-free/svgs/solid/comments.svg +1 -0
  1185. package/static/vendor/fontawesome-free/svgs/solid/compact-disc.svg +1 -0
  1186. package/static/vendor/fontawesome-free/svgs/solid/compass.svg +1 -0
  1187. package/static/vendor/fontawesome-free/svgs/solid/compress-alt.svg +1 -0
  1188. package/static/vendor/fontawesome-free/svgs/solid/compress-arrows-alt.svg +1 -0
  1189. package/static/vendor/fontawesome-free/svgs/solid/compress.svg +1 -0
  1190. package/static/vendor/fontawesome-free/svgs/solid/concierge-bell.svg +1 -0
  1191. package/static/vendor/fontawesome-free/svgs/solid/cookie-bite.svg +1 -0
  1192. package/static/vendor/fontawesome-free/svgs/solid/cookie.svg +1 -0
  1193. package/static/vendor/fontawesome-free/svgs/solid/copy.svg +1 -0
  1194. package/static/vendor/fontawesome-free/svgs/solid/copyright.svg +1 -0
  1195. package/static/vendor/fontawesome-free/svgs/solid/couch.svg +1 -0
  1196. package/static/vendor/fontawesome-free/svgs/solid/credit-card.svg +1 -0
  1197. package/static/vendor/fontawesome-free/svgs/solid/crop-alt.svg +1 -0
  1198. package/static/vendor/fontawesome-free/svgs/solid/crop.svg +1 -0
  1199. package/static/vendor/fontawesome-free/svgs/solid/cross.svg +1 -0
  1200. package/static/vendor/fontawesome-free/svgs/solid/crosshairs.svg +1 -0
  1201. package/static/vendor/fontawesome-free/svgs/solid/crow.svg +1 -0
  1202. package/static/vendor/fontawesome-free/svgs/solid/crown.svg +1 -0
  1203. package/static/vendor/fontawesome-free/svgs/solid/crutch.svg +1 -0
  1204. package/static/vendor/fontawesome-free/svgs/solid/cube.svg +1 -0
  1205. package/static/vendor/fontawesome-free/svgs/solid/cubes.svg +1 -0
  1206. package/static/vendor/fontawesome-free/svgs/solid/cut.svg +1 -0
  1207. package/static/vendor/fontawesome-free/svgs/solid/database.svg +1 -0
  1208. package/static/vendor/fontawesome-free/svgs/solid/deaf.svg +1 -0
  1209. package/static/vendor/fontawesome-free/svgs/solid/democrat.svg +1 -0
  1210. package/static/vendor/fontawesome-free/svgs/solid/desktop.svg +1 -0
  1211. package/static/vendor/fontawesome-free/svgs/solid/dharmachakra.svg +1 -0
  1212. package/static/vendor/fontawesome-free/svgs/solid/diagnoses.svg +1 -0
  1213. package/static/vendor/fontawesome-free/svgs/solid/dice-d20.svg +1 -0
  1214. package/static/vendor/fontawesome-free/svgs/solid/dice-d6.svg +1 -0
  1215. package/static/vendor/fontawesome-free/svgs/solid/dice-five.svg +1 -0
  1216. package/static/vendor/fontawesome-free/svgs/solid/dice-four.svg +1 -0
  1217. package/static/vendor/fontawesome-free/svgs/solid/dice-one.svg +1 -0
  1218. package/static/vendor/fontawesome-free/svgs/solid/dice-six.svg +1 -0
  1219. package/static/vendor/fontawesome-free/svgs/solid/dice-three.svg +1 -0
  1220. package/static/vendor/fontawesome-free/svgs/solid/dice-two.svg +1 -0
  1221. package/static/vendor/fontawesome-free/svgs/solid/dice.svg +1 -0
  1222. package/static/vendor/fontawesome-free/svgs/solid/digital-tachograph.svg +1 -0
  1223. package/static/vendor/fontawesome-free/svgs/solid/directions.svg +1 -0
  1224. package/static/vendor/fontawesome-free/svgs/solid/disease.svg +1 -0
  1225. package/static/vendor/fontawesome-free/svgs/solid/divide.svg +1 -0
  1226. package/static/vendor/fontawesome-free/svgs/solid/dizzy.svg +1 -0
  1227. package/static/vendor/fontawesome-free/svgs/solid/dna.svg +1 -0
  1228. package/static/vendor/fontawesome-free/svgs/solid/dog.svg +1 -0
  1229. package/static/vendor/fontawesome-free/svgs/solid/dollar-sign.svg +1 -0
  1230. package/static/vendor/fontawesome-free/svgs/solid/dolly-flatbed.svg +1 -0
  1231. package/static/vendor/fontawesome-free/svgs/solid/dolly.svg +1 -0
  1232. package/static/vendor/fontawesome-free/svgs/solid/donate.svg +1 -0
  1233. package/static/vendor/fontawesome-free/svgs/solid/door-closed.svg +1 -0
  1234. package/static/vendor/fontawesome-free/svgs/solid/door-open.svg +1 -0
  1235. package/static/vendor/fontawesome-free/svgs/solid/dot-circle.svg +1 -0
  1236. package/static/vendor/fontawesome-free/svgs/solid/dove.svg +1 -0
  1237. package/static/vendor/fontawesome-free/svgs/solid/download.svg +1 -0
  1238. package/static/vendor/fontawesome-free/svgs/solid/drafting-compass.svg +1 -0
  1239. package/static/vendor/fontawesome-free/svgs/solid/dragon.svg +1 -0
  1240. package/static/vendor/fontawesome-free/svgs/solid/draw-polygon.svg +1 -0
  1241. package/static/vendor/fontawesome-free/svgs/solid/drum-steelpan.svg +1 -0
  1242. package/static/vendor/fontawesome-free/svgs/solid/drum.svg +1 -0
  1243. package/static/vendor/fontawesome-free/svgs/solid/drumstick-bite.svg +1 -0
  1244. package/static/vendor/fontawesome-free/svgs/solid/dumbbell.svg +1 -0
  1245. package/static/vendor/fontawesome-free/svgs/solid/dumpster-fire.svg +1 -0
  1246. package/static/vendor/fontawesome-free/svgs/solid/dumpster.svg +1 -0
  1247. package/static/vendor/fontawesome-free/svgs/solid/dungeon.svg +1 -0
  1248. package/static/vendor/fontawesome-free/svgs/solid/edit.svg +1 -0
  1249. package/static/vendor/fontawesome-free/svgs/solid/egg.svg +1 -0
  1250. package/static/vendor/fontawesome-free/svgs/solid/eject.svg +1 -0
  1251. package/static/vendor/fontawesome-free/svgs/solid/ellipsis-h.svg +1 -0
  1252. package/static/vendor/fontawesome-free/svgs/solid/ellipsis-v.svg +1 -0
  1253. package/static/vendor/fontawesome-free/svgs/solid/envelope-open-text.svg +1 -0
  1254. package/static/vendor/fontawesome-free/svgs/solid/envelope-open.svg +1 -0
  1255. package/static/vendor/fontawesome-free/svgs/solid/envelope-square.svg +1 -0
  1256. package/static/vendor/fontawesome-free/svgs/solid/envelope.svg +1 -0
  1257. package/static/vendor/fontawesome-free/svgs/solid/equals.svg +1 -0
  1258. package/static/vendor/fontawesome-free/svgs/solid/eraser.svg +1 -0
  1259. package/static/vendor/fontawesome-free/svgs/solid/ethernet.svg +1 -0
  1260. package/static/vendor/fontawesome-free/svgs/solid/euro-sign.svg +1 -0
  1261. package/static/vendor/fontawesome-free/svgs/solid/exchange-alt.svg +1 -0
  1262. package/static/vendor/fontawesome-free/svgs/solid/exclamation-circle.svg +1 -0
  1263. package/static/vendor/fontawesome-free/svgs/solid/exclamation-triangle.svg +1 -0
  1264. package/static/vendor/fontawesome-free/svgs/solid/exclamation.svg +1 -0
  1265. package/static/vendor/fontawesome-free/svgs/solid/expand-alt.svg +1 -0
  1266. package/static/vendor/fontawesome-free/svgs/solid/expand-arrows-alt.svg +1 -0
  1267. package/static/vendor/fontawesome-free/svgs/solid/expand.svg +1 -0
  1268. package/static/vendor/fontawesome-free/svgs/solid/external-link-alt.svg +1 -0
  1269. package/static/vendor/fontawesome-free/svgs/solid/external-link-square-alt.svg +1 -0
  1270. package/static/vendor/fontawesome-free/svgs/solid/eye-dropper.svg +1 -0
  1271. package/static/vendor/fontawesome-free/svgs/solid/eye-slash.svg +1 -0
  1272. package/static/vendor/fontawesome-free/svgs/solid/eye.svg +1 -0
  1273. package/static/vendor/fontawesome-free/svgs/solid/fan.svg +1 -0
  1274. package/static/vendor/fontawesome-free/svgs/solid/fast-backward.svg +1 -0
  1275. package/static/vendor/fontawesome-free/svgs/solid/fast-forward.svg +1 -0
  1276. package/static/vendor/fontawesome-free/svgs/solid/faucet.svg +1 -0
  1277. package/static/vendor/fontawesome-free/svgs/solid/fax.svg +1 -0
  1278. package/static/vendor/fontawesome-free/svgs/solid/feather-alt.svg +1 -0
  1279. package/static/vendor/fontawesome-free/svgs/solid/feather.svg +1 -0
  1280. package/static/vendor/fontawesome-free/svgs/solid/female.svg +1 -0
  1281. package/static/vendor/fontawesome-free/svgs/solid/fighter-jet.svg +1 -0
  1282. package/static/vendor/fontawesome-free/svgs/solid/file-alt.svg +1 -0
  1283. package/static/vendor/fontawesome-free/svgs/solid/file-archive.svg +1 -0
  1284. package/static/vendor/fontawesome-free/svgs/solid/file-audio.svg +1 -0
  1285. package/static/vendor/fontawesome-free/svgs/solid/file-code.svg +1 -0
  1286. package/static/vendor/fontawesome-free/svgs/solid/file-contract.svg +1 -0
  1287. package/static/vendor/fontawesome-free/svgs/solid/file-csv.svg +1 -0
  1288. package/static/vendor/fontawesome-free/svgs/solid/file-download.svg +1 -0
  1289. package/static/vendor/fontawesome-free/svgs/solid/file-excel.svg +1 -0
  1290. package/static/vendor/fontawesome-free/svgs/solid/file-export.svg +1 -0
  1291. package/static/vendor/fontawesome-free/svgs/solid/file-image.svg +1 -0
  1292. package/static/vendor/fontawesome-free/svgs/solid/file-import.svg +1 -0
  1293. package/static/vendor/fontawesome-free/svgs/solid/file-invoice-dollar.svg +1 -0
  1294. package/static/vendor/fontawesome-free/svgs/solid/file-invoice.svg +1 -0
  1295. package/static/vendor/fontawesome-free/svgs/solid/file-medical-alt.svg +1 -0
  1296. package/static/vendor/fontawesome-free/svgs/solid/file-medical.svg +1 -0
  1297. package/static/vendor/fontawesome-free/svgs/solid/file-pdf.svg +1 -0
  1298. package/static/vendor/fontawesome-free/svgs/solid/file-powerpoint.svg +1 -0
  1299. package/static/vendor/fontawesome-free/svgs/solid/file-prescription.svg +1 -0
  1300. package/static/vendor/fontawesome-free/svgs/solid/file-signature.svg +1 -0
  1301. package/static/vendor/fontawesome-free/svgs/solid/file-upload.svg +1 -0
  1302. package/static/vendor/fontawesome-free/svgs/solid/file-video.svg +1 -0
  1303. package/static/vendor/fontawesome-free/svgs/solid/file-word.svg +1 -0
  1304. package/static/vendor/fontawesome-free/svgs/solid/file.svg +1 -0
  1305. package/static/vendor/fontawesome-free/svgs/solid/fill-drip.svg +1 -0
  1306. package/static/vendor/fontawesome-free/svgs/solid/fill.svg +1 -0
  1307. package/static/vendor/fontawesome-free/svgs/solid/film.svg +1 -0
  1308. package/static/vendor/fontawesome-free/svgs/solid/filter.svg +1 -0
  1309. package/static/vendor/fontawesome-free/svgs/solid/fingerprint.svg +1 -0
  1310. package/static/vendor/fontawesome-free/svgs/solid/fire-alt.svg +1 -0
  1311. package/static/vendor/fontawesome-free/svgs/solid/fire-extinguisher.svg +1 -0
  1312. package/static/vendor/fontawesome-free/svgs/solid/fire.svg +1 -0
  1313. package/static/vendor/fontawesome-free/svgs/solid/first-aid.svg +1 -0
  1314. package/static/vendor/fontawesome-free/svgs/solid/fish.svg +1 -0
  1315. package/static/vendor/fontawesome-free/svgs/solid/fist-raised.svg +1 -0
  1316. package/static/vendor/fontawesome-free/svgs/solid/flag-checkered.svg +1 -0
  1317. package/static/vendor/fontawesome-free/svgs/solid/flag-usa.svg +1 -0
  1318. package/static/vendor/fontawesome-free/svgs/solid/flag.svg +1 -0
  1319. package/static/vendor/fontawesome-free/svgs/solid/flask.svg +1 -0
  1320. package/static/vendor/fontawesome-free/svgs/solid/flushed.svg +1 -0
  1321. package/static/vendor/fontawesome-free/svgs/solid/folder-minus.svg +1 -0
  1322. package/static/vendor/fontawesome-free/svgs/solid/folder-open.svg +1 -0
  1323. package/static/vendor/fontawesome-free/svgs/solid/folder-plus.svg +1 -0
  1324. package/static/vendor/fontawesome-free/svgs/solid/folder.svg +1 -0
  1325. package/static/vendor/fontawesome-free/svgs/solid/font-awesome-logo-full.svg +1 -0
  1326. package/static/vendor/fontawesome-free/svgs/solid/font.svg +1 -0
  1327. package/static/vendor/fontawesome-free/svgs/solid/football-ball.svg +1 -0
  1328. package/static/vendor/fontawesome-free/svgs/solid/forward.svg +1 -0
  1329. package/static/vendor/fontawesome-free/svgs/solid/frog.svg +1 -0
  1330. package/static/vendor/fontawesome-free/svgs/solid/frown-open.svg +1 -0
  1331. package/static/vendor/fontawesome-free/svgs/solid/frown.svg +1 -0
  1332. package/static/vendor/fontawesome-free/svgs/solid/funnel-dollar.svg +1 -0
  1333. package/static/vendor/fontawesome-free/svgs/solid/futbol.svg +1 -0
  1334. package/static/vendor/fontawesome-free/svgs/solid/gamepad.svg +1 -0
  1335. package/static/vendor/fontawesome-free/svgs/solid/gas-pump.svg +1 -0
  1336. package/static/vendor/fontawesome-free/svgs/solid/gavel.svg +1 -0
  1337. package/static/vendor/fontawesome-free/svgs/solid/gem.svg +1 -0
  1338. package/static/vendor/fontawesome-free/svgs/solid/genderless.svg +1 -0
  1339. package/static/vendor/fontawesome-free/svgs/solid/ghost.svg +1 -0
  1340. package/static/vendor/fontawesome-free/svgs/solid/gift.svg +1 -0
  1341. package/static/vendor/fontawesome-free/svgs/solid/gifts.svg +1 -0
  1342. package/static/vendor/fontawesome-free/svgs/solid/glass-cheers.svg +1 -0
  1343. package/static/vendor/fontawesome-free/svgs/solid/glass-martini-alt.svg +1 -0
  1344. package/static/vendor/fontawesome-free/svgs/solid/glass-martini.svg +1 -0
  1345. package/static/vendor/fontawesome-free/svgs/solid/glass-whiskey.svg +1 -0
  1346. package/static/vendor/fontawesome-free/svgs/solid/glasses.svg +1 -0
  1347. package/static/vendor/fontawesome-free/svgs/solid/globe-africa.svg +1 -0
  1348. package/static/vendor/fontawesome-free/svgs/solid/globe-americas.svg +1 -0
  1349. package/static/vendor/fontawesome-free/svgs/solid/globe-asia.svg +1 -0
  1350. package/static/vendor/fontawesome-free/svgs/solid/globe-europe.svg +1 -0
  1351. package/static/vendor/fontawesome-free/svgs/solid/globe.svg +1 -0
  1352. package/static/vendor/fontawesome-free/svgs/solid/golf-ball.svg +1 -0
  1353. package/static/vendor/fontawesome-free/svgs/solid/gopuram.svg +1 -0
  1354. package/static/vendor/fontawesome-free/svgs/solid/graduation-cap.svg +1 -0
  1355. package/static/vendor/fontawesome-free/svgs/solid/greater-than-equal.svg +1 -0
  1356. package/static/vendor/fontawesome-free/svgs/solid/greater-than.svg +1 -0
  1357. package/static/vendor/fontawesome-free/svgs/solid/grimace.svg +1 -0
  1358. package/static/vendor/fontawesome-free/svgs/solid/grin-alt.svg +1 -0
  1359. package/static/vendor/fontawesome-free/svgs/solid/grin-beam-sweat.svg +1 -0
  1360. package/static/vendor/fontawesome-free/svgs/solid/grin-beam.svg +1 -0
  1361. package/static/vendor/fontawesome-free/svgs/solid/grin-hearts.svg +1 -0
  1362. package/static/vendor/fontawesome-free/svgs/solid/grin-squint-tears.svg +1 -0
  1363. package/static/vendor/fontawesome-free/svgs/solid/grin-squint.svg +1 -0
  1364. package/static/vendor/fontawesome-free/svgs/solid/grin-stars.svg +1 -0
  1365. package/static/vendor/fontawesome-free/svgs/solid/grin-tears.svg +1 -0
  1366. package/static/vendor/fontawesome-free/svgs/solid/grin-tongue-squint.svg +1 -0
  1367. package/static/vendor/fontawesome-free/svgs/solid/grin-tongue-wink.svg +1 -0
  1368. package/static/vendor/fontawesome-free/svgs/solid/grin-tongue.svg +1 -0
  1369. package/static/vendor/fontawesome-free/svgs/solid/grin-wink.svg +1 -0
  1370. package/static/vendor/fontawesome-free/svgs/solid/grin.svg +1 -0
  1371. package/static/vendor/fontawesome-free/svgs/solid/grip-horizontal.svg +1 -0
  1372. package/static/vendor/fontawesome-free/svgs/solid/grip-lines-vertical.svg +1 -0
  1373. package/static/vendor/fontawesome-free/svgs/solid/grip-lines.svg +1 -0
  1374. package/static/vendor/fontawesome-free/svgs/solid/grip-vertical.svg +1 -0
  1375. package/static/vendor/fontawesome-free/svgs/solid/guitar.svg +1 -0
  1376. package/static/vendor/fontawesome-free/svgs/solid/h-square.svg +1 -0
  1377. package/static/vendor/fontawesome-free/svgs/solid/hamburger.svg +1 -0
  1378. package/static/vendor/fontawesome-free/svgs/solid/hammer.svg +1 -0
  1379. package/static/vendor/fontawesome-free/svgs/solid/hamsa.svg +1 -0
  1380. package/static/vendor/fontawesome-free/svgs/solid/hand-holding-heart.svg +1 -0
  1381. package/static/vendor/fontawesome-free/svgs/solid/hand-holding-medical.svg +1 -0
  1382. package/static/vendor/fontawesome-free/svgs/solid/hand-holding-usd.svg +1 -0
  1383. package/static/vendor/fontawesome-free/svgs/solid/hand-holding-water.svg +1 -0
  1384. package/static/vendor/fontawesome-free/svgs/solid/hand-holding.svg +1 -0
  1385. package/static/vendor/fontawesome-free/svgs/solid/hand-lizard.svg +1 -0
  1386. package/static/vendor/fontawesome-free/svgs/solid/hand-middle-finger.svg +1 -0
  1387. package/static/vendor/fontawesome-free/svgs/solid/hand-paper.svg +1 -0
  1388. package/static/vendor/fontawesome-free/svgs/solid/hand-peace.svg +1 -0
  1389. package/static/vendor/fontawesome-free/svgs/solid/hand-point-down.svg +1 -0
  1390. package/static/vendor/fontawesome-free/svgs/solid/hand-point-left.svg +1 -0
  1391. package/static/vendor/fontawesome-free/svgs/solid/hand-point-right.svg +1 -0
  1392. package/static/vendor/fontawesome-free/svgs/solid/hand-point-up.svg +1 -0
  1393. package/static/vendor/fontawesome-free/svgs/solid/hand-pointer.svg +1 -0
  1394. package/static/vendor/fontawesome-free/svgs/solid/hand-rock.svg +1 -0
  1395. package/static/vendor/fontawesome-free/svgs/solid/hand-scissors.svg +1 -0
  1396. package/static/vendor/fontawesome-free/svgs/solid/hand-sparkles.svg +1 -0
  1397. package/static/vendor/fontawesome-free/svgs/solid/hand-spock.svg +1 -0
  1398. package/static/vendor/fontawesome-free/svgs/solid/hands-helping.svg +1 -0
  1399. package/static/vendor/fontawesome-free/svgs/solid/hands-wash.svg +1 -0
  1400. package/static/vendor/fontawesome-free/svgs/solid/hands.svg +1 -0
  1401. package/static/vendor/fontawesome-free/svgs/solid/handshake-alt-slash.svg +1 -0
  1402. package/static/vendor/fontawesome-free/svgs/solid/handshake-slash.svg +1 -0
  1403. package/static/vendor/fontawesome-free/svgs/solid/handshake.svg +1 -0
  1404. package/static/vendor/fontawesome-free/svgs/solid/hanukiah.svg +1 -0
  1405. package/static/vendor/fontawesome-free/svgs/solid/hard-hat.svg +1 -0
  1406. package/static/vendor/fontawesome-free/svgs/solid/hashtag.svg +1 -0
  1407. package/static/vendor/fontawesome-free/svgs/solid/hat-cowboy-side.svg +1 -0
  1408. package/static/vendor/fontawesome-free/svgs/solid/hat-cowboy.svg +1 -0
  1409. package/static/vendor/fontawesome-free/svgs/solid/hat-wizard.svg +1 -0
  1410. package/static/vendor/fontawesome-free/svgs/solid/hdd.svg +1 -0
  1411. package/static/vendor/fontawesome-free/svgs/solid/head-side-cough-slash.svg +1 -0
  1412. package/static/vendor/fontawesome-free/svgs/solid/head-side-cough.svg +1 -0
  1413. package/static/vendor/fontawesome-free/svgs/solid/head-side-mask.svg +1 -0
  1414. package/static/vendor/fontawesome-free/svgs/solid/head-side-virus.svg +1 -0
  1415. package/static/vendor/fontawesome-free/svgs/solid/heading.svg +1 -0
  1416. package/static/vendor/fontawesome-free/svgs/solid/headphones-alt.svg +1 -0
  1417. package/static/vendor/fontawesome-free/svgs/solid/headphones.svg +1 -0
  1418. package/static/vendor/fontawesome-free/svgs/solid/headset.svg +1 -0
  1419. package/static/vendor/fontawesome-free/svgs/solid/heart-broken.svg +1 -0
  1420. package/static/vendor/fontawesome-free/svgs/solid/heart.svg +1 -0
  1421. package/static/vendor/fontawesome-free/svgs/solid/heartbeat.svg +1 -0
  1422. package/static/vendor/fontawesome-free/svgs/solid/helicopter.svg +1 -0
  1423. package/static/vendor/fontawesome-free/svgs/solid/highlighter.svg +1 -0
  1424. package/static/vendor/fontawesome-free/svgs/solid/hiking.svg +1 -0
  1425. package/static/vendor/fontawesome-free/svgs/solid/hippo.svg +1 -0
  1426. package/static/vendor/fontawesome-free/svgs/solid/history.svg +1 -0
  1427. package/static/vendor/fontawesome-free/svgs/solid/hockey-puck.svg +1 -0
  1428. package/static/vendor/fontawesome-free/svgs/solid/holly-berry.svg +1 -0
  1429. package/static/vendor/fontawesome-free/svgs/solid/home.svg +1 -0
  1430. package/static/vendor/fontawesome-free/svgs/solid/horse-head.svg +1 -0
  1431. package/static/vendor/fontawesome-free/svgs/solid/horse.svg +1 -0
  1432. package/static/vendor/fontawesome-free/svgs/solid/hospital-alt.svg +1 -0
  1433. package/static/vendor/fontawesome-free/svgs/solid/hospital-symbol.svg +1 -0
  1434. package/static/vendor/fontawesome-free/svgs/solid/hospital-user.svg +1 -0
  1435. package/static/vendor/fontawesome-free/svgs/solid/hospital.svg +1 -0
  1436. package/static/vendor/fontawesome-free/svgs/solid/hot-tub.svg +1 -0
  1437. package/static/vendor/fontawesome-free/svgs/solid/hotdog.svg +1 -0
  1438. package/static/vendor/fontawesome-free/svgs/solid/hotel.svg +1 -0
  1439. package/static/vendor/fontawesome-free/svgs/solid/hourglass-end.svg +1 -0
  1440. package/static/vendor/fontawesome-free/svgs/solid/hourglass-half.svg +1 -0
  1441. package/static/vendor/fontawesome-free/svgs/solid/hourglass-start.svg +1 -0
  1442. package/static/vendor/fontawesome-free/svgs/solid/hourglass.svg +1 -0
  1443. package/static/vendor/fontawesome-free/svgs/solid/house-damage.svg +1 -0
  1444. package/static/vendor/fontawesome-free/svgs/solid/house-user.svg +1 -0
  1445. package/static/vendor/fontawesome-free/svgs/solid/hryvnia.svg +1 -0
  1446. package/static/vendor/fontawesome-free/svgs/solid/i-cursor.svg +1 -0
  1447. package/static/vendor/fontawesome-free/svgs/solid/ice-cream.svg +1 -0
  1448. package/static/vendor/fontawesome-free/svgs/solid/icicles.svg +1 -0
  1449. package/static/vendor/fontawesome-free/svgs/solid/icons.svg +1 -0
  1450. package/static/vendor/fontawesome-free/svgs/solid/id-badge.svg +1 -0
  1451. package/static/vendor/fontawesome-free/svgs/solid/id-card-alt.svg +1 -0
  1452. package/static/vendor/fontawesome-free/svgs/solid/id-card.svg +1 -0
  1453. package/static/vendor/fontawesome-free/svgs/solid/igloo.svg +1 -0
  1454. package/static/vendor/fontawesome-free/svgs/solid/image.svg +1 -0
  1455. package/static/vendor/fontawesome-free/svgs/solid/images.svg +1 -0
  1456. package/static/vendor/fontawesome-free/svgs/solid/inbox.svg +1 -0
  1457. package/static/vendor/fontawesome-free/svgs/solid/indent.svg +1 -0
  1458. package/static/vendor/fontawesome-free/svgs/solid/industry.svg +1 -0
  1459. package/static/vendor/fontawesome-free/svgs/solid/infinity.svg +1 -0
  1460. package/static/vendor/fontawesome-free/svgs/solid/info-circle.svg +1 -0
  1461. package/static/vendor/fontawesome-free/svgs/solid/info.svg +1 -0
  1462. package/static/vendor/fontawesome-free/svgs/solid/italic.svg +1 -0
  1463. package/static/vendor/fontawesome-free/svgs/solid/jedi.svg +1 -0
  1464. package/static/vendor/fontawesome-free/svgs/solid/joint.svg +1 -0
  1465. package/static/vendor/fontawesome-free/svgs/solid/journal-whills.svg +1 -0
  1466. package/static/vendor/fontawesome-free/svgs/solid/kaaba.svg +1 -0
  1467. package/static/vendor/fontawesome-free/svgs/solid/key.svg +1 -0
  1468. package/static/vendor/fontawesome-free/svgs/solid/keyboard.svg +1 -0
  1469. package/static/vendor/fontawesome-free/svgs/solid/khanda.svg +1 -0
  1470. package/static/vendor/fontawesome-free/svgs/solid/kiss-beam.svg +1 -0
  1471. package/static/vendor/fontawesome-free/svgs/solid/kiss-wink-heart.svg +1 -0
  1472. package/static/vendor/fontawesome-free/svgs/solid/kiss.svg +1 -0
  1473. package/static/vendor/fontawesome-free/svgs/solid/kiwi-bird.svg +1 -0
  1474. package/static/vendor/fontawesome-free/svgs/solid/landmark.svg +1 -0
  1475. package/static/vendor/fontawesome-free/svgs/solid/language.svg +1 -0
  1476. package/static/vendor/fontawesome-free/svgs/solid/laptop-code.svg +1 -0
  1477. package/static/vendor/fontawesome-free/svgs/solid/laptop-house.svg +1 -0
  1478. package/static/vendor/fontawesome-free/svgs/solid/laptop-medical.svg +1 -0
  1479. package/static/vendor/fontawesome-free/svgs/solid/laptop.svg +1 -0
  1480. package/static/vendor/fontawesome-free/svgs/solid/laugh-beam.svg +1 -0
  1481. package/static/vendor/fontawesome-free/svgs/solid/laugh-squint.svg +1 -0
  1482. package/static/vendor/fontawesome-free/svgs/solid/laugh-wink.svg +1 -0
  1483. package/static/vendor/fontawesome-free/svgs/solid/laugh.svg +1 -0
  1484. package/static/vendor/fontawesome-free/svgs/solid/layer-group.svg +1 -0
  1485. package/static/vendor/fontawesome-free/svgs/solid/leaf.svg +1 -0
  1486. package/static/vendor/fontawesome-free/svgs/solid/lemon.svg +1 -0
  1487. package/static/vendor/fontawesome-free/svgs/solid/less-than-equal.svg +1 -0
  1488. package/static/vendor/fontawesome-free/svgs/solid/less-than.svg +1 -0
  1489. package/static/vendor/fontawesome-free/svgs/solid/level-down-alt.svg +1 -0
  1490. package/static/vendor/fontawesome-free/svgs/solid/level-up-alt.svg +1 -0
  1491. package/static/vendor/fontawesome-free/svgs/solid/life-ring.svg +1 -0
  1492. package/static/vendor/fontawesome-free/svgs/solid/lightbulb.svg +1 -0
  1493. package/static/vendor/fontawesome-free/svgs/solid/link.svg +1 -0
  1494. package/static/vendor/fontawesome-free/svgs/solid/lira-sign.svg +1 -0
  1495. package/static/vendor/fontawesome-free/svgs/solid/list-alt.svg +1 -0
  1496. package/static/vendor/fontawesome-free/svgs/solid/list-ol.svg +1 -0
  1497. package/static/vendor/fontawesome-free/svgs/solid/list-ul.svg +1 -0
  1498. package/static/vendor/fontawesome-free/svgs/solid/list.svg +1 -0
  1499. package/static/vendor/fontawesome-free/svgs/solid/location-arrow.svg +1 -0
  1500. package/static/vendor/fontawesome-free/svgs/solid/lock-open.svg +1 -0
  1501. package/static/vendor/fontawesome-free/svgs/solid/lock.svg +1 -0
  1502. package/static/vendor/fontawesome-free/svgs/solid/long-arrow-alt-down.svg +1 -0
  1503. package/static/vendor/fontawesome-free/svgs/solid/long-arrow-alt-left.svg +1 -0
  1504. package/static/vendor/fontawesome-free/svgs/solid/long-arrow-alt-right.svg +1 -0
  1505. package/static/vendor/fontawesome-free/svgs/solid/long-arrow-alt-up.svg +1 -0
  1506. package/static/vendor/fontawesome-free/svgs/solid/low-vision.svg +1 -0
  1507. package/static/vendor/fontawesome-free/svgs/solid/luggage-cart.svg +1 -0
  1508. package/static/vendor/fontawesome-free/svgs/solid/lungs-virus.svg +1 -0
  1509. package/static/vendor/fontawesome-free/svgs/solid/lungs.svg +1 -0
  1510. package/static/vendor/fontawesome-free/svgs/solid/magic.svg +1 -0
  1511. package/static/vendor/fontawesome-free/svgs/solid/magnet.svg +1 -0
  1512. package/static/vendor/fontawesome-free/svgs/solid/mail-bulk.svg +1 -0
  1513. package/static/vendor/fontawesome-free/svgs/solid/male.svg +1 -0
  1514. package/static/vendor/fontawesome-free/svgs/solid/map-marked-alt.svg +1 -0
  1515. package/static/vendor/fontawesome-free/svgs/solid/map-marked.svg +1 -0
  1516. package/static/vendor/fontawesome-free/svgs/solid/map-marker-alt.svg +1 -0
  1517. package/static/vendor/fontawesome-free/svgs/solid/map-marker.svg +1 -0
  1518. package/static/vendor/fontawesome-free/svgs/solid/map-pin.svg +1 -0
  1519. package/static/vendor/fontawesome-free/svgs/solid/map-signs.svg +1 -0
  1520. package/static/vendor/fontawesome-free/svgs/solid/map.svg +1 -0
  1521. package/static/vendor/fontawesome-free/svgs/solid/marker.svg +1 -0
  1522. package/static/vendor/fontawesome-free/svgs/solid/mars-double.svg +1 -0
  1523. package/static/vendor/fontawesome-free/svgs/solid/mars-stroke-h.svg +1 -0
  1524. package/static/vendor/fontawesome-free/svgs/solid/mars-stroke-v.svg +1 -0
  1525. package/static/vendor/fontawesome-free/svgs/solid/mars-stroke.svg +1 -0
  1526. package/static/vendor/fontawesome-free/svgs/solid/mars.svg +1 -0
  1527. package/static/vendor/fontawesome-free/svgs/solid/mask.svg +1 -0
  1528. package/static/vendor/fontawesome-free/svgs/solid/medal.svg +1 -0
  1529. package/static/vendor/fontawesome-free/svgs/solid/medkit.svg +1 -0
  1530. package/static/vendor/fontawesome-free/svgs/solid/meh-blank.svg +1 -0
  1531. package/static/vendor/fontawesome-free/svgs/solid/meh-rolling-eyes.svg +1 -0
  1532. package/static/vendor/fontawesome-free/svgs/solid/meh.svg +1 -0
  1533. package/static/vendor/fontawesome-free/svgs/solid/memory.svg +1 -0
  1534. package/static/vendor/fontawesome-free/svgs/solid/menorah.svg +1 -0
  1535. package/static/vendor/fontawesome-free/svgs/solid/mercury.svg +1 -0
  1536. package/static/vendor/fontawesome-free/svgs/solid/meteor.svg +1 -0
  1537. package/static/vendor/fontawesome-free/svgs/solid/microchip.svg +1 -0
  1538. package/static/vendor/fontawesome-free/svgs/solid/microphone-alt-slash.svg +1 -0
  1539. package/static/vendor/fontawesome-free/svgs/solid/microphone-alt.svg +1 -0
  1540. package/static/vendor/fontawesome-free/svgs/solid/microphone-slash.svg +1 -0
  1541. package/static/vendor/fontawesome-free/svgs/solid/microphone.svg +1 -0
  1542. package/static/vendor/fontawesome-free/svgs/solid/microscope.svg +1 -0
  1543. package/static/vendor/fontawesome-free/svgs/solid/minus-circle.svg +1 -0
  1544. package/static/vendor/fontawesome-free/svgs/solid/minus-square.svg +1 -0
  1545. package/static/vendor/fontawesome-free/svgs/solid/minus.svg +1 -0
  1546. package/static/vendor/fontawesome-free/svgs/solid/mitten.svg +1 -0
  1547. package/static/vendor/fontawesome-free/svgs/solid/mobile-alt.svg +1 -0
  1548. package/static/vendor/fontawesome-free/svgs/solid/mobile.svg +1 -0
  1549. package/static/vendor/fontawesome-free/svgs/solid/money-bill-alt.svg +1 -0
  1550. package/static/vendor/fontawesome-free/svgs/solid/money-bill-wave-alt.svg +1 -0
  1551. package/static/vendor/fontawesome-free/svgs/solid/money-bill-wave.svg +1 -0
  1552. package/static/vendor/fontawesome-free/svgs/solid/money-bill.svg +1 -0
  1553. package/static/vendor/fontawesome-free/svgs/solid/money-check-alt.svg +1 -0
  1554. package/static/vendor/fontawesome-free/svgs/solid/money-check.svg +1 -0
  1555. package/static/vendor/fontawesome-free/svgs/solid/monument.svg +1 -0
  1556. package/static/vendor/fontawesome-free/svgs/solid/moon.svg +1 -0
  1557. package/static/vendor/fontawesome-free/svgs/solid/mortar-pestle.svg +1 -0
  1558. package/static/vendor/fontawesome-free/svgs/solid/mosque.svg +1 -0
  1559. package/static/vendor/fontawesome-free/svgs/solid/motorcycle.svg +1 -0
  1560. package/static/vendor/fontawesome-free/svgs/solid/mountain.svg +1 -0
  1561. package/static/vendor/fontawesome-free/svgs/solid/mouse-pointer.svg +1 -0
  1562. package/static/vendor/fontawesome-free/svgs/solid/mouse.svg +1 -0
  1563. package/static/vendor/fontawesome-free/svgs/solid/mug-hot.svg +1 -0
  1564. package/static/vendor/fontawesome-free/svgs/solid/music.svg +1 -0
  1565. package/static/vendor/fontawesome-free/svgs/solid/network-wired.svg +1 -0
  1566. package/static/vendor/fontawesome-free/svgs/solid/neuter.svg +1 -0
  1567. package/static/vendor/fontawesome-free/svgs/solid/newspaper.svg +1 -0
  1568. package/static/vendor/fontawesome-free/svgs/solid/not-equal.svg +1 -0
  1569. package/static/vendor/fontawesome-free/svgs/solid/notes-medical.svg +1 -0
  1570. package/static/vendor/fontawesome-free/svgs/solid/object-group.svg +1 -0
  1571. package/static/vendor/fontawesome-free/svgs/solid/object-ungroup.svg +1 -0
  1572. package/static/vendor/fontawesome-free/svgs/solid/oil-can.svg +1 -0
  1573. package/static/vendor/fontawesome-free/svgs/solid/om.svg +1 -0
  1574. package/static/vendor/fontawesome-free/svgs/solid/otter.svg +1 -0
  1575. package/static/vendor/fontawesome-free/svgs/solid/outdent.svg +1 -0
  1576. package/static/vendor/fontawesome-free/svgs/solid/pager.svg +1 -0
  1577. package/static/vendor/fontawesome-free/svgs/solid/paint-brush.svg +1 -0
  1578. package/static/vendor/fontawesome-free/svgs/solid/paint-roller.svg +1 -0
  1579. package/static/vendor/fontawesome-free/svgs/solid/palette.svg +1 -0
  1580. package/static/vendor/fontawesome-free/svgs/solid/pallet.svg +1 -0
  1581. package/static/vendor/fontawesome-free/svgs/solid/paper-plane.svg +1 -0
  1582. package/static/vendor/fontawesome-free/svgs/solid/paperclip.svg +1 -0
  1583. package/static/vendor/fontawesome-free/svgs/solid/parachute-box.svg +1 -0
  1584. package/static/vendor/fontawesome-free/svgs/solid/paragraph.svg +1 -0
  1585. package/static/vendor/fontawesome-free/svgs/solid/parking.svg +1 -0
  1586. package/static/vendor/fontawesome-free/svgs/solid/passport.svg +1 -0
  1587. package/static/vendor/fontawesome-free/svgs/solid/pastafarianism.svg +1 -0
  1588. package/static/vendor/fontawesome-free/svgs/solid/paste.svg +1 -0
  1589. package/static/vendor/fontawesome-free/svgs/solid/pause-circle.svg +1 -0
  1590. package/static/vendor/fontawesome-free/svgs/solid/pause.svg +1 -0
  1591. package/static/vendor/fontawesome-free/svgs/solid/paw.svg +1 -0
  1592. package/static/vendor/fontawesome-free/svgs/solid/peace.svg +1 -0
  1593. package/static/vendor/fontawesome-free/svgs/solid/pen-alt.svg +1 -0
  1594. package/static/vendor/fontawesome-free/svgs/solid/pen-fancy.svg +1 -0
  1595. package/static/vendor/fontawesome-free/svgs/solid/pen-nib.svg +1 -0
  1596. package/static/vendor/fontawesome-free/svgs/solid/pen-square.svg +1 -0
  1597. package/static/vendor/fontawesome-free/svgs/solid/pen.svg +1 -0
  1598. package/static/vendor/fontawesome-free/svgs/solid/pencil-alt.svg +1 -0
  1599. package/static/vendor/fontawesome-free/svgs/solid/pencil-ruler.svg +1 -0
  1600. package/static/vendor/fontawesome-free/svgs/solid/people-arrows.svg +1 -0
  1601. package/static/vendor/fontawesome-free/svgs/solid/people-carry.svg +1 -0
  1602. package/static/vendor/fontawesome-free/svgs/solid/pepper-hot.svg +1 -0
  1603. package/static/vendor/fontawesome-free/svgs/solid/percent.svg +1 -0
  1604. package/static/vendor/fontawesome-free/svgs/solid/percentage.svg +1 -0
  1605. package/static/vendor/fontawesome-free/svgs/solid/person-booth.svg +1 -0
  1606. package/static/vendor/fontawesome-free/svgs/solid/phone-alt.svg +1 -0
  1607. package/static/vendor/fontawesome-free/svgs/solid/phone-slash.svg +1 -0
  1608. package/static/vendor/fontawesome-free/svgs/solid/phone-square-alt.svg +1 -0
  1609. package/static/vendor/fontawesome-free/svgs/solid/phone-square.svg +1 -0
  1610. package/static/vendor/fontawesome-free/svgs/solid/phone-volume.svg +1 -0
  1611. package/static/vendor/fontawesome-free/svgs/solid/phone.svg +1 -0
  1612. package/static/vendor/fontawesome-free/svgs/solid/photo-video.svg +1 -0
  1613. package/static/vendor/fontawesome-free/svgs/solid/piggy-bank.svg +1 -0
  1614. package/static/vendor/fontawesome-free/svgs/solid/pills.svg +1 -0
  1615. package/static/vendor/fontawesome-free/svgs/solid/pizza-slice.svg +1 -0
  1616. package/static/vendor/fontawesome-free/svgs/solid/place-of-worship.svg +1 -0
  1617. package/static/vendor/fontawesome-free/svgs/solid/plane-arrival.svg +1 -0
  1618. package/static/vendor/fontawesome-free/svgs/solid/plane-departure.svg +1 -0
  1619. package/static/vendor/fontawesome-free/svgs/solid/plane-slash.svg +1 -0
  1620. package/static/vendor/fontawesome-free/svgs/solid/plane.svg +1 -0
  1621. package/static/vendor/fontawesome-free/svgs/solid/play-circle.svg +1 -0
  1622. package/static/vendor/fontawesome-free/svgs/solid/play.svg +1 -0
  1623. package/static/vendor/fontawesome-free/svgs/solid/plug.svg +1 -0
  1624. package/static/vendor/fontawesome-free/svgs/solid/plus-circle.svg +1 -0
  1625. package/static/vendor/fontawesome-free/svgs/solid/plus-square.svg +1 -0
  1626. package/static/vendor/fontawesome-free/svgs/solid/plus.svg +1 -0
  1627. package/static/vendor/fontawesome-free/svgs/solid/podcast.svg +1 -0
  1628. package/static/vendor/fontawesome-free/svgs/solid/poll-h.svg +1 -0
  1629. package/static/vendor/fontawesome-free/svgs/solid/poll.svg +1 -0
  1630. package/static/vendor/fontawesome-free/svgs/solid/poo-storm.svg +1 -0
  1631. package/static/vendor/fontawesome-free/svgs/solid/poo.svg +1 -0
  1632. package/static/vendor/fontawesome-free/svgs/solid/poop.svg +1 -0
  1633. package/static/vendor/fontawesome-free/svgs/solid/portrait.svg +1 -0
  1634. package/static/vendor/fontawesome-free/svgs/solid/pound-sign.svg +1 -0
  1635. package/static/vendor/fontawesome-free/svgs/solid/power-off.svg +1 -0
  1636. package/static/vendor/fontawesome-free/svgs/solid/pray.svg +1 -0
  1637. package/static/vendor/fontawesome-free/svgs/solid/praying-hands.svg +1 -0
  1638. package/static/vendor/fontawesome-free/svgs/solid/prescription-bottle-alt.svg +1 -0
  1639. package/static/vendor/fontawesome-free/svgs/solid/prescription-bottle.svg +1 -0
  1640. package/static/vendor/fontawesome-free/svgs/solid/prescription.svg +1 -0
  1641. package/static/vendor/fontawesome-free/svgs/solid/print.svg +1 -0
  1642. package/static/vendor/fontawesome-free/svgs/solid/procedures.svg +1 -0
  1643. package/static/vendor/fontawesome-free/svgs/solid/project-diagram.svg +1 -0
  1644. package/static/vendor/fontawesome-free/svgs/solid/pump-medical.svg +1 -0
  1645. package/static/vendor/fontawesome-free/svgs/solid/pump-soap.svg +1 -0
  1646. package/static/vendor/fontawesome-free/svgs/solid/puzzle-piece.svg +1 -0
  1647. package/static/vendor/fontawesome-free/svgs/solid/qrcode.svg +1 -0
  1648. package/static/vendor/fontawesome-free/svgs/solid/question-circle.svg +1 -0
  1649. package/static/vendor/fontawesome-free/svgs/solid/question.svg +1 -0
  1650. package/static/vendor/fontawesome-free/svgs/solid/quidditch.svg +1 -0
  1651. package/static/vendor/fontawesome-free/svgs/solid/quote-left.svg +1 -0
  1652. package/static/vendor/fontawesome-free/svgs/solid/quote-right.svg +1 -0
  1653. package/static/vendor/fontawesome-free/svgs/solid/quran.svg +1 -0
  1654. package/static/vendor/fontawesome-free/svgs/solid/radiation-alt.svg +1 -0
  1655. package/static/vendor/fontawesome-free/svgs/solid/radiation.svg +1 -0
  1656. package/static/vendor/fontawesome-free/svgs/solid/rainbow.svg +1 -0
  1657. package/static/vendor/fontawesome-free/svgs/solid/random.svg +1 -0
  1658. package/static/vendor/fontawesome-free/svgs/solid/receipt.svg +1 -0
  1659. package/static/vendor/fontawesome-free/svgs/solid/record-vinyl.svg +1 -0
  1660. package/static/vendor/fontawesome-free/svgs/solid/recycle.svg +1 -0
  1661. package/static/vendor/fontawesome-free/svgs/solid/redo-alt.svg +1 -0
  1662. package/static/vendor/fontawesome-free/svgs/solid/redo.svg +1 -0
  1663. package/static/vendor/fontawesome-free/svgs/solid/registered.svg +1 -0
  1664. package/static/vendor/fontawesome-free/svgs/solid/remove-format.svg +1 -0
  1665. package/static/vendor/fontawesome-free/svgs/solid/reply-all.svg +1 -0
  1666. package/static/vendor/fontawesome-free/svgs/solid/reply.svg +1 -0
  1667. package/static/vendor/fontawesome-free/svgs/solid/republican.svg +1 -0
  1668. package/static/vendor/fontawesome-free/svgs/solid/restroom.svg +1 -0
  1669. package/static/vendor/fontawesome-free/svgs/solid/retweet.svg +1 -0
  1670. package/static/vendor/fontawesome-free/svgs/solid/ribbon.svg +1 -0
  1671. package/static/vendor/fontawesome-free/svgs/solid/ring.svg +1 -0
  1672. package/static/vendor/fontawesome-free/svgs/solid/road.svg +1 -0
  1673. package/static/vendor/fontawesome-free/svgs/solid/robot.svg +1 -0
  1674. package/static/vendor/fontawesome-free/svgs/solid/rocket.svg +1 -0
  1675. package/static/vendor/fontawesome-free/svgs/solid/route.svg +1 -0
  1676. package/static/vendor/fontawesome-free/svgs/solid/rss-square.svg +1 -0
  1677. package/static/vendor/fontawesome-free/svgs/solid/rss.svg +1 -0
  1678. package/static/vendor/fontawesome-free/svgs/solid/ruble-sign.svg +1 -0
  1679. package/static/vendor/fontawesome-free/svgs/solid/ruler-combined.svg +1 -0
  1680. package/static/vendor/fontawesome-free/svgs/solid/ruler-horizontal.svg +1 -0
  1681. package/static/vendor/fontawesome-free/svgs/solid/ruler-vertical.svg +1 -0
  1682. package/static/vendor/fontawesome-free/svgs/solid/ruler.svg +1 -0
  1683. package/static/vendor/fontawesome-free/svgs/solid/running.svg +1 -0
  1684. package/static/vendor/fontawesome-free/svgs/solid/rupee-sign.svg +1 -0
  1685. package/static/vendor/fontawesome-free/svgs/solid/sad-cry.svg +1 -0
  1686. package/static/vendor/fontawesome-free/svgs/solid/sad-tear.svg +1 -0
  1687. package/static/vendor/fontawesome-free/svgs/solid/satellite-dish.svg +1 -0
  1688. package/static/vendor/fontawesome-free/svgs/solid/satellite.svg +1 -0
  1689. package/static/vendor/fontawesome-free/svgs/solid/save.svg +1 -0
  1690. package/static/vendor/fontawesome-free/svgs/solid/school.svg +1 -0
  1691. package/static/vendor/fontawesome-free/svgs/solid/screwdriver.svg +1 -0
  1692. package/static/vendor/fontawesome-free/svgs/solid/scroll.svg +1 -0
  1693. package/static/vendor/fontawesome-free/svgs/solid/sd-card.svg +1 -0
  1694. package/static/vendor/fontawesome-free/svgs/solid/search-dollar.svg +1 -0
  1695. package/static/vendor/fontawesome-free/svgs/solid/search-location.svg +1 -0
  1696. package/static/vendor/fontawesome-free/svgs/solid/search-minus.svg +1 -0
  1697. package/static/vendor/fontawesome-free/svgs/solid/search-plus.svg +1 -0
  1698. package/static/vendor/fontawesome-free/svgs/solid/search.svg +1 -0
  1699. package/static/vendor/fontawesome-free/svgs/solid/seedling.svg +1 -0
  1700. package/static/vendor/fontawesome-free/svgs/solid/server.svg +1 -0
  1701. package/static/vendor/fontawesome-free/svgs/solid/shapes.svg +1 -0
  1702. package/static/vendor/fontawesome-free/svgs/solid/share-alt-square.svg +1 -0
  1703. package/static/vendor/fontawesome-free/svgs/solid/share-alt.svg +1 -0
  1704. package/static/vendor/fontawesome-free/svgs/solid/share-square.svg +1 -0
  1705. package/static/vendor/fontawesome-free/svgs/solid/share.svg +1 -0
  1706. package/static/vendor/fontawesome-free/svgs/solid/shekel-sign.svg +1 -0
  1707. package/static/vendor/fontawesome-free/svgs/solid/shield-alt.svg +1 -0
  1708. package/static/vendor/fontawesome-free/svgs/solid/shield-virus.svg +1 -0
  1709. package/static/vendor/fontawesome-free/svgs/solid/ship.svg +1 -0
  1710. package/static/vendor/fontawesome-free/svgs/solid/shipping-fast.svg +1 -0
  1711. package/static/vendor/fontawesome-free/svgs/solid/shoe-prints.svg +1 -0
  1712. package/static/vendor/fontawesome-free/svgs/solid/shopping-bag.svg +1 -0
  1713. package/static/vendor/fontawesome-free/svgs/solid/shopping-basket.svg +1 -0
  1714. package/static/vendor/fontawesome-free/svgs/solid/shopping-cart.svg +1 -0
  1715. package/static/vendor/fontawesome-free/svgs/solid/shower.svg +1 -0
  1716. package/static/vendor/fontawesome-free/svgs/solid/shuttle-van.svg +1 -0
  1717. package/static/vendor/fontawesome-free/svgs/solid/sign-in-alt.svg +1 -0
  1718. package/static/vendor/fontawesome-free/svgs/solid/sign-language.svg +1 -0
  1719. package/static/vendor/fontawesome-free/svgs/solid/sign-out-alt.svg +1 -0
  1720. package/static/vendor/fontawesome-free/svgs/solid/sign.svg +1 -0
  1721. package/static/vendor/fontawesome-free/svgs/solid/signal.svg +1 -0
  1722. package/static/vendor/fontawesome-free/svgs/solid/signature.svg +1 -0
  1723. package/static/vendor/fontawesome-free/svgs/solid/sim-card.svg +1 -0
  1724. package/static/vendor/fontawesome-free/svgs/solid/sink.svg +1 -0
  1725. package/static/vendor/fontawesome-free/svgs/solid/sitemap.svg +1 -0
  1726. package/static/vendor/fontawesome-free/svgs/solid/skating.svg +1 -0
  1727. package/static/vendor/fontawesome-free/svgs/solid/skiing-nordic.svg +1 -0
  1728. package/static/vendor/fontawesome-free/svgs/solid/skiing.svg +1 -0
  1729. package/static/vendor/fontawesome-free/svgs/solid/skull-crossbones.svg +1 -0
  1730. package/static/vendor/fontawesome-free/svgs/solid/skull.svg +1 -0
  1731. package/static/vendor/fontawesome-free/svgs/solid/slash.svg +1 -0
  1732. package/static/vendor/fontawesome-free/svgs/solid/sleigh.svg +1 -0
  1733. package/static/vendor/fontawesome-free/svgs/solid/sliders-h.svg +1 -0
  1734. package/static/vendor/fontawesome-free/svgs/solid/smile-beam.svg +1 -0
  1735. package/static/vendor/fontawesome-free/svgs/solid/smile-wink.svg +1 -0
  1736. package/static/vendor/fontawesome-free/svgs/solid/smile.svg +1 -0
  1737. package/static/vendor/fontawesome-free/svgs/solid/smog.svg +1 -0
  1738. package/static/vendor/fontawesome-free/svgs/solid/smoking-ban.svg +1 -0
  1739. package/static/vendor/fontawesome-free/svgs/solid/smoking.svg +1 -0
  1740. package/static/vendor/fontawesome-free/svgs/solid/sms.svg +1 -0
  1741. package/static/vendor/fontawesome-free/svgs/solid/snowboarding.svg +1 -0
  1742. package/static/vendor/fontawesome-free/svgs/solid/snowflake.svg +1 -0
  1743. package/static/vendor/fontawesome-free/svgs/solid/snowman.svg +1 -0
  1744. package/static/vendor/fontawesome-free/svgs/solid/snowplow.svg +1 -0
  1745. package/static/vendor/fontawesome-free/svgs/solid/soap.svg +1 -0
  1746. package/static/vendor/fontawesome-free/svgs/solid/socks.svg +1 -0
  1747. package/static/vendor/fontawesome-free/svgs/solid/solar-panel.svg +1 -0
  1748. package/static/vendor/fontawesome-free/svgs/solid/sort-alpha-down-alt.svg +1 -0
  1749. package/static/vendor/fontawesome-free/svgs/solid/sort-alpha-down.svg +1 -0
  1750. package/static/vendor/fontawesome-free/svgs/solid/sort-alpha-up-alt.svg +1 -0
  1751. package/static/vendor/fontawesome-free/svgs/solid/sort-alpha-up.svg +1 -0
  1752. package/static/vendor/fontawesome-free/svgs/solid/sort-amount-down-alt.svg +1 -0
  1753. package/static/vendor/fontawesome-free/svgs/solid/sort-amount-down.svg +1 -0
  1754. package/static/vendor/fontawesome-free/svgs/solid/sort-amount-up-alt.svg +1 -0
  1755. package/static/vendor/fontawesome-free/svgs/solid/sort-amount-up.svg +1 -0
  1756. package/static/vendor/fontawesome-free/svgs/solid/sort-down.svg +1 -0
  1757. package/static/vendor/fontawesome-free/svgs/solid/sort-numeric-down-alt.svg +1 -0
  1758. package/static/vendor/fontawesome-free/svgs/solid/sort-numeric-down.svg +1 -0
  1759. package/static/vendor/fontawesome-free/svgs/solid/sort-numeric-up-alt.svg +1 -0
  1760. package/static/vendor/fontawesome-free/svgs/solid/sort-numeric-up.svg +1 -0
  1761. package/static/vendor/fontawesome-free/svgs/solid/sort-up.svg +1 -0
  1762. package/static/vendor/fontawesome-free/svgs/solid/sort.svg +1 -0
  1763. package/static/vendor/fontawesome-free/svgs/solid/spa.svg +1 -0
  1764. package/static/vendor/fontawesome-free/svgs/solid/space-shuttle.svg +1 -0
  1765. package/static/vendor/fontawesome-free/svgs/solid/spell-check.svg +1 -0
  1766. package/static/vendor/fontawesome-free/svgs/solid/spider.svg +1 -0
  1767. package/static/vendor/fontawesome-free/svgs/solid/spinner.svg +1 -0
  1768. package/static/vendor/fontawesome-free/svgs/solid/splotch.svg +1 -0
  1769. package/static/vendor/fontawesome-free/svgs/solid/spray-can.svg +1 -0
  1770. package/static/vendor/fontawesome-free/svgs/solid/square-full.svg +1 -0
  1771. package/static/vendor/fontawesome-free/svgs/solid/square-root-alt.svg +1 -0
  1772. package/static/vendor/fontawesome-free/svgs/solid/square.svg +1 -0
  1773. package/static/vendor/fontawesome-free/svgs/solid/stamp.svg +1 -0
  1774. package/static/vendor/fontawesome-free/svgs/solid/star-and-crescent.svg +1 -0
  1775. package/static/vendor/fontawesome-free/svgs/solid/star-half-alt.svg +1 -0
  1776. package/static/vendor/fontawesome-free/svgs/solid/star-half.svg +1 -0
  1777. package/static/vendor/fontawesome-free/svgs/solid/star-of-david.svg +1 -0
  1778. package/static/vendor/fontawesome-free/svgs/solid/star-of-life.svg +1 -0
  1779. package/static/vendor/fontawesome-free/svgs/solid/star.svg +1 -0
  1780. package/static/vendor/fontawesome-free/svgs/solid/step-backward.svg +1 -0
  1781. package/static/vendor/fontawesome-free/svgs/solid/step-forward.svg +1 -0
  1782. package/static/vendor/fontawesome-free/svgs/solid/stethoscope.svg +1 -0
  1783. package/static/vendor/fontawesome-free/svgs/solid/sticky-note.svg +1 -0
  1784. package/static/vendor/fontawesome-free/svgs/solid/stop-circle.svg +1 -0
  1785. package/static/vendor/fontawesome-free/svgs/solid/stop.svg +1 -0
  1786. package/static/vendor/fontawesome-free/svgs/solid/stopwatch-20.svg +1 -0
  1787. package/static/vendor/fontawesome-free/svgs/solid/stopwatch.svg +1 -0
  1788. package/static/vendor/fontawesome-free/svgs/solid/store-alt-slash.svg +1 -0
  1789. package/static/vendor/fontawesome-free/svgs/solid/store-alt.svg +1 -0
  1790. package/static/vendor/fontawesome-free/svgs/solid/store-slash.svg +1 -0
  1791. package/static/vendor/fontawesome-free/svgs/solid/store.svg +1 -0
  1792. package/static/vendor/fontawesome-free/svgs/solid/stream.svg +1 -0
  1793. package/static/vendor/fontawesome-free/svgs/solid/street-view.svg +1 -0
  1794. package/static/vendor/fontawesome-free/svgs/solid/strikethrough.svg +1 -0
  1795. package/static/vendor/fontawesome-free/svgs/solid/stroopwafel.svg +1 -0
  1796. package/static/vendor/fontawesome-free/svgs/solid/subscript.svg +1 -0
  1797. package/static/vendor/fontawesome-free/svgs/solid/subway.svg +1 -0
  1798. package/static/vendor/fontawesome-free/svgs/solid/suitcase-rolling.svg +1 -0
  1799. package/static/vendor/fontawesome-free/svgs/solid/suitcase.svg +1 -0
  1800. package/static/vendor/fontawesome-free/svgs/solid/sun.svg +1 -0
  1801. package/static/vendor/fontawesome-free/svgs/solid/superscript.svg +1 -0
  1802. package/static/vendor/fontawesome-free/svgs/solid/surprise.svg +1 -0
  1803. package/static/vendor/fontawesome-free/svgs/solid/swatchbook.svg +1 -0
  1804. package/static/vendor/fontawesome-free/svgs/solid/swimmer.svg +1 -0
  1805. package/static/vendor/fontawesome-free/svgs/solid/swimming-pool.svg +1 -0
  1806. package/static/vendor/fontawesome-free/svgs/solid/synagogue.svg +1 -0
  1807. package/static/vendor/fontawesome-free/svgs/solid/sync-alt.svg +1 -0
  1808. package/static/vendor/fontawesome-free/svgs/solid/sync.svg +1 -0
  1809. package/static/vendor/fontawesome-free/svgs/solid/syringe.svg +1 -0
  1810. package/static/vendor/fontawesome-free/svgs/solid/table-tennis.svg +1 -0
  1811. package/static/vendor/fontawesome-free/svgs/solid/table.svg +1 -0
  1812. package/static/vendor/fontawesome-free/svgs/solid/tablet-alt.svg +1 -0
  1813. package/static/vendor/fontawesome-free/svgs/solid/tablet.svg +1 -0
  1814. package/static/vendor/fontawesome-free/svgs/solid/tablets.svg +1 -0
  1815. package/static/vendor/fontawesome-free/svgs/solid/tachometer-alt.svg +1 -0
  1816. package/static/vendor/fontawesome-free/svgs/solid/tag.svg +1 -0
  1817. package/static/vendor/fontawesome-free/svgs/solid/tags.svg +1 -0
  1818. package/static/vendor/fontawesome-free/svgs/solid/tape.svg +1 -0
  1819. package/static/vendor/fontawesome-free/svgs/solid/tasks.svg +1 -0
  1820. package/static/vendor/fontawesome-free/svgs/solid/taxi.svg +1 -0
  1821. package/static/vendor/fontawesome-free/svgs/solid/teeth-open.svg +1 -0
  1822. package/static/vendor/fontawesome-free/svgs/solid/teeth.svg +1 -0
  1823. package/static/vendor/fontawesome-free/svgs/solid/temperature-high.svg +1 -0
  1824. package/static/vendor/fontawesome-free/svgs/solid/temperature-low.svg +1 -0
  1825. package/static/vendor/fontawesome-free/svgs/solid/tenge.svg +1 -0
  1826. package/static/vendor/fontawesome-free/svgs/solid/terminal.svg +1 -0
  1827. package/static/vendor/fontawesome-free/svgs/solid/text-height.svg +1 -0
  1828. package/static/vendor/fontawesome-free/svgs/solid/text-width.svg +1 -0
  1829. package/static/vendor/fontawesome-free/svgs/solid/th-large.svg +1 -0
  1830. package/static/vendor/fontawesome-free/svgs/solid/th-list.svg +1 -0
  1831. package/static/vendor/fontawesome-free/svgs/solid/th.svg +1 -0
  1832. package/static/vendor/fontawesome-free/svgs/solid/theater-masks.svg +1 -0
  1833. package/static/vendor/fontawesome-free/svgs/solid/thermometer-empty.svg +1 -0
  1834. package/static/vendor/fontawesome-free/svgs/solid/thermometer-full.svg +1 -0
  1835. package/static/vendor/fontawesome-free/svgs/solid/thermometer-half.svg +1 -0
  1836. package/static/vendor/fontawesome-free/svgs/solid/thermometer-quarter.svg +1 -0
  1837. package/static/vendor/fontawesome-free/svgs/solid/thermometer-three-quarters.svg +1 -0
  1838. package/static/vendor/fontawesome-free/svgs/solid/thermometer.svg +1 -0
  1839. package/static/vendor/fontawesome-free/svgs/solid/thumbs-down.svg +1 -0
  1840. package/static/vendor/fontawesome-free/svgs/solid/thumbs-up.svg +1 -0
  1841. package/static/vendor/fontawesome-free/svgs/solid/thumbtack.svg +1 -0
  1842. package/static/vendor/fontawesome-free/svgs/solid/ticket-alt.svg +1 -0
  1843. package/static/vendor/fontawesome-free/svgs/solid/times-circle.svg +1 -0
  1844. package/static/vendor/fontawesome-free/svgs/solid/times.svg +1 -0
  1845. package/static/vendor/fontawesome-free/svgs/solid/tint-slash.svg +1 -0
  1846. package/static/vendor/fontawesome-free/svgs/solid/tint.svg +1 -0
  1847. package/static/vendor/fontawesome-free/svgs/solid/tired.svg +1 -0
  1848. package/static/vendor/fontawesome-free/svgs/solid/toggle-off.svg +1 -0
  1849. package/static/vendor/fontawesome-free/svgs/solid/toggle-on.svg +1 -0
  1850. package/static/vendor/fontawesome-free/svgs/solid/toilet-paper-slash.svg +1 -0
  1851. package/static/vendor/fontawesome-free/svgs/solid/toilet-paper.svg +1 -0
  1852. package/static/vendor/fontawesome-free/svgs/solid/toilet.svg +1 -0
  1853. package/static/vendor/fontawesome-free/svgs/solid/toolbox.svg +1 -0
  1854. package/static/vendor/fontawesome-free/svgs/solid/tools.svg +1 -0
  1855. package/static/vendor/fontawesome-free/svgs/solid/tooth.svg +1 -0
  1856. package/static/vendor/fontawesome-free/svgs/solid/torah.svg +1 -0
  1857. package/static/vendor/fontawesome-free/svgs/solid/torii-gate.svg +1 -0
  1858. package/static/vendor/fontawesome-free/svgs/solid/tractor.svg +1 -0
  1859. package/static/vendor/fontawesome-free/svgs/solid/trademark.svg +1 -0
  1860. package/static/vendor/fontawesome-free/svgs/solid/traffic-light.svg +1 -0
  1861. package/static/vendor/fontawesome-free/svgs/solid/trailer.svg +1 -0
  1862. package/static/vendor/fontawesome-free/svgs/solid/train.svg +1 -0
  1863. package/static/vendor/fontawesome-free/svgs/solid/tram.svg +1 -0
  1864. package/static/vendor/fontawesome-free/svgs/solid/transgender-alt.svg +1 -0
  1865. package/static/vendor/fontawesome-free/svgs/solid/transgender.svg +1 -0
  1866. package/static/vendor/fontawesome-free/svgs/solid/trash-alt.svg +1 -0
  1867. package/static/vendor/fontawesome-free/svgs/solid/trash-restore-alt.svg +1 -0
  1868. package/static/vendor/fontawesome-free/svgs/solid/trash-restore.svg +1 -0
  1869. package/static/vendor/fontawesome-free/svgs/solid/trash.svg +1 -0
  1870. package/static/vendor/fontawesome-free/svgs/solid/tree.svg +1 -0
  1871. package/static/vendor/fontawesome-free/svgs/solid/trophy.svg +1 -0
  1872. package/static/vendor/fontawesome-free/svgs/solid/truck-loading.svg +1 -0
  1873. package/static/vendor/fontawesome-free/svgs/solid/truck-monster.svg +1 -0
  1874. package/static/vendor/fontawesome-free/svgs/solid/truck-moving.svg +1 -0
  1875. package/static/vendor/fontawesome-free/svgs/solid/truck-pickup.svg +1 -0
  1876. package/static/vendor/fontawesome-free/svgs/solid/truck.svg +1 -0
  1877. package/static/vendor/fontawesome-free/svgs/solid/tshirt.svg +1 -0
  1878. package/static/vendor/fontawesome-free/svgs/solid/tty.svg +1 -0
  1879. package/static/vendor/fontawesome-free/svgs/solid/tv.svg +1 -0
  1880. package/static/vendor/fontawesome-free/svgs/solid/umbrella-beach.svg +1 -0
  1881. package/static/vendor/fontawesome-free/svgs/solid/umbrella.svg +1 -0
  1882. package/static/vendor/fontawesome-free/svgs/solid/underline.svg +1 -0
  1883. package/static/vendor/fontawesome-free/svgs/solid/undo-alt.svg +1 -0
  1884. package/static/vendor/fontawesome-free/svgs/solid/undo.svg +1 -0
  1885. package/static/vendor/fontawesome-free/svgs/solid/universal-access.svg +1 -0
  1886. package/static/vendor/fontawesome-free/svgs/solid/university.svg +1 -0
  1887. package/static/vendor/fontawesome-free/svgs/solid/unlink.svg +1 -0
  1888. package/static/vendor/fontawesome-free/svgs/solid/unlock-alt.svg +1 -0
  1889. package/static/vendor/fontawesome-free/svgs/solid/unlock.svg +1 -0
  1890. package/static/vendor/fontawesome-free/svgs/solid/upload.svg +1 -0
  1891. package/static/vendor/fontawesome-free/svgs/solid/user-alt-slash.svg +1 -0
  1892. package/static/vendor/fontawesome-free/svgs/solid/user-alt.svg +1 -0
  1893. package/static/vendor/fontawesome-free/svgs/solid/user-astronaut.svg +1 -0
  1894. package/static/vendor/fontawesome-free/svgs/solid/user-check.svg +1 -0
  1895. package/static/vendor/fontawesome-free/svgs/solid/user-circle.svg +1 -0
  1896. package/static/vendor/fontawesome-free/svgs/solid/user-clock.svg +1 -0
  1897. package/static/vendor/fontawesome-free/svgs/solid/user-cog.svg +1 -0
  1898. package/static/vendor/fontawesome-free/svgs/solid/user-edit.svg +1 -0
  1899. package/static/vendor/fontawesome-free/svgs/solid/user-friends.svg +1 -0
  1900. package/static/vendor/fontawesome-free/svgs/solid/user-graduate.svg +1 -0
  1901. package/static/vendor/fontawesome-free/svgs/solid/user-injured.svg +1 -0
  1902. package/static/vendor/fontawesome-free/svgs/solid/user-lock.svg +1 -0
  1903. package/static/vendor/fontawesome-free/svgs/solid/user-md.svg +1 -0
  1904. package/static/vendor/fontawesome-free/svgs/solid/user-minus.svg +1 -0
  1905. package/static/vendor/fontawesome-free/svgs/solid/user-ninja.svg +1 -0
  1906. package/static/vendor/fontawesome-free/svgs/solid/user-nurse.svg +1 -0
  1907. package/static/vendor/fontawesome-free/svgs/solid/user-plus.svg +1 -0
  1908. package/static/vendor/fontawesome-free/svgs/solid/user-secret.svg +1 -0
  1909. package/static/vendor/fontawesome-free/svgs/solid/user-shield.svg +1 -0
  1910. package/static/vendor/fontawesome-free/svgs/solid/user-slash.svg +1 -0
  1911. package/static/vendor/fontawesome-free/svgs/solid/user-tag.svg +1 -0
  1912. package/static/vendor/fontawesome-free/svgs/solid/user-tie.svg +1 -0
  1913. package/static/vendor/fontawesome-free/svgs/solid/user-times.svg +1 -0
  1914. package/static/vendor/fontawesome-free/svgs/solid/user.svg +1 -0
  1915. package/static/vendor/fontawesome-free/svgs/solid/users-cog.svg +1 -0
  1916. package/static/vendor/fontawesome-free/svgs/solid/users-slash.svg +1 -0
  1917. package/static/vendor/fontawesome-free/svgs/solid/users.svg +1 -0
  1918. package/static/vendor/fontawesome-free/svgs/solid/utensil-spoon.svg +1 -0
  1919. package/static/vendor/fontawesome-free/svgs/solid/utensils.svg +1 -0
  1920. package/static/vendor/fontawesome-free/svgs/solid/vector-square.svg +1 -0
  1921. package/static/vendor/fontawesome-free/svgs/solid/venus-double.svg +1 -0
  1922. package/static/vendor/fontawesome-free/svgs/solid/venus-mars.svg +1 -0
  1923. package/static/vendor/fontawesome-free/svgs/solid/venus.svg +1 -0
  1924. package/static/vendor/fontawesome-free/svgs/solid/vest-patches.svg +1 -0
  1925. package/static/vendor/fontawesome-free/svgs/solid/vest.svg +1 -0
  1926. package/static/vendor/fontawesome-free/svgs/solid/vial.svg +1 -0
  1927. package/static/vendor/fontawesome-free/svgs/solid/vials.svg +1 -0
  1928. package/static/vendor/fontawesome-free/svgs/solid/video-slash.svg +1 -0
  1929. package/static/vendor/fontawesome-free/svgs/solid/video.svg +1 -0
  1930. package/static/vendor/fontawesome-free/svgs/solid/vihara.svg +1 -0
  1931. package/static/vendor/fontawesome-free/svgs/solid/virus-slash.svg +1 -0
  1932. package/static/vendor/fontawesome-free/svgs/solid/virus.svg +1 -0
  1933. package/static/vendor/fontawesome-free/svgs/solid/viruses.svg +1 -0
  1934. package/static/vendor/fontawesome-free/svgs/solid/voicemail.svg +1 -0
  1935. package/static/vendor/fontawesome-free/svgs/solid/volleyball-ball.svg +1 -0
  1936. package/static/vendor/fontawesome-free/svgs/solid/volume-down.svg +1 -0
  1937. package/static/vendor/fontawesome-free/svgs/solid/volume-mute.svg +1 -0
  1938. package/static/vendor/fontawesome-free/svgs/solid/volume-off.svg +1 -0
  1939. package/static/vendor/fontawesome-free/svgs/solid/volume-up.svg +1 -0
  1940. package/static/vendor/fontawesome-free/svgs/solid/vote-yea.svg +1 -0
  1941. package/static/vendor/fontawesome-free/svgs/solid/vr-cardboard.svg +1 -0
  1942. package/static/vendor/fontawesome-free/svgs/solid/walking.svg +1 -0
  1943. package/static/vendor/fontawesome-free/svgs/solid/wallet.svg +1 -0
  1944. package/static/vendor/fontawesome-free/svgs/solid/warehouse.svg +1 -0
  1945. package/static/vendor/fontawesome-free/svgs/solid/water.svg +1 -0
  1946. package/static/vendor/fontawesome-free/svgs/solid/wave-square.svg +1 -0
  1947. package/static/vendor/fontawesome-free/svgs/solid/weight-hanging.svg +1 -0
  1948. package/static/vendor/fontawesome-free/svgs/solid/weight.svg +1 -0
  1949. package/static/vendor/fontawesome-free/svgs/solid/wheelchair.svg +1 -0
  1950. package/static/vendor/fontawesome-free/svgs/solid/wifi.svg +1 -0
  1951. package/static/vendor/fontawesome-free/svgs/solid/wind.svg +1 -0
  1952. package/static/vendor/fontawesome-free/svgs/solid/window-close.svg +1 -0
  1953. package/static/vendor/fontawesome-free/svgs/solid/window-maximize.svg +1 -0
  1954. package/static/vendor/fontawesome-free/svgs/solid/window-minimize.svg +1 -0
  1955. package/static/vendor/fontawesome-free/svgs/solid/window-restore.svg +1 -0
  1956. package/static/vendor/fontawesome-free/svgs/solid/wine-bottle.svg +1 -0
  1957. package/static/vendor/fontawesome-free/svgs/solid/wine-glass-alt.svg +1 -0
  1958. package/static/vendor/fontawesome-free/svgs/solid/wine-glass.svg +1 -0
  1959. package/static/vendor/fontawesome-free/svgs/solid/won-sign.svg +1 -0
  1960. package/static/vendor/fontawesome-free/svgs/solid/wrench.svg +1 -0
  1961. package/static/vendor/fontawesome-free/svgs/solid/x-ray.svg +1 -0
  1962. package/static/vendor/fontawesome-free/svgs/solid/yen-sign.svg +1 -0
  1963. package/static/vendor/fontawesome-free/svgs/solid/yin-yang.svg +1 -0
  1964. package/static/vendor/fontawesome-free/webfonts/fa-brands-400.eot +0 -0
  1965. package/static/vendor/fontawesome-free/webfonts/fa-brands-400.svg +3717 -0
  1966. package/static/vendor/fontawesome-free/webfonts/fa-brands-400.ttf +0 -0
  1967. package/static/vendor/fontawesome-free/webfonts/fa-brands-400.woff +0 -0
  1968. package/static/vendor/fontawesome-free/webfonts/fa-brands-400.woff2 +0 -0
  1969. package/static/vendor/fontawesome-free/webfonts/fa-regular-400.eot +0 -0
  1970. package/static/vendor/fontawesome-free/webfonts/fa-regular-400.svg +801 -0
  1971. package/static/vendor/fontawesome-free/webfonts/fa-regular-400.ttf +0 -0
  1972. package/static/vendor/fontawesome-free/webfonts/fa-regular-400.woff +0 -0
  1973. package/static/vendor/fontawesome-free/webfonts/fa-regular-400.woff2 +0 -0
  1974. package/static/vendor/fontawesome-free/webfonts/fa-solid-900.eot +0 -0
  1975. package/static/vendor/fontawesome-free/webfonts/fa-solid-900.svg +5034 -0
  1976. package/static/vendor/fontawesome-free/webfonts/fa-solid-900.ttf +0 -0
  1977. package/static/vendor/fontawesome-free/webfonts/fa-solid-900.woff +0 -0
  1978. package/static/vendor/fontawesome-free/webfonts/fa-solid-900.woff2 +0 -0
  1979. package/static/vendor/handlebars/handlebars.min-v4.7.7.js +29 -0
  1980. package/static/vendor/jquery/jquery.js +10881 -0
  1981. package/static/vendor/jquery/jquery.min.js +2 -0
  1982. package/static/vendor/jquery/jquery.min.map +1 -0
  1983. package/static/vendor/jquery/jquery.slim.js +8782 -0
  1984. package/static/vendor/jquery/jquery.slim.min.js +2 -0
  1985. package/static/vendor/jquery/jquery.slim.min.map +1 -0
  1986. package/static/vendor/jquery-easing/jquery.easing.min.js +1 -0
  1987. package/systemd/emailengine.service +11 -3
  1988. package/systemd/nginx-proxy.conf +1 -1
  1989. package/test/api-test.js +899 -0
  1990. package/test/bounce-test.js +151 -0
  1991. package/test/fixtures/bounces/163.eml +2521 -0
  1992. package/test/fixtures/bounces/fastmail.eml +242 -0
  1993. package/test/fixtures/bounces/gmail.eml +252 -0
  1994. package/test/fixtures/bounces/hotmail.eml +655 -0
  1995. package/test/fixtures/bounces/mailru.eml +121 -0
  1996. package/test/fixtures/bounces/outlook.eml +1107 -0
  1997. package/test/fixtures/bounces/postfix.eml +101 -0
  1998. package/test/fixtures/bounces/rambler.eml +116 -0
  1999. package/test/fixtures/bounces/workmail.eml +142 -0
  2000. package/test/fixtures/bounces/yahoo.eml +139 -0
  2001. package/test/fixtures/bounces/zoho.eml +83 -0
  2002. package/test/fixtures/bounces/zonemta.eml +100 -0
  2003. package/test/oauth2-apps-test.js +301 -0
  2004. package/test/sendonly-test.js +160 -0
  2005. package/test/test-config.js +34 -0
  2006. package/test/webhooks-server.js +39 -0
  2007. package/translations/README.md +16 -0
  2008. package/translations/de.mo +0 -0
  2009. package/translations/de.po +335 -0
  2010. package/translations/en.mo +0 -0
  2011. package/translations/en.po +310 -0
  2012. package/translations/et.mo +0 -0
  2013. package/translations/et.po +331 -0
  2014. package/translations/fr.mo +0 -0
  2015. package/translations/fr.po +333 -0
  2016. package/translations/ja.mo +0 -0
  2017. package/translations/ja.po +322 -0
  2018. package/translations/locales.json +43 -0
  2019. package/translations/messages.pot +323 -0
  2020. package/translations/nl.mo +0 -0
  2021. package/translations/nl.po +325 -0
  2022. package/translations/pl.mo +0 -0
  2023. package/translations/pl.po +328 -0
  2024. package/update-info.sh +10 -0
  2025. package/views/account/login.hbs +54 -0
  2026. package/views/account/password.hbs +88 -0
  2027. package/views/account/security.hbs +269 -0
  2028. package/views/account/totp.hbs +30 -0
  2029. package/views/accounts/account.hbs +1254 -0
  2030. package/views/accounts/browse.hbs +102 -0
  2031. package/views/accounts/edit.hbs +332 -0
  2032. package/views/accounts/index.hbs +143 -0
  2033. package/views/accounts/register/imap-server.hbs +507 -0
  2034. package/views/accounts/register/imap.hbs +56 -0
  2035. package/views/accounts/register/index.hbs +52 -0
  2036. package/views/arena/index.hbs +4 -0
  2037. package/views/config/ai.hbs +820 -0
  2038. package/views/config/document-store/chat.hbs +362 -0
  2039. package/views/config/document-store/index.hbs +231 -0
  2040. package/views/config/document-store/mappings/index.hbs +116 -0
  2041. package/views/config/document-store/mappings/new.hbs +95 -0
  2042. package/views/config/document-store/pre-processing/index.hbs +459 -0
  2043. package/views/config/imap-proxy.hbs +479 -0
  2044. package/views/config/license.hbs +256 -0
  2045. package/views/config/logging.hbs +61 -0
  2046. package/views/config/network.hbs +334 -0
  2047. package/views/config/oauth/app.hbs +309 -0
  2048. package/views/config/oauth/edit.hbs +92 -0
  2049. package/views/config/oauth/index.hbs +150 -0
  2050. package/views/config/oauth/new.hbs +90 -0
  2051. package/views/config/oauth.hbs +354 -0
  2052. package/views/config/service-preview.hbs +14 -0
  2053. package/views/config/service.hbs +718 -0
  2054. package/views/config/smtp.hbs +525 -0
  2055. package/views/config/webhooks.hbs +404 -0
  2056. package/views/dashboard.hbs +315 -0
  2057. package/views/error.hbs +6 -1
  2058. package/views/gateways/edit.hbs +52 -0
  2059. package/views/gateways/gateway.hbs +120 -0
  2060. package/views/gateways/index.hbs +152 -0
  2061. package/views/gateways/new.hbs +61 -0
  2062. package/views/index.hbs +21 -0
  2063. package/views/internals/index.hbs +170 -0
  2064. package/views/internals/thread.hbs +143 -0
  2065. package/views/layout/app.hbs +516 -0
  2066. package/views/layout/login.hbs +78 -0
  2067. package/views/layout/main.hbs +67 -0
  2068. package/views/layout/public.hbs +90 -0
  2069. package/views/legal.hbs +83 -0
  2070. package/views/license.hbs +5 -0
  2071. package/views/partials/accounts_header.hbs +6 -0
  2072. package/views/partials/add_account_modal.hbs +60 -0
  2073. package/views/partials/address_list.hbs +37 -0
  2074. package/views/partials/alerts.hbs +33 -0
  2075. package/views/partials/document_store_header.hbs +52 -0
  2076. package/views/partials/editor_scope_info.hbs +10 -0
  2077. package/views/partials/gateway_form.hbs +65 -0
  2078. package/views/partials/gateway_js.hbs +90 -0
  2079. package/views/partials/gateways_header.hbs +6 -0
  2080. package/views/partials/oauth_config_header.hbs +10 -0
  2081. package/views/partials/oauth_form.hbs +1204 -0
  2082. package/views/partials/scope_info.hbs +134 -0
  2083. package/views/partials/security_header.hbs +11 -0
  2084. package/views/partials/side_menu.hbs +114 -0
  2085. package/views/partials/template_form.hbs +121 -0
  2086. package/views/partials/templates_header.hbs +6 -0
  2087. package/views/partials/test_send.hbs +327 -0
  2088. package/views/partials/tokens_header.hbs +6 -0
  2089. package/views/partials/webhook_form.hbs +151 -0
  2090. package/views/partials/webhooks_editor_functions.hbs +372 -0
  2091. package/views/partials/webhooks_header.hbs +6 -0
  2092. package/views/redirect.hbs +1 -0
  2093. package/views/swagger/index.hbs +76 -0
  2094. package/views/templates/edit.hbs +87 -0
  2095. package/views/templates/index.hbs +208 -0
  2096. package/views/templates/new.hbs +85 -0
  2097. package/views/templates/template.hbs +423 -0
  2098. package/views/tokens/index.hbs +207 -0
  2099. package/views/tokens/new.hbs +230 -0
  2100. package/views/unsubscribe.hbs +93 -0
  2101. package/views/upgrade.hbs +56 -0
  2102. package/views/webhooks/edit.hbs +31 -0
  2103. package/views/webhooks/index.hbs +144 -0
  2104. package/views/webhooks/new.hbs +27 -0
  2105. package/views/webhooks/webhook.hbs +265 -0
  2106. package/winconf.js +93 -0
  2107. package/workers/api.js +8246 -1256
  2108. package/workers/documents.js +1120 -0
  2109. package/workers/imap-proxy.js +91 -0
  2110. package/workers/imap.js +552 -161
  2111. package/workers/smtp.js +355 -82
  2112. package/workers/submit.js +319 -54
  2113. package/workers/webhooks.js +542 -80
  2114. package/.eslintrc +0 -14
  2115. package/.github/FUNDING.yml +0 -4
  2116. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -38
  2117. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
  2118. package/LICENSE.txt +0 -661
  2119. package/examples/api.md +0 -137
  2120. package/lib/connection.js +0 -1769
  2121. package/lib/lua/z-push.lua +0 -14
  2122. package/lib/mailbox.js +0 -1546
  2123. package/license-report-config.json +0 -3
  2124. package/licenses.txt +0 -37
  2125. package/static/bootstrap-4.6.0-dist/css/bootstrap-grid.css.map +0 -1
  2126. package/static/bootstrap-4.6.0-dist/css/bootstrap-reboot.css.map +0 -1
  2127. package/static/bootstrap-4.6.0-dist/css/bootstrap-reboot.min.css.map +0 -1
  2128. package/static/bootstrap-4.6.0-dist/css/bootstrap.css.map +0 -1
  2129. package/static/bootstrap-4.6.0-dist/css/bootstrap.min.css +0 -7
  2130. package/static/bootstrap-4.6.0-dist/css/bootstrap.min.css.map +0 -1
  2131. package/static/bootstrap-4.6.0-dist/js/bootstrap.bundle.js +0 -7045
  2132. package/static/bootstrap-4.6.0-dist/js/bootstrap.bundle.js.map +0 -1
  2133. package/static/bootstrap-4.6.0-dist/js/bootstrap.bundle.min.js +0 -7
  2134. package/static/bootstrap-4.6.0-dist/js/bootstrap.bundle.min.js.map +0 -1
  2135. package/static/bootstrap-4.6.0-dist/js/bootstrap.js.map +0 -1
  2136. package/static/bootstrap-4.6.0-dist/js/bootstrap.min.js +0 -7
  2137. package/static/bootstrap-4.6.0-dist/js/bootstrap.min.js.map +0 -1
  2138. package/static/js/emailengine.js +0 -581
  2139. package/workers/arena.js +0 -89
@@ -0,0 +1,2628 @@
1
+ 'use strict';
2
+
3
+ const { parentPort } = require('worker_threads');
4
+ const { ImapFlow } = require('imapflow');
5
+ const { Mailbox } = require('./imap/mailbox');
6
+ const logger = require('../logger');
7
+ const packageData = require('../../package.json');
8
+ const { backOff } = require('exponential-backoff');
9
+ const msgpack = require('msgpack5')();
10
+
11
+ const { oauth2ProviderData } = require('../oauth2-apps');
12
+ const { BaseClient } = require('./base-client');
13
+ const { oauth2Apps } = require('../oauth2-apps');
14
+
15
+ const { Subconnection } = require('./imap/subconnection');
16
+
17
+ const {
18
+ getLocalAddress,
19
+ normalizePath,
20
+ resolveCredentials,
21
+ emitChangeEvent,
22
+ getByteSize,
23
+ getBoolean,
24
+ readEnvValue,
25
+ validUidValidity,
26
+ getDuration,
27
+ LRUCache
28
+ } = require('../tools');
29
+
30
+ // Time to wait between mailbox resync operations (15 minutes)
31
+ const RESYNC_DELAY = 15 * 60;
32
+ // TTL for ensuring main mailbox selection after operations (5 seconds)
33
+ const ENSURE_MAIN_TTL = 5 * 1000;
34
+
35
+ const { AUTH_ERROR_NOTIFY, AUTH_SUCCESS_NOTIFY, CONNECT_ERROR_NOTIFY, DEFAULT_DOWNLOAD_CHUNK_SIZE, MAX_BACKOFF_DELAY, TLS_DEFAULTS } = require('../consts');
36
+
37
+ // Configuration for download operations - chunk size for streaming attachments/messages
38
+ const DOWNLOAD_CHUNK_SIZE = getByteSize(readEnvValue('EENGINE_CHUNK_SIZE')) || DEFAULT_DOWNLOAD_CHUNK_SIZE;
39
+ // Flag to disable IMAP compression (COMPRESS extension) if needed for debugging or compatibility
40
+ const DISABLE_IMAP_COMPRESSION = getBoolean(readEnvValue('EENGINE_DISABLE_COMPRESSION'));
41
+ // Custom socket timeout for IMAP connections
42
+ const IMAP_SOCKET_TIMEOUT = getDuration(readEnvValue('EENGINE_IMAP_SOCKET_TIMEOUT'));
43
+
44
+ // Gmail API configuration
45
+ const GMAIL_API_BASE = 'https://gmail.googleapis.com';
46
+
47
+ logger.trace({ msg: 'Worker configuration', DOWNLOAD_CHUNK_SIZE, DISABLE_IMAP_COMPRESSION, IMAP_SOCKET_TIMEOUT });
48
+
49
+ const settings = require('../settings');
50
+ const { redis } = require('../db');
51
+
52
+ /**
53
+ * Sends metrics data to the parent process for monitoring and analytics
54
+ * @param {Object} meta - Metadata object
55
+ * @param {Object} logger - Logger instance
56
+ * @param {string} key - Metric key
57
+ * @param {string} method - Metric method (e.g., 'inc', 'dec')
58
+ * @param {...any} args - Additional arguments for the metric
59
+ */
60
+ async function metricsMeta(meta, logger, key, method, ...args) {
61
+ try {
62
+ parentPort.postMessage({
63
+ cmd: 'metrics',
64
+ key,
65
+ method,
66
+ args,
67
+ meta: meta || {}
68
+ });
69
+ } catch (err) {
70
+ logger.error({ msg: 'Failed to post metrics to parent', err });
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Main IMAP client class that handles all IMAP operations for an email account
76
+ * Extends BaseClient for common email client functionality
77
+ */
78
+ class IMAPClient extends BaseClient {
79
+ constructor(account, options) {
80
+ options = options || {};
81
+ super(account, options);
82
+
83
+ // Connection state flags
84
+ this.isClosing = false;
85
+ this.isClosed = false;
86
+
87
+ // Base IMAP configuration that will be merged with account-specific settings
88
+ this.imapConfig = {
89
+ // Set emitLogs to true if you want to get all the log entries as objects from the IMAP module
90
+ logger: this.mainLogger.child({
91
+ sub: 'imap-connection',
92
+ channel: 'primary'
93
+ }),
94
+ clientInfo: {
95
+ name: packageData.name,
96
+ version: packageData.version,
97
+ vendor: (packageData.author && packageData.author.name) || packageData.author,
98
+ 'support-url': (packageData.bugs && packageData.bugs.url) || packageData.bugs
99
+ },
100
+ logRaw: this.options.logRaw
101
+ };
102
+
103
+ // Map of normalized mailbox paths to Mailbox instances
104
+ this.mailboxes = new Map();
105
+
106
+ // Timer for handling untagged EXPUNGE responses
107
+ this.untaggedExpungeTimer = false;
108
+
109
+ // Timer for periodic mailbox listing refresh
110
+ this.refreshListingTimer = false;
111
+ // Timer for periodic mailbox resynchronization
112
+ this.resyncTimer = false;
113
+
114
+ // Timer to ensure we return to the main mailbox after operations
115
+ this.completedTimer = false;
116
+
117
+ // LRU caches for efficient UID packing/unpacking operations
118
+ this.pathCache = new LRUCache();
119
+ this.idCache = new LRUCache();
120
+
121
+ // Default folder delimiter (usually '/' or '.')
122
+ this.defaultDelimiter = '/';
123
+
124
+ // Array of subconnection instances for monitoring multiple folders simultaneously
125
+ this.subconnections = [];
126
+
127
+ // Flag indicating if the connection is paused
128
+ this.paused = false;
129
+
130
+ // Primary IMAP connection instance
131
+ this.imapClient = null;
132
+ // Secondary connection for commands that shouldn't interrupt IDLE
133
+ this.commandClient = null;
134
+
135
+ // Flag indicating if mailbox synchronization is in progress
136
+ this.syncing = false;
137
+
138
+ // Counter for generating unique connection IDs
139
+ this.connectionCount = 0;
140
+ // Set of all active connections for tracking
141
+ this.connections = new Set();
142
+
143
+ // Indexing strategy for this account ('full' or other modes)
144
+ this.imapIndexer = null;
145
+
146
+ // Current connection state
147
+ this.state = 'connecting';
148
+
149
+ // Reconnection tracking for capped exponential backoff
150
+ this.reconnectRetries = 0;
151
+ this.reconnectMaxDelay = 30000; // 30 seconds max delay
152
+
153
+ // Error reconnection tracking
154
+ this.errorReconnectDelay = 2000;
155
+ this.errorReconnectMaxDelay = 30000;
156
+ this.reconnectTimer = null;
157
+ }
158
+
159
+ /**
160
+ * Called when a task is completed - ensures we return to the main mailbox
161
+ * This prevents the connection from staying in a rarely-used mailbox
162
+ */
163
+ onTaskCompleted() {
164
+ // check if we need to re-select main mailbox
165
+ this.completedTimer = setTimeout(() => {
166
+ clearTimeout(this.completedTimer);
167
+ this.ensureMainMailbox().catch(err => this.logger.error({ msg: 'Failed to select main mailbox', err }));
168
+ }, ENSURE_MAIN_TTL);
169
+ }
170
+
171
+ /**
172
+ * Gets an IMAP connection for executing commands
173
+ * @param {Object} connectionOptions - Connection options
174
+ * @param {boolean} connectionOptions.allowSecondary - Whether to allow using secondary connections
175
+ * @param {boolean} connectionOptions.noPool - Force creation of new connection
176
+ * @param {Object} connectionOptions.connectionClient - Existing connection to reuse
177
+ * @param {string} reason - Reason for requesting the connection (for logging)
178
+ * @returns {Object} IMAP connection instance
179
+ */
180
+ async getImapConnection(connectionOptions, reason) {
181
+ connectionOptions = connectionOptions || {};
182
+
183
+ let { allowSecondary, noPool, connectionClient: existingConnectionClient } = connectionOptions || {};
184
+
185
+ // If an existing connection was provided and it's usable, return it
186
+ if (existingConnectionClient && existingConnectionClient.usable) {
187
+ return existingConnectionClient;
188
+ }
189
+
190
+ // Determine if we're in a syncing state where secondary connections might be needed
191
+ let syncing = this.syncing || ['init', 'connecting', 'syncing'].includes(this.state);
192
+ if (!noPool && (!syncing || !allowSecondary)) {
193
+ // Return the primary connection for most operations
194
+ return this.imapClient;
195
+ }
196
+
197
+ // TODO: if noPool is true, then always create a new connection
198
+
199
+ try {
200
+ // Try to get or create a command connection for operations that shouldn't interrupt IDLE
201
+ const connectionClient = await this.getCommandConnection(reason);
202
+ if (connectionClient && connectionClient.usable) {
203
+ connectionOptions.connectionClient = connectionClient;
204
+ return connectionClient;
205
+ } else {
206
+ // fall back to default connection
207
+ return this.imapClient;
208
+ }
209
+ } catch (err) {
210
+ this.logger.error({ msg: 'Failed to acquire command connection', reason, err });
211
+ return this.imapClient;
212
+ }
213
+ }
214
+
215
+ /**
216
+ * Gets or creates a command connection (secondary connection for non-IDLE operations)
217
+ * This allows running IMAP commands without interrupting the primary connection's IDLE state
218
+ * @param {string} reason - Reason for requesting the connection
219
+ * @returns {Object} Command connection instance
220
+ */
221
+ async getCommandConnection(reason) {
222
+ // Return existing command connection if available
223
+ if (this.commandClient && this.commandClient.usable) {
224
+ // use existing command channel
225
+ return this.commandClient;
226
+ }
227
+
228
+ // Acquire a lock to prevent multiple simultaneous connection attempts
229
+ let lock = this.accountObject.getLock();
230
+
231
+ let connectLock;
232
+ let lockKey = ['commandClient', this.account].join(':');
233
+
234
+ try {
235
+ this.logger.debug({ msg: 'Acquiring connection lock', lockKey });
236
+ connectLock = await lock.waitAcquireLock(lockKey, 5 * 60 * 1000, 1 * 60 * 1000);
237
+ if (!connectLock.success) {
238
+ this.logger.error({ msg: 'Failed to get lock', lockKey });
239
+ throw new Error('Failed to get connection lock');
240
+ }
241
+ this.logger.debug({ msg: 'Acquired connection lock', lockKey, index: connectLock.index });
242
+ } catch (err) {
243
+ this.logger.error({ msg: 'Failed to get lock', lockKey, err });
244
+ throw err;
245
+ }
246
+
247
+ try {
248
+ // create a new connection for the command channel
249
+ let accountData = await this.accountObject.loadAccountData();
250
+
251
+ // Check if IMAP is configured and enabled
252
+ if ((!accountData.imap && !accountData.oauth2) || (accountData.imap && accountData.imap.disabled)) {
253
+ return null;
254
+ }
255
+
256
+ // Check again if command client was created while waiting for lock
257
+ if (this.commandClient && this.commandClient.usable) {
258
+ // use existing command channel created during the lock
259
+ return this.commandClient;
260
+ }
261
+
262
+ // Generate unique connection ID for tracking
263
+ const commandCid = `${this.cid}:c:${this.connectionCount++}`;
264
+
265
+ let imapConfig = await this.getImapConfig(accountData);
266
+
267
+ // Create new IMAP connection with specific settings for command operations
268
+ let commandClient = new ImapFlow(
269
+ Object.assign({}, imapConfig, {
270
+ disableAutoIdle: true, // Don't automatically IDLE on this connection
271
+ id: commandCid,
272
+ socketTimeout: 60 * 1000, // 60 second timeout for command operations
273
+ logger: this.logger.child({
274
+ cid: commandCid,
275
+ channel: 'command'
276
+ })
277
+ })
278
+ );
279
+ this.connections.add(commandClient);
280
+ await this.redis.hSetExists(this.getAccountKey(), 'connections', this.connections.size.toString());
281
+
282
+ commandClient.log.debug({ msg: 'Created command client', reason });
283
+
284
+ this.commandClient = commandClient;
285
+
286
+ // Mark this as a secondary connection for identification
287
+ commandClient.secondaryConnection = true;
288
+
289
+ // Set up error handling for the command connection
290
+ const onErr = err => {
291
+ commandClient?.log.error({ msg: 'IMAP connection error', cid: commandCid, channel: 'command', account: this.account, err });
292
+ commandClient.close();
293
+ this.commandClient = null;
294
+ };
295
+ commandClient.on('error', onErr);
296
+
297
+ try {
298
+ await commandClient.connect();
299
+ commandClient.log.info({ msg: 'Command channel connected', cid: commandCid, channel: 'command', account: this.account });
300
+ } catch (err) {
301
+ if (this.connections.delete(commandClient)) {
302
+ await this.redis.hSetExists(this.getAccountKey(), 'connections', this.connections.size.toString());
303
+ }
304
+ commandClient.log.error({ msg: 'Failed to connect command client', cid: commandCid, channel: 'command', account: this.account, err });
305
+ throw err;
306
+ }
307
+
308
+ // Clean up when connection closes
309
+ commandClient.on('close', async () => {
310
+ try {
311
+ if (this.connections.delete(commandClient)) {
312
+ await this.redis.hSetExists(this.getAccountKey(), 'connections', this.connections.size.toString());
313
+ }
314
+ commandClient.log.info({ msg: 'Connection closed', cid: commandCid, channel: 'command', account: this.account });
315
+ } catch (err) {
316
+ this.logger.error({ msg: 'Error in command client close handler', cid: commandCid, account: this.account, err });
317
+ }
318
+
319
+ this.commandClient = null;
320
+ commandClient.removeAllListeners();
321
+ commandClient = null;
322
+ });
323
+
324
+ return commandClient;
325
+ } finally {
326
+ // Always release the lock
327
+ this.logger.debug({ msg: 'Releasing connection lock', lockKey, index: connectLock.index });
328
+ await lock.releaseLock(connectLock);
329
+ this.logger.debug({ msg: 'Released connection lock', lockKey, index: connectLock.index });
330
+ }
331
+ }
332
+
333
+ /**
334
+ * Ensures the main mailbox is selected on the primary connection
335
+ * This is called after operations to return to the monitored mailbox
336
+ */
337
+ async ensureMainMailbox() {
338
+ let mainPath = this.main ? this.main.path : 'INBOX';
339
+ if (this.mailbox && normalizePath(this.mailbox.path) === normalizePath(mainPath)) {
340
+ // already selected
341
+ return;
342
+ }
343
+
344
+ // start waiting for changes
345
+ await this.select(mainPath);
346
+ }
347
+
348
+ /**
349
+ * Packs a mailbox path and UID into a compact base64url string for use as message IDs
350
+ * This creates a unique identifier that can be unpacked later to retrieve the message
351
+ * @param {Object|string} mailbox - Mailbox object or path
352
+ * @param {number} uid - Message UID
353
+ * @returns {string|false} Base64url encoded ID or false on error
354
+ */
355
+ async packUid(mailbox, uid) {
356
+ if (isNaN(uid) || !mailbox) {
357
+ return false;
358
+ }
359
+
360
+ if (typeof uid !== 'number') {
361
+ uid = Number(uid);
362
+ }
363
+
364
+ // Convert mailbox path to mailbox object if needed
365
+ if (typeof mailbox === 'string') {
366
+ if (this.mailboxes.has(normalizePath(mailbox))) {
367
+ mailbox = this.mailboxes.get(normalizePath(mailbox));
368
+ } else {
369
+ return false;
370
+ }
371
+ }
372
+
373
+ // Get stored mailbox status including UID validity
374
+ const storedStatus = await mailbox.getStoredStatus();
375
+ if (!validUidValidity(storedStatus.uidValidity) || !storedStatus.path) {
376
+ return false;
377
+ }
378
+
379
+ // Pack UID validity and mailbox path into a buffer
380
+ let uidValBuf = Buffer.alloc(8);
381
+ uidValBuf.writeBigUInt64BE(storedStatus.uidValidity, 0);
382
+ let mailboxBuf = Buffer.concat([uidValBuf, Buffer.from(storedStatus.path)]);
383
+
384
+ // Get or create a numeric mailbox ID for efficient storage
385
+ let mailboxId;
386
+ if (this.pathCache.has(mailboxBuf.toString('hex'))) {
387
+ mailboxId = this.pathCache.get(mailboxBuf.toString('hex'));
388
+ } else {
389
+ mailboxId = await this.redis.zGetMailboxId(this.getAccountKey(), this.getMailboxHashKey(), mailboxBuf);
390
+ if (isNaN(mailboxId) || typeof mailboxId !== 'number') {
391
+ return false;
392
+ }
393
+
394
+ // Cache for future use
395
+ this.pathCache.set(mailboxBuf.toString('hex'), mailboxId);
396
+ this.idCache.set(mailboxId, mailboxBuf);
397
+ }
398
+
399
+ // Pack mailbox ID and UID into final buffer
400
+ let uidBuf = Buffer.alloc(4 + 4);
401
+ uidBuf.writeUInt32BE(mailboxId, 0);
402
+ uidBuf.writeUInt32BE(uid, 4);
403
+
404
+ let res = uidBuf.toString('base64url');
405
+
406
+ return res;
407
+ }
408
+
409
+ /**
410
+ * Unpacks a base64url encoded ID back into mailbox path and UID
411
+ * @param {string|Buffer} id - Packed message ID
412
+ * @returns {Object|false} Object with path, uidValidity, and uid or false on error
413
+ */
414
+ async unpackUid(id) {
415
+ const packed = Buffer.isBuffer(id) ? id : Buffer.from(id, 'base64url');
416
+
417
+ let mailboxId = packed.readUInt32BE(0);
418
+ let uid = packed.readUInt32BE(4);
419
+
420
+ // Look up mailbox path from ID
421
+ let mailboxBuf;
422
+ if (this.idCache.has(mailboxId)) {
423
+ mailboxBuf = this.idCache.get(mailboxId);
424
+ } else {
425
+ mailboxBuf = await this.redis.zGetMailboxPathBuffer(this.getMailboxHashKey(), mailboxId);
426
+ if (!mailboxBuf) {
427
+ return false;
428
+ }
429
+
430
+ // Cache for future use
431
+ this.pathCache.set(mailboxBuf.toString('hex'), mailboxId);
432
+ this.idCache.set(mailboxId, mailboxBuf);
433
+ }
434
+
435
+ if (!mailboxBuf) {
436
+ return false;
437
+ }
438
+
439
+ // Extract path and UID validity from buffer
440
+ let path = mailboxBuf.subarray(8).toString();
441
+ return {
442
+ path,
443
+ uidValidity: mailboxBuf.readBigUInt64BE(0).toString(),
444
+ uid
445
+ };
446
+ }
447
+
448
+ /**
449
+ * Unpacks a text content ID to get message location and text part paths
450
+ * @param {string} textId - Base64url encoded text ID
451
+ * @returns {Object} Object with message info and text parts array
452
+ */
453
+ async getMessageTextPaths(textId) {
454
+ let buf = Buffer.from(textId, 'base64url');
455
+ let id = buf.subarray(0, 8);
456
+ let textParts = msgpack.decode(buf.subarray(8));
457
+
458
+ let message = await this.unpackUid(id);
459
+ if (!message) {
460
+ return { message: false };
461
+ }
462
+
463
+ return { message, textParts };
464
+ }
465
+
466
+ /**
467
+ * Clears all cached data for a specific mailbox
468
+ * Used when a mailbox is deleted or needs to be reset
469
+ * @param {Object} entry - Mailbox entry with path
470
+ */
471
+ async clearMailboxEntry(entry) {
472
+ if (!entry || !entry.path) {
473
+ return; // ?
474
+ }
475
+
476
+ let mailbox;
477
+ if (!this.mailboxes.has(normalizePath(entry.path))) {
478
+ mailbox = new Mailbox(this, entry);
479
+ } else {
480
+ mailbox = this.mailboxes.get(normalizePath(entry.path));
481
+ }
482
+
483
+ await mailbox.clear();
484
+ mailbox = false;
485
+ }
486
+
487
+ /**
488
+ * Retrieves the current mailbox listing from the IMAP server
489
+ * Compares with stored listing to detect new/deleted/renamed folders
490
+ * @param {Object} options - Listing options
491
+ * @param {Object} connectionOptions - Connection options
492
+ * @returns {Array} Array of mailbox objects
493
+ */
494
+ async getCurrentListing(options, connectionOptions) {
495
+ options = options || {};
496
+
497
+ this.checkIMAPConnection(connectionOptions);
498
+
499
+ const connectionClient = await this.getImapConnection(connectionOptions, 'getCurrentListing');
500
+ if (!connectionClient) {
501
+ this.imapClient.close();
502
+ let error = new Error('Failed to get connection');
503
+ error.code = 'ConnectionError';
504
+ throw error;
505
+ }
506
+
507
+ let accountData = await this.accountObject.loadAccountData();
508
+
509
+ // Build hints for special-use folders from account configuration
510
+ let specialUseHints = {};
511
+ for (let type of ['sent', 'drafts', 'junk', 'trash', 'archive']) {
512
+ if (accountData.imap && accountData.imap[`${type}MailPath`]) {
513
+ specialUseHints[type] = accountData.imap[`${type}MailPath`];
514
+ }
515
+ }
516
+
517
+ options = Object.assign({}, options, {
518
+ specialUseHints
519
+ });
520
+
521
+ // Get mailbox listing from server
522
+ let listing = await connectionClient.list(options);
523
+ if (!listing.length) {
524
+ // server bug, the list can never be empty
525
+ this.imapClient.close();
526
+ let error = new Error('Server bug: empty mailbox listing');
527
+ error.code = 'ServerBug';
528
+ throw error;
529
+ }
530
+
531
+ // Extract delimiter from INBOX (most reliable source)
532
+ let inboxData = (listing || []).find(entry => /^INBOX$/i.test(entry.path));
533
+ if (inboxData && inboxData.delimiter) {
534
+ this.defaultDelimiter = inboxData.delimiter;
535
+ }
536
+
537
+ // ignore non-selectable folders
538
+ listing = listing
539
+ .filter(mailbox => !mailbox.flags.has('\\Noselect'))
540
+ .map(mailbox => {
541
+ mailbox.noInferiors = mailbox.flags.has('\\Noinferiors');
542
+ return mailbox;
543
+ });
544
+
545
+ let hasChanges = false;
546
+
547
+ // compare listing for new / deleted / renamed folders
548
+ let storedListing = await this.redis.hgetallBuffer(this.getMailboxListKey());
549
+
550
+ storedListing = Object.keys(storedListing || {})
551
+ .map(path => {
552
+ try {
553
+ return msgpack.decode(storedListing[path]);
554
+ } catch (err) {
555
+ // should not happen
556
+ }
557
+ return false;
558
+ })
559
+ .filter(entry => entry);
560
+
561
+ // compare listings to detect changes
562
+ for (let mailbox of listing) {
563
+ let existingMailbox = storedListing.find(entry => normalizePath(entry.path) === normalizePath(mailbox.path));
564
+ if (!existingMailbox) {
565
+ // found new!
566
+ mailbox.isNew = true;
567
+ hasChanges = true;
568
+ } else if (
569
+ existingMailbox.delimiter !== mailbox.delimiter ||
570
+ existingMailbox.specialUseSource !== mailbox.specialUseSource ||
571
+ existingMailbox.noInferiors !== mailbox.noInferiors
572
+ ) {
573
+ hasChanges = true;
574
+ }
575
+ }
576
+
577
+ // Check for deleted mailboxes
578
+ for (let entry of storedListing) {
579
+ if (!listing.some(mailbox => normalizePath(entry.path) === normalizePath(mailbox.path))) {
580
+ // found deleted!
581
+ await this.clearMailboxEntry(entry);
582
+ hasChanges = true;
583
+ }
584
+ }
585
+
586
+ // on changes store updated listing
587
+ if (hasChanges) {
588
+ // store
589
+ const listingObject = {};
590
+ listing.forEach(entry => {
591
+ let mailbox = {};
592
+ Object.keys(entry).forEach(key => {
593
+ if (['path', 'specialUse', 'name', 'listed', 'subscribed', 'delimiter', 'specialUseSource', 'noInferiors'].includes(key)) {
594
+ mailbox[key] = entry[key];
595
+ }
596
+ });
597
+ listingObject[normalizePath(entry.path)] = msgpack.encode(mailbox);
598
+ });
599
+
600
+ // Atomic update of the mailbox listing
601
+ await this.redis.multi().del(this.getMailboxListKey()).hmset(this.getMailboxListKey(), listingObject).exec();
602
+ }
603
+
604
+ return listing;
605
+ }
606
+
607
+ /**
608
+ * Refreshes the folder list and creates Mailbox instances for new folders
609
+ * @returns {Set} Set of newly created mailbox instances that need syncing
610
+ */
611
+ async refreshFolderList() {
612
+ if (this.refreshingList) {
613
+ return;
614
+ }
615
+ this.refreshingList = true;
616
+
617
+ try {
618
+ let accountData = await this.accountObject.loadAccountData();
619
+
620
+ // Get configured paths to monitor (default to all)
621
+ const accountPaths = [].concat(accountData.path || '*');
622
+ if (!accountPaths.length) {
623
+ accountPaths.push('*');
624
+ }
625
+
626
+ let listing = await this.getCurrentListing();
627
+
628
+ let syncNeeded = new Set();
629
+ for (let entry of listing) {
630
+ if (
631
+ // previously unseen
632
+ !this.mailboxes.has(normalizePath(entry.path))
633
+ ) {
634
+ // Apply filtering rules based on account configuration
635
+ if (!accountPaths.includes('*')) {
636
+ if (!accountPaths.includes(entry.path) && !accountPaths.includes(entry.specialUse)) {
637
+ // ignore changes
638
+ entry.syncDisabled = true;
639
+ }
640
+ } else if (this.isGmail && !['\\All', '\\Junk', '\\Trash'].includes(entry.specialUse)) {
641
+ // For Gmail, only monitor All Mail, Spam, and Trash folders
642
+ // Other folders are just labels and covered by All Mail
643
+ entry.syncDisabled = true;
644
+ }
645
+
646
+ let mailbox = new Mailbox(this, entry);
647
+ this.mailboxes.set(normalizePath(entry.path), mailbox);
648
+ syncNeeded.add(mailbox);
649
+ }
650
+ }
651
+
652
+ // sync new mailboxes
653
+ for (let mailbox of syncNeeded) {
654
+ await mailbox.sync(true);
655
+ }
656
+
657
+ return syncNeeded;
658
+ } finally {
659
+ this.refreshingList = false;
660
+ }
661
+ }
662
+
663
+ /**
664
+ * Establishes initial IMAP connection and performs setup
665
+ * Sets up event handlers and determines account type (Gmail, Outlook, etc.)
666
+ * @returns {Object} Connection response
667
+ */
668
+ async connect() {
669
+ if (this.isClosing || this.isClosed) {
670
+ return false;
671
+ }
672
+
673
+ this.state = 'connecting';
674
+ await this.setStateVal();
675
+
676
+ let imapClient = this.imapClient;
677
+
678
+ let accountData = await this.accountObject.loadAccountData();
679
+
680
+ // throws if connection fails
681
+ let response = await imapClient.connect();
682
+
683
+ this.state = 'syncing';
684
+ await this.setStateVal();
685
+ await emitChangeEvent(this.logger, this.account, 'state', this.state);
686
+
687
+ let listing = await this.getCurrentListing();
688
+
689
+ // Detect email provider type based on capabilities and folder structure
690
+ // User might have disabled All Mail folder access and in that case we should treat it as a regular mailbox
691
+ this.isGmail = imapClient.capabilities.has('X-GM-EXT-1') && listing.some(entry => entry.specialUse === '\\All');
692
+ this.isOutlook = /\boffice365\.com$/i.test(imapClient.host); // || /The Microsoft Exchange IMAP4 service is ready/.test(imapClient.greeting);
693
+ this.isLarkSuite = /\blarksuite\.com$/i.test(imapClient.host);
694
+
695
+ const accountPaths = [].concat(accountData.path || '*');
696
+ if (!accountPaths.length) {
697
+ accountPaths.push('*');
698
+ }
699
+
700
+ // store synced folder entries
701
+ const mainList = [];
702
+
703
+ // Process mailbox listing and determine which folders to monitor
704
+ for (let entry of listing) {
705
+ if (!accountPaths.includes('*')) {
706
+ // Limited path monitoring - only specific folders
707
+ if (!accountPaths.includes(entry.path) && !accountPaths.includes(entry.specialUse)) {
708
+ entry.syncDisabled = true;
709
+ } else {
710
+ // insert to stored list with the sorting index
711
+ let index = accountPaths.indexOf(entry.path) >= 0 ? accountPaths.indexOf(entry.path) : accountPaths.indexOf(entry.specialUse);
712
+ mainList.push({ index, entry });
713
+ }
714
+ } else {
715
+ // Monitor all folders - determine main folder for IDLE
716
+ if ((this.isGmail && entry.specialUse === '\\All') || (!this.isGmail && entry.specialUse === '\\Inbox')) {
717
+ // In case of gmail prefer All mail folder as the folder to actively track, otherwise INBOX
718
+ // idle in this folder
719
+ this.main = entry;
720
+ }
721
+
722
+ if (this.isGmail && !['\\All', '\\Junk', '\\Trash'].includes(entry.specialUse)) {
723
+ // do not look for changes from this folder
724
+ entry.syncDisabled = true;
725
+ }
726
+ }
727
+
728
+ let mailbox = new Mailbox(this, entry);
729
+ this.mailboxes.set(normalizePath(entry.path), mailbox);
730
+ }
731
+
732
+ if (mainList.length) {
733
+ // set the highest synced entry as the main folder
734
+ this.main = mainList.sort((a, b) => a.index - b.index)[0].entry;
735
+ }
736
+
737
+ // Set up event handlers for IMAP notifications
738
+
739
+ // Process untagged EXISTS responses (new messages)
740
+ imapClient.on('exists', async event => {
741
+ if (!event || !event.path || !this.mailboxes.has(normalizePath(event.path))) {
742
+ return; //?
743
+ }
744
+
745
+ let mailbox = this.mailboxes.get(normalizePath(event.path));
746
+ try {
747
+ await mailbox.onExists(event);
748
+ } catch (err) {
749
+ imapClient.log.error({ msg: 'Exists error', err });
750
+ }
751
+ });
752
+
753
+ // Handle mailbox open events
754
+ imapClient.on('mailboxOpen', async event => {
755
+ if (!event || !event.path || !this.mailboxes.has(normalizePath(event.path))) {
756
+ return; //?
757
+ }
758
+
759
+ let mailbox = this.mailboxes.get(normalizePath(event.path));
760
+ try {
761
+ await mailbox.onOpen(event);
762
+ } catch (err) {
763
+ imapClient.log.error({ msg: 'Open error', err });
764
+ }
765
+ });
766
+
767
+ // Handle mailbox close events
768
+ imapClient.on('mailboxClose', async event => {
769
+ if (!event || !event.path || !this.mailboxes.has(normalizePath(event.path))) {
770
+ return; //?
771
+ }
772
+
773
+ let mailbox = this.mailboxes.get(normalizePath(event.path));
774
+ try {
775
+ await mailbox.onClose(event);
776
+ } catch (err) {
777
+ imapClient.log.error({ msg: 'Close error', err });
778
+ }
779
+ });
780
+
781
+ // Handle flag changes
782
+ imapClient.on('flags', async event => {
783
+ if (!event || !event.path || !this.mailboxes.has(normalizePath(event.path))) {
784
+ return; //?
785
+ }
786
+
787
+ let mailbox = this.mailboxes.get(normalizePath(event.path));
788
+ try {
789
+ await mailbox.onFlags(event);
790
+ } catch (err) {
791
+ imapClient.log.error({ msg: 'Flags error', err });
792
+ }
793
+ });
794
+
795
+ return response;
796
+ }
797
+
798
+ /**
799
+ * Handles reconnection with exponential backoff
800
+ * @param {boolean} force - Force reconnection even if paused/closed
801
+ * @returns {boolean} Success status
802
+ */
803
+ async reconnect(force) {
804
+ if (this._connecting) {
805
+ // backoff reconnect already in progress
806
+ return false;
807
+ }
808
+ if (this.paused || this.isClosing || (this.isClosed && !force)) {
809
+ this.logger.debug({
810
+ msg: 'Skipped establishing connection',
811
+ paused: this.paused,
812
+ hasClient: !!this.imapClient,
813
+ usable: this.imapClient?.usable,
814
+ closing: this.isClosing,
815
+ closed: this.isClosed,
816
+ force
817
+ });
818
+ return false;
819
+ }
820
+ this.logger.debug({ msg: 'Establishing connection', force });
821
+
822
+ if (force) {
823
+ // Close all subconnections and command client when forcing reconnection
824
+ this.closeSubconnections();
825
+ if (this.commandClient) {
826
+ this.commandClient.close();
827
+ }
828
+ }
829
+
830
+ this._connecting = true;
831
+ this.isClosed = false;
832
+
833
+ let accountData = await this.accountObject.loadAccountData();
834
+ // Get indexing strategy for this account
835
+ this.imapIndexer = typeof accountData.imapIndexer === 'string' && accountData.imapIndexer ? accountData.imapIndexer : 'full';
836
+
837
+ try {
838
+ this.logger.debug({ msg: 'Initiating connection to IMAP' });
839
+ // Use exponential backoff for connection attempts
840
+ await backOff(() => this.start(), {
841
+ maxDelay: MAX_BACKOFF_DELAY,
842
+ numOfAttempts: Infinity,
843
+ retry: () => !this.isClosing && !this.isClosed,
844
+ startingDelay: 2000
845
+ });
846
+ this.logger.debug({
847
+ msg: 'Connection created',
848
+ hasClient: !!this.imapClient,
849
+ usable: this.imapClient && this.imapClient.usable,
850
+ connected: this.isConnected()
851
+ });
852
+ } finally {
853
+ this._connecting = false;
854
+ }
855
+
856
+ if (this.paused) {
857
+ this.logger.debug({ msg: 'Skipped connection setup', reason: 'paused' });
858
+ return;
859
+ }
860
+
861
+ if (this.state === 'unset') {
862
+ this.logger.debug({ msg: 'Skipped connection setup', reason: 'unset' });
863
+ return;
864
+ }
865
+
866
+ try {
867
+ await this.checkIMAPConnection();
868
+ this.logger.debug({ msg: 'Starting mailbox sync' });
869
+ await this.syncMailboxes();
870
+ this.logger.debug({ msg: 'Mailboxes synced', usable: this.imapClient?.usable });
871
+
872
+ if (this.imapClient?.usable) {
873
+ // was able to finish syncing, clear the failure flag
874
+ try {
875
+ await this.redis.hdel(this.getAccountKey(), 'syncError');
876
+ } catch (err) {
877
+ // ignore
878
+ }
879
+ }
880
+ } catch (err) {
881
+ // ended in an unconncted state
882
+ this.logger.error({ msg: 'Failed to set up connection, will retry', err });
883
+
884
+ // Calculate delay with capped exponential backoff
885
+ const retryDelay = Math.min(this.reconnectMaxDelay, 1000 * Math.pow(1.5, Math.min(this.reconnectRetries, 10)));
886
+ this.reconnectRetries++;
887
+
888
+ this.logger.info({
889
+ msg: 'Scheduling reconnection attempt',
890
+ attempt: this.reconnectRetries,
891
+ delay: retryDelay
892
+ });
893
+
894
+ return setTimeout(() => {
895
+ this.reconnect()
896
+ .then(() => {
897
+ // Reset counter on successful reconnect
898
+ this.reconnectRetries = 0;
899
+ })
900
+ .catch(err => {
901
+ this.logger.error({
902
+ msg: 'Connection retry failed',
903
+ err,
904
+ attempt: this.reconnectRetries
905
+ });
906
+ });
907
+ }, retryDelay);
908
+ }
909
+
910
+ this.logger.debug({
911
+ msg: 'Connection established',
912
+ hasClient: !!this.imapClient,
913
+ usable: this.imapClient && this.imapClient.usable,
914
+ connected: this.isConnected()
915
+ });
916
+ }
917
+
918
+ /**
919
+ * Synchronizes all mailboxes and schedules periodic resync
920
+ * Handles the main synchronization loop for the account
921
+ */
922
+ async syncMailboxes() {
923
+ // Clear any pending timers
924
+ clearTimeout(this.untaggedExpungeTimer);
925
+ clearTimeout(this.resyncTimer);
926
+ clearTimeout(this.completedTimer);
927
+
928
+ if (!this.imapClient || !this.imapClient.usable) {
929
+ this.logger.debug({ msg: 'Skipped syncing', reason: 'no imap client' });
930
+ return;
931
+ }
932
+
933
+ // Refresh folder list and sync new folders
934
+ let synced = await this.refreshFolderList();
935
+
936
+ // Sync existing folders that weren't just synced
937
+ for (let mailbox of this.mailboxes.values()) {
938
+ if (!synced || !synced.has(mailbox)) {
939
+ await mailbox.sync();
940
+ }
941
+ }
942
+
943
+ if (!this.imapClient || !this.imapClient.usable) {
944
+ this.logger.debug({ msg: 'Syncing completed, skipping state change', reason: 'no imap client' });
945
+ return;
946
+ }
947
+
948
+ // Update state to connected
949
+ this.state = 'connected';
950
+ await this.setStateVal();
951
+
952
+ // Store IMAP server capabilities for reference
953
+ const capabilities = (this.imapClient.rawCapabilities || []).map(entry => entry && entry.value).filter(entry => entry);
954
+ const authCapabilities = [];
955
+ let lastUsedAuthCapability = null;
956
+ if (this.imapClient.authCapabilities) {
957
+ for (let [authCapa, usedAuth] of this.imapClient.authCapabilities) {
958
+ authCapabilities.push(authCapa);
959
+ if (usedAuth) {
960
+ lastUsedAuthCapability = authCapa;
961
+ }
962
+ }
963
+ }
964
+
965
+ const serverInfo = Object.assign({}, this.imapClient.serverInfo || {}, {
966
+ capabilities,
967
+ authCapabilities,
968
+ lastUsedAuthCapability
969
+ });
970
+
971
+ await this.redis.hSetExists(this.getAccountKey(), 'imapServerInfo', JSON.stringify(serverInfo));
972
+ // Clear error state on successful connection
973
+ await this.redis.hdel(this.getAccountKey(), 'lastErrorState', 'lastError:errorCount', 'lastError:first');
974
+ await emitChangeEvent(this.logger, this.account, 'state', this.state);
975
+
976
+ // Select main mailbox for IDLE monitoring
977
+ let mainPath = this.main ? this.main.path : 'INBOX';
978
+ if (this.mailbox && normalizePath(this.mailbox.path) === normalizePath(mainPath)) {
979
+ // already selected
980
+ return;
981
+ }
982
+
983
+ this.logger.debug({ msg: 'Syncing completed, selecting main path', path: mainPath });
984
+ // start waiting for changes
985
+ await this.select(mainPath);
986
+
987
+ // Schedule next sync cycle
988
+ let retryCount = 0;
989
+ let setSyncTimer = () => {
990
+ clearTimeout(this.resyncTimer);
991
+ this.resyncTimer = setTimeout(() => {
992
+ this.syncMailboxes()
993
+ .then(() => {
994
+ // Reset retry count on successful sync
995
+ retryCount = 0;
996
+ })
997
+ .catch(err => {
998
+ this.logger.error({ msg: 'Mailbox Sync Error', err, retryCount });
999
+ retryCount++;
1000
+ // Exponential backoff with max delay of 30 seconds
1001
+ const retryDelay = Math.min(30000, 2000 * Math.pow(2, retryCount));
1002
+ this.logger.warn({ msg: 'Scheduling sync retry with backoff', retryDelay, retryCount });
1003
+ setTimeout(setSyncTimer, retryDelay);
1004
+ });
1005
+ }, this.resyncDelay);
1006
+ };
1007
+ setSyncTimer();
1008
+ }
1009
+
1010
+ /**
1011
+ * Selects a mailbox on the IMAP connection
1012
+ * @param {string} path - Mailbox path to select
1013
+ */
1014
+ async select(path) {
1015
+ if (!this.mailboxes.has(normalizePath(path))) {
1016
+ // nothing to do here, mailbox not found
1017
+ this.logger.debug({ msg: 'Can not select unlisted path', path });
1018
+ return;
1019
+ }
1020
+
1021
+ let mailbox = this.mailboxes.get(normalizePath(path));
1022
+ await mailbox.select();
1023
+ }
1024
+
1025
+ /**
1026
+ * Builds IMAP configuration from account data
1027
+ * Handles both OAuth2 and regular authentication
1028
+ * @param {Object} accountData - Account configuration data
1029
+ * @param {Object} ctx - Context object (defaults to this)
1030
+ * @returns {Object} Complete IMAP configuration
1031
+ */
1032
+ async getImapConfig(accountData, ctx) {
1033
+ if (!accountData) {
1034
+ accountData = await this.accountObject.loadAccountData();
1035
+ }
1036
+
1037
+ // the same method is also called by subconnections, so do not mark the primary connection as failing if something happens
1038
+ ctx = ctx || this;
1039
+ let imapConnectionConfig;
1040
+
1041
+ if (accountData.oauth2 && accountData.oauth2.auth) {
1042
+ // OAuth2 authentication configuration
1043
+ const { oauth2User, accessToken, oauth2App } = await this.loadOAuth2AccountCredentials(accountData, ctx, 'imap');
1044
+ const providerData = oauth2ProviderData(oauth2App.provider, oauth2App.cloud);
1045
+
1046
+ imapConnectionConfig = Object.assign(
1047
+ {
1048
+ auth: {
1049
+ user: oauth2User,
1050
+ accessToken
1051
+ },
1052
+ resyncDelay: RESYNC_DELAY
1053
+ },
1054
+ providerData.imap || {}
1055
+ );
1056
+ } else {
1057
+ // Regular password authentication
1058
+ // deep copy of imap settings
1059
+ imapConnectionConfig = JSON.parse(JSON.stringify(accountData.imap));
1060
+ }
1061
+
1062
+ // If authentication server is set then it overrides authentication data
1063
+ if (imapConnectionConfig.useAuthServer) {
1064
+ try {
1065
+ imapConnectionConfig.auth = await resolveCredentials(this.account, 'imap');
1066
+ } catch (err) {
1067
+ err.authenticationFailed = true;
1068
+ await ctx.notify(false, AUTH_ERROR_NOTIFY, {
1069
+ response: err.message,
1070
+ serverResponseCode: 'HTTPRequestError'
1071
+ });
1072
+ ctx.logger.error({
1073
+ account: this.account,
1074
+ err
1075
+ });
1076
+ ctx.state = AUTH_ERROR_NOTIFY;
1077
+ throw err;
1078
+ }
1079
+ }
1080
+
1081
+ // Configure TLS settings
1082
+ if (!imapConnectionConfig.tls) {
1083
+ imapConnectionConfig.tls = {};
1084
+ }
1085
+
1086
+ // Set local address for outgoing connections (for IP rotation)
1087
+ const localAddress = await getLocalAddress(redis, 'imap', this.account);
1088
+ imapConnectionConfig.tls.localAddress = localAddress.localAddress;
1089
+ this.logger.info({
1090
+ msg: 'Selected local address',
1091
+ account: this.account,
1092
+ proto: 'IMAP',
1093
+ address: localAddress.localAddress,
1094
+ name: localAddress.name,
1095
+ selector: localAddress.addressSelector
1096
+ });
1097
+
1098
+ // Apply default TLS settings
1099
+ for (let key of Object.keys(TLS_DEFAULTS)) {
1100
+ if (!(key in imapConnectionConfig.tls)) {
1101
+ imapConnectionConfig.tls[key] = TLS_DEFAULTS[key];
1102
+ }
1103
+ }
1104
+
1105
+ // reload log config
1106
+ await this.accountLogger.reload();
1107
+
1108
+ // Build final IMAP configuration
1109
+ let imapConfig = Object.assign(
1110
+ {
1111
+ resyncDelay: RESYNC_DELAY,
1112
+ id: this.cid,
1113
+ emitLogs: this.accountLogger.enabled
1114
+ },
1115
+ imapConnectionConfig,
1116
+ this.imapConfig,
1117
+ {
1118
+ // Allow customization of client identification
1119
+ clientInfo: {
1120
+ name: (await settings.get('imapClientName')) || this.imapConfig.clientInfo.name,
1121
+ version: (await settings.get('imapClientVersion')) || this.imapConfig.clientInfo.version,
1122
+ vendor: (await settings.get('imapClientVendor')) || this.imapConfig.clientInfo.vendor,
1123
+ 'support-url': (await settings.get('imapClientSupportUrl')) || this.imapConfig.clientInfo['support-url']
1124
+ }
1125
+ }
1126
+ );
1127
+
1128
+ this.resyncDelay = imapConfig.resyncDelay * 1000;
1129
+
1130
+ // set up proxy if needed
1131
+ if (accountData.proxy) {
1132
+ imapConfig.proxy = accountData.proxy;
1133
+ } else {
1134
+ let proxyUrl = await settings.get('proxyUrl');
1135
+ let proxyEnabled = await settings.get('proxyEnabled');
1136
+ if (proxyEnabled && proxyUrl && !imapConfig.proxy) {
1137
+ imapConfig.proxy = proxyUrl;
1138
+ }
1139
+ }
1140
+
1141
+ // Provider-specific workarounds
1142
+ if (/(\.rambler\.ru|\.163\.com)$/i.test(imapConfig.host)) {
1143
+ // Special case for Rambler and 163. Break IDLE at least once a minute
1144
+ imapConfig.maxIdleTime = 55 * 1000;
1145
+ } else if (/\.yahoo\.com$/i.test(imapConfig.host)) {
1146
+ // Special case for Yahoo. Break IDLE at least once every three minutes
1147
+ imapConfig.maxIdleTime = 3 * 60 * 1000;
1148
+ }
1149
+
1150
+ /*
1151
+ else if (/(\.naver\.com)$/i.test(imapConfig.host)) {
1152
+ // NOOP does nothing in Naver, must run SELECT for changes in the folder to apply
1153
+ imapConfig.maxIdleTime = 55 * 1000;
1154
+ imapConfig.missingIdleCommand = 'SELECT';
1155
+ }
1156
+ */
1157
+
1158
+ // Apply global settings
1159
+ if (DISABLE_IMAP_COMPRESSION) {
1160
+ imapConfig.disableCompression = true;
1161
+ }
1162
+
1163
+ if (IMAP_SOCKET_TIMEOUT) {
1164
+ imapConfig.socketTimeout = IMAP_SOCKET_TIMEOUT;
1165
+ }
1166
+
1167
+ // Handle certificate validation settings
1168
+ const ignoreMailCertErrors = await settings.get('ignoreMailCertErrors');
1169
+ if (ignoreMailCertErrors && imapConfig?.tls?.rejectUnauthorized !== false) {
1170
+ imapConfig.tls = imapConfig.tls || {};
1171
+ imapConfig.tls.rejectUnauthorized = false;
1172
+ }
1173
+
1174
+ return imapConfig;
1175
+ }
1176
+
1177
+ /**
1178
+ * Initializes a new IMAP connection and sets up event handlers
1179
+ * This is the main connection setup method
1180
+ */
1181
+ async start() {
1182
+ if (this.paused) {
1183
+ this.logger.debug({ msg: 'Skipped start', reason: 'paused' });
1184
+ return;
1185
+ }
1186
+
1187
+ let initialState = this.state;
1188
+
1189
+ // Clean up existing connection if any
1190
+ if (this.imapClient) {
1191
+ this.logger.debug({ msg: 'Clearing previous connection' });
1192
+ let prevImapClient = this.imapClient;
1193
+ prevImapClient.disabled = true;
1194
+ try {
1195
+ prevImapClient.removeAllListeners();
1196
+
1197
+ const prevImapErrorHandler = err => {
1198
+ this.logger.error({ msg: 'IMAP connection error', type: 'imapClient', previous: true, account: this.account, err });
1199
+ };
1200
+
1201
+ prevImapClient.once('error', prevImapErrorHandler);
1202
+ prevImapClient.close();
1203
+ prevImapClient.removeListener('error', prevImapErrorHandler);
1204
+
1205
+ if (this.commandClient) {
1206
+ this.logger.debug({ msg: 'Clearing previous command connection' });
1207
+ this.commandClient.close();
1208
+ }
1209
+ } catch (err) {
1210
+ this.logger.error({ msg: 'IMAP close error', err });
1211
+ } finally {
1212
+ if (prevImapClient === this.imapClient) {
1213
+ this.imapClient = null;
1214
+ }
1215
+ prevImapClient = null;
1216
+ }
1217
+ }
1218
+
1219
+ try {
1220
+ let accountData = await this.accountObject.loadAccountData();
1221
+
1222
+ // Load notification settings
1223
+ this.notifyFrom = accountData.notifyFrom;
1224
+ this.syncFrom = accountData.syncFrom;
1225
+
1226
+ if ((!accountData.imap && !accountData.oauth2) || (accountData.imap && accountData.imap.disabled)) {
1227
+ // can not make a connection
1228
+ this.state = 'unset';
1229
+ return;
1230
+ }
1231
+
1232
+ let imapConfig = await this.getImapConfig(accountData);
1233
+
1234
+ // Generate unique connection ID
1235
+ imapConfig.id = `${imapConfig.id}:m:${this.connectionCount++}`;
1236
+
1237
+ // Create new IMAP connection instance
1238
+ let imapClient = new ImapFlow(
1239
+ Object.assign({}, imapConfig, {
1240
+ expungeHandler: async payload => await this.expungeHandler(payload)
1241
+ })
1242
+ );
1243
+ this.connections.add(imapClient);
1244
+ await this.redis.hSetExists(this.getAccountKey(), 'connections', this.connections.size.toString());
1245
+
1246
+ imapClient.log.debug({ msg: 'Created primary client' });
1247
+
1248
+ this.imapClient = imapClient;
1249
+
1250
+ // Mark as primary connection
1251
+ imapClient.primaryConnection = true;
1252
+
1253
+ // Forward IMAP logs to account logger
1254
+ // if emitLogs option is true then separate log event is fired for every log entry
1255
+ imapClient.on('log', entry => {
1256
+ if (!entry) {
1257
+ return false;
1258
+ }
1259
+
1260
+ if (typeof entry === 'string') {
1261
+ // should not happen
1262
+ entry = { msg: entry };
1263
+ }
1264
+
1265
+ this.accountLogger.log(entry);
1266
+ });
1267
+
1268
+ // Handle connection errors
1269
+ imapClient.on('error', err => {
1270
+ imapClient?.log.error({ msg: 'IMAP connection error', type: 'imapClient', account: this.account, err });
1271
+ if (imapClient !== this.imapClient || this._connecting) {
1272
+ return;
1273
+ }
1274
+ imapClient.close(); // ensure the client is closed on errors
1275
+
1276
+ // Debounced reconnection with exponential backoff
1277
+ if (!this.reconnectTimer) {
1278
+ // Calculate delay with cap
1279
+ this.errorReconnectDelay = Math.min(this.errorReconnectMaxDelay, this.errorReconnectDelay * 1.5);
1280
+
1281
+ this.logger.info({
1282
+ msg: 'Scheduling error-triggered reconnection',
1283
+ delay: this.errorReconnectDelay
1284
+ });
1285
+
1286
+ this.reconnectTimer = setTimeout(() => {
1287
+ this.reconnectTimer = null;
1288
+ this.reconnect()
1289
+ .then(() => {
1290
+ // Reset delay on success
1291
+ this.errorReconnectDelay = 2000;
1292
+ })
1293
+ .catch(err => {
1294
+ this.logger.error({
1295
+ msg: 'IMAP reconnection error',
1296
+ account: this.account,
1297
+ err,
1298
+ nextDelay: this.errorReconnectDelay
1299
+ });
1300
+ });
1301
+ }, this.errorReconnectDelay);
1302
+ }
1303
+ });
1304
+
1305
+ // Track IMAP command/response metrics
1306
+ imapClient.on('response', data => {
1307
+ metricsMeta({}, this.logger, 'imapResponses', 'inc', data);
1308
+
1309
+ // update byte counters as well
1310
+ let imapStats = imapClient.stats(true);
1311
+
1312
+ metricsMeta({}, this.logger, 'imapBytesSent', 'inc', imapStats.sent);
1313
+ metricsMeta({}, this.logger, 'imapBytesReceived', 'inc', imapStats.received);
1314
+ });
1315
+
1316
+ // Handle connection close events
1317
+ imapClient.on('close', async () => {
1318
+ const wasDeleted = this.connections.delete(imapClient);
1319
+
1320
+ if (wasDeleted) {
1321
+ try {
1322
+ await this.redis.hSetExists(this.getAccountKey(), 'connections', this.connections.size.toString());
1323
+ } catch (err) {
1324
+ this.logger.error({ msg: 'Failed to update connection count in Redis', err });
1325
+ }
1326
+ }
1327
+ imapClient?.log.info({ msg: 'Connection closed', type: 'imapClient', account: this.account, disabled: imapClient.disabled });
1328
+
1329
+ // Update state on unexpected disconnect
1330
+ if (['init', 'connecting', 'syncing', 'connected'].includes(this.state)) {
1331
+ this.state = 'disconnected';
1332
+ try {
1333
+ await this.setStateVal();
1334
+ await emitChangeEvent(this.logger, this.account, 'state', this.state);
1335
+ } catch (err) {
1336
+ this.logger.error({ msg: 'Failed to update state on connection close', account: this.account, err });
1337
+ }
1338
+ }
1339
+
1340
+ try {
1341
+ // Handle cleanup for all mailboxes
1342
+ for (let [, mailbox] of this.mailboxes) {
1343
+ if (mailbox.syncing) {
1344
+ try {
1345
+ // set failure flag
1346
+ await this.redis.hSetNew(
1347
+ this.getAccountKey(),
1348
+ 'syncError',
1349
+ JSON.stringify({
1350
+ path: mailbox.path,
1351
+ time: new Date().toISOString(),
1352
+ error: {
1353
+ error: 'Connection closed unexpectedly'
1354
+ }
1355
+ })
1356
+ );
1357
+ } catch (err) {
1358
+ // ignore
1359
+ }
1360
+ }
1361
+
1362
+ if (mailbox.selected) {
1363
+ // should be at most one though
1364
+ await mailbox.onClose();
1365
+ }
1366
+ }
1367
+ } catch (err) {
1368
+ imapClient.log.error({ msg: 'Connection close error', err });
1369
+ }
1370
+
1371
+ try {
1372
+ // Attempt reconnection if this was an unexpected close
1373
+ if (!imapClient.disabled && imapClient === this.imapClient && !this._connecting) {
1374
+ imapClient.log.debug({ msg: 'Requesting reconnection due to unexpected close', type: 'imapClient', account: this.account });
1375
+ await this.reconnect();
1376
+ }
1377
+ } catch (err) {
1378
+ imapClient.log.error({ msg: 'Reconnection error', err });
1379
+ }
1380
+
1381
+ imapClient = null;
1382
+ });
1383
+
1384
+ try {
1385
+ // Establish connection and perform initial sync
1386
+ await this.connect();
1387
+
1388
+ // Check if this is the first successful connection
1389
+ let prevConnectedCount = await this.redis.hget(this.getAccountKey(), `state:count:connected`);
1390
+ let isFirstSuccessfulConnection = prevConnectedCount === '0'; // string zero means the account has been initialized but not yet connected
1391
+
1392
+ let isiInitial = !!isFirstSuccessfulConnection;
1393
+
1394
+ if (!isFirstSuccessfulConnection) {
1395
+ // check if the connection was previously in an errored state
1396
+ let prevLastErrorState = await this.redis.hget(this.getAccountKey(), 'lastErrorState');
1397
+ if (prevLastErrorState) {
1398
+ try {
1399
+ prevLastErrorState = JSON.parse(prevLastErrorState);
1400
+ } catch (err) {
1401
+ // ignore
1402
+ }
1403
+ }
1404
+
1405
+ if (prevLastErrorState && typeof prevLastErrorState === 'object' && Object.keys(prevLastErrorState).length) {
1406
+ // was previously errored
1407
+ isFirstSuccessfulConnection = true;
1408
+ }
1409
+ }
1410
+
1411
+ // Send appropriate notifications based on connection history
1412
+ if (isFirstSuccessfulConnection) {
1413
+ this.logger.info({ msg: 'Successful login without a previous active session', account: this.account, isiInitial, prevActive: false });
1414
+ await this.notify(false, AUTH_SUCCESS_NOTIFY, {
1415
+ user: imapConfig.auth.user
1416
+ });
1417
+ } else {
1418
+ this.logger.info({ msg: 'Successful login with a previous active session', account: this.account, isiInitial, prevActive: true });
1419
+ }
1420
+
1421
+ // Set up subconnections for monitoring multiple folders
1422
+ this.setupSubConnections()
1423
+ .then(result => {
1424
+ this.logger.info({ msg: 'Set up subconnections', account: this.account, result });
1425
+ })
1426
+ .catch(err => {
1427
+ this.logger.error({ msg: 'Failed to set up subconnections', account: this.account, err });
1428
+ });
1429
+ } catch (err) {
1430
+ // Handle various authentication and connection errors
1431
+ if (err.oauthError && err.oauthError.status === 'invalid_request') {
1432
+ // access token is invalid, clear it
1433
+ try {
1434
+ await this.accountObject.invalidateAccessToken();
1435
+ } catch (err) {
1436
+ this.logger.error({ msg: 'Failed to invalidate OAuth2 access token', account: this.account, err });
1437
+ }
1438
+ }
1439
+
1440
+ if (err.authenticationFailed) {
1441
+ this.logger.error({ msg: 'Failed to authenticate', account: this.account, err });
1442
+ await this.notify(false, AUTH_ERROR_NOTIFY, {
1443
+ response: err.response,
1444
+ serverResponseCode: err.serverResponseCode
1445
+ });
1446
+ this.state = 'authenticationError';
1447
+ } else {
1448
+ this.logger.error({ msg: 'Failed to connect', account: this.account, err });
1449
+ await this.notify(false, CONNECT_ERROR_NOTIFY, {
1450
+ response: err.response || err.message,
1451
+ serverResponseCode: err.serverResponseCode || err.code
1452
+ });
1453
+ this.state = 'connectError';
1454
+ }
1455
+ throw err;
1456
+ }
1457
+ } finally {
1458
+ // Update state if it changed during connection
1459
+ if (this.state !== initialState) {
1460
+ // update state
1461
+ try {
1462
+ let existingState = await this.redis.hget(this.getAccountKey(), 'state');
1463
+ if (existingState !== this.state) {
1464
+ await this.setStateVal();
1465
+ await emitChangeEvent(this.logger, this.account, 'state', this.state);
1466
+ }
1467
+ } catch (err) {
1468
+ // ignore
1469
+ }
1470
+ }
1471
+ }
1472
+ }
1473
+
1474
+ /**
1475
+ * Initializes the IMAP client and starts the connection
1476
+ */
1477
+ async init() {
1478
+ await this.reconnect();
1479
+ }
1480
+
1481
+ /**
1482
+ * Deletes the account and cleans up all resources
1483
+ * This permanently removes all cached data
1484
+ */
1485
+ async delete() {
1486
+ if (this.isClosed || this.isClosing) {
1487
+ return;
1488
+ }
1489
+ this.isClosing = true;
1490
+
1491
+ if (this.imapClient) {
1492
+ this.imapClient.disabled = true;
1493
+ this.imapClient.close();
1494
+ if (this.commandClient) {
1495
+ this.commandClient.close();
1496
+ }
1497
+ }
1498
+
1499
+ // Clear all timers
1500
+ clearTimeout(this.refreshListingTimer);
1501
+ clearTimeout(this.untaggedExpungeTimer);
1502
+ clearTimeout(this.resyncTimer);
1503
+ clearTimeout(this.completedTimer);
1504
+
1505
+ try {
1506
+ // Clean up all mailboxes
1507
+ for (let [, mailbox] of this.mailboxes) {
1508
+ if (mailbox.selected) {
1509
+ await mailbox.onClose();
1510
+ }
1511
+ await mailbox.clear({ skipNotify: true });
1512
+ mailbox = false;
1513
+ }
1514
+
1515
+ // Remove mailbox listing from Redis
1516
+ await this.redis.del(this.getMailboxListKey());
1517
+ } finally {
1518
+ this.isClosing = false;
1519
+ this.isClosed = true;
1520
+ }
1521
+
1522
+ this.logger.info({ msg: 'Closed account', account: this.account });
1523
+ }
1524
+
1525
+ /**
1526
+ * Closes the IMAP connection without deleting account data
1527
+ * Can be reopened later
1528
+ */
1529
+ close() {
1530
+ if (this.isClosed || this.isClosing) {
1531
+ return;
1532
+ }
1533
+ this.isClosing = true;
1534
+
1535
+ if (this.imapClient) {
1536
+ this.imapClient.close();
1537
+ }
1538
+
1539
+ if (this.commandClient) {
1540
+ this.commandClient.close();
1541
+ }
1542
+
1543
+ clearTimeout(this.refreshListingTimer);
1544
+ clearTimeout(this.untaggedExpungeTimer);
1545
+ clearTimeout(this.resyncTimer);
1546
+ clearTimeout(this.completedTimer);
1547
+
1548
+ this.isClosing = false;
1549
+ this.isClosed = true;
1550
+
1551
+ this.closeSubconnections();
1552
+ }
1553
+
1554
+ /**
1555
+ * Checks if the IMAP connection is active and usable
1556
+ * @returns {boolean} Connection status
1557
+ */
1558
+ isConnected() {
1559
+ return this.imapClient && this.imapClient.usable && !this.isClosing && !this.isClosed;
1560
+ }
1561
+
1562
+ /**
1563
+ * Gets the current connection state
1564
+ * @returns {string} Current state
1565
+ */
1566
+ async currentState() {
1567
+ if (this.state === 'connected' && !this.isConnected()) {
1568
+ this.state = 'disconnected';
1569
+ }
1570
+ return this.state;
1571
+ }
1572
+
1573
+ /**
1574
+ * Validates that IMAP connection is available
1575
+ * @param {Object} connectionOptions - Connection options
1576
+ * @throws {Error} If connection is not available
1577
+ */
1578
+ checkIMAPConnection(connectionOptions) {
1579
+ connectionOptions = connectionOptions || {};
1580
+
1581
+ if (
1582
+ !this.isConnected() &&
1583
+ !connectionOptions.noPool &&
1584
+ !connectionOptions.allowSecondary &&
1585
+ (!connectionOptions.connectionClient || !connectionOptions.connectionClient.usable)
1586
+ ) {
1587
+ let err = new Error('IMAP connection is currently not available for requested account');
1588
+ err.code = 'IMAPUnavailable';
1589
+ err.statusCode = 503;
1590
+ throw err;
1591
+ }
1592
+ }
1593
+
1594
+ // Mailbox level user methods
1595
+
1596
+ /**
1597
+ * Fetch message text from IMAP. Resulting value is a unicode string.
1598
+ *
1599
+ * @param {string} textId ID of the text content
1600
+ * @param {object} [options] Options object
1601
+ * @param {number} [options.maxLength] If set then limits output stream to specified chars (NB! not bytes but unicode characters). Limit applies to each text type separately, so 1000 would mean you'd get a 1000 char string for plaintext and 1000 char string for html.
1602
+ * @param {string} [options.contentType] If set then limits output for selected type only
1603
+ * @returns {Object} Text object, where key is text type (either 'plain' or 'html') and value is a unicode string
1604
+ */
1605
+ async getText(textId, options, connectionOptions) {
1606
+ options = options || {};
1607
+ connectionOptions = connectionOptions || { allowSecondary: true };
1608
+
1609
+ this.checkIMAPConnection(connectionOptions);
1610
+
1611
+ let { message, textParts } = await this.getMessageTextPaths(textId);
1612
+ if (!message || !textParts || !textParts.length) {
1613
+ return false;
1614
+ }
1615
+
1616
+ if (!this.mailboxes.has(normalizePath(message.path))) {
1617
+ return false; //?
1618
+ }
1619
+
1620
+ let mailbox = this.mailboxes.get(normalizePath(message.path));
1621
+
1622
+ let textType = (options.textType || '').toLowerCase().trim();
1623
+
1624
+ // Process text parts based on requested type
1625
+ if (Array.isArray(textParts)) {
1626
+ let re = /^\d+(\.\d+)*$/;
1627
+ switch (textType) {
1628
+ case 'plain':
1629
+ textParts = Array.isArray(textParts[0]) ? textParts[0].filter(entry => re.test(entry)) : false;
1630
+ break;
1631
+ case 'html':
1632
+ textParts = Array.isArray(textParts[1]) ? textParts[1].filter(entry => re.test(entry)) : false;
1633
+ break;
1634
+ default:
1635
+ textParts = textParts.flatMap(part => part).filter(entry => re.test(entry));
1636
+ break;
1637
+ }
1638
+ } else {
1639
+ textParts = [];
1640
+ }
1641
+
1642
+ let result = await mailbox.getText(message, textParts, options, connectionOptions);
1643
+
1644
+ // Filter result based on requested type
1645
+ if (textType && textType !== '*') {
1646
+ result = {
1647
+ [textType]: result[textType] || '',
1648
+ hasMore: result.hasMore
1649
+ };
1650
+ }
1651
+
1652
+ return result;
1653
+ }
1654
+
1655
+ /**
1656
+ * Retrieves a complete message by ID
1657
+ * @param {string} id - Message ID
1658
+ * @param {Object} options - Retrieval options
1659
+ * @param {Object} connectionOptions - Connection options
1660
+ * @returns {Object|false} Message object or false if not found
1661
+ */
1662
+ async getMessage(id, options, connectionOptions) {
1663
+ options = options || {};
1664
+ connectionOptions = connectionOptions || { allowSecondary: true };
1665
+
1666
+ this.checkIMAPConnection(connectionOptions);
1667
+
1668
+ let buf = Buffer.from(id, 'base64url');
1669
+ let message = await this.unpackUid(buf.subarray(0, 8));
1670
+ if (!message) {
1671
+ return false;
1672
+ }
1673
+
1674
+ if (!this.mailboxes.has(normalizePath(message.path))) {
1675
+ return false; //?
1676
+ }
1677
+
1678
+ let mailbox = this.mailboxes.get(normalizePath(message.path));
1679
+
1680
+ return await mailbox.getMessage(message, options, connectionOptions);
1681
+ }
1682
+
1683
+ /**
1684
+ * Updates message flags/labels
1685
+ * @param {string} id - Message ID
1686
+ * @param {Object} updates - Update operations (e.g., flags to add/remove)
1687
+ * @param {Object} connectionOptions - Connection options
1688
+ * @returns {Object|false} Update result or false if failed
1689
+ */
1690
+ async updateMessage(id, updates, connectionOptions) {
1691
+ updates = updates || {};
1692
+ connectionOptions = connectionOptions || { allowSecondary: true };
1693
+
1694
+ this.checkIMAPConnection(connectionOptions);
1695
+
1696
+ let buf = Buffer.from(id, 'base64url');
1697
+ let message = await this.unpackUid(buf.subarray(0, 8));
1698
+ if (!message) {
1699
+ return false;
1700
+ }
1701
+
1702
+ if (!this.mailboxes.has(normalizePath(message.path))) {
1703
+ return false; //?
1704
+ }
1705
+
1706
+ let mailbox = this.mailboxes.get(normalizePath(message.path));
1707
+
1708
+ return await mailbox.updateMessage(message, updates, connectionOptions);
1709
+ }
1710
+
1711
+ /**
1712
+ * Updates multiple messages matching search criteria
1713
+ * @param {string} path - Mailbox path
1714
+ * @param {Object} search - Search criteria
1715
+ * @param {Object} updates - Update operations
1716
+ * @param {Object} connectionOptions - Connection options
1717
+ * @returns {Object|false} Update result or false if failed
1718
+ */
1719
+ async updateMessages(path, search, updates, connectionOptions) {
1720
+ updates = updates || {};
1721
+ connectionOptions = connectionOptions || { allowSecondary: true };
1722
+
1723
+ this.checkIMAPConnection(connectionOptions);
1724
+
1725
+ if (!this.mailboxes.has(normalizePath(path))) {
1726
+ return false; //?
1727
+ }
1728
+
1729
+ let mailbox = this.mailboxes.get(normalizePath(path));
1730
+
1731
+ return await mailbox.updateMessages(search, updates, connectionOptions);
1732
+ }
1733
+
1734
+ /**
1735
+ * Lists all mailboxes/folders
1736
+ * @param {Object} options - Listing options
1737
+ * @param {Object} connectionOptions - Connection options
1738
+ * @returns {Array} Array of mailbox objects
1739
+ */
1740
+ async listMailboxes(options, connectionOptions) {
1741
+ connectionOptions = connectionOptions || { allowSecondary: true };
1742
+
1743
+ this.checkIMAPConnection(connectionOptions);
1744
+
1745
+ return await this.getCurrentListing(options, connectionOptions);
1746
+ }
1747
+
1748
+ /**
1749
+ * Moves a message to another mailbox
1750
+ * @param {string} id - Message ID
1751
+ * @param {Object} target - Target mailbox info
1752
+ * @param {Object} options - Move options
1753
+ * @param {Object} connectionOptions - Connection options
1754
+ * @returns {Object|false} Move result or false if failed
1755
+ */
1756
+ async moveMessage(id, target, options, connectionOptions) {
1757
+ target = target || {};
1758
+ connectionOptions = connectionOptions || { allowSecondary: true };
1759
+
1760
+ this.checkIMAPConnection(connectionOptions);
1761
+
1762
+ let buf = Buffer.from(id, 'base64url');
1763
+ let message = await this.unpackUid(buf.subarray(0, 8));
1764
+
1765
+ if (!message) {
1766
+ return false;
1767
+ }
1768
+
1769
+ if (!this.mailboxes.has(normalizePath(message.path))) {
1770
+ return false; //?
1771
+ }
1772
+
1773
+ let mailbox = this.mailboxes.get(normalizePath(message.path));
1774
+ return await mailbox.moveMessage(message, target, options, connectionOptions);
1775
+ }
1776
+
1777
+ /**
1778
+ * Moves multiple messages to another mailbox
1779
+ * @param {string} source - Source mailbox path
1780
+ * @param {Object} search - Search criteria
1781
+ * @param {Object} target - Target mailbox info
1782
+ * @param {Object} connectionOptions - Connection options
1783
+ * @returns {Object|false} Move result or false if failed
1784
+ */
1785
+ async moveMessages(source, search, target, connectionOptions) {
1786
+ target = target || {};
1787
+ connectionOptions = connectionOptions || { allowSecondary: true };
1788
+
1789
+ this.checkIMAPConnection(connectionOptions);
1790
+
1791
+ if (!this.mailboxes.has(normalizePath(source))) {
1792
+ return false; //?
1793
+ }
1794
+
1795
+ let mailbox = this.mailboxes.get(normalizePath(source));
1796
+
1797
+ let res = await mailbox.moveMessages(search, target, connectionOptions);
1798
+
1799
+ // force sync target mailbox to show moved messages
1800
+ let targetMailbox = this.mailboxes.get(normalizePath(target.path));
1801
+ if (targetMailbox) {
1802
+ targetMailbox.sync().catch(err => this.logger.error({ msg: 'Mailbox sync error', path: target.path, err }));
1803
+ }
1804
+
1805
+ return res;
1806
+ }
1807
+
1808
+ /**
1809
+ * Deletes a message
1810
+ * @param {string} id - Message ID
1811
+ * @param {boolean} force - Force permanent deletion
1812
+ * @param {Object} connectionOptions - Connection options
1813
+ * @returns {Object|false} Delete result or false if failed
1814
+ */
1815
+ async deleteMessage(id, force, connectionOptions) {
1816
+ connectionOptions = connectionOptions || { allowSecondary: true };
1817
+
1818
+ this.checkIMAPConnection(connectionOptions);
1819
+
1820
+ let buf = Buffer.from(id, 'base64url');
1821
+ let message = await this.unpackUid(buf.subarray(0, 8));
1822
+ if (!message) {
1823
+ return false;
1824
+ }
1825
+
1826
+ if (!this.mailboxes.has(normalizePath(message.path))) {
1827
+ return false; //?
1828
+ }
1829
+
1830
+ let mailbox = this.mailboxes.get(normalizePath(message.path));
1831
+
1832
+ return await mailbox.deleteMessage(message, force, connectionOptions);
1833
+ }
1834
+
1835
+ /**
1836
+ * Deletes multiple messages matching search criteria
1837
+ * @param {string} path - Mailbox path
1838
+ * @param {Object} search - Search criteria
1839
+ * @param {boolean} force - Force permanent deletion
1840
+ * @param {Object} connectionOptions - Connection options
1841
+ * @returns {Object|false} Delete result or false if failed
1842
+ */
1843
+ async deleteMessages(path, search, force, connectionOptions) {
1844
+ connectionOptions = connectionOptions || { allowSecondary: true };
1845
+
1846
+ this.checkIMAPConnection(connectionOptions);
1847
+
1848
+ if (!this.mailboxes.has(normalizePath(path))) {
1849
+ return false; //?
1850
+ }
1851
+
1852
+ let mailbox = this.mailboxes.get(normalizePath(path));
1853
+ let res = await mailbox.deleteMessages(search, force, connectionOptions);
1854
+
1855
+ // force sync target mailbox if messages were moved to trash
1856
+ if (res && res.moved && res.moved.destination) {
1857
+ let targetMailbox = this.mailboxes.get(normalizePath(res.moved.destination));
1858
+ if (targetMailbox) {
1859
+ targetMailbox.sync().catch(err => this.logger.error({ msg: 'Mailbox sync error', path: res && res.moved && res.moved.destination, err }));
1860
+ }
1861
+ }
1862
+
1863
+ return res;
1864
+ }
1865
+
1866
+ /**
1867
+ * Downloads an attachment from IMAP as a binary stream
1868
+ *
1869
+ * @param {string} attachmentId ID of the attachment
1870
+ * @param {object} [options] Options object
1871
+ * @param {number} [options.maxLength] If set then limits output stream to specified bytes
1872
+ * @returns {Boolean|Stream} Attachment stream or `false` if not found
1873
+ */
1874
+ async getAttachment(attachmentId, options, connectionOptions) {
1875
+ options = Object.assign(
1876
+ {
1877
+ chunkSize: DOWNLOAD_CHUNK_SIZE
1878
+ },
1879
+ options || {}
1880
+ );
1881
+ connectionOptions = connectionOptions || { allowSecondary: true };
1882
+
1883
+ this.checkIMAPConnection(connectionOptions);
1884
+
1885
+ // Unpack attachment ID to get message location and part number
1886
+ let buf = Buffer.from(attachmentId, 'base64url');
1887
+ let id = buf.subarray(0, 8);
1888
+ let part = buf.subarray(8).toString();
1889
+
1890
+ let message = await this.unpackUid(id);
1891
+ if (!message) {
1892
+ return false;
1893
+ }
1894
+
1895
+ if (!this.mailboxes.has(normalizePath(message.path))) {
1896
+ return false; //?
1897
+ }
1898
+
1899
+ let mailbox = this.mailboxes.get(normalizePath(message.path));
1900
+
1901
+ return mailbox.getAttachment(message, part, options, connectionOptions);
1902
+ }
1903
+
1904
+ /**
1905
+ * Downloads attachment content as a buffer
1906
+ * @param {string} attachmentId - Attachment ID
1907
+ * @param {Object} options - Download options
1908
+ * @param {Object} connectionOptions - Connection options
1909
+ * @returns {Buffer|false} Attachment content or false if not found
1910
+ */
1911
+ async getAttachmentContent(attachmentId, options, connectionOptions) {
1912
+ let stream = await this.getAttachment(attachmentId, options, connectionOptions);
1913
+ if (!stream) {
1914
+ return false;
1915
+ }
1916
+
1917
+ return new Promise((resolve, reject) => {
1918
+ let chunks = [];
1919
+ let chunklen = 0;
1920
+ stream.on('error', reject);
1921
+ stream.on('readable', () => {
1922
+ let chunk;
1923
+ while ((chunk = stream.read()) !== null) {
1924
+ chunks.push(chunk);
1925
+ chunklen += chunk.length;
1926
+ }
1927
+ });
1928
+ stream.on('end', () => resolve(Buffer.concat(chunks, chunklen)));
1929
+ });
1930
+ }
1931
+
1932
+ /**
1933
+ * Downloads raw message from IMAP as a binary stream
1934
+ *
1935
+ * @param {string} id ID of the message
1936
+ * @param {object} [options] Options object
1937
+ * @param {number} [options.maxLength] If set then limits output stream to specified bytes
1938
+ * @returns {Boolean|Stream} Attachment stream or `false` if not found
1939
+ */
1940
+ async getRawMessage(id, options, connectionOptions) {
1941
+ options = Object.assign(
1942
+ {
1943
+ chunkSize: DOWNLOAD_CHUNK_SIZE
1944
+ },
1945
+ options || {}
1946
+ );
1947
+ connectionOptions = connectionOptions || { allowSecondary: true };
1948
+
1949
+ this.checkIMAPConnection(connectionOptions);
1950
+
1951
+ let buf = Buffer.from(id, 'base64url');
1952
+ let message = await this.unpackUid(buf.subarray(0, 8));
1953
+ if (!message) {
1954
+ return false;
1955
+ }
1956
+
1957
+ if (!this.mailboxes.has(normalizePath(message.path))) {
1958
+ return false; //?
1959
+ }
1960
+
1961
+ let mailbox = this.mailboxes.get(normalizePath(message.path));
1962
+
1963
+ // Use false as part to get the entire message
1964
+ return mailbox.getAttachment(message, false, options, connectionOptions);
1965
+ }
1966
+
1967
+ /**
1968
+ * Lists messages in a mailbox with pagination and search
1969
+ * @param {Object} options - Listing options including path, search criteria, pagination
1970
+ * @param {Object} connectionOptions - Connection options
1971
+ * @returns {Object|false} Message listing or false if failed
1972
+ */
1973
+ async listMessages(options, connectionOptions) {
1974
+ options = options || {};
1975
+ connectionOptions = connectionOptions || { allowSecondary: true };
1976
+
1977
+ this.checkIMAPConnection(connectionOptions);
1978
+
1979
+ let path = normalizePath(options.path);
1980
+
1981
+ // Handle special-use folder aliases
1982
+ if (['\\Junk', '\\Sent', '\\Trash', '\\Inbox', '\\Drafts', '\\All'].includes(path)) {
1983
+ let resolvedPath = await this.getSpecialUseMailbox(path);
1984
+ if (resolvedPath) {
1985
+ path = resolvedPath.path;
1986
+ }
1987
+ }
1988
+
1989
+ if (!this.mailboxes.has(path)) {
1990
+ return false; //?
1991
+ }
1992
+
1993
+ let mailbox = this.mailboxes.get(path);
1994
+
1995
+ let listing = await mailbox.listMessages(options, connectionOptions);
1996
+ return listing;
1997
+ }
1998
+
1999
+ /**
2000
+ * Deletes a mailbox/folder
2001
+ * @param {string} path - Mailbox path to delete
2002
+ * @param {Object} connectionOptions - Connection options
2003
+ * @returns {Object} Delete result
2004
+ */
2005
+ async deleteMailbox(path, connectionOptions) {
2006
+ connectionOptions = connectionOptions || { allowSecondary: true };
2007
+
2008
+ this.checkIMAPConnection(connectionOptions);
2009
+
2010
+ const connectionClient = await this.getImapConnection(connectionOptions, 'deleteMailbox');
2011
+
2012
+ let result = {
2013
+ path,
2014
+ deleted: false // set to true if mailbox is actually deleted
2015
+ };
2016
+
2017
+ try {
2018
+ // Acquire lock to prevent concurrent operations on the mailbox
2019
+ let lock = await connectionClient.getMailboxLock(path, { description: `Delete mailbox ${path}` });
2020
+
2021
+ try {
2022
+ await connectionClient.mailboxClose();
2023
+ try {
2024
+ await connectionClient.mailboxDelete(path);
2025
+ result.deleted = true;
2026
+ } catch (err) {
2027
+ // kind of ignore
2028
+ }
2029
+ } finally {
2030
+ lock.release();
2031
+ }
2032
+ } catch (err) {
2033
+ this.logger.debug({ msg: 'Mailbox select error', path, err });
2034
+ }
2035
+
2036
+ // Clean up local cache
2037
+ if (this.mailboxes.has(normalizePath(path))) {
2038
+ let mailbox = this.mailboxes.get(normalizePath(path));
2039
+ await mailbox.clear();
2040
+ mailbox = false;
2041
+ }
2042
+
2043
+ return result;
2044
+ }
2045
+
2046
+ /**
2047
+ * Refreshes mailbox listing after account configuration changes
2048
+ * @param {Object} accountData - Account data with path configuration
2049
+ */
2050
+ runPostListing(accountData) {
2051
+ const accountPaths = [].concat(accountData.path || '*');
2052
+ if (!accountPaths.length) {
2053
+ accountPaths.push('*');
2054
+ }
2055
+
2056
+ this.getCurrentListing()
2057
+ .then(listing => {
2058
+ let syncNeeded = new Set();
2059
+ for (let entry of listing) {
2060
+ if (
2061
+ // previously unseen
2062
+ !this.mailboxes.has(normalizePath(entry.path))
2063
+ ) {
2064
+ // Apply filtering based on account configuration
2065
+ if (!accountPaths.includes('*')) {
2066
+ if (!accountPaths.includes(entry.path) && !accountPaths.includes(entry.specialUse)) {
2067
+ // ignore changes
2068
+ entry.syncDisabled = true;
2069
+ }
2070
+ } else if (this.isGmail && !['\\All', '\\Junk', '\\Trash'].includes(entry.specialUse)) {
2071
+ // do not look for changes from this folder
2072
+ entry.syncDisabled = true;
2073
+ }
2074
+
2075
+ let mailbox = new Mailbox(this, entry);
2076
+ this.mailboxes.set(normalizePath(entry.path), mailbox);
2077
+ syncNeeded.add(mailbox);
2078
+ }
2079
+ }
2080
+
2081
+ let runSyncs = async () => {
2082
+ // sync new mailboxes
2083
+ for (let mailbox of syncNeeded) {
2084
+ await mailbox.sync(true);
2085
+ }
2086
+ };
2087
+
2088
+ return runSyncs();
2089
+ })
2090
+ .catch(err => {
2091
+ this.logger.error({ msg: 'List refresh error', err });
2092
+ });
2093
+ }
2094
+
2095
+ /**
2096
+ * Gets IMAP quota information
2097
+ * @param {Object} connectionOptions - Connection options
2098
+ * @returns {Object|false} Quota info or false if not supported
2099
+ */
2100
+ async getQuota(connectionOptions) {
2101
+ connectionOptions = connectionOptions || { allowSecondary: true };
2102
+
2103
+ this.checkIMAPConnection(connectionOptions);
2104
+
2105
+ const connectionClient = await this.getImapConnection(connectionOptions, 'getQuota');
2106
+
2107
+ try {
2108
+ let result = await connectionClient.getQuota();
2109
+ return (result && result.storage) || false;
2110
+ } catch (err) {
2111
+ if (err.serverResponseCode) {
2112
+ let error = new Error('Quota request failed');
2113
+ error.info = {
2114
+ response: err.response && typeof err.response === 'string' && err.response.replace(/^[^\s]*\s*/, '')
2115
+ };
2116
+ error.code = err.serverResponseCode;
2117
+ error.statusCode = 400;
2118
+ throw error;
2119
+ } else if (err.responseStatus === 'NO') {
2120
+ return false;
2121
+ } else {
2122
+ throw err;
2123
+ }
2124
+ }
2125
+ }
2126
+
2127
+ /**
2128
+ * Creates a new mailbox/folder
2129
+ * @param {string} path - Mailbox path to create
2130
+ * @param {Object} connectionOptions - Connection options
2131
+ * @returns {Object} Create result
2132
+ */
2133
+ async createMailbox(path, connectionOptions) {
2134
+ connectionOptions = connectionOptions || { allowSecondary: true };
2135
+
2136
+ this.checkIMAPConnection(connectionOptions);
2137
+
2138
+ const connectionClient = await this.getImapConnection(connectionOptions, 'createMailbox');
2139
+
2140
+ try {
2141
+ let result = await connectionClient.mailboxCreate(path);
2142
+ if (result) {
2143
+ result.created = !!result.created;
2144
+ }
2145
+
2146
+ // Refresh listing to include new mailbox
2147
+ let accountData = await this.accountObject.loadAccountData();
2148
+ setImmediate(() => this.runPostListing(accountData));
2149
+
2150
+ return result;
2151
+ } catch (err) {
2152
+ if (err.serverResponseCode) {
2153
+ let error = new Error('Create failed');
2154
+ error.info = {
2155
+ response: err.response && typeof err.response === 'string' && err.response.replace(/^[^\s]*\s*/, '')
2156
+ };
2157
+ error.code = err.serverResponseCode;
2158
+ error.statusCode = 400;
2159
+ throw error;
2160
+ } else if (err.responseStatus === 'NO') {
2161
+ return {
2162
+ path,
2163
+ created: false
2164
+ };
2165
+ } else {
2166
+ throw err;
2167
+ }
2168
+ }
2169
+ }
2170
+
2171
+ /**
2172
+ * Modifies a mailbox (rename and/or change subscription status)
2173
+ * @param {string} path - Current mailbox path
2174
+ * @param {string|Array<string>} newPath - New mailbox path (optional)
2175
+ * @param {boolean} subscribed - Subscription status (optional)
2176
+ * @param {Object} connectionOptions - Connection options
2177
+ * @returns {Object} Modify result
2178
+ */
2179
+ async modifyMailbox(path, newPath, subscribed, connectionOptions) {
2180
+ connectionOptions = connectionOptions || { allowSecondary: true };
2181
+
2182
+ this.checkIMAPConnection(connectionOptions);
2183
+
2184
+ const connectionClient = await this.getImapConnection(connectionOptions, 'modifyMailbox');
2185
+
2186
+ let result = {};
2187
+
2188
+ // Handle rename if newPath is provided and different from path
2189
+ if (newPath) {
2190
+ let normalizedNewPath = [].concat(newPath || []).join('/');
2191
+ let normalizedPath = [].concat(path || []).join('/');
2192
+
2193
+ if (normalizedNewPath !== normalizedPath) {
2194
+ try {
2195
+ let renameResult = await connectionClient.mailboxRename(path, newPath);
2196
+ if (renameResult) {
2197
+ result.path = renameResult.path;
2198
+ result.newPath = renameResult.newPath;
2199
+ result.renamed = !!renameResult.newPath;
2200
+ path = renameResult.newPath;
2201
+
2202
+ // Subscribe to renamed mailbox if not explicitly managing subscription
2203
+ if (subscribed === undefined) {
2204
+ try {
2205
+ await connectionClient.mailboxSubscribe(renameResult.newPath);
2206
+ } catch (err) {
2207
+ this.logger.debug({ msg: 'Failed to subscribe mailbox', path: renameResult.newPath, err });
2208
+ }
2209
+ }
2210
+ }
2211
+ } catch (err) {
2212
+ if (err.serverResponseCode && err.serverResponseCode !== 'ALREADYEXISTS') {
2213
+ let error = new Error('Rename failed');
2214
+ error.info = {
2215
+ response: err.response
2216
+ };
2217
+ error.code = err.serverResponseCode;
2218
+ error.statusCode = 400;
2219
+ throw error;
2220
+ } else if (err.responseStatus === 'NO') {
2221
+ let error = new Error('Can not rename mailbox');
2222
+ error.info = {
2223
+ response: err.response && typeof err.response === 'string' && err.response.replace(/^[^\s]*\s*/, '')
2224
+ };
2225
+ error.code = err.serverResponseCode;
2226
+ error.statusCode = 400;
2227
+ throw error;
2228
+ } else {
2229
+ throw err;
2230
+ }
2231
+ }
2232
+ } else {
2233
+ result.path = normalizedPath;
2234
+ result.renamed = false;
2235
+ }
2236
+ } else {
2237
+ result.path = [].concat(path || []).join('/');
2238
+ }
2239
+
2240
+ // Handle subscription change if explicitly specified
2241
+ if (subscribed !== undefined) {
2242
+ try {
2243
+ if (subscribed) {
2244
+ await connectionClient.mailboxSubscribe(path);
2245
+ } else {
2246
+ await connectionClient.mailboxUnsubscribe(path);
2247
+ }
2248
+ result.subscribed = subscribed;
2249
+ } catch (err) {
2250
+ this.logger.debug({ msg: 'Failed to change subscription status', path, subscribed, err });
2251
+ }
2252
+ }
2253
+
2254
+ // Refresh listing to update mailbox paths
2255
+ let accountData = await this.accountObject.loadAccountData();
2256
+ setImmediate(() => this.runPostListing(accountData));
2257
+
2258
+ return result;
2259
+ }
2260
+
2261
+ /**
2262
+ * Gets a mailbox by its special-use flag
2263
+ * @param {string} specialUse - Special-use flag (e.g., '\\Sent', '\\Drafts')
2264
+ * @returns {Object|undefined} Mailbox info if found
2265
+ */
2266
+ async getSpecialUseMailbox(specialUse) {
2267
+ let storedListing = await this.redis.hgetallBuffer(this.getMailboxListKey());
2268
+ return Object.keys(storedListing || {})
2269
+ .map(path => {
2270
+ try {
2271
+ return msgpack.decode(storedListing[path]);
2272
+ } catch (err) {
2273
+ // should not happen
2274
+ }
2275
+ return false;
2276
+ })
2277
+ .filter(entry => entry)
2278
+ .find(entry => entry.specialUse === specialUse);
2279
+ }
2280
+
2281
+ /**
2282
+ * Uploads a message to a mailbox
2283
+ * @param {Object} data - Message data including path, flags, content
2284
+ * @param {Object} connectionOptions - Connection options
2285
+ * @returns {Object} Upload result with message ID
2286
+ */
2287
+ async uploadMessage(data, connectionOptions) {
2288
+ connectionOptions = connectionOptions || { allowSecondary: true };
2289
+
2290
+ this.checkIMAPConnection(connectionOptions);
2291
+
2292
+ const connectionClient = await this.getImapConnection(connectionOptions, 'uploadMessage');
2293
+
2294
+ // Prepare raw message for upload
2295
+ let { raw, messageId, documentStoreUsed, referencedMessage } = await this.prepareRawMessage(data, null, { connectionClient });
2296
+
2297
+ // Upload message to selected folder
2298
+ try {
2299
+ let response = {};
2300
+
2301
+ let uploadResponse = await connectionClient.append(data.path, raw, data.flags, data.internalDate);
2302
+
2303
+ // Return to IDLE if using primary connection
2304
+ if (connectionClient === this.imapClient && this.imapClient.mailbox && !this.imapClient.idling) {
2305
+ // force back to IDLE
2306
+ this.imapClient.idle().catch(err => {
2307
+ this.logger.error({ msg: 'IDLE error', err });
2308
+ });
2309
+ }
2310
+
2311
+ // Pack response data
2312
+ if (uploadResponse.uid) {
2313
+ response.id = await this.packUid(uploadResponse.path || data.path, uploadResponse.uid);
2314
+ }
2315
+
2316
+ response.path = uploadResponse.path;
2317
+
2318
+ if (uploadResponse.uid) {
2319
+ response.uid = uploadResponse.uid;
2320
+ }
2321
+
2322
+ if (validUidValidity(uploadResponse.uidValidity)) {
2323
+ response.uidValidity = uploadResponse.uidValidity.toString();
2324
+ }
2325
+
2326
+ if (uploadResponse.seq) {
2327
+ response.seq = uploadResponse.seq;
2328
+ }
2329
+
2330
+ if (messageId) {
2331
+ response.messageId = messageId;
2332
+ }
2333
+
2334
+ // Include reference information if provided
2335
+ if (data.reference && data.reference.message) {
2336
+ response.reference = {
2337
+ message: data.reference.message,
2338
+ documentStore: documentStoreUsed,
2339
+ success: referencedMessage ? true : false
2340
+ };
2341
+
2342
+ if (!referencedMessage) {
2343
+ response.reference.error = 'Referenced message was not found';
2344
+ }
2345
+ }
2346
+
2347
+ return response;
2348
+ } catch (err) {
2349
+ if (err.mailboxMissing) {
2350
+ // this mailbox is missing, refresh listing
2351
+ try {
2352
+ await this.getCurrentListing(false, { connectionClient });
2353
+ } catch (E) {
2354
+ this.logger.error({ msg: 'Missing mailbox', err, E });
2355
+ }
2356
+ }
2357
+
2358
+ err.code = 'UploadFail';
2359
+ err.statusCode = 502;
2360
+ throw err;
2361
+ }
2362
+ }
2363
+
2364
+ /**
2365
+ * Handles EXPUNGE and VANISHED notifications in order
2366
+ * @param {Object} payload - Expunge event data
2367
+ */
2368
+ async expungeHandler(payload) {
2369
+ if (!payload || !payload.path || !this.mailboxes.has(normalizePath(payload.path))) {
2370
+ return; //?
2371
+ }
2372
+
2373
+ let mailbox = this.mailboxes.get(normalizePath(payload.path));
2374
+ try {
2375
+ await mailbox.onExpunge(payload);
2376
+ } catch (err) {
2377
+ this.logger.error({ msg: 'Expunge error', err });
2378
+ }
2379
+ }
2380
+
2381
+ /**
2382
+ * Sets up subconnections for monitoring multiple folders simultaneously
2383
+ * @returns {number|null} Number of subconnections created
2384
+ */
2385
+ async setupSubConnections() {
2386
+ const accountData = await this.accountObject.loadAccountData();
2387
+
2388
+ if (!accountData.subconnections?.length && !this.subconnections.length) {
2389
+ // Nothing to do here
2390
+ return null;
2391
+ }
2392
+
2393
+ const mailboxes = [];
2394
+
2395
+ const listing = await this.getCurrentListing(false, { allowSecondary: true });
2396
+
2397
+ // Process each configured subconnection
2398
+ for (const path of accountData.subconnections || []) {
2399
+ const entry = listing.find(entry => path === entry.path || path === entry.specialUse);
2400
+
2401
+ if (!entry) {
2402
+ // Mailbox not found - mark as disabled
2403
+ mailboxes.push({
2404
+ path,
2405
+ disabled: true,
2406
+ state: 'disabled',
2407
+ disabledReason: 'Mailbox folder not found'
2408
+ });
2409
+ continue;
2410
+ }
2411
+
2412
+ const accountPaths = [].concat(accountData.path || '*');
2413
+ if (!accountPaths.length) {
2414
+ accountPaths.push('*');
2415
+ }
2416
+
2417
+ // Check if already covered by primary connection
2418
+ if (accountPaths[0] === entry.path) {
2419
+ mailboxes.push({
2420
+ path: entry.path,
2421
+ disabled: true,
2422
+ state: 'disabled',
2423
+ disabledReason: 'Covered by the primary connection'
2424
+ });
2425
+ continue;
2426
+ }
2427
+
2428
+ // Gmail-specific checks
2429
+ if (this.isGmail && accountPaths.includes('*') && !['\\Trash', '\\Junk'].includes(entry.specialUse)) {
2430
+ // no need to check this folder, as \All already covers it
2431
+ this.logger.info({ msg: 'Skip subconnection', path, reason: 'Covered by the All Mail folder' });
2432
+ mailboxes.push({
2433
+ path: entry.path,
2434
+ disabled: true,
2435
+ state: 'disabled',
2436
+ disabledReason: 'Covered by the "All Mail" folder'
2437
+ });
2438
+ continue;
2439
+ }
2440
+
2441
+ // Non-Gmail checks
2442
+ if (!this.isGmail && accountPaths.includes('*') && entry.specialUse === '\\Inbox') {
2443
+ // already the default
2444
+ this.logger.info({ msg: 'Skip subconnection', path, reason: 'Trying to use the default folder' });
2445
+ mailboxes.push({
2446
+ path: entry.path,
2447
+ disabled: true,
2448
+ state: 'disabled',
2449
+ disabledReason: 'Can not use the default folder'
2450
+ });
2451
+ continue;
2452
+ }
2453
+
2454
+ mailboxes.push(entry);
2455
+ }
2456
+
2457
+ // remove unneeded subconnections
2458
+ for (let i = this.subconnections.length - 1; i >= 0; i--) {
2459
+ let subconnection = this.subconnections[i];
2460
+ if (!mailboxes.find(mailbox => mailbox.path === subconnection.path)) {
2461
+ // not listed anymore
2462
+ this.subconnections.splice(i, 1);
2463
+
2464
+ if (!subconnection.disabled) {
2465
+ try {
2466
+ subconnection.removeAllListeners();
2467
+ subconnection.close();
2468
+ } catch (err) {
2469
+ this.logger.error({ msg: 'Failed to close unlisted subconnection', path: subconnection.path, err });
2470
+ }
2471
+ }
2472
+ }
2473
+ }
2474
+
2475
+ // create missing subconnections
2476
+ for (const mailbox of mailboxes) {
2477
+ if (this.subconnections.find(subconnection => mailbox.path === subconnection.path)) {
2478
+ // already exists
2479
+ continue;
2480
+ }
2481
+
2482
+ if (mailbox.disabled) {
2483
+ this.subconnections.push(mailbox);
2484
+ continue;
2485
+ }
2486
+
2487
+ // create new subconnection
2488
+ const subconnection = new Subconnection({
2489
+ parent: this,
2490
+ account: this.account,
2491
+ mailbox,
2492
+ getImapConfig: async () => await this.getImapConfig(),
2493
+ logger: this.logger.child({
2494
+ cid: `${this.cid}:s:${this.connectionCount++}`,
2495
+ channel: 'subconnection',
2496
+ subconnection: mailbox.path
2497
+ })
2498
+ });
2499
+ this.subconnections.push(subconnection);
2500
+
2501
+ // Handle change notifications from subconnection
2502
+ subconnection.on('changes', path => {
2503
+ let mailbox;
2504
+
2505
+ if (this.mailboxes.has(normalizePath(path))) {
2506
+ mailbox = this.mailboxes.get(normalizePath(path));
2507
+ try {
2508
+ mailbox
2509
+ .sync()
2510
+ .then(() => this.ensureMainMailbox())
2511
+ .catch(err => {
2512
+ this.logger.error({ msg: 'Failed to sync mailbox', path, err });
2513
+ });
2514
+ } catch (err) {
2515
+ this.logger.error({ msg: 'Failed to sync mailbox', path, err });
2516
+ }
2517
+ }
2518
+ });
2519
+
2520
+ await subconnection.init();
2521
+ }
2522
+
2523
+ return this.subconnections.length;
2524
+ }
2525
+
2526
+ /**
2527
+ * Closes all subconnections
2528
+ */
2529
+ closeSubconnections() {
2530
+ const subconnections = [...this.subconnections];
2531
+ this.subconnections = [];
2532
+
2533
+ for (let subconnection of subconnections) {
2534
+ if (!subconnection.disabled) {
2535
+ try {
2536
+ subconnection.removeAllListeners();
2537
+ subconnection.close();
2538
+ } catch (err) {
2539
+ this.logger.error({ msg: 'Failed to close unlisted subconnection', path: subconnection.path, err });
2540
+ }
2541
+ }
2542
+ }
2543
+ }
2544
+
2545
+ /**
2546
+ * Pauses the IMAP connection
2547
+ * @returns {boolean} Success status
2548
+ */
2549
+ async pause() {
2550
+ if (this.paused) {
2551
+ return false;
2552
+ }
2553
+ this.paused = true;
2554
+ this.logger.info({ msg: 'Closing connection', action: 'pause' });
2555
+ this.close();
2556
+
2557
+ this.state = 'paused';
2558
+ await this.setStateVal();
2559
+ await emitChangeEvent(this.logger, this.account, 'state', this.state);
2560
+ }
2561
+
2562
+ /**
2563
+ * Resumes a paused IMAP connection
2564
+ * @returns {boolean} Success status
2565
+ */
2566
+ async resume() {
2567
+ if (!this.paused) {
2568
+ return false;
2569
+ }
2570
+ this.paused = false;
2571
+ if (this.isClosed) {
2572
+ this.isClosed = false;
2573
+ }
2574
+
2575
+ this.logger.info({ msg: 'Creating connection', action: 'resume' });
2576
+ // do not wait
2577
+ this.init().catch(err => this.logger.error({ msg: 'Resuming failed', action: 'resume', err }));
2578
+ }
2579
+
2580
+ /**
2581
+ * Lists email signatures (Gmail only via API)
2582
+ * @returns {Object} Signatures list with support status
2583
+ */
2584
+ async listSignatures() {
2585
+ const emptyResponse = { signatures: [], signaturesSupported: false };
2586
+ let accountData = await this.accountObject.loadAccountData();
2587
+
2588
+ if (!accountData.oauth2.provider) {
2589
+ // Not an OAuth2 account
2590
+ return emptyResponse;
2591
+ }
2592
+
2593
+ if (accountData?._app?.provider && !['gmail'].includes(accountData?._app?.provider)) {
2594
+ // Signatures not supported for this provider
2595
+ return emptyResponse;
2596
+ }
2597
+
2598
+ const { accessToken, oauth2App } = await this.loadOAuth2AccountCredentials(accountData, this, 'api');
2599
+
2600
+ if (oauth2App && !this.oAuth2Client) {
2601
+ this.oAuth2Client = await oauth2Apps.getClient(accountData.oauth2.provider, {
2602
+ logger: this.logger,
2603
+ logRaw: this.options.logRaw
2604
+ });
2605
+ }
2606
+
2607
+ if (!oauth2App || !this.oAuth2Client) {
2608
+ return emptyResponse;
2609
+ }
2610
+
2611
+ switch (oauth2App.provider) {
2612
+ case 'gmail': {
2613
+ // Fetch Gmail signatures via API
2614
+ const signatureListRes = await this.oAuth2Client.request(accessToken, `${GMAIL_API_BASE}/gmail/v1/users/me/settings/sendAs`, 'get');
2615
+
2616
+ let signatures = signatureListRes?.sendAs
2617
+ ?.map(entry => ({ address: entry.sendAsEmail, signature: entry.signature }))
2618
+ .filter(entry => entry.signature);
2619
+
2620
+ return { signatures, signaturesSupported: true };
2621
+ }
2622
+ }
2623
+
2624
+ return emptyResponse;
2625
+ }
2626
+ }
2627
+
2628
+ module.exports = { IMAPClient };