Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5c8e05a4fc | ||
|
|
d791ce393b | ||
|
|
a452231086 | ||
|
|
a392a19c9c | ||
|
|
a864c04702 | ||
|
|
8d2f7296a1 | ||
|
|
040936eb47 | ||
|
|
101beec3ae | ||
|
|
2f1a836bf0 | ||
|
|
62f5e0a1a9 | ||
|
|
cca771e70e | ||
|
|
0c7e6b548f | ||
|
|
8b87e8aa92 | ||
|
|
415bbf2932 | ||
|
|
48df4f18cd | ||
|
|
dc0f9aca4a | ||
|
|
1b9b8e3f6c | ||
|
|
5d10e9dbee | ||
|
|
0adc858c85 | ||
|
|
eda1e8a402 | ||
|
|
4b0e34cdf4 | ||
|
|
c688687ff8 | ||
|
|
d56e5bea62 | ||
|
|
aed7b6b37a | ||
|
|
8114443e97 | ||
|
|
8ba0a33f84 | ||
|
|
661ed61779 | ||
|
|
427f95337f | ||
|
|
fa8490fb4e | ||
|
|
5be1c6381b | ||
|
|
6794a89f79 | ||
|
|
8f19ee7b97 | ||
|
|
c63135ec7f | ||
|
|
5c87f2f22c | ||
|
|
6e6e34c423 | ||
|
|
bb983fb4b2 | ||
|
|
285bbf50e9 | ||
|
|
c2ad2e1151 | ||
|
|
46e796ffaa | ||
|
|
3bf25d86f2 | ||
|
|
2dca4805b0 | ||
|
|
54aa4678d1 | ||
|
|
3ab0e6cade | ||
|
|
41e3b23253 | ||
|
|
b00d780a50 | ||
|
|
71b3e26232 | ||
|
|
40f28c02b9 | ||
|
|
362b22a673 | ||
|
|
d6be9a2bba | ||
|
|
6bfd113a87 | ||
|
|
b7f86ba743 | ||
|
|
2bab274056 | ||
|
|
dd6bffdd0d | ||
|
|
bcc044eb92 | ||
|
|
a7f1982d03 | ||
|
|
d013e0fc78 | ||
|
|
6f69ad93c1 | ||
|
|
7ea2093a91 | ||
|
|
dd32deb2ad | ||
|
|
ad71fb321c | ||
|
|
cc6c28a7ff | ||
|
|
c763087462 | ||
|
|
63ff4ddea0 | ||
|
|
4178fc125d | ||
|
|
dcfa7ad657 | ||
|
|
c061e60664 | ||
|
|
a0dd3ecd68 | ||
|
|
0168a312f2 | ||
|
|
92fe5a5b58 | ||
|
|
7f3d450b32 | ||
|
|
8166339920 | ||
|
|
57424d4a26 | ||
|
|
6511b6dd5d | ||
|
|
0625b97246 | ||
|
|
9f8ce82825 | ||
|
|
c3c925dc84 | ||
|
|
36f3703499 | ||
|
|
6ae59c3711 | ||
|
|
c8f5f85635 | ||
|
|
4e5e186784 | ||
|
|
828f7a513c | ||
|
|
6085998d57 | ||
|
|
71e44d5b65 | ||
|
|
e762bbdbf8 | ||
|
|
fe0d2272f6 | ||
|
|
e017b88adf | ||
|
|
5f76d9cf33 | ||
|
|
85a5bdf4dc | ||
|
|
4abc34ffd1 | ||
|
|
250b1d511b | ||
|
|
59e3b0285a | ||
|
|
f961f993c8 | ||
|
|
adf124c00c | ||
|
|
f8579131e8 | ||
|
|
1dde754724 | ||
|
|
771696fda8 | ||
|
|
dd5f469c83 | ||
|
|
6d3fda12cd | ||
|
|
dc32480563 | ||
|
|
06ac9e18cb | ||
|
|
0648943220 | ||
|
|
7a4a82e872 | ||
|
|
6c0c05cf7f | ||
|
|
efd2db129f | ||
|
|
f4f276f370 | ||
|
|
bff1462e9e | ||
|
|
4d06f33089 | ||
|
|
a433d9ef03 | ||
|
|
58606e1702 | ||
|
|
1ccc9aa72e | ||
|
|
49a9bb5a8b | ||
|
|
380d6ac5c2 | ||
|
|
7d9f76df05 | ||
|
|
96707acb4e | ||
|
|
4e504823c0 | ||
|
|
82faa2e9c9 | ||
|
|
1df9cd8071 | ||
|
|
a8d5e4dd28 | ||
|
|
e59ea39a33 | ||
|
|
62d1dc1eea | ||
|
|
379af7dec2 | ||
|
|
68a45adac7 | ||
|
|
9ea8e29cb0 | ||
|
|
90092c0762 | ||
|
|
b379816178 | ||
|
|
e4353255ca | ||
|
|
923f2c7635 | ||
|
|
a8309ef705 | ||
|
|
bad05485d0 | ||
|
|
38d7799ffa | ||
|
|
6e6696ccd4 | ||
|
|
feb546920e | ||
|
|
81b05b9de4 | ||
|
|
ab10b042be | ||
|
|
26699914cc | ||
|
|
45e4b3c423 | ||
|
|
6a5a139e33 | ||
|
|
1908d3200e | ||
|
|
f4cf40d38f | ||
|
|
514de84b97 | ||
|
|
7e7d0bb354 | ||
|
|
e468b90442 | ||
|
|
926959ab47 | ||
|
|
4663090a8f | ||
|
|
b0868a4d0b | ||
|
|
9088b00006 | ||
|
|
9c0fe8999d | ||
|
|
901aa5f7c1 | ||
|
|
3ee28c035b | ||
|
|
1e31b90905 | ||
|
|
48333041f4 | ||
|
|
717c9dbe89 | ||
|
|
fd86eb7aa7 | ||
|
|
9b4b35eff5 | ||
|
|
ac528caf2b | ||
|
|
fbe626e791 | ||
|
|
9ca37d30d8 | ||
|
|
84986898c8 | ||
|
|
5cebce3f4b | ||
|
|
bb344b14a8 | ||
|
|
20e613b444 | ||
|
|
a0952e0012 | ||
|
|
49e66f809e | ||
|
|
5152ed8731 | ||
|
|
33811a826f | ||
|
|
d33aebfd31 | ||
|
|
7d53c52a6b | ||
|
|
f015a8686e | ||
|
|
ab791d2a2d | ||
|
|
a303858da7 | ||
|
|
4c58c62cfe | ||
|
|
4593332204 | ||
|
|
9f5d8c4280 | ||
|
|
b0d44bf0ba | ||
|
|
59b8434e36 | ||
|
|
e6f27cbaf3 | ||
|
|
6c13df1aff | ||
|
|
44bf059b2f | ||
|
|
9ade464c2e | ||
|
|
aed5d4e05b | ||
|
|
b57648df14 | ||
|
|
7bce887077 | ||
|
|
cacd9c7f95 | ||
|
|
cd64bfe84b | ||
|
|
52ed68ed24 | ||
|
|
20577021a6 | ||
|
|
838a2236a1 | ||
|
|
d03941b792 | ||
|
|
92299c3079 | ||
|
|
d9f05532cd | ||
|
|
2fd2dff126 | ||
|
|
8e14ad0536 | ||
|
|
2b325102f3 | ||
|
|
1f2be606fa | ||
|
|
6b29a2a724 | ||
|
|
f79edeb053 | ||
|
|
84b92096d4 | ||
|
|
70f4814cb1 | ||
|
|
49579eb2b4 | ||
|
|
cc6caeeca9 | ||
|
|
90af22eba1 | ||
|
|
f4b4b41264 | ||
|
|
9918b03c11 | ||
|
|
95f44246bf | ||
|
|
b098723f78 | ||
|
|
a819513a92 | ||
|
|
7531b28b4c | ||
|
|
2b8586d1b7 | ||
|
|
8167291ffc | ||
|
|
0dfcf9607a | ||
|
|
4827831107 | ||
|
|
0ebb6d5d30 | ||
|
|
f4ed5062f6 | ||
|
|
434b129746 | ||
|
|
2f5041ac7d | ||
|
|
24f9766b39 | ||
|
|
ba872217d7 | ||
|
|
b2ae517dac | ||
|
|
32b52dc0c8 | ||
|
|
33a3fe9bbd | ||
|
|
245dc76503 | ||
|
|
21dbfd79d8 | ||
|
|
b9f2250278 | ||
|
|
a0601f1891 | ||
|
|
70403ee433 | ||
|
|
f3cde58c8f | ||
|
|
71c267776a | ||
|
|
359ff94a8c | ||
|
|
efe1c1492f | ||
|
|
2aaaf7c358 | ||
|
|
cefaffa0f0 | ||
|
|
a22d56dc41 | ||
|
|
51eca94504 | ||
|
|
2b6d24d328 | ||
|
|
4932025423 | ||
|
|
c466abf4d0 | ||
|
|
2ece3a8b4c | ||
|
|
3f760e1875 | ||
|
|
1da134c38c | ||
|
|
0bf96e9864 | ||
|
|
1f5c19306e | ||
|
|
db10b3821c | ||
|
|
4245a6d04d | ||
|
|
6920c1159b | ||
|
|
3801e1eade | ||
|
|
3e419303a7 | ||
|
|
0de1e6a3af | ||
|
|
99c415f898 | ||
|
|
f68d83dbf0 | ||
|
|
6e97905bce | ||
|
|
572a10d5a0 | ||
|
|
eaa6199de0 | ||
|
|
70799101e4 | ||
|
|
9cc70d0323 | ||
|
|
20c5da6e55 | ||
|
|
4c356bc368 | ||
|
|
aeb04deae4 | ||
|
|
873e4d6547 | ||
|
|
9ba20304c2 | ||
|
|
252619b1a0 | ||
|
|
38b129de66 | ||
|
|
da028d1af9 | ||
|
|
bba361016d | ||
|
|
c362af1f81 | ||
|
|
520507afd9 | ||
|
|
4e7584167b | ||
|
|
112bd61a25 | ||
|
|
1df8bc0dfe | ||
|
|
f2076fe309 | ||
|
|
67dea15bf2 | ||
|
|
910f19fe55 | ||
|
|
290bf0b6d2 | ||
|
|
4c87a776e6 | ||
|
|
4436093816 | ||
|
|
b85aa7b084 | ||
|
|
99e28b639d | ||
|
|
9b94b4da26 | ||
|
|
5b46986628 | ||
|
|
d0e5690bfd | ||
|
|
ddbfa06bcc | ||
|
|
2c6fc99c68 | ||
|
|
d8ad0ac72c | ||
|
|
9de50d7981 | ||
|
|
2c5c46dc48 | ||
|
|
6423b4cbb9 | ||
|
|
2566aa725a | ||
|
|
eb463bbb2b | ||
|
|
1a8a559d84 | ||
|
|
57c1d787e3 | ||
|
|
999a32424f | ||
|
|
c2ed20ba23 | ||
|
|
01cbb37359 | ||
|
|
3e205e9536 | ||
|
|
b29d6b4478 | ||
|
|
b9424e4c21 | ||
|
|
87fe912d8d | ||
|
|
59343c2f82 | ||
|
|
700fc64383 | ||
|
|
ca256b9949 | ||
|
|
68750f3455 | ||
|
|
906fc417c8 | ||
|
|
ac203c56df | ||
|
|
734ad45f1c | ||
|
|
4a1f2e0dd3 | ||
|
|
24e3514640 | ||
|
|
dadb05e022 | ||
|
|
ca3dfb3c07 | ||
|
|
cf452942fa | ||
|
|
28ee40bebe | ||
|
|
6267752a2a | ||
|
|
2ece24e077 | ||
|
|
59013e62d3 | ||
|
|
824763aae9 | ||
|
|
a8c5b04feb | ||
|
|
64f069ec24 | ||
|
|
515e438d4f | ||
|
|
9ec064f9d9 | ||
|
|
60c6b04a01 | ||
|
|
9deaa81a72 | ||
|
|
ae703db6ee | ||
|
|
267f54bc0e | ||
|
|
8aa26fb2cd | ||
|
|
e7667f2537 | ||
|
|
bac15d2ecf | ||
|
|
ae27e07903 | ||
|
|
605dfa7366 | ||
|
|
85db19e33f | ||
|
|
052bc6b356 | ||
|
|
24985e2bca | ||
|
|
8e3eb8b3d2 | ||
|
|
2be44dbd94 | ||
|
|
7c6b26faa2 | ||
|
|
cfc42512ed | ||
|
|
50f5834296 | ||
|
|
07e91bb73a | ||
|
|
3c547eeed8 | ||
|
|
6f011fce3b | ||
|
|
5aebed95a4 | ||
|
|
8321f9f6e9 | ||
|
|
bf9d69ab56 | ||
|
|
faaff57d2b | ||
|
|
40667ef1c1 | ||
|
|
04b4e3298b | ||
|
|
43cbd3a61e | ||
|
|
bfb091f2f4 | ||
|
|
4974303e6b | ||
|
|
664bb0a663 | ||
|
|
491596d03d | ||
|
|
75538be235 | ||
|
|
1cb99ea2fc | ||
|
|
c0f4bde5fc | ||
|
|
a4430dd49d | ||
|
|
b513d40bd6 | ||
|
|
fbaaf89a21 | ||
|
|
7625a0154e | ||
|
|
396ee803b2 | ||
|
|
5a42319a07 | ||
|
|
61b9820f78 | ||
|
|
a383a45269 | ||
|
|
7bd4869ae6 | ||
|
|
49a6559453 | ||
|
|
2e16a10720 | ||
|
|
cd973b50ff | ||
|
|
b6fc67fff2 | ||
|
|
12f00d785d | ||
|
|
de1ff6ed49 | ||
|
|
d0a6cbe5dd | ||
|
|
35924ce550 | ||
|
|
ad1d8cbedd | ||
|
|
6294ce59f7 | ||
|
|
d445ff40c2 | ||
|
|
c6010c3ab4 | ||
|
|
9da80d7b7d | ||
|
|
2c62e58dbd | ||
|
|
efc54375dd | ||
|
|
0c3946033b | ||
|
|
9dc86aa77d | ||
|
|
0cbe320a5f | ||
|
|
1c749a5310 | ||
|
|
a647a69791 | ||
|
|
12db089c73 | ||
|
|
f5ff7cfcf1 | ||
|
|
2ddf71ec46 | ||
|
|
9017374292 | ||
|
|
633f50cf5b | ||
|
|
1993e9c65b | ||
|
|
8edc8610dc | ||
|
|
6700b373cd | ||
|
|
8d824799a0 | ||
|
|
dc86c62d8b | ||
|
|
4ae4ff72e3 | ||
|
|
958eebb16c | ||
|
|
43e48d2ba6 | ||
|
|
b6d8099c74 | ||
|
|
25bac7c5ce | ||
|
|
5d7a080e39 | ||
|
|
b2a76dba98 | ||
|
|
15ad69c8cb | ||
|
|
e3ca006265 | ||
|
|
961cc13948 | ||
|
|
50da233258 | ||
|
|
15ad58b5cc | ||
|
|
61a27ff430 | ||
|
|
befdb0a708 | ||
|
|
06b79600ac | ||
|
|
b9e633ad06 | ||
|
|
736a78faed | ||
|
|
d76e69f9a7 | ||
|
|
1612e1d142 | ||
|
|
56a33fd4c5 | ||
|
|
1ca3244868 | ||
|
|
8f358f09b8 | ||
|
|
d903de6526 | ||
|
|
c41ade2983 | ||
|
|
99dbbc7f39 | ||
|
|
4dd51cc889 | ||
|
|
54c651f7e2 | ||
|
|
d1c9d7ffdc | ||
|
|
052b40680d | ||
|
|
b0d2519192 | ||
|
|
997da11cc5 | ||
|
|
476232ea22 | ||
|
|
4c83f4e2de | ||
|
|
4bf39e18d9 | ||
|
|
edfa533a4d | ||
|
|
28262145ab | ||
|
|
51136ce982 | ||
|
|
84893ec582 | ||
|
|
382362668e |
No files matched your search
@@ -1,17 +1,26 @@
|
|||||||
name: CIFuzz
|
name: CIFuzz
|
||||||
on: [pull_request]
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- "mongoose.c"
|
||||||
|
- "mongoose.h"
|
||||||
jobs:
|
jobs:
|
||||||
Fuzzing:
|
Fuzzing:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: if ./test/match_changed_files.sh '^src/' ; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
- name: Build Fuzzers
|
- name: Build Fuzzers
|
||||||
id: build
|
id: build
|
||||||
|
if: ${{ env.GO == 1 }}
|
||||||
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
|
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
|
||||||
with:
|
with:
|
||||||
oss-fuzz-project-name: 'mongoose'
|
oss-fuzz-project-name: 'mongoose'
|
||||||
dry-run: false
|
dry-run: false
|
||||||
language: c++
|
language: c++
|
||||||
- name: Run Fuzzers
|
- name: Run Fuzzers
|
||||||
|
if: ${{ env.GO == 1 }}
|
||||||
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
|
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
|
||||||
with:
|
with:
|
||||||
oss-fuzz-project-name: 'mongoose'
|
oss-fuzz-project-name: 'mongoose'
|
||||||
@@ -20,7 +29,7 @@ jobs:
|
|||||||
language: c++
|
language: c++
|
||||||
- name: Upload Crash
|
- name: Upload Crash
|
||||||
uses: actions/upload-artifact@v1
|
uses: actions/upload-artifact@v1
|
||||||
if: failure() && steps.build.outcome == 'success'
|
if: env.GO == 1 && failure() && steps.build.outcome == 'success'
|
||||||
with:
|
with:
|
||||||
name: artifacts
|
name: artifacts
|
||||||
path: ./out/artifacts
|
path: ./out/artifacts
|
||||||
@@ -1,5 +1,10 @@
|
|||||||
name: build
|
name: build
|
||||||
on: [push, pull_request]
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- "**Makefile"
|
||||||
|
- "**.c"
|
||||||
|
- "**.h"
|
||||||
env:
|
env:
|
||||||
IPV6: 0
|
IPV6: 0
|
||||||
jobs:
|
jobs:
|
||||||
@@ -10,7 +15,6 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
cc: [gcc, clang, g++, clang++]
|
cc: [gcc, clang, g++, clang++]
|
||||||
target: [test, mip_test]
|
target: [test, mip_test]
|
||||||
# target: [test]
|
|
||||||
ssl: [MBEDTLS, OPENSSL]
|
ssl: [MBEDTLS, OPENSSL]
|
||||||
name: linux ${{ matrix.target }} CC=${{ matrix.cc }} SSL=${{ matrix.ssl }}
|
name: linux ${{ matrix.target }} CC=${{ matrix.cc }} SSL=${{ matrix.ssl }}
|
||||||
env:
|
env:
|
||||||
@@ -18,61 +22,67 @@ jobs:
|
|||||||
SSL: ${{ matrix.ssl }}
|
SSL: ${{ matrix.ssl }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- run: ./test/setup_ga_network.sh
|
with: { fetch-depth: 2 }
|
||||||
- run: sudo apt-get update ; sudo apt-get install libmbedtls-dev
|
- run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
- run: make ${{ matrix.target }}
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: ./test/setup_ga_network.sh && sudo apt -y update ; sudo apt -y install libmbedtls-dev && make ${{ matrix.target }}
|
||||||
s390:
|
s390:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- run: sudo apt-get update && sudo apt-get install qemu binfmt-support qemu-user-static
|
with: { fetch-depth: 2 }
|
||||||
- run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
|
- run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
- run: make s390
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: sudo apt -y update ; sudo apt -y install qemu binfmt-support qemu-user-static && docker run --rm --privileged multiarch/qemu-user-static --reset -p yes && make s390
|
||||||
armhf:
|
armhf:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- run: sudo apt-get update && sudo apt-get install qemu binfmt-support qemu-user-static
|
with: { fetch-depth: 2 }
|
||||||
- run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
|
- run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
- run: make armhf
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: sudo apt -y update ; sudo apt -y install qemu binfmt-support qemu-user-static && docker run --rm --privileged multiarch/qemu-user-static --reset -p yes && make armhf
|
||||||
linux2:
|
linux2:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- run: sudo apt-get update ; sudo apt-get install libmbedtls-dev valgrind
|
with: { fetch-depth: 2 }
|
||||||
- run: make unamalgamated
|
- run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
- run: make valgrind
|
- if: ${{ env.GO == 1 }}
|
||||||
- run: make mg_prefix
|
run: sudo apt -y update ; sudo apt -y install libmbedtls-dev valgrind
|
||||||
examples:
|
- if: ${{ env.GO == 1 }}
|
||||||
runs-on: ubuntu-latest
|
run: make unamalgamated && make valgrind && make mg_prefix
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- run: sudo apt -y install libmbedtls-dev libpcap-dev
|
|
||||||
- run: make clean examples
|
|
||||||
- run: make clean test MG_ENABLE_POLL=1
|
|
||||||
macos:
|
macos:
|
||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
|
env: { HOMEBREW_NO_AUTO_UPDATE: 1 }
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- run: HOMEBREW_NO_AUTO_UPDATE=1 brew install jq mbedtls openssl
|
with: { fetch-depth: 2 }
|
||||||
- run: make test upload-coverage SSL=OPENSSL ASAN_OPTIONS= OPENSSL=`echo /usr/local/Cellar/openssl*/*`
|
- run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
- run: make test SSL=MBEDTLS ASAN_OPTIONS= MBEDTLS=`echo /usr/local/Cellar/mbedtls*/*`
|
- if: ${{ env.GO == 1 }}
|
||||||
#- run: make mip_test ASAN_OPTIONS=
|
run: brew install jq mbedtls openssl
|
||||||
- run: make mg_prefix
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make test upload-coverage TFLAGS=-DNO_SNTP_CHECK SSL=OPENSSL ASAN_OPTIONS= OPENSSL=`echo /usr/local/Cellar/openssl*/*`
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make test SSL=MBEDTLS TFLAGS=-DNO_SNTP_CHECK ASAN_OPTIONS= MBEDTLS=`echo /usr/local/Cellar/mbedtls*/*`
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make mg_prefix
|
||||||
windows:
|
windows:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- run: make vc98
|
with: { fetch-depth: 2 }
|
||||||
- run: make vc17
|
- run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
- run: make vc22
|
- if: ${{ env.GO == 1 }}
|
||||||
- run: make mingw
|
run: make vc98 vc17 vc22 mingw mingw++
|
||||||
- run: make mingw++
|
|
||||||
arduino-xiao:
|
arduino-xiao:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- run: make arduino-xiao
|
with: { fetch-depth: 2 }
|
||||||
|
- run: if ./test/match_changed_files.sh '^examples/arduino|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make arduino-xiao
|
||||||
arm:
|
arm:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
@@ -83,6 +93,119 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- run: make riscv
|
- run: make riscv
|
||||||
|
|
||||||
|
examples:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- run: sudo apt -y install libmbedtls-dev libpcap-dev
|
||||||
|
- run: make clean examples
|
||||||
|
- run: make clean test MG_ENABLE_POLL=1
|
||||||
|
examples_win:
|
||||||
|
runs-on: windows-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
# - uses: egor-tensin/setup-mingw@v2
|
||||||
|
# with:
|
||||||
|
# platform: x64
|
||||||
|
- name: test they build
|
||||||
|
run: make examples_win
|
||||||
|
shell: cmd
|
||||||
|
- name: test they clean
|
||||||
|
run: make clean_examples_win
|
||||||
|
shell: cmd
|
||||||
|
examples_mac:
|
||||||
|
runs-on: macos-latest
|
||||||
|
env: { HOMEBREW_NO_AUTO_UPDATE: 1 }
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- run: make examples_mac
|
||||||
|
- run: make clean_examples_mac
|
||||||
|
|
||||||
|
test_f7:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/stm32/nucleo-f7" ; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: sudo apt -y update; sudo apt -y install gcc-arm-none-eabi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C examples/stm32/nucleo-f746zg-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C examples/stm32/nucleo-f746zg-freertos test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C examples/stm32/nucleo-f746zg-freertos-tcp test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
- run: echo GO=0 >> $GITHUB_ENV ; if ./test/match_changed_files.sh '^src|examples/stm32/nucleo-f7.*-cube-'; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f746zg-cube-baremetal VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f746zg-cube-freertos VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f746zg-cube-freertos-lwip VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
||||||
|
|
||||||
|
test_f4:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/stm32/nucleo-f4" ; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: sudo apt -y update; sudo apt -y install gcc-arm-none-eabi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C examples/stm32/nucleo-f429zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C examples/stm32/nucleo-f429zi-freertos test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
- run: echo GO=0 >> $GITHUB_ENV ; if ./test/match_changed_files.sh '^src|examples/stm32/nucleo-f4.*-cube-'; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f429zi-cube-baremetal VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f429zi-cube-freertos VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f429zi-cube-freertos-lwip VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
||||||
|
|
||||||
|
test_h7:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with: { fetch-depth: 3 }
|
||||||
|
- run: if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/stm32/nucleo-h7" ; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: sudo apt -y update; sudo apt -y install gcc-arm-none-eabi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C examples/stm32/nucleo-h743zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
- run: echo GO=0 >> $GITHUB_ENV ; if ./test/match_changed_files.sh '^src|examples/stm32/nucleo-h7.*-cube-'; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-h743zi-cube-baremetal VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-h743zi-cube-freertos VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6
|
||||||
|
|
||||||
|
test_tm4c:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/ti/ek-tm4c" ; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: sudo apt -y update; sudo apt -y install gcc-arm-none-eabi
|
||||||
|
- run: echo GO=0 > $GITHUB_ENV ; if ./test/match_changed_files.sh "^src|examples/ti/ek-tm4c1294xl-baremetal" ; then echo GO=1 > $GITHUB_ENV ; fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C examples/ti/ek-tm4c1294xl-baremetal test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
- run: echo GO=0 > $GITHUB_ENV ; if ./test/match_changed_files.sh "^src|examples/ti/ek-tm4c1294xl-freertos" ; then echo GO=1 > $GITHUB_ENV ; fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C examples/ti/ek-tm4c1294xl-freertos test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
|
||||||
|
test_pico_w5500:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/rp2040/pico-w5500" ; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: sudo apt -y update; sudo apt -y install gcc-arm-none-eabi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C examples/rp2040/pico-w5500 test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
|
||||||
matrix_examples:
|
matrix_examples:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
@@ -92,20 +215,14 @@ jobs:
|
|||||||
- path: esp32/device-dashboard
|
- path: esp32/device-dashboard
|
||||||
- path: esp32/uart-bridge
|
- path: esp32/uart-bridge
|
||||||
- path: esp8266/http-client-server
|
- path: esp8266/http-client-server
|
||||||
- path: stm32/nucleo-h743zi-baremetal
|
- path: stm32/nucleo-f429zi-make-baremetal-builtin
|
||||||
target: test
|
- path: stm32/nucleo-f429zi-freertos
|
||||||
- path: stm32/stm32-freertos-tcp
|
- path: stm32/nucleo-f429zi-rndis
|
||||||
- path: stm32/stm32-nucleo-f746z
|
- path: stm32/nucleo-f746zg-make-baremetal-builtin
|
||||||
- path: stm32/stm32-nucleo-f746zg
|
- path: stm32/nucleo-f746zg-freertos
|
||||||
- path: stm32/stm32-nucleo-f429z
|
- path: stm32/nucleo-f746zg-freertos-tcp
|
||||||
- path: stm32/stm32-nucleo-h743z
|
- path: stm32/nucleo-f746zg-rndis
|
||||||
- path: stm32/nucleo-f429zi-baremetal
|
- path: stm32/nucleo-h743zi-make-baremetal-builtin
|
||||||
target: test
|
|
||||||
- path: stm32/nucleo-f429zi-freertos-mip
|
|
||||||
- path: stm32/nucleo-f429zi-usb-rndis
|
|
||||||
- path: stm32/nucleo-f746zg-baremetal
|
|
||||||
- path: stm32/nucleo-f746zg-freertos-mip
|
|
||||||
- path: stm32/nucleo-f746zg-usb-rndis
|
|
||||||
- path: nxp/nxp-mimxrt1020-azurertos
|
- path: nxp/nxp-mimxrt1020-azurertos
|
||||||
- path: nxp/nxp-frdmk66f-freertos
|
- path: nxp/nxp-frdmk66f-freertos
|
||||||
- path: nxp/nxp-lpcxpresso54s018m-freertos
|
- path: nxp/nxp-lpcxpresso54s018m-freertos
|
||||||
@@ -128,30 +245,52 @@ jobs:
|
|||||||
- path: infineon/infineon-xmc4700_4800-lwip-rtx-rtos
|
- path: infineon/infineon-xmc4700_4800-lwip-rtx-rtos
|
||||||
- path: ti/ti-ek-tm4c1294xl-http-server
|
- path: ti/ti-ek-tm4c1294xl-http-server
|
||||||
- path: ti/ek-tm4c1294xl-baremetal
|
- path: ti/ek-tm4c1294xl-baremetal
|
||||||
- path: ti/ek-tm4c1294xl-freertos-mip
|
- path: ti/ek-tm4c1294xl-freertos
|
||||||
- path: rp2040/pico-rmii
|
- path: rp2040/pico-rmii
|
||||||
- path: rp2040/pico-rndis-dashboard
|
- path: rp2040/pico-rndis-dashboard
|
||||||
- path: rp2040/pico-w
|
- path: rp2040/pico-w
|
||||||
- path: rp2040/pico-w5500
|
- path: rp2040/pico-w5500
|
||||||
target: test
|
|
||||||
name: ${{ matrix.example.path }}
|
name: ${{ matrix.example.path }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- run: sudo apt -y install gcc-arm-none-eabi
|
with: { fetch-depth: 2 }
|
||||||
- name: ${{ matrix.example.path }}
|
- run: if ./test/match_changed_files.sh '^src|^examples/${{ matrix.example.path }}'; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
run: make -C examples/${{ matrix.example.path }} ${{ matrix.example.target || 'build' }} VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: sudo apt -y update ; sudo apt -y install gcc-arm-none-eabi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C examples/${{ matrix.example.path }} build
|
||||||
|
|
||||||
|
cube_examples:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: if ./test/match_changed_files.sh '^src|examples/stm32/nucleo-*-cube-*'; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: cd test/cube && make
|
||||||
|
|
||||||
zephyr_examples:
|
zephyr_examples:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- run: make -C examples/zephyr init
|
with: { fetch-depth: 2 }
|
||||||
|
- run: if ./test/match_changed_files.sh '^src/.*.[ch]|^examples/zephyr'; then sudo apt -y update ; sudo apt -y install gcc-arm-none-eabi ; fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C examples/zephyr init
|
||||||
- name: minify manifest
|
- name: minify manifest
|
||||||
|
if: ${{ env.GO == 1 }}
|
||||||
uses: mikefarah/yq@master
|
uses: mikefarah/yq@master
|
||||||
with:
|
with:
|
||||||
cmd: yq -i eval '(.manifest.defaults, .manifest.remotes, .manifest.projects[] | select(.name == "cmsis" or .name == "hal_stm32" or .name == "mbedtls" or .name == "mcuboot" or .name == "picolibc" | del(.null) ), .manifest.self) as $i ireduce({};setpath($i | path; $i)) | del(.manifest.projects.[].null) | del(..|select(length==0))' examples/zephyr/zephyrproject/zephyr/west.yml
|
cmd: yq -i eval '(.manifest.defaults, .manifest.remotes, .manifest.projects[] | select(.name == "cmsis" or .name == "hal_stm32" or .name == "mbedtls" or .name == "mcuboot" or .name == "picolibc" | del(.null) ), .manifest.self) as $i ireduce({};setpath($i | path; $i)) | del(.manifest.projects.[].null) | del(..|select(length==0))' examples/zephyr/zephyrproject/zephyr/west.yml
|
||||||
- run: make -C examples/zephyr update
|
- if: ${{ env.GO == 1 }}
|
||||||
- run: make -C examples/zephyr/device-dashboard build
|
run: make -C examples/zephyr update
|
||||||
- run: make -C examples/zephyr/http-client build
|
- if: ${{ env.GO == 1 }}
|
||||||
- run: make -C examples/zephyr/http-server build
|
run: make -C examples/zephyr/device-dashboard build
|
||||||
- run: make -C examples/zephyr/mqtt-aws-client build
|
- if: ${{ env.GO == 1 }}
|
||||||
- run: make -C examples/zephyr/websocket-server build
|
run: make -C examples/zephyr/http-client build
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C examples/zephyr/http-server build
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C examples/zephyr/mqtt-aws-client build
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C examples/zephyr/websocket-server build
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
SRCS = mongoose.c test/unit_test.c test/packed_fs.c
|
SRCS = mongoose.c test/unit_test.c test/packed_fs.c
|
||||||
HDRS = $(wildcard src/*.h) $(wildcard mip/*.h)
|
HDRS = $(wildcard src/*.h) $(wildcard src/tcpip/*.h)
|
||||||
DEFS ?= -DMG_MAX_HTTP_HEADERS=7 -DMG_ENABLE_LINES -DMG_ENABLE_PACKED_FS=1 -DMG_ENABLE_SSI=1
|
DEFS ?= -DMG_MAX_HTTP_HEADERS=7 -DMG_ENABLE_LINES -DMG_ENABLE_PACKED_FS=1 -DMG_ENABLE_SSI=1 -DMG_ENABLE_ASSERT=1
|
||||||
WARN ?= -pedantic -W -Wall -Werror -Wshadow -Wdouble-promotion -fno-common -Wconversion -Wundef
|
WARN ?= -pedantic -W -Wall -Werror -Wshadow -Wdouble-promotion -fno-common -Wconversion -Wundef
|
||||||
OPTS ?= -O3 -g3
|
OPTS ?= -O3 -g3
|
||||||
INCS ?= -Isrc -I.
|
INCS ?= -Isrc -I.
|
||||||
@@ -13,13 +13,18 @@ IPV6 ?= 1
|
|||||||
ASAN ?= -fsanitize=address,undefined,alignment -fno-sanitize-recover=all -fno-omit-frame-pointer -fno-common
|
ASAN ?= -fsanitize=address,undefined,alignment -fno-sanitize-recover=all -fno-omit-frame-pointer -fno-common
|
||||||
ASAN_OPTIONS ?= detect_leaks=1
|
ASAN_OPTIONS ?= detect_leaks=1
|
||||||
EXAMPLES := $(dir $(wildcard examples/*/Makefile))
|
EXAMPLES := $(dir $(wildcard examples/*/Makefile))
|
||||||
|
EXAMPLES_MAC := $(filter-out examples/mip-pcap/ examples/mip-tap/, $(EXAMPLES))
|
||||||
|
EXAMPLES_WIN := $(dir $(wildcard examples/device-dashboard/Makefile) $(wildcard examples/file-*/Makefile) $(wildcard examples/http-*/Makefile) $(wildcard examples/mqtt-*/Makefile) $(wildcard examples/websocket-*/Makefile) $(wildcard examples/webui-*/Makefile))
|
||||||
|
EXAMPLES_EMBEDDED := $(filter-out $(wildcard examples/zephyr/*/), $(dir $(wildcard examples/*/*/Makefile)))
|
||||||
PREFIX ?= /usr/local
|
PREFIX ?= /usr/local
|
||||||
|
LIBDIR ?= $(PREFIX)/lib
|
||||||
|
INCLUDEDIR ?= $(PREFIX)/include
|
||||||
VERSION ?= $(shell cut -d'"' -f2 src/version.h)
|
VERSION ?= $(shell cut -d'"' -f2 src/version.h)
|
||||||
COMMON_CFLAGS ?= $(C_WARN) $(WARN) $(INCS) $(DEFS) -DMG_ENABLE_IPV6=$(IPV6) $(TFLAGS)
|
COMMON_CFLAGS ?= $(C_WARN) $(WARN) $(INCS) $(DEFS) -DMG_ENABLE_IPV6=$(IPV6) $(TFLAGS) -pthread
|
||||||
CFLAGS ?= $(OPTS) $(ASAN) $(COMMON_CFLAGS)
|
CFLAGS ?= $(OPTS) $(ASAN) $(COMMON_CFLAGS)
|
||||||
VALGRIND_CFLAGS ?= $(OPTS) $(COMMON_CFLAGS)
|
VALGRIND_CFLAGS ?= $(OPTS) $(COMMON_CFLAGS)
|
||||||
VALGRIND_RUN ?= valgrind --tool=memcheck --gen-suppressions=all --leak-check=full --show-leak-kinds=all --leak-resolution=high --track-origins=yes --error-exitcode=1 --exit-on-first-error=yes
|
VALGRIND_RUN ?= valgrind --tool=memcheck --gen-suppressions=all --leak-check=full --show-leak-kinds=all --leak-resolution=high --track-origins=yes --error-exitcode=1 --exit-on-first-error=yes --fair-sched=yes
|
||||||
.PHONY: examples test valgrind mip_test
|
.PHONY: clean_examples examples mip_test test valgrind
|
||||||
|
|
||||||
ifeq "$(findstring ++,$(CC))" ""
|
ifeq "$(findstring ++,$(CC))" ""
|
||||||
# $(CC) does not end with ++, i.e. we're using C. Apply C flags
|
# $(CC) does not end with ++, i.e. we're using C. Apply C flags
|
||||||
@@ -32,13 +37,13 @@ endif
|
|||||||
ifeq "$(SSL)" "MBEDTLS"
|
ifeq "$(SSL)" "MBEDTLS"
|
||||||
MBEDTLS ?= /usr/local
|
MBEDTLS ?= /usr/local
|
||||||
CFLAGS += -DMG_ENABLE_MBEDTLS=1 -I$(MBEDTLS)/include -I/usr/include
|
CFLAGS += -DMG_ENABLE_MBEDTLS=1 -I$(MBEDTLS)/include -I/usr/include
|
||||||
LDFLAGS ?= -L$(MBEDTLS)/lib -lmbedtls -lmbedcrypto -lmbedx509
|
LDFLAGS += -L$(MBEDTLS)/lib -lmbedtls -lmbedcrypto -lmbedx509
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq "$(SSL)" "OPENSSL"
|
ifeq "$(SSL)" "OPENSSL"
|
||||||
OPENSSL ?= /usr/local
|
OPENSSL ?= /usr/local
|
||||||
CFLAGS += -DMG_ENABLE_OPENSSL=1 -I$(OPENSSL)/include
|
CFLAGS += -DMG_ENABLE_OPENSSL=1 -I$(OPENSSL)/include
|
||||||
LDFLAGS ?= -L$(OPENSSL)/lib -lssl -lcrypto
|
LDFLAGS += -L$(OPENSSL)/lib -lssl -lcrypto
|
||||||
endif
|
endif
|
||||||
|
|
||||||
all:
|
all:
|
||||||
@@ -56,6 +61,18 @@ mip_tap_test: test/mip_tap_test.c mongoose.c mongoose.h Makefile
|
|||||||
|
|
||||||
examples:
|
examples:
|
||||||
@for X in $(EXAMPLES); do test -f $$X/Makefile || continue; $(MAKE) -C $$X example || exit 1; done
|
@for X in $(EXAMPLES); do test -f $$X/Makefile || continue; $(MAKE) -C $$X example || exit 1; done
|
||||||
|
clean_examples:
|
||||||
|
for X in $(EXAMPLES); do test -f $$X/Makefile || continue; $(MAKE) -C $$X clean || exit 1; done
|
||||||
|
|
||||||
|
examples_mac:
|
||||||
|
for X in $(EXAMPLES_MAC); do test -f $$X/Makefile || continue; $(MAKE) -C $$X example || exit 1; done
|
||||||
|
clean_examples_mac:
|
||||||
|
for X in $(EXAMPLES_MAC); do test -f $$X/Makefile || continue; $(MAKE) -C $$X clean || exit 1; done
|
||||||
|
|
||||||
|
examples_win:
|
||||||
|
$(foreach X, $(EXAMPLES_WIN), $(MAKE) -C $(X) example &)
|
||||||
|
clean_examples_win:
|
||||||
|
$(foreach X, $(EXAMPLES_WIN), $(MAKE) -C $(X) clean &)
|
||||||
|
|
||||||
test/packed_fs.c: Makefile src/ssi.h test/fuzz.c test/data/a.txt
|
test/packed_fs.c: Makefile src/ssi.h test/fuzz.c test/data/a.txt
|
||||||
$(CC) $(CFLAGS) test/pack.c -o pack
|
$(CC) $(CFLAGS) test/pack.c -o pack
|
||||||
@@ -120,11 +137,11 @@ s390: CC = $(DOCKER) mdashnet/s390 cc
|
|||||||
s390: RUN = $(DOCKER) mdashnet/s390
|
s390: RUN = $(DOCKER) mdashnet/s390
|
||||||
s390: test
|
s390: test
|
||||||
|
|
||||||
arm: DEFS += -DMG_ENABLE_FILE=0 -DMG_ENABLE_MIP=1 -DMG_ARCH=MG_ARCH_NEWLIB
|
arm: DEFS += -DMG_ENABLE_FILE=0 -DMG_ENABLE_TCPIP=1 -DMG_ARCH=MG_ARCH_NEWLIB
|
||||||
arm: mongoose.h $(SRCS)
|
arm: mongoose.h $(SRCS)
|
||||||
$(DOCKER) mdashnet/armgcc arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb $(SRCS) $(OPTS) $(WARN) $(INCS) $(DEFS) $(TFLAGS) -o unit_test -nostartfiles --specs nosys.specs -e 0
|
$(DOCKER) mdashnet/armgcc arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb $(SRCS) $(OPTS) $(WARN) $(INCS) $(DEFS) $(TFLAGS) -o unit_test -nostartfiles --specs nosys.specs -e 0
|
||||||
|
|
||||||
riscv: DEFS += -DMG_ENABLE_FILE=0 -DMG_ENABLE_MIP=1 -DMG_ARCH=MG_ARCH_NEWLIB
|
riscv: DEFS += -DMG_ENABLE_FILE=0 -DMG_ENABLE_TCPIP=1 -DMG_ARCH=MG_ARCH_NEWLIB
|
||||||
riscv: mongoose.h $(SRCS)
|
riscv: mongoose.h $(SRCS)
|
||||||
$(DOCKER) mdashnet/riscv riscv-none-elf-gcc -march=rv32imc -mabi=ilp32 $(SRCS) $(OPTS) $(WARN) $(INCS) $(DEFS) $(TFLAGS) -o unit_test
|
$(DOCKER) mdashnet/riscv riscv-none-elf-gcc -march=rv32imc -mabi=ilp32 $(SRCS) $(OPTS) $(WARN) $(INCS) $(DEFS) $(TFLAGS) -o unit_test
|
||||||
|
|
||||||
@@ -163,24 +180,30 @@ mingw++: Makefile mongoose.h $(SRCS)
|
|||||||
$(DOCKER) mdashnet/mingw x86_64-w64-mingw32-g++ $(SRCS) -W -Wall -Werror -I. $(DEFS) -lwsock32 -o $@.exe
|
$(DOCKER) mdashnet/mingw x86_64-w64-mingw32-g++ $(SRCS) -W -Wall -Werror -I. $(DEFS) -lwsock32 -o $@.exe
|
||||||
|
|
||||||
linux-libs: CFLAGS += -fPIC
|
linux-libs: CFLAGS += -fPIC
|
||||||
|
linux-libs: LDFLAGS += -Wl,-soname,libmongoose.so.$(VERSION)
|
||||||
linux-libs: mongoose.o
|
linux-libs: mongoose.o
|
||||||
$(CC) mongoose.o $(LDFLAGS) -shared -o libmongoose.so.$(VERSION)
|
$(CC) mongoose.o $(LDFLAGS) -shared -o libmongoose.so.$(VERSION)
|
||||||
$(AR) rcs libmongoose.a mongoose.o
|
$(AR) rcs libmongoose.a mongoose.o
|
||||||
|
|
||||||
install: linux-libs
|
install: linux-libs
|
||||||
install -Dm644 libmongoose.a libmongoose.so.$(VERSION) $(DESTDIR)$(PREFIX)/lib
|
install -Dm644 libmongoose.a libmongoose.so.$(VERSION) $(DESTDIR)$(LIBDIR)
|
||||||
ln -s libmongoose.so.$(VERSION) $(DESTDIR)$(PREFIX)/lib/libmongoose.so
|
ln -s libmongoose.so.$(VERSION) $(DESTDIR)$(LIBDIR)/libmongoose.so
|
||||||
install -Dm644 mongoose.h $(DESTDIR)$(PREFIX)/include/mongoose.h
|
install -Dm644 mongoose.h $(DESTDIR)$(INCLUDEDIR)/mongoose.h
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
rm -rf $(DESTDIR)$(PREFIX)/lib/libmongoose.a $(DESTDIR)$(PREFIX)/lib/libmongoose.so.$(VERSION) $(DESTDIR)$(PREFIX)/include/mongoose.h $(DESTDIR)$(PREFIX)/lib/libmongoose.so
|
rm -rf $(DESTDIR)$(LIBDIR)/libmongoose.a $(DESTDIR)$(LIBDIR)/libmongoose.so.$(VERSION) $(DESTDIR)$(INCLUDEDIR)/mongoose.h $(DESTDIR)$(LIBDIR)/libmongoose.so
|
||||||
|
|
||||||
mongoose.c: Makefile $(wildcard src/*) $(wildcard mip/*.c)
|
mongoose.c: Makefile $(wildcard src/*.c) $(wildcard src/tcpip/*.c)
|
||||||
(cat src/license.h; echo; echo '#include "mongoose.h"' ; (for F in src/*.c mip/*.c ; do echo; echo '#ifdef MG_ENABLE_LINES'; echo "#line 1 \"$$F\""; echo '#endif'; cat $$F | sed -e 's,#include ".*,,'; done))> $@
|
(cat src/license.h; echo; echo '#include "mongoose.h"' ; (for F in src/*.c src/tcpip/*.c ; do echo; echo '#ifdef MG_ENABLE_LINES'; echo "#line 1 \"$$F\""; echo '#endif'; cat $$F | sed -e 's,#include ".*,,'; done))> $@
|
||||||
|
|
||||||
mongoose.h: $(HDRS) Makefile
|
mongoose.h: $(HDRS) Makefile
|
||||||
(cat src/license.h; echo; echo '#ifndef MONGOOSE_H'; echo '#define MONGOOSE_H'; echo; cat src/version.h ; echo; echo '#ifdef __cplusplus'; echo 'extern "C" {'; echo '#endif'; cat src/arch.h src/arch_*.h src/net_*.h src/config.h src/str.h src/fmt.h src/log.h src/timer.h src/fs.h src/util.h src/url.h src/iobuf.h src/base64.h src/md5.h src/sha1.h src/event.h src/net.h src/http.h src/ssi.h src/tls.h src/tls_mbed.h src/tls_openssl.h src/ws.h src/sntp.h src/mqtt.h src/dns.h src/json.h src/rpc.h mip/mip.h mip/driver_*.h | sed -e '/keep/! s,#include ".*,,' -e 's,^#pragma once,,'; echo; echo '#ifdef __cplusplus'; echo '}'; echo '#endif'; echo '#endif // MONGOOSE_H')> $@
|
(cat src/license.h; echo; echo '#ifndef MONGOOSE_H'; echo '#define MONGOOSE_H'; echo; cat src/version.h ; echo; echo '#ifdef __cplusplus'; echo 'extern "C" {'; echo '#endif'; cat src/arch.h src/arch_*.h src/net_*.h src/config.h src/str.h src/queue.h src/fmt.h src/printf.h src/log.h src/timer.h src/fs.h src/util.h src/url.h src/iobuf.h src/base64.h src/md5.h src/sha1.h src/event.h src/net.h src/http.h src/ssi.h src/tls.h src/tls_mbed.h src/tls_openssl.h src/ws.h src/sntp.h src/mqtt.h src/dns.h src/json.h src/rpc.h src/tcpip/tcpip.h src/tcpip/driver_*.h | sed -e '/keep/! s,#include ".*,,' -e 's,^#pragma once,,'; echo; echo '#ifdef __cplusplus'; echo '}'; echo '#endif'; echo '#endif // MONGOOSE_H')> $@
|
||||||
|
|
||||||
clean:
|
|
||||||
|
clean: clean_examples clean_embedded
|
||||||
rm -rf $(PROG) *.exe *.o *.dSYM *_test* ut fuzzer *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb slow-unit* _CL_* infer-out data.txt crash-* test/packed_fs.c pack arduino tmp
|
rm -rf $(PROG) *.exe *.o *.dSYM *_test* ut fuzzer *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb slow-unit* _CL_* infer-out data.txt crash-* test/packed_fs.c pack arduino tmp
|
||||||
find examples -maxdepth 3 -name zephyr -prune -o -name Makefile -print | xargs dirname | xargs -n1 make clean -C
|
#find examples -maxdepth 3 -name zephyr -prune -o -name Makefile -print | xargs dirname | xargs -n1 make clean -C
|
||||||
|
|
||||||
|
clean_embedded:
|
||||||
|
for X in $(EXAMPLES_EMBEDDED); do test -f $$X/Makefile || continue; $(MAKE) -C $$X clean || exit 1; done
|
||||||
|
|
||||||
@@ -5,29 +5,33 @@
|
|||||||
[](https://codecov.io/gh/cesanta/mongoose)
|
[](https://codecov.io/gh/cesanta/mongoose)
|
||||||
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:mongoose)
|
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:mongoose)
|
||||||
|
|
||||||
Mongoose is a networking library for C/C++. It implements event-driven
|
Mongoose is a network library for C/C++.
|
||||||
|
It implements event-driven
|
||||||
non-blocking APIs for TCP, UDP, HTTP, WebSocket, MQTT. It is designed for
|
non-blocking APIs for TCP, UDP, HTTP, WebSocket, MQTT. It is designed for
|
||||||
connecting devices and bringing them online. On the market since 2004, used by
|
connecting devices and bringing them online. On the market since 2004, used by
|
||||||
vast number of open source and commercial products - it even runs on the
|
vast number of open source and commercial products - it even runs on the
|
||||||
International Space Station! Mongoose makes embedded network programming fast,
|
International Space Station! Mongoose makes embedded network programming fast,
|
||||||
robust, and easy. Features include:
|
robust, and easy. Features include:
|
||||||
|
|
||||||
- Cross-platform: works on Linux/UNIX, MacOS, Windows, Android, FreeRTOS, etc.
|
- Cross-platform:
|
||||||
- Supported embedded architectures: ESP32, NRF52, STM32, NXP, and more
|
- works on Linux/UNIX, MacOS, Windows, Android
|
||||||
- Built-in protocols: plain TCP/UDP, HTTP, MQTT, Websocket
|
- works on STM32, NXP, ESP32, NRF52, TI, Microchip, and other
|
||||||
|
- write code once - and it'll work everywhere
|
||||||
|
- ideal for the unification of the network infrastructure code across company
|
||||||
|
- Built-in protocols: plain TCP/UDP, SNTP, HTTP, MQTT, Websocket
|
||||||
- SSL/TLS support: mbedTLS, OpenSSL or custom (via API)
|
- SSL/TLS support: mbedTLS, OpenSSL or custom (via API)
|
||||||
- Asynchronous DNS resolver
|
- Asynchronous DNS resolver
|
||||||
- Tiny static and run-time footprint
|
- Tiny static and run-time footprint
|
||||||
- Source code is both ISO C and ISO C++ compliant
|
- Source code is both ISO C and ISO C++ compliant
|
||||||
|
- Very easy to integrate: just copy `mongoose.c` and `mongoose.h` files to your source tree. See
|
||||||
|
[exact steps](https://mongoose.ws/documentation/#2-minute-integration-guide)
|
||||||
- Works with any network stack with socket API, like LwIP or FreeRTOS-Plus-TCP
|
- Works with any network stack with socket API, like LwIP or FreeRTOS-Plus-TCP
|
||||||
- Very easy to integrate: just copy `mongoose.c` and `mongoose.h` files to your build tree
|
- Provides a built-in TCP/IP stack with drivers for bare metal or RTOS systems
|
||||||
- Optional built-in TCP/IP stack with drivers for bare metal or RTOS firmwares
|
- A complete Web device dashboard
|
||||||
- A full device dashboard
|
|
||||||
[bare metal example on Nucleo-F429ZI](examples/stm32/nucleo-f429zi-baremetal)
|
[bare metal example on Nucleo-F429ZI](examples/stm32/nucleo-f429zi-baremetal)
|
||||||
is only 6 files
|
is only 6 files
|
||||||
- For comparison, a CubeIDE generated HTTP example is 400+ files
|
- For comparison, a CubeIDE generated HTTP example is 400+ files
|
||||||
- Detailed [documentation](https://mongoose.ws/documentation/) and
|
- Detailed [user guide, API reference and tons of tutorials](https://mongoose.ws/documentation/) available
|
||||||
[tutorials](https://mongoose.ws/tutorials/)
|
|
||||||
|
|
||||||
|
|
||||||
# Commercial use
|
# Commercial use
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<svg viewBox="-5.229 8.358 512.162 263.062" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
||||||
<image width="512.162" height="263.062" x="-5.229" y="8.358" style="" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAArkAAAFmCAYAAABp3oLTAAAAAXNSR0IArs4c6QAAIABJREFUeF7sXQdYFUcXva9TBQEr9t4ARewFNVbsGhG7wRI1UeyixhLRoGLsXZNYYu8NxQJ2FMGKBcWCSAdp0l79v7PPMe8nqEhRILvfh+B7u7MzZ2Z3ztw5914B8QePAI8AjwCPAI8AjwCPAI8Aj0ARQ0BQxNrDN4dHgEeAR4BHgEeAR4BHgEeAR4B4kssPAh4BHgEeAR4BHgEeAR4BHoEihwBPcotcl/IN4hHgEeAR4BHgEeAR4BHgEeBJLj8GeAR4BHgEeAR4BHgEeAR4BIocAjzJLUJdOmnSpIFxcTGW27fv/F0gEKiLUNP4pvAI8AjwCPAI8AjwCPAIfBECPMn9IrgK9snW1tYX79+/39rYxPh1N4duG4cMGbLewcEhqWDXmq8djwCPAI8AjwCPAI8Aj0DeI8CT3LzH9JuVWL9+/YfPX72s06qVPb18+UoTFR4RbN+23YlxY0Yu6NChQ+I3qxh/Yx4BHgEeAR4BHgEeAR6Br4wAT3K/MuD5eTsrG+ug9Ax1jV/d3EgpV9DVq9fp6pUrFBMVGdisRbMj/fsN2DZoUN8X+VkHvmweAR4BHgEeAR4BHgEegYKAAE9yC0Iv5FEdrKxsglIz1DXmL3AjIgHJpHqUnJREd+/cIW/v8xQVFfHStr6198iRwxY4Ojq+zqPb8sXwCPAI8AjwCPAI8AjwCBQ4BHiSW+C6JOcVsrJu8FiuEtea7jqLRAIRqVVqkojFJJNJSalUkN/Na3ThwlmKjAx7ZtfE7tTg4cPXDOrLW3Zzjjh/JY8AjwCPAI8AjwCPQEFFgCe5BbVnclAvKyubh2lKYZ3ZcxaQQEOkUROJxSKSy+WED4oZG5I8PZXu3r9HFy6cp5BXL17XqV372kjnkfOHDXN6moNb8pfwCPAI8AjwCPAI8AjwCBRIBHiSWyC7JWeVqmdl/SBDLao3a/Y8juASCUmtIRIKhKTRqEmjUZKABGRsbEzv3qXQ06eP6OqVi/Tgwf2whg3rew4Z4Lj8hx9+eJKzu/NX8QjwCPAI8AjwCPAI8AgUHAR4kltw+iLXNalnZX0/Qy2y0iW5GpBcoYg0GhVHdAUCAalUahKLxaQnk1BGeiqFvnlN3hfO0f17dyOq16zuPbj/9+4///zzw1xXiC+AR4BHgEeAR4BHgEeAR+AbIcCT3G8EfH7c9lMkl0hNarWKky/AwqtQKEggIJKIRSQSCUmjVtHz4Gd07rwXBT64H1q5UgUv5+FDfh8/fjxv2c2PzuLL5BHgEeAR4BHgEeARyFcEeJKbr/B+3cKzkitoLblauQKIrlKpJJFI8t6iC9Ir5qy8GAgymYwU8gwKCwuliz4X6Kafb2T5cqWv9e7b181t7tx7X7c1/N14BHgEeAR4BHgEeAR4BHKOAE9yc45dgbvSyso6MF0tqptZriAQCEmtVpJYLOTqrNEISKPRcORXrdaQSoXvxCQSibR/i0QkEhKFhLygS5cvUkDArQjz4qbnBjkNWjxnzozHBa7hfIV4BHgEeAR4BHgEeAR4BDIhwJPcIjQk6llZPZRrJHVmzZrLEVnO8UxNnNUWVlytJldLcrWHhvsO5BbyBcTWhX5XpVJxMgapVEwqlZzevHlDvtev0PWrlyNLlyxxxdGxr9vcuXMfFCHo+KbwCPAI8AjwCPAI8AgUMQR4kluEOrSelfUjhUZce+ZHSC5IrfZHa9EF8dXGGsMwYD9CsGIu/hhHijVEBoZ6XJzdmOgIunzxAt28cSNcX1//yvd9+6xesmTR9SIEId8UHgEeAR4BHgEeAR6BIoIAT3KLSEeiGfWsrB8rNOJaOSO5DAghZ92FBVir19WQQiHXOqgJ1Zx1Nzo6mi6cP093bgfEaTQq/8EDB3j89tuCC0UISr4pPAI8AjwCPAI8AjwChRwBnuQW8g7UrX49K+snCo24ZvZJLq6GZZcd+Fur14XDGrS8IpH4PelVEWmUpNaoSCKRklQsotDQ13TnTgD5eJ9P0NfT83Xo6rBq7arfvYoQpHxTvjICPj4+eqmpqabp6elikUgk0NPTSylfvvy7unXryr9yVfjb8QjwCPAI8AgUcgR4klvIO1C3+nWtrIOUGnGNLyG5SA6hpbpMyqAhlRqaXDERibhoDNDpqtVqEomFJBQKSKlQkFBAJJVKQYkpOSmBrl27QhcvXkxSKxT+ffr0XLt69YojRQhavin5gIC/v7/k8uXLTZ88edLh2bNnjRISEsySkpKMU1JS9BQKhVAgEKgNDQ3lUqk0w8TEJMXS0jKsevXqV6pVq3ZrzJgxvvlQJb5IHgEeAR4BHoEihABPcotQZ9arZ/1UQeLq2SW5ILiC905oILkagYYEpCYVtLhQ7Ko1nFMaky9oBAIuexq9TywhEuJ6LT02MJBR/Ns4juz6+fklJycnXOndo9uWtWvXHi1CEPNNyQME1q5da3vu3LnxT548qR8eHl4xOTm5uE6xiHWHIcXl7HsvFoeInBOSS6VSTbFixaIrVKjwxNra2qdz5857nJz4lNR50C3frIi7d+/WDQ0NbfjmzZsaISEhFeLi4iwSExMN09PTEQEmUU9PL8TY2DiqdOnSTytUqPDa0tLyjYODw5tvVmH+xjwCPAKFBgGe5Baarvp8RRnJRQgxaGoRRQG/ESpMyxkyO55lXSYXjIEjuYjGwJzUtFEa1NAxvA8/pj1H9U+UBqGQZFIJxcW9pUePHpDXmZPvMlKT73Xp1m3L5g3rtn++BfwZRRkBd3f3NidPnpwWGBhok5iYaPm+rSpjY+NQc3PzpyVKlHhXunTpRGNjY5WBgYEIx9u3bw0SEhKMo6KiikdGRprEx8eXUSgUxiC/GI9ly5aNsLa2vjlo0KC5gwcP5iN+FIIBpNFoBK9fvx7i4+Mz/PLlyy38/f2l0PmnpKQQiC3eO5BMoX/x7kK0FxxisViur6+fUKxYsYQqVaqE29raXm7WrNkRR0fHu4Wg2XwVc4jAw4cPpS9evCiRnJxsnJaWJhMIBCI9Pb1UExOTBAcHhyiBAO7R/MEj8BE+wwNTdBAAyVUKJJwlNzck90sRYRMSF3pMIuEc1lQqBSkyUunevTt07uzZjKioiBs9uzls3rbtj91fWj5/fuFGYOfOndW2b9++zM/Pr2lycnIpjUajNjMze1KtWrUXzZo1S6pXr16V+vXrNzQxMZEUK1aMS0qCMYRDLpdzP/Hx8fT8+XO6f/8+PXv27K2fn1/GmzdvDJOSkophzJUtWzasffv224YPH/57q1at4gs3YkWz9iC39+/fn3X27Nlpnp6eJkFBQVy/pqWlcWQW/a6vr096enrcb/Qr3ikIb5iRkcERYJyLv1mcbzMzs0g7Ozu/Ll26bHBxcTlTNJH7b7XqxIkTlrdu3er86NGjjmFhYSVjY2PNEhMTTdLS0vQVCoUEq1uZTKbU09NLNjIyijM3N48uV67cyyZNmpysUaPGw169eoX+txDjW/spBHhLbhEaH9Y29Z8qSVJ9husvpFKxUGFwJIPZ6x/N7T8hxPKm8bC44AcTEou7q4EVmNSkpyejlHfJdOeOP13wvpARGx15r327trsmT3bZYGdnh+C8/FGEEZg2bdqAw4cPz3n+/HltmPwtLCzu29vbB3Tr1q2Kra1tm/Lly5OhoSFHchixhSUPPxhPID7swP9BdGDxA0Hy9fUlLy+v9Js3b2pSUlL0oRG3tbW9MWzYMJexY8f6FWFYC13THj161Mvb23v1vn37yqPv4uLiOKJqampKlpaWVLVqVapSpQr3u0yZMoTFDsguDvR3QkIChYWF0evXr+np06cUHBycERYWpkpJSTHAOSYmJolNmjS57uzs/IuTk9PtQgcQX2Fyd3fv5+PjM/bx48e1oqOjS2ZkZIgwn2Cc4N0hEok0EokEc4ZGoVBIVSoVi3vJoWdgYJBYsmTJ6Dp16jy1t7f/c8aMGYd5WHkEeJJbhMZA/QYNgxQkrjF9+ixSKrHdB6lB/pNcQAjtLiMnDFKRSEhKhZJEYhEZ6EkpJeUdPX70kC6c96LwyDDfFi2bHRg6YMDWnj17JhehbuCbQkQ+Pj7iLVu2/H706NFBqamp5sWKFXtlZ2d3w9nZuXybNm1agNiwA5Y5zomR6WSyQJCNLbagYtvYgYGBdOTIETpw4IAa5EmlUglh1Rk6dKjrb7/9tp/vjG+PwNmzZ5ft3LlzyokTJzjCisWKubk5NWjQgNq0aUOtWrWimjVrcp9ppVUfP7DISUpKoocPH9KFCxfo2rVrbwIDAxWxsbGVcVX58uVfd+3adevgwYNXtmzZkn+vfPvu/2wNXF1dB3l7e4978uSJbVJSkh6ecbFYrDI0NBSUKlVKiHdFiRIlyNjYmIyMjLh5hi18sFiKiIhAWMuMd+/eCZVKpQSk2MTEJLVmzZq3O3fuvPHXX3/dzUsaPtsNRfYEnuQWoa5taNcoSEGSGlOmupJSoX5PPDkJbb5acrXaXW3mNLxg8H8cAkxYXDgyDYmFQhLAUY3wvYIeBj6gs+fO0Juw0KB2rdp4OjkNX9SnT/u4ItQd/9mm+Pj4mC5atGjb1atXu6Snp0urVKlyrWfPnqEDBgxwql27NkdoMVYYoXlvqeHGEJO+ALwP4+j9TgEjwex8kCWUk5iYCFJNhw8fpvPnz8sjIyOlJUqUiHV0dFy0bt26lf/ZjigADd+2bdu+rVu3Ovr7+3N9W7x4cWrRogV1796dmjdvTuXKlfuwwGH9qjsGuPfI+/7XhjbU/qDfU1NTKSQkhLy9veXHjx9/fPPmzdJJSUmlIHNo2rTppfHjx493dHTkddoFYBxkVYWNGzfa7NixY+n9+/ebvHv3zLine truncated
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 163 KiB |
@@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<svg viewBox="-11.551 4.783 524.391 265.184" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
||||||
<image width="524.391" height="265.184" style="" x="-11.551" y="4.783" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAr4AAAFjCAYAAADbzwgZAAAAAXNSR0IArs4c6QAAIABJREFUeF7sXQdYVEcXvVvYpQqiYsUWuyJgb7E3sJcQo7Fgxd4FrFhjrLF3FHuLDewFRMUGCip2QRQRFaV3dvf/zuDohh8EpAjyJh8fxH1v3syZ2Tdn7px7r4iEIiAgICAgICAgICAgICAgICAgUAAQEBWAPgpdFBAQEBAQEBAQEBAQEBAQEBAQIIH4CpNAQEBAQEBAQEBAQEBAQEBAoEAgIBDfAjHMQicFBAQEBAQEBAQEBAQEBAQEBOIrzAEBAQEBAQEBAQEBAQEBAQGBAoGAQHwLxDALnRQQEBAQEBAQEBAQEBAQEBAQiK8wBwQEBAQEBAQEBAQEBAQEBAQKBAIC8S0Qwyx0UkBAQEBAQEBAQEBAQEBAQEAgvgVgDhw/flxv5syZ66tWrRrcr1+/hT169AgrAN0WuiggICAgICAgICAgICAg8B8EBOJbACaEk5NT6YEDB/pLpVJp0aJFnjRp0vR4nz59lltZWX0oAN0XuiggICAgICAgICAgICAgwBAQiG8BmAhbt24tZ2Nj49utW3ed4sWLk4eHB717F/yscePG5/v06fO3lZXVqwIAg9BFAQEBAQEBAQEBAQGBAo6AQHwLwATYsmVLhWHDhj+bPM1e0qJFGwoJCSHf+z50yfUiBb4JfF7XzPzw4MED1lpZWb0pAHAIXRQQEBAQEBAQEBAQECigCAjEtwAM/I4dO34ZNGjIk/GT7ST1GzalxIRE0tHWpMjISHr69BGdPXuGAl48e1K3bh3n4cMHQwIRXABgEbooICAgICAgICAgICBQwBAQiG8BGPCtW7dWGjp0xGNGfBs1o4T4BFIpFSQRi0lbW5tiYiLp2dPHdOH8OfLze36/Vo0axwYPttnQv3+vtwUAHqGLAgICAgICAgICAgICBQQBgfgWgIF2cnKqMnDg4EfjJ9uJGzRsRgkJiUzdDeKbkJhAEpGItOQyUqiU9ND3AV29cpke+D54WrNmjTOD+vdZMHjwYMEJrgDME6GLAgICAgICAgICAj87AgLx/dlHmIi2b99ezdp66MPxk+1EjPgmJVFSkoJEIhFpSCWkVCpIpVQxJDQ1ZSRSqejJ06d0xf0yPX784H7FCsb7f/+t16YxY8Z8LABwCV0UEBAQEBAQEBAQEBD4SREQiO9POrDq3XJ0dKwxePAw3/GT7ahBo2YUG5dAYomYFAoFScUSUqmSSS+KWESkTEokbR0dUiqV5Of3jK5dcaW7d7weGhuXdu77x++LJ06cKMQBLgDzRuiigICAgICAgICAwM+GgEB8f7YRTaU/27dvN7G2HnZv4lR7qtegKcXGxzNrr3rB/6sUSpJIQISVjPRKxBKSSsQklRAFBLykixfPk7f3XS+jYkWODhrQd9OUKVNCCgB8QhcFBAQEBAQEBAQEBAR+EgQE4vuTDOS3urFli1PtYcOG+HDiG5eQkOrlmAww/v5nUqhUzAoMSYREIqagt0F0/twZuuN167Gevt7FP/v8NtPBwUGwABeAeSR0UUBAQEBAQEBAQCC/IyAQ3/w+ghlo//bt282srYfdTY/48qpEX5UPzDKMH8giJCIiOZzgFEkUHPyGPDyukdvlSz6G+voH/+xr9Y+Dg0NMBpojXCIgICAgICAgICAgICAg8EMQEIjvD4E9dx+6dauT+dChQ+5w4hsfn7rFV71Vqi8zAxIIIpUIxFdMKkggpGKSSsWkIZFQ8LtguuzmRrdv3nygrS073qVT+7+WLVsWnbs9FJ4mICAgICAgICAgICAgIJA+AgLxTR+jfH+Fo6NjncGDh3t9Jb6J6fTpq8lXxbTAKlKSiml+SakkpUr52SlOycivXC6noDdv6NatG3TZ9aynplxy2MLCYsOaNWsi8j14QgcEBAQEBAQEBAQEBAR+GgQE4vvTDGXaHeHEd9JUe6rboCnFx4P4pjX0IL1qxJdUJBKLSCSWkFKhYHcplEoSi0SMCCuTFMwRTltbi90XFRFCV69eVrlfdnuWpEhy69Wj2+xVq1a9KwAwC13MQQRUKpVIJFIX4eTgw4SqBQQEBAQEBAR+WgQE4vvTDu3XjjHiO8TGa8o0ezKv1+gz8c3+jmMySSUiksmkLB3y1SvuSIbxKDY25kgfq+7/LF++XIgCkf2w/zQ1qlQqDQ8Pj5qvXr2q8erVq9oBAQHmERERhWJjY2WJiYkiqVSqKFKkSHThwoUDy5Qpc7dSpUoPS5cufd/U1DTwpwFB6IiAgICAgICAQI4iIBDfHIU3b1SeW8QXvU1WRihZQgwdHS0KDw+lO163ydX10ovYmMgr7dq0W75t28YHeQMZoRV5AYFz587V8/Dw+NPT07P1y5cvSwUGBupHRkZKcZLAC481zcPwyWQyhaGhYXS5cuXCTE1NnzVo0GBno0aNXGrWrPkpL/RJaMP3IfDhwwe9z3OgelRUVOHo6OhCRKTU0dGJ0tPTCylcuPDLEiVKvK1ataqwif4+iIW7BAQKPAIC8S0AUyA3iS9EEkiBDCkEMsKBCMtlUoqOjmIE+NKliwEfQz6e69DJYvMux02eBQB+oYtpIODs7Nz4yJEjM93c3OoHBAQUA7kFsUUsaW1tbdLS0mI/0JBLpVJKSkqi6Ohoio2Npfj4ePaTmJisV9fX14+qXr36406dOu3r1q3bHhMTE0Fekw9mnq+vr+zt27fV7t+/3/7evXttnz17Vubt27eGMTExenFxcZpxcXESSFzkcnmSTCaL19TUjDI0NAyrUKHCm7p167qbmpperV69+p1ffvklPB90V2jidyDg7++vqVQq5UqlUpaUlKSUyWSYCwnGxsax31GdcIuAQJpCTwGanwiBXCW+KjGRCBZfJYnEYpKKYQBWMgKspanJJBDe3nfIze3yu48hwbfbtGq6YdeuXad+IriFrqSDwKVLl6oeOnRoyqlTpzq/fv26BAivjo4OFS5cmKpWrcp+qlevTuXKlQOhJU1NTRKLxZSQkEARERFsDj148ICeP39Ojx8/Jn9/fwoPT+Y9mpqaCSYmJj4DBw78a+TIkUeFwcibCLx48ULf3d29vbOz87gHDx5UDgoKMoqKivqPIQabIJlMxjqAsVfPMIl/09HRURYuXPhjrVq1nrVo0eJI69atjzRs2NA/b/ZYaFVGEbh8+XIFf3//On5+fi3evn1rFhQUZBgVFSWPj4+XiMVilba2dlKhQoXiSpQo8bp06dKe5cuXv161atVH9erVe5XRZwjXFWwEBItvARj/3CS+iUlKFutXJCZSJCYxCx4sdWI4yKmgARaTXFNGUVHR9OD+Xbrkejbs/bt3l5s1buJ46ND+EwVgOApsF2G5OXLkSJ9t27ZNffr0aTWFQiE2MDAgExMTRnR79OjB/jYyMmJW35TZBdWBAwmC9Rfk9/r16+Tu7k5XrlxhpDgqKooKFSoU2rFjxzODBg2a3bFjx+cFFvQ81vHg4GCdf//99zdnZ+fR169frx4eHq6DJsKiX6xYsYjixYtHFStWLL5s2bKKQoUKgdzCq5FiYmKkYWFh0qCgIMnHjx813r17p/n27VvdhIQEtobp6OhEmpmZPWnXrt2+Xr16CRb/PDbu6TXn2rVr5c6fP9//7t27HR8+fFguMDCwWGxsrDy9+zBvihQpEleuXLm31apVu9+oUaNDTZs2dRN0/+khV7A/F4hvARh/xPEdYWNzZ9IUWzKt04ASEpJyrNdiiZSSFElM5sDJC/S+mGhikZhFgED0B2SBQyxgRVIc+T54QBcvXIh+GeB/u3XrlhsO7tt9MMcaKFT8QxDw9fUtsWTJkvXHjx9vFR4ebgD5Qu3atal79+7UsWNHqlatGmloaHxOmZ0cVYQnT0mtwZA4YH7BEoyN1du3b+nJkye0a9cucnV1pTdv3rDPzM3NPW1sbCYOGTLk6g/puPDQLwicOXOmwbZt2xZfunSpwcePHxnhLVSoUJSJiUlE06ZNk8zNzUtWqlRJo2TJkkzqAmsv5gQKxhg/kLl8+PCB/Pz8YPVP8vDwiHzw4IE4ICBAH9dpa2tHt2jR4vaff/65uF+/fmcF+PM2Aq6urpWcnZ0nnTp1ysLf37885Eu86OnpJRQqVChGX18/XldXN0lHR0eB9SMqKkocFhYmiYiIkOFdkpCQIOHvC2yWqlWr9qRbt26OHTt23F2nTp2gvI2A0LofgYBAfH8E6rn8TGRuG24z5u6kybZkYlYvR4kvidkr6P97qFRLB/f502QyrCKxBPGBFfTk8SM6f/Fs7KuX/lcbNai7Z/DgQYe6dOkiZIPL5fmS3Y+7fft2xSVLlmw7ceJESxxZ6+npUf/+/alfv35kZmbGpAwgNbDepCxpWX1TOrtxYgQpxMmTJ2nnzp3MEoznVapU6fmQIUMm2dnZOWd334T6MobAypUrh+/bt2/q7du3K2HsDAwMEhs3bvxx9OjRhapVq6ZtbGzMSC7Gm2u906oZWST5vAgJCaE7d+7QoUOHkk6ePJn47t07xFWkihUr+ltZWW3p37//JsHhMWNjlJtX4fRn/fr105ydnQc+fvy4IieuhoaGH83NzRPMzMxkNWvWLAK5U6lSpdg7Aj8oOOnBqQ42u8+fPw++f/9+hI+Pj9zX19cgMjKSbYAgnTI1NfXp37//Ihsbm8Mikeirp2xudlR4Vp5EQCC+eXJYsrdR27btMrUZZeMNi29ts/o5Fs6MtVr8/wQX/8wWs/98BOuvilnlxBIRiZQq0pRrUFxCHPn7PafzZ08rnj9/+qBuXXPnoYMH/dOzZ8+P2YuKUFtuIHDt2rVf5syZs+fSpUsNMdY1atSg4cOHU6dOnahs2bKfZTBiZr1NrXxL7qB+PSxBLine truncated
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 158 KiB |
@@ -1,97 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 1034 239" style="enable-background:new 0 0 1034 239;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{fill:#576174;}
|
|
||||||
.st1{fill:#FFFFFF;}
|
|
||||||
.st2{font-family:'Courier-Bold';}
|
|
||||||
.st3{font-size:16.7604px;}
|
|
||||||
.st4{fill:#00983A;}
|
|
||||||
.st5{fill:none;stroke:#45CFFF;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st6{fill:#45CFFF;}
|
|
||||||
.st7{fill:none;stroke:#A000FF;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st8{fill:#A000FF;}
|
|
||||||
.st9{fill:none;stroke:#FFDE00;stroke-width:2.793;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st10{fill:#FFDE00;}
|
|
||||||
.st11{fill:none;stroke:#EA5B0C;stroke-width:2.793;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st12{fill:#EA5B0C;}
|
|
||||||
</style>
|
|
||||||
<g>
|
|
||||||
<path class="st0" d="M485.3,224.22H8.5c-4.7,0-8.5-3.8-8.5-8.5V27.22c0-4.7,3.8-8.5,8.5-8.5h476.8c4.7,0,8.5,3.8,8.5,8.5v188.5
|
|
||||||
C493.8,220.32,490,224.22,485.3,224.22z"/>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 21.294 60.1267)" class="st1 st2 st3">struct mg_str k,v,s = mg_str(”a=333, b=777”);</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 21.294 136.2499)" class="st1 st2 st3">mg_commalist(&s, &k, &v); </text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 21.294 197.1485)" class="st1 st2 st3">mg_commalist(&s, &k, &v); </text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 291.5096 140.18)" class="st4 st2 st3">// 1st call</text>
|
|
||||||
<text transform="matrix(1 0 0 1 291.5096 199.8101)" class="st4 st2 st3">// 2nd call</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st5" points="336.4,64.52 336.4,68.52 317.8,68.52 317.8,64.52 "/>
|
|
||||||
<g>
|
|
||||||
<path class="st5" d="M122.3,59.62"/>
|
|
||||||
<g>
|
|
||||||
<polyline class="st5" points="327.5,76.82 327.6,94.02 203.3,94.02 203.3,116.12 "/>
|
|
||||||
<path class="st6" d="M331,77.62c0,1.8-1.4,3.2-3.2,3.3c-1.8,0.1-3.2-1.4-3.3-3.2c0-1.8,1.4-3.2,3.2-3.3l0,0
|
|
||||||
C329.5,74.42,331,75.92,331,77.62z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<path class="st6" d="M203.2,114.92c-1.8,0-3.2,1.3-3.3,3s1.4,3,3.2,3s3.2-1.3,3.3-3l0,0C206.5,116.32,205,114.92,203.2,114.92z"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st7" points="407.4,64.52 407.4,68.52 388.8,68.52 388.8,64.52 "/>
|
|
||||||
<g>
|
|
||||||
<path class="st5" d="M193.4,59.62"/>
|
|
||||||
<g>
|
|
||||||
<polyline class="st7" points="398.6,76.82 398.6,149.02 203.4,149.02 203.4,177.12 "/>
|
|
||||||
<path class="st8" d="M402,77.62c0,1.8-1.4,3.2-3.2,3.3c-1.8,0.1-3.2-1.4-3.3-3.2c0-1.8,1.4-3.2,3.2-3.3l0,0
|
|
||||||
C400.6,74.42,402,75.92,402,77.62z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<path class="st8" d="M203.2,175.42c-1.8,0-3.2,1.3-3.3,3s1.4,3,3.2,3s3.2-1.3,3.3-3l0,0C206.5,176.82,205,175.42,203.2,175.42z"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st9" points="440.8,64.52 440.8,68.52 414.2,68.52 414.2,64.52 "/>
|
|
||||||
<g>
|
|
||||||
<path class="st5" d="M218.8,59.62"/>
|
|
||||||
<g>
|
|
||||||
<polyline class="st9" points="428,76.82 428,163.02 245.7,163.02 245.7,176.12 "/>
|
|
||||||
<path class="st10" d="M431.4,77.62c0,1.8-1.4,3.2-3.2,3.3c-1.8,0.1-3.2-1.4-3.3-3.2c0-1.8,1.4-3.2,3.2-3.3l0,0
|
|
||||||
C430,74.42,431.4,75.92,431.4,77.62z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<path class="st10" d="M245.4,175.42c-1.8,0-3.2,1.3-3.3,3s1.4,3,3.2,3s3.2-1.3,3.3-3l0,0C248.7,176.82,247.2,175.42,245.4,175.42z
|
|
||||||
"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st11" points="372.8,64.52 372.8,68.52 343.2,68.52 343.2,64.52 "/>
|
|
||||||
<g>
|
|
||||||
<path class="st5" d="M164.7,59.62"/>
|
|
||||||
<g>
|
|
||||||
<polyline class="st11" points="358.3,76.62 358.3,104.82 245.7,105.02 245.7,116.12 "/>
|
|
||||||
<path class="st12" d="M361.4,77.62c0,1.8-1.4,3.2-3.2,3.3c-1.8,0.1-3.2-1.4-3.3-3.2c0-1.8,1.4-3.2,3.2-3.3l0,0
|
|
||||||
C359.9,74.42,361.4,75.92,361.4,77.62z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<path class="st12" d="M245.7,114.92c-1.8,0-3.2,1.3-3.3,3s1.4,3,3.2,3s3.2-1.3,3.3-3l0,0C248.9,116.32,247.4,114.92,245.7,114.92z
|
|
||||||
"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 3.9 KiB |
@@ -1,48 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 1034 158.07" style="enable-background:new 0 0 1034 158.07;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{fill:#67748A;}
|
|
||||||
.st1{fill:#FFFFFF;}
|
|
||||||
.st2{font-family:'Courier-Bold';}
|
|
||||||
.st3{font-size:16.7604px;}
|
|
||||||
.st4{fill:none;stroke:#45CFFF;stroke-width:2.793;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st5{fill:#45CFFF;}
|
|
||||||
.st6{font-family:'Arial-BoldMT';}
|
|
||||||
</style>
|
|
||||||
<g>
|
|
||||||
<path class="st0" d="M516.7,39.8v56.33c0,4.17-3.8,7.54-8.5,7.54H14.6H8.5c-4.7,0-8.5-3.37-8.5-7.54V39.8c0-4.17,3.8-7.54,8.5-7.54
|
|
||||||
h499.7C512.9,32.26,516.7,35.63,516.7,39.8z"/>
|
|
||||||
<text transform="matrix(1 0 0 1 51.0379 69.3318)" class="st1 st2 st3">GET /test \n\nGET /test \n\nGET test \n\n</text>
|
|
||||||
<g>
|
|
||||||
<polyline class="st4" points="189.5,76.47 189.5,80.47 51.8,80.47 51.8,76.47 "/>
|
|
||||||
<polyline class="st4" points="331.3,76.47 331.3,80.47 195.6,80.47 195.6,76.47 "/>
|
|
||||||
<polyline class="st4" points="462.7,76.47 462.7,80.47 336.9,80.47 336.9,76.47 "/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 78.8909 148.8896)" class="st5 st6 st3">1st request</text>
|
|
||||||
<g>
|
|
||||||
<line class="st4" x1="120.2" y1="93.57" x2="120.3" y2="129.57"/>
|
|
||||||
<path class="st5" d="M117.1,92.57c0-1.8,1.4-3.2,3.2-3.3c1.8,0,3.2,1.4,3.3,3.2c0,1.8-1.4,3.2-3.2,3.3l0,0
|
|
||||||
C118.5,95.77,117.1,94.37,117.1,92.57z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 217.3594 148.8891)" class="st5 st6 st3">2nd request </text>
|
|
||||||
<g>
|
|
||||||
<line class="st4" x1="263.8" y1="93.57" x2="263.9" y2="129.57"/>
|
|
||||||
<path class="st5" d="M260.7,92.57c0-1.8,1.4-3.2,3.2-3.3c1.8,0,3.2,1.4,3.3,3.2c0,1.8-1.4,3.2-3.2,3.3l0,0
|
|
||||||
C262.1,95.77,260.7,94.37,260.7,92.57z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 354.7297 148.8896)" class="st5 st6 st3">3rd request </text>
|
|
||||||
<g>
|
|
||||||
<line class="st4" x1="399.4" y1="93.57" x2="399.4" y2="129.57"/>
|
|
||||||
<path class="st5" d="M396.2,92.57c0-1.8,1.4-3.2,3.2-3.3c1.8,0,3.2,1.4,3.3,3.2c0,1.8-1.4,3.2-3.2,3.3l0,0
|
|
||||||
C397.7,95.77,396.2,94.37,396.2,92.57z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 2.2 KiB |
@@ -1,113 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 1035.4 429.9" style="enable-background:new 0 0 1035.4 429.9;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{fill:#576174;}
|
|
||||||
.st1{fill:#67748A;}
|
|
||||||
.st2{fill:none;stroke:#87005B;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st3{fill:#87005B;}
|
|
||||||
.st4{fill:#FFFFFF;}
|
|
||||||
.st5{font-family:'Courier-Bold';}
|
|
||||||
.st6{font-size:16.7604px;}
|
|
||||||
.st7{fill:none;stroke:#EA5B0C;stroke-width:2.793;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st8{fill:#EA5B0C;}
|
|
||||||
.st9{fill:none;stroke:#CA70FF;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st10{fill:#CA70FF;}
|
|
||||||
.st11{fill:none;stroke:#FFDE00;stroke-width:2.793;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st12{fill:#FFDE00;}
|
|
||||||
.st13{fill:none;stroke:#00CF4F;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st14{fill:#00CF4F;}
|
|
||||||
.st15{fill:none;stroke:#45CFFF;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st16{fill:none;stroke:#EA5B0C;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st17{font-family:'Arial-BoldMT';}
|
|
||||||
.st18{font-size:24px;}
|
|
||||||
.st19{fill:#45CFFF;}
|
|
||||||
</style>
|
|
||||||
<g>
|
|
||||||
<path class="st0" d="M755.8,391.8H8.5c-4.7,0-8.5-3.8-8.5-8.5v-153c0-4.7,3.8-8.5,8.5-8.5h747.3c4.7,0,8.5,3.8,8.5,8.5v153
|
|
||||||
C764.3,388,760.5,391.8,755.8,391.8z"/>
|
|
||||||
<path class="st1" d="M996.9,261.5h-427c-4.7,0-8.5-3.8-8.5-8.5V81.2c0-4.7,3.8-8.5,8.5-8.5h427c4.7,0,8.5,3.8,8.5,8.5V253
|
|
||||||
C1005.4,257.7,1001.5,261.5,996.9,261.5z"/>
|
|
||||||
<g>
|
|
||||||
<polyline class="st2" points="598.1,238.2 598.1,242.3 787.7,242.3 787.7,238.2 "/>
|
|
||||||
<g>
|
|
||||||
<line class="st2" x1="689.3" y1="342.2" x2="276.4" y2="343.3"/>
|
|
||||||
<g>
|
|
||||||
<line class="st2" x1="689.4" y1="253.3" x2="689.4" y2="342.1"/>
|
|
||||||
<path class="st3" d="M689.4,249.3c1.8,0,3.2,1.4,3.3,3.2c0,1.8-1.4,3.2-3.2,3.3c-1.8,0-3.2-1.4-3.3-3.2l0,0
|
|
||||||
C686.1,250.7,687.6,249.3,689.4,249.3z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<path class="st3" d="M274.2,340.4c1.8,0,3.2,1.4,3.3,3.2s-1.4,3.2-3.2,3.3c-1.8,0-3.2-1.4-3.3-3.2l0,0
|
|
||||||
C270.9,341.8,272.4,340.4,274.2,340.4z"/>
|
|
||||||
</g>
|
|
||||||
<text transform="matrix(1 0 0 1 26.0923 262.5192)" class="st4 st5 st6">struct mg_http_message {</text>
|
|
||||||
<text transform="matrix(1 0 0 1 45.542 286.2874)" class="st4 st5 st6">struct mg_str method; uri, query, proto; </text>
|
|
||||||
<text transform="matrix(1 0 0 1 45.542 306.3874)" class="st4 st5 st6">struct mg_http_header headers[MG_MAX_HTTP_HEADERS];</text>
|
|
||||||
<text transform="matrix(1 0 0 1 45.542 326.4874)" class="st4 st5 st6">struct mg_str body;</text>
|
|
||||||
<text transform="matrix(1 0 0 1 45.542 346.5874)" class="st4 st5 st6">struct mg_str message; </text>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st7" points="621.1,89.6 621.1,78.6 215.4,79.7 215.3,269.4 "/>
|
|
||||||
<path class="st8" d="M624.3,90.6c0,1.8-1.4,3.2-3.2,3.3c-1.8,0-3.2-1.4-3.3-3.2c0-1.8,1.4-3.2,3.2-3.3l0,0
|
|
||||||
C622.8,87.4,624.3,88.8,624.3,90.6z"/>
|
|
||||||
</g>
|
|
||||||
<path class="st8" d="M212.3,269.4c0-1.8,1.4-3.2,3.2-3.3c1.8,0,3.2,1.4,3.3,3.2c0,1.8-1.4,3.2-3.2,3.3l0,0
|
|
||||||
C213.7,272.6,212.3,271.2,212.3,269.4z"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st9" points="597.2,183.6 593.1,183.6 593.1,127.8 597.2,127.8 "/>
|
|
||||||
<g>
|
|
||||||
<polyline class="st9" points="582.4,156.2 575.2,156.2 575,302.8 563.4,302.8 "/>
|
|
||||||
<path class="st10" d="M586.1,156.2c0-1.8-1.4-3.2-3.2-3.3c-1.8,0-3.2,1.4-3.3,3.2c0,1.8,1.4,3.2,3.2,3.3l0,0
|
|
||||||
C584.7,159.4,586.1,158,586.1,156.2z"/>
|
|
||||||
<path class="st10" d="M564.2,303c0-1.8-1.4-3.2-3.2-3.3c-1.8,0-3.2,1.4-3.3,3.2s1.4,3.2,3.2,3.3l0,0
|
|
||||||
C562.7,306.2,564.2,304.7,564.2,303z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<text transform="matrix(1 0 0 1 601.1215 118.1291)" class="st4 st5 st6">POST /foo/bar/baz?aa=b&cc=ddd HTTP/1.1</text>
|
|
||||||
<text transform="matrix(1 0 0 1 601.1215 138.2291)" class="st4 st5 st6">Content-Type: application/json</text>
|
|
||||||
<text transform="matrix(1 0 0 1 601.1215 158.3291)" class="st4 st5 st6">Content-Length: 19</text>
|
|
||||||
<text transform="matrix(1 0 0 1 601.1215 178.4291)" class="st4 st5 st6">Host: reqbin.com</text>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st11" points="712.3,90.6 712.4,67.6 277.8,67.6 279.7,269.3 "/>
|
|
||||||
<path class="st12" d="M715.6,90.8c0,1.8-1.4,3.2-3.2,3.3c-1.8,0-3.2-1.4-3.3-3.2c0-1.8,1.4-3.2,3.2-3.3l0,0
|
|
||||||
C714.1,87.6,715.6,89.1,715.6,90.8z"/>
|
|
||||||
</g>
|
|
||||||
<path class="st12" d="M276.5,269.4c0-1.8,1.4-3.2,3.2-3.3s3.2,1.4,3.3,3.2s-1.4,3.2-3.2,3.3l0,0
|
|
||||||
C278,272.6,276.5,271.2,276.5,269.4z"/>
|
|
||||||
</g>
|
|
||||||
<polyline class="st11" points="771.5,104.3 771.5,100.3 652.7,100.3 652.7,104.3 "/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st13" points="836.3,90.6 836.3,56.6 342.8,56.6 344.7,268.3 "/>
|
|
||||||
<path class="st14" d="M839.5,90.6c0,1.8-1.4,3.2-3.2,3.3c-1.8,0-3.2-1.4-3.3-3.2c0-1.8,1.4-3.2,3.2-3.3l0,0
|
|
||||||
C838,87.4,839.5,88.9,839.5,90.6z"/>
|
|
||||||
</g>
|
|
||||||
<path class="st14" d="M341.4,269.3c0-1.8,1.4-3.2,3.2-3.3c1.8,0,3.2,1.4,3.3,3.2c0,1.8-1.4,3.2-3.2,3.3l0,0
|
|
||||||
C342.9,272.5,341.4,271.1,341.4,269.3z"/>
|
|
||||||
</g>
|
|
||||||
<polyline class="st15" points="981.4,104.2 981.4,100.2 902.6,100.2 902.6,104.2 "/>
|
|
||||||
</g>
|
|
||||||
<text transform="matrix(1 0 0 1 596.891 232.3658)" class="st4 st5 st6">{"success": "true"}</text>
|
|
||||||
<polyline class="st16" points="643.1,104.4 643.1,100.4 599.3,100.4 599.3,104.4 "/>
|
|
||||||
<text transform="matrix(1 0 0 1 9.5506 207.5157)" class="st17 st18">Source Code</text>
|
|
||||||
<text transform="matrix(1 0 0 1 797.0799 32.3923)" class="st17 st18">HTTP message</text>
|
|
||||||
<text transform="matrix(1 0 0 1 26.0924 359.209)" class="st4 st5 st6">};</text>
|
|
||||||
<polyline class="st13" points="894.2,104.2 894.2,100.2 774.4,100.2 774.4,104.2 "/>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st15" points="941.3,90.6 941.3,45.6 412.8,45.6 414.7,268.3 "/>
|
|
||||||
<path class="st19" d="M944.5,90.6c0,1.8-1.4,3.2-3.2,3.3c-1.8,0-3.2-1.4-3.3-3.2c0-1.8,1.4-3.2,3.2-3.3l0,0
|
|
||||||
C943,87.4,944.5,88.9,944.5,90.6z"/>
|
|
||||||
</g>
|
|
||||||
<path class="st19" d="M411.4,269.3c0-1.8,1.4-3.2,3.2-3.3c1.8,0,3.2,1.4,3.3,3.2c0,1.8-1.4,3.2-3.2,3.3l0,0
|
|
||||||
C412.9,272.5,411.4,271.1,411.4,269.3z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 6.0 KiB |
@@ -1,109 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 1034 663.54" style="enable-background:new 0 0 1034 663.54;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{fill:none;stroke:#45CFFF;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st1{fill:#45CFFF;}
|
|
||||||
.st2{fill:#576174;}
|
|
||||||
.st3{fill:#FFFFFF;}
|
|
||||||
.st4{font-family:'Courier-Bold';}
|
|
||||||
.st5{font-size:16.7604px;}
|
|
||||||
.st6{font-family:'Arial-BoldMT';}
|
|
||||||
.st7{font-size:24px;}
|
|
||||||
.st8{fill:#67748A;}
|
|
||||||
.st9{fill:#8B9CBA;}
|
|
||||||
.st10{fill:none;stroke:#00CF4F;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st11{fill:#00CF4F;}
|
|
||||||
.st12{fill:none;stroke:#EA5B0C;stroke-width:2.793;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st13{fill:#EA5B0C;}
|
|
||||||
.st14{fill:#414857;}
|
|
||||||
</style>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st0" points="498.5,624.21 498.5,628.21 447.9,628.21 447.9,624.21 "/>
|
|
||||||
<g>
|
|
||||||
<path class="st0" d="M491.8,844.81"/>
|
|
||||||
<g>
|
|
||||||
<path class="st1" d="M473.8,636.11c-1.8,0-3.2,1.4-3.3,3.2c0,1.8,1.4,3.2,3.2,3.3c1.8,0,3.2-1.4,3.3-3.2l0,0
|
|
||||||
C477.1,637.61,475.6,636.11,473.8,636.11z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<path class="st1" d="M296.7,852.71c-1.8,0-3.2,1.3-3.3,3c0,1.7,1.4,3,3.2,3c1.8,0,3.2-1.3,3.3-3l0,0
|
|
||||||
C299.9,854.01,298.5,852.71,296.7,852.71z"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<path class="st2" d="M584.6,199.01H8.5c-4.7,0-8.5-3.8-8.5-8.5V60.71c0-4.7,3.8-8.5,8.5-8.5h576.1c4.7,0,8.5,3.8,8.5,8.5v129.8
|
|
||||||
C593.1,195.21,589.3,199.01,584.6,199.01z"/>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 28.7 90.8107)" class="st3 st4 st5">struct mg_http_part part;</text>
|
|
||||||
<text transform="matrix(1 0 0 1 28.7 110.9108)" class="st3 st4 st5">size_t pos = 0;</text>
|
|
||||||
<text transform="matrix(1 0 0 1 28.7 151.1107)" class="st3 st4 st5">pos = mg_http_next_multipart(&hm->body, pos, &part);</text>
|
|
||||||
<text transform="matrix(1 0 0 1 28.7 171.3107)" class="st3 st4 st5">pos = mg_http_next_multipart(&hm->body, pos, &part);</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<text transform="matrix(1 0 0 1 1.3738 40.559)" class="st6 st7">Source Code</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<path class="st8" d="M685.5,646.41H8.5c-4.7,0-8.5-3.8-8.5-8.5v-362.9c0-4.7,3.8-8.5,8.5-8.5h677c4.7,0,8.5,3.8,8.5,8.5v362.9
|
|
||||||
C694,642.61,690.2,646.41,685.5,646.41z"/>
|
|
||||||
</g>
|
|
||||||
<path class="st9" d="M640.2,629.41H26.3c-4.7,0-8.5-3.8-8.5-8.5v-106.5c0-4.7,3.8-8.5,8.5-8.5h613.9c4.7,0,8.5,3.8,8.5,8.5v106.5
|
|
||||||
C648.7,625.61,644.8,629.41,640.2,629.41z"/>
|
|
||||||
<path class="st9" d="M644,490.91H30.1c-4.7,0-8.5-3.8-8.5-8.5v-106.5c0-4.7,3.8-8.5,8.5-8.5H644c4.7,0,8.5,3.8,8.5,8.5v106.5
|
|
||||||
C652.5,487.11,648.7,490.91,644,490.91z"/>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 0.0299 253.0343)" class="st6 st7">HTTP message</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 28.7 302.8107)" class="st3 st4 st5">POST /upload HTTP/1.1 </text>
|
|
||||||
<text transform="matrix(1 0 0 1 28.7 322.9107)" class="st3 st4 st5">Content-Type: multipart/form-data; boundary="--xyz"</text>
|
|
||||||
<text transform="matrix(1 0 0 1 28.7 363.1107)" class="st3 st4 st5">--xyz</text>
|
|
||||||
<text transform="matrix(1 0 0 1 28.7 383.3107)" class="st3 st4 st5">Content-Disposition: form-data; name="foo"; filename="a.txt"</text>
|
|
||||||
<text transform="matrix(1 0 0 1 28.7 403.4107)" class="st3 st4 st5">Content-Type: text/plain</text>
|
|
||||||
<text transform="matrix(1 0 0 1 28.7 443.6107)" class="st3 st4 st5">hello world</text>
|
|
||||||
<text transform="matrix(1 0 0 1 28.7 483.8107)" class="st3 st4 st5">--xyz---</text>
|
|
||||||
<text transform="matrix(1 0 0 1 28.7 524.0107)" class="st3 st4 st5">Content-Disposition: form-data; name="bar"; filename="b.txt"</text>
|
|
||||||
<text transform="matrix(1 0 0 1 28.7 544.2108)" class="st3 st4 st5">Content-Type: text/plain</text>
|
|
||||||
<text transform="matrix(1 0 0 1 28.7 584.4108)" class="st3 st4 st5">hello world again</text>
|
|
||||||
<text transform="matrix(1 0 0 1 28.7 624.6107)" class="st3 st4 st5">--xyz--</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st10" points="569.5,162.51 574.5,162.51 574.5,176.11 569.5,176.11 "/>
|
|
||||||
<g>
|
|
||||||
<path class="st0" d="M726.8,392.91"/>
|
|
||||||
<g>
|
|
||||||
<polyline class="st10" points="587.3,169.71 726.7,169.71 726.6,569.31 684.3,569.31 "/>
|
|
||||||
<path class="st11" d="M585,166.41c-1.8,0-3.2,1.4-3.3,3.2c0,1.8,1.4,3.2,3.2,3.3c1.8,0,3.2-1.4,3.3-3.2l0,0
|
|
||||||
C588.2,167.91,586.8,166.41,585,166.41z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<path class="st11" d="M685,566.31c-1.7,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3l0,0C688,567.61,686.6,566.31,685,566.31z"/>
|
|
||||||
</g>
|
|
||||||
<polyline class="st10" points="657.9,501.61 673.9,501.61 673.9,634.21 657.9,634.21 "/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st12" points="569.5,143.21 574.5,143.21 574.5,156.81 569.5,156.81 "/>
|
|
||||||
<g>
|
|
||||||
<path class="st0" d="M726.8,254.61"/>
|
|
||||||
<g>
|
|
||||||
<polyline class="st12" points="587.3,150.41 710.7,150.41 710.6,431.01 684.3,431.01 "/>
|
|
||||||
<path class="st13" d="M585,147.11c-1.8,0-3.2,1.4-3.3,3.2s1.4,3.2,3.2,3.3c1.8,0,3.2-1.4,3.3-3.2l0,0
|
|
||||||
C588.2,148.61,586.8,147.11,585,147.11z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<path class="st13" d="M685,428.01c-1.7,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3l0,0C688,429.31,686.6,428.01,685,428.01z"/>
|
|
||||||
</g>
|
|
||||||
<polyline class="st12" points="657.9,363.31 673.9,363.31 673.9,495.91 657.9,495.91 "/>
|
|
||||||
</g>
|
|
||||||
<text transform="matrix(1 0 0 1 537.9671 462.1467)" class="st14 st6 st7">Part 1</text>
|
|
||||||
<text transform="matrix(1 0 0 1 537.9671 600.4373)" class="st14 st6 st7">Part 2</text>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 5.5 KiB |
@@ -1,94 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 1034 480.6" style="enable-background:new 0 0 1034 480.6;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{fill:#67748A;}
|
|
||||||
.st1{fill:#8B9CBA;}
|
|
||||||
.st2{fill:#FFFFFF;}
|
|
||||||
.st3{font-family:'Courier-Bold';}
|
|
||||||
.st4{font-size:16.7604px;}
|
|
||||||
.st5{fill:#414857;}
|
|
||||||
.st6{font-family:'Arial-BoldMT';}
|
|
||||||
.st7{font-size:30px;}
|
|
||||||
.st8{font-size:24px;}
|
|
||||||
.st9{fill:#576174;}
|
|
||||||
.st10{fill:none;stroke:#45CFFF;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st11{fill:#45CFFF;}
|
|
||||||
.st12{fill:none;stroke:#EA5B0C;stroke-width:2.793;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st13{fill:#EA5B0C;}
|
|
||||||
.st14{fill:none;stroke:#EA5B0C;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st15{fill:none;stroke:#FFDE00;stroke-width:2.793;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st16{fill:#FFDE00;}
|
|
||||||
</style>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<path class="st0" d="M908.4,454.9H272c-4.7,0-8.5-3.8-8.5-8.5V216c0-4.7,3.8-8.5,8.5-8.5h636.4c4.7,0,8.5,3.8,8.5,8.5v230.4
|
|
||||||
C916.9,451.1,913.1,454.9,908.4,454.9z"/>
|
|
||||||
<g>
|
|
||||||
<path class="st1" d="M898.6,430.8H284.7c-4.7,0-8.5-3.8-8.5-8.5V315.9c0-4.7,3.8-8.5,8.5-8.5h613.9c4.7,0,8.5,3.8,8.5,8.5v106.5
|
|
||||||
C907.1,427,903.3,430.8,898.6,430.8z"/>
|
|
||||||
<text transform="matrix(1 0 0 1 295.3688 243.086)" class="st2 st3 st4">POST /upload HTTP/1.1 </text>
|
|
||||||
<text transform="matrix(1 0 0 1 295.3688 263.186)" class="st2 st3 st4">Content-Type: multipart/form-data: boundary="--xyz"</text>
|
|
||||||
<text transform="matrix(1 0 0 1 295.3688 303.386)" class="st2 st3 st4">--xyz</text>
|
|
||||||
<text transform="matrix(1 0 0 1 295.3688 323.586)" class="st2 st3 st4">Content-Disposition: form-data; name="foo"; filename="a.txt"</text>
|
|
||||||
<text transform="matrix(1 0 0 1 295.3688 343.686)" class="st2 st3 st4">Content-Type: text/plain</text>
|
|
||||||
<text transform="matrix(1 0 0 1 295.3688 383.886)" class="st2 st3 st4">hello world</text>
|
|
||||||
<text transform="matrix(1 0 0 1 295.3688 424.086)" class="st2 st3 st4">--xyz---</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<text transform="matrix(1 0 0 1 739.2766 414.2906)" class="st5 st6 st7">HTTP part</text>
|
|
||||||
<text transform="matrix(1 0 0 1 739.2764 193.4305)" class="st6 st8">HTTP message</text>
|
|
||||||
<path class="st9" d="M304.9,198H8.5c-4.7,0-8.5-3.8-8.5-8.5V64.8c0-4.7,3.8-8.5,8.5-8.5H305c4.7,0,8.5,3.8,8.5,8.5v124.7
|
|
||||||
C313.4,194.2,309.6,198,304.9,198z"/>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 25.2409 91.1617)" class="st2 st3 st4">struct mg_http_part {</text>
|
|
||||||
<text transform="matrix(1 0 0 1 47.0734 113.7079)" class="st2 st3 st4">struct mg_str name;</text>
|
|
||||||
<text transform="matrix(1 0 0 1 47.0734 133.8079)" class="st2 st3 st4">strucy mg_str filename;</text>
|
|
||||||
<text transform="matrix(1 0 0 1 47.0734 153.9079)" class="st2 st3 st4">struct mg_str body;</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st10" points="237.4,159 237.4,163 185.8,163 185.8,159 "/>
|
|
||||||
<g>
|
|
||||||
<polyline class="st10" points="211.7,348.3 349.5,348.4 349.5,355.6 "/>
|
|
||||||
<g>
|
|
||||||
<line class="st10" x1="211.6" y1="174.4" x2="211.6" y2="348.1"/>
|
|
||||||
<path class="st11" d="M211.6,170.3c-1.8,0-3.2,1.4-3.3,3.2c0,1.8,1.4,3.2,3.2,3.3c1.8,0,3.2-1.4,3.3-3.2l0,0
|
|
||||||
C214.8,171.8,213.4,170.3,211.6,170.3z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<path class="st11" d="M349.6,353.6c-1.8,0-3.2,1.4-3.3,3.2s1.4,3.2,3.2,3.3c1.8,0,3.2-1.4,3.3-3.2l0,0
|
|
||||||
C352.8,355.1,351.4,353.6,349.6,353.6z"/>
|
|
||||||
<polyline class="st10" points="237.4,159 237.4,163 185.8,163 185.8,159 "/>
|
|
||||||
<polyline class="st10" points="407.3,371.1 407.3,367.1 293.3,367.1 293.3,371.1 "/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st12" points="693.7,291.6 693.7,277.7 280.7,278.8 280.5,109.4 248.3,109.4 "/>
|
|
||||||
<path class="st13" d="M696.9,293.6c0,1.8-1.4,3.2-3.2,3.3c-1.8,0-3.2-1.4-3.3-3.2c0-1.8,1.4-3.2,3.2-3.3l0,0
|
|
||||||
C695.4,290.4,696.9,291.9,696.9,293.6z"/>
|
|
||||||
</g>
|
|
||||||
<path class="st13" d="M243.9,109.5c0-1.8,1.4-3.2,3.2-3.3c1.8,0,3.2,1.4,3.3,3.2c0,1.8-1.4,3.2-3.2,3.3l0,0
|
|
||||||
C245.3,112.7,243.9,111.3,243.9,109.5z"/>
|
|
||||||
</g>
|
|
||||||
<polyline class="st14" points="707.6,309.2 707.6,305.2 679.9,305.2 679.9,309.2 "/>
|
|
||||||
</g>
|
|
||||||
<text transform="matrix(1 0 0 1 0.8627 37.8099)" class="st6 st8">Source Code</text>
|
|
||||||
<text transform="matrix(1 0 0 1 25.2408 177.7241)" class="st2 st3 st4">};</text>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st15" points="863.8,291.5 863.7,218.6 329.7,218.7 329.6,130.3 298.4,130.3 "/>
|
|
||||||
<path class="st16" d="M867.1,293.6c0,1.8-1.4,3.2-3.2,3.3c-1.8,0-3.2-1.4-3.3-3.2c0-1.8,1.4-3.2,3.2-3.3l0,0
|
|
||||||
C865.6,290.3,867.1,291.8,867.1,293.6z"/>
|
|
||||||
</g>
|
|
||||||
<path class="st16" d="M293,130.1c0-1.8,1.4-3.2,3.2-3.3c1.8,0,3.2,1.4,3.3,3.2c0,1.8-1.4,3.2-3.2,3.3l0,0
|
|
||||||
C294.4,133.3,293,131.9,293,130.1z"/>
|
|
||||||
</g>
|
|
||||||
<polyline class="st15" points="888.7,309.1 888.7,305.1 838.9,305.1 838.9,309.1 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 4.9 KiB |
@@ -1,84 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 1034 331.2" style="enable-background:new 0 0 1034 331.2;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{fill:#576174;}
|
|
||||||
.st1{fill:#67748A;}
|
|
||||||
.st2{fill:#FFFFFF;}
|
|
||||||
.st3{font-family:'Courier-Bold';}
|
|
||||||
.st4{font-size:16.7604px;}
|
|
||||||
.st5{font-family:'Arial-BoldMT';}
|
|
||||||
.st6{font-size:24px;}
|
|
||||||
.st7{fill:none;stroke:#45CFFF;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st8{fill:#45CFFF;}
|
|
||||||
.st9{fill:none;stroke:#EA5B0C;stroke-width:2.793;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st10{fill:#EA5B0C;}
|
|
||||||
.st11{fill:none;stroke:#EA5B0C;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st12{fill:none;stroke:#00CF4F;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st13{fill:#00CF4F;}
|
|
||||||
</style>
|
|
||||||
<g>
|
|
||||||
<path class="st0" d="M541.43,184.2H8.53c-4.7,0-8.5-3.8-8.5-8.5V54.8c0-4.7,3.8-8.5,8.5-8.5h532.9c4.7,0,8.5,3.8,8.5,8.5v120.9
|
|
||||||
C549.93,180.4,546.13,184.2,541.43,184.2z"/>
|
|
||||||
<g>
|
|
||||||
<path class="st1" d="M829.23,315.5h-370c-4.7,0-8.5-3.8-8.5-8.5V157c0-4.7,3.8-8.5,8.5-8.5h370c4.7,0,8.5,3.8,8.5,8.5v150
|
|
||||||
C837.83,311.7,833.93,315.5,829.23,315.5z"/>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 490.6096 184.0905)" class="st2 st3 st4">HTTP/1.1 200 OK</text>
|
|
||||||
<text transform="matrix(1 0 0 1 490.6096 204.1905)" class="st2 st3 st4">Content-Length; 13</text>
|
|
||||||
<text transform="matrix(1 0 0 1 490.6096 224.2905)" class="st2 st3 st4">X-Header-1: additional value 1</text>
|
|
||||||
<text transform="matrix(1 0 0 1 490.6096 244.3905)" class="st2 st3 st4">X-Header-2: additional value 2</text>
|
|
||||||
<text transform="matrix(1 0 0 1 490.8657 293.1559)" class="st2 st3 st4">Hello, world!</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<text transform="matrix(1 0 0 1 660.5036 137.3383)" class="st5 st6">HTTP message</text>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 20.7331 85.1617)" class="st2 st3 st4">mg_http_reply(c, 200</text>
|
|
||||||
<text transform="matrix(1 0 0 1 159.5657 113.7079)" class="st2 st3 st4">"X-Header-1: additional value 1\r\n"</text>
|
|
||||||
<text transform="matrix(1 0 0 1 159.5657 133.8079)" class="st2 st3 st4">"X-Header-2: additional value 2\r\n",</text>
|
|
||||||
<text transform="matrix(1 0 0 1 159.5657 153.9079)" class="st2 st3 st4">"Hello, %s!", "world");</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st7" points="362.93,159 362.93,163 167.33,163 167.33,159 "/>
|
|
||||||
<g>
|
|
||||||
<polyline class="st7" points="265.93,256.6 552.13,256.7 552.13,264.4 "/>
|
|
||||||
<g>
|
|
||||||
<line class="st7" x1="265.83" y1="174.4" x2="265.83" y2="256.6"/>
|
|
||||||
<path class="st8" d="M265.83,170.3c-1.8,0-3.2,1.4-3.3,3.2c0,1.8,1.4,3.2,3.2,3.3c1.8,0,3.2-1.4,3.3-3.2l0,0
|
|
||||||
C269.03,171.8,267.53,170.3,265.83,170.3z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<path class="st8" d="M552.23,261.6c-1.8,0-3.2,1.4-3.3,3.2c0,1.8,1.4,3.2,3.2,3.3c1.8,0,3.2-1.4,3.3-3.2l0,0
|
|
||||||
C555.43,263.1,554.03,261.6,552.23,261.6z"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st9" points="206.33,53.6 206.43,37.6 596.43,38.7 596.53,161.3 "/>
|
|
||||||
<path class="st10" d="M203.23,54.6c0,1.8,1.4,3.2,3.2,3.3c1.8,0,3.2-1.4,3.3-3.2c0-1.8-1.4-3.2-3.2-3.3l0,0
|
|
||||||
C204.63,51.4,203.23,52.8,203.23,54.6z"/>
|
|
||||||
</g>
|
|
||||||
<path class="st10" d="M599.83,164c0-1.8-1.4-3.2-3.2-3.3c-1.8,0-3.2,1.4-3.3,3.2c0,1.8,1.4,3.2,3.2,3.3l0,0
|
|
||||||
C598.33,167.2,599.83,165.8,599.83,164z"/>
|
|
||||||
</g>
|
|
||||||
<polyline class="st11" points="192.43,69.2 192.43,65.2 220.23,65.2 220.23,69.2 "/>
|
|
||||||
</g>
|
|
||||||
<text transform="matrix(1 0 0 1 -1.917133e-04 35.0037)" class="st5 st6">Source Code</text>
|
|
||||||
<g>
|
|
||||||
<polyline class="st12" points="160.13,135.9 156.03,135.9 156.03,100.1 160.13,100.1 "/>
|
|
||||||
<g>
|
|
||||||
<line class="st12" x1="123.93" y1="231" x2="469.73" y2="231"/>
|
|
||||||
<polyline class="st12" points="144.73,117.2 123.83,117.2 123.73,230.8 "/>
|
|
||||||
<path class="st13" d="M147.83,117.2c0-1.8-1.4-3.2-3.2-3.3c-1.8,0-3.2,1.4-3.3,3.2c0,1.8,1.4,3.2,3.2,3.3l0,0
|
|
||||||
C146.33,120.4,147.83,119,147.83,117.2z"/>
|
|
||||||
<path class="st13" d="M474.83,230.8c0-1.8-1.4-3.2-3.2-3.3c-1.8,0-3.2,1.4-3.3,3.2c0,1.8,1.4,3.2,3.2,3.3l0,0
|
|
||||||
C473.43,234,474.83,232.5,474.83,230.8z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<polyline class="st7" points="489.03,279.6 489.03,275.6 620.63,275.6 620.63,279.6 "/>
|
|
||||||
<polyline class="st12" points="487.63,248.3 483.63,248.3 483.63,211.5 487.63,211.5 "/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 4.4 KiB |
@@ -1,124 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 869.6 185.67" style="enable-background:new 0 0 869.6 185.67;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{font-family:'Arial-BoldMT';}
|
|
||||||
.st1{font-size:24px;}
|
|
||||||
.st2{opacity:0.2;fill:#00983A;enable-background:new ;}
|
|
||||||
.st3{fill:none;stroke:#7A8387;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st4{fill:#00983A;}
|
|
||||||
.st5{fill:none;stroke:#576174;stroke-miterlimit:10;}
|
|
||||||
.st6{fill:#F2F3F3;stroke:#7A8387;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st7{fill:none;stroke:#576174;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st8{font-family:'Courier-Bold';}
|
|
||||||
.st9{font-size:16.7604px;}
|
|
||||||
.st10{fill:none;stroke:#00983A;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st11{fill:#576174;}
|
|
||||||
.st12{font-family:'Courier';}
|
|
||||||
.st13{fill:none;}
|
|
||||||
.st14{fill:#7A8387;}
|
|
||||||
</style>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 1.0956 32.4549)" class="st0 st1">Memory</text>
|
|
||||||
<polyline class="st2" points="424.58,115.4 219.88,115.4 219.88,90.7 424.58,90.7 "/>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st3" points="458.98,115.4 218.98,115.4 218.98,90.7 458.98,90.7 "/>
|
|
||||||
<polyline class="st4" points="219.18,115.1 2.98,115.1 2.98,91.3 219.18,91.3 "/>
|
|
||||||
<line class="st3" x1="2.98" y1="69.2" x2="2.98" y2="130.4"/>
|
|
||||||
<line class="st5" x1="219.78" y1="69.2" x2="219.78" y2="130.4"/>
|
|
||||||
<line class="st5" x1="425.28" y1="69.2" x2="425.28" y2="130.4"/>
|
|
||||||
<path class="st6" d="M458.98,115.4"/>
|
|
||||||
<path class="st7" d="M33.98,114.6"/>
|
|
||||||
<path class="st7" d="M33.98,90.9"/>
|
|
||||||
<path class="st7" d="M2.98,90.7h216.8v24.9l-216.8-0.2C2.98,115.4,3.18,90.7,2.98,90.7z"/>
|
|
||||||
<line class="st3" x1="425.18" y1="90.8" x2="425.18" y2="115.3"/>
|
|
||||||
<path class="st6" d="M251.98,115.6"/>
|
|
||||||
<path class="st6" d="M251.98,91.9"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 -2.290726e-04 175.3858)" class="st4 st8 st9">buf</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st10" x1="2.68" y1="158.2" x2="2.68" y2="137.2"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st4" points="0.28,137.6 5.08,137.6 2.68,135.1 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 214.6515 175.3858)" class="st4 st8 st9">len</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st10" x1="219.78" y1="158.2" x2="219.78" y2="137.2"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st4" points="217.38,137.6 222.18,137.6 219.78,135.1 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 421.6186 175.3858)" class="st4 st8 st9">size</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st10" x1="425.38" y1="158.2" x2="425.38" y2="137.2"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st4" points="422.98,137.6 427.78,137.6 425.38,135.1 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 93.1143 69.4458)" class="st11 st12 st9">data</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 273.8231 69.4458)" class="st11 st12 st9">free space</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st5" x1="132.98" y1="76.3" x2="13.98" y2="76.3"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st11" points="14.28,78.7 14.28,73.8 11.88,76.3 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<line class="st13" x1="123.88" y1="76.3" x2="210.88" y2="76.3"/>
|
|
||||||
<g>
|
|
||||||
<line class="st5" x1="123.88" y1="76.3" x2="208.78" y2="76.3"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st11" points="208.48,73.8 208.48,78.7 210.88,76.3 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st5" x1="320.38" y1="76.3" x2="414.28" y2="76.3"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st14" points="413.98,73.8 413.98,78.7 416.38,76.3 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st5" x1="322.28" y1="76.3" x2="233.28" y2="76.3"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st14" points="233.68,78.7 233.68,73.8 231.18,76.3 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 4.1 KiB |
@@ -1,52 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 869 124.66" style="enable-background:new 0 0 869 124.66;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{fill:#F2F3F3;stroke:#7A8387;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st1{fill:none;stroke:#7A8387;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st2{fill:#00983A;}
|
|
||||||
.st3{font-family:'Courier-Bold';}
|
|
||||||
.st4{font-size:16.7604px;}
|
|
||||||
.st5{fill:none;stroke:#00983A;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st6{fill:#7A8387;}
|
|
||||||
</style>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st0" points="830.92,78.4 5.52,78.4 5.52,53.7 830.92,53.6 "/>
|
|
||||||
<line class="st1" x1="5.52" y1="32.2" x2="5.52" y2="93.4"/>
|
|
||||||
<path class="st0" d="M830.92,78.4"/>
|
|
||||||
<line class="st1" x1="36.52" y1="53.9" x2="36.52" y2="77.6"/>
|
|
||||||
<line class="st1" x1="68.92" y1="53.9" x2="68.92" y2="77.6"/>
|
|
||||||
<line class="st1" x1="101.42" y1="53.9" x2="101.42" y2="77.6"/>
|
|
||||||
<line class="st1" x1="133.72" y1="53.9" x2="133.72" y2="77.6"/>
|
|
||||||
<line class="st1" x1="166.22" y1="53.9" x2="166.22" y2="77.6"/>
|
|
||||||
<line class="st1" x1="198.52" y1="54.6" x2="198.52" y2="78.3"/>
|
|
||||||
<line class="st1" x1="230.92" y1="54.6" x2="230.92" y2="78.3"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 59.1908 40.8585)" class="st2 st3 st4">buf=NULL, len=0, size=0 </text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 -1.811981e-04 109.9024)" class="st2 st3 st4">0</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st5" x1="46.72" y1="37.7" x2="17.72" y2="37.7"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st2" points="18.12,40.1 18.12,35.2 15.62,37.7 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<path class="st6" d="M511.52,66.4c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6s0.7-1.6,1.6-1.6S511.52,65.5,511.52,66.4z"/>
|
|
||||||
<path class="st6" d="M525.32,66.4c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6s0.7-1.6,1.6-1.6S525.32,65.5,525.32,66.4z"/>
|
|
||||||
<path class="st6" d="M539.02,66.4c0,0.9-0.7,1.6-1.6,1.6c-0.9,0-1.6-0.7-1.6-1.6s0.7-1.6,1.6-1.6S539.02,65.5,539.02,66.4z"/>
|
|
||||||
<path class="st6" d="M552.82,66.4c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6s0.7-1.6,1.6-1.6S552.82,65.5,552.82,66.4z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 2.3 KiB |
@@ -1,185 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 869.6 127.5" style="enable-background:new 0 0 869.6 127.5;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{opacity:0.2;fill:#00983A;enable-background:new ;}
|
|
||||||
.st1{fill:#F2F3F3;}
|
|
||||||
.st2{fill:none;stroke:#7A8387;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st3{fill:#00983A;}
|
|
||||||
.st4{fill:#F2F3F3;stroke:#7A8387;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st5{fill:none;stroke:#576174;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st6{fill:none;stroke:#576174;stroke-width:1.2;stroke-linecap:square;stroke-linejoin:round;}
|
|
||||||
.st7{font-family:'Courier-Bold';}
|
|
||||||
.st8{font-size:16.7604px;}
|
|
||||||
.st9{fill:none;stroke:#00983A;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st10{fill:#7A8387;}
|
|
||||||
.st11{fill:#576174;}
|
|
||||||
.st12{fill:none;stroke:#576174;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st13{fill:none;stroke:#7A8387;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st14{fill:#333A45;}
|
|
||||||
</style>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st0" points="577.2,72.8 282.4,72.8 282.4,48 577.2,48 "/>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st1" points="122.6,72.8 5.9,72.8 5.9,48 122.6,48 "/>
|
|
||||||
<polyline class="st2" points="831.51,72.8 5.5,72.8 5.5,48 831.51,48 "/>
|
|
||||||
<polyline class="st3" points="282.7,72.5 122.5,72.5 122.5,47.7 282.7,47.7 "/>
|
|
||||||
<line class="st2" x1="122.5" y1="26.6" x2="122.5" y2="87.8"/>
|
|
||||||
<line class="st2" x1="283.3" y1="26.6" x2="283.3" y2="87.8"/>
|
|
||||||
<line class="st2" x1="576.8" y1="26.6" x2="576.8" y2="87.8"/>
|
|
||||||
<path class="st4" d="M831.51,72.8"/>
|
|
||||||
<line class="st5" x1="153.5" y1="48.3" x2="153.5" y2="72"/>
|
|
||||||
<line class="st2" x1="36.5" y1="48.3" x2="36.5" y2="72"/>
|
|
||||||
<line class="st2" x1="67.6" y1="48.3" x2="67.6" y2="72"/>
|
|
||||||
<line class="st5" x1="186" y1="48.3" x2="186" y2="72"/>
|
|
||||||
<line class="st5" x1="218.4" y1="48.3" x2="218.4" y2="72"/>
|
|
||||||
<line class="st5" x1="250.9" y1="48.3" x2="250.9" y2="72"/>
|
|
||||||
<line class="st2" x1="315.9" y1="48.3" x2="315.9" y2="72"/>
|
|
||||||
<line class="st2" x1="348.4" y1="48.3" x2="348.4" y2="72"/>
|
|
||||||
<line class="st2" x1="381.2" y1="48.3" x2="381.2" y2="72"/>
|
|
||||||
<line class="st2" x1="413.8" y1="48.3" x2="413.8" y2="72"/>
|
|
||||||
<line class="st2" x1="446.3" y1="48.3" x2="446.3" y2="72"/>
|
|
||||||
<line class="st2" x1="478.9" y1="48.3" x2="478.9" y2="72"/>
|
|
||||||
<line class="st5" x1="511.51" y1="48.3" x2="511.51" y2="72"/>
|
|
||||||
<line class="st2" x1="511.51" y1="48.3" x2="511.51" y2="72"/>
|
|
||||||
<line class="st5" x1="544.01" y1="48.3" x2="544.01" y2="72"/>
|
|
||||||
<line class="st2" x1="544.1" y1="48.3" x2="544.1" y2="72"/>
|
|
||||||
<line class="st6" x1="283.3" y1="73" x2="122.5" y2="72.8"/>
|
|
||||||
<line class="st6" x1="122.5" y1="48" x2="283.3" y2="48.1"/>
|
|
||||||
<path class="st4" d="M385.5,73"/>
|
|
||||||
<path class="st4" d="M385.5,49.3"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 127.5176 105.8013)" class="st3 st7 st8">buf</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st9" x1="122.2" y1="105.6" x2="122.2" y2="94.6"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st3" points="119.8,94.9 124.6,94.9 122.2,92.5 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 286.6495 105.8008)" class="st3 st7 st8">len=5</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st9" x1="283.3" y1="105.6" x2="283.3" y2="94.6"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st3" points="280.9,94.9 285.8,94.9 283.3,92.5 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 581.4624 105.8013)" class="st3 st7 st8">size=16</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st9" x1="576.9" y1="105.6" x2="576.9" y2="94.6"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st3" points="574.51,94.9 579.4,94.9 576.9,92.5 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<path class="st10" d="M687.51,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S687.51,59.9,687.51,60.7z"/>
|
|
||||||
<path class="st10" d="M701.2,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S701.2,59.9,701.2,60.7z"/>
|
|
||||||
<path class="st10" d="M714.9,60.7c0,0.9-0.7,1.6-1.6,1.6c-0.9,0-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6
|
|
||||||
C714.2,59.1,714.9,59.9,714.9,60.7z"/>
|
|
||||||
<path class="st10" d="M728.7,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6
|
|
||||||
C728.01,59.1,728.7,59.9,728.7,60.7z"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<path class="st10" d="M82.8,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S82.8,59.9,82.8,60.7z"/>
|
|
||||||
<path class="st10" d="M96.5,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6C95.8,59.1,96.5,59.9,96.5,60.7
|
|
||||||
z"/>
|
|
||||||
<path class="st10" d="M110.2,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S110.2,59.9,110.2,60.7z"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 180.6541 26.8123)" class="st11 st7 st8">data</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 387.363 26.8123)" class="st10 st7 st8">free space</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st12" x1="272.2" y1="33.6" x2="133.5" y2="33.6"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st11" points="271.9,36.2 273.5,33.6 271.9,31.1 271.8,31.1 271.8,36.2 "/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<polygon class="st11" points="133.8,36.1 133.8,31.2 131.4,33.6 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st13" x1="563.7" y1="33.6" x2="295.9" y2="33.6"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st10" points="563.4,36.1 563.4,31.2 565.8,33.6 "/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<polygon class="st10" points="296.2,36.1 296.2,31.2 293.7,33.6 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 615.4679 25.1898)" class="st10 st7 st8">non-allocated space</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st13" x1="593.7" y1="33.6" x2="829.7" y2="33.6"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st10" points="829.4,31.2 829.4,36.1 831.8,33.6 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st13" x1="678.7" y1="33.6" x2="589.7" y2="33.6"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st10" points="590.01,36.1 590.01,31.2 587.6,33.6 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 133.1212 64.9593)" class="st14 st7 st8">h</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 165.1564 64.9593)" class="st14 st7 st8">e</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 196.8744 64.9593)" class="st14 st7 st8">l</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 229.8611 64.9593)" class="st14 st7 st8">l</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 262.2135 64.9593)" class="st14 st7 st8">o</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 1.811981e-04 105.8011)" class="st3 st7 st8">0</text>
|
|
||||||
</g>
|
|
||||||
<line class="st2" x1="5.5" y1="26.4" x2="5.5" y2="87.6"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 7.1 KiB |
@@ -1,347 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 869.6 247.73" style="enable-background:new 0 0 869.6 247.73;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{opacity:0.2;fill:#00983A;enable-background:new ;}
|
|
||||||
.st1{fill:#00983A;}
|
|
||||||
.st2{fill:#FF80A4;}
|
|
||||||
.st3{fill:#F2F3F3;}
|
|
||||||
.st4{fill:none;stroke:#7A8387;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st5{fill:#F2F3F3;stroke:#7A8387;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st6{fill:none;stroke:#576174;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st7{fill:none;stroke:#576174;stroke-width:1.2;stroke-linejoin:round;}
|
|
||||||
.st8{fill:none;stroke:#576174;stroke-width:1.2;stroke-linecap:square;stroke-linejoin:round;}
|
|
||||||
.st9{font-family:'Courier-Bold';}
|
|
||||||
.st10{font-size:16.7604px;}
|
|
||||||
.st11{fill:none;stroke:#00983A;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st12{fill:#7A8387;}
|
|
||||||
.st13{fill:#576174;}
|
|
||||||
.st14{fill:none;stroke:#576174;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st15{fill:none;stroke:#7A8387;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st16{fill:#333A45;}
|
|
||||||
</style>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st0" points="577.2,72.8 282.4,72.8 282.4,48 577.2,48 "/>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<rect x="250.9" y="47.7" class="st1" width="32.4" height="24.8"/>
|
|
||||||
<rect x="153.5" y="47.7" class="st2" width="97.3" height="24.8"/>
|
|
||||||
<polyline class="st3" points="122.6,72.8 5.9,72.8 5.9,48 122.6,48 "/>
|
|
||||||
<polyline class="st4" points="831.51,72.8 5.5,72.8 5.5,48 831.51,48 "/>
|
|
||||||
<rect x="122.5" y="47.7" class="st1" width="31" height="24.8"/>
|
|
||||||
<line class="st4" x1="122.5" y1="26.6" x2="122.5" y2="87.8"/>
|
|
||||||
<line class="st4" x1="576.8" y1="26.6" x2="576.8" y2="87.8"/>
|
|
||||||
<path class="st5" d="M831.51,72.8"/>
|
|
||||||
<line class="st6" x1="153.5" y1="48.3" x2="153.5" y2="72"/>
|
|
||||||
<line class="st4" x1="36.5" y1="48.3" x2="36.5" y2="72"/>
|
|
||||||
<line class="st4" x1="67.6" y1="48.3" x2="67.6" y2="72"/>
|
|
||||||
<line class="st6" x1="186" y1="48.3" x2="186" y2="72"/>
|
|
||||||
<line class="st6" x1="218.4" y1="48.3" x2="218.4" y2="72"/>
|
|
||||||
<line class="st7" x1="250.9" y1="73" x2="250.81" y2="47.7"/>
|
|
||||||
<line class="st4" x1="315.9" y1="48.3" x2="315.9" y2="72"/>
|
|
||||||
<line class="st4" x1="348.4" y1="48.3" x2="348.4" y2="72"/>
|
|
||||||
<line class="st4" x1="381.2" y1="48.3" x2="381.2" y2="72"/>
|
|
||||||
<line class="st4" x1="413.8" y1="48.3" x2="413.8" y2="72"/>
|
|
||||||
<line class="st4" x1="446.3" y1="48.3" x2="446.3" y2="72"/>
|
|
||||||
<line class="st4" x1="478.9" y1="48.3" x2="478.9" y2="72"/>
|
|
||||||
<line class="st6" x1="511.51" y1="48.3" x2="511.51" y2="72"/>
|
|
||||||
<line class="st4" x1="511.51" y1="48.3" x2="511.51" y2="72"/>
|
|
||||||
<line class="st6" x1="544.01" y1="48.3" x2="544.01" y2="72"/>
|
|
||||||
<line class="st4" x1="544.1" y1="48.3" x2="544.1" y2="72"/>
|
|
||||||
<line class="st8" x1="283.3" y1="73" x2="122.5" y2="72.8"/>
|
|
||||||
<line class="st8" x1="122.5" y1="48" x2="283.3" y2="48.1"/>
|
|
||||||
<path class="st5" d="M385.5,73"/>
|
|
||||||
<path class="st5" d="M385.5,49.3"/>
|
|
||||||
<line class="st4" x1="283.3" y1="26.6" x2="283.3" y2="87.8"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 127.5176 105.8013)" class="st1 st9 st10">buf</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st11" x1="122.2" y1="105.6" x2="122.2" y2="94.6"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st1" points="119.8,94.9 124.6,94.9 122.2,92.5 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 286.6495 105.8008)" class="st1 st9 st10">len=5</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st11" x1="283.3" y1="105.6" x2="283.3" y2="94.6"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st1" points="280.9,94.9 285.8,94.9 283.3,92.5 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 581.4624 105.8013)" class="st1 st9 st10">size=16</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st11" x1="576.9" y1="105.6" x2="576.9" y2="94.6"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st1" points="574.51,94.9 579.4,94.9 576.9,92.5 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<path class="st12" d="M687.51,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S687.51,59.9,687.51,60.7z"/>
|
|
||||||
<path class="st12" d="M701.2,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S701.2,59.9,701.2,60.7z"/>
|
|
||||||
<path class="st12" d="M714.9,60.7c0,0.9-0.7,1.6-1.6,1.6c-0.9,0-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6
|
|
||||||
C714.2,59.1,714.9,59.9,714.9,60.7z"/>
|
|
||||||
<path class="st12" d="M728.7,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6
|
|
||||||
C728.01,59.1,728.7,59.9,728.7,60.7z"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<path class="st12" d="M82.8,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S82.8,59.9,82.8,60.7z"/>
|
|
||||||
<path class="st12" d="M96.5,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6C95.8,59.1,96.5,59.9,96.5,60.7
|
|
||||||
z"/>
|
|
||||||
<path class="st12" d="M110.2,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S110.2,59.9,110.2,60.7z"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 180.6541 26.8123)" class="st13 st9 st10">data</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 387.363 26.8123)" class="st12 st9 st10">free space</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st14" x1="272.2" y1="33.6" x2="133.5" y2="33.6"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st13" points="271.9,36.2 273.5,33.6 271.9,31.1 271.8,31.1 271.8,36.2 "/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<polygon class="st13" points="133.8,36.1 133.8,31.2 131.4,33.6 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st15" x1="563.7" y1="33.6" x2="295.9" y2="33.6"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st12" points="563.4,36.1 563.4,31.2 565.8,33.6 "/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<polygon class="st12" points="296.2,36.1 296.2,31.2 293.7,33.6 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 615.4679 25.1898)" class="st12 st9 st10">non-allocated space</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st15" x1="593.7" y1="33.6" x2="829.7" y2="33.6"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st12" points="829.4,31.2 829.4,36.1 831.8,33.6 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st15" x1="678.7" y1="33.6" x2="589.7" y2="33.6"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st12" points="590.01,36.1 590.01,31.2 587.6,33.6 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 133.1212 64.9593)" class="st16 st9 st10">h</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 165.1564 64.9593)" class="st16 st9 st10">e</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 196.8744 64.9593)" class="st16 st9 st10">l</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 229.8611 64.9593)" class="st16 st9 st10">l</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 262.2135 64.9593)" class="st16 st9 st10">o</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 1.811981e-04 105.8011)" class="st1 st9 st10">0</text>
|
|
||||||
</g>
|
|
||||||
<line class="st4" x1="5.5" y1="26.4" x2="5.5" y2="87.6"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st0" points="577.2,207.99 186.3,207.99 186.3,183.19 577.2,183.19 "/>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st3" points="122.6,207.99 5.9,207.99 5.9,183.19 122.6,183.19 "/>
|
|
||||||
<polyline class="st4" points="831.51,207.99 5.5,207.99 5.5,183.19 831.51,183.19 "/>
|
|
||||||
<polyline class="st1" points="186.3,207.69 122.5,207.69 122.5,182.89 186.3,182.89 "/>
|
|
||||||
<line class="st4" x1="122.5" y1="161.79" x2="122.5" y2="222.99"/>
|
|
||||||
<line class="st4" x1="186" y1="161.79" x2="186" y2="222.99"/>
|
|
||||||
<line class="st4" x1="576.8" y1="161.79" x2="576.8" y2="222.99"/>
|
|
||||||
<path class="st5" d="M831.51,207.99"/>
|
|
||||||
<line class="st6" x1="153.5" y1="183.49" x2="153.5" y2="207.19"/>
|
|
||||||
<line class="st4" x1="36.5" y1="183.49" x2="36.5" y2="207.19"/>
|
|
||||||
<line class="st4" x1="67.6" y1="183.49" x2="67.6" y2="207.19"/>
|
|
||||||
<line class="st6" x1="186" y1="183.49" x2="186" y2="207.99"/>
|
|
||||||
<line class="st4" x1="218.4" y1="183.49" x2="218.4" y2="207.19"/>
|
|
||||||
<line class="st4" x1="250.9" y1="183.49" x2="250.9" y2="207.19"/>
|
|
||||||
<line class="st4" x1="283.3" y1="183.49" x2="283.3" y2="207.19"/>
|
|
||||||
<line class="st4" x1="315.9" y1="183.49" x2="315.9" y2="207.19"/>
|
|
||||||
<line class="st4" x1="348.4" y1="183.49" x2="348.4" y2="207.19"/>
|
|
||||||
<line class="st4" x1="381.2" y1="183.49" x2="381.2" y2="207.19"/>
|
|
||||||
<line class="st4" x1="413.8" y1="183.49" x2="413.8" y2="207.19"/>
|
|
||||||
<line class="st4" x1="446.3" y1="183.49" x2="446.3" y2="207.19"/>
|
|
||||||
<line class="st4" x1="478.9" y1="183.49" x2="478.9" y2="207.19"/>
|
|
||||||
<line class="st6" x1="511.51" y1="183.49" x2="511.51" y2="207.19"/>
|
|
||||||
<line class="st4" x1="511.51" y1="183.49" x2="511.51" y2="207.19"/>
|
|
||||||
<line class="st6" x1="544.01" y1="183.49" x2="544.01" y2="207.19"/>
|
|
||||||
<line class="st4" x1="544.1" y1="183.49" x2="544.1" y2="207.19"/>
|
|
||||||
<line class="st8" x1="186" y1="208.19" x2="122.5" y2="207.99"/>
|
|
||||||
<line class="st8" x1="122.5" y1="183.19" x2="186" y2="183.29"/>
|
|
||||||
<path class="st5" d="M385.5,208.19"/>
|
|
||||||
<path class="st5" d="M385.5,184.49"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 127.5176 240.9952)" class="st1 st9 st10">buf</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st11" x1="122.2" y1="240.79" x2="122.2" y2="229.79"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st1" points="119.8,230.09 124.6,230.09 122.2,227.69 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 189.2273 240.9947)" class="st1 st9 st10">len=2</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st11" x1="185.88" y1="240.79" x2="185.88" y2="229.79"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st1" points="183.48,230.09 188.38,230.09 185.88,227.69 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 581.4624 240.9952)" class="st1 st9 st10">size=16</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st11" x1="576.9" y1="240.79" x2="576.9" y2="229.79"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st1" points="574.51,230.09 579.4,230.09 576.9,227.69 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<path class="st12" d="M687.51,195.89c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6
|
|
||||||
S687.51,195.09,687.51,195.89z"/>
|
|
||||||
<path class="st12" d="M701.2,195.89c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S701.2,195.09,701.2,195.89z
|
|
||||||
"/>
|
|
||||||
<path class="st12" d="M714.9,195.89c0,0.9-0.7,1.6-1.6,1.6c-0.9,0-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6
|
|
||||||
S714.9,195.09,714.9,195.89z"/>
|
|
||||||
<path class="st12" d="M728.7,195.89c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6
|
|
||||||
C728.01,194.29,728.7,195.09,728.7,195.89z"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<path class="st12" d="M82.8,195.89c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S82.8,195.09,82.8,195.89z"/>
|
|
||||||
<path class="st12" d="M96.5,195.89c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6
|
|
||||||
C95.8,194.29,96.5,195.09,96.5,195.89z"/>
|
|
||||||
<path class="st12" d="M110.2,195.89c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S110.2,195.09,110.2,195.89z
|
|
||||||
"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 133.6541 162.0062)" class="st13 st9 st10">data</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 327.363 162.0062)" class="st12 st9 st10">free space</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st14" x1="175.2" y1="168.79" x2="133.5" y2="168.79"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st13" points="174.9,171.39 176.5,168.79 174.9,166.29 174.8,166.29 174.8,171.39 "/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<polygon class="st13" points="133.8,171.29 133.8,166.39 131.4,168.79 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st15" x1="563.7" y1="168.79" x2="197.49" y2="168.79"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st12" points="563.4,171.29 563.4,166.39 565.8,168.79 "/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<polygon class="st12" points="197.79,171.29 197.79,166.39 195.29,168.79 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 615.4679 160.3837)" class="st12 st9 st10">non-allocated space</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st15" x1="593.7" y1="168.79" x2="829.7" y2="168.79"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st12" points="829.4,166.39 829.4,171.29 831.8,168.79 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st15" x1="678.7" y1="168.79" x2="589.7" y2="168.79"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st12" points="590.01,171.29 590.01,166.39 587.6,168.79 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 133.1212 200.1532)" class="st16 st9 st10">h</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 165.1565 200.1532)" class="st16 st9 st10">o</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 1.811981e-04 240.995)" class="st1 st9 st10">0</text>
|
|
||||||
</g>
|
|
||||||
<line class="st4" x1="5.5" y1="161.59" x2="5.5" y2="222.79"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 13 KiB |
@@ -0,0 +1,24 @@
|
|||||||
|
# Mongoose Network Library Examples
|
||||||
|
|
||||||
|
In order to build and run any of the existing examples, please follow:
|
||||||
|
https://mongoose.ws/documentation/#how-to-build-and-run-examples
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
Rules for creating a new example:
|
||||||
|
|
||||||
|
- Makefile golden reference for desktop/server example: [http-server](http-server)
|
||||||
|
- Makefile golden reference for the embedded example:
|
||||||
|
[stm32/nucleo-f746zg-baremetal](stm32/nucleo-f746zg-baremetal)
|
||||||
|
- An example must build on Windows, Mac and Ubuntu Linux systems
|
||||||
|
- Assume that user installed tools according to https://mongoose.ws/tutorials/tools/
|
||||||
|
- Makefile must not include any other make files
|
||||||
|
- Use `CFLAGS` for system-specific compilation options
|
||||||
|
- Use `CFLAGS_MONGOOSE` for mongoose-specific compilation options
|
||||||
|
- Use `$(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA)` to compile
|
||||||
|
- If external repository is required, download it on demand using git
|
||||||
|
shallow clone. See embedded example golden reference
|
||||||
|
- Keep Makefile as short as possible, but verbose to understand it easily
|
||||||
|
- Symlink files when required, like `mongoose.c`, `ca.pem`, etc. Make no copies
|
||||||
|
- Example's README.md should contain only the title and the link to mongoose.ws
|
||||||
|
tutorial page
|
||||||
@@ -9,6 +9,6 @@
|
|||||||
|
|
||||||
#define MG_ARCH MG_ARCH_CUSTOM
|
#define MG_ARCH MG_ARCH_CUSTOM
|
||||||
#define MG_ENABLE_SOCKET 0
|
#define MG_ENABLE_SOCKET 0
|
||||||
#define MG_ENABLE_MIP 1
|
#define MG_ENABLE_TCPIP 1
|
||||||
#define mkdir(a, b) (-1)
|
#define mkdir(a, b) (-1)
|
||||||
//#define MG_ENABLE_LOG 0
|
//#define MG_ENABLE_LOG 0
|
||||||
@@ -3,13 +3,13 @@
|
|||||||
|
|
||||||
#define SS_PIN 3 // Slave select pin
|
#define SS_PIN 3 // Slave select pin
|
||||||
struct mg_mgr mgr; // Mongoose event manager
|
struct mg_mgr mgr; // Mongoose event manager
|
||||||
struct mip_spi spi = {
|
struct mg_tcpip_spi spi = {
|
||||||
NULL, // SPI data
|
NULL, // SPI data
|
||||||
[](void *) { digitalWrite(SS_PIN, LOW); }, // begin transation
|
[](void *) { digitalWrite(SS_PIN, LOW); }, // begin transation
|
||||||
[](void *) { digitalWrite(SS_PIN, HIGH); }, // end transaction
|
[](void *) { digitalWrite(SS_PIN, HIGH); }, // end transaction
|
||||||
[](void *, uint8_t c) { return SPI.transfer(c); }, // execute transaction
|
[](void *, uint8_t c) { return SPI.transfer(c); }, // execute transaction
|
||||||
};
|
};
|
||||||
struct mip_if mif = {.mac = {2, 0, 1, 2, 3, 5}}; // MIP network interface
|
struct mg_tcpip_if mif = {.mac = {2, 0, 1, 2, 3, 5}}; // network interface
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
@@ -23,15 +23,15 @@ void setup() {
|
|||||||
delay(3000);
|
delay(3000);
|
||||||
MG_INFO(("Starting TCP/IP stack..."));
|
MG_INFO(("Starting TCP/IP stack..."));
|
||||||
|
|
||||||
mif.driver = &mip_driver_w5500;
|
mif.driver = &mg_tcpip_driver_w5500;
|
||||||
mif.driver_data = &spi;
|
mif.driver_data = &spi;
|
||||||
mip_init(&mgr, &mif);
|
mg_tcpip_init(&mgr, &mif);
|
||||||
|
|
||||||
// Start a 5 sec timer, print status message periodically
|
// Start a 5 sec timer, print status message periodically
|
||||||
mg_timer_add(
|
mg_timer_add(
|
||||||
&mgr, 5000, MG_TIMER_REPEAT,
|
&mgr, 5000, MG_TIMER_REPEAT,
|
||||||
[](void *) {
|
[](void *) {
|
||||||
MG_INFO(("ethernet: %s", mip_driver_w5500.up(&mif) ? "up" : "down"));
|
MG_INFO(("ethernet: %s", mg_tcpip_driver_w5500.up(&mif) ? "up" : "down"));
|
||||||
},
|
},
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,25 @@
|
|||||||
PROG ?= example
|
PROG ?= example # Program we are building
|
||||||
CFLAGS ?= -DMG_IO_SIZE=8192 -DMG_ENABLE_LINES
|
DELETE = rm -rf # Command to remove files
|
||||||
|
OUT ?= -o $(PROG) # Compiler argument for output file
|
||||||
|
SOURCES = main.c mongoose.c # Source code files
|
||||||
|
CFLAGS = -W -Wall -Wextra -g -I. # Build options
|
||||||
|
|
||||||
all: $(PROG)
|
# Mongoose build options. See https://mongoose.ws/documentation/#build-options
|
||||||
$(DEBUGGER) ./$(PROG) $(ARGS)
|
CFLAGS_MONGOOSE += -DMG_IO_SIZE=8192 -DMG_ENABLE_LINES
|
||||||
|
|
||||||
$(PROG): main.c
|
ifeq ($(OS),Windows_NT) # Windows settings. Assume MinGW compiler. To use VC: make CC=cl CFLAGS=/MD OUT=/Feprog.exe
|
||||||
$(CC) ../../mongoose.c -I../.. -W -Wall $(CFLAGS) -o $(PROG) main.c
|
PROG ?= example.exe # Use .exe suffix for the binary
|
||||||
|
CC = gcc # Use MinGW gcc compiler
|
||||||
|
CFLAGS += -lws2_32 # Link against Winsock library
|
||||||
|
DELETE = cmd /C del /Q /F /S # Command prompt command to delete files
|
||||||
|
OUT ?= -o $(PROG) # Build output
|
||||||
|
endif
|
||||||
|
|
||||||
clean:
|
all: $(PROG) # Default target. Build and run program
|
||||||
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb
|
$(RUN) ./$(PROG) $(ARGS)
|
||||||
|
|
||||||
|
$(PROG): $(SOURCES) # Build program from sources
|
||||||
|
$(CC) $(SOURCES) $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA) $(OUT)
|
||||||
|
|
||||||
|
clean: # Cleanup. Delete built program and all build artifacts
|
||||||
|
$(DELETE) $(PROG) *.o *.obj *.exe *.dSYM
|
||||||
@@ -1 +1 @@
|
|||||||
See detailed tutorial at https://mongoose.ws/tutorials/captive-dns-portal/
|
See detailed tutorial at https://mongoose.ws/tutorials/captive-dns-server/
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../../mongoose.c
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../../mongoose.h
|
||||||
@@ -1,40 +1,51 @@
|
|||||||
PROG ?= example
|
PROG ?= ./example # Program we are building
|
||||||
SOURCES ?= ../../mongoose.c main.c net.c packed_fs.c
|
PACK ?= ./pack # Packing executable
|
||||||
CFLAGS ?= -I../.. -DMG_ENABLE_PACKED_FS=1 -DMG_ENABLE_LINES=1 $(EXTRA)
|
DELETE = rm -rf # Command to remove files
|
||||||
FILES_TO_EMBED ?= $(wildcard web_root/*)
|
OUT ?= -o $(PROG) # Compiler argument for output file
|
||||||
ROOT ?= $(realpath $(CURDIR)/../../..)
|
SOURCES = main.c mongoose.c net.c # Source code files
|
||||||
DOCKER ?= docker run --rm -e Tmp=. -e WINEDEBUG=-all -v $(ROOT):$(ROOT) -w $(CURDIR)
|
CFLAGS = -W -Wall -Wextra -g -I. # Build options
|
||||||
VC98 ?= $(DOCKER) mdashnet/vc98 wine
|
|
||||||
MINGW ?= $(DOCKER) mdashnet/mingw
|
|
||||||
|
|
||||||
ifeq "$(SSL)" "MBEDTLS"
|
# Mongoose build options. See https://mongoose.ws/documentation/#build-options
|
||||||
CFLAGS += -DMG_ENABLE_MBEDTLS=1 -I$(MBEDTLS)/include -L$(MBEDTLS)/lib -lmbedtls -lmbedcrypto -lmbedx509
|
CFLAGS_MONGOOSE +=
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq "$(SSL)" "OPENSSL"
|
ifeq ($(OS),Windows_NT) # Windows settings. Assume MinGW compiler. To use VC: make CC=cl CFLAGS=/MD OUT=/Feprog.exe
|
||||||
CFLAGS += -DMG_ENABLE_OPENSSL=1 -I$(OPENSSL)/include -L$(OPENSSL)/lib -lssl -lcrypto
|
PROG = example.exe # Use .exe suffix for the binary
|
||||||
|
PACK = pack.exe # Packing executable
|
||||||
|
CC = gcc # Use MinGW gcc compiler
|
||||||
|
CFLAGS += -lws2_32 # Link against Winsock library
|
||||||
|
DELETE = cmd /C del /Q /F /S # Command prompt command to delete files
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# Default target. Build and run program
|
||||||
all: $(PROG)
|
all: $(PROG)
|
||||||
$(RUN) ./$(PROG)
|
$(RUN) $(PROG) $(ARGS)
|
||||||
|
|
||||||
$(PROG): $(SOURCES) $(FILES_TO_EMBED)
|
# Build program from sources
|
||||||
$(CC) ../../test/pack.c -o pack
|
$(PROG): $(SOURCES)
|
||||||
./pack $(FILES_TO_EMBED) > packed_fs.c
|
$(CC) $(SOURCES) $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA) $(OUT)
|
||||||
$(CC) -W -Wall -Wextra -O0 -g3 $(CFLAGS) -o $(PROG) $(SOURCES)
|
|
||||||
|
|
||||||
|
# Bundle JS libraries (preact, preact-router, ...) into a single file
|
||||||
|
web_root/bundle.js:
|
||||||
|
curl -s https://npm.reversehttp.com/preact,preact/hooks,htm/preact,preact-router -o $@
|
||||||
|
|
||||||
mingw: $(SOURCES) $(FILES_TO_EMBED)
|
# Create optimised CSS. Prerequisite: npm -g i tailwindcss tailwindcss-font-inter
|
||||||
$(MINGW) i686-w64-mingw32-gcc $(CFLAGS) ../../test/pack.c -o pack.exe
|
web_root/main.css: web_root/index.html $(wildcard web_root/*.js)
|
||||||
$(MINGW) wine cmd /c 'pack.exe $(FILES_TO_EMBED) > packed_fs.c'
|
npx tailwindcss -o $@ --minify
|
||||||
$(MINGW) i686-w64-mingw32-gcc $(CFLAGS) $(SOURCES) -lws2_32 -o $(PROG).exe
|
|
||||||
$(MINGW) wine $(PROG).exe
|
|
||||||
|
|
||||||
vc98: $(SOURCES) $(FILES_TO_EMBED)
|
# Generate packed filesystem for serving Web UI
|
||||||
$(VC98) cl.exe /nologo $(CFLAGS) ../../test/pack.c /Fepack.exe
|
packed_fs.c: $(wildcard web_root/*) Makefile web_root/main.css web_root/bundle.js
|
||||||
$(VC98) cmd /c 'pack.exe $(FILES_TO_EMBED) > packed_fs.c'
|
$(CC) ../../test/pack.c -o $(PACK)
|
||||||
$(VC98) cl.exe /nologo /O2 $(CFLAGS) $(SOURCES) /Fe$(PROG).exe
|
$(PACK) $(wildcard web_root/*) > $@
|
||||||
$(VC98) $(PROG).exe
|
|
||||||
|
|
||||||
|
mbedtls:
|
||||||
|
git clone --depth 1 -b v2.28.2 https://github.com/mbed-tls/mbedtls $@
|
||||||
|
|
||||||
|
ifeq ($(TLS), mbedtls)
|
||||||
|
CFLAGS += -DMG_ENABLE_MBEDTLS=1 -Wno-conversion -Imbedtls/include
|
||||||
|
CFLAGS += -DMBEDTLS_CONFIG_FILE=\"mbedtls_config.h\" mbedtls/library/*.c
|
||||||
|
$(PROG): mbedtls
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Cleanup. Delete built program and all build artifacts
|
||||||
clean:
|
clean:
|
||||||
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb log.txt pack
|
$(DELETE) $(PROG) $(PACK) *.o *.obj *.exe *.dSYM mbedtls
|
||||||
@@ -5,23 +5,22 @@ into an embedded device and provide a complete device dashboard with the
|
|||||||
following features:
|
following features:
|
||||||
|
|
||||||
- Authentication: login-protected dashboard
|
- Authentication: login-protected dashboard
|
||||||
- Multiple logins with different permissions (admin and user)
|
- Multiple logins (with possibly different permissions)
|
||||||
- Web UI is fully embedded into the server/firmware binary, and does not
|
- The Web UI can be fully embedded into the firmware binary, then not
|
||||||
need a filesystem to serve it. UI is resilient to FS problems
|
needing a filesystem to serve it; so being resilient to FS problems
|
||||||
- Administrators can change server settings
|
- All changes are propagated to all connected clients
|
||||||
- All changes are propagates to all connected clients
|
|
||||||
- A device is connected to the external MQTT server
|
|
||||||
- Logged in clients can send/receive messages to a device which get
|
|
||||||
forwarded to MQTT
|
|
||||||
|
|
||||||
# Screenshots
|
## Screenshots
|
||||||
|
|
||||||
This is a login screen that prompts for user/password
|
This is a login screen that prompts for user/password
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
# Main dashboard
|
## Main dashboard
|
||||||
|
|
||||||
A main dashboard page shows and interactive MQTT console
|
The main dashboard page shows the interactive console
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
|
<!-- See a detailed tutorial at https://mongoose.ws/tutorials/device-dashboard/ -->
|
||||||
@@ -1,18 +1,33 @@
|
|||||||
// Copyright (c) 2020-2022 Cesanta Software Limited
|
// Copyright (c) 2020-2023 Cesanta Software Limited
|
||||||
// All rights reserved
|
// All rights reserved
|
||||||
|
|
||||||
#include "mongoose.h"
|
#include "mongoose.h"
|
||||||
const char *s_listening_url = "http://0.0.0.0:8000";
|
#include "net.h"
|
||||||
|
|
||||||
void device_dashboard_fn(struct mg_connection *, int, void *, void *);
|
static int s_sig_num;
|
||||||
|
static void signal_handler(int sig_num) {
|
||||||
|
signal(sig_num, signal_handler);
|
||||||
|
s_sig_num = sig_num;
|
||||||
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
struct mg_mgr mgr;
|
struct mg_mgr mgr;
|
||||||
|
|
||||||
|
signal(SIGPIPE, SIG_IGN);
|
||||||
|
signal(SIGINT, signal_handler);
|
||||||
|
signal(SIGTERM, signal_handler);
|
||||||
|
|
||||||
|
srand(time(NULL));
|
||||||
mg_log_set(MG_LL_DEBUG); // Set debug log level
|
mg_log_set(MG_LL_DEBUG); // Set debug log level
|
||||||
mg_mgr_init(&mgr);
|
mg_mgr_init(&mgr);
|
||||||
mg_http_listen(&mgr, s_listening_url, device_dashboard_fn, &mgr);
|
|
||||||
MG_INFO(("Listening on %s", s_listening_url));
|
web_init(&mgr);
|
||||||
while (mgr.conns != NULL) mg_mgr_poll(&mgr, 500);
|
while (s_sig_num == 0) {
|
||||||
|
mg_mgr_poll(&mgr, 50);
|
||||||
|
}
|
||||||
|
|
||||||
mg_mgr_free(&mgr);
|
mg_mgr_free(&mgr);
|
||||||
|
MG_INFO(("Exiting on signal %d", s_sig_num));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
/* Workaround for some mbedtls source files using INT_MAX without including limits.h */
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
#define MBEDTLS_NO_PLATFORM_ENTROPY
|
||||||
|
//#define MBEDTLS_ENTROPY_HARDWARE_ALT
|
||||||
|
#define MBEDTLS_SSL_OUT_CONTENT_LEN 2048
|
||||||
|
#define MBEDTLS_ALLOW_PRIVATE_ACCESS
|
||||||
|
#define MBEDTLS_HAVE_TIME
|
||||||
|
|
||||||
|
#define MBEDTLS_CIPHER_MODE_CBC
|
||||||
|
#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
|
||||||
|
#define MBEDTLS_ECP_DP_SECP224R1_ENABLED
|
||||||
|
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||||
|
#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
|
||||||
|
#define MBEDTLS_ECP_DP_SECP521R1_ENABLED
|
||||||
|
#define MBEDTLS_ECP_DP_SECP192K1_ENABLED
|
||||||
|
#define MBEDTLS_ECP_DP_SECP224K1_ENABLED
|
||||||
|
#define MBEDTLS_ECP_DP_SECP256K1_ENABLED
|
||||||
|
#define MBEDTLS_ECP_DP_BP256R1_ENABLED
|
||||||
|
#define MBEDTLS_ECP_DP_BP384R1_ENABLED
|
||||||
|
#define MBEDTLS_ECP_DP_BP512R1_ENABLED
|
||||||
|
#define MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||||
|
#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
|
||||||
|
#define MBEDTLS_PKCS1_V15
|
||||||
|
#define MBEDTLS_SHA256_SMALLER
|
||||||
|
#define MBEDTLS_SSL_SERVER_NAME_INDICATION
|
||||||
|
#define MBEDTLS_AES_C
|
||||||
|
#define MBEDTLS_ASN1_PARSE_C
|
||||||
|
#define MBEDTLS_BIGNUM_C
|
||||||
|
#define MBEDTLS_CIPHER_C
|
||||||
|
#define MBEDTLS_CTR_DRBG_C
|
||||||
|
#define MBEDTLS_ENTROPY_C
|
||||||
|
#define MBEDTLS_ERROR_C
|
||||||
|
#define MBEDTLS_MD_C
|
||||||
|
#define MBEDTLS_MD5_C
|
||||||
|
#define MBEDTLS_OID_C
|
||||||
|
#define MBEDTLS_PKCS5_C
|
||||||
|
#define MBEDTLS_PK_C
|
||||||
|
#define MBEDTLS_PK_PARSE_C
|
||||||
|
#define MBEDTLS_PLATFORM_C
|
||||||
|
#define MBEDTLS_RSA_C
|
||||||
|
#define MBEDTLS_SHA1_C
|
||||||
|
#define MBEDTLS_SHA224_C
|
||||||
|
#define MBEDTLS_SHA256_C
|
||||||
|
#define MBEDTLS_SHA512_C
|
||||||
|
#define MBEDTLS_SSL_CLI_C
|
||||||
|
#define MBEDTLS_SSL_SRV_C
|
||||||
|
#define MBEDTLS_SSL_TLS_C
|
||||||
|
#define MBEDTLS_X509_CRT_PARSE_C
|
||||||
|
#define MBEDTLS_X509_USE_C
|
||||||
|
#define MBEDTLS_AES_FEWER_TABLES
|
||||||
|
#define MBEDTLS_PEM_PARSE_C
|
||||||
|
#define MBEDTLS_BASE64_C
|
||||||
|
|
||||||
|
// TLS 1.2
|
||||||
|
#define MBEDTLS_SSL_PROTO_TLS1_2
|
||||||
|
#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||||
|
#define MBEDTLS_GCM_C
|
||||||
|
#define MBEDTLS_ECDH_C
|
||||||
|
#define MBEDTLS_ECP_C
|
||||||
|
#define MBEDTLS_ECDSA_C
|
||||||
|
#define MBEDTLS_ASN1_WRITE_C
|
||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../../mongoose.c
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../../mongoose.h
|
||||||
@@ -1,230 +1,252 @@
|
|||||||
// Copyright (c) 2020-2022 Cesanta Software Limited
|
// Copyright (c) 2023 Cesanta Software Limited
|
||||||
// All rights reserved
|
// All rights reserved
|
||||||
|
|
||||||
#include "mongoose.h"
|
#include "net.h"
|
||||||
|
|
||||||
#if !defined(MQTT_SERVER)
|
|
||||||
#define MQTT_SERVER "mqtt://broker.hivemq.com:1883"
|
|
||||||
#endif
|
|
||||||
#define MQTT_PUBLISH_TOPIC "mg/my_device"
|
|
||||||
#define MQTT_SUBSCRIBE_TOPIC "mg/#"
|
|
||||||
|
|
||||||
static time_t s_boot_timestamp = 0; // Updated by SNTP
|
|
||||||
#ifndef DISABLE_ROUTING
|
|
||||||
static struct mg_connection *s_sntp_conn = NULL; // SNTP connection
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Define a system time alternative
|
|
||||||
time_t ourtime(time_t *tp) {
|
|
||||||
time_t t = s_boot_timestamp + (time_t) (mg_millis() / 1000);
|
|
||||||
if (tp != NULL) *tp = t;
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Authenticated user.
|
// Authenticated user.
|
||||||
// A user can be authenticated by:
|
// A user can be authenticated by:
|
||||||
// - a name:pass pair
|
// - a name:pass pair, passed in a header Authorization: Basic .....
|
||||||
// - a token
|
// - an access_token, passed in a header Cookie: access_token=....
|
||||||
// When a user is shown a login screen, she enters a user:pass. If successful,
|
// When a user is shown a login screen, she enters a user:pass. If successful,
|
||||||
// a server returns user info which includes token. From that point on,
|
// a server responds with a http-only access_token cookie set.
|
||||||
// client can use token for authentication. Tokens could be refreshed/changed
|
|
||||||
// on a server side, forcing clients to re-login.
|
|
||||||
struct user {
|
struct user {
|
||||||
const char *name, *pass, *token;
|
const char *name, *pass, *access_token;
|
||||||
};
|
};
|
||||||
|
|
||||||
// This is a configuration structure we're going to show on a dashboard
|
// Settings
|
||||||
static struct config {
|
struct settings {
|
||||||
char *url, *pub, *sub; // MQTT settings
|
bool log_enabled;
|
||||||
} s_config;
|
int log_level;
|
||||||
|
long brightness;
|
||||||
|
char *device_name;
|
||||||
|
};
|
||||||
|
|
||||||
static struct mg_connection *s_mqtt = NULL; // MQTT connection
|
static struct settings s_settings = {true, 1, 57, NULL};
|
||||||
static bool s_connected = false; // MQTT connection established
|
|
||||||
|
|
||||||
// Try to update a single configuration value
|
static const char *s_json_header =
|
||||||
static void update_config(struct mg_str *body, const char *name, char **value) {
|
"Content-Type: application/json\r\n"
|
||||||
char buf[256];
|
"Cache-Control: no-cache\r\n";
|
||||||
if (mg_http_get_var(body, name, buf, sizeof(buf)) > 0) {
|
static uint64_t s_boot_timestamp = 0; // Updated by SNTP
|
||||||
free(*value);
|
|
||||||
*value = strdup(buf);
|
// Certificate generation procedure:
|
||||||
}
|
// openssl ecparam -name prime256v1 -genkey -noout -out key.pem
|
||||||
|
// openssl req -new -key key.pem -x509 -nodes -days 3650 -out cert.pem
|
||||||
|
static const char *s_ssl_cert =
|
||||||
|
"-----BEGIN CERTIFICATE-----\n"
|
||||||
|
"MIIBCTCBsAIJAK9wbIDkHnAoMAoGCCqGSM49BAMCMA0xCzAJBgNVBAYTAklFMB4X\n"
|
||||||
|
"DTIzMDEyOTIxMjEzOFoXDTMzMDEyNjIxMjEzOFowDTELMAkGA1UEBhMCSUUwWTAT\n"
|
||||||
|
"BgcqhkjOPQIBBggqhkjOPQMBBwNCAARzSQS5OHd17lUeNI+6kp9WYu0cxuEIi/JT\n"
|
||||||
|
"jphbCmdJD1cUvhmzM9/phvJT9ka10Z9toZhgnBq0o0xfTQ4jC1vwMAoGCCqGSM49\n"
|
||||||
|
"BAMCA0gAMEUCIQCe0T2E0GOiVe9KwvIEPeX1J1J0T7TNacgR0Ya33HV9VgIgNvdn\n"
|
||||||
|
"aEWiBp1xshs4iz6WbpxrS1IHucrqkZuJLfNZGZI=\n"
|
||||||
|
"-----END CERTIFICATE-----\n";
|
||||||
|
|
||||||
|
static const char *s_ssl_key =
|
||||||
|
"-----BEGIN EC PRIVATE KEY-----\n"
|
||||||
|
"MHcCAQEEICBz3HOkQLPBDtdknqC7k1PNsWj6HfhyNB5MenfjmqiooAoGCCqGSM49\n"
|
||||||
|
"AwEHoUQDQgAEc0kEuTh3de5VHjSPupKfVmLtHMbhCIvyU46YWwpnSQ9XFL4ZszPf\n"
|
||||||
|
"6YbyU/ZGtdGfbaGYYJwatKNMX00OIwtb8A==\n"
|
||||||
|
"-----END EC PRIVATE KEY-----\n";
|
||||||
|
|
||||||
|
// This is for newlib and TLS (mbedTLS)
|
||||||
|
uint64_t mg_now(void) {
|
||||||
|
return mg_millis() + s_boot_timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse HTTP requests, return authenticated user or NULL
|
int ui_event_next(int no, struct ui_event *e) {
|
||||||
static struct user *getuser(struct mg_http_message *hm) {
|
if (no < 0 || no >= MAX_EVENTS_NO)
|
||||||
// In production, make passwords strong and tokens randomly generated
|
return 0;
|
||||||
// In this example, user list is kept in RAM. In production, it can
|
|
||||||
// be backed by file, database, or some other method.
|
|
||||||
static struct user users[] = {
|
|
||||||
{"admin", "pass0", "admin_token"},
|
|
||||||
{"user1", "pass1", "user1_token"},
|
|
||||||
{"user2", "pass2", "user2_token"},
|
|
||||||
{NULL, NULL, NULL},
|
|
||||||
};
|
|
||||||
char user[256], pass[256];
|
|
||||||
struct user *u;
|
|
||||||
mg_http_creds(hm, user, sizeof(user), pass, sizeof(pass));
|
|
||||||
if (user[0] != '\0' && pass[0] != '\0') {
|
|
||||||
// Both user and password is set, search by user/password
|
|
||||||
for (u = users; u->name != NULL; u++)
|
|
||||||
if (strcmp(user, u->name) == 0 && strcmp(pass, u->pass) == 0) return u;
|
|
||||||
} else if (user[0] == '\0') {
|
|
||||||
// Only password is set, search by token
|
|
||||||
for (u = users; u->name != NULL; u++)
|
|
||||||
if (strcmp(pass, u->token) == 0) return u;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Notify all config watchers about the config change
|
srand(no);
|
||||||
static void send_notification(struct mg_mgr *mgr, const char *fmt, ...) {
|
e->type = (uint8_t) rand() % 4;
|
||||||
struct mg_connection *c;
|
e->prio = (uint8_t) rand() % 3;
|
||||||
for (c = mgr->conns; c != NULL; c = c->next) {
|
e->timestamp = (unsigned long) (mg_now() - 86400 * 1000 /* one day back */ +
|
||||||
if (c->data[0] == 'W') {
|
no * 300 * 1000 /* 5 mins between alerts */ +
|
||||||
va_list ap;
|
1000 * (rand() % 300) /* randomize event time */) /
|
||||||
va_start(ap, fmt);
|
1000;
|
||||||
mg_ws_vprintf(c, WEBSOCKET_OP_TEXT, fmt, &ap);
|
|
||||||
va_end(ap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send simulated metrics data to the dashboard, for chart rendering
|
mg_snprintf(e->text, MAX_EVENT_TEXT_SIZE,
|
||||||
static void timer_metrics_fn(void *param) {
|
"event#%d", no);
|
||||||
send_notification(param, "{%Q:%Q,%Q:[%lu, %d]}", "name", "metrics", "data",
|
return no + 1;
|
||||||
(unsigned long) ourtime(NULL),
|
|
||||||
10 + (int) ((double) rand() * 10 / RAND_MAX));
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef DISABLE_ROUTING
|
|
||||||
|
|
||||||
// MQTT event handler function
|
|
||||||
static void mqtt_fn(struct mg_connection *c, int ev, void *ev_data, void *fnd) {
|
|
||||||
if (ev == MG_EV_CONNECT && mg_url_is_ssl(s_config.url)) {
|
|
||||||
struct mg_tls_opts opts = {.ca = "ca.pem",
|
|
||||||
.srvname = mg_url_host(s_config.url)};
|
|
||||||
mg_tls_init(c, &opts);
|
|
||||||
} else if (ev == MG_EV_MQTT_OPEN) {
|
|
||||||
s_connected = true;
|
|
||||||
c->is_hexdumping = 1;
|
|
||||||
mg_mqtt_sub(s_mqtt, mg_str(s_config.sub), 2);
|
|
||||||
send_notification(c->mgr, "{%Q:%Q,%Q:null}", "name", "config", "data");
|
|
||||||
MG_INFO(("MQTT connected, server %s", MQTT_SERVER));
|
|
||||||
} else if (ev == MG_EV_MQTT_MSG) {
|
|
||||||
struct mg_mqtt_message *mm = ev_data;
|
|
||||||
send_notification(c->mgr, "{%Q:%Q,%Q:{%Q: %.*Q, %Q: %.*Q, %Q: %d}}", "name",
|
|
||||||
"message", "data", "topic", (int) mm->topic.len,
|
|
||||||
mm->topic.ptr, "data", (int) mm->data.len, mm->data.ptr,
|
|
||||||
"qos", (int) mm->qos);
|
|
||||||
} else if (ev == MG_EV_MQTT_CMD) {
|
|
||||||
struct mg_mqtt_message *mm = (struct mg_mqtt_message *) ev_data;
|
|
||||||
MG_DEBUG(("%lu cmd %d qos %d", c->id, mm->cmd, mm->qos));
|
|
||||||
} else if (ev == MG_EV_CLOSE) {
|
|
||||||
s_mqtt = NULL;
|
|
||||||
if (s_connected) {
|
|
||||||
s_connected = false;
|
|
||||||
send_notification(c->mgr, "{%Q:%Q,%Q:null}", "name", "config", "data");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(void) fnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keep MQTT connection open - reconnect if closed
|
|
||||||
static void timer_mqtt_fn(void *param) {
|
|
||||||
struct mg_mgr *mgr = (struct mg_mgr *) param;
|
|
||||||
if (s_mqtt == NULL) {
|
|
||||||
struct mg_mqtt_opts opts;
|
|
||||||
memset(&opts, 0, sizeof(opts));
|
|
||||||
s_mqtt = mg_mqtt_connect(mgr, s_config.url, &opts, mqtt_fn, NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SNTP connection event handler. When we get a response from an SNTP server,
|
// SNTP connection event handler. When we get a response from an SNTP server,
|
||||||
// adjust s_boot_timestamp. We'll get a valid time from that point on
|
// adjust s_boot_timestamp. We'll get a valid time from that point on
|
||||||
static void sfn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
static void sfn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||||
if (ev == MG_EV_SNTP_TIME) {
|
uint64_t *expiration_time = (uint64_t *) c->data;
|
||||||
|
if (ev == MG_EV_OPEN) {
|
||||||
|
*expiration_time = mg_millis() + 3000; // Store expiration time in 3s
|
||||||
|
} else if (ev == MG_EV_SNTP_TIME) {
|
||||||
uint64_t t = *(uint64_t *) ev_data;
|
uint64_t t = *(uint64_t *) ev_data;
|
||||||
s_boot_timestamp = (time_t) ((t - mg_millis()) / 1000);
|
s_boot_timestamp = t - mg_millis();
|
||||||
c->is_closing = 1;
|
c->is_closing = 1;
|
||||||
} else if (ev == MG_EV_CLOSE) {
|
} else if (ev == MG_EV_POLL) {
|
||||||
s_sntp_conn = NULL;
|
if (mg_millis() > *expiration_time) c->is_closing = 1;
|
||||||
}
|
}
|
||||||
(void) fn_data;
|
(void) fn_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void timer_sntp_fn(void *param) { // SNTP timer function. Sync up time
|
static void timer_sntp_fn(void *param) { // SNTP timer function. Sync up time
|
||||||
struct mg_mgr *mgr = (struct mg_mgr *) param;
|
mg_sntp_connect(param, "udp://time.google.com:123", sfn, NULL);
|
||||||
if (s_sntp_conn == NULL && s_boot_timestamp == 0) {
|
|
||||||
s_sntp_conn = mg_sntp_connect(mgr, NULL, sfn, NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
// Parse HTTP requests, return authenticated user or NULL
|
||||||
|
static struct user *authenticate(struct mg_http_message *hm) {
|
||||||
|
// In production, make passwords strong and tokens randomly generated
|
||||||
|
// In this example, user list is kept in RAM. In production, it can
|
||||||
|
// be backed by file, database, or some other method.
|
||||||
|
static struct user users[] = {
|
||||||
|
{"admin", "admin", "admin_token"},
|
||||||
|
{"user1", "user1", "user1_token"},
|
||||||
|
{"user2", "user2", "user2_token"},
|
||||||
|
{NULL, NULL, NULL},
|
||||||
|
};
|
||||||
|
char user[64], pass[64];
|
||||||
|
struct user *u, *result = NULL;
|
||||||
|
mg_http_creds(hm, user, sizeof(user), pass, sizeof(pass));
|
||||||
|
MG_INFO(("user [%s] pass [%s]", user, pass));
|
||||||
|
|
||||||
|
if (user[0] != '\0' && pass[0] != '\0') {
|
||||||
|
// Both user and password is set, search by user/password
|
||||||
|
for (u = users; result == NULL && u->name != NULL; u++)
|
||||||
|
if (strcmp(user, u->name) == 0 && strcmp(pass, u->pass) == 0) result = u;
|
||||||
|
} else if (user[0] == '\0') {
|
||||||
|
// Only password is set, search by token
|
||||||
|
for (u = users; result == NULL && u->name != NULL; u++)
|
||||||
|
if (strcmp(pass, u->access_token) == 0) result = u;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_login(struct mg_connection *c, struct user *u) {
|
||||||
|
char cookie[256];
|
||||||
|
mg_snprintf(cookie, sizeof(cookie),
|
||||||
|
"Set-Cookie: access_token=%s; Path=/; "
|
||||||
|
"%sHttpOnly; SameSite=Lax; Max-Age=%d\r\n",
|
||||||
|
u->access_token, c->is_tls ? "Secure; " : "", 3600 * 24);
|
||||||
|
mg_http_reply(c, 200, cookie, "{%m:%m}", MG_ESC("user"), MG_ESC(u->name));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_logout(struct mg_connection *c) {
|
||||||
|
char cookie[256];
|
||||||
|
mg_snprintf(cookie, sizeof(cookie),
|
||||||
|
"Set-Cookie: access_token=; Path=/; "
|
||||||
|
"Expires=Thu, 01 Jan 1970 00:00:00 UTC; "
|
||||||
|
"%sHttpOnly; Max-Age=0; \r\n",
|
||||||
|
c->is_tls ? "Secure; " : "");
|
||||||
|
mg_http_reply(c, 200, cookie, "true\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_debug(struct mg_connection *c, struct mg_http_message *hm) {
|
||||||
|
int level = mg_json_get_long(hm->body, "$.level", MG_LL_DEBUG);
|
||||||
|
mg_log_set(level);
|
||||||
|
mg_http_reply(c, 200, "", "Debug level set to %d\n", level);
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t print_int_arr(void (*out)(char, void *), void *ptr, va_list *ap) {
|
||||||
|
size_t len = 0, num = va_arg(*ap, size_t); // Number of items in the array
|
||||||
|
int *arr = va_arg(*ap, int *); // Array ptr
|
||||||
|
for (size_t i = 0; i < num; i++) {
|
||||||
|
len += mg_xprintf(out, ptr, "%s%d", i == 0 ? "" : ",", arr[i]);
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_stats_get(struct mg_connection *c) {
|
||||||
|
int points[] = {21, 22, 22, 19, 18, 20, 23, 23, 22, 22, 22, 23, 22};
|
||||||
|
mg_http_reply(c, 200, s_json_header, "{%m:%d,%m:%d,%m:[%M]}",
|
||||||
|
MG_ESC("temperature"), 21, //
|
||||||
|
MG_ESC("humidity"), 67, //
|
||||||
|
MG_ESC("points"), print_int_arr,
|
||||||
|
sizeof(points) / sizeof(points[0]), points);
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t print_events(void (*out)(char, void *), void *ptr, va_list *ap) {
|
||||||
|
size_t len = 0;
|
||||||
|
struct ui_event ev;
|
||||||
|
int pageno = va_arg(*ap, unsigned);
|
||||||
|
int no = (pageno - 1) * EVENTS_PER_PAGE;
|
||||||
|
int end = no + EVENTS_PER_PAGE;
|
||||||
|
|
||||||
|
while ((no = ui_event_next(no, &ev)) != 0 && no <= end) {
|
||||||
|
len += mg_xprintf(out, ptr, "%s{%m:%lu,%m:%d,%m:%d,%m:%m}", //
|
||||||
|
len == 0 ? "" : ",", //
|
||||||
|
MG_ESC("time"), ev.timestamp, //
|
||||||
|
MG_ESC("type"), ev.type, //
|
||||||
|
MG_ESC("prio"), ev.prio, //
|
||||||
|
MG_ESC("text"), MG_ESC(ev.text));
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_events_get(struct mg_connection *c, struct mg_http_message *hm) {
|
||||||
|
int pageno = mg_json_get_long(hm->body, "$.page", 1);
|
||||||
|
mg_http_reply(c, 200, s_json_header, "{%m:[%M], %m:%d}", MG_ESC("arr"),
|
||||||
|
print_events, pageno, MG_ESC("totalCount"), MAX_EVENTS_NO);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_settings_set(struct mg_connection *c, struct mg_str body) {
|
||||||
|
struct settings settings;
|
||||||
|
memset(&settings, 0, sizeof(settings));
|
||||||
|
mg_json_get_bool(body, "$.log_enabled", &settings.log_enabled);
|
||||||
|
settings.log_level = mg_json_get_long(body, "$.log_level", 0);
|
||||||
|
settings.brightness = mg_json_get_long(body, "$.brightness", 0);
|
||||||
|
char *s = mg_json_get_str(body, "$.device_name");
|
||||||
|
if (s && strlen(s) < MAX_DEVICE_NAME) {
|
||||||
|
free(settings.device_name);
|
||||||
|
settings.device_name = s;
|
||||||
|
} else {
|
||||||
|
free(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save to the device flash
|
||||||
|
s_settings = settings;
|
||||||
|
bool ok = true;
|
||||||
|
mg_http_reply(c, 200, s_json_header,
|
||||||
|
"{%m:%s,%m:%m}", //
|
||||||
|
MG_ESC("status"), ok ? "true" : "false", //
|
||||||
|
MG_ESC("message"), MG_ESC(ok ? "Success" : "Failed"));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_settings_get(struct mg_connection *c) {
|
||||||
|
mg_http_reply(c, 200, s_json_header, "{%m:%s,%m:%hhu,%m:%hhu,%m:%m}", //
|
||||||
|
MG_ESC("log_enabled"),
|
||||||
|
s_settings.log_enabled ? "true" : "false", //
|
||||||
|
MG_ESC("log_level"), s_settings.log_level, //
|
||||||
|
MG_ESC("brightness"), s_settings.brightness, //
|
||||||
|
MG_ESC("device_name"), MG_ESC(s_settings.device_name));
|
||||||
|
}
|
||||||
|
|
||||||
// HTTP request handler function
|
// HTTP request handler function
|
||||||
void device_dashboard_fn(struct mg_connection *c, int ev, void *ev_data,
|
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||||
void *fn_data) {
|
if (ev == MG_EV_ACCEPT && fn_data != NULL) {
|
||||||
if (ev == MG_EV_OPEN && c->is_listening) {
|
struct mg_tls_opts opts = {.cert = s_ssl_cert, .certkey = s_ssl_key};
|
||||||
mg_timer_add(c->mgr, 1000, MG_TIMER_REPEAT, timer_metrics_fn, c->mgr);
|
mg_tls_init(c, &opts);
|
||||||
#ifndef DISABLE_ROUTING
|
|
||||||
mg_timer_add(c->mgr, 1000, MG_TIMER_REPEAT, timer_mqtt_fn, c->mgr);
|
|
||||||
mg_timer_add(c->mgr, 1000, MG_TIMER_REPEAT, timer_sntp_fn, c->mgr);
|
|
||||||
#endif
|
|
||||||
s_config.url = strdup(MQTT_SERVER);
|
|
||||||
s_config.pub = strdup(MQTT_PUBLISH_TOPIC);
|
|
||||||
s_config.sub = strdup(MQTT_SUBSCRIBE_TOPIC);
|
|
||||||
} else if (ev == MG_EV_HTTP_MSG) {
|
} else if (ev == MG_EV_HTTP_MSG) {
|
||||||
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
||||||
struct user *u = getuser(hm);
|
struct user *u = authenticate(hm);
|
||||||
// MG_INFO(("%p [%.*s] auth %s", c->fd, (int) hm->uri.len, hm->uri.ptr,
|
|
||||||
// u ? u->name : "NULL"));
|
if (mg_http_match_uri(hm, "/api/#") && u == NULL) {
|
||||||
if (mg_http_match_uri(hm, "/api/hi")) {
|
mg_http_reply(c, 403, "", "Not Authorised\n");
|
||||||
mg_http_reply(c, 200, "", "hi\n"); // Testing endpoint
|
|
||||||
} else if (mg_http_match_uri(hm, "/api/debug")) {
|
|
||||||
int level = mg_json_get_long(hm->body, "$.level", MG_LL_DEBUG);
|
|
||||||
mg_log_set(level);
|
|
||||||
mg_http_reply(c, 200, "", "Debug level set to %d\n", level);
|
|
||||||
} else if (u == NULL && mg_http_match_uri(hm, "/api/#")) {
|
|
||||||
// All URIs starting with /api/ must be authenticated
|
|
||||||
mg_http_reply(c, 403, "", "Denied\n");
|
|
||||||
} else if (mg_http_match_uri(hm, "/api/config/get")) {
|
|
||||||
#ifdef DISABLE_ROUTING
|
|
||||||
mg_http_reply(c, 200, NULL, "{%Q:%Q,%Q:%Q,%Q:%Q}\n", "url", s_config.url,
|
|
||||||
"pub", s_config.pub, "sub", s_config.sub);
|
|
||||||
#else
|
|
||||||
mg_http_reply(c, 200, NULL, "{%Q:%Q,%Q:%Q,%Q:%Q,%Q:%s}\n", "url",
|
|
||||||
s_config.url, "pub", s_config.pub, "sub", s_config.sub,
|
|
||||||
"connected", s_connected ? "true" : "false");
|
|
||||||
#endif
|
|
||||||
} else if (mg_http_match_uri(hm, "/api/config/set")) {
|
|
||||||
// Admins only
|
|
||||||
if (strcmp(u->name, "admin") == 0) {
|
|
||||||
update_config(&hm->body, "url", &s_config.url);
|
|
||||||
update_config(&hm->body, "pub", &s_config.pub);
|
|
||||||
update_config(&hm->body, "sub", &s_config.sub);
|
|
||||||
if (s_mqtt) s_mqtt->is_closing = 1; // Ask to disconnect from MQTT
|
|
||||||
send_notification(fn_data, "{%Q:%Q,%Q:null}", "name", "config", "data");
|
|
||||||
mg_http_reply(c, 200, "", "ok\n");
|
|
||||||
} else {
|
|
||||||
mg_http_reply(c, 403, "", "Denied\n");
|
|
||||||
}
|
|
||||||
} else if (mg_http_match_uri(hm, "/api/message/send")) {
|
|
||||||
char buf[256];
|
|
||||||
if (s_connected &&
|
|
||||||
mg_http_get_var(&hm->body, "message", buf, sizeof(buf)) > 0) {
|
|
||||||
mg_mqtt_pub(s_mqtt, mg_str(s_config.pub), mg_str(buf), 1, false);
|
|
||||||
}
|
|
||||||
mg_http_reply(c, 200, "", "ok\n");
|
|
||||||
} else if (mg_http_match_uri(hm, "/api/watch")) {
|
|
||||||
c->data[0] = 'W'; // Mark ourselves as a event listener
|
|
||||||
mg_ws_upgrade(c, hm, NULL);
|
|
||||||
} else if (mg_http_match_uri(hm, "/api/login")) {
|
} else if (mg_http_match_uri(hm, "/api/login")) {
|
||||||
mg_http_reply(c, 200, NULL, "{%Q:%Q,%Q:%Q}\n", "user", u->name, "token",
|
handle_login(c, u);
|
||||||
u->token);
|
} else if (mg_http_match_uri(hm, "/api/logout")) {
|
||||||
|
handle_logout(c);
|
||||||
|
} else if (mg_http_match_uri(hm, "/api/debug")) {
|
||||||
|
handle_debug(c, hm);
|
||||||
|
} else if (mg_http_match_uri(hm, "/api/stats/get")) {
|
||||||
|
handle_stats_get(c);
|
||||||
|
} else if (mg_http_match_uri(hm, "/api/events/get")) {
|
||||||
|
handle_events_get(c, hm);
|
||||||
|
} else if (mg_http_match_uri(hm, "/api/settings/get")) {
|
||||||
|
handle_settings_get(c);
|
||||||
|
} else if (mg_http_match_uri(hm, "/api/settings/set")) {
|
||||||
|
handle_settings_set(c, hm->body);
|
||||||
} else {
|
} else {
|
||||||
struct mg_http_serve_opts opts;
|
struct mg_http_serve_opts opts;
|
||||||
memset(&opts, 0, sizeof(opts));
|
memset(&opts, 0, sizeof(opts));
|
||||||
#if 1
|
#if MG_ENABLE_PACKED_FS
|
||||||
opts.root_dir = "/web_root";
|
opts.root_dir = "/web_root";
|
||||||
opts.fs = &mg_fs_packed;
|
opts.fs = &mg_fs_packed;
|
||||||
#else
|
#else
|
||||||
@@ -237,3 +259,16 @@ void device_dashboard_fn(struct mg_connection *c, int ev, void *ev_data,
|
|||||||
&c->send.buf[9]));
|
&c->send.buf[9]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void web_init(struct mg_mgr *mgr) {
|
||||||
|
s_settings.device_name = strdup("My Device");
|
||||||
|
|
||||||
|
mg_http_listen(mgr, HTTP_URL, fn, NULL);
|
||||||
|
#if MG_ENABLE_MBEDTLS || MG_ENABLE_OPENSSL
|
||||||
|
mg_http_listen(mgr, HTTPS_URL, fn, "");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// mg_timer_add(c->mgr, 1000, MG_TIMER_REPEAT, timer_mqtt_fn, c->mgr);
|
||||||
|
mg_timer_add(mgr, 3600 * 1000, MG_TIMER_RUN_NOW | MG_TIMER_REPEAT,
|
||||||
|
timer_sntp_fn, mgr);
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
// Copyright (c) 2023 Cesanta Software Limited
|
||||||
|
// All rights reserved
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mongoose.h"
|
||||||
|
|
||||||
|
#if !defined(HTTP_URL)
|
||||||
|
#define HTTP_URL "http://0.0.0.0:8000"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(HTTPS_URL)
|
||||||
|
#define HTTPS_URL "http://0.0.0.0:8443"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MAX_DEVICE_NAME 40
|
||||||
|
#define MAX_EVENTS_NO 400
|
||||||
|
#define MAX_EVENT_TEXT_SIZE 10
|
||||||
|
#define EVENTS_PER_PAGE 20
|
||||||
|
|
||||||
|
// Event log entry
|
||||||
|
struct ui_event {
|
||||||
|
uint8_t type, prio;
|
||||||
|
unsigned long timestamp;
|
||||||
|
char text[10];
|
||||||
|
};
|
||||||
|
|
||||||
|
void web_init(struct mg_mgr *mgr);
|
||||||
|
Before Width: | Height: | Size: 283 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 16 KiB |
@@ -0,0 +1,17 @@
|
|||||||
|
module.exports = {
|
||||||
|
content: ['./web_root/*.{html,js}'],
|
||||||
|
xplugins: [ 'tailwindcss', 'xautoprefixer' ],
|
||||||
|
corePlugins: {outline: false},
|
||||||
|
theme: {
|
||||||
|
extend: {},
|
||||||
|
fontFamily: {
|
||||||
|
sans:
|
||||||
|
[
|
||||||
|
"Inter var, Helvetica, sans-serif", {
|
||||||
|
fontFeatureSettings: '"cv11", "ss01"',
|
||||||
|
fontVariationSettings: '"opsz" 32',
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
var n,t,e,_,r,o,i,u,l,c={},a=[],s=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function f(n,t){for(var e in t)n[e]=t[e];return n}function p(n){var t=n.parentNode;t&&t.removeChild(n)}function h(t,e,_){var r,o,i,u={};for(i in e)"key"==i?r=e[i]:"ref"==i?o=e[i]:u[i]=e[i];if(arguments.length>2&&(u.children=arguments.length>3?n.call(arguments,2):_),"function"==typeof t&&null!=t.defaultProps)for(i in t.defaultProps)void 0===u[i]&&(u[i]=t.defaultProps[i]);return d(t,u,r,o,null)}function d(n,_,r,o,i){var u={type:n,props:_,key:r,ref:o,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==i?++e:i};return null==i&&null!=t.vnode&&t.vnode(u),u}function v(){return{current:null}}function m(n){return n.children}function y(n,t){this.props=n,this.context=t}function g(n,t){if(null==t)return n.__?g(n.__,n.__.__k.indexOf(n)+1):null;for(var e;t<n.__k.length;t++)if(null!=(e=n.__k[t])&&null!=e.__e)return e.__e;return"function"==typeof n.type?g(n):null}function b(n){var t,e;if(null!=(n=n.__)&&null!=n.__c){for(n.__e=n.__c.base=null,t=0;t<n.__k.length;t++)if(null!=(e=n.__k[t])&&null!=e.__e){n.__e=n.__c.base=e.__e;break}return b(n)}}function k(n){(!n.__d&&(n.__d=!0)&&r.push(n)&&!C.__r++||o!==t.debounceRendering)&&((o=t.debounceRendering)||i)(C)}function C(){var n,t,e,_,o,i,l,c;for(r.sort(u);n=r.shift();)n.__d&&(t=r.length,_=void 0,o=void 0,l=(i=(e=n).__v).__e,(c=e.__P)&&(_=[],(o=f({},i)).__v=i.__v+1,T(c,i,o,e.__n,void 0!==c.ownerSVGElement,null!=i.__h?[l]:null,_,null==l?g(i):l,i.__h),R(_,i),i.__e!=l&&b(i)),r.length>t&&r.sort(u));C.__r=0}function x(n,t,e,_,r,o,i,u,l,s){var f,p,h,v,y,b,k,C=_&&_.__k||a,x=C.length;for(e.__k=[],f=0;f<t.length;f++)if(null!=(v=e.__k[f]=null==(v=t[f])||"boolean"==typeof v||"function"==typeof v?null:"string"==typeof v||"number"==typeof v||"bigint"==typeof v?d(null,v,null,null,v):Array.isArray(v)?d(m,{children:v},null,null,null):v.__b>0?d(v.type,v.props,v.key,v.ref?v.ref:null,v.__v):v)){if(v.__=e,v.__b=e.__b+1,null===(h=C[f])||h&&v.key==h.key&&v.type===h.type)C[f]=void 0;else for(p=0;p<x;p++){if((h=C[p])&&v.key==h.key&&v.type===h.type){C[p]=void 0;break}h=null}T(n,v,h=h||c,r,o,i,u,l,s),y=v.__e,(p=v.ref)&&h.ref!=p&&(k||(k=[]),h.ref&&k.push(h.ref,null,v),k.push(p,v.__c||y,v)),null!=y?(null==b&&(b=y),"function"==typeof v.type&&v.__k===h.__k?v.__d=l=E(v,l,n):l=U(n,v,h,C,y,l),"function"==typeof e.type&&(e.__d=l)):l&&h.__e==l&&l.parentNode!=n&&(l=g(h))}for(e.__e=b,f=x;f--;)null!=C[f]&&("function"==typeof e.type&&null!=C[f].__e&&C[f].__e==e.__d&&(e.__d=A(_).nextSibling),W(C[f],C[f]));if(k)for(f=0;f<k.length;f++)M(k[f],k[++f],k[++f])}function E(n,t,e){for(var _,r=n.__k,o=0;r&&o<r.length;o++)(_=r[o])&&(_.__=n,t="function"==typeof _.type?E(_,t,e):U(e,_,_,r,_.__e,t));return t}function H(n,t){return t=t||[],null==n||"boolean"==typeof n||(Array.isArray(n)?n.some((function(n){H(n,t)})):t.push(n)),t}function U(n,t,e,_,r,o){var i,u,l;if(void 0!==t.__d)i=t.__d,t.__d=void 0;else if(null==e||r!=o||null==r.parentNode)n:if(null==o||o.parentNode!==n)n.appendChild(r),i=null;else{for(u=o,l=0;(u=u.nextSibling)&&l<_.length;l+=1)if(u==r)break n;n.insertBefore(r,o),i=o}return void 0!==i?i:r.nextSibling}function A(n){var t,e,_;if(null==n.type||"string"==typeof n.type)return n.__e;if(n.__k)for(t=n.__k.length-1;t>=0;t--)if((e=n.__k[t])&&(_=A(e)))return _;return null}function P(n,t,e,_,r){var o;for(o in e)"children"===o||"key"===o||o in t||N(n,o,null,e[o],_);for(o in t)r&&"function"!=typeof t[o]||"children"===o||"key"===o||"value"===o||"checked"===o||e[o]===t[o]||N(n,o,t[o],e[o],_)}function S(n,t,e){"-"===t[0]?n.setProperty(t,null==e?"":e):n[t]=null==e?"":"number"!=typeof e||s.test(t)?e:e+"px"}function N(n,t,e,_,r){var o;n:if("style"===t)if("string"==typeof e)n.style.cssText=e;else{if("string"==typeof _&&(n.style.cssText=_=""),_)for(t in _)e&&t in e||S(n.style,t,"");if(e)for(t in e)_&&e[t]===_[t]||S(n.style,t,e[t])}else if("o"===t[0]&&"n"===t[1])o=t!==(t=t.replace(/Capture$/,"")),t=t.toLowerCase()in n?t.toLowerCase().slice(2):t.slice(2),n.l||(n.l={}),n.l[t+o]=e,e?_||n.addEventListener(t,o?D:w,o):n.removeEventListener(t,o?D:w,o);else if("dangerouslySetInnerHTML"!==t){if(r)t=t.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if("width"!==t&&"height"!==t&&"href"!==t&&"list"!==t&&"form"!==t&&"tabIndex"!==t&&"download"!==t&&t in n)try{n[t]=null==e?"":e;break n}catch(n){}"function"==typeof e||(null==e||!1===e&&"-"!==t[4]?n.removeAttribute(t):n.setAttribute(t,e))}}function w(n){return this.l[n.type+!1](t.event?t.event(n):n)}function D(n){return this.l[n.type+!0](t.event?t.event(n):n)}function T(n,e,_,r,o,i,u,l,c){var a,s,p,h,d,v,g,b,k,C,E,H,U,A,P,S=e.type;if(void 0!==e.constructor)return null;null!=_.__h&&(c=_.__h,l=e.__e=_.__e,e.__h=null,i=[l]),(a=t.__b)&&a(e);try{n:if("function"==typeof S){if(b=e.props,k=(a=S.contextType)&&r[a.__c],C=a?k?k.props.value:a.__:r,_.__c?g=(s=e.__c=_.__c).__=s.__E:("prototype"in S&&S.prototype.render?e.__c=s=new S(b,C):(e.__c=s=new y(b,C),s.constructor=S,s.rLine truncated
|
||||||
@@ -0,0 +1,255 @@
|
|||||||
|
'use strict';
|
||||||
|
import { h, render, useState, useEffect, useRef, html, Router } from './bundle.js';
|
||||||
|
|
||||||
|
export const Icons = {
|
||||||
|
heart: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"></path></svg>`,
|
||||||
|
downArrowBox: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M9 8.25H7.5a2.25 2.25 0 00-2.25 2.25v9a2.25 2.25 0 002.25 2.25h9a2.25 2.25 0 002.25-2.25v-9a2.25 2.25 0 00-2.25-2.25H15M9 12l3 3m0 0l3-3m-3 3V2.25" /> </svg>`,
|
||||||
|
upArrowBox: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M9 8.25H7.5a2.25 2.25 0 00-2.25 2.25v9a2.25 2.25 0 002.25 2.25h9a2.25 2.25 0 002.25-2.25v-9a2.25 2.25 0 00-2.25-2.25H15m0-3l-3-3m0 0l-3 3m3-3V15" /> </svg>`,
|
||||||
|
settings: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 011.37.49l1.296 2.247a1.125 1.125 0 01-.26 1.431l-1.003.827c-.293.24-.438.613-.431.992a6.759 6.759 0 010 .255c-.007.378.138.75.43.99l1.005.828c.424.35.534.954.26 1.43l-1.298 2.247a1.125 1.125 0 01-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.57 6.57 0 01-.22.128c-.331.183-.581.495-.644.869l-.213 1.28c-.09.543-.56.941-1.11.941h-2.594c-.55 0-1.02-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 01-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 01-1.369-.49l-1.297-2.247a1.125 1.125 0 01.26-1.431l1.004-.827c.292-.24.437-.613.43-.992a6.932 6.932 0 010-.255c.007-.378-.138-.75-.43-.99l-1.004-.828a1.125 1.125 0 01-.26-1.43l1.297-2.247a1.125 1.125 0 011.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.087.22-.128.332-.183.582-.495.644-.869l.214-1.281z" /> <path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" /> </svg>`,
|
||||||
|
scan: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M7.5 3.75H6A2.25 2.25 0 003.75 6v1.5M16.5 3.75H18A2.25 2.25 0 0120.25 6v1.5m0 9V18A2.25 2.25 0 0118 20.25h-1.5m-9 0H6A2.25 2.25 0 013.75 18v-1.5M15 12a3 3 0 11-6 0 3 3 0 016 0z" /> </svg> `,
|
||||||
|
desktop: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M9 17.25v1.007a3 3 0 01-.879 2.122L7.5 21h9l-.621-.621A3 3 0 0115 18.257V17.25m6-12V15a2.25 2.25 0 01-2.25 2.25H5.25A2.25 2.25 0 013 15V5.25m18 0A2.25 2.25 0 0018.75 3H5.25A2.25 2.25 0 003 5.25m18 0V12a2.25 2.25 0 01-2.25 2.25H5.25A2.25 2.25 0 013 12V5.25" /> </svg>`,
|
||||||
|
alert: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0M3.124 7.5A8.969 8.969 0 015.292 3m13.416 0a8.969 8.969 0 012.168 4.5" /> </svg>`,
|
||||||
|
bell: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0M3.124 7.5A8.969 8.969 0 015.292 3m13.416 0a8.969 8.969 0 012.168 4.5" /> </svg>`,
|
||||||
|
refresh: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0l3.181 3.183a8.25 8.25 0 0013.803-3.7M4.031 9.865a8.25 8.25 0 0113.803-3.7l3.181 3.182m0-4.991v4.99" /> </svg> `,
|
||||||
|
bars4: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 5.25h16.5m-16.5 4.5h16.5m-16.5 4.5h16.5m-16.5 4.5h16.5" /> </svg>`,
|
||||||
|
bars3: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" /> </svg>`,
|
||||||
|
logout: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M12.75 15l3-3m0 0l-3-3m3 3h-7.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /> </svg>`,
|
||||||
|
save: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M16.5 3.75V16.5L12 14.25 7.5 16.5V3.75m9 0H18A2.25 2.25 0 0120.25 6v12A2.25 2.25 0 0118 20.25H6A2.25 2.25 0 013.75 18V6A2.25 2.25 0 016 3.75h1.5m9 0h-9" /> </svg>`,
|
||||||
|
email: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M21.75 6.75v10.5a2.25 2.25 0 01-2.25 2.25h-15a2.25 2.25 0 01-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25m19.5 0v.243a2.25 2.25 0 01-1.07 1.916l-7.5 4.615a2.25 2.25 0 01-2.36 0L3.32 8.91a2.25 2.25 0 01-1.07-1.916V6.75" /> </svg>`,
|
||||||
|
expand: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 3.75v4.5m0-4.5h4.5m-4.5 0L9 9M3.75 20.25v-4.5m0 4.5h4.5m-4.5 0L9 15M20.25 3.75h-4.5m4.5 0v4.5m0-4.5L15 9m5.25 11.25h-4.5m4.5 0v-4.5m0 4.5L15 15" /> </svg>`,
|
||||||
|
shrink: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M9 9V4.5M9 9H4.5M9 9L3.75 3.75M9 15v4.5M9 15H4.5M9 15l-5.25 5.25M15 9h4.5M15 9V4.5M15 9l5.25-5.25M15 15h4.5M15 15v4.5m0-4.5l5.25 5.25" /> </svg>`,
|
||||||
|
ok: props => html`<svg class=${props.class} fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true"> <path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /> </svg>`,
|
||||||
|
fail: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M9.75 9.75l4.5 4.5m0-4.5l-4.5 4.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /> </svg>`,
|
||||||
|
upload: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5" /> </svg> `,
|
||||||
|
download: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5M16.5 12L12 16.5m0 0L7.5 12m4.5 4.5V3" /> </svg> `,
|
||||||
|
bolt: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 13.5l10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75z" /> </svg>`,
|
||||||
|
home: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M2.25 12l8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25" /> </svg> `,
|
||||||
|
link: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244" /> </svg> `,
|
||||||
|
shield: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75m-3-7.036A11.959 11.959 0 013.598 6 11.99 11.99 0 003 9.749c0 5.592 3.824 10.29 9 11.623 5.176-1.332 9-6.03 9-11.622 0-1.31-.21-2.571-.598-3.751h-.152c-3.196 0-6.1-1.248-8.25-3.285z" /> </svg> `,
|
||||||
|
barsdown: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M3 4.5h14.25M3 9h9.75M3 13.5h9.75m4.5-4.5v12m0 0l-3.75-3.75M17.25 21L21 17.25" /> </svg> `,
|
||||||
|
arrowdown: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m0 0l6.75-6.75M12 19.5l-6.75-6.75" /> </svg> `,
|
||||||
|
arrowup: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M12 19.5v-15m0 0l-6.75 6.75M12 4.5l6.75 6.75" /> </svg>`,
|
||||||
|
warn: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" /> </svg>`,
|
||||||
|
info: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z" /> </svg>`,
|
||||||
|
exclamationTriangle: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" /> </svg>`
|
||||||
|
};
|
||||||
|
|
||||||
|
export const tipColors = {
|
||||||
|
green: 'bg-green-100 text-green-900',
|
||||||
|
yellow: 'bg-yellow-100 text-yellow-900',
|
||||||
|
red: 'bg-red-100 text-red-900',
|
||||||
|
};
|
||||||
|
|
||||||
|
export function Button({title, onclick, disabled, cls, icon, ref, colors, hovercolor, disabledcolor}) {
|
||||||
|
const [spin, setSpin] = useState(false);
|
||||||
|
const cb = function(ev) {
|
||||||
|
const res = onclick ? onclick() : null;
|
||||||
|
if (res && typeof (res.catch) === 'function') {
|
||||||
|
setSpin(true);
|
||||||
|
res.catch(() => false).then(() => setSpin(false));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (!colors) colors = 'bg-blue-600 hover:bg-blue-500 disabled:bg-blue-400';
|
||||||
|
return html`
|
||||||
|
<button type="button" class="inline-flex justify-center items-center gap-1 rounded px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm ${colors} ${cls}"
|
||||||
|
ref=${ref} onclick=${cb} disabled=${disabled || spin} >
|
||||||
|
${title}
|
||||||
|
<${spin ? Icons.refresh : icon} class="w-4 ${spin ? 'animate-spin' : ''}" />
|
||||||
|
<//>`
|
||||||
|
};
|
||||||
|
|
||||||
|
export function Notification({ok, text, close}) {
|
||||||
|
const closebtn = useRef(null);
|
||||||
|
const from = 'translate-y-2 opacity-0 sm:translate-y-0 sm:translate-x-2';
|
||||||
|
const to = 'translate-y-0 opacity-100 sm:translate-x-0';
|
||||||
|
const [tr, setTr] = useState(from);
|
||||||
|
useEffect(function() {
|
||||||
|
setTr(to);
|
||||||
|
setTimeout(ev => closebtn && closebtn.current.click && closebtn.current.click(), 1500);
|
||||||
|
}, []);
|
||||||
|
const onclose = ev => { setTr(from); setTimeout(close, 300); };
|
||||||
|
return html`
|
||||||
|
<div aria-live="assertive" class="z-10 pointer-events-none absolute inset-0 flex items-end px-4 py-6 sm:items-start sm:p-6">
|
||||||
|
<div class="flex w-full flex-col items-center space-y-4 sm:items-end">
|
||||||
|
<div class="pointer-events-auto w-full max-w-sm overflow-hidden rounded-lg bg-white shadow-lg ring-1 ring-black ring-opacity-5 transform ease-out duration-300 transition ${tr}">
|
||||||
|
<div class="p-4">
|
||||||
|
<div class="flex items-start">
|
||||||
|
<div class="flex-shrink-0">
|
||||||
|
<${ok ? Icons.ok : Icons.failed} class="h-6 w-6 ${ok ? 'text-green-400' : 'text-red-400'}" />
|
||||||
|
<//>
|
||||||
|
<div class="ml-3 w-0 flex-1 pt-0.5">
|
||||||
|
<p class="text-sm font-medium text-gray-900">${text}</p>
|
||||||
|
<p class="hidden mt-1 text-sm text-gray-500">Anyone with a link can now view this file.</p>
|
||||||
|
<//>
|
||||||
|
<div class="ml-4 flex flex-shrink-0">
|
||||||
|
<button type="button" ref=${closebtn} onclick=${onclose} class="inline-flex rounded-md bg-white text-gray-400 hover:text-gray-500 focus:outline-none">
|
||||||
|
<span class="sr-only">Close</span>
|
||||||
|
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||||
|
<path d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z" />
|
||||||
|
<//>
|
||||||
|
<//>
|
||||||
|
<//>
|
||||||
|
<//>
|
||||||
|
<//>
|
||||||
|
<//>
|
||||||
|
<//>
|
||||||
|
<//>`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function Login({loginFn, logoIcon, title, tipText}) {
|
||||||
|
const [user, setUser] = useState('');
|
||||||
|
const [pass, setPass] = useState('');
|
||||||
|
const onsubmit = function(ev) {
|
||||||
|
const authhdr = 'Basic ' + btoa(user + ':' + pass);
|
||||||
|
const headers = {Authorization: authhdr};
|
||||||
|
return fetch('api/login', {headers}).then(loginFn).finally(r => setPass(''));
|
||||||
|
};
|
||||||
|
return html`
|
||||||
|
<div class="h-full flex items-center justify-center bg-slate-200">
|
||||||
|
<div class="border rounded bg-white w-96 p-5">
|
||||||
|
<div class="my-5 py-2 flex items-center justify-center gap-x-4">
|
||||||
|
<${logoIcon} class="h-12 stroke-cyan-600 stroke-1" />
|
||||||
|
<h1 class="font-bold text-xl">${title || 'Login'}<//>
|
||||||
|
<//>
|
||||||
|
<div class="my-3">
|
||||||
|
<label class="block text-sm mb-1 dark:text-white">Username</label>
|
||||||
|
<input type="text" autocomplete="current-user" required
|
||||||
|
class="font-normal bg-white rounded border border-gray-300 w-full
|
||||||
|
flex-1 py-0.5 px-2 text-gray-900 placeholder:text-gray-400
|
||||||
|
focus:outline-none sm:text-sm sm:leading-6 disabled:cursor-not-allowed
|
||||||
|
disabled:bg-gray-100 disabled:text-gray-500"
|
||||||
|
oninput=${ev => setUser(ev.target.value)} value=${user} />
|
||||||
|
<//>
|
||||||
|
<div class="my-3">
|
||||||
|
<label class="block text-sm mb-1 dark:text-white">Password</label>
|
||||||
|
<input type="password" autocomplete="current-password" required
|
||||||
|
class="font-normal bg-white rounded border border-gray-300 w-full flex-1 py-0.5 px-2 text-gray-900 placeholder:text-gray-400 focus:outline-none sm:text-sm sm:leading-6 disabled:cursor-not-allowed disabled:bg-gray-100 disabled:text-gray-500"
|
||||||
|
oninput=${ev => setPass(ev.target.value)}
|
||||||
|
value=${pass} onchange=${onsubmit} />
|
||||||
|
<//>
|
||||||
|
<div class="mt-7">
|
||||||
|
<${Button} title="Sign In" icon=${Icons.logout} onclick=${onsubmit} cls="flex w-full justify-center" />
|
||||||
|
<//>
|
||||||
|
<div class="mt-5 text-slate-400 text-xs">${tipText}<//>
|
||||||
|
<//>
|
||||||
|
<//>`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function Colored({icon, text, colors}) {
|
||||||
|
return html`
|
||||||
|
<span class="inline-flex items-center gap-1.5 py-0.5 px-2 rounded-full ${colors || 'bg-slate-100 text-slate-900'}">
|
||||||
|
${icon && html`<${icon} class="w-5 h-5" />`}
|
||||||
|
<span class="inline-block text-xs font-medium">${text}<//>
|
||||||
|
<//>`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function Stat({title, text, tipText, tipIcon, tipColors}) {
|
||||||
|
return html`
|
||||||
|
<div class="flex flex-col bg-white border shadow-sm rounded-xl dark:bg-slate-900 dark:border-gray-800">
|
||||||
|
<div class="p-4 md:p-5">
|
||||||
|
<div class="flex items-center gap-x-2">
|
||||||
|
<p class="text-xs uppercase tracking-wide text-gray-500"> ${title} </p>
|
||||||
|
<//>
|
||||||
|
<div class="mt-1 flex items-center gap-x-2">
|
||||||
|
<h3 class="text-xl sm:text-2xl font-medium text-gray-800 dark:text-gray-200">
|
||||||
|
${text}
|
||||||
|
<//>
|
||||||
|
<span class="flex items-center">
|
||||||
|
<${Colored} text=${tipText} icon=${tipIcon} colors=${tipColors} />
|
||||||
|
<//>
|
||||||
|
<//>
|
||||||
|
<//>
|
||||||
|
<//>`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function TextValue({value, setfn, disabled, placeholder, type, addonRight, addonLeft, attr}) {
|
||||||
|
const f = type == 'number' ? x => setfn(parseInt(x)) : setfn;
|
||||||
|
return html`
|
||||||
|
<div class="flex w-full items-center rounded border shadow-sm">
|
||||||
|
${ addonLeft && html`<span class="inline-flex font-normal truncate py-1 border-r bg-slate-100 items-center border-gray-300 px-2 text-gray-500 text-xs">${addonLeft}</>` }
|
||||||
|
<input type=${type || 'text'} disabled=${disabled}
|
||||||
|
oninput=${ev => f(ev.target.value)} ...${attr}
|
||||||
|
class="font-normal text-sm rounded w-full flex-1 py-0.5 px-2 text-gray-700 placeholder:text-gray-400 focus:outline-none disabled:cursor-not-allowed disabled:bg-gray-100 disabled:text-gray-500" placeholder=${placeholder} value=${value} />
|
||||||
|
${ addonRight && html`<span class="inline-flex font-normal truncate py-1 border-l bg-slate-100 items-center border-gray-300 px-2 text-gray-500 text-xs">${addonRight}</>` }
|
||||||
|
<//>`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function SelectValue({value, setfn, options, disabled}) {
|
||||||
|
const toInt = x => x == parseInt(x) ? parseInt(x) : x;
|
||||||
|
const onchange = ev => setfn(toInt(ev.target.value));
|
||||||
|
return html`
|
||||||
|
<select onchange=${onchange} class="w-full rounded font-normal border py-0.5 px-1 text-gray-600 focus:outline-none text-sm disabled:cursor-not-allowed" disabled=${disabled}>
|
||||||
|
${options.map(v => html`<option value=${v[0]} selected=${v[0] == value}>${v[1]}<//>`) }
|
||||||
|
<//>`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function SwitchValue({value, setfn}) {
|
||||||
|
const onclick = ev => setfn(!value);
|
||||||
|
const bg = !!value ? 'bg-blue-600' : 'bg-gray-200';
|
||||||
|
const tr = !!value ? 'translate-x-5' : 'translate-x-0';
|
||||||
|
return html`
|
||||||
|
<button type="button" onclick=${onclick} class="${bg} inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-0 ring-0" role="switch" aria-checked=${!!value}>
|
||||||
|
<span aria-hidden="true" class="${tr} pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 focus:ring-0 transition duration-200 ease-in-out"></span>
|
||||||
|
</button>`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function Setting(props) {
|
||||||
|
return html`
|
||||||
|
<div class=${props.cls || 'grid grid-cols-2 gap-2 my-1'}>
|
||||||
|
<label class="flex items-center text-sm text-gray-700 mr-2 font-medium">${props.title}<//>
|
||||||
|
<div class="flex items-center">
|
||||||
|
${props.type == 'switch' ? h(SwitchValue, props) :
|
||||||
|
props.type == 'select' ? h(SelectValue, props) :
|
||||||
|
h(TextValue, props) }
|
||||||
|
<//>
|
||||||
|
<//>`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function Pagination({ totalItems, itemsPerPage, currentPage, setPageFn }) {
|
||||||
|
const totalPages = Math.ceil(totalItems / itemsPerPage);
|
||||||
|
const maxPageRange = 2;
|
||||||
|
const lessThanSymbol = "<";
|
||||||
|
const greaterThanSymbol = ">";
|
||||||
|
const whiteSpace = " ";
|
||||||
|
const itemcls = 'relative inline-flex items-center px-3 py-1 text-sm focus:z-20 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-0 focus-visible:outline-blue-600';
|
||||||
|
|
||||||
|
const PageItem = ({ page, isActive }) => (
|
||||||
|
html`<a
|
||||||
|
onClick=${() => setPageFn(page)}
|
||||||
|
class="${itemcls} ${isActive ? 'bg-blue-600 text-white' : 'cursor-pointer text-gray-700 ring-1 ring-inset ring-gray-300 hover:bg-gray-50'}"
|
||||||
|
>
|
||||||
|
${page}
|
||||||
|
</a>`
|
||||||
|
);
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<div class="flex items-center justify-between bg-white px-3 py-2">
|
||||||
|
<div class="sm:flex sm:flex-1 sm:items-center sm:justify-between space-x-4 whitespace-nowrap select-none">
|
||||||
|
<p class="text-sm text-slate-500 font-medium">
|
||||||
|
showing <span class="font-bold text-slate-700">${(currentPage - 1) * itemsPerPage + 1}</span> - <span class="font-medium">${Math.min(currentPage * itemsPerPage, totalItems)}</span> of ${whiteSpace}
|
||||||
|
<span class="font-bold text-slate-700">${totalItems}</span> results
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<nav class="isolate inline-flex -space-x-px rounded-md" aria-label="Pagination">
|
||||||
|
<a
|
||||||
|
onClick=${() => setPageFn(Math.max(currentPage - 1, 1))}
|
||||||
|
class="relative inline-flex px-3 items-center text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 ${currentPage != 1 ? 'cursor-pointer' : ''} focus:z-20 focus:outline-offset-0">
|
||||||
|
${lessThanSymbol}
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<${PageItem} page=${1} isActive=${currentPage === 1} />
|
||||||
|
${currentPage > maxPageRange + 2 ? html`<span class="${itemcls} ring-1 ring-inset ring-gray-300 text-slate-300">...</span>` : ''}
|
||||||
|
${Array.from({length: Math.min(totalPages, maxPageRange * 2 + 1)}, (_, i) => Math.max(2, currentPage - maxPageRange) + i).map(page => page > 1 && page < totalPages && html`<${PageItem} page=${page} isActive=${currentPage === page} />`)}
|
||||||
|
${currentPage < totalPages - (maxPageRange + 1) ? html`<span class="${itemcls} ring-1 ring-inset ring-gray-300 text-slate-300">...</span>` : ''}
|
||||||
|
${totalPages > 1 ? html`<${PageItem} page=${totalPages} isActive=${currentPage === totalPages} />` : ''}
|
||||||
|
|
||||||
|
<a
|
||||||
|
onClick=${() => setPageFn(Math.min(currentPage + 1, totalPages))}
|
||||||
|
class="relative inline-flex px-3 items-center text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 ${currentPage != totalPages ? 'cursor-pointer' : ''} focus:z-20 focus:outline-offset-0">
|
||||||
|
${greaterThanSymbol}
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
};
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
!function(t,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define([],n):"object"==typeof exports?exports.History=n():t.History=n()}(this,function(){return function(t){function n(o){if(e[o])return e[o].exports;var r=e[o]={exports:{},id:o,loaded:!1};return t[o].call(r.exports,r,r.exports,n),r.loaded=!0,r.exports}var e={};return n.m=t,n.c=e,n.p="",n(0)}([function(t,n,e){"use strict";function o(t){return t&&t.__esModule?t:{default:t}}n.__esModule=!0,n.createPath=n.parsePath=n.locationsAreEqual=n.createLocation=n.createMemoryHistory=n.createHashHistory=n.createBrowserHistory=void 0;var r=e(2);Object.defineProperty(n,"createLocation",{enumerable:!0,get:function(){return r.createLocation}}),Object.defineProperty(n,"locationsAreEqual",{enumerable:!0,get:function(){return r.locationsAreEqual}});var i=e(1);Object.defineProperty(n,"parsePath",{enumerable:!0,get:function(){return i.parsePath}}),Object.defineProperty(n,"createPath",{enumerable:!0,get:function(){return i.createPath}});var a=e(7),c=o(a),u=e(8),s=o(u),f=e(9),l=o(f);n.createBrowserHistory=c.default,n.createHashHistory=s.default,n.createMemoryHistory=l.default},function(t,n){"use strict";n.__esModule=!0;n.addLeadingSlash=function(t){return"/"===t.charAt(0)?t:"/"+t},n.stripLeadingSlash=function(t){return"/"===t.charAt(0)?t.substr(1):t},n.stripPrefix=function(t,n){return 0===t.indexOf(n)?t.substr(n.length):t},n.stripTrailingSlash=function(t){return"/"===t.charAt(t.length-1)?t.slice(0,-1):t},n.parsePath=function(t){var n=t||"/",e="",o="",r=n.indexOf("#");r!==-1&&(o=n.substr(r),n=n.substr(0,r));var i=n.indexOf("?");return i!==-1&&(e=n.substr(i),n=n.substr(0,i)),n=decodeURI(n),{pathname:n,search:"?"===e?"":e,hash:"#"===o?"":o}},n.createPath=function(t){var n=t.pathname,e=t.search,o=t.hash,r=encodeURI(n||"/");return e&&"?"!==e&&(r+="?"===e.charAt(0)?e:"?"+e),o&&"#"!==o&&(r+="#"===o.charAt(0)?o:"#"+o),r}},function(t,n,e){"use strict";function o(t){return t&&t.__esModule?t:{default:t}}n.__esModule=!0,n.locationsAreEqual=n.createLocation=void 0;var r=Object.assign||function(t){for(var n=1;n<arguments.length;n++){var e=arguments[n];for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=e[o])}return t},i=e(10),a=o(i),c=e(11),u=o(c),s=e(1);n.createLocation=function(t,n,e,o){var i=void 0;return"string"==typeof t?(i=(0,s.parsePath)(t),i.state=n):(i=r({},t),void 0===i.pathname&&(i.pathname=""),i.search?"?"!==i.search.charAt(0)&&(i.search="?"+i.search):i.search="",i.hash?"#"!==i.hash.charAt(0)&&(i.hash="#"+i.hash):i.hash="",void 0!==n&&void 0===i.state&&(i.state=n)),i.key=e,o&&(i.pathname?"/"!==i.pathname.charAt(0)&&(i.pathname=(0,a.default)(i.pathname,o.pathname)):i.pathname=o.pathname),i},n.locationsAreEqual=function(t,n){return t.pathname===n.pathname&&t.search===n.search&&t.hash===n.hash&&t.key===n.key&&(0,u.default)(t.state,n.state)}},function(t,n,e){"use strict";var o=function(){};t.exports=o},function(t,n,e){"use strict";function o(t){return t&&t.__esModule?t:{default:t}}n.__esModule=!0;var r=e(3),i=(o(r),function(){var t=null,n=function(n){return t=n,function(){t===n&&(t=null)}},e=function(n,e,o,r){if(null!=t){var i="function"==typeof t?t(n,e):t;"string"==typeof i?"function"==typeof o?o(i,r):r(!0):r(i!==!1)}else r(!0)},o=[],r=function(t){var n=!0,e=function(){n&&t.apply(void 0,arguments)};return o.push(e),function(){n=!1,o=o.filter(function(t){return t!==e})}},i=function(){for(var t=arguments.length,n=Array(t),e=0;e<t;e++)n[e]=arguments[e];o.forEach(function(t){return t.apply(void 0,n)})};return{setPrompt:n,confirmTransitionTo:e,appendListener:r,notifyListeners:i}});n.default=i},function(t,n){"use strict";n.__esModule=!0;n.canUseDOM=!("undefined"==typeof window||!window.document||!window.document.createElement),n.addEventListener=function(t,n,e){return t.addEventListener?t.addEventListener(n,e,!1):t.attachEvent("on"+n,e)},n.removeEventListener=function(t,n,e){return t.removeEventListener?t.removeEventListener(n,e,!1):t.detachEvent("on"+n,e)},n.getConfirmation=function(t,n){return n(window.confirm(t))},n.supportsHistory=function(){var t=window.navigator.userAgent;return(t.indexOf("Android 2.")===-1&&t.indexOf("Android 4.0")===-1||t.indexOf("Mobile Safari")===-1||t.indexOf("Chrome")!==-1||t.indexOf("Windows Phone")!==-1)&&(window.history&&"pushState"in window.history)},n.supportsPopStateOnHashChange=function(){return window.navigator.userAgent.indexOf("Trident")===-1},n.supportsGoWithoutReloadUsingHash=function(){return window.navigator.userAgent.indexOf("Firefox")===-1},n.isExtraneousPopstateEvent=function(t){return void 0===t.state&&navigator.userAgent.indexOf("CriOS")===-1}},function(t,n,e){"use strict";var o=function(t,n,e,o,r,i,a,c){if(!t){var u;if(void 0===n)u=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var s=[e,o,r,i,a,c],f=0;u=new Error(n.replace(/%s/g,function(){return s[f++]})),u.name="InLine truncated
|
||||||
@@ -1,12 +1,15 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en" class="h-full bg-white">
|
||||||
<head>
|
<head>
|
||||||
<title>Device Dashboard</title>
|
<title></title>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<link rel="stylesheet" href="style.css" />
|
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke-width='1.5' stroke='currentColor'> <path stroke-linecap='round' stroke-linejoin='round' d='M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0' /> </svg>" />
|
||||||
|
<link href="main.css" rel="stylesheet" />
|
||||||
|
<link href="https://rsms.me/inter/inter.css" rel="stylesheet" />
|
||||||
</head>
|
</head>
|
||||||
<body></body>
|
<body class="h-full"></body>
|
||||||
|
<script src="history.min.js"></script>
|
||||||
<script type="module" src="main.js"></script>
|
<script type="module" src="main.js"></script>
|
||||||
</html>
|
</html>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
/*! tailwindcss v3.3.2 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Inter var,Helvetica,sans-serif;font-feature-settings:"cv11","ss01";font-variation-settings:"opsz" 32}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:0}.bottom-0{bottom:0}.left-0{left:0}.right-auto{right:auto}.top-0{top:0}.isolate{isolation:isolate}.z-10{z-index:10}.z-\[48\]{z-index:48}.z-\[60\]{z-index:60}.col-span-2{grid-column:span 2/span 2}.m-4{margin:1rem}.mx-auto{margin-left:auto;margin-right:auto}.my-0{margin-top:0;margin-bottom:0}.my-1{margin-top:.25rem;margin-bottom:.25rem}.my-2{margin-top:.5rem;margin-bottom:.5rem}.my-3{margin-top:.75rem;margin-bottom:.75rem}.my-4{margin-top:1rem;margin-bottom:1rem}.my-5{margin-top:1.25rem;margin-bottom:1.25rem}.mb-1{margin-bottom:.25rem}.ml-3{margin-left:.75rem}.ml-4{margin-left:1rem}.mr-2{margin-right:.5rem}.mr-4{margin-right:1rem}.mt-1{margin-top:.25rem}.mt-3{margin-top:.75rem}.mt-5{margin-top:1.25rem}.mt-7{margin-top:1.75rem}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-10{height:2.5rem}.h-12{height:3rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-full{height:100%}.min-h-screen{min-height:100vh}.w-0{width:0}.w-11{width:2.75rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-72{width:18rem}.w-96{width:24rem}.w-full{width:100%}.min-w-full{min-width:100%}.max-w-sm{max-width:24rem}.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.grow-0{flex-grow:0}.basis-\[30px\]{flex-basis:30px}.border-separate{border-collapse:initial}.border-spacing-0{--tw-border-spaciLine truncated
|
||||||
@@ -1,385 +1,265 @@
|
|||||||
|
// NOTE: API calls must start with 'api/' in order to serve the app at any URI
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
import {Component, h, html, render, useEffect, useState, useRef} from './preact.min.js';
|
import { h, render, useState, useEffect, useRef, html, Router } from './bundle.js';
|
||||||
|
import { Icons, Login, Setting, Button, Stat, tipColors, Colored, Notification, Pagination } from './components.js';
|
||||||
|
|
||||||
var devaddr = "address:port";
|
const Logo = props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12.87 12.85"><defs><style>.ll-cls-1{fill:none;stroke:#000;stroke-miterlimit:10;stroke-width:0.5px;}</style></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="ll-cls-1" d="M12.62,1.82V8.91A1.58,1.58,0,0,1,11,10.48H4a1.44,1.44,0,0,1-1-.37A.69.69,0,0,1,2.84,10l-.1-.12a.81.81,0,0,1-.15-.48V5.57a.87.87,0,0,1,.86-.86H4.73V7.28a.86.86,0,0,0,.86.85H9.42a.85.85,0,0,0,.85-.85V3.45A.86.86,0,0,0,10.13,3,.76.76,0,0,0,10,2.84a.29.29,0,0,0-.12-.1,1.49,1.49,0,0,0-1-.37H2.39V1.82A1.57,1.57,0,0,1,4,.25H11A1.57,1.57,0,0,1,12.62,1.82Z"/><path class="ll-cls-1" d="M10.48,10.48V11A1.58,1.58,0,0,1,8.9,12.6H1.82A1.57,1.57,0,0,1,.25,11V3.94A1.57,1.57,0,0,1,1.82,2.37H8.9a1.49,1.49,0,0,1,1,.37l.12.1a.76.76,0,0,1,.11.14.86.86,0,0,1,.14.47V7.28a.85.85,0,0,1-.85.85H8.13V5.57a.86.86,0,0,0-.85-.86H3.45a.87.87,0,0,0-.86.86V9.4a.81.81,0,0,0,.15.48l.1.12a.69.69,0,0,0,.13.11,1.44,1.44,0,0,0,1,.37Z"/></g></g></svg>`;
|
||||||
|
|
||||||
const MaxMetricsDataPoints = 50;
|
function Header({logout, user, setShowSidebar, showSidebar}) {
|
||||||
|
|
||||||
// This simple publish/subscribe is used to pass notifications that were
|
|
||||||
// received from the server, to all child components of the app.
|
|
||||||
var PubSub = (function() {
|
|
||||||
var handlers = {}, id = 0;
|
|
||||||
return {
|
|
||||||
subscribe: function(fn) {
|
|
||||||
handlers[id++] = fn;
|
|
||||||
},
|
|
||||||
unsubscribe: function(id) {
|
|
||||||
delete handlers[id];
|
|
||||||
},
|
|
||||||
publish: function(data) {
|
|
||||||
for (var k in handlers) handlers[k](data);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
|
|
||||||
const Nav = props => html`
|
|
||||||
<div style="background: #333; padding: 0.5em; color: #fff;">
|
|
||||||
<div class="container d-flex">
|
|
||||||
<div style="flex: 1 1 auto; display: flex; align-items: center;">
|
|
||||||
<b>Your Product</b>
|
|
||||||
</div>
|
|
||||||
<div style="display: flex; align-items: center; flex: 0 0 auto; ">
|
|
||||||
<span>Logged in as:</span>
|
|
||||||
<span style="padding: 0 0.5em;"><img src="user.png" height="22" /></span>
|
|
||||||
<span>${props.user}</span>
|
|
||||||
<a class="btn" onclick=${props.logout}
|
|
||||||
style="margin-left: 1em; font-size: 0.8em; background: #8aa;">logout</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>`;
|
|
||||||
|
|
||||||
|
|
||||||
const Hero = props => html`
|
|
||||||
<div class="section">
|
|
||||||
<div style="margin-top: 1em; background: #eee; padding: 1em; border-radius: 0.5em; color: #777; ">
|
|
||||||
<h1 style="margin: 0.2em 0;">Interactive Device Dashboard</h1>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
This device dashboard is developed using the modern and compact Preact framework,
|
|
||||||
in order to fit on very small devices. This is
|
|
||||||
a <a href="https://mongoose.ws/tutorials/http-server/">hybrid server</a> which
|
|
||||||
provides both static and dynamic content. Static files, like CSS/JS/HTML
|
|
||||||
or images, are compiled into the server binary.
|
|
||||||
|
|
||||||
This UI uses the REST API implemented by the device, which you can examine
|
|
||||||
using <code>curl</code> command-line utility:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div><code>curl -u admin:pass0 ${devaddr}/api/config/get</code> </div>
|
|
||||||
<div><code>curl -u admin:pass0 ${devaddr}/api/config/set -d 'pub=mg/topic'</code> </div>
|
|
||||||
<div><code>curl -u admin:pass0 ${devaddr}/api/message/send -d 'message=hello'</code> </div>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The device can send notifications to this dashboard at anytime. Notifications
|
|
||||||
are sent over WebSocket at URI <code>/api/watch</code> as JSON strings: <code>{"name": "..", "data": ...}</code>
|
|
||||||
<div>Try <code>wscat --auth user1:pass1 --connect ws://${devaddr}/api/watch</code></div>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>`;
|
|
||||||
|
|
||||||
const Login = function(props) {
|
|
||||||
const [user, setUser] = useState('');
|
|
||||||
const [pass, setPass] = useState('');
|
|
||||||
const login = ev =>
|
|
||||||
fetch(
|
|
||||||
'/api/login',
|
|
||||||
{headers: {Authorization: 'Basic ' + btoa(user + ':' + pass)}})
|
|
||||||
.then(r => r.json())
|
|
||||||
.then(r => r && props.login(r))
|
|
||||||
.catch(err => err);
|
|
||||||
return html`
|
return html`
|
||||||
<div class="rounded border" style="max-width: 480px; margin: 0 auto; margin-top: 5em; background: #eee; ">
|
<div class="bg-white sticky top-0 z-[48] xw-full border-b py-2 ${showSidebar && 'pl-72'} transition-all duration-300 transform">
|
||||||
<div style="padding: 2em; ">
|
<div class="px-2 w-full py-0 my-0 flex items-center">
|
||||||
<h1 style="color: #666;">Device Dashboard Login </h1>
|
<button type="button" onclick=${ev => setShowSidebar(v => !v)} class="text-slate-400">
|
||||||
<div style="margin: 0.5em 0;">
|
<${Icons.bars3} class="h-6" />
|
||||||
<input type='text' placeholder='Name' style="width: 100%;"
|
<//>
|
||||||
oninput=${ev => setUser(ev.target.value)} value=${user} />
|
<div class="flex flex-1 gap-x-4 self-stretch lg:gap-x-6">
|
||||||
</div>
|
<div class="relative flex flex-1"><//>
|
||||||
<div style="margin: 0.5em 0;">
|
<div class="flex items-center gap-x-4 lg:gap-x-6">
|
||||||
<input type="password" placeholder="Password" style="width: 100%;"
|
<span class="text-sm text-slate-400">logged in as: ${user}<//>
|
||||||
oninput=${ev => setPass(ev.target.value)} value=${pass}
|
<div class="hidden lg:block lg:h-4 lg:w-px lg:bg-gray-200" aria-hidden="true"><//>
|
||||||
onchange=${login} />
|
<${Button} title="Logout" icon=${Icons.logout} onclick=${logout} />
|
||||||
</div>
|
<//>
|
||||||
<div style="margin: 1em 0;">
|
<//>
|
||||||
<button class="btn" style="width: 100%; background: #8aa;"
|
<//>
|
||||||
disabled=${!user || !pass} onclick=${login}> Login </button>
|
<//>`;
|
||||||
</div>
|
|
||||||
<div style="color: #777; margin-top: 2em;">
|
|
||||||
Valid logins: admin:pass0, user1:pass1, user2:pass2
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>`;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function Sidebar({url, show}) {
|
||||||
const Configuration = function(props) {
|
const NavLink = ({title, icon, href, url}) => html`
|
||||||
const [url, setUrl] = useState(props.config.url || '');
|
|
||||||
const [pub, setPub] = useState(props.config.pub || '');
|
|
||||||
const [sub, setSub] = useState(props.config.sub || '');
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setUrl(props.config.url);
|
|
||||||
setPub(props.config.pub);
|
|
||||||
setSub(props.config.sub);
|
|
||||||
}, [props.config]);
|
|
||||||
|
|
||||||
const update = (name, val) => fetch('/api/config/set', {
|
|
||||||
method: 'post',
|
|
||||||
body: `${name}=${encodeURIComponent(val)}`
|
|
||||||
}).catch(err => err);
|
|
||||||
const updateurl = ev => update('url', url);
|
|
||||||
const updatepub = ev => update('pub', pub);
|
|
||||||
const updatesub = ev => update('sub', sub);
|
|
||||||
|
|
||||||
// console.log(props, [url, pub, sub]);
|
|
||||||
return html`
|
|
||||||
<div class="section">
|
|
||||||
<h3 style="background: #c03434; color: #fff; padding: 0.4em;">
|
|
||||||
Device Configuration</h3>
|
|
||||||
<div style="margin: 0.5em 0; display: flex;">
|
|
||||||
<span class="addon nowrap">MQTT server:</span>
|
|
||||||
<input type="text" style="flex: 1 100%;"
|
|
||||||
value=${url} onchange=${updateurl}
|
|
||||||
oninput=${ev => setUrl(ev.target.value)} />
|
|
||||||
<button class="btn" disabled=${!url} onclick=${updateurl}
|
|
||||||
style="margin-left: 1em; background: #8aa;">Update</button>
|
|
||||||
</div>
|
|
||||||
<div style="margin: 0.5em 0; display: flex; ">
|
|
||||||
<span class="addon nowrap">Subscribe topic:</span>
|
|
||||||
<input type="text" style="flex: 1 100%;"
|
|
||||||
value=${sub} onchange=${updatesub}
|
|
||||||
oninput=${ev => setSub(ev.target.value)} />
|
|
||||||
<button class="btn" disabled=${!sub} onclick=${updatesub}
|
|
||||||
style="margin-left: 1em; background: #8aa;">Update</button>
|
|
||||||
</div>
|
|
||||||
<div style="margin: 0.5em 0; display: flex;">
|
|
||||||
<span class="addon nowrap">Publish topic:</span>
|
|
||||||
<input type="text" style="flex: 1 100%;"
|
|
||||||
value=${pub} onchange=${updatepub}
|
|
||||||
oninput=${ev => setPub(ev.target.value)} />
|
|
||||||
<button class="btn" disabled=${!pub} onclick=${updatepub}
|
|
||||||
style="margin-left: 1em; background: #8aa;">Update</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
You can use <a href="http://www.hivemq.com/demos/websocket-client/">
|
<a href="#${href}" class="${href == url ? 'bg-slate-50 text-blue-600 group' : 'text-gray-700 hover:text-blue-600 hover:bg-gray-50 group'} flex gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold">
|
||||||
HiveMQ Websocket web client</a> to send messages to this console.
|
<${icon} class="w-6 h-6"/>
|
||||||
</div>
|
${title}
|
||||||
<div class="msg">
|
<///>
|
||||||
The device keeps a persistent connection to the configured MQTT server.
|
<//>`;
|
||||||
Changes to this configuration are propagated to all dashboards: try
|
return html`
|
||||||
changing them in this dashboard and observe changes in other opened
|
<div class="bg-violet-100 hs-overlay hs-overlay-open:translate-x-0
|
||||||
dashboards.
|
-translate-x-full transition-all duration-300 transform
|
||||||
</div><div class="msg">
|
fixed top-0 left-0 bottom-0 z-[60] w-72 bg-white border-r
|
||||||
Note: administrators can see this section and can change device
|
border-gray-200 overflow-y-auto scrollbar-y
|
||||||
configuration, whilst users cannot.
|
${show && 'translate-x-0'} right-auto bottom-0">
|
||||||
</div>
|
<div class="flex flex-col m-4 gap-y-6">
|
||||||
</div>`;
|
<div class="flex h-10 shrink-0 items-center gap-x-4 font-bold text-xl text-slate-500">
|
||||||
|
<${Logo} class="h-full"/> Your Brand
|
||||||
|
<//>
|
||||||
|
<div class="flex flex-1 flex-col">
|
||||||
|
<${NavLink} title="Dashboard" icon=${Icons.home} href="/" url=${url} />
|
||||||
|
<${NavLink} title="Settings" icon=${Icons.settings} href="/settings" url=${url} />
|
||||||
|
<${NavLink} title="Events" icon=${Icons.alert} href="/events" url=${url} />
|
||||||
|
<//>
|
||||||
|
<//>
|
||||||
|
<//>`;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function Events({}) {
|
||||||
|
const [events, setEvents] = useState([]);
|
||||||
|
const [page, setPage] = useState(1);
|
||||||
|
|
||||||
const Message = m => html`<div style="margin: 0.5em 0;">
|
const refresh = () =>
|
||||||
<span class="qos">qos: ${m.message.qos} </span>
|
fetch('api/events/get', {
|
||||||
<span class="topic">topic: ${m.message.topic} </span>
|
method: 'POST', body: JSON.stringify({page: page}),
|
||||||
<span class="data">data: ${m.message.data}</span>
|
}).then(r => r.json())
|
||||||
</div>`;
|
.then(r => setEvents(r));
|
||||||
|
|
||||||
const Messages = function(props) {
|
useEffect(refresh, [page]);
|
||||||
const [messages, setMessages] = useState([]);
|
|
||||||
const [txt, setTxt] = useState('');
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const id = PubSub.subscribe(function(msg) {
|
setPage(JSON.parse(localStorage.getItem('page')));
|
||||||
if (msg.name == 'message') setMessages(x => x.concat([msg.data]));
|
}, []);
|
||||||
});
|
|
||||||
return PubSub.unsubscribe(id);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const sendmessage = ev => fetch('/api/message/send', {
|
|
||||||
method: 'post',
|
|
||||||
body: `message=${encodeURIComponent(txt)}`
|
|
||||||
}).then(r => setTxt(''));
|
|
||||||
const routing = "connected" in props.config;
|
|
||||||
const connstatus = !routing ? 'This device has no MQTT functionality' : props.config.connected ? 'connected' : 'disconnected';
|
|
||||||
return html`
|
|
||||||
<div class="section">
|
|
||||||
<h3 style="background: #30c040; color: #fff; padding: 0.4em;">MQTT messages</h3>
|
|
||||||
<div>
|
|
||||||
MQTT server status: <b>${connstatus}</b>
|
|
||||||
</div>
|
|
||||||
<div style="height: 10em; overflow: auto; padding: 0.5em; " class="border">
|
|
||||||
${messages.map(message => h(Message, {message}))}
|
|
||||||
</div>
|
|
||||||
<div style="margin: 0.5em 0; display: flex">
|
|
||||||
<span class="addon nowrap">Publish message:</span>
|
|
||||||
<input placeholder="type and press enter..." style="flex: 1 100%;"
|
|
||||||
value=${txt} onchange=${sendmessage} disabled=${!routing}
|
|
||||||
oninput=${ev => setTxt(ev.target.value)} />
|
|
||||||
</div>
|
|
||||||
<div class="msg">
|
|
||||||
The message gets passed to the device via REST. Then the device sends it to
|
|
||||||
the MQTT server over MQTT. All MQTT messages on a subscribed topic
|
|
||||||
received by the device, are propagated to this dashboard via /api/watch.
|
|
||||||
</div>
|
|
||||||
</div>`;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Expected arguments:
|
|
||||||
// data: timeseries, e.g. [ [1654361352, 19], [1654361353, 18], ... ]
|
|
||||||
// width, height, yticks, xticks, ymin, ymax, xmin, xmax
|
|
||||||
const SVG = function(props) {
|
|
||||||
// w
|
|
||||||
// +---------------------+
|
|
||||||
// | h1 |
|
|
||||||
// | +-----------+ |
|
|
||||||
// | | | | h
|
|
||||||
// | w1 | | w2 |
|
|
||||||
// | +-----------+ |
|
|
||||||
// | h2 |
|
|
||||||
// +---------------------+
|
|
||||||
//
|
|
||||||
let w = props.width, h = props.height, w1 = 30, w2 = 0, h1 = 8, h2 = 18;
|
|
||||||
let yticks = props.yticks || 4, xticks = props.xticks || 5;
|
|
||||||
let data = props.data || [];
|
|
||||||
let ymin = props.ymin || 0;
|
|
||||||
let ymax = props.ymax || Math.max.apply(null, data.map(p => p[1]));
|
|
||||||
let xmin = props.xmin || Math.min.apply(null, data.map(p => p[0]));
|
|
||||||
let xmax = props.xmax || Math.max.apply(null, data.map(p => p[0]));
|
|
||||||
|
|
||||||
// Y-axis tick lines and labels
|
|
||||||
let yta = (new Array(yticks + 1)).fill(0).map((_, i) => i); // indices
|
|
||||||
let yti = i => h - h2 - (h - h1 - h2) * i / yticks; // index's Y
|
|
||||||
let ytv = i => (ymax - ymin) * i / yticks;
|
|
||||||
let ytl = y => html`<line x1=${w1} y1=${y} x2=${w} y2=${y} class="tick"/>`;
|
|
||||||
let ytt = (y, v) => html`<text x=0 y=${y + 5} class="label">${v}</text>`;
|
|
||||||
|
|
||||||
// X-axis tick lines and labels
|
|
||||||
let datefmt = unix => (new Date(unix * 1000)).toISOString().substr(14, 5);
|
|
||||||
let xta = (new Array(xticks + 1)).fill(0).map((_, i) => i); // indices
|
|
||||||
let xti = i => w1 + (w - w1 - w2) * i / xticks; // index's X
|
|
||||||
let xtv = i => datefmt(xmin + (xmax - xmin) * i / xticks);
|
|
||||||
let xtl = x => html`<path d="M ${x},${h1} L ${x},${h - h2}" class="tick"/>`;
|
|
||||||
let xtt = (x, v) =>
|
|
||||||
html`<text x=${x - 15} y=${h - 2} class="label">${v}</text>`;
|
|
||||||
|
|
||||||
// Transform data points array into coordinate
|
|
||||||
let dx = v => w1 + (v - xmin) / ((xmax - xmin) || 1) * (w - w1 - w2);
|
|
||||||
let dy = v => h - h2 - (v - ymin) / ((ymax - ymin) || 1) * (h - h1 - h2);
|
|
||||||
let dd = data.map(p => [Math.round(dx(p[0])), Math.round(dy(p[1]))]);
|
|
||||||
let ddl = dd.length;
|
|
||||||
// And plot the data as <path> element
|
|
||||||
let begin0 = ddl ? `M ${dd[0][0]},${dd[0][1]}` : `M 0,0`;
|
|
||||||
let begin = `M ${w1},${h - h2}`; // Initial point
|
|
||||||
let end = ddl ? `L ${dd[ddl - 1][0]},${h - h2}` : `L ${w1},${h - h2}`;
|
|
||||||
let series = ddl ? dd.map(p => `L ${p[0]} ${p[1]}`) : [];
|
|
||||||
|
|
||||||
return html`
|
|
||||||
<svg viewBox="0 0 ${w} ${h}">
|
|
||||||
<style>
|
|
||||||
.axis { stroke: #aaa; fill: none; }
|
|
||||||
.label { stroke: #aaa; font-size: 13px; }
|
|
||||||
.tick { stroke: #ccc; fill: none; stroke-dasharray: 5; }
|
|
||||||
.seriesbg { stroke: none; fill: rgba(200,225,255, 0.25)}
|
|
||||||
.series { stroke: #25a; fill: none; }
|
|
||||||
</style>
|
|
||||||
${yta.map(i => ytl(yti(i)))}
|
|
||||||
${yta.map(i => ytt(yti(i), ytv(i)))}
|
|
||||||
${xta.map(i => xtl(xti(i)))}
|
|
||||||
${data.length ? xta.map(i => xtt(xti(i), xtv(i))) : ''}
|
|
||||||
<path d="${begin} ${series.join(' ')} ${end}" class="seriesbg" />
|
|
||||||
<path d="${begin0} ${series.join(' ')}" class="series" />
|
|
||||||
</svg>`;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const Chart = function(props) {
|
|
||||||
const [data, setData] = useState([]);
|
|
||||||
useEffect(() => {
|
|
||||||
const id = PubSub.subscribe(function(msg) {
|
|
||||||
if (msg.name != 'metrics') return;
|
|
||||||
setData(x => x.concat([msg.data]).splice(-MaxMetricsDataPoints));
|
|
||||||
});
|
|
||||||
return PubSub.unsubscribe(id);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
let xmax = 0, missing = MaxMetricsDataPoints - data.length;
|
|
||||||
if (missing > 0) xmax = Math.round(Date.now() / 1000) + missing;
|
|
||||||
return html`
|
|
||||||
<div class="section">
|
|
||||||
<h3 style="background: #ec3; color: #fff; padding: 0.4em;">Data Chart</h3>
|
|
||||||
<div style="overflow: auto; padding: 0.5em;" class="">
|
|
||||||
<${SVG} height=240 width=600 ymin=0 ymax=20 xmax=${xmax} data=${data} />
|
|
||||||
</div>
|
|
||||||
<div class="msg">
|
|
||||||
This chart plots live sensor data, sent by the device via /api/watch.
|
|
||||||
</div>
|
|
||||||
</div>`;
|
|
||||||
};
|
|
||||||
|
|
||||||
const App = function(props) {
|
|
||||||
const [user, setUser] = useState('');
|
|
||||||
const [config, setConfig] = useState({});
|
|
||||||
|
|
||||||
const getconfig = () =>
|
|
||||||
fetch('/api/config/get', {headers: {Authorization: ''}})
|
|
||||||
.then(r => r.json())
|
|
||||||
.then(r => setConfig(r))
|
|
||||||
.catch(err => console.log(err));
|
|
||||||
|
|
||||||
// Watch for notifications. As soon as a notification arrives, pass it on
|
|
||||||
// to all subscribed components
|
|
||||||
const watch = function() {
|
|
||||||
var l = window.location, proto = l.protocol.replace('http', 'ws');
|
|
||||||
var tid, wsURI = proto + '//' + l.host + '/api/watch'
|
|
||||||
var reconnect = function() {
|
|
||||||
var ws = new WebSocket(wsURI);
|
|
||||||
// ws.onopen = () => console.log('ws connected');
|
|
||||||
ws.onmessage = function(ev) {
|
|
||||||
try {
|
|
||||||
var msg = JSON.parse(ev.data);
|
|
||||||
PubSub.publish(msg);
|
|
||||||
// if (msg.name != 'metrics') console.log('ws->', msg);
|
|
||||||
} catch (e) {
|
|
||||||
console.log('Invalid ws frame:', ev.data); // eslint-disable-line
|
|
||||||
}
|
|
||||||
};
|
|
||||||
ws.onclose = function() {
|
|
||||||
clearTimeout(tid);
|
|
||||||
tid = setTimeout(reconnect, 1000);
|
|
||||||
console.log('ws disconnected');
|
|
||||||
};
|
|
||||||
};
|
|
||||||
reconnect();
|
|
||||||
};
|
|
||||||
|
|
||||||
const login = function(u) {
|
|
||||||
document.cookie = `access_token=${u.token}; Secure, HttpOnly; SameSite=Lax; path=/; max-age=3600`;
|
|
||||||
setUser(u.user);
|
|
||||||
if (location.search.substring(1) == 'nows') {
|
|
||||||
// If query string is ?nows, then do not connect to websocket. For debug.
|
|
||||||
} else {
|
|
||||||
watch(); // Connect to websocket, receive constant graph updates
|
|
||||||
}
|
|
||||||
return getconfig();
|
|
||||||
};
|
|
||||||
|
|
||||||
const logout = ev => {
|
|
||||||
document.cookie = `access_token=; Secure, HttpOnly; SameSite=Lax; path=/; max-age=0`;
|
|
||||||
setUser('');
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Called once at init time
|
localStorage.setItem('page', page.toString());
|
||||||
PubSub.subscribe(msg => msg.name == 'config' && getconfig());
|
}, [page]);
|
||||||
fetch('/api/login', {headers: {Authorization: ''}})
|
|
||||||
.then(r => r.json())
|
|
||||||
.then(r => login(r))
|
|
||||||
.catch(err => setUser(''));
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
if (!user) return html`<${Login} login=${login} />`;
|
const Th = props => html`<th scope="col" class="sticky top-0 z-10 border-b border-slate-300 bg-white bg-opacity-75 py-1.5 px-4 text-left text-sm font-semibold text-slate-900 backdrop-blur backdrop-filter">${props.title}</th>`;
|
||||||
|
const Td = props => html`<td class="whitespace-nowrap border-b border-slate-200 py-2 px-4 pr-3 text-sm text-slate-900">${props.text}</td>`;
|
||||||
|
const Prio = ({prio}) => {
|
||||||
|
const text = ['high', 'medium', 'low'][prio];
|
||||||
|
const colors = [tipColors.red, tipColors.yellow, tipColors.green][prio];
|
||||||
|
return html`<${Colored} colors=${colors} text=${text} />`;
|
||||||
|
};
|
||||||
|
|
||||||
return html`
|
const Event = ({e}) => html`
|
||||||
<${Nav} user=${user} logout=${logout} />
|
<tr>
|
||||||
<div class="container">
|
<${Td} text=${['power', 'hardware', 'tier3', 'tier4'][e.type]} />
|
||||||
<div class="row">
|
<${Td} text=${html`<${Prio} prio=${e.prio}/>`} />
|
||||||
<div class="col col-6"><${Hero} /></div>
|
<${Td} text=${e.time ? (new Date(e.time * 1000)).toLocaleString() : '1970-01-01'} />
|
||||||
<div class="col col-6"><${Chart} /></div>
|
<${Td} text=${e.text} />
|
||||||
<div class="col col-6">
|
<//>`;
|
||||||
${user == 'admin' && h(Configuration, {config})}
|
|
||||||
|
return html`
|
||||||
|
<div class="m-4 divide-y divide-gray-200 overflow-auto rounded bg-white">
|
||||||
|
<div class="font-semibold flex items-center text-gray-600 px-3 justify-between whitespace-nowrap">
|
||||||
|
<div class="font-semibold flex items-center text-gray-600">
|
||||||
|
<div class="mr-4">EVENT LOG</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-6"><${Messages} config=${config} /></div>
|
<${Pagination} currentPage=${page} setPageFn=${setPage} totalItems=400 itemsPerPage=20 />
|
||||||
</div>
|
<//>
|
||||||
</div>`;
|
<div class="inline-block min-w-full align-middle" style="max-height: 82vh; overflow: auto;">
|
||||||
|
<table class="min-w-full border-separate border-spacing-0">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<${Th} title="Type" />
|
||||||
|
<${Th} title="Prio" />
|
||||||
|
<${Th} title="Time" />
|
||||||
|
<${Th} title="Description" />
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
${(events.arr ? events.arr : []).map(e => h(Event, {e}))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<//>
|
||||||
|
<//>`;
|
||||||
|
};
|
||||||
|
|
||||||
|
function Chart({data}) {
|
||||||
|
const n = data.length /* entries */, w = 20 /* entry width */, ls = 15/* left space */;
|
||||||
|
const h = 100 /* graph height */, yticks = 5 /* Y axis ticks */, bs = 10 /* bottom space */;
|
||||||
|
const ymax = 25;
|
||||||
|
const yt = i => (h - bs) / yticks * (i + 1);
|
||||||
|
const bh = p => (h - bs) * p / 100; // Bar height
|
||||||
|
const by = p => (h - bs) - bh(p);
|
||||||
|
const range = (start, size, step) => Array.from({length: size}, (_, i) => i * (step || 1) + start);
|
||||||
|
// console.log(ds);
|
||||||
|
return html`
|
||||||
|
<div class="my-4 divide-y divide-gray-200 overflow-auto rounded bg-white">
|
||||||
|
<div class="font-light uppercase flex items-center text-gray-600 px-4 py-2">
|
||||||
|
Temperature, last 24h
|
||||||
|
<//>
|
||||||
|
<div class="relative">
|
||||||
|
<svg class="bg-yellow-x50 w-full p-4" viewBox="0 0 ${n*w+ls} ${h}">
|
||||||
|
${range(0, yticks).map(i => html`
|
||||||
|
<line x1=0 y1=${yt(i)} x2=${ls+n*w} y2=${yt(i)} stroke-width=0.3 class="stroke-slate-300" stroke-dasharray="1,1" />
|
||||||
|
<text x=0 y=${yt(i)-2} class="text-[6px] fill-slate-400">${ymax-ymax/yticks*(i+1)}<//>
|
||||||
|
`)}
|
||||||
|
${range(0, n).map(x => html`
|
||||||
|
<rect x=${ls+x*w} y=${by(data[x]*100/ymax)} width=12 height=${bh(data[x]*100/ymax)} rx=2 class="fill-cyan-500" />
|
||||||
|
<text x=${ls+x*w} y=100 class="text-[6px] fill-slate-400">${x*2}:00<//>
|
||||||
|
`)}
|
||||||
|
<//>
|
||||||
|
<//>
|
||||||
|
<//>`;
|
||||||
|
};
|
||||||
|
|
||||||
|
function DeveloperNote({text}) {
|
||||||
|
return html`
|
||||||
|
<div class="flex p-4 gap-2">
|
||||||
|
<${Icons.info} class="self-start basis-[30px] grow-0 shrink-0 text-green-600" />
|
||||||
|
<div class="text-sm">
|
||||||
|
<div class="font-semibold mt-1">Developer Note<//>
|
||||||
|
${text.split('.').map(v => html` <p class="my-2 text-slate-500">${v}<//>`)}
|
||||||
|
<//>
|
||||||
|
<//>`;
|
||||||
|
};
|
||||||
|
|
||||||
|
function Main({}) {
|
||||||
|
const [stats, setStats] = useState(null);
|
||||||
|
const refresh = () => fetch('api/stats/get').then(r => r.json()).then(r => setStats(r));
|
||||||
|
useEffect(refresh, []);
|
||||||
|
if (!stats) return '';
|
||||||
|
return html`
|
||||||
|
<div class="p-2">
|
||||||
|
<div class="p-4 sm:p-2 mx-auto grid grid-cols-2 lg:grid-cols-4 gap-4">
|
||||||
|
<${Stat} title="Temperature" text="${stats.temperature} °C" tipText="good" tipIcon=${Icons.ok} tipColors=${tipColors.green} />
|
||||||
|
<${Stat} title="Humidity" text="${stats.humidity} %" tipText="warn" tipIcon=${Icons.warn} tipColors=${tipColors.yellow} />
|
||||||
|
<div class="bg-white col-span-2 border rounded-md shadow-lg" role="alert">
|
||||||
|
<${DeveloperNote} text="Stats data is received from the Mongoose backend" />
|
||||||
|
<//>
|
||||||
|
<//>
|
||||||
|
<div class="p-4 sm:p-2 mx-auto grid grid-cols-1 lg:grid-cols-2 gap-4">
|
||||||
|
|
||||||
|
<${Chart} data=${stats.points} />
|
||||||
|
|
||||||
|
<div class="my-4 hx-24 bg-white border rounded-md shadow-lg" role="alert">
|
||||||
|
<${DeveloperNote}
|
||||||
|
text="This chart is an SVG image, generated on the fly from the
|
||||||
|
data returned by the api/stats/get API call" />
|
||||||
|
<//>
|
||||||
|
<//>
|
||||||
|
<//>`;
|
||||||
|
};
|
||||||
|
|
||||||
|
function Settings({}) {
|
||||||
|
const [settings, setSettings] = useState(null);
|
||||||
|
const [saveResult, setSaveResult] = useState(null);
|
||||||
|
const refresh = () => fetch('api/settings/get')
|
||||||
|
.then(r => r.json())
|
||||||
|
.then(r => setSettings(r));
|
||||||
|
useEffect(refresh, []);
|
||||||
|
|
||||||
|
const mksetfn = k => (v => setSettings(x => Object.assign({}, x, {[k]: v})));
|
||||||
|
const onsave = ev => fetch('api/settings/set', {
|
||||||
|
method: 'post', body: JSON.stringify(settings)
|
||||||
|
}).then(r => r.json())
|
||||||
|
.then(r => setSaveResult(r))
|
||||||
|
.then(refresh);
|
||||||
|
|
||||||
|
if (!settings) return '';
|
||||||
|
const logOptions = [[0, 'Disable'], [1, 'Error'], [2, 'Info'], [3, 'Debug']];
|
||||||
|
return html`
|
||||||
|
<div class="m-4 grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||||
|
|
||||||
|
<div class="py-1 divide-y border rounded bg-white flex flex-col">
|
||||||
|
<div class="font-light uppercase flex items-center text-gray-600 px-4 py-2">
|
||||||
|
Device Settings
|
||||||
|
<//>
|
||||||
|
<div class="py-2 px-5 flex-1 flex flex-col relative">
|
||||||
|
${saveResult && html`<${Notification} ok=${saveResult.status}
|
||||||
|
text=${saveResult.message} close=${() => setSaveResult(null)} />`}
|
||||||
|
|
||||||
|
<${Setting} title="Enable Logs" value=${settings.log_enabled} setfn=${mksetfn('log_enabled')} type="switch" />
|
||||||
|
<${Setting} title="Log Level" value=${settings.log_level} setfn=${mksetfn('log_level')} type="select" addonLeft="0-3" disabled=${!settings.log_enabled} options=${logOptions}/>
|
||||||
|
<${Setting} title="Brightness" value=${settings.brightness} setfn=${mksetfn('brightness')} type="number" addonRight="%" />
|
||||||
|
<${Setting} title="Device Name" value=${settings.device_name} setfn=${mksetfn('device_name')} type="" />
|
||||||
|
<div class="mb-1 mt-3 flex place-content-end"><${Button} icon=${Icons.save} onclick=${onsave} title="Save Settings" /><//>
|
||||||
|
<//>
|
||||||
|
<//>
|
||||||
|
|
||||||
|
<div class="bg-white border rounded-md text-ellipsis overflow-auto" role="alert">
|
||||||
|
<${DeveloperNote}
|
||||||
|
text="A variety of controls are pre-defined to ease the development:
|
||||||
|
toggle button, dropdown select, input field with left and right
|
||||||
|
addons. Device settings are received by calling
|
||||||
|
api/settings/get API call, which returns settings JSON object.
|
||||||
|
Clicking on the save button calls api/settings/set
|
||||||
|
API call" />
|
||||||
|
<//>
|
||||||
|
|
||||||
|
<//>`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const App = function({}) {
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [url, setUrl] = useState('/');
|
||||||
|
const [user, setUser] = useState('');
|
||||||
|
const [showSidebar, setShowSidebar] = useState(true);
|
||||||
|
|
||||||
|
const logout = () => fetch('api/logout').then(r => setUser(''));
|
||||||
|
const login = r => !r.ok ? setLoading(false) && setUser(null) : r.json()
|
||||||
|
.then(r => setUser(r.user))
|
||||||
|
.finally(r => setLoading(false));
|
||||||
|
|
||||||
|
useEffect(() => fetch('api/login').then(login), []);
|
||||||
|
|
||||||
|
if (loading) return ''; // Show blank page on initial load
|
||||||
|
if (!user) return html`<${Login} loginFn=${login} logoIcon=${Logo}
|
||||||
|
title="Device Dashboard Login"
|
||||||
|
tipText="To login, use: admin/admin, user1/user1, user2/user2" />`; // If not logged in, show login screen
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<div class="min-h-screen bg-slate-100">
|
||||||
|
<${Sidebar} url=${url} show=${showSidebar} />
|
||||||
|
<${Header} logout=${logout} user=${user} showSidebar=${showSidebar} setShowSidebar=${setShowSidebar} />
|
||||||
|
<div class="${showSidebar && 'pl-72'} transition-all duration-300 transform">
|
||||||
|
<${Router} onChange=${ev => setUrl(ev.url)} history=${History.createHashHistory()} >
|
||||||
|
<${Main} default=${true} />
|
||||||
|
<${Settings} path="settings" />
|
||||||
|
<${Events} path="events" />
|
||||||
|
<//>
|
||||||
|
<//>
|
||||||
|
<//>`;
|
||||||
};
|
};
|
||||||
|
|
||||||
window.onload = () => render(h(App), document.body);
|
window.onload = () => render(h(App), document.body);
|
||||||
@@ -1 +0,0 @@
|
|||||||
var e,n,_,t,o,r,u,l={},i=[],c=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function s(e,n){for(var _ in n)e[_]=n[_];return e}function f(e){var n=e.parentNode;n&&n.removeChild(e)}function a(n,_,t){var o,r,u,l={};for(u in _)"key"==u?o=_[u]:"ref"==u?r=_[u]:l[u]=_[u];if(arguments.length>2&&(l.children=arguments.length>3?e.call(arguments,2):t),"function"==typeof n&&null!=n.defaultProps)for(u in n.defaultProps)void 0===l[u]&&(l[u]=n.defaultProps[u]);return p(n,l,o,r,null)}function p(e,t,o,r,u){var l={type:e,props:t,key:o,ref:r,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==u?++_:u};return null!=n.vnode&&n.vnode(l),l}function h(e){return e.children}function d(e,n){this.props=e,this.context=n}function v(e,n){if(null==n)return e.__?v(e.__,e.__.__k.indexOf(e)+1):null;for(var _;n<e.__k.length;n++)if(null!=(_=e.__k[n])&&null!=_.__e)return _.__e;return"function"==typeof e.type?v(e):null}function y(e){var n,_;if(null!=(e=e.__)&&null!=e.__c){for(e.__e=e.__c.base=null,n=0;n<e.__k.length;n++)if(null!=(_=e.__k[n])&&null!=_.__e){e.__e=e.__c.base=_.__e;break}return y(e)}}function m(e){(!e.__d&&(e.__d=!0)&&t.push(e)&&!g.__r++||r!==n.debounceRendering)&&((r=n.debounceRendering)||o)(g)}function g(){for(var e;g.__r=t.length;)e=t.sort(function(e,n){return e.__v.__b-n.__v.__b}),t=[],e.some(function(e){var n,_,t,o,r,u;e.__d&&(r=(o=(n=e).__v).__e,(u=n.__P)&&(_=[],(t=s({},o)).__v=o.__v+1,P(u,o,t,n.__n,void 0!==u.ownerSVGElement,null!=o.__h?[r]:null,_,null==r?v(o):r,o.__h),D(_,o),o.__e!=r&&y(o)))})}function k(e,n,_,t,o,r,u,c,s,f){var a,d,y,m,g,k,x,H=t&&t.__k||i,E=H.length;for(_.__k=[],a=0;a<n.length;a++)if(null!=(m=_.__k[a]=null==(m=n[a])||"boolean"==typeof m?null:"string"==typeof m||"number"==typeof m||"bigint"==typeof m?p(null,m,null,null,m):Array.isArray(m)?p(h,{children:m},null,null,null):m.__b>0?p(m.type,m.props,m.key,null,m.__v):m)){if(m.__=_,m.__b=_.__b+1,null===(y=H[a])||y&&m.key==y.key&&m.type===y.type)H[a]=void 0;else for(d=0;d<E;d++){if((y=H[d])&&m.key==y.key&&m.type===y.type){H[d]=void 0;break}y=null}P(e,m,y=y||l,o,r,u,c,s,f),g=m.__e,(d=m.ref)&&y.ref!=d&&(x||(x=[]),y.ref&&x.push(y.ref,null,m),x.push(d,m.__c||g,m)),null!=g?(null==k&&(k=g),"function"==typeof m.type&&null!=m.__k&&m.__k===y.__k?m.__d=s=b(m,s,e):s=C(e,m,y,H,g,s),f||"option"!==_.type?"function"==typeof _.type&&(_.__d=s):e.value=""):s&&y.__e==s&&s.parentNode!=e&&(s=v(y))}for(_.__e=k,a=E;a--;)null!=H[a]&&("function"==typeof _.type&&null!=H[a].__e&&H[a].__e==_.__d&&(_.__d=v(t,a+1)),U(H[a],H[a]));if(x)for(a=0;a<x.length;a++)T(x[a],x[++a],x[++a])}function b(e,n,_){var t,o;for(t=0;t<e.__k.length;t++)(o=e.__k[t])&&(o.__=e,n="function"==typeof o.type?b(o,n,_):C(_,o,o,e.__k,o.__e,n));return n}function C(e,n,_,t,o,r){var u,l,i;if(void 0!==n.__d)u=n.__d,n.__d=void 0;else if(null==_||o!=r||null==o.parentNode)e:if(null==r||r.parentNode!==e)e.appendChild(o),u=null;else{for(l=r,i=0;(l=l.nextSibling)&&i<t.length;i+=2)if(l==o)break e;e.insertBefore(o,r),u=r}return void 0!==u?u:o.nextSibling}function x(e,n,_){"-"===n[0]?e.setProperty(n,_):e[n]=null==_?"":"number"!=typeof _||c.test(n)?_:_+"px"}function H(e,n,_,t,o){var r;e:if("style"===n)if("string"==typeof _)e.style.cssText=_;else{if("string"==typeof t&&(e.style.cssText=t=""),t)for(n in t)_&&n in _||x(e.style,n,"");if(_)for(n in _)t&&_[n]===t[n]||x(e.style,n,_[n])}else if("o"===n[0]&&"n"===n[1])r=n!==(n=n.replace(/Capture$/,"")),n=n.toLowerCase()in e?n.toLowerCase().slice(2):n.slice(2),e.l||(e.l={}),e.l[n+r]=_,_?t||e.addEventListener(n,r?S:E,r):e.removeEventListener(n,r?S:E,r);else if("dangerouslySetInnerHTML"!==n){if(o)n=n.replace(/xlink[H:h]/,"h").replace(/sName$/,"s");else if("href"!==n&&"list"!==n&&"form"!==n&&"tabIndex"!==n&&"download"!==n&&n in e)try{e[n]=null==_?"":_;break e}catch(e){}"function"==typeof _||(null!=_&&(!1!==_||"a"===n[0]&&"r"===n[1])?e.setAttribute(n,_):e.removeAttribute(n))}}function E(e){this.l[e.type+!1](n.event?n.event(e):e)}function S(e){this.l[e.type+!0](n.event?n.event(e):e)}function P(e,_,t,o,r,u,l,i,c){var f,a,p,v,y,m,g,b,C,x,H,E=_.type;if(void 0!==_.constructor)return null;null!=t.__h&&(c=t.__h,i=_.__e=t.__e,_.__h=null,u=[i]),(f=n.__b)&&f(_);try{e:if("function"==typeof E){if(b=_.props,C=(f=E.contextType)&&o[f.__c],x=f?C?C.props.value:f.__:o,t.__c?g=(a=_.__c=t.__c).__=a.__E:("prototype"in E&&E.prototype.render?_.__c=a=new E(b,x):(_.__c=a=new d(b,x),a.constructor=E,a.render=A),C&&C.sub(a),a.props=b,a.state||(a.state={}),a.context=x,a.__n=o,p=a.__d=!0,a.__h=[]),null==a.__s&&(a.__s=a.state),null!=E.getDerivedStateFromProps&&(a.__s==a.state&&(a.__s=s({},a.__s)),s(a.__s,E.getDerivedStateFromProps(b,a.__s))),v=a.props,y=a.state,p)null==E.getDerivedStateFromProps&&null!=a.componentWillMount&&a.componentWillMount(),null!=a.componentDidMount&&a.__h.push(a.componentDidMount);else{if(null==E.getDerivedStateFromProps&&b!==v&&null!=a.componentWillReceiveProps&&a.componentWillReceiveProps(b,x),!a.__e&&null!=a.shouldComponentUpdate&&!1===a.shouldCompLine truncated
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
* { box-sizing: border-box; }
|
|
||||||
html, body { margin: 0; padding: 0; height: 100%; font: 16px sans-serif; }
|
|
||||||
select, input, label::before, textarea { outline: none; box-shadow:none !important; border: 1px solid #ccc !important; }
|
|
||||||
code, pre { color: #373; font-family: monospace; font-weight: bolder; font-size: smaller; background: #ddd; padding: 0.1em 0.3em; border-radius: 0.2em; }
|
|
||||||
textarea, input, .addon { font-size: 15px; border: 1px solid #ccc; padding: 0.5em; }
|
|
||||||
a, a:visited, a:active { color: #55f; }
|
|
||||||
.addon { background: #eee; min-width: 9em;}
|
|
||||||
.btn {
|
|
||||||
background: #ccc; border-radius: 0.3em; border: 0; color: #fff; cursor: pointer;
|
|
||||||
display: inline-block; padding: 0.6em 2em; font-weight: bolder;
|
|
||||||
}
|
|
||||||
.btn[disabled] { opacity: 0.5; cursor: auto;}
|
|
||||||
.smooth { transition: all .2s; }
|
|
||||||
.container { margin: 0 20px; width: auto; }
|
|
||||||
.d-flex { display: flex; }
|
|
||||||
.d-none { display: none; }
|
|
||||||
.border { border: 1px solid #ddd; }
|
|
||||||
.rounded { border-radius: 0.5em; }
|
|
||||||
.nowrap { white-space: nowrap; }
|
|
||||||
.msg { background: #def; border-left: 5px solid #59d; padding: 0.5em; font-size: 90%; margin: 1em 0; }
|
|
||||||
.section { margin: 0 1em; }
|
|
||||||
.topic, .data, .qos { padding: 0.2em 0.5em; border-radius: 0.4em; margin-right: 0.5em; }
|
|
||||||
.qos { background: #efa; }
|
|
||||||
.topic { background: #fea; }
|
|
||||||
.data { background: #aef; }
|
|
||||||
|
|
||||||
/* Grid */
|
|
||||||
.row { display: flex; flex-wrap: wrap; }
|
|
||||||
.col { margin: 0; padding: 0; overflow: auto; }
|
|
||||||
.col-12 { width: 100%; }
|
|
||||||
.col-11 { width: 91.66%; }
|
|
||||||
.col-10 { width: 83.33%; }
|
|
||||||
.col-9 { width: 75%; }
|
|
||||||
.col-8 { width: 66.66%; }
|
|
||||||
.col-7 { width: 58.33%; }
|
|
||||||
.col-6 { width: 50%; }
|
|
||||||
.col-5 { width: 41.66%; }
|
|
||||||
.col-4 { width: 33.33%; }
|
|
||||||
.col-3 { width: 25%; }
|
|
||||||
.col-2 { width: 16.66%; }
|
|
||||||
.col-1 { width: 8.33%; }
|
|
||||||
@media (min-width: 1310px) { .container { margin: auto; width: 1270px; } }
|
|
||||||
@media (max-width: 920px) { .row .col { width: 100%; } }
|
|
||||||
|
Before Width: | Height: | Size: 3.8 KiB |
@@ -1,38 +1,38 @@
|
|||||||
PROG ?= example
|
PROG ?= example # Program we are building
|
||||||
SOURCES ?= ../../mongoose.c main.c packed_fs.c
|
DELETE = rm -rf # Command to remove files
|
||||||
CFLAGS ?= -I../.. -DMG_ENABLE_PACKED_FS=1 -DMG_ENABLE_LINES=1 $(EXTRA)
|
OUT ?= -o $(PROG) # Compiler argument for output file
|
||||||
|
SOURCES = main.c mongoose.c packed_fs.c # Source code files
|
||||||
|
CFLAGS = -W -Wall -Wextra -g -I. # Build options
|
||||||
|
PACK = ./pack # Utility to pack files into a packed filesystem
|
||||||
|
|
||||||
|
# Mongoose build options. See https://mongoose.ws/documentation/#build-options
|
||||||
|
CFLAGS_MONGOOSE += -DMG_ENABLE_PACKED_FS=1
|
||||||
|
|
||||||
FILES_TO_EMBED ?= $(wildcard web_root/*)
|
FILES_TO_EMBED ?= $(wildcard web_root/*)
|
||||||
ROOT ?= $(realpath $(CURDIR)/../../..)
|
|
||||||
DOCKER ?= docker run --rm -e Tmp=. -e WINEDEBUG=-all -v $(ROOT):$(ROOT) -w $(CURDIR)
|
|
||||||
VC98 ?= $(DOCKER) mdashnet/vc98 wine
|
|
||||||
MINGW ?= $(DOCKER) mdashnet/mingw
|
|
||||||
|
|
||||||
all: $(PROG)
|
ifeq ($(OS),Windows_NT) # Windows settings. Assume MinGW compiler. To use VC: make CC=cl CFLAGS=/MD OUT=/Feprog.exe
|
||||||
$(RUN) ./$(PROG)
|
PROG ?= example.exe # Use .exe suffix for the binary
|
||||||
|
CC = gcc # Use MinGW gcc compiler
|
||||||
|
CFLAGS += -lws2_32 # Link against Winsock library
|
||||||
|
DELETE = cmd /C del /Q /F /S # Command prompt command to delete files
|
||||||
|
OUT ?= -o $(PROG) # Build output
|
||||||
|
PACK = pack.exe
|
||||||
|
endif
|
||||||
|
|
||||||
$(PROG): $(SOURCES) $(FILES_TO_EMBED)
|
all: $(PROG) # Default target. Build and run program
|
||||||
$(CC) ../../test/pack.c -o pack
|
$(RUN) ./$(PROG) $(ARGS)
|
||||||
./pack $(FILES_TO_EMBED) > packed_fs.c
|
|
||||||
$(CC) -W -Wall -Wextra -O0 -g3 $(CFLAGS) -o $(PROG) $(SOURCES)
|
|
||||||
|
|
||||||
|
$(PROG): $(SOURCES) $(FILES_TO_EMBED) # Build program from sources
|
||||||
|
$(CC) ../../test/pack.c -o $(PACK)
|
||||||
|
$(PACK) $(FILES_TO_EMBED) > packed_fs.c
|
||||||
|
$(CC) $(SOURCES) $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA) $(OUT)
|
||||||
|
|
||||||
mingw: $(SOURCES) $(FILES_TO_EMBED)
|
clean: # Cleanup. Delete built program and all build artifacts
|
||||||
$(MINGW) i686-w64-mingw32-gcc $(CFLAGS) ../../test/pack.c -o pack.exe
|
$(DELETE) $(PROG) *.dSYM $(PACK)
|
||||||
$(MINGW) wine cmd /c 'pack.exe $(FILES_TO_EMBED) > packed_fs.c'
|
|
||||||
$(MINGW) i686-w64-mingw32-gcc $(CFLAGS) $(SOURCES) -lws2_32 -o $(PROG).exe
|
|
||||||
$(MINGW) wine $(PROG).exe
|
|
||||||
|
|
||||||
vc98: $(SOURCES) $(FILES_TO_EMBED)
|
|
||||||
$(VC98) cl.exe /nologo $(CFLAGS) ../../test/pack.c /Fepack.exe
|
|
||||||
$(VC98) cmd /c 'pack.exe $(FILES_TO_EMBED) > packed_fs.c'
|
|
||||||
$(VC98) cl.exe /nologo /O2 $(CFLAGS) $(SOURCES) /Fe$(PROG).exe
|
|
||||||
$(VC98) $(PROG).exe
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb log.txt pack
|
|
||||||
|
|
||||||
.PHONY: compress expand gzipped plain all
|
.PHONY: compress expand gzipped plain all
|
||||||
|
|
||||||
|
# See tutorial at https://mongoose.ws/tutorials/embedded-filesystem/#build-and-try
|
||||||
gzipped: compress
|
gzipped: compress
|
||||||
$(MAKE) all
|
$(MAKE) all
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
See detailed tutorial at https://mongoose.ws/tutorials/embedded-filesystem/
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../../mongoose.c
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../../mongoose.h
|
||||||
@@ -3,51 +3,552 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
static const unsigned char v1[] = {
|
static const unsigned char v1[] = {
|
||||||
60, 33, 68, 79, 67, 84, 89, 80, 69, 32, 104, 116, // <!DOCTYPE ht
|
31, 139, 8, 8, 219, 27, 244, 98, 0, 3, 112, 114, // .......b..pr
|
||||||
109, 108, 62, 10, 60, 104, 116, 109, 108, 32, 108, 97, // ml>.<html la
|
101, 97, 99, 116, 46, 109, 105, 110, 46, 106, 115, 0, // eact.min.js.
|
||||||
110, 103, 61, 34, 101, 110, 34, 62, 10, 32, 32, 60, // ng="en">. <
|
157, 91, 123, 119, 219, 182, 146, 255, 127, 63, 69, 164, // .[{w.....?E.
|
||||||
104, 101, 97, 100, 62, 10, 32, 32, 32, 32, 60, 109, // head>. <m
|
211, 163, 18, 43, 68, 177, 147, 182, 187, 75, 5, 213, // ...+D....K..
|
||||||
101, 116, 97, 32, 110, 97, 109, 101, 61, 34, 100, 101, // eta name="de
|
105, 29, 183, 238, 109, 234, 230, 38, 105, 123, 123, 85, // i...m..&i{{U
|
||||||
115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 99, // scription" c
|
93, 30, 138, 132, 44, 214, 20, 169, 242, 97, 91, 53, // ]...,....a[5
|
||||||
111, 110, 116, 101, 110, 116, 61, 34, 77, 111, 110, 103, // ontent="Mong
|
245, 221, 247, 55, 3, 128, 164, 108, 185, 247, 236, 158, // ...7...l....
|
||||||
111, 111, 115, 101, 32, 69, 109, 98, 101, 100, 100, 101, // oose Embedde
|
36, 34, 30, 131, 1, 48, 47, 204, 12, 144, 155, 176, // $"...0/.....
|
||||||
100, 32, 70, 105, 108, 101, 115, 121, 116, 101, 109, 32, // d Filesytem
|
120, 166, 101, 38, 3, 89, 201, 92, 22, 178, 150, 169, // x.e&.Y......
|
||||||
101, 120, 97, 109, 112, 108, 101, 34, 32, 47, 62, 10, // example" />.
|
186, 223, 203, 68, 205, 23, 50, 82, 47, 194, 40, 169, // ...D..2R/.(.
|
||||||
32, 32, 32, 32, 60, 109, 101, 116, 97, 32, 104, 116, // <meta ht
|
26, 125, 231, 205, 252, 178, 185, 106, 178, 102, 219, 124, // .}.....j.f.|
|
||||||
116, 112, 45, 101, 113, 117, 105, 118, 61, 34, 67, 111, // tp-equiv="Co
|
34, 154, 98, 187, 110, 174, 138, 36, 110, 242, 219, 178, // ".b.n..$n...
|
||||||
110, 116, 101, 110, 116, 45, 84, 121, 112, 101, 34, 32, // ntent-Type"
|
217, 100, 81, 147, 85, 183, 77, 146, 233, 121, 180, 94, // .dQ.U.M..y.^
|
||||||
99, 111, 110, 116, 101, 110, 116, 61, 34, 116, 101, 120, // content="tex
|
52, 127, 230, 121, 243, 175, 188, 136, 155, 164, 210, 69, // 4..y.......E
|
||||||
116, 47, 104, 116, 109, 108, 59, 32, 99, 104, 97, 114, // t/html; char
|
248, 34, 153, 174, 234, 44, 170, 146, 60, 123, 86, 122, // ."...,..<{Vz
|
||||||
115, 101, 116, 61, 85, 84, 70, 45, 56, 34, 62, 10, // set=UTF-8">.
|
152, 72, 220, 175, 242, 194, 187, 193, 172, 193, 179, 36, // .H.........$
|
||||||
32, 32, 32, 32, 60, 109, 101, 116, 97, 32, 104, 116, // <meta ht
|
123, 150, 9, 61, 15, 22, 42, 195, 207, 180, 208, 85, // {..=..*....U
|
||||||
116, 112, 45, 101, 113, 117, 105, 118, 61, 34, 88, 45, // tp-equiv="X-
|
93, 100, 207, 244, 190, 29, 177, 242, 180, 184, 39, 216, // ]d........'.
|
||||||
85, 65, 45, 67, 111, 109, 112, 97, 116, 105, 98, 108, // UA-Compatibl
|
76, 233, 201, 54, 44, 116, 86, 93, 230, 177, 158, 102, // L..6,tV]...f
|
||||||
101, 34, 32, 99, 111, 110, 116, 101, 110, 116, 61, 34, // e" content="
|
163, 81, 54, 41, 244, 38, 191, 209, 103, 235, 36, 141, // .Q6).&..g.$.
|
||||||
73, 69, 61, 101, 100, 103, 101, 34, 62, 10, 32, 32, // IE=edge">.
|
1, 214, 13, 10, 61, 222, 141, 25, 216, 109, 105, 74, // ....=....miJ
|
||||||
32, 32, 60, 109, 101, 116, 97, 32, 110, 97, 109, 101, // <meta name
|
243, 214, 52, 103, 32, 134, 215, 122, 55, 84, 170, 158, // ..4g ..z7T..
|
||||||
61, 34, 118, 105, 101, 119, 112, 111, 114, 116, 34, 32, // ="viewport"
|
229, 42, 152, 215, 11, 127, 88, 232, 21, 215, 11, 83, // .*....X....S
|
||||||
99, 111, 110, 116, 101, 110, 116, 61, 34, 119, 105, 100, // content="wid
|
79, 241, 195, 165, 105, 178, 242, 194, 226, 170, 222, 96, // O...i......`
|
||||||
116, 104, 61, 100, 101, 118, 105, 99, 101, 45, 119, 105, // th=device-wi
|
230, 114, 146, 234, 236, 170, 90, 127, 249, 114, 52, 242, // .r....Z..r4.
|
||||||
100, 116, 104, 44, 32, 105, 110, 105, 116, 105, 97, 108, // dth, initial
|
210, 73, 68, 19, 99, 69, 234, 81, 255, 171, 153, 158, // .ID.cE.Q....
|
||||||
45, 115, 99, 97, 108, 101, 61, 49, 34, 62, 10, 32, // -scale=1">.
|
68, 97, 154, 118, 35, 229, 75, 225, 87, 66, 14, 221, // Da.v#.K.WB..
|
||||||
32, 32, 32, 32, 32, 32, 32, 60, 116, 105, 116, 108, // <titl
|
26, 49, 87, 181, 219, 234, 124, 245, 140, 118, 82, 167, // .1W...|..vR.
|
||||||
101, 62, 77, 111, 110, 103, 111, 111, 115, 101, 32, 69, // e>Mongoose E
|
233, 64, 101, 147, 88, 175, 194, 58, 173, 222, 21, 249, // .@e.X..:....
|
||||||
109, 98, 101, 100, 100, 101, 100, 32, 70, 105, 108, 101, // mbedded File
|
182, 20, 237, 98, 31, 180, 223, 228, 73, 252, 236, 68, // ...b....I..D
|
||||||
115, 121, 116, 101, 109, 32, 101, 120, 97, 109, 112, 108, // sytem exampl
|
41, 69, 75, 164, 117, 208, 74, 15, 97, 208, 34, 28, // )EK.u.J.a.".
|
||||||
101, 60, 47, 116, 105, 116, 108, 101, 62, 10, 32, 32, // e</title>.
|
45, 183, 160, 69, 202, 124, 165, 89, 122, 68, 218, 130, // -..E.|.YzD..
|
||||||
32, 32, 60, 108, 105, 110, 107, 32, 114, 101, 108, 61, // <link rel=
|
23, 150, 225, 134, 80, 32, 17, 45, 201, 215, 114, 75, // ....P .-..rK
|
||||||
34, 115, 116, 121, 108, 101, 115, 104, 101, 101, 116, 34, // "stylesheet"
|
72, 252, 74, 130, 70, 62, 0, 244, 202, 47, 100, 16, // H.J.F>.../d.
|
||||||
32, 104, 114, 101, 102, 61, 34, 115, 116, 121, 108, 101, // href="style
|
92, 251, 132, 1, 5, 247, 93, 250, 39, 248, 213, 174, // ......].'...
|
||||||
46, 99, 115, 115, 34, 32, 47, 62, 10, 32, 32, 60, // .css" />. <
|
26, 251, 102, 105, 40, 70, 174, 109, 109, 10, 81, 158, // ..fi(F.mm.Q.
|
||||||
47, 104, 101, 97, 100, 62, 10, 32, 32, 60, 98, 111, // /head>. <bo
|
149, 85, 81, 71, 85, 94, 116, 64, 55, 220, 71, 52, // .UQGU^t@7.G4
|
||||||
100, 121, 62, 60, 47, 98, 111, 100, 121, 62, 10, 32, // dy></body>.
|
31, 143, 3, 191, 222, 187, 21, 59, 106, 220, 100, 96, // .......;j.d`
|
||||||
32, 60, 115, 99, 114, 105, 112, 116, 32, 116, 121, 112, // <script typ
|
52, 177, 153, 11, 94, 42, 100, 218, 173, 126, 77, 114, // 4...^*d..~Mr
|
||||||
101, 61, 34, 109, 111, 100, 117, 108, 101, 34, 32, 115, // e="module" s
|
225, 196, 165, 229, 68, 215, 31, 27, 73, 171, 214, 73, // ....D...I..I
|
||||||
114, 99, 61, 34, 109, 97, 105, 110, 46, 106, 115, 34, // rc="main.js"
|
57, 225, 237, 40, 236, 150, 42, 88, 74, 165, 239, 42, // 9..(..*XJ..*
|
||||||
62, 60, 47, 115, 99, 114, 105, 112, 116, 62, 10, 60, // ></script>.<
|
213, 131, 189, 49, 176, 96, 180, 89, 80, 38, 90, 196, // ...1.`.YP&Z.
|
||||||
47, 104, 116, 109, 108, 62, 10, 0 // /html>.
|
65, 48, 67, 47, 62, 146, 126, 240, 247, 122, 146, 100, // A0C/>.~..z.d
|
||||||
|
177, 190, 251, 145, 228, 114, 124, 42, 120, 11, 211, 86, // .....r|*x..V
|
||||||
|
158, 167, 217, 107, 205, 64, 70, 14, 166, 217, 120, 44, // ...k.@F...x,
|
||||||
|
44, 218, 129, 242, 2, 197, 157, 243, 108, 33, 28, 207, // ,.......l!..
|
||||||
|
9, 165, 118, 211, 113, 197, 82, 225, 136, 160, 232, 9, // ..v.q.R.....
|
||||||
|
21, 104, 61, 102, 218, 110, 3, 187, 86, 73, 100, 48, // .h=f.n..VId0
|
||||||
|
237, 230, 211, 60, 95, 59, 23, 85, 34, 163, 124, 84, // ...<_;.U".|T
|
||||||
|
52, 189, 209, 100, 25, 150, 90, 49, 151, 50, 117, 242, // 4..d..Z1.2u.
|
||||||
|
255, 220, 192, 253, 35, 132, 102, 47, 203, 66, 135, 215, // ....#.f/.B..
|
||||||
|
123, 187, 61, 90, 229, 190, 91, 244, 134, 22, 237, 13, // {.=Z..[.....
|
||||||
|
104, 76, 12, 49, 230, 175, 26, 156, 0, 115, 53, 217, // hL.1.....s5.
|
||||||
|
214, 37, 49, 120, 52, 26, 92, 161, 185, 24, 143, 155, // .%1x4.......
|
||||||
|
166, 24, 40, 150, 242, 101, 14, 4, 250, 189, 6, 23, // ..(..e......
|
||||||
|
138, 36, 187, 2, 140, 231, 21, 71, 123, 154, 38, 23, // .$.....G{.&.
|
||||||
|
222, 85, 79, 226, 175, 188, 206, 244, 232, 41, 99, 86, // .UO......)cV
|
||||||
|
149, 219, 169, 208, 40, 151, 121, 81, 121, 14, 222, 72, // ....(.yQy..H
|
||||||
|
69, 79, 20, 110, 240, 111, 249, 60, 115, 165, 189, 144, // EO.n.o.<s...
|
||||||
|
21, 217, 72, 141, 97, 27, 221, 27, 214, 242, 194, 233, // ..H.a.......
|
||||||
|
215, 212, 109, 178, 80, 94, 174, 60, 152, 50, 65, 72, // ..m.P^.<.2AH
|
||||||
|
232, 71, 75, 175, 86, 132, 242, 29, 237, 36, 32, 124, // .GK.V....$ |
|
||||||
|
94, 165, 74, 15, 6, 56, 23, 12, 165, 114, 250, 29, // ^.J..8...r..
|
||||||
|
159, 202, 119, 94, 13, 116, 149, 36, 232, 76, 26, 53, // ..w^.t.$.L.5
|
||||||
|
2, 81, 234, 73, 126, 155, 233, 226, 195, 207, 223, 158, // .Q.I~.......
|
||||||
|
167, 154, 108, 141, 52, 156, 161, 97, 235, 217, 188, 88, // ..l.4..a...X
|
||||||
|
88, 93, 148, 70, 184, 11, 8, 80, 46, 160, 208, 220, // X].F...P....
|
||||||
|
47, 228, 27, 47, 192, 76, 92, 211, 3, 85, 140, 70, // /../.L...U.F
|
||||||
|
59, 116, 11, 177, 239, 209, 237, 218, 59, 60, 30, 34, // ;t......;<."
|
||||||
|
89, 202, 149, 217, 100, 40, 99, 185, 147, 27, 121, 37, // Y...d(c...y%
|
||||||
|
175, 229, 157, 188, 80, 21, 113, 15, 34, 210, 52, 137, // ....P.q.".4.
|
||||||
|
60, 87, 23, 142, 184, 68, 117, 214, 30, 218, 95, 8, // <W...Du..._.
|
||||||
|
49, 11, 95, 103, 174, 47, 60, 16, 177, 13, 75, 206, // 1._g./<...K.
|
||||||
|
245, 60, 92, 40, 179, 94, 180, 100, 168, 129, 155, 195, // .<.(.^.d....
|
||||||
|
101, 158, 167, 58, 236, 105, 196, 102, 70, 48, 254, 16, // e..:.i.fF0..
|
||||||
|
182, 5, 12, 239, 181, 3, 56, 171, 55, 75, 93, 28, // ......8.7K].
|
||||||
|
182, 45, 147, 171, 36, 171, 250, 227, 183, 60, 47, 54, // .-..$....</6
|
||||||
|
96, 20, 128, 203, 194, 255, 170, 40, 194, 221, 36, 41, // `......(..$)
|
||||||
|
249, 235, 109, 4, 192, 214, 242, 222, 25, 25, 127, 179, // ..m.........
|
||||||
|
239, 129, 179, 85, 245, 55, 36, 16, 95, 158, 0, 112, // ...U.7$._..p
|
||||||
|
195, 90, 42, 55, 198, 234, 224, 11, 35, 106, 17, 51, // .Z*7....#j.3
|
||||||
|
207, 253, 141, 96, 83, 67, 53, 21, 112, 227, 146, 247, // ...`SC5.p...
|
||||||
|
188, 4, 139, 205, 150, 149, 183, 83, 23, 102, 207, 187, // .......S.f..
|
||||||
|
209, 136, 49, 40, 181, 163, 15, 213, 8, 189, 162, 58, // ..1(.......:
|
||||||
|
21, 4, 193, 41, 35, 11, 83, 157, 150, 250, 25, 145, // ...)#.S.....
|
||||||
|
58, 6, 133, 227, 215, 231, 211, 24, 164, 165, 185, 24, // :...........
|
||||||
|
95, 76, 74, 251, 215, 200, 238, 9, 202, 97, 51, 186, // _LJ......a3.
|
||||||
|
187, 99, 54, 236, 223, 65, 4, 54, 114, 167, 118, 77, // .c6..A.6r.vM
|
||||||
|
147, 30, 72, 129, 188, 82, 27, 35, 198, 49, 10, 56, // ..H..R.#.1.8
|
||||||
|
42, 48, 201, 142, 190, 3, 69, 2, 127, 215, 52, 222, // *0....E...4.
|
||||||
|
29, 152, 46, 36, 55, 142, 70, 119, 70, 183, 185, 230, // ...$7.FwF...
|
||||||
|
232, 45, 109, 99, 204, 212, 136, 154, 230, 10, 141, 194, // .-mc........
|
||||||
|
138, 241, 213, 204, 90, 229, 107, 160, 187, 86, 87, 71, // ....Z.k..VWG
|
||||||
|
207, 80, 179, 17, 103, 147, 8, 203, 53, 237, 142, 4, // .P..g...5...
|
||||||
|
142, 54, 135, 239, 108, 195, 246, 165, 84, 75, 111, 131, // .6..l...TKo.
|
||||||
|
133, 195, 132, 150, 234, 204, 108, 74, 94, 64, 124, 75, // ......lJ^@|K
|
||||||
|
33, 87, 144, 144, 124, 203, 136, 161, 86, 129, 177, 182, // !W..|...V...
|
||||||
|
71, 38, 11, 236, 100, 44, 209, 64, 41, 124, 61, 185, // G&..d,.@)|=.
|
||||||
|
9, 211, 90, 171, 225, 16, 104, 105, 255, 100, 12, 21, // ..Z...hi.d..
|
||||||
|
74, 101, 207, 101, 129, 1, 198, 152, 82, 221, 120, 59, // Je.e....R.x;
|
||||||
|
168, 151, 211, 8, 173, 174, 161, 16, 231, 211, 240, 249, // ............
|
||||||
|
243, 169, 48, 203, 39, 150, 2, 242, 47, 102, 238, 224, // ..0.'.../f..
|
||||||
|
8, 195, 104, 228, 74, 138, 5, 41, 110, 151, 118, 227, // ..h.J..)n.v.
|
||||||
|
85, 50, 196, 41, 37, 228, 79, 30, 193, 72, 150, 42, // U2.)%.O..H.*
|
||||||
|
65, 71, 196, 29, 251, 23, 70, 21, 239, 250, 170, 248, // AG....F.....
|
||||||
|
209, 187, 35, 200, 187, 249, 120, 220, 126, 122, 182, 96, // ..#...x.~z.`
|
||||||
|
105, 108, 129, 209, 126, 24, 4, 86, 237, 10, 104, 170, // il..~..V..h.
|
||||||
|
195, 131, 163, 2, 42, 216, 58, 115, 94, 84, 36, 122, // ....*.:s^T$z
|
||||||
|
30, 153, 24, 156, 194, 153, 58, 178, 179, 220, 80, 123, // ......:...P{
|
||||||
|
233, 229, 140, 221, 63, 35, 171, 132, 63, 60, 222, 24, // ....?#..?<..
|
||||||
|
39, 24, 227, 214, 169, 233, 29, 222, 103, 125, 227, 100, // '.......g}.d
|
||||||
|
150, 5, 111, 79, 38, 180, 201, 214, 70, 146, 201, 140, // ..oO&...F...
|
||||||
|
133, 49, 180, 49, 27, 208, 248, 64, 105, 218, 163, 63, // .1.1...@i..?
|
||||||
|
192, 161, 1, 43, 216, 52, 166, 154, 247, 248, 39, 180, // ...+.4....'.
|
||||||
|
223, 130, 1, 160, 56, 96, 45, 44, 186, 158, 132, 219, // ....8`-,....
|
||||||
|
45, 14, 31, 227, 142, 194, 164, 214, 172, 58, 60, 1, // -........:<.
|
||||||
|
31, 59, 169, 42, 224, 84, 159, 76, 81, 72, 39, 25, // .;.*.T.LQH'.
|
||||||
|
124, 144, 15, 201, 50, 53, 71, 88, 242, 186, 61, 135, // |...25GX..=.
|
||||||
|
146, 177, 122, 73, 246, 144, 102, 23, 172, 131, 56, 171, // ..zI..f...8.
|
||||||
|
52, 188, 142, 82, 23, 213, 215, 26, 136, 180, 71, 59, // 4..R......G;
|
||||||
|
5, 250, 194, 157, 172, 221, 89, 48, 171, 253, 188, 143, // ......Y0....
|
||||||
|
187, 163, 211, 157, 99, 220, 240, 57, 200, 14, 155, 122, // ....c..9...z
|
||||||
|
178, 128, 147, 90, 106, 246, 24, 129, 122, 231, 49, 225, // ...Zj...z.1.
|
||||||
|
53, 14, 119, 107, 121, 131, 217, 112, 232, 59, 59, 58, // 5.wky..p.;;:
|
||||||
|
104, 101, 176, 105, 162, 73, 165, 203, 202, 203, 196, 44, // he.i.I.....,
|
||||||
|
240, 131, 241, 112, 123, 55, 236, 166, 185, 232, 216, 97, // ...p{7.....a
|
||||||
|
152, 81, 76, 153, 110, 176, 209, 187, 84, 243, 204, 194, // .QL.n...T...
|
||||||
|
84, 15, 77, 118, 0, 250, 49, 200, 36, 42, 203, 143, // T.Mv..1.$*..
|
||||||
|
228, 160, 5, 134, 114, 199, 128, 43, 246, 23, 14, 193, // ....r..+....
|
||||||
|
43, 210, 62, 248, 252, 68, 233, 140, 220, 230, 74, 4, // +.>..D....J.
|
||||||
|
208, 20, 246, 246, 155, 230, 206, 193, 99, 113, 128, 35, // ........cq.#
|
||||||
|
225, 8, 58, 208, 64, 0, 99, 64, 59, 199, 20, 248, // ..:.@.c@;...
|
||||||
|
28, 194, 83, 135, 216, 59, 57, 25, 230, 142, 124, 163, // ..S..;9...|.
|
||||||
|
209, 48, 51, 229, 211, 133, 128, 11, 2, 250, 227, 104, // .03........h
|
||||||
|
167, 168, 100, 155, 134, 145, 246, 94, 156, 133, 91, 176, // ..d....^..[.
|
||||||
|
71, 127, 242, 130, 166, 132, 61, 67, 95, 149, 191, 205, // G.....=C_...
|
||||||
|
111, 117, 113, 6, 23, 201, 19, 152, 89, 207, 30, 180, // ouq.....Y...
|
||||||
|
77, 202, 52, 193, 88, 68, 11, 89, 91, 132, 22, 164, // M.4.XD.Y[...
|
||||||
|
176, 163, 248, 69, 16, 195, 181, 121, 54, 46, 16, 158, // ...E...y6...
|
||||||
|
200, 96, 86, 53, 13, 4, 47, 142, 207, 111, 32, 139, // .`V5../..o .
|
||||||
|
111, 147, 178, 210, 240, 5, 192, 202, 98, 246, 193, 63, // o.......b..?
|
||||||
|
135, 152, 192, 54, 153, 40, 233, 41, 128, 86, 1, 134, // ...6.(.).V..
|
||||||
|
113, 152, 93, 233, 34, 175, 203, 116, 247, 65, 87, 223, // q.]."..t.AW.
|
||||||
|
101, 128, 187, 248, 248, 195, 91, 50, 134, 198, 59, 206, // e.....[2..;.
|
||||||
|
197, 193, 246, 238, 32, 96, 215, 243, 11, 127, 189, 192, // .... `......
|
||||||
|
6, 215, 67, 209, 245, 148, 151, 225, 134, 183, 93, 14, // ..C.......].
|
||||||
|
123, 248, 215, 20, 98, 17, 50, 16, 46, 197, 66, 92, // {...b.2...B.
|
||||||
|
25, 108, 216, 184, 114, 21, 46, 191, 35, 255, 218, 213, // .l..r...#...
|
||||||
|
99, 248, 54, 105, 30, 198, 182, 206, 220, 210, 162, 42, // c.6i.......*
|
||||||
|
118, 247, 15, 5, 53, 152, 90, 101, 217, 71, 97, 21, // v...5.Ze.Ga.
|
||||||
|
113, 120, 176, 63, 102, 66, 65, 72, 235, 185, 66, 136, // qx.?fBAH..B.
|
||||||
|
6, 167, 3, 214, 249, 97, 216, 99, 106, 209, 50, 213, // .....a.cj.2.
|
||||||
|
40, 200, 87, 21, 196, 111, 89, 87, 218, 106, 136, 37, // (.W..oYW.j.%
|
||||||
|
104, 175, 89, 244, 253, 218, 115, 154, 154, 67, 141, 116, // h.Y...s..C.t
|
||||||
|
110, 92, 246, 241, 224, 116, 225, 101, 19, 77, 28, 152, // n....t.e.M..
|
||||||
|
217, 47, 57, 241, 253, 144, 245, 195, 145, 81, 39, 255, // ./9......Q'.
|
||||||
|
118, 20, 29, 203, 189, 176, 93, 38, 50, 50, 90, 183, // v.....]&22Z.
|
||||||
|
146, 161, 220, 202, 27, 235, 155, 45, 229, 25, 121, 103, // .......-..yg
|
||||||
|
240, 200, 204, 9, 114, 96, 27, 131, 73, 47, 58, 19, // ....r`..I/:.
|
||||||
|
189, 24, 108, 106, 232, 68, 254, 220, 26, 180, 138, 76, // ..lj.D.....L
|
||||||
|
9, 38, 204, 156, 91, 21, 27, 101, 42, 175, 77, 248, // .&..[..e*.M.
|
||||||
|
80, 171, 121, 130, 131, 222, 91, 177, 153, 93, 194, 172, // P.y...[..]..
|
||||||
|
145, 146, 77, 153, 89, 108, 2, 30, 115, 227, 156, 229, // ..M.Yl..s...
|
||||||
|
138, 252, 31, 227, 45, 157, 41, 140, 62, 119, 49, 218, // ....-.).>w1.
|
||||||
|
71, 242, 73, 70, 163, 124, 190, 34, 183, 0, 135, 145, // G.IF.|."....
|
||||||
|
90, 205, 206, 102, 103, 6, 214, 28, 185, 62, 117, 33, // Z..fg....>u!
|
||||||
|
70, 165, 197, 68, 179, 43, 133, 19, 141, 86, 100, 214, // F..D.+...Vd.
|
||||||
|
26, 145, 255, 172, 66, 252, 156, 251, 222, 16, 163, 170, // ....B.......
|
||||||
|
156, 230, 29, 66, 134, 206, 71, 163, 243, 73, 219, 2, // ...B..G..I..
|
||||||
|
142, 82, 208, 48, 51, 67, 67, 149, 233, 91, 176, 113, // .R.03CC..[.q
|
||||||
|
41, 239, 132, 239, 245, 219, 98, 110, 147, 97, 159, 98, // ).....bn.a.b
|
||||||
|
234, 28, 117, 51, 94, 125, 37, 228, 217, 104, 116, 54, // ..u3^}%..ht6
|
||||||
|
41, 235, 165, 23, 18, 156, 137, 60, 151, 40, 149, 85, // )......<.(.U
|
||||||
|
88, 105, 200, 158, 45, 177, 34, 135, 109, 48, 122, 39, // Xi..-.".m0z'
|
||||||
|
105, 149, 153, 202, 229, 150, 215, 75, 129, 16, 55, 173, // i......K..7.
|
||||||
|
217, 119, 50, 98, 78, 117, 248, 20, 30, 127, 149, 69, // .w2bNu.....E
|
||||||
|
228, 220, 164, 243, 201, 149, 174, 222, 32, 240, 185, 209, // ........ ...
|
||||||
|
241, 7, 234, 248, 166, 200, 55, 156, 12, 104, 71, 184, // ......7..hG.
|
||||||
|
33, 109, 3, 71, 25, 92, 132, 117, 42, 77, 163, 124, // !m.G...u*M.|
|
||||||
|
26, 145, 183, 116, 192, 66, 222, 40, 187, 57, 248, 132, // ...t.B.(.9..
|
||||||
|
22, 173, 220, 10, 179, 206, 191, 90, 138, 89, 44, 109, // .......Z.Y,m
|
||||||
|
124, 179, 205, 51, 72, 244, 47, 73, 154, 254, 128, 192, // |..3H./I....
|
||||||
|
13, 6, 248, 88, 171, 231, 246, 215, 235, 124, 147, 196, // ...X.....|..
|
||||||
|
237, 8, 80, 200, 248, 142, 71, 250, 69, 123, 128, 252, // ..P...G.E{..
|
||||||
|
251, 117, 45, 161, 8, 55, 79, 44, 239, 189, 142, 52, // .u-..7O,...4
|
||||||
|
198, 88, 200, 191, 232, 52, 210, 49, 8, 141, 83, 230, // .X...4.1..S.
|
||||||
|
112, 149, 235, 188, 78, 227, 51, 55, 232, 167, 109, 204, // p...N.37..m.
|
||||||
|
60, 24, 156, 42, 245, 84, 175, 163, 52, 208, 53, 77, // <..*.T..4.5M
|
||||||
|
192, 65, 160, 98, 137, 190, 17, 247, 143, 132, 202, 200, // .A.b........
|
||||||
|
5, 43, 226, 205, 192, 130, 89, 22, 67, 140, 78, 5, // .+....Y.C.N.
|
||||||
|
163, 186, 161, 195, 226, 129, 218, 94, 115, 249, 218, 148, // .......^s...
|
||||||
|
39, 176, 194, 231, 33, 236, 102, 63, 140, 213, 54, 46, // '...!.f?..6.
|
||||||
|
87, 129, 216, 27, 60, 107, 235, 166, 140, 70, 169, 165, // W...<k...F..
|
||||||
|
187, 104, 237, 238, 81, 226, 185, 237, 30, 109, 238, 237, // .h..Q....m..
|
||||||
|
243, 40, 155, 187, 193, 45, 159, 219, 229, 17, 37, 30, // .(...-....%.
|
||||||
|
195, 122, 108, 242, 40, 122, 61, 84, 174, 227, 52, 179, // .zl.(z=T..4.
|
||||||
|
166, 170, 176, 166, 74, 58, 154, 181, 36, 163, 239, 59, // ....J:..$..;
|
||||||
|
248, 172, 43, 229, 116, 220, 115, 114, 239, 164, 190, 157, // ..+.t.sr....
|
||||||
|
71, 60, 64, 238, 54, 4, 161, 99, 151, 240, 204, 128, // G<@.6..c....
|
||||||
|
145, 35, 12, 205, 179, 17, 190, 124, 212, 239, 145, 122, // .#.....|...z
|
||||||
|
109, 157, 3, 202, 221, 31, 178, 112, 11, 57, 177, 222, // m......p.9..
|
||||||
|
159, 217, 40, 76, 201, 230, 233, 94, 34, 3, 208, 92, // ..(L...^"...
|
||||||
|
40, 179, 8, 196, 93, 43, 23, 234, 173, 141, 100, 42, // (...]+....d*
|
||||||
|
181, 162, 24, 112, 182, 178, 214, 180, 13, 110, 87, 146, // ...p.....nW.
|
||||||
|
194, 253, 195, 8, 248, 66, 204, 46, 252, 249, 197, 226, // .....B......
|
||||||
|
209, 89, 131, 229, 119, 217, 158, 254, 89, 240, 132, 172, // .Y..w...Y...
|
||||||
|
200, 43, 43, 153, 231, 76, 36, 134, 53, 100, 215, 32, // .++..L$.5d.
|
||||||
|
187, 241, 177, 108, 82, 16, 14, 89, 95, 240, 103, 222, // ...lR..Y_.g.
|
||||||
|
67, 145, 181, 162, 44, 124, 83, 185, 245, 172, 100, 247, // C...,|S...d.
|
||||||
|
150, 24, 137, 41, 179, 56, 78, 86, 43, 29, 91, 46, // ...).8NV+.[.
|
||||||
|
119, 254, 129, 153, 128, 215, 235, 69, 134, 226, 3, 85, // w......E...U
|
||||||
|
11, 27, 62, 105, 149, 216, 29, 13, 6, 145, 172, 231, // ..>i........
|
||||||
|
117, 155, 249, 75, 196, 194, 174, 156, 164, 71, 155, 51, // u..K.....G.3
|
||||||
|
184, 239, 2, 188, 161, 38, 113, 79, 189, 17, 37, 48, // .....&qO..%0
|
||||||
|
241, 65, 60, 163, 197, 163, 84, 17, 128, 248, 120, 100, // .A<...T...xd
|
||||||
|
2, 174, 237, 116, 199, 83, 74, 54, 161, 76, 154, 216, // ...t.SJ6.L..
|
||||||
|
237, 160, 157, 159, 109, 195, 190, 159, 180, 185, 245, 250, // ....m.......
|
||||||
|
41, 155, 214, 49, 40, 217, 49, 88, 131, 118, 70, 140, // )..1(.1X.vF.
|
||||||
|
227, 246, 236, 221, 89, 231, 64, 110, 16, 163, 176, 215, // ....Y.@n....
|
||||||
|
125, 67, 46, 183, 218, 113, 222, 106, 112, 226, 84, 180, // }C...q.jp.T.
|
||||||
|
102, 191, 121, 186, 121, 93, 187, 144, 101, 99, 50, 56, // f.y.y]..ec28
|
||||||
|
136, 109, 235, 249, 134, 67, 189, 146, 60, 40, 136, 232, // .m...C..<(..
|
||||||
|
110, 6, 127, 38, 199, 194, 201, 33, 4, 42, 255, 21, // n..&...!.*..
|
||||||
|
194, 226, 9, 165, 115, 249, 108, 23, 216, 129, 42, 37, // ....s.l...*%
|
||||||
|
141, 50, 177, 146, 201, 57, 244, 18, 177, 157, 245, 86, // .2...9.....V
|
||||||
|
59, 231, 155, 196, 121, 196, 57, 245, 73, 4, 232, 74, // ;...y.9.I..J
|
||||||
|
147, 247, 79, 65, 152, 23, 139, 105, 166, 138, 217, 131, // ..OA...i....
|
||||||
|
110, 155, 20, 187, 252, 0, 7, 180, 170, 182, 254, 139, // n...........
|
||||||
|
23, 183, 183, 183, 147, 219, 87, 147, 188, 184, 122, 241, // ......W...z.
|
||||||
|
242, 228, 228, 228, 5, 237, 19, 234, 226, 31, 31, 232, // ............
|
||||||
|
237, 100, 12, 69, 24, 141, 98, 23, 209, 201, 136, 100, // .d.E..b....d
|
||||||
|
181, 191, 176, 53, 126, 99, 196, 69, 196, 107, 168, 95, // ...5~c.E.k._
|
||||||
|
104, 170, 158, 173, 196, 221, 65, 84, 147, 92, 91, 78, // h.....AT..[N
|
||||||
|
102, 70, 231, 104, 233, 37, 116, 64, 121, 45, 83, 154, // fF.h.%t@y-S.
|
||||||
|
38, 21, 147, 39, 188, 113, 56, 8, 241, 147, 125, 131, // &..'.q8...}.
|
||||||
|
168, 37, 152, 227, 211, 154, 174, 114, 136, 163, 155, 215, // .%.....r....
|
||||||
|
217, 36, 116, 46, 107, 217, 103, 221, 122, 222, 239, 1, // .$t.k.g.z...
|
||||||
|
47, 38, 25, 184, 69, 119, 10, 135, 173, 236, 112, 77, // /&..Ew....pM
|
||||||
|
61, 216, 166, 144, 120, 188, 37, 85, 30, 141, 182, 36, // =...x.%U...$
|
||||||
|
179, 213, 198, 250, 39, 84, 106, 154, 174, 13, 72, 18, // ....'Tj...H.
|
||||||
|
183, 60, 193, 36, 105, 171, 106, 219, 13, 134, 7, 142, // .<.$i.j.....
|
||||||
|
8, 137, 104, 218, 79, 190, 30, 134, 145, 180, 155, 194, // ..h.O.......
|
||||||
|
94, 222, 56, 107, 69, 242, 137, 88, 220, 94, 230, 112, // ^.8kE..X.^.p
|
||||||
|
88, 206, 55, 38, 77, 67, 113, 168, 185, 242, 64, 252, // X.7&MCq...@.
|
||||||
|
86, 44, 160, 159, 29, 130, 76, 228, 20, 118, 56, 111, // V,....L..v8o
|
||||||
|
180, 13, 109, 51, 0, 2, 217, 211, 200, 135, 76, 2, // ..m3......L.
|
||||||
|
87, 137, 214, 58, 186, 214, 177, 173, 210, 44, 28, 55, // W..:.....,.7
|
||||||
|
16, 14, 59, 59, 77, 108, 103, 223, 67, 29, 99, 185, // ..;;Mlg.C.c.
|
||||||
|
70, 43, 172, 230, 86, 184, 100, 104, 27, 29, 109, 156, // F+..V.dh..m.
|
||||||
|
30, 182, 150, 24, 118, 56, 147, 143, 50, 145, 27, 31, // ....v8..2...
|
||||||
|
172, 112, 138, 109, 130, 39, 157, 92, 101, 63, 46, 127, // .p.m.'..e?..
|
||||||
|
215, 17, 71, 84, 59, 214, 246, 122, 86, 35, 152, 241, // ..GT;..zV#..
|
||||||
|
43, 147, 9, 163, 60, 16, 244, 55, 58, 84, 225, 141, // +...<..7:T..
|
||||||
|
234, 52, 184, 203, 62, 145, 50, 146, 161, 100, 85, 158, // .4..>.2..dU.
|
||||||
|
194, 44, 122, 118, 215, 32, 92, 12, 84, 46, 108, 192, // .,zv. ..T.l.
|
||||||
|
240, 216, 136, 4, 9, 195, 134, 147, 44, 92, 5, 101, // ........,..e
|
||||||
|
176, 145, 171, 66, 151, 165, 53, 31, 131, 13, 64, 46, // ...B..5...@.
|
||||||
|
176, 27, 139, 9, 49, 201, 218, 192, 74, 242, 79, 90, // ....1...J.OZ
|
||||||
|
66, 30, 155, 193, 246, 81, 234, 146, 167, 176, 117, 139, // B....Q....u.
|
||||||
|
207, 141, 100, 140, 182, 66, 56, 197, 254, 113, 162, 232, // ..d..B8..q..
|
||||||
|
163, 181, 211, 108, 113, 143, 93, 175, 204, 180, 199, 225, // ...lq.].....
|
||||||
|
93, 84, 23, 148, 216, 81, 193, 99, 59, 123, 96, 229, // ]T...Q.c;{`.
|
||||||
|
127, 114, 8, 237, 45, 35, 223, 188, 76, 234, 108, 99, // .r..-#..L.lc
|
||||||
|
156, 211, 182, 8, 4, 146, 83, 97, 38, 59, 234, 229, // ......Sa&;..
|
||||||
|
110, 6, 132, 54, 174, 72, 25, 36, 154, 163, 105, 62, // n..6.H.$..i>
|
||||||
|
82, 10, 140, 197, 182, 77, 129, 218, 60, 90, 100, 18, // R....M..<Zd.
|
||||||
|
199, 249, 3, 79, 202, 76, 194, 49, 241, 241, 46, 239, // ...O.L.1....
|
||||||
|
216, 129, 33, 246, 185, 57, 186, 115, 118, 113, 56, 201, // ..!..9.svq8.
|
||||||
|
75, 200, 77, 198, 142, 229, 163, 128, 213, 40, 94, 231, // K.M......(^.
|
||||||
|
78, 70, 10, 152, 138, 28, 194, 60, 26, 253, 228, 229, // NF.....<....
|
||||||
|
44, 217, 242, 136, 14, 153, 216, 21, 81, 159, 243, 96, // ,.......Q..`
|
||||||
|
236, 182, 86, 230, 206, 73, 200, 238, 166, 200, 165, 224, // ..V..I......
|
||||||
|
58, 138, 126, 229, 114, 84, 150, 123, 238, 194, 206, 197, // :.~.rT.{....
|
||||||
|
90, 102, 225, 45, 248, 15, 94, 223, 64, 144, 220, 79, // Zf.-..^.@..O
|
||||||
|
105, 127, 230, 196, 165, 62, 178, 216, 216, 198, 177, 124, // i....>.....|
|
||||||
|
163, 48, 87, 7, 57, 241, 128, 239, 43, 140, 99, 193, // .0W.9...+.c.
|
||||||
|
151, 222, 239, 160, 46, 129, 242, 6, 208, 175, 28, 29, // ............
|
||||||
|
130, 117, 53, 244, 214, 134, 47, 243, 0, 17, 89, 77, // .u5.../...YM
|
||||||
|
121, 240, 180, 187, 132, 169, 30, 93, 194, 240, 232, 217, // y......]....
|
||||||
|
60, 95, 248, 181, 153, 170, 154, 172, 146, 162, 52, 190, // <_........4.
|
||||||
|
158, 187, 30, 174, 250, 103, 128, 185, 167, 73, 236, 200, // .....g...I..
|
||||||
|
28, 227, 106, 162, 213, 193, 64, 74, 252, 189, 241, 146, // ..j...@J....
|
||||||
|
3, 50, 124, 99, 46, 170, 248, 2, 82, 221, 243, 229, // .2|c....R...
|
||||||
|
171, 26, 226, 115, 54, 28, 215, 227, 49, 221, 215, 106, // ...s6...1..j
|
||||||
|
9, 231, 178, 196, 225, 86, 248, 79, 92, 110, 57, 163, // .....V.O.n9.
|
||||||
|
227, 101, 98, 47, 17, 204, 220, 36, 241, 1, 176, 69, // .eb/...$...E
|
||||||
|
47, 171, 105, 159, 53, 15, 92, 87, 216, 10, 119, 129, // /.i.5..W..w.
|
||||||
|
133, 240, 150, 242, 51, 4, 37, 143, 129, 170, 158, 31, // ....3.%.....
|
||||||
|
239, 48, 238, 13, 228, 209, 136, 72, 245, 151, 210, 93, // .0.....H...]
|
||||||
|
234, 26, 43, 194, 202, 195, 37, 114, 26, 217, 115, 66, // ..+...%r..sB
|
||||||
|
8, 96, 177, 213, 203, 131, 177, 129, 187, 91, 156, 186, // .`.......[..
|
||||||
|
71, 5, 199, 84, 102, 122, 188, 185, 191, 106, 76, 180, // G..Tfz...jL.
|
||||||
|
229, 252, 92, 208, 187, 17, 150, 48, 103, 252, 50, 129, // .......0g.2.
|
||||||
|
185, 75, 215, 157, 36, 240, 237, 237, 116, 123, 197, 29, // .K..$...t{..
|
||||||
|
76, 28, 141, 57, 186, 154, 56, 246, 244, 51, 31, 176, // L..9..8..3..
|
||||||
|
63, 112, 65, 77, 18, 80, 102, 196, 88, 253, 128, 123, // ?pAM.Pf.X..{
|
||||||
|
237, 181, 51, 105, 193, 52, 227, 88, 102, 202, 158, 88, // ..3i.4.Xf..X
|
||||||
|
192, 229, 136, 46, 80, 233, 164, 97, 227, 64, 237, 213, // ....P..a.@..
|
||||||
|
131, 108, 143, 139, 82, 171, 99, 161, 241, 121, 81, 228, // .l..R.c..yQ.
|
||||||
|
5, 59, 195, 37, 162, 12, 106, 245, 158, 134, 195, 102, // .;.%..j....f
|
||||||
|
133, 204, 205, 253, 131, 179, 91, 193, 65, 128, 118, 70, // ......[.A.vF
|
||||||
|
54, 136, 209, 61, 106, 37, 202, 181, 99, 243, 254, 117, // 6..=j%..c..u
|
||||||
|
248, 121, 107, 133, 177, 95, 173, 178, 125, 181, 46, 242, // .yk.._..}...
|
||||||
|
91, 4, 155, 123, 104, 232, 9, 60, 179, 46, 135, 227, // [..{h..<....
|
||||||
|
22, 169, 14, 137, 100, 238, 229, 3, 27, 9, 177, 76, // ....d......L
|
||||||
|
112, 26, 197, 149, 72, 121, 89, 80, 104, 236, 204, 181, // p...HyYPh...
|
||||||
|
250, 174, 96, 146, 36, 29, 196, 209, 235, 39, 142, 147, // ..`.$....'..
|
||||||
|
149, 54, 65, 29, 226, 200, 78, 64, 65, 20, 116, 150, // .6A...N@A.t.
|
||||||
|
198, 251, 183, 215, 240, 237, 220, 20, 166, 103, 109, 205, // .........gm.
|
||||||
|
6, 184, 153, 144, 27, 143, 154, 112, 136, 29, 236, 15, // .......p....
|
||||||
|
220, 142, 244, 83, 218, 96, 144, 217, 162, 166, 236, 145, // ...S.`......
|
||||||
|
126, 136, 88, 63, 133, 216, 38, 175, 214, 230, 54, 59, // ~.X?..&...6;
|
||||||
|
63, 102, 46, 33, 173, 155, 164, 212, 51, 251, 237, 13, // ?f.!....3...
|
||||||
|
174, 214, 58, 155, 44, 161, 1, 158, 235, 195, 193, 159, // ..:.,.......
|
||||||
|
167, 55, 26, 113, 172, 15, 150, 124, 76, 54, 58, 175, // .7.q...|L6:.
|
||||||
|
43, 105, 110, 219, 79, 96, 144, 79, 88, 243, 222, 202, // +in.O`.OX...
|
||||||
|
75, 249, 139, 124, 143, 150, 239, 104, 214, 31, 77, 206, // K..|...h..M.
|
||||||
|
80, 254, 108, 2, 114, 249, 71, 27, 181, 201, 175, 141, // P.l.r.G.....
|
||||||
|
44, 203, 79, 84, 123, 162, 118, 15, 138, 126, 239, 34, // ,.OT{.v..~."
|
||||||
|
173, 181, 177, 251, 107, 239, 82, 106, 249, 30, 14, 153, // ....k.Rj....
|
||||||
|
32, 244, 60, 89, 165, 46, 209, 115, 1, 251, 196, 95, // .<Y...s..._
|
||||||
|
210, 37, 31, 147, 210, 243, 148, 249, 98, 223, 222, 42, // .%......b..*
|
||||||
|
233, 47, 57, 164, 108, 195, 86, 174, 48, 237, 40, 91, // ./9.l.V.0.([
|
||||||
|
71, 181, 185, 94, 116, 118, 247, 219, 222, 19, 148, 247, // G..^tv......
|
||||||
|
234, 84, 254, 233, 37, 90, 246, 179, 179, 127, 30, 220, // .T..%Z......
|
||||||
|
149, 169, 223, 189, 183, 48, 199, 47, 219, 233, 170, 73, // .....0./...I
|
||||||
|
69, 143, 82, 38, 124, 229, 201, 209, 171, 154, 7, 179, // E.R&|.......
|
||||||
|
0, 18, 224, 39, 218, 230, 103, 33, 193, 242, 209, 195, // ...'..g!....
|
||||||
|
2, 172, 178, 98, 120, 184, 120, 146, 206, 90, 83, 52, // ...bx.x..ZS4
|
||||||
|
41, 114, 139, 40, 51, 235, 61, 93, 44, 204, 12, 157, // )r.(3.=],...
|
||||||
|
14, 99, 47, 98, 111, 91, 213, 165, 217, 87, 183, 230, // .c/bo[...W..
|
||||||
|
191, 25, 130, 246, 87, 252, 74, 76, 7, 153, 81, 154, // ....W.JL..Q.
|
||||||
|
84, 51, 250, 11, 73, 175, 74, 204, 76, 102, 7, 23, // T3..I.J.Lf..
|
||||||
|
42, 144, 76, 219, 78, 222, 42, 209, 35, 197, 247, 143, // *.L.N.*.#...
|
||||||
|
209, 126, 246, 127, 64, 123, 12, 229, 223, 15, 200, 255, // .~..@{......
|
||||||
|
185, 252, 213, 123, 116, 166, 220, 91, 239, 202, 39, 123, // ...{t..[..'{
|
||||||
|
49, 239, 95, 99, 254, 195, 177, 230, 189, 250, 66, 126, // 1._c......B~
|
||||||
|
223, 31, 249, 132, 103, 152, 145, 60, 155, 124, 152, 243, // ....g..<.|..
|
||||||
|
15, 169, 105, 47, 221, 21, 68, 224, 179, 105, 133, 177, // ..i/..D..i..
|
||||||
|
34, 83, 216, 205, 244, 107, 255, 116, 54, 59, 255, 175, // "S...k.t6;..
|
||||||
|
86, 4, 82, 205, 169, 134, 11, 64, 216, 172, 3, 172, // V.R....@....
|
||||||
|
136, 224, 112, 254, 66, 101, 54, 31, 160, 77, 67, 135, // ..p.Be6..MC.
|
||||||
|
242, 159, 7, 135, 247, 123, 245, 223, 199, 246, 14, 27, // .....{......
|
||||||
|
9, 160, 110, 144, 214, 157, 252, 92, 186, 115, 102, 206, // ..n......sf.
|
||||||
|
126, 37, 52, 193, 174, 236, 127, 68, 119, 66, 69, 116, // ~%4....DwBEt
|
||||||
|
87, 235, 46, 223, 3, 246, 171, 204, 10, 97, 92, 50, // W........a.2
|
||||||
|
78, 113, 95, 146, 135, 218, 63, 136, 201, 123, 238, 47, // Nq_...?..{./
|
||||||
|
52, 211, 78, 61, 235, 82, 191, 209, 203, 250, 234, 103, // 4.N=.R.....g
|
||||||
|
115, 74, 63, 104, 240, 72, 236, 31, 92, 109, 4, 189, // sJ?h.H...m..
|
||||||
|
245, 154, 197, 157, 34, 132, 9, 212, 183, 94, 119, 11, // ...."....^w.
|
||||||
|
108, 4, 229, 242, 241, 129, 194, 154, 254, 168, 245, 192, // l...........
|
||||||
|
108, 246, 60, 69, 34, 48, 52, 133, 206, 107, 1, 247, // l.<E"04..k..
|
||||||
|
142, 180, 170, 127, 208, 83, 151, 209, 70, 232, 77, 183, // .....S..F.M.
|
||||||
|
64, 168, 146, 184, 255, 238, 104, 222, 52, 49, 222, 238, // @.....h.41..
|
||||||
|
59, 115, 81, 213, 170, 133, 3, 45, 172, 27, 124, 216, // ;sQ....-..|.
|
||||||
|
90, 247, 91, 97, 19, 237, 185, 23, 136, 251, 126, 171, // Z.[a......~.
|
||||||
|
77, 57, 153, 247, 104, 156, 242, 97, 3, 186, 103, 243, // M9..h..a..g.
|
||||||
|
121, 176, 193, 75, 147, 172, 248, 113, 52, 250, 145, 118, // y..K...q4..v
|
||||||
|
198, 3, 139, 3, 136, 159, 71, 163, 159, 105, 243, 111, // ......G..i.o
|
||||||
|
173, 153, 204, 148, 119, 105, 35, 13, 154, 145, 222, 88, // ....wi#....X
|
||||||
|
122, 217, 163, 149, 103, 143, 86, 157, 217, 181, 241, 36, // z...g.V....$
|
||||||
|
198, 106, 31, 204, 243, 199, 104, 244, 135, 243, 184, 204, // .j....h.....
|
||||||
|
19, 178, 104, 26, 152, 252, 222, 133, 253, 28, 164, 11, // ..h.........
|
||||||
|
61, 186, 149, 251, 206, 168, 60, 89, 132, 95, 56, 143, // =.....<Y._8.
|
||||||
|
80, 232, 63, 106, 93, 86, 95, 101, 201, 38, 36, 204, // P.?j]V_e.&$.
|
||||||
|
223, 20, 225, 134, 210, 160, 222, 47, 79, 117, 10, 132, // ......./Ou..
|
||||||
|
29, 143, 31, 101, 245, 157, 184, 40, 213, 97, 97, 143, // ...e...(.aa.
|
||||||
|
40, 88, 23, 153, 67, 54, 163, 48, 139, 116, 122, 136, // (X..C6.0.tz.
|
||||||
|
137, 78, 229, 238, 48, 99, 114, 86, 170, 215, 16, 64, // .N..0crV...@
|
||||||
|
56, 79, 196, 148, 134, 123, 153, 58, 186, 24, 236, 4, // 8O...{.:....
|
||||||
|
226, 229, 85, 228, 39, 93, 186, 200, 135, 73, 23, 245, // ..U.']...I..
|
||||||
|
61, 150, 128, 61, 203, 135, 201, 63, 39, 71, 143, 101, // =..=...?'G.e
|
||||||
|
104, 173, 108, 123, 146, 86, 186, 56, 24, 100, 180, 132, // h.l{.V.8.d..
|
||||||
|
31, 216, 53, 77, 173, 89, 188, 173, 80, 85, 71, 103, // ..5M.Y..PUGg
|
||||||
|
209, 230, 20, 245, 116, 203, 79, 82, 184, 86, 230, 170, // ....t.OR.V..
|
||||||
|
158, 204, 125, 61, 26, 125, 109, 162, 49, 217, 158, 202, // ..}=.}m.1...
|
||||||
|
7, 60, 255, 100, 52, 250, 228, 33, 207, 233, 210, 221, // .<.d4..!....
|
||||||
|
242, 155, 53, 195, 113, 190, 191, 169, 167, 115, 155, 140, // ..5.q....s..
|
||||||
|
42, 215, 199, 220, 147, 163, 4, 239, 156, 132, 162, 111, // *..........o
|
||||||
|
250, 166, 71, 95, 86, 114, 162, 150, 63, 30, 177, 167, // ..G_Vr..?...
|
||||||
|
151, 54, 168, 15, 6, 51, 8, 111, 231, 33, 92, 170, // .6...3.o.!..
|
||||||
|
251, 86, 121, 160, 233, 94, 222, 8, 52, 231, 45, 76, // .Vy..^..4.-L
|
||||||
|
17, 65, 241, 3, 178, 247, 195, 93, 122, 65, 64, 111, // .A.....]zA@o
|
||||||
|
161, 251, 105, 220, 228, 0, 237, 177, 231, 195, 179, 140, // ..i.........
|
||||||
|
31, 132, 238, 105, 137, 209, 161, 247, 219, 75, 79, 76, // ...i.....KOL
|
||||||
|
233, 114, 27, 122, 238, 98, 134, 66, 157, 34, 184, 207, // .r.z.b.B."..
|
||||||
|
250, 193, 189, 121, 59, 67, 25, 172, 241, 120, 33, 83, // ...y;C...x!S
|
||||||
|
78, 101, 193, 254, 99, 92, 163, 234, 217, 169, 255, 146, // Ne..c.......
|
||||||
|
94, 66, 112, 231, 2, 243, 205, 199, 227, 98, 49, 125, // ^Bp......b1}
|
||||||
|
165, 232, 209, 73, 69, 184, 83, 255, 51, 91, 57, 93, // ...IE.S.3[9]
|
||||||
|
40, 147, 143, 154, 132, 101, 153, 92, 101, 30, 53, 53, // (....e..e.55
|
||||||
|
13, 124, 227, 84, 248, 159, 51, 16, 55, 41, 215, 142, // .|.T..3.7)..
|
||||||
|
88, 145, 209, 17, 146, 47, 90, 36, 174, 113, 172, 210, // X..../Z$.q..
|
||||||
|
241, 112, 136, 112, 152, 179, 19, 225, 118, 155, 238, 188, // .p.p....v...
|
||||||
|
84, 70, 68, 24, 122, 214, 56, 31, 14, 249, 16, 94, // TFD.z.8....^
|
||||||
|
8, 242, 101, 216, 104, 228, 66, 166, 244, 190, 197, 172, // ..e.h.B.....
|
||||||
|
253, 165, 143, 77, 20, 207, 95, 98, 251, 156, 146, 83, // ...M.._b...S
|
||||||
|
57, 142, 114, 11, 153, 182, 153, 34, 132, 159, 244, 14, // 9.r...."....
|
||||||
|
86, 223, 62, 251, 33, 220, 202, 213, 161, 143, 109, 216, // V.>.!.....m.
|
||||||
|
15, 231, 22, 225, 143, 241, 161, 219, 51, 136, 146, 154, // ........3...
|
||||||
|
237, 176, 146, 195, 16, 134, 160, 231, 74, 18, 93, 88, // ........J.]X
|
||||||
|
167, 169, 242, 88, 109, 146, 160, 4, 68, 65, 93, 127, // ...Xm...DA].
|
||||||
|
14, 199, 25, 230, 26, 220, 73, 56, 226, 67, 89, 208, // ......I8.CY.
|
||||||
|
79, 173, 232, 72, 74, 15, 160, 233, 246, 144, 159, 193, // O..HJ.......
|
||||||
|
0, 95, 174, 242, 238, 237, 197, 191, 126, 43, 255, 243, // ._......~+..
|
||||||
|
183, 12, 63, 141, 43, 124, 242, 226, 138, 31, 160, 136, // ..?.+|......
|
||||||
|
89, 109, 54, 141, 224, 0, 81, 22, 229, 226, 29, 138, // Ym6...Q.....
|
||||||
|
92, 204, 60, 219, 249, 138, 59, 177, 130, 151, 194, 127, // ..<...;.....
|
||||||
|
105, 32, 134, 147, 201, 132, 82, 121, 57, 84, 196, 225, // i ....Ry9T..
|
||||||
|
248, 12, 96, 39, 45, 4, 122, 6, 109, 215, 231, 242, // ..`'-.z.m...
|
||||||
|
68, 194, 71, 192, 12, 213, 151, 234, 115, 122, 159, 155, // D.G.....sz..
|
||||||
|
55, 205, 0, 166, 145, 88, 95, 145, 163, 99, 1, 43, // 7....X_..c.+
|
||||||
|
0, 230, 28, 47, 169, 47, 56, 78, 234, 58, 128, 220, // ..././8N.:..
|
||||||
|
117, 8, 166, 196, 158, 159, 78, 37, 175, 117, 247, 78, // u.....N%.u.N
|
||||||
|
138, 222, 54, 210, 97, 97, 150, 144, 66, 33, 83, 47, // ..6.aa..B!S/
|
||||||
|
17, 162, 21, 241, 8, 3, 162, 215, 122, 158, 44, 220, // ........z.,.
|
||||||
|
152, 8, 99, 16, 242, 163, 101, 14, 167, 135, 7, 206, // ..c...e.....
|
||||||
|
134, 175, 249, 185, 199, 204, 35, 4, 160, 116, 13, 215, // ......#..t..
|
||||||
|
88, 189, 18, 126, 62, 86, 25, 75, 52, 64, 158, 63, // X..~>V.K4@.?
|
||||||
|
183, 219, 31, 126, 105, 129, 29, 131, 0, 167, 178, 113, // ...~i......q
|
||||||
|
78, 185, 214, 98, 150, 81, 38, 120, 70, 44, 51, 163, // N..b.Q&xF,3.
|
||||||
|
63, 29, 126, 106, 238, 65, 134, 159, 154, 97, 5, 26, // ?.~j.A...a..
|
||||||
|
91, 20, 52, 31, 208, 128, 74, 244, 216, 79, 181, 136, // [.4...J..O..
|
||||||
|
63, 135, 205, 205, 45, 242, 225, 11, 110, 38, 167, 248, // ?...-...n&..
|
||||||
|
245, 231, 192, 195, 99, 205, 250, 199, 244, 62, 133, 145, // ....c....>..
|
||||||
|
56, 62, 214, 138, 114, 190, 132, 180, 150, 174, 98, 232, // 8>..r.....b.
|
||||||
|
249, 18, 212, 172, 168, 3, 28, 27, 62, 27, 218, 69, // ........>..E
|
||||||
|
253, 86, 181, 165, 172, 45, 21, 7, 171, 123, 105, 232, // .V...-...{i.
|
||||||
|
208, 206, 49, 28, 180, 164, 192, 74, 63, 147, 118, 22, // ..1....J?.v.
|
||||||
|
167, 67, 76, 194, 61, 167, 2, 48, 166, 251, 191, 15, // .CL.=..0....
|
||||||
|
56, 74, 132, 251, 175, 17, 167, 179, 204, 39, 189, 220, // 8J.......'..
|
||||||
|
155, 168, 49, 20, 83, 125, 183, 205, 139, 234, 62, 124, // ..1.S}....>|
|
||||||
|
22, 150, 207, 214, 208, 60, 254, 86, 155, 84, 254, 64, // .....<.V.T.@
|
||||||
|
37, 19, 157, 202, 152, 202, 109, 82, 72, 126, 67, 85, // %.....mRH~CU
|
||||||
|
115, 79, 99, 51, 74, 242, 91, 106, 130, 91, 201, 81, // sOc3J.[j.[.Q
|
||||||
|
142, 252, 211, 214, 222, 235, 184, 142, 48, 254, 111, 182, // ........0.o.
|
||||||
|
126, 14, 239, 36, 170, 228, 247, 182, 250, 54, 220, 225, // ~..$.....6..
|
||||||
|
252, 182, 141, 127, 111, 199, 172, 228, 63, 108, 249, 187, // ....o...?l..
|
||||||
|
205, 86, 23, 56, 84, 110, 244, 69, 152, 197, 169, 150, // .V.8Tn.E....
|
||||||
|
191, 218, 142, 31, 244, 38, 151, 255, 180, 149, 179, 48, // .....&.....0
|
||||||
|
77, 151, 97, 116, 45, 181, 118, 45, 118, 85, 153, 107, // M.at-.v-vU.k
|
||||||
|
232, 188, 93, 25, 184, 54, 206, 156, 124, 141, 179, 51, // ..]..6..|..3
|
||||||
|
14, 139, 221, 126, 250, 31, 255, 11, 22, 19, 178, 116, // ...~.......t
|
||||||
|
138, 51, 0, 0, 0 // .3..
|
||||||
};
|
};
|
||||||
static const unsigned char v2[] = {
|
static const unsigned char v2[] = {
|
||||||
|
31, 139, 8, 8, 219, 27, 244, 98, 0, 3, 109, 97, // .......b..ma
|
||||||
|
105, 110, 46, 106, 115, 0, 165, 86, 237, 110, 219, 54, // in.js..V.n.6
|
||||||
|
20, 253, 239, 167, 184, 8, 6, 52, 65, 109, 41, 77, // .......4Am)M
|
||||||
|
246, 1, 52, 138, 1, 55, 93, 129, 20, 93, 61, 204, // ..4..7]..]=.
|
||||||
|
233, 218, 254, 43, 37, 210, 22, 91, 138, 84, 249, 97, // ...+%..[.T.a
|
||||||
|
205, 11, 242, 46, 125, 150, 62, 217, 14, 37, 217, 177, // ....}.>..%..
|
||||||
|
19, 103, 195, 218, 95, 166, 36, 222, 123, 15, 207, 185, // .g.._.$.{...
|
||||||
|
247, 208, 143, 130, 19, 228, 188, 149, 133, 127, 116, 54, // ..........t6
|
||||||
|
144, 85, 109, 172, 167, 107, 42, 135, 84, 250, 74, 13, // .Um..k*.T.J.
|
||||||
|
201, 10, 205, 133, 165, 27, 154, 91, 83, 209, 163, 36, // .......[S..$
|
||||||
|
173, 173, 96, 133, 79, 42, 169, 147, 143, 14, 33, 131, // ..`.O*....!.
|
||||||
|
65, 97, 180, 243, 244, 142, 206, 105, 30, 116, 225, 165, // Aa.....i.t..
|
||||||
|
209, 116, 120, 68, 215, 131, 1, 33, 218, 7, 171, 219, // .txD...!....
|
||||||
|
84, 31, 240, 152, 113, 185, 164, 66, 49, 231, 206, 15, // T...q..B1...
|
||||||
|
16, 229, 153, 212, 194, 30, 140, 241, 5, 223, 202, 147, // ............
|
||||||
|
245, 39, 39, 218, 44, 7, 227, 201, 179, 233, 155, 43, // .''.,......+
|
||||||
|
122, 51, 203, 210, 242, 164, 223, 181, 149, 193, 154, 166, // z3..........
|
||||||
|
143, 189, 155, 89, 141, 126, 217, 124, 193, 183, 122, 220, // ...Y.~.|..z.
|
||||||
|
45, 54, 111, 136, 46, 132, 99, 168, 79, 51, 51, 247, // -6o...c.O33.
|
||||||
|
13, 179, 130, 94, 121, 158, 144, 116, 84, 10, 198, 63, // ...^y..tT..?
|
||||||
|
7, 102, 189, 176, 130, 127, 253, 34, 53, 61, 15, 185, // .f....."5=..
|
||||||
|
146, 122, 72, 127, 136, 58, 174, 10, 50, 115, 186, 180, // .zH..:..2s..
|
||||||
|
66, 49, 205, 147, 219, 26, 105, 189, 83, 112, 231, 121, // B1....i.Sp.y
|
||||||
|
26, 44, 40, 54, 118, 69, 214, 24, 239, 40, 103, 197, // .,(6vE...(g.
|
||||||
|
39, 242, 134, 78, 142, 143, 127, 28, 82, 83, 10, 77, // '..N....RS.M
|
||||||
|
191, 25, 189, 48, 6, 82, 188, 21, 57, 205, 132, 93, // ...0.R..9..]
|
||||||
|
130, 243, 87, 50, 183, 204, 174, 190, 126, 225, 98, 41, // ..W2....~.b)
|
||||||
|
148, 169, 43, 161, 61, 242, 68, 108, 192, 154, 229, 118, // ..+.=.Dl...v
|
||||||
|
60, 216, 148, 152, 184, 189, 41, 22, 86, 52, 132, 51, // <.....).V4.3
|
||||||
|
212, 166, 14, 138, 89, 233, 87, 4, 216, 84, 49, 200, // ....Y.W..T1.
|
||||||
|
34, 56, 153, 184, 199, 151, 130, 230, 70, 41, 211, 72, // "8......F).H
|
||||||
|
189, 160, 149, 96, 214, 13, 99, 204, 201, 241, 147, 211, // ...`..c.....
|
||||||
|
13, 79, 13, 115, 36, 80, 27, 4, 184, 18, 145, 64, // .O.s$P.....@
|
||||||
|
31, 5, 148, 58, 8, 146, 56, 210, 54, 196, 88, 97, // ...:..8.6.Xa
|
||||||
|
3, 172, 182, 102, 41, 57, 90, 44, 212, 109, 107, 33, // ...f)9Z,.mk!
|
||||||
|
208, 128, 142, 37, 83, 1, 105, 138, 0, 94, 42, 97, // ...%S.i..^*a
|
||||||
|
221, 195, 76, 190, 21, 20, 245, 65, 158, 208, 150, 45, // ..L....A...-
|
||||||
|
217, 18, 111, 42, 28, 182, 77, 180, 201, 128, 67, 233, // ..o*..M...C.
|
||||||
|
21, 101, 114, 252, 2, 101, 130, 22, 244, 211, 241, 113, // .er..e.....q
|
||||||
|
150, 202, 49, 112, 86, 53, 211, 82, 56, 194, 25, 26, // ..1pV5.R8...
|
||||||
|
161, 84, 252, 173, 4, 151, 161, 106, 161, 186, 138, 225, // .T.....j....
|
||||||
|
157, 147, 127, 11, 202, 131, 67, 71, 58, 39, 182, 240, // ......CG:'..
|
||||||
|
16, 184, 44, 194, 134, 58, 244, 134, 138, 107, 52, 65, // ..,..:...k4A
|
||||||
|
44, 239, 140, 10, 177, 87, 93, 236, 29, 70, 53, 179, // ,....W]..F5.
|
||||||
|
128, 22, 64, 194, 220, 88, 10, 174, 13, 105, 9, 198, // ..@..X...i..
|
||||||
|
204, 96, 193, 252, 94, 153, 16, 139, 49, 228, 148, 175, // .`..^...1...
|
||||||
|
232, 245, 100, 54, 33, 150, 27, 102, 187, 192, 75, 141, // ..d6!..f..K.
|
||||||
|
78, 212, 44, 214, 96, 138, 102, 53, 43, 4, 205, 124, // N.,.`.f5+..|
|
||||||
|
251, 28, 195, 182, 96, 198, 221, 57, 52, 138, 194, 204, // ....`..94...
|
||||||
|
165, 173, 186, 61, 96, 76, 250, 100, 135, 212, 150, 214, // ...=`L.d....
|
||||||
|
153, 212, 200, 20, 53, 30, 110, 68, 46, 163, 200, 127, // ....5.nD....
|
||||||
|
129, 44, 14, 44, 81, 85, 144, 206, 3, 128, 71, 229, // .,.,QU....G.
|
||||||
|
208, 34, 210, 36, 64, 189, 214, 186, 61, 27, 151, 209, // .".$@...=...
|
||||||
|
59, 242, 224, 5, 137, 42, 23, 60, 70, 186, 245, 76, // ;....*.<F..L
|
||||||
|
197, 13, 37, 14, 210, 62, 52, 210, 151, 96, 5, 122, // ..%..>4..`.z
|
||||||
|
17, 96, 1, 163, 198, 148, 99, 119, 95, 227, 150, 170, // .`....cw_...
|
||||||
|
238, 196, 194, 71, 138, 175, 74, 244, 164, 235, 224, 175, // ...G..J.....
|
||||||
|
39, 61, 197, 168, 247, 102, 176, 94, 246, 139, 15, 103, // '=...f.^...g
|
||||||
|
131, 155, 179, 181, 31, 189, 255, 110, 63, 58, 189, 239, // .......n?:..
|
||||||
|
71, 155, 182, 187, 69, 109, 197, 83, 216, 211, 233, 55, // G...Em.S...7
|
||||||
|
219, 83, 22, 212, 150, 52, 153, 146, 219, 66, 81, 6, // .S...4...BQ.
|
||||||
|
85, 172, 152, 159, 31, 148, 222, 215, 238, 105, 154, 86, // U........i.V
|
||||||
|
125, 251, 36, 141, 75, 15, 198, 123, 154, 41, 75, 217, // }.$.K..{.)K.
|
||||||
|
78, 134, 17, 136, 189, 213, 166, 193, 62, 215, 53, 93, // N.......>.5]
|
||||||
|
228, 27, 52, 55, 198, 126, 138, 131, 175, 58, 183, 217, // ..47.~...:..
|
||||||
|
130, 146, 238, 96, 249, 79, 100, 75, 48, 152, 72, 3, // ...`.OdK0.H.
|
||||||
|
84, 127, 94, 76, 95, 99, 117, 31, 201, 196, 242, 32, // T.^L_cu....
|
||||||
|
181, 25, 181, 35, 233, 101, 174, 208, 177, 177, 211, 93, // ...#.e.....]
|
||||||
|
215, 29, 121, 144, 202, 143, 96, 61, 177, 125, 219, 166, // ..y...`=.}..
|
||||||
|
153, 94, 77, 40, 212, 156, 121, 225, 182, 51, 117, 30, // .^M(..y..3u.
|
||||||
|
166, 217, 66, 180, 134, 195, 153, 43, 219, 60, 223, 14, // ..B....+.<..
|
||||||
|
190, 138, 57, 18, 208, 1, 248, 213, 243, 126, 189, 151, // ..9......~..
|
||||||
|
74, 152, 5, 32, 142, 12, 28, 230, 210, 92, 209, 239, // J.. ........
|
||||||
|
138, 97, 52, 108, 245, 29, 165, 123, 13, 71, 198, 37, // .a4l...{.G.%
|
||||||
|
32, 102, 75, 212, 233, 108, 47, 2, 83, 11, 11, 246, // fK..l/.S...
|
||||||
|
160, 153, 91, 57, 47, 170, 214, 107, 96, 223, 163, 218, // ..[9/..k`...
|
||||||
|
52, 208, 181, 146, 133, 53, 177, 155, 45, 76, 29, 198, // 4....5..-L..
|
||||||
|
120, 23, 217, 255, 128, 182, 128, 42, 33, 143, 168, 210, // x......*!...
|
||||||
|
162, 243, 136, 180, 250, 232, 192, 208, 203, 253, 200, 54, // ...........6
|
||||||
|
109, 246, 146, 45, 217, 172, 176, 178, 246, 36, 244, 2, // m..-.....$..
|
||||||
|
83, 213, 98, 188, 72, 47, 30, 63, 126, 128, 168, 44, // S.b.H/.?~..,
|
||||||
|
189, 157, 131, 173, 17, 191, 63, 58, 63, 239, 222, 236, // ......?:?...
|
||||||
|
89, 62, 158, 238, 248, 112, 55, 144, 249, 238, 13, 188, // Y>...p7.....
|
||||||
|
59, 100, 237, 193, 37, 108, 102, 1, 30, 163, 213, 105, // ;d..%lf....i
|
||||||
|
184, 164, 47, 77, 192, 17, 209, 139, 240, 29, 156, 24, // ../M........
|
||||||
|
119, 74, 33, 97, 185, 235, 73, 191, 35, 107, 155, 131, // wJ!a..I.#k..
|
||||||
|
139, 90, 153, 85, 119, 29, 150, 65, 115, 220, 169, 109, // .Z.Uw..As..m
|
||||||
|
120, 37, 149, 106, 193, 192, 42, 37, 152, 107, 175, 224, // x%.j..*%.k..
|
||||||
|
46, 79, 116, 35, 161, 151, 210, 26, 29, 123, 247, 78, // .Ot#.....{.N
|
||||||
|
218, 7, 88, 248, 87, 163, 155, 212, 245, 142, 213, 161, // ..X.W.......
|
||||||
|
80, 237, 246, 249, 93, 86, 62, 25, 63, 99, 14, 255, // P...]V>.?c..
|
||||||
|
96, 126, 93, 235, 244, 66, 42, 209, 55, 17, 23, 21, // `~]..B*.7...
|
||||||
|
38, 22, 91, 6, 89, 95, 236, 135, 235, 242, 240, 221, // &.[.Y_......
|
||||||
|
209, 205, 160, 47, 186, 253, 250, 253, 230, 117, 15, 5, // .../.....u..
|
||||||
|
255, 29, 184, 105, 18, 163, 149, 97, 28, 112, 96, 184, // ...i...a.p`.
|
||||||
|
231, 227, 254, 207, 227, 97, 121, 8, 140, 71, 67, 226, // .....ay..GC.
|
||||||
|
112, 255, 120, 232, 36, 55, 124, 117, 116, 54, 248, 7, // p.x.$7|ut6..
|
||||||
|
71, 33, 75, 134, 124, 10, 0, 0, 0 // G!K.|...
|
||||||
|
};
|
||||||
|
static const unsigned char v3[] = {
|
||||||
39, 117, 115, 101, 32, 115, 116, 114, 105, 99, 116, 39, // 'use strict'
|
39, 117, 115, 101, 32, 115, 116, 114, 105, 99, 116, 39, // 'use strict'
|
||||||
59, 10, 105, 109, 112, 111, 114, 116, 32, 123, 32, 104, // ;.import { h
|
59, 10, 105, 109, 112, 111, 114, 116, 32, 123, 32, 104, // ;.import { h
|
||||||
44, 32, 104, 116, 109, 108, 44, 32, 114, 101, 110, 100, // , html, rend
|
44, 32, 104, 116, 109, 108, 44, 32, 114, 101, 110, 100, // , html, rend
|
||||||
@@ -273,7 +774,7 @@ static const unsigned char v2[] = {
|
|||||||
112, 41, 44, 32, 100, 111, 99, 117, 109, 101, 110, 116, // p), document
|
112, 41, 44, 32, 100, 111, 99, 117, 109, 101, 110, 116, // p), document
|
||||||
46, 98, 111, 100, 121, 41, 59, 10, 0 // .body);.
|
46, 98, 111, 100, 121, 41, 59, 10, 0 // .body);.
|
||||||
};
|
};
|
||||||
static const unsigned char v3[] = {
|
static const unsigned char v4[] = {
|
||||||
118, 97, 114, 32, 101, 44, 110, 44, 95, 44, 116, 44, // var e,n,_,t,
|
118, 97, 114, 32, 101, 44, 110, 44, 95, 44, 116, 44, // var e,n,_,t,
|
||||||
111, 44, 114, 44, 117, 44, 108, 61, 123, 125, 44, 105, // o,r,u,l={},i
|
111, 44, 114, 44, 117, 44, 108, 61, 123, 125, 44, 105, // o,r,u,l={},i
|
||||||
61, 91, 93, 44, 99, 61, 47, 97, 99, 105, 116, 124, // =[],c=/acit|
|
61, 91, 93, 44, 99, 61, 47, 97, 99, 105, 116, 124, // =[],c=/acit|
|
||||||
@@ -1375,7 +1876,147 @@ static const unsigned char v3[] = {
|
|||||||
115, 101, 69, 114, 114, 111, 114, 66, 111, 117, 110, 100, // seErrorBound
|
115, 101, 69, 114, 114, 111, 114, 66, 111, 117, 110, 100, // seErrorBound
|
||||||
97, 114, 121, 125, 59, 10, 0 // ary};.
|
97, 114, 121, 125, 59, 10, 0 // ary};.
|
||||||
};
|
};
|
||||||
static const unsigned char v4[] = {
|
static const unsigned char v5[] = {
|
||||||
|
60, 33, 68, 79, 67, 84, 89, 80, 69, 32, 104, 116, // <!DOCTYPE ht
|
||||||
|
109, 108, 62, 10, 60, 104, 116, 109, 108, 32, 108, 97, // ml>.<html la
|
||||||
|
110, 103, 61, 34, 101, 110, 34, 62, 10, 32, 32, 60, // ng="en">. <
|
||||||
|
104, 101, 97, 100, 62, 10, 32, 32, 32, 32, 60, 109, // head>. <m
|
||||||
|
101, 116, 97, 32, 110, 97, 109, 101, 61, 34, 100, 101, // eta name="de
|
||||||
|
115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 99, // scription" c
|
||||||
|
111, 110, 116, 101, 110, 116, 61, 34, 77, 111, 110, 103, // ontent="Mong
|
||||||
|
111, 111, 115, 101, 32, 69, 109, 98, 101, 100, 100, 101, // oose Embedde
|
||||||
|
100, 32, 70, 105, 108, 101, 115, 121, 116, 101, 109, 32, // d Filesytem
|
||||||
|
101, 120, 97, 109, 112, 108, 101, 34, 32, 47, 62, 10, // example" />.
|
||||||
|
32, 32, 32, 32, 60, 109, 101, 116, 97, 32, 104, 116, // <meta ht
|
||||||
|
116, 112, 45, 101, 113, 117, 105, 118, 61, 34, 67, 111, // tp-equiv="Co
|
||||||
|
110, 116, 101, 110, 116, 45, 84, 121, 112, 101, 34, 32, // ntent-Type"
|
||||||
|
99, 111, 110, 116, 101, 110, 116, 61, 34, 116, 101, 120, // content="tex
|
||||||
|
116, 47, 104, 116, 109, 108, 59, 32, 99, 104, 97, 114, // t/html; char
|
||||||
|
115, 101, 116, 61, 85, 84, 70, 45, 56, 34, 62, 10, // set=UTF-8">.
|
||||||
|
32, 32, 32, 32, 60, 109, 101, 116, 97, 32, 104, 116, // <meta ht
|
||||||
|
116, 112, 45, 101, 113, 117, 105, 118, 61, 34, 88, 45, // tp-equiv="X-
|
||||||
|
85, 65, 45, 67, 111, 109, 112, 97, 116, 105, 98, 108, // UA-Compatibl
|
||||||
|
101, 34, 32, 99, 111, 110, 116, 101, 110, 116, 61, 34, // e" content="
|
||||||
|
73, 69, 61, 101, 100, 103, 101, 34, 62, 10, 32, 32, // IE=edge">.
|
||||||
|
32, 32, 60, 109, 101, 116, 97, 32, 110, 97, 109, 101, // <meta name
|
||||||
|
61, 34, 118, 105, 101, 119, 112, 111, 114, 116, 34, 32, // ="viewport"
|
||||||
|
99, 111, 110, 116, 101, 110, 116, 61, 34, 119, 105, 100, // content="wid
|
||||||
|
116, 104, 61, 100, 101, 118, 105, 99, 101, 45, 119, 105, // th=device-wi
|
||||||
|
100, 116, 104, 44, 32, 105, 110, 105, 116, 105, 97, 108, // dth, initial
|
||||||
|
45, 115, 99, 97, 108, 101, 61, 49, 34, 62, 10, 32, // -scale=1">.
|
||||||
|
32, 32, 32, 32, 32, 32, 32, 60, 116, 105, 116, 108, // <titl
|
||||||
|
101, 62, 77, 111, 110, 103, 111, 111, 115, 101, 32, 69, // e>Mongoose E
|
||||||
|
109, 98, 101, 100, 100, 101, 100, 32, 70, 105, 108, 101, // mbedded File
|
||||||
|
115, 121, 116, 101, 109, 32, 101, 120, 97, 109, 112, 108, // sytem exampl
|
||||||
|
101, 60, 47, 116, 105, 116, 108, 101, 62, 10, 32, 32, // e</title>.
|
||||||
|
32, 32, 60, 108, 105, 110, 107, 32, 114, 101, 108, 61, // <link rel=
|
||||||
|
34, 115, 116, 121, 108, 101, 115, 104, 101, 101, 116, 34, // "stylesheet"
|
||||||
|
32, 104, 114, 101, 102, 61, 34, 115, 116, 121, 108, 101, // href="style
|
||||||
|
46, 99, 115, 115, 34, 32, 47, 62, 10, 32, 32, 60, // .css" />. <
|
||||||
|
47, 104, 101, 97, 100, 62, 10, 32, 32, 60, 98, 111, // /head>. <bo
|
||||||
|
100, 121, 62, 60, 47, 98, 111, 100, 121, 62, 10, 32, // dy></body>.
|
||||||
|
32, 60, 115, 99, 114, 105, 112, 116, 32, 116, 121, 112, // <script typ
|
||||||
|
101, 61, 34, 109, 111, 100, 117, 108, 101, 34, 32, 115, // e="module" s
|
||||||
|
114, 99, 61, 34, 109, 97, 105, 110, 46, 106, 115, 34, // rc="main.js"
|
||||||
|
62, 60, 47, 115, 99, 114, 105, 112, 116, 62, 10, 60, // ></script>.<
|
||||||
|
47, 104, 116, 109, 108, 62, 10, 0 // /html>.
|
||||||
|
};
|
||||||
|
static const unsigned char v6[] = {
|
||||||
|
31, 139, 8, 8, 219, 27, 244, 98, 0, 3, 105, 110, // .......b..in
|
||||||
|
100, 101, 120, 46, 104, 116, 109, 108, 0, 141, 145, 77, // dex.html...M
|
||||||
|
75, 3, 49, 16, 134, 239, 253, 21, 99, 206, 166, 139, // K.1.....c...
|
||||||
|
55, 193, 205, 130, 212, 22, 60, 136, 30, 90, 208, 99, // 7.....<..Z.c
|
||||||
|
154, 140, 205, 104, 62, 214, 205, 244, 99, 255, 189, 217, // ...h>...c...
|
||||||
|
110, 133, 5, 17, 60, 205, 7, 47, 15, 51, 239, 91, // n...<../.3.[
|
||||||
|
95, 61, 60, 47, 214, 111, 47, 75, 112, 28, 124, 51, // _=</.o/Kp.|3
|
||||||
|
171, 135, 2, 94, 199, 157, 18, 24, 69, 51, 3, 168, // ...^....E3..
|
||||||
|
29, 106, 59, 52, 165, 13, 200, 26, 162, 14, 168, 132, // .j;4........
|
||||||
|
197, 108, 58, 106, 153, 82, 20, 96, 82, 100, 140, 172, // .l:j.R.`Rd..
|
||||||
|
196, 83, 138, 187, 148, 50, 194, 50, 108, 209, 90, 180, // .S...2.2l.Z.
|
||||||
|
176, 34, 143, 185, 103, 12, 128, 39, 29, 90, 143, 2, // ."..g..'.Z..
|
||||||
|
170, 41, 205, 49, 183, 18, 191, 246, 116, 80, 98, 49, // .).1....tPb1
|
||||||
|
98, 228, 186, 111, 113, 2, 101, 60, 113, 53, 28, 118, // b..oq.e<q5.v
|
||||||
|
7, 198, 233, 46, 35, 171, 205, 122, 37, 111, 197, 95, // ....#..z%o._
|
||||||
|
156, 87, 185, 185, 151, 139, 20, 90, 205, 180, 245, 83, // .W.....Z...S
|
||||||
|
212, 227, 82, 161, 221, 161, 248, 253, 207, 129, 240, 216, // ..R.........
|
||||||
|
166, 142, 39, 226, 35, 89, 118, 202, 226, 129, 12, 202, // ..'.#Yv.....
|
||||||
|
243, 112, 13, 20, 137, 73, 123, 153, 141, 246, 168, 110, // .p...I{....n
|
||||||
|
46, 160, 51, 140, 137, 61, 54, 255, 112, 160, 174, 70, // ..3..=6.p..F
|
||||||
|
233, 120, 131, 167, 248, 9, 29, 122, 37, 50, 247, 69, // .x.....z%2.E
|
||||||
|
233, 16, 203, 17, 174, 195, 247, 203, 102, 110, 114, 190, // ........fnr.
|
||||||
|
152, 86, 87, 63, 97, 212, 219, 100, 251, 166, 174, 206, // .VW?a..d....
|
||||||
|
101, 152, 199, 52, 128, 139, 117, 74, 132, 100, 247, 195, // e..4..uJ.d..
|
||||||
|
223, 185, 51, 101, 208, 20, 231, 31, 89, 20, 245, 40, // ..3e....Y..(
|
||||||
|
42, 49, 87, 99, 220, 223, 14, 156, 225, 97, 255, 1, // *1Wc.....a..
|
||||||
|
0, 0, 0 // ..
|
||||||
|
};
|
||||||
|
static const unsigned char v7[] = {
|
||||||
|
31, 139, 8, 8, 219, 27, 244, 98, 0, 3, 115, 116, // .......b..st
|
||||||
|
121, 108, 101, 46, 99, 115, 115, 0, 117, 84, 203, 110, // yle.css.uT.n
|
||||||
|
219, 48, 16, 188, 251, 43, 88, 4, 5, 218, 32, 82, // .0...+X... R
|
||||||
|
44, 41, 178, 99, 249, 210, 91, 63, 162, 232, 129, 18, // ,).c..[?....
|
||||||
|
87, 54, 17, 138, 84, 73, 58, 118, 90, 248, 223, 187, // W6..TI:vZ...
|
||||||
|
164, 30, 164, 226, 228, 98, 75, 187, 163, 125, 204, 12, // .....bK..}..
|
||||||
|
121, 79, 254, 145, 90, 93, 18, 195, 255, 114, 121, 168, // yO..Z]...ry.
|
||||||
|
240, 89, 51, 208, 9, 134, 246, 228, 186, 58, 218, 78, // .Y3......:.N
|
||||||
|
60, 96, 140, 189, 33, 172, 163, 250, 192, 101, 69, 214, // <`..!....eE.
|
||||||
|
123, 210, 83, 198, 60, 28, 159, 143, 192, 15, 71, 91, // {.S.<.....G[
|
||||||
|
145, 108, 189, 254, 186, 39, 173, 146, 238, 121, 211, 95, // .l...'...y._
|
||||||
|
136, 161, 210, 36, 6, 52, 111, 93, 41, 3, 2, 26, // ...$.4o])...
|
||||||
|
251, 64, 184, 236, 79, 248, 39, 104, 13, 162, 170, 106, // .@..O.'h...j
|
||||||
|
104, 149, 134, 7, 98, 225, 98, 169, 6, 138, 109, 212, // h...b.b...m.
|
||||||
|
201, 10, 46, 161, 34, 82, 73, 216, 15, 195, 29, 41, // ...."RI....)
|
||||||
|
83, 231, 202, 5, 200, 23, 222, 245, 74, 91, 42, 237, // S.......J[*.
|
||||||
|
126, 28, 22, 219, 185, 110, 74, 112, 70, 238, 154, 166, // ~....nJpF...
|
||||||
|
89, 64, 174, 171, 70, 49, 108, 208, 107, 192, 218, 141, // Y@..F1l.k...
|
||||||
|
18, 10, 241, 119, 197, 182, 24, 70, 77, 90, 218, 113, // ...w...FMZ.q
|
||||||
|
241, 86, 145, 78, 73, 101, 122, 218, 192, 24, 63, 143, // .V.NIez...?.
|
||||||
|
91, 213, 74, 96, 139, 49, 136, 36, 225, 92, 166, 163, // [.J`.1.$....
|
||||||
|
66, 184, 88, 77, 155, 151, 131, 86, 39, 201, 176, 36, // B.XM...V'..$
|
||||||
|
99, 44, 230, 37, 205, 160, 195, 223, 2, 186, 105, 204, // c,.%......i.
|
||||||
|
68, 83, 198, 79, 198, 229, 114, 23, 189, 174, 166, 165, // DS.O..r.....
|
||||||
|
103, 82, 82, 252, 92, 73, 156, 51, 234, 150, 149, 253, // gRR..I.3....
|
||||||
|
229, 179, 77, 23, 13, 203, 161, 40, 86, 163, 213, 43, // ..M....(V..+
|
||||||
|
55, 220, 2, 115, 143, 180, 177, 252, 53, 222, 189, 44, // 7..s....5..,
|
||||||
|
189, 30, 115, 175, 197, 22, 0, 72, 0, 233, 184, 76, // ..s....H...L
|
||||||
|
206, 156, 217, 99, 69, 118, 88, 21, 193, 181, 69, 232, // ...cEvX...E.
|
||||||
|
138, 44, 193, 126, 130, 155, 229, 162, 149, 189, 63, 166, // .,.~......?.
|
||||||
|
190, 109, 139, 125, 155, 147, 54, 238, 173, 87, 92, 90, // .m.}..6..W.Z
|
||||||
|
228, 16, 75, 50, 110, 122, 65, 81, 2, 46, 157, 238, // ..K2nzAQ....
|
||||||
|
73, 45, 84, 243, 178, 216, 108, 131, 84, 122, 202, 62, // I-T...l.Tz.>
|
||||||
|
82, 102, 53, 76, 247, 11, 203, 208, 90, 0, 251, 237, // Rf5L....Z...
|
||||||
|
44, 132, 66, 114, 251, 230, 89, 9, 61, 233, 201, 42, // ,.Br..Y.=..*
|
||||||
|
183, 139, 233, 148, 178, 71, 132, 89, 141, 14, 229, 150, // .....G.Y....
|
||||||
|
43, 52, 53, 74, 74, 210, 220, 120, 102, 26, 108, 67, // +45JJ..xf.lC
|
||||||
|
113, 20, 29, 155, 158, 228, 107, 39, 196, 72, 139, 175, // q.....k'.H..
|
||||||
|
229, 176, 44, 105, 5, 92, 16, 56, 175, 225, 222, 199, // ..,i...8....
|
||||||
|
148, 55, 108, 148, 26, 28, 237, 6, 246, 244, 248, 163, // .7l.........
|
||||||
|
119, 163, 171, 55, 18, 98, 60, 203, 192, 102, 80, 68, // w..7.b<..fPD
|
||||||
|
241, 40, 117, 42, 213, 89, 211, 30, 17, 231, 35, 202, // .(u*.Y....#.
|
||||||
|
157, 120, 255, 186, 46, 46, 234, 1, 157, 57, 188, 87, // .x.......9.W
|
||||||
|
152, 65, 59, 139, 38, 160, 69, 34, 203, 208, 187, 220, // .A;.&.E"....
|
||||||
|
177, 91, 79, 69, 102, 220, 185, 35, 62, 81, 226, 29, // .[OEf..#>Q..
|
||||||
|
238, 219, 24, 60, 217, 220, 155, 41, 208, 149, 141, 51, // ...<...)...3
|
||||||
|
90, 213, 243, 6, 173, 205, 168, 69, 107, 166, 127, 148, // Z......Ek...
|
||||||
|
65, 88, 220, 35, 247, 7, 165, 252, 240, 160, 60, 185, // AX.#......<.
|
||||||
|
232, 80, 51, 209, 131, 236, 35, 212, 149, 30, 106, 45, // .P3...#...j-
|
||||||
|
253, 219, 210, 208, 245, 125, 178, 133, 33, 233, 70, 121, // .....}..!.Fy
|
||||||
|
159, 163, 224, 79, 197, 234, 241, 158, 252, 212, 72, 197, // ...O......H.
|
||||||
|
253, 163, 83, 224, 124, 43, 172, 251, 77, 28, 193, 21, // ..S.|+..M...
|
||||||
|
153, 105, 70, 139, 127, 126, 63, 170, 87, 208, 173, 192, // .iF..~?.W...
|
||||||
|
235, 43, 152, 6, 241, 73, 150, 59, 221, 6, 55, 13, // .+...I.;..7.
|
||||||
|
87, 231, 148, 200, 66, 98, 151, 165, 155, 77, 148, 90, // W...Bb...M.Z
|
||||||
|
135, 212, 115, 145, 22, 69, 72, 237, 66, 102, 91, 134, // ..s..EH.Bf[.
|
||||||
|
240, 115, 8, 111, 54, 139, 90, 219, 144, 41, 159, 23, // .s.o6.Z..)..
|
||||||
|
165, 54, 81, 38, 154, 171, 12, 225, 167, 229, 88, 79, // .6Q&......XO
|
||||||
|
33, 83, 44, 167, 42, 66, 38, 143, 166, 138, 87, 95, // !S,.*B&...W_
|
||||||
|
78, 21, 237, 62, 15, 245, 163, 3, 198, 41, 249, 22, // N..>.....)..
|
||||||
|
221, 74, 89, 145, 225, 105, 252, 142, 224, 15, 15, 235, // .JY..i......
|
||||||
|
64, 244, 132, 205, 183, 254, 228, 94, 227, 82, 244, 50, // @......^.R.2
|
||||||
|
95, 112, 249, 84, 201, 201, 61, 74, 185, 212, 5, 63, // _p.T..=J...?
|
||||||
|
252, 15, 225, 232, 67, 124, 39, 7, 0, 0, 0 // ....C|'...
|
||||||
|
};
|
||||||
|
static const unsigned char v8[] = {
|
||||||
42, 32, 123, 32, 98, 111, 120, 45, 115, 105, 122, 105, // * { box-sizi
|
42, 32, 123, 32, 98, 111, 120, 45, 115, 105, 122, 105, // * { box-sizi
|
||||||
110, 103, 58, 32, 98, 111, 114, 100, 101, 114, 45, 98, // ng: border-b
|
110, 103, 58, 32, 98, 111, 114, 100, 101, 114, 45, 98, // ng: border-b
|
||||||
111, 120, 59, 32, 125, 10, 104, 116, 109, 108, 44, 32, // ox; }.html,
|
111, 120, 59, 32, 125, 10, 104, 116, 109, 108, 44, 32, // ox; }.html,
|
||||||
@@ -1537,10 +2178,14 @@ static const struct packed_file {
|
|||||||
size_t size;
|
size_t size;
|
||||||
time_t mtime;
|
time_t mtime;
|
||||||
} packed_files[] = {
|
} packed_files[] = {
|
||||||
{"/web_root/index.html", v1, sizeof(v1), 1660216320},
|
{"/web_root/preact.min.js.gz", v1, sizeof(v1), 1660165083},
|
||||||
{"/web_root/main.js", v2, sizeof(v2), 1660216320},
|
{"/web_root/main.js.gz", v2, sizeof(v2), 1660165083},
|
||||||
{"/web_root/preact.min.js", v3, sizeof(v3), 1660216320},
|
{"/web_root/main.js", v3, sizeof(v3), 1660586478},
|
||||||
{"/web_root/style.css", v4, sizeof(v4), 1660216320},
|
{"/web_root/preact.min.js", v4, sizeof(v4), 1660586478},
|
||||||
|
{"/web_root/index.html", v5, sizeof(v5), 1660586478},
|
||||||
|
{"/web_root/index.html.gz", v6, sizeof(v6), 1660165083},
|
||||||
|
{"/web_root/style.css.gz", v7, sizeof(v7), 1660165083},
|
||||||
|
{"/web_root/style.css", v8, sizeof(v8), 1660586478},
|
||||||
{NULL, NULL, 0, 0}
|
{NULL, NULL, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -5,3 +5,6 @@ idf_component_register(SRCS "main.c"
|
|||||||
"mongoose.c")
|
"mongoose.c")
|
||||||
component_compile_options(-DMG_ENABLE_LINES)
|
component_compile_options(-DMG_ENABLE_LINES)
|
||||||
component_compile_options(-DMG_ENABLE_PACKED_FS)
|
component_compile_options(-DMG_ENABLE_PACKED_FS)
|
||||||
|
component_compile_options(-DHTTP_URL="http://0.0.0.0:80")
|
||||||
|
component_compile_options(-DHTTPS_URL="https://0.0.0.0:443")
|
||||||
|
component_compile_options(-DMG_ENABLE_MBEDTLS=0) # change to '1' to enable TLS
|
||||||
@@ -2,11 +2,8 @@
|
|||||||
// All rights reserved
|
// All rights reserved
|
||||||
|
|
||||||
#include "esp_spiffs.h"
|
#include "esp_spiffs.h"
|
||||||
//#include "freertos/FreeRTOS.h"
|
|
||||||
#include "mongoose.h"
|
#include "mongoose.h"
|
||||||
|
#include "net.h"
|
||||||
const char *s_listening_url = "http://0.0.0.0:80";
|
|
||||||
void device_dashboard_fn(struct mg_connection *, int, void *, void *);
|
|
||||||
|
|
||||||
#define WIFI_SSID "YOUR_WIFI_NETWORK_NAME" // SET THIS!
|
#define WIFI_SSID "YOUR_WIFI_NETWORK_NAME" // SET THIS!
|
||||||
#define WIFI_PASS "YOUR_WIFI_PASSWORD" // SET THIS!
|
#define WIFI_PASS "YOUR_WIFI_PASSWORD" // SET THIS!
|
||||||
@@ -29,7 +26,12 @@ void app_main(void) {
|
|||||||
struct mg_mgr mgr;
|
struct mg_mgr mgr;
|
||||||
mg_log_set(MG_LL_DEBUG); // Set log level
|
mg_log_set(MG_LL_DEBUG); // Set log level
|
||||||
mg_mgr_init(&mgr);
|
mg_mgr_init(&mgr);
|
||||||
MG_INFO(("Mongoose v%s on %s", MG_VERSION, s_listening_url));
|
MG_INFO(("Mongoose version : v%s", MG_VERSION));
|
||||||
mg_http_listen(&mgr, s_listening_url, device_dashboard_fn, &mgr);
|
MG_INFO(("Listening on : %s", HTTP_URL));
|
||||||
|
#if MG_ENABLE_MBEDTLS
|
||||||
|
MG_INFO(("Listening on : %s", HTTPS_URL));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
web_init(&mgr);
|
||||||
for (;;) mg_mgr_poll(&mgr, 1000); // Infinite event loop
|
for (;;) mg_mgr_poll(&mgr, 1000); // Infinite event loop
|
||||||
}
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../../../device-dashboard/net.h
|
||||||
@@ -1,30 +1,10 @@
|
|||||||
# A UART to network bridge for ESP32
|
# A UART to network bridge for ESP32
|
||||||
|
|
||||||
This example is a demonstration of how Mongoose Library could be integrated
|
|
||||||
into an embedded device and provide a UART-to-Network bridge capability:
|
|
||||||
|
|
||||||
- A device opens listening TCP port and Websocket port and waits for connections
|
|
||||||
- When a client connects, data is exchanged with the device's UART
|
|
||||||
- Everything that client send, is sent to the UART
|
|
||||||
- Everything that is read from the UART, gets sent to the client
|
|
||||||
- Multiple clients are allowed
|
|
||||||
- Live UART console allows to talk to the UART from the web page
|
|
||||||
- Web UI is hardcoded into the binary and does not need a filesystem
|
|
||||||
|
|
||||||
# Screenshots
|
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
# Build and flash
|
- See detailed tutorial at https://mongoose.ws/tutorials/esp32/uart-bridge/
|
||||||
|
|
||||||
Build requires Docker installed, and uses Espressif's ESP-IDF docker image:
|
## Flash pre-built firmware
|
||||||
|
|
||||||
```sh
|
|
||||||
make build
|
|
||||||
make flash PORT=/dev/YOURSERIAL
|
|
||||||
```
|
|
||||||
|
|
||||||
# Flash pre-built firmware
|
|
||||||
|
|
||||||
You can flash a pre-built firmware to the ESP32 device using the following
|
You can flash a pre-built firmware to the ESP32 device using the following
|
||||||
instructions:
|
instructions:
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
static void cli_wifi(const char *ssid, const char *pass) {
|
static void cli_wifi(const char *ssid, const char *pass) {
|
||||||
if (wifi_init(ssid, pass)) {
|
if (wifi_init(ssid, pass)) {
|
||||||
mg_file_printf(&mg_fs_posix, WIFI_FILE, "{%Q:%Q,%Q:%Q}\n", "ssid", ssid,
|
mg_file_printf(&mg_fs_posix, WIFI_FILE, "{%m:%m,%m:%m}\n", mg_print_esc, 0,
|
||||||
"pass", pass);
|
"ssid", mg_print_esc, 0, ssid, mg_print_esc, 0, "pass",
|
||||||
|
mg_print_esc, 0, pass);
|
||||||
MG_INFO(("Reboot now"));
|
MG_INFO(("Reboot now"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1 @@
|
|||||||
# An example ESP8266 application
|
See detailed tutorial at https://mongoose.ws/tutorials/esp8266/http-client-server/
|
||||||
|
|
||||||
To build this application, follow these steps:
|
|
||||||
|
|
||||||
1. Make sure you have Docker installed
|
|
||||||
2. Clone whole mongoose repository on your machine:
|
|
||||||
```sh
|
|
||||||
git clone https://github.com/cesanta/mongoose.git
|
|
||||||
```
|
|
||||||
3. Start command line or terminal, and go into the example's directory:
|
|
||||||
```sh
|
|
||||||
cd mongoose/examples/esp8266
|
|
||||||
```
|
|
||||||
4. Run `make`. This invokes a Docker-based build. A firmware will be built
|
|
||||||
in the `src/build/` directory:
|
|
||||||
```sh
|
|
||||||
make build
|
|
||||||
```
|
|
||||||
5. Flash your ESP8266. If you have esptool.py installed, the build process will end telling you the command to flash your device. You can just run `make` again to use Docker:
|
|
||||||
```sh
|
|
||||||
make flash PORT=/your/serial
|
|
||||||
```
|
|
||||||
@@ -1,10 +1,25 @@
|
|||||||
PROG ?= example
|
PROG ?= example # Program we are building
|
||||||
|
DELETE = rm -rf # Command to remove files
|
||||||
|
OUT ?= -o $(PROG) # Compiler argument for output file
|
||||||
|
SOURCES = main.c mongoose.c # Source code files
|
||||||
|
CFLAGS = -W -Wall -Wextra -g -I. # Build options
|
||||||
|
|
||||||
all: $(PROG)
|
# Mongoose build options. See https://mongoose.ws/documentation/#build-options
|
||||||
$(DEBUGGER) ./$(PROG)
|
#CFLAGS_MONGOOSE += -DMG_ENABLE_LINES
|
||||||
|
|
||||||
$(PROG):
|
ifeq ($(OS),Windows_NT) # Windows settings. Assume MinGW compiler. To use VC: make CC=cl CFLAGS=/MD OUT=/Feprog.exe
|
||||||
$(CC) ../../mongoose.c -I../.. $(CFLAGS) $(EXTRA) -o $(PROG) main.c
|
PROG ?= example.exe # Use .exe suffix for the binary
|
||||||
|
CC = gcc # Use MinGW gcc compiler
|
||||||
|
CFLAGS += -lws2_32 # Link against Winsock library
|
||||||
|
DELETE = cmd /C del /Q /F /S # Command prompt command to delete files
|
||||||
|
OUT ?= -o $(PROG) # Build output
|
||||||
|
endif
|
||||||
|
|
||||||
clean:
|
all: $(PROG) # Default target. Build and run program
|
||||||
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb log.txt
|
$(RUN) ./$(PROG) $(ARGS)
|
||||||
|
|
||||||
|
$(PROG): $(SOURCES) # Build program from sources
|
||||||
|
$(CC) $(SOURCES) $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA) $(OUT)
|
||||||
|
|
||||||
|
clean: # Cleanup. Delete built program and all build artifacts
|
||||||
|
$(DELETE) $(PROG) *.o *.obj *.exe *.dSYM
|
||||||
@@ -35,6 +35,7 @@ static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|||||||
mg_http_serve_dir(c, ev_data, &opts);
|
mg_http_serve_dir(c, ev_data, &opts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
(void) fn_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
../../mongoose.c
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../../mongoose.h
|
||||||
@@ -1,10 +1,25 @@
|
|||||||
PROG ?= example
|
PROG ?= example # Program we are building
|
||||||
|
DELETE = rm -rf # Command to remove files
|
||||||
|
OUT ?= -o $(PROG) # Compiler argument for output file
|
||||||
|
SOURCES = main.c mongoose.c # Source code files
|
||||||
|
CFLAGS = -W -Wall -Wextra -g -I. # Build options
|
||||||
|
|
||||||
all: $(PROG)
|
# Mongoose build options. See https://mongoose.ws/documentation/#build-options
|
||||||
$(DEBUGGER) ./$(PROG)
|
#CFLAGS_MONGOOSE += -DMG_ENABLE_LINES
|
||||||
|
|
||||||
$(PROG):
|
ifeq ($(OS),Windows_NT) # Windows settings. Assume MinGW compiler. To use VC: make CC=cl CFLAGS=/MD OUT=/Feprog.exe
|
||||||
$(CC) ../../mongoose.c -I../.. $(CFLAGS) $(EXTRA) -o $(PROG) main.c
|
PROG ?= example.exe # Use .exe suffix for the binary
|
||||||
|
CC = gcc # Use MinGW gcc compiler
|
||||||
|
CFLAGS += -lws2_32 # Link against Winsock library
|
||||||
|
DELETE = cmd /C del /Q /F /S # Command prompt command to delete files
|
||||||
|
OUT ?= -o $(PROG) # Build output
|
||||||
|
endif
|
||||||
|
|
||||||
clean:
|
all: $(PROG) # Default target. Build and run program
|
||||||
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb log.txt
|
$(RUN) ./$(PROG) $(ARGS)
|
||||||
|
|
||||||
|
$(PROG): $(SOURCES) # Build program from sources
|
||||||
|
$(CC) $(SOURCES) $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA) $(OUT)
|
||||||
|
|
||||||
|
clean: # Cleanup. Delete built program and all build artifacts
|
||||||
|
$(DELETE) $(PROG) *.o *.obj *.exe *.dSYM
|
||||||
@@ -12,22 +12,24 @@ static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|||||||
if (mg_http_match_uri(hm, "/upload")) {
|
if (mg_http_match_uri(hm, "/upload")) {
|
||||||
char path[80], name[64];
|
char path[80], name[64];
|
||||||
mg_http_get_var(&hm->query, "name", name, sizeof(name));
|
mg_http_get_var(&hm->query, "name", name, sizeof(name));
|
||||||
|
mg_snprintf(path, sizeof(path), "/tmp/%s", name);
|
||||||
if (name[0] == '\0') {
|
if (name[0] == '\0') {
|
||||||
mg_http_reply(c, 400, "", "%s", "name required");
|
mg_http_reply(c, 400, "", "%s", "name required");
|
||||||
|
} else if (!mg_path_is_sane(path)) {
|
||||||
|
mg_http_reply(c, 400, "", "%s", "invalid path");
|
||||||
} else {
|
} else {
|
||||||
mg_snprintf(path, sizeof(path), "/tmp/%s", name);
|
mg_http_upload(c, hm, &mg_fs_posix, path, 99999);
|
||||||
mg_http_upload(c, hm, &mg_fs_posix, mg_remove_double_dots(path), 99999);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
struct mg_http_serve_opts opts = {.root_dir = "web_root"};
|
struct mg_http_serve_opts opts = {.root_dir = "web_root"};
|
||||||
mg_http_serve_dir(c, ev_data, &opts);
|
mg_http_serve_dir(c, ev_data, &opts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
(void) fn_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
struct mg_mgr mgr;
|
struct mg_mgr mgr;
|
||||||
struct mg_timer t1;
|
|
||||||
|
|
||||||
mg_mgr_init(&mgr);
|
mg_mgr_init(&mgr);
|
||||||
mg_log_set(MG_LL_DEBUG); // Set log level
|
mg_log_set(MG_LL_DEBUG); // Set log level
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
../../mongoose.c
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../../mongoose.h
|
||||||
@@ -1,10 +1,25 @@
|
|||||||
PROG ?= example
|
PROG ?= example # Program we are building
|
||||||
|
DELETE = rm -rf # Command to remove files
|
||||||
|
OUT ?= -o $(PROG) # Compiler argument for output file
|
||||||
|
SOURCES = main.c mongoose.c # Source code files
|
||||||
|
CFLAGS = -W -Wall -Wextra -g -I. # Build options
|
||||||
|
|
||||||
all: $(PROG)
|
# Mongoose build options. See https://mongoose.ws/documentation/#build-options
|
||||||
$(DEBUGGER) ./$(PROG)
|
#CFLAGS_MONGOOSE += -DMG_ENABLE_LINES
|
||||||
|
|
||||||
$(PROG):
|
ifeq ($(OS),Windows_NT) # Windows settings. Assume MinGW compiler. To use VC: make CC=cl CFLAGS=/MD OUT=/Feprog.exe
|
||||||
$(CC) ../../mongoose.c -I../.. $(CFLAGS) $(EXTRA) -o $(PROG) main.c
|
PROG ?= example.exe # Use .exe suffix for the binary
|
||||||
|
CC = gcc # Use MinGW gcc compiler
|
||||||
|
CFLAGS += -lws2_32 # Link against Winsock library
|
||||||
|
DELETE = cmd /C del /Q /F /S # Command prompt command to delete files
|
||||||
|
OUT ?= -o $(PROG) # Build output
|
||||||
|
endif
|
||||||
|
|
||||||
clean:
|
all: $(PROG) # Default target. Build and run program
|
||||||
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb log.txt
|
$(RUN) ./$(PROG) $(ARGS)
|
||||||
|
|
||||||
|
$(PROG): $(SOURCES) # Build program from sources
|
||||||
|
$(CC) $(SOURCES) $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA) $(OUT)
|
||||||
|
|
||||||
|
clean: # Cleanup. Delete built program and all build artifacts
|
||||||
|
$(DELETE) $(PROG) *.o *.obj *.exe *.dSYM
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
// Copyright (c) 2020 Cesanta Software Limited
|
// Copyright (c) 2020 Cesanta Software Limited
|
||||||
// All rights reserved
|
// All rights reserved
|
||||||
//
|
//
|
||||||
// Streaming upload example. Demonstrates how to use chunked encoding
|
// Streaming upload example. Demonstrates how to use MG_EV_HTTP_CHUNK events
|
||||||
// to send large payload in smaller chunks. To test, use curl utility:
|
// to send large payload in smaller chunks. To test, use curl utility:
|
||||||
//
|
//
|
||||||
// curl http://localhost:8000/upload?name=a.txt --data-binary @large_file.txt
|
// curl http://localhost:8000/upload?name=a.txt --data-binary @large_file.txt
|
||||||
@@ -26,6 +26,7 @@ static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|||||||
struct mg_http_serve_opts opts = {.root_dir = "web_root"};
|
struct mg_http_serve_opts opts = {.root_dir = "web_root"};
|
||||||
mg_http_serve_dir(c, hm, &opts);
|
mg_http_serve_dir(c, hm, &opts);
|
||||||
}
|
}
|
||||||
|
(void) fn_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
../../mongoose.c
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../../mongoose.h
|
||||||
@@ -32,21 +32,22 @@
|
|||||||
<div id="wrapper">
|
<div id="wrapper">
|
||||||
<input type="file" id="el1" style="display: none"/>
|
<input type="file" id="el1" style="display: none"/>
|
||||||
<button id="el2">choose file...</button>
|
<button id="el2">choose file...</button>
|
||||||
|
<span>Selected file:</span> <span id="el4"></span> <br/>
|
||||||
|
<button id="el5" style="margin: 0.5em 0;" disabled>upload file</button>
|
||||||
<div id="el3" style="margin-top: 1em;"></div>
|
<div id="el3" style="margin-top: 1em;"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
<script>
|
<script>
|
||||||
|
var f; // selected file
|
||||||
|
|
||||||
// When user clicks on a button, trigger file selection dialog
|
// When user clicks on a button, trigger file selection dialog
|
||||||
document.getElementById('el2').onclick = function(ev) {
|
document.getElementById('el2').onclick = function(ev) {
|
||||||
document.getElementById('el1').click();
|
document.getElementById('el1').click();
|
||||||
};
|
};
|
||||||
|
|
||||||
// If user selected a file, read it into memory and trigger sendFileData()
|
document.getElementById('el5').onclick = function(ev) {
|
||||||
document.getElementById('el1').onchange = function(ev) {
|
var r = new FileReader();
|
||||||
if (!ev.target.files[0]) return;
|
|
||||||
var f = ev.target.files[0], r = new FileReader();
|
|
||||||
r.readAsArrayBuffer(f);
|
r.readAsArrayBuffer(f);
|
||||||
r.onload = function() {
|
r.onload = function() {
|
||||||
ev.target.value = '';
|
ev.target.value = '';
|
||||||
@@ -60,5 +61,13 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// If user selected a file, read it into memory and trigger sendFileData()
|
||||||
|
document.getElementById('el1').onchange = function(ev) {
|
||||||
|
f = ev.target.files[0];
|
||||||
|
if (!f) return;
|
||||||
|
document.getElementById('el4').innerText = f.name;
|
||||||
|
document.getElementById('el5').removeAttribute('disabled');
|
||||||
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</html>
|
</html>
|
||||||
@@ -1,41 +1,32 @@
|
|||||||
PROG ?= example
|
PROG ?= example # Program we are building
|
||||||
ROOT ?= $(realpath $(CURDIR)/../..)
|
DELETE = rm -rf # Command to remove files
|
||||||
CFLAGS ?= -DMG_ENABLE_LINES $(EXTRA_CFLAGS)
|
OUT ?= -o $(PROG) # Compiler argument for output file
|
||||||
LIN = docker run -it --rm -v $(ROOT):$(ROOT) -w $(CURDIR) mdashnet/cc2
|
SOURCES = main.c mongoose.c # Source code files
|
||||||
SSL = ?
|
CFLAGS = -W -Wall -Wextra -g -I. # Build options
|
||||||
|
|
||||||
ifeq "$(SSL)" "MBEDTLS"
|
# Mongoose build options. See https://mongoose.ws/documentation/#build-options
|
||||||
CFLAGS += -DMG_ENABLE_MBEDTLS=1 -lmbedtls -lmbedcrypto -lmbedx509
|
CFLAGS_MONGOOSE += -DMG_ENABLE_LINES=1
|
||||||
|
|
||||||
|
ifeq ($(OS),Windows_NT) # Windows settings. Assume MinGW compiler. To use VC: make CC=cl CFLAGS=/MD OUT=/Feprog.exe
|
||||||
|
PROG ?= example.exe # Use .exe suffix for the binary
|
||||||
|
CC = gcc # Use MinGW gcc compiler
|
||||||
|
CFLAGS += -lws2_32 # Link against Winsock library
|
||||||
|
DELETE = cmd /C del /Q /F /S # Command prompt command to delete files
|
||||||
|
OUT ?= -o $(PROG) # Build output
|
||||||
|
MAKE += WINDOWS=1 CC=$(CC)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq "$(SSL)" "OPENSSL"
|
all: $(PROG) # Default target. Build and run program
|
||||||
CFLAGS += -DMG_ENABLE_OPENSSL=1 -lssl -lcrypto
|
|
||||||
endif
|
|
||||||
|
|
||||||
all: $(PROG)
|
|
||||||
$(RUN) ./$(PROG) $(ARGS)
|
$(RUN) ./$(PROG) $(ARGS)
|
||||||
|
|
||||||
$(PROG): main.c
|
$(PROG): $(SOURCES) # Build program from sources
|
||||||
$(CC) ../../mongoose.c -I../.. -W -Wall $(CFLAGS) -o $(PROG) main.c
|
$(CC) $(SOURCES) $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA) $(OUT)
|
||||||
|
|
||||||
linux: all
|
clean: # Cleanup. Delete built program and all build artifacts
|
||||||
linux: CFLAGS += -O2 -g -fsanitize=address,undefined,shift,null,return,bounds,alignment,object-size,bool,enum -static-libasan
|
$(DELETE) $(PROG) *.o *.obj *.exe *.dSYM mbedtls
|
||||||
linux: CC = $(LIN) cc
|
|
||||||
linux: RUN = $(LIN)
|
|
||||||
|
|
||||||
|
# see https://mongoose.ws/tutorials/tls/#how-to-build for TLS build options
|
||||||
|
|
||||||
ROOT ?= $(realpath $(CURDIR)/../..)
|
mbedtls: # Pull and build mbedTLS library
|
||||||
DOCKER = docker run -it --rm -e Tmp=. -e WINEDEBUG=-all -v $(ROOT):$(ROOT) -w $(CURDIR)
|
git clone --depth 1 -b v2.28.2 https://github.com/mbed-tls/mbedtls $@
|
||||||
WDEFS = -DMG_ENABLE_MBEDTLS -DMG_ENABLE_LINES -Imbedtls/include -Imbedtls/library $(EXTRA)
|
$(MAKE) -C mbedtls/library
|
||||||
WFLAGS = /nologo -O2 -I. -I../.. ws2_32.lib advapi32.lib /link /out:$(PROG).exe
|
|
||||||
WSRCS = ../../mongoose.c main.c mbedtls/library/*.c
|
|
||||||
$(PROG).exe: main.c mbedtls
|
|
||||||
$(DOCKER) mdashnet/vc2017 wine cl $(WSRCS) $(WDEFS) $(WFLAGS)
|
|
||||||
vc2017: ARGS = https://cesanta.com
|
|
||||||
vc2017: $(PROG).exe
|
|
||||||
$(DOCKER) mdashnet/vc2017 wine $(PROG).exe $(ARGS)
|
|
||||||
mbedtls:
|
|
||||||
git clone --depth 1 -b v3.1.0 https://github.com/ARMmbed/mbedtls
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(PROG) _CL* *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb mbedtls
|
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
// print the response and exit.
|
// print the response and exit.
|
||||||
// You can change `s_url` from the command line by executing: ./example YOUR_URL
|
// You can change `s_url` from the command line by executing: ./example YOUR_URL
|
||||||
//
|
//
|
||||||
// To enable SSL/TLS, make SSL=OPENSSL or make SSL=MBEDTLS
|
// To enable SSL/TLS, , see https://mongoose.ws/tutorials/tls/#how-to-build
|
||||||
|
|
||||||
#include "mongoose.h"
|
#include "mongoose.h"
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
../../mongoose.c
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../../mongoose.h
|
||||||
@@ -1,21 +1,35 @@
|
|||||||
PROG ?= example
|
PROG ?= example # Program we are building
|
||||||
ARGS ?= 167.235.63.238:3128 http://info.cern.ch/
|
DELETE = rm -rf # Command to remove files
|
||||||
SSL = ?
|
OUT ?= -o $(PROG) # Compiler argument for output file
|
||||||
|
SOURCES = main.c mongoose.c # Source code files
|
||||||
|
CFLAGS = -W -Wall -Wextra -g -I. # Build options
|
||||||
|
|
||||||
ifeq "$(SSL)" "MBEDTLS"
|
# Mongoose build options. See https://mongoose.ws/documentation/#build-options
|
||||||
CFLAGS += -DMG_ENABLE_MBEDTLS=1 -lmbedtls -lmbedcrypto -lmbedx509
|
#CFLAGS_MONGOOSE += -DMG_ENABLE_LINES=1
|
||||||
|
|
||||||
|
// see tutorial at https://mongoose.ws/tutorials/http-proxy-client/
|
||||||
|
ARGS ?= 167.235.63.238:3128 http://info.cern.ch/ # default call arguments
|
||||||
|
|
||||||
|
ifeq ($(OS),Windows_NT) # Windows settings. Assume MinGW compiler. To use VC: make CC=cl CFLAGS=/MD OUT=/Feprog.exe
|
||||||
|
PROG ?= example.exe # Use .exe suffix for the binary
|
||||||
|
CC = gcc # Use MinGW gcc compiler
|
||||||
|
CFLAGS += -lws2_32 # Link against Winsock library
|
||||||
|
DELETE = cmd /C del /Q /F /S # Command prompt command to delete files
|
||||||
|
OUT ?= -o $(PROG) # Build output
|
||||||
|
MAKE += WINDOWS=1 CC=$(CC)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq "$(SSL)" "OPENSSL"
|
all: $(PROG) # Default target. Build and run program
|
||||||
CFLAGS += -DMG_ENABLE_OPENSSL=1 -lssl -lcrypto
|
$(RUN) ./$(PROG) $(ARGS)
|
||||||
endif
|
|
||||||
|
|
||||||
all: $(PROG)
|
$(PROG): $(SOURCES) # Build program from sources
|
||||||
$(DEBUGGER) ./$(PROG) $(ARGS)
|
$(CC) $(SOURCES) $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA) $(OUT)
|
||||||
|
|
||||||
|
clean: # Cleanup. Delete built program and all build artifacts
|
||||||
|
$(DELETE) $(PROG) *.o *.obj *.exe *.dSYM mbedtls
|
||||||
|
|
||||||
$(PROG): main.c
|
# see https://mongoose.ws/tutorials/tls/#how-to-build for TLS build options
|
||||||
$(CC) ../../mongoose.c -I../.. -W -Wall $(CFLAGS) $(EXTRA_CFLAGS) -o $(PROG) main.c
|
|
||||||
|
|
||||||
clean:
|
mbedtls: # Pull and build mbedTLS library
|
||||||
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb
|
git clone --depth 1 -b v2.28.2 https://github.com/mbed-tls/mbedtls $@
|
||||||
|
$(MAKE) -C mbedtls/library
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
See detailed tutorial at https://mongoose.ws/tutorials/http-proxy-client/
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
// make
|
// make
|
||||||
// ./example PROXY:PORT http://www.ladyada.net
|
// ./example PROXY:PORT http://www.ladyada.net
|
||||||
//
|
//
|
||||||
// To enable SSL/TLS, make SSL=OPENSSL or make SSL=MBEDTLS
|
// To enable SSL/TLS, see https://mongoose.ws/tutorials/tls/#how-to-build
|
||||||
//
|
//
|
||||||
#include "mongoose.h"
|
#include "mongoose.h"
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
../../mongoose.c
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../../mongoose.h
|
||||||
@@ -1,20 +1,32 @@
|
|||||||
PROG ?= example
|
PROG ?= example # Program we are building
|
||||||
CFLAGS ?= -W -Wall -DMG_ENABLE_LINES=1
|
DELETE = rm -rf # Command to remove files
|
||||||
SSL = ?
|
OUT ?= -o $(PROG) # Compiler argument for output file
|
||||||
|
SOURCES = main.c mongoose.c # Source code files
|
||||||
|
CFLAGS = -W -Wall -Wextra -g -I. # Build options
|
||||||
|
|
||||||
ifeq "$(SSL)" "MBEDTLS"
|
# Mongoose build options. See https://mongoose.ws/documentation/#build-options
|
||||||
CFLAGS += -DMG_ENABLE_MBEDTLS=1 -lmbedtls -lmbedcrypto -lmbedx509
|
CFLAGS_MONGOOSE += -DMG_ENABLE_LINES=1
|
||||||
|
|
||||||
|
ifeq ($(OS),Windows_NT) # Windows settings. Assume MinGW compiler. To use VC: make CC=cl CFLAGS=/MD OUT=/Feprog.exe
|
||||||
|
PROG ?= example.exe # Use .exe suffix for the binary
|
||||||
|
CC = gcc # Use MinGW gcc compiler
|
||||||
|
CFLAGS += -lws2_32 # Link against Winsock library
|
||||||
|
DELETE = cmd /C del /Q /F /S # Command prompt command to delete files
|
||||||
|
OUT ?= -o $(PROG) # Build output
|
||||||
|
MAKE += WINDOWS=1 CC=$(CC)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq "$(SSL)" "OPENSSL"
|
all: $(PROG) # Default target. Build and run program
|
||||||
CFLAGS += -DMG_ENABLE_OPENSSL=1 -lssl -lcrypto
|
$(RUN) ./$(PROG) $(ARGS)
|
||||||
endif
|
|
||||||
|
|
||||||
all: $(PROG)
|
$(PROG): $(SOURCES) # Build program from sources
|
||||||
$(DEBUGGER) ./$(PROG) $(ARGS)
|
$(CC) $(SOURCES) $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA) $(OUT)
|
||||||
|
|
||||||
$(PROG): main.c
|
clean: # Cleanup. Delete built program and all build artifacts
|
||||||
$(CC) ../../mongoose.c -I../.. $(CFLAGS) $(EFLAGS) -o $(PROG) main.c
|
$(DELETE) $(PROG) *.o *.obj *.exe *.dSYM mbedtls
|
||||||
|
|
||||||
clean:
|
# see https://mongoose.ws/tutorials/tls/#how-to-build for TLS build options
|
||||||
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb
|
|
||||||
|
mbedtls: # Pull and build mbedTLS library
|
||||||
|
git clone --depth 1 -b v2.28.2 https://github.com/mbed-tls/mbedtls $@
|
||||||
|
$(MAKE) -C mbedtls/library
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
See detailed tutorial at https://mongoose.ws/tutorials/http-server/
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
// any other URI serves static files from s_root_dir
|
// any other URI serves static files from s_root_dir
|
||||||
//
|
//
|
||||||
// To enable SSL/TLS (using self-signed certificates in PEM files),
|
// To enable SSL/TLS (using self-signed certificates in PEM files),
|
||||||
// 1. make SSL=OPENSSL or make SSL=MBEDTLS
|
// 1. See https://mongoose.ws/tutorials/tls/#how-to-build
|
||||||
// 2. curl -k https://127.0.0.1:8443
|
// 2. curl -k https://127.0.0.1:8443
|
||||||
|
|
||||||
#include "mongoose.h"
|
#include "mongoose.h"
|
||||||
@@ -35,12 +35,12 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|||||||
mg_printf(c, "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
|
mg_printf(c, "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
|
||||||
mg_http_printf_chunk(c, "ID PROTO TYPE LOCAL REMOTE\n");
|
mg_http_printf_chunk(c, "ID PROTO TYPE LOCAL REMOTE\n");
|
||||||
for (struct mg_connection *t = c->mgr->conns; t != NULL; t = t->next) {
|
for (struct mg_connection *t = c->mgr->conns; t != NULL; t = t->next) {
|
||||||
mg_http_printf_chunk(c, "%-3lu %4s %s %I %I\n", t->id,
|
mg_http_printf_chunk(c, "%-3lu %4s %s %M %M\n", t->id,
|
||||||
t->is_udp ? "UDP" : "TCP",
|
t->is_udp ? "UDP" : "TCP",
|
||||||
t->is_listening ? "LISTENING"
|
t->is_listening ? "LISTENING"
|
||||||
: t->is_accepted ? "ACCEPTED "
|
: t->is_accepted ? "ACCEPTED "
|
||||||
: "CONNECTED",
|
: "CONNECTED",
|
||||||
4, &t->loc.ip, 4, &t->rem.ip);
|
mg_print_ip, &t->loc, mg_print_ip, &t->rem);
|
||||||
}
|
}
|
||||||
mg_http_printf_chunk(c, ""); // Don't forget the last empty chunk
|
mg_http_printf_chunk(c, ""); // Don't forget the last empty chunk
|
||||||
} else if (mg_http_match_uri(hm, "/api/f2/*")) {
|
} else if (mg_http_match_uri(hm, "/api/f2/*")) {
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
../../mongoose.c
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../../mongoose.h
|
||||||
@@ -1,21 +1,32 @@
|
|||||||
PROG ?= example
|
PROG ?= example # Program we are building
|
||||||
CFLAGS ?= -DMG_IO_SIZE=128
|
DELETE = rm -rf # Command to remove files
|
||||||
SSL = ?
|
OUT ?= -o $(PROG) # Compiler argument for output file
|
||||||
|
SOURCES = main.c mongoose.c # Source code files
|
||||||
|
CFLAGS = -W -Wall -Wextra -g -I. # Build options
|
||||||
|
|
||||||
ifeq "$(SSL)" "MBEDTLS"
|
# Mongoose build options. See https://mongoose.ws/documentation/#build-options
|
||||||
CFLAGS += -DMG_ENABLE_MBEDTLS=1 -lmbedtls -lmbedcrypto -lmbedx509
|
CFLAGS_MONGOOSE += -DMG_IO_SIZE=128 -DMG_ENABLE_LINES=1
|
||||||
|
|
||||||
|
ifeq ($(OS),Windows_NT) # Windows settings. Assume MinGW compiler. To use VC: make CC=cl CFLAGS=/MD OUT=/Feprog.exe
|
||||||
|
PROG ?= example.exe # Use .exe suffix for the binary
|
||||||
|
CC = gcc # Use MinGW gcc compiler
|
||||||
|
CFLAGS += -lws2_32 # Link against Winsock library
|
||||||
|
DELETE = cmd /C del /Q /F /S # Command prompt command to delete files
|
||||||
|
OUT ?= -o $(PROG) # Build output
|
||||||
|
MAKE += WINDOWS=1 CC=$(CC)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq "$(SSL)" "OPENSSL"
|
all: $(PROG) # Default target. Build and run program
|
||||||
CFLAGS += -DMG_ENABLE_OPENSSL=1 -lssl -lcrypto
|
$(RUN) ./$(PROG) $(ARGS)
|
||||||
endif
|
|
||||||
|
|
||||||
all: $(PROG)
|
$(PROG): $(SOURCES) # Build program from sources
|
||||||
$(DEBUGGER) ./$(PROG) $(ARGS)
|
$(CC) $(SOURCES) $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA) $(OUT)
|
||||||
|
|
||||||
|
clean: # Cleanup. Delete built program and all build artifacts
|
||||||
|
$(DELETE) $(PROG) *.o *.obj *.exe *.dSYM mbedtls
|
||||||
|
|
||||||
$(PROG): main.c
|
# see https://mongoose.ws/tutorials/tls/#how-to-build for TLS build options
|
||||||
$(CC) ../../mongoose.c -I../.. -W -Wall $(CFLAGS) $(EXTRA_CFLAGS) -o $(PROG) main.c
|
|
||||||
|
|
||||||
clean:
|
mbedtls: # Pull and build mbedTLS library
|
||||||
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb
|
git clone --depth 1 -b v2.28.2 https://github.com/mbed-tls/mbedtls $@
|
||||||
|
$(MAKE) -C mbedtls/library
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
See detailed tutorial at https://mongoose.ws/tutorials/http-reverse-proxy/
|
||||||
@@ -5,18 +5,18 @@
|
|||||||
// 1. Run `make`. This builds and starts a proxy on port 8000
|
// 1. Run `make`. This builds and starts a proxy on port 8000
|
||||||
// 2. Start your browser, go to https://localhost:8000
|
// 2. Start your browser, go to https://localhost:8000
|
||||||
//
|
//
|
||||||
// To enable SSL/TLS, add SSL=OPENSSL or SSL=MBEDTLS
|
// To enable SSL/TLS, see https://mongoose.ws/tutorials/tls/#how-to-build
|
||||||
|
|
||||||
|
#include "mongoose.h"
|
||||||
|
|
||||||
static const char *s_backend_url =
|
static const char *s_backend_url =
|
||||||
#if defined(MG_ENABLE_MBEDTLS) || defined(MG_ENABLE_OPENSSL)
|
#if MG_ENABLE_MBEDTLS || MG_ENABLE_OPENSSL
|
||||||
"https://cesanta.com";
|
"https://cesanta.com";
|
||||||
#else
|
#else
|
||||||
"http://info.cern.ch";
|
"http://info.cern.ch";
|
||||||
#endif
|
#endif
|
||||||
static const char *s_listen_url = "http://localhost:8000";
|
static const char *s_listen_url = "http://localhost:8000";
|
||||||
|
|
||||||
#include "mongoose.h"
|
|
||||||
|
|
||||||
// Forward client request to the backend connection, rewriting the Host header
|
// Forward client request to the backend connection, rewriting the Host header
|
||||||
static void forward_request(struct mg_http_message *hm,
|
static void forward_request(struct mg_http_message *hm,
|
||||||
struct mg_connection *c) {
|
struct mg_connection *c) {
|
||||||
@@ -64,6 +64,7 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|||||||
}
|
}
|
||||||
c->fn_data = c2;
|
c->fn_data = c2;
|
||||||
forward_request(hm, c2);
|
forward_request(hm, c2);
|
||||||
|
c->is_resp = 0; // process further msgs in keep-alive connection
|
||||||
c2->is_hexdumping = 1;
|
c2->is_hexdumping = 1;
|
||||||
}
|
}
|
||||||
} else if (ev == MG_EV_CLOSE) {
|
} else if (ev == MG_EV_CLOSE) {
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
../../mongoose.c
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../../mongoose.h
|
||||||
@@ -1,21 +1,26 @@
|
|||||||
PROG ?= example
|
PROG ?= example # Program we are building
|
||||||
ROOT ?= $(realpath $(CURDIR)/../..)
|
DELETE = rm -rf # Command to remove files
|
||||||
DEFS ?= -DMG_ENABLE_LINES=1 -DMG_ENABLE_IPV6=1 -DMG_ENABLE_SSI=1 -DMG_HTTP_DIRLIST_TIME=1
|
OUT ?= -o $(PROG) # Compiler argument for output file
|
||||||
CFLAGS ?= -I../.. -W -Wall $(DEFS) $(EXTRA)
|
SOURCES = main.c mongoose.c # Source code files
|
||||||
VCFLAGS = /nologo /W3 /O2 /I../.. $(DEFS) $(EXTRA) /link /incremental:no /machine:IX86
|
CFLAGS = -W -Wall -Wextra -g -I. # Build options
|
||||||
VC98 = docker run -it --rm -e Tmp=. -v $(ROOT):$(ROOT) -w $(CURDIR) mdashnet/vc98
|
|
||||||
|
|
||||||
all: $(PROG)
|
# Mongoose build options. See https://mongoose.ws/documentation/#build-options
|
||||||
|
CFLAGS_MONGOOSE += -DMG_HTTP_DIRLIST_TIME_FMT="%Y/%m/%d %H:%M:%S"
|
||||||
|
CFLAGS_MONGOOSE += -DMG_ENABLE_LINES=1 -DMG_ENABLE_IPV6=1 -DMG_ENABLE_SSI=1
|
||||||
|
|
||||||
|
ifeq ($(OS),Windows_NT) # Windows settings. Assume MinGW compiler. To use VC: make CC=cl CFLAGS=/MD OUT=/Feprog.exe
|
||||||
|
PROG ?= example.exe # Use .exe suffix for the binary
|
||||||
|
CC = gcc # Use MinGW gcc compiler
|
||||||
|
CFLAGS += -lws2_32 # Link against Winsock library
|
||||||
|
DELETE = cmd /C del /Q /F /S # Command prompt command to delete files
|
||||||
|
OUT ?= -o $(PROG) # Build output
|
||||||
|
endif
|
||||||
|
|
||||||
|
all: $(PROG) # Default target. Build and run program
|
||||||
$(RUN) ./$(PROG) $(ARGS)
|
$(RUN) ./$(PROG) $(ARGS)
|
||||||
|
|
||||||
$(PROG): main.c Makefile
|
$(PROG): $(SOURCES) # Build program from sources
|
||||||
$(CC) ../../mongoose.c main.c -I../.. $(CFLAGS) -o $@
|
$(CC) $(SOURCES) $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA) $(OUT)
|
||||||
|
|
||||||
mongoose.exe: main.c
|
clean: # Cleanup. Delete built program and all build artifacts
|
||||||
$(VC98) wine cl ../../mongoose.c main.c $(VCFLAGS) ws2_32.lib /out:$@
|
$(DELETE) $(PROG) *.o *.obj *.exe *.dSYM
|
||||||
|
|
||||||
mingw:
|
|
||||||
gcc ../../mongoose.c main.c -I../.. -W -Wall $(DEFS) -D_POSIX_C_SOURCE=200000L -lws2_32 -o mongoose.exe
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb mongoose mongoose_* mongoose.*
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../../mongoose.c
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../../mongoose.h
|
||||||
@@ -1,22 +1,32 @@
|
|||||||
PROG ?= example
|
PROG ?= example # Program we are building
|
||||||
CFLAGS ?= -DMG_ENABLE_LINES $(EXTRA)
|
DELETE = rm -rf # Command to remove files
|
||||||
|
OUT ?= -o $(PROG) # Compiler argument for output file
|
||||||
|
SOURCES = main.c mongoose.c # Source code files
|
||||||
|
CFLAGS = -W -Wall -Wextra -g -I. # Build options
|
||||||
|
|
||||||
ifneq ($(MBEDTLS),)
|
# Mongoose build options. See https://mongoose.ws/documentation/#build-options
|
||||||
CFLAGS += -DMG_ENABLE_MBEDTLS=1 -I$(MBEDTLS)/include -I/usr/include
|
CFLAGS_MONGOOSE += -DMG_ENABLE_LINES=1
|
||||||
CFLAGS += -L$(MBEDTLS)/lib -lmbedtls -lmbedcrypto -lmbedx509
|
|
||||||
|
ifeq ($(OS),Windows_NT) # Windows settings. Assume MinGW compiler. To use VC: make CC=cl CFLAGS=/MD OUT=/Feprog.exe
|
||||||
|
PROG ?= example.exe # Use .exe suffix for the binary
|
||||||
|
CC = gcc # Use MinGW gcc compiler
|
||||||
|
CFLAGS += -lws2_32 # Link against Winsock library
|
||||||
|
DELETE = cmd /C del /Q /F /S # Command prompt command to delete files
|
||||||
|
OUT ?= -o $(PROG) # Build output
|
||||||
|
MAKE += WINDOWS=1 CC=$(CC)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(OPENSSL),)
|
all: $(PROG) # Default target. Build and run program
|
||||||
CFLAGS += -DMG_ENABLE_OPENSSL=1 -I$(OPENSSL)/include
|
$(RUN) ./$(PROG) $(ARGS)
|
||||||
CFLAGS += -L$(OPENSSL)/lib -lssl -lcrypto
|
|
||||||
endif
|
|
||||||
|
|
||||||
all: $(PROG)
|
$(PROG): $(SOURCES) # Build program from sources
|
||||||
$(DEBUGGER) ./$(PROG) $(ARGS)
|
$(CC) $(SOURCES) $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA) $(OUT)
|
||||||
|
|
||||||
|
clean: # Cleanup. Delete built program and all build artifacts
|
||||||
|
$(DELETE) $(PROG) *.o *.obj *.exe *.dSYM mbedtls
|
||||||
|
|
||||||
$(PROG): main.c
|
# see https://mongoose.ws/tutorials/tls/#how-to-build for TLS build options
|
||||||
$(CC) ../../mongoose.c -I../.. -W -Wall $(CFLAGS) -o $(PROG) main.c
|
|
||||||
|
|
||||||
clean:
|
mbedtls: # Pull and build mbedTLS library
|
||||||
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb
|
git clone --depth 1 -b v2.28.2 https://github.com/mbed-tls/mbedtls $@
|
||||||
|
$(MAKE) -C mbedtls/library
|
||||||
@@ -9,9 +9,7 @@
|
|||||||
//
|
//
|
||||||
// You can change `s_url` from the command line by executing: ./example YOUR_URL
|
// You can change `s_url` from the command line by executing: ./example YOUR_URL
|
||||||
//
|
//
|
||||||
// To enable SSL/TLS for this client, build it like this:
|
// To enable SSL/TLS, see https://mongoose.ws/tutorials/tls/#how-to-build
|
||||||
// make MBEDTLS=/path/to/your/mbedtls/installation
|
|
||||||
// make OPENSSL=/path/to/your/openssl/installation
|
|
||||||
|
|
||||||
#include "mongoose.h"
|
#include "mongoose.h"
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
../../mongoose.c
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../../mongoose.h
|
||||||
@@ -1,11 +1,25 @@
|
|||||||
PROG ?= example
|
PROG ?= example # Program we are building
|
||||||
CFLAGS ?= -W -Wall -Wextra -O0 -g
|
DELETE = rm -rf # Command to remove files
|
||||||
|
OUT ?= -o $(PROG) # Compiler argument for output file
|
||||||
|
SOURCES = main.c mongoose.c # Source code files
|
||||||
|
CFLAGS = -W -Wall -Wextra -g -I. # Build options
|
||||||
|
|
||||||
all: $(PROG)
|
# Mongoose build options. See https://mongoose.ws/documentation/#build-options
|
||||||
|
CFLAGS_MONGOOSE += -DMG_ENABLE_LINES=1
|
||||||
|
|
||||||
|
ifeq ($(OS),Windows_NT) # Windows settings. Assume MinGW compiler. To use VC: make CC=cl CFLAGS=/MD OUT=/Feprog.exe
|
||||||
|
PROG ?= example.exe # Use .exe suffix for the binary
|
||||||
|
CC = gcc # Use MinGW gcc compiler
|
||||||
|
CFLAGS += -lws2_32 # Link against Winsock library
|
||||||
|
DELETE = cmd /C del /Q /F /S # Command prompt command to delete files
|
||||||
|
OUT ?= -o $(PROG) # Build output
|
||||||
|
endif
|
||||||
|
|
||||||
|
all: $(PROG) # Default target. Build and run program
|
||||||
$(RUN) ./$(PROG) $(ARGS)
|
$(RUN) ./$(PROG) $(ARGS)
|
||||||
|
|
||||||
$(PROG): main.c
|
$(PROG): $(SOURCES) # Build program from sources
|
||||||
$(CC) ../../mongoose.c -I../.. -W -Wall -DMG_ENABLE_LINES=1 $(CFLAGS) -o $(PROG) main.c
|
$(CC) $(SOURCES) $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA) $(OUT)
|
||||||
|
|
||||||
clean:
|
clean: # Cleanup. Delete built program and all build artifacts
|
||||||
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb
|
$(DELETE) $(PROG) *.o *.obj *.exe *.dSYM
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
See detailed tutorial at https://mongoose.ws/tutorials/huge-response/
|
||||||
@@ -52,12 +52,13 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|||||||
if (version > 0 && version != s_version) {
|
if (version > 0 && version != s_version) {
|
||||||
// Version mismatch: s_data has changed while client fetches it
|
// Version mismatch: s_data has changed while client fetches it
|
||||||
// Tell client to restart
|
// Tell client to restart
|
||||||
mg_http_reply(c, 200, headers, "{%Q:%Q, %Q:%ld}", "error",
|
mg_http_reply(c, 200, headers, "{%m:%m, %m:%ld}", MG_ESC("error"),
|
||||||
"wrong version", "version", version);
|
MG_ESC("wrong version"), MG_ESC("version"), version);
|
||||||
} else {
|
} else {
|
||||||
// Return data, up to CHUNK_SIZE elements
|
// Return data, up to CHUNK_SIZE elements
|
||||||
mg_http_reply(c, 200, headers, "{%Q:%ld,%Q:%ld,%Q:[%M]}", "version",
|
mg_http_reply(c, 200, headers, "{%m:%ld,%m:%ld,%m:[%M]}",
|
||||||
s_version, "start", start, "data", printdata, start);
|
MG_ESC("version"), s_version, MG_ESC("start"), start,
|
||||||
|
MG_ESC("data"), printdata, start);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
struct mg_http_serve_opts opts = {0};
|
struct mg_http_serve_opts opts = {0};
|
||||||
|
|||||||