mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-10-18 11:09:39 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d92c314466 | ||
|
|
b747fb111d | ||
|
|
7e0a0b2d0c | ||
|
|
362d064afa | ||
|
|
1bd88de2e5 | ||
|
|
0b541ffebc | ||
|
|
106be19c3e | ||
|
|
25d72bf881 | ||
|
|
9d5b5297cc | ||
|
|
462884bebb | ||
|
|
b1cc24b795 | ||
|
|
f0eb55b327 | ||
|
|
6dc285b5ca | ||
|
|
07e614eef7 | ||
|
|
916b2a8fd3 | ||
|
|
869f5bb279 | ||
|
|
3e21338f82 | ||
|
|
37bb3c6a77 | ||
|
|
d4ab2fa0e6 | ||
|
|
72d3f4896a | ||
|
|
5e6f973b99 | ||
|
|
7ed77b02ad | ||
|
|
127a64d5a0 | ||
|
|
caa31aafda | ||
|
|
dae318495f | ||
|
|
305a7abcb9 | ||
|
|
219d13b718 | ||
|
|
df20c27696 | ||
|
|
a5a62768c0 | ||
|
|
4001637beb | ||
|
|
47044c05a8 | ||
|
|
a449d82723 | ||
|
|
fee8e97b4e | ||
|
|
72d9ed4056 | ||
|
|
1be1b3a86d |
No files matched your search
+4
-15
@@ -100,6 +100,7 @@ if (BUILD_SHARED_LIBS AND WIN32 AND HTTPLIB_COMPILE)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Threads needed for <thread> on some systems, and for <pthread.h> on Linux
|
# Threads needed for <thread> on some systems, and for <pthread.h> on Linux
|
||||||
|
set(THREADS_PREFER_PTHREAD_FLAG true)
|
||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
# Since Cmake v3.11, Crypto & SSL became optional when not specified as COMPONENTS.
|
# Since Cmake v3.11, Crypto & SSL became optional when not specified as COMPONENTS.
|
||||||
if(HTTPLIB_REQUIRE_OPENSSL)
|
if(HTTPLIB_REQUIRE_OPENSSL)
|
||||||
@@ -160,7 +161,7 @@ if(HTTPLIB_COMPILE)
|
|||||||
ERROR_VARIABLE _httplib_split_error
|
ERROR_VARIABLE _httplib_split_error
|
||||||
)
|
)
|
||||||
if(_httplib_split_error)
|
if(_httplib_split_error)
|
||||||
message(FATAL_ERROR "Failed when trying to split Cpp-httplib with the Python script.\n${_httplib_split_error}")
|
message(FATAL_ERROR "Failed when trying to split cpp-httplib with the Python script.\n${_httplib_split_error}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# split.py puts output in "out"
|
# split.py puts output in "out"
|
||||||
@@ -187,19 +188,9 @@ endif()
|
|||||||
# Only useful if building in-tree, versus using it from an installation.
|
# Only useful if building in-tree, versus using it from an installation.
|
||||||
add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
|
add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
|
||||||
|
|
||||||
# Might be missing some, but this list is somewhat comprehensive
|
# Require C++11
|
||||||
target_compile_features(${PROJECT_NAME} ${_INTERFACE_OR_PUBLIC}
|
target_compile_features(${PROJECT_NAME} ${_INTERFACE_OR_PUBLIC}
|
||||||
cxx_std_11
|
cxx_std_11
|
||||||
cxx_nullptr
|
|
||||||
cxx_lambdas
|
|
||||||
cxx_override
|
|
||||||
cxx_defaulted_functions
|
|
||||||
cxx_attribute_deprecated
|
|
||||||
cxx_auto_type
|
|
||||||
cxx_decltype
|
|
||||||
cxx_deleted_functions
|
|
||||||
cxx_range_for
|
|
||||||
cxx_sizeof_member
|
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(${PROJECT_NAME} ${_INTERFACE_OR_PUBLIC}
|
target_include_directories(${PROJECT_NAME} ${_INTERFACE_OR_PUBLIC}
|
||||||
@@ -274,11 +265,9 @@ endif()
|
|||||||
# and linkage information (doesn't find deps though).
|
# and linkage information (doesn't find deps though).
|
||||||
install(TARGETS ${PROJECT_NAME}
|
install(TARGETS ${PROJECT_NAME}
|
||||||
EXPORT httplibTargets
|
EXPORT httplibTargets
|
||||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|
||||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
install(FILES "${_httplib_build_includedir}/httplib.h" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
install(FILES "${_httplib_build_includedir}/httplib.h" TYPE INCLUDE)
|
||||||
|
|
||||||
install(FILES
|
install(FILES
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
|
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ A C++11 single-file header-only cross platform HTTP/HTTPS library.
|
|||||||
|
|
||||||
It's extremely easy to setup. Just include the **httplib.h** file in your code!
|
It's extremely easy to setup. Just include the **httplib.h** file in your code!
|
||||||
|
|
||||||
NOTE: This is a multi-threaded 'blocking' HTTP library. If you are looking for a 'non-blocking' library, this is not the one that you want.
|
NOTE: This library uses 'blocking' socket I/O. If you are looking for a library with 'non-blocking' socket I/O, this is not the one that you want.
|
||||||
|
|
||||||
Simple examples
|
Simple examples
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
#### Server
|
#### Server (Multi-threaded)
|
||||||
|
|
||||||
```c++
|
```c++
|
||||||
#define CPPHTTPLIB_OPENSSL_SUPPORT
|
#define CPPHTTPLIB_OPENSSL_SUPPORT
|
||||||
@@ -212,15 +212,23 @@ svr.set_error_handler([](const auto& req, auto& res) {
|
|||||||
The exception handler gets called if a user routing handler throws an error.
|
The exception handler gets called if a user routing handler throws an error.
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
svr.set_exception_handler([](const auto& req, auto& res, std::exception &e) {
|
svr.set_exception_handler([](const auto& req, auto& res, std::exception_ptr ep) {
|
||||||
res.status = 500;
|
|
||||||
auto fmt = "<h1>Error 500</h1><p>%s</p>";
|
auto fmt = "<h1>Error 500</h1><p>%s</p>";
|
||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
|
try {
|
||||||
|
std::rethrow_exception(ep);
|
||||||
|
} catch (std::exception &e) {
|
||||||
snprintf(buf, sizeof(buf), fmt, e.what());
|
snprintf(buf, sizeof(buf), fmt, e.what());
|
||||||
|
} catch (...) { // See the following NOTE
|
||||||
|
snprintf(buf, sizeof(buf), fmt, "Unknown Exception");
|
||||||
|
}
|
||||||
res.set_content(buf, "text/html");
|
res.set_content(buf, "text/html");
|
||||||
|
res.status = 500;
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
NOTE: if you don't provide the `catch (...)` block for a rethrown exception pointer, an uncaught exception will end up causing the server crash. Be careful!
|
||||||
|
|
||||||
### Pre routing handler
|
### Pre routing handler
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
@@ -435,7 +443,7 @@ int main(void)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto err = res.error();
|
auto err = res.error();
|
||||||
...
|
std::cout << "HTTP error: " << httplib::to_string(err) << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -468,7 +476,9 @@ enum Error {
|
|||||||
SSLConnection,
|
SSLConnection,
|
||||||
SSLLoadingCerts,
|
SSLLoadingCerts,
|
||||||
SSLServerVerification,
|
SSLServerVerification,
|
||||||
UnsupportedMultipartBoundaryChars
|
UnsupportedMultipartBoundaryChars,
|
||||||
|
Compression,
|
||||||
|
ConnectionTimeout,
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -799,12 +809,12 @@ Include `httplib.h` before `Windows.h` or include `Windows.h` by defining `WIN32
|
|||||||
|
|
||||||
Note: cpp-httplib officially supports only the latest Visual Studio. It might work with former versions of Visual Studio, but I can no longer verify it. Pull requests are always welcome for the older versions of Visual Studio unless they break the C++11 conformance.
|
Note: cpp-httplib officially supports only the latest Visual Studio. It might work with former versions of Visual Studio, but I can no longer verify it. Pull requests are always welcome for the older versions of Visual Studio unless they break the C++11 conformance.
|
||||||
|
|
||||||
Note: Windows 8 or lower and Cygwin on Windows are not supported.
|
Note: Windows 8 or lower, Visual Studio 2013 or lower, and Cygwin on Windows are not supported.
|
||||||
|
|
||||||
License
|
License
|
||||||
-------
|
-------
|
||||||
|
|
||||||
MIT license (© 2021 Yuji Hirose)
|
MIT license (© 2022 Yuji Hirose)
|
||||||
|
|
||||||
Special Thanks To
|
Special Thanks To
|
||||||
-----------------
|
-----------------
|
||||||
|
|||||||
+2
-3
@@ -19,7 +19,6 @@ project(
|
|||||||
# Check just in case downstream decides to edit the source
|
# Check just in case downstream decides to edit the source
|
||||||
# and add a project version
|
# and add a project version
|
||||||
version = meson.project_version()
|
version = meson.project_version()
|
||||||
python3 = find_program('python3')
|
|
||||||
if version == 'undefined'
|
if version == 'undefined'
|
||||||
cxx = meson.get_compiler('cpp')
|
cxx = meson.get_compiler('cpp')
|
||||||
version = cxx.get_define('CPPHTTPLIB_VERSION',
|
version = cxx.get_define('CPPHTTPLIB_VERSION',
|
||||||
@@ -28,8 +27,6 @@ if version == 'undefined'
|
|||||||
assert(version != '', 'failed to get version from httplib.h')
|
assert(version != '', 'failed to get version from httplib.h')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
message('cpp-httplib version ' + version)
|
|
||||||
|
|
||||||
deps = [dependency('threads')]
|
deps = [dependency('threads')]
|
||||||
args = []
|
args = []
|
||||||
|
|
||||||
@@ -64,6 +61,8 @@ endif
|
|||||||
cpp_httplib_dep = dependency('', required: false)
|
cpp_httplib_dep = dependency('', required: false)
|
||||||
|
|
||||||
if get_option('cpp-httplib_compile')
|
if get_option('cpp-httplib_compile')
|
||||||
|
python3 = find_program('python3')
|
||||||
|
|
||||||
httplib_ch = custom_target(
|
httplib_ch = custom_target(
|
||||||
'split',
|
'split',
|
||||||
input: 'httplib.h',
|
input: 'httplib.h',
|
||||||
|
|||||||
+1
-1
@@ -5,5 +5,5 @@
|
|||||||
option('cpp-httplib_openssl', type: 'feature', value: 'auto', description: 'Enable OpenSSL support')
|
option('cpp-httplib_openssl', type: 'feature', value: 'auto', description: 'Enable OpenSSL support')
|
||||||
option('cpp-httplib_zlib', type: 'feature', value: 'auto', description: 'Enable zlib support')
|
option('cpp-httplib_zlib', type: 'feature', value: 'auto', description: 'Enable zlib support')
|
||||||
option('cpp-httplib_brotli', type: 'feature', value: 'auto', description: 'Enable Brotli support')
|
option('cpp-httplib_brotli', type: 'feature', value: 'auto', description: 'Enable Brotli support')
|
||||||
option('cpp-httplib_compile', type: 'boolean', value: false, description: 'Split the header into a compilable header & source file')
|
option('cpp-httplib_compile', type: 'boolean', value: false, description: 'Split the header into a compilable header & source file (requires python3)')
|
||||||
option('cpp-httplib_test', type: 'boolean', value: false, description: 'Build tests')
|
option('cpp-httplib_test', type: 'boolean', value: false, description: 'Build tests')
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
CXX = clang++
|
CXX = clang++
|
||||||
CXXFLAGS = -g -std=c++11 -I. -Wall -Wextra -Wtype-limits -Wconversion # -fno-exceptions -DCPPHTTPLIB_NO_EXCEPTIONS -fsanitize=address
|
CXXFLAGS = -g -std=c++11 -I. -Wall -Wextra -Wtype-limits -Wconversion -Wshadow # -fno-exceptions -DCPPHTTPLIB_NO_EXCEPTIONS -fsanitize=address
|
||||||
|
|
||||||
PREFIX = /usr/local
|
PREFIX = /usr/local
|
||||||
#PREFIX = $(shell brew --prefix)
|
#PREFIX = $(shell brew --prefix)
|
||||||
|
|||||||
Binary file not shown.
@@ -0,0 +1,19 @@
|
|||||||
|
POST /fform%u008ano栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽栽Line truncated
|
||||||
|
Don | ||||||