refactor: website files are now templated and compiled
7
.gitignore
vendored
@ -1,4 +1,5 @@
|
||||
upload
|
||||
data.db
|
||||
target/*
|
||||
logs/*
|
||||
pack.yml
|
||||
upload/
|
||||
target/
|
||||
logs/
|
||||
|
||||
67
Cargo.lock
generated
@ -32,6 +32,48 @@ version = "1.0.98"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
|
||||
|
||||
[[package]]
|
||||
name = "askama"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f75363874b771be265f4ffe307ca705ef6f3baa19011c149da8674a87f1b75c4"
|
||||
dependencies = [
|
||||
"askama_derive",
|
||||
"itoa",
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "askama_derive"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "129397200fe83088e8a68407a8e2b1f826cf0086b21ccdb866a722c8bcd3a94f"
|
||||
dependencies = [
|
||||
"askama_parser",
|
||||
"basic-toml",
|
||||
"memchr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustc-hash",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "askama_parser"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6ab5630b3d5eaf232620167977f95eb51f3432fc76852328774afbd242d4358"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atomic-waker"
|
||||
version = "1.1.2"
|
||||
@ -120,6 +162,15 @@ version = "0.22.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||
|
||||
[[package]]
|
||||
name = "basic-toml"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba62675e8242a4c4e806d12f11d136e626e6c8361d6b829310732241652a178a"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.9.0"
|
||||
@ -871,6 +922,7 @@ name = "pack"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"askama",
|
||||
"axum",
|
||||
"bytes",
|
||||
"env_filter",
|
||||
@ -1093,6 +1145,12 @@ version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "1.0.5"
|
||||
@ -2099,6 +2157,15 @@ version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.7.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-rt"
|
||||
version = "0.39.0"
|
||||
|
||||
@ -6,6 +6,7 @@ authors = ["Kenneth Jao"]
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.98"
|
||||
askama = { version = "0.14.0", features = ["blocks"] }
|
||||
axum = { version = "0.8.1", features = ["multipart"] }
|
||||
bytes = "1.10.1"
|
||||
env_filter = "0.1.3"
|
||||
|
||||
BIN
assets/favicon.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
26
assets/fragile.svg
Normal file
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
version="1.1"
|
||||
id="svg1852"
|
||||
width="500"
|
||||
height="500"
|
||||
viewBox="0 0 500 500"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs1856" />
|
||||
<path
|
||||
d="m 237.22651,265.4401 v 148.14986 h -72.40403 v 25.09037 H 335.82315 V 413.58996 H 263.41311 V 265.30632 C 322.38109,254.83555 368.1994,176.30943 368.1994,80.939099 c 0,-6.629314 -0.23449,-13.174288 -0.66756,-19.619425 h -58.77239 l 16.45555,55.312416 -18.107,58.89411 6.79535,58.8815 -37.3216,-55.31726 20.35516,-60.66703 -26.71846,-57.103736 H 132.46816 c -0.43607,6.445137 -0.66756,12.99011 -0.66756,19.619424 0,95.723142 46.1536,174.499352 105.42591,184.500992"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.0983483"
|
||||
id="path10892" />
|
||||
<rect
|
||||
style="display:inline;fill:none;fill-opacity:0.988235;stroke:#000000;stroke-width:25.4064;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:2;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke"
|
||||
id="rect7030"
|
||||
width="474.59354"
|
||||
height="474.59354"
|
||||
x="12.459805"
|
||||
y="12.703235"
|
||||
ry="0" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
64
assets/keep_dry.svg
Normal file
@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
version="1.1"
|
||||
id="svg1852"
|
||||
width="500"
|
||||
height="500"
|
||||
viewBox="0 0 500 500"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs1856" />
|
||||
<g
|
||||
id="g1862"
|
||||
transform="matrix(0.09388818,0,0,-0.09388818,21.082497,529.0621)"
|
||||
style="fill:#000000;fill-opacity:0.988235">
|
||||
<path
|
||||
d="m 1999.88,1286.63 c -0.91,-5.74 -1.47,-13.6 -1.28,-23.03 0.41,-36.42 9,-88.28 33.43,-133.6 20.15,-37.26 52.81,-69.26 103.81,-77.77 11.59,-1.91 23.7,-2.9 36.18,-2.73 85.06,1.11 135.06,32.01 163.01,77.39 33.38,54.2 43.55,131.92 43.67,210.19 l 2.6,1507.16 c -126.9,-21.04 -233.24,-103.14 -287.97,-215.21 -63.82,130.62 -197.67,220.48 -352.46,220.48 -149.3,0 -279.07,-83.62 -345.41,-206.77 -66.27,123.15 -196.08,206.77 -345.37,206.77 -157.59,0 -293.481,-93.15 -355.844,-227.67 C 861.051,3314.35 1549.72,3838.21 2383,3863.05 l 0.27,148.88 h 187.77 l -0.27,-151.71 c 783.7,-47.65 1428.25,-537.3 1611.37,-1186.35 -70.31,105.89 -190.37,175.64 -326.75,175.64 -155.04,0 -289.08,-90.24 -352.74,-221.17 -63.72,130.93 -197.78,221.17 -352.83,221.17 -154.44,0 -288.02,-89.58 -352.07,-219.69 -46.12,93.84 -128.46,166.58 -228.77,199.85 l -2.55,-1492.59 c -0.12,-108.37 -16.81,-220.06 -71.65,-309.22 -60.27,-97.981 -159.91,-164.618 -320.61,-166.712 -25.01,-0.316 -48.08,1.403 -69.23,4.934 -119.15,19.93 -193.7,91.43 -238.54,174.538 -40.59,75.2 -54.83,160.79 -55.62,220.78 -0.16,12.23 0.39,25.75 1,33.95 l 188.1,-8.72"
|
||||
style="fill:#000000;fill-opacity:0.988235;fill-rule:nonzero;stroke:none"
|
||||
id="path2290" />
|
||||
<path
|
||||
d="m 3074.81,4774.53 c -4.53,-29.67 -16.02,-59.39 -36.62,-79.82 -20.86,-20.57 -49.46,-33.3 -80.93,-33.3 -31.86,0 -60.74,12.97 -81.6,33.87 h -0.03 c -21.81,23.81 -33.79,49.02 -33.79,81.85 0,18.13 4.21,35.41 11.7,50.77 7.58,15.5 22.35,32.15 30.37,40.51 l 208.22,211.25 c 4.81,4.99 12.79,5.05 17.77,0.21 3.2,-3.14 4.38,-7.55 3.53,-11.64 l -38.62,-293.7"
|
||||
style="fill:#000000;fill-opacity:0.988235;fill-rule:evenodd;stroke:none"
|
||||
id="path2292" />
|
||||
<path
|
||||
d="m 2778.9,4254.29 c -4.55,-29.69 -16.02,-59.41 -36.61,-79.82 -20.83,-20.58 -49.45,-33.33 -80.96,-33.33 -31.81,0 -60.72,12.95 -81.55,33.89 h -0.05 c -21.79,23.8 -33.82,48.98 -33.82,81.85 0,18.14 4.26,35.36 11.72,50.76 7.61,15.49 22.37,32.15 30.32,40.52 l 208.28,211.26 c 4.85,4.94 12.8,5.04 17.77,0.19 3.15,-3.13 4.36,-7.55 3.55,-11.64 l -38.65,-293.68"
|
||||
style="fill:#000000;fill-opacity:0.988235;fill-rule:evenodd;stroke:none"
|
||||
id="path2294" />
|
||||
<path
|
||||
d="m 1987.59,4044.19 c -4.5,-29.7 -16.02,-59.44 -36.6,-79.83 -20.83,-20.58 -49.44,-33.32 -80.98,-33.32 -31.77,0 -60.62,13.01 -81.53,33.87 v 0 c -21.79,23.82 -33.81,49 -33.81,81.87 0,18.11 4.18,35.37 11.73,50.77 7.52,15.49 22.33,32.16 30.29,40.49 l 208.29,211.28 c 4.83,4.99 12.79,5.05 17.73,0.18 3.18,-3.12 4.34,-7.55 3.54,-11.63 l -38.66,-293.68"
|
||||
style="fill:#000000;fill-opacity:0.988235;fill-rule:evenodd;stroke:none"
|
||||
id="path2296" />
|
||||
<path
|
||||
d="m 3267.59,3987.48 c -4.46,-29.67 -15.95,-59.41 -36.58,-79.82 -20.82,-20.58 -49.46,-33.28 -80.94,-33.28 -31.82,0 -60.68,12.95 -81.56,33.89 h -0.03 c -21.75,23.77 -33.83,48.96 -33.83,81.82 0,18.14 4.22,35.4 11.77,50.77 7.53,15.5 22.28,32.14 30.28,40.5 l 208.29,211.24 c 4.81,4.99 12.81,5.11 17.72,0.25 3.23,-3.16 4.38,-7.6 3.49,-11.66 l -38.61,-293.71"
|
||||
style="fill:#000000;fill-opacity:0.988235;fill-rule:evenodd;stroke:none"
|
||||
id="path2298" />
|
||||
<path
|
||||
d="m 3596.74,4484.43 c -4.5,-29.7 -15.99,-59.43 -36.62,-79.82 -20.84,-20.63 -49.44,-33.33 -80.97,-33.33 -31.74,0 -60.61,12.98 -81.49,33.9 h -0.04 c -21.79,23.74 -33.82,48.99 -33.82,81.82 0,18.14 4.2,35.39 11.73,50.77 7.51,15.5 22.28,32.16 30.32,40.52 l 208.28,211.25 c 4.83,4.98 12.8,5.04 17.75,0.18 3.18,-3.13 4.34,-7.54 3.46,-11.62 l -38.6,-293.67"
|
||||
style="fill:#000000;fill-opacity:0.988235;fill-rule:evenodd;stroke:none"
|
||||
id="path2300" />
|
||||
<path
|
||||
d="m 4009.05,3960.81 c -4.5,-29.68 -15.99,-59.39 -36.64,-79.8 -20.81,-20.58 -49.41,-33.33 -80.93,-33.33 -31.85,0 -60.73,12.97 -81.56,33.89 h -0.06 c -21.78,23.8 -33.82,49 -33.82,81.85 0,18.13 4.24,35.36 11.76,50.8 7.57,15.49 22.33,32.11 30.32,40.45 l 208.26,211.29 c 4.84,4.96 12.81,5.06 17.8,0.18 3.11,-3.1 4.31,-7.52 3.44,-11.66 l -38.57,-293.67"
|
||||
style="fill:#000000;fill-opacity:0.988235;fill-rule:evenodd;stroke:none"
|
||||
id="path2302" />
|
||||
<path
|
||||
d="m 2396.48,4761.2 c -4.44,-29.65 -15.95,-59.39 -36.58,-79.81 -20.79,-20.59 -49.46,-33.32 -80.97,-33.32 -31.75,0 -60.59,12.94 -81.51,33.88 h -0.02 c -21.79,23.81 -33.83,49.01 -33.83,81.85 0,18.1 4.18,35.35 11.73,50.77 7.52,15.51 22.33,32.12 30.3,40.49 l 208.28,211.26 c 4.85,4.97 12.8,5.07 17.82,0.21 3.12,-3.12 4.33,-7.54 3.45,-11.66 l -38.67,-293.67"
|
||||
style="fill:#000000;fill-opacity:0.988235;fill-rule:evenodd;stroke:none"
|
||||
id="path2304" />
|
||||
<path
|
||||
d="m 1598.56,4601.13 c -4.46,-29.68 -15.96,-59.42 -36.6,-79.81 -20.77,-20.59 -49.43,-33.35 -80.92,-33.35 -31.81,0 -60.62,13 -81.55,33.92 h -0.07 c -21.72,23.77 -33.73,48.99 -33.73,81.83 0,18.13 4.14,35.39 11.71,50.76 7.5,15.52 22.34,32.17 30.26,40.52 L 1616,4906.26 c 4.83,4.98 12.81,5.08 17.73,0.19 3.22,-3.14 4.32,-7.54 3.45,-11.63 l -38.62,-293.69"
|
||||
style="fill:#000000;fill-opacity:0.988235;fill-rule:evenodd;stroke:none"
|
||||
id="path2306" />
|
||||
</g>
|
||||
<rect
|
||||
style="fill:none;fill-opacity:0.988235;stroke:#000000;stroke-width:25.4064;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:2;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke"
|
||||
id="rect7030"
|
||||
width="474.5936"
|
||||
height="474.5936"
|
||||
x="12.7032"
|
||||
y="-487.29681"
|
||||
transform="scale(1,-1)"
|
||||
ry="0" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.7 KiB |
341
assets/qr_code.svg
Normal file
@ -0,0 +1,341 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg width="264" height="264" viewBox="0 0 264 264"
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events">
|
||||
<rect x="0" y="0" width="264" height="264" fill="#ffffff"/>
|
||||
<defs>
|
||||
<rect id="p" width="8" height="8"/>
|
||||
</defs>
|
||||
<g fill="#000000">
|
||||
<use xlink:href="#p" x="32" y="32"/>
|
||||
<use xlink:href="#p" x="32" y="40"/>
|
||||
<use xlink:href="#p" x="32" y="48"/>
|
||||
<use xlink:href="#p" x="32" y="56"/>
|
||||
<use xlink:href="#p" x="32" y="64"/>
|
||||
<use xlink:href="#p" x="32" y="72"/>
|
||||
<use xlink:href="#p" x="32" y="80"/>
|
||||
<use xlink:href="#p" x="32" y="96"/>
|
||||
<use xlink:href="#p" x="32" y="112"/>
|
||||
<use xlink:href="#p" x="32" y="128"/>
|
||||
<use xlink:href="#p" x="32" y="176"/>
|
||||
<use xlink:href="#p" x="32" y="184"/>
|
||||
<use xlink:href="#p" x="32" y="192"/>
|
||||
<use xlink:href="#p" x="32" y="200"/>
|
||||
<use xlink:href="#p" x="32" y="208"/>
|
||||
<use xlink:href="#p" x="32" y="216"/>
|
||||
<use xlink:href="#p" x="32" y="224"/>
|
||||
<use xlink:href="#p" x="40" y="32"/>
|
||||
<use xlink:href="#p" x="40" y="80"/>
|
||||
<use xlink:href="#p" x="40" y="104"/>
|
||||
<use xlink:href="#p" x="40" y="112"/>
|
||||
<use xlink:href="#p" x="40" y="120"/>
|
||||
<use xlink:href="#p" x="40" y="128"/>
|
||||
<use xlink:href="#p" x="40" y="136"/>
|
||||
<use xlink:href="#p" x="40" y="144"/>
|
||||
<use xlink:href="#p" x="40" y="152"/>
|
||||
<use xlink:href="#p" x="40" y="160"/>
|
||||
<use xlink:href="#p" x="40" y="176"/>
|
||||
<use xlink:href="#p" x="40" y="224"/>
|
||||
<use xlink:href="#p" x="48" y="32"/>
|
||||
<use xlink:href="#p" x="48" y="48"/>
|
||||
<use xlink:href="#p" x="48" y="56"/>
|
||||
<use xlink:href="#p" x="48" y="64"/>
|
||||
<use xlink:href="#p" x="48" y="80"/>
|
||||
<use xlink:href="#p" x="48" y="96"/>
|
||||
<use xlink:href="#p" x="48" y="104"/>
|
||||
<use xlink:href="#p" x="48" y="176"/>
|
||||
<use xlink:href="#p" x="48" y="192"/>
|
||||
<use xlink:href="#p" x="48" y="200"/>
|
||||
<use xlink:href="#p" x="48" y="208"/>
|
||||
<use xlink:href="#p" x="48" y="224"/>
|
||||
<use xlink:href="#p" x="56" y="32"/>
|
||||
<use xlink:href="#p" x="56" y="48"/>
|
||||
<use xlink:href="#p" x="56" y="56"/>
|
||||
<use xlink:href="#p" x="56" y="64"/>
|
||||
<use xlink:href="#p" x="56" y="80"/>
|
||||
<use xlink:href="#p" x="56" y="96"/>
|
||||
<use xlink:href="#p" x="56" y="104"/>
|
||||
<use xlink:href="#p" x="56" y="112"/>
|
||||
<use xlink:href="#p" x="56" y="128"/>
|
||||
<use xlink:href="#p" x="56" y="160"/>
|
||||
<use xlink:href="#p" x="56" y="176"/>
|
||||
<use xlink:href="#p" x="56" y="192"/>
|
||||
<use xlink:href="#p" x="56" y="200"/>
|
||||
<use xlink:href="#p" x="56" y="208"/>
|
||||
<use xlink:href="#p" x="56" y="224"/>
|
||||
<use xlink:href="#p" x="64" y="32"/>
|
||||
<use xlink:href="#p" x="64" y="48"/>
|
||||
<use xlink:href="#p" x="64" y="56"/>
|
||||
<use xlink:href="#p" x="64" y="64"/>
|
||||
<use xlink:href="#p" x="64" y="80"/>
|
||||
<use xlink:href="#p" x="64" y="96"/>
|
||||
<use xlink:href="#p" x="64" y="104"/>
|
||||
<use xlink:href="#p" x="64" y="128"/>
|
||||
<use xlink:href="#p" x="64" y="136"/>
|
||||
<use xlink:href="#p" x="64" y="144"/>
|
||||
<use xlink:href="#p" x="64" y="160"/>
|
||||
<use xlink:href="#p" x="64" y="176"/>
|
||||
<use xlink:href="#p" x="64" y="192"/>
|
||||
<use xlink:href="#p" x="64" y="200"/>
|
||||
<use xlink:href="#p" x="64" y="208"/>
|
||||
<use xlink:href="#p" x="64" y="224"/>
|
||||
<use xlink:href="#p" x="72" y="32"/>
|
||||
<use xlink:href="#p" x="72" y="80"/>
|
||||
<use xlink:href="#p" x="72" y="96"/>
|
||||
<use xlink:href="#p" x="72" y="104"/>
|
||||
<use xlink:href="#p" x="72" y="136"/>
|
||||
<use xlink:href="#p" x="72" y="144"/>
|
||||
<use xlink:href="#p" x="72" y="160"/>
|
||||
<use xlink:href="#p" x="72" y="176"/>
|
||||
<use xlink:href="#p" x="72" y="224"/>
|
||||
<use xlink:href="#p" x="80" y="32"/>
|
||||
<use xlink:href="#p" x="80" y="40"/>
|
||||
<use xlink:href="#p" x="80" y="48"/>
|
||||
<use xlink:href="#p" x="80" y="56"/>
|
||||
<use xlink:href="#p" x="80" y="64"/>
|
||||
<use xlink:href="#p" x="80" y="72"/>
|
||||
<use xlink:href="#p" x="80" y="80"/>
|
||||
<use xlink:href="#p" x="80" y="96"/>
|
||||
<use xlink:href="#p" x="80" y="112"/>
|
||||
<use xlink:href="#p" x="80" y="128"/>
|
||||
<use xlink:href="#p" x="80" y="144"/>
|
||||
<use xlink:href="#p" x="80" y="160"/>
|
||||
<use xlink:href="#p" x="80" y="176"/>
|
||||
<use xlink:href="#p" x="80" y="184"/>
|
||||
<use xlink:href="#p" x="80" y="192"/>
|
||||
<use xlink:href="#p" x="80" y="200"/>
|
||||
<use xlink:href="#p" x="80" y="208"/>
|
||||
<use xlink:href="#p" x="80" y="216"/>
|
||||
<use xlink:href="#p" x="80" y="224"/>
|
||||
<use xlink:href="#p" x="88" y="104"/>
|
||||
<use xlink:href="#p" x="88" y="112"/>
|
||||
<use xlink:href="#p" x="88" y="144"/>
|
||||
<use xlink:href="#p" x="96" y="48"/>
|
||||
<use xlink:href="#p" x="96" y="56"/>
|
||||
<use xlink:href="#p" x="96" y="64"/>
|
||||
<use xlink:href="#p" x="96" y="72"/>
|
||||
<use xlink:href="#p" x="96" y="80"/>
|
||||
<use xlink:href="#p" x="96" y="88"/>
|
||||
<use xlink:href="#p" x="96" y="112"/>
|
||||
<use xlink:href="#p" x="96" y="120"/>
|
||||
<use xlink:href="#p" x="96" y="136"/>
|
||||
<use xlink:href="#p" x="96" y="160"/>
|
||||
<use xlink:href="#p" x="96" y="168"/>
|
||||
<use xlink:href="#p" x="96" y="184"/>
|
||||
<use xlink:href="#p" x="96" y="192"/>
|
||||
<use xlink:href="#p" x="96" y="200"/>
|
||||
<use xlink:href="#p" x="96" y="208"/>
|
||||
<use xlink:href="#p" x="96" y="224"/>
|
||||
<use xlink:href="#p" x="104" y="32"/>
|
||||
<use xlink:href="#p" x="104" y="48"/>
|
||||
<use xlink:href="#p" x="104" y="56"/>
|
||||
<use xlink:href="#p" x="104" y="64"/>
|
||||
<use xlink:href="#p" x="104" y="72"/>
|
||||
<use xlink:href="#p" x="104" y="88"/>
|
||||
<use xlink:href="#p" x="104" y="96"/>
|
||||
<use xlink:href="#p" x="104" y="104"/>
|
||||
<use xlink:href="#p" x="104" y="120"/>
|
||||
<use xlink:href="#p" x="104" y="136"/>
|
||||
<use xlink:href="#p" x="104" y="144"/>
|
||||
<use xlink:href="#p" x="104" y="152"/>
|
||||
<use xlink:href="#p" x="104" y="168"/>
|
||||
<use xlink:href="#p" x="104" y="200"/>
|
||||
<use xlink:href="#p" x="104" y="224"/>
|
||||
<use xlink:href="#p" x="112" y="40"/>
|
||||
<use xlink:href="#p" x="112" y="48"/>
|
||||
<use xlink:href="#p" x="112" y="56"/>
|
||||
<use xlink:href="#p" x="112" y="64"/>
|
||||
<use xlink:href="#p" x="112" y="72"/>
|
||||
<use xlink:href="#p" x="112" y="80"/>
|
||||
<use xlink:href="#p" x="112" y="120"/>
|
||||
<use xlink:href="#p" x="112" y="136"/>
|
||||
<use xlink:href="#p" x="112" y="144"/>
|
||||
<use xlink:href="#p" x="112" y="160"/>
|
||||
<use xlink:href="#p" x="112" y="176"/>
|
||||
<use xlink:href="#p" x="112" y="200"/>
|
||||
<use xlink:href="#p" x="112" y="216"/>
|
||||
<use xlink:href="#p" x="112" y="224"/>
|
||||
<use xlink:href="#p" x="120" y="32"/>
|
||||
<use xlink:href="#p" x="120" y="40"/>
|
||||
<use xlink:href="#p" x="120" y="48"/>
|
||||
<use xlink:href="#p" x="120" y="64"/>
|
||||
<use xlink:href="#p" x="120" y="104"/>
|
||||
<use xlink:href="#p" x="120" y="112"/>
|
||||
<use xlink:href="#p" x="120" y="128"/>
|
||||
<use xlink:href="#p" x="120" y="176"/>
|
||||
<use xlink:href="#p" x="120" y="184"/>
|
||||
<use xlink:href="#p" x="120" y="192"/>
|
||||
<use xlink:href="#p" x="128" y="40"/>
|
||||
<use xlink:href="#p" x="128" y="56"/>
|
||||
<use xlink:href="#p" x="128" y="80"/>
|
||||
<use xlink:href="#p" x="128" y="96"/>
|
||||
<use xlink:href="#p" x="128" y="136"/>
|
||||
<use xlink:href="#p" x="128" y="152"/>
|
||||
<use xlink:href="#p" x="128" y="160"/>
|
||||
<use xlink:href="#p" x="128" y="176"/>
|
||||
<use xlink:href="#p" x="128" y="200"/>
|
||||
<use xlink:href="#p" x="128" y="216"/>
|
||||
<use xlink:href="#p" x="128" y="224"/>
|
||||
<use xlink:href="#p" x="136" y="32"/>
|
||||
<use xlink:href="#p" x="136" y="40"/>
|
||||
<use xlink:href="#p" x="136" y="56"/>
|
||||
<use xlink:href="#p" x="136" y="64"/>
|
||||
<use xlink:href="#p" x="136" y="96"/>
|
||||
<use xlink:href="#p" x="136" y="136"/>
|
||||
<use xlink:href="#p" x="136" y="144"/>
|
||||
<use xlink:href="#p" x="136" y="152"/>
|
||||
<use xlink:href="#p" x="136" y="200"/>
|
||||
<use xlink:href="#p" x="136" y="208"/>
|
||||
<use xlink:href="#p" x="136" y="216"/>
|
||||
<use xlink:href="#p" x="144" y="40"/>
|
||||
<use xlink:href="#p" x="144" y="56"/>
|
||||
<use xlink:href="#p" x="144" y="72"/>
|
||||
<use xlink:href="#p" x="144" y="80"/>
|
||||
<use xlink:href="#p" x="144" y="88"/>
|
||||
<use xlink:href="#p" x="144" y="96"/>
|
||||
<use xlink:href="#p" x="144" y="112"/>
|
||||
<use xlink:href="#p" x="144" y="120"/>
|
||||
<use xlink:href="#p" x="144" y="144"/>
|
||||
<use xlink:href="#p" x="144" y="160"/>
|
||||
<use xlink:href="#p" x="144" y="184"/>
|
||||
<use xlink:href="#p" x="144" y="200"/>
|
||||
<use xlink:href="#p" x="144" y="208"/>
|
||||
<use xlink:href="#p" x="144" y="224"/>
|
||||
<use xlink:href="#p" x="152" y="40"/>
|
||||
<use xlink:href="#p" x="152" y="72"/>
|
||||
<use xlink:href="#p" x="152" y="88"/>
|
||||
<use xlink:href="#p" x="152" y="96"/>
|
||||
<use xlink:href="#p" x="152" y="112"/>
|
||||
<use xlink:href="#p" x="152" y="144"/>
|
||||
<use xlink:href="#p" x="152" y="168"/>
|
||||
<use xlink:href="#p" x="152" y="192"/>
|
||||
<use xlink:href="#p" x="152" y="200"/>
|
||||
<use xlink:href="#p" x="152" y="216"/>
|
||||
<use xlink:href="#p" x="152" y="224"/>
|
||||
<use xlink:href="#p" x="160" y="40"/>
|
||||
<use xlink:href="#p" x="160" y="48"/>
|
||||
<use xlink:href="#p" x="160" y="64"/>
|
||||
<use xlink:href="#p" x="160" y="72"/>
|
||||
<use xlink:href="#p" x="160" y="80"/>
|
||||
<use xlink:href="#p" x="160" y="104"/>
|
||||
<use xlink:href="#p" x="160" y="136"/>
|
||||
<use xlink:href="#p" x="160" y="144"/>
|
||||
<use xlink:href="#p" x="160" y="160"/>
|
||||
<use xlink:href="#p" x="160" y="168"/>
|
||||
<use xlink:href="#p" x="160" y="176"/>
|
||||
<use xlink:href="#p" x="160" y="184"/>
|
||||
<use xlink:href="#p" x="160" y="192"/>
|
||||
<use xlink:href="#p" x="160" y="200"/>
|
||||
<use xlink:href="#p" x="160" y="208"/>
|
||||
<use xlink:href="#p" x="160" y="216"/>
|
||||
<use xlink:href="#p" x="168" y="120"/>
|
||||
<use xlink:href="#p" x="168" y="128"/>
|
||||
<use xlink:href="#p" x="168" y="152"/>
|
||||
<use xlink:href="#p" x="168" y="160"/>
|
||||
<use xlink:href="#p" x="168" y="192"/>
|
||||
<use xlink:href="#p" x="168" y="200"/>
|
||||
<use xlink:href="#p" x="168" y="224"/>
|
||||
<use xlink:href="#p" x="176" y="32"/>
|
||||
<use xlink:href="#p" x="176" y="40"/>
|
||||
<use xlink:href="#p" x="176" y="48"/>
|
||||
<use xlink:href="#p" x="176" y="56"/>
|
||||
<use xlink:href="#p" x="176" y="64"/>
|
||||
<use xlink:href="#p" x="176" y="72"/>
|
||||
<use xlink:href="#p" x="176" y="80"/>
|
||||
<use xlink:href="#p" x="176" y="96"/>
|
||||
<use xlink:href="#p" x="176" y="112"/>
|
||||
<use xlink:href="#p" x="176" y="120"/>
|
||||
<use xlink:href="#p" x="176" y="128"/>
|
||||
<use xlink:href="#p" x="176" y="144"/>
|
||||
<use xlink:href="#p" x="176" y="160"/>
|
||||
<use xlink:href="#p" x="176" y="176"/>
|
||||
<use xlink:href="#p" x="176" y="192"/>
|
||||
<use xlink:href="#p" x="176" y="200"/>
|
||||
<use xlink:href="#p" x="184" y="32"/>
|
||||
<use xlink:href="#p" x="184" y="80"/>
|
||||
<use xlink:href="#p" x="184" y="96"/>
|
||||
<use xlink:href="#p" x="184" y="104"/>
|
||||
<use xlink:href="#p" x="184" y="128"/>
|
||||
<use xlink:href="#p" x="184" y="136"/>
|
||||
<use xlink:href="#p" x="184" y="144"/>
|
||||
<use xlink:href="#p" x="184" y="152"/>
|
||||
<use xlink:href="#p" x="184" y="160"/>
|
||||
<use xlink:href="#p" x="184" y="192"/>
|
||||
<use xlink:href="#p" x="184" y="216"/>
|
||||
<use xlink:href="#p" x="184" y="224"/>
|
||||
<use xlink:href="#p" x="192" y="32"/>
|
||||
<use xlink:href="#p" x="192" y="48"/>
|
||||
<use xlink:href="#p" x="192" y="56"/>
|
||||
<use xlink:href="#p" x="192" y="64"/>
|
||||
<use xlink:href="#p" x="192" y="80"/>
|
||||
<use xlink:href="#p" x="192" y="96"/>
|
||||
<use xlink:href="#p" x="192" y="128"/>
|
||||
<use xlink:href="#p" x="192" y="144"/>
|
||||
<use xlink:href="#p" x="192" y="152"/>
|
||||
<use xlink:href="#p" x="192" y="160"/>
|
||||
<use xlink:href="#p" x="192" y="168"/>
|
||||
<use xlink:href="#p" x="192" y="176"/>
|
||||
<use xlink:href="#p" x="192" y="184"/>
|
||||
<use xlink:href="#p" x="192" y="192"/>
|
||||
<use xlink:href="#p" x="192" y="200"/>
|
||||
<use xlink:href="#p" x="192" y="216"/>
|
||||
<use xlink:href="#p" x="192" y="224"/>
|
||||
<use xlink:href="#p" x="200" y="32"/>
|
||||
<use xlink:href="#p" x="200" y="48"/>
|
||||
<use xlink:href="#p" x="200" y="56"/>
|
||||
<use xlink:href="#p" x="200" y="64"/>
|
||||
<use xlink:href="#p" x="200" y="80"/>
|
||||
<use xlink:href="#p" x="200" y="96"/>
|
||||
<use xlink:href="#p" x="200" y="112"/>
|
||||
<use xlink:href="#p" x="200" y="136"/>
|
||||
<use xlink:href="#p" x="200" y="144"/>
|
||||
<use xlink:href="#p" x="200" y="168"/>
|
||||
<use xlink:href="#p" x="200" y="184"/>
|
||||
<use xlink:href="#p" x="200" y="200"/>
|
||||
<use xlink:href="#p" x="200" y="208"/>
|
||||
<use xlink:href="#p" x="200" y="216"/>
|
||||
<use xlink:href="#p" x="200" y="224"/>
|
||||
<use xlink:href="#p" x="208" y="32"/>
|
||||
<use xlink:href="#p" x="208" y="48"/>
|
||||
<use xlink:href="#p" x="208" y="56"/>
|
||||
<use xlink:href="#p" x="208" y="64"/>
|
||||
<use xlink:href="#p" x="208" y="80"/>
|
||||
<use xlink:href="#p" x="208" y="96"/>
|
||||
<use xlink:href="#p" x="208" y="128"/>
|
||||
<use xlink:href="#p" x="208" y="160"/>
|
||||
<use xlink:href="#p" x="208" y="176"/>
|
||||
<use xlink:href="#p" x="208" y="192"/>
|
||||
<use xlink:href="#p" x="208" y="200"/>
|
||||
<use xlink:href="#p" x="208" y="208"/>
|
||||
<use xlink:href="#p" x="208" y="224"/>
|
||||
<use xlink:href="#p" x="216" y="32"/>
|
||||
<use xlink:href="#p" x="216" y="80"/>
|
||||
<use xlink:href="#p" x="216" y="104"/>
|
||||
<use xlink:href="#p" x="216" y="112"/>
|
||||
<use xlink:href="#p" x="216" y="128"/>
|
||||
<use xlink:href="#p" x="216" y="136"/>
|
||||
<use xlink:href="#p" x="216" y="144"/>
|
||||
<use xlink:href="#p" x="216" y="176"/>
|
||||
<use xlink:href="#p" x="216" y="192"/>
|
||||
<use xlink:href="#p" x="216" y="200"/>
|
||||
<use xlink:href="#p" x="216" y="224"/>
|
||||
<use xlink:href="#p" x="224" y="32"/>
|
||||
<use xlink:href="#p" x="224" y="40"/>
|
||||
<use xlink:href="#p" x="224" y="48"/>
|
||||
<use xlink:href="#p" x="224" y="56"/>
|
||||
<use xlink:href="#p" x="224" y="64"/>
|
||||
<use xlink:href="#p" x="224" y="72"/>
|
||||
<use xlink:href="#p" x="224" y="80"/>
|
||||
<use xlink:href="#p" x="224" y="112"/>
|
||||
<use xlink:href="#p" x="224" y="120"/>
|
||||
<use xlink:href="#p" x="224" y="128"/>
|
||||
<use xlink:href="#p" x="224" y="144"/>
|
||||
<use xlink:href="#p" x="224" y="152"/>
|
||||
<use xlink:href="#p" x="224" y="176"/>
|
||||
<use xlink:href="#p" x="224" y="184"/>
|
||||
<use xlink:href="#p" x="224" y="192"/>
|
||||
<use xlink:href="#p" x="224" y="200"/>
|
||||
<use xlink:href="#p" x="224" y="208"/>
|
||||
<use xlink:href="#p" x="224" y="216"/>
|
||||
<use xlink:href="#p" x="224" y="224"/>
|
||||
</g>
|
||||
<g></g></svg>
|
||||
|
After Width: | Height: | Size: 13 KiB |
30
assets/recycle.svg
Normal file
@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
version="1.1"
|
||||
id="svg1852"
|
||||
width="500"
|
||||
height="500"
|
||||
viewBox="0 0 500 500"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs1856" />
|
||||
<g
|
||||
id="g9426"
|
||||
transform="matrix(0.10916853,0,0,-0.10916853,-59.454168,597.04669)">
|
||||
<path
|
||||
d="m 4125.96,4640.21 c -60.45,105.33 -126.32,210.05 -194.01,325.81 -59.51,101.77 -115.02,247.69 -233.79,288.49 -88.97,30.57 -218.55,24.87 -335.74,24.87 -238.52,0 -471.48,4.96 -708.8,7.46 115.68,-111.3 194.18,-264.61 286.02,-400.41 31.49,-46.59 56.11,-98.61 84.55,-146.74 114.69,-194.18 232.64,-389.07 343.21,-581.96 -95.1,-52.48 -191.01,-104.12 -281.03,-161.66 296.9,17.35 577.91,27.92 877.91,44.77 137.57,245.43 280.22,499.06 410.38,743.62 -82.35,-48.66 -164.78,-97.22 -248.7,-144.25 z m -1248.51,166.64 c -53.07,84.43 -111.38,177.15 -169.12,268.59 -55.7,88.24 -126.21,174.96 -233.78,203.94 -20.3,5.47 -49.31,7.78 -77.09,12.43 -25.3,4.25 -53.65,10.67 -77.1,12.45 -163.65,12.42 -273.55,-67.71 -348.2,-149.23 -34.1,-37.26 -55.41,-86.3 -82.06,-134.3 -127.21,-229.18 -269.64,-477.23 -385.49,-693.89 285.43,-153.11 565.14,-311.94 850.57,-465.07 m 1803.1,902.79 c 154.09,87.98 305.54,178.61 460.1,266.11 -199.68,-359.9 -396.33,-722.85 -599.39,-1079.37 -433.28,-21.84 -870.82,-42.72 -1308.18,-64.66 -2.27,5.2 13.74,13.73 24.88,19.9 165.99,92.14 340.08,192.34 504.87,286.02 -101.8,173.43 -204.22,346.23 -305.9,519.77 -184.74,-321.8 -361.72,-651.32 -544.66,-974.91 -338.03,183.44 -673.86,369.03 -1009.74,554.62 114.18,211.08 229.87,419.32 353.15,639.16 59.08,105.34 109.28,220.43 189.02,305.9 77.4,82.98 199.37,151.4 345.7,159.17 52.84,2.81 104.95,-13.21 156.69,-17.41 94.81,-7.68 197.91,-2.48 295.94,-2.48 245.41,0 492.06,-7.47 738.66,-7.47 100.19,0 187.99,-2.45 261.14,-24.87 126.97,-38.91 189.11,-153.41 251.19,-258.64 64.97,-110.17 124.97,-214.57 186.53,-320.84"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
id="path9858" />
|
||||
<path
|
||||
d="m 4640.77,2469.03 c -184.34,-12.36 -393.76,2.49 -601.88,2.49 -207.08,0 -414.32,2.29 -601.85,7.47 1.22,98.66 9.77,219.19 4.96,323.31 -136.6,-262.16 -280.27,-517.25 -417.81,-778.46 143.98,-242.29 281.8,-490.82 425.27,-733.67 4.53,99.18 0.77,195.09 7.47,288.5 95.04,-1.2 198.28,-4.97 300.92,-4.97 105.41,0 212.31,-10.51 303.43,-2.5 146.62,12.92 202.16,117.08 263.63,213.9 148.23,233.45 303.64,481.76 450.14,708.8 -0.99,4.29 3.69,6.38 0,7.45 -40.63,-16.78 -87.23,-29.16 -134.28,-32.32 z m -932.64,1029.64 c 165.79,-293.25 333.99,-588.18 504.86,-880.41 11.88,-20.34 25.18,-52.99 37.31,-57.2 21.31,-7.42 70.62,0 99.47,0 98.19,0 222.77,-8.87 295.96,0 111.22,13.45 204.78,78.03 263.64,144.25 87.85,98.84 152.41,266.37 104.43,435.23 -13.84,48.76 -35.98,84.65 -59.69,126.83 -135.64,241.53 -272.96,480.57 -407.84,711.29 -275.88,-153.55 -557.25,-323.17 -838.14,-479.99 z m 870.46,606.84 c 2.01,-0.48 2.46,-2.5 4.96,-2.49 123.6,-214.99 242.66,-429.99 368.1,-646.64 78.16,-135.04 186.73,-261.92 171.61,-487.45 -11.1,-165.26 -114.82,-275.77 -186.53,-390.47 -174.63,-279.29 -344.05,-546.98 -519.82,-825.68 -77.96,-123.69 -147.75,-232.92 -310.85,-266.12 -54.08,-11.02 -113.29,-8.09 -181.57,-4.99 -123.95,5.65 -259.75,-1.14 -380.51,2.5 -0.74,-175.84 -6.02,-347.16 -7.46,-522.291 -5.89,-3.617 -13.59,14.101 -19.89,24.871 -199.27,339.78 -396.99,696.46 -596.9,1037.09 206.96,387.43 418.13,770.71 624.25,1158.98 -0.3,-190.38 -9.75,-412.48 -12.45,-616.8 202.92,1.47 398.55,-4.36 601.89,-2.49 -173.7,322.08 -370.65,642.4 -549.64,967.46 331.45,191.65 663.62,382.6 994.81,574.52"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
id="path9860" />
|
||||
<path
|
||||
d="m 1447.4,2270.08 c -46.21,-78.85 -95.63,-159.69 -94.49,-266.13 1.81,-172.7 95.5,-317.04 198.96,-387.96 82.01,-56.24 184.38,-79.6 318.33,-79.6 256.45,0.02 521.31,-2.09 793.36,2.49 -2.81,321.34 -2.82,645.47 -2.48,969.94 -357.31,0 -714.62,0 -1071.91,0 -47.61,-73.71 -91.59,-153.18 -141.77,-238.74 z m -325.8,1410.14 c -76.5,-133.74 -157.479,-262.83 -233.784,-392.96 -25.332,-43.2 -57.761,-87.1 -77.086,-131.8 -50.343,-116.47 -0.851,-226.72 42.266,-308.41 137.602,-260.55 278.474,-523.3 415.334,-773.46 13.71,124.29 86.65,215.53 141.77,310.88 167.68,290.08 327.8,575.06 499.9,863.01 93.53,-52.38 186.41,-118.66 278.54,-164.15 -135.06,216.08 -272.93,436.74 -407.88,656.57 -15.15,24.7 -42.29,85.59 -62.17,92.03 -21.62,7 -67.46,0 -104.45,0 -238.34,0 -531.63,-0.02 -738.649,0 77.593,-55.05 167.129,-98.16 246.209,-151.71 z m 1345.48,-872.95 c -173.7,95.71 -348.89,211.51 -524.76,313.37 -102.26,-172.15 -203.97,-344.85 -300.92,-522.28 368.91,0 751.06,0 1111.7,0 0,-384.68 0,-769.32 0,-1153.98 -322.47,0 -602.15,0 -907.77,0 -293.56,0 -455.02,139.48 -544.66,360.61 -40.87,100.82 -101.41,198.5 -154.19,298.46 -130.44,246.98 -258.828,486.89 -392.964,738.64 -37.481,70.34 -61.715,131.77 -54.711,236.27 8.261,123.16 82.304,205.41 136.781,295.95 58.137,96.62 107.676,189.42 161.66,271.09 -145.043,96.19 -312.867,182.88 -452.637,276.05 300.981,0 606.771,0 910.261,0 103.02,0 204.66,-5.91 303.42,0 7.03,0.44 5.98,1.86 9.95,2.5 8.82,1.41 34.47,-41.84 47.24,-62.18 218.06,-347.29 435.03,-714.78 651.6,-1054.5"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
id="path9862" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.3 KiB |
3
pack.yml
@ -1,6 +1,7 @@
|
||||
---
|
||||
host: "192.168.0.220"
|
||||
host: "127.0.0.1"
|
||||
port: "3000"
|
||||
domain: "http://127.0.0.1:3000/"
|
||||
db_path: "data.db"
|
||||
log_path: "logs"
|
||||
upload_path: "upload"
|
||||
|
||||
10
pack.yml.template
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
host: "127.0.0.1"
|
||||
port: "3000"
|
||||
domain:
|
||||
db_path: "data.db"
|
||||
log_path: "logs"
|
||||
upload_path: "upload"
|
||||
gitea_host:
|
||||
client_id:
|
||||
client_secret:
|
||||
59
src/api.rs
@ -1,4 +1,4 @@
|
||||
use std::{fs, path, slice::Iter};
|
||||
use std::{fs, fmt, path, slice::Iter};
|
||||
use bytes::Bytes;
|
||||
use std::process::Command;
|
||||
use rand::distr::{Alphanumeric, SampleString};
|
||||
@ -17,9 +17,9 @@ use serde_json::Value;
|
||||
|
||||
use crate::{query, ServerState};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[repr(u8)]
|
||||
enum RepoFeature {
|
||||
pub enum RepoFeature {
|
||||
Docs = 0,
|
||||
Builds = 1,
|
||||
Nightly = 2,
|
||||
@ -35,6 +35,32 @@ impl RepoFeature {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for RepoFeature {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::Debug::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RepoFeature> for String {
|
||||
fn from(value: RepoFeature) -> Self {
|
||||
value.to_string().to_lowercase()
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for RepoFeature {
|
||||
type Error = APIError;
|
||||
|
||||
fn try_from(value: &str) -> Result<Self> {
|
||||
for feature in RepoFeature::iter() {
|
||||
if feature.to_string().to_lowercase() == value.to_lowercase() {
|
||||
return Ok(*feature);
|
||||
}
|
||||
}
|
||||
Err(APIError::InvalidFeature { feature: value.to_owned() })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum APIError {
|
||||
#[error("Request error: {0}")]
|
||||
@ -105,37 +131,12 @@ impl IntoResponse for APIError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RepoFeature> for &str {
|
||||
fn from(value: RepoFeature) -> Self {
|
||||
match value {
|
||||
RepoFeature::Docs => "docs",
|
||||
RepoFeature::Builds => "builds",
|
||||
RepoFeature::Nightly => "nightly",
|
||||
RepoFeature::PreProd => "preprod",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for RepoFeature {
|
||||
type Error = APIError;
|
||||
|
||||
fn try_from(value: &str) -> Result<Self> {
|
||||
match value.to_lowercase().as_str() {
|
||||
"docs" => Ok(RepoFeature::Docs),
|
||||
"builds" => Ok(RepoFeature::Builds),
|
||||
"nightly" => Ok(RepoFeature::Nightly),
|
||||
"preprod" => Ok(RepoFeature::PreProd),
|
||||
other => Err(APIError::InvalidFeature { feature: other.to_owned() }),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn as_feature_list(value: u64) -> FeatureList {
|
||||
let mut v: Vec<String> = Vec::new();
|
||||
for feature in RepoFeature::iter() {
|
||||
let feat_num = 1 << (*feature as u64);
|
||||
if (value & feat_num) == feat_num {
|
||||
v.push(Into::<&str>::into(*feature).to_owned());
|
||||
v.push(Into::<String>::into(*feature).to_owned());
|
||||
}
|
||||
}
|
||||
v
|
||||
|
||||
104
src/compile.rs
Normal file
@ -0,0 +1,104 @@
|
||||
use anyhow::{Context, Result};
|
||||
use askama::Template;
|
||||
use std::{fs, io, path::Path};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct WebStates<'a> {
|
||||
auth: &'a str,
|
||||
error: &'a str,
|
||||
loading: &'a str,
|
||||
repo_selected: &'a str,
|
||||
repo_created: &'a str,
|
||||
button_on: &'a str,
|
||||
feature_on: &'a str,
|
||||
confirm_on: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(
|
||||
ext = "html",
|
||||
path = "html/contentDefault.html",
|
||||
whitespace = "suppress"
|
||||
)]
|
||||
struct Default<'a> {
|
||||
config: crate::ServerConfig,
|
||||
features: Vec<String>,
|
||||
content_text: String,
|
||||
state: WebStates<'a>,
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(ext = "html", path = "html/base.html", whitespace = "suppress")]
|
||||
struct NotFound {
|
||||
config: crate::ServerConfig,
|
||||
content_text: String,
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "index.css", escape = "txt", whitespace = "suppress")]
|
||||
struct Css<'a> {
|
||||
state: WebStates<'a>,
|
||||
}
|
||||
|
||||
pub fn make_templates(config: &crate::ServerConfig) -> Result<()> {
|
||||
let states = WebStates {
|
||||
auth: "auth",
|
||||
error: "error",
|
||||
loading: "loading",
|
||||
repo_selected: "repoSelected",
|
||||
repo_created: "repoCreated",
|
||||
button_on: "enabled",
|
||||
feature_on: "fEnabled",
|
||||
confirm_on: "enabled",
|
||||
};
|
||||
|
||||
let default = Default {
|
||||
config: config.clone(),
|
||||
features: crate::api::RepoFeature::iter()
|
||||
.map(|f| f.to_string())
|
||||
.collect(),
|
||||
content_text: "awaiting authorization...".to_owned(),
|
||||
state: states,
|
||||
}
|
||||
.render()
|
||||
.context("Unable to process 'Default' template")?;
|
||||
|
||||
fs::write("static/index.html", default).context("Could not write to static/index.html")?;
|
||||
|
||||
let not_found = NotFound {
|
||||
config: config.clone(),
|
||||
content_text: "404: not found...".to_owned(),
|
||||
}
|
||||
.render()
|
||||
.context("Unable to process 'NotFound' template.")?;
|
||||
|
||||
fs::write("static/404.html", not_found).context("Could not write to static/404.html")?;
|
||||
|
||||
let css = Css { state: states }
|
||||
.render()
|
||||
.context("Unable to process 'CSS' template.")?;
|
||||
|
||||
fs::write("static/index.css", css).context("Could not write to static/index.css")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> {
|
||||
fs::create_dir_all(&dst)?;
|
||||
for entry in fs::read_dir(src)? {
|
||||
let entry = entry?;
|
||||
let ty = entry.file_type()?;
|
||||
if ty.is_dir() {
|
||||
copy_dir_all(entry.path(), dst.as_ref().join(entry.file_name()))?;
|
||||
} else {
|
||||
fs::copy(entry.path(), dst.as_ref().join(entry.file_name()))?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn copy_assets() -> Result<()> {
|
||||
fs::create_dir("static").context("Could not create directory 'static'.")?;
|
||||
copy_dir_all("assets", "static").context("Could not copy 'assets' into 'static'.")?;
|
||||
Ok(())
|
||||
}
|
||||
@ -24,6 +24,7 @@ use tracing_appender::rolling;
|
||||
use serde::Deserialize;
|
||||
|
||||
mod api;
|
||||
mod compile;
|
||||
mod util;
|
||||
|
||||
type SQLConn = sqlite::ConnectionThreadSafe;
|
||||
@ -34,6 +35,7 @@ type SQLConn = sqlite::ConnectionThreadSafe;
|
||||
struct ServerConfig {
|
||||
host: String,
|
||||
port: String,
|
||||
domain: String,
|
||||
db_path: String,
|
||||
log_path: String,
|
||||
upload_path: String,
|
||||
@ -81,9 +83,12 @@ async fn main() -> Result<()> {
|
||||
.context(format!("Failed to setup SQLite database at '{}'.", &config.db_path))?;
|
||||
|
||||
// Make file upload folder.
|
||||
fs::create_dir_all(&config.upload_path)?;
|
||||
fs::create_dir_all(&config.upload_path)
|
||||
.context(format!("Unable to make directory at '{}'.", &config.upload_path))?;
|
||||
let log_file = rolling::daily(&config.log_path, "");
|
||||
let upload_path = config.upload_path.clone();
|
||||
compile::copy_assets()?;
|
||||
compile::make_templates(&config)?;
|
||||
|
||||
let sql: &'static sqlite::ConnectionThreadSafe = Box::leak(Box::new(sql));
|
||||
let server_state = ServerState { config, sql };
|
||||
@ -118,10 +123,8 @@ async fn main() -> Result<()> {
|
||||
method = format!("{}", request.method()),
|
||||
version = format!("{:?}", request.version()),
|
||||
remote_ip = addr,
|
||||
|
||||
)
|
||||
});
|
||||
|
||||
|
||||
// Build routes
|
||||
let api_routes = Router::new()
|
||||
|
||||
272
static/404.html
Normal file
@ -0,0 +1,272 @@
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
||||
<title>Pack</title>
|
||||
<link rel="icon" href="assets/favicon.ico?v=2">
|
||||
<link rel="stylesheet" href="assets/index.css">
|
||||
<link href="https://fonts.googleapis.com/css?family=Quicksand:300,400" rel="stylesheet">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
|
||||
</head>
|
||||
<body>
|
||||
<div id="themeSwitchContainer">
|
||||
<input type="checkbox" id="themeSwitch">
|
||||
<span></span><span></span><span></span>
|
||||
</div>
|
||||
<div id="package">
|
||||
<img src="assets/fragile.svg">
|
||||
<img src="assets/keep_dry.svg">
|
||||
<img src="assets/recycle.svg">
|
||||
<img src="assets/qr_code.svg">
|
||||
</div><svg id="packageTape" viewbox="0 0 100 10">
|
||||
<rect width="100" height="0.3" x="0" y="4.85" style="fill:#483320;fill-opacity:0.8" />
|
||||
<rect width="100" height="10" x="0" y="0" style="fill:#111;fill-opacity:0.8" />
|
||||
|
||||
<polygon points="21,0.0 20,0.625 21,1.25 20,1.875 21,2.5 20,3.125 21,3.75 20,4.375 21,5.0 20,5.625 21,6.25 20,6.875 21,7.5 20,8.125 21,8.75 20,9.375 21,10.0 100,10 100,0" style="fill:#111;fill-opacity:0.5"/>
|
||||
<text>
|
||||
<textPath href="#packTape0">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape1">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape2">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape3">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape4">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape5">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape6">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape7">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape8">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape9">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape10">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape11">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape12">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape13">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape14">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape15">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape16">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape17">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape18">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape19">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape20">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape21">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape22">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape23">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape24">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape25">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape26">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape27">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape28">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape29">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape30">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape31">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape32">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape33">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape34">PACK.PACK.PACK.PACK.</textPath>
|
||||
</text>
|
||||
<path id="packTape0" fill="none" stroke="none" d="M-3.00 -0.00 l6 20"/>
|
||||
<path id="packTape1" fill="none" stroke="none" d="M-0.60 -2.00 l6 20"/>
|
||||
<path id="packTape2" fill="none" stroke="none" d="M1.80 -4.00 l6 20"/>
|
||||
<path id="packTape3" fill="none" stroke="none" d="M6.00 -0.00 l6 20"/>
|
||||
<path id="packTape4" fill="none" stroke="none" d="M8.40 -2.00 l6 20"/>
|
||||
<path id="packTape5" fill="none" stroke="none" d="M10.80 -4.00 l6 20"/>
|
||||
<path id="packTape6" fill="none" stroke="none" d="M15.00 -0.00 l6 20"/>
|
||||
<path id="packTape7" fill="none" stroke="none" d="M17.40 -2.00 l6 20"/>
|
||||
<path id="packTape8" fill="none" stroke="none" d="M19.80 -4.00 l6 20"/>
|
||||
<path id="packTape9" fill="none" stroke="none" d="M24.00 -0.00 l6 20"/>
|
||||
<path id="packTape10" fill="none" stroke="none" d="M26.40 -2.00 l6 20"/>
|
||||
<path id="packTape11" fill="none" stroke="none" d="M28.80 -4.00 l6 20"/>
|
||||
<path id="packTape12" fill="none" stroke="none" d="M33.00 -0.00 l6 20"/>
|
||||
<path id="packTape13" fill="none" stroke="none" d="M35.40 -2.00 l6 20"/>
|
||||
<path id="packTape14" fill="none" stroke="none" d="M37.80 -4.00 l6 20"/>
|
||||
<path id="packTape15" fill="none" stroke="none" d="M42.00 -0.00 l6 20"/>
|
||||
<path id="packTape16" fill="none" stroke="none" d="M44.40 -2.00 l6 20"/>
|
||||
<path id="packTape17" fill="none" stroke="none" d="M46.80 -4.00 l6 20"/>
|
||||
<path id="packTape18" fill="none" stroke="none" d="M51.00 -0.00 l6 20"/>
|
||||
<path id="packTape19" fill="none" stroke="none" d="M53.40 -2.00 l6 20"/>
|
||||
<path id="packTape20" fill="none" stroke="none" d="M55.80 -4.00 l6 20"/>
|
||||
<path id="packTape21" fill="none" stroke="none" d="M60.00 -0.00 l6 20"/>
|
||||
<path id="packTape22" fill="none" stroke="none" d="M62.40 -2.00 l6 20"/>
|
||||
<path id="packTape23" fill="none" stroke="none" d="M64.80 -4.00 l6 20"/>
|
||||
<path id="packTape24" fill="none" stroke="none" d="M69.00 -0.00 l6 20"/>
|
||||
<path id="packTape25" fill="none" stroke="none" d="M71.40 -2.00 l6 20"/>
|
||||
<path id="packTape26" fill="none" stroke="none" d="M73.80 -4.00 l6 20"/>
|
||||
<path id="packTape27" fill="none" stroke="none" d="M78.00 -0.00 l6 20"/>
|
||||
<path id="packTape28" fill="none" stroke="none" d="M80.40 -2.00 l6 20"/>
|
||||
<path id="packTape29" fill="none" stroke="none" d="M82.80 -4.00 l6 20"/>
|
||||
<path id="packTape30" fill="none" stroke="none" d="M87.00 -0.00 l6 20"/>
|
||||
<path id="packTape31" fill="none" stroke="none" d="M89.40 -2.00 l6 20"/>
|
||||
<path id="packTape32" fill="none" stroke="none" d="M91.80 -4.00 l6 20"/>
|
||||
<path id="packTape33" fill="none" stroke="none" d="M96.00 -0.00 l6 20"/>
|
||||
<path id="packTape34" fill="none" stroke="none" d="M98.40 -2.00 l6 20"/>
|
||||
</svg><div id="packageLabel">
|
||||
<div id="packageLabelTop"><div>
|
||||
<svg width="48" height="48" viewBox="0 0 12.7 12.7" version="1.1">
|
||||
<defs id="defs2" />
|
||||
<path d="m 12.323869,4.1992062 -6.2301843,2.5959093 -1e-7,0.095169 6.3500004,-2.6458336 z" />
|
||||
<path d="M 12.443685,4.2444508 V 4.3735617 L 9.2686845,4.925839 V 4.7967281 Z" />
|
||||
<path d="M 6.0936845,1.6003079 12.443177,4.2450847 9.2686845,4.796728 2.9191918,2.1519511 Z" />
|
||||
<path d="m 9.2686845,3.8880996 0.062387,0.1201924 -3.237387,3.0585598 2e-7,-0.17699 z" />
|
||||
<path d="M 9.2686845,4.7967281 V 4.925839 L 8.6378103,4.6632589 8.7123025,4.564976 Z" />
|
||||
<rect width="6.8791666" height="5.8977885" x="-13.480659" y="9.4293194" transform="matrix(-0.92307692,0.3846154,0,1,0,0)" />
|
||||
<rect width="6.8791666" height="5.8977885" x="-0.27767482" y="4.3512492" transform="matrix(0.92307692,0.3846154,0,1,0,0)" />
|
||||
<path d="M 2.9186843,1.2431113 9.2686845,3.8880996 6.0936849,6.8898618 -0.2563155,4.2448735 Z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<p><b>BYTE TRANSIT FEES PAID</b></p>
|
||||
<p>64 OF 64</p>
|
||||
<p>6.28 TB FIBRE OPTIC EXPRESS RATE</p>
|
||||
<p>ACCEPTS TAR.GZ, ZIP</p>
|
||||
</div>
|
||||
<div>
|
||||
<svg width="618" height="124" viewBox="0 0 618 124" version="1.1">
|
||||
<path d="M 2.1999999e-6,0 H 41.200002 V 123.6 H 2.1999999e-6 Z M 46.350002,0 h 5.15 v 123.6 h -5.15 z m 10.3,0 h 5.15 v 123.6 h -5.15 z m 10.3,0 h 5.15 v 123.6 h -5.15 z m 20.6,0 H 113.3 v 15.45 h 5.15 V 30.9 h -5.15 v 15.45 h -5.15 V 30.9 H 103 V 46.35 H 97.850002 V 30.9 h -5.15 v 15.45 h 5.15 V 61.8 H 103 v 15.450002 h 5.15 V 61.8 h 5.15 v 61.8 H 87.550002 Z M 118.45,0 h 5.15 v 15.45 h -5.15 z m 10.3,0 h 5.15 v 15.45 h -5.15 z m 10.3,0 h 25.75 v 15.45 h 5.15 V 30.9 H 154.5 V 15.45 h -15.45 z m 36.05,0 h 15.45 v 30.9 h -5.15 v 30.9 h 5.15 v 15.450002 h -5.15 v 15.45 h -5.15 V 108.15 h 10.3 V 123.6 H 175.1 Z m 20.6,0 h 5.15 V 15.45 H 195.7 Z M 206,0 h 10.3 v 15.45 h -5.15 V 30.9 h 5.15 V 15.45 h 10.3 V 30.9 h -5.15 v 15.45 h 5.15 V 61.8 h 5.15 v 15.450002 h -5.15 v 15.45 h 5.15 V 108.15 H 226.6 V 123.6 H 216.3 V 92.700002 H 206 V 123.6 h -5.15 V 108.15 H 195.7 V 92.700002 h 5.15 v -15.45 H 206 V 61.8 h 5.15 v 15.450002 h 10.3 V 61.8 H 216.3 V 46.35 H 206 V 61.8 H 190.55 V 46.35 h 5.15 V 30.9 H 206 Z m 20.6,0 h 20.6 v 46.35 h -5.15 V 15.45 H 226.6 Z m 36.05,0 h 10.3 v 30.9 h -5.15 v 15.45 h 5.15 v 30.900002 h -5.15 v 15.45 h 10.3 V 108.15 h 5.15 v 15.45 h -10.3 v -15.45 h -5.15 v 15.45 h -5.15 z m 30.9,0 h 10.3 V 30.9 H 309 V 0 h 5.15 v 30.9 h 5.15 v 15.45 h -5.15 V 61.8 h 5.15 v 15.450002 h 5.15 v 15.45 h -10.3 v -15.45 h -10.3 v 15.45 H 298.7 V 108.15 H 288.4 V 77.250002 h 10.3 V 61.8 h 5.15 V 46.35 H 298.7 V 30.9 h -10.3 v 30.9 h -5.15 V 15.45 h 10.3 z m 25.75,0 h 5.15 v 15.45 h 20.6 V 30.9 H 319.3 Z m 30.9,0 h 5.15 v 15.45 h 5.15 V 0 h 15.45 v 15.45 h -10.3 V 30.9 h -10.3 v 15.45 h 5.15 v 46.350002 h 5.15 V 108.15 h 5.15 v 15.45 h -20.6 z m 46.35,0 H 412 v 15.45 h 5.15 v 30.9 H 412 V 61.8 h 5.15 v 15.450002 h 5.15 V 61.8 h 10.3 v 15.450002 h -5.15 v 15.45 h -20.6 v -15.45 h -10.3 V 61.8 h 10.3 V 46.35 h -10.3 V 30.9 h 5.15 V 15.45 h -5.15 z m 20.6,0 h 5.15 v 15.45 h -5.15 z m 20.6,0 h 25.75 v 15.45 h -5.15 V 30.9 h -5.15 v 15.45 h -5.15 V 61.8 h 5.15 V 46.35 h 5.15 V 77.250002 H 453.2 V 123.6 h -5.15 v -15.45 h -5.15 v 15.45 h -5.15 z m 30.9,0 h 5.15 v 15.45 h -5.15 z m 10.3,0 h 5.15 v 15.45 h -5.15 z m 10.3,0 H 515 V 15.45 H 494.4 V 30.9 h 25.75 V 61.8 H 515 v 15.450002 h -10.3 v 15.45 h 15.45 V 108.15 h -10.3 V 123.6 H 494.4 V 92.700002 h 5.15 V 61.8 H 494.4 V 46.35 h -5.15 z m 36.05,0 h 36.05 V 123.6 H 525.3 Z m 41.2,0 h 5.15 v 123.6 h -5.15 z m 20.6,0 h 5.15 v 123.6 h -5.15 z m 10.3,0 h 5.15 v 123.6 h -5.15 z m 15.45,0 H 618 v 123.6 h -5.15 z M 123.6,15.45 h 5.15 V 30.9 h 5.15 V 15.45 h 5.15 V 30.9 h 5.15 v 15.45 h -10.3 v 30.900002 h 15.45 v 15.45 h 5.15 V 61.8 H 144.2 V 46.35 h 25.75 V 61.8 h -5.15 v 30.900002 h 5.15 V 108.15 H 154.5 V 123.6 H 144.2 V 92.700002 h -5.15 V 123.6 H 133.9 V 108.15 H 123.6 V 92.700002 h 5.15 v -15.45 h -5.15 v 15.45 h -5.15 V 61.8 H 113.3 V 46.35 h 10.3 z m 257.5,0 h 5.15 V 30.9 h -5.15 z m 41.2,0 h 10.3 V 30.9 h -10.3 z m 41.2,0 h 5.15 V 30.9 h -5.15 z m 10.3,0 h 5.15 V 30.9 H 473.8 Z M 231.75,30.9 h 5.15 v 15.45 h -5.15 z m 41.2,0 h 5.15 v 15.45 h -5.15 z m 97.85,0 h 5.15 v 15.45 h 5.15 v 30.900002 h -5.15 V 61.8 h -5.15 z m 15.45,0 h 5.15 v 15.45 h -5.15 z m 72.1,0 h 5.15 v 15.45 h -5.15 z m 10.3,0 h 5.15 v 15.45 h 10.3 V 61.8 h 5.15 v 15.450002 h 5.15 v 15.45 h -5.15 V 123.6 h -30.9 V 77.250002 h 5.15 V 108.15 h 10.3 V 92.700002 h -5.15 v -15.45 h 5.15 V 61.8 h -5.15 V 77.250002 H 463.5 V 46.35 h 5.15 z M 103,46.35 h 5.15 V 61.8 H 103 Z m 149.35,0 h 5.15 v 77.25 h -5.15 V 108.15 H 247.2 V 92.700002 h 5.15 z m 77.25,0 h 15.45 V 61.8 h -10.3 v 15.450002 h 10.3 v 15.45 H 339.9 V 108.15 H 329.6 V 123.6 H 303.85 V 92.700002 h 10.3 V 108.15 h 10.3 V 92.700002 h 5.15 v -15.45 h -5.15 V 61.8 h 5.15 z m 61.8,0 h 5.15 V 61.8 H 391.4 Z M 278.1,61.8 h 5.15 v 15.450002 h -5.15 z m -41.2,15.450002 h 5.15 v 15.45 h -5.15 z m 128.75,0 h 10.3 v 15.45 h 5.15 v -15.45 h 5.15 v 15.45 h 5.15 V 108.15 h -5.15 v 15.45 h -10.3 V 108.15 H 370.8 V 92.700002 h -5.15 z M 103,92.700002 V 108.15 h 5.15 V 92.700002 Z m 293.55,0 h 10.3 V 108.15 h -10.3 z m 30.9,0 h 5.15 V 123.6 h -5.15 z M 118.45,108.15 h 5.15 v 15.45 h -5.15 z m 221.45,0 h 5.15 v 15.45 h -5.15 z m 66.95,0 h 10.3 v 15.45 h -10.3 z" fill-rule="evenodd" style="stroke-width:0.858333" />
|
||||
</svg>
|
||||
<h1 id="login"></h1>
|
||||
</div>
|
||||
</div></div>
|
||||
<div id="packageLabelTitle">
|
||||
<h1><b></b></h1>
|
||||
</div>
|
||||
<div id="packageLabelContent">
|
||||
<h1>404: NOT FOUND...</h1></div>
|
||||
<div id="packageLabelBot"><svg width="1596" height="432" viewBox="0 0 1596 432" version="1.1">
|
||||
<path d="M 0,432 H 12 V 0 H 0 Z" />
|
||||
<path d="m 18,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 36,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 66,432 h 6 V 0 h -6 z" />
|
||||
<path d="M 84,432 H 96 V 0 H 84 Z" />
|
||||
<path d="m 120,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 132,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 150,432 h 24 V 0 h -24 z" />
|
||||
<path d="m 180,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 198,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 216,432 h 24 V 0 h -24 z" />
|
||||
<path d="m 246,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 264,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 276,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 294,432 h 24 V 0 h -24 z" />
|
||||
<path d="m 330,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 342,432 h 24 V 0 h -24 z" />
|
||||
<path d="m 378,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 396,432 h 18 V 0 h -18 z" />
|
||||
<path d="m 426,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 444,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 462,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 474,432 h 18 V 0 h -18 z" />
|
||||
<path d="m 504,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 528,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 540,432 h 18 V 0 h -18 z" />
|
||||
<path d="m 570,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 594,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 606,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 624,432 h 24 V 0 h -24 z" />
|
||||
<path d="m 660,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 678,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 690,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 726,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 756,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 768,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 792,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 828,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 846,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 858,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 876,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 900,432 h 18 V 0 h -18 z" />
|
||||
<path d="m 924,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 960,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 978,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 990,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1020,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 1044,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1056,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1074,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1086,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 1122,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1146,432 h 24 V 0 h -24 z" />
|
||||
<path d="m 1176,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1188,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1206,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 1230,432 h 18 V 0 h -18 z" />
|
||||
<path d="m 1254,432 h 24 V 0 h -24 z" />
|
||||
<path d="m 1284,432 h 18 V 0 h -18 z" />
|
||||
<path d="m 1308,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1320,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1332,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 1356,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1386,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1398,432 h 18 V 0 h -18 z" />
|
||||
<path d="m 1428,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 1452,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1470,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1488,432 h 24 V 0 h -24 z" />
|
||||
<path d="m 1518,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 1548,432 h 18 V 0 h -18 z" />
|
||||
<path d="m 1572,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1584,432 h 12 V 0 h -12 z" />
|
||||
</svg><a href="/">http://127.0.0.1:3000/</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script>const CONFIG = {
|
||||
client_id: "3d463405-d098-4038-8b25-a44ca5b9ab9c",
|
||||
redirect_uri: "http://127.0.0.1:3000/",
|
||||
authorization_endpoint: "https://git.kjao.me/login/oauth/authorize",
|
||||
token_endpoint: "https://git.kjao.me/login/oauth/access_token",
|
||||
requested_scopes: "read:repository,write:repository"
|
||||
};
|
||||
|
||||
var G_AUTH = window.localStorage.getItem("token") !== null;
|
||||
|
||||
document.on = document.addEventListener;
|
||||
function sugar(obj) {
|
||||
obj.on = obj.addEventListener;
|
||||
obj.addClass = (x) => obj.classList.add(x);
|
||||
obj.delClass = (x) => obj.classList.remove(x);
|
||||
obj.hasClass = (x) => obj.classList.contains(x);
|
||||
obj.setClass = (x, y) => obj.classList.toggle(x, y);
|
||||
return obj;
|
||||
}
|
||||
|
||||
function get(s) {
|
||||
let x = [...document.querySelectorAll(s)].map(sugar);
|
||||
return (x.length === 1) ? x[0] : x;
|
||||
}
|
||||
|
||||
// Check if object is empty.
|
||||
function isEmpty(obj) {
|
||||
for (const prop in obj) {
|
||||
if (Object.hasOwn(obj, prop)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns error and resolves promise if necessary.
|
||||
function getErr(f) {
|
||||
return (err) => {
|
||||
if (err instanceof Promise) {
|
||||
return err.then(f);
|
||||
} else {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get("#login").on("click", async (e) => {
|
||||
e.preventDefault();
|
||||
if (G_AUTH) {
|
||||
window.localStorage.clear();
|
||||
window.location = "/";
|
||||
} else {
|
||||
// Build the authorization URL
|
||||
let url = CONFIG.authorization_endpoint
|
||||
+ "?response_type=code"
|
||||
+ "&client_id="+encodeURIComponent(CONFIG.client_id)
|
||||
+ "&scope="+encodeURIComponent(CONFIG.requested_scopes)
|
||||
+ "&redirect_uri="+encodeURIComponent(CONFIG.redirect_uri);
|
||||
|
||||
// Redirect to the authorization server
|
||||
window.location = url;
|
||||
}
|
||||
});</script>
|
||||
</html>
|
||||
@ -438,7 +438,7 @@ body {
|
||||
font-family: 'Courier';
|
||||
}
|
||||
|
||||
input.error {
|
||||
input.error{
|
||||
outline: 2px solid red !important;
|
||||
}
|
||||
|
||||
@ -454,7 +454,7 @@ body {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
input[type=submit].enabled {
|
||||
input[type=submit].enabled{
|
||||
color: var(--c-text);
|
||||
border-style: solid;
|
||||
pointer-events: auto;
|
||||
@ -468,7 +468,7 @@ body {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
input[type=submit].loading {
|
||||
input[type=submit].loading{
|
||||
border: 1px solid transparent;
|
||||
background: linear-gradient(var(--c-label), var(--c-label)) padding-box, conic-gradient(
|
||||
from var(--angle),
|
||||
@ -537,19 +537,6 @@ body {
|
||||
font-weight: 800;
|
||||
pointer-events: auto;
|
||||
}
|
||||
/* .feature { */
|
||||
/* border: 1px solid var(--c-lines); */
|
||||
/* padding: 2%; */
|
||||
/* margin-right: 2%; */
|
||||
/* font-size: 150%; */
|
||||
/* cursor: pointer; */
|
||||
/* user-select: none; */
|
||||
/* transition: background-color 0.15s ease-in-out; */
|
||||
/* } */
|
||||
|
||||
/* .feature:hover { */
|
||||
/* background-color: var(--c-login-hover); */
|
||||
/* } */
|
||||
|
||||
/* Feature states. */
|
||||
.feature {
|
||||
@ -557,7 +544,7 @@ body {
|
||||
border-style: dashed;
|
||||
}
|
||||
|
||||
.feature.fEnabled {
|
||||
.feature.fEnabled{
|
||||
color: var(--c-text);
|
||||
border-style: solid;
|
||||
|
||||
@ -611,7 +598,7 @@ body {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#confirmOverlay.enabled {
|
||||
#confirmOverlay.enabled{
|
||||
pointer-events: auto;
|
||||
top: 0;
|
||||
opacity: 1;
|
||||
@ -622,7 +609,7 @@ body {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#repoInfo.repoSelected, #repoFeatures.repoCreated {
|
||||
#repoInfo.repoSelected, #repoFeatures.repoCreated{
|
||||
opacity: 1
|
||||
}
|
||||
}
|
||||
@ -674,7 +661,7 @@ body { /* Default no authentication */
|
||||
}
|
||||
}
|
||||
|
||||
body.auth {
|
||||
body.auth{
|
||||
#packageLabelTitle h1::before {
|
||||
content: "PACKAGE INFO"
|
||||
}
|
||||
@ -700,4 +687,4 @@ body.auth {
|
||||
background: var(--c-label);
|
||||
color: var(--c-text);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6,12 +6,8 @@
|
||||
<link rel="icon" href="assets/favicon.ico?v=2">
|
||||
<link rel="stylesheet" href="assets/index.css">
|
||||
<link href="https://fonts.googleapis.com/css?family=Quicksand:300,400" rel="stylesheet">
|
||||
<!-- <link href="https://fonts.googleapis.com/css?family=Roboto+Slab:100,300" rel="stylesheet"> -->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
|
||||
<!-- <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> -->
|
||||
<!-- <script src="https://use.fontawesome.com/c8d5486cd8.js"></script> -->
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="themeSwitchContainer">
|
||||
<input type="checkbox" id="themeSwitch">
|
||||
@ -22,170 +18,589 @@
|
||||
<img src="assets/keep_dry.svg">
|
||||
<img src="assets/recycle.svg">
|
||||
<img src="assets/qr_code.svg">
|
||||
</div>
|
||||
<svg id="packageTape" viewbox="0 0 100 10">
|
||||
<rect width="100" height="0.3" x="0" y="4.85" style="fill:#483320;fill-opacity:0.8" />
|
||||
<rect width="100" height="10" x="0" y="0" style="fill:#111;fill-opacity:0.8" />
|
||||
</div><svg id="packageTape" viewbox="0 0 100 10">
|
||||
<rect width="100" height="0.3" x="0" y="4.85" style="fill:#483320;fill-opacity:0.8" />
|
||||
<rect width="100" height="10" x="0" y="0" style="fill:#111;fill-opacity:0.8" />
|
||||
|
||||
<polygon points="21,0.0 20,0.625 21,1.25 20,1.875 21,2.5 20,3.125 21,3.75 20,4.375 21,5.0 20,5.625 21,6.25 20,6.875 21,7.5 20,8.125 21,8.75 20,9.375 21,10.0 100,10 100,0" style="fill:#111;fill-opacity:0.5"/>
|
||||
<text><textPath href="#packTape0">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape1">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape2">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape3">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape4">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape5">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape6">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape7">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape8">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape9">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape10">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape11">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape12">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape13">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape14">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape15">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape16">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape17">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape18">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape19">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape20">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape21">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape22">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape23">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape24">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape25">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape26">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape27">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape28">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape29">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape30">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape31">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape32">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape33">PACK.PACK.PACK.PACK.</textPath><textPath href="#packTape34">PACK.PACK.PACK.PACK.</textPath></text>
|
||||
<path id="packTape0" fill="none" stroke="none" d="M-3.00 -0.00 l6 20"><path id="packTape1" fill="none" stroke="none" d="M-0.60 -2.00 l6 20"><path id="packTape2" fill="none" stroke="none" d="M1.80 -4.00 l6 20"><path id="packTape3" fill="none" stroke="none" d="M6.00 -0.00 l6 20"><path id="packTape4" fill="none" stroke="none" d="M8.40 -2.00 l6 20"><path id="packTape5" fill="none" stroke="none" d="M10.80 -4.00 l6 20"><path id="packTape6" fill="none" stroke="none" d="M15.00 -0.00 l6 20"><path id="packTape7" fill="none" stroke="none" d="M17.40 -2.00 l6 20"><path id="packTape8" fill="none" stroke="none" d="M19.80 -4.00 l6 20"><path id="packTape9" fill="none" stroke="none" d="M24.00 -0.00 l6 20"><path id="packTape10" fill="none" stroke="none" d="M26.40 -2.00 l6 20"><path id="packTape11" fill="none" stroke="none" d="M28.80 -4.00 l6 20"><path id="packTape12" fill="none" stroke="none" d="M33.00 -0.00 l6 20"><path id="packTape13" fill="none" stroke="none" d="M35.40 -2.00 l6 20"><path id="packTape14" fill="none" stroke="none" d="M37.80 -4.00 l6 20"><path id="packTape15" fill="none" stroke="none" d="M42.00 -0.00 l6 20"><path id="packTape16" fill="none" stroke="none" d="M44.40 -2.00 l6 20"><path id="packTape17" fill="none" stroke="none" d="M46.80 -4.00 l6 20"><path id="packTape18" fill="none" stroke="none" d="M51.00 -0.00 l6 20"><path id="packTape19" fill="none" stroke="none" d="M53.40 -2.00 l6 20"><path id="packTape20" fill="none" stroke="none" d="M55.80 -4.00 l6 20"><path id="packTape21" fill="none" stroke="none" d="M60.00 -0.00 l6 20"><path id="packTape22" fill="none" stroke="none" d="M62.40 -2.00 l6 20"><path id="packTape23" fill="none" stroke="none" d="M64.80 -4.00 l6 20"><path id="packTape24" fill="none" stroke="none" d="M69.00 -0.00 l6 20"><path id="packTape25" fill="none" stroke="none" d="M71.40 -2.00 l6 20"><path id="packTape26" fill="none" stroke="none" d="M73.80 -4.00 l6 20"><path id="packTape27" fill="none" stroke="none" d="M78.00 -0.00 l6 20"><path id="packTape28" fill="none" stroke="none" d="M80.40 -2.00 l6 20"><path id="packTape29" fill="none" stroke="none" d="M82.80 -4.00 l6 20"><path id="packTape30" fill="none" stroke="none" d="M87.00 -0.00 l6 20"><path id="packTape31" fill="none" stroke="none" d="M89.40 -2.00 l6 20"><path id="packTape32" fill="none" stroke="none" d="M91.80 -4.00 l6 20"><path id="packTape33" fill="none" stroke="none" d="M96.00 -0.00 l6 20"><path id="packTape34" fill="none" stroke="none" d="M98.40 -2.00 l6 20">
|
||||
<polygon points="21,0.0 20,0.625 21,1.25 20,1.875 21,2.5 20,3.125 21,3.75 20,4.375 21,5.0 20,5.625 21,6.25 20,6.875 21,7.5 20,8.125 21,8.75 20,9.375 21,10.0 100,10 100,0" style="fill:#111;fill-opacity:0.5"/>
|
||||
<text>
|
||||
<textPath href="#packTape0">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape1">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape2">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape3">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape4">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape5">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape6">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape7">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape8">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape9">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape10">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape11">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape12">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape13">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape14">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape15">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape16">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape17">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape18">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape19">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape20">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape21">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape22">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape23">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape24">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape25">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape26">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape27">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape28">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape29">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape30">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape31">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape32">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape33">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape34">PACK.PACK.PACK.PACK.</textPath>
|
||||
</text>
|
||||
<path id="packTape0" fill="none" stroke="none" d="M-3.00 -0.00 l6 20"/>
|
||||
<path id="packTape1" fill="none" stroke="none" d="M-0.60 -2.00 l6 20"/>
|
||||
<path id="packTape2" fill="none" stroke="none" d="M1.80 -4.00 l6 20"/>
|
||||
<path id="packTape3" fill="none" stroke="none" d="M6.00 -0.00 l6 20"/>
|
||||
<path id="packTape4" fill="none" stroke="none" d="M8.40 -2.00 l6 20"/>
|
||||
<path id="packTape5" fill="none" stroke="none" d="M10.80 -4.00 l6 20"/>
|
||||
<path id="packTape6" fill="none" stroke="none" d="M15.00 -0.00 l6 20"/>
|
||||
<path id="packTape7" fill="none" stroke="none" d="M17.40 -2.00 l6 20"/>
|
||||
<path id="packTape8" fill="none" stroke="none" d="M19.80 -4.00 l6 20"/>
|
||||
<path id="packTape9" fill="none" stroke="none" d="M24.00 -0.00 l6 20"/>
|
||||
<path id="packTape10" fill="none" stroke="none" d="M26.40 -2.00 l6 20"/>
|
||||
<path id="packTape11" fill="none" stroke="none" d="M28.80 -4.00 l6 20"/>
|
||||
<path id="packTape12" fill="none" stroke="none" d="M33.00 -0.00 l6 20"/>
|
||||
<path id="packTape13" fill="none" stroke="none" d="M35.40 -2.00 l6 20"/>
|
||||
<path id="packTape14" fill="none" stroke="none" d="M37.80 -4.00 l6 20"/>
|
||||
<path id="packTape15" fill="none" stroke="none" d="M42.00 -0.00 l6 20"/>
|
||||
<path id="packTape16" fill="none" stroke="none" d="M44.40 -2.00 l6 20"/>
|
||||
<path id="packTape17" fill="none" stroke="none" d="M46.80 -4.00 l6 20"/>
|
||||
<path id="packTape18" fill="none" stroke="none" d="M51.00 -0.00 l6 20"/>
|
||||
<path id="packTape19" fill="none" stroke="none" d="M53.40 -2.00 l6 20"/>
|
||||
<path id="packTape20" fill="none" stroke="none" d="M55.80 -4.00 l6 20"/>
|
||||
<path id="packTape21" fill="none" stroke="none" d="M60.00 -0.00 l6 20"/>
|
||||
<path id="packTape22" fill="none" stroke="none" d="M62.40 -2.00 l6 20"/>
|
||||
<path id="packTape23" fill="none" stroke="none" d="M64.80 -4.00 l6 20"/>
|
||||
<path id="packTape24" fill="none" stroke="none" d="M69.00 -0.00 l6 20"/>
|
||||
<path id="packTape25" fill="none" stroke="none" d="M71.40 -2.00 l6 20"/>
|
||||
<path id="packTape26" fill="none" stroke="none" d="M73.80 -4.00 l6 20"/>
|
||||
<path id="packTape27" fill="none" stroke="none" d="M78.00 -0.00 l6 20"/>
|
||||
<path id="packTape28" fill="none" stroke="none" d="M80.40 -2.00 l6 20"/>
|
||||
<path id="packTape29" fill="none" stroke="none" d="M82.80 -4.00 l6 20"/>
|
||||
<path id="packTape30" fill="none" stroke="none" d="M87.00 -0.00 l6 20"/>
|
||||
<path id="packTape31" fill="none" stroke="none" d="M89.40 -2.00 l6 20"/>
|
||||
<path id="packTape32" fill="none" stroke="none" d="M91.80 -4.00 l6 20"/>
|
||||
<path id="packTape33" fill="none" stroke="none" d="M96.00 -0.00 l6 20"/>
|
||||
<path id="packTape34" fill="none" stroke="none" d="M98.40 -2.00 l6 20"/>
|
||||
</svg><div id="packageLabel">
|
||||
<div id="packageLabelTop"><div>
|
||||
<svg width="48" height="48" viewBox="0 0 12.7 12.7" version="1.1">
|
||||
<defs id="defs2" />
|
||||
<path d="m 12.323869,4.1992062 -6.2301843,2.5959093 -1e-7,0.095169 6.3500004,-2.6458336 z" />
|
||||
<path d="M 12.443685,4.2444508 V 4.3735617 L 9.2686845,4.925839 V 4.7967281 Z" />
|
||||
<path d="M 6.0936845,1.6003079 12.443177,4.2450847 9.2686845,4.796728 2.9191918,2.1519511 Z" />
|
||||
<path d="m 9.2686845,3.8880996 0.062387,0.1201924 -3.237387,3.0585598 2e-7,-0.17699 z" />
|
||||
<path d="M 9.2686845,4.7967281 V 4.925839 L 8.6378103,4.6632589 8.7123025,4.564976 Z" />
|
||||
<rect width="6.8791666" height="5.8977885" x="-13.480659" y="9.4293194" transform="matrix(-0.92307692,0.3846154,0,1,0,0)" />
|
||||
<rect width="6.8791666" height="5.8977885" x="-0.27767482" y="4.3512492" transform="matrix(0.92307692,0.3846154,0,1,0,0)" />
|
||||
<path d="M 2.9186843,1.2431113 9.2686845,3.8880996 6.0936849,6.8898618 -0.2563155,4.2448735 Z" />
|
||||
</svg>
|
||||
<div id="packageLabel">
|
||||
<div id="packageLabelTop">
|
||||
<div>
|
||||
<svg width="48" height="48" viewBox="0 0 12.7 12.7" version="1.1">
|
||||
<defs id="defs2" />
|
||||
<path d="m 12.323869,4.1992062 -6.2301843,2.5959093 -1e-7,0.095169 6.3500004,-2.6458336 z" />
|
||||
<path d="M 12.443685,4.2444508 V 4.3735617 L 9.2686845,4.925839 V 4.7967281 Z" />
|
||||
<path d="M 6.0936845,1.6003079 12.443177,4.2450847 9.2686845,4.796728 2.9191918,2.1519511 Z" />
|
||||
<path d="m 9.2686845,3.8880996 0.062387,0.1201924 -3.237387,3.0585598 2e-7,-0.17699 z" />
|
||||
<path d="M 9.2686845,4.7967281 V 4.925839 L 8.6378103,4.6632589 8.7123025,4.564976 Z" />
|
||||
<rect width="6.8791666" height="5.8977885" x="-13.480659" y="9.4293194" transform="matrix(-0.92307692,0.3846154,0,1,0,0)" />
|
||||
<rect width="6.8791666" height="5.8977885" x="-0.27767482" y="4.3512492" transform="matrix(0.92307692,0.3846154,0,1,0,0)" />
|
||||
<path d="M 2.9186843,1.2431113 9.2686845,3.8880996 6.0936849,6.8898618 -0.2563155,4.2448735 Z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<p><b>BYTE TRANSIT FEES PAID</b></p>
|
||||
<p>64 OF 64</p>
|
||||
<p>6.28 TB FIBRE OPTIC EXPRESS RATE</p>
|
||||
<p>ACCEPTS TAR.GZ, ZIP</p>
|
||||
</div>
|
||||
<div>
|
||||
<svg width="618" height="124" viewBox="0 0 618 124" version="1.1">
|
||||
<path d="M 2.1999999e-6,0 H 41.200002 V 123.6 H 2.1999999e-6 Z M 46.350002,0 h 5.15 v 123.6 h -5.15 z m 10.3,0 h 5.15 v 123.6 h -5.15 z m 10.3,0 h 5.15 v 123.6 h -5.15 z m 20.6,0 H 113.3 v 15.45 h 5.15 V 30.9 h -5.15 v 15.45 h -5.15 V 30.9 H 103 V 46.35 H 97.850002 V 30.9 h -5.15 v 15.45 h 5.15 V 61.8 H 103 v 15.450002 h 5.15 V 61.8 h 5.15 v 61.8 H 87.550002 Z M 118.45,0 h 5.15 v 15.45 h -5.15 z m 10.3,0 h 5.15 v 15.45 h -5.15 z m 10.3,0 h 25.75 v 15.45 h 5.15 V 30.9 H 154.5 V 15.45 h -15.45 z m 36.05,0 h 15.45 v 30.9 h -5.15 v 30.9 h 5.15 v 15.450002 h -5.15 v 15.45 h -5.15 V 108.15 h 10.3 V 123.6 H 175.1 Z m 20.6,0 h 5.15 V 15.45 H 195.7 Z M 206,0 h 10.3 v 15.45 h -5.15 V 30.9 h 5.15 V 15.45 h 10.3 V 30.9 h -5.15 v 15.45 h 5.15 V 61.8 h 5.15 v 15.450002 h -5.15 v 15.45 h 5.15 V 108.15 H 226.6 V 123.6 H 216.3 V 92.700002 H 206 V 123.6 h -5.15 V 108.15 H 195.7 V 92.700002 h 5.15 v -15.45 H 206 V 61.8 h 5.15 v 15.450002 h 10.3 V 61.8 H 216.3 V 46.35 H 206 V 61.8 H 190.55 V 46.35 h 5.15 V 30.9 H 206 Z m 20.6,0 h 20.6 v 46.35 h -5.15 V 15.45 H 226.6 Z m 36.05,0 h 10.3 v 30.9 h -5.15 v 15.45 h 5.15 v 30.900002 h -5.15 v 15.45 h 10.3 V 108.15 h 5.15 v 15.45 h -10.3 v -15.45 h -5.15 v 15.45 h -5.15 z m 30.9,0 h 10.3 V 30.9 H 309 V 0 h 5.15 v 30.9 h 5.15 v 15.45 h -5.15 V 61.8 h 5.15 v 15.450002 h 5.15 v 15.45 h -10.3 v -15.45 h -10.3 v 15.45 H 298.7 V 108.15 H 288.4 V 77.250002 h 10.3 V 61.8 h 5.15 V 46.35 H 298.7 V 30.9 h -10.3 v 30.9 h -5.15 V 15.45 h 10.3 z m 25.75,0 h 5.15 v 15.45 h 20.6 V 30.9 H 319.3 Z m 30.9,0 h 5.15 v 15.45 h 5.15 V 0 h 15.45 v 15.45 h -10.3 V 30.9 h -10.3 v 15.45 h 5.15 v 46.350002 h 5.15 V 108.15 h 5.15 v 15.45 h -20.6 z m 46.35,0 H 412 v 15.45 h 5.15 v 30.9 H 412 V 61.8 h 5.15 v 15.450002 h 5.15 V 61.8 h 10.3 v 15.450002 h -5.15 v 15.45 h -20.6 v -15.45 h -10.3 V 61.8 h 10.3 V 46.35 h -10.3 V 30.9 h 5.15 V 15.45 h -5.15 z m 20.6,0 h 5.15 v 15.45 h -5.15 z m 20.6,0 h 25.75 v 15.45 h -5.15 V 30.9 h -5.15 v 15.45 h -5.15 V 61.8 h 5.15 V 46.35 h 5.15 V 77.250002 H 453.2 V 123.6 h -5.15 v -15.45 h -5.15 v 15.45 h -5.15 z m 30.9,0 h 5.15 v 15.45 h -5.15 z m 10.3,0 h 5.15 v 15.45 h -5.15 z m 10.3,0 H 515 V 15.45 H 494.4 V 30.9 h 25.75 V 61.8 H 515 v 15.450002 h -10.3 v 15.45 h 15.45 V 108.15 h -10.3 V 123.6 H 494.4 V 92.700002 h 5.15 V 61.8 H 494.4 V 46.35 h -5.15 z m 36.05,0 h 36.05 V 123.6 H 525.3 Z m 41.2,0 h 5.15 v 123.6 h -5.15 z m 20.6,0 h 5.15 v 123.6 h -5.15 z m 10.3,0 h 5.15 v 123.6 h -5.15 z m 15.45,0 H 618 v 123.6 h -5.15 z M 123.6,15.45 h 5.15 V 30.9 h 5.15 V 15.45 h 5.15 V 30.9 h 5.15 v 15.45 h -10.3 v 30.900002 h 15.45 v 15.45 h 5.15 V 61.8 H 144.2 V 46.35 h 25.75 V 61.8 h -5.15 v 30.900002 h 5.15 V 108.15 H 154.5 V 123.6 H 144.2 V 92.700002 h -5.15 V 123.6 H 133.9 V 108.15 H 123.6 V 92.700002 h 5.15 v -15.45 h -5.15 v 15.45 h -5.15 V 61.8 H 113.3 V 46.35 h 10.3 z m 257.5,0 h 5.15 V 30.9 h -5.15 z m 41.2,0 h 10.3 V 30.9 h -10.3 z m 41.2,0 h 5.15 V 30.9 h -5.15 z m 10.3,0 h 5.15 V 30.9 H 473.8 Z M 231.75,30.9 h 5.15 v 15.45 h -5.15 z m 41.2,0 h 5.15 v 15.45 h -5.15 z m 97.85,0 h 5.15 v 15.45 h 5.15 v 30.900002 h -5.15 V 61.8 h -5.15 z m 15.45,0 h 5.15 v 15.45 h -5.15 z m 72.1,0 h 5.15 v 15.45 h -5.15 z m 10.3,0 h 5.15 v 15.45 h 10.3 V 61.8 h 5.15 v 15.450002 h 5.15 v 15.45 h -5.15 V 123.6 h -30.9 V 77.250002 h 5.15 V 108.15 h 10.3 V 92.700002 h -5.15 v -15.45 h 5.15 V 61.8 h -5.15 V 77.250002 H 463.5 V 46.35 h 5.15 z M 103,46.35 h 5.15 V 61.8 H 103 Z m 149.35,0 h 5.15 v 77.25 h -5.15 V 108.15 H 247.2 V 92.700002 h 5.15 z m 77.25,0 h 15.45 V 61.8 h -10.3 v 15.450002 h 10.3 v 15.45 H 339.9 V 108.15 H 329.6 V 123.6 H 303.85 V 92.700002 h 10.3 V 108.15 h 10.3 V 92.700002 h 5.15 v -15.45 h -5.15 V 61.8 h 5.15 z m 61.8,0 h 5.15 V 61.8 H 391.4 Z M 278.1,61.8 h 5.15 v 15.450002 h -5.15 z m -41.2,15.450002 h 5.15 v 15.45 h -5.15 z m 128.75,0 h 10.3 v 15.45 h 5.15 v -15.45 h 5.15 v 15.45 h 5.15 V 108.15 h -5.15 v 15.45 h -10.3 V 108.15 H 370.8 V 92.700002 h -5.15 z M 103,92.700002 V 108.15 h 5.15 V 92.700002 Z m 293.55,0 h 10.3 V 108.15 h -10.3 z m 30.9,0 h 5.15 V 123.6 h -5.15 z M 118.45,108.15 h 5.15 v 15.45 h -5.15 z m 221.45,0 h 5.15 v 15.45 h -5.15 z m 66.95,0 h 10.3 v 15.45 h -10.3 z" fill-rule="evenodd" style="stroke-width:0.858333" />
|
||||
</svg>
|
||||
<h1 id="login"></h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<p><b>BYTE TRANSIT FEES PAID</b></p>
|
||||
<p>64 OF 64</p>
|
||||
<p>6.28 TB FIBRE OPTIC EXPRESS RATE</p>
|
||||
<p>ACCEPTS TAR.GZ, ZIP</p>
|
||||
</div>
|
||||
<div>
|
||||
<svg width="618" height="124" viewBox="0 0 618 124" version="1.1">
|
||||
<path d="M 2.1999999e-6,0 H 41.200002 V 123.6 H 2.1999999e-6 Z M 46.350002,0 h 5.15 v 123.6 h -5.15 z m 10.3,0 h 5.15 v 123.6 h -5.15 z m 10.3,0 h 5.15 v 123.6 h -5.15 z m 20.6,0 H 113.3 v 15.45 h 5.15 V 30.9 h -5.15 v 15.45 h -5.15 V 30.9 H 103 V 46.35 H 97.850002 V 30.9 h -5.15 v 15.45 h 5.15 V 61.8 H 103 v 15.450002 h 5.15 V 61.8 h 5.15 v 61.8 H 87.550002 Z M 118.45,0 h 5.15 v 15.45 h -5.15 z m 10.3,0 h 5.15 v 15.45 h -5.15 z m 10.3,0 h 25.75 v 15.45 h 5.15 V 30.9 H 154.5 V 15.45 h -15.45 z m 36.05,0 h 15.45 v 30.9 h -5.15 v 30.9 h 5.15 v 15.450002 h -5.15 v 15.45 h -5.15 V 108.15 h 10.3 V 123.6 H 175.1 Z m 20.6,0 h 5.15 V 15.45 H 195.7 Z M 206,0 h 10.3 v 15.45 h -5.15 V 30.9 h 5.15 V 15.45 h 10.3 V 30.9 h -5.15 v 15.45 h 5.15 V 61.8 h 5.15 v 15.450002 h -5.15 v 15.45 h 5.15 V 108.15 H 226.6 V 123.6 H 216.3 V 92.700002 H 206 V 123.6 h -5.15 V 108.15 H 195.7 V 92.700002 h 5.15 v -15.45 H 206 V 61.8 h 5.15 v 15.450002 h 10.3 V 61.8 H 216.3 V 46.35 H 206 V 61.8 H 190.55 V 46.35 h 5.15 V 30.9 H 206 Z m 20.6,0 h 20.6 v 46.35 h -5.15 V 15.45 H 226.6 Z m 36.05,0 h 10.3 v 30.9 h -5.15 v 15.45 h 5.15 v 30.900002 h -5.15 v 15.45 h 10.3 V 108.15 h 5.15 v 15.45 h -10.3 v -15.45 h -5.15 v 15.45 h -5.15 z m 30.9,0 h 10.3 V 30.9 H 309 V 0 h 5.15 v 30.9 h 5.15 v 15.45 h -5.15 V 61.8 h 5.15 v 15.450002 h 5.15 v 15.45 h -10.3 v -15.45 h -10.3 v 15.45 H 298.7 V 108.15 H 288.4 V 77.250002 h 10.3 V 61.8 h 5.15 V 46.35 H 298.7 V 30.9 h -10.3 v 30.9 h -5.15 V 15.45 h 10.3 z m 25.75,0 h 5.15 v 15.45 h 20.6 V 30.9 H 319.3 Z m 30.9,0 h 5.15 v 15.45 h 5.15 V 0 h 15.45 v 15.45 h -10.3 V 30.9 h -10.3 v 15.45 h 5.15 v 46.350002 h 5.15 V 108.15 h 5.15 v 15.45 h -20.6 z m 46.35,0 H 412 v 15.45 h 5.15 v 30.9 H 412 V 61.8 h 5.15 v 15.450002 h 5.15 V 61.8 h 10.3 v 15.450002 h -5.15 v 15.45 h -20.6 v -15.45 h -10.3 V 61.8 h 10.3 V 46.35 h -10.3 V 30.9 h 5.15 V 15.45 h -5.15 z m 20.6,0 h 5.15 v 15.45 h -5.15 z m 20.6,0 h 25.75 v 15.45 h -5.15 V 30.9 h -5.15 v 15.45 h -5.15 V 61.8 h 5.15 V 46.35 h 5.15 V 77.250002 H 453.2 V 123.6 h -5.15 v -15.45 h -5.15 v 15.45 h -5.15 z m 30.9,0 h 5.15 v 15.45 h -5.15 z m 10.3,0 h 5.15 v 15.45 h -5.15 z m 10.3,0 H 515 V 15.45 H 494.4 V 30.9 h 25.75 V 61.8 H 515 v 15.450002 h -10.3 v 15.45 h 15.45 V 108.15 h -10.3 V 123.6 H 494.4 V 92.700002 h 5.15 V 61.8 H 494.4 V 46.35 h -5.15 z m 36.05,0 h 36.05 V 123.6 H 525.3 Z m 41.2,0 h 5.15 v 123.6 h -5.15 z m 20.6,0 h 5.15 v 123.6 h -5.15 z m 10.3,0 h 5.15 v 123.6 h -5.15 z m 15.45,0 H 618 v 123.6 h -5.15 z M 123.6,15.45 h 5.15 V 30.9 h 5.15 V 15.45 h 5.15 V 30.9 h 5.15 v 15.45 h -10.3 v 30.900002 h 15.45 v 15.45 h 5.15 V 61.8 H 144.2 V 46.35 h 25.75 V 61.8 h -5.15 v 30.900002 h 5.15 V 108.15 H 154.5 V 123.6 H 144.2 V 92.700002 h -5.15 V 123.6 H 133.9 V 108.15 H 123.6 V 92.700002 h 5.15 v -15.45 h -5.15 v 15.45 h -5.15 V 61.8 H 113.3 V 46.35 h 10.3 z m 257.5,0 h 5.15 V 30.9 h -5.15 z m 41.2,0 h 10.3 V 30.9 h -10.3 z m 41.2,0 h 5.15 V 30.9 h -5.15 z m 10.3,0 h 5.15 V 30.9 H 473.8 Z M 231.75,30.9 h 5.15 v 15.45 h -5.15 z m 41.2,0 h 5.15 v 15.45 h -5.15 z m 97.85,0 h 5.15 v 15.45 h 5.15 v 30.900002 h -5.15 V 61.8 h -5.15 z m 15.45,0 h 5.15 v 15.45 h -5.15 z m 72.1,0 h 5.15 v 15.45 h -5.15 z m 10.3,0 h 5.15 v 15.45 h 10.3 V 61.8 h 5.15 v 15.450002 h 5.15 v 15.45 h -5.15 V 123.6 h -30.9 V 77.250002 h 5.15 V 108.15 h 10.3 V 92.700002 h -5.15 v -15.45 h 5.15 V 61.8 h -5.15 V 77.250002 H 463.5 V 46.35 h 5.15 z M 103,46.35 h 5.15 V 61.8 H 103 Z m 149.35,0 h 5.15 v 77.25 h -5.15 V 108.15 H 247.2 V 92.700002 h 5.15 z m 77.25,0 h 15.45 V 61.8 h -10.3 v 15.450002 h 10.3 v 15.45 H 339.9 V 108.15 H 329.6 V 123.6 H 303.85 V 92.700002 h 10.3 V 108.15 h 10.3 V 92.700002 h 5.15 v -15.45 h -5.15 V 61.8 h 5.15 z m 61.8,0 h 5.15 V 61.8 H 391.4 Z M 278.1,61.8 h 5.15 v 15.450002 h -5.15 z m -41.2,15.450002 h 5.15 v 15.45 h -5.15 z m 128.75,0 h 10.3 v 15.45 h 5.15 v -15.45 h 5.15 v 15.45 h 5.15 V 108.15 h -5.15 v 15.45 h -10.3 V 108.15 H 370.8 V 92.700002 h -5.15 z M 103,92.700002 V 108.15 h 5.15 V 92.700002 Z m 293.55,0 h 10.3 V 108.15 h -10.3 z m 30.9,0 h 5.15 V 123.6 h -5.15 z M 118.45,108.15 h 5.15 v 15.45 h -5.15 z m 221.45,0 h 5.15 v 15.45 h -5.15 z m 66.95,0 h 10.3 v 15.45 h -10.3 z" fill-rule="evenodd" style="stroke-width:0.858333" />
|
||||
</svg>
|
||||
<h1 id="login"></h1>
|
||||
</div>
|
||||
</div></div>
|
||||
<div id="packageLabelTitle">
|
||||
<h1><b></b></h1>
|
||||
</div>
|
||||
<div id="packageLabelContent">
|
||||
<h1>AWAITING AUTHORIZATION...</h1>
|
||||
<div>
|
||||
<div id="repoSelect">
|
||||
<h1>REPOSITORY:</h1>
|
||||
<input id="repoSelectInput" type="text" size="32" placeholder="<user>/<repository>">
|
||||
<input class="enabled" id="repoSelectButton" type="submit" value="Select">
|
||||
<p id="repoSelectError"></p>
|
||||
</div>
|
||||
<div id="repoInfo">
|
||||
<h1>ACTIONS:</h1>
|
||||
<div id="repoActions">
|
||||
<input class="enabled" id="repoCreate" type="submit" value="Create">
|
||||
<input id="repoDelete" type="submit" value="Delete">
|
||||
<input id="repoSecret" type="submit" value="Regenerate Secret">
|
||||
</div>
|
||||
<div id="repoFeatures">
|
||||
<h1>LINK:</h1>
|
||||
<input id="repoLinkInput" type="text" size="32" readonly>
|
||||
<input class="enabled" id="repoLinkButton" type="submit" value="Copy">
|
||||
<h1>FEATURES:</h1>
|
||||
<div id="featureBox">
|
||||
<input class="feature" type="submit" data-tag="docs" value="Docs">
|
||||
<input class="feature" type="submit" data-tag="builds" value="Builds">
|
||||
<input class="feature" type="submit" data-tag="nightly" value="Nightly">
|
||||
<input class="feature" type="submit" data-tag="preprod" value="PreProd">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="confirmOverlay">
|
||||
<div>
|
||||
<div>
|
||||
<h1>CONFIRMATION:</h1>
|
||||
<input id="confirmInput" type="text" size="32" placeholder="<user>/<repository>">
|
||||
<input class="enabled" id="confirmButtonYes" type="submit" value="Confirm">
|
||||
<input class="enabled" id="confirmButtonNo" type="submit" value="Cancel">
|
||||
<p>This will (irreversibly) delete all associated files! Please type in the full repository name to confirm.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h1>AWAITING AUTHORIZATION...</h1><div>
|
||||
<div id="repoSelect">
|
||||
<h1>REPOSITORY:</h1>
|
||||
<input id="repoSelectInput" type="text" size="32" placeholder="<user>/<repository>">
|
||||
<input class="enabled" id="repoSelectButton" type="submit" value="Select">
|
||||
<p id="repoSelectError"></p>
|
||||
</div>
|
||||
<div id="repoInfo">
|
||||
<h1>ACTIONS:</h1>
|
||||
<div id="repoActions">
|
||||
<input class="enabled" id="repoCreate" type="submit" value="Create">
|
||||
<input id="repoDelete" type="submit" value="Delete">
|
||||
<input id="repoSecret" type="submit" value="Regenerate Secret">
|
||||
</div>
|
||||
<div id="packageLabelBot">
|
||||
<svg width="1596" height="432" viewBox="0 0 1596 432" version="1.1">
|
||||
<path d="M 0,432 H 12 V 0 H 0 Z" />
|
||||
<path d="m 18,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 36,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 66,432 h 6 V 0 h -6 z" />
|
||||
<path d="M 84,432 H 96 V 0 H 84 Z" />
|
||||
<path d="m 120,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 132,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 150,432 h 24 V 0 h -24 z" />
|
||||
<path d="m 180,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 198,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 216,432 h 24 V 0 h -24 z" />
|
||||
<path d="m 246,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 264,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 276,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 294,432 h 24 V 0 h -24 z" />
|
||||
<path d="m 330,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 342,432 h 24 V 0 h -24 z" />
|
||||
<path d="m 378,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 396,432 h 18 V 0 h -18 z" />
|
||||
<path d="m 426,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 444,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 462,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 474,432 h 18 V 0 h -18 z" />
|
||||
<path d="m 504,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 528,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 540,432 h 18 V 0 h -18 z" />
|
||||
<path d="m 570,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 594,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 606,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 624,432 h 24 V 0 h -24 z" />
|
||||
<path d="m 660,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 678,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 690,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 726,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 756,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 768,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 792,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 828,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 846,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 858,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 876,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 900,432 h 18 V 0 h -18 z" />
|
||||
<path d="m 924,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 960,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 978,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 990,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1020,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 1044,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1056,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1074,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1086,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 1122,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1146,432 h 24 V 0 h -24 z" />
|
||||
<path d="m 1176,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1188,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1206,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 1230,432 h 18 V 0 h -18 z" />
|
||||
<path d="m 1254,432 h 24 V 0 h -24 z" />
|
||||
<path d="m 1284,432 h 18 V 0 h -18 z" />
|
||||
<path d="m 1308,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1320,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1332,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 1356,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1386,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1398,432 h 18 V 0 h -18 z" />
|
||||
<path d="m 1428,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 1452,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1470,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1488,432 h 24 V 0 h -24 z" />
|
||||
<path d="m 1518,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 1548,432 h 18 V 0 h -18 z" />
|
||||
<path d="m 1572,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1584,432 h 12 V 0 h -12 z" />
|
||||
</svg>
|
||||
<a href="/">https://pack.kjao.me/</a>
|
||||
<div id="repoFeatures">
|
||||
<h1>LINK:</h1>
|
||||
<input id="repoLinkInput" type="text" size="32" readonly>
|
||||
<input class="enabled" id="repoLinkButton" type="submit" value="Copy">
|
||||
<h1>FEATURES:</h1>
|
||||
<div id="featureBox"><input class="feature" type="submit" data-tag="docs" value="Docs"><input class="feature" type="submit" data-tag="builds" value="Builds"><input class="feature" type="submit" data-tag="nightly" value="Nightly"><input class="feature" type="submit" data-tag="preprod" value="PreProd"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="confirmOverlay">
|
||||
<div>
|
||||
<div>
|
||||
<h1>CONFIRMATION:</h1>
|
||||
<input id="confirmInput" type="text" size="32" placeholder="<user>/<repository>">
|
||||
<input class="enabled" id="confirmButtonYes" type="submit" value="Confirm">
|
||||
<input class="enabled" id="confirmButtonNo" type="submit" value="Cancel">
|
||||
<p>This will (irreversibly) delete all associated files! Please type in the full repository name to confirm.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div></div>
|
||||
<div id="packageLabelBot"><svg width="1596" height="432" viewBox="0 0 1596 432" version="1.1">
|
||||
<path d="M 0,432 H 12 V 0 H 0 Z" />
|
||||
<path d="m 18,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 36,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 66,432 h 6 V 0 h -6 z" />
|
||||
<path d="M 84,432 H 96 V 0 H 84 Z" />
|
||||
<path d="m 120,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 132,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 150,432 h 24 V 0 h -24 z" />
|
||||
<path d="m 180,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 198,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 216,432 h 24 V 0 h -24 z" />
|
||||
<path d="m 246,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 264,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 276,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 294,432 h 24 V 0 h -24 z" />
|
||||
<path d="m 330,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 342,432 h 24 V 0 h -24 z" />
|
||||
<path d="m 378,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 396,432 h 18 V 0 h -18 z" />
|
||||
<path d="m 426,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 444,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 462,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 474,432 h 18 V 0 h -18 z" />
|
||||
<path d="m 504,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 528,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 540,432 h 18 V 0 h -18 z" />
|
||||
<path d="m 570,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 594,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 606,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 624,432 h 24 V 0 h -24 z" />
|
||||
<path d="m 660,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 678,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 690,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 726,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 756,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 768,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 792,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 828,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 846,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 858,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 876,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 900,432 h 18 V 0 h -18 z" />
|
||||
<path d="m 924,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 960,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 978,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 990,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1020,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 1044,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1056,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1074,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1086,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 1122,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1146,432 h 24 V 0 h -24 z" />
|
||||
<path d="m 1176,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1188,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1206,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 1230,432 h 18 V 0 h -18 z" />
|
||||
<path d="m 1254,432 h 24 V 0 h -24 z" />
|
||||
<path d="m 1284,432 h 18 V 0 h -18 z" />
|
||||
<path d="m 1308,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1320,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1332,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 1356,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1386,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1398,432 h 18 V 0 h -18 z" />
|
||||
<path d="m 1428,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 1452,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1470,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1488,432 h 24 V 0 h -24 z" />
|
||||
<path d="m 1518,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 1548,432 h 18 V 0 h -18 z" />
|
||||
<path d="m 1572,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1584,432 h 12 V 0 h -12 z" />
|
||||
</svg><a href="/">http://127.0.0.1:3000/</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
<script src="assets/index.js"></script>
|
||||
</html>
|
||||
<script>const CONFIG = {
|
||||
client_id: "3d463405-d098-4038-8b25-a44ca5b9ab9c",
|
||||
redirect_uri: "http://127.0.0.1:3000/",
|
||||
authorization_endpoint: "https://git.kjao.me/login/oauth/authorize",
|
||||
token_endpoint: "https://git.kjao.me/login/oauth/access_token",
|
||||
requested_scopes: "read:repository,write:repository"
|
||||
};
|
||||
|
||||
var G_AUTH = window.localStorage.getItem("token") !== null;
|
||||
|
||||
document.on = document.addEventListener;
|
||||
function sugar(obj) {
|
||||
obj.on = obj.addEventListener;
|
||||
obj.addClass = (x) => obj.classList.add(x);
|
||||
obj.delClass = (x) => obj.classList.remove(x);
|
||||
obj.hasClass = (x) => obj.classList.contains(x);
|
||||
obj.setClass = (x, y) => obj.classList.toggle(x, y);
|
||||
return obj;
|
||||
}
|
||||
|
||||
function get(s) {
|
||||
let x = [...document.querySelectorAll(s)].map(sugar);
|
||||
return (x.length === 1) ? x[0] : x;
|
||||
}
|
||||
|
||||
// Check if object is empty.
|
||||
function isEmpty(obj) {
|
||||
for (const prop in obj) {
|
||||
if (Object.hasOwn(obj, prop)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns error and resolves promise if necessary.
|
||||
function getErr(f) {
|
||||
return (err) => {
|
||||
if (err instanceof Promise) {
|
||||
return err.then(f);
|
||||
} else {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get("#login").on("click", async (e) => {
|
||||
e.preventDefault();
|
||||
if (G_AUTH) {
|
||||
window.localStorage.clear();
|
||||
window.location = "/";
|
||||
} else {
|
||||
// Build the authorization URL
|
||||
let url = CONFIG.authorization_endpoint
|
||||
+ "?response_type=code"
|
||||
+ "&client_id="+encodeURIComponent(CONFIG.client_id)
|
||||
+ "&scope="+encodeURIComponent(CONFIG.requested_scopes)
|
||||
+ "&redirect_uri="+encodeURIComponent(CONFIG.redirect_uri);
|
||||
|
||||
// Redirect to the authorization server
|
||||
window.location = url;
|
||||
}
|
||||
});// Fetch function for applet use case.
|
||||
async function jfetch(url, method, obj={}) {
|
||||
let request = {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": window.localStorage.getItem("token"),
|
||||
},
|
||||
method: method,
|
||||
};
|
||||
|
||||
if (!isEmpty(obj)) request["body"] = JSON.stringify(obj);
|
||||
|
||||
return fetch(url, request)
|
||||
.then((response) => {
|
||||
let contentType = response.headers.get("Content-Type");
|
||||
let json;
|
||||
if (contentType && contentType.indexOf("application/json" !== -1)) {
|
||||
json = response.json();
|
||||
} else { // Reprocess non-json into json.
|
||||
json = response.text().then((text) => {
|
||||
return { status: response.status, "message": text };
|
||||
});
|
||||
}
|
||||
if (!response.ok) { throw json; }
|
||||
return json;
|
||||
});
|
||||
}
|
||||
|
||||
// OAUTH //
|
||||
|
||||
async function getToken() {
|
||||
let response;
|
||||
if (G_QUERY.code) {
|
||||
response = await jfetch("/api/token", "POST", { code: G_QUERY.code });
|
||||
} else {
|
||||
response = await jfetch("/api/token", "PATCH", { code: window.localStorage.getItem("refresh_token") });
|
||||
}
|
||||
|
||||
window.localStorage.setItem("token", response.access_token);
|
||||
window.localStorage.setItem("token_expiry", (Date.now() + response.expires_in*1000).toString());
|
||||
window.localStorage.setItem("refresh_token", response.refresh_token);
|
||||
}
|
||||
|
||||
async function tryRefresh() {
|
||||
if (Date.now() < parseInt(window.localStorage.getItem("token_expiry"))) return; // Not expired.
|
||||
await getToken().catch((err) => {
|
||||
let json = err.json();
|
||||
if (json.status == 401 && json.code === 0) { // Could not refresh, so refresh token expired.
|
||||
window.localStorage.clear();
|
||||
alert(`Could not get new session, did you remove access from Gitea?`);
|
||||
window.location = "/";
|
||||
} else {
|
||||
throw json;
|
||||
}
|
||||
});
|
||||
}const STATES = { // Either the non-d
|
||||
auth: "auth",
|
||||
error: "error",
|
||||
loading: "loading",
|
||||
repoSelected: "repoSelected",
|
||||
repoCreated: "repoCreated",
|
||||
buttonOn: "enabled",
|
||||
featureOn: "fEnabled",
|
||||
confirmOn: "enabled",
|
||||
}
|
||||
|
||||
var G_REPO_VALUE = "",
|
||||
G_CONFIRM_VALUE = "",
|
||||
G_CONFIRM = -1;
|
||||
|
||||
// UTILITY //
|
||||
|
||||
// Parse a query string into an object
|
||||
function parseQueryString(string) {
|
||||
if(string == "") { return {}; }
|
||||
var segments = string.split("&").map(s => s.split("=") );
|
||||
var queryString = {};
|
||||
segments.forEach(s => queryString[s[0]] = s[1]);
|
||||
return queryString;
|
||||
}
|
||||
|
||||
// BUTTON ONCLICK MIDDLEWARE //
|
||||
|
||||
// Refresh token if necessary.
|
||||
function tryAuth(f) {
|
||||
return async (e) => {
|
||||
e.preventDefault();
|
||||
if (!G_AUTH) return;
|
||||
await tryRefresh();
|
||||
await f(e);
|
||||
}
|
||||
}
|
||||
|
||||
// Adds loading classes for UI while awaiting.
|
||||
function doLoading(f) {
|
||||
return async (e) => {
|
||||
if (e.target.hasClass("loading")) return;
|
||||
e.target.addClass(STATES["loading"]);
|
||||
await f(e);
|
||||
e.target.delClass(STATES["loading"]);
|
||||
}
|
||||
}
|
||||
|
||||
// BUTTON ONCLICK HELPERS //
|
||||
|
||||
function setRepoError(s, err) {
|
||||
const input = get("#repoSelectInput"),
|
||||
error = get("#repoSelectError"),
|
||||
info = get("#repoInfo");
|
||||
error.innerText = s;
|
||||
info.setClass(STATES["repoSelected"], !err);
|
||||
input.setClass(STATES["error"], err);
|
||||
}
|
||||
|
||||
function setRepoActions(s) {
|
||||
get("#repoCreate").setClass(STATES["buttonOn"], !s);
|
||||
get("#repoDelete").setClass(STATES["buttonOn"], s);
|
||||
get("#repoSecret").setClass(STATES["buttonOn"], s);
|
||||
get("#repoFeatures").setClass(STATES["repoCreated"], s);
|
||||
}
|
||||
|
||||
async function getConfirm() {
|
||||
get("#confirmOverlay").addClass(STATES["confirmOn"]);
|
||||
return new Promise((resolve, reject) => {
|
||||
const check = function() {
|
||||
if (G_CONFIRM == -1) {
|
||||
setTimeout(check, 100);
|
||||
} else {
|
||||
get("#confirmOverlay").delClass(STATES["confirmOn"]);
|
||||
resolve(G_CONFIRM);
|
||||
G_CONFIRM = -1;
|
||||
}
|
||||
}
|
||||
check();
|
||||
});
|
||||
}
|
||||
|
||||
document.on("keydown", (e) => {
|
||||
if (e.keyCode == 27) get("#confirmOverlay").delClass(STATES["confirmOn"]);
|
||||
});
|
||||
|
||||
// BUTTON ONCLICK FUNCTIONS //
|
||||
|
||||
get("#repoSelectInput").on("keydown", (e) => {
|
||||
if (e.keyCode === 13) {
|
||||
get("#repoSelectButton").click();
|
||||
return;
|
||||
}
|
||||
|
||||
let value = e.target.value;
|
||||
if (value !== G_REPO_VALUE) {
|
||||
get("#repoSelectError").innerText = ""; // Delete error text.
|
||||
get("#repoSelectInput").delClass(STATES["error"]); // Remove error class.
|
||||
get("#repoInfo").delClass(STATES["repoSelected"]); // Remove repoSelect class.
|
||||
setRepoActions(false); // Set actions to default.
|
||||
get(".feature").forEach((feature) => feature.delClass(STATES["featureOn"]));
|
||||
G_REPO_VALUE = value;
|
||||
}
|
||||
});
|
||||
|
||||
get("#repoSelectButton").on("click", tryAuth(doLoading(selectRepo)));
|
||||
async function selectRepo(e) {
|
||||
const input = get("#repoSelectInput");
|
||||
let repo = input.value.trim();
|
||||
input.value = repo;
|
||||
|
||||
if (repo === "") {
|
||||
setRepoError("Field cannot be empty.", true);
|
||||
return;
|
||||
}
|
||||
|
||||
await jfetch("/api/repo/" + repo, "GET")
|
||||
.then((json) => {
|
||||
setRepoError("OK", false);
|
||||
setRepoActions(json["exists"]);
|
||||
|
||||
if (json["exists"]) {
|
||||
json["features"].forEach((feature) => {
|
||||
get(`.feature[data-tag=${feature}]`).addClass(STATES["featureOn"]);
|
||||
});
|
||||
}
|
||||
|
||||
get("#repoLinkInput").value = CONFIG["redirect_uri"] + repo;
|
||||
get("#repoInfo").addClass(STATES["repoSelected"]);
|
||||
|
||||
})
|
||||
.catch(getErr((err) => {
|
||||
console.log(err);
|
||||
setRepoError("Unable to find repository or you have insufficient permissions.", true);
|
||||
}));
|
||||
}
|
||||
|
||||
get("#repoCreate").on("click", tryAuth(doLoading(createRepo)));
|
||||
async function createRepo(e) {
|
||||
const input = get("#repoSelectInput");
|
||||
await jfetch("/api/repo/" + input.value, "POST")
|
||||
.then((json) => {
|
||||
setRepoActions(true);
|
||||
})
|
||||
.catch(getErr((err) => {
|
||||
console.log(err);
|
||||
alert("An unexpected error occurred! Check console for more details.");
|
||||
}));
|
||||
}
|
||||
|
||||
get("#repoDelete").on("click", tryAuth(doLoading(deleteRepo)));
|
||||
async function deleteRepo(e) {
|
||||
const input = get("#repoSelectInput");
|
||||
if (!(await getConfirm())) return;
|
||||
await jfetch("/api/repo/" + input.value, "DELETE")
|
||||
.then((json) => {
|
||||
setRepoActions(false);
|
||||
})
|
||||
.catch(getErr((err) => {
|
||||
console.log(err);
|
||||
alert("An unexpected error occurred! Check console for more details.");
|
||||
}));
|
||||
}
|
||||
|
||||
get("#repoSecret").on("click", tryAuth(doLoading(regenSecret)));
|
||||
async function regenSecret(e) {
|
||||
const input = get("#repoSelectInput");
|
||||
await jfetch("/api/repo/" + input.value, "PATCH", { secret: true, feature: "" })
|
||||
.then((json) => {
|
||||
setRepoActions(true);
|
||||
})
|
||||
.catch(getErr((err) => {
|
||||
console.log(err);
|
||||
alert("An unexpected error occurred! Check console for more details.");
|
||||
}));
|
||||
}
|
||||
|
||||
get("#repoLinkButton").on("click", async (e) => {
|
||||
const input = get("#repoLinkInput");
|
||||
input.select();
|
||||
input.setSelectionRange(0, 99999);
|
||||
navigator.clipboard.writeText(input.value);
|
||||
});
|
||||
|
||||
get(".feature").forEach((el) => el.on("click", tryAuth(doLoading(toggleFeature))));
|
||||
async function toggleFeature(e) {
|
||||
const input = get("#repoSelectInput");
|
||||
let attr = e.target.getAttribute("data-tag");
|
||||
if (e.target.hasClass(STATES["featureOn"]) && !(await getConfirm())) return;
|
||||
await jfetch("/api/repo/" + input.value, "PATCH", { secret: false, feature: attr })
|
||||
.then((json) => {
|
||||
e.target.setClass(STATES["featureOn"]);
|
||||
})
|
||||
.catch(getErr((err) => {
|
||||
console.log(err);
|
||||
alert("An unexpected error occurred! Check console for more details.");
|
||||
}));
|
||||
}
|
||||
|
||||
get("#confirmInput").on("keydown", function(e) {
|
||||
if (e.keyCode === 13) {
|
||||
get("#confirmButtonYes").click();
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.keyCode === 27) {
|
||||
get("#confirmButtonNo").click();
|
||||
return;
|
||||
}
|
||||
|
||||
let value = e.target.value;
|
||||
if (value !== G_CONFIRM_VALUE) {
|
||||
get("#confirmInput").delClass(STATES["error"]);
|
||||
G_REPO_VALUE = value;
|
||||
}
|
||||
});
|
||||
|
||||
get("#confirmButtonNo").on("click", (e) => {
|
||||
G_CONFIRM = false;
|
||||
get("#confirmInput").value = "";
|
||||
});
|
||||
|
||||
get("#confirmButtonYes").on("click", (e) => {
|
||||
let confirmValue = get("#confirmInput").value.trim();
|
||||
let repoValue = get("#repoSelectInput").value;
|
||||
|
||||
if (confirmValue === repoValue) {
|
||||
G_CONFIRM = true;
|
||||
get("#confirmInput").value = "";
|
||||
} else {
|
||||
get("#confirmInput").addClass(STATES["error"]);
|
||||
}
|
||||
});
|
||||
|
||||
async function init() {
|
||||
// Get query and delete URL parameters.
|
||||
if(G_QUERY.error) alert("Error returned from authorization server: "+q.error); // Check for auth errors.
|
||||
if(G_QUERY.code) {
|
||||
await getToken();
|
||||
G_AUTH = true;
|
||||
window.history.replaceState({}, document.title, window.location.pathname);
|
||||
}
|
||||
get("body").setClass(STATES["auth"], G_AUTH);
|
||||
}
|
||||
|
||||
var G_QUERY = parseQueryString(window.location.search.substring(1));
|
||||
init();</script>
|
||||
</html>
|
||||
42
templates/html/base.html
Normal file
@ -0,0 +1,42 @@
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
||||
<title>Pack</title>
|
||||
<link rel="icon" href="assets/favicon.ico?v=2">
|
||||
<link rel="stylesheet" href="assets/index.css">
|
||||
<link href="https://fonts.googleapis.com/css?family=Quicksand:300,400" rel="stylesheet">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
|
||||
</head>
|
||||
<body>
|
||||
<div id="themeSwitchContainer">
|
||||
<input type="checkbox" id="themeSwitch">
|
||||
<span></span><span></span><span></span>
|
||||
</div>
|
||||
<div id="package">
|
||||
<img src="assets/fragile.svg">
|
||||
<img src="assets/keep_dry.svg">
|
||||
<img src="assets/recycle.svg">
|
||||
<img src="assets/qr_code.svg">
|
||||
</div>
|
||||
{% include "svgTape.svg" %}
|
||||
<div id="packageLabel">
|
||||
<div id="packageLabelTop">{% include "labelTop.html" %}</div>
|
||||
<div id="packageLabelTitle">
|
||||
<h1><b></b></h1>
|
||||
</div>
|
||||
<div id="packageLabelContent">
|
||||
<h1>{{ content_text | upper }}</h1>
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
<div id="packageLabelBot">
|
||||
{% include "labelBot.svg" %}
|
||||
<a href="/">{{ config.domain }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
{% include "js/base.js" %}
|
||||
{% block script %}{% endblock %}
|
||||
</script>
|
||||
</html>
|
||||
47
templates/html/contentDefault.html
Normal file
@ -0,0 +1,47 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<div>
|
||||
<div id="repoSelect">
|
||||
<h1>REPOSITORY:</h1>
|
||||
<input id="repoSelectInput" type="text" size="32" placeholder="<user>/<repository>">
|
||||
<input class="enabled" id="repoSelectButton" type="submit" value="Select">
|
||||
<p id="repoSelectError"></p>
|
||||
</div>
|
||||
<div id="repoInfo">
|
||||
<h1>ACTIONS:</h1>
|
||||
<div id="repoActions">
|
||||
<input class="enabled" id="repoCreate" type="submit" value="Create">
|
||||
<input id="repoDelete" type="submit" value="Delete">
|
||||
<input id="repoSecret" type="submit" value="Regenerate Secret">
|
||||
</div>
|
||||
<div id="repoFeatures">
|
||||
<h1>LINK:</h1>
|
||||
<input id="repoLinkInput" type="text" size="32" readonly>
|
||||
<input class="enabled" id="repoLinkButton" type="submit" value="Copy">
|
||||
<h1>FEATURES:</h1>
|
||||
<div id="featureBox">
|
||||
{% for feature in features %}
|
||||
<input class="feature" type="submit" data-tag="{{ feature | lower }}" value="{{ feature }}">
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="confirmOverlay">
|
||||
<div>
|
||||
<div>
|
||||
<h1>CONFIRMATION:</h1>
|
||||
<input id="confirmInput" type="text" size="32" placeholder="<user>/<repository>">
|
||||
<input class="enabled" id="confirmButtonYes" type="submit" value="Confirm">
|
||||
<input class="enabled" id="confirmButtonNo" type="submit" value="Cancel">
|
||||
<p>This will (irreversibly) delete all associated files! Please type in the full repository name to confirm.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block script %}
|
||||
{% include "js/token.js" %}
|
||||
{% include "js/default.js" %}
|
||||
{% endblock %}
|
||||
75
templates/html/labelBot.svg
Normal file
@ -0,0 +1,75 @@
|
||||
<svg width="1596" height="432" viewBox="0 0 1596 432" version="1.1">
|
||||
<path d="M 0,432 H 12 V 0 H 0 Z" />
|
||||
<path d="m 18,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 36,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 66,432 h 6 V 0 h -6 z" />
|
||||
<path d="M 84,432 H 96 V 0 H 84 Z" />
|
||||
<path d="m 120,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 132,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 150,432 h 24 V 0 h -24 z" />
|
||||
<path d="m 180,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 198,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 216,432 h 24 V 0 h -24 z" />
|
||||
<path d="m 246,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 264,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 276,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 294,432 h 24 V 0 h -24 z" />
|
||||
<path d="m 330,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 342,432 h 24 V 0 h -24 z" />
|
||||
<path d="m 378,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 396,432 h 18 V 0 h -18 z" />
|
||||
<path d="m 426,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 444,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 462,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 474,432 h 18 V 0 h -18 z" />
|
||||
<path d="m 504,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 528,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 540,432 h 18 V 0 h -18 z" />
|
||||
<path d="m 570,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 594,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 606,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 624,432 h 24 V 0 h -24 z" />
|
||||
<path d="m 660,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 678,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 690,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 726,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 756,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 768,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 792,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 828,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 846,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 858,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 876,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 900,432 h 18 V 0 h -18 z" />
|
||||
<path d="m 924,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 960,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 978,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 990,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1020,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 1044,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1056,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1074,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1086,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 1122,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1146,432 h 24 V 0 h -24 z" />
|
||||
<path d="m 1176,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1188,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1206,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 1230,432 h 18 V 0 h -18 z" />
|
||||
<path d="m 1254,432 h 24 V 0 h -24 z" />
|
||||
<path d="m 1284,432 h 18 V 0 h -18 z" />
|
||||
<path d="m 1308,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1320,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1332,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 1356,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1386,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1398,432 h 18 V 0 h -18 z" />
|
||||
<path d="m 1428,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 1452,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1470,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1488,432 h 24 V 0 h -24 z" />
|
||||
<path d="m 1518,432 h 12 V 0 h -12 z" />
|
||||
<path d="m 1548,432 h 18 V 0 h -18 z" />
|
||||
<path d="m 1572,432 h 6 V 0 h -6 z" />
|
||||
<path d="m 1584,432 h 12 V 0 h -12 z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.2 KiB |
27
templates/html/labelTop.html
Normal file
@ -0,0 +1,27 @@
|
||||
<div>
|
||||
<svg width="48" height="48" viewBox="0 0 12.7 12.7" version="1.1">
|
||||
<defs id="defs2" />
|
||||
<path d="m 12.323869,4.1992062 -6.2301843,2.5959093 -1e-7,0.095169 6.3500004,-2.6458336 z" />
|
||||
<path d="M 12.443685,4.2444508 V 4.3735617 L 9.2686845,4.925839 V 4.7967281 Z" />
|
||||
<path d="M 6.0936845,1.6003079 12.443177,4.2450847 9.2686845,4.796728 2.9191918,2.1519511 Z" />
|
||||
<path d="m 9.2686845,3.8880996 0.062387,0.1201924 -3.237387,3.0585598 2e-7,-0.17699 z" />
|
||||
<path d="M 9.2686845,4.7967281 V 4.925839 L 8.6378103,4.6632589 8.7123025,4.564976 Z" />
|
||||
<rect width="6.8791666" height="5.8977885" x="-13.480659" y="9.4293194" transform="matrix(-0.92307692,0.3846154,0,1,0,0)" />
|
||||
<rect width="6.8791666" height="5.8977885" x="-0.27767482" y="4.3512492" transform="matrix(0.92307692,0.3846154,0,1,0,0)" />
|
||||
<path d="M 2.9186843,1.2431113 9.2686845,3.8880996 6.0936849,6.8898618 -0.2563155,4.2448735 Z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<p><b>BYTE TRANSIT FEES PAID</b></p>
|
||||
<p>64 OF 64</p>
|
||||
<p>6.28 TB FIBRE OPTIC EXPRESS RATE</p>
|
||||
<p>ACCEPTS TAR.GZ, ZIP</p>
|
||||
</div>
|
||||
<div>
|
||||
<svg width="618" height="124" viewBox="0 0 618 124" version="1.1">
|
||||
<path d="M 2.1999999e-6,0 H 41.200002 V 123.6 H 2.1999999e-6 Z M 46.350002,0 h 5.15 v 123.6 h -5.15 z m 10.3,0 h 5.15 v 123.6 h -5.15 z m 10.3,0 h 5.15 v 123.6 h -5.15 z m 20.6,0 H 113.3 v 15.45 h 5.15 V 30.9 h -5.15 v 15.45 h -5.15 V 30.9 H 103 V 46.35 H 97.850002 V 30.9 h -5.15 v 15.45 h 5.15 V 61.8 H 103 v 15.450002 h 5.15 V 61.8 h 5.15 v 61.8 H 87.550002 Z M 118.45,0 h 5.15 v 15.45 h -5.15 z m 10.3,0 h 5.15 v 15.45 h -5.15 z m 10.3,0 h 25.75 v 15.45 h 5.15 V 30.9 H 154.5 V 15.45 h -15.45 z m 36.05,0 h 15.45 v 30.9 h -5.15 v 30.9 h 5.15 v 15.450002 h -5.15 v 15.45 h -5.15 V 108.15 h 10.3 V 123.6 H 175.1 Z m 20.6,0 h 5.15 V 15.45 H 195.7 Z M 206,0 h 10.3 v 15.45 h -5.15 V 30.9 h 5.15 V 15.45 h 10.3 V 30.9 h -5.15 v 15.45 h 5.15 V 61.8 h 5.15 v 15.450002 h -5.15 v 15.45 h 5.15 V 108.15 H 226.6 V 123.6 H 216.3 V 92.700002 H 206 V 123.6 h -5.15 V 108.15 H 195.7 V 92.700002 h 5.15 v -15.45 H 206 V 61.8 h 5.15 v 15.450002 h 10.3 V 61.8 H 216.3 V 46.35 H 206 V 61.8 H 190.55 V 46.35 h 5.15 V 30.9 H 206 Z m 20.6,0 h 20.6 v 46.35 h -5.15 V 15.45 H 226.6 Z m 36.05,0 h 10.3 v 30.9 h -5.15 v 15.45 h 5.15 v 30.900002 h -5.15 v 15.45 h 10.3 V 108.15 h 5.15 v 15.45 h -10.3 v -15.45 h -5.15 v 15.45 h -5.15 z m 30.9,0 h 10.3 V 30.9 H 309 V 0 h 5.15 v 30.9 h 5.15 v 15.45 h -5.15 V 61.8 h 5.15 v 15.450002 h 5.15 v 15.45 h -10.3 v -15.45 h -10.3 v 15.45 H 298.7 V 108.15 H 288.4 V 77.250002 h 10.3 V 61.8 h 5.15 V 46.35 H 298.7 V 30.9 h -10.3 v 30.9 h -5.15 V 15.45 h 10.3 z m 25.75,0 h 5.15 v 15.45 h 20.6 V 30.9 H 319.3 Z m 30.9,0 h 5.15 v 15.45 h 5.15 V 0 h 15.45 v 15.45 h -10.3 V 30.9 h -10.3 v 15.45 h 5.15 v 46.350002 h 5.15 V 108.15 h 5.15 v 15.45 h -20.6 z m 46.35,0 H 412 v 15.45 h 5.15 v 30.9 H 412 V 61.8 h 5.15 v 15.450002 h 5.15 V 61.8 h 10.3 v 15.450002 h -5.15 v 15.45 h -20.6 v -15.45 h -10.3 V 61.8 h 10.3 V 46.35 h -10.3 V 30.9 h 5.15 V 15.45 h -5.15 z m 20.6,0 h 5.15 v 15.45 h -5.15 z m 20.6,0 h 25.75 v 15.45 h -5.15 V 30.9 h -5.15 v 15.45 h -5.15 V 61.8 h 5.15 V 46.35 h 5.15 V 77.250002 H 453.2 V 123.6 h -5.15 v -15.45 h -5.15 v 15.45 h -5.15 z m 30.9,0 h 5.15 v 15.45 h -5.15 z m 10.3,0 h 5.15 v 15.45 h -5.15 z m 10.3,0 H 515 V 15.45 H 494.4 V 30.9 h 25.75 V 61.8 H 515 v 15.450002 h -10.3 v 15.45 h 15.45 V 108.15 h -10.3 V 123.6 H 494.4 V 92.700002 h 5.15 V 61.8 H 494.4 V 46.35 h -5.15 z m 36.05,0 h 36.05 V 123.6 H 525.3 Z m 41.2,0 h 5.15 v 123.6 h -5.15 z m 20.6,0 h 5.15 v 123.6 h -5.15 z m 10.3,0 h 5.15 v 123.6 h -5.15 z m 15.45,0 H 618 v 123.6 h -5.15 z M 123.6,15.45 h 5.15 V 30.9 h 5.15 V 15.45 h 5.15 V 30.9 h 5.15 v 15.45 h -10.3 v 30.900002 h 15.45 v 15.45 h 5.15 V 61.8 H 144.2 V 46.35 h 25.75 V 61.8 h -5.15 v 30.900002 h 5.15 V 108.15 H 154.5 V 123.6 H 144.2 V 92.700002 h -5.15 V 123.6 H 133.9 V 108.15 H 123.6 V 92.700002 h 5.15 v -15.45 h -5.15 v 15.45 h -5.15 V 61.8 H 113.3 V 46.35 h 10.3 z m 257.5,0 h 5.15 V 30.9 h -5.15 z m 41.2,0 h 10.3 V 30.9 h -10.3 z m 41.2,0 h 5.15 V 30.9 h -5.15 z m 10.3,0 h 5.15 V 30.9 H 473.8 Z M 231.75,30.9 h 5.15 v 15.45 h -5.15 z m 41.2,0 h 5.15 v 15.45 h -5.15 z m 97.85,0 h 5.15 v 15.45 h 5.15 v 30.900002 h -5.15 V 61.8 h -5.15 z m 15.45,0 h 5.15 v 15.45 h -5.15 z m 72.1,0 h 5.15 v 15.45 h -5.15 z m 10.3,0 h 5.15 v 15.45 h 10.3 V 61.8 h 5.15 v 15.450002 h 5.15 v 15.45 h -5.15 V 123.6 h -30.9 V 77.250002 h 5.15 V 108.15 h 10.3 V 92.700002 h -5.15 v -15.45 h 5.15 V 61.8 h -5.15 V 77.250002 H 463.5 V 46.35 h 5.15 z M 103,46.35 h 5.15 V 61.8 H 103 Z m 149.35,0 h 5.15 v 77.25 h -5.15 V 108.15 H 247.2 V 92.700002 h 5.15 z m 77.25,0 h 15.45 V 61.8 h -10.3 v 15.450002 h 10.3 v 15.45 H 339.9 V 108.15 H 329.6 V 123.6 H 303.85 V 92.700002 h 10.3 V 108.15 h 10.3 V 92.700002 h 5.15 v -15.45 h -5.15 V 61.8 h 5.15 z m 61.8,0 h 5.15 V 61.8 H 391.4 Z M 278.1,61.8 h 5.15 v 15.450002 h -5.15 z m -41.2,15.450002 h 5.15 v 15.45 h -5.15 z m 128.75,0 h 10.3 v 15.45 h 5.15 v -15.45 h 5.15 v 15.45 h 5.15 V 108.15 h -5.15 v 15.45 h -10.3 V 108.15 H 370.8 V 92.700002 h -5.15 z M 103,92.700002 V 108.15 h 5.15 V 92.700002 Z m 293.55,0 h 10.3 V 108.15 h -10.3 z m 30.9,0 h 5.15 V 123.6 h -5.15 z M 118.45,108.15 h 5.15 v 15.45 h -5.15 z m 221.45,0 h 5.15 v 15.45 h -5.15 z m 66.95,0 h 10.3 v 15.45 h -10.3 z" fill-rule="evenodd" style="stroke-width:0.858333" />
|
||||
</svg>
|
||||
<h1 id="login"></h1>
|
||||
</div>
|
||||
</div>
|
||||
78
templates/html/svgTape.svg
Normal file
@ -0,0 +1,78 @@
|
||||
<svg id="packageTape" viewbox="0 0 100 10">
|
||||
<rect width="100" height="0.3" x="0" y="4.85" style="fill:#483320;fill-opacity:0.8" />
|
||||
<rect width="100" height="10" x="0" y="0" style="fill:#111;fill-opacity:0.8" />
|
||||
|
||||
<polygon points="21,0.0 20,0.625 21,1.25 20,1.875 21,2.5 20,3.125 21,3.75 20,4.375 21,5.0 20,5.625 21,6.25 20,6.875 21,7.5 20,8.125 21,8.75 20,9.375 21,10.0 100,10 100,0" style="fill:#111;fill-opacity:0.5"/>
|
||||
<text>
|
||||
<textPath href="#packTape0">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape1">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape2">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape3">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape4">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape5">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape6">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape7">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape8">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape9">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape10">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape11">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape12">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape13">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape14">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape15">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape16">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape17">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape18">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape19">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape20">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape21">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape22">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape23">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape24">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape25">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape26">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape27">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape28">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape29">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape30">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape31">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape32">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape33">PACK.PACK.PACK.PACK.</textPath>
|
||||
<textPath href="#packTape34">PACK.PACK.PACK.PACK.</textPath>
|
||||
</text>
|
||||
<path id="packTape0" fill="none" stroke="none" d="M-3.00 -0.00 l6 20"/>
|
||||
<path id="packTape1" fill="none" stroke="none" d="M-0.60 -2.00 l6 20"/>
|
||||
<path id="packTape2" fill="none" stroke="none" d="M1.80 -4.00 l6 20"/>
|
||||
<path id="packTape3" fill="none" stroke="none" d="M6.00 -0.00 l6 20"/>
|
||||
<path id="packTape4" fill="none" stroke="none" d="M8.40 -2.00 l6 20"/>
|
||||
<path id="packTape5" fill="none" stroke="none" d="M10.80 -4.00 l6 20"/>
|
||||
<path id="packTape6" fill="none" stroke="none" d="M15.00 -0.00 l6 20"/>
|
||||
<path id="packTape7" fill="none" stroke="none" d="M17.40 -2.00 l6 20"/>
|
||||
<path id="packTape8" fill="none" stroke="none" d="M19.80 -4.00 l6 20"/>
|
||||
<path id="packTape9" fill="none" stroke="none" d="M24.00 -0.00 l6 20"/>
|
||||
<path id="packTape10" fill="none" stroke="none" d="M26.40 -2.00 l6 20"/>
|
||||
<path id="packTape11" fill="none" stroke="none" d="M28.80 -4.00 l6 20"/>
|
||||
<path id="packTape12" fill="none" stroke="none" d="M33.00 -0.00 l6 20"/>
|
||||
<path id="packTape13" fill="none" stroke="none" d="M35.40 -2.00 l6 20"/>
|
||||
<path id="packTape14" fill="none" stroke="none" d="M37.80 -4.00 l6 20"/>
|
||||
<path id="packTape15" fill="none" stroke="none" d="M42.00 -0.00 l6 20"/>
|
||||
<path id="packTape16" fill="none" stroke="none" d="M44.40 -2.00 l6 20"/>
|
||||
<path id="packTape17" fill="none" stroke="none" d="M46.80 -4.00 l6 20"/>
|
||||
<path id="packTape18" fill="none" stroke="none" d="M51.00 -0.00 l6 20"/>
|
||||
<path id="packTape19" fill="none" stroke="none" d="M53.40 -2.00 l6 20"/>
|
||||
<path id="packTape20" fill="none" stroke="none" d="M55.80 -4.00 l6 20"/>
|
||||
<path id="packTape21" fill="none" stroke="none" d="M60.00 -0.00 l6 20"/>
|
||||
<path id="packTape22" fill="none" stroke="none" d="M62.40 -2.00 l6 20"/>
|
||||
<path id="packTape23" fill="none" stroke="none" d="M64.80 -4.00 l6 20"/>
|
||||
<path id="packTape24" fill="none" stroke="none" d="M69.00 -0.00 l6 20"/>
|
||||
<path id="packTape25" fill="none" stroke="none" d="M71.40 -2.00 l6 20"/>
|
||||
<path id="packTape26" fill="none" stroke="none" d="M73.80 -4.00 l6 20"/>
|
||||
<path id="packTape27" fill="none" stroke="none" d="M78.00 -0.00 l6 20"/>
|
||||
<path id="packTape28" fill="none" stroke="none" d="M80.40 -2.00 l6 20"/>
|
||||
<path id="packTape29" fill="none" stroke="none" d="M82.80 -4.00 l6 20"/>
|
||||
<path id="packTape30" fill="none" stroke="none" d="M87.00 -0.00 l6 20"/>
|
||||
<path id="packTape31" fill="none" stroke="none" d="M89.40 -2.00 l6 20"/>
|
||||
<path id="packTape32" fill="none" stroke="none" d="M91.80 -4.00 l6 20"/>
|
||||
<path id="packTape33" fill="none" stroke="none" d="M96.00 -0.00 l6 20"/>
|
||||
<path id="packTape34" fill="none" stroke="none" d="M98.40 -2.00 l6 20"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.4 KiB |
690
templates/index.css
Normal file
@ -0,0 +1,690 @@
|
||||
:root {
|
||||
--font-family: 'Quicksand', sans-serif;
|
||||
|
||||
/* Light Colors */
|
||||
--cl-bg: #e0ffdd;
|
||||
--cl-text: black;
|
||||
--cl-dec-text: black;
|
||||
--cl-box: #e7bb69;
|
||||
--cl-box-edge: #c19d59;
|
||||
--cl-box-ridge: #e1b768;
|
||||
--cl-label: white;
|
||||
--cl-lines: black;
|
||||
--cl-login-hover: rgba(255, 255, 255, 0.8);
|
||||
--cl-null-text: #9b9b9b;
|
||||
|
||||
/* Dark Colors */
|
||||
--cd-bg: #111;
|
||||
--cd-text: #fff;
|
||||
--cd-dec-text: #9b9b9b;
|
||||
--cd-box: #262933;
|
||||
--cd-box-edge: #1a1a1a;
|
||||
--cd-box-ridge: #282b35;
|
||||
--cd-label: #222;
|
||||
--cd-lines: #4d4d4d;
|
||||
--cd-login-hover: rgba(0, 0, 0, 0.5);
|
||||
--cd-null-text: #9b9b9b;
|
||||
|
||||
--c-loading: #d6d6d6;
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
--c-bg: var(--cl-bg);
|
||||
--c-text: var(--cl-text);
|
||||
--c-dec-text: var(--cl-dec-text);
|
||||
--c-box: var(--cl-box);
|
||||
--c-box-edge: var(--cl-box-edge);
|
||||
--c-box-ridge: var(--cl-box-ridge);
|
||||
--c-label: var(--cl-label);
|
||||
--c-lines: var(--cl-lines);
|
||||
--c-login-hover: var(--cl-login-hover);
|
||||
--c-null-text: var(--cl-null-text);
|
||||
|
||||
--p-theme-switch-0: 0;
|
||||
--p-theme-switch-1: 1;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
--c-bg: var(--cd-bg);
|
||||
--c-text: var(--cd-text);
|
||||
--c-dec-text: var(--cd-dec-text);
|
||||
--c-box: var(--cd-box);
|
||||
--c-box-edge: var(--cd-box-edge);
|
||||
--c-box-ridge: var(--cd-box-ridge);
|
||||
--c-label: var(--cd-label);
|
||||
--c-lines: var(--cd-lines);
|
||||
--c-login-hover: var(--cd-login-hover);
|
||||
--c-null-text: var(--cd-null-text);
|
||||
|
||||
--p-theme-switch-0: 1;
|
||||
--p-theme-switch-1: 0;
|
||||
}
|
||||
}
|
||||
|
||||
:root:has(#themeSwitch:checked) {
|
||||
/* Swapped light and dark themes. */
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
--c-bg: var(--cl-bg);
|
||||
--c-text: var(--cl-text);
|
||||
--c-dec-text: var(--cl-dec-text);
|
||||
--c-box: var(--cl-box);
|
||||
--c-box-edge: var(--cl-box-edge);
|
||||
--c-box-ridge: var(--cl-box-ridge);
|
||||
--c-label: var(--cl-label);
|
||||
--c-lines: var(--cl-lines);
|
||||
--c-login-hover: var(--cl-login-hover);
|
||||
--c-null-text: var(--cl-null-text);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
--c-bg: var(--cd-bg);
|
||||
--c-text: var(--cd-text);
|
||||
--c-dec-text: var(--cd-dec-text);
|
||||
--c-box: var(--cd-box);
|
||||
--c-box-edge: var(--cd-box-edge);
|
||||
--c-box-ridge: var(--cd-box-ridge);
|
||||
--c-label: var(--cd-label);
|
||||
--c-lines: var(--cd-lines);
|
||||
--c-login-hover: var(--cd-login-hover);
|
||||
--c-null-text: var(--cd-null-text);
|
||||
}
|
||||
}
|
||||
|
||||
html {
|
||||
width: 100%; height: 100%;
|
||||
font-family: var(--font-family);
|
||||
color: var(--c-text);
|
||||
overflow: hidden;
|
||||
|
||||
@media (min-aspect-ratio: 100/135) { /* Wider */
|
||||
font-size: min(calc(100/135 * 1vh), 62.5%);
|
||||
/* Centered around the main box: packageLabel with net height/width 100/135 */
|
||||
}
|
||||
|
||||
@media (max-aspect-ratio: 100/135) { /* longer */
|
||||
font-size: min(calc(100/100 * 1vw), 62.5%);
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
width: 100vw; height: 100%;
|
||||
margin: 0 auto 0 auto;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
background-color: var(--c-bg);
|
||||
}
|
||||
|
||||
#themeSwitchContainer {
|
||||
width: 10rem; height: 10rem;
|
||||
position: fixed;
|
||||
top: 0; left: 0;
|
||||
z-index: 5;
|
||||
user-select: none;
|
||||
|
||||
--sun-color: #fffb15;
|
||||
--moon-color: #ffe598;
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
--day-color: #a3e0ee;
|
||||
--night-color: #222;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
--night-color: #a3e0ee;
|
||||
--day-color: #222;
|
||||
}
|
||||
|
||||
--w: 6deg;
|
||||
--spokes: 10;
|
||||
|
||||
input {
|
||||
width: 100%; height: 100%;
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
span {
|
||||
transition: opacity 0.15s ease-in-out;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
span:nth-child(2) {
|
||||
width: 100%; height: 100%;
|
||||
top: 0; left: 0;
|
||||
background-color: var(--day-color);
|
||||
filter: brightness(100%);
|
||||
transition: background-color 0.15s ease-in-out,
|
||||
filter 0.15s ease-in-out;
|
||||
}
|
||||
|
||||
span:nth-child(3) {
|
||||
width: 4rem; height: 4rem;
|
||||
position: absolute;
|
||||
top: 3rem; left: 3rem;
|
||||
background-color: var(--sun-color);
|
||||
border-radius: 50%;
|
||||
opacity: var(--p-theme-switch-1);
|
||||
}
|
||||
|
||||
span:nth-child(3)::before {
|
||||
content: "";
|
||||
width: 7rem; height: 7rem;
|
||||
position: absolute;
|
||||
top: -1.5rem; left: -1.5rem;
|
||||
border-radius: inherit;
|
||||
background-image: repeating-conic-gradient(
|
||||
from calc(-1*var(--w)/2), var(--sun-color) 0 calc(var(--w) - 2deg),
|
||||
transparent calc(var(--w)) calc(360deg/var(--spokes) - 2deg),
|
||||
var(--sun-color) calc(360deg/var(--spokes))
|
||||
);
|
||||
}
|
||||
|
||||
span:nth-child(4) {
|
||||
width: 6rem; height: 6rem;
|
||||
top: 1.75rem; left: 1.75rem;
|
||||
background-color: var(--moon-color);
|
||||
border-radius: 50%;
|
||||
opacity: var(--p-theme-switch-0);
|
||||
mask-image: radial-gradient(circle, rgba(0,0,0,0) 33%, black 34%);
|
||||
mask-position: -3rem -3rem;
|
||||
mask-repeat: no-repeat;
|
||||
mask-size: 166.66% 166.66%;
|
||||
}
|
||||
|
||||
input:hover ~ span:nth-child(2) {
|
||||
filter: brightness(110%);
|
||||
}
|
||||
|
||||
input:checked ~ span:nth-child(2) {
|
||||
background-color: var(--night-color);
|
||||
}
|
||||
|
||||
input:checked ~ span:nth-child(3) {
|
||||
opacity: var(--p-theme-switch-0);
|
||||
}
|
||||
|
||||
input:checked ~ span:nth-child(4) {
|
||||
opacity: var(--p-theme-switch-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#package {
|
||||
margin: auto;
|
||||
width: 298rem;
|
||||
height: 200rem;
|
||||
--spacing: 0.8rem;
|
||||
background: repeating-linear-gradient(90deg,
|
||||
var(--c-box) 0rem,
|
||||
var(--c-box) var(--spacing),
|
||||
var(--c-box-ridge) var(--spacing),
|
||||
var(--c-box-ridge) calc(2 *var(--spacing))
|
||||
);
|
||||
|
||||
border: 1rem solid var(--c-box-edge);
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
user-select: none;
|
||||
|
||||
img {
|
||||
display: block;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
:nth-child(1) {
|
||||
width: 30rem;
|
||||
top: 6rem; left: 263rem;
|
||||
}
|
||||
|
||||
:nth-child(2) {
|
||||
width: 30rem;
|
||||
top: 6rem; left: 228rem;
|
||||
}
|
||||
|
||||
:nth-child(3) {
|
||||
width: 35rem;
|
||||
top: 162rem; left: 257rem;
|
||||
}
|
||||
|
||||
:nth-child(4) {
|
||||
width: 25rem;
|
||||
top: 165rem; left: 10rem;
|
||||
}
|
||||
}
|
||||
|
||||
#packageTape {
|
||||
margin: auto;
|
||||
height: 30rem;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
|
||||
text {
|
||||
font: 1.5px var(--font-family);
|
||||
fill: rgba(255, 255, 255, 0.4);
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
|
||||
#packageLabel {
|
||||
width: 80rem;
|
||||
height: 115rem;
|
||||
|
||||
outline-width: 5rem;
|
||||
outline-style: solid;
|
||||
outline-color: var(--c-label);
|
||||
|
||||
border-radius: 12px;
|
||||
background-color: var(--c-label);
|
||||
border: 0.5rem solid var(--c-lines);
|
||||
|
||||
transition: background-color 0.15s ease-in-out,
|
||||
border 0.15s ease-in-out,
|
||||
outline-color 0.15s ease-in-out;
|
||||
|
||||
display: grid;
|
||||
grid-template-rows: 2fr 1fr 7fr 2fr;
|
||||
|
||||
z-index: 2;
|
||||
|
||||
svg {
|
||||
fill: var(--c-dec-text);
|
||||
}
|
||||
}
|
||||
|
||||
#packageLabelTop {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 3fr;
|
||||
border-bottom: 0.5rem solid var(--c-lines);
|
||||
|
||||
> div:nth-child(1) {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-right: 0.5rem solid var(--c-lines);
|
||||
|
||||
svg {
|
||||
width: 80%; height: 80%;
|
||||
}
|
||||
}
|
||||
|
||||
> div:nth-child(2) {
|
||||
padding: 3%;
|
||||
display: grid;
|
||||
grid-template-rows: 1fr 1fr;
|
||||
|
||||
> div:nth-child(1) {
|
||||
display: block;
|
||||
color: var(--c-dec-text);
|
||||
user-select: none;
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
font-size: 150%;
|
||||
}
|
||||
|
||||
p:nth-child(1) {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
p:nth-child(2) {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
> div:nth-child(2) {
|
||||
width: 80%;
|
||||
position: relative;
|
||||
|
||||
svg {
|
||||
position: absolute;
|
||||
left: 0; top: 0;
|
||||
width: 35rem; height: 7rem;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#login {
|
||||
display: block;
|
||||
margin: 0;
|
||||
width: 24.8rem; height: 7rem;
|
||||
line-height: 7rem;
|
||||
position: relative;
|
||||
left: 5rem;
|
||||
|
||||
font-size: 6rem;
|
||||
font-family: 'Courier';
|
||||
font-weight: 800;
|
||||
text-align: center;
|
||||
|
||||
transition: background 0.15s ease-in-out,
|
||||
color 0.15s ease-in-out;
|
||||
|
||||
z-index: 4;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
#packageLabelTitle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-bottom: 0.5rem solid var(--c-lines);
|
||||
user-select: none;
|
||||
|
||||
h1 {
|
||||
margin: 1%;
|
||||
font-size: 430%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes cursorWait {
|
||||
0% { content: "█"; }
|
||||
50% { content: ""; }
|
||||
100% { content: "█"; }
|
||||
}
|
||||
|
||||
@keyframes rotate {
|
||||
to { --angle: 360deg; }
|
||||
}
|
||||
|
||||
@property --angle {
|
||||
syntax: "<angle>";
|
||||
initial-value: 0deg;
|
||||
inherits: false;
|
||||
}
|
||||
|
||||
#packageLabelContent {
|
||||
border-bottom: 0.5rem solid var(--c-lines);
|
||||
font-size: 150%;
|
||||
font-family: 'Courier';
|
||||
|
||||
> h1 {
|
||||
padding: 7%;
|
||||
margin: 0;
|
||||
line-height: 100%;
|
||||
color: var(--c-lines);
|
||||
}
|
||||
|
||||
> h1::after {
|
||||
animation: 1.5s infinite normal cursorWait;
|
||||
content: "hello";
|
||||
}
|
||||
|
||||
> div:nth-child(2) {
|
||||
padding: 7% 7% 0 7%;
|
||||
color: var(--c-text);
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0;
|
||||
line-height: 100%;
|
||||
}
|
||||
|
||||
input {
|
||||
background: none;
|
||||
color: var(--c-text);
|
||||
border: 1px solid var(--c-lines);
|
||||
padding: 2%;
|
||||
margin: 2% 0 2% 0;
|
||||
font-size: 150%;
|
||||
font-family: 'Courier';
|
||||
}
|
||||
|
||||
input.{{ state.error }} {
|
||||
outline: 2px solid red !important;
|
||||
}
|
||||
|
||||
input[type=submit] {
|
||||
cursor: pointer;
|
||||
transition: background-color 0.15s ease-in-out;
|
||||
}
|
||||
|
||||
/* Button enabled/disabled. */
|
||||
input[type=submit] {
|
||||
color: var(--c-null-text);
|
||||
border-style: dashed;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
input[type=submit].{{ state.button_on }} {
|
||||
color: var(--c-text);
|
||||
border-style: solid;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
input[type=submit]:hover {
|
||||
background-color: var(--c-login-hover);
|
||||
}
|
||||
|
||||
input:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
input[type=submit].{{ state.loading }} {
|
||||
border: 1px solid transparent;
|
||||
background: linear-gradient(var(--c-label), var(--c-label)) padding-box, conic-gradient(
|
||||
from var(--angle),
|
||||
var(--c-lines) 0% 30%,
|
||||
var(--c-loading) 30% 50%,
|
||||
var(--c-lines) 50% 80%,
|
||||
var(--c-loading) 80% 100%
|
||||
) border-box;
|
||||
animation: 1.5s rotate linear infinite;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
#repoSelect {
|
||||
border-bottom: 2px solid var(--c-lines);
|
||||
|
||||
#repoSelectInput {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
#repoSelectButton {
|
||||
float: right;
|
||||
}
|
||||
|
||||
#repoSelectError {
|
||||
line-height: 100%;
|
||||
height: 3rem;
|
||||
margin: 2% 0 2% 0;
|
||||
}
|
||||
}
|
||||
|
||||
#repoInfo {
|
||||
margin-top: 2%;
|
||||
transition: opacity 0.15s ease-in-out;
|
||||
|
||||
> h1:first-child {
|
||||
margin-top: 4%;
|
||||
}
|
||||
|
||||
#repoActions {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#repoLinkInput::selection {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
#repoLinkButton {
|
||||
float: right;
|
||||
}
|
||||
|
||||
#repoFeatures {
|
||||
margin-top: 2%;
|
||||
transition: opacity 0.15s ease-in-out;
|
||||
|
||||
#featureBox {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
|
||||
.feature {
|
||||
margin-right: 2%;
|
||||
font-weight: 800;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
/* Feature states. */
|
||||
.feature {
|
||||
color: var(--c-null-text);
|
||||
border-style: dashed;
|
||||
}
|
||||
|
||||
.feature.{{ state.feature_on }} {
|
||||
color: var(--c-text);
|
||||
border-style: solid;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#confirmOverlay {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
|
||||
position: absolute;
|
||||
left: 0;
|
||||
z-index: 10;
|
||||
|
||||
transition: opacity 0.15s ease-in-out;
|
||||
|
||||
> div {
|
||||
margin: 30% auto 0 auto;
|
||||
|
||||
width: 80rem;
|
||||
height: 30rem;
|
||||
|
||||
outline-width: 5rem;
|
||||
outline-style: solid;
|
||||
outline-color: var(--c-label);
|
||||
|
||||
border-radius: 12px;
|
||||
background-color: var(--c-label);
|
||||
border: 0.5rem solid var(--c-lines);
|
||||
|
||||
transition: background-color 0.15s ease-in-out,
|
||||
border 0.15s ease-in-out,
|
||||
outline-color 0.15s ease-in-out;
|
||||
|
||||
> div {
|
||||
padding: 7%;
|
||||
|
||||
input[type=submit] {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#confirmOverlay {
|
||||
pointer-events: none;
|
||||
top: 100%;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#confirmOverlay.{{ state.confirm_on }} {
|
||||
pointer-events: auto;
|
||||
top: 0;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Repo selected and created states. */
|
||||
#repoInfo, #repoFeatures {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#repoInfo.{{ state.repo_selected }}, #repoFeatures.{{ state.repo_created }} {
|
||||
opacity: 1
|
||||
}
|
||||
}
|
||||
|
||||
#packageLabelBot {
|
||||
display: grid;
|
||||
grid-template-rows: 6fr 1fr;
|
||||
|
||||
svg {
|
||||
margin: 3% auto 0 auto;
|
||||
width: 80%; height: 85%;
|
||||
}
|
||||
|
||||
a {
|
||||
margin: auto;
|
||||
margin-bottom: 1%;
|
||||
font-size: 2rem;
|
||||
color: var(--c-dec-text);
|
||||
text-decoration: none;
|
||||
transition: filter 0.15s ease-in-out;
|
||||
filter: brightness(100%);
|
||||
}
|
||||
|
||||
a:hover {
|
||||
filter: brightness(120%);
|
||||
}
|
||||
}
|
||||
|
||||
body { /* Default no authentication */
|
||||
#packageLabelTitle h1::before {
|
||||
content: "PRIORITY PACKAGING"
|
||||
}
|
||||
|
||||
#packageLabelContent > div {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#login {
|
||||
background: var(--c-label);
|
||||
color: var(--c-text);
|
||||
}
|
||||
|
||||
#login::before {
|
||||
content: "LOGIN";
|
||||
}
|
||||
|
||||
#login:hover {
|
||||
background-color: var(--c-login-hover);
|
||||
}
|
||||
}
|
||||
|
||||
body.{{ state.auth }} {
|
||||
#packageLabelTitle h1::before {
|
||||
content: "PACKAGE INFO"
|
||||
}
|
||||
|
||||
#packageLabelContent > div {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#packageLabelContent > h1 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#login {
|
||||
color: transparent;
|
||||
background:transparent;
|
||||
}
|
||||
|
||||
#login::before {
|
||||
content: "LOGOUT";
|
||||
}
|
||||
|
||||
#login:hover {
|
||||
background: var(--c-label);
|
||||
color: var(--c-text);
|
||||
}
|
||||
}
|
||||
63
templates/js/base.js
Normal file
@ -0,0 +1,63 @@
|
||||
const CONFIG = {
|
||||
client_id: "{{ config.client_id }}",
|
||||
redirect_uri: "{{ config.domain }}",
|
||||
authorization_endpoint: "{{ config.gitea_host }}/login/oauth/authorize",
|
||||
token_endpoint: "{{ config.gitea_host }}/login/oauth/access_token",
|
||||
requested_scopes: "read:repository,write:repository"
|
||||
};
|
||||
|
||||
var G_AUTH = window.localStorage.getItem("token") !== null;
|
||||
|
||||
document.on = document.addEventListener;
|
||||
function sugar(obj) {
|
||||
obj.on = obj.addEventListener;
|
||||
obj.addClass = (x) => obj.classList.add(x);
|
||||
obj.delClass = (x) => obj.classList.remove(x);
|
||||
obj.hasClass = (x) => obj.classList.contains(x);
|
||||
obj.setClass = (x, y) => obj.classList.toggle(x, y);
|
||||
return obj;
|
||||
}
|
||||
|
||||
function get(s) {
|
||||
let x = [...document.querySelectorAll(s)].map(sugar);
|
||||
return (x.length === 1) ? x[0] : x;
|
||||
}
|
||||
|
||||
// Check if object is empty.
|
||||
function isEmpty(obj) {
|
||||
for (const prop in obj) {
|
||||
if (Object.hasOwn(obj, prop)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns error and resolves promise if necessary.
|
||||
function getErr(f) {
|
||||
return (err) => {
|
||||
if (err instanceof Promise) {
|
||||
return err.then(f);
|
||||
} else {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get("#login").on("click", async (e) => {
|
||||
e.preventDefault();
|
||||
if (G_AUTH) {
|
||||
window.localStorage.clear();
|
||||
window.location = "/";
|
||||
} else {
|
||||
// Build the authorization URL
|
||||
let url = CONFIG.authorization_endpoint
|
||||
+ "?response_type=code"
|
||||
+ "&client_id="+encodeURIComponent(CONFIG.client_id)
|
||||
+ "&scope="+encodeURIComponent(CONFIG.requested_scopes)
|
||||
+ "&redirect_uri="+encodeURIComponent(CONFIG.redirect_uri);
|
||||
|
||||
// Redirect to the authorization server
|
||||
window.location = url;
|
||||
}
|
||||
});
|
||||
@ -1,20 +1,12 @@
|
||||
const CONFIG = {
|
||||
client_id: "3d463405-d098-4038-8b25-a44ca5b9ab9c",
|
||||
redirect_uri: "http://127.0.0.1:3000/",
|
||||
authorization_endpoint: "https://git.kjao.me/login/oauth/authorize",
|
||||
token_endpoint: "https://git.kjao.me/login/oauth/access_token",
|
||||
requested_scopes: "read:repository,write:repository"
|
||||
};
|
||||
|
||||
const STATES = { // Either the non-d
|
||||
auth: "auth",
|
||||
error: "error",
|
||||
loading: "loading",
|
||||
repoSelected: "repoSelected",
|
||||
repoCreated: "repoCreated",
|
||||
buttonOn: "enabled",
|
||||
featureOn: "fEnabled",
|
||||
confirmOn: "enabled",
|
||||
auth: "{{ state.auth }}",
|
||||
error: "{{ state.error }}",
|
||||
loading: "{{ state.loading }}",
|
||||
repoSelected: "{{ state.repo_selected }}",
|
||||
repoCreated: "{{ state.repo_created }}",
|
||||
buttonOn: "{{ state.button_on }}",
|
||||
featureOn: "{{ state.feature_on }}",
|
||||
confirmOn: "{{ state.confirm_on }}",
|
||||
}
|
||||
|
||||
var G_REPO_VALUE = "",
|
||||
@ -23,108 +15,15 @@ var G_REPO_VALUE = "",
|
||||
|
||||
// UTILITY //
|
||||
|
||||
document.on = document.addEventListener;
|
||||
function sugar(obj) {
|
||||
obj.on = obj.addEventListener;
|
||||
obj.addClass = (x) => obj.classList.add(x);
|
||||
obj.delClass = (x) => obj.classList.remove(x);
|
||||
obj.hasClass = (x) => obj.classList.contains(x);
|
||||
obj.setClass = (x, y) => obj.classList.toggle(x, y);
|
||||
return obj;
|
||||
}
|
||||
|
||||
function get(s) {
|
||||
let x = [...document.querySelectorAll(s)].map(sugar);
|
||||
return (x.length === 1) ? x[0] : x;
|
||||
}
|
||||
|
||||
// Check if object is empty.
|
||||
function isEmpty(obj) {
|
||||
for (const prop in obj) {
|
||||
if (Object.hasOwn(obj, prop)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns error and resolves promise if necessary.
|
||||
function getErr(f) {
|
||||
return (err) => {
|
||||
if (err instanceof Promise) {
|
||||
return err.then(f);
|
||||
} else {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parse a query string into an object
|
||||
function parseQueryString(string) {
|
||||
if(string == "") { return {}; }
|
||||
var segments = string.split("&").map(s => s.split("=") );
|
||||
var queryString = {};
|
||||
segments.forEach(s => G_QUERYString[s[0]] = s[1]);
|
||||
segments.forEach(s => queryString[s[0]] = s[1]);
|
||||
return queryString;
|
||||
}
|
||||
|
||||
// Fetch function for applet use case.
|
||||
async function jfetch(url, method, obj={}) {
|
||||
let request = {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": window.localStorage.getItem("token"),
|
||||
},
|
||||
method: method,
|
||||
};
|
||||
|
||||
if (!isEmpty(obj)) request["body"] = JSON.stringify(obj);
|
||||
|
||||
return fetch(url, request)
|
||||
.then((response) => {
|
||||
let contentType = response.headers.get("Content-Type");
|
||||
let json;
|
||||
if (contentType && contentType.indexOf("application/json" !== -1)) {
|
||||
json = response.json();
|
||||
} else { // Reprocess non-json into json.
|
||||
json = response.text().then((text) => {
|
||||
return { status: response.status, "message": text };
|
||||
});
|
||||
}
|
||||
if (!response.ok) { throw json; }
|
||||
return json;
|
||||
});
|
||||
}
|
||||
|
||||
// OAUTH //
|
||||
|
||||
async function getToken() {
|
||||
let response;
|
||||
if (G_QUERY.code) {
|
||||
response = await jfetch("/api/token", "POST", { code: G_QUERY.code });
|
||||
} else {
|
||||
response = await jfetch("/api/token", "PATCH", { code: window.localStorage.getItem("refresh_token") });
|
||||
}
|
||||
|
||||
window.localStorage.setItem("token", response.access_token);
|
||||
window.localStorage.setItem("token_expiry", (Date.now() + response.expires_in*1000).toString());
|
||||
window.localStorage.setItem("refresh_token", response.refresh_token);
|
||||
}
|
||||
|
||||
async function tryRefresh() {
|
||||
if (Date.now() < parseInt(window.localStorage.getItem("token_expiry"))) return; // Not expired.
|
||||
await getToken().catch((err) => {
|
||||
let json = err.json();
|
||||
if (json.status == 401 && json.code === 0) { // Could not refresh, so refresh token expired.
|
||||
window.localStorage.clear();
|
||||
alert(`Could not get new session, did you remove access from Gitea?`);
|
||||
window.location = "/";
|
||||
} else {
|
||||
throw json;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// BUTTON ONCLICK MIDDLEWARE //
|
||||
|
||||
// Refresh token if necessary.
|
||||
@ -137,7 +36,6 @@ function tryAuth(f) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Adds loading classes for UI while awaiting.
|
||||
function doLoading(f) {
|
||||
return async (e) => {
|
||||
@ -188,24 +86,6 @@ document.on("keydown", (e) => {
|
||||
|
||||
// BUTTON ONCLICK FUNCTIONS //
|
||||
|
||||
get("#login").on("click", async (e) => {
|
||||
e.preventDefault();
|
||||
if (G_AUTH) {
|
||||
window.localStorage.clear();
|
||||
window.location = "/";
|
||||
} else {
|
||||
// Build the authorization URL
|
||||
let url = CONFIG.authorization_endpoint
|
||||
+ "?response_type=code"
|
||||
+ "&client_id="+encodeURIComponent(CONFIG.client_id)
|
||||
+ "&scope="+encodeURIComponent(CONFIG.requested_scopes)
|
||||
+ "&redirect_uri="+encodeURIComponent(CONFIG.redirect_uri);
|
||||
|
||||
// Redirect to the authorization server
|
||||
window.location = url;
|
||||
}
|
||||
});
|
||||
|
||||
get("#repoSelectInput").on("keydown", (e) => {
|
||||
if (e.keyCode === 13) {
|
||||
get("#repoSelectButton").click();
|
||||
@ -364,5 +244,4 @@ async function init() {
|
||||
}
|
||||
|
||||
var G_QUERY = parseQueryString(window.location.search.substring(1));
|
||||
var G_AUTH = window.localStorage.getItem("token") !== null;
|
||||
init();
|
||||
56
templates/js/token.js
Normal file
@ -0,0 +1,56 @@
|
||||
// Fetch function for applet use case.
|
||||
async function jfetch(url, method, obj={}) {
|
||||
let request = {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": window.localStorage.getItem("token"),
|
||||
},
|
||||
method: method,
|
||||
};
|
||||
|
||||
if (!isEmpty(obj)) request["body"] = JSON.stringify(obj);
|
||||
|
||||
return fetch(url, request)
|
||||
.then((response) => {
|
||||
let contentType = response.headers.get("Content-Type");
|
||||
let json;
|
||||
if (contentType && contentType.indexOf("application/json" !== -1)) {
|
||||
json = response.json();
|
||||
} else { // Reprocess non-json into json.
|
||||
json = response.text().then((text) => {
|
||||
return { status: response.status, "message": text };
|
||||
});
|
||||
}
|
||||
if (!response.ok) { throw json; }
|
||||
return json;
|
||||
});
|
||||
}
|
||||
|
||||
// OAUTH //
|
||||
|
||||
async function getToken() {
|
||||
let response;
|
||||
if (G_QUERY.code) {
|
||||
response = await jfetch("/api/token", "POST", { code: G_QUERY.code });
|
||||
} else {
|
||||
response = await jfetch("/api/token", "PATCH", { code: window.localStorage.getItem("refresh_token") });
|
||||
}
|
||||
|
||||
window.localStorage.setItem("token", response.access_token);
|
||||
window.localStorage.setItem("token_expiry", (Date.now() + response.expires_in*1000).toString());
|
||||
window.localStorage.setItem("refresh_token", response.refresh_token);
|
||||
}
|
||||
|
||||
async function tryRefresh() {
|
||||
if (Date.now() < parseInt(window.localStorage.getItem("token_expiry"))) return; // Not expired.
|
||||
await getToken().catch((err) => {
|
||||
let json = err.json();
|
||||
if (json.status == 401 && json.code === 0) { // Could not refresh, so refresh token expired.
|
||||
window.localStorage.clear();
|
||||
alert(`Could not get new session, did you remove access from Gitea?`);
|
||||
window.location = "/";
|
||||
} else {
|
||||
throw json;
|
||||
}
|
||||
});
|
||||
}
|
||||