├── .changeset
└── config.json
├── .dockerignore
├── .github
├── ISSUE_TEMPLATE
│ ├── ISSUE-TEMPLATE.md
│ └── config.yml
├── PULL_REQUEST_TEMPLATE
│ └── pull_request_template.md
└── workflows
│ ├── binaries.yml
│ ├── docker-build.yml
│ └── release.yml
├── .gitignore
├── .gitmodules
├── CHANGELOG.md
├── Dockerfile
├── LICENSE
├── README.md
├── astro.config.ts
├── config.example.toml
├── deno.jsonc
├── deno.lock
├── docker-builds.yml
├── docker-compose.yml
├── package.json
├── public
├── logo.svg
├── search.js
├── sw.js
└── uv
│ └── uv.config.js
├── server
├── cli.ts
├── config
│ └── config.ts
├── env.d.ts
├── full
│ ├── server.ts
│ └── serverFactory.ts
├── message.ts
└── standalone
│ └── standalone.ts
├── src
├── assets
│ ├── apps
│ │ ├── coolmath.png
│ │ ├── discord.jpg
│ │ ├── gfnow.png
│ │ ├── google.jpg
│ │ ├── reddit.png
│ │ ├── retroarch.png
│ │ ├── spotify.png
│ │ ├── tt.jpg
│ │ ├── twitch.jpg
│ │ ├── twitter.png
│ │ ├── y8.png
│ │ └── yt.png
│ └── games
│ │ ├── 1v1-lol.png
│ │ ├── 2048.png
│ │ ├── basketball-stars.png
│ │ ├── binding-of-isaac.jpeg
│ │ ├── bloons.webp
│ │ ├── bloonstd.jpg
│ │ ├── bloonstd2.png
│ │ ├── bloxors.png
│ │ ├── cat-ninja.png
│ │ ├── chromedino.png
│ │ ├── cookieclicker.jpg
│ │ ├── crossy-road.png
│ │ ├── cybertanks.png
│ │ ├── dadish-2.png
│ │ ├── dadish.png
│ │ ├── doodle-jump.png
│ │ ├── ducklife.webp
│ │ ├── ducklife2.jpg
│ │ ├── ducklife3.jpg
│ │ ├── eaglerx.webp
│ │ ├── emulatorjs.png
│ │ ├── flashtetris.png
│ │ ├── frogger.jpeg
│ │ ├── fruit-ninja.png
│ │ ├── fruitninja.jpg
│ │ ├── geometrydash.png
│ │ ├── gm2.jpeg
│ │ ├── gpacman.jpg
│ │ ├── hardestgame.jpg
│ │ ├── hexgl.jpg
│ │ ├── mario.webp
│ │ ├── miniagario.png
│ │ ├── moke.png
│ │ ├── monkey-mart.png
│ │ ├── pacman.jpg
│ │ ├── paper.io2.webp
│ │ ├── portaltheflashversion.jpg
│ │ ├── retrobowl.jpg
│ │ ├── riddleschool.webp
│ │ ├── riddleschool2.webp
│ │ ├── riddleschool3.jpg
│ │ ├── riddleschool4.jpg
│ │ ├── riddleschool5.webp
│ │ ├── run3.png
│ │ ├── shellshock.png
│ │ ├── slitherio.webp
│ │ ├── slope-2.png
│ │ ├── slope.jpg
│ │ ├── snake.png
│ │ ├── ssf.jpeg
│ │ ├── stack.png
│ │ ├── sticmanhook.jpg
│ │ ├── stuntcars2.png
│ │ ├── stuntcars3.jpg
│ │ ├── subway-surfers.png
│ │ ├── superhot.webp
│ │ ├── supermario64.jpeg
│ │ ├── tanktrouble.webp
│ │ ├── tanuki.jpg
│ │ ├── templerun2.jpg
│ │ ├── the-worlds-hardest-game-2.jpg
│ │ ├── tunnel-rush.jpg
│ │ ├── vex3.png
│ │ ├── vex4.png
│ │ ├── vex5.jpeg
│ │ ├── vex6.jpeg
│ │ ├── vex7.png
│ │ ├── watermelon.png
│ │ ├── webretro.png
│ │ └── yohoho.jpeg
├── components
│ ├── FrameManager.astro
│ ├── Header.astro
│ ├── MobileNav.astro
│ ├── NavLinks.astro
│ ├── Scripts.astro
│ ├── Search.astro
│ └── settings
│ │ └── Loader.astro
├── data
│ └── games.json
├── env.d.ts
├── global.d.ts
├── layouts
│ └── Layout.astro
├── pages
│ ├── apps.astro
│ ├── community.astro
│ ├── gs
│ │ ├── [game].astro
│ │ └── index.astro
│ ├── index.astro
│ ├── load.astro
│ ├── options
│ │ ├── about.astro
│ │ ├── bt.astro
│ │ └── index.astro
│ └── support.astro
└── ts
│ ├── serviceWorker.ts
│ └── settings.ts
├── tailwind.config.mjs
├── tsconfig.json
└── vendor
└── scramjet
├── LICENSE
├── README.md
├── dist
├── scramjet.client.js
├── scramjet.client.js.map
├── scramjet.controller.js
├── scramjet.controller.js.map
├── scramjet.shared.js
├── scramjet.shared.js.map
├── scramjet.sync.js
├── scramjet.sync.js.map
├── scramjet.wasm.js
├── scramjet.worker.js
└── scramjet.worker.js.map
├── lib
├── index.cjs
└── index.d.ts
└── package.json
/.changeset/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json",
3 | "changelog": ["@changesets/changelog-github", { "repo": "titaniumnetwork-dev/incognito" }],
4 | "commit": false,
5 | "fixed": [],
6 | "linked": [],
7 | "access": "public",
8 | "baseBranch": "main",
9 | "updateInternalDependencies": "patch",
10 | "ignore": [],
11 | "privatePackages": { "version": true, "tag": true }
12 | }
13 |
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .vscode
3 | npm-debug.log
4 | yarn-error.log
5 | .github/
6 | .env.example
7 | .env
8 | dist/
9 | .git/
10 | .astro/
11 | ~/
12 | .gitignore
13 | biome.json
14 | docker-compose.yml
15 | Dockerfile
16 | README.md
17 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/ISSUE-TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report Or Feature request
3 | about: Report a Bug or submit a Feature that you would like to see
4 | title: "[BUG/Feature Request]"
5 | labels: ''
6 | assignees: ''
7 | ---
8 |
9 | **Note: for support questions, please use our [Discord](https://discord.gg/unblock)**. This repository's issues are reserved for feature requests and bug reports.
10 |
11 | - **I'm submitting a ...**
12 | - [ ] bug report
13 | - [ ] feature request
14 | - [ ] support request => Please do not submit support request here, see note at the top of this template.
15 |
16 | - **Do you want to request a _feature_ or report a _bug_?**
17 |
18 | - **What is the current behavior?**
19 |
20 | - **If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem**
21 |
22 | - **What is the expected behavior?**
23 |
24 | - **What is the motivation / use case for changing the behavior?**
25 |
26 | - **Please tell us about your environment:**
27 |
28 | - Version: 2.0.0-beta.X
29 | - Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]
30 | - Language: [all | TypeScript X.X | ES6/7 | ES5 | Dart]
31 |
32 | - **Other information** (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, gitter, etc)
33 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 | contact_links:
3 | - name: Communtiy Support
4 | url: https://discord.gg/unblock
5 | about: Please ask and answer questions here.
6 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md:
--------------------------------------------------------------------------------
1 | - **Please check if the PR fulfills these requirements**
2 |
3 | * [ ] Tests for the changes have been added (for bug fixes / features)
4 | * [ ] Docs have been added / updated (for bug fixes / features)
5 |
6 | - **What kind of change does this PR introduce?** (Bug fix, feature, docs update, ...)
7 |
8 | - **What is the current behavior?** (You can also link to an open issue here)
9 |
10 | - **What is the new behavior (if this is a feature change)?**
11 |
12 | - **Does this PR introduce a breaking change?** (What changes might users need to make in their application due to this PR?)
13 |
14 | - **Other information**:
15 |
--------------------------------------------------------------------------------
/.github/workflows/binaries.yml:
--------------------------------------------------------------------------------
1 | name: Add Binaries to current release.
2 |
3 | on:
4 | push:
5 | tags:
6 | - v*
7 | #workflow_run:
8 | # workflows:
9 | # - Release
10 | # types:
11 | # - completed
12 | workflow_dispatch:
13 |
14 | #defaults:
15 | #run:
16 | #shell: bash
17 |
18 | env:
19 | FORCE_COLOR: true
20 |
21 | jobs:
22 | windows-build:
23 | name: Build Windows
24 | if: ${{ github.repository_owner == 'titaniumnetwork-dev' }}
25 | runs-on: windows-latest
26 | permissions:
27 | contents: write
28 | id-token: write
29 | steps:
30 | - uses: actions/checkout@v4
31 |
32 | - name: Setup Deno
33 | uses: denoland/setup-deno@v2
34 | with:
35 | deno-version: 2.1.4
36 |
37 | - name: Install dependencies
38 | run: deno install --allow-scripts
39 |
40 | - name: Build Incog
41 | run: cp config.example.toml config.toml && deno task build
42 |
43 | - name: Compile Windows Binaries
44 | run: deno task exe:windows
45 |
46 | - name: Upload artifacts
47 | uses: actions/upload-artifact@v4
48 | with:
49 | name: incognito-windows
50 | path: |
51 | *.exe
52 | maclinux-build:
53 | name: Build MacOS & Linux
54 | if: ${{ github.repository_owner == 'titaniumnetwork-dev' }}
55 | runs-on: ubuntu-latest
56 | permissions:
57 | contents: write
58 | id-token: write
59 | steps:
60 | - uses: actions/checkout@v4
61 |
62 | - name: Setup Deno
63 | uses: denoland/setup-deno@v2
64 | with:
65 | deno-version: 2.1.4
66 |
67 | - name: Install dependencies
68 | run: deno install --allow-scripts
69 |
70 | - name: Build Incog
71 | run: cp config.example.toml config.toml && deno task build
72 |
73 | - name: Compile MacOS
74 | run: deno task exe:macOS
75 |
76 | - name: Compile MacOS Arm64
77 | run: deno task exe:macOSarm
78 |
79 | - name: Compile Linux
80 | run: deno task exe:linux
81 |
82 | - name: Compile Linux Arm64
83 | run: deno task exe:linuxArm
84 |
85 | - name: Upload artifacts
86 | uses: actions/upload-artifact@v4
87 | with:
88 | name: incognito-linux-mac
89 | retention-days: 1
90 | path: |
91 | incognito-*
92 |
93 |
94 | upload-release:
95 | name: Upload the binary files
96 | if: ${{ github.repository_owner == 'titaniumnetwork-dev' }}
97 | runs-on: ubuntu-latest
98 | needs: [windows-build, maclinux-build]
99 |
100 | steps:
101 | - uses: actions/checkout@v4
102 | with:
103 | fetch-depth: 0
104 | fetch-tags: true
105 | - name: Make sure tag is there
106 | id: tag
107 | run:
108 | echo "tag=$(git describe --tags --abbrev=0)" >> $GITHUB_OUTPUT
109 |
110 | - name: Download artifacts for Linux & MacOS
111 | uses: actions/download-artifact@v4
112 | with:
113 | path: .
114 |
115 | - name: Upload Linux & MacOS
116 | uses: svenstaro/upload-release-action@v2
117 | with:
118 | repo_token: ${{ secrets.GITHUB_TOKEN }}
119 | file: incognito-linux-mac/*
120 | tag: ${{ steps.tag.outputs.tag }}
121 | overwrite: true
122 | file_glob: true
123 |
124 | - name: Upload Windows binary
125 | uses: svenstaro/upload-release-action@v2
126 | with:
127 | repo_token: ${{ secrets.GITHUB_TOKEN }}
128 | file: incognito-windows/*.exe
129 | tag: ${{ steps.tag.outputs.tag }}
130 | overwrite: true
131 | file_glob: true
132 |
--------------------------------------------------------------------------------
/.github/workflows/docker-build.yml:
--------------------------------------------------------------------------------
1 | name: Build Docker image
2 | on:
3 | push:
4 | tags:
5 | - v*
6 | workflow_dispatch:
7 |
8 | env:
9 | REGISTRY: ghcr.io
10 | IMAGE_NAME: ${{ github.repository }}
11 |
12 | jobs:
13 | build-and-push:
14 | name: Build and push Docker image to registry
15 | runs-on: ubuntu-latest
16 | if: ${{ github.repository_owner == 'titaniumnetwork-dev' }}
17 | permissions:
18 | contents: write
19 | packages: write
20 | steps:
21 | - name: Checkout repo
22 | uses: actions/checkout@v3
23 | - name: Setup docker buildx
24 | uses: docker/setup-buildx-action@v3
25 | - name: Login To registry ${{ env.REGISTRY }}
26 | uses: docker/login-action@v3
27 | with:
28 | registry: ${{ env.REGISTRY }}
29 | username: ${{ github.actor }}
30 | password: ${{ github.token }}
31 | - name: Extract Docker metadata
32 | id: meta
33 | uses: docker/metadata-action@v3
34 | with:
35 | images: ${{ env.REGISTRY }}/titaniumnetwork-dev/incognito
36 | - name: Build and push
37 | id: build-and-push
38 | uses: docker/build-push-action@v4
39 | with:
40 | context: .
41 | platforms: linux/amd64,linux/arm64
42 | file: ./Dockerfile
43 | name: incognito
44 | push: ${{ github.event_name != 'pull_request' }}
45 | tags: ${{ steps.meta.outputs.tags }}
46 | labels: ${{ steps.meta.outputs.labels }}
47 | cache-from: type=gha
48 | cache-to: type=gha,mode=max
49 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Release
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | workflow_dispatch:
8 |
9 | defaults:
10 | run:
11 | shell: bash
12 |
13 | env:
14 | FORCE_COLOR: true
15 |
16 | jobs:
17 | changelog:
18 | name: Release TAG
19 | if: ${{ github.repository_owner == 'titaniumnetwork-dev' }}
20 | runs-on: ubuntu-latest
21 | permissions:
22 | contents: write
23 | id-token: write
24 | steps:
25 | - uses: actions/checkout@v4
26 |
27 | - name: Setup Deno
28 | uses: denoland/setup-deno@v2
29 | with:
30 | deno-version: 2.1.4
31 |
32 | - name: Install dependencies
33 | run: deno install --allow-scripts
34 |
35 | - name: Create Release Pull Request or Publish
36 | id: changesets
37 | uses: changesets/action@v1
38 | with:
39 | version: deno task changeset:version
40 | publish: deno task changeset:publish
41 | commit: "[ci] release"
42 | title: "[ci] release"
43 | env:
44 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
45 |
46 | - name: Push tags if created.
47 | run: git push --follow-tags
48 | env:
49 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
50 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # build output
2 | dist/
3 | !vendor/scramjet/dist/
4 |
5 | # generated types
6 | .astro/
7 |
8 | # dependencies
9 | node_modules/
10 |
11 | # logs
12 | npm-debug.log*
13 | yarn-debug.log*
14 | yarn-error.log*
15 | pnpm-debug.log*
16 |
17 | # environment variables
18 | .env
19 | .env.production
20 |
21 | #Config stuff
22 | config.toml
23 |
24 | # macOS-specific files
25 | .DS_Store
26 |
27 | # jetbrains setting folder
28 | .idea/
29 |
30 | # Stupidness
31 | ~/
32 |
33 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/.gitmodules
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # 1.0.0
2 | - The initial rewrite to Astro. Includes:
3 | - Fully static
4 | - Easier to build
5 | - Feels/is faster to use
6 | - Fixes some bugs
7 | - Among tons of other stuff
8 |
9 | # 1.0.1
10 | - Fixes the games and apps page looking weird
11 |
12 | # 1.0.2
13 | - Fixes Dockerfile issues
14 |
15 | # 1.0.3
16 | - Turns off Rammerhead by default for now
17 | - Docker env fixes again
18 | - SEO
19 |
20 | # 1.0.4
21 | - Bumps RH
22 | - Fixes issues with bare-server-node
23 |
24 | # 1.1.0
25 | - Switches to Deno (mostly)
26 | - General bug fixes
27 | - Removes Rammerhead as an option and replaces it with Scramjet (coming soon)
28 | - Removes bare server and adds libcurl as an option
29 | - Adds a different Deno native server (Hono) - Command: `deno task start:standalone`
30 | - Removes Masqr
31 | - No more SSR, it's purely statically generated
32 | - CI fixes and other general improvements
33 | - Configuration is done via TOML over a bunch of environment vars
34 | - Removes Biome in place of Deno's native formatter
35 | - A better roadmap of what should be done in the future.
36 |
37 | # 1.1.1
38 | - Fixes a bug where if games aren't enabled it redirects to localhost:8080 over just /
39 | - Fixes a bug where if games aren't enabled, it still loads and compresses images over just ignoring them.
40 |
41 | # 1.1.2
42 | - Fixes bugs with apps opening as the full url instead of just the correct link
43 | - Fixes a bug with the iFrame panel where it copies & pastes the full link instead of just the normal link.
44 | - Add Scramjet
45 |
46 | # 1.1.3
47 | - Add the notice that ScramJet is in beta and may break
48 |
49 | # 1.1.4
50 | - Add the ability to disable/enable SEO or selectively render/show it
51 | - Adds the docker-builds.yml file to show the builds I am doing for the docker images.
52 |
53 | # 1.1.5
54 | - Fixes the games (mostly)
55 |
56 | # 1.1.6
57 | - Add the ability to run Incog from a prebuilt file
58 |
59 | # 1.1.7
60 | - Builds both the SEO & non SEO versions of the website for easier deployment
61 | - Adds a `--seo` CLI flag which can enable the SEO build without the config.toml file
62 | - CLI is now easier to use & interact with
63 | - Change and cleanup docs
64 | - Docker command cleanup to reflect new changes
65 | - docker-compose.build.yml no longer exists.
66 |
67 | # v1.1.8
68 | - Add the ability to self update your binary
69 | - Change the way parts of the CLI look
70 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM denoland/deno:debian-2.1.4
2 |
3 | WORKDIR /app
4 |
5 | COPY package*.json .
6 | COPY deno.jsonc .
7 | COPY . .
8 |
9 | RUN apt update
10 | RUN apt install -y python3 python3-pip libssl-dev build-essential python3-dev nodejs
11 | RUN cp -n config.example.toml config.toml
12 | RUN deno install --allow-scripts
13 | RUN deno task build
14 | RUN export TERM=xterm-256color
15 | ENV PORT="8000"
16 | VOLUME /app
17 | EXPOSE 8000
18 | ENTRYPOINT ["deno", "task", "start", "--color", "--server"]
19 | CMD ["full"]
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
26 |
27 | ## NOTE:
28 |
29 | - This will **NOT** deploy on Github Pages, Netlify, Vercel, Gitlab Pages or any other _static_ host
30 | - This will **NOT** work on Render
31 |
32 | ---
33 |
34 | ## How to get links
35 |
36 | [](https://discord.gg/unblock)
37 |
38 | ---
39 |
40 | ## Features
41 |
42 | - Lots and lots of games
43 |
44 | - Multiple Proxy "Backends":
45 | - [Ultraviolet](https://github.com/titaniumnetwork-dev/ultraviolet)
46 | - [Scramjet](https://github.com/mercuryworkshop/scramjet)
47 |
48 | ---
49 |
50 | ## Contributors
51 |
52 | - [MotorTruck1221](https://motortruck1221.com) - Maintainer
53 | - [Rifting](https://github.com/rifting) - Maintainer
54 | - [caracal-js](https://github.com/caracal-js) - Original Creator
55 |
56 | ---
57 |
58 | ## Tech Stack
59 |
60 | - [Astro](https://astro.build)
61 | - [Fastify](https://fastify.dev)
62 | - [Ultraviolet](https://github.com/titaniumnetwork-dev/ultraviolet)
63 | - [Epoxy](https://github.com/mercuryworkshop/epoxy-tls)
64 | - [Libcurl.js](https://github.com/ading2210/libcurl.js)
65 | - [Hono](https://github.com/honojs) as a Deno native alternative to fastify. Run with command: `deno task start --server standalone`
66 | - [Deno 2.0](https://github.com/denoland/deno)
67 | - HTML, CSS, and JavaScript (DUH)
68 |
69 | ---
70 |
71 | ## Roadmap
72 |
73 | - [x] - [Implement Scramjet](https://github.com/mercuryworkshop/scramjet)
74 | - [ ] - Remove dependency on Fastify & switch completely to Hono
75 | - [ ] - General codebase cleanup & remove all of the functions exisiting on `window`
76 | - [ ] - Games page needs to be reworked due to more games
77 | - [ ] - [i18n](https://github.com/alexandre-fernandez/astro-i18n)
78 | - [ ] - More themes
79 | - [ ] - Detatch from the [Original repo](https://github.com/caracal-js/incognito)
80 |
81 | ---
82 |
83 | ## Branches
84 |
85 | - main - Latest stable branch & production ready
86 | - dev - all major changes are made here before being merged into main
87 |
88 | ---
89 |
90 | ## Deployment
91 |
92 | - Incognito is the easiest proxy to deploy!
93 | - Currently, there are 3 ways to deploy Incognito
94 | - [Pre-built binaries](#Pre-built-binaries)
95 | - [Docker]()
96 | - [Building and running yourself]()
97 |
98 | #### Pre-built Binaries
99 |
100 | - When a new version is pushed, our CI automagically builds & uploads pre-built binaries to the release.
101 | - This enables you to:
102 | - A. Not install any extra runtime or install any new packages
103 | - B. Updates are easy and quick. Just download the new binary!
104 |
105 | ###### Usage:
106 |
107 | - First grab the current binary for your system & OS [here](https://github.com/titaniumnetwork-dev/incognito/releases/latest)
108 | - Then simply run the binary!
109 | - For example using linux:
110 | ```bash
111 | ./incognito-linux --server full
112 | ```
113 |
114 | > [!NOTE]
115 | > - You MAY have to make the binary executable on certain systems.
116 | > - For example in Linux:
117 | > ```bash
118 | > chmod +x ./incognito-linux
119 | > ```
120 | >
121 | > - To see all of the CLI options & usage see: [cli](#cli)
122 |
123 | #### Docker
124 |
125 | - Docker is the second easiest way to run Incognito.
126 | - Currently, Docker images are built by [@motortruck1221](https://github.com/motortruck1221) manually per version update.
127 | - They can be located here: [https://hub.docker.com/r/motortruck1221/incognito](https://hub.docker.com/r/motortruck1221/incognito)
128 | - This enables:
129 | - Automatic updates
130 | - Easier deployment then building yourself.
131 | - No dependencies besides docker w/compose
132 |
133 | ###### Usage:
134 |
135 | - The Docker builds currently have 2 tags:
136 | - Latest
137 | - Or a pinned version of the build (eg: 1.1.7)
138 | - Currently, only Docker compose is supported. Docker without compose *can be used* but it's highly discouraged.
139 |
140 | - Prerequisites:
141 | - Docker w/compose
142 |
143 | - First, create a `config.toml` file and copy the [example config from the repo](https://github.com/titaniumnetwork-dev/incognito/blob/main/config.example.toml)
144 | - Then, copy and paste the contents of the [docker-compose.yml file](https://github.com/titaniumnetwork-dev/incognito/blob/main/docker-compose.yml) into your own docker-compose.yml file
145 | - After that, edit the `docker-compose.yml` file to your liking.
146 | - And finally:
147 | ```bash
148 | docker compose up
149 | ```
150 | - That should fire Incognito up and you should be good!
151 |
152 | > [!NOTE]
153 | > - To see all of the CLI options & usage see: [cli](#cli)
154 | >
155 | > - To see all of the `config.toml` options see: [config](#config)
156 |
157 | #### Building & Running yourself
158 |
159 | - This is the last way to run Incognito
160 |
161 | ###### Usage:
162 |
163 | - Prerequisites:
164 | - Git
165 | - Deno 2.1.4 or newer
166 | - Node.js & NPM
167 |
168 | 1. Clone the repo
169 | ```bash
170 | git clone https://github.com/titaniumnetwork-dev/incognito.git
171 | ```
172 |
173 | 2. Install all of the dependencies:
174 | ```bash
175 | deno install --allow-scripts # This flag is here due to sharp, bufferutil and some others
176 | ```
177 |
178 | 3. Create a `config.toml` file
179 | ```bash
180 | cp config.example.toml config.toml
181 | ```
182 |
183 | 4. Modify the `config.toml` file to your liking. See: [config](#config)
184 |
185 | 5. Build the frontend
186 | ```bash
187 | deno task build
188 | ```
189 |
190 | 6. Start the server
191 | ```bash
192 | deno task start --server full
193 | ```
194 |
195 | > [!NOTE]
196 | > - To see all of the CLI options & usage see: [cli](#cli)
197 |
198 | ---
199 |
200 | ## CLI
201 |
202 | - Incognito has a built in CLI for starting and running
203 | - Currently, there are only 4 flags. And 1 extra command
204 |
205 | - `--help` - This triggers the help prompt even when other flags are passed.
206 | - `--server [full|standalone]` - Choose between the full or standalone server. This option is ***required*** otherwise, it will just show the help prompt.
207 | - Full - Uses Fastify has a built in Wisp server (via [wisp server node](https://github.com/mercuryworkshop/wisp-server-node)) *(recommended for self hosters)*
208 | - Standalone - Uses Hono as the server with no built in Wisp server. *(recommended for a huge production instance with an external wisp server)*
209 | - These are the only two options. Anything else passed here WILL throw an error.
210 | - `--config ` - Use a config located somewhere else.
211 | - Useful when using the [Pre-built binaries](#pre-built-binaries)
212 | - The path can either be absolute or relative.
213 | - `--seo` - Currently the default is to only use the build with no seo enabled. This flag enables the seo build.
214 | - Domain must be set in the [config](#config)
215 | - Overrides the enabled option in the [config](#config)
216 |
217 | - `upgrade` - Allows for the ability to self-update the binary. Run this to self upgrade
218 | - `--check` check for a new version. Tells you if one is available.
219 |
220 | ---
221 |
222 | ## Config
223 |
224 | - Incognito currently uses a config file in the toml format.
225 | - An example of this file can be found [here](https://github.com/titaniumnetwork-dev/incognito/blob/main/config.example.toml)
226 |
227 | ##### Build Opts
228 | | Type | Default | Description | Can be overwritten by ENV var |
229 | |------|---------|------------------------------------|-------------------------------|
230 | | games | `true` | Disables or enables the games page | - [ ] - No |
231 |
232 | ##### Server
233 | | Type | Default | Description | Can be overwritten by ENV var |
234 | |------|---------|-----------------------------------------------------------------------------------------------------------------|------------------------------|
235 | | port | `8000` | Change the default port. *Note: the environment var `PORT` takes precedence* | - [x] - Yes |
236 | | wisp | `true` | Disable or enables the in built wisp server. *Note: when using the Hono server there is no built-in wisp server | - [ ] - No |
237 |
238 | ##### SEO
239 | | Type | Default | Description | Can be overwritten by ENV var |
240 | ---------|-------------------------|--------------------------------------------------------------------------|-------------------------------|
241 | | SEO | `false` | Change whether or not to enabled SEO | - [x] - Yes - `SEO` (as well via a CLI flag `--seo` |
242 | | DOMAIN | `http://localhost:8000` | When the `both` option is enable, only show the SEO stuff on this domain | - [x] - Yes - `DOMAIN` |
243 |
--------------------------------------------------------------------------------
/astro.config.ts:
--------------------------------------------------------------------------------
1 | import sitemap from '@astrojs/sitemap';
2 | import tailwind from '@astrojs/tailwind';
3 | import { baremuxPath } from '@mercuryworkshop/bare-mux/node';
4 | //@ts-expect-error No types
5 | import { epoxyPath } from '@mercuryworkshop/epoxy-transport';
6 | import { libcurlPath } from '@mercuryworkshop/libcurl-transport';
7 | import playformCompress from '@playform/compress';
8 | import { uvPath } from '@titaniumnetwork-dev/ultraviolet';
9 | import icon from 'astro-icon';
10 | import robotsTxt from 'astro-robots-txt';
11 | import { defineConfig, envField, passthroughImageService } from 'astro/config';
12 | import { viteStaticCopy } from 'vite-plugin-static-copy';
13 | //we need the buildOpts from here : D
14 | import { config } from './server/config/config.ts';
15 | const scramjetPath = `${import.meta.dirname}/vendor/scramjet/dist/`
16 | const parsedDoc = await config(`${Deno.cwd()}/config.toml`);
17 | // https://astro.build/config
18 | export default defineConfig({
19 | site: Deno.env.get('SITE') || 'https://localhost:8080',
20 | integrations: [
21 | tailwind(),
22 | robotsTxt(),
23 | sitemap(),
24 | icon(),
25 | playformCompress({
26 | CSS: false,
27 | HTML: true,
28 | Image: true,
29 | JavaScript: true,
30 | SVG: true,
31 | }),
32 | ],
33 | output: 'static',
34 | image: {
35 | service: passthroughImageService()
36 | },
37 | env: {
38 | schema: {
39 | GAMES_LINK: envField.boolean({
40 | context: 'client',
41 | access: 'public',
42 | default: parsedDoc.buildOpts.games,
43 | }),
44 | SEO: envField.boolean({
45 | context: 'client',
46 | access: 'public',
47 | default: Boolean(Deno.env.get('SEO'))
48 | })
49 | },
50 | },
51 | vite: {
52 | plugins: [
53 | viteStaticCopy({
54 | targets: [
55 | {
56 | src: `${uvPath}/**/*`.replace(/\\/g, '/'),
57 | dest: 'uv',
58 | overwrite: false,
59 | },
60 | {
61 | src: `${epoxyPath}/**/*`.replace(/\\/g, '/'),
62 | dest: 'epoxy',
63 | overwrite: false,
64 | },
65 | {
66 | src: `${libcurlPath}/**/*`.replace(/\\/g, '/'),
67 | dest: 'libcurl',
68 | overwrite: false,
69 | },
70 | {
71 | src: `${baremuxPath}/**/*`.replace(/\\/g, '/'),
72 | dest: 'baremux',
73 | overwrite: false,
74 | },
75 | {
76 | src: `${scramjetPath}/**/*`.replace(/\\/g, '/'),
77 | dest: 'scram',
78 | overwrite: false
79 | }
80 | ],
81 | }) as any,
82 | ],
83 | server: {
84 | proxy: {
85 | '/wisp/': {
86 | target: 'wss://ruby.rubynetwork.co/wisp/',
87 | changeOrigin: true,
88 | ws: true,
89 | rewrite: (path: any) => path.replace(/^\/wisp\//, ''),
90 | },
91 | '/gms/': {
92 | target: 'https://rawcdn.githack.com/ruby-network/ruby-assets/main/',
93 | changeOrigin: true,
94 | ws: true,
95 | secure: false,
96 | rewrite: (path: any) => path.replace(/^\/gms\//, ''),
97 | },
98 | },
99 | },
100 | },
101 | });
102 |
--------------------------------------------------------------------------------
/config.example.toml:
--------------------------------------------------------------------------------
1 | [buildOpts]
2 | games = true
3 |
4 | [server]
5 | wisp = true
6 | port = 8000
7 |
8 | [seo]
9 | enabled = false
10 | both = false
11 | domain = "http://localhost:8000"
12 |
--------------------------------------------------------------------------------
/deno.jsonc:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://deno.land/x/deno@v2.1.4/cli/schemas/config-file.v1.json",
3 | "nodeModulesDir": "auto",
4 | "tasks": {
5 | "dev:server": "deno run -A --watch server/server.ts",
6 | "dev:client": "astro dev",
7 | "dev": "deno task dev:server & deno task dev:client",
8 | "build": "SEO=true astro build --outDir dist/seo/ && SEO=false astro build --outDir dist/noseo/",
9 | "exe:gen": "deno compile --target $ARC --include public --include dist --include server --include vendor --include deno.jsonc --include config.toml --include package.json --node-modules-dir --output incognito-$ARCN -A server/cli.ts",
10 | "exe:windows": "ARCN=windows ARC=x86_64-pc-windows-msvc deno task exe:gen",
11 | "exe:macOS": "ARCN=MacOS ARC=x86_64-apple-darwin deno task exe:gen",
12 | "exe:macOSarm": "ARCN=MacOS-arm ARC=aarch64-apple-darwin deno task exe:gen",
13 | "exe:linux": "ARCN=linux ARC=x86_64-unknown-linux-gnu deno task exe:gen",
14 | "exe:linuxArm": "ARCN=linux-arm ARC=aarch64-unknown-linux-gnu deno task exe:gen",
15 | "exe:all": "deno task exe:windows & deno task exe:macOS & deno task exe:macOSarm & deno task exe:linux & deno task exe:linuxArm",
16 | "exe": "deno compile --include public --include dist --include server --include vendor --include deno.jsonc --include config.toml --include package.json --node-modules-dir --output incognito -A server/cli.ts",
17 | "start": "deno run --allow-net --allow-read --allow-env --allow-ffi --allow-sys server/cli.ts",
18 | "bstart": "deno task build && deno task start",
19 | "bstart:seo": "deno task build:seo && deno task start",
20 | "check:frontend": "astro check",
21 | "check:server": "deno check server/**/*.ts",
22 | "check": "deno task check:frontend && deno task check:server",
23 | "changeset:version": "changeset version",
24 | "changeset:publish": "changeset publish"
25 | },
26 | "fmt": {
27 | "indentWidth": 4,
28 | "lineWidth": 100,
29 | "semiColons": true,
30 | "proseWrap": "preserve",
31 | "singleQuote": true
32 | },
33 | "imports": {
34 | // Astro deps
35 | "@astrojs/check": "npm:@astrojs/check@^0.9.4",
36 | "@astrojs/sitemap": "npm:@astrojs/sitemap@^3.2.1",
37 | "@astrojs/tailwind": "npm:@astrojs/tailwind@^5.1.3",
38 | "astro": "npm:astro@^5.2.3",
39 | "astro-seo": "npm:astro-seo@^0.8.4",
40 | "astro-icon": "npm:astro-icon@^1.1.4",
41 | "astro-robots-txt": "npm:astro-robots-txt@^1.0.0",
42 | "tailwindcss": "npm:tailwindcss@^3.4.16",
43 | "vite-plugin-static-copy": "npm:vite-plugin-static-copy@^2.2.0",
44 | "@iconify-json/fa-solid": "npm:@iconify-json/fa-solid@^1.2.0",
45 | "@iconify-json/fa6-solid": "npm:@iconify-json/fa6-solid@^1.2.2",
46 | "@iconify-json/mdi": "npm:@iconify-json/mdi@1.2.1",
47 | "@playform/compress": "npm:@playform/compress@^0.1.6",
48 | "sharp": "npm:sharp@^0.33.5",
49 | //Server stuff
50 | "@fastify/compress": "npm:@fastify/compress@^8.0.1",
51 | "@fastify/cookie": "npm:@fastify/cookie@^11.0.1",
52 | "@fastify/http-proxy": "npm:@fastify/http-proxy@^10.0.1",
53 | "@fastify/middie": "npm:@fastify/middie@^9.0.2",
54 | "@fastify/static": "npm:@fastify/static@^8.0.2",
55 | "fastify": "npm:fastify@^5.1.0",
56 | //UV, bare-mux, RH, corlink & wisp
57 | "@mercuryworkshop/bare-mux": "npm:@mercuryworkshop/bare-mux@^2.1.7",
58 | "@mercuryworkshop/epoxy-transport": "npm:@mercuryworkshop/epoxy-transport@^2.1.27",
59 | "@mercuryworkshop/libcurl-transport": "npm:@mercuryworkshop/libcurl-transport@^1.3.14",
60 | "@titaniumnetwork-dev/ultraviolet": "npm:@titaniumnetwork-dev/ultraviolet@^3.2.10",
61 | "wisp-server-node": "npm:wisp-server-node@^1.1.7",
62 | //random other deps
63 | "chalk": "npm:chalk@^5.3.0",
64 | "@changesets/cli": "npm:@changesets/cli@^2.27.10",
65 | "smol-toml": "npm:smol-toml@^1.3.1",
66 | "@types/node": "npm:@types/node@^22.9.0",
67 | "gradient-string": "npm:gradient-string@^3.0.0",
68 | "@types/deno": "npm:@types/deno@^2.0.0",
69 | "typescript": "npm:typescript@^5.7.2" //I need this for astro typechecking for some damn reason
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/docker-builds.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 |
3 | # This file is for building the docker images and pushing them to the registry. You can safely ignore this
4 |
5 | services:
6 | incognito:
7 | image: motortruck1221/incognito:latest
8 | build:
9 | context: .
10 | dockerfile: Dockerfile
11 | container_name: incognito
12 | restart: unless-stopped
13 | incognito-versioned:
14 | image: motortruck1221/incognito:1.1.7
15 | build:
16 | context: .
17 | dockerfile: Dockerfile
18 | container_name: incognito
19 | restart: unless-stopped
20 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 |
3 | services:
4 | incognito:
5 | image: motortruck1221/incognito:latest
6 | container_name: incognito
7 | restart: unless-stopped
8 | ports:
9 | # The ports work like this: Host:Container (DO NOT MODIFY THE CONTAINER PORT)
10 | - '8081:8000'
11 | volumes:
12 | - ./config.toml:/app/config.toml # This can be removed if you need the image to be stateless
13 | #environment:
14 | #- DOMAIN=https://incog.works # If you don't have a config.toml file and you want to still use the SEO build, set this variable
15 | command:
16 | - "full" # Full is the server type. Change to "standalone" if you want something simpler and lighter.
17 | #- "--seo" # Enable this line if you wish to use the SEO build. (NOTE: the domain env var MUST be set OR SEO must be enabled in your config.toml)
18 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "incognito",
3 | "version": "1.1.8",
4 | "private": true,
5 | "type": "module",
6 | "dependencies": {
7 | "@iconify-json/fa-solid": "^1.1.8",
8 | "@iconify-json/fa6-solid": "^1.1.21",
9 | "@iconify-json/mdi": "^1.2.1"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/public/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
--------------------------------------------------------------------------------
/public/search.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | /**
3 | * @param {string} input
4 | * @param {string} template Template for a search query.
5 | * @returns {string} Fully qualified URL
6 | */
7 | function search(input, template) {
8 | try {
9 | // input is a valid URL:
10 | // eg: https://example.com, https://example.com/test?q=param
11 | return new URL(input).toString();
12 | } catch (err) {
13 | // input was not a valid URL
14 | }
15 |
16 | try {
17 | // input is a valid URL when http:// is added to the start:
18 | // eg: example.com, https://example.com/test?q=param
19 | const url = new URL(`http://${input}`);
20 | // only if the hostname has a TLD/subdomain
21 | if (url.hostname.includes('.')) return url.toString();
22 | } catch (err) {
23 | // input was not valid URL
24 | }
25 |
26 | // input may have been a valid URL, however the hostname was invalid
27 |
28 | // Attempts to convert the input to a fully qualified URL have failed
29 | // Treat the input as a search query
30 | return template.replace('%s', encodeURIComponent(input));
31 | }
32 |
--------------------------------------------------------------------------------
/public/sw.js:
--------------------------------------------------------------------------------
1 | importScripts(
2 | '/uv/uv.bundle.js',
3 | '/uv/uv.config.js',
4 | '/scram/scramjet.wasm.js',
5 | '/scram/scramjet.shared.js',
6 | '/scram/scramjet.worker.js'
7 | );
8 | importScripts(__uv$config.sw || '/uv/uv.sw.js');
9 | const uv = new UVServiceWorker();
10 | const sj = new ScramjetServiceWorker();
11 | (async function () {
12 | await sj.loadConfig();
13 | })();
14 | self.addEventListener('fetch', function (event) {
15 | if (event.request.url.startsWith(location.origin + __uv$config.prefix)) {
16 | event.respondWith(
17 | (async function () {
18 | return await uv.fetch(event);
19 | })(),
20 | );
21 | }
22 | else if (sj.route(event)) {
23 | event.respondWith(
24 | (async function() {
25 | return await sj.fetch(event);
26 | })()
27 | );
28 | }
29 | else {
30 | event.respondWith(
31 | (async function () {
32 | return await fetch(event.request);
33 | })()
34 | );
35 | }
36 | });
37 |
38 | assets = [
39 | '/',
40 | '/favicon.ico',
41 | '/manifest.json',
42 | '/transports/bareTransport.js',
43 | 'sw.js',
44 | 'uv.config.js',
45 | 'logo.svg',
46 | ];
47 |
--------------------------------------------------------------------------------
/public/uv/uv.config.js:
--------------------------------------------------------------------------------
1 | self.__uv$config = {
2 | prefix: '/~/uv/',
3 | encodeUrl: function encode(str) {
4 | if (!str) return str;
5 | return encodeURIComponent(
6 | str
7 | .toString()
8 | .split('')
9 | .map((char, ind) => (ind % 2 ? String.fromCharCode(char.charCodeAt() ^ 3) : char))
10 | .join(''),
11 | );
12 | },
13 | decodeUrl: function decode(str) {
14 | if (!str) return str;
15 | let [input, ...search] = str.split('?');
16 |
17 | return (
18 | decodeURIComponent(input)
19 | .split('')
20 | .map((char, ind) => (ind % 2 ? String.fromCharCode(char.charCodeAt(0) ^ 3) : char))
21 | .join('') + (search.length ? '?' + search.join('?') : '')
22 | );
23 | },
24 | handler: '/uv/uv.handler.js',
25 | client: '/uv/uv.client.js',
26 | bundle: '/uv/uv.bundle.js',
27 | config: '/uv/uv.config.js',
28 | sw: '/uv/uv.sw.js',
29 | };
30 |
--------------------------------------------------------------------------------
/server/cli.ts:
--------------------------------------------------------------------------------
1 | // A basic CLI to provide a custom config.toml & to choose between the two servers.
2 | // Hono or Fastify
3 | import chalk from 'chalk';
4 | import gradient from 'npm:gradient-string';
5 | import { message, messageColors } from "./message.ts";
6 | import { parseArgs } from "jsr:@std/cli";
7 | import { startServer as HonoServer } from './standalone/standalone.ts';
8 | import { startServer as FastifyServer } from './full/server.ts';
9 | import { fromFileUrl } from 'jsr:@std/path';
10 | import ora, { Ora } from 'npm:ora';
11 |
12 | import packageJSON from "../package.json" with { type: 'json' };
13 | const { version } = packageJSON;
14 |
15 | interface CLIArgs {
16 | _: any[];
17 | help: boolean;
18 | };
19 |
20 | interface StartArgs extends CLIArgs {
21 | server: "full" | "standalone";
22 | config?: string;
23 | seo?: boolean;
24 | };
25 |
26 | interface UpgradeArgs extends CLIArgs {
27 | check: boolean;
28 | };
29 |
30 | interface DescriptionType {
31 | name: string;
32 | description: string;
33 | default?: string;
34 | };
35 |
36 | class CLI {
37 | #args: T;
38 | constructor(config: { booleans: string[], strings: string[] }) {
39 | this.#args = parseArgs(Deno.args, {
40 | boolean: config.booleans,
41 | string: config.strings
42 | }) as T;
43 | }
44 |
45 | #white(text: string) {
46 | return chalk.whiteBright.bold(text);
47 | }
48 |
49 | getArgs(): T {
50 | return this.#args;
51 | }
52 |
53 | help(descriptions?: DescriptionType[]) {
54 | console.log(chalk.whiteBright.bold('--help - Trigger this menu'));
55 | descriptions?.map((val) => console.log(`${this.#white('--')}${this.#white(val.name)} ${this.#white('-')} ${this.#white(val.description)} ${val.default ? this.#white(`(default: ${val.default})`) : ''}`))
56 | Deno.exit();
57 | }
58 |
59 | async start(fn: () => unknown) {
60 | await fn();
61 | }
62 | }
63 |
64 | console.log(gradient(Object.values(messageColors)).multiline(message));
65 | console.log(chalk.hex('#34b874')(`Welcome to the Incognito CLI!\nVersion: ${version}\n`));
66 |
67 | const cli = new CLI({
68 | booleans: [], strings: []
69 | });
70 |
71 | const args = cli.getArgs();
72 |
73 | if (args._.length !== 0 && args._[0] !== "upgrade") {
74 | console.log(chalk.redBright.bold(`The command ${args._[0]} is not available.\nPlease use a valid command`))
75 | Deno.exit();
76 | }
77 |
78 | if (args._[0] === "upgrade") {
79 | const upgradeCLI = new CLI({ booleans: ["check"], strings: [] });
80 | const uArgs = upgradeCLI.getArgs();
81 |
82 | const checkForVersion = async (checkFlag: boolean) => {
83 | const res = await fetch("https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/refs/heads/main/package.json");
84 | const resp = await res.json();
85 | if (resp.version !== version) {
86 | checkFlag ? console.log(chalk.greenBright.bold(`A new version is available! Re-run this command without --check to upgrade!`)): '';
87 | return resp.version;
88 | }
89 | else {
90 | console.log(chalk.redBright.bold('A new version is not available at this moment, check back later'));
91 | Deno.exit();
92 | }
93 | }
94 |
95 | if (uArgs.help) {
96 | upgradeCLI.help([
97 | { name: 'check', description: 'Check for a new version' }
98 | ]);
99 | }
100 |
101 | if (uArgs.check) {
102 | await checkForVersion(true);
103 | Deno.exit();
104 | }
105 |
106 | const download = async (version: string, spinner: Ora) => {
107 | const os = Deno.build.os;
108 | const arch = Deno.build.arch;
109 | if (os === "aix" || os === "netbsd" || os === "android" || os === "freebsd" || os === "solaris" || os === "illumos") {
110 | spinner.fail('Your OS is NOT supported! Exiting...');
111 | Deno.exit();
112 | }
113 | if (os === "darwin") {
114 | const res = await fetch(`https://github.com/titaniumnetwork-dev/incognito/releases/download/v${version}/incognito-MacOS${arch === "aarch64" ? '-arm': ''}`);
115 | const resp = await res.bytes();
116 | await Deno.writeFile(`incognito-MacOS${arch === "aarch64" ? '-arm': ''}`, resp, { mode: 0o775 });
117 | }
118 | else {
119 | const res = await fetch(`https://github.com/titaniumnetwork-dev/incognito/releases/download/v${version}/incognito-${os}${arch === "aarch64" ? '-arm': ''}`);
120 | const resp = await res.bytes();
121 | await Deno.writeFile(`incognito-${os}${arch === "aarch64" ? '-arm': ''}`, resp, { mode: 0o775 });
122 | }
123 | };
124 |
125 | await upgradeCLI.start(async () => {
126 | const version = await checkForVersion(false);
127 | const spinner = ora('Downloading...').start();
128 | await download(version, spinner);
129 | spinner.succeed('Upgraded!');
130 | });
131 |
132 | Deno.exit();
133 | }
134 |
135 | const startCLI = new CLI({
136 | booleans: ["help", "seo"], strings: ["config"]
137 | });
138 |
139 | const startArgs = startCLI.getArgs();
140 |
141 | if (startArgs.help || !startArgs.server) {
142 | startCLI.help([
143 | { name: "server [full|standalone]", description: "Select the server type", default: "full" },
144 | { name: "config [path]", description: "The path to a custom config", default: 'config.toml' },
145 | { name: "seo", description: "Enable SEO website regardless of the config file", default: 'false' }
146 | ]);
147 | }
148 |
149 | if (startArgs.config) {
150 | const path = await Deno.realPath(startArgs.config);
151 | startArgs.config = path;
152 | }
153 |
154 | if (startArgs.server !== "full" && startArgs.server !== "standalone") {
155 | console.log(chalk.redBright.bold(`Error with option --server!\nThe value: "${startArgs.server}" is not valid!\nThe only available options are: "full" or "standalone"`));
156 | }
157 |
158 | startCLI.start(async () => {
159 | startArgs.server === "standalone"
160 | ? await HonoServer(startArgs.config ?? fromFileUrl(new URL('../config.toml', import.meta.url)), startArgs.seo)
161 | : await FastifyServer(startArgs.config ?? fromFileUrl(new URL('../config.toml', import.meta.url)), startArgs.seo)
162 | });
163 |
--------------------------------------------------------------------------------
/server/config/config.ts:
--------------------------------------------------------------------------------
1 | import { parse } from "smol-toml";
2 |
3 | interface Data {
4 | buildOpts: {
5 | games: boolean;
6 | };
7 | server: {
8 | wisp: boolean;
9 | port: number;
10 | };
11 | seo: {
12 | enabled: boolean;
13 | domain: string;
14 | };
15 | }
16 |
17 | const config = async (configFile: string): Promise => {
18 | const doc = await Deno.readTextFile(configFile);
19 | const parsedDoc = parse(doc) as unknown as Data;
20 |
21 | if (typeof parsedDoc.buildOpts !== "object") {
22 | throw new Error(`Invalid structure: "buildOpts" should be an object`);
23 | }
24 | if (typeof parsedDoc.server !== "object") {
25 | throw new Error(`Invalid structure: "server" should be an object`);
26 | }
27 | if (typeof parsedDoc.buildOpts.games !== "boolean") {
28 | throw new Error(`Invalid type for "buildOpts.games"! It should be a boolean (true/false)`);
29 | }
30 | if (typeof parsedDoc.server.wisp !== "boolean") {
31 | throw new Error(`Invalid type for "server.wisp"! It should be a boolean (true/false)`);
32 | }
33 | if (typeof parsedDoc.server.port !== "number") {
34 | throw new Error(`Invalid type for "server.port"! It should be a number`);
35 | }
36 | if (typeof parsedDoc.seo.enabled !== "boolean") {
37 | throw new Error(`Invalid type for "seo.enabled"! It should be an boolean (true/false)`);
38 | }
39 | if (typeof parsedDoc.seo.domain !== "string") {
40 | throw new Error(`Invalid type for "seo.domain"! It should be an string`);
41 | } else {
42 | try {
43 | new URL(parsedDoc.seo.domain);
44 | } catch (e: any) {
45 | throw new Error(e);
46 | }
47 | }
48 | return parsedDoc;
49 | }
50 |
51 | export { type Data as TOMLConfig, config };
52 |
--------------------------------------------------------------------------------
/server/env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
--------------------------------------------------------------------------------
/server/full/server.ts:
--------------------------------------------------------------------------------
1 | import fastifyCompress from '@fastify/compress';
2 | import fastifyCookie from '@fastify/cookie';
3 | import fastifyHttpProxy from '@fastify/http-proxy';
4 | import fastifyMiddie from '@fastify/middie';
5 | import fastifyStatic from '@fastify/static';
6 | import Fastify from 'fastify';
7 | import { sFactory } from './serverFactory.ts';
8 | import { listeningMessage } from "../message.ts";
9 | import { config } from "../config/config.ts";
10 | import { fromFileUrl } from "jsr:@std/path";
11 |
12 | const startServer = async (configPath: string, seo?: boolean) => {
13 | const parsedDoc = await config(configPath);
14 | const serverFactory = await sFactory(configPath);
15 | const distPath = fromFileUrl(new URL('../../dist', import.meta.url));
16 | const app = Fastify({ logger: false, serverFactory: serverFactory });
17 |
18 | await app.register(fastifyCookie, {
19 | secret: Deno.env.get('COOKIE_SECRET') || 'yes',
20 | parseOptions: {}
21 | });
22 | await app.register(fastifyCompress, {
23 | encodings: ['br', 'gzip', 'deflate']
24 | });
25 |
26 | await app.register(fastifyStatic, {
27 | root: `${distPath}/noseo`,
28 | etag: false,
29 | lastModified: false
30 | });
31 | if (seo || parsedDoc.seo.enabled) {
32 | await app.register(fastifyStatic, {
33 | root: `${distPath}/seo`,
34 | constraints: { host: new URL(Deno.env.get('DOMAIN') || parsedDoc.seo.domain).host },
35 | etag: false,
36 | lastModified: false,
37 | decorateReply: false
38 | })
39 | }
40 |
41 | await app.register(fastifyMiddie);
42 | await app.register(fastifyHttpProxy, {
43 | upstream: 'https://rawcdn.githack.com/ruby-network/ruby-assets/main/',
44 | prefix: '/gms/',
45 | http2: false
46 | });
47 |
48 | const port = parseInt(Deno.env.get('PORT') as string) || parsedDoc.server.port || 8000;
49 |
50 | app.listen({ port: port, host: '0.0.0.0' }).then(() => {
51 | listeningMessage(port, "fastify");
52 | });
53 | }
54 |
55 | export { startServer }
56 |
--------------------------------------------------------------------------------
/server/full/serverFactory.ts:
--------------------------------------------------------------------------------
1 | import { createServer } from 'node:http';
2 | import { Socket } from 'node:net';
3 | import {
4 | type FastifyServerFactory,
5 | FastifyServerFactoryHandler,
6 | RawServerDefault,
7 | } from 'npm:fastify';
8 | import wisp from 'npm:wisp-server-node';
9 | import { config } from '../config/config.ts';
10 |
11 | const sFactory = async (configPath: string): Promise => {
12 | const parsedDoc = await config(configPath);
13 | const serverFactory: FastifyServerFactory = (handler: FastifyServerFactoryHandler): RawServerDefault => {
14 | return createServer()
15 | .on('request', (req, res) => {
16 | handler(req, res);
17 | })
18 | .on('upgrade', (req, socket, head) => {
19 | if (req.url?.endsWith('/wisp/') && parsedDoc.server.wisp === true) {
20 | wisp.routeRequest(req, socket as Socket, head);
21 | }
22 | });
23 | };
24 | return serverFactory;
25 | }
26 |
27 | export { sFactory };
28 |
--------------------------------------------------------------------------------
/server/message.ts:
--------------------------------------------------------------------------------
1 | import gradient from 'npm:gradient-string';
2 | import chalk from 'chalk';
3 | const message = `
4 | ___ _ _
5 | |_ _|_ __ ___ ___ _ __ (_) |_ ___
6 | | || '_ \\ / __/ _ \\| '_ \\| | __/ _ \\
7 | | || | | | (_| (_) | | | | | || (_) |
8 | |___|_| |_|\\___\\___/|_| |_|_|\\__\\___/
9 | `;
10 | const messageColors = {
11 | green: '#34b874',
12 | white: '#ffffff',
13 | blue: '#161923',
14 | };
15 |
16 | const listeningMessage = (port: number, server: 'fastify' | 'hono') => {
17 | console.log(
18 | `${chalk.hex('#34b874')('Server listening on')} ${
19 | chalk.white.bold('http://localhost:' + port)
20 | }`,
21 | );
22 | console.log(
23 | chalk.white.bold(
24 | `Server also listening on ${chalk.hex('#34b874').bold('http://0.0.0.0:' + port)}`,
25 | ),
26 | );
27 | console.log(
28 | chalk.hex('#34b874').bold(
29 | `The server in use ${
30 | server === 'fastify'
31 | ? chalk.bold.whiteBright('Fastify (Not Deno native, includes wisp server)')
32 | : chalk.bold.whiteBright('Hono (no wisp server, deno-native)')
33 | }`,
34 | ),
35 | );
36 | };
37 |
38 | export { listeningMessage, message, messageColors };
39 |
--------------------------------------------------------------------------------
/server/standalone/standalone.ts:
--------------------------------------------------------------------------------
1 | import { Hono } from 'jsr:@hono/hono';
2 | import { serveStatic } from 'jsr:@hono/hono/deno';
3 | import { compress } from 'jsr:@hono/hono/compress';
4 | import { listeningMessage } from '../message.ts';
5 | import { config } from '../config/config.ts';
6 | import { fromFileUrl } from 'jsr:@std/path';
7 |
8 | const startServer = async (configPath: string, seo?: boolean) => {
9 | const parsedDoc = await config(configPath);
10 | const app = new Hono();
11 | const distPath = fromFileUrl(new URL('../../dist', import.meta.url));
12 |
13 | app.use(compress({
14 | encoding: 'gzip',
15 | }));
16 |
17 | app.use('/*', (ctx, next) => {
18 | if (new URL(ctx.req.url).host === new URL(Deno.env.get('DOMAIN') || parsedDoc.seo.domain).host && seo || parsedDoc.seo.enabled) {
19 | return serveStatic({ root: `${distPath}/seo` })(ctx, next);
20 | }
21 | else {
22 | return serveStatic({ root: `${distPath}/noseo` })(ctx, next);
23 | }
24 | });
25 |
26 | Deno.serve({
27 | hostname: '0.0.0.0',
28 | port: parseInt(Deno.env.get('PORT') as string) || parsedDoc.server.port || 8000,
29 | onListen() {
30 | listeningMessage(parseInt(Deno.env.get('PORT') as string) || parsedDoc.server.port || 8000, 'hono');
31 | },
32 | }, app.fetch);
33 | }
34 |
35 | export { startServer }
36 |
--------------------------------------------------------------------------------
/src/assets/apps/coolmath.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/apps/coolmath.png
--------------------------------------------------------------------------------
/src/assets/apps/discord.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/apps/discord.jpg
--------------------------------------------------------------------------------
/src/assets/apps/gfnow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/apps/gfnow.png
--------------------------------------------------------------------------------
/src/assets/apps/google.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/apps/google.jpg
--------------------------------------------------------------------------------
/src/assets/apps/reddit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/apps/reddit.png
--------------------------------------------------------------------------------
/src/assets/apps/retroarch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/apps/retroarch.png
--------------------------------------------------------------------------------
/src/assets/apps/spotify.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/apps/spotify.png
--------------------------------------------------------------------------------
/src/assets/apps/tt.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/apps/tt.jpg
--------------------------------------------------------------------------------
/src/assets/apps/twitch.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/apps/twitch.jpg
--------------------------------------------------------------------------------
/src/assets/apps/twitter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/apps/twitter.png
--------------------------------------------------------------------------------
/src/assets/apps/y8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/apps/y8.png
--------------------------------------------------------------------------------
/src/assets/apps/yt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/apps/yt.png
--------------------------------------------------------------------------------
/src/assets/games/1v1-lol.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/1v1-lol.png
--------------------------------------------------------------------------------
/src/assets/games/2048.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/2048.png
--------------------------------------------------------------------------------
/src/assets/games/basketball-stars.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/basketball-stars.png
--------------------------------------------------------------------------------
/src/assets/games/binding-of-isaac.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/binding-of-isaac.jpeg
--------------------------------------------------------------------------------
/src/assets/games/bloons.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/bloons.webp
--------------------------------------------------------------------------------
/src/assets/games/bloonstd.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/bloonstd.jpg
--------------------------------------------------------------------------------
/src/assets/games/bloonstd2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/bloonstd2.png
--------------------------------------------------------------------------------
/src/assets/games/bloxors.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/bloxors.png
--------------------------------------------------------------------------------
/src/assets/games/cat-ninja.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/cat-ninja.png
--------------------------------------------------------------------------------
/src/assets/games/chromedino.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/chromedino.png
--------------------------------------------------------------------------------
/src/assets/games/cookieclicker.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/cookieclicker.jpg
--------------------------------------------------------------------------------
/src/assets/games/crossy-road.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/crossy-road.png
--------------------------------------------------------------------------------
/src/assets/games/cybertanks.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/cybertanks.png
--------------------------------------------------------------------------------
/src/assets/games/dadish-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/dadish-2.png
--------------------------------------------------------------------------------
/src/assets/games/dadish.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/dadish.png
--------------------------------------------------------------------------------
/src/assets/games/doodle-jump.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/doodle-jump.png
--------------------------------------------------------------------------------
/src/assets/games/ducklife.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/ducklife.webp
--------------------------------------------------------------------------------
/src/assets/games/ducklife2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/ducklife2.jpg
--------------------------------------------------------------------------------
/src/assets/games/ducklife3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/ducklife3.jpg
--------------------------------------------------------------------------------
/src/assets/games/eaglerx.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/eaglerx.webp
--------------------------------------------------------------------------------
/src/assets/games/emulatorjs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/emulatorjs.png
--------------------------------------------------------------------------------
/src/assets/games/flashtetris.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/flashtetris.png
--------------------------------------------------------------------------------
/src/assets/games/frogger.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/frogger.jpeg
--------------------------------------------------------------------------------
/src/assets/games/fruit-ninja.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/fruit-ninja.png
--------------------------------------------------------------------------------
/src/assets/games/fruitninja.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/fruitninja.jpg
--------------------------------------------------------------------------------
/src/assets/games/geometrydash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/geometrydash.png
--------------------------------------------------------------------------------
/src/assets/games/gm2.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/gm2.jpeg
--------------------------------------------------------------------------------
/src/assets/games/gpacman.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/gpacman.jpg
--------------------------------------------------------------------------------
/src/assets/games/hardestgame.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/hardestgame.jpg
--------------------------------------------------------------------------------
/src/assets/games/hexgl.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/hexgl.jpg
--------------------------------------------------------------------------------
/src/assets/games/mario.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/mario.webp
--------------------------------------------------------------------------------
/src/assets/games/miniagario.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/miniagario.png
--------------------------------------------------------------------------------
/src/assets/games/moke.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/moke.png
--------------------------------------------------------------------------------
/src/assets/games/monkey-mart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/monkey-mart.png
--------------------------------------------------------------------------------
/src/assets/games/pacman.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/pacman.jpg
--------------------------------------------------------------------------------
/src/assets/games/paper.io2.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/paper.io2.webp
--------------------------------------------------------------------------------
/src/assets/games/portaltheflashversion.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/portaltheflashversion.jpg
--------------------------------------------------------------------------------
/src/assets/games/retrobowl.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/retrobowl.jpg
--------------------------------------------------------------------------------
/src/assets/games/riddleschool.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/riddleschool.webp
--------------------------------------------------------------------------------
/src/assets/games/riddleschool2.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/riddleschool2.webp
--------------------------------------------------------------------------------
/src/assets/games/riddleschool3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/riddleschool3.jpg
--------------------------------------------------------------------------------
/src/assets/games/riddleschool4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/riddleschool4.jpg
--------------------------------------------------------------------------------
/src/assets/games/riddleschool5.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/riddleschool5.webp
--------------------------------------------------------------------------------
/src/assets/games/run3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/run3.png
--------------------------------------------------------------------------------
/src/assets/games/shellshock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/shellshock.png
--------------------------------------------------------------------------------
/src/assets/games/slitherio.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/slitherio.webp
--------------------------------------------------------------------------------
/src/assets/games/slope-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/slope-2.png
--------------------------------------------------------------------------------
/src/assets/games/slope.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/slope.jpg
--------------------------------------------------------------------------------
/src/assets/games/snake.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/snake.png
--------------------------------------------------------------------------------
/src/assets/games/ssf.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/ssf.jpeg
--------------------------------------------------------------------------------
/src/assets/games/stack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/stack.png
--------------------------------------------------------------------------------
/src/assets/games/sticmanhook.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/sticmanhook.jpg
--------------------------------------------------------------------------------
/src/assets/games/stuntcars2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/stuntcars2.png
--------------------------------------------------------------------------------
/src/assets/games/stuntcars3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/stuntcars3.jpg
--------------------------------------------------------------------------------
/src/assets/games/subway-surfers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/subway-surfers.png
--------------------------------------------------------------------------------
/src/assets/games/superhot.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/superhot.webp
--------------------------------------------------------------------------------
/src/assets/games/supermario64.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/supermario64.jpeg
--------------------------------------------------------------------------------
/src/assets/games/tanktrouble.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/tanktrouble.webp
--------------------------------------------------------------------------------
/src/assets/games/tanuki.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/tanuki.jpg
--------------------------------------------------------------------------------
/src/assets/games/templerun2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/templerun2.jpg
--------------------------------------------------------------------------------
/src/assets/games/the-worlds-hardest-game-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/the-worlds-hardest-game-2.jpg
--------------------------------------------------------------------------------
/src/assets/games/tunnel-rush.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/tunnel-rush.jpg
--------------------------------------------------------------------------------
/src/assets/games/vex3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/vex3.png
--------------------------------------------------------------------------------
/src/assets/games/vex4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/vex4.png
--------------------------------------------------------------------------------
/src/assets/games/vex5.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/vex5.jpeg
--------------------------------------------------------------------------------
/src/assets/games/vex6.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/vex6.jpeg
--------------------------------------------------------------------------------
/src/assets/games/vex7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/vex7.png
--------------------------------------------------------------------------------
/src/assets/games/watermelon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/watermelon.png
--------------------------------------------------------------------------------
/src/assets/games/webretro.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/webretro.png
--------------------------------------------------------------------------------
/src/assets/games/yohoho.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/titaniumnetwork-dev/Incognito/b386547f3285e9b15668f3ebd5c3bbdfbb196c24/src/assets/games/yohoho.jpeg
--------------------------------------------------------------------------------
/src/components/FrameManager.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import { Icon } from 'astro-icon/components';
3 | ---
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
61 |
--------------------------------------------------------------------------------
/src/components/Header.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import { Icon } from 'astro-icon/components';
3 | const { pageName, pageLocation } = Astro.props;
4 | ---
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | {pageName}
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/components/MobileNav.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import { Icon } from 'astro-icon/components';
3 | const { options, page } = Astro.props;
4 | import { GAMES_LINK } from 'astro:env/client';
5 | ---
6 |
7 |
8 |
9 |
10 |
11 |
29 |
39 |
--------------------------------------------------------------------------------
/src/components/NavLinks.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import { GAMES_LINK } from 'astro:env/client';
3 | import NavMenu from '@components/MobileNav.astro';
4 | import { Icon } from 'astro-icon/components';
5 | ---
6 |
32 |
--------------------------------------------------------------------------------
/src/components/Scripts.astro:
--------------------------------------------------------------------------------
1 |
57 |
--------------------------------------------------------------------------------
/src/components/Search.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import { Icon } from 'astro-icon/components';
3 | import FrameManager from '@components/FrameManager.astro';
4 | ---
5 |
6 |
115 |
--------------------------------------------------------------------------------
/src/components/settings/Loader.astro:
--------------------------------------------------------------------------------
1 |
28 |
--------------------------------------------------------------------------------
/src/data/games.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "img": "/src/assets/games/tanuki.jpg",
4 | "baseFile": "index.html",
5 | "name": "Tanuki Sunset",
6 | "tags": ["arcade", "platformer", "static"],
7 | "cdn": "true",
8 | "proxy": "false",
9 | "url": ""
10 | },
11 | {
12 | "img": "/src/assets/games/tunnel-rush.jpg",
13 | "baseFile": "index.html",
14 | "name": "Tunnel Rush",
15 | "tags": ["arcade", "platformer", "static"],
16 | "cdn": "true",
17 | "proxy": "false",
18 | "url": ""
19 | },
20 | {
21 | "img": "/src/assets/games/stuntcars2.png",
22 | "baseFile": "index.html",
23 | "name": "Madalin Stunt Cars 2",
24 | "tags": ["racing", "static"],
25 | "cdn": "true",
26 | "proxy": "false",
27 | "url": ""
28 | },
29 | {
30 | "img": "/src/assets/games/moke.png",
31 | "baseFile": "index.html",
32 | "name": "Spank The Monkey",
33 | "tags": ["arcade", "flash", "static"],
34 | "cdn": "true",
35 | "proxy": "false",
36 | "url": ""
37 | },
38 | {
39 | "img": "/src/assets/games/slope.jpg",
40 | "baseFile": "index.html",
41 | "name": "Slope",
42 | "tags": ["arcade", "platformer", "static"],
43 | "cdn": "true",
44 | "proxy": "false",
45 | "url": ""
46 | },
47 | {
48 | "img": "/src/assets/games/run3.png",
49 | "baseFile": "index.html",
50 | "name": "Run 3",
51 | "tags": ["arcade", "adventure", "platformer", "static"],
52 | "cdn": "true",
53 | "proxy": "false",
54 | "url": ""
55 | },
56 | {
57 | "img": "/src/assets/games/pacman.jpg",
58 | "baseFile": "index.html",
59 | "name": "Pacman",
60 | "tags": ["arcade", "multiplayer", "static"],
61 | "cdn": "true",
62 | "proxy": "false",
63 | "url": ""
64 | },
65 | {
66 | "img": "/src/assets/games/hexgl.jpg",
67 | "baseFile": "index.html",
68 | "name": "HexGL",
69 | "tags": ["racing", "static"],
70 | "cdn": "true",
71 | "proxy": "false",
72 | "url": ""
73 | },
74 | {
75 | "img": "/src/assets/games/snake.png",
76 | "baseFile": "index.html",
77 | "name": "Google Snake",
78 | "tags": ["arcade", "static"],
79 | "cdn": "true",
80 | "proxy": "false",
81 | "url": ""
82 | },
83 | {
84 | "img": "/src/assets/games/gpacman.jpg",
85 | "baseFile": "index.html",
86 | "name": "Google Pacman",
87 | "tags": ["arcade", "static"],
88 | "cdn": "true",
89 | "proxy": "false",
90 | "url": ""
91 | },
92 | {
93 | "img": "/src/assets/games/mario.webp",
94 | "baseFile": "index.html",
95 | "name": "Super Mario Bros.",
96 | "tags": ["arcade", "adventure", "retro", "platformer", "emulation"],
97 | "cdn": "true",
98 | "proxy": "false",
99 | "url": ""
100 | },
101 | {
102 | "img": "/src/assets/games/ducklife.webp",
103 | "baseFile": "index.html",
104 | "name": "DuckLife",
105 | "tags": ["arcade", "static"],
106 | "cdn": "tru",
107 | "proxy": "false",
108 | "url": ""
109 | },
110 | {
111 | "img": "/src/assets/games/ducklife2.jpg",
112 | "baseFile": "index.html",
113 | "name": "DuckLife 2",
114 | "tags": ["arcade", "static"],
115 | "cdn": "true",
116 | "proxy": "false",
117 | "url": ""
118 | },
119 | {
120 | "img": "/src/assets/games/ducklife3.jpg",
121 | "baseFile": "index.html",
122 | "name": "DuckLife 3",
123 | "tags": ["arcade", "static"],
124 | "cdn": "true",
125 | "proxy": "false",
126 | "url": ""
127 | },
128 | {
129 | "img": "/src/assets/games/chromedino.png",
130 | "baseFile": "index.html",
131 | "name": "Google Dino Game",
132 | "tags": ["arcade", "static"],
133 | "cdn": "true",
134 | "proxy": "false",
135 | "url": ""
136 | },
137 | {
138 | "img": "/src/assets/games/cookieclicker.jpg",
139 | "baseFile": "index.html",
140 | "name": "Cookie Clicker",
141 | "tags": ["arcade", "static"],
142 | "cdn": "true",
143 | "proxy": "false",
144 | "url": ""
145 | },
146 | {
147 | "img": "/src/assets/games/retrobowl.jpg",
148 | "baseFile": "index.html",
149 | "name": "Retro Bowl",
150 | "tags": ["arcade", "sports", "static"],
151 | "cdn": "true",
152 | "proxy": "false",
153 | "url": ""
154 | },
155 | {
156 | "img": "/src/assets/games/riddleschool.webp",
157 | "baseFile": "index.html",
158 | "name": "Riddle School",
159 | "tags": ["arcade", "adventure", "strategy", "static"],
160 | "cdn": "true",
161 | "proxy": "false",
162 | "url": ""
163 | },
164 | {
165 | "img": "/src/assets/games/riddleschool2.webp",
166 | "baseFile": "index.html",
167 | "name": "Riddle School 2",
168 | "tags": ["arcade", "adventure", "strategy", "static"],
169 | "cdn": "true",
170 | "proxy": "false",
171 | "url": ""
172 | },
173 | {
174 | "img": "/src/assets/games/riddleschool3.jpg",
175 | "baseFile": "index.html",
176 | "name": "Riddle School 3",
177 | "tags": ["arcade", "adventure", "strategy", "static"],
178 | "cdn": "true",
179 | "proxy": "false",
180 | "url": ""
181 | },
182 | {
183 | "img": "/src/assets/games/riddleschool4.jpg",
184 | "baseFile": "index.html",
185 | "name": "Riddle School 4",
186 | "tags": ["arcade", "adventure", "strategy", "static"],
187 | "cdn": "true",
188 | "proxy": "false",
189 | "url": ""
190 | },
191 | {
192 | "img": "/src/assets/games/riddleschool5.webp",
193 | "baseFile": "index.html",
194 | "name": "Riddle School 5",
195 | "tags": ["arcade", "adventure", "strategy", "static"],
196 | "cdn": "true",
197 | "proxy": "false",
198 | "url": ""
199 | },
200 | {
201 | "img": "/src/assets/games/superhot.webp",
202 | "baseFile": "index.html",
203 | "name": "SuperHot",
204 | "tags": ["arcade", "shooter", "static"],
205 | "cdn": "true",
206 | "proxy": "false",
207 | "url": ""
208 | },
209 | {
210 | "img": "/src/assets/games/tanktrouble.webp",
211 | "baseFile": "index.html",
212 | "name": "Tank Trouble 2",
213 | "tags": ["arcade", "shooter", "strategy", "static"],
214 | "cdn": "true",
215 | "proxy": "false",
216 | "url": ""
217 | },
218 | {
219 | "img": "/src/assets/games/templerun2.jpg",
220 | "baseFile": "index.html",
221 | "name": "Temple Run 2",
222 | "tags": ["arcade", "adventure", "static"],
223 | "cdn": "true",
224 | "proxy": "false",
225 | "url": ""
226 | },
227 | {
228 | "img": "/src/assets/games/flashtetris.png",
229 | "baseFile": "index.html",
230 | "name": "Flash Tetris",
231 | "tags": ["arcade", "strategy", "retro", "static"],
232 | "cdn": "true",
233 | "proxy": "false",
234 | "url": ""
235 | },
236 | {
237 | "img": "/src/assets/games/emulatorjs.png",
238 | "baseFile": "index.html",
239 | "name": "EmulatorJS",
240 | "tags": ["arcade", "strategy", "retro", "emulation"],
241 | "cdn": "true",
242 | "proxy": "false",
243 | "url": ""
244 | },
245 | {
246 | "img": "/src/assets/games/webretro.png",
247 | "baseFile": "index.html",
248 | "name": "WebRetro",
249 | "tags": ["arcade", "strategy", "retro", "emulation"],
250 | "cdn": "true",
251 | "proxy": "false",
252 | "url": ""
253 | },
254 | {
255 | "img": "/src/assets/games/bloons.webp",
256 | "baseFile": "index.html",
257 | "name": "Bloons",
258 | "tags": ["arcade", "strategy", "static"],
259 | "cdn": "true",
260 | "proxy": "false",
261 | "url": ""
262 | },
263 | {
264 | "img": "/src/assets/games/bloonstd.jpg",
265 | "baseFile": "index.html",
266 | "name": "Bloons TD",
267 | "tags": ["arcade", "strategy", "static"],
268 | "cdn": "true",
269 | "proxy": "false",
270 | "url": ""
271 | },
272 | {
273 | "img": "/src/assets/games/bloonstd2.png",
274 | "baseFile": "index.html",
275 | "name": "Bloons TD 2",
276 | "tags": ["arcade", "strategy", "static"],
277 | "cdn": "true",
278 | "proxy": "false",
279 | "url": ""
280 | },
281 | {
282 | "img": "/src/assets/games/2048.png",
283 | "baseFile": "index.html",
284 | "name": "2048",
285 | "tags": ["arcade", "strategy", "static"],
286 | "cdn": "true",
287 | "proxy": "false",
288 | "url": ""
289 | },
290 | {
291 | "img": "/src/assets/games/bloxors.png",
292 | "baseFile": "index.html",
293 | "name": "Bloxors",
294 | "tags": ["arcade", "strategy", "static"],
295 | "cdn": "true",
296 | "proxy": "false",
297 | "url": ""
298 | },
299 | {
300 | "img": "/src/assets/games/geometrydash.png",
301 | "baseFile": "index.html",
302 | "name": "Geometry Dash",
303 | "tags": ["arcade", "static"],
304 | "cdn": "true",
305 | "proxy": "false",
306 | "url": ""
307 | },
308 | {
309 | "img": "/src/assets/games/sticmanhook.jpg",
310 | "baseFile": "index.html",
311 | "name": "Stickman Hook",
312 | "tags": ["arcade", "platformer", "static"],
313 | "cdn": "true",
314 | "proxy": "false",
315 | "url": ""
316 | },
317 | {
318 | "img": "/src/assets/games/vex3.png",
319 | "baseFile": "index.html",
320 | "name": "Vex 3",
321 | "tags": ["arcade", "platformer", "static"],
322 | "cdn": "true",
323 | "proxy": "false",
324 | "url": ""
325 | },
326 | {
327 | "img": "/src/assets/games/vex4.png",
328 | "baseFile": "index.html",
329 | "name": "Vex 4",
330 | "tags": ["arcade", "platformer", "static"],
331 | "cdn": "true",
332 | "proxy": "false",
333 | "url": ""
334 | },
335 | {
336 | "img": "/src/assets/games/vex5.jpeg",
337 | "baseFile": "index.html",
338 | "name": "Vex 5",
339 | "tags": ["arcade", "platformer", "static"],
340 | "cdn": "true",
341 | "proxy": "false",
342 | "url": ""
343 | },
344 | {
345 | "img": "/src/assets/games/vex6.jpeg",
346 | "baseFile": "index.html",
347 | "name": "Vex 6",
348 | "tags": ["arcade", "platformer", "static"],
349 | "cdn": "true",
350 | "proxy": "false",
351 | "url": ""
352 | },
353 | {
354 | "img": "/src/assets/games/vex7.png",
355 | "baseFile": "index.html",
356 | "name": "Vex 7",
357 | "tags": ["arcade", "platformer", "static"],
358 | "cdn": "true",
359 | "proxy": "false",
360 | "url": ""
361 | },
362 | {
363 | "img": "/src/assets/games/stuntcars3.jpg",
364 | "baseFile": "index.html",
365 | "name": "Madalin Stunt Cars 3",
366 | "tags": ["arcade", "racing", "static"],
367 | "cdn": "true",
368 | "proxy": "false",
369 | "url": ""
370 | },
371 | {
372 | "img": "/src/assets/games/hardestgame.jpg",
373 | "baseFile": "index.html",
374 | "name": "Worlds Hardest Game",
375 | "tags": ["arcade", "strategy", "static"],
376 | "cdn": "true",
377 | "proxy": "false",
378 | "url": ""
379 | },
380 | {
381 | "img": "/src/assets/games/portaltheflashversion.jpg",
382 | "baseFile": "index.html",
383 | "name": "Portal Flash",
384 | "tags": ["arcade", "strategy", "static"],
385 | "cdn": "true",
386 | "proxy": "false",
387 | "url": ""
388 | },
389 | {
390 | "img": "/src/assets/games/crossy-road.png",
391 | "baseFile": "index.html",
392 | "name": "Crossy Road",
393 | "tags": ["arcade", "platformer", "static"],
394 | "cdn": "true",
395 | "proxy": "false",
396 | "url": ""
397 | },
398 | {
399 | "img": "/src/assets/games/subway-surfers.png",
400 | "baseFile": "index.html",
401 | "name": "Subway Surfers",
402 | "tags": ["arcade", "platformer", "static"],
403 | "cdn": "true",
404 | "proxy": "false",
405 | "url": ""
406 | },
407 | {
408 | "img": "/src/assets/games/dadish.png",
409 | "baseFile": "index.html",
410 | "name": "Dadish",
411 | "tags": ["arcade", "platformer", "static"],
412 | "cdn": "true",
413 | "proxy": "false",
414 | "url": ""
415 | },
416 | {
417 | "img": "/src/assets/games/dadish-2.png",
418 | "baseFile": "index.html",
419 | "name": "Dadish 2",
420 | "tags": ["arcade", "platformer", "static"],
421 | "cdn": "true",
422 | "proxy": "false",
423 | "url": ""
424 | },
425 | {
426 | "img": "/src/assets/games/doodle-jump.png",
427 | "baseFile": "index.html",
428 | "name": "Doodle Jump",
429 | "tags": ["arcade", "platformer", "static"],
430 | "cdn": "true",
431 | "proxy": "false",
432 | "url": ""
433 | },
434 | {
435 | "img": "/src/assets/games/fruit-ninja.png",
436 | "baseFile": "index.html",
437 | "name": "Fruit Ninja",
438 | "tags": ["arcade", "static"],
439 | "cdn": "true",
440 | "proxy": "false",
441 | "url": ""
442 | },
443 | {
444 | "img": "/src/assets/games/basketball-stars.png",
445 | "baseFile": "index.html",
446 | "name": "Basketball Stars",
447 | "tags": ["arcade", "static"],
448 | "cdn": "true",
449 | "proxy": "false",
450 | "url": ""
451 | },
452 | {
453 | "img": "/src/assets/games/slope-2.png",
454 | "baseFile": "index.html",
455 | "name": "Slope 2",
456 | "tags": ["arcade", "platformer", "multiplayer", "static"],
457 | "cdn": "true",
458 | "proxy": "false",
459 | "url": ""
460 | },
461 | {
462 | "img": "/src/assets/games/stack.png",
463 | "baseFile": "index.html",
464 | "name": "Stack",
465 | "tags": ["static", "strategy"],
466 | "cdn": "true",
467 | "proxy": "false",
468 | "url": ""
469 | },
470 | {
471 | "img": "/src/assets/games/1v1-lol.png",
472 | "baseFile": "none",
473 | "name": "1v1.lol",
474 | "tags": ["multiplayer", "strategy", "proxied"],
475 | "cdn": "false",
476 | "proxy": "true",
477 | "url": "https://1v1.lol"
478 | },
479 | {
480 | "img": "/src/assets/games/shellshock.png",
481 | "baseFile": "none",
482 | "name": "Shell Shockers",
483 | "tags": ["multiplayer", "strategy", "proxied"],
484 | "cdn": "false",
485 | "proxy": "true",
486 | "url": "https://shellshock.io"
487 | },
488 | {
489 | "img": "/src/assets/games/binding-of-isaac.jpeg",
490 | "baseFile": "index.html",
491 | "name": "The Binding of Isaac",
492 | "tags": ["arcade", "strategy", "shooter", "flash", "static"],
493 | "cdn": "true",
494 | "proxy": "false",
495 | "url": ""
496 | },
497 | {
498 | "img": "/src/assets/games/eaglerx.webp",
499 | "baseFile": "index.html",
500 | "name": "EaglerCraft X",
501 | "tags": ["static", "sandbox", "multiplayer"],
502 | "cdn": "true",
503 | "proxy": "false",
504 | "url": ""
505 | },
506 | {
507 | "img": "/src/assets/games/miniagario.png",
508 | "baseFile": "dots.html",
509 | "name": "Mini Agario",
510 | "tags": ["static", "arcade", "strategy"],
511 | "cdn": "true",
512 | "proxy": "false",
513 | "url": ""
514 | },
515 | {
516 | "img": "/src/assets/games/yohoho.jpeg",
517 | "baseFile": "",
518 | "name": "YoHoHo",
519 | "tags": ["multiplayer", "strategy", "proxied"],
520 | "cdn": "false",
521 | "proxy": "true",
522 | "url": "https://yohoho.io"
523 | },
524 | {
525 | "img": "/src/assets/games/paper.io2.webp",
526 | "baseFile": "",
527 | "name": "Paper.io 2",
528 | "tags": ["multiplayer", "strategy", "proxied"],
529 | "cdn": "false",
530 | "proxy": "true",
531 | "url": "https://paper-io.com/"
532 | },
533 | {
534 | "img": "/src/assets/games/frogger.jpeg",
535 | "baseFile": "index.html",
536 | "name": "Frogger",
537 | "tags": ["arcade", "platformer", "retro", "static"],
538 | "cdn": "true",
539 | "proxy": "false",
540 | "url": ""
541 | },
542 | {
543 | "img": "/src/assets/games/supermario64.jpeg",
544 | "baseFile": "index.html",
545 | "name": "Super Mario 64",
546 | "tags": ["arcade", "platformer", "retro", "emulation"],
547 | "cdn": "true",
548 | "proxy": "false",
549 | "url": ""
550 | },
551 | {
552 | "img": "/src/assets/games/cybertanks.png",
553 | "baseFile": "",
554 | "name": "CyberTanks",
555 | "tags": ["multiplayer", "strategy", "proxied"],
556 | "cdn": "false",
557 | "proxy": "true",
558 | "url": "https://xigency.herokuapp.com/"
559 | },
560 | {
561 | "img": "/src/assets/games/slitherio.webp",
562 | "baseFile": "",
563 | "name": "Slither.io",
564 | "tags": ["multiplayer", "strategy", "proxied"],
565 | "cdn": "false",
566 | "proxy": "true",
567 | "url": "http://slither.io"
568 | },
569 | {
570 | "img": "/src/assets/games/cat-ninja.png",
571 | "baseFile": "index.html",
572 | "name": "Cat Ninja",
573 | "tags": ["arcade", "static"],
574 | "cdn": "true",
575 | "proxy": "false",
576 | "url": ""
577 | },
578 | {
579 | "img": "/src/assets/games/gm2.jpeg",
580 | "baseFile": "index.html",
581 | "name": "Gun Mayhem 2",
582 | "tags": ["arcade", "shooter", "static"],
583 | "cdn": "true",
584 | "proxy": "false",
585 | "url": ""
586 | },
587 | {
588 | "img": "/src/assets/games/ssf.jpeg",
589 | "baseFile": "index.html",
590 | "name": "Super Smash Flash",
591 | "tags": ["arcade", "shooter", "static"],
592 | "cdn": "true",
593 | "proxy": "false",
594 | "url": ""
595 | },
596 | {
597 | "img": "/src/assets/games/monkey-mart.png",
598 | "baseFile": "index.html",
599 | "name": "Monkey Mart",
600 | "tags": ["arcade"],
601 | "cdn": "true",
602 | "proxy": "false",
603 | "url": ""
604 | },
605 | {
606 | "img": "/src/assets/games/watermelon.png",
607 | "baseFile": "index.html",
608 | "name": "Watermelon Game",
609 | "tags": ["arcade"],
610 | "cdn": "true",
611 | "proxy": "false",
612 | "url": ""
613 | }
614 | ]
615 |
--------------------------------------------------------------------------------
/src/env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 | ///
4 | ///
5 | declare var search: (input: string, template: string) => any;
6 | type Suggestion = {
7 | phrase: string;
8 | };
9 | declare var BareMux: any;
10 | declare var EpxMod: any;
11 | declare var ScramjetController: any;
12 | declare var $scramjet: any;
13 |
--------------------------------------------------------------------------------
/src/global.d.ts:
--------------------------------------------------------------------------------
1 | declare global {
2 | interface Window {
3 | openApp(url: string): void;
4 | searchApps(val: string): void;
5 | setTheme(val: string): void;
6 | setProxy(val: string): void;
7 | transport(val: string): void;
8 | changeTitle(val: string): void;
9 | changeFavicon(val: string): void;
10 | searchGames(val: string): void;
11 | fullScreenGame(val: string): void;
12 | loadProxyScripts(): Promise;
13 | setTransport(transport: string): Promise;
14 | loadMobileNav(): void;
15 | closeMobileNav(): void;
16 | createLink(): void;
17 | exitIframe(): void;
18 | refreshIframe(): void;
19 | setTitle(): void;
20 | __uv: any;
21 | __get$ProxyUrl: any;
22 | $scramjet: any;
23 | }
24 | }
25 |
26 | export {};
27 |
--------------------------------------------------------------------------------
/src/layouts/Layout.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import { SEO } from 'astro-seo';
3 | import { SEO as SEOConf } from "astro:env/client";
4 |
5 | interface Props {
6 | title?: string;
7 | redirect?: {
8 | path: string;
9 | interval: number;
10 | }
11 | }
12 | const { title, redirect } = Astro.props;
13 | import { ClientRouter } from 'astro:transitions';
14 | import LoadScripts from '@components/Scripts.astro';
15 | import SettingsLoader from '@components/settings/Loader.astro';
16 | ---
17 |
18 |
19 |
20 |
21 |
22 |
63 | {redirect !== undefined && }
64 |
65 |
66 |
67 |
146 |
147 |
148 |
149 |
--------------------------------------------------------------------------------
/src/pages/apps.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import { Image } from 'astro:assets';
3 | import Layout from '@layouts/Layout.astro';
4 | import type { ImageMetadata } from 'astro';
5 | import { Icon } from 'astro-icon/components';
6 | const images = import.meta.glob<{ default: ImageMetadata }>(
7 | '/src/assets/apps/*.{jpeg,jpg,png,gif}'
8 | );
9 | ---
10 |
11 |
12 |
13 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
86 |
87 |
--------------------------------------------------------------------------------
/src/pages/community.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import Header from '@components/Header.astro';
3 | import Layout from '@layouts/Layout.astro';
4 | ---
5 |
6 |
7 |
8 |
9 |
You are being taken to another website (discord.gg/unblock)
10 |
11 | Are you sure you want to proceed ?
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/pages/gs/[game].astro:
--------------------------------------------------------------------------------
1 | ---
2 | import type { GetStaticPaths } from 'astro';
3 | import games from '../../data/games.json';
4 | const { game } = Astro.params;
5 | import { GAMES_LINK } from 'astro:env/client';
6 | import Layout from '@layouts/Layout.astro';
7 | import { Icon } from 'astro-icon/components';
8 | function decode(val: string) {
9 | try {
10 | return atob(val);
11 | } catch (_) {}
12 | }
13 | if (!GAMES_LINK) {
14 | return Astro.redirect('/');
15 | }
16 | interface Game {
17 | params: { game: string };
18 | }
19 | export const getStaticPaths = (async () => {
20 | const gamesList: Game[] = games.map((game) => ({
21 | params: { game: btoa(game.name) },
22 | }));
23 | return gamesList;
24 | }) satisfies GetStaticPaths;
25 | ---
26 |
27 |
28 |
29 |
30 |
35 |
36 |
37 |
38 | {decode(game as string)}
39 |
40 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
111 |
112 |
--------------------------------------------------------------------------------
/src/pages/gs/index.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import { Image } from 'astro:assets';
3 | import { GAMES_LINK } from 'astro:env/client';
4 | import Layout from '@layouts/Layout.astro';
5 | import type { ImageMetadata } from 'astro';
6 | import { Icon } from 'astro-icon/components';
7 | import games from "../../data/games.json";
8 | const images = import.meta.glob<{ default: ImageMetadata }>(
9 | '/src/assets/games/*.{jpeg,jpg,png,gif,webp}'
10 | );
11 | ---
12 |
13 |
14 | {GAMES_LINK &&
15 |
23 |
24 | {games.map((game) => (
25 |
26 |
27 |
28 | ))}
29 |
30 | }
31 |
32 |
33 |
55 |
--------------------------------------------------------------------------------
/src/pages/index.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import Links from '@components/NavLinks.astro';
3 | import Search from '@components/Search.astro';
4 | import Layout from '@layouts/Layout.astro';
5 | ---
6 |
7 |
8 |
9 |
10 |
11 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/pages/load.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import Layout from '@layouts/Layout.astro';
3 | ---
4 |
5 |
6 |
7 |
8 | Please wait a moment. Our service maybe under high load causing some slowness on our
9 | servers. Your request will eventually be responded to.
10 |
11 |
12 |
38 |
39 |
--------------------------------------------------------------------------------
/src/pages/options/about.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import NavMenu from '@components/MobileNav.astro';
3 | import Layout from '@layouts/Layout.astro';
4 | import { Icon } from 'astro-icon/components';
5 | ---
6 |
7 |
8 |
9 |
10 |
18 |
38 |
39 |
40 |
41 |
42 |
43 |
About Incognito
44 |
45 | Access the world wide web, Incognito is an anti-censorship web service.
46 |
47 |
48 |
49 |
94 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/src/pages/options/bt.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import NavMenu from '@components/MobileNav.astro';
3 | import Layout from '@layouts/Layout.astro';
4 | import { Icon } from 'astro-icon/components';
5 | ---
6 |
7 |
8 |
9 |
10 |
18 |
23 |
24 |
25 |
26 |
27 |
28 |
Tab Title
29 |
30 |
Change the title of Incognito's browser tab title
31 |
32 |
33 |
Tab Icon
34 |
35 |
Change the icon of Incognito's browser tab. To change it into something like Google, type in "https://www.google.com/favicon.ico"
36 |
37 |
38 |
39 |
71 |
72 |
--------------------------------------------------------------------------------
/src/pages/options/index.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import NavMenu from '@components/MobileNav.astro';
3 | import Layout from '@layouts/Layout.astro';
4 | import { Icon } from 'astro-icon/components';
5 | ---
6 |
7 |
8 |
9 |
17 |
34 |
35 |
36 |
37 |
38 |
89 |
90 |
Proxy
91 |
94 |
95 |
100 | Ultraviolet
101 |
102 |
107 | Scramjet (BETA, MAY BREAK)
108 |
109 |
110 |
111 |
112 |
113 |
Transport
114 |
117 |
118 |
123 | Epoxy
124 |
125 |
130 | Libcurl.js
131 |
132 |
133 |
134 |
135 |
136 |
137 |
178 |
179 |
--------------------------------------------------------------------------------
/src/pages/support.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import Header from '@components/Header.astro';
3 | import Layout from '@layouts/Layout.astro';
4 | ---
5 |
6 |
7 |
8 |
9 |
A page is not functioning or loading on the proxy
11 |
12 | Our web servers are either under really high load, or the web page you tried
13 | accessing is not currently supported.
14 |
15 |
16 |
17 |
29 |
30 |
31 |
Where can I obtain more links to Incognito
33 |
34 | Links to incognito can be generated at Titanium Network
40 |
41 |
42 |
43 |
44 |
45 |
Why is GeForce Now is responding with "403 Access Denied"
47 |
48 | At the moment, too many people are using GeForce Now on our servers. Try again
49 | later.
50 |
51 |
52 |
53 |
54 |
Google login is saying this app is insecure
56 |
57 | At the moment, Google login is not supported for @gmail accounts. However, it is
58 | supported for GSuite accounts (School / work email).
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/src/ts/serviceWorker.ts:
--------------------------------------------------------------------------------
1 | function initServiceWorker() {
2 | return new Promise((resolve) => {
3 | if ('serviceWorker' in navigator) {
4 | console.log('OOGOGOGOGO');
5 | //@ts-ignore these are a fucking thing
6 | //wait for the scripts to load
7 | const scram = window.loadProxyScripts().then(async (): typeof ScramjetController => {
8 | const scramjet = new ScramjetController({
9 | prefix: "/~/scramjet/",
10 | files: {
11 | wasm: "/scram/scramjet.wasm.js",
12 | worker: "/scram/scramjet.worker.js",
13 | client: "/scram/scramjet.client.js",
14 | shared: "/scram/scramjet.shared.js",
15 | sync: "/scram/scramjet.sync.js"
16 | }
17 | });
18 | //@ts-ignore these fucking exist
19 | //make sure the transport is set before continuing
20 | await window.setTransport(localStorage.getItem('incog||transport'));
21 | await scramjet.init('/sw.js');
22 | return scramjet;
23 | });
24 | return resolve(scram);
25 | };
26 | });
27 | }
28 |
29 | export { initServiceWorker };
30 |
--------------------------------------------------------------------------------
/src/ts/settings.ts:
--------------------------------------------------------------------------------
1 | function setTheme(name: string | null) {
2 | if (name === 'ocean') {
3 | localStorage.setItem('incog||currentTheme', 'ocean');
4 | document.documentElement.className = '';
5 | } else {
6 | localStorage.setItem('incog||currentTheme', name as string);
7 | document.documentElement.className = name as string;
8 | }
9 | }
10 | function setProxy(name: string) {
11 | localStorage.setItem('incog||proxy', name);
12 | }
13 | function setTransport(name: string) {
14 | localStorage.setItem('incog||transport', name);
15 | }
16 | function changeTitle(title: string | null) {
17 | localStorage.setItem('incog||title', title as string);
18 | if (title === null || title === 'null') {
19 | return;
20 | } else {
21 | document.title = title;
22 | }
23 | }
24 | function changeFavicon(url: string | null) {
25 | localStorage.setItem('incog||favicon', url as string);
26 | if (url === null || url === 'null') {
27 | return;
28 | } else {
29 | let favicon = document.getElementById('favicon') as HTMLLinkElement;
30 | favicon.href = url;
31 | }
32 | }
33 |
34 | export { changeFavicon, changeTitle, setProxy, setTheme, setTransport };
35 |
--------------------------------------------------------------------------------
/tailwind.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | export default {
3 | content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
4 | theme: {
5 | extend: {},
6 | },
7 | plugins: [],
8 | variants: {
9 | extend: {
10 | display: ['group-hover'],
11 | },
12 | },
13 | };
14 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "astro/tsconfigs/strict",
3 | "exclude": ["server/**/*", "dist/**/*", "node_modules/**/*", "public/**/*", "vendor/**"],
4 | "compilerOptions": {
5 | "baseUrl": ".",
6 | "paths": {
7 | "@components/*": ["src/components/*"],
8 | "@layouts/*": ["src/layouts/*"],
9 | "@scripts/*": ["src/ts/*"]
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/vendor/scramjet/LICENSE:
--------------------------------------------------------------------------------
1 | Scramjet is licensed under AGPL-3. You can view the full terms of the license here: https://www.gnu.org/licenses/agpl-3.0.txt
2 |
3 | - Your project using scramjet MUST be open source, and must be compatible with GPL
4 | - Your project must include clear and prominent credit to the scramjet project, with a link to https://discord.gg/88CapFYSEd
5 |
6 | If these terms cannot work for your project, email contact@mercurywork.shop for information on a obtaining a dual license.
7 |
--------------------------------------------------------------------------------
/vendor/scramjet/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ---
6 |
7 | > [!WARNING]
8 | > Scramjet is not currently production ready, DO NOT USE THIS AS THE MAIN OPTION IN YOUR SITE.
9 |
10 |
11 |
12 | Scramjet is an experimental interception based web proxy that aims to be the successor to Ultraviolet. It is designed with security, developer friendliness, and performance in mind. Scramjet strives to have a clean, organized codebase to improve maintainability. Scramjet is made to evade internet censorship and bypass arbitrary web browser restrictions.
13 |
14 | ## Supported Sites
15 |
16 | Some of the popular websites that Scramjet supports include:
17 |
18 | - [Google](https://google.com)
19 | - [Youtube](https://www.youtube.com)
20 | - [Spotify](https://spotify.com)
21 | - [Discord](https://discord.com)
22 | - [Reddit](https://reddit.com)
23 | - [GeForce NOW](https://play.geforcenow.com/)
24 | - [now.gg](https://now.gg)
25 |
26 | ## Development
27 |
28 | ### Dependencies
29 |
30 | - Recent versions of `node.js` and `pnpm`
31 | - `rustup`
32 | - `wasm-bindgen`
33 | - `wasm-opt`
34 | - [this `wasm-snip` fork](https://github.com/r58Playz/wasm-snip)
35 |
36 | #### Building
37 |
38 | - Clone the repository with `git clone --recursive https://github.com/MercuryWorkshop/scramjet`
39 | - Install the dependencies with `pnpm i`
40 | - Build the rewriter with `pnpm rewriter:build`
41 | - Build Scramjet with `pnpm build`
42 |
43 | ### Running Scramjet Locally
44 |
45 | You can run the Scramjet dev server with the command
46 |
47 | ```sh
48 | pnpm dev
49 | ```
50 |
51 | Scramjet should now be running at `localhost:1337` and should rebuild upon a file being changed (excluding the rewriter).
52 |
--------------------------------------------------------------------------------
/vendor/scramjet/dist/scramjet.controller.js:
--------------------------------------------------------------------------------
1 | (()=>{"use strict";var e={1762:function(e,r,t){t.d(r,{Z:function(){return o}});let o={fmt:function(e,r,...t){let o=Error.prepareStackTrace;Error.prepareStackTrace=(e,r)=>{r.shift(),r.shift(),r.shift();let t="";for(let e=1;e `+t);return t+=r[0].getFunctionName()||"Anonymous"};let n=function(){try{throw Error()}catch(e){return e.stack}}();Error.prepareStackTrace=o;let c=console[e]||console.log;c(`%c${n}%c ${r}`,`
2 | background-color: ${{log:"#000",warn:"#f80",error:"#f00",debug:"transparent"}[e]};
3 | color: ${{log:"#fff",warn:"#fff",error:"#fff",debug:"gray"}[e]};
4 | padding: ${{log:2,warn:4,error:4,debug:0}[e]}px;
5 | font-weight: bold;
6 | font-family: monospace;
7 | font-size: 0.9em;
8 | `,`${"debug"===e?"color: gray":""}`,...t)},log:function(e,...r){this.fmt("log",e,...r)},warn:function(e,...r){this.fmt("warn",e,...r)},error:function(e,...r){this.fmt("error",e,...r)},debug:function(e,...r){this.fmt("debug",e,...r)}}}},r={};function t(o){var n=r[o];if(void 0!==n)return n.exports;var c=r[o]={exports:{}};return e[o](c,c.exports,t),c.exports}t.d=function(e,r){for(var o in r)t.o(r,o)&&!t.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:r[o]})},t.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)};let o=Symbol.for("scramjet client global"),n=Symbol.for("scramjet frame handle");var c=t(1762).Z;class s extends EventTarget{controller;frame;constructor(e,r){super(),this.controller=e,this.frame=r,r[n]=this}get client(){return this.frame.contentWindow.window[o]}get url(){return this.client.url}go(e){e instanceof URL&&(e=e.toString()),c.log("navigated to",e),this.frame.src=this.controller.encodeUrl(e)}back(){this.frame.contentWindow?.history.back()}forward(){this.frame.contentWindow?.history.forward()}reload(){this.frame.contentWindow?.location.reload()}}!("$scramjet"in self)&&(self.$scramjet={version:{build:"1efcf85",version:"1.0.2-dev"},codec:{},flagEnabled:function(e,r){let t=i.config.flags[e];for(let t in i.config.siteFlags){let o=i.config.siteFlags[t];if(new RegExp(t).test(r.href)&&e in o)return o[e]}return t}});let i=self.$scramjet,a=Function;function f(){i.codec.encode=a("url",i.config.codec.encode),i.codec.decode=a("url",i.config.codec.decode)}var l=t(1762).Z;window.ScramjetController=class e{db;constructor(e){let r={prefix:"/scramjet/",globals:{wrapfn:"$scramjet$wrap",wrapthisfn:"$scramjet$wrapthis",trysetfn:"$scramjet$tryset",importfn:"$scramjet$import",rewritefn:"$scramjet$rewrite",metafn:"$scramjet$meta",setrealmfn:"$scramjet$setrealm",pushsourcemapfn:"$scramjet$pushsourcemap"},files:{wasm:"/scramjet.wasm.js",shared:"/scramjet.shared.js",worker:"/scramjet.worker.js",client:"/scramjet.client.js",sync:"/scramjet.sync.js"},flags:{serviceworkers:!1,syncxhr:!1,naiiveRewriter:!1,strictRewrites:!0,rewriterLogs:!0,captureErrors:!0,cleanErrors:!1,scramitize:!1,sourcemaps:!1},siteFlags:{},codec:{encode:`if (!url) return url;
9 | return encodeURIComponent(url);`,decode:`if (!url) return url;
10 | return decodeURIComponent(url);`}},t=(e,r)=>{for(let o in r)r[o]instanceof Object&&o in e&&Object.assign(r[o],t(e[o],r[o]));return Object.assign(e||{},r)};i.config=t(r,e)}async init(e){f(),await this.openIDB();let r=await navigator.serviceWorker.register(e);return l.log("service worker registered"),r}createFrame(e){return!e&&(e=document.createElement("iframe")),new s(this,e)}encodeUrl(e){return e instanceof URL&&(e=e.toString()),i.config.prefix+i.codec.encode(e)}decodeUrl(e){return e instanceof URL&&(e=e.toString()),i.codec.decode(e)}async openIDB(){let e=indexedDB.open("$scramjet",1);return new Promise((r,t)=>{e.onsuccess=async()=>{this.db=e.result,await this.#e(),r(e.result)},e.onupgradeneeded=()=>{let r=e.result;!r.objectStoreNames.contains("config")&&r.createObjectStore("config"),!r.objectStoreNames.contains("cookies")&&r.createObjectStore("cookies")},e.onerror=()=>t(e.error)})}async #e(){if(!this.db){console.error("Store not ready!");return}let e=this.db.transaction("config","readwrite").objectStore("config").put(i.config,"config");return new Promise((r,t)=>{e.onsuccess=r,e.onerror=t})}async modifyConfig(e){i.config=Object.assign({},i.config,e),f(),await this.#e()}}})();
11 | //# sourceMappingURL=scramjet.controller.js.map
--------------------------------------------------------------------------------
/vendor/scramjet/dist/scramjet.controller.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"scramjet.controller.js","sources":["webpack://@mercuryworkshop/scramjet/./src/log.ts","webpack://@mercuryworkshop/scramjet/./src/symbols.ts","webpack://@mercuryworkshop/scramjet/./src/controller/frame.ts","webpack://@mercuryworkshop/scramjet/./src/scramjet.ts","webpack://@mercuryworkshop/scramjet/./src/controller/index.ts"],"sourcesContent":["export default {\n\tfmt: function (severity: string, message: string, ...args: any[]) {\n\t\tconst old = Error.prepareStackTrace;\n\n\t\tError.prepareStackTrace = (_, stack) => {\n\t\t\tstack.shift(); // stack();\n\t\t\tstack.shift(); // fmt();\n\t\t\tstack.shift();\n\n\t\t\tlet fmt = \"\";\n\t\t\tfor (let i = 1; i < Math.min(2, stack.length); i++) {\n\t\t\t\tif (stack[i].getFunctionName()) {\n\t\t\t\t\t// const f = stack[i].getThis()?.constructor?.name;\n\t\t\t\t\t// if (f) fmt += `${f}.`\n\t\t\t\t\tfmt += `${stack[i].getFunctionName()} -> ` + fmt;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfmt += stack[0].getFunctionName() || \"Anonymous\";\n\n\t\t\treturn fmt;\n\t\t};\n\n\t\tconst fmt = (function stack() {\n\t\t\ttry {\n\t\t\t\tthrow new Error();\n\t\t\t} catch (e) {\n\t\t\t\treturn e.stack;\n\t\t\t}\n\t\t})();\n\n\t\tError.prepareStackTrace = old;\n\n\t\tconst fn = console[severity] || console.log;\n\t\tconst bg = {\n\t\t\tlog: \"#000\",\n\t\t\twarn: \"#f80\",\n\t\t\terror: \"#f00\",\n\t\t\tdebug: \"transparent\",\n\t\t}[severity];\n\t\tconst fg = {\n\t\t\tlog: \"#fff\",\n\t\t\twarn: \"#fff\",\n\t\t\terror: \"#fff\",\n\t\t\tdebug: \"gray\",\n\t\t}[severity];\n\t\tconst padding = {\n\t\t\tlog: 2,\n\t\t\twarn: 4,\n\t\t\terror: 4,\n\t\t\tdebug: 0,\n\t\t}[severity];\n\n\t\tfn(\n\t\t\t`%c${fmt}%c ${message}`,\n\t\t\t`\n\t\tbackground-color: ${bg};\n\t\tcolor: ${fg};\n\t\tpadding: ${padding}px;\n\t\tfont-weight: bold;\n\t\tfont-family: monospace;\n\t\tfont-size: 0.9em;\n\t`,\n\t\t\t`${severity === \"debug\" ? \"color: gray\" : \"\"}`,\n\t\t\t...args\n\t\t);\n\t},\n\tlog: function (message: string, ...args: any[]) {\n\t\tthis.fmt(\"log\", message, ...args);\n\t},\n\twarn: function (message: string, ...args: any[]) {\n\t\tthis.fmt(\"warn\", message, ...args);\n\t},\n\terror: function (message: string, ...args: any[]) {\n\t\tthis.fmt(\"error\", message, ...args);\n\t},\n\tdebug: function (message: string, ...args: any[]) {\n\t\tthis.fmt(\"debug\", message, ...args);\n\t},\n};\n","// see types.d.ts for what these mean\nexport const SCRAMJETCLIENT = Symbol.for(\"scramjet client global\");\nexport const SCRAMJETFRAME = Symbol.for(\"scramjet frame handle\");\n","import { ScramjetController } from \".\";\nimport type { ScramjetClient } from \"../client/client\";\nimport { SCRAMJETCLIENT, SCRAMJETFRAME } from \"../symbols\";\n\nexport class ScramjetFrame extends EventTarget {\n\tconstructor(\n\t\tprivate controller: ScramjetController,\n\t\tpublic frame: HTMLIFrameElement\n\t) {\n\t\tsuper();\n\t\tframe[SCRAMJETFRAME] = this;\n\t}\n\n\tget client(): ScramjetClient {\n\t\treturn this.frame.contentWindow.window[SCRAMJETCLIENT];\n\t}\n\n\tget url(): URL {\n\t\treturn this.client.url;\n\t}\n\n\tgo(url: string | URL) {\n\t\tif (url instanceof URL) url = url.toString();\n\n\t\tdbg.log(\"navigated to\", url);\n\n\t\tthis.frame.src = this.controller.encodeUrl(url);\n\t}\n\n\tback() {\n\t\tthis.frame.contentWindow?.history.back();\n\t}\n\n\tforward() {\n\t\tthis.frame.contentWindow?.history.forward();\n\t}\n\n\treload() {\n\t\tthis.frame.contentWindow?.location.reload();\n\t}\n}\n","import { ScramjetFlags } from \"./types\";\n\nif (!(\"$scramjet\" in self)) {\n\t// @ts-expect-error ts stuff\n\tself.$scramjet = {\n\t\tversion: {\n\t\t\tbuild: COMMITHASH,\n\t\t\tversion: VERSION,\n\t\t},\n\t\tcodec: {},\n\t\tflagEnabled,\n\t};\n}\n\nexport const $scramjet = self.$scramjet;\n\nconst nativeFunction = Function;\nexport function loadCodecs() {\n\t$scramjet.codec.encode = nativeFunction(\n\t\t\"url\",\n\t\t$scramjet.config.codec.encode\n\t) as any;\n\t$scramjet.codec.decode = nativeFunction(\n\t\t\"url\",\n\t\t$scramjet.config.codec.decode\n\t) as any;\n}\n\nexport function flagEnabled(flag: keyof ScramjetFlags, url: URL): boolean {\n\tconst value = $scramjet.config.flags[flag];\n\tfor (const regex in $scramjet.config.siteFlags) {\n\t\tconst partialflags = $scramjet.config.siteFlags[regex];\n\t\tif (new RegExp(regex).test(url.href) && flag in partialflags) {\n\t\t\treturn partialflags[flag];\n\t\t}\n\t}\n\n\treturn value;\n}\n","import { ScramjetConfig } from \"../types\";\nimport { ScramjetFrame } from \"./frame\";\nimport { $scramjet, loadCodecs } from \"../scramjet\";\n\nexport class ScramjetController {\n\tprivate db: IDBDatabase;\n\n\tconstructor(config: Partial) {\n\t\t// sane ish defaults\n\t\tconst defaultConfig: ScramjetConfig = {\n\t\t\tprefix: \"/scramjet/\",\n\t\t\tglobals: {\n\t\t\t\twrapfn: \"$scramjet$wrap\",\n\t\t\t\twrapthisfn: \"$scramjet$wrapthis\",\n\t\t\t\ttrysetfn: \"$scramjet$tryset\",\n\t\t\t\timportfn: \"$scramjet$import\",\n\t\t\t\trewritefn: \"$scramjet$rewrite\",\n\t\t\t\tmetafn: \"$scramjet$meta\",\n\t\t\t\tsetrealmfn: \"$scramjet$setrealm\",\n\t\t\t\tpushsourcemapfn: \"$scramjet$pushsourcemap\",\n\t\t\t},\n\t\t\tfiles: {\n\t\t\t\twasm: \"/scramjet.wasm.js\",\n\t\t\t\tshared: \"/scramjet.shared.js\",\n\t\t\t\tworker: \"/scramjet.worker.js\",\n\t\t\t\tclient: \"/scramjet.client.js\",\n\t\t\t\tsync: \"/scramjet.sync.js\",\n\t\t\t},\n\t\t\tflags: {\n\t\t\t\tserviceworkers: false,\n\t\t\t\tsyncxhr: false,\n\t\t\t\tnaiiveRewriter: false,\n\t\t\t\tstrictRewrites: true,\n\t\t\t\trewriterLogs: true,\n\t\t\t\tcaptureErrors: true,\n\t\t\t\tcleanErrors: false,\n\t\t\t\tscramitize: false,\n\t\t\t\tsourcemaps: false,\n\t\t\t},\n\t\t\tsiteFlags: {},\n\t\t\tcodec: {\n\t\t\t\tencode: `if (!url) return url;\n\t\t\t\t\treturn encodeURIComponent(url);`,\n\t\t\t\tdecode: `if (!url) return url;\n\t\t\t\t\treturn decodeURIComponent(url);`,\n\t\t\t},\n\t\t};\n\n\t\tconst deepMerge = (target: any, source: any): any => {\n\t\t\tfor (const key in source) {\n\t\t\t\tif (source[key] instanceof Object && key in target) {\n\t\t\t\t\tObject.assign(source[key], deepMerge(target[key], source[key]));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn Object.assign(target || {}, source);\n\t\t};\n\n\t\t$scramjet.config = deepMerge(defaultConfig, config);\n\t}\n\n\tasync init(serviceWorkerPath: string): Promise {\n\t\tloadCodecs();\n\n\t\tawait this.openIDB();\n\n\t\tconst reg = await navigator.serviceWorker.register(serviceWorkerPath);\n\t\tdbg.log(\"service worker registered\");\n\n\t\treturn reg;\n\t}\n\n\tcreateFrame(frame?: HTMLIFrameElement): ScramjetFrame {\n\t\tif (!frame) {\n\t\t\tframe = document.createElement(\"iframe\");\n\t\t}\n\n\t\treturn new ScramjetFrame(this, frame);\n\t}\n\n\tencodeUrl(url: string | URL): string {\n\t\tif (url instanceof URL) url = url.toString();\n\n\t\treturn $scramjet.config.prefix + $scramjet.codec.encode(url);\n\t}\n\n\tdecodeUrl(url: string | URL) {\n\t\tif (url instanceof URL) url = url.toString();\n\n\t\treturn $scramjet.codec.decode(url);\n\t}\n\n\tasync openIDB(): Promise {\n\t\tconst db = indexedDB.open(\"$scramjet\", 1);\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tdb.onsuccess = async () => {\n\t\t\t\tthis.db = db.result;\n\t\t\t\tawait this.#saveConfig();\n\t\t\t\tresolve(db.result);\n\t\t\t};\n\t\t\tdb.onupgradeneeded = () => {\n\t\t\t\tconst res = db.result;\n\t\t\t\tif (!res.objectStoreNames.contains(\"config\")) {\n\t\t\t\t\tres.createObjectStore(\"config\");\n\t\t\t\t}\n\t\t\t\tif (!res.objectStoreNames.contains(\"cookies\")) {\n\t\t\t\t\tres.createObjectStore(\"cookies\");\n\t\t\t\t}\n\t\t\t};\n\t\t\tdb.onerror = () => reject(db.error);\n\t\t});\n\t}\n\n\tasync #saveConfig() {\n\t\tif (!this.db) {\n\t\t\tconsole.error(\"Store not ready!\");\n\n\t\t\treturn;\n\t\t}\n\t\tconst tx = this.db.transaction(\"config\", \"readwrite\");\n\t\tconst store = tx.objectStore(\"config\");\n\t\tconst req = store.put($scramjet.config, \"config\");\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\treq.onsuccess = resolve;\n\t\t\treq.onerror = reject;\n\t\t});\n\t}\n\n\tasync modifyConfig(config: ScramjetConfig) {\n\t\t$scramjet.config = Object.assign({}, $scramjet.config, config);\n\t\tloadCodecs();\n\n\t\tawait this.#saveConfig();\n\t}\n}\n\nwindow.ScramjetController = ScramjetController;\n"],"names":["severity","message","args","old","Error","_","stack","fmt","i","Math","e","fn","console","SCRAMJETCLIENT","Symbol","SCRAMJETFRAME","ScramjetFrame","EventTarget","controller","frame","url","URL","dbg","self","COMMITHASH","VERSION","flagEnabled","flag","value","$scramjet","regex","partialflags","RegExp","nativeFunction","Function","loadCodecs","window","ScramjetController","config","defaultConfig","deepMerge","target","source","key","Object","serviceWorkerPath","reg","navigator","document","db","indexedDB","Promise","resolve","reject","res","req","store","tx"],"mappings":"+EAAA,MAAe,CACd,IAAK,SAAUA,CAAgB,CAAEC,CAAe,CAAE,GAAGC,CAAW,EAC/D,IAAMC,EAAMC,MAAM,iBAAiB,AAEnCA,CAAAA,MAAM,iBAAiB,CAAG,CAACC,EAAGC,KAC7BA,EAAM,KAAK,GACXA,EAAM,KAAK,GACXA,EAAM,KAAK,GAEX,IAAIC,EAAM,GACV,IAAK,IAAIC,EAAI,EAAGA,EAAIC,KAAK,GAAG,CAAC,EAAGH,EAAM,MAAM,EAAGE,IAC1CF,CAAK,CAACE,EAAE,CAAC,eAAe,IAG3BD,CAAAA,GAAO,CAAC,EAAED,CAAK,CAACE,EAAE,CAAC,eAAe,GAAG,IAAI,CAAC,CAAGD,CAAE,EAKjD,OAFAA,GAAOD,CAAK,CAAC,EAAE,CAAC,eAAe,IAAM,WAGtC,EAEA,IAAMC,EAAO,WACZ,GAAI,CACH,MAAM,AAAIH,OACX,CAAE,MAAOM,EAAG,CACX,OAAOA,EAAE,KAAK,AACf,CACD,GAEAN,CAAAA,MAAM,iBAAiB,CAAGD,EAE1B,IAAMQ,EAAKC,OAAO,CAACZ,EAAS,EAAIY,QAAQ,GAAG,CAoB3CD,EACC,CAAC,EAAE,EAAEJ,EAAI,GAAG,EAAEN,EAAQ,CAAC,CACvB;oBACiB,EAtBP,CACV,IAAK,OACL,KAAM,OACN,MAAO,OACP,MAAO,aACR,CAAC,CAACD,EAAS,CAiBY;SAChB,EAjBI,CACV,IAAK,OACL,KAAM,OACN,MAAO,OACP,MAAO,MACR,CAAC,CAACA,EAAS,CAYC;WACH,EAZO,CACf,IAAK,EACL,KAAM,EACN,MAAO,EACP,MAAO,CACR,CAAC,CAACA,EAAS,CAOQ;;;;CAIpB,CAAC,CACC,CAAC,EAAEA,AAAa,UAAbA,EAAuB,cAAgB,GAAG,CAAC,IAC3CE,EAEL,EACA,IAAK,SAAUD,CAAe,CAAE,GAAGC,CAAW,EAC7C,IAAI,CAAC,GAAG,CAAC,MAAOD,KAAYC,EAC7B,EACA,KAAM,SAAUD,CAAe,CAAE,GAAGC,CAAW,EAC9C,IAAI,CAAC,GAAG,CAAC,OAAQD,KAAYC,EAC9B,EACA,MAAO,SAAUD,CAAe,CAAE,GAAGC,CAAW,EAC/C,IAAI,CAAC,GAAG,CAAC,QAASD,KAAYC,EAC/B,EACA,MAAO,SAAUD,CAAe,CAAE,GAAGC,CAAW,EAC/C,IAAI,CAAC,GAAG,CAAC,QAASD,KAAYC,EAC/B,CACD,C,4SC7EO,IAAMW,EAAiBC,OAAO,GAAG,CAAC,0BAC5BC,EAAgBD,OAAO,GAAG,CAAC,yB,eCEjC,OAAME,UAAsBC,Y,gBAClC,aACSC,CAA8B,CAC/BC,CAAwB,CAC9B,CACD,KAAK,QAHGD,UAAU,CAAVA,EAAAA,IAAAA,CACDC,KAAK,CAALA,EAGPA,CAAK,CAACJ,EAAc,CAAG,IAAI,AAC5B,CAEA,IAAI,QAAyB,CAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAACF,EAAe,AACvD,CAEA,IAAI,KAAW,CACd,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,AACvB,CAEA,GAAGO,CAAiB,CAAE,CACjBA,aAAeC,KAAKD,CAAAA,EAAMA,EAAI,QAAQ,EAAC,EAE3CE,EAAI,GAAG,CAAC,eAAgBF,GAExB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAG,IAAI,CAAC,UAAU,CAAC,SAAS,CAACA,EAC5C,CAEA,MAAO,CACN,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,QAAQ,MACnC,CAEA,SAAU,CACT,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,QAAQ,SACnC,CAEA,QAAS,CACR,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,SAAS,QACpC,CACD,CCtCI,CAAE,eAAeG,IAAG,GAEvBA,CAAAA,KAAK,SAAS,CAAG,CAChB,QAAS,CACR,MAAOC,UACP,QAASC,WACV,EACA,MAAO,CAAC,EACRC,YAkBK,SAAqBC,CAAyB,CAAEP,CAAQ,EAC9D,IAAMQ,EAAQC,EAAU,MAAM,CAAC,KAAK,CAACF,EAAK,CAC1C,IAAK,IAAMG,KAASD,EAAU,MAAM,CAAC,SAAS,CAAE,CAC/C,IAAME,EAAeF,EAAU,MAAM,CAAC,SAAS,CAACC,EAAM,CACtD,GAAI,IAAIE,OAAOF,GAAO,IAAI,CAACV,EAAI,IAAI,GAAKO,KAAQI,EAC/C,OAAOA,CAAY,CAACJ,EAAK,AAE3B,CAEA,OAAOC,CACR,CA3BC,GAGM,IAAMC,EAAYN,KAAK,SAAS,CAEjCU,EAAiBC,SAChB,SAASC,IACfN,EAAU,KAAK,CAAC,MAAM,CAAGI,EACxB,MACAJ,EAAU,MAAM,CAAC,KAAK,CAAC,MAAM,EAE9BA,EAAU,KAAK,CAAC,MAAM,CAAGI,EACxB,MACAJ,EAAU,MAAM,CAAC,KAAK,CAAC,MAAM,CAE/B,C,eCgHAO,CAAAA,OAAO,kBAAkB,CAtIlB,MAAMC,EACJ,EAAgB,AAExB,aAAYC,CAA+B,CAAE,CAE5C,IAAMC,EAAgC,CACrC,OAAQ,aACR,QAAS,CACR,OAAQ,iBACR,WAAY,qBACZ,SAAU,mBACV,SAAU,mBACV,UAAW,oBACX,OAAQ,iBACR,WAAY,qBACZ,gBAAiB,yBAClB,EACA,MAAO,CACN,KAAM,oBACN,OAAQ,sBACR,OAAQ,sBACR,OAAQ,sBACR,KAAM,mBACP,EACA,MAAO,CACN,eAAgB,GAChB,QAAS,GACT,eAAgB,GAChB,eAAgB,GAChB,aAAc,GACd,cAAe,GACf,YAAa,GACb,WAAY,GACZ,WAAY,EACb,EACA,UAAW,CAAC,EACZ,MAAO,CACN,OAAQ,CAAC;oCACuB,CAAC,CACjC,OAAQ,CAAC;oCACuB,CAAC,AAClC,CACD,EAEMC,EAAY,CAACC,EAAaC,KAC/B,IAAK,IAAMC,KAAOD,EACbA,CAAM,CAACC,EAAI,WAAYC,QAAUD,KAAOF,GAC3CG,OAAO,MAAM,CAACF,CAAM,CAACC,EAAI,CAAEH,EAAUC,CAAM,CAACE,EAAI,CAAED,CAAM,CAACC,EAAI,GAI/D,OAAOC,OAAO,MAAM,CAACH,GAAU,CAAC,EAAGC,EACpC,CAEAb,CAAAA,EAAU,MAAM,CAAGW,EAAUD,EAAeD,EAC7C,CAEA,MAAM,KAAKO,CAAyB,CAAsC,CACzEV,IAEA,MAAM,IAAI,CAAC,OAAO,GAElB,IAAMW,EAAM,MAAMC,UAAU,aAAa,CAAC,QAAQ,CAACF,GAGnD,OAFAvB,EAAI,GAAG,CAAC,6BAEDwB,CACR,CAEA,YAAY3B,CAAyB,CAAiB,CAKrD,MAJI,CAACA,GACJA,CAAAA,EAAQ6B,SAAS,aAAa,CAAC,SAAQ,EAGjC,IAAIhC,EAAc,IAAI,CAAEG,EAChC,CAEA,UAAUC,CAAiB,CAAU,CAGpC,OAFIA,aAAeC,KAAKD,CAAAA,EAAMA,EAAI,QAAQ,EAAC,EAEpCS,EAAU,MAAM,CAAC,MAAM,CAAGA,EAAU,KAAK,CAAC,MAAM,CAACT,EACzD,CAEA,UAAUA,CAAiB,CAAE,CAG5B,OAFIA,aAAeC,KAAKD,CAAAA,EAAMA,EAAI,QAAQ,EAAC,EAEpCS,EAAU,KAAK,CAAC,MAAM,CAACT,EAC/B,CAEA,MAAM,SAAgC,CACrC,IAAM6B,EAAKC,UAAU,IAAI,CAAC,YAAa,GAEvC,OAAO,IAAIC,QAAqB,CAACC,EAASC,KACzCJ,EAAG,SAAS,CAAG,UACd,IAAI,CAAC,EAAE,CAAGA,EAAG,MAAM,CACnB,MAAM,IAAI,CAAC,EAAW,GACtBG,EAAQH,EAAG,MAAM,CAClB,EACAA,EAAG,eAAe,CAAG,KACpB,IAAMK,EAAML,EAAG,MAAM,AACjB,EAACK,EAAI,gBAAgB,CAAC,QAAQ,CAAC,WAClCA,EAAI,iBAAiB,CAAC,UAEnB,CAACA,EAAI,gBAAgB,CAAC,QAAQ,CAAC,YAClCA,EAAI,iBAAiB,CAAC,UAExB,EACAL,EAAG,OAAO,CAAG,IAAMI,EAAOJ,EAAG,KAAK,CACnC,EACD,CAEA,MAAM,EAAW,GAChB,GAAI,CAAC,IAAI,CAAC,EAAE,CAAE,CACbrC,QAAQ,KAAK,CAAC,oBAEd,MACD,CAGA,IAAM2C,EAAMC,AADEC,AADH,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,SAAU,aACxB,WAAW,CAAC,UACX,GAAG,CAAC5B,EAAU,MAAM,CAAE,UAExC,OAAO,IAAIsB,QAAQ,CAACC,EAASC,KAC5BE,EAAI,SAAS,CAAGH,EAChBG,EAAI,OAAO,CAAGF,CACf,EACD,CAEA,MAAM,aAAaf,CAAsB,CAAE,CAC1CT,EAAU,MAAM,CAAGe,OAAO,MAAM,CAAC,CAAC,EAAGf,EAAU,MAAM,CAAES,GACvDH,IAEA,MAAM,IAAI,CAAC,EAAW,EACvB,CACD,C"}
--------------------------------------------------------------------------------
/vendor/scramjet/dist/scramjet.sync.js:
--------------------------------------------------------------------------------
1 | addEventListener("message",({data:{sab:e,args:[t,n,s,r,o],body:a,headers:g}})=>{let i=new DataView(e),l=new Uint8Array(e),d=new XMLHttpRequest;if(d.responseType="arraybuffer",d.open(t,n,!0,r,o),g)for(let[e,t]of Object.entries(g))d.setRequestHeader(e,t);d.send(a),d.onload=()=>{let t=1;i.setUint16(t,d.status),t+=2;let n=d.getAllResponseHeaders();i.setUint32(t,n.length),t+=4,e.byteLength{console.error("xhr failed"),i.setUint8(0,1)}});
2 | //# sourceMappingURL=scramjet.sync.js.map
--------------------------------------------------------------------------------
/vendor/scramjet/dist/scramjet.sync.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"scramjet.sync.js","sources":["webpack://@mercuryworkshop/scramjet/./src/sync.ts"],"sourcesContent":["addEventListener(\n\t\"message\",\n\t({\n\t\tdata: {\n\t\t\tsab,\n\t\t\targs: [method, url, _, username, password],\n\t\t\tbody,\n\t\t\theaders,\n\t\t},\n\t}) => {\n\t\tconst view = new DataView(sab);\n\t\tconst u8view = new Uint8Array(sab);\n\n\t\tconst xhr = new XMLHttpRequest();\n\t\txhr.responseType = \"arraybuffer\";\n\n\t\t// force async since we need it to resolve to the sw\n\t\txhr.open(method, url, true, username, password);\n\n\t\tif (headers)\n\t\t\tfor (const [k, v] of Object.entries(headers)) {\n\t\t\t\txhr.setRequestHeader(k, v as string);\n\t\t\t}\n\n\t\txhr.send(body);\n\n\t\txhr.onload = () => {\n\t\t\tlet cursor = 1; // first byte is the lock\n\n\t\t\tview.setUint16(cursor, xhr.status);\n\t\t\tcursor += 2;\n\n\t\t\t// next write the header string\n\t\t\tconst headers = xhr.getAllResponseHeaders();\n\t\t\tview.setUint32(cursor, headers.length);\n\t\t\tcursor += 4;\n\n\t\t\tif (sab.byteLength < cursor + headers.length)\n\t\t\t\tsab.grow(cursor + headers.length);\n\t\t\tu8view.set(new TextEncoder().encode(headers), cursor);\n\t\t\tcursor += headers.length;\n\n\t\t\tview.setUint32(cursor, xhr.response.byteLength);\n\t\t\tcursor += 4;\n\n\t\t\tif (sab.byteLength < cursor + xhr.response.byteLength)\n\t\t\t\tsab.grow(cursor + xhr.response.byteLength);\n\t\t\tu8view.set(new Uint8Array(xhr.response), cursor);\n\n\t\t\t// release the lock, main thread will stop spinning now\n\t\t\tview.setUint8(0, 1);\n\t\t};\n\t\txhr.ontimeout =\n\t\t\txhr.onerror =\n\t\t\txhr.onabort =\n\t\t\t\t() => {\n\t\t\t\t\tconsole.error(\"xhr failed\");\n\t\t\t\t\tview.setUint8(0, 1);\n\t\t\t\t};\n\t}\n);\n"],"names":["addEventListener","sab","method","url","_","username","password","body","headers","view","DataView","u8view","Uint8Array","xhr","XMLHttpRequest","k","v","Object","cursor","TextEncoder","console"],"mappings":"AAAAA,iBACC,UACA,CAAC,CACA,KAAM,CACLC,IAAAA,CAAG,CACH,KAAM,CAACC,EAAQC,EAAKC,EAAGC,EAAUC,EAAS,CAC1CC,KAAAA,CAAI,CACJC,QAAAA,CAAO,CACP,CACD,IACA,IAAMC,EAAO,IAAIC,SAAST,GACpBU,EAAS,IAAIC,WAAWX,GAExBY,EAAM,IAAIC,eAMhB,GALAD,EAAI,YAAY,CAAG,cAGnBA,EAAI,IAAI,CAACX,EAAQC,EAAK,GAAME,EAAUC,GAElCE,EACH,IAAK,GAAM,CAACO,EAAGC,EAAE,GAAIC,OAAO,OAAO,CAACT,GACnCK,EAAI,gBAAgB,CAACE,EAAGC,GAG1BH,EAAI,IAAI,CAACN,GAETM,EAAI,MAAM,CAAG,KACZ,IAAIK,EAAS,EAEbT,EAAK,SAAS,CAACS,EAAQL,EAAI,MAAM,EACjCK,GAAU,EAGV,IAAMV,EAAUK,EAAI,qBAAqB,GACzCJ,EAAK,SAAS,CAACS,EAAQV,EAAQ,MAAM,EACrCU,GAAU,EAENjB,EAAI,UAAU,CAAGiB,EAASV,EAAQ,MAAM,EAC3CP,EAAI,IAAI,CAACiB,EAASV,EAAQ,MAAM,EACjCG,EAAO,GAAG,CAAC,IAAIQ,cAAc,MAAM,CAACX,GAAUU,GAC9CA,GAAUV,EAAQ,MAAM,CAExBC,EAAK,SAAS,CAACS,EAAQL,EAAI,QAAQ,CAAC,UAAU,EAC9CK,GAAU,EAENjB,EAAI,UAAU,CAAGiB,EAASL,EAAI,QAAQ,CAAC,UAAU,EACpDZ,EAAI,IAAI,CAACiB,EAASL,EAAI,QAAQ,CAAC,UAAU,EAC1CF,EAAO,GAAG,CAAC,IAAIC,WAAWC,EAAI,QAAQ,EAAGK,GAGzCT,EAAK,QAAQ,CAAC,EAAG,EAClB,EACAI,EAAI,SAAS,CACZA,EAAI,OAAO,CACXA,EAAI,OAAO,CACV,KACCO,QAAQ,KAAK,CAAC,cACdX,EAAK,QAAQ,CAAC,EAAG,EAClB,CACH"}
--------------------------------------------------------------------------------
/vendor/scramjet/dist/scramjet.worker.js:
--------------------------------------------------------------------------------
1 | (()=>{"use strict";var e={1762:function(e,t,r){r.d(t,{Z:function(){return o}});let o={fmt:function(e,t,...r){let o=Error.prepareStackTrace;Error.prepareStackTrace=(e,t)=>{t.shift(),t.shift(),t.shift();let r="";for(let e=1;e `+r);return r+=t[0].getFunctionName()||"Anonymous"};let s=function(){try{throw Error()}catch(e){return e.stack}}();Error.prepareStackTrace=o;let n=console[e]||console.log;n(`%c${s}%c ${t}`,`
2 | background-color: ${{log:"#000",warn:"#f80",error:"#f00",debug:"transparent"}[e]};
3 | color: ${{log:"#fff",warn:"#fff",error:"#fff",debug:"gray"}[e]};
4 | padding: ${{log:2,warn:4,error:4,debug:0}[e]}px;
5 | font-weight: bold;
6 | font-family: monospace;
7 | font-size: 0.9em;
8 | `,`${"debug"===e?"color: gray":""}`,...r)},log:function(e,...t){this.fmt("log",e,...t)},warn:function(e,...t){this.fmt("warn",e,...t)},error:function(e,...t){this.fmt("error",e,...t)},debug:function(e,...t){this.fmt("debug",e,...t)}}}},t={};function r(o){var s=t[o];if(void 0!==s)return s.exports;var n=t[o]={exports:{}};return e[o](n,n.exports,r),n.exports}r.d=function(e,t){for(var o in t)r.o(t,o)&&!r.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:t[o]})},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)};class o{handle;origin;syncToken;promises;messageChannel;connected;constructor(e,t){this.handle=e,this.origin=t,this.syncToken=0,this.promises={},this.messageChannel=new MessageChannel,this.connected=!1,this.messageChannel.port1.addEventListener("message",e=>{"scramjet$type"in e.data&&("init"===e.data.scramjet$type?this.connected=!0:this.handleMessage(e.data))}),this.messageChannel.port1.start(),this.handle.postMessage({scramjet$type:"init",scramjet$port:this.messageChannel.port2},[this.messageChannel.port2])}handleMessage(e){let t=this.promises[e.scramjet$token];t&&(t(e),delete this.promises[e.scramjet$token])}async fetch(e){let t=this.syncToken++,r={scramjet$type:"fetch",scramjet$token:t,scramjet$request:{url:e.url,body:e.body,headers:Array.from(e.headers.entries()),method:e.method,mode:e.mode,destinitation:e.destination}},o=e.body?[e.body]:[];this.handle.postMessage(r,o);let{scramjet$response:s}=await new Promise(e=>{this.promises[t]=e});return!!s&&new Response(s.body,{headers:s.headers,status:s.status,statusText:s.statusText})}}!("$scramjet"in self)&&(self.$scramjet={version:{build:"1efcf85",version:"1.0.2-dev"},codec:{},flagEnabled:function(e,t){let r=s.config.flags[e];for(let r in s.config.siteFlags){let o=s.config.siteFlags[r];if(new RegExp(r).test(t.href)&&e in o)return o[e]}return r}});let s=self.$scramjet,n=Function,{util:{BareClient:i,ScramjetHeaders:a,BareMuxConnection:c},url:{rewriteUrl:l,unrewriteUrl:d,rewriteBlob:u,unrewriteBlob:h},rewrite:{rewriteCss:p,unrewriteCss:f,rewriteHtml:m,unrewriteHtml:g,rewriteSrcset:y,rewriteJs:b,rewriteHeaders:w,rewriteWorkers:v,htmlRules:k},CookieStore:x}=s.shared;function R(e){return{origin:e,base:e}}async function S(e,t){let r=new URLSearchParams(new URL(e.url).search);if(r.has("url"))return Response.redirect(l(r.get("url"),R(new URL(r.get("url")))));try{let o=new URL(e.url),n="";if(o.searchParams.has("type")&&(n=o.searchParams.get("type"),o.searchParams.delete("type")),o.searchParams.has("dest")&&o.searchParams.delete("dest"),o.pathname.startsWith(this.config.prefix+"blob:")||o.pathname.startsWith(this.config.prefix+"data:")){let r,s=o.pathname.substring(this.config.prefix.length);s.startsWith("blob:")&&(s=h(s));let i=await fetch(s,{}),a=s.startsWith("blob:")?s:"(data url)";i.finalURL=a,i.body&&(r=await $(i,t?{base:new URL(new URL(t.url).origin),origin:new URL(new URL(t.url).origin)}:R(new URL(d(e.referrer))),e.destination,n,this.cookieStore));let c=Object.fromEntries(i.headers.entries());return crossOriginIsolated&&(c["Cross-Origin-Opener-Policy"]="same-origin",c["Cross-Origin-Embedder-Policy"]="require-corp"),new Response(r,{status:i.status,statusText:i.statusText,headers:c})}let i=new URL(d(o)),c=this.serviceWorkers.find(e=>e.origin===i.origin);if(c&&c.connected&&"swruntime"!==r.get("from")){let t=await c.fetch(e);if(t)return t}if(i.origin==new URL(e.url).origin)throw Error("attempted to fetch from same origin - this means the site has obtained a reference to the real origin, aborting");let l=new a;for(let[t,r]of e.headers.entries())l.set(t,r);if(t&&new URL(t.url).pathname.startsWith(s.config.prefix)){let e=new URL(d(t.url));e.toString().includes("youtube.com")||(l.set("Referer",e.toString()),l.set("Origin",e.origin?`${e.protocol}//${e.host}`:"null"))}let u=this.cookieStore.getCookies(i,!1);u.length&&l.set("Cookie",u),l.set("Sec-Fetch-Dest",e.destination),l.set("Sec-Fetch-Site","same-origin"),l.set("Sec-Fetch-Mode","cors"===e.mode?e.mode:"same-origin");let p=new E(i,e.body,e.method,e.destination,t,l.headers);this.dispatchEvent(p);let f=p.response||await this.client.fetch(p.url,{method:p.method,body:p.body,headers:p.requestHeaders,credentials:"omit",mode:"cors"===e.mode?e.mode:"same-origin",cache:e.cache,redirect:"manual",duplex:"half"});return await C(i,n,e.destination,f,this.cookieStore,t,this)}catch(r){let t={message:r.message,url:e.url,destination:e.destination,timestamp:new Date().toISOString()};if(r.stack&&(t.stack=r.stack),console.error("ERROR FROM SERVICE WORKER FETCH: ",t),!["document","iframe"].includes(e.destination))return new Response(void 0,{status:500});return function(e,t){let r={"content-type":"text/html"};return crossOriginIsolated&&(r["Cross-Origin-Embedder-Policy"]="require-corp"),new Response(function(e,t){let r=`
9 | errorTrace.value = ${JSON.stringify(e)};
10 | fetchedURL.textContent = ${JSON.stringify(t)};
11 | for (const node of document.querySelectorAll("#hostname")) node.textContent = ${JSON.stringify(location.hostname)};
12 | reload.addEventListener("click", () => location.reload());
13 | version.textContent = ${JSON.stringify(s.version.version)};
14 | build.textContent = ${JSON.stringify(s.version.build)};
15 |
16 | document.getElementById('copy-button').addEventListener('click', async () => {
17 | const text = document.getElementById('errorTrace').value;
18 | await navigator.clipboard.writeText(text);
19 | const btn = document.getElementById('copy-button');
20 | btn.textContent = 'Copied!';
21 | setTimeout(() => btn.textContent = 'Copy', 2000);
22 | });
23 | `;return`
24 |
25 |
26 |
27 | Scramjet
28 |
141 |
142 |
143 |
144 |
145 |
Uh oh!
146 |
There was an error loading
147 |
148 |
149 |
150 |
151 |
152 | Copy
153 |
154 |
155 |
Try:
156 |
157 | Checking your internet connection
158 | Verifying you entered the correct address
159 | Clearing the site data
160 | Contacting 's administrator
161 | Verify the server isn't censored
162 |
163 |
If you're the administrator of , try:
164 |
165 | Restarting your server
166 | Updating Scramjet
167 | Troubleshooting the error on the GitHub repository
168 |
169 |
170 |
171 |
172 |
Reload
173 |
174 | Scramjet v (build )
175 |
176 |
177 |
178 | `}(String(e),t),{status:500,headers:r})}(Object.entries(t).map(([e,t])=>`${e.charAt(0).toUpperCase()+e.slice(1)}: ${t}`).join("\n\n"),d(e.url))}}async function C(e,t,r,o,s,n,i){let a;let c=w(o.rawHeaders,R(e)),l=c["set-cookie"]||[];for(let t in l)n&&n.postMessage({scramjet$type:"cookie",cookie:t,url:e.href});for(let t in await s.setCookies(l instanceof Array?l:[l],e),c)Array.isArray(c[t])&&(c[t]=c[t][0]);if(o.body&&(a=await $(o,R(e),r,t,s)),["document","iframe"].includes(r)){let e=c["content-disposition"];if(!/\s*?((inline|attachment);\s*?)filename=/i.test(e)){let t=/^\s*?attachment/i.test(e)?"attachment":"inline",[r]=new URL(o.finalURL).pathname.split("/").slice(-1);c["content-disposition"]=`${t}; filename=${JSON.stringify(r)}`}}"text/event-stream"===c.accept&&(c["content-type"]="text/event-stream"),delete c["permissions-policy"],crossOriginIsolated&&["document","iframe","worker","sharedworker","style","script"].includes(r)&&(c["Cross-Origin-Embedder-Policy"]="require-corp",c["Cross-Origin-Opener-Policy"]="same-origin");let d=new j(a,c,o.status,o.statusText,r,e,o,n);return i.dispatchEvent(d),new Response(d.responseBody,{headers:d.responseHeaders,status:d.status,statusText:d.statusText})}async function $(e,t,r,o,s){switch(r){case"iframe":case"document":if(e.headers.get("content-type")?.startsWith("text/html"))return m(await e.text(),s,t,!0);return e.body;case"script":return b(await e.arrayBuffer(),e.finalURL,t);case"style":return p(await e.text(),t);case"sharedworker":case"worker":return v(await e.arrayBuffer(),o,e.finalURL,t);default:return e.body}}s.config;class j extends Event{responseBody;responseHeaders;status;statusText;destination;url;rawResponse;client;constructor(e,t,r,o,s,n,i,a){super("handleResponse"),this.responseBody=e,this.responseHeaders=t,this.status=r,this.statusText=o,this.destination=s,this.url=n,this.rawResponse=i,this.client=a}}class E extends Event{url;body;method;destination;client;requestHeaders;constructor(e,t,r,o,s,n){super("request"),this.url=e,this.body=t,this.method=r,this.destination=o,this.client=s,this.requestHeaders=n}response}var T=r(1762).Z;class O extends EventTarget{client;config;syncPool={};synctoken=0;cookieStore=new s.shared.CookieStore;serviceWorkers=[];constructor(){super(),this.client=new s.shared.util.BareClient;let e=indexedDB.open("$scramjet",1);e.onsuccess=()=>{let t=e.result.transaction("cookies","readonly").objectStore("cookies").get("cookies");t.onsuccess=()=>{t.result&&(this.cookieStore.load(t.result),T.log("Loaded cookies from IDB!"))}},addEventListener("message",async({data:t})=>{if("scramjet$type"in t){if("registerServiceWorker"===t.scramjet$type){this.serviceWorkers.push(new o(t.port,t.origin));return}"cookie"===t.scramjet$type&&(this.cookieStore.setCookies([t.cookie],new URL(t.url)),e.result.transaction("cookies","readwrite").objectStore("cookies").put(JSON.parse(this.cookieStore.dump()),"cookies"))}})}async loadConfig(){if(this.config)return;let e=indexedDB.open("$scramjet",1);return new Promise((t,r)=>{e.onsuccess=async()=>{let o=e.result.transaction("config","readonly").objectStore("config").get("config");o.onsuccess=()=>{this.config=o.result,s.config=o.result,s.codec.encode=n("url",s.config.codec.encode),s.codec.decode=n("url",s.config.codec.decode),t()},o.onerror=()=>r(o.error)},e.onerror=()=>r(e.error)})}route({request:e}){return!!e.url.startsWith(location.origin+this.config.prefix)||!1}async fetch({request:e,clientId:t}){let r=await self.clients.get(t);return S.call(this,e,r)}}self.ScramjetServiceWorker=O})();
179 | //# sourceMappingURL=scramjet.worker.js.map
--------------------------------------------------------------------------------
/vendor/scramjet/lib/index.cjs:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const { resolve } = require("node:path");
4 |
5 | const scramjetPath = resolve(__dirname, "..", "dist");
6 |
7 | exports.scramjetPath = scramjetPath;
8 |
--------------------------------------------------------------------------------
/vendor/scramjet/lib/index.d.ts:
--------------------------------------------------------------------------------
1 | declare const scramjetPath: string;
2 |
3 | export { scramjetPath };
4 |
--------------------------------------------------------------------------------
/vendor/scramjet/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@mercuryworkshop/scramjet",
3 | "version": "1.0.2-dev",
4 | "description": "An experimental web proxy that aims to be the successor to Ultraviolet",
5 | "main": "./lib/index.cjs",
6 | "types": "./lib/index.d.js",
7 | "type": "module",
8 | "repository": {
9 | "type": "git",
10 | "url": "https://github.com/MercuryWorkshop/scramjet"
11 | },
12 | "files": [
13 | "dist/*.js",
14 | "dist/*.js.map",
15 | "lib"
16 | ],
17 | "keywords": [],
18 | "author": "",
19 | "license": "MIT",
20 | "devDependencies": {
21 | "@eslint/eslintrc": "^3.2.0",
22 | "@eslint/js": "^9.17.0",
23 | "@estruyf/github-actions-reporter": "^1.9.2",
24 | "@fastify/static": "^8.0.3",
25 | "@mercuryworkshop/bare-as-module3": "^2.2.5",
26 | "@mercuryworkshop/epoxy-transport": "^2.1.27",
27 | "@mercuryworkshop/libcurl-transport": "^1.3.14",
28 | "@nebula-services/bare-server-node": "^2.0.4",
29 | "@playwright/test": "^1.49.1",
30 | "@rsdoctor/rspack-plugin": "^0.4.11",
31 | "@rspack/cli": "^1.1.6",
32 | "@rspack/core": "^1.1.6",
33 | "@types/eslint": "^9.6.1",
34 | "@types/estree": "^1.0.6",
35 | "@types/node": "^22.10.2",
36 | "@types/serviceworker": "^0.0.107",
37 | "@typescript-eslint/eslint-plugin": "^8.18.0",
38 | "@typescript-eslint/parser": "^8.18.0",
39 | "dotenv": "^16.4.7",
40 | "eslint": "^9.17.0",
41 | "fastify": "^5.1.0",
42 | "playwright": "^1.49.1",
43 | "prettier": "^3.4.2",
44 | "tslib": "^2.8.1",
45 | "typescript": "^5.7.2",
46 | "wisp-server-node": "^1.1.7"
47 | },
48 | "dependencies": {
49 | "@mercuryworkshop/bare-mux": "^2.1.7",
50 | "dom-serializer": "^2.0.0",
51 | "domhandler": "^5.0.3",
52 | "domutils": "^3.1.0",
53 | "htmlparser2": "^9.1.0",
54 | "parse-domain": "^8.2.2",
55 | "set-cookie-parser": "^2.7.1"
56 | },
57 | "scripts": {
58 | "build": "rspack build --mode production",
59 | "rewriter:build": "cd rewriter/wasm/ && bash build.sh && cd ../../",
60 | "dev": "node server.js",
61 | "pub": "npm publish --no-git-checks --access public",
62 | "format": "prettier --config .prettierrc.js --write .",
63 | "lint": "eslint ./src/",
64 | "lint:fix": "eslint ./src/ --fix",
65 | "test": "npx playwright test"
66 | }
67 | }
--------------------------------------------------------------------------------