♻️ Migrated to actix rs
This commit is contained in:
		| @@ -5,24 +5,24 @@ on: | |||||||
|     branches: [ master ] |     branches: [ master ] | ||||||
| 
 | 
 | ||||||
| jobs: | jobs: | ||||||
|   build-docker: |   build-image: | ||||||
|     runs-on: edge |     runs-on: ubuntu-latest | ||||||
|     steps: |     steps: | ||||||
|       - name: Checkout |       - name: Checkout | ||||||
|         uses: actions/checkout@v3 |         uses: actions/checkout@v4 | ||||||
|       - name: Set up QEMU |       - name: Set up QEMU | ||||||
|         uses: docker/setup-qemu-action@v2 |         uses: docker/setup-qemu-action@v3 | ||||||
|       - name: Set up Docker Buildx |       - name: Set up Docker Buildx | ||||||
|         uses: docker/setup-buildx-action@v2 |         uses: docker/setup-buildx-action@v3 | ||||||
|       - name: Login to Docker Hub |       - name: Login to Docker Hub | ||||||
|         uses: docker/login-action@v2 |         uses: docker/login-action@v3 | ||||||
|         with: |         with: | ||||||
|           username: ${{ secrets.DOCKER_REGISTRY_USERNAME }} |           username: ${{ secrets.DOCKER_REGISTRY_USERNAME }} | ||||||
|           password: ${{ secrets.DOCKER_REGISTRY_TOKEN }} |           password: ${{ secrets.DOCKER_REGISTRY_TOKEN }} | ||||||
|       - name: Build and push |       - name: Build and push | ||||||
|         uses: docker/build-push-action@v4 |         uses: docker/build-push-action@v5 | ||||||
|         with: |         with: | ||||||
|           context: . |           context: . | ||||||
|           file: ./Dockerfile |  | ||||||
|           push: true |           push: true | ||||||
|           tags: xsheep2010/roadsign:nightly |           file: ./Dockerfile | ||||||
|  |           tags: xsheep2010/roadsign:sigma | ||||||
							
								
								
									
										490
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										490
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @@ -2,6 +2,240 @@ | |||||||
| # It is not intended for manual editing. | # It is not intended for manual editing. | ||||||
| version = 3 | version = 3 | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "actix-codec" | ||||||
|  | version = "0.5.2" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a" | ||||||
|  | dependencies = [ | ||||||
|  |  "bitflags 2.4.1", | ||||||
|  |  "bytes", | ||||||
|  |  "futures-core", | ||||||
|  |  "futures-sink", | ||||||
|  |  "memchr", | ||||||
|  |  "pin-project-lite", | ||||||
|  |  "tokio", | ||||||
|  |  "tokio-util", | ||||||
|  |  "tracing", | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "actix-files" | ||||||
|  | version = "0.6.5" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "bf0bdd6ff79de7c9a021f5d9ea79ce23e108d8bfc9b49b5b4a2cf6fad5a35212" | ||||||
|  | dependencies = [ | ||||||
|  |  "actix-http", | ||||||
|  |  "actix-service", | ||||||
|  |  "actix-utils", | ||||||
|  |  "actix-web", | ||||||
|  |  "bitflags 2.4.1", | ||||||
|  |  "bytes", | ||||||
|  |  "derive_more", | ||||||
|  |  "futures-core", | ||||||
|  |  "http-range", | ||||||
|  |  "log", | ||||||
|  |  "mime", | ||||||
|  |  "mime_guess", | ||||||
|  |  "percent-encoding", | ||||||
|  |  "pin-project-lite", | ||||||
|  |  "v_htmlescape", | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "actix-http" | ||||||
|  | version = "3.6.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "d223b13fd481fc0d1f83bb12659ae774d9e3601814c68a0bc539731698cca743" | ||||||
|  | dependencies = [ | ||||||
|  |  "actix-codec", | ||||||
|  |  "actix-rt", | ||||||
|  |  "actix-service", | ||||||
|  |  "actix-utils", | ||||||
|  |  "ahash 0.8.8", | ||||||
|  |  "base64 0.21.7", | ||||||
|  |  "bitflags 2.4.1", | ||||||
|  |  "brotli", | ||||||
|  |  "bytes", | ||||||
|  |  "bytestring", | ||||||
|  |  "derive_more", | ||||||
|  |  "encoding_rs", | ||||||
|  |  "flate2", | ||||||
|  |  "futures-core", | ||||||
|  |  "h2 0.3.24", | ||||||
|  |  "http 0.2.11", | ||||||
|  |  "httparse", | ||||||
|  |  "httpdate", | ||||||
|  |  "itoa", | ||||||
|  |  "language-tags", | ||||||
|  |  "local-channel", | ||||||
|  |  "mime", | ||||||
|  |  "percent-encoding", | ||||||
|  |  "pin-project-lite", | ||||||
|  |  "rand", | ||||||
|  |  "sha1", | ||||||
|  |  "smallvec", | ||||||
|  |  "tokio", | ||||||
|  |  "tokio-util", | ||||||
|  |  "tracing", | ||||||
|  |  "zstd", | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "actix-macros" | ||||||
|  | version = "0.2.4" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" | ||||||
|  | dependencies = [ | ||||||
|  |  "quote", | ||||||
|  |  "syn 2.0.48", | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "actix-proxy" | ||||||
|  | version = "0.2.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "3eb1ba1258bd79835d602dffb79f62aae42da7569036c67929e21961e2b3693c" | ||||||
|  | dependencies = [ | ||||||
|  |  "actix-web", | ||||||
|  |  "awc", | ||||||
|  |  "openssl", | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "actix-router" | ||||||
|  | version = "0.5.2" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "d22475596539443685426b6bdadb926ad0ecaefdfc5fb05e5e3441f15463c511" | ||||||
|  | dependencies = [ | ||||||
|  |  "bytestring", | ||||||
|  |  "http 0.2.11", | ||||||
|  |  "regex", | ||||||
|  |  "serde", | ||||||
|  |  "tracing", | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "actix-rt" | ||||||
|  | version = "2.9.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "28f32d40287d3f402ae0028a9d54bef51af15c8769492826a69d28f81893151d" | ||||||
|  | dependencies = [ | ||||||
|  |  "futures-core", | ||||||
|  |  "tokio", | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "actix-server" | ||||||
|  | version = "2.3.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "3eb13e7eef0423ea6eab0e59f6c72e7cb46d33691ad56a726b3cd07ddec2c2d4" | ||||||
|  | dependencies = [ | ||||||
|  |  "actix-rt", | ||||||
|  |  "actix-service", | ||||||
|  |  "actix-utils", | ||||||
|  |  "futures-core", | ||||||
|  |  "futures-util", | ||||||
|  |  "mio", | ||||||
|  |  "socket2", | ||||||
|  |  "tokio", | ||||||
|  |  "tracing", | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "actix-service" | ||||||
|  | version = "2.0.2" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "3b894941f818cfdc7ccc4b9e60fa7e53b5042a2e8567270f9147d5591893373a" | ||||||
|  | dependencies = [ | ||||||
|  |  "futures-core", | ||||||
|  |  "paste", | ||||||
|  |  "pin-project-lite", | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "actix-tls" | ||||||
|  | version = "3.3.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "d4cce60a2f2b477bc72e5cde0af1812a6e82d8fd85b5570a5dcf2a5bf2c5be5f" | ||||||
|  | dependencies = [ | ||||||
|  |  "actix-rt", | ||||||
|  |  "actix-service", | ||||||
|  |  "actix-utils", | ||||||
|  |  "futures-core", | ||||||
|  |  "http 0.2.11", | ||||||
|  |  "http 1.0.0", | ||||||
|  |  "impl-more", | ||||||
|  |  "openssl", | ||||||
|  |  "pin-project-lite", | ||||||
|  |  "tokio", | ||||||
|  |  "tokio-openssl", | ||||||
|  |  "tokio-util", | ||||||
|  |  "tracing", | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "actix-utils" | ||||||
|  | version = "3.0.1" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "88a1dcdff1466e3c2488e1cb5c36a71822750ad43839937f85d2f4d9f8b705d8" | ||||||
|  | dependencies = [ | ||||||
|  |  "local-waker", | ||||||
|  |  "pin-project-lite", | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "actix-web" | ||||||
|  | version = "4.5.1" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "43a6556ddebb638c2358714d853257ed226ece6023ef9364f23f0c70737ea984" | ||||||
|  | dependencies = [ | ||||||
|  |  "actix-codec", | ||||||
|  |  "actix-http", | ||||||
|  |  "actix-macros", | ||||||
|  |  "actix-router", | ||||||
|  |  "actix-rt", | ||||||
|  |  "actix-server", | ||||||
|  |  "actix-service", | ||||||
|  |  "actix-utils", | ||||||
|  |  "actix-web-codegen", | ||||||
|  |  "ahash 0.8.8", | ||||||
|  |  "bytes", | ||||||
|  |  "bytestring", | ||||||
|  |  "cfg-if", | ||||||
|  |  "cookie 0.16.2", | ||||||
|  |  "derive_more", | ||||||
|  |  "encoding_rs", | ||||||
|  |  "futures-core", | ||||||
|  |  "futures-util", | ||||||
|  |  "itoa", | ||||||
|  |  "language-tags", | ||||||
|  |  "log", | ||||||
|  |  "mime", | ||||||
|  |  "once_cell", | ||||||
|  |  "pin-project-lite", | ||||||
|  |  "regex", | ||||||
|  |  "serde", | ||||||
|  |  "serde_json", | ||||||
|  |  "serde_urlencoded", | ||||||
|  |  "smallvec", | ||||||
|  |  "socket2", | ||||||
|  |  "time", | ||||||
|  |  "url", | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "actix-web-codegen" | ||||||
|  | version = "4.2.2" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "eb1f50ebbb30eca122b188319a4398b3f7bb4a8cdf50ecfb73bfc6a3c3ce54f5" | ||||||
|  | dependencies = [ | ||||||
|  |  "actix-router", | ||||||
|  |  "proc-macro2", | ||||||
|  |  "quote", | ||||||
|  |  "syn 2.0.48", | ||||||
|  | ] | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "addr2line" | name = "addr2line" | ||||||
| version = "0.21.0" | version = "0.21.0" | ||||||
| @@ -63,6 +297,19 @@ dependencies = [ | |||||||
|  "version_check", |  "version_check", | ||||||
| ] | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "ahash" | ||||||
|  | version = "0.8.8" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "42cd52102d3df161c77a887b608d7a4897d7cc112886a9537b738a887a03aaff" | ||||||
|  | dependencies = [ | ||||||
|  |  "cfg-if", | ||||||
|  |  "getrandom", | ||||||
|  |  "once_cell", | ||||||
|  |  "version_check", | ||||||
|  |  "zerocopy", | ||||||
|  | ] | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "aho-corasick" | name = "aho-corasick" | ||||||
| version = "1.1.2" | version = "1.1.2" | ||||||
| @@ -72,6 +319,21 @@ dependencies = [ | |||||||
|  "memchr", |  "memchr", | ||||||
| ] | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "alloc-no-stdlib" | ||||||
|  | version = "2.0.4" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "alloc-stdlib" | ||||||
|  | version = "0.2.2" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" | ||||||
|  | dependencies = [ | ||||||
|  |  "alloc-no-stdlib", | ||||||
|  | ] | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "android-tzdata" | name = "android-tzdata" | ||||||
| version = "0.1.1" | version = "0.1.1" | ||||||
| @@ -104,6 +366,40 @@ version = "1.1.0" | |||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
| checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "awc" | ||||||
|  | version = "3.4.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "68c09cc97310b926f01621faee652f3d1b0962545a3cec6c9ac07def9ea36c2c" | ||||||
|  | dependencies = [ | ||||||
|  |  "actix-codec", | ||||||
|  |  "actix-http", | ||||||
|  |  "actix-rt", | ||||||
|  |  "actix-service", | ||||||
|  |  "actix-tls", | ||||||
|  |  "actix-utils", | ||||||
|  |  "base64 0.21.7", | ||||||
|  |  "bytes", | ||||||
|  |  "cfg-if", | ||||||
|  |  "cookie 0.16.2", | ||||||
|  |  "derive_more", | ||||||
|  |  "futures-core", | ||||||
|  |  "futures-util", | ||||||
|  |  "h2 0.3.24", | ||||||
|  |  "http 0.2.11", | ||||||
|  |  "itoa", | ||||||
|  |  "log", | ||||||
|  |  "mime", | ||||||
|  |  "openssl", | ||||||
|  |  "percent-encoding", | ||||||
|  |  "pin-project-lite", | ||||||
|  |  "rand", | ||||||
|  |  "serde", | ||||||
|  |  "serde_json", | ||||||
|  |  "serde_urlencoded", | ||||||
|  |  "tokio", | ||||||
|  | ] | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "backtrace" | name = "backtrace" | ||||||
| version = "0.3.69" | version = "0.3.69" | ||||||
| @@ -152,6 +448,27 @@ dependencies = [ | |||||||
|  "generic-array", |  "generic-array", | ||||||
| ] | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "brotli" | ||||||
|  | version = "3.4.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "516074a47ef4bce09577a3b379392300159ce5b1ba2e501ff1c819950066100f" | ||||||
|  | dependencies = [ | ||||||
|  |  "alloc-no-stdlib", | ||||||
|  |  "alloc-stdlib", | ||||||
|  |  "brotli-decompressor", | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "brotli-decompressor" | ||||||
|  | version = "2.5.1" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" | ||||||
|  | dependencies = [ | ||||||
|  |  "alloc-no-stdlib", | ||||||
|  |  "alloc-stdlib", | ||||||
|  | ] | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "bumpalo" | name = "bumpalo" | ||||||
| version = "3.14.0" | version = "3.14.0" | ||||||
| @@ -170,12 +487,22 @@ version = "1.5.0" | |||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
| checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" | checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "bytestring" | ||||||
|  | version = "1.3.1" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "74d80203ea6b29df88012294f62733de21cfeab47f17b41af3a38bc30a03ee72" | ||||||
|  | dependencies = [ | ||||||
|  |  "bytes", | ||||||
|  | ] | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "cc" | name = "cc" | ||||||
| version = "1.0.83" | version = "1.0.83" | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
| checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" | checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" | ||||||
| dependencies = [ | dependencies = [ | ||||||
|  |  "jobserver", | ||||||
|  "libc", |  "libc", | ||||||
| ] | ] | ||||||
|  |  | ||||||
| @@ -232,6 +559,17 @@ version = "0.4.0" | |||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
| checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" | checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "cookie" | ||||||
|  | version = "0.16.2" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" | ||||||
|  | dependencies = [ | ||||||
|  |  "percent-encoding", | ||||||
|  |  "time", | ||||||
|  |  "version_check", | ||||||
|  | ] | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "cookie" | name = "cookie" | ||||||
| version = "0.17.0" | version = "0.17.0" | ||||||
| @@ -275,6 +613,15 @@ dependencies = [ | |||||||
|  "libc", |  "libc", | ||||||
| ] | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "crc32fast" | ||||||
|  | version = "1.3.2" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" | ||||||
|  | dependencies = [ | ||||||
|  |  "cfg-if", | ||||||
|  | ] | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "crypto-common" | name = "crypto-common" | ||||||
| version = "0.1.6" | version = "0.1.6" | ||||||
| @@ -406,6 +753,16 @@ version = "2.0.1" | |||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
| checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" | checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "flate2" | ||||||
|  | version = "1.0.28" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" | ||||||
|  | dependencies = [ | ||||||
|  |  "crc32fast", | ||||||
|  |  "miniz_oxide", | ||||||
|  | ] | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "fnv" | name = "fnv" | ||||||
| version = "1.0.7" | version = "1.0.7" | ||||||
| @@ -528,9 +885,9 @@ checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" | |||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "h2" | name = "h2" | ||||||
| version = "0.3.23" | version = "0.3.24" | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
| checksum = "b553656127a00601c8ae5590fcfdc118e4083a7924b6cf4ffc1ea4b99dc429d7" | checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" | ||||||
| dependencies = [ | dependencies = [ | ||||||
|  "bytes", |  "bytes", | ||||||
|  "fnv", |  "fnv", | ||||||
| @@ -570,7 +927,7 @@ version = "0.12.3" | |||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
| checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" | ||||||
| dependencies = [ | dependencies = [ | ||||||
|  "ahash", |  "ahash 0.7.7", | ||||||
| ] | ] | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| @@ -683,6 +1040,12 @@ dependencies = [ | |||||||
|  "pin-project-lite", |  "pin-project-lite", | ||||||
| ] | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "http-range" | ||||||
|  | version = "0.1.5" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "httparse" | name = "httparse" | ||||||
| version = "1.8.0" | version = "1.8.0" | ||||||
| @@ -705,7 +1068,7 @@ dependencies = [ | |||||||
|  "futures-channel", |  "futures-channel", | ||||||
|  "futures-core", |  "futures-core", | ||||||
|  "futures-util", |  "futures-util", | ||||||
|  "h2 0.3.23", |  "h2 0.3.24", | ||||||
|  "http 0.2.11", |  "http 0.2.11", | ||||||
|  "http-body 0.4.6", |  "http-body 0.4.6", | ||||||
|  "httparse", |  "httparse", | ||||||
| @@ -814,6 +1177,12 @@ dependencies = [ | |||||||
|  "unicode-normalization", |  "unicode-normalization", | ||||||
| ] | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "impl-more" | ||||||
|  | version = "0.1.6" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "206ca75c9c03ba3d4ace2460e57b189f39f43de612c2f85836e65c929701bb2d" | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "indexmap" | name = "indexmap" | ||||||
| version = "2.1.0" | version = "2.1.0" | ||||||
| @@ -845,6 +1214,15 @@ version = "1.0.10" | |||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
| checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" | checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "jobserver" | ||||||
|  | version = "0.1.28" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" | ||||||
|  | dependencies = [ | ||||||
|  |  "libc", | ||||||
|  | ] | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "js-sys" | name = "js-sys" | ||||||
| version = "0.3.67" | version = "0.3.67" | ||||||
| @@ -865,6 +1243,12 @@ dependencies = [ | |||||||
|  "serde", |  "serde", | ||||||
| ] | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "language-tags" | ||||||
|  | version = "0.3.2" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "lazy_static" | name = "lazy_static" | ||||||
| version = "1.4.0" | version = "1.4.0" | ||||||
| @@ -889,6 +1273,23 @@ version = "0.4.12" | |||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
| checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" | checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "local-channel" | ||||||
|  | version = "0.1.5" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "b6cbc85e69b8df4b8bb8b89ec634e7189099cea8927a276b7384ce5488e53ec8" | ||||||
|  | dependencies = [ | ||||||
|  |  "futures-core", | ||||||
|  |  "futures-sink", | ||||||
|  |  "local-waker", | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "local-waker" | ||||||
|  | version = "0.1.4" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "4d873d7c67ce09b42110d801813efbc9364414e356be9935700d368351657487" | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "lock_api" | name = "lock_api" | ||||||
| version = "0.4.11" | version = "0.4.11" | ||||||
| @@ -949,6 +1350,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||||||
| checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" | checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" | ||||||
| dependencies = [ | dependencies = [ | ||||||
|  "libc", |  "libc", | ||||||
|  |  "log", | ||||||
|  "wasi", |  "wasi", | ||||||
|  "windows-sys 0.48.0", |  "windows-sys 0.48.0", | ||||||
| ] | ] | ||||||
| @@ -1144,6 +1546,12 @@ dependencies = [ | |||||||
|  "windows-targets 0.48.5", |  "windows-targets 0.48.5", | ||||||
| ] | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "paste" | ||||||
|  | version = "1.0.14" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "pathdiff" | name = "pathdiff" | ||||||
| version = "0.2.1" | version = "0.2.1" | ||||||
| @@ -1249,7 +1657,7 @@ dependencies = [ | |||||||
|  "base64 0.21.7", |  "base64 0.21.7", | ||||||
|  "bytes", |  "bytes", | ||||||
|  "chrono", |  "chrono", | ||||||
|  "cookie", |  "cookie 0.17.0", | ||||||
|  "futures-util", |  "futures-util", | ||||||
|  "headers", |  "headers", | ||||||
|  "http 1.0.0", |  "http 1.0.0", | ||||||
| @@ -1495,7 +1903,7 @@ dependencies = [ | |||||||
|  "encoding_rs", |  "encoding_rs", | ||||||
|  "futures-core", |  "futures-core", | ||||||
|  "futures-util", |  "futures-util", | ||||||
|  "h2 0.3.23", |  "h2 0.3.24", | ||||||
|  "http 0.2.11", |  "http 0.2.11", | ||||||
|  "http-body 0.4.6", |  "http-body 0.4.6", | ||||||
|  "hyper 0.14.28", |  "hyper 0.14.28", | ||||||
| @@ -1571,6 +1979,10 @@ dependencies = [ | |||||||
| name = "roadsign" | name = "roadsign" | ||||||
| version = "0.1.0" | version = "0.1.0" | ||||||
| dependencies = [ | dependencies = [ | ||||||
|  |  "actix-files", | ||||||
|  |  "actix-proxy", | ||||||
|  |  "actix-web", | ||||||
|  |  "awc", | ||||||
|  "config", |  "config", | ||||||
|  "futures-util", |  "futures-util", | ||||||
|  "http 1.0.0", |  "http 1.0.0", | ||||||
| @@ -2032,6 +2444,18 @@ dependencies = [ | |||||||
|  "tokio", |  "tokio", | ||||||
| ] | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "tokio-openssl" | ||||||
|  | version = "0.6.4" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "6ffab79df67727f6acf57f1ff743091873c24c579b1e2ce4d8f53e47ded4d63d" | ||||||
|  | dependencies = [ | ||||||
|  |  "futures-util", | ||||||
|  |  "openssl", | ||||||
|  |  "openssl-sys", | ||||||
|  |  "tokio", | ||||||
|  | ] | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "tokio-stream" | name = "tokio-stream" | ||||||
| version = "0.1.14" | version = "0.1.14" | ||||||
| @@ -2318,6 +2742,12 @@ version = "0.7.6" | |||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
| checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" | checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "v_htmlescape" | ||||||
|  | version = "0.15.8" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "4e8257fbc510f0a46eb602c10215901938b5c2a7d5e70fc11483b1d3c9b5b18c" | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "valuable" | name = "valuable" | ||||||
| version = "0.1.0" | version = "0.1.0" | ||||||
| @@ -2623,3 +3053,51 @@ checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" | |||||||
| dependencies = [ | dependencies = [ | ||||||
|  "linked-hash-map", |  "linked-hash-map", | ||||||
| ] | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "zerocopy" | ||||||
|  | version = "0.7.32" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" | ||||||
|  | dependencies = [ | ||||||
|  |  "zerocopy-derive", | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "zerocopy-derive" | ||||||
|  | version = "0.7.32" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" | ||||||
|  | dependencies = [ | ||||||
|  |  "proc-macro2", | ||||||
|  |  "quote", | ||||||
|  |  "syn 2.0.48", | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "zstd" | ||||||
|  | version = "0.13.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "bffb3309596d527cfcba7dfc6ed6052f1d39dfbd7c867aa2e865e4a449c10110" | ||||||
|  | dependencies = [ | ||||||
|  |  "zstd-safe", | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "zstd-safe" | ||||||
|  | version = "7.0.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "43747c7422e2924c11144d5229878b98180ef8b06cca4ab5af37afc8a8d8ea3e" | ||||||
|  | dependencies = [ | ||||||
|  |  "zstd-sys", | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "zstd-sys" | ||||||
|  | version = "2.0.9+zstd.1.5.5" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" | ||||||
|  | dependencies = [ | ||||||
|  |  "cc", | ||||||
|  |  "pkg-config", | ||||||
|  | ] | ||||||
|   | |||||||
| @@ -6,6 +6,10 @@ edition = "2021" | |||||||
| # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||||||
|  |  | ||||||
| [dependencies] | [dependencies] | ||||||
|  | actix-files = "0.6.5" | ||||||
|  | actix-proxy = "0.2.0" | ||||||
|  | actix-web = "4.5.1" | ||||||
|  | awc = "3.4.0" | ||||||
| config = { version = "0.13.4", features = ["toml"] } | config = { version = "0.13.4", features = ["toml"] } | ||||||
| futures-util = "0.3.30" | futures-util = "0.3.30" | ||||||
| http = "1.0.0" | http = "1.0.0" | ||||||
|   | |||||||
							
								
								
									
										98
									
								
								certs/fullchain.pem
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								certs/fullchain.pem
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,98 @@ | |||||||
|  | -----BEGIN CERTIFICATE----- | ||||||
|  | MIIGITCCBQmgAwIBAgISBPa2ahmRa5l0SrbR75K29TlqMA0GCSqGSIb3DQEBCwUA | ||||||
|  | MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD | ||||||
|  | EwJSMzAeFw0yNDAxMjgxNjM1MzZaFw0yNDA0MjcxNjM1MzVaMBwxGjAYBgNVBAMT | ||||||
|  | EXNtYXJ0c2hlZXAuc3R1ZGlvMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC | ||||||
|  | AgEAumtDoEkBHiqBGNl9JUbt3Nw1a/iLa2JHZvCmUuilvafAj0k1UPEu457iJVjh | ||||||
|  | nxlTl/tgpCooRNviboB0lMAecwiKb5PIZzInY2/gb+rceL7rycalDAjWnwZZg8Tl | ||||||
|  | 3JWJaU0D3+jeBQ9p7xkRPTcRpkGxFX9hRdInRqFGmCK4/OXrBwI3FkoP9Z8Nvgzc | ||||||
|  | RyIhmMEafOi2AaLJSXZQE508djHpcxlwoxvVmFIYsjTMJiq+zdqCZDTjDqt7bZC+ | ||||||
|  | mp3n/DFLL0sTzIBLuHnPkrjwlE4w/XTLkMLgrGPvEJVHn4kOvnJSWJb95d3sRZqB | ||||||
|  | PLrekQGDtcb0dpFx8ctWycVp0qhBTpuLAoN+AK6cJ3IkxOcGm7sKzYwRINjAblMe | ||||||
|  | n1Y6as6JKL4zSZBt1jxua1NGIRQ1c4ReA78NniTMrFIk1mFL4kNT9ppgDsWGNTJx | ||||||
|  | FqC76rr3TdKXKzD/c8h57j3CPTF9lGB4Vmlkrq/zA++br0IG7Ki/+1n04Q1UDN0E | ||||||
|  | 8z/vgUsT+pMItrmUhpnhb+4QWLQHTWOg1CyWT9xSm77ArkuNSdzNFGjpSbYZEPlh | ||||||
|  | pmAYTz+kWvnyg7T3Lt7fmSPCBnnIWhi9CJofvyomICWfcKEfwc0msJquXMyJBayA | ||||||
|  | K91VMoudbveI+CX8Zuc5u4uCOk/Dr6JJWnYkIDK7cW+tFh0CAwEAAaOCAkUwggJB | ||||||
|  | MA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw | ||||||
|  | DAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUPabqUNdBFv+3fEpgh2seAHvPQFgwHwYD | ||||||
|  | VR0jBBgwFoAUFC6zF7dYVsuuUAlA5h+vnYsUwsYwVQYIKwYBBQUHAQEESTBHMCEG | ||||||
|  | CCsGAQUFBzABhhVodHRwOi8vcjMuby5sZW5jci5vcmcwIgYIKwYBBQUHMAKGFmh0 | ||||||
|  | dHA6Ly9yMy5pLmxlbmNyLm9yZy8wTQYDVR0RBEYwRIIaKi5wbGF5bWMuc21hcnRz | ||||||
|  | aGVlcC5zdHVkaW+CEyouc21hcnRzaGVlcC5zdHVkaW+CEXNtYXJ0c2hlZXAuc3R1 | ||||||
|  | ZGlvMBMGA1UdIAQMMAowCAYGZ4EMAQIBMIIBBQYKKwYBBAHWeQIEAgSB9gSB8wDx | ||||||
|  | AHcAO1N3dT4tuYBOizBbBv5AO2fYT8P0x70ADS1yb+H61BcAAAGNUSQZ5gAABAMA | ||||||
|  | SDBGAiEA9i8QVPKh68OY9Ug+KqZ1aWSx5SVUvPKVyp8KkI/RMssCIQD0JsqwhLFx | ||||||
|  | SQFVROa1yhbZIdIHs9NMuW7lHbOWOU4F+AB2AO7N0GTV2xrOxVy3nbTNE6Iyh0Z8 | ||||||
|  | vOzew1FIWUZxH7WbAAABjVEkGesAAAQDAEcwRQIhAKXGxcDa/aGK50QyhOXAdlKl | ||||||
|  | VCk0Yo9wYzw2sB48BF1TAiBsW2R+CJXhnCBzcRRh8GQuj+aBcYIzHBaRvsanC9nx | ||||||
|  | 9zANBgkqhkiG9w0BAQsFAAOCAQEAgYR8uizQZkkvlEyI5dsz/tGJ0Vuejnd6yfoE | ||||||
|  | OT6BaNF45UtdMfSoJRLwgW6SM1hsuwmPjoUVS9VZ83NAhnWQqSeR9P4m7aMfhaeK | ||||||
|  | qPlDDcGh/SZOvgeja8AsUhCq+9csUzR+FEfk7xJXFflcG1FNGzRglzmqrSvFHKhE | ||||||
|  | EyJQuk6Oa/UiL0ICdKiLxh75gTJvTB/7wznTP7NGsayzqkBj4nxqHIwCGh7hPe2c | ||||||
|  | 2xMEbcFA9aArInJEg2PzlYRy1C9qtuhU2hJUhLjEix4WVCHUyAV/X6kwjqIaUEOz | ||||||
|  | NdUrFCahGkWDVZZcPgl/FdFSPfSL/pnT8jOotELnhj0AiX2SNQ== | ||||||
|  | -----END CERTIFICATE----- | ||||||
|  |  | ||||||
|  | -----BEGIN CERTIFICATE----- | ||||||
|  | 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 | ||||||
|  | nLRbwHOoq7hHwg== | ||||||
|  | -----END CERTIFICATE----- | ||||||
|  |  | ||||||
|  | -----BEGIN CERTIFICATE----- | ||||||
|  | MIIFYDCCBEigAwIBAgIQQAF3ITfU6UK47naqPGQKtzANBgkqhkiG9w0BAQsFADA/ | ||||||
|  | MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT | ||||||
|  | DkRTVCBSb290IENBIFgzMB4XDTIxMDEyMDE5MTQwM1oXDTI0MDkzMDE4MTQwM1ow | ||||||
|  | TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh | ||||||
|  | cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwggIiMA0GCSqGSIb3DQEB | ||||||
|  | AQUAA4ICDwAwggIKAoICAQCt6CRz9BQ385ueK1coHIe+3LffOJCMbjzmV6B493XC | ||||||
|  | ov71am72AE8o295ohmxEk7axY/0UEmu/H9LqMZshftEzPLpI9d1537O4/xLxIZpL | ||||||
|  | wYqGcWlKZmZsj348cL+tKSIG8+TA5oCu4kuPt5l+lAOf00eXfJlII1PoOK5PCm+D | ||||||
|  | LtFJV4yAdLbaL9A4jXsDcCEbdfIwPPqPrt3aY6vrFk/CjhFLfs8L6P+1dy70sntK | ||||||
|  | 4EwSJQxwjQMpoOFTJOwT2e4ZvxCzSow/iaNhUd6shweU9GNx7C7ib1uYgeGJXDR5 | ||||||
|  | bHbvO5BieebbpJovJsXQEOEO3tkQjhb7t/eo98flAgeYjzYIlefiN5YNNnWe+w5y | ||||||
|  | sR2bvAP5SQXYgd0FtCrWQemsAXaVCg/Y39W9Eh81LygXbNKYwagJZHduRze6zqxZ | ||||||
|  | Xmidf3LWicUGQSk+WT7dJvUkyRGnWqNMQB9GoZm1pzpRboY7nn1ypxIFeFntPlF4 | ||||||
|  | FQsDj43QLwWyPntKHEtzBRL8xurgUBN8Q5N0s8p0544fAQjQMNRbcTa0B7rBMDBc | ||||||
|  | SLeCO5imfWCKoqMpgsy6vYMEG6KDA0Gh1gXxG8K28Kh8hjtGqEgqiNx2mna/H2ql | ||||||
|  | PRmP6zjzZN7IKw0KKP/32+IVQtQi0Cdd4Xn+GOdwiK1O5tmLOsbdJ1Fu/7xk9TND | ||||||
|  | TwIDAQABo4IBRjCCAUIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw | ||||||
|  | SwYIKwYBBQUHAQEEPzA9MDsGCCsGAQUFBzAChi9odHRwOi8vYXBwcy5pZGVudHJ1 | ||||||
|  | c3QuY29tL3Jvb3RzL2RzdHJvb3RjYXgzLnA3YzAfBgNVHSMEGDAWgBTEp7Gkeyxx | ||||||
|  | +tvhS5B1/8QVYIWJEDBUBgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEEAYLfEwEB | ||||||
|  | ATAwMC4GCCsGAQUFBwIBFiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2VuY3J5cHQu | ||||||
|  | b3JnMDwGA1UdHwQ1MDMwMaAvoC2GK2h0dHA6Ly9jcmwuaWRlbnRydXN0LmNvbS9E | ||||||
|  | U1RST09UQ0FYM0NSTC5jcmwwHQYDVR0OBBYEFHm0WeZ7tuXkAXOACIjIGlj26Ztu | ||||||
|  | MA0GCSqGSIb3DQEBCwUAA4IBAQAKcwBslm7/DlLQrt2M51oGrS+o44+/yQoDFVDC | ||||||
|  | 5WxCu2+b9LRPwkSICHXM6webFGJueN7sJ7o5XPWioW5WlHAQU7G75K/QosMrAdSW | ||||||
|  | 9MUgNTP52GE24HGNtLi1qoJFlcDyqSMo59ahy2cI2qBDLKobkx/J3vWraV0T9VuG | ||||||
|  | WCLKTVXkcGdtwlfFRjlBz4pYg1htmf5X6DYO8A4jqv2Il9DjXA6USbW1FzXSLr9O | ||||||
|  | he8Y4IWS6wY7bCkjCWDcRQJMEhg76fsO3txE+FiYruq9RUWhiF1myv4Q6W+CyBFC | ||||||
|  | Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5 | ||||||
|  | -----END CERTIFICATE----- | ||||||
							
								
								
									
										51
									
								
								certs/privkey.pem
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								certs/privkey.pem
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | |||||||
|  | -----BEGIN RSA PRIVATE KEY----- | ||||||
|  | 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 | ||||||
|  | -----END RSA PRIVATE KEY----- | ||||||
							
								
								
									
										44
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								src/main.rs
									
									
									
									
									
								
							| @@ -1,16 +1,14 @@ | |||||||
| pub mod auth; | pub mod auth; | ||||||
| mod config; | mod config; | ||||||
| mod proxies; | mod proxies; | ||||||
| mod sideload; |  | ||||||
| pub mod warden; | pub mod warden; | ||||||
|  |  | ||||||
|  | use actix_web::{App, HttpServer, web}; | ||||||
|  | use awc::Client; | ||||||
| use lazy_static::lazy_static; | use lazy_static::lazy_static; | ||||||
| use poem::{listener::TcpListener, EndpointExt, Route, Server}; |  | ||||||
| use poem_openapi::OpenApiService; |  | ||||||
| use proxies::RoadInstance; | use proxies::RoadInstance; | ||||||
| use tokio::sync::Mutex; | use tokio::sync::Mutex; | ||||||
| use tracing::{error, info, Level}; | use tracing::{error, info, Level}; | ||||||
|  |  | ||||||
| use crate::proxies::route; | use crate::proxies::route; | ||||||
|  |  | ||||||
| lazy_static! { | lazy_static! { | ||||||
| @@ -20,9 +18,6 @@ lazy_static! { | |||||||
| #[tokio::main] | #[tokio::main] | ||||||
| async fn main() -> Result<(), std::io::Error> { | async fn main() -> Result<(), std::io::Error> { | ||||||
|     // Setting up logging |     // Setting up logging | ||||||
|     if std::env::var_os("RUST_LOG").is_none() { |  | ||||||
|         std::env::set_var("RUST_LOG", "poem=debug"); |  | ||||||
|     } |  | ||||||
|     tracing_subscriber::fmt() |     tracing_subscriber::fmt() | ||||||
|         .with_max_level(Level::DEBUG) |         .with_max_level(Level::DEBUG) | ||||||
|         .init(); |         .init(); | ||||||
| @@ -44,36 +39,17 @@ async fn main() -> Result<(), std::io::Error> { | |||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     // Proxies |     // Proxies | ||||||
|     let proxies_server = Server::new(TcpListener::bind( |     let proxies_server = HttpServer::new(|| { | ||||||
|  |         App::new() | ||||||
|  |             .app_data(web::Data::new(Client::default())) | ||||||
|  |             .route("/", web::to(route::handle)) | ||||||
|  |     }).bind( | ||||||
|         config::C |         config::C | ||||||
|             .read() |             .read() | ||||||
|             .await |             .await | ||||||
|             .get_string("listen.proxies") |             .get_string("listen.proxies") | ||||||
|             .unwrap_or("0.0.0.0:80".to_string()), |             .unwrap_or("0.0.0.0:80".to_string()) | ||||||
|     )) |     )?.run(); | ||||||
|     .run(route::handle); |  | ||||||
|  |  | ||||||
|     // Sideload |  | ||||||
|     let sideload = OpenApiService::new(sideload::SideloadApi, "Sideload API", "1.0") |  | ||||||
|         .server("http://localhost:3000/cgi"); |  | ||||||
|  |  | ||||||
|     let sideload_server = Server::new(TcpListener::bind( |  | ||||||
|         config::C |  | ||||||
|             .read() |  | ||||||
|             .await |  | ||||||
|             .get_string("listen.sideload") |  | ||||||
|             .unwrap_or("0.0.0.0:81".to_string()), |  | ||||||
|     )) |  | ||||||
|     .run( |  | ||||||
|         Route::new().nest("/cgi", sideload).with(auth::BasicAuth { |  | ||||||
|             username: "RoadSign".to_string(), |  | ||||||
|             password: config::C |  | ||||||
|                 .read() |  | ||||||
|                 .await |  | ||||||
|                 .get_string("secret") |  | ||||||
|                 .unwrap_or("password".to_string()), |  | ||||||
|         }), |  | ||||||
|     ); |  | ||||||
|  |  | ||||||
|     // Process manager |     // Process manager | ||||||
|     { |     { | ||||||
| @@ -85,7 +61,7 @@ async fn main() -> Result<(), std::io::Error> { | |||||||
|         app.warden.start().await; |         app.warden.start().await; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     tokio::try_join!(proxies_server, sideload_server)?; |     tokio::try_join!(proxies_server)?; | ||||||
|  |  | ||||||
|     Ok(()) |     Ok(()) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,52 +0,0 @@ | |||||||
| use std::fmt::Write; |  | ||||||
|  |  | ||||||
| pub struct DirectoryTemplate<'a> { |  | ||||||
|     pub path: &'a str, |  | ||||||
|     pub files: Vec<FileRef>, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl<'a> DirectoryTemplate<'a> { |  | ||||||
|     pub fn render(&self) -> String { |  | ||||||
|         let mut s = format!( |  | ||||||
|             r#" |  | ||||||
|         <html> |  | ||||||
|             <head> |  | ||||||
|             <title>Index of {}</title> |  | ||||||
|         </head> |  | ||||||
|         <body> |  | ||||||
|         <h1>Index of /{}</h1> |  | ||||||
|         <ul>"#, |  | ||||||
|             self.path, self.path |  | ||||||
|         ); |  | ||||||
|  |  | ||||||
|         for file in &self.files { |  | ||||||
|             if file.is_dir { |  | ||||||
|                 let _ = write!( |  | ||||||
|                     s, |  | ||||||
|                     r#"<li><a href="{}">{}/</a></li>"#, |  | ||||||
|                     file.url, file.filename |  | ||||||
|                 ); |  | ||||||
|             } else { |  | ||||||
|                 let _ = write!( |  | ||||||
|                     s, |  | ||||||
|                     r#"<li><a href="{}">{}</a></li>"#, |  | ||||||
|                     file.url, file.filename |  | ||||||
|                 ); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         s.push_str( |  | ||||||
|             r#"</ul> |  | ||||||
|         </body> |  | ||||||
|         </html>"#, |  | ||||||
|         ); |  | ||||||
|  |  | ||||||
|         s |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| pub struct FileRef { |  | ||||||
|     pub url: String, |  | ||||||
|     pub filename: String, |  | ||||||
|     pub is_dir: bool, |  | ||||||
| } |  | ||||||
| @@ -75,15 +75,6 @@ impl Destination { | |||||||
|         .collect::<Vec<_>>()[0] |         .collect::<Vec<_>>()[0] | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     pub fn get_websocket_uri(&self) -> Result<String, ()> { |  | ||||||
|         let parts = self.uri.as_str().splitn(2, "://").collect::<Vec<_>>(); |  | ||||||
|         let url = parts.get(1).unwrap_or(&""); |  | ||||||
|         match self.get_protocol() { |  | ||||||
|             "http" | "https" => Ok(url.replace("http", "ws")), |  | ||||||
|             _ => Err(()), |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     pub fn get_hypertext_uri(&self) -> Result<String, ()> { |     pub fn get_hypertext_uri(&self) -> Result<String, ()> { | ||||||
|         match self.get_protocol() { |         match self.get_protocol() { | ||||||
|             "http" => Ok("http://".to_string() + self.get_host()), |             "http" => Ok("http://".to_string() + self.get_host()), | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| use http::Method; | use actix_web::http::header::HeaderMap; | ||||||
| use poem::http::{HeaderMap, Uri}; | use actix_web::http::{Method, Uri}; | ||||||
| use regex::Regex; | use regex::Regex; | ||||||
| use wildmatch::WildMatch; | use wildmatch::WildMatch; | ||||||
|  |  | ||||||
| @@ -10,7 +10,6 @@ use self::{ | |||||||
|     metrics::RoadMetrics, |     metrics::RoadMetrics, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| pub mod browser; |  | ||||||
| pub mod config; | pub mod config; | ||||||
| pub mod loader; | pub mod loader; | ||||||
| pub mod metrics; | pub mod metrics; | ||||||
| @@ -38,7 +37,7 @@ impl RoadInstance { | |||||||
|     pub fn filter( |     pub fn filter( | ||||||
|         &self, |         &self, | ||||||
|         uri: &Uri, |         uri: &Uri, | ||||||
|         method: Method, |         method: &Method, | ||||||
|         headers: &HeaderMap, |         headers: &HeaderMap, | ||||||
|     ) -> Option<(&Region, &Location)> { |     ) -> Option<(&Region, &Location)> { | ||||||
|         self.regions.iter().find_map(|region| { |         self.regions.iter().find_map(|region| { | ||||||
|   | |||||||
| @@ -1,117 +1,50 @@ | |||||||
| use futures_util::{SinkExt, StreamExt}; | use futures_util::{SinkExt}; | ||||||
| use http::{header, request::Builder, HeaderMap, Method, StatusCode, Uri}; |  | ||||||
| use lazy_static::lazy_static; |  | ||||||
| use poem::{ |  | ||||||
|     web::{websocket::WebSocket, StaticFileRequest}, |  | ||||||
|     Body, Error, FromRequest, IntoResponse, Request, Response, |  | ||||||
| }; |  | ||||||
| use std::{ | use std::{ | ||||||
|     ffi::OsStr, |     ffi::OsStr, | ||||||
|     path::{Path, PathBuf}, |     path::{Path, PathBuf}, | ||||||
|     sync::Arc, |  | ||||||
| }; | }; | ||||||
| use tokio::sync::RwLock; | use actix_files::{NamedFile}; | ||||||
| use tokio_tungstenite::connect_async; | use actix_proxy::IntoHttpResponse; | ||||||
|  | use actix_web::{HttpRequest, HttpResponse, web}; | ||||||
| use super::browser::{DirectoryTemplate, FileRef}; | use actix_web::http::Method; | ||||||
|  | use awc::Client; | ||||||
| lazy_static! { |  | ||||||
|     pub static ref CLIENT: reqwest::Client = reqwest::Client::new(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| pub async fn repond_websocket(req: Builder, ws: WebSocket) -> Response { |  | ||||||
|     ws.on_upgrade(move |socket| async move { |  | ||||||
|         let (mut clientsink, mut clientstream) = socket.split(); |  | ||||||
|  |  | ||||||
|         // Start connection to server |  | ||||||
|         let (serversocket, _) = connect_async(req.body(()).unwrap()).await.unwrap(); |  | ||||||
|         let (mut serversink, mut serverstream) = serversocket.split(); |  | ||||||
|  |  | ||||||
|         let client_live = Arc::new(RwLock::new(true)); |  | ||||||
|         let server_live = client_live.clone(); |  | ||||||
|  |  | ||||||
|         tokio::spawn(async move { |  | ||||||
|             while let Some(Ok(msg)) = clientstream.next().await { |  | ||||||
|                 if (serversink.send(msg.into()).await).is_err() { |  | ||||||
|                     break; |  | ||||||
|                 }; |  | ||||||
|                 if !*client_live.read().await { |  | ||||||
|                     break; |  | ||||||
|                 }; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             *client_live.write().await = false; |  | ||||||
|         }); |  | ||||||
|  |  | ||||||
|         // Relay server messages to the client |  | ||||||
|         tokio::spawn(async move { |  | ||||||
|             while let Some(Ok(msg)) = serverstream.next().await { |  | ||||||
|                 if (clientsink.send(msg.into()).await).is_err() { |  | ||||||
|                     break; |  | ||||||
|                 }; |  | ||||||
|                 if !*server_live.read().await { |  | ||||||
|                     break; |  | ||||||
|                 }; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             *server_live.write().await = false; |  | ||||||
|         }); |  | ||||||
|     }) |  | ||||||
|     .into_response() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| pub async fn respond_hypertext( | pub async fn respond_hypertext( | ||||||
|     uri: String, |     uri: String, | ||||||
|     ori: &Uri, |     req: HttpRequest, | ||||||
|     req: &Request, |     client: web::Data<Client>, | ||||||
|     method: Method, | ) -> Result<HttpResponse, HttpResponse> { | ||||||
|     body: Body, |     let ip = req.peer_addr().unwrap().ip().to_string(); | ||||||
|     headers: &HeaderMap, |  | ||||||
| ) -> Result<Response, Error> { |  | ||||||
|     let ip = req.remote_addr().to_string(); |  | ||||||
|     let proto = req.uri().scheme_str().unwrap(); |     let proto = req.uri().scheme_str().unwrap(); | ||||||
|     let host = req.uri().host().unwrap(); |     let host = req.uri().host().unwrap(); | ||||||
|  |  | ||||||
|     let mut headers = headers.clone(); |     let mut headers = req.headers().clone(); | ||||||
|     headers.insert("Server", "RoadSign".parse().unwrap()); |     headers.insert("Server".parse().unwrap(), "RoadSign".parse().unwrap()); | ||||||
|     headers.insert("X-Forward-For", ip.parse().unwrap()); |     headers.insert("X-Forward-For".parse().unwrap(), ip.parse().unwrap()); | ||||||
|     headers.insert("X-Forwarded-Proto", proto.parse().unwrap()); |     headers.insert("X-Forwarded-Proto".parse().unwrap(), proto.parse().unwrap()); | ||||||
|     headers.insert("X-Forwarded-Host", host.parse().unwrap()); |     headers.insert("X-Forwarded-Host".parse().unwrap(), host.parse().unwrap()); | ||||||
|     headers.insert("X-Real-IP", ip.parse().unwrap()); |     headers.insert("X-Real-IP".parse().unwrap(), ip.parse().unwrap()); | ||||||
|     headers.insert( |     headers.insert( | ||||||
|         "Forwarded", |         "Forwarded".parse().unwrap(), | ||||||
|         format!("by={};for={};host={};proto={}", ip, ip, host, proto) |         format!("by={};for={};host={};proto={}", ip, ip, host, proto) | ||||||
|             .parse() |             .parse() | ||||||
|             .unwrap(), |             .unwrap(), | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|     let res = CLIENT |     let res = client.get(uri).send().await; | ||||||
|         .request(method, uri + ori.path() + ori.query().unwrap_or("")) |  | ||||||
|         .headers(headers.clone()) |  | ||||||
|         .body(body.into_bytes().await.unwrap()) |  | ||||||
|         .send() |  | ||||||
|         .await; |  | ||||||
|  |  | ||||||
|     match res { |     return match res { | ||||||
|         Ok(result) => { |         Ok(result) => { | ||||||
|             let mut res = Response::default(); |             let mut res = result.into_http_response(); | ||||||
|             res.extensions().clone_from(&result.extensions()); |             res.headers_mut().insert("Server".parse().unwrap(), "RoadSign".parse().unwrap()); | ||||||
|             result.headers().iter().for_each(|(key, val)| { |  | ||||||
|                 res.headers_mut().insert(key, val.to_owned()); |  | ||||||
|             }); |  | ||||||
|             res.headers_mut() |  | ||||||
|                 .insert("Server", "RoadSign".parse().unwrap()); |  | ||||||
|             res.set_status(result.status()); |  | ||||||
|             res.set_version(result.version()); |  | ||||||
|             res.set_body(result.bytes().await.unwrap()); |  | ||||||
|             Ok(res) |             Ok(res) | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         Err(error) => Err(Error::from_string( |         Err(error) => { | ||||||
|             error.to_string(), |             Err(HttpResponse::BadGateway() | ||||||
|             error.status().unwrap_or(StatusCode::BAD_GATEWAY), |                 .body(format!("Something went wrong... {:}", error))) | ||||||
|         )), |         } | ||||||
|     } |     }; | ||||||
| } | } | ||||||
|  |  | ||||||
| pub struct StaticResponderConfig { | pub struct StaticResponderConfig { | ||||||
| @@ -126,14 +59,11 @@ pub struct StaticResponderConfig { | |||||||
|  |  | ||||||
| pub async fn respond_static( | pub async fn respond_static( | ||||||
|     cfg: StaticResponderConfig, |     cfg: StaticResponderConfig, | ||||||
|     method: Method, |     req: HttpRequest, | ||||||
|     req: &Request, | ) -> Result<HttpResponse, HttpResponse> { | ||||||
| ) -> Result<Response, Error> { |     if req.method() != Method::GET { | ||||||
|     if method != Method::GET { |         return Err(HttpResponse::MethodNotAllowed() | ||||||
|         return Err(Error::from_string( |             .body("This destination only support GET request.")); | ||||||
|             "This destination only support GET request.", |  | ||||||
|             StatusCode::METHOD_NOT_ALLOWED, |  | ||||||
|         )); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     let path = req |     let path = req | ||||||
| @@ -142,9 +72,12 @@ pub async fn respond_static( | |||||||
|         .trim_start_matches('/') |         .trim_start_matches('/') | ||||||
|         .trim_end_matches('/'); |         .trim_end_matches('/'); | ||||||
|  |  | ||||||
|     let path = percent_encoding::percent_decode_str(path) |     let path = match percent_encoding::percent_decode_str(path).decode_utf8() { | ||||||
|         .decode_utf8() |         Ok(val) => val, | ||||||
|         .map_err(|_| Error::from_status(StatusCode::NOT_FOUND))?; |         Err(_) => { | ||||||
|  |             return Err(HttpResponse::NotFound().body("Not found.")); | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  |  | ||||||
|     let base_path = cfg.uri.parse::<PathBuf>().unwrap(); |     let base_path = cfg.uri.parse::<PathBuf>().unwrap(); | ||||||
|     let mut file_path = base_path.clone(); |     let mut file_path = base_path.clone(); | ||||||
| @@ -159,7 +92,8 @@ pub async fn respond_static( | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     if !file_path.starts_with(cfg.uri) { |     if !file_path.starts_with(cfg.uri) { | ||||||
|         return Err(Error::from_status(StatusCode::FORBIDDEN)); |         return Err(HttpResponse::Forbidden() | ||||||
|  |             .body("Unexpected path.")); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if !file_path.exists() { |     if !file_path.exists() { | ||||||
| @@ -172,87 +106,30 @@ pub async fn respond_static( | |||||||
|             file_path.pop(); |             file_path.pop(); | ||||||
|             file_path.push((file_name + &suffix).as_str()); |             file_path.push((file_name + &suffix).as_str()); | ||||||
|             if file_path.is_file() { |             if file_path.is_file() { | ||||||
|                 return Ok(StaticFileRequest::from_request_without_body(req) |                 return Ok(NamedFile::open(file_path).unwrap().into_response(&req)); | ||||||
|                     .await? |  | ||||||
|                     .create_response(&file_path, cfg.utf8)? |  | ||||||
|                     .into_response()); |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if let Some(file) = cfg.fallback { |         if let Some(file) = cfg.fallback { | ||||||
|             let fallback_path = base_path.join(file); |             let fallback_path = base_path.join(file); | ||||||
|             if fallback_path.is_file() { |             if fallback_path.is_file() { | ||||||
|                 return Ok(StaticFileRequest::from_request_without_body(req) |                 return Ok(NamedFile::open(fallback_path).unwrap().into_response(&req)); | ||||||
|                     .await? |  | ||||||
|                     .create_response(&fallback_path, cfg.utf8)? |  | ||||||
|                     .into_response()); |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         return Err(Error::from_status(StatusCode::NOT_FOUND)); |  | ||||||
|  |         return Err(HttpResponse::NotFound().body("Not found.")); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if file_path.is_file() { |     return if file_path.is_file() { | ||||||
|         Ok(StaticFileRequest::from_request_without_body(req) |         Ok(NamedFile::open(file_path).unwrap().into_response(&req)) | ||||||
|             .await? |  | ||||||
|             .create_response(&file_path, cfg.utf8)? |  | ||||||
|             .into_response()) |  | ||||||
|     } else { |     } else { | ||||||
|         if cfg.with_slash |  | ||||||
|             && !req.original_uri().path().ends_with('/') |  | ||||||
|             && (cfg.index.is_some() || cfg.browse) |  | ||||||
|         { |  | ||||||
|             let redirect_to = format!("{}/", req.original_uri().path()); |  | ||||||
|             return Ok(Response::builder() |  | ||||||
|                 .status(StatusCode::FOUND) |  | ||||||
|                 .header(header::LOCATION, redirect_to) |  | ||||||
|                 .finish()); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if let Some(index_file) = &cfg.index { |         if let Some(index_file) = &cfg.index { | ||||||
|             let index_path = file_path.join(index_file); |             let index_path = file_path.join(index_file); | ||||||
|             if index_path.is_file() { |             if index_path.is_file() { | ||||||
|                 return Ok(StaticFileRequest::from_request_without_body(req) |                 return Ok(NamedFile::open(index_path).unwrap().into_response(&req)); | ||||||
|                     .await? |  | ||||||
|                     .create_response(&index_path, cfg.utf8)? |  | ||||||
|                     .into_response()); |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if cfg.browse { |         Err(HttpResponse::NotFound().body("Not found.")) | ||||||
|             let read_dir = file_path |     }; | ||||||
|                 .read_dir() |  | ||||||
|                 .map_err(|_| Error::from_status(StatusCode::FORBIDDEN))?; |  | ||||||
|             let mut template = DirectoryTemplate { |  | ||||||
|                 path: &path, |  | ||||||
|                 files: Vec::new(), |  | ||||||
|             }; |  | ||||||
|  |  | ||||||
|             for res in read_dir { |  | ||||||
|                 let entry = res.map_err(|_| Error::from_status(StatusCode::FORBIDDEN))?; |  | ||||||
|  |  | ||||||
|                 if let Some(filename) = entry.file_name().to_str() { |  | ||||||
|                     let mut base_url = req.original_uri().path().to_string(); |  | ||||||
|                     if !base_url.ends_with('/') { |  | ||||||
|                         base_url.push('/'); |  | ||||||
|                     } |  | ||||||
|                     let filename_url = percent_encoding::percent_encode( |  | ||||||
|                         filename.as_bytes(), |  | ||||||
|                         percent_encoding::NON_ALPHANUMERIC, |  | ||||||
|                     ); |  | ||||||
|                     template.files.push(FileRef { |  | ||||||
|                         url: format!("{base_url}{filename_url}"), |  | ||||||
|                         filename: filename.to_string(), |  | ||||||
|                         is_dir: entry.path().is_dir(), |  | ||||||
|                     }); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             let html = template.render(); |  | ||||||
|             Ok(Response::builder() |  | ||||||
|                 .header(header::CONTENT_TYPE, mime::TEXT_HTML_UTF_8.as_ref()) |  | ||||||
|                 .body(Body::from_string(html))) |  | ||||||
|         } else { |  | ||||||
|             Err(Error::from_status(StatusCode::NOT_FOUND)) |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,10 +1,5 @@ | |||||||
| use http::Method; | use actix_web::{HttpRequest, HttpResponse, web}; | ||||||
| use poem::{ | use awc::Client; | ||||||
|     handler, |  | ||||||
|     http::{HeaderMap, StatusCode, Uri}, |  | ||||||
|     web::websocket::WebSocket, |  | ||||||
|     Body, Error, FromRequest, IntoResponse, Request, Response, Result, |  | ||||||
| }; |  | ||||||
| use rand::seq::SliceRandom; | use rand::seq::SliceRandom; | ||||||
|  |  | ||||||
| use crate::{ | use crate::{ | ||||||
| @@ -15,22 +10,13 @@ use crate::{ | |||||||
|     ROAD, |     ROAD, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #[handler] | pub async fn handle(req: HttpRequest, client: web::Data<Client>) -> HttpResponse { | ||||||
| pub async fn handle( |  | ||||||
|     req: &Request, |  | ||||||
|     uri: &Uri, |  | ||||||
|     headers: &HeaderMap, |  | ||||||
|     method: Method, |  | ||||||
|     body: Body, |  | ||||||
| ) -> Result<impl IntoResponse, Error> { |  | ||||||
|     let readable_app = ROAD.lock().await; |     let readable_app = ROAD.lock().await; | ||||||
|     let (region, location) = match readable_app.filter(uri, method.clone(), headers) { |     let (region, location) = match readable_app.filter(req.uri(), req.method(), req.headers()) { | ||||||
|         Some(val) => val, |         Some(val) => val, | ||||||
|         None => { |         None => { | ||||||
|             return Err(Error::from_string( |             return HttpResponse::NotFound() | ||||||
|                 "There are no region be able to respone this request.", |                 .body("There are no region be able to respone this request."); | ||||||
|                 StatusCode::NOT_FOUND, |  | ||||||
|             )) |  | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
| @@ -41,58 +27,31 @@ pub async fn handle( | |||||||
|  |  | ||||||
|     async fn forward( |     async fn forward( | ||||||
|         end: &Destination, |         end: &Destination, | ||||||
|         req: &Request, |         req: HttpRequest, | ||||||
|         ori: &Uri, |         client: web::Data<Client>, | ||||||
|         headers: &HeaderMap, |     ) -> Result<HttpResponse, HttpResponse> { | ||||||
|         method: Method, |  | ||||||
|         body: Body, |  | ||||||
|     ) -> Result<Response, Error> { |  | ||||||
|         // Handle websocket |  | ||||||
|         if let Ok(ws) = WebSocket::from_request_without_body(req).await { |  | ||||||
|             // Get uri |  | ||||||
|             let Ok(uri) = end.get_websocket_uri() else { |  | ||||||
|                 return Err(Error::from_string( |  | ||||||
|                     "This destination was not support websockets.", |  | ||||||
|                     StatusCode::NOT_IMPLEMENTED, |  | ||||||
|                 )); |  | ||||||
|             }; |  | ||||||
|  |  | ||||||
|             // Build request |  | ||||||
|             let mut ws_req = http::Request::builder().uri(&uri); |  | ||||||
|             for (key, value) in headers.iter() { |  | ||||||
|                 ws_req = ws_req.header(key, value); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             // Start the websocket connection |  | ||||||
|             return Ok(responder::repond_websocket(ws_req, ws).await); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         // Handle normal web request |         // Handle normal web request | ||||||
|         match end.get_type() { |         match end.get_type() { | ||||||
|             DestinationType::Hypertext => { |             DestinationType::Hypertext => { | ||||||
|                 let Ok(uri) = end.get_hypertext_uri() else { |                 let Ok(uri) = end.get_hypertext_uri() else { | ||||||
|                     return Err(Error::from_string( |                     return Err(HttpResponse::NotImplemented() | ||||||
|                         "This destination was not support web requests.", |                         .body("This destination was not support web requests.")); | ||||||
|                         StatusCode::NOT_IMPLEMENTED, |  | ||||||
|                     )); |  | ||||||
|                 }; |                 }; | ||||||
|  |  | ||||||
|                 responder::respond_hypertext(uri, ori, req, method, body, headers).await |                 responder::respond_hypertext(uri, req, client).await | ||||||
|             } |             } | ||||||
|             DestinationType::StaticFiles => { |             DestinationType::StaticFiles => { | ||||||
|                 let Ok(cfg) = end.get_static_config() else { |                 let Ok(cfg) = end.get_static_config() else { | ||||||
|                     return Err(Error::from_string( |                     return Err(HttpResponse::NotImplemented() | ||||||
|                         "This destination was not support static files.", |                         .body("This destination was not support static files.")); | ||||||
|                         StatusCode::NOT_IMPLEMENTED, |  | ||||||
|                     )); |  | ||||||
|                 }; |                 }; | ||||||
|  |  | ||||||
|                 responder::respond_static(cfg, method, req).await |                 responder::respond_static(cfg, req).await | ||||||
|  |             } | ||||||
|  |             _ => { | ||||||
|  |                 return Err(HttpResponse::NotImplemented() | ||||||
|  |                     .body("Unsupported destination protocol.")); | ||||||
|             } |             } | ||||||
|             _ => Err(Error::from_string( |  | ||||||
|                 "Unsupported destination protocol.", |  | ||||||
|                 StatusCode::NOT_IMPLEMENTED, |  | ||||||
|             )), |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -100,23 +59,22 @@ pub async fn handle( | |||||||
|     let loc = location.clone(); |     let loc = location.clone(); | ||||||
|     let end = destination.clone(); |     let end = destination.clone(); | ||||||
|  |  | ||||||
|     match forward(&end, req, uri, headers, method, body).await { |     return match forward(&end, req, client).await { | ||||||
|         Ok(resp) => { |         Ok(resp) => { | ||||||
|             tokio::spawn(async move { |             tokio::spawn(async move { | ||||||
|                 let writable_app = &mut ROAD.lock().await; |                 let writable_app = &mut ROAD.lock().await; | ||||||
|                 writable_app.metrics.add_success_request(reg, loc, end); |                 writable_app.metrics.add_success_request(reg, loc, end); | ||||||
|             }); |             }); | ||||||
|             Ok(resp) |             resp | ||||||
|         } |         } | ||||||
|         Err(err) => { |         Err(resp) => { | ||||||
|             let message = format!("{:}", err); |  | ||||||
|             tokio::spawn(async move { |             tokio::spawn(async move { | ||||||
|                 let writable_app = &mut ROAD.lock().await; |                 let writable_app = &mut ROAD.lock().await; | ||||||
|                 writable_app |                 writable_app | ||||||
|                     .metrics |                     .metrics | ||||||
|                     .add_faliure_request(reg, loc, end, message); |                     .add_faliure_request(reg, loc, end, "TODO".to_owned()); | ||||||
|             }); |             }); | ||||||
|             Err(err) |             resp | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,19 +0,0 @@ | |||||||
| use poem_openapi::OpenApi; |  | ||||||
|  |  | ||||||
| pub mod overview; |  | ||||||
| pub mod regions; |  | ||||||
|  |  | ||||||
| pub struct SideloadApi; |  | ||||||
|  |  | ||||||
| #[OpenApi] |  | ||||||
| impl SideloadApi { |  | ||||||
|     #[oai(path = "/", method = "get")] |  | ||||||
|     async fn index(&self) -> overview::OverviewResponse { |  | ||||||
|         overview::index().await |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[oai(path = "/regions", method = "get")] |  | ||||||
|     async fn regions_index(&self) -> regions::RegionResponse { |  | ||||||
|         regions::index().await |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,75 +0,0 @@ | |||||||
| use poem_openapi::{payload::Json, ApiResponse, Object}; |  | ||||||
|  |  | ||||||
| use crate::{ |  | ||||||
|     proxies::{ |  | ||||||
|         config::{Destination, Location}, |  | ||||||
|         metrics::RoadTrace, |  | ||||||
|     }, |  | ||||||
|     ROAD, |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| #[derive(ApiResponse)] |  | ||||||
| pub enum OverviewResponse { |  | ||||||
|     /// Return the overview data. |  | ||||||
|     #[oai(status = 200)] |  | ||||||
|     Ok(Json<OverviewData>), |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[derive(Debug, Object, Clone, PartialEq)] |  | ||||||
| pub struct OverviewData { |  | ||||||
|     /// Loaded regions count |  | ||||||
|     #[oai(read_only)] |  | ||||||
|     regions: usize, |  | ||||||
|     /// Loaded locations count |  | ||||||
|     #[oai(read_only)] |  | ||||||
|     locations: usize, |  | ||||||
|     /// Loaded destnations count |  | ||||||
|     #[oai(read_only)] |  | ||||||
|     destinations: usize, |  | ||||||
|     /// Recent requests count |  | ||||||
|     requests_count: u64, |  | ||||||
|     /// Recent requests success count |  | ||||||
|     faliures_count: u64, |  | ||||||
|     /// Recent requests falied count |  | ||||||
|     successes_count: u64, |  | ||||||
|     /// Recent requests success rate |  | ||||||
|     success_rate: f64, |  | ||||||
|     /// Recent successes |  | ||||||
|     recent_successes: Vec<RoadTrace>, |  | ||||||
|     /// Recent errors |  | ||||||
|     recent_errors: Vec<RoadTrace>, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| pub async fn index() -> OverviewResponse { |  | ||||||
|     let locked_app = ROAD.lock().await; |  | ||||||
|     let regions = locked_app.regions.clone(); |  | ||||||
|     let locations = regions |  | ||||||
|         .iter() |  | ||||||
|         .flat_map(|item| item.locations.clone()) |  | ||||||
|         .collect::<Vec<Location>>(); |  | ||||||
|     let destinations = locations |  | ||||||
|         .iter() |  | ||||||
|         .flat_map(|item| item.destinations.clone()) |  | ||||||
|         .collect::<Vec<Destination>>(); |  | ||||||
|     OverviewResponse::Ok(Json(OverviewData { |  | ||||||
|         regions: regions.len(), |  | ||||||
|         locations: locations.len(), |  | ||||||
|         destinations: destinations.len(), |  | ||||||
|         requests_count: locked_app.metrics.requests_count, |  | ||||||
|         successes_count: locked_app.metrics.requests_count - locked_app.metrics.failures_count, |  | ||||||
|         faliures_count: locked_app.metrics.failures_count, |  | ||||||
|         success_rate: locked_app.metrics.get_success_rate(), |  | ||||||
|         recent_successes: locked_app |  | ||||||
|             .metrics |  | ||||||
|             .recent_successes |  | ||||||
|             .clone() |  | ||||||
|             .into_iter() |  | ||||||
|             .collect::<Vec<_>>(), |  | ||||||
|         recent_errors: locked_app |  | ||||||
|             .metrics |  | ||||||
|             .recent_errors |  | ||||||
|             .clone() |  | ||||||
|             .into_iter() |  | ||||||
|             .collect::<Vec<_>>(), |  | ||||||
|     })) |  | ||||||
| } |  | ||||||
| @@ -1,25 +0,0 @@ | |||||||
| use poem_openapi::{payload::Json, ApiResponse}; |  | ||||||
|  |  | ||||||
| use crate::{proxies::config::Region, ROAD}; |  | ||||||
|  |  | ||||||
| #[derive(ApiResponse)] |  | ||||||
| pub enum RegionResponse { |  | ||||||
|     /// Return the region data. |  | ||||||
|     #[oai(status = 200)] |  | ||||||
|     Ok(Json<Region>), |  | ||||||
|     /// Return the list of region data. |  | ||||||
|     #[oai(status = 200)] |  | ||||||
|     OkMany(Json<Vec<Region>>), |  | ||||||
|     /// Return the region data after created. |  | ||||||
|     #[oai(status = 201)] |  | ||||||
|     Created(Json<Region>), |  | ||||||
|     /// Return was not found. |  | ||||||
|     #[oai(status = 404)] |  | ||||||
|     NotFound, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| pub async fn index() -> RegionResponse { |  | ||||||
|     let locked_app = ROAD.lock().await; |  | ||||||
|  |  | ||||||
|     RegionResponse::OkMany(Json(locked_app.regions.clone())) |  | ||||||
| } |  | ||||||
							
								
								
									
										179
									
								
								test/data/warden/dist/client/_astro/Media.7FWSwaPB.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								test/data/warden/dist/client/_astro/Media.7FWSwaPB.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										1
									
								
								test/data/warden/dist/client/_astro/Media.Co8_pG1j.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								test/data/warden/dist/client/_astro/Media.Co8_pG1j.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										1
									
								
								test/data/warden/dist/client/_astro/_slug_.bcjV8AoT.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								test/data/warden/dist/client/_astro/_slug_.bcjV8AoT.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | :root{--bs-body-font-family: "IBM Plex Serif", "Noto Serif SC", sans-serif !important}html,body{font-family:var(--bs-body-font-family)}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:normal;font-weight:100;src:url(/_astro/ibm-plex-serif-v19-latin-100.6qNbweSL.woff2) format("woff2")}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:italic;font-weight:100;src:url(/_astro/ibm-plex-serif-v19-latin-100italic.E22nrI7z.woff2) format("woff2")}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:normal;font-weight:200;src:url(/_astro/ibm-plex-serif-v19-latin-200.GFXE_YJc.woff2) format("woff2")}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:italic;font-weight:200;src:url(/_astro/ibm-plex-serif-v19-latin-200italic.pJK4yaaG.woff2) format("woff2")}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:normal;font-weight:300;src:url(/_astro/ibm-plex-serif-v19-latin-300.RVbRgkxX.woff2) format("woff2")}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:italic;font-weight:300;src:url(/_astro/ibm-plex-serif-v19-latin-300italic.ZdSVgmcR.woff2) format("woff2")}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:normal;font-weight:400;src:url(/_astro/ibm-plex-serif-v19-latin-regular.HRmMD3sQ.woff2) format("woff2")}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:italic;font-weight:400;src:url(/_astro/ibm-plex-serif-v19-latin-italic.MiJiQVsi.woff2) format("woff2")}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:normal;font-weight:500;src:url(/_astro/ibm-plex-serif-v19-latin-500.xAA_w-Ac.woff2) format("woff2")}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:italic;font-weight:500;src:url(/_astro/ibm-plex-serif-v19-latin-500italic.Unq84pJ7.woff2) format("woff2")}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:normal;font-weight:600;src:url(/_astro/ibm-plex-serif-v19-latin-600.cuuqzllG.woff2) format("woff2")}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:italic;font-weight:600;src:url(/_astro/ibm-plex-serif-v19-latin-600italic.vDhUog1q.woff2) format("woff2")}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:normal;font-weight:700;src:url(/_astro/ibm-plex-serif-v19-latin-700.yX9JjmCp.woff2) format("woff2")}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:italic;font-weight:700;src:url(/_astro/ibm-plex-serif-v19-latin-700italic.QM1RA0vx.woff2) format("woff2")}@font-face{font-display:swap;font-family:"Noto Serif SC";font-style:normal;font-weight:200;src:url(/_astro/noto-serif-sc-v22-chinese-simplified-200.g4OBZhIi.woff2) format("woff2")}@font-face{font-display:swap;font-family:"Noto Serif SC";font-style:normal;font-weight:300;src:url(/_astro/noto-serif-sc-v22-chinese-simplified-300.yFtdUYoh.woff2) format("woff2")}@font-face{font-display:swap;font-family:"Noto Serif SC";font-style:normal;font-weight:400;src:url(/_astro/noto-serif-sc-v22-chinese-simplified-regular.9muiKgFz.woff2) format("woff2")}@font-face{font-display:swap;font-family:"Noto Serif SC";font-style:normal;font-weight:500;src:url(/_astro/noto-serif-sc-v22-chinese-simplified-500.exkAspFQ.woff2) format("woff2")}@font-face{font-display:swap;font-family:"Noto Serif SC";font-style:normal;font-weight:600;src:url(/_astro/noto-serif-sc-v22-chinese-simplified-600.4n6uFOXj.woff2) format("woff2")}@font-face{font-display:swap;font-family:"Noto Serif SC";font-style:normal;font-weight:700;src:url(/_astro/noto-serif-sc-v22-chinese-simplified-700.HyiB9Pzv.woff2) format("woff2")}@font-face{font-display:swap;font-family:"Noto Serif SC";font-style:normal;font-weight:900;src:url(/_astro/noto-serif-sc-v22-chinese-simplified-900.ERSRy_0V.woff2) format("woff2")}.astro-route-announcer{position:absolute;left:0;top:0;clip:rect(0 0 0 0);-webkit-clip-path:inset(50%);clip-path:inset(50%);overflow:hidden;white-space:nowrap;width:1px;height:1px}.h-fullpage{height:calc(100vh - 64px)}.max-h-fullpage{max-height:calc(100vh - 64px)}.mt-header{margin-top:64px}.top-header{top:64px}html{overflow-x:hidden!important;overflow-y:auto!important}@keyframes astroFadeInOut{0%{opacity:1}to{opacity:0}}@keyframes astroFadeIn{0%{opacity:0}}@keyframes astroFadeOut{to{opacity:0}}@keyframes astroSlideFromRight{0%{transform:translate(100%)}}@keyframes astroSlideFromLeft{0%{transform:translate(-100%)}}@keyframes astroSlideToRight{to{transform:translate(100%)}}@keyframes astroSlideToLeft{to{transform:translate(-100%)}}@media (prefers-reduced-motion){::view-transition-group(*),::view-transition-old(*),::view-transition-new(*){animation:none!important}[data-astro-transition-scope]{animation:none!important}} | ||||||
							
								
								
									
										1
									
								
								test/data/warden/dist/client/_astro/_slug_.yOjdTrIk.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								test/data/warden/dist/client/_astro/_slug_.yOjdTrIk.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										24
									
								
								test/data/warden/dist/client/_astro/client.olTvLX7Y.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								test/data/warden/dist/client/_astro/client.olTvLX7Y.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										1
									
								
								test/data/warden/dist/client/_astro/hoisted.l-JsOPk0.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								test/data/warden/dist/client/_astro/hoisted.l-JsOPk0.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-100.6qNbweSL.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-100.6qNbweSL.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-100italic.E22nrI7z.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-100italic.E22nrI7z.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-200.GFXE_YJc.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-200.GFXE_YJc.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-200italic.pJK4yaaG.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-200italic.pJK4yaaG.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-300.RVbRgkxX.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-300.RVbRgkxX.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-300italic.ZdSVgmcR.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-300italic.ZdSVgmcR.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-500.xAA_w-Ac.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-500.xAA_w-Ac.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-500italic.Unq84pJ7.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-500italic.Unq84pJ7.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-600.cuuqzllG.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-600.cuuqzllG.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-600italic.vDhUog1q.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-600italic.vDhUog1q.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-700.yX9JjmCp.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-700.yX9JjmCp.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-700italic.QM1RA0vx.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-700italic.QM1RA0vx.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-italic.MiJiQVsi.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-italic.MiJiQVsi.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-regular.HRmMD3sQ.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-regular.HRmMD3sQ.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										9
									
								
								test/data/warden/dist/client/_astro/index.LFf77hJu.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								test/data/warden/dist/client/_astro/index.LFf77hJu.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/noto-serif-sc-v22-chinese-simplified-200.g4OBZhIi.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/noto-serif-sc-v22-chinese-simplified-200.g4OBZhIi.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/noto-serif-sc-v22-chinese-simplified-300.yFtdUYoh.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/noto-serif-sc-v22-chinese-simplified-300.yFtdUYoh.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/noto-serif-sc-v22-chinese-simplified-500.exkAspFQ.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/noto-serif-sc-v22-chinese-simplified-500.exkAspFQ.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/noto-serif-sc-v22-chinese-simplified-600.4n6uFOXj.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/noto-serif-sc-v22-chinese-simplified-600.4n6uFOXj.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/noto-serif-sc-v22-chinese-simplified-700.HyiB9Pzv.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/noto-serif-sc-v22-chinese-simplified-700.HyiB9Pzv.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/noto-serif-sc-v22-chinese-simplified-900.ERSRy_0V.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/noto-serif-sc-v22-chinese-simplified-900.ERSRy_0V.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/noto-serif-sc-v22-chinese-simplified-regular.9muiKgFz.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/noto-serif-sc-v22-chinese-simplified-regular.9muiKgFz.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										2
									
								
								test/data/warden/dist/client/admin/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								test/data/warden/dist/client/admin/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | index.html | ||||||
|  | assets/ | ||||||
							
								
								
									
										21
									
								
								test/data/warden/dist/client/favicon.svg
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								test/data/warden/dist/client/favicon.svg
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | <svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1024" height="1024"> | ||||||
|  | 	<title>SmartSheep Logo</title> | ||||||
|  | 	<defs> | ||||||
|  | 		<image  width="124" height="198" id="img1" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHwAAADGCAMAAAAnkRSfAAAAAXNSR0IB2cksfwAAAq9QTFRFAAAA////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////J9QBRAAAAOV0Uk5TAA0WEiFfjMLMr40/BRdmtuz//vbQYAQmpfLdQAGovyURj/iOD0r07loDGJfbPDTf/bhd94QLdPrrVQLWcPmtHU31egknzehRg9Ev1xnzbgYHhfzmTMorSOSbFJloKsniReXDKG/7kQ6m8WMw3ue7I4cKNdTZOFTqsR5/Hzra0zZY7al4Ir5SPWHvnpbG4MRrlKJs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"/> | ||||||
|  | 		<image  width="122" height="142" id="img2" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHoAAACOCAMAAADJhOzZAAAAAXNSR0IB2cksfwAAAppQTFRFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1tr9yQAAAN50Uk5TAAkMHUtzmZp0UaTn/6ZSIOrrnRqo/P2qC/qf9PZTG7O4UPL1VASO/psHwdHc7BXo+CIF+y0BOuNI1lfGarGEl6V7vJxi10oGMRQcKrcK7k7zAtt9u6uR02Eh6TZB7+08zbU/4kBjET4vMxBvON+yMAOtJQhr+fcPiSvhWTXVHoPD0q6BwHB+ualmTJ4oH/BJRN11vxdnIzQZ5ZCjiMTUis7eVn+TGEPI5mh85Cd6bNqVXiRa2YLgR1wTW4sWN24OmL1yMk9gDSmhlstk8cKNZbCicXaFhml5vl/JXaynVit8GwAABu9JREFUeJztm/tDk1UYx88GCbLDZcDmGIoKjImATubENAhNJW9cLDU10kQhVGhqYGYMxUzNrLRMtMRLoRheyGtWhlqZl+x+Mav/pSkou3y3Pefddvyl7+/f97Nz3rPnPOd5zstYCKRSq9WqUDxIVBGRj/TrFxUdGSEbrOofo+F3pYmNkzvy+KgEfl/axHiJ5KRkHe+TfkCSNLIhKoW7Smc0yELHpXJ3DRwkiZw2mHtqSJoc9NB0L3RGphSyKcvshebDTDLQ2cO9yTxHLQWdC9B5I6SgRwK0ZZQMdL4WoK2jZaBtCQBtHiMDzQoQeqwU9KMAzcdJQY9H6MfEn6Mg1ShE6CJRcERktHiq8ThCG8XAqv6xvalGsUiqMQGhJwqR45/o+4dqh9FTjUkIPVmEnDRA72LVJ5NTjSkInVBCJxuMVjdvShQ11XgS7FzcMpWOHpThYU6NIzqnWQBaN51MTpvh5R5MTDVmlgK0uYyMzvTMrzgvH0qzVsxCL/spKtk0DPzwLGKq8TRCz6ai1TnAPTybZp6D0HOp6BFo080lop9BS7yUGpTmoVU6n4heoAfmFGowHm0F7tJ8mjkpBZjNzxLRC3TAXWmjmbOfA2Y+gYheiF5XHtFsW4TQzxPdixFaSzSzRISuIs7ZEoROoKKXwiheTTPXoEVKHvULyK2vpZkXBoVeNhDN+HKaeQVCl1LRFXUIXU8zv4jQ6XYqeyVCF9C8q1BIyVhNRb+E0CnLSN4khG4grlHGatES5zUkb3UjsFqnUdFrkJ2/TPKqyoFVv5aKtuUidA7Ja0dhWE8/LsYidCopsbS9AqzmKWT0OvSy9a+SvE3oZ9OPiw608/Fmknc9stKPi3aUlfINpB2kBVk3ktHsNeS3rKFY4XExkY7ehPycVFt4HTk309HTUSTmWyjWrchJTmidSVIlekAp5dD3BnJqBI6L8GWbFxCccOtqFDguwh2EbyM401BCq3uTjt6ONiCeR5i3mW+h+XqbjmZVcMbfCWys2IGcOwXQ/eCMv0twotIyTxZA18JY2vheYGcUMjYJoO2oQkwqoO1CvvSZAmwjRFcFTvBWIJ/ufQH0bhjQrIHT8dYGZBRpn5j2wGHvDWgsQWVt/oEAmn0I0fsqAhphgbdOBN0Ko0pba0DjfuQj5tK9OoAecTAweiycrkMi6DiUoTUFRreiKM73iaCzUTGoPjDahHoY3EI+/NzVR97DNn9M8G2BMy7USWjXePkPUpKkTIjWEMtI92SL9hp2DMU/AtXOuDlSAM2m1nvYZx0m/eTJcNg7RIbNHEfczB1HaUXDTyCaLxVBs4j1LqG8cxexjOSAYZxXijWfjh1v6zm2WusKy6gzVjEXDztGCM1KVp0oPHDyZGFXmYFcEWGfwuIA15HP2fdlOOWUkAPn8c6VJhTJlQmevDi91BqEHLD25gxJQuFUmYoxuuF0+NHz8P+Lrww/GteXnZm8hGtkUz2bfD06I+MG29mHh1597mFNOGPn0dkpSmj7UqoKEFf2fCaDzFi+90l5xgU5aFbrWautXCeJzNjn7uzyL76UhmYXO93IEjauPi2endGT55hTq77qlkl2RrUpl5o687QbLl85Ju1mZp8MXzslH/u/Qi1Vd3e3SHkoZHL0P1scU3zlm+2ywepvL/dcgNFsO3RVKvni+L76QZ5RyoXPXn3nVlC0XiN3D4OWw6P6bOmScr3XqVFeZ5tK+h2poGTr8E5BrkuZ8qtt3mTesUQC2XYDkLn1poScbyIic/0cgZ6SQiVDMjeHH+2DzPnecKNhc+PehG+ilzyUyBaL6yROfU+7SaFUqlu+wJxfDmt+b8KFwHvShfVQU4u6hve1KIxfh5QUwb5br8oVvWnaDfb2Gz4XmFN66s1gV0WU7RwwZMi147V+w2B+M+wrPNAP4mBV5paexpTZsmOjz5al6cc8v2D+kzg5/pLrzR1r2wlEb98I22YuGk6sGbso6WfPlaM7t3eMS4pnW33sl0X+p9qpHHGyYQ6srDUWTOz69ejNm8v3158ph71Nd9WJk1lkoIkkqYPQ1fZUGu7NC0qrYMysBt3QElWlwO2LBzIthV0hMSUoGTPL/81feKJJo6xUkP87YfX6Vy75rqQHuihY9C1Fs+2UfVLAWOFX5kTiRXugi7nBkFNErth46oKvxgxF84MrL9fgaxgUbW4PisxYlsK3nfpHkGDGqrcpWeTmkOSeaqP4uEeOC00CaDoNvyfyrdT9oavYtP9ZQJ/1gddDW9K2H77t/RUWkFlbpDBw+lP3X0dwT6xPDXf+DlehRh3ZMt9Xjq9PvxPtCBO3R/ZTW1vqMnRue6m+sfN280IpBXx79drzW892xcxu+edfY1b0oN2tApvEf5wd39VVwSN7AAAAAElFTkSuQmCC"/> | ||||||
|  | 	</defs> | ||||||
|  | 	<style> | ||||||
|  | 		.s0 { fill: #ffffff;stroke: #000000;stroke-miterlimit:100;stroke-width: 56 }  | ||||||
|  | 		.s1 { fill: #4750a3;stroke: #000000;stroke-miterlimit:100;stroke-width: 56 }  | ||||||
|  | 	</style> | ||||||
|  | 	<path id="Wool" fill-rule="evenodd" class="s0" d="m128 608.4c0 95.9 77.4 173.6 172.8 173.6h441.6c84.8 0 153.6-69.1 153.6-154.3 0-74.6-52.8-136.9-122.9-151.1 4.9-12.9 7.7-27 7.7-41.7 0-63.9-51.6-115.8-115.2-115.8-23.6 0-45.7 7.3-64 19.6-33.2-57.9-95.2-96.7-166.4-96.7-106.1 0-192 86.3-192 192.9 0 3.2 0.1 6.5 0.2 9.7-67.2 23.8-115.4 88.1-115.4 163.8z"/> | ||||||
|  | 	<g id="Crystal"> | ||||||
|  | 		<path id="Crystal" class="s1" d="m699 224l138.6 80v160l-138.6 80-138.6-80v-160z"/> | ||||||
|  | 		<use id="Highlight" href="#img1" x="688" y="255"/> | ||||||
|  | 	</g> | ||||||
|  | 	<g id="Horn"> | ||||||
|  | 	</g> | ||||||
|  | 	<g id="Face"> | ||||||
|  | 		<use id="Slime" href="#img2" x="233" y="538"/> | ||||||
|  | 	</g> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 8.1 KiB | 
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/media/nicolas-saintot-xkFhOdId7mA-unsplash.jpg
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/media/nicolas-saintot-xkFhOdId7mA-unsplash.jpg
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 1.3 MiB | 
							
								
								
									
										1
									
								
								test/data/warden/dist/client/sitemap-0.xml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								test/data/warden/dist/client/sitemap-0.xml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1"><url><loc>https://smartsheep.studio/</loc></url><url><loc>https://smartsheep.studio/events/</loc></url><url><loc>https://smartsheep.studio/posts/</loc></url></urlset> | ||||||
							
								
								
									
										1
									
								
								test/data/warden/dist/client/sitemap-index.xml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								test/data/warden/dist/client/sitemap-index.xml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8"?><sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"><sitemap><loc>https://smartsheep.studio/sitemap-0.xml</loc></sitemap></sitemapindex> | ||||||
							
								
								
									
										3
									
								
								test/data/warden/dist/server/_empty-middleware.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								test/data/warden/dist/server/_empty-middleware.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | const onRequest = undefined; | ||||||
|  |  | ||||||
|  | export { onRequest }; | ||||||
							
								
								
									
										6
									
								
								test/data/warden/dist/server/chunks/_slug__3BAY271A.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								test/data/warden/dist/server/chunks/_slug__3BAY271A.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | export { renderers } from '../renderers.mjs'; | ||||||
|  | export { onRequest } from '../_empty-middleware.mjs'; | ||||||
|  |  | ||||||
|  | const page = () => import('./pages/_slug__TUDhKBhQ.mjs').then(n => n.c); | ||||||
|  |  | ||||||
|  | export { page }; | ||||||
							
								
								
									
										6
									
								
								test/data/warden/dist/server/chunks/_slug__EgGcJ0nJ.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								test/data/warden/dist/server/chunks/_slug__EgGcJ0nJ.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | export { renderers } from '../renderers.mjs'; | ||||||
|  | export { onRequest } from '../_empty-middleware.mjs'; | ||||||
|  |  | ||||||
|  | const page = () => import('./pages/_slug__TUDhKBhQ.mjs').then(n => n._); | ||||||
|  |  | ||||||
|  | export { page }; | ||||||
							
								
								
									
										6
									
								
								test/data/warden/dist/server/chunks/_slug__wxGnmrgA.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								test/data/warden/dist/server/chunks/_slug__wxGnmrgA.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | export { renderers } from '../renderers.mjs'; | ||||||
|  | export { onRequest } from '../_empty-middleware.mjs'; | ||||||
|  |  | ||||||
|  | const page = () => import('./pages/_slug__TUDhKBhQ.mjs').then(n => n.d); | ||||||
|  |  | ||||||
|  | export { page }; | ||||||
							
								
								
									
										342
									
								
								test/data/warden/dist/server/chunks/astro/assets-service_4dMyVCFm.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										342
									
								
								test/data/warden/dist/server/chunks/astro/assets-service_4dMyVCFm.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,342 @@ | |||||||
|  | import { isRemotePath, joinPaths } from '@astrojs/internal-helpers/path'; | ||||||
|  | import { A as AstroError, E as ExpectedImage, L as LocalImageUsedWrongly, M as MissingImageDimension, U as UnsupportedImageFormat, I as IncompatibleDescriptorOptions, a as UnsupportedImageConversion, b as MissingSharp } from '../astro_5WdVqH1c.mjs'; | ||||||
|  |  | ||||||
|  | const VALID_SUPPORTED_FORMATS = [ | ||||||
|  |   "jpeg", | ||||||
|  |   "jpg", | ||||||
|  |   "png", | ||||||
|  |   "tiff", | ||||||
|  |   "webp", | ||||||
|  |   "gif", | ||||||
|  |   "svg", | ||||||
|  |   "avif" | ||||||
|  | ]; | ||||||
|  | const DEFAULT_OUTPUT_FORMAT = "webp"; | ||||||
|  | const DEFAULT_HASH_PROPS = ["src", "width", "height", "format", "quality"]; | ||||||
|  |  | ||||||
|  | function isESMImportedImage(src) { | ||||||
|  |   return typeof src === "object"; | ||||||
|  | } | ||||||
|  | function isRemoteImage(src) { | ||||||
|  |   return typeof src === "string"; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function matchPattern(url, remotePattern) { | ||||||
|  |   return matchProtocol(url, remotePattern.protocol) && matchHostname(url, remotePattern.hostname, true) && matchPort(url, remotePattern.port) && matchPathname(url, remotePattern.pathname, true); | ||||||
|  | } | ||||||
|  | function matchPort(url, port) { | ||||||
|  |   return !port || port === url.port; | ||||||
|  | } | ||||||
|  | function matchProtocol(url, protocol) { | ||||||
|  |   return !protocol || protocol === url.protocol.slice(0, -1); | ||||||
|  | } | ||||||
|  | function matchHostname(url, hostname, allowWildcard) { | ||||||
|  |   if (!hostname) { | ||||||
|  |     return true; | ||||||
|  |   } else if (!allowWildcard || !hostname.startsWith("*")) { | ||||||
|  |     return hostname === url.hostname; | ||||||
|  |   } else if (hostname.startsWith("**.")) { | ||||||
|  |     const slicedHostname = hostname.slice(2); | ||||||
|  |     return slicedHostname !== url.hostname && url.hostname.endsWith(slicedHostname); | ||||||
|  |   } else if (hostname.startsWith("*.")) { | ||||||
|  |     const slicedHostname = hostname.slice(1); | ||||||
|  |     const additionalSubdomains = url.hostname.replace(slicedHostname, "").split(".").filter(Boolean); | ||||||
|  |     return additionalSubdomains.length === 1; | ||||||
|  |   } | ||||||
|  |   return false; | ||||||
|  | } | ||||||
|  | function matchPathname(url, pathname, allowWildcard) { | ||||||
|  |   if (!pathname) { | ||||||
|  |     return true; | ||||||
|  |   } else if (!allowWildcard || !pathname.endsWith("*")) { | ||||||
|  |     return pathname === url.pathname; | ||||||
|  |   } else if (pathname.endsWith("/**")) { | ||||||
|  |     const slicedPathname = pathname.slice(0, -2); | ||||||
|  |     return slicedPathname !== url.pathname && url.pathname.startsWith(slicedPathname); | ||||||
|  |   } else if (pathname.endsWith("/*")) { | ||||||
|  |     const slicedPathname = pathname.slice(0, -1); | ||||||
|  |     const additionalPathChunks = url.pathname.replace(slicedPathname, "").split("/").filter(Boolean); | ||||||
|  |     return additionalPathChunks.length === 1; | ||||||
|  |   } | ||||||
|  |   return false; | ||||||
|  | } | ||||||
|  | function isRemoteAllowed(src, { | ||||||
|  |   domains = [], | ||||||
|  |   remotePatterns = [] | ||||||
|  | }) { | ||||||
|  |   if (!isRemotePath(src)) | ||||||
|  |     return false; | ||||||
|  |   const url = new URL(src); | ||||||
|  |   return domains.some((domain) => matchHostname(url, domain)) || remotePatterns.some((remotePattern) => matchPattern(url, remotePattern)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function isLocalService(service) { | ||||||
|  |   if (!service) { | ||||||
|  |     return false; | ||||||
|  |   } | ||||||
|  |   return "transform" in service; | ||||||
|  | } | ||||||
|  | function parseQuality(quality) { | ||||||
|  |   let result = parseInt(quality); | ||||||
|  |   if (Number.isNaN(result)) { | ||||||
|  |     return quality; | ||||||
|  |   } | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  | const baseService = { | ||||||
|  |   propertiesToHash: DEFAULT_HASH_PROPS, | ||||||
|  |   validateOptions(options) { | ||||||
|  |     if (!options.src || typeof options.src !== "string" && typeof options.src !== "object") { | ||||||
|  |       throw new AstroError({ | ||||||
|  |         ...ExpectedImage, | ||||||
|  |         message: ExpectedImage.message( | ||||||
|  |           JSON.stringify(options.src), | ||||||
|  |           typeof options.src, | ||||||
|  |           JSON.stringify(options, (_, v) => v === void 0 ? null : v) | ||||||
|  |         ) | ||||||
|  |       }); | ||||||
|  |     } | ||||||
|  |     if (!isESMImportedImage(options.src)) { | ||||||
|  |       if (options.src.startsWith("/@fs/") || !isRemotePath(options.src) && !options.src.startsWith("/")) { | ||||||
|  |         throw new AstroError({ | ||||||
|  |           ...LocalImageUsedWrongly, | ||||||
|  |           message: LocalImageUsedWrongly.message(options.src) | ||||||
|  |         }); | ||||||
|  |       } | ||||||
|  |       let missingDimension; | ||||||
|  |       if (!options.width && !options.height) { | ||||||
|  |         missingDimension = "both"; | ||||||
|  |       } else if (!options.width && options.height) { | ||||||
|  |         missingDimension = "width"; | ||||||
|  |       } else if (options.width && !options.height) { | ||||||
|  |         missingDimension = "height"; | ||||||
|  |       } | ||||||
|  |       if (missingDimension) { | ||||||
|  |         throw new AstroError({ | ||||||
|  |           ...MissingImageDimension, | ||||||
|  |           message: MissingImageDimension.message(missingDimension, options.src) | ||||||
|  |         }); | ||||||
|  |       } | ||||||
|  |     } else { | ||||||
|  |       if (!VALID_SUPPORTED_FORMATS.includes(options.src.format)) { | ||||||
|  |         throw new AstroError({ | ||||||
|  |           ...UnsupportedImageFormat, | ||||||
|  |           message: UnsupportedImageFormat.message( | ||||||
|  |             options.src.format, | ||||||
|  |             options.src.src, | ||||||
|  |             VALID_SUPPORTED_FORMATS | ||||||
|  |           ) | ||||||
|  |         }); | ||||||
|  |       } | ||||||
|  |       if (options.widths && options.densities) { | ||||||
|  |         throw new AstroError(IncompatibleDescriptorOptions); | ||||||
|  |       } | ||||||
|  |       if (options.src.format === "svg") { | ||||||
|  |         options.format = "svg"; | ||||||
|  |       } | ||||||
|  |       if (options.src.format === "svg" && options.format !== "svg" || options.src.format !== "svg" && options.format === "svg") { | ||||||
|  |         throw new AstroError(UnsupportedImageConversion); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     if (!options.format) { | ||||||
|  |       options.format = DEFAULT_OUTPUT_FORMAT; | ||||||
|  |     } | ||||||
|  |     if (options.width) | ||||||
|  |       options.width = Math.round(options.width); | ||||||
|  |     if (options.height) | ||||||
|  |       options.height = Math.round(options.height); | ||||||
|  |     return options; | ||||||
|  |   }, | ||||||
|  |   getHTMLAttributes(options) { | ||||||
|  |     const { targetWidth, targetHeight } = getTargetDimensions(options); | ||||||
|  |     const { src, width, height, format, quality, densities, widths, formats, ...attributes } = options; | ||||||
|  |     return { | ||||||
|  |       ...attributes, | ||||||
|  |       width: targetWidth, | ||||||
|  |       height: targetHeight, | ||||||
|  |       loading: attributes.loading ?? "lazy", | ||||||
|  |       decoding: attributes.decoding ?? "async" | ||||||
|  |     }; | ||||||
|  |   }, | ||||||
|  |   getSrcSet(options) { | ||||||
|  |     const srcSet = []; | ||||||
|  |     const { targetWidth } = getTargetDimensions(options); | ||||||
|  |     const { widths, densities } = options; | ||||||
|  |     const targetFormat = options.format ?? DEFAULT_OUTPUT_FORMAT; | ||||||
|  |     let imageWidth = options.width; | ||||||
|  |     let maxWidth = Infinity; | ||||||
|  |     if (isESMImportedImage(options.src)) { | ||||||
|  |       imageWidth = options.src.width; | ||||||
|  |       maxWidth = imageWidth; | ||||||
|  |     } | ||||||
|  |     const { | ||||||
|  |       width: transformWidth, | ||||||
|  |       height: transformHeight, | ||||||
|  |       ...transformWithoutDimensions | ||||||
|  |     } = options; | ||||||
|  |     const allWidths = []; | ||||||
|  |     if (densities) { | ||||||
|  |       const densityValues = densities.map((density) => { | ||||||
|  |         if (typeof density === "number") { | ||||||
|  |           return density; | ||||||
|  |         } else { | ||||||
|  |           return parseFloat(density); | ||||||
|  |         } | ||||||
|  |       }); | ||||||
|  |       const densityWidths = densityValues.sort().map((density) => Math.round(targetWidth * density)); | ||||||
|  |       allWidths.push( | ||||||
|  |         ...densityWidths.map((width, index) => ({ | ||||||
|  |           maxTargetWidth: Math.min(width, maxWidth), | ||||||
|  |           descriptor: `${densityValues[index]}x` | ||||||
|  |         })) | ||||||
|  |       ); | ||||||
|  |     } else if (widths) { | ||||||
|  |       allWidths.push( | ||||||
|  |         ...widths.map((width) => ({ | ||||||
|  |           maxTargetWidth: Math.min(width, maxWidth), | ||||||
|  |           descriptor: `${width}w` | ||||||
|  |         })) | ||||||
|  |       ); | ||||||
|  |     } | ||||||
|  |     for (const { maxTargetWidth, descriptor } of allWidths) { | ||||||
|  |       const srcSetTransform = { ...transformWithoutDimensions }; | ||||||
|  |       if (maxTargetWidth !== imageWidth) { | ||||||
|  |         srcSetTransform.width = maxTargetWidth; | ||||||
|  |       } else { | ||||||
|  |         if (options.width && options.height) { | ||||||
|  |           srcSetTransform.width = options.width; | ||||||
|  |           srcSetTransform.height = options.height; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       srcSet.push({ | ||||||
|  |         transform: srcSetTransform, | ||||||
|  |         descriptor, | ||||||
|  |         attributes: { | ||||||
|  |           type: `image/${targetFormat}` | ||||||
|  |         } | ||||||
|  |       }); | ||||||
|  |     } | ||||||
|  |     return srcSet; | ||||||
|  |   }, | ||||||
|  |   getURL(options, imageConfig) { | ||||||
|  |     const searchParams = new URLSearchParams(); | ||||||
|  |     if (isESMImportedImage(options.src)) { | ||||||
|  |       searchParams.append("href", options.src.src); | ||||||
|  |     } else if (isRemoteAllowed(options.src, imageConfig)) { | ||||||
|  |       searchParams.append("href", options.src); | ||||||
|  |     } else { | ||||||
|  |       return options.src; | ||||||
|  |     } | ||||||
|  |     const params = { | ||||||
|  |       w: "width", | ||||||
|  |       h: "height", | ||||||
|  |       q: "quality", | ||||||
|  |       f: "format" | ||||||
|  |     }; | ||||||
|  |     Object.entries(params).forEach(([param, key]) => { | ||||||
|  |       options[key] && searchParams.append(param, options[key].toString()); | ||||||
|  |     }); | ||||||
|  |     const imageEndpoint = joinPaths("/", "/_image"); | ||||||
|  |     return `${imageEndpoint}?${searchParams}`; | ||||||
|  |   }, | ||||||
|  |   parseURL(url) { | ||||||
|  |     const params = url.searchParams; | ||||||
|  |     if (!params.has("href")) { | ||||||
|  |       return void 0; | ||||||
|  |     } | ||||||
|  |     const transform = { | ||||||
|  |       src: params.get("href"), | ||||||
|  |       width: params.has("w") ? parseInt(params.get("w")) : void 0, | ||||||
|  |       height: params.has("h") ? parseInt(params.get("h")) : void 0, | ||||||
|  |       format: params.get("f"), | ||||||
|  |       quality: params.get("q") | ||||||
|  |     }; | ||||||
|  |     return transform; | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  | function getTargetDimensions(options) { | ||||||
|  |   let targetWidth = options.width; | ||||||
|  |   let targetHeight = options.height; | ||||||
|  |   if (isESMImportedImage(options.src)) { | ||||||
|  |     const aspectRatio = options.src.width / options.src.height; | ||||||
|  |     if (targetHeight && !targetWidth) { | ||||||
|  |       targetWidth = Math.round(targetHeight * aspectRatio); | ||||||
|  |     } else if (targetWidth && !targetHeight) { | ||||||
|  |       targetHeight = Math.round(targetWidth / aspectRatio); | ||||||
|  |     } else if (!targetWidth && !targetHeight) { | ||||||
|  |       targetWidth = options.src.width; | ||||||
|  |       targetHeight = options.src.height; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return { | ||||||
|  |     targetWidth, | ||||||
|  |     targetHeight | ||||||
|  |   }; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | let sharp; | ||||||
|  | const qualityTable = { | ||||||
|  |   low: 25, | ||||||
|  |   mid: 50, | ||||||
|  |   high: 80, | ||||||
|  |   max: 100 | ||||||
|  | }; | ||||||
|  | async function loadSharp() { | ||||||
|  |   let sharpImport; | ||||||
|  |   try { | ||||||
|  |     sharpImport = (await import('sharp')).default; | ||||||
|  |   } catch (e) { | ||||||
|  |     throw new AstroError(MissingSharp); | ||||||
|  |   } | ||||||
|  |   return sharpImport; | ||||||
|  | } | ||||||
|  | const sharpService = { | ||||||
|  |   validateOptions: baseService.validateOptions, | ||||||
|  |   getURL: baseService.getURL, | ||||||
|  |   parseURL: baseService.parseURL, | ||||||
|  |   getHTMLAttributes: baseService.getHTMLAttributes, | ||||||
|  |   getSrcSet: baseService.getSrcSet, | ||||||
|  |   async transform(inputBuffer, transformOptions, config) { | ||||||
|  |     if (!sharp) | ||||||
|  |       sharp = await loadSharp(); | ||||||
|  |     const transform = transformOptions; | ||||||
|  |     if (transform.format === "svg") | ||||||
|  |       return { data: inputBuffer, format: "svg" }; | ||||||
|  |     const result = sharp(inputBuffer, { | ||||||
|  |       failOnError: false, | ||||||
|  |       pages: -1, | ||||||
|  |       limitInputPixels: config.service.config.limitInputPixels | ||||||
|  |     }); | ||||||
|  |     result.rotate(); | ||||||
|  |     if (transform.height && !transform.width) { | ||||||
|  |       result.resize({ height: Math.round(transform.height) }); | ||||||
|  |     } else if (transform.width) { | ||||||
|  |       result.resize({ width: Math.round(transform.width) }); | ||||||
|  |     } | ||||||
|  |     if (transform.format) { | ||||||
|  |       let quality = void 0; | ||||||
|  |       if (transform.quality) { | ||||||
|  |         const parsedQuality = parseQuality(transform.quality); | ||||||
|  |         if (typeof parsedQuality === "number") { | ||||||
|  |           quality = parsedQuality; | ||||||
|  |         } else { | ||||||
|  |           quality = transform.quality in qualityTable ? qualityTable[transform.quality] : void 0; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       result.toFormat(transform.format, { quality }); | ||||||
|  |     } | ||||||
|  |     const { data, info } = await result.toBuffer({ resolveWithObject: true }); | ||||||
|  |     return { | ||||||
|  |       data, | ||||||
|  |       format: info.format | ||||||
|  |     }; | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  | var sharp_default = sharpService; | ||||||
|  |  | ||||||
|  | const sharp$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ | ||||||
|  |   __proto__: null, | ||||||
|  |   default: sharp_default | ||||||
|  | }, Symbol.toStringTag, { value: 'Module' })); | ||||||
|  |  | ||||||
|  | export { DEFAULT_HASH_PROPS as D, isLocalService as a, isRemoteImage as b, isRemoteAllowed as c, isESMImportedImage as i, sharp$1 as s }; | ||||||
							
								
								
									
										2196
									
								
								test/data/warden/dist/server/chunks/astro_5WdVqH1c.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2196
									
								
								test/data/warden/dist/server/chunks/astro_5WdVqH1c.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										6
									
								
								test/data/warden/dist/server/chunks/index_5_WFUSxR.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								test/data/warden/dist/server/chunks/index_5_WFUSxR.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | export { renderers } from '../renderers.mjs'; | ||||||
|  | export { onRequest } from '../_empty-middleware.mjs'; | ||||||
|  |  | ||||||
|  | const page = () => import('./pages/index_l5vwnKzb.mjs').then(n => n.b); | ||||||
|  |  | ||||||
|  | export { page }; | ||||||
							
								
								
									
										6
									
								
								test/data/warden/dist/server/chunks/index_6C3b8yBv.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								test/data/warden/dist/server/chunks/index_6C3b8yBv.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | export { renderers } from '../renderers.mjs'; | ||||||
|  | export { onRequest } from '../_empty-middleware.mjs'; | ||||||
|  |  | ||||||
|  | const page = () => import('./pages/index_l5vwnKzb.mjs').then(n => n.i); | ||||||
|  |  | ||||||
|  | export { page }; | ||||||
							
								
								
									
										6
									
								
								test/data/warden/dist/server/chunks/index_Ij1Dwoh1.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								test/data/warden/dist/server/chunks/index_Ij1Dwoh1.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | export { renderers } from '../renderers.mjs'; | ||||||
|  | export { onRequest } from '../_empty-middleware.mjs'; | ||||||
|  |  | ||||||
|  | const page = () => import('./pages/index_l5vwnKzb.mjs').then(n => n.a); | ||||||
|  |  | ||||||
|  | export { page }; | ||||||
							
								
								
									
										6
									
								
								test/data/warden/dist/server/chunks/node_0Fr8CwHA.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								test/data/warden/dist/server/chunks/node_0Fr8CwHA.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | export { renderers } from '../renderers.mjs'; | ||||||
|  | export { onRequest } from '../_empty-middleware.mjs'; | ||||||
|  |  | ||||||
|  | const page = () => import('./pages/node_hIg2I-Kh.mjs'); | ||||||
|  |  | ||||||
|  | export { page }; | ||||||
							
								
								
									
										245
									
								
								test/data/warden/dist/server/chunks/pages/_slug__TUDhKBhQ.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										245
									
								
								test/data/warden/dist/server/chunks/pages/_slug__TUDhKBhQ.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,245 @@ | |||||||
|  | /* empty css                           */ | ||||||
|  | import 'html-escaper'; | ||||||
|  | import { c as createAstro, d as createComponent, r as renderTemplate, m as maybeRenderHead, e as addAttribute, f as renderSlot, g as renderTransition, h as renderComponent, i as renderHead } from '../astro_5WdVqH1c.mjs'; | ||||||
|  | import 'kleur/colors'; | ||||||
|  | import 'clsx'; | ||||||
|  | import { DocumentRenderer } from '@keystone-6/document-renderer'; | ||||||
|  | /* empty css                           */ | ||||||
|  | /* empty css                           */ | ||||||
|  |  | ||||||
|  | const $$Astro$7 = createAstro("https://smartsheep.studio"); | ||||||
|  | const $$Navbar = createComponent(async ($$result, $$props, $$slots) => { | ||||||
|  |   const Astro2 = $$result.createAstro($$Astro$7, $$props, $$slots); | ||||||
|  |   Astro2.self = $$Navbar; | ||||||
|  |   const items = [ | ||||||
|  |     { | ||||||
|  |       label: "\u60C5\u62A5", | ||||||
|  |       children: [ | ||||||
|  |         { href: "/posts", label: "\u8BB0\u5F55" }, | ||||||
|  |         { href: "/events", label: "\u6D3B\u52A8" } | ||||||
|  |       ] | ||||||
|  |     } | ||||||
|  |   ]; | ||||||
|  |   return renderTemplate`${maybeRenderHead()}<div class="fixed top-0 navbar shadow-md bg-base-100 lg:px-5 z-10"> <div class="navbar-start"> <div class="dropdown"> <div tabindex="0" role="button" class="btn btn-ghost lg:hidden"> <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h8m-8 6h16"></path> </svg> </div> <ul tabindex="0" class="menu menu-sm dropdown-content mt-3 z-[1] p-2 shadow bg-base-100 rounded-box w-52"> ${items.map((item) => renderTemplate`<li> <a${addAttribute(item.href, "href")}>${item.label}</a> ${item.children && renderTemplate`<ul class="p-2"> ${item.children?.map((child) => renderTemplate`<li> <a${addAttribute(child.href, "href")}>${child.label}</a> </li>`)} </ul>`} </li>`)} </ul> </div> <a class="btn btn-ghost text-xl" href="/">山羊寒舍</a> </div> <div class="navbar-center hidden lg:flex"> <ul class="menu menu-horizontal px-1"> ${items.map((item) => renderTemplate`<li> ${item.children ? renderTemplate`<details> <summary>${item.label}</summary> <ul class="p-2"> ${item.children?.map((child) => renderTemplate`<li> <a${addAttribute(child.href, "href")}>${child.label}</a> </li>`)} </ul> </details>` : renderTemplate`<a${addAttribute(item.href, "href")}>${item.label}</a>`} </li>`)} </ul> </div> <div class="navbar-end"> <label class="swap swap-rotate px-[16px]"> <input type="checkbox" class="theme-controller" value="light" checked> <svg class="swap-on fill-current w-8 h-8" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M5.64,17l-.71.71a1,1,0,0,0,0,1.41,1,1,0,0,0,1.41,0l.71-.71A1,1,0,0,0,5.64,17ZM5,12a1,1,0,0,0-1-1H3a1,1,0,0,0,0,2H4A1,1,0,0,0,5,12Zm7-7a1,1,0,0,0,1-1V3a1,1,0,0,0-2,0V4A1,1,0,0,0,12,5ZM5.64,7.05a1,1,0,0,0,.7.29,1,1,0,0,0,.71-.29,1,1,0,0,0,0-1.41l-.71-.71A1,1,0,0,0,4.93,6.34Zm12,.29a1,1,0,0,0,.7-.29l.71-.71a1,1,0,1,0-1.41-1.41L17,5.64a1,1,0,0,0,0,1.41A1,1,0,0,0,17.66,7.34ZM21,11H20a1,1,0,0,0,0,2h1a1,1,0,0,0,0-2Zm-9,8a1,1,0,0,0-1,1v1a1,1,0,0,0,2,0V20A1,1,0,0,0,12,19ZM18.36,17A1,1,0,0,0,17,18.36l.71.71a1,1,0,0,0,1.41,0,1,1,0,0,0,0-1.41ZM12,6.5A5.5,5.5,0,1,0,17.5,12,5.51,5.51,0,0,0,12,6.5Zm0,9A3.5,3.5,0,1,1,15.5,12,3.5,3.5,0,0,1,12,15.5Z"></path> </svg> <svg class="swap-off fill-current w-8 h-8" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M21.64,13a1,1,0,0,0-1.05-.14,8.05,8.05,0,0,1-3.37.73A8.15,8.15,0,0,1,9.08,5.49a8.59,8.59,0,0,1,.25-2A1,1,0,0,0,8,2.36,10.14,10.14,0,1,0,22,14.05,1,1,0,0,0,21.64,13Zm-9.5,6.69A8.14,8.14,0,0,1,7.08,5.22v.27A10.15,10.15,0,0,0,17.22,15.63a9.79,9.79,0,0,0,2.1-.22A8.11,8.11,0,0,1,12.14,19.73Z"></path> </svg> </label> </div> </div>`; | ||||||
|  | }, "/Users/littlesheep/Documents/Projects/Capital/src/components/Navbar.astro", void 0); | ||||||
|  |  | ||||||
|  | const $$Astro$6 = createAstro("https://smartsheep.studio"); | ||||||
|  | const $$ViewTransitions = createComponent(async ($$result, $$props, $$slots) => { | ||||||
|  |   const Astro2 = $$result.createAstro($$Astro$6, $$props, $$slots); | ||||||
|  |   Astro2.self = $$ViewTransitions; | ||||||
|  |   const { fallback = "animate" } = Astro2.props; | ||||||
|  |   return renderTemplate`<meta name="astro-view-transitions-enabled" content="true"><meta name="astro-view-transitions-fallback"${addAttribute(fallback, "content")}>`; | ||||||
|  | }, "/Users/littlesheep/Documents/Projects/Capital/node_modules/astro/components/ViewTransitions.astro", void 0); | ||||||
|  |  | ||||||
|  | var __freeze = Object.freeze; | ||||||
|  | var __defProp = Object.defineProperty; | ||||||
|  | var __template = (cooked, raw) => __freeze(__defProp(cooked, "raw", { value: __freeze(raw || cooked.slice()) })); | ||||||
|  | var _a; | ||||||
|  | const $$Astro$5 = createAstro("https://smartsheep.studio"); | ||||||
|  | const $$RootLayout = createComponent(async ($$result, $$props, $$slots) => { | ||||||
|  |   const Astro2 = $$result.createAstro($$Astro$5, $$props, $$slots); | ||||||
|  |   Astro2.self = $$RootLayout; | ||||||
|  |   const { title } = Astro2.props; | ||||||
|  |   return renderTemplate(_a || (_a = __template(['<html lang="en" data-astro-cid-mdysn4oi> <head><meta charset="utf-8"><link rel="icon" type="image/svg+xml" href="/favicon.svg"><meta name="viewport" content="width=device-width"><meta name="generator"', ">", "", "", "", "</head> <body data-astro-cid-mdysn4oi> <!-- Header --> ", " <!-- Content --> <main data-astro-cid-mdysn4oi", "> ", ' </main> <!-- Styles -->   <script async src="https://analytics.smartsheep.studio/script.js" data-website-id="9d676a27-b473-44a3-b444-5a7d851e31e8"><\/script> </body> </html>'])), addAttribute(Astro2.generator, "content"), title && renderTemplate`<title>山羊寒舍 | ${title}</title>`, !title && renderTemplate`<title>山羊寒舍</title>`, renderComponent($$result, "ViewTransitions", $$ViewTransitions, { "data-astro-cid-mdysn4oi": true }), renderHead(), renderComponent($$result, "Navbar", $$Navbar, { "data-astro-cid-mdysn4oi": true }), addAttribute(renderTransition($$result, "53mar5bf", "slide", ""), "data-astro-transition-scope"), renderSlot($$result, $$slots["default"])); | ||||||
|  | }, "/Users/littlesheep/Documents/Projects/Capital/src/layouts/RootLayout.astro", "self"); | ||||||
|  |  | ||||||
|  | const $$Astro$4 = createAstro("https://smartsheep.studio"); | ||||||
|  | const $$PageLayout = createComponent(async ($$result, $$props, $$slots) => { | ||||||
|  |   const Astro2 = $$result.createAstro($$Astro$4, $$props, $$slots); | ||||||
|  |   Astro2.self = $$PageLayout; | ||||||
|  |   const { title } = Astro2.props; | ||||||
|  |   return renderTemplate`${renderComponent($$result, "RootLayout", $$RootLayout, { "title": title }, { "default": ($$result2) => renderTemplate` ${maybeRenderHead()}<main class="container mx-auto h-fullpage mt-header"> ${renderSlot($$result2, $$slots["default"])} </main> ` })}`; | ||||||
|  | }, "/Users/littlesheep/Documents/Projects/Capital/src/layouts/PageLayout.astro", void 0); | ||||||
|  |  | ||||||
|  | const defaultCms = "https://smartsheep.studio"; | ||||||
|  | async function graphQuery(query, variables) { | ||||||
|  |   const response = await fetch(`${process.env.PUBLIC_CMS ?? defaultCms}/api/graphql`, { | ||||||
|  |     method: "POST", | ||||||
|  |     headers: { "Content-Type": "application/json" }, | ||||||
|  |     body: JSON.stringify({ | ||||||
|  |       query, | ||||||
|  |       variables | ||||||
|  |     }) | ||||||
|  |   }); | ||||||
|  |   return await response.json(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const POST_TYPES = { | ||||||
|  |   article: "文章", | ||||||
|  |   podcast: "播客", | ||||||
|  |   announcements: "通告" | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | const $$Astro$3 = createAstro("https://smartsheep.studio"); | ||||||
|  | const $$PostList = createComponent(async ($$result, $$props, $$slots) => { | ||||||
|  |   const Astro2 = $$result.createAstro($$Astro$3, $$props, $$slots); | ||||||
|  |   Astro2.self = $$PostList; | ||||||
|  |   const { posts } = Astro2.props; | ||||||
|  |   return renderTemplate`${maybeRenderHead()}<div class="grid justify-items-strench shadow-lg"> ${posts?.map((item) => renderTemplate`<a${addAttribute(`/p/${item.slug}`, "href")}> <div class="card sm:card-side hover:bg-base-200 transition-colors sm:max-w-none"> ${item.cover.image.url && renderTemplate`<figure class="mx-auto w-full object-cover p-6 max-sm:pb-0 sm:max-w-[12rem] sm:pe-0"> <img loading="lazy"${addAttribute(item.cover.image.url, "src")} class="border-base-content bg-base-300 rounded-btn border border-opacity-5"${addAttribute(item.title, "alt")}> </figure>`} <div class="card-body"> <h2 class="text-xl">${item.title}</h2> <div class="mx-[-2px] mt-[-4px]"> <span class="badge badge-accent">${POST_TYPES[item.type]}</span> ${item.categories?.map((category) => renderTemplate`<span class="badge badge-primary">${category.name}</span>`)} ${item.tags?.map((tag) => renderTemplate`<span class="badge badge-secondary">${tag.name}</span>`)} </div> <div class="text-xs opacity-60 line-clamp-3"> ${item.description} </div> </div> </div> </a>`)} </div>`; | ||||||
|  | }, "/Users/littlesheep/Documents/Projects/Capital/src/components/PostList.astro", void 0); | ||||||
|  |  | ||||||
|  | const $$Astro$2 = createAstro("https://smartsheep.studio"); | ||||||
|  | const prerender$2 = false; | ||||||
|  | const $$slug$2 = createComponent(async ($$result, $$props, $$slots) => { | ||||||
|  |   const Astro2 = $$result.createAstro($$Astro$2, $$props, $$slots); | ||||||
|  |   Astro2.self = $$slug$2; | ||||||
|  |   const { slug } = Astro2.params; | ||||||
|  |   const { posts } = (await graphQuery( | ||||||
|  |     `query Query($where: PostWhereInput!, $orderBy: [PostOrderByInput!]!) { | ||||||
|  |   posts(where: $where, orderBy: $orderBy) { | ||||||
|  |     slug | ||||||
|  |     type | ||||||
|  |     title | ||||||
|  |     description | ||||||
|  |     cover { | ||||||
|  |       image { | ||||||
|  |         url | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     content { | ||||||
|  |       document | ||||||
|  |     } | ||||||
|  |     categories { | ||||||
|  |       name | ||||||
|  |     } | ||||||
|  |     tags { | ||||||
|  |       name | ||||||
|  |     } | ||||||
|  |     createdAt | ||||||
|  |   } | ||||||
|  | }`, | ||||||
|  |     { | ||||||
|  |       orderBy: [ | ||||||
|  |         { | ||||||
|  |           createdAt: "desc" | ||||||
|  |         } | ||||||
|  |       ], | ||||||
|  |       where: { categories: { some: { slug: { equals: slug } } } } | ||||||
|  |     } | ||||||
|  |   )).data; | ||||||
|  |   return renderTemplate`${renderComponent($$result, "PageLayout", $$PageLayout, { "title": "\u5206\u7C7B\u68C0\u7D22" }, { "default": ($$result2) => renderTemplate` ${maybeRenderHead()}<div class="max-w-[720px] mx-auto"> <div class="pt-16 pb-6 px-6"> <h1 class="text-4xl font-bold">分类检索</h1> <p class="pt-3">以下是包含该分类的记录……</p> </div> ${renderComponent($$result2, "PostList", $$PostList, { "posts": posts })} </div> ` })}`; | ||||||
|  | }, "/Users/littlesheep/Documents/Projects/Capital/src/pages/categories/[slug].astro", void 0); | ||||||
|  |  | ||||||
|  | const $$file$2 = "/Users/littlesheep/Documents/Projects/Capital/src/pages/categories/[slug].astro"; | ||||||
|  | const $$url$2 = "/categories/[slug]"; | ||||||
|  |  | ||||||
|  | const _slug_$2 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ | ||||||
|  |   __proto__: null, | ||||||
|  |   default: $$slug$2, | ||||||
|  |   file: $$file$2, | ||||||
|  |   prerender: prerender$2, | ||||||
|  |   url: $$url$2 | ||||||
|  | }, Symbol.toStringTag, { value: 'Module' })); | ||||||
|  |  | ||||||
|  | const $$Astro$1 = createAstro("https://smartsheep.studio"); | ||||||
|  | const prerender$1 = false; | ||||||
|  | const $$slug$1 = createComponent(async ($$result, $$props, $$slots) => { | ||||||
|  |   const Astro2 = $$result.createAstro($$Astro$1, $$props, $$slots); | ||||||
|  |   Astro2.self = $$slug$1; | ||||||
|  |   const { slug } = Astro2.params; | ||||||
|  |   const { post } = (await graphQuery( | ||||||
|  |     `query Query($where: PostWhereUniqueInput!) { | ||||||
|  |   post(where: $where) { | ||||||
|  |     slug | ||||||
|  |     type | ||||||
|  |     title | ||||||
|  |     description | ||||||
|  |     author { | ||||||
|  |       name | ||||||
|  |     } | ||||||
|  |     assets { | ||||||
|  |       caption | ||||||
|  |       url | ||||||
|  |       type | ||||||
|  |     } | ||||||
|  |     cover { | ||||||
|  |       image { | ||||||
|  |         url | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     content { | ||||||
|  |       document | ||||||
|  |     } | ||||||
|  |     categories { | ||||||
|  |       slug | ||||||
|  |       name | ||||||
|  |     } | ||||||
|  |     tags { | ||||||
|  |       slug | ||||||
|  |       name | ||||||
|  |     } | ||||||
|  |     createdAt | ||||||
|  |   } | ||||||
|  | }`, | ||||||
|  |     { | ||||||
|  |       where: { slug } | ||||||
|  |     } | ||||||
|  |   )).data; | ||||||
|  |   return renderTemplate`${renderComponent($$result, "PageLayout", $$PageLayout, { "title": post.title, "data-astro-cid-gysqo7gh": true }, { "default": ($$result2) => renderTemplate` ${maybeRenderHead()}<div class="wrapper" data-astro-cid-gysqo7gh> <div class="card w-full shadow-xl" data-astro-cid-gysqo7gh> ${post.cover && renderTemplate`<figure data-astro-cid-gysqo7gh> <img${addAttribute(post.cover.image.url, "src")}${addAttribute(post.title, "alt")} data-astro-cid-gysqo7gh> </figure>`} <div class="card-body" data-astro-cid-gysqo7gh> <h2 class="card-title" data-astro-cid-gysqo7gh>${post.title}</h2> <p class="description" data-astro-cid-gysqo7gh>${post.description ?? "No description"}</p> <div class="divider" data-astro-cid-gysqo7gh></div> ${post.assets?.length > 0 && renderTemplate`<div class="mb-5 w-full" data-astro-cid-gysqo7gh> ${renderComponent($$result2, "Media", null, { "client:only": true, "sources": post.assets, "author": post.author, "client:component-hydration": "only", "data-astro-cid-gysqo7gh": true, "client:component-path": "/Users/littlesheep/Documents/Projects/Capital/src/components/posts/Media", "client:component-export": "default" })} </div>`} <div class="prose max-w-none" data-astro-cid-gysqo7gh> ${renderComponent($$result2, "DocumentRenderer", DocumentRenderer, { "document": post.content.document, "data-astro-cid-gysqo7gh": true })} </div> </div> </div> <div class="h-fit sticky top-header" data-astro-cid-gysqo7gh> <div class="card shadow-xl" data-astro-cid-gysqo7gh> <div class="card-body" data-astro-cid-gysqo7gh> <div class="gap-2 text-sm metadata description" data-astro-cid-gysqo7gh> <div data-astro-cid-gysqo7gh> <div data-astro-cid-gysqo7gh>作者</div> <div data-astro-cid-gysqo7gh>${post.author?.name ?? "\u4F5A\u540D"}</div> </div> <div data-astro-cid-gysqo7gh> <div data-astro-cid-gysqo7gh>类型</div> <div class="text-accent" data-astro-cid-gysqo7gh> ${POST_TYPES[post.type]} </div> </div> <div data-astro-cid-gysqo7gh> <div data-astro-cid-gysqo7gh>分类</div> <div class="flex gap-1" data-astro-cid-gysqo7gh> ${post.categories?.map((category) => renderTemplate`<a${addAttribute(`/categories/${category.slug}`, "href")} class="link link-primary" data-astro-cid-gysqo7gh> ${category.name} </a>`)} </div> </div> <div data-astro-cid-gysqo7gh> <div data-astro-cid-gysqo7gh>标签</div> <div class="flex gap-1" data-astro-cid-gysqo7gh> ${post.tags?.map((tag) => renderTemplate`<a${addAttribute(`/tags/${tag.slug}`, "href")} class="link link-secondary" data-astro-cid-gysqo7gh> ${tag.name} </a>`)} </div> </div> <div data-astro-cid-gysqo7gh> <div data-astro-cid-gysqo7gh>发布于</div> <div data-astro-cid-gysqo7gh>${new Date(post.createdAt).toLocaleString()}</div> </div> </div> </div> </div> </div> </div> ` })} `; | ||||||
|  | }, "/Users/littlesheep/Documents/Projects/Capital/src/pages/posts/[slug].astro", void 0); | ||||||
|  |  | ||||||
|  | const $$file$1 = "/Users/littlesheep/Documents/Projects/Capital/src/pages/posts/[slug].astro"; | ||||||
|  | const $$url$1 = "/posts/[slug]"; | ||||||
|  |  | ||||||
|  | const _slug_$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ | ||||||
|  |   __proto__: null, | ||||||
|  |   default: $$slug$1, | ||||||
|  |   file: $$file$1, | ||||||
|  |   prerender: prerender$1, | ||||||
|  |   url: $$url$1 | ||||||
|  | }, Symbol.toStringTag, { value: 'Module' })); | ||||||
|  |  | ||||||
|  | const $$Astro = createAstro("https://smartsheep.studio"); | ||||||
|  | const prerender = false; | ||||||
|  | const $$slug = createComponent(async ($$result, $$props, $$slots) => { | ||||||
|  |   const Astro2 = $$result.createAstro($$Astro, $$props, $$slots); | ||||||
|  |   Astro2.self = $$slug; | ||||||
|  |   const { slug } = Astro2.params; | ||||||
|  |   const { posts } = (await graphQuery( | ||||||
|  |     `query Query($where: PostWhereInput!, $orderBy: [PostOrderByInput!]!) { | ||||||
|  |   posts(where: $where, orderBy: $orderBy) { | ||||||
|  |     slug | ||||||
|  |     type | ||||||
|  |     title | ||||||
|  |     description | ||||||
|  |     cover { | ||||||
|  |       image { | ||||||
|  |         url | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     content { | ||||||
|  |       document | ||||||
|  |     } | ||||||
|  |     categories { | ||||||
|  |       name | ||||||
|  |     } | ||||||
|  |     tags { | ||||||
|  |       name | ||||||
|  |     } | ||||||
|  |     createdAt | ||||||
|  |   } | ||||||
|  | }`, | ||||||
|  |     { | ||||||
|  |       orderBy: [ | ||||||
|  |         { | ||||||
|  |           createdAt: "desc" | ||||||
|  |         } | ||||||
|  |       ], | ||||||
|  |       where: { tags: { some: { slug: { equals: slug } } } } | ||||||
|  |     } | ||||||
|  |   )).data; | ||||||
|  |   return renderTemplate`${renderComponent($$result, "PageLayout", $$PageLayout, { "title": "\u6807\u7B7E\u68C0\u7D22" }, { "default": ($$result2) => renderTemplate` ${maybeRenderHead()}<div class="max-w-[720px] mx-auto"> <div class="pt-16 pb-6 px-6"> <h1 class="text-4xl font-bold">标签检索</h1> <p class="pt-3">以下是包含该标签的记录……</p> </div> ${renderComponent($$result2, "PostList", $$PostList, { "posts": posts })} </div> ` })}`; | ||||||
|  | }, "/Users/littlesheep/Documents/Projects/Capital/src/pages/tags/[slug].astro", void 0); | ||||||
|  |  | ||||||
|  | const $$file = "/Users/littlesheep/Documents/Projects/Capital/src/pages/tags/[slug].astro"; | ||||||
|  | const $$url = "/tags/[slug]"; | ||||||
|  |  | ||||||
|  | const _slug_ = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ | ||||||
|  |   __proto__: null, | ||||||
|  |   default: $$slug, | ||||||
|  |   file: $$file, | ||||||
|  |   prerender, | ||||||
|  |   url: $$url | ||||||
|  | }, Symbol.toStringTag, { value: 'Module' })); | ||||||
|  |  | ||||||
|  | export { $$PageLayout as $, _slug_$2 as _, $$PostList as a, $$RootLayout as b, _slug_$1 as c, _slug_ as d, graphQuery as g }; | ||||||
							
								
								
									
										153
									
								
								test/data/warden/dist/server/chunks/pages/index_l5vwnKzb.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								test/data/warden/dist/server/chunks/pages/index_l5vwnKzb.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,153 @@ | |||||||
|  | /* empty css                           */ | ||||||
|  | import { c as createAstro, d as createComponent, r as renderTemplate, h as renderComponent, m as maybeRenderHead, e as addAttribute } from '../astro_5WdVqH1c.mjs'; | ||||||
|  | import 'kleur/colors'; | ||||||
|  | import 'html-escaper'; | ||||||
|  | import { g as graphQuery, $ as $$PageLayout, a as $$PostList, b as $$RootLayout } from './_slug__TUDhKBhQ.mjs'; | ||||||
|  | import { DocumentRenderer } from '@keystone-6/document-renderer'; | ||||||
|  | import 'clsx'; | ||||||
|  | /* empty css                          */ | ||||||
|  |  | ||||||
|  | const $$Astro$2 = createAstro("https://smartsheep.studio"); | ||||||
|  | const prerender$2 = false; | ||||||
|  | const $$Index$2 = createComponent(async ($$result, $$props, $$slots) => { | ||||||
|  |   const Astro2 = $$result.createAstro($$Astro$2, $$props, $$slots); | ||||||
|  |   Astro2.self = $$Index$2; | ||||||
|  |   const { events } = (await graphQuery( | ||||||
|  |     `query Query($where: EventWhereInput!) { | ||||||
|  |   events(where: $where) { | ||||||
|  |     slug | ||||||
|  |     title | ||||||
|  |     description | ||||||
|  |     content { | ||||||
|  |       document | ||||||
|  |     } | ||||||
|  |     createdAt | ||||||
|  |   } | ||||||
|  | }`, | ||||||
|  |     { | ||||||
|  |       where: { | ||||||
|  |         isHistory: { | ||||||
|  |           equals: true | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   )).data; | ||||||
|  |   return renderTemplate`${renderComponent($$result, "PageLayout", $$PageLayout, { "title": "\u6D3B\u52A8" }, { "default": ($$result2) => renderTemplate` ${maybeRenderHead()}<div class="max-w-[720px] mx-auto"> <div class="card w-full shadow-xl"> <div class="card-body"> <h2 class="card-title">活动</h2> <p>读岁月史书,涨人生阅历</p> <div class="divider"></div> <ul class="timeline timeline-snap-icon max-md:timeline-compact timeline-vertical"> ${events?.map((item, idx) => { | ||||||
|  |     let align = idx % 2 === 0 ? "timeline-start" : "timeline-end"; | ||||||
|  |     let textAlign = idx % 2 === 0 ? "md:text-right" : "md:text-left"; | ||||||
|  |     return renderTemplate`<li> ${idx > 0 && renderTemplate`<hr>`} <div class="timeline-middle"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="h-5 w-5"> <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z" clip-rule="evenodd"></path> </svg> </div> <div${addAttribute(`${align} ${textAlign} mb-10`, "class")}> <time class="font-mono italic"> ${new Date(item.createdAt).toLocaleDateString()} </time> <div class="text-lg font-black">${item.title}</div> ${renderComponent($$result2, "DocumentRenderer", DocumentRenderer, { "document": item.content.document })} </div> <hr> </li>`; | ||||||
|  |   })} </ul> <div class="text-center max-md:text-left italic"> | ||||||
|  | 我们的故事还在继续…… | ||||||
|  | </div> </div> </div> </div> ` })}`; | ||||||
|  | }, "/Users/littlesheep/Documents/Projects/Capital/src/pages/events/index.astro", void 0); | ||||||
|  |  | ||||||
|  | const $$file$2 = "/Users/littlesheep/Documents/Projects/Capital/src/pages/events/index.astro"; | ||||||
|  | const $$url$2 = "/events"; | ||||||
|  |  | ||||||
|  | const index$2 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ | ||||||
|  |   __proto__: null, | ||||||
|  |   default: $$Index$2, | ||||||
|  |   file: $$file$2, | ||||||
|  |   prerender: prerender$2, | ||||||
|  |   url: $$url$2 | ||||||
|  | }, Symbol.toStringTag, { value: 'Module' })); | ||||||
|  |  | ||||||
|  | const $$Astro$1 = createAstro("https://smartsheep.studio"); | ||||||
|  | const prerender$1 = false; | ||||||
|  | const $$Index$1 = createComponent(async ($$result, $$props, $$slots) => { | ||||||
|  |   const Astro2 = $$result.createAstro($$Astro$1, $$props, $$slots); | ||||||
|  |   Astro2.self = $$Index$1; | ||||||
|  |   const { posts } = (await graphQuery( | ||||||
|  |     `query Query($where: PostWhereInput!, $orderBy: [PostOrderByInput!]!) { | ||||||
|  |   posts(where: $where, orderBy: $orderBy) { | ||||||
|  |     slug | ||||||
|  |     type | ||||||
|  |     title | ||||||
|  |     description | ||||||
|  |     cover { | ||||||
|  |       image { | ||||||
|  |         url | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     content { | ||||||
|  |       document | ||||||
|  |     } | ||||||
|  |     categories { | ||||||
|  |       name | ||||||
|  |     } | ||||||
|  |     tags { | ||||||
|  |       name | ||||||
|  |     } | ||||||
|  |     createdAt | ||||||
|  |   } | ||||||
|  | }`, | ||||||
|  |     { | ||||||
|  |       orderBy: [ | ||||||
|  |         { | ||||||
|  |           createdAt: "desc" | ||||||
|  |         } | ||||||
|  |       ], | ||||||
|  |       where: {} | ||||||
|  |     } | ||||||
|  |   )).data; | ||||||
|  |   return renderTemplate`${renderComponent($$result, "PageLayout", $$PageLayout, { "title": "\u8BB0\u5F55" }, { "default": ($$result2) => renderTemplate` ${maybeRenderHead()}<div class="max-w-[720px] mx-auto"> <div class="pt-16 pb-6 px-6"> <h1 class="text-4xl font-bold">记录</h1> <p class="pt-2">记录生活,记录理想,记录记录……</p> </div> ${renderComponent($$result2, "PostList", $$PostList, { "posts": posts })} </div> ` })}`; | ||||||
|  | }, "/Users/littlesheep/Documents/Projects/Capital/src/pages/posts/index.astro", void 0); | ||||||
|  |  | ||||||
|  | const $$file$1 = "/Users/littlesheep/Documents/Projects/Capital/src/pages/posts/index.astro"; | ||||||
|  | const $$url$1 = "/posts"; | ||||||
|  |  | ||||||
|  | const index$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ | ||||||
|  |   __proto__: null, | ||||||
|  |   default: $$Index$1, | ||||||
|  |   file: $$file$1, | ||||||
|  |   prerender: prerender$1, | ||||||
|  |   url: $$url$1 | ||||||
|  | }, Symbol.toStringTag, { value: 'Module' })); | ||||||
|  |  | ||||||
|  | const $$Astro = createAstro("https://smartsheep.studio"); | ||||||
|  | const prerender = false; | ||||||
|  | const $$Index = createComponent(async ($$result, $$props, $$slots) => { | ||||||
|  |   const Astro2 = $$result.createAstro($$Astro, $$props, $$slots); | ||||||
|  |   Astro2.self = $$Index; | ||||||
|  |   const { events } = (await graphQuery( | ||||||
|  |     `query Query($where: EventWhereInput!) { | ||||||
|  |   events(where: $where) { | ||||||
|  |     slug | ||||||
|  |     title | ||||||
|  |     description | ||||||
|  |     createdAt | ||||||
|  |   } | ||||||
|  | }`, | ||||||
|  |     { | ||||||
|  |       where: { | ||||||
|  |         isHistory: { | ||||||
|  |           equals: true | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   )).data; | ||||||
|  |   return renderTemplate`${renderComponent($$result, "RootLayout", $$RootLayout, { "data-astro-cid-j7pv25f6": true }, { "default": ($$result2) => renderTemplate` ${maybeRenderHead()}<div class="max-h-fullpage mt-header wrapper px-5 snap-y snap-mandatory" data-astro-cid-j7pv25f6> <div id="hello" class="hero h-fullpage snap-start" data-astro-cid-j7pv25f6> <div class="hero-content w-full grid grid-cols-1 md:grid-cols-2 max-md:gap-[60px]" data-astro-cid-j7pv25f6> <div class="max-md:text-center" data-astro-cid-j7pv25f6> <h1 class="text-5xl font-bold" data-astro-cid-j7pv25f6>你好呀 👋</h1> <p class="py-6" data-astro-cid-j7pv25f6> | ||||||
|  | 欢迎来到 SmartSheep Studio | ||||||
|  |             的官方网站!在这里了解,订阅,跟踪我们的最新消息。 | ||||||
|  |             接触我们最大的官方社区,并且尝试最新产品,参与各种活动,提供反馈,让我们更好的服务您。 | ||||||
|  | </p> <a href="#about" class="btn btn-primary btn-md" data-astro-cid-j7pv25f6>了解更多</a> </div> <div class="flex justify-center md:justify-end max-md:order-first" data-astro-cid-j7pv25f6> <div class="spinning p-3 md:p-5 shadow-2xl aspect-square rounded-[30%] w-[192px] md:w-[256px] lg:w-[384px]" data-astro-cid-j7pv25f6> <img src="/favicon.svg" alt="logo" loading="lazy" data-astro-cid-j7pv25f6> </div> </div> </div> </div> <div id="about" class="hero h-fullpage snap-start" data-astro-cid-j7pv25f6> <div class="hero-content w-full grid grid-cols-1 md:grid-cols-2 max-md:gap-[60px]" data-astro-cid-j7pv25f6> <div class="flex justify-center md:justify-start" data-astro-cid-j7pv25f6> <div class="stats shadow overflow-x-auto" data-astro-cid-j7pv25f6> <div class="stat" data-astro-cid-j7pv25f6> <div class="stat-figure text-secondary" data-astro-cid-j7pv25f6> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="inline-block w-8 h-8 stroke-current" data-astro-cid-j7pv25f6><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" data-astro-cid-j7pv25f6></path></svg> </div> <div class="stat-title" data-astro-cid-j7pv25f6>People</div> <div class="stat-value" data-astro-cid-j7pv25f6>1</div> <div class="stat-desc" data-astro-cid-j7pv25f6>2019 - ${(/* @__PURE__ */ new Date()).getFullYear()}</div> </div> <div class="stat" data-astro-cid-j7pv25f6> <div class="stat-figure text-secondary" data-astro-cid-j7pv25f6> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="inline-block w-8 h-8 stroke-current" data-astro-cid-j7pv25f6><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4" data-astro-cid-j7pv25f6></path></svg> </div> <div class="stat-title" data-astro-cid-j7pv25f6>Clients</div> <div class="stat-value" data-astro-cid-j7pv25f6>180</div> <div class="stat-desc" data-astro-cid-j7pv25f6>↗︎ 80 (44%)</div> </div> <div class="stat" data-astro-cid-j7pv25f6> <div class="stat-figure text-secondary" data-astro-cid-j7pv25f6> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="inline-block w-8 h-8 stroke-current" data-astro-cid-j7pv25f6><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 8h14M5 8a2 2 0 110-4h14a2 2 0 110 4M5 8v10a2 2 0 002 2h10a2 2 0 002-2V8m-9 4h4" data-astro-cid-j7pv25f6></path></svg> </div> <div class="stat-title" data-astro-cid-j7pv25f6>Products</div> <div class="stat-value" data-astro-cid-j7pv25f6>4</div> <div class="stat-desc" data-astro-cid-j7pv25f6>↘︎ 8 (67%)</div> </div> </div> </div> <div class="max-md:text-center" data-astro-cid-j7pv25f6> <h1 class="text-5xl font-bold" data-astro-cid-j7pv25f6>关于我们 🔖</h1> <p class="py-6" data-astro-cid-j7pv25f6> | ||||||
|  | 我们是一群充满活力、对开源充满热情的开发者。成立于 2019 | ||||||
|  |             年。自那年起我们一直在开发让人喜欢的开源软件。在我们这里,“取之于开源,用之于开源” | ||||||
|  |             不仅是原则,更是我们信仰的座右铭。 | ||||||
|  | </p> <a href="#history" class="btn btn-primary btn-md pl-[24px]" data-astro-cid-j7pv25f6> | ||||||
|  | 查看「岁月史书」 | ||||||
|  | </a> </div> </div> </div> <div id="history" class="flex flex-col justify-center items-center h-fullpage snap-start" data-astro-cid-j7pv25f6> <div class="text-center" data-astro-cid-j7pv25f6> <div data-astro-cid-j7pv25f6> <h1 class="text-4xl font-bold" data-astro-cid-j7pv25f6>岁月史书</h1> <p class="pt-2 pb-4 tracking-[8px]" data-astro-cid-j7pv25f6>但当涉猎,见往事耳</p> <ul class="pb-6 mx-[-20px] max-w-[100vw] px-5 flex justify-center history timeline timeline-horizontal" data-astro-cid-j7pv25f6> ${events?.map((item, idx) => renderTemplate`<li data-astro-cid-j7pv25f6> ${idx > 0 && renderTemplate`<hr data-astro-cid-j7pv25f6>`} <div class="timeline-start" data-astro-cid-j7pv25f6> ${new Date(item.createdAt).toLocaleDateString()} </div> <div class="timeline-middle" data-astro-cid-j7pv25f6> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-5 h-5" data-astro-cid-j7pv25f6> <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z" clip-rule="evenodd" data-astro-cid-j7pv25f6></path> </svg> </div> <div class="timeline-end timeline-box" data-astro-cid-j7pv25f6> <h2 class="font-bold text-lg" data-astro-cid-j7pv25f6>${item.title}</h2> <div class="line-clamp-2" data-astro-cid-j7pv25f6>${item.description}</div> </div> ${idx < events?.length - 1 && renderTemplate`<hr data-astro-cid-j7pv25f6>`} </li>`)} </ul> <a class="btn btn-primary" href="/events" data-astro-cid-j7pv25f6>查看更多</a> </div> </div> </div> </div> ` })}  `; | ||||||
|  | }, "/Users/littlesheep/Documents/Projects/Capital/src/pages/index.astro", void 0); | ||||||
|  |  | ||||||
|  | const $$file = "/Users/littlesheep/Documents/Projects/Capital/src/pages/index.astro"; | ||||||
|  | const $$url = ""; | ||||||
|  |  | ||||||
|  | const index = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ | ||||||
|  |   __proto__: null, | ||||||
|  |   default: $$Index, | ||||||
|  |   file: $$file, | ||||||
|  |   prerender, | ||||||
|  |   url: $$url | ||||||
|  | }, Symbol.toStringTag, { value: 'Module' })); | ||||||
|  |  | ||||||
|  | export { index$1 as a, index as b, index$2 as i }; | ||||||
							
								
								
									
										240
									
								
								test/data/warden/dist/server/chunks/pages/node_hIg2I-Kh.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										240
									
								
								test/data/warden/dist/server/chunks/pages/node_hIg2I-Kh.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,240 @@ | |||||||
|  | import { isRemotePath } from '@astrojs/internal-helpers/path'; | ||||||
|  | import { readFile } from 'fs/promises'; | ||||||
|  | import mime from 'mime/lite.js'; | ||||||
|  | import 'os'; | ||||||
|  | import { A as AstroError, j as InvalidImageService, k as ExpectedImageOptions, E as ExpectedImage, c as createAstro, d as createComponent, l as ImageMissingAlt, r as renderTemplate, m as maybeRenderHead, e as addAttribute, s as spreadAttributes } from '../astro_5WdVqH1c.mjs'; | ||||||
|  | import { i as isESMImportedImage, a as isLocalService, b as isRemoteImage, D as DEFAULT_HASH_PROPS, c as isRemoteAllowed } from '../astro/assets-service_4dMyVCFm.mjs'; | ||||||
|  | import 'html-escaper'; | ||||||
|  | import 'clsx'; | ||||||
|  |  | ||||||
|  | async function getConfiguredImageService() { | ||||||
|  |   if (!globalThis?.astroAsset?.imageService) { | ||||||
|  |     const { default: service } = await import( | ||||||
|  |       // @ts-expect-error | ||||||
|  |       '../astro/assets-service_4dMyVCFm.mjs' | ||||||
|  |     ).then(n => n.s).catch((e) => { | ||||||
|  |       const error = new AstroError(InvalidImageService); | ||||||
|  |       error.cause = e; | ||||||
|  |       throw error; | ||||||
|  |     }); | ||||||
|  |     if (!globalThis.astroAsset) | ||||||
|  |       globalThis.astroAsset = {}; | ||||||
|  |     globalThis.astroAsset.imageService = service; | ||||||
|  |     return service; | ||||||
|  |   } | ||||||
|  |   return globalThis.astroAsset.imageService; | ||||||
|  | } | ||||||
|  | async function getImage$1(options, imageConfig) { | ||||||
|  |   if (!options || typeof options !== "object") { | ||||||
|  |     throw new AstroError({ | ||||||
|  |       ...ExpectedImageOptions, | ||||||
|  |       message: ExpectedImageOptions.message(JSON.stringify(options)) | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  |   if (typeof options.src === "undefined") { | ||||||
|  |     throw new AstroError({ | ||||||
|  |       ...ExpectedImage, | ||||||
|  |       message: ExpectedImage.message( | ||||||
|  |         options.src, | ||||||
|  |         "undefined", | ||||||
|  |         JSON.stringify(options) | ||||||
|  |       ) | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  |   const service = await getConfiguredImageService(); | ||||||
|  |   const resolvedOptions = { | ||||||
|  |     ...options, | ||||||
|  |     src: typeof options.src === "object" && "then" in options.src ? (await options.src).default ?? await options.src : options.src | ||||||
|  |   }; | ||||||
|  |   const originalPath = isESMImportedImage(resolvedOptions.src) ? resolvedOptions.src.fsPath : resolvedOptions.src; | ||||||
|  |   const clonedSrc = isESMImportedImage(resolvedOptions.src) ? ( | ||||||
|  |     // @ts-expect-error - clone is a private, hidden prop | ||||||
|  |     resolvedOptions.src.clone ?? resolvedOptions.src | ||||||
|  |   ) : resolvedOptions.src; | ||||||
|  |   resolvedOptions.src = clonedSrc; | ||||||
|  |   const validatedOptions = service.validateOptions ? await service.validateOptions(resolvedOptions, imageConfig) : resolvedOptions; | ||||||
|  |   const srcSetTransforms = service.getSrcSet ? await service.getSrcSet(validatedOptions, imageConfig) : []; | ||||||
|  |   let imageURL = await service.getURL(validatedOptions, imageConfig); | ||||||
|  |   let srcSets = await Promise.all( | ||||||
|  |     srcSetTransforms.map(async (srcSet) => ({ | ||||||
|  |       transform: srcSet.transform, | ||||||
|  |       url: await service.getURL(srcSet.transform, imageConfig), | ||||||
|  |       descriptor: srcSet.descriptor, | ||||||
|  |       attributes: srcSet.attributes | ||||||
|  |     })) | ||||||
|  |   ); | ||||||
|  |   if (isLocalService(service) && globalThis.astroAsset.addStaticImage && !(isRemoteImage(validatedOptions.src) && imageURL === validatedOptions.src)) { | ||||||
|  |     const propsToHash = service.propertiesToHash ?? DEFAULT_HASH_PROPS; | ||||||
|  |     imageURL = globalThis.astroAsset.addStaticImage(validatedOptions, propsToHash, originalPath); | ||||||
|  |     srcSets = srcSetTransforms.map((srcSet) => ({ | ||||||
|  |       transform: srcSet.transform, | ||||||
|  |       url: globalThis.astroAsset.addStaticImage(srcSet.transform, propsToHash, originalPath), | ||||||
|  |       descriptor: srcSet.descriptor, | ||||||
|  |       attributes: srcSet.attributes | ||||||
|  |     })); | ||||||
|  |   } | ||||||
|  |   return { | ||||||
|  |     rawOptions: resolvedOptions, | ||||||
|  |     options: validatedOptions, | ||||||
|  |     src: imageURL, | ||||||
|  |     srcSet: { | ||||||
|  |       values: srcSets, | ||||||
|  |       attribute: srcSets.map((srcSet) => `${srcSet.url} ${srcSet.descriptor}`).join(", ") | ||||||
|  |     }, | ||||||
|  |     attributes: service.getHTMLAttributes !== void 0 ? await service.getHTMLAttributes(validatedOptions, imageConfig) : {} | ||||||
|  |   }; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const fnv1a52 = (str) => { | ||||||
|  |   const len = str.length; | ||||||
|  |   let i = 0, t0 = 0, v0 = 8997, t1 = 0, v1 = 33826, t2 = 0, v2 = 40164, t3 = 0, v3 = 52210; | ||||||
|  |   while (i < len) { | ||||||
|  |     v0 ^= str.charCodeAt(i++); | ||||||
|  |     t0 = v0 * 435; | ||||||
|  |     t1 = v1 * 435; | ||||||
|  |     t2 = v2 * 435; | ||||||
|  |     t3 = v3 * 435; | ||||||
|  |     t2 += v0 << 8; | ||||||
|  |     t3 += v1 << 8; | ||||||
|  |     t1 += t0 >>> 16; | ||||||
|  |     v0 = t0 & 65535; | ||||||
|  |     t2 += t1 >>> 16; | ||||||
|  |     v1 = t1 & 65535; | ||||||
|  |     v3 = t3 + (t2 >>> 16) & 65535; | ||||||
|  |     v2 = t2 & 65535; | ||||||
|  |   } | ||||||
|  |   return (v3 & 15) * 281474976710656 + v2 * 4294967296 + v1 * 65536 + (v0 ^ v3 >> 4); | ||||||
|  | }; | ||||||
|  | const etag = (payload, weak = false) => { | ||||||
|  |   const prefix = weak ? 'W/"' : '"'; | ||||||
|  |   return prefix + fnv1a52(payload).toString(36) + payload.length.toString(36) + '"'; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | const $$Astro$1 = createAstro("https://smartsheep.studio"); | ||||||
|  | const $$Image = createComponent(async ($$result, $$props, $$slots) => { | ||||||
|  |   const Astro2 = $$result.createAstro($$Astro$1, $$props, $$slots); | ||||||
|  |   Astro2.self = $$Image; | ||||||
|  |   const props = Astro2.props; | ||||||
|  |   if (props.alt === void 0 || props.alt === null) { | ||||||
|  |     throw new AstroError(ImageMissingAlt); | ||||||
|  |   } | ||||||
|  |   if (typeof props.width === "string") { | ||||||
|  |     props.width = parseInt(props.width); | ||||||
|  |   } | ||||||
|  |   if (typeof props.height === "string") { | ||||||
|  |     props.height = parseInt(props.height); | ||||||
|  |   } | ||||||
|  |   const image = await getImage(props); | ||||||
|  |   const additionalAttributes = {}; | ||||||
|  |   if (image.srcSet.values.length > 0) { | ||||||
|  |     additionalAttributes.srcset = image.srcSet.attribute; | ||||||
|  |   } | ||||||
|  |   return renderTemplate`${maybeRenderHead()}<img${addAttribute(image.src, "src")}${spreadAttributes(additionalAttributes)}${spreadAttributes(image.attributes)}>`; | ||||||
|  | }, "/Users/littlesheep/Documents/Projects/Capital/node_modules/astro/components/Image.astro", void 0); | ||||||
|  |  | ||||||
|  | const $$Astro = createAstro("https://smartsheep.studio"); | ||||||
|  | const $$Picture = createComponent(async ($$result, $$props, $$slots) => { | ||||||
|  |   const Astro2 = $$result.createAstro($$Astro, $$props, $$slots); | ||||||
|  |   Astro2.self = $$Picture; | ||||||
|  |   const defaultFormats = ["webp"]; | ||||||
|  |   const defaultFallbackFormat = "png"; | ||||||
|  |   const specialFormatsFallback = ["gif", "svg", "jpg", "jpeg"]; | ||||||
|  |   const { formats = defaultFormats, pictureAttributes = {}, fallbackFormat, ...props } = Astro2.props; | ||||||
|  |   if (props.alt === void 0 || props.alt === null) { | ||||||
|  |     throw new AstroError(ImageMissingAlt); | ||||||
|  |   } | ||||||
|  |   const optimizedImages = await Promise.all( | ||||||
|  |     formats.map( | ||||||
|  |       async (format) => await getImage({ ...props, format, widths: props.widths, densities: props.densities }) | ||||||
|  |     ) | ||||||
|  |   ); | ||||||
|  |   let resultFallbackFormat = fallbackFormat ?? defaultFallbackFormat; | ||||||
|  |   if (!fallbackFormat && isESMImportedImage(props.src) && specialFormatsFallback.includes(props.src.format)) { | ||||||
|  |     resultFallbackFormat = props.src.format; | ||||||
|  |   } | ||||||
|  |   const fallbackImage = await getImage({ | ||||||
|  |     ...props, | ||||||
|  |     format: resultFallbackFormat, | ||||||
|  |     widths: props.widths, | ||||||
|  |     densities: props.densities | ||||||
|  |   }); | ||||||
|  |   const imgAdditionalAttributes = {}; | ||||||
|  |   const sourceAdditionaAttributes = {}; | ||||||
|  |   if (props.sizes) { | ||||||
|  |     sourceAdditionaAttributes.sizes = props.sizes; | ||||||
|  |   } | ||||||
|  |   if (fallbackImage.srcSet.values.length > 0) { | ||||||
|  |     imgAdditionalAttributes.srcset = fallbackImage.srcSet.attribute; | ||||||
|  |   } | ||||||
|  |   return renderTemplate`${maybeRenderHead()}<picture${spreadAttributes(pictureAttributes)}> ${Object.entries(optimizedImages).map(([_, image]) => { | ||||||
|  |     const srcsetAttribute = props.densities || !props.densities && !props.widths ? `${image.src}${image.srcSet.values.length > 0 ? ", " + image.srcSet.attribute : ""}` : image.srcSet.attribute; | ||||||
|  |     return renderTemplate`<source${addAttribute(srcsetAttribute, "srcset")}${addAttribute("image/" + image.options.format, "type")}${spreadAttributes(sourceAdditionaAttributes)}>`; | ||||||
|  |   })} <img${addAttribute(fallbackImage.src, "src")}${spreadAttributes(imgAdditionalAttributes)}${spreadAttributes(fallbackImage.attributes)}> </picture>`; | ||||||
|  | }, "/Users/littlesheep/Documents/Projects/Capital/node_modules/astro/components/Picture.astro", void 0); | ||||||
|  |  | ||||||
|  | const imageConfig = {"service":{"entrypoint":"astro/assets/services/sharp","config":{}},"domains":[],"remotePatterns":[],"endpoint":"astro/assets/endpoint/node"}; | ||||||
|  | 					const assetsDir = new URL("file:///Users/littlesheep/Documents/Projects/Capital/dist/client/"); | ||||||
|  | 					const getImage = async (options) => await getImage$1(options, imageConfig); | ||||||
|  |  | ||||||
|  | async function loadLocalImage(src, url) { | ||||||
|  |   const filePath = new URL("." + src, assetsDir); | ||||||
|  |   let buffer = void 0; | ||||||
|  |   try { | ||||||
|  |     buffer = await readFile(filePath); | ||||||
|  |   } catch (e) { | ||||||
|  |     const sourceUrl = new URL(src, url.origin); | ||||||
|  |     buffer = await loadRemoteImage(sourceUrl); | ||||||
|  |   } | ||||||
|  |   return buffer; | ||||||
|  | } | ||||||
|  | async function loadRemoteImage(src) { | ||||||
|  |   try { | ||||||
|  |     const res = await fetch(src); | ||||||
|  |     if (!res.ok) { | ||||||
|  |       return void 0; | ||||||
|  |     } | ||||||
|  |     return Buffer.from(await res.arrayBuffer()); | ||||||
|  |   } catch (err) { | ||||||
|  |     return void 0; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const GET = async ({ request }) => { | ||||||
|  |   try { | ||||||
|  |     const imageService = await getConfiguredImageService(); | ||||||
|  |     if (!("transform" in imageService)) { | ||||||
|  |       throw new Error("Configured image service is not a local service"); | ||||||
|  |     } | ||||||
|  |     const url = new URL(request.url); | ||||||
|  |     const transform = await imageService.parseURL(url, imageConfig); | ||||||
|  |     if (!transform?.src) { | ||||||
|  |       throw new Error("Incorrect transform returned by `parseURL`"); | ||||||
|  |     } | ||||||
|  |     let inputBuffer = void 0; | ||||||
|  |     if (isRemotePath(transform.src)) { | ||||||
|  |       if (isRemoteAllowed(transform.src, imageConfig) === false) { | ||||||
|  |         return new Response("Forbidden", { status: 403 }); | ||||||
|  |       } | ||||||
|  |       inputBuffer = await loadRemoteImage(new URL(transform.src)); | ||||||
|  |     } else { | ||||||
|  |       inputBuffer = await loadLocalImage(transform.src, url); | ||||||
|  |     } | ||||||
|  |     if (!inputBuffer) { | ||||||
|  |       return new Response("Not Found", { status: 404 }); | ||||||
|  |     } | ||||||
|  |     const { data, format } = await imageService.transform(inputBuffer, transform, imageConfig); | ||||||
|  |     return new Response(data, { | ||||||
|  |       status: 200, | ||||||
|  |       headers: { | ||||||
|  |         "Content-Type": mime.getType(format) ?? `image/${format}`, | ||||||
|  |         "Cache-Control": "public, max-age=31536000", | ||||||
|  |         ETag: etag(data.toString()), | ||||||
|  |         Date: (/* @__PURE__ */ new Date()).toUTCString() | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  |   } catch (err) { | ||||||
|  |     console.error("Could not process image request:", err); | ||||||
|  |     return new Response(`Server Error: ${err}`, { status: 500 }); | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export { GET }; | ||||||
							
								
								
									
										31
									
								
								test/data/warden/dist/server/chunks/vnode-children_3wEZly-Z.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								test/data/warden/dist/server/chunks/vnode-children_3wEZly-Z.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | |||||||
|  | import { parse, DOCUMENT_NODE, ELEMENT_NODE, TEXT_NODE } from 'ultrahtml'; | ||||||
|  | import { createElement, Fragment } from 'react'; | ||||||
|  |  | ||||||
|  | let ids = 0; | ||||||
|  | function convert(children) { | ||||||
|  | 	let doc = parse(children.toString().trim()); | ||||||
|  | 	let id = ids++; | ||||||
|  | 	let key = 0; | ||||||
|  |  | ||||||
|  | 	function createReactElementFromNode(node) { | ||||||
|  | 		const childVnodes = | ||||||
|  | 			Array.isArray(node.children) && node.children.length | ||||||
|  | 				? node.children.map((child) => createReactElementFromNode(child)).filter(Boolean) | ||||||
|  | 				: undefined; | ||||||
|  |  | ||||||
|  | 		if (node.type === DOCUMENT_NODE) { | ||||||
|  | 			return createElement(Fragment, {}, childVnodes); | ||||||
|  | 		} else if (node.type === ELEMENT_NODE) { | ||||||
|  | 			const { class: className, ...props } = node.attributes; | ||||||
|  | 			return createElement(node.name, { ...props, className, key: `${id}-${key++}` }, childVnodes); | ||||||
|  | 		} else if (node.type === TEXT_NODE) { | ||||||
|  | 			// 0-length text gets omitted in JSX | ||||||
|  | 			return node.value.trim() ? node.value : undefined; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	const root = createReactElementFromNode(doc); | ||||||
|  | 	return root.props.children; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export { convert as default }; | ||||||
							
								
								
									
										2355
									
								
								test/data/warden/dist/server/entry.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2355
									
								
								test/data/warden/dist/server/entry.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										197
									
								
								test/data/warden/dist/server/manifest_irk0fM_a.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								test/data/warden/dist/server/manifest_irk0fM_a.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										263
									
								
								test/data/warden/dist/server/renderers.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										263
									
								
								test/data/warden/dist/server/renderers.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,263 @@ | |||||||
|  | import React, { createElement } from 'react'; | ||||||
|  | import ReactDOM from 'react-dom/server'; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Astro passes `children` as a string of HTML, so we need | ||||||
|  |  * a wrapper `div` to render that content as VNodes. | ||||||
|  |  * | ||||||
|  |  * As a bonus, we can signal to React that this subtree is | ||||||
|  |  * entirely static and will never change via `shouldComponentUpdate`. | ||||||
|  |  */ | ||||||
|  | const StaticHtml = ({ value, name, hydrate = true }) => { | ||||||
|  | 	if (!value) return null; | ||||||
|  | 	const tagName = hydrate ? 'astro-slot' : 'astro-static-slot'; | ||||||
|  | 	return createElement(tagName, { | ||||||
|  | 		name, | ||||||
|  | 		suppressHydrationWarning: true, | ||||||
|  | 		dangerouslySetInnerHTML: { __html: value }, | ||||||
|  | 	}); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * This tells React to opt-out of re-rendering this subtree, | ||||||
|  |  * In addition to being a performance optimization, | ||||||
|  |  * this also allows other frameworks to attach to `children`. | ||||||
|  |  * | ||||||
|  |  * See https://preactjs.com/guide/v8/external-dom-mutations | ||||||
|  |  */ | ||||||
|  | StaticHtml.shouldComponentUpdate = () => false; | ||||||
|  |  | ||||||
|  | const contexts = new WeakMap(); | ||||||
|  |  | ||||||
|  | const ID_PREFIX = 'r'; | ||||||
|  |  | ||||||
|  | function getContext(rendererContextResult) { | ||||||
|  | 	if (contexts.has(rendererContextResult)) { | ||||||
|  | 		return contexts.get(rendererContextResult); | ||||||
|  | 	} | ||||||
|  | 	const ctx = { | ||||||
|  | 		currentIndex: 0, | ||||||
|  | 		get id() { | ||||||
|  | 			return ID_PREFIX + this.currentIndex.toString(); | ||||||
|  | 		}, | ||||||
|  | 	}; | ||||||
|  | 	contexts.set(rendererContextResult, ctx); | ||||||
|  | 	return ctx; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function incrementId(rendererContextResult) { | ||||||
|  | 	const ctx = getContext(rendererContextResult); | ||||||
|  | 	const id = ctx.id; | ||||||
|  | 	ctx.currentIndex++; | ||||||
|  | 	return id; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const opts = { | ||||||
|  | 						experimentalReactChildren: false | ||||||
|  | 					}; | ||||||
|  |  | ||||||
|  | const slotName = (str) => str.trim().replace(/[-_]([a-z])/g, (_, w) => w.toUpperCase()); | ||||||
|  | const reactTypeof = Symbol.for('react.element'); | ||||||
|  |  | ||||||
|  | function errorIsComingFromPreactComponent(err) { | ||||||
|  | 	return ( | ||||||
|  | 		err.message && | ||||||
|  | 		(err.message.startsWith("Cannot read property '__H'") || | ||||||
|  | 			err.message.includes("(reading '__H')")) | ||||||
|  | 	); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | async function check(Component, props, children) { | ||||||
|  | 	// Note: there are packages that do some unholy things to create "components". | ||||||
|  | 	// Checking the $$typeof property catches most of these patterns. | ||||||
|  | 	if (typeof Component === 'object') { | ||||||
|  | 		return Component['$$typeof'].toString().slice('Symbol('.length).startsWith('react'); | ||||||
|  | 	} | ||||||
|  | 	if (typeof Component !== 'function') return false; | ||||||
|  | 	if (Component.name === 'QwikComponent') return false; | ||||||
|  |  | ||||||
|  | 	// Preact forwarded-ref components can be functions, which React does not support | ||||||
|  | 	if (typeof Component === 'function' && Component['$$typeof'] === Symbol.for('react.forward_ref')) | ||||||
|  | 		return false; | ||||||
|  |  | ||||||
|  | 	if (Component.prototype != null && typeof Component.prototype.render === 'function') { | ||||||
|  | 		return React.Component.isPrototypeOf(Component) || React.PureComponent.isPrototypeOf(Component); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	let error = null; | ||||||
|  | 	let isReactComponent = false; | ||||||
|  | 	function Tester(...args) { | ||||||
|  | 		try { | ||||||
|  | 			const vnode = Component(...args); | ||||||
|  | 			if (vnode && vnode['$$typeof'] === reactTypeof) { | ||||||
|  | 				isReactComponent = true; | ||||||
|  | 			} | ||||||
|  | 		} catch (err) { | ||||||
|  | 			if (!errorIsComingFromPreactComponent(err)) { | ||||||
|  | 				error = err; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		return React.createElement('div'); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	await renderToStaticMarkup(Tester, props, children, {}); | ||||||
|  |  | ||||||
|  | 	if (error) { | ||||||
|  | 		throw error; | ||||||
|  | 	} | ||||||
|  | 	return isReactComponent; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | async function getNodeWritable() { | ||||||
|  | 	let nodeStreamBuiltinModuleName = 'node:stream'; | ||||||
|  | 	let { Writable } = await import(/* @vite-ignore */ nodeStreamBuiltinModuleName); | ||||||
|  | 	return Writable; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function needsHydration(metadata) { | ||||||
|  | 	// Adjust how this is hydrated only when the version of Astro supports `astroStaticSlot` | ||||||
|  | 	return metadata.astroStaticSlot ? !!metadata.hydrate : true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | async function renderToStaticMarkup(Component, props, { default: children, ...slotted }, metadata) { | ||||||
|  | 	let prefix; | ||||||
|  | 	if (this && this.result) { | ||||||
|  | 		prefix = incrementId(this.result); | ||||||
|  | 	} | ||||||
|  | 	const attrs = { prefix }; | ||||||
|  |  | ||||||
|  | 	delete props['class']; | ||||||
|  | 	const slots = {}; | ||||||
|  | 	for (const [key, value] of Object.entries(slotted)) { | ||||||
|  | 		const name = slotName(key); | ||||||
|  | 		slots[name] = React.createElement(StaticHtml, { | ||||||
|  | 			hydrate: needsHydration(metadata), | ||||||
|  | 			value, | ||||||
|  | 			name, | ||||||
|  | 		}); | ||||||
|  | 	} | ||||||
|  | 	// Note: create newProps to avoid mutating `props` before they are serialized | ||||||
|  | 	const newProps = { | ||||||
|  | 		...props, | ||||||
|  | 		...slots, | ||||||
|  | 	}; | ||||||
|  | 	const newChildren = children ?? props.children; | ||||||
|  | 	if (children && opts.experimentalReactChildren) { | ||||||
|  | 		attrs['data-react-children'] = true; | ||||||
|  | 		const convert = await import('./chunks/vnode-children_3wEZly-Z.mjs').then((mod) => mod.default); | ||||||
|  | 		newProps.children = convert(children); | ||||||
|  | 	} else if (newChildren != null) { | ||||||
|  | 		newProps.children = React.createElement(StaticHtml, { | ||||||
|  | 			hydrate: needsHydration(metadata), | ||||||
|  | 			value: newChildren, | ||||||
|  | 		}); | ||||||
|  | 	} | ||||||
|  | 	const vnode = React.createElement(Component, newProps); | ||||||
|  | 	const renderOptions = { | ||||||
|  | 		identifierPrefix: prefix, | ||||||
|  | 	}; | ||||||
|  | 	let html; | ||||||
|  | 	if (metadata?.hydrate) { | ||||||
|  | 		if ('renderToReadableStream' in ReactDOM) { | ||||||
|  | 			html = await renderToReadableStreamAsync(vnode, renderOptions); | ||||||
|  | 		} else { | ||||||
|  | 			html = await renderToPipeableStreamAsync(vnode, renderOptions); | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		if ('renderToReadableStream' in ReactDOM) { | ||||||
|  | 			html = await renderToReadableStreamAsync(vnode, renderOptions); | ||||||
|  | 		} else { | ||||||
|  | 			html = await renderToStaticNodeStreamAsync(vnode, renderOptions); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return { html, attrs }; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | async function renderToPipeableStreamAsync(vnode, options) { | ||||||
|  | 	const Writable = await getNodeWritable(); | ||||||
|  | 	let html = ''; | ||||||
|  | 	return new Promise((resolve, reject) => { | ||||||
|  | 		let error = undefined; | ||||||
|  | 		let stream = ReactDOM.renderToPipeableStream(vnode, { | ||||||
|  | 			...options, | ||||||
|  | 			onError(err) { | ||||||
|  | 				error = err; | ||||||
|  | 				reject(error); | ||||||
|  | 			}, | ||||||
|  | 			onAllReady() { | ||||||
|  | 				stream.pipe( | ||||||
|  | 					new Writable({ | ||||||
|  | 						write(chunk, _encoding, callback) { | ||||||
|  | 							html += chunk.toString('utf-8'); | ||||||
|  | 							callback(); | ||||||
|  | 						}, | ||||||
|  | 						destroy() { | ||||||
|  | 							resolve(html); | ||||||
|  | 						}, | ||||||
|  | 					}) | ||||||
|  | 				); | ||||||
|  | 			}, | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | async function renderToStaticNodeStreamAsync(vnode, options) { | ||||||
|  | 	const Writable = await getNodeWritable(); | ||||||
|  | 	let html = ''; | ||||||
|  | 	return new Promise((resolve, reject) => { | ||||||
|  | 		let stream = ReactDOM.renderToStaticNodeStream(vnode, options); | ||||||
|  | 		stream.on('error', (err) => { | ||||||
|  | 			reject(err); | ||||||
|  | 		}); | ||||||
|  | 		stream.pipe( | ||||||
|  | 			new Writable({ | ||||||
|  | 				write(chunk, _encoding, callback) { | ||||||
|  | 					html += chunk.toString('utf-8'); | ||||||
|  | 					callback(); | ||||||
|  | 				}, | ||||||
|  | 				destroy() { | ||||||
|  | 					resolve(html); | ||||||
|  | 				}, | ||||||
|  | 			}) | ||||||
|  | 		); | ||||||
|  | 	}); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Use a while loop instead of "for await" due to cloudflare and Vercel Edge issues | ||||||
|  |  * See https://github.com/facebook/react/issues/24169 | ||||||
|  |  */ | ||||||
|  | async function readResult(stream) { | ||||||
|  | 	const reader = stream.getReader(); | ||||||
|  | 	let result = ''; | ||||||
|  | 	const decoder = new TextDecoder('utf-8'); | ||||||
|  | 	while (true) { | ||||||
|  | 		const { done, value } = await reader.read(); | ||||||
|  | 		if (done) { | ||||||
|  | 			if (value) { | ||||||
|  | 				result += decoder.decode(value); | ||||||
|  | 			} else { | ||||||
|  | 				// This closes the decoder | ||||||
|  | 				decoder.decode(new Uint8Array()); | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			return result; | ||||||
|  | 		} | ||||||
|  | 		result += decoder.decode(value, { stream: true }); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | async function renderToReadableStreamAsync(vnode, options) { | ||||||
|  | 	return await readResult(await ReactDOM.renderToReadableStream(vnode, options)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const _renderer0 = { | ||||||
|  | 	check, | ||||||
|  | 	renderToStaticMarkup, | ||||||
|  | 	supportsAstroStaticSlot: true, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | const renderers = [Object.assign({"name":"@astrojs/react","clientEntrypoint":"@astrojs/react/client.js","serverEntrypoint":"@astrojs/react/server.js"}, { ssr: _renderer0 }),]; | ||||||
|  |  | ||||||
|  | export { renderers }; | ||||||
		Reference in New Issue
	
	Block a user