Privately introducing QDecompressHelper for network purposes

To support streaming decompression in QNAM.
Will also be used to refactor existing decompression code in QNAM.

Task-number: QTBUG-83269
Change-Id: Iecf3e359734163f15686c949f75d41fa4794a00e
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Mårten Nordheim 2020-04-09 13:23:42 +02:00
parent c8db3115a2
commit 07b008425a
20 changed files with 3027 additions and 2 deletions

View File

@ -100,6 +100,7 @@ qt_extend_target(Network CONDITION WASM
qt_extend_target(Network CONDITION QT_FEATURE_http
SOURCES
access/qdecompresshelper.cpp access/qdecompresshelper_p.h
access/http2/bitstreams.cpp access/http2/bitstreams_p.h
access/http2/hpack.cpp access/http2/hpack_p.h
access/http2/hpacktable.cpp access/http2/hpacktable_p.h

View File

@ -100,6 +100,7 @@ qt_extend_target(Network CONDITION WASM
qt_extend_target(Network CONDITION QT_FEATURE_http
SOURCES
access/qdecompresshelper.cpp access/qdecompresshelper_p.h
access/http2/bitstreams.cpp access/http2/bitstreams_p.h
access/http2/hpack.cpp access/http2/hpack_p.h
access/http2/hpacktable.cpp access/http2/hpacktable_p.h

View File

@ -87,6 +87,7 @@ qtConfig(http) {
include($$PWD/http2/http2.pri)
SOURCES += \
access/qdecompresshelper.cpp \
access/qabstractprotocolhandler.cpp \
access/qhttp2protocolhandler.cpp \
access/qhttpmultipart.cpp \
@ -101,6 +102,7 @@ qtConfig(http) {
access/qhttp2configuration.cpp
HEADERS += \
access/qdecompresshelper_p.h \
access/qabstractprotocolhandler_p.h \
access/qhttp2protocolhandler_p.h \
access/qhttpmultipart.h \

View File

@ -0,0 +1,479 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtNetwork module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qdecompresshelper_p.h"
#include <QtCore/private/qbytearray_p.h>
#include <QtCore/qiodevice.h>
#include <zlib.h>
#include <array>
QT_BEGIN_NAMESPACE
namespace {
struct ContentEncodingMapping
{
char name[8];
QDecompressHelper::ContentEncoding encoding;
};
constexpr ContentEncodingMapping contentEncodingMapping[] {
{ "deflate", QDecompressHelper::Deflate },
{ "gzip", QDecompressHelper::GZip },
};
QDecompressHelper::ContentEncoding encodingFromByteArray(const QByteArray &ce) noexcept
{
for (const auto &mapping : contentEncodingMapping) {
if (ce.compare(QByteArrayView(mapping.name, strlen(mapping.name)), Qt::CaseInsensitive) == 0)
return mapping.encoding;
}
return QDecompressHelper::None;
}
z_stream *toZlibPointer(void *ptr)
{
return static_cast<z_stream_s *>(ptr);
}
}
bool QDecompressHelper::isSupportedEncoding(const QByteArray &encoding)
{
return encodingFromByteArray(encoding) != QDecompressHelper::None;
}
QDecompressHelper::~QDecompressHelper()
{
clear();
}
bool QDecompressHelper::setEncoding(const QByteArray &encoding)
{
Q_ASSERT(contentEncoding == QDecompressHelper::None);
if (contentEncoding != QDecompressHelper::None) {
qWarning("Encoding is already set.");
return false;
}
ContentEncoding ce = encodingFromByteArray(encoding);
if (ce == None) {
qWarning("An unsupported content encoding was selected: %s", encoding.data());
return false;
}
return setEncoding(ce);
}
bool QDecompressHelper::setEncoding(ContentEncoding ce)
{
Q_ASSERT(contentEncoding == None);
contentEncoding = ce;
switch (contentEncoding) {
case None:
Q_UNREACHABLE();
break;
case Deflate:
case GZip: {
z_stream *inflateStream = new z_stream;
memset(inflateStream, 0, sizeof(z_stream));
// "windowBits can also be greater than 15 for optional gzip decoding.
// Add 32 to windowBits to enable zlib and gzip decoding with automatic header detection"
// http://www.zlib.net/manual.html
if (inflateInit2(inflateStream, MAX_WBITS + 32) != Z_OK) {
delete inflateStream;
inflateStream = nullptr;
}
decoderPointer = inflateStream;
break;
}
}
if (!decoderPointer) {
qWarning("Failed to initialize the decoder.");
contentEncoding = QDecompressHelper::None;
return false;
}
return true;
}
/*!
\internal
Returns true if the QDecompressHelper is measuring the
size of the decompressed data.
\sa setCountingBytesEnabled, uncompressedSize
*/
bool QDecompressHelper::isCountingBytes() const
{
return countDecompressed;
}
/*!
\internal
Enable or disable counting the decompressed size of the data
based on \a shouldCount. Enabling this means the data will be
decompressed twice (once for counting and once when data is
being read).
\note Can only be called before contentEncoding is set and data
is fed to the object.
\sa isCountingBytes, uncompressedSize
*/
void QDecompressHelper::setCountingBytesEnabled(bool shouldCount)
{
// These are a best-effort check to ensure that no data has already been processed before this
// gets enabled
Q_ASSERT(compressedDataBuffer.byteAmount() == 0);
Q_ASSERT(contentEncoding == None);
countDecompressed = shouldCount;
}
/*!
\internal
Returns the amount of uncompressed bytes left.
\note Since this is only based on the data received
so far the final size could be larger.
\note It is only valid to call this if isCountingBytes()
returns true
\sa isCountingBytes, setCountBytes
*/
qint64 QDecompressHelper::uncompressedSize() const
{
Q_ASSERT(countDecompressed);
return uncompressedBytes;
}
/*!
\internal
\overload
*/
void QDecompressHelper::feed(const QByteArray &data)
{
return feed(QByteArray(data));
}
/*!
\internal
Give \a data to the QDecompressHelper which will be stored until
a read is attempted.
If \c isCountingBytes() is true then it will decompress immediately
before discarding the data, but will count the uncompressed byte
size.
*/
void QDecompressHelper::feed(QByteArray &&data)
{
Q_ASSERT(contentEncoding != None);
if (!countInternal(data))
clear(); // If our counting brother failed then so will we :|
else
compressedDataBuffer.append(std::move(data));
}
/*!
\internal
\overload
*/
void QDecompressHelper::feed(const QByteDataBuffer &buffer)
{
Q_ASSERT(contentEncoding != None);
if (!countInternal(buffer))
clear(); // If our counting brother failed then so will we :|
else
compressedDataBuffer.append(buffer);
}
/*!
\internal
\overload
*/
void QDecompressHelper::feed(QByteDataBuffer &&buffer)
{
Q_ASSERT(contentEncoding != None);
if (!countInternal(buffer))
clear(); // If our counting brother failed then so will we :|
else
compressedDataBuffer.append(std::move(buffer));
}
/*!
\internal
Decompress the data internally and immediately discard the
uncompressed data, but count how many bytes were decoded.
This lets us know the final size, unfortunately at the cost of
increased computation.
Potential @future improvement:
Decompress XX MiB/KiB before starting the count.
For smaller files the extra decompression can then be avoided.
*/
bool QDecompressHelper::countInternal()
{
Q_ASSERT(countDecompressed);
while (countHelper->hasData()) {
std::array<char, 1024> temp;
qsizetype bytesRead = countHelper->read(temp.data(), temp.size());
if (bytesRead == -1)
return false;
uncompressedBytes += bytesRead;
}
return true;
}
/*!
\internal
\overload
*/
bool QDecompressHelper::countInternal(const QByteArray &data)
{
if (countDecompressed) {
if (!countHelper) {
countHelper = std::make_unique<QDecompressHelper>();
countHelper->setEncoding(contentEncoding);
}
countHelper->feed(data);
return countInternal();
}
return true;
}
/*!
\internal
\overload
*/
bool QDecompressHelper::countInternal(const QByteDataBuffer &buffer)
{
if (countDecompressed) {
if (!countHelper) {
countHelper = std::make_unique<QDecompressHelper>();
countHelper->setEncoding(contentEncoding);
}
countHelper->feed(buffer);
return countInternal();
}
return true;
}
qsizetype QDecompressHelper::read(char *data, qsizetype maxSize)
{
if (!isValid())
return -1;
qsizetype bytesRead = -1;
if (!hasData())
return 0;
switch (contentEncoding) {
case None:
Q_UNREACHABLE();
break;
case Deflate:
case GZip:
bytesRead = readZLib(data, maxSize);
break;
}
if (bytesRead == -1)
clear();
else if (countDecompressed)
uncompressedBytes -= bytesRead;
return bytesRead;
}
/*!
\internal
Returns true if there are encoded bytes left or there is some
indication that the decoder still has data left internally.
\note Even if this returns true the next call to read() might
read 0 bytes. This most likely means the decompression is done.
*/
bool QDecompressHelper::hasData() const
{
return encodedBytesAvailable() || decoderHasData;
}
qint64 QDecompressHelper::encodedBytesAvailable() const
{
return compressedDataBuffer.byteAmount();
}
bool QDecompressHelper::isValid() const
{
return contentEncoding != None;
}
void QDecompressHelper::clear()
{
switch (contentEncoding) {
case None:
break;
case Deflate:
case GZip: {
z_stream *inflateStream = toZlibPointer(decoderPointer);
if (inflateStream)
inflateEnd(inflateStream);
delete inflateStream;
break;
}
}
decoderPointer = nullptr;
contentEncoding = None;
compressedDataBuffer.clear();
decoderHasData = false;
countDecompressed = false;
countHelper.reset();
uncompressedBytes = 0;
}
qsizetype QDecompressHelper::readZLib(char *data, const qsizetype maxSize)
{
bool triedRawDeflate = false;
z_stream *inflateStream = toZlibPointer(decoderPointer);
static const size_t zlibMaxSize =
size_t(std::numeric_limits<decltype(inflateStream->avail_in)>::max());
QByteArray input;
if (!compressedDataBuffer.isEmpty()) {
if (zlibMaxSize < size_t(compressedDataBuffer.sizeNextBlock()))
input = compressedDataBuffer.read(zlibMaxSize);
else
input = compressedDataBuffer.read();
}
inflateStream->avail_in = input.size();
inflateStream->next_in = reinterpret_cast<Bytef *>(input.data());
bool bigMaxSize = (zlibMaxSize < size_t(maxSize));
qsizetype adjustedAvailableOut = bigMaxSize ? qsizetype(zlibMaxSize) : maxSize;
inflateStream->avail_out = adjustedAvailableOut;
inflateStream->next_out = reinterpret_cast<Bytef *>(data);
qsizetype bytesDecoded = 0;
do {
auto previous_avail_out = inflateStream->avail_out;
int ret = inflate(inflateStream, Z_NO_FLUSH);
// All negative return codes are errors, in the context of HTTP compression, Z_NEED_DICT is
// also an error.
// in the case where we get Z_DATA_ERROR this could be because we received raw deflate
// compressed data.
if (ret == Z_DATA_ERROR && !triedRawDeflate) {
inflateEnd(inflateStream);
triedRawDeflate = true;
inflateStream->zalloc = Z_NULL;
inflateStream->zfree = Z_NULL;
inflateStream->opaque = Z_NULL;
inflateStream->avail_in = 0;
inflateStream->next_in = Z_NULL;
int ret = inflateInit2(inflateStream, -MAX_WBITS);
if (ret != Z_OK) {
return -1;
} else {
inflateStream->avail_in = input.size();
inflateStream->next_in = reinterpret_cast<Bytef *>(input.data());
continue;
}
} else if (ret < 0 || ret == Z_NEED_DICT) {
return -1;
}
bytesDecoded += qsizetype(previous_avail_out - inflateStream->avail_out);
if (ret == Z_STREAM_END) {
// If there's more data after the stream then this is probably composed of multiple
// streams.
if (inflateStream->avail_in != 0) {
inflateEnd(inflateStream);
Bytef *next_in = inflateStream->next_in;
uInt avail_in = inflateStream->avail_in;
inflateStream->zalloc = Z_NULL;
inflateStream->zfree = Z_NULL;
inflateStream->opaque = Z_NULL;
if (inflateInit2(inflateStream, MAX_WBITS + 32) != Z_OK) {
delete inflateStream;
decoderPointer = nullptr;
// Failed to reinitialize, so we'll just return what we have
return bytesDecoded;
} else {
inflateStream->next_in = next_in;
inflateStream->avail_in = avail_in;
// Keep going to handle the other cases below
}
} else {
// No extra data, stream is at the end. We're done.
return bytesDecoded;
}
}
if (bigMaxSize && inflateStream->avail_out == 0) {
// Need to adjust the next_out and avail_out parameters since we reached the end
// of the current range
bigMaxSize = (zlibMaxSize < size_t(maxSize - bytesDecoded));
inflateStream->avail_out = bigMaxSize ? qsizetype(zlibMaxSize) : maxSize - bytesDecoded;
inflateStream->next_out = reinterpret_cast<Bytef *>(data + bytesDecoded);
}
if (inflateStream->avail_in == 0 && inflateStream->avail_out > 0
&& !compressedDataBuffer.isEmpty()) {
// Grab the next input!
if (zlibMaxSize < size_t(compressedDataBuffer.sizeNextBlock()))
input = compressedDataBuffer.read(zlibMaxSize);
else
input = compressedDataBuffer.read();
inflateStream->avail_in = input.size();
inflateStream->next_in = reinterpret_cast<Bytef *>(input.data());
}
} while (inflateStream->avail_out > 0 && inflateStream->avail_in > 0);
if (inflateStream->avail_in) {
// Some input was left unused; move back to the buffer
input = input.right(inflateStream->avail_in);
compressedDataBuffer.prepend(input);
}
return bytesDecoded;
}
QT_END_NAMESPACE

View File

@ -0,0 +1,118 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtNetwork module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef DECOMPRESS_HELPER_P_H
#define DECOMPRESS_HELPER_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists for the convenience
// of the Network Access API. This header file may change from
// version to version without notice, or even be removed.
//
// We mean it.
//
#include <QtNetwork/private/qtnetworkglobal_p.h>
#include <QtCore/private/qbytedata_p.h>
#include <memory>
QT_BEGIN_NAMESPACE
class QIODevice;
class Q_AUTOTEST_EXPORT QDecompressHelper
{
public:
enum ContentEncoding {
None,
Deflate,
GZip,
};
QDecompressHelper() = default;
~QDecompressHelper();
bool setEncoding(const QByteArray &contentEncoding);
bool isCountingBytes() const;
void setCountingBytesEnabled(bool shouldCount);
qint64 uncompressedSize() const;
bool hasData() const;
void feed(const QByteArray &data);
void feed(QByteArray &&data);
void feed(const QByteDataBuffer &buffer);
void feed(QByteDataBuffer &&buffer);
qsizetype read(char *data, qsizetype maxSize);
bool isValid() const;
void clear();
static bool isSupportedEncoding(const QByteArray &encoding);
private:
bool countInternal();
bool countInternal(const QByteArray &data);
bool countInternal(const QByteDataBuffer &buffer);
bool setEncoding(ContentEncoding ce);
qint64 encodedBytesAvailable() const;
qsizetype readZLib(char *data, qsizetype maxSize);
QByteDataBuffer compressedDataBuffer;
bool decoderHasData = false;
bool countDecompressed = false;
std::unique_ptr<QDecompressHelper> countHelper;
qint64 uncompressedBytes = 0;
ContentEncoding contentEncoding = None;
void *decoderPointer = nullptr;
};
QT_END_NAMESPACE
#endif // DECOMPRESS_HELPER_P_H

View File

@ -14,6 +14,7 @@ if(QT_FEATURE_private_tests)
add_subdirectory(hpack)
add_subdirectory(http2)
add_subdirectory(hsts)
add_subdirectory(qdecompresshelper)
endif()
if(QT_FEATURE_ftp AND QT_FEATURE_private_tests)
add_subdirectory(qftp)

View File

@ -14,13 +14,15 @@ SUBDIRS=\
qabstractnetworkcache \
hpack \
http2 \
hsts
hsts \
qdecompresshelper
!qtConfig(private_tests): SUBDIRS -= \
qhttpnetworkconnection \
qhttpnetworkreply \
hpack \
http2 \
hsts
hsts \
qdecompresshelper
qtConfig(ftp): qtConfig(private_tests): SUBDIRS += qftp

View File

@ -0,0 +1,19 @@
# Generated from qdecompresshelper.pro.
#####################################################################
## tst_qdecompresshelper Test:
#####################################################################
qt_add_test(tst_qdecompresshelper
SOURCES
gzip.rcc.cpp
inflate.rcc.cpp
tst_qdecompresshelper.cpp
DEFINES
SRC_DIR="${CMAKE_CURRENT_SOURCE_DIR}"
PUBLIC_LIBRARIES
Qt::NetworkPrivate
)
#### Keys ignored in scope 1:.:.:qdecompresshelper.pro:<TRUE>:
# TEMPLATE = "app"

View File

@ -0,0 +1,19 @@
# Generated from qdecompresshelper.pro.
#####################################################################
## tst_qdecompresshelper Test:
#####################################################################
qt_add_test(tst_qdecompresshelper
SOURCES
gzip.rcc.cpp
inflate.rcc.cpp
tst_qdecompresshelper.cpp
DEFINES
SRC_DIR=${CMAKE_CURRENT_SOURCE_DIR} # special case
PUBLIC_LIBRARIES
Qt::NetworkPrivate
)
#### Keys ignored in scope 1:.:.:qdecompresshelper.pro:<TRUE>:
# TEMPLATE = "app"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,617 @@
/****************************************************************************
** Resource object code
**
** Created by: The Resource Compiler for Qt version 6.0.0
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/
static const unsigned char qt_resource_data[] = {
// D:/projects/qt/dev/src/qtbase/tests/auto/network/access/qdecompresshelper/5GiB.txt.inflate
0x0,0x0,0x20,0xca,
0x0,
0x4f,0x9f,0x57,0x78,0xda,0xec,0xdc,0x3d,0x2e,0x44,0x1,0x18,0x86,0xd1,0x3b,0x31,
0x85,0x28,0xfc,0x14,0x2a,0x8d,0x65,0x68,0x24,0x34,0x6a,0x5,0xb5,0x58,0x80,0x5e,
0x67,0x12,0xd1,0x5b,0x80,0x3d,0x4c,0x65,0x1,0x3a,0x3b,0x40,0x67,0x1,0xa2,0x50,
0xa8,0xc4,0x88,0xbb,0x8c,0xfb,0x9c,0xb3,0x84,0xb7,0xfc,0xf2,0xe5,0xb9,0x7e,0xf8,
0x78,0x9a,0xcd,0x86,0x61,0x58,0xdc,0xff,0x2e,0x3f,0xd7,0x37,0x6,0x0,0x0,0x0,
0x60,0xe2,0x16,0x6f,0xb7,0x6b,0xff,0xc7,0x80,0x61,0x7f,0xf5,0x72,0x72,0x7a,0xe,
0x0,0x0,0x0,0x4c,0xdd,0xe5,0xd6,0xe6,0x7c,0x3c,0xa,0xfc,0x5c,0xec,0x1d,0x9b,
0x3,0x0,0x0,0x0,0x26,0xef,0xee,0xf0,0x60,0x7b,0xfc,0x10,0xf8,0xba,0xb9,0x9a,
0x9b,0x3,0x0,0x0,0x0,0x26,0x6f,0xf7,0xfb,0xfd,0x68,0xbc,0x5,0x3c,0xaf,0x1e,
0x77,0xce,0xec,0x1,0x0,0x0,0x0,0x93,0xf7,0x2a,0x18,0x0,0x0,0x0,0x0,0x29,
0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,
0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,
0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,
0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,
0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,
0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,
0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,
0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,
0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,
0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,
0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,
0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,
0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,
0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,
0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,
0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,
0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,
0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,
0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,
0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,
0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,
0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,
0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,
0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,
0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,
0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,
0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,
0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,
0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,
0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,
0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,
0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,
0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,
0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,
0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,
0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,
0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,
0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,
0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,
0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,
0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,
0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,
0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,
0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,
0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,
0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,
0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,
0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,
0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,
0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,
0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,
0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,
0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,
0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,
0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,
0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,
0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,
0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,
0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,
0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,
0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,
0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,
0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,
0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,
0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,
0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,
0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,
0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,
0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,
0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,
0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,
0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,
0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,
0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,
0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,
0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,
0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,
0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,
0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,
0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,
0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,
0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,
0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,
0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,
0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,
0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,
0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,
0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,
0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,
0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,
0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,
0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,
0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,
0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,
0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,
0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,
0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,
0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,
0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,
0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,
0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,
0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,
0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,
0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,
0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,
0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,
0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,
0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,
0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,
0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,
0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,
0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,
0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,
0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,
0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,
0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,
0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,
0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,
0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,
0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,
0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,
0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,
0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,
0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,
0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,
0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,
0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,
0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,
0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,
0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,
0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,
0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,
0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,
0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,
0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,
0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,
0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,
0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,
0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,
0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,
0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,
0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,
0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,
0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,
0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,
0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,
0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,
0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,
0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,
0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,
0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,
0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,
0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,
0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,
0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,
0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,
0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,
0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,
0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,
0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,
0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,
0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,
0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,
0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,
0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,
0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,
0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,
0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,
0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,
0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,
0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,
0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,
0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,
0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,
0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,
0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,
0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,
0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,
0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,
0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,
0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,
0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,
0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,
0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,
0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,
0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,
0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,
0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,
0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,
0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,
0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,
0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,
0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,
0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,
0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,
0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,
0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,
0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,
0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,
0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,
0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,
0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,
0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,
0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,
0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,
0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,
0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,
0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,
0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,
0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,
0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,
0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,
0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,
0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,
0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,
0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,
0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,
0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,
0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,
0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,
0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,
0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,
0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,
0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,
0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,
0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,
0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,
0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,
0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,
0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,
0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,
0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,
0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,
0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,
0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,
0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,
0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,
0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,
0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,
0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,
0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,
0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,
0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,
0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,
0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,
0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,
0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,
0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,
0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,
0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,
0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,
0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,
0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,
0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,
0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,
0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,
0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,
0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,
0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,
0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,
0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,
0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,
0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,
0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,
0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,
0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,
0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,
0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,
0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,
0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,
0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,
0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,
0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,
0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,
0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,
0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,
0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,
0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,
0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,
0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,
0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,
0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,
0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,
0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,
0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,
0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,
0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,
0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,
0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,
0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,
0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,
0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,
0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,
0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,
0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,
0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,
0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,
0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,
0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,
0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,
0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,
0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,
0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,
0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,
0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,
0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,
0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,
0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,
0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,
0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,
0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,
0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,
0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,
0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,
0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,
0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,
0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,
0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,
0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,
0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,
0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,
0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,
0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,
0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,
0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,
0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,
0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,
0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,
0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,
0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,
0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,
0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,
0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,
0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,
0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,
0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,
0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,
0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,
0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,
0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,
0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,
0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,
0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,
0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,
0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,
0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,
0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,
0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,
0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,
0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,
0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,
0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,
0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,
0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,
0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,
0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,
0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,
0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,
0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,
0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,
0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,
0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,
0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,
0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,
0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,
0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,
0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,
0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,
0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,
0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,
0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,
0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,
0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,
0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,
0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,
0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,
0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,
0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,
0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,
0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,
0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,
0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,
0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,
0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,
0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,
0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,
0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,
0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,
0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,
0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,
0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,
0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,
0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,
0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,
0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,
0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,
0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,
0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,
0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,
0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,
0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,
0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,
0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,
0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,
0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,
0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,
0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,
0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,
0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,
0x10,0x23,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,
0x0,0x0,0x0,0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0x10,0x23,0x18,0x0,0x0,0x0,
0x0,0x2d,0x82,0x1,0x0,0x0,0x0,0xd0,0x22,0x18,0x0,0x0,0x0,0x0,0x2d,0x82,
0x1,0x0,0x7f,0xed,0xdc,0x31,0x15,0x40,0x0,0x0,0x40,0x41,0xde,0x63,0x65,0xd4,
0x47,0xd,0x9,0xb4,0x53,0x41,0x2c,0x9b,0x45,0x7,0xc3,0xbf,0xb,0x72,0x0,0x0,
0x10,0x23,0xc,0x0,0x0,0x0,0x80,0x16,0x61,0x0,0x0,0x0,0x0,0xb4,0x8,0x3,
0x0,0x0,0x0,0xa0,0x45,0x18,0x0,0x0,0x0,0x0,0x31,0xc2,0x0,0x0,0x0,0x0,
0x68,0x11,0x6,0x0,0x0,0x0,0x40,0x8b,0x30,0x0,0x0,0x0,0x0,0x5a,0x84,0x1,
0x0,0x0,0x0,0x10,0x23,0xc,0x0,0x0,0x0,0x80,0x16,0x61,0x0,0x0,0x0,0x0,
0xb4,0x8,0x3,0x0,0x0,0x0,0xa0,0x45,0x18,0x0,0x0,0x0,0x0,0x31,0xc2,0x0,
0x0,0x0,0x0,0x68,0x11,0x6,0x0,0x0,0x0,0x40,0x8b,0x30,0x0,0x0,0x0,0x0,
0x5a,0x84,0x1,0x0,0x0,0x0,0x10,0x23,0xc,0x0,0x0,0x0,0x80,0x16,0x61,0x0,
0x0,0x0,0x0,0xb4,0x8,0x3,0x0,0x0,0x0,0xa0,0x45,0x18,0x0,0x0,0x0,0x0,
0x31,0xc2,0x0,0x0,0x0,0x0,0x68,0x11,0x6,0x0,0x0,0x0,0x40,0x8b,0x30,0x0,
0x0,0x0,0x0,0x5a,0x84,0x1,0x0,0x0,0x0,0x10,0x23,0xc,0x0,0x0,0x0,0x80,
0x16,0x61,0x0,0x0,0x0,0x0,0xb4,0x8,0x3,0x0,0x0,0x0,0xa0,0x45,0x18,0x0,
0x0,0x0,0x0,0x31,0xc2,0x0,0x0,0x0,0x0,0x68,0x11,0x6,0x0,0x0,0x0,0x40,
0x8b,0x30,0x0,0x0,0x0,0x0,0x5a,0x84,0x1,0x0,0x0,0x0,0x10,0x23,0xc,0x0,
0x0,0x0,0x80,0x16,0x61,0x0,0x0,0x0,0x0,0xb4,0x8,0x3,0x0,0x0,0x0,0xa0,
0x45,0x18,0x0,0x0,0x0,0x0,0x31,0xc2,0x0,0x0,0x0,0x0,0x68,0x11,0x6,0x0,
0x0,0x0,0x40,0x8b,0x30,0x0,0x0,0x0,0x0,0x5a,0x84,0x1,0x0,0x0,0x0,0x10,
0x23,0xc,0x0,0x0,0x0,0x80,0x16,0x61,0x0,0x0,0x0,0x0,0xb4,0x8,0x3,0x0,
0x0,0x0,0xa0,0x45,0x18,0x0,0x0,0x0,0x0,0x31,0xc2,0x0,0x0,0x0,0x0,0x68,
0x11,0x6,0x0,0x0,0x0,0x40,0x8b,0x30,0x0,0x0,0x0,0x0,0x5a,0x84,0x1,0x0,
0x0,0x0,0x10,0x23,0xc,0x0,0x0,0x0,0x80,0x16,0x61,0x0,0x0,0x0,0x0,0xb4,
0x8,0x3,0x0,0x0,0x0,0xa0,0x45,0x18,0x0,0x0,0x0,0x0,0x31,0xc2,0x0,0x0,
0x0,0x0,0x68,0x11,0x6,0x0,0x0,0x0,0x40,0x8b,0x30,0x0,0x0,0x0,0x0,0x5a,
0x84,0x1,0x0,0x0,0x0,0x10,0x23,0xc,0x0,0x0,0x0,0x80,0x16,0x61,0x0,0x0,
0x0,0x0,0xb4,0x8,0x3,0x0,0x0,0x0,0xa0,0x45,0x18,0x0,0x0,0x0,0x0,0x31,
0xc2,0x0,0x0,0x0,0x0,0x68,0x11,0x6,0x0,0x0,0x0,0x40,0x8b,0x30,0x0,0x0,
0x0,0x0,0x5a,0x84,0x1,0x0,0x0,0x0,0x10,0x23,0xc,0x0,0x0,0x0,0x80,0x16,
0x61,0x0,0x0,0x0,0x0,0xb4,0x8,0x3,0x0,0x0,0x0,0xa0,0x45,0x18,0x0,0x0,
0x0,0x0,0x31,0xc2,0x0,0x0,0x0,0x0,0x68,0x11,0x6,0x0,0x0,0x0,0x40,0x8b,
0x30,0x0,0x0,0x0,0x0,0x5a,0x84,0x1,0x0,0x0,0x0,0x10,0x23,0xc,0x0,0x0,
0x0,0x80,0x16,0x61,0x0,0x0,0x0,0x0,0xb4,0x8,0x3,0x0,0x0,0x0,0xa0,0x45,
0x18,0x0,0x0,0x0,0x0,0x31,0xc2,0x0,0x0,0x0,0x0,0x68,0x11,0x6,0x0,0x0,
0x0,0x40,0x8b,0x30,0x0,0x0,0x0,0x0,0x5a,0x84,0x1,0x0,0x0,0x0,0x10,0x23,
0xc,0x0,0x0,0x0,0x80,0x16,0x61,0x0,0x0,0x0,0x0,0xb4,0x8,0x3,0x0,0x0,
0x0,0xa0,0x45,0x18,0x0,0x0,0x0,0x0,0x31,0xc2,0x0,0x0,0x0,0x0,0x68,0x11,
0x6,0x0,0x0,0x0,0x40,0x8b,0x30,0x0,0x0,0x0,0x0,0x5a,0x84,0x1,0x0,0x0,
0x0,0x10,0x23,0xc,0x0,0x0,0x0,0x80,0x16,0x61,0x0,0x0,0x0,0x0,0xb4,0x8,
0x3,0x0,0x0,0x0,0xa0,0x45,0x18,0x0,0x0,0x0,0x0,0x31,0xc2,0x0,0x0,0x0,
0x0,0x68,0x11,0x6,0x0,0x0,0x0,0x40,0x8b,0x30,0x0,0x0,0x0,0x0,0x5a,0x84,
0x1,0x0,0x0,0x0,0x10,0x23,0xc,0x0,0x0,0x0,0x80,0x16,0x61,0x0,0x0,0x0,
0x0,0xb4,0x8,0x3,0x0,0x0,0x0,0xa0,0x45,0x18,0x0,0x0,0x0,0x0,0x31,0xc2,
0x0,0x0,0x0,0x0,0x68,0x11,0x6,0x0,0x0,0x0,0x40,0x8b,0x30,0x0,0x0,0x0,
0x0,0x5a,0x84,0x1,0x0,0x0,0x0,0x10,0x23,0xc,0x0,0x0,0x0,0x80,0x16,0x61,
0x0,0x0,0x0,0x0,0xb4,0x8,0x3,0x0,0x0,0x0,0xa0,0x45,0x18,0x0,0x0,0x0,
0x0,0x31,0xc2,0x0,0x0,0x0,0x0,0x68,0x11,0x6,0x0,0x0,0x0,0x40,0x8b,0x30,
0x0,0x0,0x0,0x0,0x5a,0x84,0x1,0x0,0x0,0x0,0x10,0x23,0xc,0x0,0x0,0x0,
0x80,0x16,0x61,0x0,0x0,0x0,0x0,0xb4,0x8,0x3,0x0,0x0,0x0,0xa0,0x45,0x18,
0x0,0x0,0x0,0x0,0x31,0xc2,0x0,0x0,0x0,0x0,0x68,0x11,0x6,0x0,0x0,0x0,
0x40,0x8b,0x30,0x0,0x0,0x0,0x0,0x5a,0x84,0x1,0x0,0x0,0x0,0x10,0x23,0xc,
0x0,0x0,0x0,0x80,0x16,0x61,0x0,0x0,0x0,0x0,0xb4,0x8,0x3,0x0,0x0,0x0,
0xa0,0x45,0x18,0x0,0x0,0x0,0x0,0x31,0xc2,0x0,0x0,0x0,0x0,0x68,0x11,0x6,
0x0,0x0,0x0,0x40,0x8b,0x30,0x0,0x0,0x0,0x0,0x5a,0x84,0x1,0x0,0x0,0x0,
0x10,0x23,0xc,0x0,0x0,0x0,0x80,0x16,0x61,0x0,0x0,0x0,0x0,0xb4,0x8,0x3,
0x0,0x0,0x0,0xa0,0x45,0x18,0x0,0x0,0x0,0x0,0x31,0xc2,0x0,0x0,0x0,0x0,
0x68,0x11,0x6,0x0,0x0,0x0,0x40,0x8b,0x30,0x0,0x0,0x0,0x0,0x5a,0x84,0x1,
0x0,0x0,0x0,0x10,0x23,0xc,0x0,0x0,0x0,0x80,0x16,0x61,0x0,0x0,0x0,0x0,
0xb4,0x8,0x3,0x0,0x0,0x0,0xa0,0x45,0x18,0x0,0x0,0x0,0x0,0x31,0xc2,0x0,
0x0,0x0,0x0,0x68,0x11,0x6,0x0,0x0,0x0,0x40,0x8b,0x30,0x0,0x0,0x0,0x0,
0x5a,0x84,0x1,0x0,0x0,0x0,0x10,0x23,0xc,0x0,0x0,0x0,0x80,0x16,0x61,0x0,
0x0,0x0,0x0,0xb4,0x8,0x3,0x0,0x0,0x0,0xa0,0x45,0x18,0x0,0x0,0x0,0x0,
0x31,0xc2,0x0,0x0,0x0,0x0,0x68,0x11,0x6,0x0,0x0,0x0,0x40,0x8b,0x30,0x0,
0x0,0x0,0x0,0x5a,0x84,0x1,0x0,0x0,0x0,0x10,0x23,0xc,0x0,0x0,0x0,0x80,
0x16,0x61,0x0,0x0,0x0,0x0,0xb4,0x8,0x3,0x0,0x0,0x0,0xa0,0x45,0x18,0x0,
0x0,0x0,0x0,0x31,0xc2,0x0,0x0,0x0,0x0,0x68,0x11,0x6,0x0,0x0,0x0,0x40,
0x8b,0x30,0x0,0x0,0x0,0x0,0x5a,0x84,0x1,0x0,0x0,0x0,0x10,0x23,0xc,0x0,
0x0,0x0,0x80,0x16,0x61,0x0,0x0,0x0,0x0,0xb4,0x8,0x3,0x0,0x0,0x0,0xa0,
0x45,0x18,0x0,0x0,0x0,0x0,0x31,0xc2,0x0,0x0,0x0,0x0,0x68,0x11,0x6,0x0,
0x0,0x0,0x40,0x8b,0x30,0x0,0x0,0x0,0x0,0x5a,0x84,0x1,0x0,0x0,0x0,0x10,
0x23,0xc,0x0,0x0,0x0,0x80,0x16,0x61,0x0,0x0,0x0,0x0,0xb4,0x8,0x3,0x0,
0x0,0x0,0xa0,0x45,0x18,0x0,0x0,0x0,0x0,0x31,0xc2,0x0,0x0,0x0,0x0,0x68,
0x11,0x6,0x0,0x0,0x0,0x40,0x8b,0x30,0x0,0x0,0x0,0x0,0x5a,0x84,0x1,0x0,
0x0,0x0,0x10,0x23,0xc,0x0,0x0,0x0,0x80,0x16,0x61,0x0,0x0,0x0,0x0,0xb4,
0x8,0x3,0x0,0x0,0x0,0xa0,0x45,0x18,0x0,0x0,0x0,0x0,0x31,0xc2,0x0,0x0,
0x0,0x0,0x68,0x11,0x6,0x0,0x0,0x0,0x40,0x8b,0x30,0x0,0x0,0x0,0x0,0x5a,
0x84,0x1,0x0,0x0,0x0,0x10,0x23,0xc,0x0,0x0,0x0,0x80,0x16,0x61,0x0,0x0,
0x0,0x0,0xb4,0x8,0x3,0x0,0x0,0x0,0xa0,0x45,0x18,0x0,0x0,0x0,0x0,0x31,
0xc2,0x0,0x0,0x0,0x0,0x68,0x11,0x6,0x0,0x0,0x0,0x40,0x8b,0x30,0x0,0x0,
0x0,0x0,0x5a,0x84,0x1,0x0,0x0,0x0,0x10,0x23,0xc,0x0,0x0,0x0,0x80,0x16,
0x61,0x0,0x0,0x0,0x0,0xb4,0x8,0x3,0x0,0x0,0x0,0xa0,0x45,0x18,0x0,0x0,
0x0,0x0,0x31,0xc2,0x0,0x0,0x0,0x0,0x68,0x11,0x6,0x0,0x0,0x0,0x40,0x8b,
0x30,0x0,0x0,0x0,0x0,0x5a,0x84,0x1,0x0,0x0,0x0,0x10,0x23,0xc,0x0,0x0,
0x0,0x80,0x16,0x61,0x0,0x0,0x0,0x0,0xb4,0x8,0x3,0x0,0x0,0x0,0xa0,0x45,
0x18,0x0,0x0,0x0,0x0,0x31,0xc2,0x0,0x0,0x0,0x0,0x68,0x11,0x6,0x0,0x0,
0x0,0x40,0x8b,0x30,0x0,0x0,0x0,0x0,0x5a,0x84,0x1,0x0,0x0,0x0,0x10,0x23,
0xc,0x0,0x0,0x0,0x80,0x16,0x61,0x0,0x0,0x0,0x0,0xb4,0x8,0x3,0x0,0x0,
0x0,0xa0,0x45,0x18,0x0,0x0,0x0,0x0,0x31,0xc2,0x0,0x0,0x0,0x0,0x68,0x11,
0x6,0x0,0x0,0x0,0x40,0x8b,0x30,0x0,0x0,0x0,0x0,0x5a,0x84,0x1,0x0,0x0,
0x0,0x10,0x23,0xc,0x0,0x0,0x0,0x80,0x16,0x61,0x0,0x0,0x0,0x0,0xb4,0x8,
0x3,0x0,0x0,0x0,0xa0,0x45,0x18,0x0,0x0,0x0,0x0,0x31,0xc2,0x0,0x0,0x0,
0x0,0x68,0x11,0x6,0x0,0x0,0x0,0x40,0x8b,0x30,0x0,0x0,0x0,0x0,0x5a,0x84,
0x1,0x0,0x0,0x0,0x10,0x23,0xc,0x0,0x0,0x0,0x80,0x16,0x61,0x0,0x0,0x0,
0x0,0xb4,0x8,0x3,0x0,0x0,0x0,0xa0,0x45,0x18,0x0,0x0,0x0,0x0,0x31,0xc2,
0x0,0x0,0x0,0x0,0x68,0x11,0x6,0x0,0x0,0x0,0x40,0x8b,0x30,0x0,0x0,0x0,
0x0,0x5a,0x84,0x1,0x0,0x0,0x0,0x10,0x23,0xc,0x0,0x0,0x0,0x80,0x16,0x61,
0x0,0x0,0x0,0x0,0xb4,0x8,0x3,0x0,0x0,0x0,0xa0,0x45,0x18,0x0,0x0,0x0,
0x0,0x31,0xc2,0x0,0x0,0x0,0x0,0x68,0x11,0x6,0x0,0x0,0x0,0x40,0x8b,0x30,
0x0,0x0,0x0,0x0,0x5a,0x84,0x1,0x0,0x0,0x0,0x10,0x23,0xc,0x0,0x0,0x0,
0x80,0x16,0x61,0x0,0x0,0x0,0x0,0xb4,0x8,0x3,0x0,0x0,0x0,0xa0,0x45,0x18,
0x0,0x0,0x0,0x0,0x31,0xc2,0x0,0x0,0x0,0x0,0x68,0x11,0x6,0x0,0x0,0x0,
0x40,0x8b,0x30,0x0,0x0,0x0,0x0,0x5a,0x84,0x1,0x0,0x0,0x0,0x10,0x23,0xc,
0x0,0x0,0x0,0x80,0x96,0xf3,0xb,0x3,0xa6,0xe7,0x58,0xaf,0x7d,0x1e,0xe0,0x1f,
0xdb,0xbd,0xc,0xe3,0xb,0x89,0xb2,0x9c,0x98,
};
static const unsigned char qt_resource_name[] = {
// 5GiB.txt.inflate
0x0,0x10,
0x6,0xf4,0xb1,0x65,
0x0,0x35,
0x0,0x47,0x0,0x69,0x0,0x42,0x0,0x2e,0x0,0x74,0x0,0x78,0x0,0x74,0x0,0x2e,0x0,0x69,0x0,0x6e,0x0,0x66,0x0,0x6c,0x0,0x61,0x0,0x74,0x0,0x65,
};
static const unsigned char qt_resource_struct[] = {
// :
0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x1,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
// :/5GiB.txt.inflate
0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,
0x0,0x0,0x1,0x72,0x1c,0xae,0x5,0x93,
};
#ifdef QT_NAMESPACE
# define QT_RCC_PREPEND_NAMESPACE(name) ::QT_NAMESPACE::name
# define QT_RCC_MANGLE_NAMESPACE0(x) x
# define QT_RCC_MANGLE_NAMESPACE1(a, b) a##_##b
# define QT_RCC_MANGLE_NAMESPACE2(a, b) QT_RCC_MANGLE_NAMESPACE1(a,b)
# define QT_RCC_MANGLE_NAMESPACE(name) QT_RCC_MANGLE_NAMESPACE2( \
QT_RCC_MANGLE_NAMESPACE0(name), QT_RCC_MANGLE_NAMESPACE0(QT_NAMESPACE))
#else
# define QT_RCC_PREPEND_NAMESPACE(name) name
# define QT_RCC_MANGLE_NAMESPACE(name) name
#endif
#ifdef QT_NAMESPACE
namespace QT_NAMESPACE {
#endif
bool qRegisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *);
bool qUnregisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *);
#if defined(__ELF__) || defined(__APPLE__)
static inline unsigned char qResourceFeatureZlib()
{
extern const unsigned char qt_resourceFeatureZlib;
return qt_resourceFeatureZlib;
}
#else
unsigned char qResourceFeatureZlib();
#endif
#ifdef QT_NAMESPACE
}
#endif
int QT_RCC_MANGLE_NAMESPACE(qInitResources_inflate)();
int QT_RCC_MANGLE_NAMESPACE(qInitResources_inflate)()
{
int version = 3;
QT_RCC_PREPEND_NAMESPACE(qRegisterResourceData)
(version, qt_resource_struct, qt_resource_name, qt_resource_data);
return 1;
}
int QT_RCC_MANGLE_NAMESPACE(qCleanupResources_inflate)();
int QT_RCC_MANGLE_NAMESPACE(qCleanupResources_inflate)()
{
int version = 3;
version += QT_RCC_PREPEND_NAMESPACE(qResourceFeatureZlib());
QT_RCC_PREPEND_NAMESPACE(qUnregisterResourceData)
(version, qt_resource_struct, qt_resource_name, qt_resource_data);
return 1;
}
namespace {
struct initializer {
initializer() { QT_RCC_MANGLE_NAMESPACE(qInitResources_inflate)(); }
~initializer() { QT_RCC_MANGLE_NAMESPACE(qCleanupResources_inflate)(); }
} dummy;
}

View File

@ -0,0 +1,11 @@
QT = network-private testlib
CONFIG += testcase parallel_test
TEMPLATE = app
TARGET = tst_qdecompresshelper
SOURCES += \
tst_qdecompresshelper.cpp \
gzip.rcc.cpp \
inflate.rcc.cpp \
DEFINES += SRC_DIR="$$PWD"

View File

@ -0,0 +1,377 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtTest/QtTest>
#include <QtNetwork/private/qdecompresshelper_p.h>
#include <QtCore/qbytearray.h>
const QString srcDir = QStringLiteral(QT_STRINGIFY(SRC_DIR));
class tst_QDecompressHelper : public QObject
{
Q_OBJECT
private:
void sharedDecompress_data();
private Q_SLOTS:
void initTestCase();
void cleanupTestCase();
void encodingSupported();
void decompress_data();
void decompress();
void partialDecompress_data();
void partialDecompress();
void countAhead_data();
void countAhead();
void countAheadByteDataBuffer_data();
void countAheadByteDataBuffer();
void countAheadPartialRead_data();
void countAheadPartialRead();
void decompressBigData_data();
void decompressBigData();
#if QT_POINTER_SIZE >= 8
void bigZlib();
#endif
};
void tst_QDecompressHelper::initTestCase()
{
Q_INIT_RESOURCE(gzip);
Q_INIT_RESOURCE(inflate);
}
void tst_QDecompressHelper::cleanupTestCase()
{
Q_CLEANUP_RESOURCE(inflate);
Q_CLEANUP_RESOURCE(gzip);
}
void tst_QDecompressHelper::encodingSupported()
{
QVERIFY(!QDecompressHelper::isSupportedEncoding("identity"));
QVERIFY(!QDecompressHelper::isSupportedEncoding("fake"));
QVERIFY(QDecompressHelper::isSupportedEncoding("deflate"));
QVERIFY(QDecompressHelper::isSupportedEncoding("gzip"));
}
void tst_QDecompressHelper::sharedDecompress_data()
{
QTest::addColumn<QByteArray>("encoding");
QTest::addColumn<QByteArray>("data");
QTest::addColumn<QByteArray>("expected");
QTest::newRow("gzip-hello-world")
<< QByteArray("gzip")
<< QByteArray::fromBase64("H4sIAAAAAAAAA8tIzcnJVyjPL8pJAQCFEUoNCwAAAA==")
<< QByteArray("hello world");
// Has two streams. ZLib reports end of stream after the first one, but we need to decompress
// all of the streams to get the full file.
QTest::newRow("gzip-multistream-hello-world")
<< QByteArray("gzip")
<< QByteArray::fromBase64(
"H4sIAAAAAAAAA8tIzcnJBwCGphA2BQAAAB+LCAAAAAAAAANTKM8vykkBAMtCO0oGAAAA")
<< QByteArray("hello world");
QTest::newRow("deflate-hello-world")
<< QByteArray("deflate") << QByteArray::fromBase64("eJzLSM3JyVcozy/KSQEAGgsEXQ==")
<< QByteArray("hello world");
}
void tst_QDecompressHelper::decompress_data()
{
sharedDecompress_data();
}
void tst_QDecompressHelper::decompress()
{
QDecompressHelper helper;
QFETCH(QByteArray, encoding);
QVERIFY(helper.setEncoding(encoding));
QFETCH(QByteArray, data);
helper.feed(data);
QFETCH(QByteArray, expected);
QByteArray actual(expected.size(), Qt::Uninitialized);
qsizetype read = helper.read(actual.data(), actual.size());
QCOMPARE(read, expected.size());
QCOMPARE(actual, expected);
}
void tst_QDecompressHelper::partialDecompress_data()
{
sharedDecompress_data();
}
// Test that even though we read 1 byte at a time we
// don't lose data from the decoder's internal storage
void tst_QDecompressHelper::partialDecompress()
{
QDecompressHelper helper;
QFETCH(QByteArray, encoding);
QVERIFY(helper.setEncoding(encoding));
QFETCH(QByteArray, data);
helper.feed(data);
QFETCH(QByteArray, expected);
QByteArray actual(expected.size(), Qt::Uninitialized);
qsizetype readTotal = 0;
while (helper.hasData()) {
qsizetype read = helper.read(actual.data() + readTotal, 1);
if (read != 0) // last read might return 0
QCOMPARE(read, 1); // Make sure we don't suddenly read too much
readTotal += read;
}
QCOMPARE(readTotal, expected.size());
QCOMPARE(actual, expected);
}
void tst_QDecompressHelper::countAhead_data()
{
sharedDecompress_data();
}
// Test the double-decompress / count uncompressed size feature.
// We expect that after it has been fed data it will be able to
// tell us the full size of the data when uncompressed.
void tst_QDecompressHelper::countAhead()
{
QDecompressHelper helper;
helper.setCountingBytesEnabled(true);
QFETCH(QByteArray, encoding);
QVERIFY(helper.setEncoding(encoding));
QFETCH(QByteArray, data);
QByteArray firstPart = data.left(data.size() - data.size() / 6);
QVERIFY(firstPart.size() < data.size()); // sanity check
QByteArray secondPart = data.mid(firstPart.size());
helper.feed(firstPart); // feed by copy
// it's a reasonable assumption that after feeding it the first part
// should have decompressed something
QVERIFY(helper.uncompressedSize() > 0);
helper.feed(std::move(secondPart)); // feed by move
QFETCH(QByteArray, expected);
QCOMPARE(helper.uncompressedSize(), expected.size());
QByteArray actual(helper.uncompressedSize(), Qt::Uninitialized);
qsizetype read = helper.read(actual.data(), actual.size());
QCOMPARE(read, expected.size());
QCOMPARE(actual, expected);
}
void tst_QDecompressHelper::countAheadByteDataBuffer_data()
{
sharedDecompress_data();
}
void tst_QDecompressHelper::countAheadByteDataBuffer()
{
QFETCH(QByteArray, encoding);
QFETCH(QByteArray, data);
QFETCH(QByteArray, expected);
{ // feed buffer by const-ref
QDecompressHelper helper;
helper.setCountingBytesEnabled(true);
QVERIFY(helper.setEncoding(encoding));
QByteArray firstPart = data.left(data.size() - data.size() / 6);
QVERIFY(firstPart.size() < data.size()); // sanity check
QByteArray secondPart = data.mid(firstPart.size());
QByteDataBuffer buffer;
buffer.append(firstPart);
buffer.append(secondPart);
helper.feed(buffer);
QCOMPARE(helper.uncompressedSize(), expected.size());
QByteArray actual(helper.uncompressedSize(), Qt::Uninitialized);
qsizetype read = helper.read(actual.data(), actual.size());
QCOMPARE(read, expected.size());
QCOMPARE(actual, expected);
}
{ // Feed buffer by move
QDecompressHelper helper;
helper.setCountingBytesEnabled(true);
QVERIFY(helper.setEncoding(encoding));
QByteArray firstPart = data.left(data.size() - data.size() / 6);
QVERIFY(firstPart.size() < data.size()); // sanity check
QByteArray secondPart = data.mid(firstPart.size());
QByteDataBuffer buffer;
buffer.append(firstPart);
buffer.append(secondPart);
helper.feed(std::move(buffer));
QCOMPARE(helper.uncompressedSize(), expected.size());
QByteArray actual(helper.uncompressedSize(), Qt::Uninitialized);
qsizetype read = helper.read(actual.data(), actual.size());
QCOMPARE(read, expected.size());
QCOMPARE(actual, expected);
}
}
void tst_QDecompressHelper::countAheadPartialRead_data()
{
sharedDecompress_data();
}
// Make sure that the size is adjusted as we read data
void tst_QDecompressHelper::countAheadPartialRead()
{
QDecompressHelper helper;
helper.setCountingBytesEnabled(true);
QFETCH(QByteArray, encoding);
QVERIFY(helper.setEncoding(encoding));
QFETCH(QByteArray, data);
QByteArray firstPart = data.left(data.size() - data.size() / 6);
QVERIFY(firstPart.size() < data.size()); // sanity check
QByteArray secondPart = data.mid(firstPart.size());
helper.feed(firstPart);
// it's a reasonable assumption that after feeding it half the data it
// should have decompressed something
QVERIFY(helper.uncompressedSize() > 0);
helper.feed(secondPart);
QFETCH(QByteArray, expected);
QCOMPARE(helper.uncompressedSize(), expected.size());
QByteArray actual(helper.uncompressedSize(), Qt::Uninitialized);
qsizetype read = helper.read(actual.data(), 5);
QCOMPARE(read, 5);
QCOMPARE(helper.uncompressedSize(), expected.size() - read);
read += helper.read(actual.data() + read, 1);
QCOMPARE(read, 6);
QCOMPARE(helper.uncompressedSize(), expected.size() - read);
read += helper.read(actual.data() + read, expected.size() - read);
QCOMPARE(read, expected.size());
QCOMPARE(actual, expected);
}
void tst_QDecompressHelper::decompressBigData_data()
{
QTest::addColumn<QByteArray>("encoding");
QTest::addColumn<QString>("path");
QTest::addColumn<qint64>("size");
qint64 fourGiB = 4ll * 1024ll * 1024ll * 1024ll;
qint64 fiveGiB = 5ll * 1024ll * 1024ll * 1024ll;
QTest::newRow("gzip-4G") << QByteArray("gzip") << QString(":/4G.gz") << fourGiB;
QTest::newRow("deflate-5G") << QByteArray("deflate") << QString(":/5GiB.txt.inflate")
<< fiveGiB;
}
void tst_QDecompressHelper::decompressBigData()
{
QFETCH(QString, path);
QFile file(path);
QVERIFY(file.open(QIODevice::ReadOnly));
const qint64 third = file.bytesAvailable() / 3;
QDecompressHelper helper;
QFETCH(QByteArray, encoding);
helper.setEncoding(encoding);
QByteArray output(32 * 1024, Qt::Uninitialized);
qint64 totalSize = 0;
while (!file.atEnd()) {
helper.feed(file.read(third));
while (helper.hasData()) {
qsizetype bytesRead = helper.read(output.data(), output.size());
QVERIFY(bytesRead <= output.size());
totalSize += bytesRead;
const auto isZero = [](char c) { return c == '\0'; };
bool allZero = std::all_of(output.cbegin(), output.cbegin() + bytesRead, isZero);
QVERIFY(allZero);
}
}
QTEST(totalSize, "size");
}
#if QT_POINTER_SIZE >= 8
void tst_QDecompressHelper::bigZlib()
{
// ZLib uses unsigned integers as their size type internally which creates some special
// cases in the internal code that should be tested!
QFile file(":/5GiB.txt.inflate");
QVERIFY(file.open(QIODevice::ReadOnly));
QByteArray compressedData = file.readAll();
QDecompressHelper helper;
helper.setEncoding("deflate");
auto firstHalf = compressedData.left(compressedData.size() - 2);
helper.feed(firstHalf);
helper.feed(compressedData.mid(firstHalf.size()));
// We need the whole thing in one go... which is why this test is not available for 32-bit
qint64 expected = 5ll * 1024ll * 1024ll * 1024ll;
// This can be replaced with QByteArray after the qsizetype change is merged
std::unique_ptr<char[]> output(new char[expected]);
qsizetype size = helper.read(output.get(), expected);
QCOMPARE(size, expected);
}
#endif
QTEST_MAIN(tst_QDecompressHelper)
#include "tst_qdecompresshelper.moc"

View File

@ -4,3 +4,6 @@ add_subdirectory(qfile_vs_qnetworkaccessmanager)
add_subdirectory(qnetworkreply)
add_subdirectory(qnetworkreply_from_cache)
add_subdirectory(qnetworkdiskcache)
if(QT_FEATURE_private_tests)
add_subdirectory(qdecompresshelper)
endif()

View File

@ -4,3 +4,8 @@ SUBDIRS = \
qnetworkreply \
qnetworkreply_from_cache \
qnetworkdiskcache
qtConfig(private_tests): \
SUBDIRS += \
qdecompresshelper \

View File

@ -0,0 +1,19 @@
# Generated from qdecompresshelper.pro.
#####################################################################
## qdecompresshelper Binary:
#####################################################################
qt_add_executable(qdecompresshelper
SOURCES
main.cpp
DEFINES
SRC_DIR="${CMAKE_CURRENT_SOURCE_DIR}"
PUBLIC_LIBRARIES
Qt::NetworkPrivate
Qt::Test
)
#### Keys ignored in scope 1:.:.:qdecompresshelper.pro:<TRUE>:
# TEMPLATE = "app"
# _REQUIREMENTS = "qtConfig(private_tests)"

View File

@ -0,0 +1,19 @@
# Generated from qdecompresshelper.pro.
#####################################################################
## qdecompresshelper Binary:
#####################################################################
qt_add_executable(qdecompresshelper
SOURCES
main.cpp
DEFINES
SRC_DIR=${CMAKE_CURRENT_SOURCE_DIR} # special case
PUBLIC_LIBRARIES
Qt::NetworkPrivate
Qt::Test
)
#### Keys ignored in scope 1:.:.:decompresshelper.pro:<TRUE>:
# TEMPLATE = "app"
# _REQUIREMENTS = "qtConfig(private_tests)"

View File

@ -0,0 +1,89 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtNetwork/private/qdecompresshelper_p.h>
#include <QtTest/QTest>
class tst_QDecompressHelper : public QObject
{
Q_OBJECT
private slots:
void decompress_data();
void decompress();
};
void tst_QDecompressHelper::decompress_data()
{
QTest::addColumn<QByteArray>("encoding");
QTest::addColumn<QString>("fileName");
QString srcDir = QStringLiteral(QT_STRINGIFY(SRC_DIR));
srcDir = QDir::fromNativeSeparators(srcDir);
if (!srcDir.endsWith("/"))
srcDir += "/";
bool dataAdded = false;
#ifndef QT_NO_COMPRESS
QTest::addRow("gzip") << QByteArray("gzip") << srcDir + QString("50mb.txt.gz");
dataAdded = true;
#endif
if (!dataAdded)
QSKIP("There's no decompression support");
}
void tst_QDecompressHelper::decompress()
{
QFETCH(QByteArray, encoding);
QFETCH(QString, fileName);
QFile file { fileName };
QVERIFY(file.open(QIODevice::ReadOnly));
QBENCHMARK {
file.seek(0);
QDecompressHelper helper;
helper.setEncoding(encoding);
QVERIFY(helper.isValid());
helper.feed(file.readAll());
qsizetype bytes = 0;
while (helper.hasData()) {
QByteArray out(64 * 1024, Qt::Uninitialized);
qsizetype bytesRead = helper.read(out.data(), out.size());
bytes += bytesRead;
}
QCOMPARE(bytes, 50 * 1024 * 1024);
}
}
QTEST_MAIN(tst_QDecompressHelper)
#include "main.moc"

View File

@ -0,0 +1,8 @@
requires(qtConfig(private_tests))
TEMPLATE = app
QT = network-private testlib
SOURCES = main.cpp
CONFIG += release
DEFINES += SRC_DIR="$$PWD"