├── .env.template
├── .github
├── FUNDING.yml
├── dependabot.yml
└── workflows
│ ├── ci.yml
│ └── release.yml
├── .gitignore
├── .prettierrc.json
├── .tool-versions
├── .vscode
└── settings.json
├── LICENSE
├── README.md
├── babel.config.js
├── eslint.config.mjs
├── flood.png
├── jsconfig.json
├── package-lock.json
├── package.json
├── public
├── browserconfig.xml
├── fonts
│ ├── LICENSE.txt
│ ├── Roboto-500
│ │ ├── Roboto-500.eot
│ │ ├── Roboto-500.svg
│ │ ├── Roboto-500.ttf
│ │ ├── Roboto-500.woff
│ │ └── Roboto-500.woff2
│ ├── Roboto-700
│ │ ├── Roboto-700.eot
│ │ ├── Roboto-700.svg
│ │ ├── Roboto-700.ttf
│ │ ├── Roboto-700.woff
│ │ └── Roboto-700.woff2
│ ├── Roboto-700italic
│ │ ├── Roboto-700italic.eot
│ │ ├── Roboto-700italic.svg
│ │ ├── Roboto-700italic.ttf
│ │ ├── Roboto-700italic.woff
│ │ └── Roboto-700italic.woff2
│ ├── Roboto-italic
│ │ ├── Roboto-italic.eot
│ │ ├── Roboto-italic.svg
│ │ ├── Roboto-italic.ttf
│ │ ├── Roboto-italic.woff
│ │ └── Roboto-italic.woff2
│ └── Roboto-regular
│ │ ├── Roboto-regular.eot
│ │ ├── Roboto-regular.svg
│ │ ├── Roboto-regular.ttf
│ │ ├── Roboto-regular.woff
│ │ └── Roboto-regular.woff2
├── images
│ ├── favicon
│ │ ├── android-chrome-192x192.png
│ │ ├── android-chrome-512x512.png
│ │ ├── apple-touch-icon.png
│ │ ├── favicon-16x16.png
│ │ ├── favicon-32x32.png
│ │ ├── favicon.ico
│ │ ├── mstile-150x150.png
│ │ └── safari-pinned-tab.svg
│ ├── flags
│ │ ├── _unknown.png
│ │ ├── ad.png
│ │ ├── ae.png
│ │ ├── af.png
│ │ ├── ag.png
│ │ ├── ai.png
│ │ ├── al.png
│ │ ├── am.png
│ │ ├── an.png
│ │ ├── ao.png
│ │ ├── aq.png
│ │ ├── ar.png
│ │ ├── as.png
│ │ ├── at.png
│ │ ├── au.png
│ │ ├── aw.png
│ │ ├── ax.png
│ │ ├── az.png
│ │ ├── ba.png
│ │ ├── bb.png
│ │ ├── bd.png
│ │ ├── be.png
│ │ ├── bf.png
│ │ ├── bg.png
│ │ ├── bh.png
│ │ ├── bi.png
│ │ ├── bj.png
│ │ ├── bl.png
│ │ ├── bm.png
│ │ ├── bn.png
│ │ ├── bo.png
│ │ ├── br.png
│ │ ├── bs.png
│ │ ├── bt.png
│ │ ├── bw.png
│ │ ├── by.png
│ │ ├── bz.png
│ │ ├── ca.png
│ │ ├── cc.png
│ │ ├── cd.png
│ │ ├── cf.png
│ │ ├── cg.png
│ │ ├── ch.png
│ │ ├── ci.png
│ │ ├── ck.png
│ │ ├── cl.png
│ │ ├── cm.png
│ │ ├── cn.png
│ │ ├── co.png
│ │ ├── cr.png
│ │ ├── cu.png
│ │ ├── cv.png
│ │ ├── cw.png
│ │ ├── cx.png
│ │ ├── cy.png
│ │ ├── cz.png
│ │ ├── de.png
│ │ ├── dj.png
│ │ ├── dk.png
│ │ ├── dm.png
│ │ ├── do.png
│ │ ├── dz.png
│ │ ├── ec.png
│ │ ├── ee.png
│ │ ├── eg.png
│ │ ├── eh.png
│ │ ├── er.png
│ │ ├── es.png
│ │ ├── et.png
│ │ ├── eu.png
│ │ ├── fi.png
│ │ ├── fj.png
│ │ ├── fk.png
│ │ ├── fm.png
│ │ ├── fo.png
│ │ ├── fr.png
│ │ ├── ga.png
│ │ ├── gb.png
│ │ ├── gd.png
│ │ ├── ge.png
│ │ ├── gg.png
│ │ ├── gh.png
│ │ ├── gi.png
│ │ ├── gl.png
│ │ ├── gm.png
│ │ ├── gn.png
│ │ ├── gq.png
│ │ ├── gr.png
│ │ ├── gs.png
│ │ ├── gt.png
│ │ ├── gu.png
│ │ ├── gw.png
│ │ ├── gy.png
│ │ ├── hk.png
│ │ ├── hn.png
│ │ ├── hr.png
│ │ ├── ht.png
│ │ ├── hu.png
│ │ ├── ic.png
│ │ ├── id.png
│ │ ├── ie.png
│ │ ├── il.png
│ │ ├── im.png
│ │ ├── in.png
│ │ ├── iq.png
│ │ ├── ir.png
│ │ ├── is.png
│ │ ├── it.png
│ │ ├── je.png
│ │ ├── jm.png
│ │ ├── jo.png
│ │ ├── jp.png
│ │ ├── ke.png
│ │ ├── kg.png
│ │ ├── kh.png
│ │ ├── ki.png
│ │ ├── km.png
│ │ ├── kn.png
│ │ ├── kp.png
│ │ ├── kr.png
│ │ ├── kw.png
│ │ ├── ky.png
│ │ ├── kz.png
│ │ ├── la.png
│ │ ├── lb.png
│ │ ├── lc.png
│ │ ├── li.png
│ │ ├── lk.png
│ │ ├── lr.png
│ │ ├── ls.png
│ │ ├── lt.png
│ │ ├── lu.png
│ │ ├── lv.png
│ │ ├── ly.png
│ │ ├── ma.png
│ │ ├── mc.png
│ │ ├── md.png
│ │ ├── me.png
│ │ ├── mf.png
│ │ ├── mg.png
│ │ ├── mh.png
│ │ ├── mk.png
│ │ ├── ml.png
│ │ ├── mm.png
│ │ ├── mn.png
│ │ ├── mo.png
│ │ ├── mp.png
│ │ ├── mq.png
│ │ ├── mr.png
│ │ ├── ms.png
│ │ ├── mt.png
│ │ ├── mu.png
│ │ ├── mv.png
│ │ ├── mw.png
│ │ ├── mx.png
│ │ ├── my.png
│ │ ├── mz.png
│ │ ├── na.png
│ │ ├── nc.png
│ │ ├── ne.png
│ │ ├── nf.png
│ │ ├── ng.png
│ │ ├── ni.png
│ │ ├── nl.png
│ │ ├── no.png
│ │ ├── np.png
│ │ ├── nr.png
│ │ ├── nu.png
│ │ ├── nz.png
│ │ ├── om.png
│ │ ├── pa.png
│ │ ├── pe.png
│ │ ├── pf.png
│ │ ├── pg.png
│ │ ├── ph.png
│ │ ├── pk.png
│ │ ├── pl.png
│ │ ├── pn.png
│ │ ├── pr.png
│ │ ├── ps.png
│ │ ├── pt.png
│ │ ├── pw.png
│ │ ├── py.png
│ │ ├── qa.png
│ │ ├── ro.png
│ │ ├── rs.png
│ │ ├── ru.png
│ │ ├── rw.png
│ │ ├── sa.png
│ │ ├── sb.png
│ │ ├── sc.png
│ │ ├── sd.png
│ │ ├── se.png
│ │ ├── sg.png
│ │ ├── sh.png
│ │ ├── si.png
│ │ ├── sk.png
│ │ ├── sl.png
│ │ ├── sm.png
│ │ ├── sn.png
│ │ ├── so.png
│ │ ├── sr.png
│ │ ├── ss.png
│ │ ├── st.png
│ │ ├── sv.png
│ │ ├── sy.png
│ │ ├── sz.png
│ │ ├── tc.png
│ │ ├── td.png
│ │ ├── tf.png
│ │ ├── tg.png
│ │ ├── th.png
│ │ ├── tj.png
│ │ ├── tk.png
│ │ ├── tl.png
│ │ ├── tm.png
│ │ ├── tn.png
│ │ ├── to.png
│ │ ├── tr.png
│ │ ├── tt.png
│ │ ├── tv.png
│ │ ├── tw.png
│ │ ├── tz.png
│ │ ├── ua.png
│ │ ├── ug.png
│ │ ├── us.png
│ │ ├── uy.png
│ │ ├── uz.png
│ │ ├── va.png
│ │ ├── vc.png
│ │ ├── ve.png
│ │ ├── vg.png
│ │ ├── vi.png
│ │ ├── vn.png
│ │ ├── vu.png
│ │ ├── wf.png
│ │ ├── ws.png
│ │ ├── ye.png
│ │ ├── yt.png
│ │ ├── za.png
│ │ ├── zm.png
│ │ └── zw.png
│ └── flood.svg
├── index.html
├── manifest.webmanifest
└── style
│ ├── colors.css
│ ├── fonts.css
│ └── reset.css
├── rollup.config.mjs
├── screenshots
├── Main - Context menu.png
├── Main - Limits.png
├── Main.png
├── README.md
├── Settings - Network.png
├── Settings - Peers.png
├── Settings - Speed.png
├── Settings - Torrents.png
├── Settings - User interface.png
├── Torrent - Details.png
├── Torrent - Files.png
├── Torrent - Peers.png
└── Torrent - Trackers.png
├── src
├── components
│ ├── Alerts
│ │ ├── Alerts.svelte
│ │ └── index.js
│ ├── App
│ │ ├── App.svelte
│ │ └── index.js
│ ├── Badge
│ │ ├── Badge.svelte
│ │ └── index.js
│ ├── Button
│ │ ├── Button.svelte
│ │ └── index.js
│ ├── Checkbox
│ │ ├── Checkbox.svelte
│ │ └── index.js
│ ├── ContextMenu
│ │ ├── ContextMenu.svelte
│ │ ├── Paths
│ │ │ ├── Paths.svelte
│ │ │ └── index.js
│ │ ├── Torrent
│ │ │ ├── Torrent.svelte
│ │ │ └── index.js
│ │ └── index.js
│ ├── DiskUsage
│ │ ├── DiskUsage.svelte
│ │ └── index.js
│ ├── Dropdown
│ │ ├── Dropdown.svelte
│ │ └── index.js
│ ├── Filters
│ │ ├── Filters.svelte
│ │ └── index.js
│ ├── Graph
│ │ ├── Bytes.svelte
│ │ ├── Graph.svelte
│ │ ├── SpeedLimit.svelte
│ │ └── index.js
│ ├── Icon
│ │ ├── Active.svelte
│ │ ├── Add.svelte
│ │ ├── All.svelte
│ │ ├── CheckboxCheckmark.svelte
│ │ ├── Checkmark.svelte
│ │ ├── Chevron.svelte
│ │ ├── CircleCheckmarkIcon.svelte
│ │ ├── CircleExclamationIcon.svelte
│ │ ├── Close.svelte
│ │ ├── Completed.svelte
│ │ ├── Disk.svelte
│ │ ├── Download.svelte
│ │ ├── DownloadSmall.svelte
│ │ ├── ETA.svelte
│ │ ├── ErrorIcon.svelte
│ │ ├── File.svelte
│ │ ├── Files.svelte
│ │ ├── FolderClosed.svelte
│ │ ├── FolderOpen.svelte
│ │ ├── Icon.svelte
│ │ ├── InfinityIcon.svelte
│ │ ├── InformationIcon.svelte
│ │ ├── Limits.svelte
│ │ ├── MenuIcon.svelte
│ │ ├── RatioIcon.svelte
│ │ ├── Remove.svelte
│ │ ├── Search.svelte
│ │ ├── SeedsIcon.svelte
│ │ ├── SettingsIcon.svelte
│ │ ├── SpinnerIcon.svelte
│ │ ├── StartIcon.svelte
│ │ ├── StopIcon.svelte
│ │ ├── Upload.svelte
│ │ └── index.js
│ ├── Input
│ │ ├── Input.svelte
│ │ └── index.js
│ ├── InputFile
│ │ ├── InputFile.svelte
│ │ └── index.js
│ ├── InputMultiple
│ │ ├── InputMultiple.svelte
│ │ └── index.js
│ ├── InputPath
│ │ ├── InputPath.svelte
│ │ └── index.js
│ ├── Modal
│ │ ├── Add
│ │ │ ├── Add.svelte
│ │ │ └── index.js
│ │ ├── Labels
│ │ │ ├── Labels.svelte
│ │ │ └── index.js
│ │ ├── Location
│ │ │ ├── Location.svelte
│ │ │ └── index.js
│ │ ├── Modal.svelte
│ │ ├── Remove
│ │ │ ├── Remove.svelte
│ │ │ └── index.js
│ │ ├── Settings
│ │ │ ├── About.svelte
│ │ │ ├── Header.svelte
│ │ │ ├── Menu.svelte
│ │ │ ├── Network.svelte
│ │ │ ├── Peers.svelte
│ │ │ ├── Settings.svelte
│ │ │ ├── Speed.svelte
│ │ │ ├── Torrents.svelte
│ │ │ ├── UserInterface.svelte
│ │ │ └── index.js
│ │ ├── TorrentDetail
│ │ │ ├── ActionBarView
│ │ │ │ ├── ActionBarView.svelte
│ │ │ │ └── index.js
│ │ │ ├── Details
│ │ │ │ ├── Details.svelte
│ │ │ │ └── index.js
│ │ │ ├── Files
│ │ │ │ ├── Files.svelte
│ │ │ │ ├── Folder.svelte
│ │ │ │ ├── IconCheckbox.svelte
│ │ │ │ └── index.js
│ │ │ ├── Header
│ │ │ │ ├── Header.svelte
│ │ │ │ └── index.js
│ │ │ ├── Peers
│ │ │ │ ├── Peers.svelte
│ │ │ │ └── index.js
│ │ │ ├── TorrentDetail.svelte
│ │ │ ├── Trackers
│ │ │ │ ├── Trackers.svelte
│ │ │ │ └── index.js
│ │ │ └── index.js
│ │ └── index.js
│ ├── Panel
│ │ ├── Actions.svelte
│ │ ├── Panel.svelte
│ │ └── index.js
│ ├── PriorityIndicator
│ │ ├── PriorityIndicator.svelte
│ │ └── index.js
│ ├── ProgressBar
│ │ ├── ProgressBar.svelte
│ │ └── index.js
│ ├── Search
│ │ ├── Search.svelte
│ │ └── index.js
│ ├── Select
│ │ ├── Select.svelte
│ │ └── index.js
│ ├── Switch
│ │ ├── Switch.svelte
│ │ └── index.js
│ ├── TopBar
│ │ ├── TopBar.svelte
│ │ └── index.js
│ └── TorrentList
│ │ ├── ColumnHeader.svelte
│ │ ├── Renderers
│ │ ├── ArrivalRenderer.svelte
│ │ ├── BooleanRenderer.svelte
│ │ ├── ConnectionRenderer.svelte
│ │ ├── DateRenderer.svelte
│ │ ├── LabelRenderer.svelte
│ │ ├── ProgressRenderer.svelte
│ │ ├── SizeRenderer.svelte
│ │ ├── TextRenderer.svelte
│ │ └── index.js
│ │ ├── Torrent.svelte
│ │ ├── TorrentDropzone.svelte
│ │ ├── TorrentList.svelte
│ │ └── index.js
├── helpers
│ ├── Transmission.js
│ ├── actions
│ │ ├── clickOutside.js
│ │ ├── contextmenu.js
│ │ ├── index.js
│ │ ├── orderable.js
│ │ └── resizeableTable.js
│ ├── classHelper.js
│ ├── configHelper.js
│ ├── constants
│ │ ├── columns.js
│ │ ├── defaultConfig.json
│ │ ├── paths.js
│ │ └── statuses.js
│ ├── copyHelper.js
│ ├── fileHelper.js
│ ├── filterHelper.js
│ ├── folderStructureHelper.js
│ ├── sizeHelper.js
│ ├── stores
│ │ ├── alerts.js
│ │ ├── columns.js
│ │ ├── contextMenu.js
│ │ ├── darkMode.js
│ │ ├── diskUsage.js
│ │ ├── filters.js
│ │ ├── index.js
│ │ ├── ipAddress.js
│ │ ├── modals.js
│ │ ├── panel.js
│ │ ├── paths.js
│ │ ├── rateData.js
│ │ ├── selectedTorrents.js
│ │ ├── session.js
│ │ ├── sessionStats.js
│ │ ├── sorting.js
│ │ ├── switchSpeedColors.js
│ │ ├── tableHeaderConfig.js
│ │ ├── timeConfig.js
│ │ ├── torrentDetails.js
│ │ └── torrents.js
│ ├── timeHelper.js
│ ├── trackerHelper.js
│ ├── urlHelper.js
│ └── uuidHelper.js
└── main.js
└── workbox-config.js
/.env.template:
--------------------------------------------------------------------------------
1 | TRANSMISSION_HOST="localhost"
2 | TRANSMISSION_SSL=false
3 | TRANSMISSION_PORT=9091
4 | TRANSMISSION_PATH="/rpc"
5 | TRANSMISSION_USERNAME=
6 | TRANSMISSION_PASSWORD=
7 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: ['johman10']
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
14 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # To get started with Dependabot version updates, you'll need to specify which
2 | # package ecosystems to update and where the package manifests are located.
3 | # Please see the documentation for all configuration options:
4 | # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5 |
6 | version: 2
7 | updates:
8 | - package-ecosystem: 'npm' # See documentation for possible values
9 | directory: '/' # Location of package manifests
10 | target-branch: 'dependency_updates'
11 | schedule:
12 | interval: 'daily'
13 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | # Run this workflow every time a new commit pushed to your repository
4 | on:
5 | push:
6 | branches-ignore: [master]
7 | pull_request:
8 | branches: [master]
9 |
10 | jobs:
11 | # Set the job key. The key is displayed as the job name
12 | # when a job name is not provided
13 | format:
14 | # Name the Job
15 | name: Format
16 | # Set the type of machine to run on
17 | runs-on: ubuntu-latest
18 |
19 | steps:
20 | # Checks out a copy of your repository on the ubuntu-latest machine
21 | - name: Checkout code
22 | uses: actions/checkout@v2
23 | with:
24 | # Make sure the actual branch is checked out when running on pull requests
25 | ref: ${{ github.head_ref }}
26 |
27 | - name: Cache node modules
28 | uses: actions/cache@v4
29 | env:
30 | cache-name: cache-node-modules
31 | with:
32 | path: ~/.npm
33 | key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
34 | restore-keys: |
35 | ${{ runner.os }}-build-${{ env.cache-name }}-
36 | ${{ runner.os }}-build-
37 | ${{ runner.os }}-
38 |
39 | - name: Install modules
40 | run: npm ci
41 |
42 | - name: Build
43 | run: npm run build
44 |
45 | - name: Prettify code
46 | uses: creyD/prettier_action@v3.1
47 | with:
48 | prettier_options: --write ./src/**/*.{js,svelte}
49 | env:
50 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
51 |
52 | - name: Run ESLint
53 | run: npm run lint
54 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: 'Release'
2 |
3 | on:
4 | push:
5 | branches:
6 | - 'master'
7 |
8 | jobs:
9 | release:
10 | name: 'Release'
11 | runs-on: 'ubuntu-latest'
12 |
13 | steps:
14 | - name: Set time var
15 | run: |
16 | echo "time=$(date +'%Y-%m-%dT%H:%M:%S')" >> $GITHUB_ENV
17 | echo "ref=$(date +'%Y-%m-%dT%H-%M-%S')" >> $GITHUB_ENV
18 | # Checks out a copy of your repository on the ubuntu-latest machine
19 | - name: Checkout code
20 | uses: actions/checkout@v2
21 | with:
22 | # Make sure the actual branch is checked out when running on pull requests
23 | ref: ${{ github.head_ref }}
24 |
25 | - name: Cache node modules
26 | uses: actions/cache@v4
27 | env:
28 | cache-name: cache-node-modules
29 | with:
30 | path: ~/.npm
31 | key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
32 | restore-keys: |
33 | ${{ runner.os }}-build-${{ env.cache-name }}-
34 | ${{ runner.os }}-build-
35 | ${{ runner.os }}-
36 |
37 | - name: Install modules
38 | run: npm ci
39 |
40 | - name: Build
41 | run: npm run build
42 |
43 | - name: Copy public
44 | run: cp -r public flood-for-transmission
45 |
46 | - name: Zip release
47 | run: zip -r flood-for-transmission.zip flood-for-transmission
48 |
49 | - name: Tar release
50 | run: tar -czvf flood-for-transmission.tar.gz flood-for-transmission
51 |
52 | - name: Release time based version
53 | uses: 'marvinpinto/action-automatic-releases@latest'
54 | with:
55 | repo_token: '${{ secrets.GITHUB_TOKEN }}'
56 | automatic_release_tag: '${{ env.ref }}'
57 | prerelease: false
58 | title: '${{ env.time }}'
59 | files: |
60 | flood-for-transmission.zip
61 | flood-for-transmission.tar.gz
62 |
63 | - name: Release latest
64 | uses: 'marvinpinto/action-automatic-releases@latest'
65 | with:
66 | repo_token: '${{ secrets.GITHUB_TOKEN }}'
67 | automatic_release_tag: 'latest'
68 | prerelease: false
69 | title: 'Latest'
70 | files: |
71 | flood-for-transmission.zip
72 | flood-for-transmission.tar.gz
73 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules/
2 | /public/build/
3 | /public/sw.js*
4 | /public/workbox-*.js*
5 | /public/config.json
6 | /public/config.json.defaults
7 |
8 | .DS_Store
9 |
10 | .env
11 |
12 | public.zip
13 |
14 | .eslintcache
15 |
--------------------------------------------------------------------------------
/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | "prettier-plugin-svelte"
4 | ],
5 | "tabWidth": 2,
6 | "semi": true,
7 | "singleQuote": true,
8 | "trailingComma": "es5",
9 | "quoteProps": "consistent",
10 | "svelteSortOrder": "options-scripts-markup-styles",
11 | "svelteStrictMode": true,
12 | "svelteBracketNewLine": true,
13 | "svelteAllowShorthand": false
14 | }
15 |
--------------------------------------------------------------------------------
/.tool-versions:
--------------------------------------------------------------------------------
1 | nodejs 24.2.0
2 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.formatOnSave": true
3 | }
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | [
4 | '@babel/preset-env',
5 | {
6 | useBuiltIns: 'usage',
7 | corejs: 3,
8 | targets:
9 | 'last 2 Chrome versions, last 2 Firefox versions, last 2 Edge versions',
10 | },
11 | ],
12 | ],
13 | plugins: [
14 | '@babel/plugin-proposal-class-properties',
15 | '@babel/plugin-transform-private-methods',
16 | ],
17 | };
18 |
--------------------------------------------------------------------------------
/eslint.config.mjs:
--------------------------------------------------------------------------------
1 | import globals from 'globals';
2 | import babelParser from '@babel/eslint-parser';
3 | import svelte from 'eslint-plugin-svelte';
4 | import parser from 'svelte-eslint-parser';
5 | import js from '@eslint/js';
6 |
7 | export default [
8 | js.configs.recommended,
9 | ...svelte.configs.recommended,
10 | {
11 | languageOptions: {
12 | globals: {
13 | ...globals.browser,
14 | __TRANSMISSION_HOST__: 'readonly',
15 | __TRANSMISSION_PORT__: 'readonly',
16 | __TRANSMISSION_USERNAME__: 'readonly',
17 | __TRANSMISSION_PATH__: 'readonly',
18 | __TRANSMISSION_PASSWORD__: 'readonly',
19 | __TRANSMISSION_SSL__: 'readonly',
20 | __ENV__: 'readonly',
21 | },
22 | parser: babelParser,
23 | ecmaVersion: 2021,
24 | sourceType: 'module',
25 | },
26 |
27 | rules: {
28 | 'svelte/valid-compile': [
29 | 'error',
30 | {
31 | ignoreWarnings: true,
32 | },
33 | ],
34 | },
35 | },
36 | {
37 | files: ['**/*.svelte'],
38 |
39 | languageOptions: {
40 | parser: parser,
41 | },
42 | },
43 | ];
44 |
--------------------------------------------------------------------------------
/flood.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/flood.png
--------------------------------------------------------------------------------
/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": "./src",
4 | "paths": {
5 | "~components/*": ["./components/*"],
6 | "~helpers/*": ["./helpers/*"]
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "svelte-app",
3 | "version": "1.0.0",
4 | "scripts": {
5 | "build": "rm -rf public/build public/sw* public/workbox-* && rollup -c --silent",
6 | "postbuild": "workbox generateSW workbox-config.js",
7 | "start": "rollup -c -w",
8 | "serve": "sirv public",
9 | "lint": "eslint \"./src/**/*.{js,svelte}\"",
10 | "lint:fix": "npm run lint -- --fix",
11 | "prettier": "prettier --write \"./src/**/*.{js,svelte}\""
12 | },
13 | "devDependencies": {
14 | "@babel/core": "^7.28.0",
15 | "@babel/eslint-parser": "^7.28.0",
16 | "@babel/plugin-proposal-class-properties": "^7.17.12",
17 | "@babel/plugin-transform-private-methods": "^7.27.1",
18 | "@babel/preset-env": "^7.28.0",
19 | "@eslint/eslintrc": "^3.3.1",
20 | "@eslint/js": "^9.31.0",
21 | "@rollup/plugin-alias": "^5.1.1",
22 | "@rollup/plugin-babel": "^6.0.4",
23 | "@rollup/plugin-commonjs": "^28.0.6",
24 | "@rollup/plugin-json": "^6.1.0",
25 | "@rollup/plugin-node-resolve": "^16.0.1",
26 | "@rollup/plugin-replace": "^6.0.2",
27 | "@rollup/plugin-terser": "^0.4.4",
28 | "dotenv": "^17.2.0",
29 | "eslint": "^9.31.0",
30 | "eslint-plugin-svelte": "^3.11.0",
31 | "globals": "^16.3.0",
32 | "prettier": "^3.6.2",
33 | "prettier-plugin-svelte": "^3.4.0",
34 | "rollup": "^4.45.1",
35 | "rollup-plugin-copy": "^3.5.0",
36 | "rollup-plugin-css-only": "^4.5.2",
37 | "rollup-plugin-livereload": "^2.0.5",
38 | "rollup-plugin-svelte": "^7.2.2",
39 | "svelte": "^5.36.8",
40 | "svelte-eslint-parser": "^1.3.0",
41 | "workbox-cli": "^7.3.0"
42 | },
43 | "dependencies": {
44 | "core-js": "^3.44.0",
45 | "d3-array": "^3.2.4",
46 | "d3-scale": "^4.0.2",
47 | "d3-shape": "^3.2.0",
48 | "sirv-cli": "^3.0.1"
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/public/browserconfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | #0e2337
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/public/fonts/Roboto-500/Roboto-500.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/fonts/Roboto-500/Roboto-500.eot
--------------------------------------------------------------------------------
/public/fonts/Roboto-500/Roboto-500.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/fonts/Roboto-500/Roboto-500.ttf
--------------------------------------------------------------------------------
/public/fonts/Roboto-500/Roboto-500.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/fonts/Roboto-500/Roboto-500.woff
--------------------------------------------------------------------------------
/public/fonts/Roboto-500/Roboto-500.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/fonts/Roboto-500/Roboto-500.woff2
--------------------------------------------------------------------------------
/public/fonts/Roboto-700/Roboto-700.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/fonts/Roboto-700/Roboto-700.eot
--------------------------------------------------------------------------------
/public/fonts/Roboto-700/Roboto-700.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/fonts/Roboto-700/Roboto-700.ttf
--------------------------------------------------------------------------------
/public/fonts/Roboto-700/Roboto-700.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/fonts/Roboto-700/Roboto-700.woff
--------------------------------------------------------------------------------
/public/fonts/Roboto-700/Roboto-700.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/fonts/Roboto-700/Roboto-700.woff2
--------------------------------------------------------------------------------
/public/fonts/Roboto-700italic/Roboto-700italic.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/fonts/Roboto-700italic/Roboto-700italic.eot
--------------------------------------------------------------------------------
/public/fonts/Roboto-700italic/Roboto-700italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/fonts/Roboto-700italic/Roboto-700italic.ttf
--------------------------------------------------------------------------------
/public/fonts/Roboto-700italic/Roboto-700italic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/fonts/Roboto-700italic/Roboto-700italic.woff
--------------------------------------------------------------------------------
/public/fonts/Roboto-700italic/Roboto-700italic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/fonts/Roboto-700italic/Roboto-700italic.woff2
--------------------------------------------------------------------------------
/public/fonts/Roboto-italic/Roboto-italic.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/fonts/Roboto-italic/Roboto-italic.eot
--------------------------------------------------------------------------------
/public/fonts/Roboto-italic/Roboto-italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/fonts/Roboto-italic/Roboto-italic.ttf
--------------------------------------------------------------------------------
/public/fonts/Roboto-italic/Roboto-italic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/fonts/Roboto-italic/Roboto-italic.woff
--------------------------------------------------------------------------------
/public/fonts/Roboto-italic/Roboto-italic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/fonts/Roboto-italic/Roboto-italic.woff2
--------------------------------------------------------------------------------
/public/fonts/Roboto-regular/Roboto-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/fonts/Roboto-regular/Roboto-regular.eot
--------------------------------------------------------------------------------
/public/fonts/Roboto-regular/Roboto-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/fonts/Roboto-regular/Roboto-regular.ttf
--------------------------------------------------------------------------------
/public/fonts/Roboto-regular/Roboto-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/fonts/Roboto-regular/Roboto-regular.woff
--------------------------------------------------------------------------------
/public/fonts/Roboto-regular/Roboto-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/fonts/Roboto-regular/Roboto-regular.woff2
--------------------------------------------------------------------------------
/public/images/favicon/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/favicon/android-chrome-192x192.png
--------------------------------------------------------------------------------
/public/images/favicon/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/favicon/android-chrome-512x512.png
--------------------------------------------------------------------------------
/public/images/favicon/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/favicon/apple-touch-icon.png
--------------------------------------------------------------------------------
/public/images/favicon/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/favicon/favicon-16x16.png
--------------------------------------------------------------------------------
/public/images/favicon/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/favicon/favicon-32x32.png
--------------------------------------------------------------------------------
/public/images/favicon/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/favicon/favicon.ico
--------------------------------------------------------------------------------
/public/images/favicon/mstile-150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/favicon/mstile-150x150.png
--------------------------------------------------------------------------------
/public/images/favicon/safari-pinned-tab.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/images/flags/_unknown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/_unknown.png
--------------------------------------------------------------------------------
/public/images/flags/ad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ad.png
--------------------------------------------------------------------------------
/public/images/flags/ae.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ae.png
--------------------------------------------------------------------------------
/public/images/flags/af.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/af.png
--------------------------------------------------------------------------------
/public/images/flags/ag.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ag.png
--------------------------------------------------------------------------------
/public/images/flags/ai.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ai.png
--------------------------------------------------------------------------------
/public/images/flags/al.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/al.png
--------------------------------------------------------------------------------
/public/images/flags/am.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/am.png
--------------------------------------------------------------------------------
/public/images/flags/an.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/an.png
--------------------------------------------------------------------------------
/public/images/flags/ao.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ao.png
--------------------------------------------------------------------------------
/public/images/flags/aq.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/aq.png
--------------------------------------------------------------------------------
/public/images/flags/ar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ar.png
--------------------------------------------------------------------------------
/public/images/flags/as.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/as.png
--------------------------------------------------------------------------------
/public/images/flags/at.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/at.png
--------------------------------------------------------------------------------
/public/images/flags/au.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/au.png
--------------------------------------------------------------------------------
/public/images/flags/aw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/aw.png
--------------------------------------------------------------------------------
/public/images/flags/ax.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ax.png
--------------------------------------------------------------------------------
/public/images/flags/az.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/az.png
--------------------------------------------------------------------------------
/public/images/flags/ba.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ba.png
--------------------------------------------------------------------------------
/public/images/flags/bb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/bb.png
--------------------------------------------------------------------------------
/public/images/flags/bd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/bd.png
--------------------------------------------------------------------------------
/public/images/flags/be.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/be.png
--------------------------------------------------------------------------------
/public/images/flags/bf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/bf.png
--------------------------------------------------------------------------------
/public/images/flags/bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/bg.png
--------------------------------------------------------------------------------
/public/images/flags/bh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/bh.png
--------------------------------------------------------------------------------
/public/images/flags/bi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/bi.png
--------------------------------------------------------------------------------
/public/images/flags/bj.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/bj.png
--------------------------------------------------------------------------------
/public/images/flags/bl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/bl.png
--------------------------------------------------------------------------------
/public/images/flags/bm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/bm.png
--------------------------------------------------------------------------------
/public/images/flags/bn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/bn.png
--------------------------------------------------------------------------------
/public/images/flags/bo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/bo.png
--------------------------------------------------------------------------------
/public/images/flags/br.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/br.png
--------------------------------------------------------------------------------
/public/images/flags/bs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/bs.png
--------------------------------------------------------------------------------
/public/images/flags/bt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/bt.png
--------------------------------------------------------------------------------
/public/images/flags/bw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/bw.png
--------------------------------------------------------------------------------
/public/images/flags/by.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/by.png
--------------------------------------------------------------------------------
/public/images/flags/bz.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/bz.png
--------------------------------------------------------------------------------
/public/images/flags/ca.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ca.png
--------------------------------------------------------------------------------
/public/images/flags/cc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/cc.png
--------------------------------------------------------------------------------
/public/images/flags/cd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/cd.png
--------------------------------------------------------------------------------
/public/images/flags/cf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/cf.png
--------------------------------------------------------------------------------
/public/images/flags/cg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/cg.png
--------------------------------------------------------------------------------
/public/images/flags/ch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ch.png
--------------------------------------------------------------------------------
/public/images/flags/ci.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ci.png
--------------------------------------------------------------------------------
/public/images/flags/ck.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ck.png
--------------------------------------------------------------------------------
/public/images/flags/cl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/cl.png
--------------------------------------------------------------------------------
/public/images/flags/cm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/cm.png
--------------------------------------------------------------------------------
/public/images/flags/cn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/cn.png
--------------------------------------------------------------------------------
/public/images/flags/co.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/co.png
--------------------------------------------------------------------------------
/public/images/flags/cr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/cr.png
--------------------------------------------------------------------------------
/public/images/flags/cu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/cu.png
--------------------------------------------------------------------------------
/public/images/flags/cv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/cv.png
--------------------------------------------------------------------------------
/public/images/flags/cw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/cw.png
--------------------------------------------------------------------------------
/public/images/flags/cx.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/cx.png
--------------------------------------------------------------------------------
/public/images/flags/cy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/cy.png
--------------------------------------------------------------------------------
/public/images/flags/cz.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/cz.png
--------------------------------------------------------------------------------
/public/images/flags/de.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/de.png
--------------------------------------------------------------------------------
/public/images/flags/dj.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/dj.png
--------------------------------------------------------------------------------
/public/images/flags/dk.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/dk.png
--------------------------------------------------------------------------------
/public/images/flags/dm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/dm.png
--------------------------------------------------------------------------------
/public/images/flags/do.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/do.png
--------------------------------------------------------------------------------
/public/images/flags/dz.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/dz.png
--------------------------------------------------------------------------------
/public/images/flags/ec.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ec.png
--------------------------------------------------------------------------------
/public/images/flags/ee.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ee.png
--------------------------------------------------------------------------------
/public/images/flags/eg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/eg.png
--------------------------------------------------------------------------------
/public/images/flags/eh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/eh.png
--------------------------------------------------------------------------------
/public/images/flags/er.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/er.png
--------------------------------------------------------------------------------
/public/images/flags/es.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/es.png
--------------------------------------------------------------------------------
/public/images/flags/et.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/et.png
--------------------------------------------------------------------------------
/public/images/flags/eu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/eu.png
--------------------------------------------------------------------------------
/public/images/flags/fi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/fi.png
--------------------------------------------------------------------------------
/public/images/flags/fj.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/fj.png
--------------------------------------------------------------------------------
/public/images/flags/fk.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/fk.png
--------------------------------------------------------------------------------
/public/images/flags/fm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/fm.png
--------------------------------------------------------------------------------
/public/images/flags/fo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/fo.png
--------------------------------------------------------------------------------
/public/images/flags/fr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/fr.png
--------------------------------------------------------------------------------
/public/images/flags/ga.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ga.png
--------------------------------------------------------------------------------
/public/images/flags/gb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/gb.png
--------------------------------------------------------------------------------
/public/images/flags/gd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/gd.png
--------------------------------------------------------------------------------
/public/images/flags/ge.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ge.png
--------------------------------------------------------------------------------
/public/images/flags/gg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/gg.png
--------------------------------------------------------------------------------
/public/images/flags/gh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/gh.png
--------------------------------------------------------------------------------
/public/images/flags/gi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/gi.png
--------------------------------------------------------------------------------
/public/images/flags/gl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/gl.png
--------------------------------------------------------------------------------
/public/images/flags/gm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/gm.png
--------------------------------------------------------------------------------
/public/images/flags/gn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/gn.png
--------------------------------------------------------------------------------
/public/images/flags/gq.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/gq.png
--------------------------------------------------------------------------------
/public/images/flags/gr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/gr.png
--------------------------------------------------------------------------------
/public/images/flags/gs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/gs.png
--------------------------------------------------------------------------------
/public/images/flags/gt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/gt.png
--------------------------------------------------------------------------------
/public/images/flags/gu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/gu.png
--------------------------------------------------------------------------------
/public/images/flags/gw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/gw.png
--------------------------------------------------------------------------------
/public/images/flags/gy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/gy.png
--------------------------------------------------------------------------------
/public/images/flags/hk.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/hk.png
--------------------------------------------------------------------------------
/public/images/flags/hn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/hn.png
--------------------------------------------------------------------------------
/public/images/flags/hr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/hr.png
--------------------------------------------------------------------------------
/public/images/flags/ht.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ht.png
--------------------------------------------------------------------------------
/public/images/flags/hu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/hu.png
--------------------------------------------------------------------------------
/public/images/flags/ic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ic.png
--------------------------------------------------------------------------------
/public/images/flags/id.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/id.png
--------------------------------------------------------------------------------
/public/images/flags/ie.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ie.png
--------------------------------------------------------------------------------
/public/images/flags/il.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/il.png
--------------------------------------------------------------------------------
/public/images/flags/im.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/im.png
--------------------------------------------------------------------------------
/public/images/flags/in.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/in.png
--------------------------------------------------------------------------------
/public/images/flags/iq.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/iq.png
--------------------------------------------------------------------------------
/public/images/flags/ir.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ir.png
--------------------------------------------------------------------------------
/public/images/flags/is.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/is.png
--------------------------------------------------------------------------------
/public/images/flags/it.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/it.png
--------------------------------------------------------------------------------
/public/images/flags/je.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/je.png
--------------------------------------------------------------------------------
/public/images/flags/jm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/jm.png
--------------------------------------------------------------------------------
/public/images/flags/jo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/jo.png
--------------------------------------------------------------------------------
/public/images/flags/jp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/jp.png
--------------------------------------------------------------------------------
/public/images/flags/ke.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ke.png
--------------------------------------------------------------------------------
/public/images/flags/kg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/kg.png
--------------------------------------------------------------------------------
/public/images/flags/kh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/kh.png
--------------------------------------------------------------------------------
/public/images/flags/ki.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ki.png
--------------------------------------------------------------------------------
/public/images/flags/km.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/km.png
--------------------------------------------------------------------------------
/public/images/flags/kn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/kn.png
--------------------------------------------------------------------------------
/public/images/flags/kp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/kp.png
--------------------------------------------------------------------------------
/public/images/flags/kr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/kr.png
--------------------------------------------------------------------------------
/public/images/flags/kw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/kw.png
--------------------------------------------------------------------------------
/public/images/flags/ky.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ky.png
--------------------------------------------------------------------------------
/public/images/flags/kz.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/kz.png
--------------------------------------------------------------------------------
/public/images/flags/la.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/la.png
--------------------------------------------------------------------------------
/public/images/flags/lb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/lb.png
--------------------------------------------------------------------------------
/public/images/flags/lc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/lc.png
--------------------------------------------------------------------------------
/public/images/flags/li.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/li.png
--------------------------------------------------------------------------------
/public/images/flags/lk.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/lk.png
--------------------------------------------------------------------------------
/public/images/flags/lr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/lr.png
--------------------------------------------------------------------------------
/public/images/flags/ls.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ls.png
--------------------------------------------------------------------------------
/public/images/flags/lt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/lt.png
--------------------------------------------------------------------------------
/public/images/flags/lu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/lu.png
--------------------------------------------------------------------------------
/public/images/flags/lv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/lv.png
--------------------------------------------------------------------------------
/public/images/flags/ly.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ly.png
--------------------------------------------------------------------------------
/public/images/flags/ma.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ma.png
--------------------------------------------------------------------------------
/public/images/flags/mc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/mc.png
--------------------------------------------------------------------------------
/public/images/flags/md.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/md.png
--------------------------------------------------------------------------------
/public/images/flags/me.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/me.png
--------------------------------------------------------------------------------
/public/images/flags/mf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/mf.png
--------------------------------------------------------------------------------
/public/images/flags/mg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/mg.png
--------------------------------------------------------------------------------
/public/images/flags/mh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/mh.png
--------------------------------------------------------------------------------
/public/images/flags/mk.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/mk.png
--------------------------------------------------------------------------------
/public/images/flags/ml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ml.png
--------------------------------------------------------------------------------
/public/images/flags/mm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/mm.png
--------------------------------------------------------------------------------
/public/images/flags/mn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/mn.png
--------------------------------------------------------------------------------
/public/images/flags/mo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/mo.png
--------------------------------------------------------------------------------
/public/images/flags/mp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/mp.png
--------------------------------------------------------------------------------
/public/images/flags/mq.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/mq.png
--------------------------------------------------------------------------------
/public/images/flags/mr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/mr.png
--------------------------------------------------------------------------------
/public/images/flags/ms.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ms.png
--------------------------------------------------------------------------------
/public/images/flags/mt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/mt.png
--------------------------------------------------------------------------------
/public/images/flags/mu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/mu.png
--------------------------------------------------------------------------------
/public/images/flags/mv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/mv.png
--------------------------------------------------------------------------------
/public/images/flags/mw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/mw.png
--------------------------------------------------------------------------------
/public/images/flags/mx.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/mx.png
--------------------------------------------------------------------------------
/public/images/flags/my.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/my.png
--------------------------------------------------------------------------------
/public/images/flags/mz.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/mz.png
--------------------------------------------------------------------------------
/public/images/flags/na.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/na.png
--------------------------------------------------------------------------------
/public/images/flags/nc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/nc.png
--------------------------------------------------------------------------------
/public/images/flags/ne.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ne.png
--------------------------------------------------------------------------------
/public/images/flags/nf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/nf.png
--------------------------------------------------------------------------------
/public/images/flags/ng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ng.png
--------------------------------------------------------------------------------
/public/images/flags/ni.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ni.png
--------------------------------------------------------------------------------
/public/images/flags/nl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/nl.png
--------------------------------------------------------------------------------
/public/images/flags/no.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/no.png
--------------------------------------------------------------------------------
/public/images/flags/np.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/np.png
--------------------------------------------------------------------------------
/public/images/flags/nr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/nr.png
--------------------------------------------------------------------------------
/public/images/flags/nu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/nu.png
--------------------------------------------------------------------------------
/public/images/flags/nz.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/nz.png
--------------------------------------------------------------------------------
/public/images/flags/om.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/om.png
--------------------------------------------------------------------------------
/public/images/flags/pa.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/pa.png
--------------------------------------------------------------------------------
/public/images/flags/pe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/pe.png
--------------------------------------------------------------------------------
/public/images/flags/pf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/pf.png
--------------------------------------------------------------------------------
/public/images/flags/pg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/pg.png
--------------------------------------------------------------------------------
/public/images/flags/ph.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ph.png
--------------------------------------------------------------------------------
/public/images/flags/pk.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/pk.png
--------------------------------------------------------------------------------
/public/images/flags/pl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/pl.png
--------------------------------------------------------------------------------
/public/images/flags/pn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/pn.png
--------------------------------------------------------------------------------
/public/images/flags/pr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/pr.png
--------------------------------------------------------------------------------
/public/images/flags/ps.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ps.png
--------------------------------------------------------------------------------
/public/images/flags/pt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/pt.png
--------------------------------------------------------------------------------
/public/images/flags/pw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/pw.png
--------------------------------------------------------------------------------
/public/images/flags/py.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/py.png
--------------------------------------------------------------------------------
/public/images/flags/qa.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/qa.png
--------------------------------------------------------------------------------
/public/images/flags/ro.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ro.png
--------------------------------------------------------------------------------
/public/images/flags/rs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/rs.png
--------------------------------------------------------------------------------
/public/images/flags/ru.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ru.png
--------------------------------------------------------------------------------
/public/images/flags/rw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/rw.png
--------------------------------------------------------------------------------
/public/images/flags/sa.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/sa.png
--------------------------------------------------------------------------------
/public/images/flags/sb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/sb.png
--------------------------------------------------------------------------------
/public/images/flags/sc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/sc.png
--------------------------------------------------------------------------------
/public/images/flags/sd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/sd.png
--------------------------------------------------------------------------------
/public/images/flags/se.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/se.png
--------------------------------------------------------------------------------
/public/images/flags/sg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/sg.png
--------------------------------------------------------------------------------
/public/images/flags/sh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/sh.png
--------------------------------------------------------------------------------
/public/images/flags/si.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/si.png
--------------------------------------------------------------------------------
/public/images/flags/sk.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/sk.png
--------------------------------------------------------------------------------
/public/images/flags/sl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/sl.png
--------------------------------------------------------------------------------
/public/images/flags/sm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/sm.png
--------------------------------------------------------------------------------
/public/images/flags/sn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/sn.png
--------------------------------------------------------------------------------
/public/images/flags/so.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/so.png
--------------------------------------------------------------------------------
/public/images/flags/sr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/sr.png
--------------------------------------------------------------------------------
/public/images/flags/ss.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ss.png
--------------------------------------------------------------------------------
/public/images/flags/st.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/st.png
--------------------------------------------------------------------------------
/public/images/flags/sv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/sv.png
--------------------------------------------------------------------------------
/public/images/flags/sy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/sy.png
--------------------------------------------------------------------------------
/public/images/flags/sz.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/sz.png
--------------------------------------------------------------------------------
/public/images/flags/tc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/tc.png
--------------------------------------------------------------------------------
/public/images/flags/td.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/td.png
--------------------------------------------------------------------------------
/public/images/flags/tf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/tf.png
--------------------------------------------------------------------------------
/public/images/flags/tg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/tg.png
--------------------------------------------------------------------------------
/public/images/flags/th.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/th.png
--------------------------------------------------------------------------------
/public/images/flags/tj.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/tj.png
--------------------------------------------------------------------------------
/public/images/flags/tk.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/tk.png
--------------------------------------------------------------------------------
/public/images/flags/tl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/tl.png
--------------------------------------------------------------------------------
/public/images/flags/tm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/tm.png
--------------------------------------------------------------------------------
/public/images/flags/tn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/tn.png
--------------------------------------------------------------------------------
/public/images/flags/to.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/to.png
--------------------------------------------------------------------------------
/public/images/flags/tr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/tr.png
--------------------------------------------------------------------------------
/public/images/flags/tt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/tt.png
--------------------------------------------------------------------------------
/public/images/flags/tv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/tv.png
--------------------------------------------------------------------------------
/public/images/flags/tw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/tw.png
--------------------------------------------------------------------------------
/public/images/flags/tz.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/tz.png
--------------------------------------------------------------------------------
/public/images/flags/ua.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ua.png
--------------------------------------------------------------------------------
/public/images/flags/ug.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ug.png
--------------------------------------------------------------------------------
/public/images/flags/us.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/us.png
--------------------------------------------------------------------------------
/public/images/flags/uy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/uy.png
--------------------------------------------------------------------------------
/public/images/flags/uz.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/uz.png
--------------------------------------------------------------------------------
/public/images/flags/va.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/va.png
--------------------------------------------------------------------------------
/public/images/flags/vc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/vc.png
--------------------------------------------------------------------------------
/public/images/flags/ve.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ve.png
--------------------------------------------------------------------------------
/public/images/flags/vg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/vg.png
--------------------------------------------------------------------------------
/public/images/flags/vi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/vi.png
--------------------------------------------------------------------------------
/public/images/flags/vn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/vn.png
--------------------------------------------------------------------------------
/public/images/flags/vu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/vu.png
--------------------------------------------------------------------------------
/public/images/flags/wf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/wf.png
--------------------------------------------------------------------------------
/public/images/flags/ws.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ws.png
--------------------------------------------------------------------------------
/public/images/flags/ye.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/ye.png
--------------------------------------------------------------------------------
/public/images/flags/yt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/yt.png
--------------------------------------------------------------------------------
/public/images/flags/za.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/za.png
--------------------------------------------------------------------------------
/public/images/flags/zm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/zm.png
--------------------------------------------------------------------------------
/public/images/flags/zw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/public/images/flags/zw.png
--------------------------------------------------------------------------------
/public/images/flood.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | Flood - Transmission
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/public/manifest.webmanifest:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Flood for Transmission",
3 | "description": "Transmission with a Flood UI",
4 | "icons": [
5 | {
6 | "src": "images/favicon/android-chrome-192x192.png",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | },
10 | {
11 | "src": "images/favicon/android-chrome-512x512.png",
12 | "sizes": "512x512",
13 | "type": "image/png"
14 | }
15 | ],
16 | "start_url": "./",
17 | "theme_color": "#293341",
18 | "background_color": "#293341",
19 | "scope": "./",
20 | "display": "minimal-ui"
21 | }
22 |
--------------------------------------------------------------------------------
/public/style/reset.css:
--------------------------------------------------------------------------------
1 | /* Box sizing rules */
2 | *,
3 | *::before,
4 | *::after {
5 | box-sizing: border-box;
6 | }
7 |
8 | /* Remove default padding */
9 | ul[class],
10 | ol[class] {
11 | padding: 0;
12 | }
13 |
14 | /* Remove default margin */
15 | body,
16 | h1,
17 | h2,
18 | h3,
19 | h4,
20 | p,
21 | ul[class],
22 | ol[class],
23 | li,
24 | figure,
25 | figcaption,
26 | blockquote,
27 | dl,
28 | dd {
29 | margin: 0;
30 | }
31 |
32 | html,
33 | body {
34 | overflow: hidden;
35 | }
36 |
37 | /* Set core body defaults */
38 | body {
39 | font-family: 'Roboto', sans-serif;
40 | scroll-behavior: smooth;
41 | text-rendering: optimizeSpeed;
42 | line-height: 1.5;
43 | }
44 |
45 | /* Remove list styles on ul, ol elements with a class attribute */
46 | ul[class],
47 | ol[class] {
48 | list-style: none;
49 | }
50 |
51 | /* A elements that don't have a class get default styles */
52 | a:not([class]) {
53 | text-decoration-skip-ink: auto;
54 | }
55 |
56 | /* Make images easier to work with */
57 | img {
58 | max-width: 100%;
59 | display: block;
60 | }
61 |
62 | /* Natural flow and rhythm in articles by default */
63 | article > * + * {
64 | margin-top: 1em;
65 | }
66 |
67 | /* Inherit fonts for inputs and buttons */
68 | input,
69 | button,
70 | textarea,
71 | select {
72 | font: inherit;
73 | }
74 |
75 | /* Remove all animations and transitions for people that prefer not to see them */
76 | @media (prefers-reduced-motion: reduce) {
77 | * {
78 | animation-duration: 0.01ms !important;
79 | animation-iteration-count: 1 !important;
80 | transition-duration: 0.01ms !important;
81 | scroll-behavior: auto !important;
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/screenshots/Main - Context menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/screenshots/Main - Context menu.png
--------------------------------------------------------------------------------
/screenshots/Main - Limits.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/screenshots/Main - Limits.png
--------------------------------------------------------------------------------
/screenshots/Main.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/screenshots/Main.png
--------------------------------------------------------------------------------
/screenshots/README.md:
--------------------------------------------------------------------------------
1 | # Screenshots
2 |
3 | ## Main screen
4 | 
5 | 
6 | 
7 |
8 | ## Torrent details
9 | 
10 | 
11 | 
12 | 
13 |
14 | ## Settings
15 | 
16 | 
17 | 
18 | 
19 | 
20 |
--------------------------------------------------------------------------------
/screenshots/Settings - Network.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/screenshots/Settings - Network.png
--------------------------------------------------------------------------------
/screenshots/Settings - Peers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/screenshots/Settings - Peers.png
--------------------------------------------------------------------------------
/screenshots/Settings - Speed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/screenshots/Settings - Speed.png
--------------------------------------------------------------------------------
/screenshots/Settings - Torrents.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/screenshots/Settings - Torrents.png
--------------------------------------------------------------------------------
/screenshots/Settings - User interface.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/screenshots/Settings - User interface.png
--------------------------------------------------------------------------------
/screenshots/Torrent - Details.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/screenshots/Torrent - Details.png
--------------------------------------------------------------------------------
/screenshots/Torrent - Files.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/screenshots/Torrent - Files.png
--------------------------------------------------------------------------------
/screenshots/Torrent - Peers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/screenshots/Torrent - Peers.png
--------------------------------------------------------------------------------
/screenshots/Torrent - Trackers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johman10/flood-for-transmission/e8f0f066b0a39680b9511a6f1db58c15e6a3a231/screenshots/Torrent - Trackers.png
--------------------------------------------------------------------------------
/src/components/Alerts/Alerts.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 | {#if $alerts.length}
8 |
9 | {#each $alerts as alert (alert.id)}
10 |
11 |
16 | {alert.message}
17 |
18 | {/each}
19 |
20 | {/if}
21 |
22 |
62 |
--------------------------------------------------------------------------------
/src/components/Alerts/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './Alerts.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/App/App.svelte:
--------------------------------------------------------------------------------
1 |
10 |
11 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
60 |
--------------------------------------------------------------------------------
/src/components/App/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './App.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/Badge/Badge.svelte:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
18 |
--------------------------------------------------------------------------------
/src/components/Badge/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './Badge.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/Button/Button.svelte:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 | {#if loading}
19 |
20 | {:else}
21 |
22 | {/if}
23 |
24 |
25 |
78 |
--------------------------------------------------------------------------------
/src/components/Button/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './Button.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/Checkbox/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './Checkbox.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/ContextMenu/Paths/Paths.svelte:
--------------------------------------------------------------------------------
1 |
17 |
18 | {#if $paths.length}
19 | {#each $paths as path (path)}
20 | {path}
21 | {/each}
22 | {:else}
23 |
24 | No common paths configured yet, click here to add some.
25 |
26 | {/if}
27 |
--------------------------------------------------------------------------------
/src/components/ContextMenu/Paths/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './Paths.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/ContextMenu/Torrent/Torrent.svelte:
--------------------------------------------------------------------------------
1 |
23 |
24 | onItemClick(onStart, args)}>Start
25 | onItemClick(onStartNow, args)}>Start now
26 | onItemClick(onStop, args)}>Stop
27 | onItemClick(onRemove, args)}>Remove
28 | onItemClick(onVerify, args)}>Verify local data
29 | onItemClick(onCopyMagnetLink, args)}>
30 | Copy magnet link
31 |
32 | onItemClick(onAsk, args)}>
33 | Ask tracker for more peers
34 |
35 |
36 | onItemClick(onLabels, args)}>Set labels
37 | onItemClick(onLocation, args)}>Set location
38 |
39 |
40 | Priority
41 | {
45 | onItemClick(onPrio, [event, ...args], { shouldClose: false });
46 | prio = event.detail;
47 | }}
48 | />
49 |
50 |
--------------------------------------------------------------------------------
/src/components/ContextMenu/Torrent/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './Torrent.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/ContextMenu/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './ContextMenu.svelte';
2 | export { default as Paths } from './Paths';
3 | export { default as Torrent } from './Torrent';
4 |
--------------------------------------------------------------------------------
/src/components/DiskUsage/DiskUsage.svelte:
--------------------------------------------------------------------------------
1 |
31 |
32 | {#if $diskUsage && $session[SESSION_COLUMN_RPC_VERSION] >= 15}
33 | {#await data then pathSpaces}
34 |
35 |
Disk usage
36 |
51 |
52 | {/await}
53 | {/if}
54 |
55 |
96 |
--------------------------------------------------------------------------------
/src/components/DiskUsage/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './DiskUsage.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/Dropdown/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './Dropdown.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/Filters/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './Filters.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/Graph/Bytes.svelte:
--------------------------------------------------------------------------------
1 |
33 |
34 |
40 | {value}
41 | {size}
42 |
43 |
44 |
68 |
--------------------------------------------------------------------------------
/src/components/Graph/SpeedLimit.svelte:
--------------------------------------------------------------------------------
1 |
20 |
21 |
27 | {#if limit}
28 | {limit}
29 | {limitSize}
30 | {:else}
31 |
32 | {/if}
33 |
34 |
35 |
72 |
--------------------------------------------------------------------------------
/src/components/Graph/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './Graph.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/Icon/Active.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/src/components/Icon/Add.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/components/Icon/All.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
11 |
12 |
--------------------------------------------------------------------------------
/src/components/Icon/CheckboxCheckmark.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
11 |
12 |
--------------------------------------------------------------------------------
/src/components/Icon/Checkmark.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
10 |
11 |
--------------------------------------------------------------------------------
/src/components/Icon/Chevron.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
12 |
17 |
18 |
--------------------------------------------------------------------------------
/src/components/Icon/CircleCheckmarkIcon.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
11 |
15 |
16 |
--------------------------------------------------------------------------------
/src/components/Icon/CircleExclamationIcon.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
11 |
14 |
15 |
--------------------------------------------------------------------------------
/src/components/Icon/Close.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/src/components/Icon/Completed.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
10 |
11 |
--------------------------------------------------------------------------------
/src/components/Icon/Disk.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/src/components/Icon/Download.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
9 |
10 |
--------------------------------------------------------------------------------
/src/components/Icon/DownloadSmall.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
12 |
13 |
--------------------------------------------------------------------------------
/src/components/Icon/ETA.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
10 |
14 |
15 |
--------------------------------------------------------------------------------
/src/components/Icon/ErrorIcon.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/src/components/Icon/File.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/components/Icon/Files.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
9 |
12 |
15 |
16 |
--------------------------------------------------------------------------------
/src/components/Icon/FolderClosed.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/src/components/Icon/FolderOpen.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/src/components/Icon/Icon.svelte:
--------------------------------------------------------------------------------
1 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/src/components/Icon/InfinityIcon.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/src/components/Icon/InformationIcon.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
9 |
10 |
14 |
15 |
--------------------------------------------------------------------------------
/src/components/Icon/Limits.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
12 |
16 |
20 |
24 |
29 |
33 |
37 |
38 |
39 |
49 |
--------------------------------------------------------------------------------
/src/components/Icon/MenuIcon.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/src/components/Icon/RatioIcon.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/src/components/Icon/Remove.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/components/Icon/Search.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
11 |
18 |
19 |
--------------------------------------------------------------------------------
/src/components/Icon/SeedsIcon.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/src/components/Icon/SettingsIcon.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/src/components/Icon/StartIcon.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/components/Icon/StopIcon.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/components/Icon/Upload.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
9 |
10 |
--------------------------------------------------------------------------------
/src/components/Icon/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './Icon.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/Input/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './Input.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/InputFile/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './InputFile.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/InputMultiple/InputMultiple.svelte:
--------------------------------------------------------------------------------
1 |
64 |
65 |
66 | {#if label}
67 |
68 | {label}
69 |
70 | {/if}
71 | {#each values as value, index (value)}
72 | handlePaste(index, e)}
78 | {...$$restProps}
79 | />
80 | {/each}
81 |
82 |
83 |
97 |
--------------------------------------------------------------------------------
/src/components/InputMultiple/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './InputMultiple.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/InputPath/InputPath.svelte:
--------------------------------------------------------------------------------
1 |
25 |
26 |
33 |
--------------------------------------------------------------------------------
/src/components/InputPath/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './InputPath.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/Modal/Add/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './Add.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/Modal/Labels/Labels.svelte:
--------------------------------------------------------------------------------
1 |
40 |
41 | Set labels
42 |
43 |
59 |
60 |
81 |
--------------------------------------------------------------------------------
/src/components/Modal/Labels/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './Labels';
2 |
--------------------------------------------------------------------------------
/src/components/Modal/Location/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './Location.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/Modal/Modal.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 | {#if $modals && $modals.component}
15 |
29 | {/if}
30 |
31 |
78 |
--------------------------------------------------------------------------------
/src/components/Modal/Remove/Remove.svelte:
--------------------------------------------------------------------------------
1 |
35 |
36 | Remove torrents
37 |
38 |
50 |
51 |
77 |
--------------------------------------------------------------------------------
/src/components/Modal/Remove/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './Remove.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/Modal/Settings/About.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 | Flood for Transmission is an alternative Web UI for Transmission. It's a
8 | frontend web app that doesn't require any extra service running to communicate
9 | with Transmission. Even though it's a work-in-progress, it's definitely good
10 | enough to use.
11 |
12 |
13 | Flood for Transmission is a clone of
14 | Flood , which
15 | is originally build for rTorrent. All design and feature credit goes out to
16 | the creators of that. The code however is not a copy at all, it's been build
17 | from the ground up to make it work with Transmission.
18 |
19 |
20 |
21 |
22 | If you have a specific issue or bug, please file a
23 | GitHub issue . Also feel free to bring up feature requests that way.
27 |
28 |
29 |
41 |
--------------------------------------------------------------------------------
/src/components/Modal/Settings/Header.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 | {text}
6 |
7 |
15 |
--------------------------------------------------------------------------------
/src/components/Modal/Settings/Menu.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
22 |
23 |
80 |
--------------------------------------------------------------------------------
/src/components/Modal/Settings/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './Settings.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/Modal/TorrentDetail/ActionBarView/ActionBarView.svelte:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | {#if items.length}
18 |
19 |
20 | {items.length}
21 | {items.length === 1 ? itemName : itemNamePlural}
22 | selected
23 |
24 |
25 |
26 |
27 | {/if}
28 |
29 |
62 |
--------------------------------------------------------------------------------
/src/components/Modal/TorrentDetail/ActionBarView/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './ActionBarView.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/Modal/TorrentDetail/Details/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './Details.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/Modal/TorrentDetail/Files/Files.svelte:
--------------------------------------------------------------------------------
1 |
37 |
38 |
39 |
40 | {#if files.length}
41 |
53 | {:else}
54 |
55 | No files to show right now. Metadata is probably missing.
56 |
57 | {/if}
58 |
59 |
60 |
65 |
66 |
67 |
68 |
69 |
85 |
--------------------------------------------------------------------------------
/src/components/Modal/TorrentDetail/Files/IconCheckbox.svelte:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
52 |
--------------------------------------------------------------------------------
/src/components/Modal/TorrentDetail/Files/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './Files.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/Modal/TorrentDetail/Header/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './Header.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/Modal/TorrentDetail/Peers/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './Peers.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/Modal/TorrentDetail/Trackers/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './Trackers.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/Modal/TorrentDetail/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './TorrentDetail.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/Modal/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './Modal.svelte';
2 | export { default as TorrentDetail } from './TorrentDetail';
3 | export { default as Settings } from './Settings';
4 | export { default as Remove } from './Remove';
5 | export { default as Location } from './Location';
6 | export { default as Labels } from './Labels';
7 | export { default as Add } from './Add';
8 |
--------------------------------------------------------------------------------
/src/components/Panel/Panel.svelte:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
45 |
--------------------------------------------------------------------------------
/src/components/Panel/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './Panel.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/PriorityIndicator/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './PriorityIndicator.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/ProgressBar/ProgressBar.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
8 |
9 |
25 |
--------------------------------------------------------------------------------
/src/components/ProgressBar/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './ProgressBar.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/Search/Search.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
67 |
--------------------------------------------------------------------------------
/src/components/Search/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './Search.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/Select/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './Select.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/Switch/Switch.svelte:
--------------------------------------------------------------------------------
1 |
13 |
14 |
15 |
16 |
53 |
--------------------------------------------------------------------------------
/src/components/Switch/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './Switch.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/TopBar/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './TopBar.svelte';
2 |
--------------------------------------------------------------------------------
/src/components/TorrentList/ColumnHeader.svelte:
--------------------------------------------------------------------------------
1 |
21 |
22 | {#if id}
23 |
35 | {/if}
36 |
37 |
103 |
--------------------------------------------------------------------------------
/src/components/TorrentList/Renderers/ArrivalRenderer.svelte:
--------------------------------------------------------------------------------
1 |
21 |
22 |
23 | {#if value <= 0}
24 |
25 | {:else if days}
26 | {days}
27 | d
28 | {hours}
29 | hr
30 | {:else if hours}
31 | {hours}
32 | hr
33 | {minutes}
34 | m
35 | {:else if minutes}
36 | {minutes}
37 | m
38 | {seconds}
39 | s
40 | {:else}{seconds} s {/if}
41 |
42 |
43 |
55 |
--------------------------------------------------------------------------------
/src/components/TorrentList/Renderers/BooleanRenderer.svelte:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 | {#if value}
10 |
11 | {/if}
12 |
13 |
14 |
22 |
--------------------------------------------------------------------------------
/src/components/TorrentList/Renderers/ConnectionRenderer.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 | {value}
8 | of
9 | {connected}
10 |
11 |
17 |
--------------------------------------------------------------------------------
/src/components/TorrentList/Renderers/DateRenderer.svelte:
--------------------------------------------------------------------------------
1 |
45 |
46 | {#if value > 0}
47 | {getYear(date)}-{getMonth(date)}-{getDay(date)}
48 | {getHour(date, $timeConfig)}:{getMinutes(date)}
49 | {getPeriod(date, $timeConfig)}
50 | {:else}
51 | -
52 | {/if}
53 |
--------------------------------------------------------------------------------
/src/components/TorrentList/Renderers/LabelRenderer.svelte:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 | {#each value as label (label)}
10 | {label}
11 | {/each}
12 |
13 |
14 |
34 |
--------------------------------------------------------------------------------
/src/components/TorrentList/Renderers/SizeRenderer.svelte:
--------------------------------------------------------------------------------
1 |
13 |
14 | 0}
17 | class:upload={isUpload}
18 | class={torrentStatusClass}
19 | >
20 | {value}
21 | {size}
22 |
23 |
24 |
45 |
--------------------------------------------------------------------------------
/src/components/TorrentList/Renderers/TextRenderer.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 | {value}
8 |
9 |
19 |
--------------------------------------------------------------------------------
/src/components/TorrentList/Renderers/index.js:
--------------------------------------------------------------------------------
1 | export { default as TextRenderer } from './TextRenderer.svelte';
2 | export { default as ProgressRenderer } from './ProgressRenderer.svelte';
3 | export { default as DateRenderer } from './DateRenderer.svelte';
4 | export { default as SizeRenderer } from './SizeRenderer.svelte';
5 | export { default as ConnectionRenderer } from './ConnectionRenderer.svelte';
6 | export { default as ArrivalRenderer } from './ArrivalRenderer.svelte';
7 | export { default as BooleanRenderer } from './BooleanRenderer.svelte';
8 | export { default as LabelRenderer } from './LabelRenderer.svelte';
9 |
--------------------------------------------------------------------------------
/src/components/TorrentList/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './TorrentList.svelte';
2 | export { default as ColumnHeader } from './ColumnHeader.svelte';
3 | export { default as Torrent } from './Torrent.svelte';
4 |
--------------------------------------------------------------------------------
/src/helpers/actions/clickOutside.js:
--------------------------------------------------------------------------------
1 | export default function clickOutside(node, callback) {
2 | const handleClick = (event) => {
3 | if (node && !node.contains(event.target) && !event.defaultPrevented) {
4 | callback();
5 | }
6 | };
7 |
8 | document.addEventListener('click', handleClick, true);
9 |
10 | return {
11 | destroy() {
12 | document.removeEventListener('click', handleClick, true);
13 | },
14 | };
15 | }
16 |
--------------------------------------------------------------------------------
/src/helpers/actions/contextmenu.js:
--------------------------------------------------------------------------------
1 | const CONTEXT_MENU_TIMEOUT = 700;
2 |
3 | let timer = null;
4 |
5 | const startLongPressTimer = (e) => {
6 | clearLongPressTimer();
7 | timer = setTimeout(fireLongPressEvent.bind(null, e), CONTEXT_MENU_TIMEOUT);
8 | };
9 |
10 | const clearLongPressTimer = () => {
11 | clearTimeout(timer);
12 | timer = null;
13 | };
14 |
15 | const fireLongPressEvent = (originalEvent) => {
16 | clearLongPressTimer();
17 |
18 | const node = originalEvent.target;
19 | const x = originalEvent.touches[0].clientX;
20 | const y = originalEvent.touches[0].clientY;
21 |
22 | // This will emulate contextmenu mouse event
23 | const event = new MouseEvent('contextmenu', {
24 | bubbles: true,
25 | cancelable: true,
26 | clientX: x,
27 | clientY: y,
28 | });
29 |
30 | // fire the long-press event
31 | const suppressClickEvent = node.dispatchEvent.call(node, event);
32 |
33 | if (suppressClickEvent) {
34 | // temporarily intercept and clears the next click
35 | node.addEventListener(
36 | 'touchend',
37 | function clearMouseUp(e) {
38 | node.removeEventListener('touchend', clearMouseUp);
39 | cancelEvent(e);
40 | },
41 | true
42 | );
43 | }
44 | };
45 |
46 | const cancelEvent = (e) => {
47 | e.stopImmediatePropagation();
48 | e.preventDefault();
49 | e.stopPropagation();
50 | };
51 |
52 | export default function contextmenu(node) {
53 | const isIos = /(iPad|iPhone|iPod)/g.test(navigator.userAgent);
54 | if (!isIos) return;
55 |
56 | // hook events that clear a pending long press event
57 | node.addEventListener('touchcancel', clearLongPressTimer);
58 | node.addEventListener('touchend', clearLongPressTimer);
59 | node.addEventListener('touchmove', clearLongPressTimer);
60 |
61 | // hook events that can trigger a long press event
62 | node.addEventListener('touchstart', startLongPressTimer);
63 | }
64 |
--------------------------------------------------------------------------------
/src/helpers/actions/index.js:
--------------------------------------------------------------------------------
1 | export { default as clickOutside } from './clickOutside';
2 | export { default as contextmenu } from './contextmenu';
3 | export { default as orderable } from './orderable';
4 | export { default as resizeableTable } from './resizeableTable';
5 |
--------------------------------------------------------------------------------
/src/helpers/actions/orderable.js:
--------------------------------------------------------------------------------
1 | let draggingElement;
2 |
3 | const emptyImage = document.createElement('img');
4 | emptyImage.src =
5 | 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';
6 |
7 | export default function orderable(item, handleDrop) {
8 | const list = item.parentNode;
9 |
10 | const onDragStart = (e) => {
11 | e.dataTransfer.setDragImage(emptyImage, 0, 0);
12 | draggingElement = item;
13 | draggingElement.style = 'opacity: .6';
14 | };
15 |
16 | const onDragOver = (event) => {
17 | event.preventDefault();
18 |
19 | if (draggingElement.id === item.id) return;
20 |
21 | if (event.offsetY < 2) {
22 | list.insertBefore(draggingElement, item.nextSibling);
23 | } else {
24 | list.insertBefore(draggingElement, item);
25 | }
26 | };
27 |
28 | const onDrop = (event) => {
29 | event.preventDefault();
30 | const data = Array.from(list.childNodes).map((node) => {
31 | if (isNaN(node.id)) {
32 | return node.id;
33 | }
34 |
35 | return parseInt(node.id, 10);
36 | });
37 | handleDrop(data);
38 | draggingElement.style = 'opacity: 1';
39 | };
40 |
41 | item.addEventListener('dragstart', onDragStart);
42 | item.addEventListener('dragover', onDragOver);
43 | item.addEventListener('drop', onDrop);
44 |
45 | return {
46 | destroy() {
47 | item.removeEventListener('dragstart', onDragStart);
48 | item.removeEventListener('dragover', onDragOver);
49 | item.removeEventListener('drop', onDrop);
50 | },
51 | };
52 | }
53 |
--------------------------------------------------------------------------------
/src/helpers/actions/resizeableTable.js:
--------------------------------------------------------------------------------
1 | export default function resizeableTable(handle, onChange) {
2 | const column = handle.parentElement;
3 | const table = handle.closest('table');
4 | let dragging = false;
5 | let handleStartX = handle.pageX;
6 | let columnStartWidth = column.getBoundingClientRect().width;
7 | let tableStartWidth = table.getBoundingClientRect().width;
8 |
9 | const handleMousedown = (e) => {
10 | dragging = true;
11 | handleStartX = e.pageX ?? e.touches[0].pageX;
12 | columnStartWidth = column.getBoundingClientRect().width;
13 | tableStartWidth = table.getBoundingClientRect().width;
14 | };
15 |
16 | const handleMouseup = () => {
17 | if (!dragging) return;
18 |
19 | const columnWidth = column.getBoundingClientRect().width;
20 | onChange(columnWidth);
21 |
22 | dragging = false;
23 | };
24 |
25 | const handleMousemove = (e) => {
26 | if (!dragging) return;
27 |
28 | const currentX = e.pageX ?? e.touches[0].pageX;
29 | const diffX = currentX - handleStartX;
30 | column.style.width = `${columnStartWidth + diffX}px`;
31 | table.style.width = `${tableStartWidth + diffX}px`;
32 | };
33 |
34 | handle.addEventListener('mousedown', handleMousedown);
35 | document.addEventListener('mouseup', handleMouseup);
36 | document.addEventListener('mousemove', handleMousemove);
37 |
38 | handle.addEventListener('touchstart', handleMousedown);
39 | document.addEventListener('touchend', handleMouseup);
40 | document.addEventListener('touchmove', handleMousemove);
41 |
42 | return {
43 | destroy() {
44 | handle.removeEventListener('mousedown', handleMousedown);
45 | document.removeEventListener('mouseup', handleMouseup);
46 | document.removeEventListener('mousemove', handleMousemove);
47 |
48 | handle.removeEventListener('touchstart', handleMousedown);
49 | document.removeEventListener('touchend', handleMouseup);
50 | document.removeEventListener('touchmove', handleMousemove);
51 | },
52 | };
53 | }
54 |
--------------------------------------------------------------------------------
/src/helpers/classHelper.js:
--------------------------------------------------------------------------------
1 | import {
2 | STATUSES,
3 | STATUS_STOPPED,
4 | STATUS_DOWNLOADING,
5 | STATUS_SEEDING,
6 | } from '~helpers/constants/statuses';
7 | import {
8 | TRANSMISSION_COLUMN_DOWNLOAD_PROGRESS,
9 | TRANSMISSION_COLUMN_ERROR,
10 | TRANSMISSION_COLUMN_METADATA_PROGRESS,
11 | TRANSMISSION_COLUMN_STATUS,
12 | } from '~helpers/constants/columns';
13 |
14 | // Some of these may not happen since Transmission would perhaps not have metadata and checking at the same time
15 | // However, there is no documentation available for what statuses are relevant together and which are not
16 | // Full list of possible combinations:
17 | // error
18 | // stopped
19 | // active
20 | // checking
21 | // completed error
22 | // completed stopped
23 | // completed active
24 | // completed checking
25 | // metadata error
26 | // metadata stopped
27 | // metadata active
28 | // metadata checking
29 | // selected error
30 | // selected stopped
31 | // selected active
32 | // selected checking
33 | // selected completed error
34 | // selected completed stopped
35 | // selected completed active
36 | // selected completed checking
37 | // selected metadata error
38 | // selected metadata stopped
39 | // selected metadata active
40 | // selected metadata checking
41 |
42 | export function generateTorrentStatusClass(torrent, selected = false) {
43 | let progressClass = '';
44 | let statusClass = '';
45 | let selectedClass = '';
46 |
47 | if (torrent[TRANSMISSION_COLUMN_DOWNLOAD_PROGRESS] === 1) {
48 | progressClass = 'completed';
49 | } else if (torrent[TRANSMISSION_COLUMN_METADATA_PROGRESS] < 1) {
50 | progressClass = 'metadata';
51 | }
52 |
53 | if (torrent[TRANSMISSION_COLUMN_ERROR] > 1) {
54 | statusClass = 'error';
55 | } else if (STATUSES[torrent[TRANSMISSION_COLUMN_STATUS]] === STATUS_STOPPED) {
56 | statusClass = 'stopped';
57 | } else if (
58 | [STATUS_DOWNLOADING, STATUS_SEEDING].includes(
59 | STATUSES[torrent[TRANSMISSION_COLUMN_STATUS]]
60 | )
61 | ) {
62 | statusClass = 'active';
63 | } else {
64 | statusClass = 'checking';
65 | }
66 |
67 | if (selected) {
68 | selectedClass = 'selected';
69 | }
70 |
71 | return [progressClass, statusClass, selectedClass].filter(Boolean).join(' ');
72 | }
73 |
--------------------------------------------------------------------------------
/src/helpers/constants/defaultConfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "DARK_MODE": "auto",
3 | "SWITCH_COLORS": false,
4 | "NOTATION_24H": true,
5 | "WRAP_HEADER": false,
6 | "COMMON_PATH": [],
7 | "COLUMNS": [
8 | { "label": "Name", "width": 600, "enabled": true },
9 | { "label": "Progress", "width": 300, "enabled": true },
10 | { "label": "ETA", "width": 100, "enabled": true },
11 | { "label": "Download Speed", "width": 100, "enabled": true },
12 | { "label": "Upload Speed", "width": 100, "enabled": true },
13 | { "label": "File Size", "width": 100, "enabled": true },
14 | { "label": "Downloaded", "width": 100, "enabled": true },
15 | { "label": "Uploaded", "width": 100, "enabled": true },
16 | { "label": "Downloading from", "width": 100, "enabled": true },
17 | { "label": "Seeding to", "width": 100, "enabled": true }
18 | ],
19 | "SORT_COLUMN": "Progress",
20 | "SORT_DIRECTION": "desc",
21 | "SHOW_DISK_USAGE": true
22 | }
--------------------------------------------------------------------------------
/src/helpers/constants/paths.js:
--------------------------------------------------------------------------------
1 | export const PATH_VALIDATION_REGEX = '^(/|[a-zA-Z]:\\\\).*$';
2 |
--------------------------------------------------------------------------------
/src/helpers/constants/statuses.js:
--------------------------------------------------------------------------------
1 | export const STATUS_STOPPED = 'Stopped';
2 | export const STATUS_CHECK_WAITING = 'Check waiting';
3 | export const STATUS_CHECKING = 'Checking';
4 | export const STATUS_DOWNLOAD_WAITING = 'Download waiting';
5 | export const STATUS_DOWNLOADING = 'Downloading';
6 | export const STATUS_SEED_WAITING = 'Seed waiting';
7 | export const STATUS_SEEDING = 'Seeding';
8 | export const STATUSES = [
9 | STATUS_STOPPED,
10 | STATUS_CHECK_WAITING,
11 | STATUS_CHECKING,
12 | STATUS_DOWNLOAD_WAITING,
13 | STATUS_DOWNLOADING,
14 | STATUS_SEED_WAITING,
15 | STATUS_SEEDING,
16 | ];
17 |
--------------------------------------------------------------------------------
/src/helpers/copyHelper.js:
--------------------------------------------------------------------------------
1 | export function copyToClipboard(textToCopy) {
2 | if (navigator.clipboard && window.isSecureContext) {
3 | return navigator.clipboard.writeText(textToCopy);
4 | }
5 |
6 | return new Promise((resolve, reject) => {
7 | let textArea = document.createElement('textarea');
8 | textArea.value = textToCopy;
9 |
10 | textArea.style.position = 'fixed';
11 | textArea.style.left = '-999999px';
12 | textArea.style.top = '-999999px';
13 |
14 | document.body.appendChild(textArea);
15 | textArea.focus();
16 | textArea.select();
17 | document.execCommand('copy') ? resolve() : reject();
18 | textArea.remove();
19 | });
20 | }
21 |
--------------------------------------------------------------------------------
/src/helpers/fileHelper.js:
--------------------------------------------------------------------------------
1 | import { alerts } from '~helpers/stores';
2 |
3 | const toBase64 = (file) => {
4 | return new Promise((resolve, reject) => {
5 | const reader = new FileReader();
6 | reader.readAsDataURL(file);
7 | reader.onload = () => resolve(reader.result.split(',')[1]);
8 | reader.onerror = (error) => reject(error);
9 | });
10 | };
11 |
12 | export const getFileAddBody = (files, start, destination) => {
13 | const promises = files.map((file) => toBase64(file));
14 | return Promise.all(promises).then((base64Files) =>
15 | base64Files.map((base64File) => ({
16 | 'metainfo': base64File,
17 | 'paused': !start,
18 | 'download-dir': destination,
19 | }))
20 | );
21 | };
22 |
23 | export const handleTorrentAddResponses = (responses) => {
24 | const duplicateResponses = responses
25 | .map((response) => response.arguments['torrent-duplicate'])
26 | .filter(Boolean);
27 | const pluralize = responses.length > 1 ? 'torrents' : 'torrent';
28 |
29 | if (!duplicateResponses.length) {
30 | alerts.add(`Succesfully added ${responses.length} ${pluralize}`);
31 | } else if (duplicateResponses.length === responses.length) {
32 | alerts.add(`All the uploaded ${pluralize} already exist`, 'negative');
33 | } else {
34 | const pluralizeDuplicates =
35 | duplicateResponses.length > 1 ? 'torrents' : 'torrent';
36 | const successCount = responses.length - duplicateResponses.length;
37 | alerts.add(
38 | `Succesfully added ${successCount} ${pluralize}, the other ${duplicateResponses.length} ${pluralizeDuplicates} already exist`,
39 | 'negative'
40 | );
41 | }
42 | };
43 |
44 | export const areAllFilesValid = (files, acceptList) => {
45 | return files.every((file) => {
46 | const splitName = file.name.split('.');
47 | const extension = `.${splitName[splitName.length - 1]}`;
48 | return acceptList.some((type) => type === file.type || type === extension);
49 | });
50 | };
51 |
--------------------------------------------------------------------------------
/src/helpers/folderStructureHelper.js:
--------------------------------------------------------------------------------
1 | const getEmptyFolder = () => ({
2 | folders: {},
3 | files: [],
4 | });
5 |
6 | const getFile = (file, fileName) => ({
7 | ...file,
8 | fileName,
9 | });
10 |
11 | const addFolderToObject = (key, object) => {
12 | if (object[key]) return object[key];
13 | object[key] = getEmptyFolder();
14 | return object[key];
15 | };
16 |
17 | const hasWrappingFolder = (sampleFile) => sampleFile.name.split('/').length > 1;
18 |
19 | export const getAllFiles = (structure) => {
20 | return [
21 | ...structure.files,
22 | ...Object.keys(structure.folders).flatMap((folderName) =>
23 | getAllFiles(structure.folders[folderName])
24 | ),
25 | ];
26 | };
27 |
28 | // Returns the absolute path folder that contains all the files
29 | export const getMainFolder = (downloadDir, sampleFile) => {
30 | if (hasWrappingFolder(sampleFile)) {
31 | const filePathParts = sampleFile.name.split('/');
32 | return `${downloadDir}/${filePathParts[0]}`;
33 | }
34 |
35 | return downloadDir;
36 | };
37 |
38 | export const getFolderStructure = (files) => {
39 | const structure = getEmptyFolder();
40 |
41 | if (!files.length) return structure;
42 |
43 | if (!hasWrappingFolder(files[0])) {
44 | structure.files.push(getFile(files[0], files[0].name, 0));
45 | return structure;
46 | }
47 |
48 | files.forEach((file, index) => {
49 | const parts = file.name.split('/');
50 |
51 | // Remove the main folder
52 | parts.shift();
53 |
54 | const fileName = parts.pop();
55 | let prevFolder = structure;
56 | parts.forEach((folderName) => {
57 | prevFolder = addFolderToObject(folderName, prevFolder.folders);
58 | });
59 | prevFolder.files.push(getFile(file, fileName, index));
60 | });
61 |
62 | return structure;
63 | };
64 |
--------------------------------------------------------------------------------
/src/helpers/sizeHelper.js:
--------------------------------------------------------------------------------
1 | const SIZES = ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB'];
2 | const SPEED_SIZES = SIZES.map((size) => `${size}/s`);
3 |
4 | export const getSize = (
5 | value,
6 | { isSpeed = false, startSize = 'B', perSize = 1024 }
7 | ) => {
8 | if (Number.isNaN(value)) return {};
9 |
10 | let sizeIndex = startSize ? SIZES.indexOf(startSize) : 0;
11 | let sizeValue = value || 0;
12 |
13 | while (sizeValue >= perSize) {
14 | sizeIndex += 1;
15 | sizeValue /= perSize;
16 | }
17 |
18 | if (sizeValue < 100) {
19 | sizeValue = Math.round((sizeValue + Number.EPSILON) * 10) / 10;
20 | } else {
21 | sizeValue = Math.round(sizeValue);
22 | }
23 |
24 | return {
25 | value: sizeValue,
26 | size: isSpeed ? SPEED_SIZES[sizeIndex] : SIZES[sizeIndex],
27 | };
28 | };
29 |
--------------------------------------------------------------------------------
/src/helpers/stores/alerts.js:
--------------------------------------------------------------------------------
1 | import { writable } from 'svelte/store';
2 | import { uuid } from '~helpers/uuidHelper';
3 |
4 | const ALERT_DURATION = 5000;
5 |
6 | function createAlertStore() {
7 | const { subscribe, update } = writable([]);
8 |
9 | const remove = (id) =>
10 | update((state) => state.filter((alert) => alert.id !== id));
11 |
12 | return {
13 | subscribe,
14 | remove,
15 | add: (message, type = 'positive') =>
16 | update((state) => {
17 | const id = uuid();
18 | setTimeout(() => {
19 | remove(id);
20 | }, ALERT_DURATION);
21 | return [...state, { id, message, type }];
22 | }),
23 | };
24 | }
25 | export const alerts = createAlertStore();
26 |
--------------------------------------------------------------------------------
/src/helpers/stores/contextMenu.js:
--------------------------------------------------------------------------------
1 | import { writable } from 'svelte/store';
2 |
3 | function createContextMenuStore() {
4 | const { subscribe, set, update } = writable();
5 |
6 | return {
7 | subscribe,
8 | set,
9 | update,
10 | updateProps: (partialProps) =>
11 | update(($contextMenu) => {
12 | if (!$contextMenu) return $contextMenu;
13 | return {
14 | ...$contextMenu,
15 | props: {
16 | ...$contextMenu.props,
17 | ...partialProps,
18 | },
19 | };
20 | }),
21 | open: ({
22 | component,
23 | props = {},
24 | coordinates,
25 | matchElementWidth,
26 | element,
27 | ...rest
28 | }) => {
29 | const restKeys = Object.keys(rest);
30 | if (restKeys.length)
31 | throw new Error(
32 | `[ContextMenu] received unrecognized parameters ${restKeys.join(',')}`
33 | );
34 | set({
35 | component,
36 | props,
37 | coordinates,
38 | matchElementWidth,
39 | element,
40 | });
41 | },
42 | close: () => {
43 | set();
44 | },
45 | };
46 | }
47 | export const contextMenu = createContextMenuStore();
48 |
--------------------------------------------------------------------------------
/src/helpers/stores/darkMode.js:
--------------------------------------------------------------------------------
1 | import config from '~helpers/configHelper';
2 | import { get, readable, writable } from 'svelte/store';
3 |
4 | const LOCAL_STORAGE_KEY = 'darkMode';
5 |
6 | const darkModeMediaQueryList =
7 | window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)');
8 | const browserPrefersDarkModeStore = readable(
9 | darkModeMediaQueryList.matches,
10 | (set) => {
11 | const handleDarkModeChange = (e) => {
12 | set(e.matches);
13 | };
14 |
15 | darkModeMediaQueryList.addEventListener('change', handleDarkModeChange);
16 |
17 | return () => {
18 | darkModeMediaQueryList.removeEventListener(
19 | 'change',
20 | handleDarkModeChange
21 | );
22 | };
23 | }
24 | );
25 |
26 | // Returns the value from the storage or 'auto' if no storage value is found
27 | function getConfiguredValue() {
28 | return window.localStorage.getItem(LOCAL_STORAGE_KEY) ?? config.DARK_MODE;
29 | }
30 |
31 | // Returns whether darkMode is enabled
32 | // Takes into account browser configuration as well as app configuration
33 | function getDarkModeEnabled(configuredValue = getConfiguredValue()) {
34 | if (configuredValue === 'enabled') {
35 | return true;
36 | }
37 |
38 | if (configuredValue === 'disabled') {
39 | return false;
40 | }
41 |
42 | return get(browserPrefersDarkModeStore);
43 | }
44 |
45 | function createDarkModeStore() {
46 | const { subscribe, set } = writable(getDarkModeEnabled());
47 | const configuredValue = writable(getConfiguredValue());
48 |
49 | browserPrefersDarkModeStore.subscribe(() => {
50 | set(getDarkModeEnabled());
51 | });
52 |
53 | return {
54 | subscribe,
55 | configuredValue,
56 | set: (newValue) => {
57 | if (!['enabled', 'disabled', 'auto'].includes(newValue)) {
58 | throw new Error(
59 | `Invalid darkMode configuration received: ${newValue}. Should be one of enabled, disabled or auto`
60 | );
61 | }
62 | window.localStorage.setItem(LOCAL_STORAGE_KEY, newValue);
63 | configuredValue.set(newValue);
64 | set(getDarkModeEnabled(newValue));
65 | },
66 | };
67 | }
68 | export const darkMode = createDarkModeStore();
69 |
--------------------------------------------------------------------------------
/src/helpers/stores/diskUsage.js:
--------------------------------------------------------------------------------
1 | import config from '~helpers/configHelper';
2 | import { writable } from 'svelte/store';
3 |
4 | const LOCAL_STORAGE_KEY = 'diskUsage';
5 |
6 | function getConfiguredValue() {
7 | return (
8 | JSON.parse(window.localStorage.getItem(LOCAL_STORAGE_KEY)) ??
9 | config.SHOW_DISK_USAGE
10 | );
11 | }
12 |
13 | function createDiskUsage() {
14 | const { subscribe, set, update } = writable(getConfiguredValue());
15 |
16 | return {
17 | subscribe,
18 | set: (value) => {
19 | window.localStorage.setItem(LOCAL_STORAGE_KEY, value);
20 | set(value);
21 | },
22 | update,
23 | };
24 | }
25 |
26 | export const diskUsage = createDiskUsage();
27 |
--------------------------------------------------------------------------------
/src/helpers/stores/filters.js:
--------------------------------------------------------------------------------
1 | import { writable } from 'svelte/store';
2 |
3 | function createFiltersStore() {
4 | const { subscribe, set, update } = writable({
5 | search: null,
6 | status: null,
7 | label: null,
8 | tracker: null,
9 | priority: null,
10 | });
11 |
12 | return {
13 | subscribe,
14 | set,
15 | update,
16 | };
17 | }
18 | export const filters = createFiltersStore();
19 |
--------------------------------------------------------------------------------
/src/helpers/stores/index.js:
--------------------------------------------------------------------------------
1 | export { alerts } from './alerts';
2 | export { columns, uiColumns, transmissionColumns } from './columns';
3 | export { contextMenu } from './contextMenu';
4 | export { darkMode } from './darkMode';
5 | export { filters } from './filters';
6 | export { ipAddress } from './ipAddress';
7 | export { modals } from './modals';
8 | export { panel } from './panel';
9 | export { paths } from './paths';
10 | export { rateData } from './rateData';
11 | export { selectedTorrents } from './selectedTorrents';
12 | export { session } from './session';
13 | export { sessionStats } from './sessionStats';
14 | export { sorting } from './sorting';
15 | export { switchSpeedColors } from './switchSpeedColors';
16 | export { tableHeaderConfig } from './tableHeaderConfig';
17 | export { timeConfig } from './timeConfig';
18 | export { torrentDetails } from './torrentDetails';
19 | export { torrents } from './torrents';
20 | export { diskUsage } from './diskUsage';
21 |
--------------------------------------------------------------------------------
/src/helpers/stores/ipAddress.js:
--------------------------------------------------------------------------------
1 | import { writable, get } from 'svelte/store';
2 |
3 | const createIpAddressStore = () => {
4 | const { set, update, subscribe } = writable({});
5 |
6 | return {
7 | set,
8 | update,
9 | subscribe,
10 | add: (ipAddresses) => {
11 | const currentStoreValue = get({ set, update, subscribe });
12 | const existingIpAddresses = Object.keys(currentStoreValue);
13 | const newIpAddresses = ipAddresses.filter(
14 | (ip) => !existingIpAddresses.includes(ip)
15 | );
16 |
17 | if (!newIpAddresses.length) {
18 | return Promise.resolve(currentStoreValue);
19 | }
20 |
21 | return fetch(
22 | `https://get.geojs.io/v1/ip/country.json?ip=${newIpAddresses.join(',')}`
23 | )
24 | .then((response) => response.json())
25 | .then((output) => {
26 | update((value) => {
27 | output.forEach((item) => {
28 | value[item.ip] = {
29 | country_code: item.country,
30 | country_name: item.name,
31 | };
32 | });
33 | return value;
34 | });
35 | return get({ set, update, subscribe });
36 | });
37 | },
38 | };
39 | };
40 |
41 | export const ipAddress = createIpAddressStore();
42 |
--------------------------------------------------------------------------------
/src/helpers/stores/modals.js:
--------------------------------------------------------------------------------
1 | import { writable } from 'svelte/store';
2 |
3 | function createModalsStore() {
4 | const { subscribe, set, update } = writable();
5 |
6 | return {
7 | subscribe,
8 | set,
9 | update,
10 | open: ({ component, props = {}, large = false, ...rest }) => {
11 | const restKeys = Object.keys(rest);
12 | if (restKeys.length)
13 | throw new Error(
14 | `[Modals] received unrecognized parameters ${restKeys.join(',')}`
15 | );
16 | set({ component, props, large });
17 | },
18 | close: () => {
19 | set();
20 | },
21 | };
22 | }
23 | export const modals = createModalsStore();
24 |
--------------------------------------------------------------------------------
/src/helpers/stores/panel.js:
--------------------------------------------------------------------------------
1 | import { writable } from 'svelte/store';
2 |
3 | const PANEL_SHOWN_STORAGE_KEY = 'panel-shown';
4 |
5 | function createPanelStore() {
6 | const value = window.localStorage.getItem(PANEL_SHOWN_STORAGE_KEY);
7 | const { subscribe, update, set } = writable(
8 | value === 'true' || value === null
9 | );
10 |
11 | return {
12 | subscribe,
13 | toggle: () => {
14 | update((currentValue) => {
15 | window.localStorage.setItem(
16 | PANEL_SHOWN_STORAGE_KEY,
17 | (!currentValue).toString()
18 | );
19 | return !currentValue;
20 | });
21 | },
22 | close: () => {
23 | window.localStorage.setItem(PANEL_SHOWN_STORAGE_KEY, 'false');
24 | set(false);
25 | },
26 | };
27 | }
28 | export const panel = createPanelStore();
29 |
--------------------------------------------------------------------------------
/src/helpers/stores/paths.js:
--------------------------------------------------------------------------------
1 | import config from '~helpers/configHelper';
2 | import { writable } from 'svelte/store';
3 |
4 | const PATHS_STORAGE_KEY = 'paths';
5 |
6 | function getPaths() {
7 | return (
8 | JSON.parse(window.localStorage.getItem(PATHS_STORAGE_KEY)) ??
9 | config.COMMON_PATH
10 | );
11 | }
12 |
13 | function cleanValue(value) {
14 | return value.filter(Boolean);
15 | }
16 |
17 | function storeValue(value) {
18 | const cleanedValue = cleanValue(value);
19 | window.localStorage.setItem(PATHS_STORAGE_KEY, JSON.stringify(cleanedValue));
20 | }
21 |
22 | const popup = writable({ element: null, shown: false });
23 |
24 | function createPathStore() {
25 | const { subscribe, set, update } = writable(getPaths());
26 |
27 | return {
28 | subscribe,
29 | set(value) {
30 | set(value);
31 | storeValue(value);
32 | },
33 | update,
34 | popup,
35 | add(path) {
36 | let newValue;
37 | update((value) => {
38 | newValue = [...value, path];
39 | return newValue;
40 | });
41 | storeValue(newValue);
42 | },
43 | remove(removingPath) {
44 | let newValue;
45 | update((value) => {
46 | newValue = value.filter((path) => path !== removingPath);
47 | return newValue;
48 | });
49 | storeValue(newValue);
50 | },
51 | };
52 | }
53 | export const paths = createPathStore();
54 |
--------------------------------------------------------------------------------
/src/helpers/stores/rateData.js:
--------------------------------------------------------------------------------
1 | import { writable } from 'svelte/store';
2 | import { torrents } from '~helpers/stores/torrents';
3 |
4 | function createRateData() {
5 | const currentTimestamp = Date.now();
6 | const dataPoints = 60;
7 | const { subscribe, update, set } = writable({
8 | upload: new Array(dataPoints).fill(0),
9 | download: new Array(dataPoints).fill(0),
10 | timestamps: new Array(dataPoints)
11 | .fill(currentTimestamp)
12 | .map((value, index) => value - (dataPoints - index) * 1000),
13 | });
14 |
15 | torrents.totalRate.subscribe(($rate) => {
16 | const data = { ...$rate, timestamp: Date.now() };
17 | update((rateData) => {
18 | const rateDataClone = { ...rateData };
19 | rateDataClone.timestamps.shift();
20 | rateDataClone.upload.shift();
21 | rateDataClone.download.shift();
22 | rateDataClone.timestamps.push(data.timestamp);
23 | rateDataClone.upload.push(data.upload);
24 | rateDataClone.download.push(data.download);
25 | return rateDataClone;
26 | });
27 | });
28 |
29 | return {
30 | subscribe,
31 | update,
32 | set,
33 | };
34 | }
35 | export const rateData = createRateData();
36 |
--------------------------------------------------------------------------------
/src/helpers/stores/selectedTorrents.js:
--------------------------------------------------------------------------------
1 | import { writable } from 'svelte/store';
2 |
3 | function createSelectedTorrentsStore() {
4 | const { subscribe, set, update } = writable([]);
5 |
6 | return {
7 | subscribe,
8 | set,
9 | update,
10 | add: (ids) =>
11 | update((state) =>
12 | [...state, ...ids].filter((v, i, a) => a.indexOf(v) === i)
13 | ),
14 | remove: (id) => update((state) => state.filter((sid) => sid !== id)),
15 | clear: () => set([]),
16 | };
17 | }
18 | export const selectedTorrents = createSelectedTorrentsStore();
19 |
--------------------------------------------------------------------------------
/src/helpers/stores/sessionStats.js:
--------------------------------------------------------------------------------
1 | import { writable } from 'svelte/store';
2 | import Transmission from '~helpers/Transmission';
3 |
4 | const transmission = new Transmission();
5 | const SESSION_STATS_REQUEST_INTERVAL = 10000;
6 | let updateSessionTimeout;
7 | const store = writable({});
8 | const { set, subscribe } = store;
9 |
10 | function updateSessionStats(setSessionStats) {
11 | if (updateSessionTimeout) {
12 | clearTimeout(updateSessionTimeout);
13 | }
14 |
15 | transmission
16 | .getSessionStats()
17 | .then((result) => {
18 | if (!result) {
19 | return;
20 | }
21 | setSessionStats(result);
22 | })
23 | // TODO: Error handling
24 | .catch(console.error)
25 | .finally(() => {
26 | updateSessionTimeout = setTimeout(
27 | updateSessionStats.bind(null, setSessionStats),
28 | SESSION_STATS_REQUEST_INTERVAL
29 | );
30 | });
31 | }
32 |
33 | function createSessionStatsStore() {
34 | updateSessionStats(set);
35 |
36 | return {
37 | subscribe,
38 | };
39 | }
40 |
41 | export const sessionStats = createSessionStatsStore();
42 |
--------------------------------------------------------------------------------
/src/helpers/stores/sorting.js:
--------------------------------------------------------------------------------
1 | import config from '~helpers/configHelper';
2 | import { writable } from 'svelte/store';
3 |
4 | const SORTING_STORAGE_KEY = 'torrent-sorting';
5 |
6 | function storeSorting(value) {
7 | window.localStorage.setItem(SORTING_STORAGE_KEY, JSON.stringify(value));
8 | }
9 |
10 | function getSorting() {
11 | const storedSorting = JSON.parse(
12 | window.localStorage.getItem(SORTING_STORAGE_KEY)
13 | );
14 | const currentSorting = {
15 | id: storedSorting?.id ?? config.SORT_COLUMN,
16 | direction: storedSorting?.direction ?? config.SORT_DIRECTION,
17 | };
18 | storeSorting(currentSorting);
19 | return currentSorting;
20 | }
21 |
22 | function createSortingStore() {
23 | const { subscribe, set, update } = writable(getSorting());
24 |
25 | return {
26 | subscribe,
27 | set(value) {
28 | storeSorting(value);
29 | set(value);
30 | },
31 | update,
32 | updateToColumn(id) {
33 | let newValue;
34 | update((value) => {
35 | if (value.id === id && value.direction === 'desc') {
36 | newValue = { id, direction: 'asc' };
37 | return newValue;
38 | }
39 |
40 | newValue = { id, direction: 'desc' };
41 | return newValue;
42 | });
43 | window.localStorage.setItem(
44 | SORTING_STORAGE_KEY,
45 | JSON.stringify(newValue)
46 | );
47 | },
48 | };
49 | }
50 | export const sorting = createSortingStore();
51 |
--------------------------------------------------------------------------------
/src/helpers/stores/switchSpeedColors.js:
--------------------------------------------------------------------------------
1 | import config from '~helpers/configHelper';
2 | import { writable } from 'svelte/store';
3 |
4 | const LOCAL_STORAGE_KEY = 'switchSpeedColors';
5 |
6 | function getConfiguredValue() {
7 | return (
8 | JSON.parse(window.localStorage.getItem(LOCAL_STORAGE_KEY)) ??
9 | config.SWITCH_COLORS
10 | );
11 | }
12 |
13 | function createSwitchSpeedColors() {
14 | const { subscribe, set, update } = writable(getConfiguredValue());
15 |
16 | return {
17 | subscribe,
18 | set: (value) => {
19 | window.localStorage.setItem(LOCAL_STORAGE_KEY, value);
20 | set(value);
21 | },
22 | update,
23 | };
24 | }
25 |
26 | export const switchSpeedColors = createSwitchSpeedColors();
27 |
--------------------------------------------------------------------------------
/src/helpers/stores/tableHeaderConfig.js:
--------------------------------------------------------------------------------
1 | import config from '~helpers/configHelper';
2 | import { writable } from 'svelte/store';
3 |
4 | const LOCAL_STORAGE_KEY = 'tableHeaderConfig';
5 |
6 | function getConfiguredValue() {
7 | return (
8 | JSON.parse(window.localStorage.getItem(LOCAL_STORAGE_KEY)) ??
9 | config.WRAP_HEADER
10 | );
11 | }
12 |
13 | function createTableHeaderConfig() {
14 | const { subscribe, set, update } = writable(getConfiguredValue());
15 |
16 | return {
17 | subscribe,
18 | set: (value) => {
19 | window.localStorage.setItem(LOCAL_STORAGE_KEY, value);
20 | set(value);
21 | },
22 | update,
23 | };
24 | }
25 |
26 | export const tableHeaderConfig = createTableHeaderConfig();
27 |
--------------------------------------------------------------------------------
/src/helpers/stores/timeConfig.js:
--------------------------------------------------------------------------------
1 | import config from '~helpers/configHelper';
2 | import { writable } from 'svelte/store';
3 |
4 | const LOCAL_STORAGE_KEY = 'timeConfig';
5 |
6 | function getConfiguredValue() {
7 | return (
8 | JSON.parse(window.localStorage.getItem(LOCAL_STORAGE_KEY)) ??
9 | config.NOTATION_24H
10 | );
11 | }
12 |
13 | function createTimeConfig() {
14 | const { subscribe, set, update } = writable(getConfiguredValue());
15 |
16 | return {
17 | subscribe,
18 | set: (value) => {
19 | window.localStorage.setItem(LOCAL_STORAGE_KEY, value);
20 | set(value);
21 | },
22 | update,
23 | };
24 | }
25 |
26 | export const timeConfig = createTimeConfig();
27 |
--------------------------------------------------------------------------------
/src/helpers/timeHelper.js:
--------------------------------------------------------------------------------
1 | const MS = 1;
2 | const MS_PER_SECOND = MS * 1000;
3 | const MS_PER_MINUTE = MS_PER_SECOND * 60;
4 | const MS_PER_HOUR = MS_PER_MINUTE * 60;
5 | const MS_PER_DAY = MS_PER_HOUR * 24;
6 |
7 | const MINUTES_PER_HOUR = 60;
8 |
9 | export function relativeTime(timestamp) {
10 | let timeLeft = Date.now() - timestamp;
11 |
12 | const days = Math.floor(timeLeft / MS_PER_DAY);
13 | const daysText = days === 1 ? 'day' : 'days';
14 | timeLeft %= MS_PER_DAY;
15 |
16 | const hours = Math.floor(timeLeft / MS_PER_HOUR);
17 | const hoursText = hours === 1 ? 'hour' : 'hours';
18 | timeLeft %= MS_PER_HOUR;
19 |
20 | if (days && hours) {
21 | return `${days} ${daysText} and ${hours} ${hoursText} ago`;
22 | }
23 | if (days) {
24 | return `${days} ${daysText} ago`;
25 | }
26 |
27 | const minutes = Math.floor(timeLeft / MS_PER_MINUTE);
28 | const minutesText = minutes === 1 ? 'minute' : 'minutes';
29 | timeLeft %= MS_PER_MINUTE;
30 |
31 | if (hours && minutes) {
32 | return `${hours} ${hoursText} and ${minutes} ${minutesText} ago`;
33 | }
34 | if (hours) {
35 | return `${hours} ${hoursText} ago`;
36 | }
37 |
38 | const seconds = Math.floor(timeLeft / MS_PER_SECOND);
39 | const secondsText = seconds === 1 ? 'second' : 'seconds';
40 | timeLeft %= MS_PER_SECOND;
41 |
42 | if (minutes && seconds) {
43 | return `${minutes} ${minutesText} and ${seconds} ${secondsText} ago`;
44 | }
45 | if (minutes) {
46 | return `${minutes} ${minutesText} ago`;
47 | }
48 |
49 | if (seconds) {
50 | return `${seconds} ${secondsText} ago`;
51 | }
52 | return 'now';
53 | }
54 |
55 | export function minutesToTime(minutes) {
56 | let minutesLeft = minutes;
57 |
58 | let hours = Math.floor(minutesLeft / MINUTES_PER_HOUR);
59 | minutesLeft %= MINUTES_PER_HOUR;
60 |
61 | if (hours === 0) {
62 | hours = '00';
63 | } else if (hours < 10) {
64 | hours = `0${hours}`;
65 | }
66 |
67 | if (minutesLeft === 0) {
68 | minutesLeft = '00';
69 | } else if (minutesLeft < 10) {
70 | minutesLeft = `0${minutesLeft}`;
71 | }
72 |
73 | return `${hours}:${minutesLeft}`;
74 | }
75 |
76 | export function timeToMinutes(time) {
77 | const splitTime = time.split(':');
78 | const hours = parseInt(splitTime[0], 10);
79 | const minutes = parseInt(splitTime[1], 10);
80 | return hours * MINUTES_PER_HOUR + minutes;
81 | }
82 |
--------------------------------------------------------------------------------
/src/helpers/trackerHelper.js:
--------------------------------------------------------------------------------
1 | export function trackerStripper(trackerUrl) {
2 | const parts = trackerUrl
3 | .split('://')[1]
4 | .split(':')[0]
5 | .split('/')[0]
6 | .split('.');
7 | return [parts[parts.length - 2], parts[parts.length - 1]].join('.');
8 | }
9 |
--------------------------------------------------------------------------------
/src/helpers/urlHelper.js:
--------------------------------------------------------------------------------
1 | export const isValidUrl = (url) => {
2 | try {
3 | new URL(url);
4 | return true;
5 | // eslint-disable-next-line no-unused-vars
6 | } catch (e) {
7 | return false;
8 | }
9 | };
10 |
--------------------------------------------------------------------------------
/src/helpers/uuidHelper.js:
--------------------------------------------------------------------------------
1 | export function uuid() {
2 | return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) =>
3 | (
4 | c ^
5 | ((crypto.getRandomValues(new Uint8Array(1))[0] & 15) >> (c / 4))
6 | ).toString(16)
7 | );
8 | }
9 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import { mount } from 'svelte';
2 | import App from '~components/App';
3 |
4 | if (__ENV__ === 'production' && 'serviceWorker' in navigator) {
5 | navigator.serviceWorker.register('./sw.js', {
6 | scope: window.location.pathname,
7 | });
8 | }
9 |
10 | mount(App, {
11 | target: document.body,
12 | });
13 |
--------------------------------------------------------------------------------
/workbox-config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | "globDirectory": "public/",
3 | "globPatterns": [
4 | "**/*.{js,css,html,woff2}"
5 | ],
6 | "swDest": "public/sw.js"
7 | };
8 |
--------------------------------------------------------------------------------