├── .eslintrc.json
├── .github
├── ISSUE_TEMPLATE
│ ├── broken-bypass.yml.old
│ ├── bug-report.yml.old
│ ├── config.yml
│ └── new-bypass.yml.old
├── dependabot.yml
├── pull_request_template.md
└── workflows
│ ├── PR_bot.yml
│ ├── Release.yml
│ ├── WebStoreDeploy.yml
│ ├── codeql-analysis.yml
│ ├── issues.yml
│ ├── main.yml
│ └── pull.yml
├── .gitignore
├── .ip_logger_patterns.php
├── .prettierrc
├── .update_locales.php
├── CONTRIBUTING.md
├── CONTRIBUTORS.md
├── LICENSE
├── PRIVACY.md
├── README.md
├── crowdin.yml
├── docs
├── Bypassed.md
├── CODE_STYLE.md
├── CONTRIBUTING.md
├── CONTRIBUTORS.md
├── Git_CLI.md
├── INSTALLING.md
└── PRIVACY.md
├── package-lock.json
├── package.json
├── platform_spec
├── chromium
│ └── manifest.json
└── firefox
│ └── manifest.json
├── scripts
├── build.js
└── build_js
│ ├── injection_script_template.js
│ └── utils.js
├── src
├── _locales
│ ├── af
│ │ └── messages.json
│ ├── am
│ │ └── messages.json
│ ├── an
│ │ └── messages.json
│ ├── ar
│ │ └── messages.json
│ ├── ast
│ │ └── messages.json
│ ├── az
│ │ └── messages.json
│ ├── bg
│ │ └── messages.json
│ ├── bn-IN
│ │ └── messages.json
│ ├── bn
│ │ └── messages.json
│ ├── br
│ │ └── messages.json
│ ├── bs
│ │ └── messages.json
│ ├── ca
│ │ └── messages.json
│ ├── ckb
│ │ └── messages.json
│ ├── cs
│ │ └── messages.json
│ ├── cy
│ │ └── messages.json
│ ├── da
│ │ └── messages.json
│ ├── de-AT
│ │ └── messages.json
│ ├── de-CH
│ │ └── messages.json
│ ├── de-LI
│ │ └── messages.json
│ ├── de
│ │ └── messages.json
│ ├── el
│ │ └── messages.json
│ ├── en
│ │ └── messages.json
│ ├── eo
│ │ └── messages.json
│ ├── es
│ │ └── messages.json
│ ├── et
│ │ └── messages.json
│ ├── fa
│ │ └── messages.json
│ ├── fi
│ │ └── messages.json
│ ├── fil
│ │ └── messages.json
│ ├── fr
│ │ └── messages.json
│ ├── ga-IE
│ │ └── messages.json
│ ├── gd
│ │ └── messages.json
│ ├── gl
│ │ └── messages.json
│ ├── gu-IN
│ │ └── messages.json
│ ├── he
│ │ └── messages.json
│ ├── hi
│ │ └── messages.json
│ ├── hmn
│ │ └── messages.json
│ ├── hr
│ │ └── messages.json
│ ├── hu
│ │ └── messages.json
│ ├── hy-AM
│ │ └── messages.json
│ ├── id
│ │ └── messages.json
│ ├── it
│ │ └── messages.json
│ ├── ja
│ │ └── messages.json
│ ├── jv
│ │ └── messages.json
│ ├── ka
│ │ └── messages.json
│ ├── kn
│ │ └── messages.json
│ ├── ko
│ │ └── messages.json
│ ├── lo
│ │ └── messages.json
│ ├── lt
│ │ └── messages.json
│ ├── lv
│ │ └── messages.json
│ ├── mi
│ │ └── messages.json
│ ├── mk
│ │ └── messages.json
│ ├── ml-IN
│ │ └── messages.json
│ ├── ms
│ │ └── messages.json
│ ├── my
│ │ └── messages.json
│ ├── nl
│ │ └── messages.json
│ ├── no
│ │ └── messages.json
│ ├── pl
│ │ └── messages.json
│ ├── pt-BR
│ │ └── messages.json
│ ├── pt-PT
│ │ └── messages.json
│ ├── ro
│ │ └── messages.json
│ ├── ru
│ │ └── messages.json
│ ├── sh
│ │ └── messages.json
│ ├── si-LK
│ │ └── messages.json
│ ├── sk
│ │ └── messages.json
│ ├── sl
│ │ └── messages.json
│ ├── sq
│ │ └── messages.json
│ ├── sr
│ │ └── messages.json
│ ├── su
│ │ └── messages.json
│ ├── sv-SE
│ │ └── messages.json
│ ├── ta
│ │ └── messages.json
│ ├── te
│ │ └── messages.json
│ ├── th
│ │ └── messages.json
│ ├── tr
│ │ └── messages.json
│ ├── uk
│ │ └── messages.json
│ ├── uz
│ │ └── messages.json
│ ├── vi
│ │ └── messages.json
│ ├── yi
│ │ └── messages.json
│ ├── zh-CN
│ │ └── messages.json
│ ├── zh-TW
│ │ └── messages.json
│ └── zu
│ │ └── messages.json
├── bypasses
│ ├── 1link.js
│ ├── 1shortlink.js
│ ├── BypassDefinition.js
│ ├── acortalink.js
│ ├── admaven.js
│ ├── adtival.js
│ ├── akoam.js
│ ├── akwam.js
│ ├── an1.js
│ ├── androidtop.js
│ ├── anonym.js
│ ├── apkhubs.js
│ ├── blitly.js
│ ├── blogtech.js
│ ├── bluemediafile.js
│ ├── boost.js
│ ├── brpaper.js
│ ├── bstlar.js
│ ├── cbrun.js
│ ├── cheatsquad.js
│ ├── clictune.js
│ ├── complete2unlock.js
│ ├── cpmlink.js
│ ├── crackedappsstore.js
│ ├── curseforge.js
│ ├── daominhha.js
│ ├── earnme.js
│ ├── enlacito.js
│ ├── favpng.js
│ ├── fclc.js
│ ├── filedm.js
│ ├── filefactory.js
│ ├── filehorse.js
│ ├── filepuma.js
│ ├── firefaucet.js
│ ├── fiveplay.js
│ ├── forex1pro.js
│ ├── fourshared.js
│ ├── fssquad.js
│ ├── gamesmega.js
│ ├── get2clickblogspot.js
│ ├── getwallpapers.js
│ ├── gixen.js
│ ├── idnation.js
│ ├── indishare.js
│ ├── leitup.js
│ ├── letsboost.js
│ ├── liblink.js
│ ├── linegee.js
│ ├── linksht.js
│ ├── linkspy.js
│ ├── linkvertise.js
│ ├── lkc21.js
│ ├── lnk.js
│ ├── lnk2.js
│ ├── lnk2cc.js
│ ├── longfiles.js
│ ├── lootlink.js
│ ├── mangalist.js
│ ├── manualsbooks.js
│ ├── mobi2c.js
│ ├── mydramalist.js
│ ├── oko.js
│ ├── onelink.js
│ ├── onepieceex.js
│ ├── onlinefix.js
│ ├── oracle.js
│ ├── ouo.js
│ ├── oxy.js
│ ├── pcgamestorrents.js
│ ├── pirateproxy.js
│ ├── portableapps.js
│ ├── ps4linux.js
│ ├── rekonise.js
│ ├── ryn.js
│ ├── sfile.js
│ ├── shortenbuddy.js
│ ├── shortly.js
│ ├── shortmoz.js
│ ├── softpedia.js
│ ├── sourceforge.js
│ ├── spaste.js
│ ├── squidssh.js
│ ├── srtam.js
│ ├── sub2unlock.js
│ ├── sub4unlock.js
│ ├── syosetu.js
│ ├── tii.js
│ ├── tiklat.js
│ ├── tlgd.js
│ ├── uiz.js
│ ├── uploadking.js
│ ├── uploadrar.js
│ ├── ux9.js
│ ├── vk.js
│ ├── wadooo.js
│ ├── workclick.js
│ ├── workink.js
│ └── ytsubme.js
├── helpers
│ ├── dom.js
│ └── infobox.js
├── html
│ ├── base.js
│ ├── before-navigate.html
│ ├── before-navigate.js
│ ├── blocked.html
│ ├── consent.html
│ ├── consent.js
│ ├── crowd-bypassed.html
│ ├── crowd-bypassed.js
│ ├── i18n.js
│ ├── noscript.html
│ ├── options.html
│ ├── options.js
│ ├── popup.html
│ ├── popup.js
│ ├── style.css
│ ├── tracker-bypass.html
│ └── tracker-bypass.js
├── icon
│ ├── 128.png
│ ├── 150.png
│ ├── 176.png
│ ├── 48.png
│ ├── 512.png
│ └── branding.png
├── icon_disabled
│ ├── 128.png
│ ├── 150.png
│ ├── 176.png
│ ├── 48.png
│ └── 512.png
├── js
│ ├── background.js
│ ├── constants.js
│ ├── content_script.js
│ ├── injection_script-original.js
│ └── rules.json
└── version.txt
└── tests
├── bypasses.json
├── index.js
└── package.json
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "es2021": true
5 | },
6 | "extends": ["eslint:recommended", "prettier"],
7 | "overrides": [
8 | ],
9 | "parserOptions": {
10 | "ecmaVersion": "latest",
11 | "sourceType": "module"
12 | },
13 | "rules": {
14 | },
15 | "globals": {
16 | "browser" :"readonly",
17 | "chrome" :"readonly"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/broken-bypass.yml.old:
--------------------------------------------------------------------------------
1 | name: Broken Bypass
2 | description: A bypass is misbehaving or no-longer working
3 | labels: [Broken-bypass]
4 | body:
5 | - type: markdown
6 | attributes:
7 | value: |
8 | ## Note
9 | Issues are not a place to go ask support questions.
10 | Please ask support questions on the [Discord](https://discord.gg/RSAf7b5njt).
11 |
12 | ### **Please don't submit multiple issue about the same website. [Search](https://github.com/FastForwardTeam/FastForward/labels/Broken-bypass) if the domain has been reported before filing the issue.**
13 | Thanks for taking the time to fill out this form!
14 |
15 | ### MV3 has less bypasses than MV2 version, we are working to migrate all bypasses.
16 | - type: input
17 | id: domain
18 | attributes:
19 | label: Link
20 | description: Submit the link you are trying to bypass.
21 | placeholder: 'Just the name of the site. example: gotiny.cc/p4bwaa'
22 | validations:
23 | required: true
24 | ### Removed: duplicate field
25 | #- type: input
26 | #id: site
27 | # attributes:
28 | #label: Link
29 | #description: Submit the exact link you are on.
30 | #placeholder: 'Example: https://www.google.com/webhp'
31 | #validations:
32 | #required: true
33 | ### Removed: duplicate field
34 | - type: dropdown
35 | id: version
36 | attributes:
37 | label: Version
38 | description: What version of the extension are you running?
39 | options:
40 | - Manifest-v2
41 | - Manifest-v3
42 | validations:
43 | required: true
44 | - type: dropdown
45 | id: browsers
46 | attributes:
47 | label: What browser(s) are you seeing the problem on?
48 | multiple: true
49 | options:
50 | - Firefox browsers
51 | - Chrome browsers (includes brave, edge, opera, etc)
52 | validations:
53 | required: true
54 | - type: dropdown
55 | id: os
56 | attributes:
57 | label: What platform are you seeing the problem on?
58 | options:
59 | - Computer (Windows, Linux, MacOS)
60 | - Phone (Android)
61 | validations:
62 | required: true
63 | - type: textarea
64 | attributes:
65 | label: Anything else?
66 | description: |
67 | Images? Videos? Anything that will give us more context about the issue you are encountering!
68 | The more information you give us, the fast we will solve the issue
69 |
70 | Tip: You can attach images files by clicking this area to highlight it and then dragging files in.
71 | validations:
72 | required: false
73 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug-report.yml.old:
--------------------------------------------------------------------------------
1 | name: Bug report
2 | title: "[Bug] "
3 | description: Something is not working in the extension
4 | labels: [Bug]
5 | body:
6 | - type: markdown
7 | attributes:
8 | value: |
9 | ## Note
10 | Issues are not a place to go ask support questions.
11 | Please ask support questions on the [Discord](https://discord.gg/RSAf7b5njt).
12 |
13 | ### **This form is not for reporting sites that are not bypassed**
14 | Thanks for taking the time to fill out this form!
15 | - type: textarea
16 | id: body
17 | attributes:
18 | label: Body
19 | description: Description of the issue you are facing
20 | validations:
21 | required: true
22 | - type: dropdown
23 | id: version
24 | attributes:
25 | label: Version
26 | description: What version of the extension are you running?
27 | options:
28 | - Manifest-v2
29 | - Manifest-v3
30 | validations:
31 | required: true
32 | - type: dropdown
33 | id: browsers
34 | attributes:
35 | label: What browser(s) are you seeing the problem on?
36 | multiple: true
37 | options:
38 | - Firefox browsers
39 | - Chrome browsers (includes brave, edge, opera, etc)
40 | validations:
41 | required: true
42 | - type: dropdown
43 | id: os
44 | attributes:
45 | label: What platform are you seeing the problem on?
46 | options:
47 | - Computer (Windows, Linux, MacOS)
48 | - Phone (Android)
49 | validations:
50 | required: true
51 | - type: textarea
52 | attributes:
53 | label: Anything else?
54 | description: |
55 | Images? Videos? Anything that will give us more context about the issue you are encountering!
56 |
57 | Tip: You can attach images files by clicking this area to highlight it and then dragging files in.
58 | validations:
59 | required: false
60 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 | contact_links:
3 | - name: Discord
4 | url: https://discord.gg/RSAf7b5njt
5 | about: We arent maintaining the extension anymore, but you can still join our Discord to chat with us.
6 | #- name: Issues
7 | #url: https://github.com/FastForwardTeam/FastForward/issues?q=label%3ANew-bypass
8 | #about: Please search before issues to check if a site is already submitted.
9 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/new-bypass.yml.old:
--------------------------------------------------------------------------------
1 | name: New Bypass
2 | description: "A website isn't bypassed"
3 | labels: [New-bypass]
4 | body:
5 | - type: markdown
6 | attributes:
7 | value: |
8 | ## Note
9 | Issues are not a place to go ask support questions.
10 | Please ask support questions on the [Discord](https://discord.gg/RSAf7b5njt).
11 |
12 | ### **Please don't submit multiple issues about the same website. [Search](https://github.com/FastForwardTeam/FastForward/labels/New-bypass) if the domain has been reported before filing the issue.**
13 | Thanks for taking the time to fill out this form!
14 | ### Disabled: duplicated field
15 | #- type: input
16 | #id: domain
17 | #attributes:
18 | #label: Domain
19 | #description: Submit one website only.
20 | #placeholder: 'Just the name of the site. example: https://google.com'
21 | #validations:
22 | #required: true
23 | ### Disabled: duplicated field
24 | - type: input
25 | id: site
26 | attributes:
27 | label: Link
28 | description: Submit the exact link you are on. Please mark as NSFW if the site contains material suitable for ages 18+ only.
29 | placeholder: 'Example: https://www.google.com/webhp'
30 | validations:
31 | required: true
32 | - type: dropdown
33 | id: version
34 | attributes:
35 | label: Version
36 | description: What version of the extension are you running?
37 | options:
38 | - Manifest-v2
39 | - Manifest-v3
40 | validations:
41 | required: true
42 | - type: dropdown
43 | id: browsers
44 | attributes:
45 | label: What browser(s) are you using?
46 | multiple: true
47 | options:
48 | - Firefox browsers
49 | - Chrome browsers (includes brave, edge, opera, etc)
50 | validations:
51 | required: true
52 | - type: dropdown
53 | id: os
54 | attributes:
55 | label: What platform are you using?
56 | options:
57 | - Computer (Windows, Linux, MacOS)
58 | - Phone (Android)
59 | validations:
60 | required: true
61 | - type: textarea
62 | attributes:
63 | label: (Optional) Anything else?
64 | description: |
65 | Images? Videos? Anything that will give us more context about the issue you are encountering!
66 |
67 | Tip: You can attach images files by clicking this area to highlight it and then dragging files in.
68 | validations:
69 | required: false
70 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "github-actions"
4 | on:
5 | push:
6 | pull_request:
7 | types: [opened]
8 | directory: ".github/workflows"
9 | schedule:
10 | interval: "weekly"
11 | - package-ecosystem: "npm"
12 | on:
13 | push:
14 | pull_request:
15 | types: [opened]
16 | directory: "/"
17 | schedule:
18 | interval: "weekly"
19 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | Fix(es):
2 |
3 |
4 |
5 | - [ ] I made sure there are no unnecessary changes in the code;
6 | - [ ] Tested on Chromium (Includes Opera, Brave, Vivaldi, Edge, etc);
7 | - [ ] Tested on Firefox.
8 |
--------------------------------------------------------------------------------
/.github/workflows/PR_bot.yml:
--------------------------------------------------------------------------------
1 | name: Comment on pull request
2 | on:
3 | workflow_run:
4 | workflows: ['Pull_req']
5 | types: [completed]
6 | jobs:
7 | pr_comment:
8 | if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success'
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/github-script@v3
12 | with:
13 | # This snippet is public-domain, taken from
14 | # https://github.com/oprypin/nightly.link/blob/master/.github/workflows/pr-comment.yml
15 | script: |
16 | const {owner, repo} = context.repo;
17 | const run_id = ${{github.event.workflow_run.id}};
18 | const pull_head_sha = '${{github.event.workflow_run.head_sha}}';
19 | const pull_user_id = ${{github.event.sender.id}};
20 | const issue_number = await (async () => {
21 | const pulls = await github.pulls.list({owner, repo});
22 | for await (const {data} of github.paginate.iterator(pulls)) {
23 | for (const pull of data) {
24 | if (pull.head.sha === pull_head_sha && pull.user.id === pull_user_id) {
25 | return pull.number;
26 | }
27 | }
28 | }
29 | })();
30 | if (issue_number) {
31 | core.info(`Using pull request ${issue_number}`);
32 | } else {
33 | return core.error(`No matching pull request found`);
34 | }
35 | const {data: {artifacts}} = await github.actions.listWorkflowRunArtifacts({owner, repo, run_id});
36 | if (!artifacts.length) {
37 | return core.error(`No artifacts found`);
38 | }
39 | let body = `Download the artifacts for this pull request:\n`;
40 | for (const art of artifacts) {
41 | body += `\n* [${art.name}.zip](https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip)`;
42 | }
43 | const {data: comments} = await github.issues.listComments({repo, owner, issue_number});
44 | const existing_comment = comments.find((c) => c.user.login === 'github-actions[bot]');
45 | if (existing_comment) {
46 | core.info(`Updating comment ${existing_comment.id}`);
47 | await github.issues.updateComment({repo, owner, comment_id: existing_comment.id, body});
48 | } else {
49 | core.info(`Creating a comment`);
50 | await github.issues.createComment({repo, owner, issue_number, body});
51 | }
52 |
--------------------------------------------------------------------------------
/.github/workflows/Release.yml:
--------------------------------------------------------------------------------
1 | name: Tag and Release
2 | on:
3 | workflow_dispatch:
4 | inputs:
5 | version:
6 | description: 'Version'
7 | required: true
8 |
9 | jobs:
10 | build:
11 | runs-on: ubuntu-latest
12 | steps:
13 | - name: Checkout repository
14 | uses: actions/checkout@v3
15 |
16 | - name: Setup Node.js
17 | uses: actions/setup-node@v3
18 | with:
19 | node-version: 'lts/*'
20 |
21 | - name: Install dependencies
22 | run: npm ci
23 |
24 | - name: Update version
25 | run: echo '${{ github.event.inputs.version }}' > src/version.txt
26 |
27 | - name: Build extension
28 | run: node ./scripts/build.js all ver
29 |
30 | - name: Sign for Firefox
31 | run: npx web-ext sign --source-dir /builds/FastForward.firefox --api-key ${{ secrets.FIREFOX_API_KEY }} --api-secret ${{ secrets.FIREFOX_API_SECRET }}
32 |
33 | - name: Tag
34 | env:
35 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
36 | run: |
37 | git config --global user.email "git@fastforward.team"
38 | git config --global user.name "FastForward Team"
39 | git tag -a ${{ github.event.inputs.version }} -m "Version ${{ github.event.inputs.version }}"
40 | git push origin ${{ github.event.inputs.version }}
41 |
42 | - name: Release
43 | uses: softprops/action-gh-release@v1
44 | with:
45 | files: |
46 | web-ext-artifacts/*.xpi
47 | build/dist/FastForward_chromium*
48 |
--------------------------------------------------------------------------------
/.github/workflows/WebStoreDeploy.yml:
--------------------------------------------------------------------------------
1 | name: Deploy to all web stores
2 |
3 | on: workflow_dispatch
4 |
5 | jobs:
6 | Build_and_upload:
7 | runs-on: ubuntu-latest
8 | steps:
9 | - uses: actions/checkout@v2
10 | with:
11 | fetch-depth: 0
12 | ref: manifest-v3
13 | - name: Make package
14 | run: |
15 | npm install
16 | node ./scripts/build.js
17 | - name: Read commit number
18 | id: read_commit_number
19 | run: |
20 | VERSION=$(jq -r '.version' manifest.json)
21 | COMMIT_NUMBER=$(echo $VERSION | cut -d '.' -f 2)
22 | echo "::set-output name=commit_number::$COMMIT_NUMBER"
23 | - name: Browser Platform Publisher
24 | uses: PlasmoHQ/bpp@v3.2.1
25 | with:
26 | keys: ${{ secrets.BPP_KEYS }}
27 | chrome-file: ./build/dist/FastForward_chromium_${{ steps.read_commit_number.outputs.commit_number }}.zip
28 | edge-file: ./build/dist/FastForward_chromium_${{ steps.read_commit_number.outputs.commit_number }}.zip
29 | firefox-file: ./build/dist/FastForward_firefox_${{ steps.read_commit_number.outputs.commit_number }}.xpi
30 | version-file: ./build/dist/FastForward.firefox/manifest.json
31 |
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | # For most projects, this workflow file will not need changing; you simply need
2 | # to commit it to your repository.
3 | #
4 | # You may wish to alter this file to override the set of languages analyzed,
5 | # or to provide custom queries or build logic.
6 | #
7 | # ******** NOTE ********
8 | # We have attempted to detect the languages in your repository. Please check
9 | # the `language` matrix defined below to confirm you have the correct set of
10 | # supported CodeQL languages.
11 | #
12 | name: "CodeQL"
13 |
14 | on:
15 | push:
16 | branches: [ main , manifest-v3 ]
17 | pull_request:
18 | # The branches below must be a subset of the branches above
19 | branches: [ main , manifest-v3 ]
20 | schedule:
21 | - cron: '39 5 * * 5'
22 |
23 | jobs:
24 | analyze:
25 | name: Analyze
26 | runs-on: ubuntu-latest
27 | permissions:
28 | actions: read
29 | contents: read
30 | security-events: write
31 |
32 | strategy:
33 | fail-fast: false
34 | matrix:
35 | language: [ 'javascript' ]
36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
37 | # Learn more about CodeQL language support at https://git.io/codeql-language-support
38 |
39 | steps:
40 | - name: Checkout repository
41 | uses: actions/checkout@v3
42 |
43 | # Initializes the CodeQL tools for scanning.
44 | - name: Initialize CodeQL
45 | uses: github/codeql-action/init@v2
46 | with:
47 | languages: ${{ matrix.language }}
48 | # If you wish to specify custom queries, you can do so here or in a config file.
49 | # By default, queries listed here will override any specified in a config file.
50 | # Prefix the list here with "+" to use these queries and those in the config file.
51 | # queries: ./path/to/local/query, your-org/your-repo/queries@main
52 |
53 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
54 | # If this step fails, then you should remove it and run the build manually (see below)
55 | - name: Autobuild
56 | uses: github/codeql-action/autobuild@v2
57 |
58 | # ℹ️ Command-line programs to run using the OS shell.
59 | # 📚 https://git.io/JvXDl
60 |
61 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
62 | # and modify them (or add more) to build your code if your project
63 | # uses a compiled language
64 |
65 | #- run: |
66 | # make bootstrap
67 | # make release
68 |
69 | - name: Perform CodeQL Analysis
70 | uses: github/codeql-action/analyze@v2
71 |
--------------------------------------------------------------------------------
/.github/workflows/issues.yml:
--------------------------------------------------------------------------------
1 | name: Close inactive issues
2 | on:
3 | schedule:
4 | - cron: "0 0 1 * *"
5 | workflow_dispatch:
6 |
7 | jobs:
8 | close-issues:
9 | runs-on: ubuntu-latest
10 | permissions:
11 | issues: write
12 | pull-requests: write
13 | steps:
14 | - uses: actions/stale@v5
15 | with:
16 | days-before-issue-stale: 1
17 | days-before-issue-close: 2
18 | operations-per-run: 900
19 | stale-issue-label: "stale"
20 | exempt-issue-labels: "no stale"
21 | stale-issue-message: "This issue will be closed soon, please see https://github.com/FastForwardTeam/FastForward/issues/1504"
22 | close-issue-message: "FastForward is no longer being actively maintained, see https://github.com/FastForwardTeam/FastForward/issues/1504 for more information."
23 | days-before-pr-stale: 30
24 | days-before-pr-close: 60
25 | repo-token: ${{ secrets.GITHUB_TOKEN }}
26 |
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: Package
2 |
3 | on:
4 | push:
5 | branches: [main, manifest-v3]
6 |
7 | workflow_dispatch:
8 |
9 | jobs:
10 | Chromium:
11 | runs-on: ubuntu-latest
12 |
13 | steps:
14 | - uses: actions/checkout@v3
15 | with:
16 | # pulls all commits (needed for commits to version)
17 | fetch-depth: 0
18 |
19 | - uses: actions/setup-node@v3
20 | with:
21 | node-version: 'lts/*'
22 | cache: 'npm'
23 |
24 | - name: Install dependencies
25 | run: npm ci
26 |
27 | - name: Make package
28 | run: node ./scripts/build.js chromium nover
29 |
30 | - name: Upload Package Artifact
31 | uses: actions/upload-artifact@v3
32 | with:
33 | name: FastForward_chromium
34 | path: build/dist
35 | if-no-files-found: error
36 |
37 | Firefox:
38 | runs-on: ubuntu-latest
39 |
40 | steps:
41 | - uses: actions/checkout@v3
42 | with:
43 | fetch-depth: 0
44 |
45 | - uses: actions/setup-node@v3
46 | with:
47 | node-version: 'lts/*'
48 | cache: 'npm'
49 |
50 | - name: Install dependencies
51 | run: npm ci
52 |
53 | - name: Make package
54 | run: node ./scripts/build.js firefox nover
55 |
56 | - name: Upload Package Artifact
57 | uses: actions/upload-artifact@v3
58 | with:
59 | name: FastForward_firefox
60 | path: build/dist
61 | if-no-files-found: error
62 |
--------------------------------------------------------------------------------
/.github/workflows/pull.yml:
--------------------------------------------------------------------------------
1 | name: Pull_req
2 |
3 | on: pull_request
4 |
5 | jobs:
6 | Chromium:
7 | runs-on: ubuntu-latest
8 |
9 | steps:
10 | - uses: actions/checkout@v3
11 | with:
12 | # pulls all commits (needed for commits to version)
13 | fetch-depth: 0
14 |
15 | - uses: actions/setup-node@v3
16 | with:
17 | node-version: 'lts/*'
18 | cache: 'npm'
19 |
20 | - name: Install dependencies
21 | run: npm ci
22 |
23 | - name: Make package
24 | run: node ./scripts/build.js chromium nover
25 |
26 | - name: Upload Package Artifact
27 | uses: actions/upload-artifact@v3
28 | with:
29 | name: FastForward_chromium
30 | path: build/dist
31 | if-no-files-found: error
32 |
33 | Firefox:
34 | runs-on: ubuntu-latest
35 |
36 | steps:
37 | - uses: actions/checkout@v3
38 | with:
39 | fetch-depth: 0
40 |
41 | - uses: actions/setup-node@v3
42 | with:
43 | node-version: 'lts/*'
44 | cache: 'npm'
45 |
46 | - name: Install dependencies
47 | run: npm ci
48 |
49 | - name: Make package
50 | run: node ./scripts/build.js firefox nover
51 |
52 | - name: Upload Package Artifact
53 | uses: actions/upload-artifact@v3
54 | with:
55 | name: FastForward_firefox
56 | path: build/dist
57 | if-no-files-found: error
58 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .next_build_id.txt
2 | build/
3 | node_modules
4 | injection_script.js
5 | .DS_Store
--------------------------------------------------------------------------------
/.ip_logger_patterns.php:
--------------------------------------------------------------------------------
1 | open("FastForward (translations).zip") or die("Failed to open FastForward (translations).zip\n");
27 | rename("_locales/en/messages.json", "messages.json");
28 | recursivelyDelete("_locales");
29 | $zip->extractTo("_locales");
30 | foreach(scandir("_locales") as $locale)
31 | {
32 | if(in_array($locale, [".", ".."]))
33 | {
34 | continue;
35 | }
36 | unlink("_locales/{$locale}/marketing.json");
37 | $cont = file_get_contents("_locales/{$locale}/messages.json");
38 | if(rtrim($cont) == "{}")
39 | {
40 | recursivelyDelete("_locales/{$locale}");
41 | continue;
42 | }
43 | $json = json_decode($cont, true);
44 | foreach($json as $key => $data)
45 | {
46 | if(in_array($key, ["bypassCounter", "optionsNavigationDelay", "optionsCrowdAutoOpen", "optionsCrowdAutoClose", "beforeNavigateDestination", "beforeNavigateTimer", "beforeNavigateUnsafeTimer", "beforeNavigateInstant", "crowdBypassedInfo", "crowdBypassedTimer", "crowdCloseTimer"]))
47 | {
48 | if(strpos($data["message"], "$1") === false)
49 | {
50 | echo "$key in $locale is missing $1\n";
51 | }
52 | }
53 | else
54 | {
55 | if(strpos($data["message"], "$1") !== false)
56 | {
57 | echo "$key in $locale has a superfluous $1\n";
58 | }
59 | }
60 | if(in_array($key, ["infoLinkvertise","infoFileHoster","infoOutdated","crowdWait","crowdDisabled"]))
61 | {
62 | if(strpos($data["message"], "\n") !== false)
63 | {
64 | echo "$key in $locale has a new line character\n";
65 | }
66 | }
67 | }
68 | if(in_array($locale, ["es-ES", "br-FR"]))
69 | {
70 | rename("_locales/{$locale}", "_locales/".substr($locale, 0, 2));
71 | }
72 | }
73 | $zip->close();
74 | unlink("FastForward (translations).zip");
75 | mkdir("_locales/en");
76 | rename("messages.json", "_locales/en/messages.json");
77 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
FastForward
4 |
Don't waste your time with compliance. FastForward automatically skips annoying link shorteners.
5 |
6 |
7 |
8 | [
](https://github.com/FastForwardTeam/FastForward/blob/main/.github/workflows/main.yml)
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | # Contributing to FastForward
17 | Thanks for taking the time to contribute to FastForward, it is volunteers like you who make this project possible.
18 |
19 | ## Contributing bypasses
20 |
21 | ### Making the bypass
22 | Initially, you may use the custom bypasses section on the extension's settings page to test out and formulate your bypass, but after that we recommend using a code editor like [VSCode](https://code.visualstudio.com/download)/[Codium](https://vscodium.com/#install).
23 |
24 | ### Submitting a Pull Request
25 |
26 | When submitting a pull please take care that:
27 | - Your code follows [the code style](docs/CODE_STYLE.md#code-style)
28 | - Commit messages should be descriptive
29 | - If it's a small change [squash all your commits](docs/Git_CLI.md#squashing-commits)
30 | - Follow the pull request template
31 |
32 | Consider joining the [Discord](https://discord.gg/RSAf7b5njt) so that we can discuss the PR in real time.
33 |
--------------------------------------------------------------------------------
/CONTRIBUTORS.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
FastForward
4 |
Don't waste your time with compliance. FastForward automatically skips annoying link shorteners.
5 |
6 |
7 |
8 | [
](https://github.com/FastForwardTeam/FastForward/blob/main/.github/workflows/main.yml)
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | # FastForward Contributors
17 |
18 | Thanks to everyone who helps make FastForward:
19 |
20 | - The [code contributors](https://github.com/FastForwardTeam/FastForward/graphs/contributors) right here at Github
21 | - The [website devs](https://github.com/FastForwardTeam/Website/graphs/contributors)
22 | - The translators over at [Crowdin](https://crowdin.com/project/fastforward)
23 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | This is free and unencumbered software released into the public domain.
2 |
3 | Anyone is free to copy, modify, publish, use, compile, sell, or
4 | distribute this software, either in source code form or as a compiled
5 | binary, for any purpose, commercial or non-commercial, and by any
6 | means.
7 |
8 | In jurisdictions that recognize copyright laws, the author or authors
9 | of this software dedicate any and all copyright interest in the
10 | software to the public domain. We make this dedication for the benefit
11 | of the public at large and to the detriment of our heirs and
12 | successors. We intend this dedication to be an overt act of
13 | relinquishment in perpetuity of all present and future rights to this
14 | software under copyright law.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 | OTHER DEALINGS IN THE SOFTWARE.
23 |
24 | For more information, please refer to
25 |
--------------------------------------------------------------------------------
/PRIVACY.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
FastForward
4 |
Don't waste your time with compliance. FastForward automatically skips annoying link shorteners.
5 |
6 |
7 |
8 | [
](https://github.com/FastForwardTeam/FastForward/blob/main/.github/workflows/main.yml)
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | # FastForward Privacy Policy
17 |
18 | ## What We Collect
19 | FastForward does not collect any personally identifiable information on its users. The only information collected is what is described below, in the Auto updating and Crowd Bypass sections.
20 |
21 |
22 | ## Auto-updating
23 | _This section does not apply to Firefox._
24 |
25 | In order to provide up-to-date bypasses, FastForward sends a request to Github every hour, and if a new commit is found, it will download the latest "injection script."
26 |
27 |
28 | For this, [Github's privacy policy](https://help.github.com/en/github/site-policy/github-privacy-statement) applies.
29 |
30 | ## Crowd Bypass
31 |
32 | When Crowd Bypass (Options > "Give and take the destinations of unbypassable shorteners.") is enabled, occasionally the extension will send requests to our server.
33 |
34 | When you visit a known unbypassable shortener website, the URL is sent so it can check against the database if someone else has already reported its destination.
35 | When you complete your visit on such a website, the URL and destination URL are sent so it can be recorded for future visitors. We store a hashed version of your IP address along with the destination to prevent spam. We may record your user-agent and other headers to analyse errors on our server. Access to this database is restricted to only those developers and administrators who require it for the purpose of maintenance. We never share this data with anyone else. We use Cloudflare to protect and improve the performance of our server. Their [privacy policy](https://www.cloudflare.com/privacypolicy/) applies to you as an "End User".
36 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | > [!IMPORTANT]
2 | > FastForward is no longer being actively maintained.
3 | > You can fork this project and continue the development if you wish, or contact @undeadjess to take over this repo.
4 | > We are still accepting some pull requests!
5 | > If you're looking for an alternative, we recommend: [bypass-all-shortlinks debloated (userscript)](https://codeberg.org/Amm0ni4/bypass-all-shortlinks-debloated) or [ads-bypasser (userscript)](https://adsbypasser.github.io).
6 | > If you have an adblocker on your browser, these filter lists can help: [yokoffing's filterlists](https://github.com/yokoffing/filterlists) | [Actually Legitimate URL Shortener Tool](https://github.com/DandelionSprout/adfilt/blob/master/LegitimateURLShortener.txt).
7 | > The Crowd-Bypass server is still running, you can see the api documentation [here](https://github.com/FastForwardTeam/Server/wiki), and anyone is free to use it.
8 | > Maybe give the devs a hug, they all deserve one:
9 | > - [0xc60f](https://github.com/0xc60f)
10 | > - [AliahX](https://github.com/AliahX)
11 | > - [driedpampas](https://github.com/driedpampas)
12 | > - [jess <3](https://github.com/undeadjess)
13 | > - [lem6ns](https://github.com/lem6ns)
14 | > - [lostdusty](https://github.com/lostdusty)
15 | > - [NotAProton](https://github.com/NotAProton)
16 | > - [reashetyrr](https://github.com/reashetyrr)
17 | >
18 | > Thanks for your support over the years!
19 | > The FastForward Team <3
20 |
21 | ---
22 |
23 |
24 |
25 |
Don't waste your time with compliance. FastForward automatically skips annoying link shorteners.
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | > **We need developers to work on bypasses! If you're interested, [join our Discord](https://discord.gg/RSAf7b5njt).**
37 |
38 | ____
39 |
40 | ## Installing the Extension
41 | Please refer to our [installation guide](./docs/INSTALLING.md).
42 |
43 | ## Supported websites
44 | Refer to our [bypassed list](./docs/Bypassed.md).
45 |
46 | ## About
47 | ### What is FastForward?
48 | FastForward is the successor of Universal Bypass (see below), a browser extension that can bypass annoying link shorteners, so you don't need to waste your time _trying_ to get to the final link. You can see the extension in action on [our official website](https://fastforward.team/example-links).
49 |
50 | ### What happened to Universal Bypass?
51 | As you may know, [Universal Bypass](https://github.com/Sainan/Universal-Bypass) is no longer maintained by its original developer, [Sainan](https://github.com/Sainan), who had worked on it for so long.
52 |
53 | ### Does FastForward have a Discord server?
54 | Yes! If you are interested in assisting the development, need help, or just wanna hang out, you can [click here to join](https://discord.gg/RSAf7b5njt) our server.
55 |
--------------------------------------------------------------------------------
/crowdin.yml:
--------------------------------------------------------------------------------
1 | files:
2 | - source: src/_locales/en/messages.json
3 | translation: src/_locales/%two_letters_code%/messages.json
4 |
--------------------------------------------------------------------------------
/docs/CODE_STYLE.md:
--------------------------------------------------------------------------------
1 | ### Code style:
2 | - [Standard JS](https://standardjs.com/rules.html) + [Prettier](https://prettier.io/)
3 | - Unix EOL (LF)
4 | - Newline at end of file
5 |
6 | ### How to set this up on VScode/Codium:
7 | - Extension: [VSCode marketplace](https://marketplace.visualstudio.com/items?itemName=numso.prettier-standard-vscode)
8 | - Newline at end of file: [stackoverflow.com/a/44704969](https://stackoverflow.com/a/44704969)
9 |
--------------------------------------------------------------------------------
/docs/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to FastForward
2 | Thanks for taking the time to contribute to FastForward, it is volunteers like you who make this project possible.
3 |
4 | ## Contibuting bypasses
5 |
6 | ### Making the bypass
7 | Initially, you may use the custom bypasses section on the extension's settings page to test out and formulate your bypass, but after that we reccomend using a code editor like [VSCode](https://code.visualstudio.com/download)/[Codium](https://vscodium.com/#install).
8 |
9 | ### Submitting a Pull Request
10 |
11 | When submitting a pull please take care that:
12 | - Your code follows [the code style](CODE_STYLE.md#code-style)
13 | - Commit messages should be descriptive
14 | - If its a small change [squash all your commits](Git_CLI.md#squashing-commits)
15 | - Follow the pull request template
16 |
17 | Consider joining the [Discord](https://discord.gg/RSAf7b5njt) so that we can discuss the PR in real time.
18 |
--------------------------------------------------------------------------------
/docs/CONTRIBUTORS.md:
--------------------------------------------------------------------------------
1 | # FastForward Contributors
2 |
3 | Thanks to everyone who helps make FastForward:
4 |
5 | - The [code contributors](https://github.com/FastForwardTeam/FastForward/graphs/contributors) right here at Github.
6 | - The [website devs](https://github.com/FastForwardTeam/Website/graphs/contributors).
7 | - The translators over at [Crowdin](https://crowdin.com/project/fastforward).
8 |
9 | ## Libraries used by FastForward
10 |
11 | - FastForward uses [UIkit](https://getuikit.com/) for its design.
12 | - The custom bypass editor is powered by [Ace](https://ace.c9.io/).
13 |
--------------------------------------------------------------------------------
/docs/Git_CLI.md:
--------------------------------------------------------------------------------
1 | Install git before using the any of the commands. https://git-scm.com/downloads
2 |
3 | ---
4 | ### Squashing commits
5 | to make this:
6 |
7 | >• Update readme.md
8 | >
9 | >• Update readme.md
10 | >
11 | >• Update readme.md
12 | >
13 | >• Update readme.md
14 |
15 | Into this:
16 |
17 | > • Fix link in README
18 |
19 |
20 | Open the terminal and run the following commands.
21 | NOTE: Remember to substitue all ``
22 | ```
23 | git clone https://github.com//FastForward
24 | ```
25 | ```
26 | cd FastForward
27 | ```
28 |
29 |
30 | If you didn't make the changes on main-
31 | git checkout <YOUR BRANCH NAME>
32 |
33 |
34 | ```
35 | git reset --soft HEAD~
36 | ```
37 | ```
38 | git commit -m ""
39 | ```
40 | NOTE: When git asks for your password use a [PAT](https://github.com/settings/tokens).
41 | ```
42 | git push --force
43 | ```
44 | ---
45 | ### Fixing a messed up main branch
46 | NOTE: If you have made any changes on your main brainch they **will be lost.**
47 |
48 | Open the terminal and run the following commands.
49 | NOTE: Remember to substitue all ``
50 | ```
51 | git clone https://github.com//FastForward
52 | ```
53 | ```
54 | cd FastForward
55 | git remote add upstream https://github.com/FastForwardteam/FastForward
56 | git fetch upstream
57 | git checkout main
58 | git reset --hard upstream/main
59 |
60 | ```
61 |
62 | NOTE: When git asks for your password use a [PAT](https://github.com/settings/tokens).
63 | ```
64 | git push origin main --force
65 | ```
66 |
--------------------------------------------------------------------------------
/docs/PRIVACY.md:
--------------------------------------------------------------------------------
1 | # FastForward Privacy Policy
2 |
3 | ## Crowd Bypass
4 |
5 | When Crowd Bypass (Options > "Give and take the destinations of unbypassable shorteners.") is enabled, ocassionally the extension will send requests to our server:
6 |
7 | - When you visit a known unbypassable shortener website, the URL is sent so it can check against the database if someone else has already reported its destination.
8 | - When you complete your visit on such a website, the URL and destination URL are sent so it can be recorded for future visitors.
9 |
10 | To prevent abuse, we log a hashed version of your IP address in our database when you submit a link. Only the developers have access to the database.
11 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "module",
3 | "devDependencies": {
4 | "ejs": "^3.1.9",
5 | "eslint": "^8.37.0",
6 | "eslint-config-prettier": "^8.8.0",
7 | "fs-extra": "^11.1.1",
8 | "prettier": "^2.8.7",
9 | "web-ext": "^7.6.2"
10 | },
11 | "scripts": {
12 | "lint": "eslint",
13 | "build": "node ./scripts/build.js"
14 | }
15 | }
--------------------------------------------------------------------------------
/platform_spec/chromium/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "manifest_version": 3,
3 | "icons": {
4 | "48": "icon/48.png",
5 | "128": "icon/128.png",
6 | "150": "icon/150.png",
7 | "176": "icon/176.png",
8 | "512": "icon/512.png"
9 | },
10 | "default_locale": "en",
11 | "name": "FastForward",
12 | "description": "__MSG_appDesc__",
13 | "homepage_url": "https://fastforward.team",
14 | "version": "13.15.2",
15 | "author": "FastForward Team",
16 | "incognito": "split",
17 | "permissions": [
18 | "alarms",
19 | "storage",
20 | "tabs",
21 | "declarativeNetRequestWithHostAccess"
22 | ],
23 | "host_permissions": [
24 | ""
25 | ],
26 | "options_ui": {
27 | "page": "html/options.html",
28 | "open_in_tab": true
29 | },
30 | "background": {
31 | "service_worker": "background.js",
32 | "type": "module"
33 | },
34 | "action": {
35 | "default_popup": "html/popup.html"
36 | },
37 | "content_scripts": [
38 | {
39 | "matches": [
40 | ""
41 | ],
42 | "js": [
43 | "content_script.js"
44 | ],
45 | "run_at": "document_start"
46 | }
47 | ],
48 | "web_accessible_resources": [{
49 | "resources": [
50 | "html/before-navigate.html",
51 | "html/blocked.html",
52 | "html/crowd-bypassed.html",
53 | "html/tracker-bypass.html",
54 | "html/options.html",
55 | "icon/48.png",
56 | "injection_script.js",
57 | "bypasses/*",
58 | "helpers/*"],
59 | "matches": [""]
60 | }],
61 |
62 | "declarative_net_request": {
63 | "rule_resources": [{
64 | "id": "ipLoggerRuleset",
65 | "enabled": true,
66 | "path": "ip_logger_blocker.json"
67 | },
68 | {
69 | "id": "trackerRuleset",
70 | "enabled": false,
71 | "path": "tracker_bypass.json"
72 | }]
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/platform_spec/firefox/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "manifest_version": 3,
3 | "icons": {
4 | "48": "icon/48.png",
5 | "128": "icon/128.png",
6 | "150": "icon/150.png",
7 | "176": "icon/176.png",
8 | "512": "icon/512.png"
9 | },
10 | "default_locale": "en",
11 | "name": "FastForward",
12 | "description": "__MSG_appDesc__",
13 | "homepage_url": "https://fastforward.team",
14 | "version": "13.15.2",
15 | "author": "FastForward Team",
16 | "browser_specific_settings": {
17 | "gecko": {
18 | "id": "addon@fastforward.team",
19 | "strict_min_version": "113.0"
20 | }
21 | },
22 | "permissions": [
23 | "alarms",
24 | "storage",
25 | "webNavigation",
26 | "tabs",
27 | "declarativeNetRequestWithHostAccess"
28 | ],
29 | "host_permissions": [
30 | ""
31 | ],
32 | "options_ui": {
33 | "page": "html/options.html",
34 | "open_in_tab": true
35 | },
36 | "background": {
37 | "scripts": ["background.js"],
38 | "type": "module"
39 | },
40 | "action": {
41 | "default_popup": "html/popup.html"
42 | },
43 | "content_scripts": [
44 | {
45 | "matches": [
46 | ""
47 | ],
48 | "js": [
49 | "content_script.js"
50 | ],
51 | "run_at": "document_start"
52 | }
53 | ],
54 | "web_accessible_resources": [{
55 | "resources": [
56 | "html/before-navigate.html",
57 | "html/blocked.html",
58 | "html/crowd-bypassed.html",
59 | "html/tracker-bypass.html",
60 | "html/options.html",
61 | "icon/48.png",
62 | "injection_script.js",
63 | "bypasses/*",
64 | "helpers/*",
65 | "rules.json"
66 | ],
67 | "matches": [""]
68 | }],
69 | "declarative_net_request": {
70 | "rule_resources": [{
71 | "id": "ipLoggerRuleset",
72 | "enabled": true,
73 | "path": "ip_logger_blocker.json"
74 | },
75 | {
76 | "id": "trackerRuleset",
77 | "enabled": false,
78 | "path": "tracker_bypass.json"
79 | }]
80 |
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/scripts/build_js/injection_script_template.js:
--------------------------------------------------------------------------------
1 | const bypasses = [/- bypasses -/];
2 | const script_src = new URL(document.currentScript.src);
3 | const ext_base_URL = script_src.searchParams.get('ext_base_URL');
4 |
5 | function matchingBypass(bypasses) {
6 | for (const [key] of Object.entries(bypasses)) {
7 | if (key.charAt(0) === '/' && key.charAt(key.length - 1) === '/') {
8 | let pattern = new RegExp(key.substring(1, key.length - 1));
9 | if (pattern.test(location.href)) {
10 | return key;
11 | }
12 | } else if (key === location.host) {
13 | return key;
14 | }
15 | }
16 | return null;
17 | }
18 |
19 | if (matchingBypass(bypasses)) {
20 | const bypass_url = bypasses[matchingBypass(bypasses)];
21 |
22 | import(ext_base_URL.concat(bypass_url)).then(({ default: bypass }) => {
23 | import(ext_base_URL.concat('helpers/dom.js')).then(
24 | ({ default: helpers }) => {
25 | const bps = new bypass();
26 | bps.set_helpers(helpers);
27 | console.log(`ensure_dom: ${bps.ensure_dom}`);
28 | if (bps.ensure_dom) {
29 | let executed = false;
30 | document.addEventListener('readystatechange', () => {
31 | if (
32 | ['interactive', 'complete'].includes(document.readyState) &&
33 | !executed
34 | ) {
35 | executed = true;
36 | bps.execute();
37 | }
38 | });
39 | document.addEventListener('DOMContentLoaded', () => {
40 | if (!executed) {
41 | executed = true;
42 | bps.execute();
43 | }
44 | });
45 | } else {
46 | bps.execute();
47 | }
48 | }
49 | );
50 | });
51 | }
52 |
--------------------------------------------------------------------------------
/src/_locales/am/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "appDesc": {
3 | "message": "በማክበር ጊዜዎን አያባክን። ሁለንተናዊ አቋራጭ የሚረብሹ አገናኝ አቋራጮችን ይገድባል።"
4 | },
5 | "firstrunTitle": {
6 | "message": "ዩኒቨርሳል Bypass ን ስለጫኑ እናመሰግናለን!"
7 | },
8 | "firstrunNoScript": {
9 | "message": "ሆኖም ኖቭስክሪፕትን ወይም ተመሳሳይን የሚጠቀሙ ፣ ዩኒቨርሳል ኦንቨርንቨር ከ ጋር የማይጣጣም ይመስላል።"
10 | },
11 | "version": {
12 | "message": "ሥሪት"
13 | },
14 | "definitionsVersion": {
15 | "message": "ትርጓሜዎችን ማለፍ"
16 | },
17 | "changelog": {
18 | "message": "መለወጫ"
19 | },
20 | "update": {
21 | "message": "ዝማኔዎችን ይመልከቱ"
22 | },
23 | "updating": {
24 | "message": "የትርጉም ፍችዎችን በማውረድ ላይ ..."
25 | },
26 | "updateYes": {
27 | "message": "የትርጉም ፍችዎችን በማውረድ ላይ ..."
28 | },
29 | "updateNo": {
30 | "message": "የማለፍ ትርጓሜዎች ወቅታዊ ናቸው።"
31 | },
32 | "faq": {
33 | "message": "ተዘውትረው የሚጠየቁ ጥያቄዎች (ተዘውትረው)"
34 | },
35 | "bypassCounter": {
36 | "message": "ሁለንተናዊ ማለፍ ቀድሞውንም ጣቢያዎችን$1 አል sitesል"
37 | },
38 | "support": {
39 | "message": "ወደ ሁለንተናዊ ማቋረጫ ያበርክቱ።"
40 | },
41 | "options": {
42 | "message": "አማራጮች"
43 | },
44 | "optionsLink": {
45 | "message": "ሁለንተናዊ አቋራጭ አማራጮችን ቀይር።"
46 | },
47 | "optionsEnabled": {
48 | "message": "የድርጣቢያ ማለፍን ያንቁ።"
49 | },
50 | "optionsNavigationDelay": {
51 | "message": "ከ$1 ሰከንድ (ሰ) በኋላ ወደ መድረሻዎች ውሰደኝ ፡፡"
52 | },
53 | "optionsTrackerBypass": {
54 | "message": "Apimon.de ን በመጠቀም ትራኮችን (ለምሳሌ bit.ly እና t.co ን) በመጠቀም ያቋርጣሉ ፡፡"
55 | },
56 | "optionsInstantNavigationTrackers": {
57 | "message": "በፍጥነት ወደ ትራካckers መድረሻዎች ውሰደኝ ፡፡"
58 | },
59 | "optionsBlockIPLoggers": {
60 | "message": "የአይ.ፒ ሎጊዎችን ማለፍ ካልቻሉ አግድ።"
61 | },
62 | "optionsCrowdBypass": {
63 | "message": "የተጨናነቀ አቋራጭ የማይተላለፍ አቋራጭ ያላቸውን መድረሻ ይስጡ እና ይውሰዱ ፡፡"
64 | },
65 | "optionsCrowdAutoOpen": {
66 | "message": "ከ$1 ሰከንድ (ቶች) በኋላ በህዝብ የተመረጡ መድረሻዎችን በአዲስ ትር ክፈት"
67 | },
68 | "optionsCrowdAutoClose": {
69 | "message": "ከጎበኙ በኋላ ከ$1 ሰከንድ (ሰት) በኋላ በሕዝብ የተፈጠረ መድረሻን የያዘ ትር ይዝጉ"
70 | },
71 | "privacyPolicy": {
72 | "message": "የ ግል የሆነ"
73 | },
74 | "contributors": {
75 | "message": "አስተዋፅutors አበርካቾች"
76 | },
77 | "optionsUserscripts": {
78 | "message": "ብጁ መተላለፊያዎች"
79 | },
80 | "optionsUserscriptsDescription": {
81 | "message": "ጣቢያዎችን ለማለፍ የራሳቸውን ስክሪፕቶች ለመፍጠር ለገንቢዎች ይህ የላቀ ባህሪ ነው። አንዴ ከተጠናቀቁ በኋላ ወደ ዩኒቨርሳል ማለፍ እንዲታከሉ በ GitHub ላይ ሊገቡ ይችላሉ ፣ ስለሆነም ለሁሉም ሰው ይገኛሉ ፡፡"
82 | },
83 | "beforeNavigate": {
84 | "message": "መድረሻዎ ላይ ደርሰዋል።"
85 | },
86 | "beforeNavigateDestination": {
87 | "message": "መድረሻዎ$1 ነው"
88 | },
89 | "beforeNavigateUnsafe": {
90 | "message": "ሆኖም ግን ፣ አሁን ከዳሰሱ ዩኒቨርሳል ኦንቨርንሌይትን ይገነዘባሉ።"
91 | },
92 | "beforeNavigateUnsafeTimer": {
93 | "message": "በ$1 ሰከንዶች ውስጥ ከእንግዲህ አይገኙም"
94 | },
95 | "beforeNavigateUnsafeTimerSingular": {
96 | "message": "በ 1 ሰከንድ ውስጥ ከእንግዲህ ወዲህ አይገኙም።"
97 | },
98 | "beforeNavigateTimer": {
99 | "message": "በ$1 ሰከንዶች ውስጥ በራስ-ሰር ይዛወራሉ።"
100 | },
101 | "beforeNavigateTimerSingular": {
102 | "message": "በ 1 ሴኮንድ ውስጥ በራስ-ሰር ይዛወራሉ።"
103 | },
104 | "beforeNavigateOptions": {
105 | "message": "በቅጽበት ወይም በ x ሰከንዶች ውስጥ አቅጣጫዎን መለወጥ ይፈልጋሉ?"
106 | },
107 | "beforeNavigateInstant": {
108 | "message": "ወደ$1 እየተጓዙ ነው"
109 | },
110 | "infoFileHoster": {
111 | "message": "እንደ አለመታደል ሆኖ የወረደው አገልጋይ ፋይሉን ለማውረድ ከመፍቀድዎ በፊት መጠበቅዎን ያረጋግጣል።"
112 | },
113 | "infoOutdated": {
114 | "message": "ይህ ድርጣቢያ በአዲሱ ኦቨርቨር ኦቨር ኦቨር ኦቨር ኦቨር ኦፕሬሽን (ስሪት) ተላል isል።"
115 | },
116 | "crowdWait": {
117 | "message": "እንደ አለመታደል ሆኖ ይህንን አገናኝ ያጋጠሙዎት እርስዎ የመጀመሪያ ነዎት ፣ ግን ከጠበቁ በኋላ ሌሎች ሁለንተናዊ የመንገድ ተጠቃሚዎች ከእንግዲህ አያስፈልጉም ፡፡"
118 | },
119 | "crowdDisabled": {
120 | "message": "ይህ ድርጣቢያ በአጋጣሚዎች ውስጥ ማንቃት በሚችሉት የሰዎች ማለፍ ተላልpassል።"
121 | },
122 | "crowdBypassed": {
123 | "message": "መጠበቅ የለብዎትም!"
124 | },
125 | "crowdBypassedInfo": {
126 | "message": "ሌሎች ሁለንተናዊ አቋራጭ ተጠቃሚዎች እርስዎን ይጠባበቁ እና ይህ ወደ$1 እንደሚወስድ ዘግቧል።"
127 | },
128 | "crowdBypassedTimer": {
129 | "message": "ይህ በ$1 ሰከንዶች ውስጥ በአዲስ ትር ውስጥ ይከፈታል።"
130 | },
131 | "crowdBypassedTimerSingular": {
132 | "message": "ይህ በ 1 ሴኮንድ ውስጥ በአዲስ ትር ውስጥ ይከፈታል"
133 | },
134 | "crowdCloseTimer": {
135 | "message": "ይህ ትር በ$1 ሰከንዶች ውስጥ ይዘጋል።"
136 | },
137 | "crowdCloseTimerSingular": {
138 | "message": "ይህ ትር በ 1 ሴኮንድ ውስጥ ይዘጋል።"
139 | },
140 | "cancel": {
141 | "message": "ይቅር።"
142 | },
143 | "crowdBypassedIgnore": {
144 | "message": "ይህ ትክክል አልነበረም?"
145 | },
146 | "crowdBypassedOptions": {
147 | "message": "ይህ በአዲሱ ትር ውስጥ ወዲያውኑ ወይም በ x ሰከንዶች ውስጥ እንዲከፈት ይፈልጋሉ?"
148 | },
149 | "blockedTitle": {
150 | "message": "ሁለንተናዊ መተላለፊያ የእርስዎ አይፒ እንዳይመዘገብ አግዶታል ፡፡"
151 | },
152 | "blockedSubtitle": {
153 | "message": "መጥፎ ተዋንያን የእርስዎን አይፒ (IP) እንዳያገኙ ለመከላከል ሁለንተናዊ ማለፍ ይፈልጋሉ?"
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/src/_locales/an/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": {
3 | "message": "Versión"
4 | },
5 | "definitionsVersion": {
6 | "message": "Omitir definiziónes"
7 | },
8 | "changelog": {
9 | "message": "Rechistro de cambio."
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/_locales/az/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "appDesc": {
3 | "message": "Vaxtınızı uyğunlaşdırmaya xərcləməyin. FastForward, zəhlətökən bağlantı qısaldıcılarını ötürür."
4 | },
5 | "firstrunTitle": {
6 | "message": "FastForward quraşdırdığınız üçün təşəkkürlər!"
7 | },
8 | "firstrunNoScript": {
9 | "message": "Buna baxmayaraq, FastForward ilə uyğunlaşmayan NoScript və ya oxşarını istifadə edirsiniz."
10 | },
11 | "version": {
12 | "message": "Versiya"
13 | },
14 | "definitionsVersion": {
15 | "message": "Bypass tərifləri"
16 | },
17 | "changelog": {
18 | "message": "Dəyişiklik qeydi"
19 | },
20 | "update": {
21 | "message": "Yeniləmələri yoxla"
22 | },
23 | "faq": {
24 | "message": "Tez-tez Soruşulan Suallar (FAQ)"
25 | },
26 | "support": {
27 | "message": "FastForward-ı Dəstəkləyin."
28 | },
29 | "options": {
30 | "message": "Seçimlər"
31 | },
32 | "optionsLink": {
33 | "message": "FastForward seçimlərini dəyişdirin."
34 | },
35 | "optionsEnabled": {
36 | "message": "Veb saytlarının ötürülməsini fəallaşdır."
37 | },
38 | "optionsBlockIPLoggers": {
39 | "message": "Ötürə bilməsə, IP qeydlərini əngəllə."
40 | },
41 | "optionsCrowdBypass": {
42 | "message": "Ötürülə bilməyən qısaldıcıların yerlərini verin və aparın."
43 | },
44 | "privacyPolicy": {
45 | "message": "Gizlilik Siyasəti"
46 | },
47 | "optionsUserscripts": {
48 | "message": "Özəl Bypass-lar"
49 | },
50 | "beforeNavigate": {
51 | "message": "Demək olar ki, təyinat yerindəsiniz."
52 | },
53 | "beforeNavigateDestination": {
54 | "message": "Təyinat yeri $1"
55 | },
56 | "beforeNavigateTimer": {
57 | "message": "$1 saniyə ərzində avtomatik yönləndiriləcəksiniz."
58 | },
59 | "beforeNavigateTimerSingular": {
60 | "message": "1 saniyə ərzində avtomatik yönləndiriləcəksiniz."
61 | },
62 | "crowdWait": {
63 | "message": "Təəssüf ki, bu bağlantı ilə qarşılaşan ilk sizsiniz, ancaq siz gözlədikdən sonra, digər FastForward istifadəçilərinin buna ehtiyacı olmayacaq."
64 | },
65 | "crowdBypassed": {
66 | "message": "Gözləməyinizə ehtiyac yoxdur!"
67 | },
68 | "crowdBypassedInfo": {
69 | "message": "Digər FastForward istifadəçiləri artıq sizi gözlədilər və bunun $1 a çatdığı bildirildi"
70 | },
71 | "crowdBypassedTimer": {
72 | "message": "Bu, $1 saniyə ərzində yeni bir vərəqdə açılacaq."
73 | },
74 | "crowdBypassedTimerSingular": {
75 | "message": "Bu, 1 saniyə ərzində yeni bir vərəq açılacaq."
76 | },
77 | "crowdBypassedIgnore": {
78 | "message": "Bu doğru deyil?"
79 | },
80 | "crowdBypassedOptions": {
81 | "message": "Bunun indi ya x saniyə sonra yeni bir vərəqdə açılmasını istəyirsiniz?"
82 | },
83 | "blockedTitle": {
84 | "message": "FastForward, IP ünvanların qeydlərə əlavə edilməsinin qarşısı aldı."
85 | },
86 | "blockedSubtitle": {
87 | "message": "FastForward-ın, pisniyyətli insanların IP ünvanınızı oğurlamasının qarşısını almasını istəmirsiniz?"
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/_locales/br/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "firstrunTitle": {
3 | "message": "Trugarez evit ho staliañ FastForward!"
4 | },
5 | "version": {
6 | "message": "Handelv"
7 | },
8 | "changelog": {
9 | "message": "Renabl ar c'hemmoù"
10 | },
11 | "update": {
12 | "message": "Gwiriañ an hizivadurioù"
13 | },
14 | "faq": {
15 | "message": "Foar ar Goulennoù (FAG)"
16 | },
17 | "bypassCounter": {
18 | "message": "Bet oc'h e-biou da $1s lec'hienn a-drugarez da FastForward."
19 | },
20 | "support": {
21 | "message": "Kenoberiañ da FastForward."
22 | },
23 | "options": {
24 | "message": "Dibarzhioù"
25 | },
26 | "optionsLink": {
27 | "message": "Kemmañ dibarzhioù FastForward."
28 | },
29 | "optionsEnabled": {
30 | "message": "Gweredekaat an tremen e-biou d'al lec'hiennoù."
31 | },
32 | "privacyPolicy": {
33 | "message": "Reolenn a-fet buhez prevez"
34 | },
35 | "contributors": {
36 | "message": "Perzhidi"
37 | },
38 | "optionsUserscripts": {
39 | "message": "Tremenadennoù e-biou personelaet"
40 | },
41 | "beforeNavigate": {
42 | "message": "Tost erru oc'h da benn hoc'h hent."
43 | },
44 | "beforeNavigateDestination": {
45 | "message": "$1 eo hoc'h arvoned"
46 | },
47 | "beforeNavigateTimer": {
48 | "message": "Adheñchet e vezoc'h bet ent emgefreek a-benn $1 eilenn."
49 | },
50 | "beforeNavigateTimerSingular": {
51 | "message": "Adheñchet e vezoc'h bet ent emgefreek a-benn 1 eilenn."
52 | },
53 | "cancel": {
54 | "message": "Nullañ."
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/_locales/ckb/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "appDesc": {
3 | "message": "کاتی خۆت بە فیڕۆ مەدە بە ڕەزای بوون، ئەم تێپەڕ گشتیە هەموو بەستەرە بێزارکەرەکان لادەبات."
4 | },
5 | "firstrunTitle": {
6 | "message": "سوپاس بۆ دامەزراندنی FastForward!"
7 | },
8 | "firstrunNoScript": {
9 | "message": "وا دیارە، تۆ زیادکراوی NoScript بەکار دەهێنیت یان هەر یەک لەو زیادکراوانە. کە ئەم زیادکراوەی ئێمە ناگونجێت لەگەڵیدا."
10 | },
11 | "version": {
12 | "message": "نوسخە"
13 | },
14 | "definitionsVersion": {
15 | "message": "ماناکانی تێپەڕەکە"
16 | },
17 | "changelog": {
18 | "message": "تۆماری گۆڕانەکان"
19 | },
20 | "update": {
21 | "message": "پشکنین بۆ نوسخە نوێکان"
22 | },
23 | "updating": {
24 | "message": "داگرتنی ماناکانی تێپەڕەکە..."
25 | },
26 | "updateYes": {
27 | "message": "داگرتنی ماناکانی تێپەڕەکە سەرکەوتوو بو"
28 | },
29 | "updateNo": {
30 | "message": "پێناسەکانی تێپەڕەکە نوێە"
31 | },
32 | "faq": {
33 | "message": "پرسیارە زۆر دووبارە کراوەکان"
34 | },
35 | "bypassCounter": {
36 | "message": "ئەم تێپەڕە گشتیە هەتا ئێستا $1 پەڕەی بۆ تێپەڕاندوویت"
37 | },
38 | "support": {
39 | "message": "یارمەتی تێپەڕەکە بدە."
40 | },
41 | "options": {
42 | "message": "هەڵبژاردنەکان"
43 | },
44 | "optionsLink": {
45 | "message": "بژاردەکانی تێپەڕەکە بگۆڕە"
46 | },
47 | "optionsEnabled": {
48 | "message": "بەکارخستنی رێگاگرتنی وێبسایت."
49 | },
50 | "optionsNavigationDelay": {
51 | "message": "بمبە شوێنی مەبەست دوای $1 چرکە"
52 | },
53 | "optionsTrackerBypass": {
54 | "message": "بیپەڕێنە سایتەکە سیخوڕیەکان (وەک bit.ly و t.co) بە بەکارهێنانی Apimon.de. "
55 | },
56 | "optionsInstantNavigationTrackers": {
57 | "message": "دەستبەجی بمبە بۆ شوێنی چوون."
58 | },
59 | "optionsBlockIPLoggers": {
60 | "message": "ڕایبگرە ئایپی دزە پێکەرەکان ئەگەر نەتوانی پەڕەکە تێ بپەڕێنیت"
61 | },
62 | "optionsCrowdAutoOpen": {
63 | "message": "لینکی کۆتایم پێ بدە لە دوای $1 چرکەدا"
64 | },
65 | "optionsUserscripts": {
66 | "message": "دەربازبوونی نەریتی"
67 | },
68 | "beforeNavigateDestination": {
69 | "message": "ئەو شوێنەی کە ذەچیت: $1"
70 | },
71 | "crowdBypassed": {
72 | "message": "لەوانەیە پێویست نەکات بوەستیت!"
73 | },
74 | "cancel": {
75 | "message": "لابردن"
76 | },
77 | "crowdBypassedIgnore": {
78 | "message": "ئایە ئەمە ڕاست نەبوو؟"
79 | },
80 | "crowdBypassedOptions": {
81 | "message": "ئایا تۆ دەتەوێت ئەمە بکرێتەوە لە پەڕیەکی نوێدا ڕاستەوخۆ یان دوای چەند چرکەیەک ؟"
82 | },
83 | "blockedTitle": {
84 | "message": "ئەم تێپەڕە نەیهێشت ئایپی ئەدرێسەکەت تۆمار بکرێت"
85 | },
86 | "blockedSubtitle": {
87 | "message": "ئایا تۆ ناتەوێت ئەم تێپەڕە ڕێگری بکات لە خەڵکانی خراپ لە بردنی IP تایبەت بە تۆ ؟"
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/_locales/eo/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "firstrunNoScript": {
3 | "message": "Vi ŝajne uzas NoScript, aŭ aferoj same. FastForward bedaŭrinde ne povas kunfari kun tioj."
4 | },
5 | "version": {
6 | "message": "versio"
7 | },
8 | "definitionsVersion": {
9 | "message": "transiranta difinoj"
10 | },
11 | "updating": {
12 | "message": "Elŝutanta preterpasa difiniojn"
13 | },
14 | "faq": {
15 | "message": "Ofta demandoj"
16 | },
17 | "bypassCounter": {
18 | "message": "FastForward preterpasinta $1 retpaĝojn. "
19 | },
20 | "options": {
21 | "message": "agordoj"
22 | },
23 | "beforeNavigateInstant": {
24 | "message": "Vi estas navigita al $1"
25 | },
26 | "infoOutdated": {
27 | "message": "Ĉi tio retpaĝo estas uzanta pli nova versio de FastForward"
28 | },
29 | "crowdWait": {
30 | "message": "Bedaŭrinde, vi estas la unua vizitanto sur ĉi retpaĝo. Sed, se vi atendas, la aliaj uzantoj ne atendos."
31 | },
32 | "crowdBypassedTimerSingular": {
33 | "message": "Nova langeto estos malfermita en 1 sekundo."
34 | },
35 | "crowdCloseTimer": {
36 | "message": "La langeto estos fermita en $1 sekundoj"
37 | },
38 | "crowdCloseTimerSingular": {
39 | "message": "La langeto estos fermita en 1 sekundo"
40 | },
41 | "cancel": {
42 | "message": "Nuligi."
43 | },
44 | "crowdBypassedOptions": {
45 | "message": "Ĉu vi volas aperi tion instante, sur nova tabo?"
46 | },
47 | "blockedTitle": {
48 | "message": "FastForward haltis via IP adreso registrita."
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/_locales/ga-IE/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "appDesc": {
3 | "message": "Ná drámhail do am lé comhlíonadh. Seachnaíonn Seachbhóthar Uilíoch go huathoibríoch gearrshaolaithe naisc atá annamh."
4 | },
5 | "firstrunTitle": {
6 | "message": "Go raibh maith agat chun FastForward a shuiteáil!"
7 | },
8 | "firstrunNoScript": {
9 | "message": "Ach, Tá tú ag usaíd NoScript ná rúd againn éile agus ní feidir le FastForward in an obair lé sin."
10 | },
11 | "faq": {
12 | "message": "Ceisteanna Coitianta (CC)"
13 | },
14 | "support": {
15 | "message": "Taspann do tachíocht le haghaidh FastForward"
16 | },
17 | "options": {
18 | "message": "Roghnna"
19 | },
20 | "optionsLink": {
21 | "message": "Athrú ná roghnna de FastForward."
22 | },
23 | "optionsEnabled": {
24 | "message": "Cumasaigh seachbhóithre láithreán gréasáin."
25 | },
26 | "optionsNavigationDelay": {
27 | "message": "Tuair me go cinn scríbe tar éis$1 an dara ceann. (Bain úsáid as 0 le nascleanúint a dhéanamh láithreach.)"
28 | },
29 | "optionsInstantNavigationTrackers": {
30 | "message": "Tóg mé chuig ceann scríbe na lorgairí láithreach."
31 | },
32 | "optionsBlockIPLoggers": {
33 | "message": "Bloc logálaithe IP mura féidir iad a sheachaint."
34 | },
35 | "optionsCrowdBypass": {
36 | "message": "Tuair agus tóg na cinn scríbe na ngiorraitheoirí nach féidir a phasáil."
37 | },
38 | "privacyPolicy": {
39 | "message": "Beartas Príobháideachais"
40 | },
41 | "optionsUserscripts": {
42 | "message": "Seachbhóithre saincheaptha"
43 | },
44 | "optionsUserscriptsDescription": {
45 | "message": "Is gné ard é seo do fhorbróirí chun a gcuid scripteanna féin a chruthú chun suíomhanna a sheachbhóthar. Nuair a bheidh siad foirfe, is féidir iad a chur isteach ansin ar GitHub le bheith curtha le Seachbhóthar Uilíoch, agus mar sin tá siad ar fáil do gach duine."
46 | },
47 | "beforeNavigate": {
48 | "message": "Ta tú beagnach ansín"
49 | },
50 | "beforeNavigateDestination": {
51 | "message": "Tá do ceann scríbe $1"
52 | },
53 | "beforeNavigateTimer": {
54 | "message": "Déanfar tú a atreorú go huathoibríoch i$1 soicind."
55 | },
56 | "beforeNavigateTimerSingular": {
57 | "message": "Déanfar tú a atreorú go huathoibríoch i 1 soicind."
58 | },
59 | "beforeNavigateOptions": {
60 | "message": "Ar mhaith leat a bheith atreoraithe láithreach nó i x soicind?"
61 | },
62 | "crowdBypassed": {
63 | "message": "B'fhéidir nach mbeidh ort fanacht!"
64 | },
65 | "crowdBypassedInfo": {
66 | "message": "Tá úsáideoirí eile Seachbhóthar Uilíoch tar éis fanacht leat cheana féin agus thuairiscigh siad go dtiocfaidh $1"
67 | },
68 | "crowdBypassedIgnore": {
69 | "message": "Nach raibh sé séo i gceart?"
70 | },
71 | "blockedTitle": {
72 | "message": "Chuir Seachbhóthar Uilíoch cosc ar do IP a bheith logáilte isteach."
73 | },
74 | "blockedSubtitle": {
75 | "message": "Ná bí ag iarraidh Seachbhóthar Uilíoch chun droch-ghníomhaithe a chosc ar do IP a fháil?"
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/_locales/he/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "appDesc": {
3 | "message": "אל תבזבז את הזמן שלך! FastForward מדלג אוטומטית על מקצרי לינקים מעצבנים."
4 | },
5 | "firstrunTitle": {
6 | "message": "תודה לך על כך שהתקנת את FastForward!"
7 | },
8 | "firstrunNoScript": {
9 | "message": "ככול הנראה אתה עושה שימוש ב-NoScript ודומיו, מה שלא מאפשר את פעולת FastForward."
10 | },
11 | "version": {
12 | "message": "גרסה"
13 | },
14 | "definitionsVersion": {
15 | "message": "הגדרות מעקף"
16 | },
17 | "changelog": {
18 | "message": "רשימת שינויים"
19 | },
20 | "update": {
21 | "message": "בדוק עדכונים"
22 | },
23 | "updating": {
24 | "message": "מוריד הגדרות עקיפה ..."
25 | },
26 | "updateYes": {
27 | "message": "הגדרות עקיפה הורדו בהצלחה."
28 | },
29 | "updateNo": {
30 | "message": "הגדרות עקיפה אותרו כעדכניות."
31 | },
32 | "faq": {
33 | "message": "שאלות נפוצות (FAQ)"
34 | },
35 | "bypassCounter": {
36 | "message": "מעקף אוניברסלי כבר עקף $1 אתרים בשבילך."
37 | },
38 | "support": {
39 | "message": "תמוך ב-FastForward"
40 | },
41 | "options": {
42 | "message": "הגדרות"
43 | },
44 | "optionsLink": {
45 | "message": "הגדר את FastForward."
46 | },
47 | "optionsEnabled": {
48 | "message": "הפעל מעקף לאתר."
49 | },
50 | "optionsNavigationDelay": {
51 | "message": "קח אותי ליעד אחרי $1 שני(ות). (השתמש ב0 על מנת לנווט במיידי)"
52 | },
53 | "optionsTrackerBypass": {
54 | "message": "תעקוף טראקרים (כמו bit.ly ו - t.co) באמצעות Apimon.de."
55 | },
56 | "optionsInstantNavigationTrackers": {
57 | "message": "העבר אותי למקור אוטומטית."
58 | },
59 | "optionsBlockIPLoggers": {
60 | "message": "חסום אוספי IP אם אי אפשר לעקוף אותם."
61 | },
62 | "optionsCrowdAutoOpen": {
63 | "message": "תפתח מקורות שנוצרו בעזרת הקהל בכרטיסייה חדשה אחרי $1 שניות."
64 | },
65 | "privacyPolicy": {
66 | "message": "מדיניות פרטיות"
67 | },
68 | "contributors": {
69 | "message": "תורמים"
70 | },
71 | "optionsUserscripts": {
72 | "message": "מעקפים מותאמים אישית"
73 | },
74 | "beforeNavigate": {
75 | "message": "כמעט ביעד שלך."
76 | },
77 | "beforeNavigateDestination": {
78 | "message": "כתובת היעד שלך היא $1"
79 | },
80 | "beforeNavigateUnsafe": {
81 | "message": "אם תנווט כעת, הם יזהו את תוספת זאת."
82 | },
83 | "beforeNavigateUnsafeTimer": {
84 | "message": "אתה לא תהיה גלוי בעוד $1 שניות"
85 | },
86 | "beforeNavigateUnsafeTimerSingular": {
87 | "message": "אתה לא תהיה גלוי בעוד שנייה."
88 | },
89 | "beforeNavigateTimer": {
90 | "message": "תועבר אוטומטית עוד $1 שניות."
91 | },
92 | "beforeNavigateTimerSingular": {
93 | "message": "תועבר אוטומטית בעוד שנייה."
94 | },
95 | "beforeNavigateOptions": {
96 | "message": "האם ברצונך להיות מכוון מחדש מיידית או בעוד x שניות?"
97 | },
98 | "beforeNavigateInstant": {
99 | "message": "מנווט ל $1"
100 | },
101 | "infoOutdated": {
102 | "message": "האתר הזה יכול להיעקף בעזרת גרסה חדשה יותר של FastForward."
103 | },
104 | "crowdWait": {
105 | "message": "לצערי, אתה הראשון שנתקל בקישור הזה, אבל אחרי שחיכית, משתמשי FastForward אחרים לא יצטרכו לחכות יותר."
106 | },
107 | "crowdDisabled": {
108 | "message": "אתר זה עוקף על ידי crowd bypass, אפשר לכבות אופציה זו בהגדרות."
109 | },
110 | "crowdBypassed": {
111 | "message": "יתכן ואתה לא צריך להמתין בכלל!"
112 | },
113 | "crowdBypassedInfo": {
114 | "message": "משתמשים נוספים כבר המתינו, ודיווחו שהקישור מוביל ל- $1"
115 | },
116 | "crowdBypassedTimer": {
117 | "message": "תוכן זה יפתח בחלון חדש בעוד $1 שניות."
118 | },
119 | "crowdBypassedTimerSingular": {
120 | "message": "תוכן זה יפתח בחלון חדש בעוד כשניה."
121 | },
122 | "crowdCloseTimer": {
123 | "message": "חלון זה ייסגר בעוד $1 שניות."
124 | },
125 | "crowdCloseTimerSingular": {
126 | "message": "חלון זה ייסגר בעוד שניה."
127 | },
128 | "cancel": {
129 | "message": "ביטול."
130 | },
131 | "crowdBypassedIgnore": {
132 | "message": "האם נתיב זה שגוי?"
133 | },
134 | "crowdBypassedOptions": {
135 | "message": "האם ברצונך לפתוח חלון זה באופן מיידי או תוך x שניות?"
136 | },
137 | "blockedTitle": {
138 | "message": "עקיפה אוניברסלית מנעה את רישום ה- IP שלך."
139 | },
140 | "blockedSubtitle": {
141 | "message": "לא רוצה שFastForward ימנע ממקורות רעים לקבל גישה לכתובת הIP שלך?"
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/src/_locales/hmn/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "appDesc": {
3 | "message": "不要浪費時間遵守法規。通用旁路繞過了惱人的鏈接縮短器。"
4 | },
5 | "firstrunTitle": {
6 | "message": "感謝您安裝通用旁路!"
7 | },
8 | "firstrunNoScript": {
9 | "message": "但是,您似乎正在使用與FastForward不兼容的NoScript或類似腳本。"
10 | },
11 | "version": {
12 | "message": "版"
13 | },
14 | "definitionsVersion": {
15 | "message": "繞過定義"
16 | },
17 | "changelog": {
18 | "message": "變更日誌"
19 | },
20 | "update": {
21 | "message": "檢查更新"
22 | },
23 | "updating": {
24 | "message": "正在下載旁路定義..."
25 | },
26 | "updateYes": {
27 | "message": "成功下載旁路定義。"
28 | },
29 | "updateNo": {
30 | "message": "旁路定義是最新的。"
31 | },
32 | "faq": {
33 | "message": "常見問題解答 (FAQ)"
34 | },
35 | "bypassCounter": {
36 | "message": "FastForward $1 已經為您繞過了站點。"
37 | },
38 | "support": {
39 | "message": "為通用旁路做貢獻。"
40 | },
41 | "options": {
42 | "message": "選件"
43 | },
44 | "optionsLink": {
45 | "message": "更改通用繞過選項。"
46 | },
47 | "optionsEnabled": {
48 | "message": "啟用網站繞過。"
49 | },
50 | "optionsTrackerBypass": {
51 | "message": "使用Apimon.de繞過跟踪器(例如bit.ly和t.co)。"
52 | },
53 | "optionsInstantNavigationTrackers": {
54 | "message": "立即將我帶到追踪器的目的地。"
55 | },
56 | "optionsBlockIPLoggers": {
57 | "message": "如果無法繞過IP記錄器,則將其阻止。"
58 | },
59 | "optionsCrowdBypass": {
60 | "message": "給予和繞過不可逾越的起酥油的目的地。"
61 | },
62 | "privacyPolicy": {
63 | "message": "隱私政策"
64 | },
65 | "contributors": {
66 | "message": "貢獻者"
67 | },
68 | "optionsUserscripts": {
69 | "message": "自定義繞過\n"
70 | },
71 | "optionsUserscriptsDescription": {
72 | "message": "這是開發人員可以創建自己的腳本來繞過站點的高級功能。完善後,可以將它們提交到GitHub上以添加到FastForward,因此每個人都可以使用。"
73 | },
74 | "beforeNavigate": {
75 | "message": "您快要到目的地了。"
76 | },
77 | "beforeNavigateDestination": {
78 | "message": "您的目的地是 $1"
79 | },
80 | "beforeNavigateUnsafe": {
81 | "message": "但是,如果您現在導航,他們將檢測到通用旁路。"
82 | },
83 | "beforeNavigateTimer": {
84 | "message": "您將在幾秒鐘內自動重定向 $1。"
85 | },
86 | "beforeNavigateTimerSingular": {
87 | "message": "您將在1秒內自動重定向。"
88 | },
89 | "beforeNavigateOptions": {
90 | "message": "您要立即重定向還是在x秒內重定向?"
91 | },
92 | "beforeNavigateInstant": {
93 | "message": "您正在導航到 $1"
94 | },
95 | "infoFileHoster": {
96 | "message": "不幸的是,下載服務器將確保您等待之後才允許下載文件。"
97 | },
98 | "infoOutdated": {
99 | "message": "較新版本的FastForward繞過了該網站。"
100 | },
101 | "crowdWait": {
102 | "message": "不幸的是,您是第一個遇到此鏈接的人,但是在等待之後,其他通用繞過用戶將不再需要。"
103 | },
104 | "crowdDisabled": {
105 | "message": "您已在選項中禁用了人群旁路,從而繞過了該網站。"
106 | },
107 | "crowdBypassed": {
108 | "message": "您可能不必等待!"
109 | },
110 | "crowdBypassedInfo": {
111 | "message": "其他通用繞過用戶已經在等您,並報告這導致 $1"
112 | },
113 | "crowdBypassedTimer": {
114 | "message": "這將在幾秒鐘內在新標籤頁中打開 $1。"
115 | },
116 | "crowdBypassedTimerSingular": {
117 | "message": "這將在1秒鐘內在新標籤頁中打開。"
118 | },
119 | "crowdCloseTimer": {
120 | "message": "此標籤將在幾秒鐘內關閉 $1。"
121 | },
122 | "crowdCloseTimerSingular": {
123 | "message": "此標籤將在1秒鐘內關閉。"
124 | },
125 | "cancel": {
126 | "message": "取消。"
127 | },
128 | "crowdBypassedIgnore": {
129 | "message": "這不正確嗎?"
130 | },
131 | "crowdBypassedOptions": {
132 | "message": "您是否要立即或在x秒內在新標籤頁中打開它?"
133 | },
134 | "blockedTitle": {
135 | "message": "通用旁路阻止您的IP被記錄。"
136 | },
137 | "blockedSubtitle": {
138 | "message": "不想讓FastForward阻止不良行為者獲取您的IP嗎?"
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/src/_locales/hy-AM/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "appDesc": {
3 | "message": "Ne perdez pas votre temps avec la conformité. Le bypass universel évite les raccourcisseurs de liens gênants."
4 | },
5 | "firstrunTitle": {
6 | "message": "Merci d'avoir installé FastForward!"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/_locales/ja/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "appDesc": {
3 | "message": "FastForwardは、迷惑な短縮リンクを回避します。コンプライアンスで時間を無駄にしないでください。"
4 | },
5 | "firstrunTitle": {
6 | "message": "FastForwardをインストールしていただき、ありがとうございます!"
7 | },
8 | "firstrunNoScript": {
9 | "message": "NoScriptなどを使用しているようですが、FastForwardとは互換性がありません。"
10 | },
11 | "version": {
12 | "message": "バージョン"
13 | },
14 | "definitionsVersion": {
15 | "message": "バイパス定義"
16 | },
17 | "changelog": {
18 | "message": "変更履歴"
19 | },
20 | "update": {
21 | "message": "アップデートを確認する"
22 | },
23 | "updating": {
24 | "message": "バイパス定義をダウンロードしています..."
25 | },
26 | "updateYes": {
27 | "message": "バイパス定義は正常にダウンロードされました。"
28 | },
29 | "updateNo": {
30 | "message": "バイパス定義は最新です。"
31 | },
32 | "faq": {
33 | "message": "よくある質問と回答(FAQ)"
34 | },
35 | "bypassCounter": {
36 | "message": "FastForwardは、いままでに$1件のサイトをバイパスしました。"
37 | },
38 | "support": {
39 | "message": "FastForwardに貢献する"
40 | },
41 | "options": {
42 | "message": "オプション"
43 | },
44 | "optionsLink": {
45 | "message": "オプションから変更できます。"
46 | },
47 | "optionsEnabled": {
48 | "message": "ウェブサイトのバイパスを有効にする"
49 | },
50 | "optionsNavigationDelay": {
51 | "message": "$1秒後にリンク先へ移動する"
52 | },
53 | "optionsTrackerBypass": {
54 | "message": "Apimon.deを使ってトラッカー (bit.ly や t.coなど) をバイパスする"
55 | },
56 | "optionsInstantNavigationTrackers": {
57 | "message": "すぐにトラッカーのリンク先へ移動する"
58 | },
59 | "optionsBlockIPLoggers": {
60 | "message": "バイパスされなかった場合はIPアドレスがログされないように阻止する"
61 | },
62 | "optionsCrowdBypass": {
63 | "message": "Crowd Bypass: バイパスできない短縮リンクの行き先を取得したり提供したりする"
64 | },
65 | "optionsCrowdAutoOpen": {
66 | "message": "$1秒後に新しいタブでクラウドソーシング先を開く"
67 | },
68 | "optionsCrowdAutoClose": {
69 | "message": "$1秒後にクラウドソーシング先を含むタブを閉じる"
70 | },
71 | "privacyPolicy": {
72 | "message": "プライバシーポリシー"
73 | },
74 | "contributors": {
75 | "message": "貢献者"
76 | },
77 | "optionsUserscripts": {
78 | "message": "カスタムバイパス"
79 | },
80 | "optionsUserscriptsDescription": {
81 | "message": "これは、開発者が独自のスクリプトを作成してサイトをバイパスするための高度な機能です。完成後、誰でも使えるように、GitHubに投稿してFastForwardに追加することもできます。"
82 | },
83 | "beforeNavigate": {
84 | "message": "リンク先まであと少しです。"
85 | },
86 | "beforeNavigateDestination": {
87 | "message": "リンク先は$1"
88 | },
89 | "beforeNavigateUnsafe": {
90 | "message": "ただし、いま移動すると、サイトはFastForwardを検出してしまいます。"
91 | },
92 | "beforeNavigateUnsafeTimer": {
93 | "message": "あと$1秒で検出されなくなります。"
94 | },
95 | "beforeNavigateUnsafeTimerSingular": {
96 | "message": "あと1秒で検出されなくなります。"
97 | },
98 | "beforeNavigateTimer": {
99 | "message": "$1秒後に自動的にリダイレクトされます。"
100 | },
101 | "beforeNavigateTimerSingular": {
102 | "message": "1秒後に自動的にリダイレクトされます。"
103 | },
104 | "beforeNavigateOptions": {
105 | "message": "すぐに、または数秒後にリダイレクトされるようにしたいですか?"
106 | },
107 | "beforeNavigateInstant": {
108 | "message": "$1に移動しています"
109 | },
110 | "infoLinkvertise": {
111 | "message": "このサイトのバイパスは許可されていませんが、私たちはこのサイトのもっとも迷惑な手順を除去するように交渉しました。"
112 | },
113 | "infoFileHoster": {
114 | "message": "残念ながら、ダウンロードサーバーはファイルのダウンロードが許可される前に待機していることを確認します。"
115 | },
116 | "infoOutdated": {
117 | "message": "このサイトは、FastForwardの新しいバージョンでバイパスされます。"
118 | },
119 | "crowdWait": {
120 | "message": "残念ながら、あなたはこのリンクの最初のアクセス者です。しばらくすれば、他のFastForwardユーザーが待つ必要はなくなります。"
121 | },
122 | "crowdDisabled": {
123 | "message": "このサイトは、Crowd Bypassを有効にしているときのみバイパスできます。オプションからこの設定をオンにすることができます。"
124 | },
125 | "crowdBypassed": {
126 | "message": "もう待つ必要はありません!"
127 | },
128 | "crowdBypassedInfo": {
129 | "message": "他のFastForwardユーザーがこのページを訪れたことがあり、$1に移動することを報告しています。"
130 | },
131 | "crowdBypassedTimer": {
132 | "message": "$1秒後に新しいタブで開きます。"
133 | },
134 | "crowdBypassedTimerSingular": {
135 | "message": "1秒後に新しいタブで開きます。"
136 | },
137 | "crowdCloseTimer": {
138 | "message": "このタブは$1秒後に閉じられます。"
139 | },
140 | "crowdCloseTimerSingular": {
141 | "message": "このタブは1秒後に閉じられます。"
142 | },
143 | "cancel": {
144 | "message": "キャンセルする"
145 | },
146 | "crowdBypassedIgnore": {
147 | "message": "正しくありませんか?"
148 | },
149 | "crowdBypassedOptions": {
150 | "message": "すぐに、または数秒後に新しいタブで開かれるようにしたいですか?"
151 | },
152 | "blockedTitle": {
153 | "message": "FastForwardは、あなたのIPアドレスがログされないように阻止しました。"
154 | },
155 | "blockedSubtitle": {
156 | "message": "悪意のある人があなたのIPアドレスをログできないようにする機能をオフにしたいですか?"
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/src/_locales/ka/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "appDesc": {
3 | "message": "ნუ დაკარგავთ დროს. FastForward გამოტოვებს მომაბეზრებელ ბმულის შემამოკლებლებს."
4 | },
5 | "firstrunTitle": {
6 | "message": "მადლობა FastForward დაყენებისთვის!"
7 | },
8 | "firstrunNoScript": {
9 | "message": "შესაძლოა თქვენ იყენებთ NoScript ან სხვა მასგავს გაფართოებას, რომელიც არ არის თავსებადი FastForward-თან"
10 | },
11 | "version": {
12 | "message": "ვერსია"
13 | },
14 | "definitionsVersion": {
15 | "message": "გამოტოვების წესები"
16 | },
17 | "changelog": {
18 | "message": "ცვლილებელის ისტორია"
19 | },
20 | "update": {
21 | "message": "განახლების შემოწმება"
22 | },
23 | "updating": {
24 | "message": "გამოტოვების წესები ითვირთება..."
25 | },
26 | "updateYes": {
27 | "message": "გამოტოვების წესები წარმატებით ჩამოიტვირთა."
28 | },
29 | "updateNo": {
30 | "message": "გამოტოვების წესები განახლებულია."
31 | },
32 | "faq": {
33 | "message": "ხშირად დასმული კითხვები"
34 | },
35 | "bypassCounter": {
36 | "message": "FastForward-მა გამოტოვა $1 გვერდი თქვენთვის."
37 | },
38 | "support": {
39 | "message": "შეიტანეთ თქვენი წვლილი."
40 | },
41 | "options": {
42 | "message": "პარამეტრები"
43 | },
44 | "optionsLink": {
45 | "message": "შეცვალეთ პარამეტრები."
46 | },
47 | "optionsEnabled": {
48 | "message": "ok"
49 | },
50 | "optionsNavigationDelay": {
51 | "message": "ავტომატური გადასვლა $1 წამში"
52 | },
53 | "optionsBlockIPLoggers": {
54 | "message": "დაბლოკე იპ ლოგერები თუ შემოვლა არ მუშაობს"
55 | },
56 | "privacyPolicy": {
57 | "message": "კონფიდენციალურობის პოლიტიკა"
58 | },
59 | "contributors": {
60 | "message": "წვლილის შემტანები"
61 | },
62 | "optionsUserscripts": {
63 | "message": "არაოფიციალური შემოსავლები"
64 | },
65 | "beforeNavigate": {
66 | "message": "თითქმით მისული ხარტ თქვენ ვებსაიტზე"
67 | },
68 | "beforeNavigateDestination": {
69 | "message": "დანიშნულების მისამართი $1"
70 | },
71 | "beforeNavigateUnsafe": {
72 | "message": "თუ ეხლა გადახვალთ საიტზე ისინი დააფიქსირებენ FastForward."
73 | },
74 | "beforeNavigateUnsafeTimer": {
75 | "message": "თქვენ არ იქნებით დაფიქსირებული $1 წამში"
76 | },
77 | "beforeNavigateUnsafeTimerSingular": {
78 | "message": "თქვენ არ იქნებით დაფიქსირებული 1 წამში"
79 | },
80 | "beforeNavigateTimer": {
81 | "message": "თქვენ გადამისამართდებით ავტომატურად $1 წამში"
82 | },
83 | "beforeNavigateTimerSingular": {
84 | "message": "თქვენ გადამისამართდებით ავტომატურად 1 წამში"
85 | },
86 | "beforeNavigateOptions": {
87 | "message": "გსურთ გადამისამართება მომენტალურად ან x წამში?"
88 | },
89 | "beforeNavigateInstant": {
90 | "message": "FastForward-ერი ეხლა წაგიყვანთ $1"
91 | },
92 | "infoFileHoster": {
93 | "message": "სამწუხაროდ, გადმოწერის სერვერი ამოწმებს დაელოდეთ თუ არა შესაბამისი დრო ფაილის გადმოსაწერად."
94 | },
95 | "infoOutdated": {
96 | "message": "ამ ვებსაიტის შემოვლა შესაძლებელია მხოლოდ FastForward-ის ახალი ვერსიით"
97 | },
98 | "crowdWait": {
99 | "message": "სამწუხაროდ, თქვენ ხართ პირველი მომხმარებელი, ვინც გახსნა ეს ბმული. სხვა მომხმარებლებს თქვენს შემდეგ აღარ მოუწევთ ლოდინი."
100 | },
101 | "crowdBypassed": {
102 | "message": "თქვენ არ გჭირდებათ ლოდინი"
103 | },
104 | "crowdBypassedInfo": {
105 | "message": "FastForward-ის სხვა მომხმარებლები დაელოდნენ თქვენს მაგივრად და შეგვატყობინეს რომ ეს მისამართი გადამისამართდება $1 -ზე."
106 | },
107 | "crowdBypassedTimer": {
108 | "message": "და ის გაიხსნება $1 წამში."
109 | },
110 | "crowdBypassedTimerSingular": {
111 | "message": "და ის გაიხსნება 1 წამში."
112 | },
113 | "crowdCloseTimer": {
114 | "message": "ეს ჩანართი დაიხურება $1 წამში."
115 | },
116 | "crowdCloseTimerSingular": {
117 | "message": "ეს ჩანართი დაიხურება 1 წამში."
118 | },
119 | "cancel": {
120 | "message": "გაუქმება"
121 | },
122 | "crowdBypassedIgnore": {
123 | "message": "ეს არასწორია?"
124 | },
125 | "crowdBypassedOptions": {
126 | "message": "გსურთ გახსნა მომენტალურად ან x წამში?"
127 | },
128 | "blockedTitle": {
129 | "message": "FastForward-მა დაგიცვათ თქვენი IP-ს დამახსოვრებისგან.\n"
130 | },
131 | "blockedSubtitle": {
132 | "message": "არ გინდათ FastForwarder-მა რო დაგიცვას ცუდი ადამიანებისგან თქვენი მდებარეობა რო არ გაიგონ?"
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/src/_locales/ko/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "appDesc": {
3 | "message": "시간을 낭비하지 마세요. FastForward로 성가신 링크 단축 서비스를 자동 생략하세요."
4 | },
5 | "firstrunTitle": {
6 | "message": "FastForward를 설치해 주셔서 감사합니다!"
7 | },
8 | "firstrunNoScript": {
9 | "message": "흠, NoScript나 비슷한 걸 쓰는 것 같지만, FastForward는 그런 것들과 호환되지 않습니다."
10 | },
11 | "version": {
12 | "message": "버전"
13 | },
14 | "definitionsVersion": {
15 | "message": "우회 정의"
16 | },
17 | "changelog": {
18 | "message": "변경 사항"
19 | },
20 | "update": {
21 | "message": "업데이트 확인"
22 | },
23 | "updating": {
24 | "message": "바이 패스 정의 다운로드 중 ..."
25 | },
26 | "updateYes": {
27 | "message": "인젝션 스크립트를 업데이트하는데 성공했습니다!"
28 | },
29 | "updateNo": {
30 | "message": "인젝션 스크립트가 이미 최신입니다."
31 | },
32 | "faq": {
33 | "message": "자주 묻는 질문"
34 | },
35 | "bypassCounter": {
36 | "message": "FastForward는 당신을 위해 $1개의 사이트를 우회했어요."
37 | },
38 | "support": {
39 | "message": "FastForward 돕기"
40 | },
41 | "options": {
42 | "message": "설정"
43 | },
44 | "optionsLink": {
45 | "message": "FastForward의 설정을 바꾸기"
46 | },
47 | "optionsEnabled": {
48 | "message": "웹사이트 우회 켜기"
49 | },
50 | "optionsNavigationDelay": {
51 | "message": "목적지로 $1초 뒤에 이동하기 (0을 쓰면 즉시 이동)"
52 | },
53 | "optionsTrackerBypass": {
54 | "message": "Apimon.de를 사용하여 트래커 (예 : bit.ly 및 t.co)를 무시하십시오."
55 | },
56 | "optionsInstantNavigationTrackers": {
57 | "message": "즉시 추적기의 목적지로 보내기"
58 | },
59 | "optionsBlockIPLoggers": {
60 | "message": "우회할 수 없는 사이트의 IP 기록 차단하기."
61 | },
62 | "optionsCrowdBypass": {
63 | "message": "우회할 수 없는 URL 단축 사이트 목적지 주고 받기."
64 | },
65 | "optionsCrowdAutoOpen": {
66 | "message": "$1초 후 새 탭에서 크라우드 소싱 대상 열기 (0 = 즉시)"
67 | },
68 | "optionsCrowdAutoClose": {
69 | "message": "크라우드소싱 대상 방문 $1초 후 해당 탭 닫기."
70 | },
71 | "privacyPolicy": {
72 | "message": "개인정보 취급방침"
73 | },
74 | "contributors": {
75 | "message": "도와주신 분들"
76 | },
77 | "optionsUserscripts": {
78 | "message": "사용자 지정 우회책"
79 | },
80 | "optionsUserscriptsDescription": {
81 | "message": "개발자를 위한 고급 기능으로 자체 우회책을 만들 수 있습니다. 완벽하게 만들어졌다면, GitHub에 제안해 FastForward에 추가되고 모두가 쓸 수 있게 됩니다."
82 | },
83 | "beforeNavigate": {
84 | "message": "거의 다 왔습니다."
85 | },
86 | "beforeNavigateDestination": {
87 | "message": "목적지는 $1 입니다."
88 | },
89 | "beforeNavigateUnsafe": {
90 | "message": "잠깐!, 지금 바로 간다면 FastForward가 들통날 거에요."
91 | },
92 | "beforeNavigateUnsafeTimer": {
93 | "message": "$1초 후에 감지되지 않게 됩니다."
94 | },
95 | "beforeNavigateUnsafeTimerSingular": {
96 | "message": "1초 후에 감지되지 않게 됩니다."
97 | },
98 | "beforeNavigateTimer": {
99 | "message": "페이지로 $1초 안에 이동합니다."
100 | },
101 | "beforeNavigateTimerSingular": {
102 | "message": "페이지로 1초 안에 이동합니다."
103 | },
104 | "beforeNavigateOptions": {
105 | "message": "자동으로 리다이렉트하고 싶나요?"
106 | },
107 | "beforeNavigateInstant": {
108 | "message": "$1 (으)로 이동 중입니다"
109 | },
110 | "infoLinkvertise": {
111 | "message": "우리는 이 웹 사이트를 우회 할 수는 없지만, 가장 귀찮은 단계를 제거하기로 협상했습니다."
112 | },
113 | "infoFileHoster": {
114 | "message": "불행히도, 다운로드 서버가 당신이 실제로 파일을 받기 위해 기다렸는지 확인하기 때문에 건너뛸 수 없습니다."
115 | },
116 | "infoOutdated": {
117 | "message": "이 사이트는 FastForward를 업데이트 해야 건너뛸 수 있습니다."
118 | },
119 | "crowdWait": {
120 | "message": "안타깝게도 이 링크의 첫 발견자신 것 같군요. 기다려주신다면 다른 사용자 분들은 기다리지 않으실 수 있어요."
121 | },
122 | "crowdDisabled": {
123 | "message": "이 사이트는 crowd bypass에 의해서만 통과할 수 있습니다. 설정에서 이 옵션을 켤 수 있습니다."
124 | },
125 | "crowdBypassed": {
126 | "message": "이제 기다릴 필요 없어요!"
127 | },
128 | "crowdBypassedInfo": {
129 | "message": "다른 FastForward 사용자가 이 페이지를 방문한 적이 있으며, $1 로 이동하는걸로 알아냈습니다."
130 | },
131 | "crowdBypassedTimer": {
132 | "message": "페이지가 새 탭에 $1초 안에 열립니다."
133 | },
134 | "crowdBypassedTimerSingular": {
135 | "message": "페이지가 새 탭에 1초 안에 열립니다."
136 | },
137 | "crowdCloseTimer": {
138 | "message": "이 탭은 $1초 후 닫힙니다."
139 | },
140 | "crowdCloseTimerSingular": {
141 | "message": "이 탭은 1초 후 닫힙니다."
142 | },
143 | "cancel": {
144 | "message": "취소"
145 | },
146 | "crowdBypassedIgnore": {
147 | "message": "올바르지 않나요?"
148 | },
149 | "crowdBypassedOptions": {
150 | "message": "자동으로 이동하고 싶나요?"
151 | },
152 | "blockedTitle": {
153 | "message": "FastForward가 당신의 IP를 기록하지 못하게 막았습니다."
154 | },
155 | "blockedSubtitle": {
156 | "message": "FastForward가 악성 사이트에서 IP를 가져가는것을 막기를 원하나요?"
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/src/_locales/lo/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "appDesc": {
3 | "message": "ຢ່າເສຍເວລາຂອງທ່ານດ້ວຍການປະຕິບັດຕາມ. FastForward ຫລີກລ້ຽງການເຊື່ອມຕໍ່ສັ້ນທີ່ ໜ້າ ຮໍາຄານ"
4 | },
5 | "firstrunTitle": {
6 | "message": "ຂອບໃຈ ສຳ ລັບຕິດຕັ້ງ FastForward!"
7 | },
8 | "firstrunNoScript": {
9 | "message": "ເຖິງຢ່າງໃດກໍ່ຕາມ, ທ່ານເບິ່ງຄືວ່າ ກຳ ລັງໃຊ້ NoScript ຫຼືຄ້າຍຄືກັນ, ເຊິ່ງ FastForward ບໍ່ເຂົ້າກັນ."
10 | },
11 | "version": {
12 | "message": "ຮຸ່ນ"
13 | },
14 | "definitionsVersion": {
15 | "message": "ຄຳ ນິຍາມບິດເບືອນ"
16 | },
17 | "changelog": {
18 | "message": "Changelog"
19 | },
20 | "update": {
21 | "message": "ກວດເບິ່ງການປັບປຸງ..."
22 | },
23 | "updating": {
24 | "message": "ກຳ ລັງດາວໂຫລດ ຄຳ ນິຍາມ bypass ..."
25 | },
26 | "updateYes": {
27 | "message": "ການດາວໂຫລດ ຄຳ ນິຍາມ bypass ສຳ ເລັດແລ້ວ."
28 | },
29 | "updateNo": {
30 | "message": "ນິຍາມ Bypass ແມ່ນທັນສະ ໄໝ."
31 | },
32 | "faq": {
33 | "message": "ຄໍາຖາມທີ່ຖືກຖາມເລື້ອຍໆ"
34 | },
35 | "support": {
36 | "message": "ປະກອບສ່ວນໃຫ້ FastForward."
37 | },
38 | "options": {
39 | "message": "ທາງເລືອກ"
40 | },
41 | "optionsLink": {
42 | "message": "ປ່ຽນຕົວເລືອກ FastForward."
43 | },
44 | "optionsEnabled": {
45 | "message": "ເປີດ ນຳ ໃຊ້ເວັບໄຊທ໌ຂ້າມຜ່ານ."
46 | },
47 | "optionsNavigationDelay": {
48 | "message": "ພາຂ້ອຍໄປທີ່ຈຸດ ໝາຍ ປາຍທາງຫຼັງຈາກ $1 ວິນາທີ."
49 | },
50 | "optionsTrackerBypass": {
51 | "message": "ຜູ້ຕິດຕາມ Bypass (ເຊັ່ນ: bit.ly ແລະ t.co) ໂດຍໃຊ້ Apimon.de"
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/_locales/mi/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "optionsUserscripts": {
3 | "message": "Custom Bypasses"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/src/_locales/no/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "appDesc": {
3 | "message": "Ikke kast bort tiden din på å følge krav. FastForward hopper automatisk over irriterende lenkeforkortere."
4 | },
5 | "firstrunTitle": {
6 | "message": "Takk for at du har installert FastForward!"
7 | },
8 | "firstrunNoScript": {
9 | "message": "Men du ser ut til å bruke NoScript eller noe lignende, som FastForward ikke er kompatibel med."
10 | },
11 | "version": {
12 | "message": "Versjon"
13 | },
14 | "definitionsVersion": {
15 | "message": "Bypass definisjoner"
16 | },
17 | "changelog": {
18 | "message": "Endringslogg"
19 | },
20 | "update": {
21 | "message": "Se etter oppdateringer"
22 | },
23 | "updating": {
24 | "message": "Laster ned bypass-definisjoner..."
25 | },
26 | "updateYes": {
27 | "message": "Oppdateringsskriptet ble oppdatert!"
28 | },
29 | "updateNo": {
30 | "message": "Forbigående definisjoner er oppdatert."
31 | },
32 | "faq": {
33 | "message": "Ofte Stilte Spørsmål (FAQ)"
34 | },
35 | "bypassCounter": {
36 | "message": "FastForward har allerede forbigått $1 nettsteder for deg."
37 | },
38 | "support": {
39 | "message": "Støtt FastForward."
40 | },
41 | "options": {
42 | "message": "Innstillinger"
43 | },
44 | "optionsLink": {
45 | "message": "Endre FastForward sine innstillinger."
46 | },
47 | "optionsEnabled": {
48 | "message": "Slå på nettside bypass."
49 | },
50 | "optionsNavigationDelay": {
51 | "message": "Ta meg til destinasjoner etter $1 sekund(er). (Bruk 0 for å navigere øyeblikkelig.)"
52 | },
53 | "optionsTrackerBypass": {
54 | "message": "Omgå for trackere (for eksempel bit.ly og t.co) ved å bruke Apimon.de."
55 | },
56 | "optionsInstantNavigationTrackers": {
57 | "message": "Ta meg til destinasjoner av trackere med en gang."
58 | },
59 | "optionsBlockIPLoggers": {
60 | "message": "Blokker IP-loggførere dersom de ikke kan bli hoppet forbi."
61 | },
62 | "optionsCrowdBypass": {
63 | "message": "Gi og ta ankomstpunktene til upasserbare forkortere."
64 | },
65 | "optionsCrowdAutoOpen": {
66 | "message": "Åpne publikumsdestinasjoner i en ny fane etter $1 sekund(er). (0 = øyeblikkelig.)"
67 | },
68 | "privacyPolicy": {
69 | "message": "Privatlivsretningslinjer"
70 | },
71 | "optionsUserscripts": {
72 | "message": "Tilpassede forbipasserere"
73 | },
74 | "optionsUserscriptsDescription": {
75 | "message": "Dette er en avansert funksjon for utviklere å lage sine egne skript for å omgå nettsteder. Når de er perfeksjonert, kan de deretter sendes inn på GitHub for å bli lagt til FastForward, slik at de er tilgjengelige for alle."
76 | },
77 | "beforeNavigate": {
78 | "message": "Du er nesten i destinasjonen din."
79 | },
80 | "beforeNavigateDestination": {
81 | "message": "Destinasjonen din er $1"
82 | },
83 | "beforeNavigateTimer": {
84 | "message": "Du blir omdirigert automatisk om $1 sekunder."
85 | },
86 | "beforeNavigateTimerSingular": {
87 | "message": "Du blir omdirigert automatisk i løpet av 1 sekund."
88 | },
89 | "beforeNavigateOptions": {
90 | "message": "Vil du bli omdirigert øyeblikkelig eller om x sekunder?"
91 | },
92 | "crowdWait": {
93 | "message": "Dessverre er du den første som møter denne lenken, men etter at du har ventet, vil andre brukere av FastForward ikke lenger behøve å gjøre det."
94 | },
95 | "crowdDisabled": {
96 | "message": "Dette nettstedet omgås av publikumsomgang, som du har deaktivert under alternativene."
97 | },
98 | "crowdBypassed": {
99 | "message": "Du vil kanskje ikke måtte vente!"
100 | },
101 | "crowdBypassedInfo": {
102 | "message": "Andre FastForward-brukere har allerede ventet på deg, og har meldt ifra om at dette fører til $1"
103 | },
104 | "crowdBypassedTimer": {
105 | "message": "Dette åpnes i en ny fane om $1 sekunder."
106 | },
107 | "crowdBypassedTimerSingular": {
108 | "message": "Dette åpnes i en ny fane om 1 sekund."
109 | },
110 | "cancel": {
111 | "message": "Avbryt."
112 | },
113 | "crowdBypassedIgnore": {
114 | "message": "Var ikke dette korrekt?"
115 | },
116 | "crowdBypassedOptions": {
117 | "message": "Vil du at dette skal åpnes i en ny fane øyeblikkelig eller om x sekunder?"
118 | },
119 | "blockedTitle": {
120 | "message": "FastForward hindret IP-adressen din fra å bli loggført."
121 | },
122 | "blockedSubtitle": {
123 | "message": "Vil du at FastForward skal stoppe dårlige folk fra å få IPen din?"
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/src/_locales/sh/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "appDesc": {
3 | "message": "Ne gubite vreme na komplikacije. FastForward zaobilazi dosadne link shortenere."
4 | },
5 | "firstrunTitle": {
6 | "message": "Hvala vam za instaliranje FastForward!"
7 | },
8 | "firstrunNoScript": {
9 | "message": "Međutim, izgleda da koristite NoScript ili slično, s čime FastForward nije kompatibilan."
10 | },
11 | "version": {
12 | "message": "Verzija"
13 | },
14 | "definitionsVersion": {
15 | "message": "Definicija bypassera"
16 | },
17 | "changelog": {
18 | "message": "Promene"
19 | },
20 | "update": {
21 | "message": "Proveri ima li ažuriranja"
22 | },
23 | "updating": {
24 | "message": "Preuzimanje definicije bypassera..."
25 | },
26 | "updateYes": {
27 | "message": "Uspešno instaliran bypass"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/_locales/sl/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "appDesc": {
3 | "message": "Ne zapravljajte časa s skladnostjo. Univerzalni bypass obide nadležne krajšave povezav."
4 | },
5 | "firstrunTitle": {
6 | "message": "Hvala, ker ste namestili FastForward!"
7 | },
8 | "firstrunNoScript": {
9 | "message": "Vendar se zdi, da uporabljate NoScript ali podobno, s čimer FastForward ni združljiv."
10 | },
11 | "version": {
12 | "message": "Različica"
13 | },
14 | "definitionsVersion": {
15 | "message": "Opredelitve definicij"
16 | },
17 | "changelog": {
18 | "message": "Dnevnik sprememb"
19 | },
20 | "update": {
21 | "message": "Preveri za posodobitve"
22 | },
23 | "updating": {
24 | "message": "Prenos definicij bypass ..."
25 | },
26 | "updateYes": {
27 | "message": "Definicije bypass so uspešno prenesene."
28 | },
29 | "updateNo": {
30 | "message": "Definicije bypass so posodobljene."
31 | },
32 | "faq": {
33 | "message": "Pogosta vprašanja (FAQ)"
34 | },
35 | "bypassCounter": {
36 | "message": "FastForward je že zaobšel$1 spletnih mest za vas."
37 | },
38 | "support": {
39 | "message": "Prispevajte k Univerzalni obvoznici."
40 | },
41 | "options": {
42 | "message": "Opcije"
43 | },
44 | "optionsLink": {
45 | "message": "Spremeni možnosti FastForward '."
46 | },
47 | "optionsEnabled": {
48 | "message": "Omogoči obhode spletnih strani"
49 | },
50 | "optionsNavigationDelay": {
51 | "message": "Odpeljite me do cilja po$1 sekundah."
52 | },
53 | "optionsTrackerBypass": {
54 | "message": "S storitvijo Apimon.de obiščite sledilnike (na primer bit.ly in t.co)."
55 | },
56 | "optionsInstantNavigationTrackers": {
57 | "message": "Takoj me popeljejo na destinacije sledilcev."
58 | },
59 | "optionsBlockIPLoggers": {
60 | "message": "Blokirajte zapisovalnike IP, če jih ni mogoče zaobiti."
61 | },
62 | "optionsCrowdBypass": {
63 | "message": "Množični obvoz: Določite in izkoristite cilje neprimerljivih skrajševalcev."
64 | },
65 | "optionsCrowdAutoOpen": {
66 | "message": "Po$1 sekundah odprite nove cilje na novem zavihku na novem zavihku."
67 | },
68 | "optionsCrowdAutoClose": {
69 | "message": "Zaprite zavihek, ki vsebuje destinacijo z množico ljudi po$1 sekunde obiska."
70 | },
71 | "privacyPolicy": {
72 | "message": "Politika zasebnosti"
73 | },
74 | "contributors": {
75 | "message": "Sodelujoči"
76 | },
77 | "optionsUserscripts": {
78 | "message": "Obvoznice po meri"
79 | },
80 | "optionsUserscriptsDescription": {
81 | "message": "To je napredna funkcija za razvijalce, da ustvarijo svoje skripte za obhod spletnih mest. Ko bodo izpopolnjeni, jih je mogoče nato poslati na GitHub in jih dodati FastForward, tako da so na voljo vsem."
82 | },
83 | "beforeNavigate": {
84 | "message": "Skoraj že ste na svojem cilju."
85 | },
86 | "beforeNavigateDestination": {
87 | "message": "Vaš cilj je$1"
88 | },
89 | "beforeNavigateUnsafe": {
90 | "message": "Če pa greste zdaj, bodo zaznali FastForward."
91 | },
92 | "beforeNavigateUnsafeTimer": {
93 | "message": "V$1 sekundah ne boste več zaznani."
94 | },
95 | "beforeNavigateUnsafeTimerSingular": {
96 | "message": "V 1 sekundi ne boste več zaznani."
97 | },
98 | "beforeNavigateTimer": {
99 | "message": "Preusmerjeni boste samodejno v$1 sekundah."
100 | },
101 | "beforeNavigateTimerSingular": {
102 | "message": "V 1 sekundi boste samodejno preusmerjeni."
103 | },
104 | "beforeNavigateOptions": {
105 | "message": "Ali želite biti preusmerjeni takoj ali v x sekundah?"
106 | },
107 | "beforeNavigateInstant": {
108 | "message": "Navigirate do$1"
109 | },
110 | "infoFileHoster": {
111 | "message": "Na žalost bo strežnik za prenos poskrbel, da ste čakali, preden boste dovolili prenos datoteke."
112 | },
113 | "infoOutdated": {
114 | "message": "To spletno mesto obide novejša različica FastForward."
115 | },
116 | "crowdWait": {
117 | "message": "Na žalost ste prvič naleteli na to povezavo, vendar po tem, ko ste čakali, drugim uporabnikom FastForward-a ne bo več treba."
118 | },
119 | "crowdDisabled": {
120 | "message": "To spletno mesto obide množica bypass, kar lahko omogočite v možnostih."
121 | },
122 | "crowdBypassed": {
123 | "message": "Morda ne bo treba čakati!"
124 | },
125 | "crowdBypassedInfo": {
126 | "message": "Drugi uporabniki FastForward-a so vas že čakali in sporočili, da to vodi do$1"
127 | },
128 | "crowdBypassedTimer": {
129 | "message": "To se odpre v novem zavihku v$1 sekundah."
130 | },
131 | "crowdBypassedTimerSingular": {
132 | "message": "To se odpre v novem zavihku v 1 sekundi."
133 | },
134 | "crowdCloseTimer": {
135 | "message": "Ta zavihek se zapre v$1 sekundah."
136 | },
137 | "crowdCloseTimerSingular": {
138 | "message": "Ta zavihek se zapre v 1 sekundi."
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/src/_locales/su/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "appDesc": {
3 | "message": "Ulah nyia-nyia keun waktos nurut kana aturan. FastForward bakal otomatis ngalangkungan alamat nu matak ngagganggu. "
4 | },
5 | "firstrunTitle": {
6 | "message": "Hatur nuhun parantos masang FastForward!"
7 | },
8 | "firstrunNoScript": {
9 | "message": "Nanging, anjeun sigana nganggo ekstensi NoScript atawa nu sajabana, nyebabkeun FastForward teu jalan."
10 | },
11 | "version": {
12 | "message": "Vérsi"
13 | },
14 | "definitionsVersion": {
15 | "message": "Pangertian Bypass"
16 | },
17 | "changelog": {
18 | "message": "Catetan parobahan"
19 | },
20 | "update": {
21 | "message": "Marios pambaharuan"
22 | },
23 | "updating": {
24 | "message": "Ngunduh definisi bypass..."
25 | },
26 | "updateYes": {
27 | "message": "Rengse ngunduh definisi bypass."
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/_locales/uz/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "appDesc": {
3 | "message": "Vaqtingizni moslashtirish uchun bekorga ketkazmang. FastForward sizga veb manzillarni qisqartirishda ko'mak beradi."
4 | },
5 | "firstrunTitle": {
6 | "message": "FastForwardni o'rnatganingiz uchun rahmat!"
7 | },
8 | "firstrunNoScript": {
9 | "message": "Siz FastForwardga mos bo'lmagan NoScript yoki shunga o'xshash dasturdan foydalanayotgangan o'xshaysiz."
10 | },
11 | "version": {
12 | "message": "Versiya"
13 | },
14 | "definitionsVersion": {
15 | "message": "Bypass ta'riflari"
16 | },
17 | "changelog": {
18 | "message": "Holati"
19 | },
20 | "update": {
21 | "message": "Yangilanishlar uchun tekshirish"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/_locales/zh-CN/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "appDesc": {
3 | "message": "不要费时等待,FastForward 可以帮你规避烦人的短链接。"
4 | },
5 | "firstrunTitle": {
6 | "message": "感谢您安装 FastForward!"
7 | },
8 | "firstrunNoScript": {
9 | "message": "看起来您正在使用 NoScript 或类似工具,FastForward 暂不与之兼容。"
10 | },
11 | "version": {
12 | "message": "版本"
13 | },
14 | "definitionsVersion": {
15 | "message": "Bypass的定义"
16 | },
17 | "changelog": {
18 | "message": "更新记录"
19 | },
20 | "update": {
21 | "message": "检查更新"
22 | },
23 | "updating": {
24 | "message": "正在下载Bypass 的定义..."
25 | },
26 | "updateYes": {
27 | "message": "Bypass的定义下载成功。"
28 | },
29 | "updateNo": {
30 | "message": "Bypass的定义已是最新版本。"
31 | },
32 | "faq": {
33 | "message": "常见问题(FAQ)"
34 | },
35 | "bypassCounter": {
36 | "message": "FastForward已经帮你跳过了$1的网站"
37 | },
38 | "support": {
39 | "message": "支持FastForward."
40 | },
41 | "options": {
42 | "message": "选项"
43 | },
44 | "optionsLink": {
45 | "message": "更改FastForward的选项"
46 | },
47 | "optionsEnabled": {
48 | "message": "启用网站跳过功能"
49 | },
50 | "optionsNavigationDelay": {
51 | "message": "在$1秒后跳到目标网站.(0 为立刻跳转.)"
52 | },
53 | "optionsTrackerBypass": {
54 | "message": "跳过使用Apimon.de的追踪器(比如bit.ly和t.co)。"
55 | },
56 | "optionsInstantNavigationTrackers": {
57 | "message": "立即将我带到追踪器的目的网址。"
58 | },
59 | "optionsBlockIPLoggers": {
60 | "message": "如果无法绕过IP记录器,则将其屏蔽。\n"
61 | },
62 | "optionsCrowdBypass": {
63 | "message": "分享/获取无法跳过的短地址提供商的目的网址。"
64 | },
65 | "optionsCrowdAutoOpen": {
66 | "message": "$1秒后在新标签页打开人们分享的目的网址。"
67 | },
68 | "optionsCrowdAutoClose": {
69 | "message": "访问人们分享的目的网址$1秒后将其标签页关闭。"
70 | },
71 | "privacyPolicy": {
72 | "message": "隐私政策"
73 | },
74 | "contributors": {
75 | "message": "贡献者"
76 | },
77 | "optionsUserscripts": {
78 | "message": "自定义跳过"
79 | },
80 | "optionsUserscriptsDescription": {
81 | "message": "此高级功能供开发者创建自己的绕过脚本。完善以后,这些脚本可以提交到GitHub上,再添加到FastForward中,让所有人都能使用。"
82 | },
83 | "beforeNavigate": {
84 | "message": "您即将到达目的网址。"
85 | },
86 | "beforeNavigateDestination": {
87 | "message": "您的目的网址为$1"
88 | },
89 | "beforeNavigateUnsafe": {
90 | "message": "如果您马上跳转,他们将会检测到FastForward。"
91 | },
92 | "beforeNavigateUnsafeTimer": {
93 | "message": "$1秒后,您将不再被检测到。"
94 | },
95 | "beforeNavigateUnsafeTimerSingular": {
96 | "message": "1秒后,您将在不再被检测到。"
97 | },
98 | "beforeNavigateTimer": {
99 | "message": "$1秒后,您将被自动导航到目的网站。"
100 | },
101 | "beforeNavigateTimerSingular": {
102 | "message": "1秒后,您将被自动导航到目的网站。"
103 | },
104 | "beforeNavigateOptions": {
105 | "message": "您想立刻导航到目的网站还是在x秒后?"
106 | },
107 | "beforeNavigateInstant": {
108 | "message": "您正在导航到$1"
109 | },
110 | "infoLinkvertise": {
111 | "message": "我们不允许绕过这个网站,但我们已经通过谈判取消了他们最烦人的步骤。"
112 | },
113 | "infoFileHoster": {
114 | "message": "很不辛的是,下载服务器会确保您已经等待,然后才允许您下载文件。"
115 | },
116 | "infoOutdated": {
117 | "message": "该网站已被新版本的FastForward跳转。"
118 | },
119 | "crowdWait": {
120 | "message": "很抱歉您是第一个点击此链接的人,过一段时间以后,其他FastForward用户将不再需要等待。"
121 | },
122 | "crowdDisabled": {
123 | "message": "该网站需使用群众分享跳过功能,但您已禁用此功能。"
124 | },
125 | "crowdBypassed": {
126 | "message": "您或许不必等待!"
127 | },
128 | "crowdBypassedInfo": {
129 | "message": "其他FastForward用户已经帮您导航,并报告该链接的目的网址为$1"
130 | },
131 | "crowdBypassedTimer": {
132 | "message": "$1秒后将会在新标签页打开。"
133 | },
134 | "crowdBypassedTimerSingular": {
135 | "message": "1秒后将会在新标签页打开。"
136 | },
137 | "crowdCloseTimer": {
138 | "message": "此选项卡将在$1秒后关闭。"
139 | },
140 | "crowdCloseTimerSingular": {
141 | "message": "此选项卡将在1秒后关闭。"
142 | },
143 | "cancel": {
144 | "message": "取消"
145 | },
146 | "crowdBypassedIgnore": {
147 | "message": "该信息不正确?"
148 | },
149 | "crowdBypassedOptions": {
150 | "message": "您想在新标签页中立刻打开还是在x秒后?"
151 | },
152 | "blockedTitle": {
153 | "message": "FastForward阻止了您的IP地址被记录"
154 | },
155 | "blockedSubtitle": {
156 | "message": "不想要FastForward阻止不良分子获取您的IP地址?"
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/src/_locales/zh-TW/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "appDesc": {
3 | "message": "別浪費時間在等待上!FastForward 能夠全自動地繞過煩人的短連結!"
4 | },
5 | "firstrunTitle": {
6 | "message": "感謝您安裝 FastForward!"
7 | },
8 | "firstrunNoScript": {
9 | "message": "然而,您似乎安裝了 NoScript 或類似的插件,導致與 FastForward 造成衝突。"
10 | },
11 | "version": {
12 | "message": "版本"
13 | },
14 | "definitionsVersion": {
15 | "message": "繞過規則定義"
16 | },
17 | "changelog": {
18 | "message": "更新紀錄"
19 | },
20 | "update": {
21 | "message": "檢查更新"
22 | },
23 | "updating": {
24 | "message": "下載規則定義"
25 | },
26 | "updateYes": {
27 | "message": "成功更新注入腳本!"
28 | },
29 | "updateNo": {
30 | "message": "繞過規則定義已是最新版本。"
31 | },
32 | "faq": {
33 | "message": "常見問答 (FAQ)"
34 | },
35 | "bypassCounter": {
36 | "message": "FastForward 已幫您繞過$1個網站。"
37 | },
38 | "support": {
39 | "message": "幫助 FastForward"
40 | },
41 | "options": {
42 | "message": "選項"
43 | },
44 | "optionsLink": {
45 | "message": "設定 FastForward 的選項"
46 | },
47 | "optionsEnabled": {
48 | "message": "啟用網站繞過功能"
49 | },
50 | "optionsNavigationDelay": {
51 | "message": "在$1秒後轉移到目標連結。 (輸入0可以瞬間轉移)"
52 | },
53 | "optionsTrackerBypass": {
54 | "message": "繞過使用Apimon.de的追踪器(比如bit.ly和t.co)。"
55 | },
56 | "optionsInstantNavigationTrackers": {
57 | "message": "跳過追蹤紀錄器,直接帶我到目的地。"
58 | },
59 | "optionsBlockIPLoggers": {
60 | "message": "若實在無法繞過,直接禁止瀏覽器訪問IP記錄網站。"
61 | },
62 | "optionsCrowdBypass": {
63 | "message": "對於無法繞過的短連結,直接帶我到短連結頁面。"
64 | },
65 | "optionsCrowdAutoOpen": {
66 | "message": "在$1秒後轉移到用戶提供的連結。 (0=立刻轉移)"
67 | },
68 | "optionsCrowdAutoClose": {
69 | "message": "訪問人們分享的目的網址$1秒後將其標籤頁關閉。"
70 | },
71 | "privacyPolicy": {
72 | "message": "隱私權政策"
73 | },
74 | "contributors": {
75 | "message": "貢獻者"
76 | },
77 | "optionsUserscripts": {
78 | "message": "自定義繞過規則"
79 | },
80 | "optionsUserscriptsDescription": {
81 | "message": "這是讓開發者自己編寫程式繞過網站的進階功能。當修改至功能完好後,可以提交到 Github,以新增至 FastForward 讓大家使用。"
82 | },
83 | "beforeNavigate": {
84 | "message": "您與目的地觸手可及。"
85 | },
86 | "beforeNavigateDestination": {
87 | "message": "您的目的地是 $1"
88 | },
89 | "beforeNavigateUnsafe": {
90 | "message": "但若您馬上跳轉,他們將會檢測到FastForward。"
91 | },
92 | "beforeNavigateUnsafeTimer": {
93 | "message": "$1秒後,您將不再被檢測到。"
94 | },
95 | "beforeNavigateUnsafeTimerSingular": {
96 | "message": "1秒後,您將不再被檢測到。"
97 | },
98 | "beforeNavigateTimer": {
99 | "message": "您將在$1秒後被重新導向。"
100 | },
101 | "beforeNavigateTimerSingular": {
102 | "message": "您將在1秒後被自動重新導向"
103 | },
104 | "beforeNavigateOptions": {
105 | "message": "您希望立刻或是x秒後被重新導向嗎?"
106 | },
107 | "beforeNavigateInstant": {
108 | "message": "您正在導航到$1"
109 | },
110 | "infoLinkvertise": {
111 | "message": "我們不受允許直接繞過這個網頁,不過我們已通過談判能夠移除這個網頁最麻煩的步驟了。"
112 | },
113 | "infoFileHoster": {
114 | "message": "很不幸,下載伺服器需要確保您在下載檔案前已等候"
115 | },
116 | "infoOutdated": {
117 | "message": "此網站被更新版本的 FastForward 繞過了。"
118 | },
119 | "crowdWait": {
120 | "message": "很遺憾地,您是第一個遇到這個連結的人,但在您等候了以後,其他 FastForward 的用戶就不用受苦了。"
121 | },
122 | "crowdDisabled": {
123 | "message": "這個網站是以用戶提供的連結繞過,而此功能已被您在設定中關閉。"
124 | },
125 | "crowdBypassed": {
126 | "message": "或許您可以不用再等待了。"
127 | },
128 | "crowdBypassedInfo": {
129 | "message": "其他的 FastForward 用戶已經替您省下寶貴的時間,並回報該短連結重導向 $1"
130 | },
131 | "crowdBypassedTimer": {
132 | "message": "將在$1秒後以新分頁開啟。"
133 | },
134 | "crowdBypassedTimerSingular": {
135 | "message": "將在1秒後以新分頁開啟。"
136 | },
137 | "crowdCloseTimer": {
138 | "message": "此分頁會在$1秒後關閉"
139 | },
140 | "crowdCloseTimerSingular": {
141 | "message": "此分頁會在1秒後關閉"
142 | },
143 | "cancel": {
144 | "message": "取消"
145 | },
146 | "crowdBypassedIgnore": {
147 | "message": "該資訊有誤嗎?"
148 | },
149 | "crowdBypassedOptions": {
150 | "message": "您希望立刻或是幾秒後以新分頁開啟嗎?"
151 | },
152 | "blockedTitle": {
153 | "message": "FastForward 防止您的IP被記錄。"
154 | },
155 | "blockedSubtitle": {
156 | "message": "不希望FastForward自動防止不法者獲取您的IP嗎?"
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/src/bypasses/1link.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class ONELink extends BypassDefinition {
4 | constructor() {
5 | super()
6 | this.ensure_dom = true
7 | }
8 |
9 | execute() {
10 | this.helpers.safelyNavigate(document.querySelector('a#download').href);
11 | }
12 | }
13 |
14 | export const matches = ['1link.club']
--------------------------------------------------------------------------------
/src/bypasses/1shortlink.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class ONEShortlink extends BypassDefinition {
4 | constructor() {
5 | super()
6 | this.ensure_dom = true
7 | }
8 |
9 | execute() {
10 | this.helpers.awaitElement('#redirect-link', e => {
11 | this.helpers.safelyNavigate(e.href);
12 | })
13 | }
14 | }
15 |
16 | export const matches = ['1shortlink.com']
--------------------------------------------------------------------------------
/src/bypasses/BypassDefinition.js:
--------------------------------------------------------------------------------
1 | const IMPLEMENTATION_ERROR = function_name => {
2 | throw new Error(`${function_name} must be implemented`)
3 | }
4 |
5 | export default class BypassDefinition {
6 | constructor() {
7 | this.ensure_dom = false
8 | }
9 |
10 | set_helpers(helpers) {
11 | this.helpers = helpers
12 | }
13 |
14 | execute() {
15 | IMPLEMENTATION_ERROR()
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/bypasses/acortalink.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Acortalink extends BypassDefinition {
4 | constructor() {
5 | super()
6 | this.ensure_dom = true
7 | }
8 |
9 | execute() {
10 | function rot13(str) {
11 | const input = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
12 | const output = 'NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm';
13 | let index = x => input.indexOf(x);
14 | let translate = x => index(x) > -1 ? output[index(x)] : x;
15 | return str.split('').map(translate).join('');
16 | }
17 | // Triggered on example.com and subdomains (e.g. www.example.com)
18 | this.helpers.ensureDomLoaded(() => {
19 | // Triggered as soon as the DOM is ready
20 | window.open = (linkacorta) => {
21 | this.helpers.safelyNavigate(rot13(atob(linkacorta.substring(30))));
22 | };
23 | GetLink();
24 | })
25 | }
26 | }
27 |
28 | export const matches = ['acortalink.me']
29 |
--------------------------------------------------------------------------------
/src/bypasses/admaven.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Admaven extends BypassDefinition {
4 | constructor() {
5 | super()
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | //Execute only if the regex matches /.*\/s\?[A-Za-z]{3}/
11 | if (window.location.pathname.match(/.*\/s\?[A-Za-z0-9]{3}/)) {
12 | this.helpers.safelyNavigate(document.scripts[0].textContent.split("link: '")[1].split("'")[0])
13 | }
14 | }
15 | }
16 |
17 | export const matches = ["mega-guy.com", "ofpacksmega.com", "depravityweb.co", "secretpack-links.com", "secret-links.com", "tavernleaks.com", "free-leaks.com", "hotstars-leaks.com", "thepremium.online", "admiregirls-byme.com", "all-fans.online", "pnp-drops.me", "megadropz.com", "goldmega.online", "badgirlsdrop.com", "rareofhub.com", "only-fun.xyz", "megadumpz.com", "leakutopia.site", "xprmpacks.com", "onlymega.co", "tomxcontent.com", "newsociety0.co", "cemendemons.com", "fansmega.com", "premiumstashdrop.com"]
18 |
--------------------------------------------------------------------------------
/src/bypasses/adtival.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Adtival extends BypassDefinition {
4 | constructor() {
5 | super();
6 | this.ensure_dom = true;
7 | }
8 |
9 | execute() {
10 | console.log('Adtival found!');
11 |
12 | const executor = async () => {
13 | const El = window.livewire.components.components()[0];
14 |
15 | const payload = {
16 | fingerprint: El.fingerprint,
17 | serverMemo: El.serverMemo,
18 | updates: [
19 | {
20 | payload: {
21 | event: 'getData',
22 | id: 'whathappen',
23 | params: [],
24 | },
25 | type: 'fireEvent',
26 | },
27 | ],
28 | };
29 |
30 | const response = await fetch(
31 | location.origin + '/livewire/message/pages.show',
32 | {
33 | headers: {
34 | 'Content-Type': 'application/json',
35 | 'X-Livewire': 'true',
36 | 'X-CSRF-TOKEN': window.livewire_token,
37 | },
38 | method: 'POST',
39 | body: JSON.stringify(payload),
40 | }
41 | );
42 |
43 | const json = await response.json();
44 |
45 | // ensure URL
46 | const url = new URL(json.effects.emits[0].params[0]);
47 |
48 | this.helpers.safelyAssign(url.href);
49 | // this.helpers.unsafelyNavigate(url.href, location.href)
50 | };
51 |
52 | // special case for sekilastekno. modbaca(?)
53 | if (RegExp(/(modebaca|sekilastekno)\.com/).exec(location.host)) {
54 | this.helpers.ifElement("form[method='post']", (a) => {
55 | console.log('addRecord...');
56 |
57 | const input = document.createElement('input');
58 | input.value = window.livewire_token;
59 | input.name = '_token';
60 | input.hidden = true;
61 | a.appendChild(input);
62 | a.submit();
63 | });
64 |
65 | // ...same step as miuiku and vebma
66 | this.helpers.ifElement('button[x-text]', async () => {
67 | console.log('getLink..');
68 | executor();
69 | });
70 |
71 | return;
72 | }
73 |
74 | // adtival getLink on miuiku
75 | this.helpers.ifElement("div[class='max-w-5xl mx-auto']", async () => {
76 | console.log('Executing..');
77 | executor();
78 | });
79 |
80 | // adtival b64UrlLastPage
81 | this.helpers.ifElement("button[id='copyVideoURL']", () => {
82 | const shortID = new URLSearchParams(window.location.search).get(
83 | 'shortid'
84 | );
85 |
86 | this.helpers.safelyAssign(atob(shortID));
87 | });
88 | }
89 | }
90 |
91 | export const matches = [
92 | /movienear\.me|lewat\.club|tautan\.pro|(droidtamvan|gubukbisnis|onlinecorp)\.me|(liveshootv|modebaca|haipedia|sekilastekno|miuiku|vebma)\.com|shrink\.world|link\.mymastah\.xyz|(sportif|cararoot)\.id|healthinsider\.online/,
93 | 'www.adtival.network',
94 | ];
95 |
--------------------------------------------------------------------------------
/src/bypasses/akoam.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Akoam extends BypassDefinition {
4 | constructor() {
5 | super()
6 | }
7 |
8 | execute() {
9 | this.helpers.ODP(window, 'timer', {
10 | value: 0,
11 | writable: false
12 | })
13 | this.helpers.awaitElement('.download_button[href]', a => {
14 | this.helpers.safelyNavigate(a.href)
15 | })
16 | }
17 | }
18 |
19 | export const matches = ['akoam.to']
20 |
--------------------------------------------------------------------------------
/src/bypasses/akwam.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Akwam extends BypassDefinition {
4 | constructor() {
5 | super()
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | window.setInterval = f => setInterval(f, 1)
11 | this.helpers.awaitElement("a.download_button[href]", a => {this.helpers.safelyNavigate(a.href)})
12 | }
13 | }
14 |
15 | export const matches = ['akwam.org', 'akw.to']
16 |
--------------------------------------------------------------------------------
/src/bypasses/an1.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class An1 extends BypassDefinition {
4 | constructor() {
5 | super()
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | window.setTimeout = f => setTimeout(f, 1)
11 | this.helpers.awaitElement("#waiting > a", a => a.click())
12 | }
13 | }
14 |
15 | export const matches = ['an1.com']
16 |
--------------------------------------------------------------------------------
/src/bypasses/androidtop.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Androidtop extends BypassDefinition {
4 | constructor() {
5 | super();
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | // If the variable downloadTimer is defined, then use clearInterval to stop the timer.
11 | document.querySelector('.counterhide').setAttribute('style', 'opacity: 0; visibility: hidden; height: 0px;');
12 | document.querySelector('.download-result').setAttribute('style', 'opacity: 1; visibility: visible;');
13 | }
14 | }
15 |
16 | export const matches = ['androidtop.net'];
17 |
--------------------------------------------------------------------------------
/src/bypasses/anonym.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Anonym extends BypassDefinition {
4 | constructor() {
5 | super()
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | this.helpers.ensureDomLoaded(() => {
11 | const a = window.location.href.split('/').slice(-1)[0]
12 | this.helpers.safelyNavigate(`https://anonym.ninja/download/file/request/${a}`)
13 | })
14 | }
15 | }
16 |
17 | export const matches = ['anonym.ninja']
18 |
--------------------------------------------------------------------------------
/src/bypasses/apkhubs.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Apkhubs extends BypassDefinition {
4 | constructor() {
5 | super();
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | this.helpers.ifElement("a#downloadbtn", a => {
11 | this.helpers.safelyNavigate(a.href)
12 | })
13 | }
14 | }
15 |
16 | export const matches = ['apkhubs.com'];
17 |
--------------------------------------------------------------------------------
/src/bypasses/blitly.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Blitly extends BypassDefinition {
4 | constructor() {
5 | super()
6 | }
7 |
8 | execute() {
9 | const target_url = new URLSearchParams(window.location.search).get('url')
10 | this.helpers.safelyNavigate(target_url)
11 | }
12 | }
13 |
14 | export const matches = ['blitly.io']
15 |
--------------------------------------------------------------------------------
/src/bypasses/blogtech.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class BlogTechh extends BypassDefinition {
4 | constructor() {
5 | super();
6 | }
7 |
8 | execute() {
9 | this.helpers.awaitElement("button#getlink", button => {
10 | button.click()
11 | })
12 | }
13 | }
14 |
15 | export const matches = ['blogtechh.com', 'oko.sh'];
16 |
--------------------------------------------------------------------------------
/src/bypasses/bluemediafile.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Bluemediafile extends BypassDefinition {
4 | constructor() {
5 | super();
6 | this.ensure_dom = true;
7 | }
8 |
9 | execute() {
10 | if (location.href.match(/\/url-generator(-\d+)?\.php\?url=/) === null)
11 | return;
12 |
13 | window.Time_Start -= 5000;
14 | window.i = 0;
15 | this.helpers.awaitElement('input#nut[src]', (i) => i.parentNode.submit());
16 | }
17 | }
18 |
19 | export const matches = [
20 | 'bluemediafiles.com',
21 | 'bluemediafile.sbs',
22 | 'bluemediafile.site',
23 | ];
24 |
--------------------------------------------------------------------------------
/src/bypasses/boost.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Boost extends BypassDefinition {
4 | constructor() {
5 | super()
6 | }
7 |
8 | execute() {
9 | // Based off of bloggerpemula's bypass: https://greasyfork.org/en/scripts/431691-bypass-all-shortlinks/code
10 | fetch(location.href).then(bo => bo.text()).then(html => this.helpers.safelyNavigate(atob(html.split('bufpsvdhmjybvgfncqfa="')[1].split('"')[0])))
11 | }
12 | }
13 |
14 | export const matches = ['boost.ink']
15 |
--------------------------------------------------------------------------------
/src/bypasses/brpaper.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Brpaper extends BypassDefinition {
4 | constructor() {
5 | super()
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | this.helpers.ensureDomLoaded(() => {
11 | const loc = location.href.replace("downloads", "downloader")
12 | this.helpers.safelyNavigate(loc)
13 | })
14 | }
15 | }
16 |
17 | export const matches = ['brpaper.com']
18 |
--------------------------------------------------------------------------------
/src/bypasses/bstlar.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Bstlar extends BypassDefinition {
4 | constructor() {
5 | super();
6 | }
7 |
8 | execute() {
9 | this.helpers.bypassRequests(async data => {
10 | if (data.currentTarget?.responseText?.includes('tasks')) {
11 | const response = JSON.parse(data.currentTarget.responseText);
12 | const userAgent = navigator.userAgent;
13 | const XSRF_TOKEN = this.getCookie('XSRF-TOKEN');
14 | const boostellar_session = this.getCookie('boostellar_session')
15 | const PfufeQwMeP6og9Poi7DmjbGJCcYhyXKQhlPnQ4Ud = this.getCookie('PfufeQwMeP6og9Poi7DmjbGJCcYhyXKQhlPnQ4Ud')
16 | const cf_clearance = this.getCookie('cf_clearance')
17 | const task_request = await fetch('https://bstlar.com/api/link-completed', {
18 | method: 'POST',
19 | headers: {
20 | accept: 'application/json, text/plain, */*',
21 | authorization: 'null',
22 | cookie: `XSRF-TOKEN=${XSRF_TOKEN}; boostellar_session=${boostellar_session}; PfufeQwMeP6og9Poi7DmjbGJCcYhyXKQhlPnQ4Ud=${PfufeQwMeP6og9Poi7DmjbGJCcYhyXKQhlPnQ4Ud}; cf_clearance=${cf_clearance}`,
23 | origin: 'https://bstlar.com',
24 | pragma: 'no-cache',
25 | priority: 'u=1, i',
26 | referer: 'https://bstlar.com/hV/krampus',
27 | 'user-agent': userAgent,
28 | 'x-xsrf-token': XSRF_TOKEN,
29 | 'Content-Type': 'application/json'
30 | },
31 | body: JSON.stringify({
32 | link_id: response['link']['id']
33 | })
34 | })
35 | if (task_request.status !== 200) return;
36 | const task_response = await task_request.text();
37 | this.helpers.safelyNavigate(task_response)
38 | }
39 | });
40 | }
41 |
42 | getCookie(name) {
43 | let value = '; ' + document.cookie;
44 | let parts = value.split('; ' + name + '=');
45 | if (parts.length === 2) return parts.pop().split(';').shift();
46 | }
47 | }
48 |
49 | export const matches = ['bstlar.com'];
50 |
--------------------------------------------------------------------------------
/src/bypasses/cbrun.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Cbrun extends BypassDefinition {
4 | constructor() {
5 | super()
6 | }
7 | execute() {
8 | const a = document.querySelector('a.btn')
9 | if (a) {
10 | this.helpers.safelyNavigate(a.href)
11 | }
12 | }
13 | }
14 |
15 | export const matches = ['cb.run', 'cb.click']
16 |
--------------------------------------------------------------------------------
/src/bypasses/cheatsquad.js:
--------------------------------------------------------------------------------
1 |
2 | import BypassDefinition from './BypassDefinition.js'
3 |
4 | export default class Cheatsquad extends BypassDefinition {
5 | constructor() {
6 | super()
7 | // custom bypass required bases can be set here
8 | }
9 |
10 | execute() {
11 | this.helpers.ODP(window, "steps", {
12 | get: () => [true]
13 | })
14 | this.helpers.ODP(window, "youtube", {
15 | get: () => 1
16 | })
17 | this.helpers.ensureDomLoaded(() => document.querySelectorAll("div.loader").forEach(d => d.className = "check_loader"))
18 | }
19 | }
20 |
21 | export const matches = ['cheatsquad.gg']
22 |
--------------------------------------------------------------------------------
/src/bypasses/clictune.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Clictune extends BypassDefinition {
4 | constructor() {
5 | super()
6 | this.ensure_dom = true
7 | }
8 |
9 | execute() {
10 | seconde = 0;
11 | Compteur();
12 |
13 | this.helpers.awaitElement('#compteur2 a[href]', a => {
14 | this.helpers.safelyNavigate(new URL(a.href).searchParams.get("url"))
15 | })
16 | }
17 | }
18 |
19 | export const matches = ['www.dlink2.net', 'www.dlink2.com', 'www.clictune.com', 'www.dlink4.com']
20 |
--------------------------------------------------------------------------------
/src/bypasses/complete2unlock.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Complete2unlock extends BypassDefinition {
4 | constructor() {
5 | super()
6 | }
7 |
8 | execute() {
9 | const timer = setInterval(() => {
10 | const link_success_button = document.getElementById('link-success-button')
11 | if (!link_success_button) return
12 |
13 | const unlock_panels = document.querySelectorAll('.unlockpanel')
14 |
15 | if (0 === unlock_panels.length) return
16 |
17 | clearInterval(timer)
18 | // override the window open method, no more annoying popups
19 | window.open = () => { }
20 |
21 | unlock_panels.forEach(panel => panel.click())
22 |
23 | const is_button_enabled_timer = setInterval(() => {
24 | if (link_success_button.hasAttribute('disabled')) return
25 |
26 | clearInterval(is_button_enabled_timer)
27 | link_success_button.click()
28 | }, 100)
29 | }, 300)
30 |
31 | setInterval(() => clearInterval(timer), 30000)
32 | }
33 | }
34 |
35 | export const matches = ['complete2unlock.com']
36 |
--------------------------------------------------------------------------------
/src/bypasses/cpmlink.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Cpmlink extends BypassDefinition {
4 | constructor() {
5 | super()
6 | this.ensure_dom = true
7 | }
8 |
9 | execute() {
10 | this.helpers.ifElement('a#btn-main', a =>{
11 | this.helpers.crowdPath(location.pathname.substring(4))
12 | this.helpers.contributeAndNavigate(a.href)
13 | },() => this.helpers.crowdBypass())
14 | }
15 | }
16 |
17 | export const matches = ['cpmlink.net']
18 |
--------------------------------------------------------------------------------
/src/bypasses/crackedappsstore.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Crackedappsstore extends BypassDefinition {
4 | constructor() {
5 | super();
6 | this.ensure_dom = true
7 | }
8 |
9 | execute() {
10 | // Find the div with the class name "show_download_links" and remove the 'display: none' style
11 | const ulElement = document.querySelector('#list-downloadlinks');
12 | let href;
13 |
14 | if (ulElement) {
15 | const liElements = ulElement.querySelectorAll('li');
16 | if (liElements.length > 1) {
17 | href = liElements[1].querySelector('a').href;
18 | } else if (liElements.length === 1) {
19 | href = liElements[0].querySelector('a').href;
20 | }
21 | }
22 |
23 | this.helpers.safelyNavigate(href);
24 |
25 | // Find the ul with the id list-downloadlinks, find the li in it, and pull the link from the first a tag
26 | const link2 = document.querySelector('#list-downloadlinks li:first-child a');
27 | this.helpers.safelyNavigate(link2);
28 | }
29 | }
30 |
31 | export const matches = ['crackedappsstore.com'];
32 |
--------------------------------------------------------------------------------
/src/bypasses/curseforge.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Curseforge extends BypassDefinition {
4 | constructor() {
5 | super();
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | window.setInterval = f => setInterval(f, 100)
11 | }
12 | }
13 |
14 | export const matches = ['curseforge.com'];
15 |
--------------------------------------------------------------------------------
/src/bypasses/daominhha.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Daominhha extends BypassDefinition {
4 | constructor() {
5 | super()
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | let str = (new URL(location.href)).searchParams.get('url')
11 | str = str.split("").reverse().join("")
12 | str = str.replaceAll("-", "+")
13 | str = str.replaceAll(".", "/")
14 | str = str.replaceAll(",", "=")
15 | this.helpers.safelyAssign(atob(str))
16 | }
17 | }
18 |
19 | export const matches = ['daominhha.com/download']
20 |
--------------------------------------------------------------------------------
/src/bypasses/earnme.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Earnme extends BypassDefinition {
4 | constructor() {
5 | super()
6 | }
7 |
8 | execute() {
9 | this.helpers.awaitElement('#tp-snp2', a => {
10 | a.click()
11 | })
12 | }
13 | }
14 |
15 | export const matches = ['earnme.club', 'usanewstoday.club']
16 |
--------------------------------------------------------------------------------
/src/bypasses/enlacito.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Enlacito extends BypassDefinition {
4 | constructor() {
5 | super()
6 | this.ensure_dom = true
7 | }
8 |
9 | execute() {
10 | this.helpers.safelyNavigate(window.DYykkzwP)
11 | }
12 | }
13 |
14 | // This is a link protecor that I've seen in many domains, so this script probably works in many of them
15 | // If you find another domain that uses this script, please add it to the array below
16 | export const matches = ['enlacito.com']
17 |
--------------------------------------------------------------------------------
/src/bypasses/favpng.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Favpng extends BypassDefinition {
4 | constructor() {
5 | super();
6 | this.ensure_dom = true;
7 | }
8 |
9 | execute() {
10 | const scripts = document.getElementsByTagName('script');
11 | for (let i = 0; i < scripts.length; i++) {
12 | let script = scripts[i];
13 | if (script.textContent.includes('https://download.favpng.com/api_download.php?')) {
14 | let startIndex = script.textContent.indexOf('https://download.favpng.com/api_download.php?');
15 | let endIndex = script.textContent.indexOf('"', startIndex);
16 | this.helpers.safelyNavigate(script.textContent.substring(startIndex, endIndex));
17 | }
18 | }
19 | }
20 | }
21 |
22 | export const matches = ['favpng.com'];
23 |
--------------------------------------------------------------------------------
/src/bypasses/fclc.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Fclc extends BypassDefinition {
4 | constructor() {
5 | super()
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | this.helpers.ensureDomLoaded(() => {
11 | this.helpers.crowdBypass()
12 | })
13 | }
14 | }
15 |
16 | export const matches = ['fc-lc.com']
17 |
--------------------------------------------------------------------------------
/src/bypasses/filedm.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Filedm extends BypassDefinition {
4 | constructor() {
5 | super()
6 | }
7 |
8 | execute() {
9 | this.helpers.awaitElement('a#d1button', address => {
10 | this.helpers.safelyNavigate("http://cdn.directdl.xyz/getfile?id=" + address.href.split("_")[1])
11 | })
12 | }
13 | }
14 |
15 | export const matches = ['filedm.com']
16 |
--------------------------------------------------------------------------------
/src/bypasses/filefactory.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Filefactory extends BypassDefinition {
4 | constructor() {
5 | super();
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | this.helpers.insertInfoBox("Unfortunately, the download server will ensure that you have waited before allowing you to download the file.")
11 | }
12 | }
13 |
14 | export const matches = ['https://filefactory.com', 'https://file-upload.com', 'https://asdfiles.com', 'https://mega4up.com', ' https://up-load.io', 'https://cosmobox.org', 'https://devdrive.cloud'];
15 |
--------------------------------------------------------------------------------
/src/bypasses/filehorse.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Filehorse extends BypassDefinition {
4 | constructor() {
5 | super()
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | this.helpers.ensureDomLoaded(() => {
11 | this.helpers.ifElement("a#download_url[href]", addr => {
12 | if (typeof timerx == "number"){
13 | clearTimeout(timerx)
14 | }
15 | this.helpers.safelyAssign(addr.href)
16 | })
17 | })
18 | }
19 | }
20 |
21 | export const matches = ['filehorse.com']
22 |
--------------------------------------------------------------------------------
/src/bypasses/filepuma.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Filepuma extends BypassDefinition {
4 | constructor() {
5 | super();
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | // Find the last script in the page
11 | let scripts = document.getElementsByTagName('script');
12 | let lastScript = scripts[scripts.length - 1];
13 | // Get the script's source
14 | let scriptSrc = lastScript.innerHTML;
15 | // Find the first location.href in the script and get the value of location.href
16 | let url = scriptSrc.split('location.href = "')[1].split('"')[0];
17 | alert(url)
18 |
19 | }
20 | }
21 |
22 | export const matches = ['filepuma.com'];
23 |
--------------------------------------------------------------------------------
/src/bypasses/firefaucet.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Firefaucet extends BypassDefinition {
4 | constructor() {
5 | super();
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | window.setInterval = f => setInterval(f, 1);
11 |
12 | }
13 | }
14 |
15 | export const matches = ['firefaucet.win', 'sfirmware.com', 'emulator.games'];
16 |
--------------------------------------------------------------------------------
/src/bypasses/fiveplay.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Fiveplay extends BypassDefinition {
4 | constructor() {
5 | super();
6 | }
7 |
8 | execute() {
9 | // Find the div with the class "download_btn", find the a tag within the div, and return the href attribute
10 | let downloadBtnGroup = document.querySelector('.download-btn-group');
11 | if (downloadBtnGroup) {
12 | let anchorElement = downloadBtnGroup.querySelector('a');
13 | if (anchorElement) {
14 | this.helpers.safelyAssign(anchorElement.getAttribute('href'));
15 | }
16 | }
17 | }
18 | }
19 |
20 | export const matches = ['5play.ru'];
21 |
--------------------------------------------------------------------------------
/src/bypasses/forex1pro.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Forex1pro extends BypassDefinition {
4 | constructor() {
5 | super()
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | this.helpers.ensureDomLoaded(() => {
11 | this.helpers.safelyAssign(`https://fx4vip.com${location.pathname}`)
12 | })
13 | }
14 | }
15 |
16 | export const matches = ['forex1pro.com']
17 |
--------------------------------------------------------------------------------
/src/bypasses/fourshared.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Fourshared extends BypassDefinition {
4 | constructor() {
5 | super()
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | if (document.cookie.indexOf("exUserId=") === -1){
11 | document.cookie = "exUserId=0; domain=.4shared.com; path=/"
12 | }
13 | }
14 | }
15 |
16 | export const matches = ['4shared.com']
17 |
--------------------------------------------------------------------------------
/src/bypasses/fssquad.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Fssquad extends BypassDefinition {
4 | constructor() {
5 | super()
6 | this.ensure_dom = true
7 | }
8 |
9 | execute() {
10 | this.helpers.ifElement("div#wpsafe-link", d => {
11 | this.helpers.safelyNavigate(d.getElementsByTagName("a")[0].onclick())
12 | })
13 | }
14 | }
15 |
16 | export const matches = ['fssquad.com']
17 |
--------------------------------------------------------------------------------
/src/bypasses/gamesmega.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Gamesmega extends BypassDefinition {
4 | constructor() {
5 | super()
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | this.helpers.ODP(window, "hash", {
11 | get: () => "",
12 | set: _ => this.helpers.safelyNavigate(decodeURIComponent(atob(_)))
13 | })
14 | }
15 | }
16 |
17 | export const matches = ['gamesmega.net']
18 |
--------------------------------------------------------------------------------
/src/bypasses/get2clickblogspot.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Get2clickblogspot extends BypassDefinition {
4 | constructor() {
5 | super();
6 | }
7 |
8 | execute() {
9 | // Find the div with the class "hidden btn waves-effect waves-light blue darken-2 white-text" and change it to "btn waves-effect waves-light blue darken-2 white-text"
10 | document.querySelector('.hidden.btn.waves-effect.waves-light.blue.darken-2.white-text').className = 'btn.waves-effect.waves-light.blue.darken-2.white-text';
11 |
12 | //Find the div with the class btn blue darken-2 waves-effect waves-light white-text hidden and make it btn blue darken-2 waves-effect waves-light white-text
13 | document.querySelector('.btn.blue.darken-2.waves-effect.waves-light.white-text.hidden').className = 'btn.blue.darken-2.waves-effect.waves-light.white-text';
14 | //Remove the disabled attribute from the div element above
15 | document.querySelector('.btn.blue.darken-2.waves-effect.waves-light.white-text').removeAttribute('disabled');
16 | //Wait until the page is changed
17 | window.addEventListener('load', () => {
18 | //The url will look like this https://get-click2.blogspot.com/2019/01/0xc60f.live?m=1
19 | //return the part of the url that is after the date, in this case it is 0xc60f.live?m=1
20 | let url = location.href.replace(/.*\/\d+\/(.*)/, '$1');
21 | this.helpers.safelyNavigate(url);
22 | });
23 | }
24 | }
25 |
26 | export const matches = ['get-click2.blogspot.com/'];
27 |
--------------------------------------------------------------------------------
/src/bypasses/getwallpapers.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Getwallpapers extends BypassDefinition {
4 | constructor() {
5 | super();
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | window.setInterval = f => setInterval(f, 1)
11 | }
12 | }
13 |
14 | export const matches = ['getwallpapers.com', 'https://sammobile.com', "https://ydfile.com", "https://mobilemodsapk.com", "https://dlandroid.com", "https://download.modsofapk.com", "https://zedge.net ", "https://fex.net", "https://k2s.cc", " https://u.to"];
15 |
--------------------------------------------------------------------------------
/src/bypasses/gixen.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Gixen extends BypassDefinition {
4 | constructor() {
5 | super()
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | const sid = document.cookie.match(/sessionid=(\d+)/)[1]
11 | if (sid){
12 | let f = document.createElement('form')
13 | f.method = 'POST'
14 | f.action = "home_2.php?sessionid=" + sid
15 | f.innerHTML = ' '
16 | document.documentElement.appendChild(f)
17 | this.helpers.countIt(() => f.submit())
18 | }
19 | }
20 | }
21 |
22 | export const matches = ['gixen.com/home_1.php']
23 |
--------------------------------------------------------------------------------
/src/bypasses/idnation.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Idnation extends BypassDefinition {
4 | constructor() {
5 | super();
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | this.helpers.ifElement("#linko[href]", b => this.helpers.safelyNavigate(b.href))
11 | }
12 | }
13 |
14 | export const matches = ['idnation.net'];
15 |
--------------------------------------------------------------------------------
/src/bypasses/indishare.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Indishare extends BypassDefinition {
4 | constructor() {
5 | super();
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | window.setTimeout = f => setTimeout(f, 1)
11 | }
12 | }
13 |
14 | export const matches = ['indishare.org', 'solvetube.site'];
15 |
--------------------------------------------------------------------------------
/src/bypasses/leitup.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Leitup extends BypassDefinition {
4 | constructor() {
5 | super()
6 | this.ensure_dom = true
7 | }
8 |
9 | execute() {
10 | this.helpers.ifElement('input.form-control[type="text"]', (input) => {
11 | let destination = input.attributes.placeholder.value
12 | this.helpers.safelyNavigate(destination)
13 | })
14 | }
15 | }
16 |
17 | export const matches = ['leitup.com']
18 |
--------------------------------------------------------------------------------
/src/bypasses/letsboost.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Letsboost extends BypassDefinition {
4 | constructor() {
5 | super();
6 | this.ensure_dom = true;
7 | }
8 |
9 | execute() {
10 | alert("FastForward: If nothing happens in a few seconds, the bypass couldn't be executed. Please disable your ad blocker and refresh the page. Press OK to continue.");
11 | this.helpers.insertInfoBox("If nothing happens in a few seconds, the bypass couldn't be executed. Please disable your ad blocker and refresh the page.");
12 | this.helpers.awaitElement("script:last-of-type:not([src])", () => {
13 | const lastScript = document.getElementsByTagName('script')[document.getElementsByTagName('script').length - 1];
14 | const scriptContent = lastScript.innerHTML;
15 | const jsonDat = JSON.parse(scriptContent.match(/stepDat = '(.*)';/)[1]);
16 | const url = jsonDat[jsonDat.length-1]["url"];
17 | this.helpers.safelyNavigate(url);
18 | });
19 | }
20 | }
21 |
22 |
23 | export const matches = ['letsboost.net'];
--------------------------------------------------------------------------------
/src/bypasses/liblink.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Liblink extends BypassDefinition {
4 | constructor() {
5 | super()
6 | this.ensure_dom = true
7 | }
8 |
9 | execute() {
10 | this.helpers.ifElement("body > div > h1 > span", addr => {
11 | this.helpers.safelyNavigate(addr.innerHTML)
12 | })
13 | }
14 | }
15 |
16 | export const matches = ['liblink.pl']
17 |
--------------------------------------------------------------------------------
/src/bypasses/linegee.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Linegee extends BypassDefinition {
4 | constructor() {
5 | super();
6 | }
7 |
8 | execute() {
9 | const continueLink = Array.from(document.getElementsByTagName('a')).find(a => a.textContent.trim() === 'Continue');
10 | const href = continueLink.getAttribute('href');
11 | this.helpers.safelyNavigate(href);
12 |
13 |
14 | }
15 | }
16 |
17 | export const matches = ['linegee.net'];
18 |
--------------------------------------------------------------------------------
/src/bypasses/linksht.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Linksht extends BypassDefinition {
4 | constructor() {
5 | super()
6 | this.ensure_dom = true
7 | }
8 |
9 | execute() {
10 | const getUrl = document.URL;
11 | const urlSplit = getUrl.split("/");
12 | $.post("/Links/Getlink", {id: urlSplit[urlSplit.length - 1]}, function (destination) {
13 | if(destination!="") {
14 | location.assign(destination);
15 | }
16 | });
17 | }
18 | }
19 |
20 | export const matches = ['linksht.com']
--------------------------------------------------------------------------------
/src/bypasses/linkspy.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Linkspy extends BypassDefinition {
4 | constructor() {
5 | super()
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | const url = document.getElementsByClassName("skipButton")[0].getAttribute("href")
11 | this.helpers.safelyNavigate(url)
12 | }
13 | }
14 |
15 | export const matches = ['linkspy.cc']
16 |
--------------------------------------------------------------------------------
/src/bypasses/lkc21.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Lkc21 extends BypassDefinition {
4 | constructor() {
5 | super();
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | window.setTimeout = f => setTimeout(f, 100)
11 | }
12 | }
13 |
14 | export const matches = ['lkc21.net'];
15 |
--------------------------------------------------------------------------------
/src/bypasses/lnk.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Lnk extends BypassDefinition {
4 | constructor() {
5 | super();
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | if (!window.location.href.includes('/go/')) {
11 | //Insert /go/ inbetween the domain and the rest of the url
12 | this.helpers.safelyNavigate(window.location.href.replace(/(https?:\/\/[^/]+)(\/.*)/, '$1/go$2'));
13 | }
14 | document.getElementById('get_link_btn').click();
15 | }
16 | }
17 |
18 | export const matches = ['lnk.parts', 'icerik.site'];
19 |
20 |
--------------------------------------------------------------------------------
/src/bypasses/lnk2.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Lnk2 extends BypassDefinition {
4 | constructor() {
5 | super();
6 | this.ensure_dom = true;
7 | }
8 |
9 | execute() {
10 | //If the url doesn't contain /go/, use the insertInfoBox
11 | if (window.location.href.includes('/go/')) {
12 | document.getElementById('getLink').removeAttribute('disabled');
13 | document.getElementById('getLink').click();
14 | } else {
15 | this.helpers.insertInfoBox('Please complete the captcha, then we can bypass you');
16 | }
17 | }
18 | }
19 |
20 | export const matches = ['lnk2.cc'];
21 |
--------------------------------------------------------------------------------
/src/bypasses/lnk2cc.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Lnk2cc extends BypassDefinition {
4 | constructor() {
5 | super()
6 | this.ensure_dom = true
7 | }
8 |
9 | execute() {
10 | //Replace substr(0,4) with substring
11 |
12 | if (location.pathname.substring(0,5) === "/go/"){
13 | document.querySelector("form").submit()
14 | }
15 | else{
16 | this.helpers.crowdBypass()
17 | }
18 | }
19 | }
20 |
21 | export const matches = ['lnk2.cc']
22 |
--------------------------------------------------------------------------------
/src/bypasses/longfiles.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Longfiles extends BypassDefinition {
4 | constructor() {
5 | super()
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | window.setTimeout = f => this.helpers.setTimeout(f, 1)
11 | }
12 | }
13 |
14 | export const matches = ['longfiles.com', 'filepuma.com', 'portableapps.com', 'indishare.org', 'solvetube.site']
15 |
--------------------------------------------------------------------------------
/src/bypasses/lootlink.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class LootLink extends BypassDefinition {
4 | constructor() {
5 | super()
6 | this.ensure_dom = true
7 | }
8 |
9 | execute() {
10 | if (/[?&]r=/.test(window.location.href.toString())) { // https://loot-link.com/s?fJjn&r=
11 | const urlParams = new URLSearchParams(window.location.search)
12 | const r = urlParams.get('r')
13 | const finalURL = decodeURIComponent(escape(atob(r)))
14 | this.helpers.safelyNavigate(finalURL)
15 | } else { // https://loot-link.com/s?fJjn
16 | const originalFetch = window.fetch
17 | window.fetch = (url, config) => this.customFetch(url, config, originalFetch)
18 | }
19 | }
20 |
21 | customFetch(url, config, originalFetch) {
22 | if (url.includes(`${INCENTIVE_SYNCER_DOMAIN}/tc`)) {
23 | return originalFetch(url, config).then(response => {
24 | if (!response.ok) return response.json()
25 | return this.handleResponse(response)
26 | });
27 | }
28 | return originalFetch(url, config)
29 | }
30 |
31 | handleResponse(response) {
32 | return response.clone().json().then(data => {
33 | this.helpers.insertInfoBox(
34 | 'Please wait a moment while we search for the destination link.'
35 | );
36 | let urid = ""
37 | let action_pixel_url = ""
38 | data.forEach(item => {
39 | urid = item.urid
40 | action_pixel_url = item.action_pixel_url
41 | });
42 |
43 | const task_id = 54; // magic number
44 |
45 | this.setupWebSocket(urid, task_id)
46 | navigator.sendBeacon(`https://${urid.substr(-5) % 3}.${INCENTIVE_SERVER_DOMAIN}/st?uid=${urid}&cat=${task_id}`)
47 | fetch(`https://${INCENTIVE_SYNCER_DOMAIN}/td?ac=1&urid=${urid}&&cat=${task_id}&tid=${TID}`)
48 | fetch(action_pixel_url)
49 |
50 | return new Response(JSON.stringify(data), {
51 | status: response.status,
52 | statusText: response.statusText,
53 | headers: response.headers
54 | })
55 | })
56 | }
57 |
58 | setupWebSocket(urid, task_id) {
59 | const ws = new WebSocket(`wss://${urid.substr(-5) % 3}.${INCENTIVE_SERVER_DOMAIN}/c?uid=${urid}&cat=${task_id}&key=${KEY}`)
60 |
61 | ws.onopen = () => setInterval(() => ws.send('0'), 1000)
62 | ws.onmessage = event => {
63 | if (event.data.includes('r:')) {
64 | this.helpers.safelyNavigate(this.decryptData(event.data.replace('r:', '')))
65 | }
66 | }
67 | }
68 |
69 | decryptData(encodedData) {
70 | let final = ""
71 | let combinationLink = atob(encodedData)
72 | let key = combinationLink.substring(0, 5)
73 | let enc_link = combinationLink.substring(5)
74 | for (let i = 0; i < enc_link.length; i++) {
75 | let enc_char = enc_link.charCodeAt(i)
76 | let keyAtOffset = key.charCodeAt(i % key.length)
77 | let charcode = enc_char ^ keyAtOffset
78 | final += String.fromCharCode(charcode)
79 | }
80 |
81 | return final
82 | }
83 | }
84 |
85 | export const matches = ['lootlinks.co', 'loot-links.com', 'loot-link.com', "linksloot.net", "lootdest.com", "lootlink.org", "lootdest.info", "lootdest.org", "links-loot.com"]
86 |
--------------------------------------------------------------------------------
/src/bypasses/mangalist.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Mangalist extends BypassDefinition {
4 | constructor() {
5 | super()
6 | this.ensure_dom = true
7 | }
8 |
9 | execute() {
10 | this.helpers.awaitElement("#btt > button.btn.btn-primary.text-center[onclick^='window.location.assign(']", b => {
11 | let o = b.getAttribute('onclick')
12 | this.helpers.safelyNavigate(o.substring(24, o.length - 3))
13 | })
14 | }
15 | }
16 |
17 | export const matches = ['mangalist.org']
18 |
--------------------------------------------------------------------------------
/src/bypasses/manualsbooks.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Manualsbooks extends BypassDefinition {
4 | constructor() {
5 | super();
6 | }
7 |
8 | execute() {
9 | // Wait for 2 seconds
10 |
11 | newElement.parentNode.replaceChild(downloadButton, newElement), clearInterval(id);
12 | this.helpers.safelyNavigate(this.helpers.parseTarget(document.getElementById("download")))
13 |
14 | }
15 | }
16 |
17 | export const matches = ['manualsbooks.com']
18 |
--------------------------------------------------------------------------------
/src/bypasses/mobi2c.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Mobi2c extends BypassDefinition {
4 | constructor() {
5 | super()
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | // /mobi2c.com|newforex.online|healthy4pepole.com|world-trips.net|forex-gold.net|healdad.com|world2our.com|gamalk-sehetk.com|mobitaak.com|forexit.online|shopforex.online|bluetechno.net/, function() {ClickIfExists('.submitBtn', 3);ClickIfExists('#go_d', 3, 'setInterval');});
11 | //Click the element .submitBtn after a delay of 3 seconds
12 | this.helpers.setTimeout(() => {
13 | document.getElementsByClassName('.submitBtn')[0].click();
14 | }, 3000);
15 | //Click the element #go_d every 3 seconds until it is clicked
16 | this.helpers.setInterval(() => {
17 | document.getElementById('#go_d')[0].click();
18 | }, 3000);
19 | }
20 | }
21 |
22 | export const matches = ['mobi2c.com', 'newforex.online', 'healthy4pepole.com', 'world-trips.net', 'forex-gold.net', 'healdad.com', 'world2our.com', 'gamalk-sehetk.com', 'mobitaak.com', 'forexit.online', 'shopforex.online', 'bluetechno.net']
23 |
--------------------------------------------------------------------------------
/src/bypasses/mydramalist.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Mydramalist extends BypassDefinition {
4 | constructor () {
5 | super()
6 | }
7 |
8 | execute () {
9 | const search_params = location.search
10 | const decoded_search_params = decodeURIComponent(search_params)
11 | const full_url = decoded_search_params.replace('?q=', '')
12 | this.helpers.safelyNavigate(full_url)
13 | }
14 | }
15 |
16 | export const matches = ['mydramalist.com']
17 |
--------------------------------------------------------------------------------
/src/bypasses/oko.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Oko extends BypassDefinition {
4 | constructor() {
5 | super()
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | // todo: make execute function
11 | }
12 | }
13 |
14 | export const matches = ['oko.sh']
15 |
--------------------------------------------------------------------------------
/src/bypasses/onelink.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Onelink extends BypassDefinition {
4 | constructor() {
5 | super();
6 | this.ensure_dom = true;
7 | }
8 |
9 | execute() {
10 | window.setInterval = f => setInterval(f, 1);
11 | let b = document.getElementById('go_next');
12 | if (b && this.helpers.isGoodLink(b.href)) {
13 | this.helpers.safelyAssign(b.href);
14 | } else {
15 | this.helpers.ifElement('#download', b => this.helpers.safelyNavigate(b.href));
16 | }
17 | }
18 | }
19 |
20 | export const matches = ['1link.club'];
21 |
--------------------------------------------------------------------------------
/src/bypasses/onepieceex.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Onepieceex extends BypassDefinition {
4 | constructor() {
5 | super()
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | this.helpers.ensureDomLoaded(() => {
11 | this.helpers.ifElement("noscript", n => this.helpers.safelyNavigate(n.textContent))
12 | })
13 | }
14 | }
15 |
16 | export const matches = ['onepieceex.net']
17 |
--------------------------------------------------------------------------------
/src/bypasses/onlinefix.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Onelinefix extends BypassDefinition {
4 | constructor() {
5 | super()
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | window.setTimeout = f => setTimeout(f,1)
11 | this.helpers.awaitElement("#res > center > button.btn[onclick]", but => but.onclick())
12 | }
13 | }
14 |
15 | export const matches = ['online-fix.me/ext/']
16 |
--------------------------------------------------------------------------------
/src/bypasses/oracle.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Oracle extends BypassDefinition {
4 | constructor() {
5 | super()
6 | this.ensure_dom = true
7 | }
8 |
9 | execute() {
10 | document.querySelectorAll("[data-file]").forEach(e => {
11 | let link = e.getAttribute("data-file"),
12 | jre8 = RegExp("download.oracle.com/otn/java/jdk/8u([0-9]*)-b([0-9]*)/([a-z0-9]{32})/(.*)$", "g").exec(link)
13 | if (jre8 && jre8[3]){
14 | os_type = RegExp("8u[0-9]*-([^-]*)-").exec(jre8[4])[1]
15 | os_type = (os_type == "macosx") ? "unix" : os_type
16 | e.onclick = () => this.helpers.safelyNavigate("https://javadl.oracle.com/webapps/download/GetFile/1.8.0_" + jre8[1] + "-b" + jre8[2] + "/" + jre8[3] + "/" + os_type + "-i586/" + jre8[4])
17 | }
18 | })
19 | }
20 | }
21 |
22 | export const matches = ['oracle.com']
23 |
--------------------------------------------------------------------------------
/src/bypasses/ouo.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from "./BypassDefinition.js"
2 |
3 | export default class Ouo extends BypassDefinition {
4 | constructor() {
5 | super()
6 | }
7 | execute() {
8 | if (location.pathname !== '/') {
9 | if (/(go|fbc)/.test(location.pathname.split("/")[1])) {
10 | document.querySelector("form").submit()
11 | }
12 | else {
13 | if (document.querySelector("form#form-captcha")) {
14 | document.querySelector("form#form-captcha").action = `/xreallcygo${location.pathname}`
15 | document.querySelector("form#form-captcha").submit()
16 | }
17 | else {
18 | //this.helpers.crowdBypass()
19 | }
20 | }
21 | }
22 | }
23 | }
24 | export const matches = ['ouo.press', 'ouo.io']
25 |
--------------------------------------------------------------------------------
/src/bypasses/oxy.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Oxy extends BypassDefinition {
4 | constructor() {
5 | super()
6 | this.ensure_dom = true
7 | }
8 |
9 | execute() {
10 | this.helpers.ifElement("button#download[disabled]", d => {
11 | this.helpers.awaitElement("button#download:not([disabled])", d => {
12 | d.click()
13 | })
14 | })
15 | }
16 | }
17 |
18 | export const matches = ['oxy.cloud']
19 |
--------------------------------------------------------------------------------
/src/bypasses/pcgamestorrents.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Pcgamestorrents extends BypassDefinition {
4 | constructor() {
5 | super();
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | window.setInterval = f => setInterval(f, 1)
11 | this.helpers.transparentProperty("Time_Start", t => t - 5000)
12 | this.helpers.awaitElement("input#nut[src]", i => i.parentNode.submit())
13 |
14 | }
15 | }
16 |
17 | export const matches = ['dl.pcgamestorrents.org'];
18 |
--------------------------------------------------------------------------------
/src/bypasses/pirateproxy.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Pirateproxy extends BypassDefinition {
4 | constructor() {
5 | super()
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | let search = location.search.replace("?", "")
11 | if (search) {
12 | this.helpers.safelyNavigate(`https://${search}`)
13 | }
14 | }
15 | }
16 |
17 | export const matches = ['pirateproxy.wtf']
18 |
--------------------------------------------------------------------------------
/src/bypasses/portableapps.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Portableapps extends BypassDefinition {
4 | constructor() {
5 | super();
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | //Check if the url contains "/downloading"
11 | if (window.location.href.indexOf('/downloading') > -1) {
12 | let url = window.location.href;
13 | let urlSplit = url.split('&f=');
14 | let urlSplit2 = urlSplit[1].split('&');
15 | let finalUrl = "https://download2.portableapps.com/portableapps/PortableApps.comPlatform/" + urlSplit2
16 | //Open finalUrl in a new tab
17 | window.open(finalUrl, '_blank');
18 | }
19 | }
20 | }
21 |
22 | export const matches = ['portableapps.com'];
23 |
--------------------------------------------------------------------------------
/src/bypasses/ps4linux.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class PS4Linux extends BypassDefinition {
4 | constructor() {
5 | super()
6 | this.ensure_dom = true
7 | }
8 |
9 | execute() {
10 | const targetURL = document.querySelector('#skipaft > a:nth-child(1)')?.href
11 | if (targetURL) {
12 | this.helpers.safelyNavigate(targetURL)
13 | }
14 | }
15 | }
16 |
17 | export const matches = ['ps4linux.com']
18 |
--------------------------------------------------------------------------------
/src/bypasses/rekonise.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Rekonise extends BypassDefinition {
4 | constructor() {
5 | super()
6 | }
7 |
8 | execute() {
9 | let xhr = new XMLHttpRequest()
10 | xhr.onload = () => {
11 | let data = JSON.parse(xhr.responseText)
12 | this.helpers.safelyNavigate(data.url)
13 | }
14 | xhr.open(
15 | 'GET',
16 | `https://api.rekonise.com/social-unlocks${location.pathname}`,
17 | true
18 | )
19 | xhr.send()
20 | }
21 | }
22 | export const matches = ['rekonise.com']
23 |
--------------------------------------------------------------------------------
/src/bypasses/ryn.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Ryn extends BypassDefinition {
4 | constructor() {
5 | super();
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | if (typeof countdown == 'function') {
11 | document.write('');
12 | countdown();
13 | this.helpers.safelyNavigate(document.querySelector('#link > a').href);
14 | }
15 | }
16 | }
17 |
18 | export const matches = ['ryn.cc'];
19 |
--------------------------------------------------------------------------------
/src/bypasses/sfile.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Sfile extends BypassDefinition {
4 | constructor() {
5 | super()
6 | }
7 |
8 | execute() {
9 | this.helpers.ODP(window, 'downloadButton', {
10 | set: a => {
11 | if (a?.href) {
12 | this.helpers.safelyAssign(a.href)
13 | }
14 | }
15 | })
16 | }
17 | }
18 |
19 | export const matches = ['sfile.mobi', 'sfile.xyz', 'apkmos.com']
20 |
--------------------------------------------------------------------------------
/src/bypasses/shortenbuddy.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Shortenbuddy extends BypassDefinition {
4 | constructor () {
5 | super()
6 | }
7 | execute () {
8 | let url = location.href.replace('links.', '')
9 | this.helpers.safelyAssign(url)
10 | }
11 | }
12 |
13 | export const matches = ['links.shortenbuddy.com']
14 |
--------------------------------------------------------------------------------
/src/bypasses/shortly.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Shortly extends BypassDefinition {
4 | constructor() {
5 | super()
6 | }
7 |
8 | execute() {
9 | if (location.pathname.substr(0, 3) === "/r/") {
10 | document.getElementById = () => ({
11 | submit: () => {
12 | let f = document.querySelector("form")
13 | f.action = "/link#" + document.querySelector("input[name='id']").value
14 | f.submit()
15 | }
16 | })
17 | }
18 | else if (location.pathname === "/link") {
19 | let xhr = new XMLHttpRequest()
20 | xhr.onload = () => this.helpers.safelyNavigate(xhr.responseText)
21 | xhr.open("POST", "https://www.shortly.xyz/getlink.php", true)
22 | xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
23 | xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest")
24 | xhr.send("id=" + location.hash.substr(1))
25 | }
26 | }
27 | }
28 |
29 | export const matches = ['shortly.xyz']
30 |
--------------------------------------------------------------------------------
/src/bypasses/shortmoz.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Shortmoz extends BypassDefinition {
4 | constructor() {
5 | super()
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | window.setInterval = f => setTimeout(f,1)
11 | this.helpers.awaitElement("a.btn.redirect[href^='http']", a =>
12 | this.helpers.safelyNavigate(a.href))
13 | }
14 | }
15 |
16 | export const matches = ['shortmoz.link']
17 |
--------------------------------------------------------------------------------
/src/bypasses/softpedia.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Softpedia extends BypassDefinition {
4 | constructor() {
5 | super();
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | this.helpers.ifElement('meta[http-equiv=\'refresh\'][content]', m => {
11 | let c = m.content.replace('; url=', ';url=');
12 | if (c.indexOf(';url=') > -1) {
13 | this.helpers.safelyAssign(c.split(';url=')[1]);
14 | }
15 | });
16 | }
17 | }
18 |
19 | export const matches = ['softpedia.com'];
20 |
--------------------------------------------------------------------------------
/src/bypasses/sourceforge.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Sourceforge extends BypassDefinition {
4 | constructor() {
5 | super()
6 | }
7 |
8 | execute() {
9 | var button = document.createElement('button')
10 | var downloaded = false
11 | button.className = 'direct-download'
12 | button.style.display = 'none'
13 | document.documentElement.appendChild(button)
14 | this.helpers.ODP(window, 'log', {
15 | value: m => {
16 | console.log(m)
17 | if (m === 'triggering downloader:start') {
18 | downloaded = true
19 | }
20 | },
21 | writable: false
22 | })
23 | this.helpers.ensureDomLoaded(() => {
24 | let buttonTimer = setInterval(() => {
25 | if (downloaded) {
26 | button.click()
27 | clearInterval(buttonTimer)
28 | }
29 | }, 100)
30 | })
31 | }
32 | }
33 |
34 | export const matches = ['/sourceforge.net/projects/.+/files/.+/download/']
35 |
--------------------------------------------------------------------------------
/src/bypasses/spaste.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Spaste extends BypassDefinition {
4 | constructor() {
5 | super();
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | this.helpers.insertInfoBox('Please complete the captcha to continue');
11 | const doTheThing = f => setTimeout(() => {
12 | let item = document.querySelector('#currentCapQue').textContent;
13 | document.querySelectorAll('.markAnswer').forEach(as => {
14 | if (as.querySelector('img').getAttribute('src').toLowerCase().indexOf(item) > -1) {
15 | as.click();
16 | }
17 | });
18 | f();
19 | }, 200);
20 | document.querySelector('#captchaVerifiedStatus').click();
21 | doTheThing(() => doTheThing(() => doTheThing(() => document.querySelector('#template-contactform-submit').click())));
22 | }
23 | }
24 |
25 | export const matches = ['spaste.com/s', 'spaste.com/site'];
26 |
--------------------------------------------------------------------------------
/src/bypasses/squidssh.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Squidssh extends BypassDefinition {
4 | constructor() {
5 | super()
6 | this.ensure_dom = true
7 | }
8 |
9 | execute() {
10 | let p = atob((new URLSearchParams(location.search)).get('short'))
11 | crowdPath(p)
12 | crowdBypass(() => this.helpers.ifElement("form[action='/user/links']", f => f.action += "#" + p))
13 | }
14 | }
15 |
16 | export const matches = ['squidssh.com/li/go.php', 'goodssh.com/li/go.php']
17 |
--------------------------------------------------------------------------------
/src/bypasses/srtam.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Srtam extends BypassDefinition {
4 | constructor() {
5 | super()
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | this.helpers.ensureDomLoaded(() => {
11 | if (document.querySelector(".skip-container")) {
12 | let form = document.createElement("form")
13 | form.method = "POST"
14 | form.innerHTML = " "
15 | form = document.documentElement.appendChild(form)
16 | this.helpers.countIt(() => form.submit())
17 | }
18 | })
19 | }
20 | }
21 |
22 | export const matches = ['srt.am']
23 |
--------------------------------------------------------------------------------
/src/bypasses/sub2unlock.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Sub2unlock extends BypassDefinition {
4 | constructor() {
5 | super()
6 | this.ensure_dom = true
7 | }
8 |
9 | execute() {
10 | const url = document.URL;
11 | let destination;
12 |
13 | if(url.includes("sub2unlock.com/link/unlock")) {
14 | destination = document.getElementById("link").getAttribute("href");
15 | } else {
16 | const urlSplit = url.split("/");
17 | destination = 'https://sub2unlock.com/link/unlock/' + urlSplit[urlSplit.length - 1];
18 | }
19 |
20 | this.helpers.safelyNavigate(destination);
21 | }
22 | }
23 |
24 | export const matches = ['sub2unlock.com']
25 |
--------------------------------------------------------------------------------
/src/bypasses/sub4unlock.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Sub4unlock extends BypassDefinition {
4 | constructor() {
5 | super()
6 | this.ensure_dom = true
7 | }
8 |
9 | execute() {
10 | if (typeof fun2 == "function") {
11 | window.open = this.helpers.safelyNavigate
12 | fun2()
13 | }
14 | }
15 | }
16 |
17 | export const matches = ['sub4unlock.com']
18 |
--------------------------------------------------------------------------------
/src/bypasses/syosetu.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Syosetu extends BypassDefinition {
4 | constructor() {
5 | super()
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | const [, second] = document.URL.match(/.*syosetu\.org\/\?mode=url_jump&url=(.+)/);
11 | this.helpers.safelyNavigate(
12 | decodeURIComponent(second)
13 | )
14 | }
15 | }
16 |
17 | export const matches = ['syosetu.org']
18 |
--------------------------------------------------------------------------------
/src/bypasses/tii.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class TiiLa extends BypassDefinition {
4 | constructor() {
5 | super();
6 | this.ensure_dom = true;
7 | }
8 |
9 | execute() {
10 | const urlObj = new URL(window.location.href)
11 | this.helpers.crowdQuery('tii.la', urlObj.pathname.slice(1)).then((dest) => {
12 | this.helpers.crowdNavigate(dest)
13 | });
14 | /*keep checking for the button*/
15 | setInterval(() => {
16 | const button = document.querySelector("a.btn.btn-success.btn-lg.get-link");
17 | if (button && button.href) {
18 | this.helpers.crowdContribute('tii.la', urlObj.pathname.slice(1), button.href)
19 | this.helpers.safelyNavigate(button.href)
20 | }
21 | }, 500);
22 |
23 | }
24 | }
25 |
26 | export const matches = ['tii.la'];
27 |
--------------------------------------------------------------------------------
/src/bypasses/tiklat.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Tiklat extends BypassDefinition {
4 | constructor () {
5 | super()
6 | }
7 |
8 | execute () {
9 | window.setInterval = func => setInterval(func, 1)
10 | this.helpers.awaitElement('.skip > .wait > .skip > .btn > a[href]', a => {
11 | this.helpers.safelyNavigate(a.href)
12 | })
13 | }
14 | }
15 |
16 | export const matches = ['tik.lat']
17 |
--------------------------------------------------------------------------------
/src/bypasses/tlgd.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Tlgd extends BypassDefinition {
4 | constructor() {
5 | super();
6 | this.ensure_dom = true
7 | }
8 |
9 | execute() {
10 | this.helpers.safelyAssign("http://www.twitlonger.com/show" + location.pathname)
11 | }
12 | }
13 |
14 | export const matches = ['tl.gd'];
15 |
--------------------------------------------------------------------------------
/src/bypasses/uiz.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Uiz extends BypassDefinition {
4 | constructor() {
5 | super()
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | Object.freeze(location)
11 | this.helpers.ensureDomLoaded(() => {
12 | const regHere = /.*window\.location\.href = "(http[^"]+)";.*/
13 | document.querySelectorAll("script").forEach(script => {
14 | let match = regHere.exec(script.textContent)
15 | if (match && match[1]){
16 | this.helpers.crowdPath(bypassClipboard)
17 | this.helpers.contributeAndNavigate(match[1])
18 |
19 | }
20 | })
21 | })
22 | }
23 | }
24 |
25 | export const matches = ['uiz.io', 'uiz.app', 'tlkm.id']
26 |
--------------------------------------------------------------------------------
/src/bypasses/uploadking.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Uploadking extends BypassDefinition {
4 | constructor() {
5 | super();
6 | this.ensure_dom = true
7 | }
8 |
9 | execute() {
10 | this.helpers.ifElement("form[name='F1']", f => this.helpers.countIt(() => f.submit()))
11 | }
12 | }
13 |
14 | export const matches = ['uploadking.net'];
15 |
--------------------------------------------------------------------------------
/src/bypasses/uploadrar.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Uploadrar extends BypassDefinition {
4 | constructor() {
5 | super()
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | document.querySelector('.mngez-free-download').click();
11 | document.querySelector('#direct_link > a:nth-child(1)').click();
12 | document.querySelector('#downloadbtn.downloadbtn').click();
13 | }
14 | }
15 |
16 | export const matches = ['uploadrar.com', 'uploadrar.net', 'uptomega.me']
17 |
--------------------------------------------------------------------------------
/src/bypasses/ux9.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Ux9 extends BypassDefinition {
4 | constructor() {
5 | super();
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | this.helpers.safelyAssign(window.ux_secure.fullUrl);
11 | }
12 | }
13 |
14 | export const matches = ['ux9.de'];
15 |
--------------------------------------------------------------------------------
/src/bypasses/vk.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Vk extends BypassDefinition {
4 | constructor() {
5 | super()
6 | }
7 |
8 | execute() {
9 | this.helpers.safelyNavigate(decodeURIComponent(document.URL.match(/vk\.com\/away\.php\?to=([^&]+)/)[1]))
10 | }
11 | }
12 |
13 | export const matches = ['vk.com/away.php?to=']
14 |
--------------------------------------------------------------------------------
/src/bypasses/wadooo.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Wadooo extends BypassDefinition {
4 | constructor() {
5 | super()
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | this.helpers.crowdPath(location.hash.substring(1))
11 | this.helpers.crowdBypass()
12 | }
13 | }
14 |
15 | export const matches = ['wadooo.com']
16 |
--------------------------------------------------------------------------------
/src/bypasses/workclick.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js';
2 |
3 | export default class Workclick extends BypassDefinition {
4 | constructor() {
5 | super();
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | async execute() {
10 | const uuid = new URLSearchParams(window.location.search).get('t');
11 | this.helpers.insertInfoBox(
12 | 'You will need to wait for 10 seconds as the site is loading the destination URL. Please be patient.'
13 | );
14 | fetch(`https://redirect-api.work.ink/externalPopups/${uuid}/pageOpened`);
15 | await new Promise((r) => setTimeout(r, 11 * 1000));
16 | let { destination } = await fetch(
17 | `https://redirect-api.work.ink/externalPopups/${uuid}/destination`
18 | ).then((r) => r.json());
19 | const url = new URL(destination);
20 | if (url.searchParams.has('duf')) {
21 | const finalUrl = window.atob(
22 | url.searchParams.get('duf').split('').reverse().join('')
23 | );
24 | destination = finalUrl;
25 | }
26 | let path = await this.helpers.ffclipboard.get('workink');
27 | this.helpers.ffclipboard.clear('workink');
28 | this.helpers.followAndContribute('work.ink', path, destination);
29 |
30 | return this.helpers.safelyNavigate(destination);
31 | }
32 | }
33 |
34 | export const matches = ['workink.click'];
35 |
--------------------------------------------------------------------------------
/src/bypasses/ytsubme.js:
--------------------------------------------------------------------------------
1 | import BypassDefinition from './BypassDefinition.js'
2 |
3 | export default class Ytsubme extends BypassDefinition {
4 | constructor() {
5 | super()
6 | // custom bypass required bases can be set here
7 | }
8 |
9 | execute() {
10 | this.helpers.ensureDomLoaded(() =>{
11 | this.helpers.ifElement("a#link", addr => {
12 | this.helpers.safelyNavigate(addr.href)
13 | })
14 | })
15 | }
16 | }
17 |
18 | export const matches = ['ytsubme.com']
19 |
--------------------------------------------------------------------------------
/src/helpers/infobox.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Inserts an info box into the DOM. This is used to show the user information or to complete a specific step (do a captcha, for example).
3 | * @param {string} text - The text to show in the info box.
4 | */
5 | export function insertInfoBox(text) {
6 | let infobox_container = document.querySelector('div#ffibv1');
7 |
8 | if (!infobox_container) {
9 | infobox_container = document.createElement('div');
10 | infobox_container.setAttribute('id', 'ffibv1');
11 | infobox_container.setAttribute(
12 | 'style',
13 | `
14 | z-index: 99999999; position: fixed; bottom: 0; line-height:normal;
15 | right: 0; padding: 20px; color:#111; font-size:21px;
16 | font-family:-apple-system,BlinkMacSystemFont,segoe ui,Roboto,helvetica neue,Arial,sans-serif,apple color emoji,segoe ui emoji,segoe ui symbol;
17 | max-width:500px; display: flex; flex-direction: column-reverse;
18 | `
19 | );
20 |
21 | document.body.appendChild(infobox_container);
22 | }
23 | const div = document.createElement('div');
24 | div.style =
25 | 'margin-left:20px; margin-bottom: 20px;background:#eee;border-radius:10px;padding:20px;box-shadow:#111 0px 5px 40px;cursor:pointer';
26 | div.innerHTML = ` `;
27 | div.setAttribute('aria-hidden', 'true');
28 | const span = div.querySelector('span');
29 | span.textContent = text;
30 | div.onclick = () => infobox_container.removeChild(div);
31 | infobox_container.appendChild(div);
32 | setTimeout(() => infobox_container.removeChild(div), 7000);
33 | }
34 |
35 | export default insertInfoBox;
36 |
--------------------------------------------------------------------------------
/src/html/base.js:
--------------------------------------------------------------------------------
1 | const brws = typeof browser == 'undefined' ? chrome : browser;
2 | document.documentElement.setAttribute(
3 | 'dir',
4 | brws.i18n.getMessage('@@bidi_dir')
5 | );
6 |
--------------------------------------------------------------------------------
/src/html/before-navigate.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
24 |
25 |
26 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/src/html/before-navigate.js:
--------------------------------------------------------------------------------
1 | /*global brws*/
2 | const timerElement = document.getElementById('timer');
3 | const timerText = timerElement.querySelector('p');
4 |
5 | // Get target URL from search parameter
6 | const urlParams = new URLSearchParams(window.location.search);
7 | const targetUrl = urlParams.get('target');
8 |
9 | function escapeHtml(unsafe) {
10 | if (!unsafe) return unsafe; //prevents null objects from throwing an error
11 | return unsafe
12 | .replaceAll('&', '&')
13 | .replaceAll('<', '<')
14 | .replaceAll('>', '>')
15 | .replaceAll('"', '"')
16 | .replaceAll("'", ''');
17 | }
18 |
19 | // Update destination message with target URL
20 | const destinationElement = document.querySelector('#destination');
21 | destinationElement.innerHTML = brws.i18n.getMessage(
22 | 'beforeNavigateDestination',
23 | ` ${escapeHtml(targetUrl)}
`
26 | );
27 |
28 | brws.storage.local.get('options', (result) => {
29 | if (!result.options.navigationDelayToggle) {
30 | return;
31 | }
32 | const delay = result.options.navigationDelay;
33 | let timeLeft = delay;
34 |
35 | timerElement.classList.remove('uk-hidden');
36 | timerText.textContent = brws.i18n.getMessage(
37 | timeLeft === 1 ? 'beforeNavigateTimerSingular' : 'beforeNavigateTimer',
38 | [timeLeft]
39 | );
40 |
41 | const interval = setInterval(() => {
42 | timeLeft--;
43 | if (timeLeft <= 0) {
44 | clearInterval(interval);
45 | window.location.href = targetUrl;
46 | } else {
47 | timerText.textContent = brws.i18n.getMessage(
48 | timeLeft === 1 ? 'beforeNavigateTimerSingular' : 'beforeNavigateTimer',
49 | [timeLeft]
50 | );
51 | }
52 | }, 1000);
53 | });
54 |
--------------------------------------------------------------------------------
/src/html/blocked.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/html/consent.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | FastForward
5 |
6 |
7 |
8 |
9 |
41 |
42 |
43 |
44 |
47 |
48 |
49 |
50 |
Thank you for installing FastForward
51 |
52 | This extension collects the tab url when you choose to add a website to the whitelist, and temporarily processes the url of bypassed sites while navigating them. This data never leaves your device.
53 |
54 |
55 | Additionally, if the "Crowd Bypass" option is enabled, the extension may send some bypassed urls to our server to be processed and added to our database in accordance with our privacy policy . They are never shared.
56 |
57 |
58 | If you consent to this data collection hit "Agree" to continue and then allow the permission request. Otherwise hit "Refuse" and the extension will be uninstalled.
59 |
60 |
Agree
61 |
Refuse
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/src/html/consent.js:
--------------------------------------------------------------------------------
1 | // Function to save consent status
2 | async function saveConsentStatus(consentStatus) {
3 | return browser.storage.local.set({ consentStatus: consentStatus });
4 | }
5 |
6 | // Function to get consent status
7 | async function getConsentStatus() {
8 | return new Promise((resolve) => {
9 | browser.storage.local.get('consentStatus').then((result) => {
10 | resolve(result.consentStatus);
11 | });
12 | });
13 | }
14 |
15 | // Event listener for "Agree" button
16 | document.querySelector('#agree').addEventListener('click', async function () {
17 | console.log("Agree button clicked.");
18 | const permissionsToRequest = {
19 | origins: ["
"],
20 | };
21 | function onResponse(response) {
22 | if (response) {
23 | console.log("Permission was granted");
24 | window.close(); // Close the window after permission is granted
25 | } else {
26 | console.log("Permission was refused");
27 | browser.management.uninstallSelf();
28 | }
29 | return browser.permissions.getAll();
30 | }
31 | const response = await browser.permissions.request(permissionsToRequest);
32 | const currentPermissions = await onResponse(response);
33 | console.log(`Current permissions:`, currentPermissions);
34 | await saveConsentStatus('consent-granted');
35 | });
36 |
37 | // Event listener for "Refuse" button
38 | document.querySelector('#refuse').addEventListener('click', async function () {
39 | console.log("Uninstalling extension.");
40 | browser.management.uninstallSelf();
41 | });
--------------------------------------------------------------------------------
/src/html/crowd-bypassed.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
15 |
16 |
17 |
18 |
19 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/src/html/crowd-bypassed.js:
--------------------------------------------------------------------------------
1 | /*global brws*/
2 | const timerElement = document.getElementById('timer');
3 | const timerText = timerElement.querySelector('p');
4 | const tempDisableCrowdButton = document.getElementById('temp-disable-crowd');
5 |
6 | // Get target URL from search parameter
7 | const urlParams = new URLSearchParams(window.location.search);
8 | const targetUrl = urlParams.get('target');
9 |
10 | function escapeHtml(unsafe) {
11 | if (!unsafe) return unsafe; //prevents null objects from throwing an error
12 | return unsafe
13 | .replaceAll('&', '&')
14 | .replaceAll('<', '<')
15 | .replaceAll('>', '>')
16 | .replaceAll('"', '"')
17 | .replaceAll("'", ''');
18 | }
19 |
20 | function updateDestinationMessage() {
21 | let msg = brws.i18n.getMessage(
22 | 'crowdBypassedInfo',
23 | ` ${escapeHtml(targetUrl)}
`
26 | );
27 | document.querySelector('#crowd-bypass-info').innerHTML = msg;
28 | }
29 |
30 | tempDisableCrowdButton.addEventListener('click', () => {
31 | brws.storage.local.get(['options']).then((result) => {
32 | let opt = result.options;
33 | if (!opt.optionCrowdBypass) {
34 | return;
35 | }
36 | opt.optionCrowdBypass = false;
37 | brws.storage.local.set({ options: opt });
38 | brws.storage.local.set({ tempDisableCrowd: 'true' });
39 | // Create an alarm that will trigger after 10 minutes
40 | brws.alarms.create('enableCrowdBypass', { delayInMinutes: 10 });
41 | history.back();
42 | });
43 | });
44 |
45 | brws.storage.local.get('options', (result) => {
46 | if (!result.options.optionCrowdOpenDelayToggle) {
47 | return;
48 | }
49 | const delay = result.options.optionCrowdOpenDelay;
50 | // Show countdown timer
51 | let timeLeft = delay;
52 | timerElement.hidden = false;
53 | timerText.textContent = brws.i18n.getMessage(
54 | timeLeft === 1 ? 'crowdBypassedTimerSingular' : 'crowdBypassedTimer',
55 | [timeLeft]
56 | );
57 |
58 | const interval = setInterval(() => {
59 | timeLeft--;
60 | if (timeLeft <= 0) {
61 | clearInterval(interval);
62 | window.open(targetUrl, '_blank').focus();
63 | timerElement.hidden = true;
64 | } else {
65 | timerText.textContent = brws.i18n.getMessage(
66 | timeLeft === 1 ? 'crowdBypassedTimerSingular' : 'crowdBypassedTimer',
67 | [timeLeft]
68 | );
69 | }
70 | }, 1000);
71 | });
72 |
73 | updateDestinationMessage();
74 |
--------------------------------------------------------------------------------
/src/html/i18n.js:
--------------------------------------------------------------------------------
1 | document.querySelectorAll("[data-message]").forEach(e=>e.textContent=brws.i18n.getMessage(e.getAttribute("data-message")))
2 | const titleElm=document.querySelector("title"),title=titleElm.textContent
3 |
--------------------------------------------------------------------------------
/src/html/noscript.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/html/popup.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | FastForward
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
16 |
17 |
37 |
38 |
39 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/src/html/popup.js:
--------------------------------------------------------------------------------
1 | /*global brws*/
2 | let defaultOptions = {
3 | navigationDelayToggle: true,
4 | navigationDelay: 10,
5 | optionTrackerBypass: false,
6 | optionInstantNavigationTrackers: false,
7 | optionBlockIpLoggers: true,
8 | optionCrowdBypass: false,
9 | optionCrowdOpenDelayToggle: false,
10 | optionCrowdOpenDelay: 5,
11 | optionCrowdCloseDelayToggle: false,
12 | optionCrowdCloseDelay: 15,
13 | whitelist: '',
14 | };
15 |
16 | async function saveOptions(options) {
17 | return brws.storage.local.set({ options: options });
18 | }
19 |
20 | async function getOptions() {
21 | return new Promise((resolve) => {
22 | brws.storage.local.get('options').then((result) => {
23 | resolve(result.options);
24 | });
25 | });
26 | }
27 |
28 | function displayExtensionVersion() {
29 | brws.storage.local
30 | .get('version')
31 | .then(
32 | (data) =>
33 | (document.getElementById('version').textContent = data.version + '-Mv3')
34 | );
35 | }
36 |
37 | function formatWhitelistDesc() {
38 | document.querySelector(
39 | "[data-message='optionsWhitelistDescription']"
40 | ).innerHTML = document
41 | .querySelector("[data-message='optionsWhitelistDescription']")
42 | .textContent.replace(
43 | 'subdomain.domain.tld',
44 | 'subdomain.domain.tld
'
45 | )
46 | .replace('domain.tld', 'domain.tld
');
47 | }
48 |
49 | function addEventListeners() {
50 | document
51 | .querySelector('#whitelist')
52 | .addEventListener('input', async function () {
53 | let options = await getOptions();
54 | options['whitelist'] = this.value;
55 | saveOptions(options);
56 | checkTextareaValidity();
57 | });
58 |
59 | document
60 | .querySelector("#openOptions")
61 | .addEventListener('click', function () {
62 | window.open("/html/options.html");
63 | });
64 |
65 | document
66 | .querySelector('#addToWhitelist')
67 | .addEventListener('click', async function () {
68 | let value = document.getElementById("whitelist").value;
69 | let prefix = "";
70 | if(value != "" && value[value.length-1] != "\n") {
71 | prefix = "\n";
72 | }
73 |
74 | chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
75 | let hostname = new URL(tabs[0].url).host;
76 | let whitelistTextarea = document.getElementById("whitelist");
77 | if(!whitelistTextarea.value.includes(hostname)) {
78 | whitelistTextarea.value += prefix + hostname;
79 | whitelistTextarea.dispatchEvent(new Event('input'));
80 | }
81 | });
82 | });
83 | }
84 |
85 | function checkTextareaValidity() {
86 | let textarea = document.querySelector('#whitelist');
87 | if (textarea.value.includes('/')) {
88 | textarea.classList.add('invalid');
89 | } else {
90 | textarea.classList.remove('invalid');
91 | }
92 | }
93 |
94 | async function repopulateOptions() {
95 | let options = Object.assign({}, defaultOptions, await getOptions());
96 | let key = 'whitelist';
97 | let element = document.querySelector('#' + key);
98 | if (element.tagName === 'TEXTAREA') {
99 | element.value = options[key];
100 | }
101 | saveOptions(options);
102 | }
103 |
104 |
105 | document.addEventListener('DOMContentLoaded', async function () {
106 | await repopulateOptions();
107 | addEventListeners();
108 | checkTextareaValidity();
109 | formatWhitelistDesc();
110 | displayExtensionVersion();
111 | });
112 |
113 | function addBottomNavbar() {
114 | if (window.innerWidth < 768 && !document.querySelector('.bottom-navbar')) {
115 | const bottomNavbar = document.createElement('nav');
116 | document.body.appendChild(bottomNavbar);
117 | const bottomNavbarUl = document.createElement('ul');
118 | bottomNavbar.appendChild(bottomNavbarUl);
119 |
120 | const navLinks = document.querySelectorAll('.navlink');
121 | navLinks.forEach((link) => {
122 | bottomNavbarUl.appendChild(link);
123 | });
124 |
125 | bottomNavbar.classList.add('bottom-navbar');
126 | } else {
127 | const bottomNavbar = document.querySelector('.bottom-navbar');
128 | if (bottomNavbar) {
129 | const navLinks = bottomNavbar.querySelectorAll('.navlink');
130 | const nav = document.querySelector('nav:not(.bottom-navbar)');
131 | const navUl = nav.querySelector('ul');
132 | navLinks.forEach((link) => {
133 | navUl.appendChild(link);
134 | });
135 | bottomNavbar.remove();
136 | }
137 | }
138 | }
139 |
140 | addBottomNavbar();
--------------------------------------------------------------------------------
/src/html/tracker-bypass.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/src/html/tracker-bypass.js:
--------------------------------------------------------------------------------
1 | /*global brws*/
2 | const trackerInfoElement = document.getElementById('tracker-info');
3 |
4 | // Get tracker URL from search parameter
5 | const urlParams = new URLSearchParams(window.location.search);
6 | let trackerUrl = urlParams.get('url');
7 | if (!trackerUrl) showError('no url param found');
8 |
9 | function escapeHtml(str) {
10 | if (!str) return str; //prevents null objects from throwing an error
11 | return str
12 | .replaceAll('&', '&')
13 | .replaceAll('<', '<')
14 | .replaceAll('>', '>')
15 | .replaceAll('"', '"')
16 | .replaceAll("'", ''');
17 | }
18 |
19 | function showError(err) {
20 | console.error(err);
21 | trackerInfoElement.textContent = brws.i18n.getMessage('trackerBypassedError');
22 | trackerInfoElement.classList.add('text-warn');
23 | setTimeout(() => {
24 | if (trackerUrl) window.location.replace(trackerUrl);
25 | else console.error('no url param found');
26 | }, 3000);
27 | }
28 |
29 | function updateTrackerMessage(url) {
30 | const trackerInfoElement = document.getElementById('tracker-info');
31 | const msg = brws.i18n.getMessage(
32 | 'beforeNavigateDestination',
33 | `
34 |
35 |
36 | ${escapeHtml(url)}
37 |
38 |
`
39 | );
40 | const newDiv = document.createElement('div');
41 |
42 | newDiv.appendChild(document.createElement('br'));
43 |
44 | newDiv.innerHTML = msg;
45 |
46 | trackerInfoElement.textContent = '';
47 | trackerInfoElement.appendChild(newDiv);
48 |
49 | brws.storage.local.get('options').then((result) => {
50 | if (!result.options.optionInstantNavigationTrackers) return;
51 | window.location.replace(url);
52 | });
53 | }
54 |
55 | async function resolveTracker(url) {
56 | //special case for out.reddit.com
57 | const urlObj = new URL(url);
58 | if (urlObj.host === 'out.reddit.com') {
59 | const newUrl = urlObj.searchParams.get('url');
60 | if (newUrl) updateTrackerMessage(newUrl);
61 | else showError();
62 | }
63 |
64 | url = url.replace(/(^\w+:|^)\/\//, '');
65 |
66 | try {
67 | const response = await fetch(`https://unshorten.me/json/${url}`);
68 | const data = await response.json();
69 | if (data.success && data.resolved_url) {
70 | updateTrackerMessage(data.resolved_url);
71 | } else {
72 | showError();
73 | }
74 | } catch (err) {
75 | showError(err);
76 | }
77 | }
78 |
79 | resolveTracker(trackerUrl);
80 |
--------------------------------------------------------------------------------
/src/icon/128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FastForwardTeam/FastForward/a9b1894387e5b14892bc6c4deab1dd4edd46c0d2/src/icon/128.png
--------------------------------------------------------------------------------
/src/icon/150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FastForwardTeam/FastForward/a9b1894387e5b14892bc6c4deab1dd4edd46c0d2/src/icon/150.png
--------------------------------------------------------------------------------
/src/icon/176.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FastForwardTeam/FastForward/a9b1894387e5b14892bc6c4deab1dd4edd46c0d2/src/icon/176.png
--------------------------------------------------------------------------------
/src/icon/48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FastForwardTeam/FastForward/a9b1894387e5b14892bc6c4deab1dd4edd46c0d2/src/icon/48.png
--------------------------------------------------------------------------------
/src/icon/512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FastForwardTeam/FastForward/a9b1894387e5b14892bc6c4deab1dd4edd46c0d2/src/icon/512.png
--------------------------------------------------------------------------------
/src/icon/branding.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FastForwardTeam/FastForward/a9b1894387e5b14892bc6c4deab1dd4edd46c0d2/src/icon/branding.png
--------------------------------------------------------------------------------
/src/icon_disabled/128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FastForwardTeam/FastForward/a9b1894387e5b14892bc6c4deab1dd4edd46c0d2/src/icon_disabled/128.png
--------------------------------------------------------------------------------
/src/icon_disabled/150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FastForwardTeam/FastForward/a9b1894387e5b14892bc6c4deab1dd4edd46c0d2/src/icon_disabled/150.png
--------------------------------------------------------------------------------
/src/icon_disabled/176.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FastForwardTeam/FastForward/a9b1894387e5b14892bc6c4deab1dd4edd46c0d2/src/icon_disabled/176.png
--------------------------------------------------------------------------------
/src/icon_disabled/48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FastForwardTeam/FastForward/a9b1894387e5b14892bc6c4deab1dd4edd46c0d2/src/icon_disabled/48.png
--------------------------------------------------------------------------------
/src/icon_disabled/512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FastForwardTeam/FastForward/a9b1894387e5b14892bc6c4deab1dd4edd46c0d2/src/icon_disabled/512.png
--------------------------------------------------------------------------------
/src/js/constants.js:
--------------------------------------------------------------------------------
1 | export const beforeNavigateRules = [
2 | {
3 | id: 1,
4 | priority: 2,
5 | action: {
6 | type: 'redirect',
7 | redirect: {
8 | regexSubstitution:
9 | chrome.runtime.getURL('/html/crowd-bypassed.html') + '\\1',
10 | },
11 | },
12 | condition: {
13 | regexFilter:
14 | '^https?://fastforward.team/bypassed(\\?(.*&)?type=crowd(&.*)?$)',
15 | resourceTypes: ['main_frame'],
16 | },
17 | },
18 | {
19 | id: 2,
20 | priority: 2,
21 | action: {
22 | type: 'redirect',
23 | redirect: {
24 | regexSubstitution:
25 | chrome.runtime.getURL('/html/tracker-bypass.html') + '\\1',
26 | },
27 | },
28 | condition: {
29 | regexFilter:
30 | '^https?://fastforward.team/bypassed(\\?(.*&)?type=tracker(&.*)?$)',
31 | resourceTypes: ['main_frame'],
32 | },
33 | },
34 | {
35 | id: 3,
36 | priority: 1,
37 | action: {
38 | type: 'redirect',
39 | redirect: {
40 | regexSubstitution:
41 | chrome.runtime.getURL('/html/before-navigate.html') + '\\1',
42 | },
43 | },
44 | condition: {
45 | regexFilter: '^https?://fastforward\\.team/bypassed(\\?.*)',
46 | resourceTypes: ['main_frame'],
47 | },
48 | },
49 | ];
50 |
--------------------------------------------------------------------------------
/src/js/content_script.js:
--------------------------------------------------------------------------------
1 | const brws = typeof browser !== 'undefined' ? browser : chrome;
2 | async function getOptions() {
3 | return new Promise((resolve) => {
4 | brws.storage.local.get('options').then((result) => {
5 | resolve(result.options);
6 | });
7 | });
8 | }
9 |
10 | function getExtBaseURL() {
11 | return brws.runtime.getURL('/');
12 | }
13 |
14 | async function injectScript() {
15 | let options = await getOptions();
16 | if (
17 | options &&
18 | options.whitelist &&
19 | matchDomains(window.location.hostname, options.whitelist)
20 | ) {
21 | console.log('FastForward: Site whitelisted');
22 | return;
23 | }
24 | let script = document.createElement('script');
25 | script.src =
26 | brws.runtime.getURL('injection_script.js') +
27 | '?' +
28 | new URLSearchParams({ ext_base_URL: getExtBaseURL() }); //pass base url to injection script https://stackoverflow.com/a/9517879
29 | script.onload = function () {
30 | script.remove();
31 | };
32 | (document.head || document.documentElement).appendChild(script);
33 | }
34 |
35 | //ff + first 10 characters of SHA256 of fastforward to prevent collisions
36 | document.addEventListener('ff53054c0e13_crowdQuery', async (event) => {
37 | let data = event.detail;
38 | const response = await chrome.runtime.sendMessage({
39 | type: 'crowdQuery',
40 | detail: data,
41 | });
42 | console.log(response);
43 | document.dispatchEvent(
44 | new CustomEvent('ff53054c0e13_crowdResponse', { detail: response })
45 | );
46 | });
47 |
48 | function matchDomains(inputString, domains) {
49 | let domainList = domains.split('\n');
50 | for (let domain of domainList) {
51 | let regex = new RegExp('^' + domain.replace(/\*/g, '[^.]+') + '$');
52 | if (regex.test(inputString)) {
53 | return true;
54 | }
55 | }
56 | return false;
57 | }
58 |
59 | document.addEventListener('ff53054c0e13_crowdContribute', (event) => {
60 | let data = event.detail;
61 | chrome.runtime.sendMessage({
62 | type: 'crowdContribute',
63 | detail: data,
64 | });
65 | });
66 | document.addEventListener('ff53054c0e13_followAndContribute', (event) => {
67 | let data = event.detail;
68 | chrome.runtime.sendMessage({
69 | type: 'followAndContribute',
70 | detail: data,
71 | });
72 | });
73 |
74 | function onFFClipboardSet(event) {
75 | const { key, value } = event.detail;
76 | chrome.storage.local.get('ffclipboard', (result) => {
77 | const ffclipboard = result.ffclipboard || {};
78 | ffclipboard[key] = value;
79 | chrome.storage.local.set({ ffclipboard });
80 | });
81 | }
82 |
83 | function onFFClipboardGet(event) {
84 | const { key } = event.detail;
85 | chrome.storage.local.get('ffclipboard', (result) => {
86 | const value = result.ffclipboard ? result.ffclipboard[key] : undefined;
87 | const responseEvent = new CustomEvent('ff53054c0e13_ffclipboardResponse', {
88 | detail: { key, value },
89 | });
90 | document.dispatchEvent(responseEvent);
91 | });
92 | }
93 |
94 | function onFFClipboardClear(event) {
95 | const { key } = event.detail;
96 | chrome.storage.local.get('ffclipboard', (result) => {
97 | if (result.ffclipboard) {
98 | delete result.ffclipboard[key];
99 | chrome.storage.local.set({ ffclipboard: result.ffclipboard });
100 | }
101 | });
102 | }
103 |
104 | injectScript();
105 | document.addEventListener('ff53054c0e13_ffclipboardSet', onFFClipboardSet);
106 | document.addEventListener('ff53054c0e13_ffclipboardGet', onFFClipboardGet);
107 | document.addEventListener('ff53054c0e13_ffclipboardClear', onFFClipboardClear);
108 |
--------------------------------------------------------------------------------
/src/version.txt:
--------------------------------------------------------------------------------
1 | 0.0.0
2 |
--------------------------------------------------------------------------------
/tests/bypasses.json:
--------------------------------------------------------------------------------
1 | {
2 | "https://cutt.ly/9WBfIgT": {
3 | "destination": "www.google.com",
4 | "timeout": 5000
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/tests/index.js:
--------------------------------------------------------------------------------
1 | const puppeteer = require('puppeteer')
2 | const path = require('path')
3 |
4 | const { EventEmitter } = require('events');
5 | const { URL } = require('url');
6 |
7 | const bypasses = require('./bypasses.json');
8 |
9 |
10 |
11 | class TimeoutError extends Error {
12 | constructor(message) {
13 | super(message);
14 | this.name = this.constructor.name;
15 | Error.captureStackTrace(this, this.constructor);
16 | }
17 | }
18 |
19 |
20 | (async() => {
21 | const browser = await puppeteer.launch({
22 | headless: false,
23 | args: [
24 | '--no-sandbox',
25 | `--load-extension=${path.join(__dirname, '../build/FastForward.chromium')}`
26 | ],
27 | ignoreDefaultArgs: ['--disable-extensions', '--enable-automation']
28 | });
29 |
30 | // We do not need to view the FastForward site
31 | browser.on('targetcreated', async target => {
32 | if (target.url() === 'https://fastforward.team/firstrun') {
33 | const targetPage = await target.page()
34 | targetPage.close()
35 | return;
36 | }
37 | })
38 | const page = await browser.newPage()
39 | await page.setRequestInterception(true);
40 | // A custom EventEmitter to emit url changes
41 | const urlEmitter = new EventEmitter()
42 | page.on('request', request => {
43 | const url = new URL(request.url())
44 | urlEmitter.emit('change', url.host)
45 | request.continue();
46 | })
47 |
48 | const waitForDomain = (domain, timeoutms) => {
49 | return new Promise((resolve, reject) => {
50 | const timeout = setTimeout(() => {
51 | reject(new TimeoutError(`Timeout limit of ${timeoutms}ms has been exceeded`))
52 | }, timeoutms)
53 | const listener = urlEmitter.on('change', changedURL => {
54 | if (domain === changedURL) {
55 | clearTimeout(timeout)
56 | resolve();
57 | urlEmitter.removeListener('change', listener);
58 | }
59 | })
60 | })
61 | }
62 |
63 | // Wait 3 seconds for FastForward to load
64 | setTimeout(async () => {
65 | for (const url in bypasses) {
66 | const destination = bypasses[url].destination
67 | const timeout = bypasses[url].timeout || 5000
68 | console.log(`⌛ Testing "${url}" with expected destination "${destination}"`)
69 | await page.goto(url)
70 | await waitForDomain(destination, timeout)
71 | .then(() => {
72 | console.log(`✔️ Success`)
73 | })
74 | .catch(err => {
75 | console.log(`❌ Failed at ${url}. ${err.message}`)
76 | process.exit(1)
77 | })
78 | }
79 | console.log('✓ All bypasses have passed the test!')
80 | }, 3000)
81 |
82 |
83 | })()
84 |
--------------------------------------------------------------------------------
/tests/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "autotest",
3 | "version": "1.0.0",
4 | "description": "A tool to automatically test FastForward extension",
5 | "main": "index.js",
6 | "repository": {
7 | "type": "git",
8 | "url": "https://github.com/FastForwardTeam/FastForward.git",
9 | "directory": "tests"
10 | }
11 | }
12 | "license" : "Unlicense",
13 | "author": "Beaness",
14 | "dependencies": {
15 | "puppeteer": "^10.2.0"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------