diff --git a/FactoryTestTool/FactoryTestTool.vcxproj b/FactoryTestTool/FactoryTestTool.vcxproj
index 4709079..41854c1 100644
--- a/FactoryTestTool/FactoryTestTool.vcxproj
+++ b/FactoryTestTool/FactoryTestTool.vcxproj
@@ -138,6 +138,9 @@
+
+
+
{2C8A5A59-2E79-4283-A0ED-D70DB305557E}
QtVS_v304
diff --git a/FactoryTestTool/FactoryTestTool.vcxproj.filters b/FactoryTestTool/FactoryTestTool.vcxproj.filters
index cdb8103..3ced2dd 100644
--- a/FactoryTestTool/FactoryTestTool.vcxproj.filters
+++ b/FactoryTestTool/FactoryTestTool.vcxproj.filters
@@ -309,4 +309,7 @@
Network\mdns\qmdnsengine\include
+
+
+
\ No newline at end of file
diff --git a/FactoryTestTool/Icon96.ico b/FactoryTestTool/Icon96.ico
new file mode 100644
index 0000000..f77c259
Binary files /dev/null and b/FactoryTestTool/Icon96.ico differ
diff --git a/FactoryTestTool/SourceCode/Media/Media.cpp b/FactoryTestTool/SourceCode/Media/Media.cpp
index a0311e5..d66e434 100644
--- a/FactoryTestTool/SourceCode/Media/Media.cpp
+++ b/FactoryTestTool/SourceCode/Media/Media.cpp
@@ -13,6 +13,85 @@ void yuvToRgb(int y, int u, int v, int& r, int& g, int& b)
b = qBound(0, b, 255);
}
+// 将 QImage 数据转换为 YUV422
+QByteArray convertQImageToYUV422(const QImage& image)
+{
+ int width = image.width();
+ int height = image.height();
+ QByteArray yuvData;
+ yuvData.resize(width * height * 2); // YUV422: 每个像素2字节
+
+ int index = 0;
+ for (int y = 0; y < height; ++y) {
+ for (int x = 0; x < width; x += 2) {
+ QRgb pixel0 = image.pixel(x, y);
+ QRgb pixel1 = image.pixel(x + 1, y);
+
+ int r0 = qRed(pixel0);
+ int g0 = qGreen(pixel0);
+ int b0 = qBlue(pixel0);
+
+ int r1 = qRed(pixel1);
+ int g1 = qGreen(pixel1);
+ int b1 = qBlue(pixel1);
+
+ // 计算YUV值
+ int y0 = (0.299 * r0 + 0.587 * g0 + 0.114 * b0);
+ int u = (-0.169 * r0 - 0.331 * g0 + 0.5 * b0 + 128);
+ int y1 = (0.299 * r1 + 0.587 * g1 + 0.114 * b1);
+ int v = (0.5 * r0 - 0.419 * g0 - 0.081 * b0 + 128);
+
+ yuvData[index++] = static_cast(qBound(0, y0, 255));
+ yuvData[index++] = static_cast(qBound(0, u, 255));
+ yuvData[index++] = static_cast(qBound(0, y1, 255));
+ yuvData[index++] = static_cast(qBound(0, v, 255));
+ }
+ }
+
+ return yuvData;
+}
+
+// 将 QImage 数据转换为 YUV420
+QByteArray convertQImageToYUV420(const QImage& image)
+{
+ int width = image.width();
+ int height = image.height();
+ QByteArray yuvData;
+ int ySize = width * height;
+ int uvSize = (width / 2) * (height / 2);
+ yuvData.resize(ySize + 2 * uvSize); // Y 分量 + U 分量 + V 分量
+
+ int yIndex = 0;
+ int uIndex = ySize;
+ int vIndex = ySize + uvSize;
+
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ QRgb pixel = image.pixel(x, y);
+
+ int r = qRed(pixel);
+ int g = qGreen(pixel);
+ int b = qBlue(pixel);
+
+ // 计算 YUV 值
+ int Y = qBound(0, static_cast(0.299 * r + 0.587 * g + 0.114 * b), 255);
+ int U = qBound(0, static_cast(-0.169 * r - 0.331 * g + 0.5 * b + 128), 255);
+ int V = qBound(0, static_cast(0.5 * r - 0.419 * g - 0.081 * b + 128), 255);
+
+ // 填充 Y 分量
+ yuvData[yIndex++] = static_cast(Y);
+
+ // 对 U 和 V 分量进行抽样
+ if (y % 2 == 0 && x % 2 == 0) {
+ yuvData[uIndex++] = static_cast(U);
+ yuvData[vIndex++] = static_cast(V);
+ }
+ }
+ }
+
+ return yuvData;
+}
+
// 将 YUV422 数据转换为 QImage
QImage convertYUV422ToQImage(const QByteArray& yuv422Data, int width, int height)
{
@@ -72,29 +151,21 @@ QImage convertYUV420ToQImage(const QByteArray& yuv420Data, int width, int height
return image;
}
-void showPic(QLabel* leftLens_m_imageLabel, QLabel* rightLens_m_imageLabel, const QString& client, const QByteArray& valData)
+void DataHandler::showPic(QSize labelSize, int lens_n,
+ int width, int height, int format, const QByteArray* valData)
{
- int lens_n = static_cast(valData[0]);
- int width = (static_cast(valData[2]) << 8) | static_cast(valData[1]);
- int height = (static_cast(valData[4]) << 8) | static_cast(valData[3]);
- int format = static_cast(valData[5]);
- qDebug() << "lens_n = " << lens_n;
- qDebug() << "format = " << format;
- qDebug() << "width = " << width;
- qDebug() << "height = " << height;
-
- QByteArray yuvData = valData.mid(6);
- qDebug() << "yuvData size = " << yuvData.size();
+ //QByteArray yuvData = valData.mid(6);
+ qDebug() << "yuvData size = " << valData->size();
QImage image;
if (format == YUV422) {
- image = convertYUV422ToQImage(yuvData, width, height);
+ image = convertYUV422ToQImage(*valData, width, height);
}
else if (format == YUV420) {
- image = convertYUV420ToQImage(yuvData, width, height);
+ image = convertYUV420ToQImage(*valData, width, height);
}
else {
- qWarning() << "Unsupported image format!";
+ qWarning() << "Unsupported image format! Please use YUV422 or YUV420 format";
return;
}
@@ -103,16 +174,48 @@ void showPic(QLabel* leftLens_m_imageLabel, QLabel* rightLens_m_imageLabel, cons
transform.rotate(90); // 可以调整旋转角度
QImage rotatedImage = image.transformed(transform);
- QImage scaledImage = rotatedImage.scaled(leftLens_m_imageLabel->size(), Qt::KeepAspectRatio);
+ QImage scaledImage = rotatedImage.scaled(labelSize, Qt::KeepAspectRatio);
+ QPixmap pixmap = QPixmap::fromImage(scaledImage);
if (lens_n == 0) {
- leftLens_m_imageLabel->setPixmap(QPixmap::fromImage(scaledImage));
- //rightLens_m_imageLabel->setPixmap(QPixmap::fromImage(scaledImage));
+ //leftLens_m_imageLabel->setPixmap(QPixmap::fromImage(scaledImage));
+ emit updateLeftLensImage(pixmap);
}
else if (lens_n == 1) {
- rightLens_m_imageLabel->setPixmap(QPixmap::fromImage(scaledImage));
+ //rightLens_m_imageLabel->setPixmap(QPixmap::fromImage(scaledImage));
+ emit updateRightLensImage(pixmap);
}
else {
qWarning() << "Unsupported image lens!";
}
+
+ // 生成保存图片的目录
+ QString saveDirPath = QDir::currentPath() + "/frontBoardImage";
+ QDir saveDir(saveDirPath);
+ if (!saveDir.exists()) {
+ saveDir.mkpath(saveDirPath);
+ }
+ QString currentTime = QDateTime::currentDateTime().toString("yyyyMMdd_HHmmss");
+ QByteArray rotatedYuvData;
+ if (format == YUV422) {
+ rotatedYuvData = convertQImageToYUV422(rotatedImage);
+ }
+ else if (format == YUV420) {
+ rotatedYuvData = convertQImageToYUV420(rotatedImage);
+ }
+ QString yuvFileName = saveDirPath + "/" + currentTime + ".yuv";
+ QFile yuvFile(yuvFileName);
+ if (yuvFile.open(QIODevice::WriteOnly)) {
+ yuvFile.write(rotatedYuvData);
+ yuvFile.close();
+ qDebug() << "YUV image saved to" << yuvFileName;
+ }
+ else {
+ qWarning() << "Failed to save rotated YUV image to" << yuvFileName;
+ }
+
+ // 额外:可以保存旋转后的图像为JPG或PNG格式
+ QString rotatedImageFileName = saveDirPath + "/" + currentTime + ".jpg";
+ rotatedImage.save(rotatedImageFileName, "JPG");
+ qDebug() << "JPG image saved to" << rotatedImageFileName;
}
diff --git a/FactoryTestTool/SourceCode/Media/Media.h b/FactoryTestTool/SourceCode/Media/Media.h
index 1f1cbf6..7715805 100644
--- a/FactoryTestTool/SourceCode/Media/Media.h
+++ b/FactoryTestTool/SourceCode/Media/Media.h
@@ -7,18 +7,18 @@
#include
#include
+#include "../RecvDataHandler/RecvDataHandler.h"
+
#define YUV420 1
#define YUV422 2
// YUV 转换为 RGB 的辅助函数
void yuvToRgb(int y, int u, int v, int& r, int& g, int& b);
+QByteArray convertQImageToYUV422(const QImage& image);
+QByteArray convertQImageToYUV420(const QImage& image);
// 转换YUV422
QImage convertYUV422ToQImage(const QByteArray& yuv422Data, int width, int height);
QImage convertYUV420ToQImage(const QByteArray& yuv420Data, int width, int height);
-// 显示图片和视频的函数
-void showPic(QLabel* leftLens_m_imageLabel, QLabel* rightLens_m_imageLabel, const QString& client, const QByteArray& valData);
-//void showVideo(QLabel* videoLabel, const QString& client, const QByteArray& valData);
-
#endif // MEDIA_H
diff --git a/FactoryTestTool/SourceCode/Media/VideoDecoder/FFmpegDecoder.cpp b/FactoryTestTool/SourceCode/Media/VideoDecoder/FFmpegDecoder.cpp
index 8d8a133..0b4a838 100644
--- a/FactoryTestTool/SourceCode/Media/VideoDecoder/FFmpegDecoder.cpp
+++ b/FactoryTestTool/SourceCode/Media/VideoDecoder/FFmpegDecoder.cpp
@@ -11,16 +11,16 @@ FFmpegDecoder::FFmpegDecoder(QObject* parent) :
frame(nullptr),
packet(nullptr),
swsContext(nullptr),
- videoStreamIndex(-1) // 初始化成员变量
+ videoStreamIndex(-1)
{
av_log_set_level(AV_LOG_QUIET); // 设置日志级别为安静模式
avformat_network_init(); // 初始化网络
- qDebug() << "FFmpegDecoder created";
+ qDebug() << "FFmpegDecoder thread created";
}
FFmpegDecoder::~FFmpegDecoder()
{
- qDebug() << "Destroying FFmpegDecoder";
+ qDebug() << "Destroying FFmpegDecoder thread";
mutex.lock();
abort = true;
condition.wakeOne();
@@ -28,7 +28,7 @@ FFmpegDecoder::~FFmpegDecoder()
wait();
cleanup();
avformat_network_deinit(); // 反初始化网络
- qDebug() << "FFmpegDecoder destroyed";
+ qDebug() << "FFmpegDecoder thread destroyed";
}
void FFmpegDecoder::processVideo(int itemIndex)
@@ -72,7 +72,7 @@ void FFmpegDecoder::stopFFmpegDecoder()
{
mutex.lock();
abort = true;
- condition.wakeOne(); // 唤醒等待的线程
+ condition.wakeOne();
mutex.unlock();
}
@@ -134,10 +134,8 @@ void FFmpegDecoder::run()
if (currentFileSize > fileSize) {
fileSize = currentFileSize;
file.seek(fileSize); // 设置文件读取位置到末尾
- //qDebug() << "---------------1---------------";
// 读取并处理数据包
while (av_read_frame(formatContext, packet) >= 0) {
- //qDebug() << "---------------2---------------";
if (packet->stream_index == videoStreamIndex) {
int ret = avcodec_send_packet(codecContext, packet);
if (ret < 0) {
@@ -145,7 +143,6 @@ void FFmpegDecoder::run()
av_packet_unref(packet);
continue;
}
- //qDebug() << "---------------3---------------";
while (ret >= 0) {
ret = avcodec_receive_frame(codecContext, frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
@@ -156,31 +153,23 @@ void FFmpegDecoder::run()
qWarning() << "Error during decoding";
break;
}
- //qDebug() << "---------------4---------------";
QImage img = avFrameToQImage(frame);
- //qDebug() << "---------------5---------------";
QImage scaledImage = img.scaled(labelSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
- //qDebug() << "---------------6---------------";
currentVideoLabel->setPixmap(QPixmap::fromImage(scaledImage));
QThread::msleep(10); // Simulate 25 FPS frame rate
- //qDebug() << "---------------7---------------";
}
}
av_packet_unref(packet);
- //qDebug() << "---------------8---------------";
}
}
- //qDebug() << "---------------9---------------";
mutex.lock();
if (restart) {
restart = false;
mutex.unlock();
break;
}
- //qDebug() << "---------------10---------------";
mutex.unlock();
}
- //qDebug() << "---------------11---------------";
cleanup();
file.close();
diff --git a/FactoryTestTool/SourceCode/Network/ClientHandler.cpp b/FactoryTestTool/SourceCode/Network/ClientHandler.cpp
index e40df41..ffb3ab6 100644
--- a/FactoryTestTool/SourceCode/Network/ClientHandler.cpp
+++ b/FactoryTestTool/SourceCode/Network/ClientHandler.cpp
@@ -142,13 +142,11 @@ void ClientHandler::sendJsonItem(const QJsonArray& jsonArray, int itemIndex, con
isClickedSend = true;
isRecvImgData = false;
if (itemType == "handleVideo") {
- if (itemIndex == 0) {
- qDebug() << "0 itemIndex: " << itemIndex;
+ if (itemIndex == 0) {
isSingleSend = false;
isClickedSend = false;
}
else {
- qDebug() << "!0 itemIndex: " << itemIndex;
stopReadVideoDataTimer(preVideoClientId);
}
}
@@ -157,8 +155,8 @@ void ClientHandler::sendJsonItem(const QJsonArray& jsonArray, int itemIndex, con
isClickedSend = false;
isRecvImgData = true;
}
- qDebug() << "itemIndex:" << itemIndex;
- qDebug() << "jsonArray.size():" << jsonArray.size();
+ //qDebug() << "itemIndex:" << itemIndex;
+ //qDebug() << "jsonArray.size():" << jsonArray.size();
if (itemIndex >= 0 && itemIndex < jsonArray.size()) {
currentItemIndex = (itemType == "test") ? itemIndex : 0;
currentFuncItemIndex = (itemType == "func") ? itemIndex : 0;
@@ -210,7 +208,6 @@ void ClientHandler::sendGetPicItem(int itemIndex, int GetPicCamIndex)
void ClientHandler::sendGetVideoItem(int itemIndex, int GetVideoCamIndex)
{
qDebug() << "sendGetVideoItem itemIndex:" << itemIndex;
- qDebug() << "sendGetVideoItem GetVideoCamIndex:" << GetVideoCamIndex;
if(isBackBoardOrAllBoard) {
sendJsonItem(getVideoJson, itemIndex, QString::number(GetVideoCamIndex), "handleVideo");
}
@@ -521,7 +518,7 @@ void ClientHandler::setThreadPriority(QThread::Priority priority) {
QThread* thread = QThread::currentThread();
if (thread) {
thread->setPriority(priority);
- qDebug() << "Thread priority set to" << priority << "for clientId:" << clientId;
+ //qDebug() << "Thread priority set to" << priority << "for clientId:" << clientId;
}
else {
qWarning() << "Failed to set thread priority. Current thread is null.";
@@ -531,7 +528,6 @@ void ClientHandler::setThreadPriority(QThread::Priority priority) {
// 处理数据接收
void ClientHandler::onDataReceived()
{
- // 接收其他数据 添加区分 视频与其他数据 的标志位
//qDebug() << "isRecvVideoData:" << isRecvVideoData;
//qDebug() << "isPowerOnSend:" << isPowerOnSend;
//qDebug() << "isClickedSend:" << isClickedSend;
@@ -556,20 +552,16 @@ void ClientHandler::onDataReceived()
emit startTimeout(0);
}
if (!allData.isEmpty()) {
- //emit dataReceived(getClientAddress(), allData, 0xFF, currentItemIndex, currentFuncItemIndex, "", "");
emit dataReceived(getClientAddress(), allData, 0xFF, currentItemIndex, currentFuncItemIndex, getCurrentItemLable(), "", currentJson, currentJsonItem);
if (!isSingleSend && !isPowerOnSend) {
currentItemIndex ++;
itemsProcessedCount ++;
}
}
- // 由于启动了 onTimeoutRead 所以 isSingleSend = false 导致连续发送
- //if (isSingleSend && clientId >= 4) {
if (isSingleSend) {
- isSingleSend = false; // 重置标志
+ isSingleSend = false;
isClickedSend = false;
}
-
else if (isPowerOnSend && currentFrontBoardIndex < frontBoardDevInfoJson.size()) {
sendDevInfoItem();
}
diff --git a/FactoryTestTool/SourceCode/RecvDataHandler/RecvDataHandler.cpp b/FactoryTestTool/SourceCode/RecvDataHandler/RecvDataHandler.cpp
index b75ca96..1115a0b 100644
--- a/FactoryTestTool/SourceCode/RecvDataHandler/RecvDataHandler.cpp
+++ b/FactoryTestTool/SourceCode/RecvDataHandler/RecvDataHandler.cpp
@@ -2,20 +2,16 @@
#include "RecvDataHandler.h"
#include "../Network/ClientHandler.h"
-DataHandler::DataHandler(QLabel* leftLens_imageLabel, QLabel* rightLens_imageLabel, QLabel* videoLabel,
- QLineEdit* VideoResolutionEdit,
- QTextEdit* licenseHwInfoEdit, QMap* devInfoLineEdits,
- QJsonArray frontBoardOneClickTest, QJsonArray frontBoardTest, QJsonArray frontBoardFuncConfig,
- QJsonArray frontBoardDevInfoJson, QJsonArray frontBoardLicenseJson,
- QJsonArray backBoardOneClickTest, QJsonArray backBoardTest, QJsonArray backBoardFuncConfig,
- QJsonArray backBoardDevInfoJson, QJsonArray backBoardUuidJson,
- QJsonArray getPicJson, QJsonArray getVideoJson, QObject* parent)
+DataHandler::DataHandler(QLabel* videoLabel, QLineEdit* VideoResolutionEdit, QSize labelSize, QMap* devInfoLineEdits,
+ QJsonArray frontBoardOneClickTest, QJsonArray frontBoardTest, QJsonArray frontBoardFuncConfig,
+ QJsonArray frontBoardDevInfoJson, QJsonArray frontBoardLicenseJson,
+ QJsonArray backBoardOneClickTest, QJsonArray backBoardTest, QJsonArray backBoardFuncConfig,
+ QJsonArray backBoardDevInfoJson, QJsonArray backBoardUuidJson,
+ QJsonArray getPicJson, QJsonArray getVideoJson, QObject* parent)
: QObject(parent),
- leftLens_m_imageLabel(leftLens_imageLabel),
- rightLens_m_imageLabel(rightLens_imageLabel),
videoLabel(videoLabel),
VideoResolutionEdit(VideoResolutionEdit),
- licenseHwInfoEdit(licenseHwInfoEdit),
+ labelSize(labelSize),
devInfoLineEdits(devInfoLineEdits),
frontBoardOneClickTest(frontBoardOneClickTest), frontBoardTest(frontBoardTest),
frontBoardFuncConfig(frontBoardFuncConfig), frontBoardDevInfoJson(frontBoardDevInfoJson),
@@ -23,18 +19,18 @@ DataHandler::DataHandler(QLabel* leftLens_imageLabel, QLabel* rightLens_imageLab
backBoardOneClickTest(backBoardOneClickTest), backBoardTest(backBoardTest),
backBoardFuncConfig(backBoardFuncConfig), backBoardDevInfoJson(backBoardDevInfoJson),
backBoardUuidJson(backBoardUuidJson), getPicJson(getPicJson), getVideoJson(getVideoJson),
- ffmpegDecoder(new FFmpegDecoder()), // 初始化FFmpeg解码器
- buffer(new QByteArray())
+ buffer(new QByteArray()), picBuffer(new QByteArray()),
+ ffmpegDecoder(new FFmpegDecoder()) // 初始化FFmpeg解码器
+
{
ffmpegDecoder->initialize(); // 初始化解码器
clearAllRecvData();
initializeMsgIdToCmdMap();
- qDebug() << "DataHandler created";
+ qDebug() << "DataHandler thread created";
}
DataHandler::~DataHandler()
{
- qDebug() << "---1--- DataHandler destroyed";
if (ffmpegDecoder) {
ffmpegDecoder->stopFFmpegDecoder();
ffmpegDecoder->requestInterruption();
@@ -44,7 +40,7 @@ DataHandler::~DataHandler()
}
delete buffer;
buffer = nullptr;
- qDebug() << "---2--- DataHandler destroyed";
+ qDebug() << "DataHandler thread destroyed";
}
void DataHandler::handleOpenFocusWindow(int itemIndex)
@@ -96,7 +92,8 @@ void DataHandler::showVideo(const QString& client, const QByteArray& valData)
void DataHandler::updateLineEdit(int msg_id, const QByteArray& actual_data) {
QString dataStr = QString(actual_data.toHex(' '));
- licenseHwInfoEdit->setPlainText(dataStr);
+ //licenseHwInfoEdit->setPlainText(dataStr);
+ emit updateLicenseHwInfoEdit(dataStr);
if (msgIdToCmdMap.contains(msg_id)) {
QString cmd = msgIdToCmdMap[msg_id];
@@ -133,8 +130,7 @@ void DataHandler::handleData(const QString& client, const QByteArray& recvData,
qDebug() << "read file data size:" << recvdata.size();
#endif
-
- //qDebug() << "---Received data size:" << recvData.size();
+ qDebug() << "---Received data size:" << recvData.size();
// 将接收到的数据追加到buffer
buffer->append(recvData);
@@ -148,17 +144,46 @@ void DataHandler::handleData(const QString& client, const QByteArray& recvData,
(static_cast(buffer->at(6)));
//qDebug() << "---Received dataSize:" << dataSize;
//qDebug() << "---msg_id:" << QString::number(msg_id, 16).toUpper();
- //qDebug() << "---(static_cast(buffer->at(10)):" << static_cast(buffer->at(10));
- //qDebug() << "---(static_cast(buffer->at(11)):" << static_cast(buffer->at(11));
- //qDebug() << "---(static_cast(buffer->at(12)):" << static_cast(buffer->at(12));
- //qDebug() << "---(static_cast(buffer->at(13)):" << static_cast(buffer->at(13));
- //qDebug() << "---(static_cast(buffer->at(14)):" << static_cast(buffer->at(14));
- //qDebug() << "---(static_cast(buffer->at(15)):" << static_cast(buffer->at(15));
+ /*qDebug() << "---(static_cast(buffer->at(0)):" << QString::number(static_cast(buffer->at(0)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(1)):" << QString::number(static_cast(buffer->at(1)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(2)):" << QString::number(static_cast(buffer->at(2)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(3)):" << QString::number(static_cast(buffer->at(3)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(4)):" << QString::number(static_cast(buffer->at(4)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(5)):" << QString::number(static_cast(buffer->at(5)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(6)):" << QString::number(static_cast(buffer->at(6)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(7)):" << QString::number(static_cast(buffer->at(7)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(8)):" << QString::number(static_cast(buffer->at(8)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(9)):" << QString::number(static_cast(buffer->at(9)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(10)):" << QString::number(static_cast(buffer->at(10)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(11)):" << QString::number(static_cast(buffer->at(11)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(12)):" << QString::number(static_cast(buffer->at(12)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(13)):" << QString::number(static_cast(buffer->at(13)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(14)):" << QString::number(static_cast(buffer->at(14)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(15)):" << QString::number(static_cast(buffer->at(15)), 16).toUpper();*/
// 第11字节为返回 OK/NG
bool success = (static_cast(buffer->at(10)) == 0x00);
int totalSize = 10 + dataSize; // 数据头大小(10字节) + 实际数据大小
if (buffer->size() >= totalSize) {
+ qDebug() << "---(static_cast(buffer->at(0)):" << QString::number(static_cast(buffer->at(0)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(1)):" << QString::number(static_cast(buffer->at(1)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(2)):" << QString::number(static_cast(buffer->at(2)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(3)):" << QString::number(static_cast(buffer->at(3)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(4)):" << QString::number(static_cast(buffer->at(4)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(5)):" << QString::number(static_cast(buffer->at(5)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(6)):" << QString::number(static_cast(buffer->at(6)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(7)):" << QString::number(static_cast(buffer->at(7)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(8)):" << QString::number(static_cast(buffer->at(8)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(9)):" << QString::number(static_cast(buffer->at(9)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(10)):" << QString::number(static_cast(buffer->at(10)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(11)):" << QString::number(static_cast(buffer->at(11)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(12)):" << QString::number(static_cast(buffer->at(12)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(13)):" << QString::number(static_cast(buffer->at(13)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(14)):" << QString::number(static_cast(buffer->at(14)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(15)):" << QString::number(static_cast(buffer->at(15)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(16)):" << QString::number(static_cast(buffer->at(16)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(17)):" << QString::number(static_cast(buffer->at(17)), 16).toUpper();
+ qDebug() << "---(static_cast(buffer->at(18)):" << QString::number(static_cast(buffer->at(18)), 16).toUpper();
// 去掉前面 11 字节
QByteArray data = buffer->mid(11, dataSize);
//QByteArray data = buffer->mid(10, dataSize);
@@ -166,7 +191,7 @@ void DataHandler::handleData(const QString& client, const QByteArray& recvData,
QByteArray actual_data = hexStringToByteArray(hexString);
//qDebug() << "---Received hexString:" << hexString;
buffer->remove(0, totalSize); // 移除已处理的数据
- if(msg_id != 0x0040 && msg_id != START_VIDEO) {
+ if(msg_id != 0x0040 && msg_id != START_VIDEO && msg_id != GET_IMG) {
//if (msg_id != 0x0040) {
qDebug() << "--- msg_id:" << msg_id;
qDebug() << "--- clientLastMsgId.value(client, 0):" << clientLastMsgId.value(client, 0);
@@ -179,8 +204,6 @@ void DataHandler::handleData(const QString& client, const QByteArray& recvData,
true, itemData, funcItemData, jsonArray, itemJsonIndex);
}
clientLastMsgId[client] = msg_id;
- qDebug() << "--- client:" << client;
- qDebug() << "--- clientLastMsgId[client]:" << clientLastMsgId[client];
}
handleCmd(msg_id, client, actual_data);
}
@@ -225,21 +248,6 @@ void DataHandler::handleCmd(int msg_id, const QString& client, QByteArray actual
void DataHandler::handleFrontCmd(int msg_id, const QString& client, QByteArray actual_data)
{
switch (msg_id) {
- case 0x0019:
- {
- showPic(leftLens_m_imageLabel, rightLens_m_imageLabel, client, actual_data);
- }
- break;
- case 0x0011:
- {
- showVideo(client, actual_data);
- }
- break;
- case 0x0021:
- {
- //showVideo(client, actual_data);
- }
- break;
case FACE_ENROLL_SINGLE:
{
@@ -297,7 +305,34 @@ void DataHandler::handleFrontCmd(int msg_id, const QString& client, QByteArray a
break;
case GET_IMG:
{
- showPic(leftLens_m_imageLabel, rightLens_m_imageLabel, client, actual_data);
+ qDebug() << "--- showPic actual_data.size():" << actual_data.size();
+ int lens_n = static_cast(actual_data[1]);
+ int width = (static_cast(actual_data[3]) << 8) | static_cast(actual_data[2]);
+ int height = (static_cast(actual_data[5]) << 8) | static_cast(actual_data[4]);
+ int format = static_cast(actual_data[6]);
+ qDebug() << "lens_n = " << lens_n;
+ qDebug() << "format = " << format;
+ qDebug() << "width = " << width;
+ qDebug() << "height = " << height;
+ qint32 picSize = width * height * 1.5;
+
+ QByteArray yuvData = actual_data.mid(7);
+ qDebug() << "--- showPic width * height * 1.5:" << picSize;
+ qDebug() << "--- showPic picBuffer.size():" << picBuffer->size();
+ if (yuvData.size() + picBuffer->size() == picSize) {
+ picBuffer->append(yuvData);
+ showPic(labelSize, lens_n, width, height, format, picBuffer);
+ picBuffer->remove(0, picSize);
+ }
+ else if (yuvData.size() + picBuffer->size() > picSize) {
+ picBuffer->append(yuvData);
+ qDebug() << "width is " << width << " height is " << height << "PIC size is" << picSize;
+ qDebug() << "But recv PIC size is " << picBuffer->size();
+ picBuffer->remove(0, picBuffer->size());
+ }
+ else {
+ picBuffer->append(yuvData);
+ }
}
break;
case START_VIDEO:
@@ -507,7 +542,6 @@ void DataHandler::handleDevInfo(int msg_id, const QString& client, QByteArray ac
case GET_FRONT_HW_INFO:
{
qDebug() << "GET_FRONT_HW_INFO";
- //QString dataStr = QString(actual_data.toHex(' '));
QStringList hexList;
QString dataStr;
qDebug() << "actual_data.size(): " << actual_data.size();
@@ -521,7 +555,8 @@ void DataHandler::handleDevInfo(int msg_id, const QString& client, QByteArray ac
else
dataStr = "前板发送的HW INFO 数据大小不正确";
QString displayText = dataStr;
- licenseHwInfoEdit->setPlainText(displayText);
+ //licenseHwInfoEdit->setPlainText(displayText);
+ emit updateLicenseHwInfoEdit(displayText);
}
break;
case WRITE_FRONT_LICENSE:
diff --git a/FactoryTestTool/SourceCode/RecvDataHandler/RecvDataHandler.h b/FactoryTestTool/SourceCode/RecvDataHandler/RecvDataHandler.h
index 369000e..26e1bd3 100644
--- a/FactoryTestTool/SourceCode/RecvDataHandler/RecvDataHandler.h
+++ b/FactoryTestTool/SourceCode/RecvDataHandler/RecvDataHandler.h
@@ -33,9 +33,7 @@ class DataHandler : public QObject
Q_OBJECT
public:
- explicit DataHandler(QLabel* leftLens_imageLabel, QLabel* rightLens_imageLabel, QLabel* videoLabel,
- QLineEdit* VideoResolutionEdit,
- QTextEdit* licenseHwInfoEdit, QMap* devInfoLineEdits,
+ explicit DataHandler(QLabel* videoLabel, QLineEdit* VideoResolutionEdit, QSize labelSize, QMap* devInfoLineEdits,
QJsonArray frontBoardOneClickTest, QJsonArray frontBoardTest, QJsonArray frontBoardFuncConfig,
QJsonArray frontBoardDevInfoJson, QJsonArray frontBoardLicenseJson,
QJsonArray backBoardOneClickTest, QJsonArray backBoardTest, QJsonArray backBoardFuncConfig,
@@ -52,7 +50,11 @@ signals:
void statusUpdated(const QString& clientAddress, int currentItemIndex, int currentFuncItemIndex,
bool success, const QString& currentItemLabel, const QString& currentFuncItemLabel,
const QJsonArray& jsonArray, int itemJsonIndex);
-
+ void updateLicenseHwInfoEdit(const QString& text);
+ void updateLeftLensImage(const QPixmap& pixmap);
+ void updateRightLensImage(const QPixmap& pixmap);
+ void updateVideoLabel(const QPixmap& pixmap);
+ void updateVideoResolution(const QString& resolutionText);
private:
QJsonArray frontBoardOneClickTest; // 前板一键功能测试 JSON
QJsonArray frontBoardTest; // 前板单项测试 JSON
@@ -67,20 +69,22 @@ private:
QJsonArray getDevInfoJson; // 获取设备信息 JSON 配置
QJsonArray getPicJson; // 发送取图指令 JSON 配置
QJsonArray getVideoJson; // 发送拉视频指令 JSON 配置
- QLabel* leftLens_m_imageLabel;
- QLabel* rightLens_m_imageLabel;
+ //QLabel* leftLens_m_imageLabel;
+ //QLabel* rightLens_m_imageLabel;
QLabel* videoLabel;
QLineEdit* VideoResolutionEdit;
- QTextEdit* licenseHwInfoEdit;
+ //QTextEdit* licenseHwInfoEdit;
QByteArray allRecvData; // 完整的一帧数据
int remain = 0;
int start_run = 0;
long dataLen = 0;
FFmpegDecoder* ffmpegDecoder;
- QByteArray *buffer;
+ QByteArray* buffer;
+ QByteArray* picBuffer;
QHash clientLastMsgId;
QMap* devInfoLineEdits;
QMap msgIdToCmdMap;
+ QSize labelSize;
// 如果接收十六进制数据,转为二进制
QByteArray hexStringToByteArray(const QString& hexString);
@@ -92,6 +96,8 @@ private:
void handleBackCmd(int msg_id, const QString& client, QByteArray actual_data);
void initializeMsgIdToCmdMap();
void updateLineEdit(int msg_id, const QByteArray& actual_data);
+ void showPic(QSize labelSize, int lens_n,
+ int width, int height, int format, const QByteArray* valData);
};
#endif // DATAHANDLER_H
diff --git a/FactoryTestTool/SourceCode/Widget/MainWidget.cpp b/FactoryTestTool/SourceCode/Widget/MainWidget.cpp
index 54848c7..454b136 100644
--- a/FactoryTestTool/SourceCode/Widget/MainWidget.cpp
+++ b/FactoryTestTool/SourceCode/Widget/MainWidget.cpp
@@ -43,17 +43,17 @@ MainWidget::MainWidget(QWidget* parent) :
connect(server, &QTcpServer::newConnection, this, [this]() {
// 检查是否有挂起的连接
while (server->hasPendingConnections()) {
- QTcpSocket* socket = server->nextPendingConnection();
- int clientId = nextClientId ++;
- QHostAddress clientIp = socket->peerAddress();
- quint16 clientPort = socket->peerPort();
- QString ipString = clientIp.toString();
+ QTcpSocket* socket = server->nextPendingConnection();
+ int clientId = nextClientId ++;
+ QHostAddress clientIp = socket->peerAddress();
+ quint16 clientPort = socket->peerPort();
+ QString ipString = clientIp.toString();
if (ipString.startsWith("::ffff:")) {
ipString = ipString.mid(7);
}
qDebug() << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>";
qDebug() << "> A client is connected. ID:" << clientId;
- qDebug() << "> Client IP:" << ipString << " Port:" << clientPort;
+ qDebug() << "> Client IP:" << ipString << " Port:" << clientPort;
qDebug() << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>";
if (ipString.startsWith("10.10.10")) {
@@ -96,14 +96,11 @@ MainWidget::MainWidget(QWidget* parent) :
handler->moveToThread(thread);
// 创建 DataHandler 对象并连接信号
- DataHandler* dataHandler = new DataHandler(leftLens_imageLabel, rightLens_imageLabel, videoLabel,
- VideoResolutionEdit,
- licenseHwInfoEdit, &devInfoLineEdits,
+ DataHandler* dataHandler = new DataHandler(videoLabel, VideoResolutionEdit, leftLens_imageLabel->size(), &devInfoLineEdits,
frontBoardOneClickTest, frontBoardTest, frontBoardFuncConfig,
frontBoardDevInfoJson, frontBoardLicenseJson,
backBoardOneClickTest, backBoardTest, backBoardFuncConfig, backBoardDevInfoJson,
backBoardUuidJson, getPicJson, getVideoJson, nullptr);
- qDebug() << "dataHandler->moveToThread(thread)";
// 将 DataHandler 移到线程池中的线程
dataHandler->moveToThread(thread);
@@ -152,14 +149,23 @@ MainWidget::MainWidget(QWidget* parent) :
connect(thread, &QThread::finished, this, [=]() {
onThreadFinished(thread, handler, dataHandler);
});
+ connect(dataHandler, &DataHandler::updateLicenseHwInfoEdit, this, [this](const QString& text) {
+ licenseHwInfoEdit->setPlainText(text);
+ });
+
+ connect(dataHandler, &DataHandler::updateLeftLensImage, leftLens_imageLabel, &QLabel::setPixmap);
+ connect(dataHandler, &DataHandler::updateRightLensImage, rightLens_imageLabel, &QLabel::setPixmap);
+ connect(dataHandler, &DataHandler::updateVideoLabel, videoLabel, &QLabel::setPixmap);
+ connect(dataHandler, &DataHandler::updateVideoResolution, VideoResolutionEdit, &QLineEdit::setText);
+
// 启动新的线程
thread->start();
connect(handler, &ClientHandler::startReadTimer, this, &MainWidget::startClientReadTimer);
connect(handler, &ClientHandler::stopReadTimer, this, &MainWidget::stopClientReadTimer);
//handler->getClientId() == handler->preVideoClientId
- qDebug() << "---- handler->getClientId():" << handler->getClientId();
- qDebug() << "---- handler->preVideoClientId:" << handler->preVideoClientId;
+ //qDebug() << "---- handler->getClientId():" << handler->getClientId();
+ //qDebug() << "---- handler->preVideoClientId:" << handler->preVideoClientId;
connect(this, &MainWidget::openFocusWindowRequested, dataHandler, &DataHandler::handleOpenFocusWindow);
// 创建和管理定时器
@@ -295,7 +301,6 @@ void MainWidget::onClientDisconnected(ClientHandler* handler)
*/
handler->deleteLater(); // 延迟删除 ClientHandler 对象
- qDebug() << "-----------dataHandlers-----------";
if (dataHandlers.contains(clientId)) {
DataHandler* dataHandler = dataHandlers[clientId];
dataHandlers.remove(clientId); // 从容器中移除
@@ -448,7 +453,7 @@ void MainWidget::setupUI()
mainLayout->addLayout(rightVerticalLayout, 3);
setLayout(mainLayout);
- setWindowTitle("SL100 工厂产测工具 - V0.0.1");
+ setWindowTitle("SL100 工厂产测工具 - V0.0.4");
resize(1340, 900);
connect(startServerButton, &QPushButton::clicked, this, &MainWidget::onStartServerClicked);
@@ -680,7 +685,7 @@ void MainWidget::FactoryToolSendPostLicenseToHttpServer(const QString& hardware_
}
void MainWidget::startClientReadTimer(int clientId) {
- qDebug() << "------ startClientReadTimer clientId:" << clientId;
+ //qDebug() << "------ startClientReadTimer clientId:" << clientId;
if (clientReadTimers.contains(clientId)) {
clientReadTimers[clientId]->start(10);
}
@@ -1268,6 +1273,7 @@ void MainWidget::onSendGetVideoClicked()
//QMutexLocker locker(&mutex);
for (ClientHandler* handler : clients) {
if (handler->getClientId() == handler->controlClientId) {
+ qDebug() << "lens number:" << lastClickedGetVideoCamIndex;
handler->sendGetVideoItem(itemIndex - 7, lastClickedGetVideoCamIndex);
break;
}
diff --git a/FactoryTestTool/SourceCode/main.cpp b/FactoryTestTool/SourceCode/main.cpp
index cd1dae6..aa40d70 100644
--- a/FactoryTestTool/SourceCode/main.cpp
+++ b/FactoryTestTool/SourceCode/main.cpp
@@ -23,8 +23,8 @@ int main(int argc, char* argv[]) {
//FreeConsole(); // 关闭控制台窗口
QApplication app(argc, argv);
qDebug() << "Current working directory:" << QDir::currentPath();
- QIcon appIcon("./app_icon.ico");
- app.setWindowIcon(appIcon);
+ //QIcon appIcon("./app_icon.ico");
+ //app.setWindowIcon(appIcon);
MainWidget w;
w.show();
diff --git a/FactoryTestTool/frontBoardImage/20240903_152605.jpg b/FactoryTestTool/frontBoardImage/20240903_152605.jpg
new file mode 100644
index 0000000..2e4f82f
Binary files /dev/null and b/FactoryTestTool/frontBoardImage/20240903_152605.jpg differ
diff --git a/FactoryTestTool/frontBoardImage/20240903_152605.yuv b/FactoryTestTool/frontBoardImage/20240903_152605.yuv
new file mode 100644
index 0000000..f390f98
--- /dev/null
+++ b/FactoryTestTool/frontBoardImage/20240903_152605.yuv
@@ -0,0 +1,220 @@
+HqėuP:25""&/&)-/!3-$5<2GBDL?J?85A>G>7/771181?+55:723KDJFKJM?D0<+)87>?DCJDPMLVPLJGIDBBJZ|oR8:55$*"%%$/+$%%&!(%%$&&!.$("#$)&/02#)+%((1&*&"#-0"#-+)(&&$)-"&&&3%$++)%%&+)"#&&%%(8($&"#$!(./!#+*2%/)(&)#$***$!)-&)*(*-$#"*"%##$*$+*(%%*"!%(&#%"&!&%!!"!"!"&(!&+&%&0&&*+.&"#(%(&&"%"!")(++#(++"%$!!&*!+!&&&%$*-"!&&+&%++28Sq٭jM7."#&!!!#+#(7<:GFKJJA?G38+2&08.821BE??JKLVPSSMPRI?BETawwR5(.(+/3*$&+'#%($&-/7$/,.02!()&1+#% #/) +&"%!$%)((%+#+&!/%)(&8"++&3-)+-/$&/1(!&#./##$ %% #2$"%&!*+$*#%%)!+&)&&&&/$!#&)&%$!#%+)"$"%&+%"%/*$!&(3)&"#)%#&&-(+.!)1"#&&&(&(#&&+($+&.+$1*#-..&+#(($%!&% !#!&)%!"$"$!(-."#"$-/5Cgyb<01$/$*)&22:GFMJBHD?F8:58<><885?8CFMHROJWWTMMCG?EHO`}rVB5#&&(&5%$%"#0 #&+*!08(! **'+-$#*,&&%%+&&73(+$/(%&"$+%"*%)&+(*%"!""(()!(&&!0*"('&%%"!('($ +" $'(#)-'%!!*&&-+!**%!)!"&)%%)%-(%!!(&#%&##"+!$#"#&"##$+)!+&/-("&$&"#&!"(.%%%*$!+!(+"$###$#(#+$!&&$"$%!"$)"%$##!*+!!!(2JMRLAF?::78?5?::<>7?CHJKJZTPVTOOMIDIM^ɓuV::2+"%*."+&$"%!&!)&0(#*(+7802(*&"&*++(/%++&)+!./++*&!&%/#!&)&$&!*#/.)#&("$*(&##&&"""$#&%#&%*+$#"+%"()+-("))&%&!&+.$#$*!(!("#!%)(&%+")%!%""!+&&!"$#&!&$$&*"+/!&(+%"-%%$($#$&""&!(!!"##!")"+&+*.&(!!)!/?FA8?8?27:27>>FMII\YSUPRKMMGKHMaʚoZKB1/-(##&+%$"%-(/#-%0+2-#&"%&"&-1&-&&/..+%&%0++/&$5*&(&5$(-&)-%-)$+!)"!%!)+%#&)((&"-/&&((&--("&"!"&)-*&#+$*!&$*(%)!($%#%+-%#")!#%"&((&&1"&&&$!#&(%&&!%!&%!&&"&%%/&02$-("&"%(%($/$!+#&!!"!!$&"!(&"%!&"%$)2/&/2MbyƠ^H0&$"""5$&&&)("!/*?8ADACC288/8C>::5CD7C3:37:8(:8FBDFKSRVYZOTOOHEEHZg˛uYC121-5+-!#&**"',27&)+(#'+&(,'!02/+'$(#+*+!%+"&*.(+(+(*&$)&%%)$$)+(00$0#"/"%"(*$!"&,&!&(.-&,&&*"""&+%"(!"+#%)"#3!!&+(+#+(2+(%&+&!(!-!1+!+#&&!#+%"-%*"%"!##")!&(+"%"##."+(%##$0+"#"$&%#&%$%#!%#&!!%/)%$$"0%.# "!-%&&%$$+"()#+&+!)(""-+BPkw]<)&+&%#(%20:8BKEAHHF8F:<280:7A72JIMRWW\ZWUPPMIGBLUeϞyWI:+%*)&+)1&++*()%&!+-%"")& $-("+&&(/.0%."#$&().*(21)"-2*#++"$&))&)/#!(+$)*(+)($!*%*&%.)#"&((!&*,)+%(%+$% !(#&#("%$"$)&*))+/#+($!#!$#(%$#!#++*!#!$(&$#"%$%+$"!##)#"&!"*$)!"$(#&2$#"&+!#!!&#!$(!!!!#-!$(!#!+$-*77>G`yױkL8-11#$!&%)&+5?DJWWWZ]\TPDCJF>YeϞyYH7:2/%*+-"%%+-&)1-&-#!#"./.%2&5--/+*%*+*+*-&&1)$&"2&&!"%(&.!%!*(&&$0%#"*+)"%$&/
+0#$&%+&+(20%%$(07&&%#&%+!!0)("#&$$&%!+#&!&!&.+!"$2/(#")&()#*0%2*&%&!("&+$&!&##.$&)&!)!%-"/)!!(!%
+$%(&)"&!#%&!"
+%!(!("!+&&#$!#!!##!"2&00:\grYE.!#"+#"#&&"*"%$5:-(2.&%!3))!"%+*%$+&$*++5$0!!++*+&0-*(&(&2*+&+**+(&&%-&&#-!&.!$()"1!#&$"$&+"#(&&&"#%$"!)%(*2++*1&-&)###!#%&&*%!*&&($&)**(*/&/*.(&!%"#)+$#%$"#&&"&$%#-(!&!$"$"!!!#&&%-&)"##"%*""+()&%#"%("!")&!"#&0"#)$+(.!#$*#&(##$%&"$)*&2:Ii|ҨqM70$#&$&&($"!02<3>EH?8C:?58322C:F??388:?<5?:7?8Fjx默ySE8/"*%*"%1*5BA2:?B:EKMKRRMVZ^ZZTOKKGDSgϣ{^??2-((+&$(#"$1)&)%0.35$$$(*$&)"%+%+)(1)($30)+)-2-($%)&*$)&&*)"("")%)#!$#+&!$!0&0#&"*)+"%&)##&""**0"$"/!$(+%#)&&)&*%"%#"%/"&((0%-$(%+&0+&&.!##%!&1(#!*!#%.!"%&)&"""$##&$)"!!""%#&+&"+)$(&!$$"$+!($$$"#*")(!!!"#&!$%"!#")-218A>WpϤaI0%++%#%"%)%$%&2BLA?<8<7BH::G8:LUMPZWVUUSMMLKESdϤx\J22(&2/$.$*.'%"*2&(+ )+"*4/$-!&&)*!/++"!!&%!&/+$-$!#%&53%/.&(%)1."#&)%+)$+&$"#-&/(,%+))&'"1#&"",1#/"$'/(")"%.("!"&$&"!%#+*)$#"+%+3%#&/#!%2"+%"#*&+/&&-#!8000#*))"%!
+#"" $$")."%&*(%%&!.!2$%
+&(.!+!
+)%""+($%0! &$%*$$!$!1&)).*)-7Hj~㵑qUB8+&$$%#(/2/C:>8:2158>AKPRWUU\ZZOTYOJLBGVexZI2/2*#(-&/2!&!&2%)-&""+&$)*()"%*#$#&&+1+&%(&%)"$%"&&-%&*.&%+($)&-&)!-/+5(&%&$!$#&*#(!!%"!&'$&('%!"#%(!).)$!(#%+%#!%"-2+&&$%&!!&%""%-"&$"($&%$#)"&!)##"%"##$%)(%*!)!#")&$&$+(&##%)"0!
#("&$&"-(-#!!#+7:D^y˜b8-("&.1&("##!"5233AD:5288:2:<*+8:8EPSTWW\YYZPMLOJKWq}ZF<--+&*+#"-.+-0-#+#-."$&))//+##&+%&)$+*.#".$5++!+%1(.*&(#&%#(%$*&"#$#)$-0($1)&&$++"!&!(&*$*%)&#"&##$%"&!*(
+!$""!*%$$%.###!%**#++!)/#&&"#*#!&"$((+)&&(*&%&(&%#%#-/&$$(!$""% "#$#&.($%#)%(&!$&(!.!"%&"#!#/%##"$&!$%%$""+*()$5**)*>DVqrF72"$&!#$!85CF8?B<:75:8>BCFGLOMOTVYVWWTRKIGKUk~yWB810$%2%&-+)/"!&+(%$&+&&+%#(&))()%)*%%/(+$(%)+)!)(%%($&%&)&*&+%&!&%$&0#&-0!)&-&&&!$!&$!&%&)&!!+&"%*(&&%$"&%&+#(+(*%%%!"&$&&")$!+%(!)&%!&$#$)$)-$%$$$&"&$!#!"+&$$&#"%!%%#!%&$%#%!!#%"")+*!+&!"-!%!$+!%#%-)21:Iey~b?).-!)!$"%#(%%1:518EC57/7:22EBIDHOPW]WZZPRUOGBDWi{㶑qW<1555+)*/*$"# &$'!#.%"1(.),+%.3(%,21. %(- -!#*.0#.&++2&&2$(&$&0&$$&%(+.*(&()%&)#)&&#"$$& &%2&$/"/ "(*'"1*%$()(/$#-%&#($"+%$/"$&.&!#&$&"%#*((&*)(*&$$&&%.-#!)"$#!"$+&#!$##!!)$)##%!"!(%$&&%$!*$&"*#"!$$!%!" "&(..+&"5AJVnձmG85+.+%#(+$".(2*CG<:A<8>73:?EFEI>?LLPWZUW^UTVRILDTbu¨rI?78&2)+--*.%%)%"0-*%!&%&&.$!$2&$$%-&&22(&)*(+*(%+*"+&$$#%#(&0%!&%&)*&2"&(+"%(+*.)#*"%*&%#!%$#&$
+$%+!&%#!&"*#*#+!))/.-$(%!%#-!&)%%%#()#!($%/#.$+.0&$&"#)%+)$("
+$"#."-*&-%!&%&##%"$ $!&&"""!/*%$"&&$&+?:5Jax͡iE/&(+"%&+(&)%+<??B?>B8?5C>DFWTPVW\\YZTMJGEFHS]wɳgUC712*31*&(%-")$"&"!.'*()"(12(%+$"$%$ ($#+&%%*$$%&+5#+*)-"*-)/&(+2#$"*&+1)1)#)$&&$+! #
"'##&"'#)$(%%!#(%#$#"!1*%&&+%")&%++$*#$"%++"!%$0+%*%"&&)*!#&*!%"%((&&!#!#!$)*$)&$#$$+-$$!&$&&&""%0-!#&*%$##%% "-"&$("(
#")!"((!#$$$2?Wg}ʞ~ZF"&*!#&&&1&+H:8<82::25<57?DMMHMTU\\^ZZZPPOKDIR^qŭqRG://%)*&+%+&&$"#(&)*'#/(1+& &&&0(#& #.%%'&+$&"+$++(#1++&""&!&-"!-+!#$#%"#%#)&+#!&&%$&"#")#'#""!&("-)(#$!&$!(&+--&(%!#""*%++&!(#*%)$&""%)&"*%(&$$#%#$$#!##%#$%(&%+!#$(!.&!"$&&%)&&%""$+&!$&
!'(#&&+!"&+713KdrܲgO2*%%&!%!(&)!*+>H<>??85?87??7GHMMMSRZ`]Z`UTTIK>JMWjάrLH1/8.)2/++##$##&))"+!%.(./1+-%-*-+.)&&""1&&-#&+")&)(-##+--+&(.(.$%"+&&"#&&*+*&+*!&#*#"&$"!+*$#!#%+0%%!+"1"%!/+-.*$&$**!(#.()%("&+"(%&-+&!$.+-"#&(-*+&&&&$##+*+#"!!!$#!$+!$$+"#&"&$$$+!&%#/($#!&%&!!$%*-$&!!(&!+/#)"(*8AZk껟{\52:.&&%(*!#%&&<5<<8??:5?A>?EKOLPWWZ^`SWPMMIMJG\qrZH52%*-&%$#)&.#!((+&+$)#&(!-!.(("&"#&)!!&!&%%&*)&&$+&(*.!+)"&&-!%(&()#"*)+)&)+(&(&"!%&&&*%&$&%"&)$#!*"!#%"))$&()&!$$-($*&$#$&.)#.&"&)$$"*&$&%#$##!)!"&&&&+&+(#$"%!""$!%%(*%!#$&")"%*""##"!$%#$$%!##!!)"##%%&&%&!%(++%/BObҪi?82*&&"""!$)728YjǠ}dE0-)"%$!&%&+<<8?AID0:::E?>EMPUYZ^`^ZSLODPHG^k}gG8+$+&(+($2+(*%1.+$"-&.$&%#/5+++()&%.++(%*&&$#$&/&22$+$!&+(+(#%"!&!!0&"&"#/2#!%&.#!$#!&!!(&!"$*#+&"&."%&*!.!&*&&!)$#.&--)#""%+("%%!""!!+&"#-%%%-*)#&#$%#"#%#!"""(&*"".&$-*#"+"%%-+(
+!#!!"&"&"*!%-+&"%&!+$#-/<:Id}⫐kM:)/%+&&()?<<25?BJGPPTTW^^YWWVPMFOK`p˨iO5102&&.!.#+#$-+##+%/+)#!)&-%(((&))#&(-*"%(-2.&)$)02*$"$)/+&$&&%%$##+-+&(%"!&&%!(&&&"#$!""&!&$%-("!"!&&"%&"(&!%&%"&"-++!)$!#)%&&%"$##$!&!"!$!$%!$"!&&""!&!%!!$"!!$%)$!*"!#/"#%"!$!$$!!%!&%%%$#(+/28M\u{Z>0"#"&&&&AA<>A55>:/5B:>?IMMPSTWW]^WWWSLMMHYpүiM30111/&"!#+++*/$(("%0#&$*'!$1'%)*'++$++(*+-#!!""(#++++&&"%)$%#&"/#)#"&&&)#%"!"+$%#%%"!%$#"!( "$#"++)*%$#!++&$!&)!!+"%%+$&!&)#+%#!#""!!#""(###"$&"$+/-(!%#!%$%"#%$!&$"!+!#&! #%$!"&&"#&/23CVkիdM-(*(-*"!%.18C<<858FFMPPPVWZa`ZZSMPPHR]wǟyWA857(/)/&0.'(())!$-&*0!!"/7$%*0%5/)(,,#*&0$($!0)"$&+)#(&$"!##.*&"%)+*.***&"&)(+)#"!%/)%$*!$-!# &&$%&&%*$&0&#)!#+&(#"0#.)*#&()*$"(&$$)"$%+&(&(%#"+&!+!!
+!$%#&&%(&$&&##!#&%%%+(!+#&*%&$("!!
+!#*%#(*+/CJd~|\F-&"&(!/+C:::EA<87:?E?A5?78?<88B?*85:?GJEJRWU\\ZWWWTOLKMZqתbO:3&)&&&"&+*((!+(#--&(2)%&%#%!""&(:!&!&$$))(%*)"!0+"%$!$#%&-&("+$"(%$%*%!##(!!&$"#"!"&)!#&!"$#+""+(&%&#($""!&"%%&$#"$%"$!(#%&!"%!"#&&$%&"%"$##&$"#!!$%""!#)%!**$%%$%)*%&5?Mb~ěy\<25-$&#+787F7>AA>8<3::5DMJKYTWW`Z\]VUPMHSZpޱdO>5.$0+(&+#+)+#&"($(+",#(!0&.*,-%##/)-#*1)!(2&(1++&.$&.52+((!.*$"%$&*%#$2%(.*%!%!#"
%( &!"$&"$$$'#"#$%&&&-%)!/($($$"""&!#&"&!"#&!#+&&((%!&%")(%%(&"%!#)"!!$ &*&%$"#%%" ! %
+%#"* !"58AbwҥjL1++!#%$$F:?<:2:778AEMLYSWYYWZY\WOMLMWn붔oUC52(&$+)!$&"+&!!!$$#($&"*+%)+&((&1/(%$#"&&!))()++#!+$)*%-#$&!&"""!-&0#"$"#!#$#$$$!%-&&#!*&%!&)&$($&"%"&!&!!(("!!##$&"&!$&*!
+!&!!!*#)"%#$!""!!$%"&!"$!!+$%-#"$%""$/+7:K`qЫdM5+&%!#1<>><<<:81BC?DEHKKZZZZWZ^WPTMMMZmqYC72&*&&!&2#*1%&$-((!"-,&&*##+"*(#$*-/#!#&+%*$&!++&$$&$%#!+&5!##&!&/!$($%&")("!$&)(!"#$&%#!$$'&&(!!!(#$!$%"-&"#%&$$#"$%!!#)"$"("##&+($""!-#()!&*&!"&!$"#$%&%"(+)"$##$"#!!%%&&&.+2:FVk嶖rP!(*!&B:?:<8<(5>:8FGGKOVTW]ZZ\ZTMOMOWg~ y^A<03&+8+)%#((!"(/0((&*(-(&!$!&&*#%"$&"#(1(#&&"-".$+&")%-/)&+"(%.)&""+!#$$"##&$&&+##"$)!!#$#"!!&($$&("%%&"#%(($$/!&#$&"&!#!"%$%$&%!"!!$&!!"&%&*##*!%")&+%!$$#%"!%##%)01DZu٪oG22#*$71:38<:8888>::BKIKMPUTUZ]ZZZVUMKI]eɤ{`I82--/&+-""!(*(#/&&%(*&+%"#%!*%)&).)+*#"+(("+#&%(%""+&("+"$%&!%"!$$"(+)#%""!#%&!+"#"&!%#!&%!"!"!&&$"$!""#"*"$$#%&"!&!$!%""%!""""#!!+("
+!&!*$!&$%!"&(+/:CUq縙uU7-)$"&?/88:5J3><8-<Og~ɡ\H2%:*%:5337?A<>5/088??HPIPTSW\YZ`ZUSPOPVc~ժdOB31)-+2+&-+#!*" +(%$" )1" 4+&!".)'(#*)-*)($%&)#"&&((-(#")#+!&!!%#)&)+*%!#"!#&%$"$ !"#!#!$!"!#%!#)$)*!""#&!!&"#!"!""!"+!*$#$$*)+#%($"!-"#&"&!""#$#!!!!"! "#!&$/&" !#).0(?OZwޱqG81"(&&:?AA8.5<58D1<<+2-&%758?><>8::81:<?ABEGPVTUZ`\YYWYVPMJVcq겎oSD887&&!&%&&)$% $&. %%''%-'%",#2.$2+&&)(%)/$)!()(+!&%()%#)#&&$""#*+.#%!"+0)"#)#"%&
+%(* !%"('!!&($"((+$"!!&+%!(&%#"%#+!# &!"*&!!""&"&(#!!!#!%&!#"+$"&""!#"#
+%&
+ &" #!)"###+%377<<81:37:8ACJKIRUSZ^ZZYWSPLLR^p굓pPA870+.+.%*))&&&"%&"$$&+'"&& ("#(%&**$!,&$&%&$")%&$+)+(&)"&"##$"#"#("#"%%#&+*!&' $$!$!#""!#""+&"!!!&"%&&!"&&+#!%%&"#&(#"&%!$!!&($!&&!!#
+% #%$!##$#!)"#+8:KWn|WF.&)(8/5?E?5:>F3B3::BKLJUWVWZTW]^WMPPMS`q깔uVE723*(#)*&+!*&&$$&"$"+()+&!$&()&"$!&*"++&&(&)(!($#!!!!$("!$#$#))$&#*#!##%!&"%"!&!!$*!!$##)"!%#"!!!#&)("$%&)%%""!$$#"#+#$+!!"(#""#!*&""$#"(!!$#!!)%"#!($)$#).&)KSmУgG$&"D7:?88:<:872<:58IEEPSWZ\^^^aZRUMMO^mwWE:5+.)((&*&+&%%%&&/)&&&%"&#$-2&!($#("$&&!#(0"!$!!!)($&+$"%(&&%#(&"%%(%($$)!#"$%!"%!%#!"!*"$!##!!&%!!!#"!%!&""!#"!$&%$""$&##%!"!%*%&#"$!&#".2:858>RLMUWZZZWZ]YWSPKMWqơy]I:750!($(2+(((%&*+"""*()(,-#+$!!$)(*,+&$&&)+-+%#!!2!("&&"!$%)&"!+&%!#%$"%%$! %(!"&$!!&#)$$!
+&"#!$&"&($&#)##!&!#!!#&!"""""!#%("&!!%" &.)85G^tw\8&&2:<:A8<<80-778::D<5>:71:CCFKISWSWY\Z]\ZVPPOPYjޭoLA822*5&&(&$+%%!$#+"*.#!$* $(')+$$$$($$#)"!#%$)#%"$"$!"#%#))%&!!"" !& $!"%)%#!&!"%#&!(#$"!#"&#!%$$""
+#&*&!$)/!"%$%$"
+!!"!$&#%'"'!%#$%$+)17AYnҧ`J5#%)#(8?<8<5::7585558CBGIKMOVWY^^`\VTPMM^k~ⴌkPA5+1-)-+%$$)(2"!+&*%")(&$ "%&!0)*%+#%&*,"*%(""(#"&!&&&&&$$!)"!"&"$"%#+&)#&"$($"#$ !)"!(!$!!!&*("!#"!"%$!"#!##
+#%##&$!!%!&"%$"(!#% !" %)&0.-2?Tk~굑kM8%#<>818C<:5778:<.?DJMTPRSY]^^^ZVVVRTTe当pY?>0++-0&(5&-)-)))$$%*%)&&.&(&)+(%"!&+#&-+!$#"%%$#%*!%%"!")*!$$#%"$&"")%!$"!&$("$#!"#!!&$)"!%%&!$#"("&(#!!$#)!#&+!""&"
+$%!$##+"$%$"#(""&+"-$#"%!(#"&!%$%&%!"%%"+!*)08:Sa|xP5."#:8:1<<<:<:<<28?>>?EGLPSZZ\^\\WUSMTWdnZA>3-%)+()-&&.(&$$)#+!%$&)!#&!+!!#%#*!#(&&%#!#!#+"$(("!#"$%!"+1"&%!!"$!"!$#!"*")#"!!&!$!!!%#&#"($""!"$!""!"&!%&"!&#%"$!$!"!&!!%)&-*!#$&+1:5?<.85>278CEKFOPRWWZ\\\TSPRUWaxtYE:1.1.-+"%++!# ,%%&*(%&)#-*$*%!((&(!*!!$#"!+./$"))!!!"$$!&&!$!%!$$%&"#%% $+!"# &&)&"!"
+"&!!!$&"&$#"##""$$%&")!"%"!""
+"""!""#"*$"&"(&
+!%!"#$#)%%("!%#**)$)2AZnൎkD<)!B??8?5?:3?/7117?DHGKPWWWZZZ^ZRPMORZd{ɟy^B>..++(-&.)%&)"!(+*&%!# ($+ !-+%)(+)$&!-!$")(!#"."%+#$!!&+"#!"$!(!!-$%&)$!!!$!%!## !!$##&%"!$&!!%&!!($%$(!!!!"""%"#&")#"$#%&$(!$%%&%!$)#15?Mg~xZ5($&5<<<8:82858578?A?BFPPTUY]^YZZZWMPPRb{ˤ^H?52(...-+&/$%+%#$)$)%$)!$)&()+%"$"%&&!"*("-##(%$&&!&$##$!$(++&!").)(#"!#%%""#(+"%##"!!""""#"#""+#!!$%")")%"$$$"!%"!!#####!(!$"$!#
+""&""#+#&+%(&$#%+8LWuЦ^C2+58:<:/7<8?8:53-8BBLPRSTW\]Z\ZYSPRSWdrШdM?:2.0./+"(&(*&"+"&$"))%&%$$%!%(#%%&%+%%%#"%%$&%$$$&$!+"!$#&#&)&!$(%"%#!%"#$#$"!!!$##"""$"$$&%%"#&!#%""&")!%"!%!$!!$&$"!+$$#%&)+1EZq㮒gF5%&*.::7?3:7??83<55DDMLJSUWY\]]WRSRMMdu֬dOB:5/-+/&-$'#%&.)&&%&)'#)'&&")"+#" &!!$"&%&#%$)#($#*$(#+#&$$""!""!)$'#%$!"%!$&%&&%%!&"#"&""&#$"$#&$0&%!(()"#$$#"#$&" %&("#-$&)&$!!"%$)/3(??7:<>8?<813888:CIHEPPWZWU\\ZWSPMMT\pױkO<83.-*)!%+'*&&(0"("$&*#$#)#%&&*#!!!"%"!!+* %*##$&"%$$%%!#%"""!#*)$&)&!$$!&%$&!+%%#!" # !#!#%$*!!$#(""!&!"+"#&*+%#!$&)$"#!$#$"#!&" "#%%"$*2(&$3+<7??<:>:<<8B8?2AAPPPVW]]Z\]\WWTSU^m㹌jMF:++(+-1/&&%$.!&""$2+.&&0$%&!&()&(%"("$+(+$#)+"%$#")!!&/&0!#$(###%!$#&)#"(2&&$+!!!%%#"#!#&!$"
+
+
+#"&&#"+##
+"$&$%"#%#!$"##+5#!#")$*&&.8>A<5:?85:57:<27??EGOPSVVWU]ZUVSPSP]n꺒tTG:72+$/+$+)-&%&(")&$%(#"&)#%%((##"!!"&&&%+"&&"!#!!%##)#$%$&%%"($%""#$!!$#$&!!!"!#&"+&!!!!&$"###"!
+$!$!$!#!!#%#!##$&*"#"$&&&$+05CPn罗nO00+>35A><<5/>?>5555>?KHLMTPU\Z]YZTWWOSVktZ?7853-!3*%%&#$"#+ $"$.(""##)*#&!&"&"*&%$$%&%())"!*!"+)*((&"!&"%#!#!#!$#$%&$%#"$&!(%!& !#&&%%$"%&!!%$#""!#"%$)+$"$#&&""#% " $$ &$"&%/$08Kiɡ~U?+88530888<<8780ICJORUWZZZZVTPMJPWe~t\G8730+!(*)++%&%&&$%!$&%!("&("&)(#&($ !$$*#$!####$#%$$!*$$"$$&""$&!!# " !##"% !$ $#!"!"")%#%!!!!!#&! $%&$%#!$!& ##"&&!$$"""#%%)-+22AG]uӭaC2&58>:?582175228?8<IJMSSUVY^^YZVUMPTZg{ͧ~bHA<.*+/&&*$)!%#(!%*(%$-+&&*&*#!+$$()%%$""!&"$)&"%!&%"!!#!"#""())$"$!$!&&%!##$!"%!"("%"$!+"!&#%$!"!"!"#!!"&&$$#!$""!&!$%!""$"%$%#723CPgxU527JMLKMUV^\]YUVUPMRVdxϫdP>7+$2()-#'%$&""-!')!!#(-#!+$'%%'%#$#!""$+$&(!"$!$&&$&(++#$$(!&"&$%$! ""#%&$)##&&(&"!""!#%%$#"!!#&!##!""""&!#!#$(+!!!$!&"!
+"#"!&"#"#"(++(+113AFg{ϨWD5:758<<5:<2:?2<53?AEKMPPPUZZ^WWVPSOUVdyիdM?5./+$-+"%"&$$)%#%##$.+$#(%'(**!%*&$&$%"+)% "%"&&"%"&$"&%0#!%$$$!$%""&($&&&(%!"&&!$"# % "& " !%###"!%"!#"!#%&%#"!"!!!!!$"#
+"%!")!!!!&#&")++0-<:8:588?857<825?787<585?<>:F7>::78<.::?2.2-)&%0&+*)&(%!(&$"*!"($$#(""+&%))$#!&"#"$!!$$($"%"%$#(#!!"!$!!$&)!%!"/!$$#!"!$!%&$#&$!##!!#!!!%!"$$!!"#!
+#""&!####"&"&"-+2COd}լ]7B7:>A><<<57:88?:/FGGHOSWW\ZZ]YPSMRU]cxԦcK8835&.&$&2$&$*($&'.")($%&.(!%*#'+ ."#!#))$$$#"%$!"&#%%&%%"!&&$!*+"+###"1""&*$#(!%"#$!(!"& %#%)"&&!&#$&%!%$%!"%&+"!)#&"$"!*/&%&!$!!! & !&&")$&055I^wⱍb<7888<7A55:<::58:8GEMOLMVZZ\\\ZZSRRPWexԫgJ?32*.+.+&+*%)+&&"&&%)(")()%!"&%!"&#-#$%#"!%!$#!!)("(%(##""$&(%&"$"#$!"%$"#!"$!&!$%$"!!#%%!$"##$"$%
+!!!%!#!!$!$()+08?Wqg83:.8:8+08?58::<<7DGDPSPTWY\Z]YWSSPPTewܱmPC:.23-2+*0+)+%+&&&+*!%+(*#.$#)***#$$("&!#"$%$"$$(!&"##$&&.#!!#&"#"(&&!$#%%(!!"!"#$)%"!!&"#"$#$#!!!$&$#""###"&$("!"&%$"&&&("!!!%"""!$&0$-!&!"$#&$&.1?CWkǠy:535:?<2?<<58800:7?>FLPRVRY^\WZWTPRPU^q峑iRD<:3&5&*+*&)(&)+))%&$+)(()(!&++)#+)!!!%&$!"&&"!$&%$"%&&$!!#"&$#$($"%%$($$*"!##!&"#!"!!&&""$!$"#""%!$&$#%!"""!"!"%$"$!#""$!!!"#!!*!#($&%&%8*:Pb~֨y32:5388:802:/158:BJKKOTTZZZUUUTKPSV\otVA32127+-7++++(*(#(+'(*$*+#"#($%(.#!'%(#*)+&%!(&$"""&"%""&)#"#*(#"""!$!###&$ $$"#%!&!""$&$!&%(("$!!"$#$#"(!!"!"$$!* !'!%'#$"!!):LUu崂827:>8>:828A8:728<:DFGJPURZZ\Z^YSURLP\qtZH:8?8:?<27<3B5./55.*.+-.*+%$(%.&(%&$)$%(&$$!+&%$&(%&")$#$$%+#!%%!+&!!"#&%%#&"#"(&$)(#!$%!!(!#!#!#&"#&!""$!$!"&$$""!!$""!!!!"!"#$*!"(&"%*!$*"&"/3DPjƔ8?<>A<:<:::<8:/8:EHLKSVTW]^]ZWWPPTPZd~Ψ~gPE832.+.+****.-$$0($(&5*"!$&$)("%'&%"#!")!&!$!#)!##+)"%#&&"%&%)##(#&%!$# #!"!'!&&!#&"&!!"&!!!&#"*"&!#"!#!%$ $&%*%#%# ! ##&&/%7F^w:25<:<58:?:72?557:>EDFLPRRU^WYYUUWMOPYdyۨeOB820-*/.*()++&"("$'&2#!%&%(%.%#&& #&'%"""&&!#!(&%%$%)&""!!""!$#!%")&)!+%$&$"%!&!$%"# !"#"!!""!!!%!!!("$#!"#!%%"$)"!!"!! '"!!#%""##(27GTo757:8:?>>:2:>2:285?>FHJMTPVZZ^ZZYWSPT\duޯjVD5217#&-0(&*()1)*&*&!&+&)*($*$#)&$*"#$()#%$%!&"%$)!#$!#$%%"&#$&)+$#""!!&"")!!"%#!"!%"!&&$$##!!&
+"#"&"!%&#"$#&&$!("""!$%&%()*!$#"++2APj:7505:::::8D8*52<:7?AKLOSUUZZ]]ZWWRPMUaopRB7/-22/+2.)+)(&$&%*#+("%&++#(+&*&!%##!$&&$"$$"$#$&($"#"%"%%$$!!"*%#%!&!&(&"!""#!#"#!#"&"!#"#%"#!"&"$(.17HZ}3><<8728815??CEPPUUUZ]ZY\WUUTTU]n廓qTG<2+12-*+&&*)."&*+)(&&*()!#"($&*%$& "" #!!%#$$(#("(&))#"""()#""%"$!%%&!"%*#"$#%!$&!!"!!&!#"&"!"%!"!"$#"!!!+!$"#%*&!!$"#$$(! $(!$#$"&$+("$(08B\t83<858::AGGFLVVYWY^YYZUTRPP]mx^E78:+1).-)$%&$##)'%.&!#+$#*"%'($$)*%#&$%!$"!$"##(&)&"%&"!!&!$#""*!%)$&$&(!%!&&$&"""#"!$#""%!#!!"%!!$!!"#!"!!"!$%"#""# #"*&+2GTn5:755::57:<::7175-::GEJROVYZZ\]]YZTVRWZkxbI>:82///)(2+&(&5%%&+((!!)#&&%+)%!%!$&$#%(!&$&%"&!!$)&"!"%%#$#!*"%!&!)$!#!&#!%*##&$&!!%$$&!$!*%###!%#!$&"!&"!$&#!
+!!$""%!#)#!$%$(*.5>Ud?<55<3:<:73<.875:AAFMIUWS\^]^\YWWRSUWk~ơ~`J<7-1.02)&*(()$)&*$%+&&+(%$)"&("$&$&&")$"!#%"!##"#!"!""!$$##&($#"("&&%%$"!$#$#!#$&!#!$"$"%!$!!""!"!"##"
+""!!$#$)$#!&#)*.AHc{::2:A>?77/01)(&)++)"!$#++!+&$$%& "/'%0%## %"!$%$"&$#!)$&%(&&$""%!%&%"#*))(*!"##$"$#!#$"#!$"(#(""!"!&&"!%#"#""!"$# !"%&!!#
+$! "##* #)")/5Oct>28>:<:15<:?F<::5<8?FKMMTWWYZZZWZWVSOOZdxЫeS?8835.12.-&'+! ($$ "$%,*# (())"+%$)#'+&%&"!!!!!+""$!"%#"$$""#$&"%"#!!$"$$#&!%$"##$!""$##%&#"!%""!$""!
+! &"!"!% $%(&.-1DVk785>:D:87225:<+<Pn3::55<:5<53858:85+><550:82888:++53?DFKPMOUZZ\^^^VYSTRTbq뺖qWJ>05312+.((%)&&)%)%!!(&*$"/&"(*'#"$"$""!####%%%"0&"#!&!#$#$%%#"#!&!$""!&$#)(("(%"&&!$"#%#"#&#
+#!"$(%&!# "$(--35E^y?85:7:87<8:78.788<5:?CLOTUVYZ\ZZWWTRRUV]mw\H>:222*2+2+*+%$**('&+%(*.(#(&$'"#""%!"&$##%"!"#"#$#!%&""$$!#$&!"%$!!$!!!!%$"#"!!!#"!"!&!""!$"!'#"! $$*"$&&$&.7>Vk817?8<5<:58>25+*::BMPTWZ]\Z]Z\ZSTRR]mś~]K<5:./+++&0$#&""#(#%&&/)&*)&&"!$!%%&*!&$$(#$""(!!#!$%$)"!!"##!"-("!#"""#"&!$"!"#$!&"#!!"!!!#$$!%#"!
+"&%$#!%&#&#"!#"$-5>Rg?52:<2<>88137??<8:>8153528:1::BGJSPTZZZZ^\YWWSURRg|ϦkT?:52%.1+.(-&!!.+%##$# %+"#($(&&!#)( &$!##&!"$!!$&*&$($&$!"($"&(%%&&)(""!#+!*"!!!!""&$&"!*#&&&"*"#("$$$%"!""%
+#!&)&!#"! *%%&!"&+0:L]u75<<::8:<::735/7530873*-+()+))&%"&*%'+/-&(*+*"!%)!%###("#'&$&!!$"$#$"$%&"$$%$!"!&"!""!##&"$!!!!!!#!!
+""%!$%"!#"#&$"&!(03?Yn5:5<:8378:885872<<8Mc~8?21D::8::888<1:278:D?FEKPPWVW\^^`WRPPPS\pu\L:20/.1.-),++"#&**)&&$-%('!,%##"'!$)$%!*%!"%&&)!"#!&&+#!"&!!$#&""#%"$!#%#"&"("%"#!%!!"""$##$$!!"#$#!
+
+&!!+ &$!! "$!!#13CR]u27888<88851:887275:8?FGMLPSVWY\Z\ZVWUSST]q{^I?88..))*'!&)+*&+(&((#&"%&"&() ) "+)%$%((&"#$"$##%*$$"&&!!!&!%%"!$$#(+&!"#!"%$"!"!!#"#$!##&!!$!#$!"!#"#!!"$ ""#!!$%,!""$)&"/.5?Wp785<<38::58885855::?BLKLWYY\]ZZ\WWORSPZeğ~bJA5205/+(-+"2+*+!&).%(""%!&%#"%)%&&&$%!""($#!$+(&%#$!%&"!"$%#$#&$!"#"$
+$$&!!"$#!!#!$"##("""$#%"!"!&%##%($"$#&"+#%#+*7COj5331835::58:E?IMMTTWW]\Y^]WSPPSWeʧeLF250)+.+))))*.+)#%*&+#-+&)!)*#!"!(&!"$(%%($&%*!"&%#%#$!!##%$##!$&$"#$"""#!"$"""!%"!""!##"$%#!!"(!!#""&&&"%%#%&/(8AKi275.87?5:883:57:8882??FLKMMUZ\YZZWWWVRTRUjw֨kJD:8230*+),*($!%&,1&)(#&%&&+("&(%"!&)"$&"%$"&!((%""#$#&"!&("&!&$!#"&$$!$"$"&"!"%#&$$"##!$!"(!
+%%"%!$!""!""!")$(#!#$,$$")#!)/(*?Fay878578EHHLPSWWWVZZZYWTRSVbq鱒rTD>5/27)/-+($.$%#&+&/.&!#+(&*&$&%(&(+!&%$"!&%##!!*)-%#!&)+&!)&%$!()!$##$!*!##!"#!$%+!"$!$$###!!&&&&"!!!!"$$&$"
+&$##%"-!"#!#&!!#&.+#+2?Pk2:?8783:858:2785>8?HJMTWUW\]ZWZZWTSRT\p빚uZG8811228*+**&-%#"&+)*$.%$&)#%+(#!("!!($!%#&"#!&"($$"#!!$!$#"$#!#%%"$!$"""%#"!!#!!!"""#!#
+#$!"$!#"*%!"""$!!$#""$(($37325A782:25828527:::828<:?<08::?DEJMPSSWY]YY\VWTPPP\g|ɥaMA88521-+&++**-++#%1%%(($#+%#&&+*&&%$+%#)%#!#)"&&%$$(&$%%"+%!#$!!#&&!!$$$#!!#"%!!"%#&%!$&!!%!"!#%#$!""
+!$#"##
+
+!("!!#&$!$!%%%#&&$-.+*3GTj<8753358<8>8578:557:>857778><85Ogy:3238<:>?>:7<7><8?8:8:EDEHLRPRWZ]\Z\ZSTPPW\k}^GA<210).+*)&)+%$%)%)($&$%"%.+#$)#(&%%($%"*-&%(%##%(!$"(%!""#$%("#%$(#%"&!"!!!!%!!"#
+!$&"$!"(&&"!&"&-22DYp~8<8>8:2<75:858585<:8582888178251>?<>8:58::::3287?AAFMPMPWWW\^ZZWVRRRVbwⱎqPE?7311./$+.*&(&%&&&-3$"(*0($(.#$#"%(#((%")(!"$#"%#"!)$(#%*"#!"$#&"&!$!("!$*!"#$!&&"!!$!%!!"""#!!%!#""$#"!%!"&!#$##+*8Ibx5?3E<<8<:827:<8:8<7788?BAJMMMPTVZ]Z\WZUUPSW`ruRI<7523,!++%)"&%%"-*%(%"&+ !&%($!#)" '#%%")%!"!"!"#$&#$*)"*&&!$%!#""$!!$!)"&"%$&"!#""$"#"!#"!"!"!#&$*$!#""
+#*!*!#&&*&")%)(8Gd{>15185<>?882><8582385778CDGKMOTVZZ\ZVVUTSSU]qyZG:5580+%.3,#)*%$&&%#&)#!(()'&) #&+!'$%!"%$&$%"##!&&%(&(###$$$!&%#!%"#$!!&#!%%#$#"##$!"""$##!&"!!!"#%!#!!""%"#$#&##$! $&$!"&+))&.>Le<553.<:2<>?7288?:555702:735885::78::8>?EJEMVVTZ]]^ZTTSRRWZeɥaLD:85-1-+-1++)%)&*&$##%!(%"$++"((**%""$&"($"#!%%#$$($#$"()&$!"#!"!"!#!&)#%!#!$!!"""%"!""!!"$"$!!"$!!!#!!#"#!"!""$#""%%%&$#"&)*%&15Pj:3758?::8:<8<<:<7:87:?BFIOMUWYZZZZYTTRPPZb~ϫiJA:7722+0/%)('&&( %+)%&()+&*$%#)'*& $('%"$)*&$"##&!##%!)"#!(#"!!$&("#"!$(#!)#""!#)"!%%%##&!$!!"$!#"%#!&&%(&(!&!%!!%((!&! )!&-$& # #&&!$%+#8Mj5<<:::<:<<<:2553885383:<3558<:3>8:AC?BGMPRTWYYZWYSRSPPW\e{`L:7550//)+)1*'))/($$#!*"#%#$"$()+)#!#(%$)$#!!()%""!%#!!"!##%%%$&+%"%"#&!!"&!"$!#""$!!$%!"#!!#"##$!!-&'! ()& &"!&+#)--2EWu:::33<5::857::78><85:55>A?HEJROPWWZZWWTRRORUZi~^SD:821,/+(/#((+#$%'&%%+(&&""" (+$&"#% &&(#$"#"&(%&(#$#*!&&$"&&"!!#!""!"#"&%"#"#"$"&"!$!"#"!"!&!#"$"&"#(# &!),)/3?Tm:882<:<<<<2727::35:<3<8:>AHHHKPSUWZZYUVUSUOPVg|cRA<8732.01-0/--+)&&$)(+*&&&%%##(&%))&%$($(&)"&$!!%"$#&%$#&"!#!$"$""!!#&!$##$!""$%"""#&#%!$##!!!$!!!#!!$-##!$)!$)")22>Sk:::7:?8?78882A?AEKMSSRUYZYVWSSOPTVc|ͪjPC<<:22/00&*++-)&&%(*"")*&)&%(&!#%$%#&!$&%"%"#$%%""&&!!$"!)#%!%!"""""%-$"""!$"%"!!"!!!!$!!
+%"!"#!""#$!"!"#&"&&$%1)&&/AMi./858?23:<<><8<58:1:5.<8>?FJLKMVSVVWZZWTTPPUWatӱmPA>8552021-+&',*+)-&*+"+$&"(%%!"%, $""$&(##"&&%"$$&"&(&&"$$%$""%#$$%!""!"!"""!"!#!!"!$"%$&!"&&#)"(!!(%$! % ""$$(,.258Fd}?>:85::7B?8<:8::885::83:?HKMPVSRZWYZWWRRMSVaqܱqYCB:50031-*-*#,0/% &(%&(# &$#%#%!#"$&&"!!)%!"%!&"%&!#!!!"&%$#$"!"!%!&"!!#!"$$"""$&""!!##!!"#
+"!)"!!!"$#(%%*+087F`w8:B::31:58<<Vq77?<55:::::::<><0875:7><578:A88<:5825887:>?EIIPMPTUWZYWUTPPTUZdyɨbPE:28522.-++-,/!)+)$"+$&'#'&$$&&"#&$&&%#$!"%%#!$"!$"!##&%"#!&$%$"""""!!##!#""!#!"$"!&$"%!%%%"% $$'"&&11DOi|>772855:827<:>:AC28??:858A?AKFIRTTZYVVUUTPOIPUarӮgWE<85//2/++---)#&)%%(&""!$$!%"&&%!!!"%&&!%%#!+"#&)!""$($%!!$"!!""%%!&"!!!!#
+!
+""$""$$$""(&&%"$++(.1<:B8?:58C?>ADEJSPRTTWWUSVUPPOPM`oܱkWE?:512010*2++%&&&)$"++$&)&&)#&#"&+%($#%!($"($""!(&$$"!$##%&&"$$&"#"!!$!#"!"!"""!!!!!"!!!#!!&("%*)%""#&#&&&*(27G`u<:<781/382:B<>8>:<88:5508?CCCJDKSTUZWWWUTPMMOSZitUH?:222),*--+)+)*'&)!(#++))"$#%!%(!%$$#(#!"!#%%&&!"""#$&+$&""""$&$!#"##(%%!#&*"#"!!#"!#"$!#!!!
+## !#""$%# #""&#%&,#$&-%%33DWt:888<<:A>>?8:>7<<8:88523:A?DKMKOPPVUVWWWUUSMLP\i缗{\J?5:8751-0/-'&+'(+"#(*#"(*$ %""*##)'%&"&%&&&%#&%!#"%##%%#&!!"&!"&$%#"!#&$%!!$$!!!!!!!!!!%" %$#$%#!"&&$!'#&!"&%($$.-2EYj?>75:7<<88>5>A<7A::<<8358AFEGJJLPRTWVVPTSRPROORdyȤ^OA::1212+*+/+++*-2+&($!(#$""$)%"%!$&$&&"(&&!!%$&&&!!$#%#""!""!!"!!""$!$#$"!"!#!!"!!"$*"!$(&$&*-00A:87?C85AA:?:8::78:8>B7>?GJLMPUPWUWWTSRPPMOU^rϪgPGA85530,*+0-.$*%&&'""&),&+()&$ ()(#,(&-#%(!"#&$(&"$)#%!"%##%%&!!!#!$"!!"$%!&#"&#"
+$!#!#$! "(($$$"))")&.-?I^u:<>8:<:??><8<<<:>>ADAMMLOMPUVRWWTPMOPPT^j֭mUFC88123/220//.**(&%"(%%)!''"%("#$!&&"""&&""!!(#%""&(""""%%%!%!"!!!!!#$!!! "!$!"(+)'0++.57HZu3?:?5<:?:?>85:8<<A><<:85<:8:?>::?CCCHKLOPRTUTOMKLJGFOWd㸔xYH?<:2370+*.-++.+/+&++$&)"(%!$!"%&%!"%%!$!!!"#$#%$#""#!$!!"!%!$###&)$&!!!"!" !"$!#!#$""%"!$&%%$#%$&&)++18JSi~A85?::>><1<8?C<8<<:::8???A<87A?8<<:?A::?<>EEIJMILOMMLJKHHKGHGR^y ~`KD>55212220-)*)*..&$$(!#!(%"#! ###&"%($"##!&"#$"$&&("##$!!#!&"!!!#!!"!#"!$!&"!$ %(###%)*,-&+7Ebx?::>88>::8?:::DA8?85?<::5Fbq:8<3>?>><>?7:ABA?8>8>8?<:??:?>::::>???<>?A?DFEBEHAGFFGDHOW^㺚yZJD?<83530.10-0&&%%)+*(()#!!%!$$!&($)#*&&*!!#$&&$#"&%$(&&&"+!""!""##!!!!# "("&"!&!$$"%$!%"+%&%0"*"&&)++18BLi}A8?::???:?A<<8<5?<>:8B?B?AFCDGHJHLKGEEILS]w긞}^I?:3555232/+.+-/2.++&&*)"%)&&$&%#&!&$$&%$##"#""&!"$)"!#(#!""!!*$!!"#$"#!!!!"!!!
+!#"$!##&!&"!#(#$((*&+*7DL`x>FE<<753,0.*/.*"0/)-(+.$$&(&"#%"$""#)"&$"""$#%$#)!#$(#"$"#!#!"!!"!"#%""!"!!!&
+!#!%#&!!"!!"%)!!$&&$#($ $)""!!$+&,+(505B\x:B::<8?<<:D>?A>><<:><<<8::<:?<:88B8>A?D?:ACAB?:8>?::<:?:888?>?B?>>8<8?>:???:<<<553>AB??8:ABBB8:<8<:88:>?ABKHHMOKLPMPMKMMR`y㳙wTIA:75421000//02-#,+)+&&&%%(%&'#!!%("#$!!!!&!"##"!$+&#&)#!!"#$!$""$#!!!"%"!!"%"#%!!% +#$" !$)-+'#*&23:Sj~BB>:8?D?<:<<<<<:>B>D?:>:AA?<7:<:>?<575522/2.-)05/--+&*&++"(+#)&&&!(%$!&%&#!!""%&%#!$!"####""!!!!! !!$!"!"!!!""""#(+%$(&$)).<7I]t?A<>?>A:B<:?<>:<<<???CGILMSTTPTRRSPPOOK\icOD>:2552-0-).0)(.1*+(&*&$()&+$%(&!#%##!##!##$%##&"&$%!%$")!#%#$!!"""#!%##""!"!#!!!!"!!!#&+&%$+##-*.31A>?8?>?>??G>:>>??>:?A?BFHGJLJMUWTUWVSLMMOMP`{ʦmSC<85432--.(.--*,..&('&%,*+!#(%!$"&#""&!"#%"$%##&&&!!##"!$#"!"!!"#!###"!"$#!##&"!&%#&$$#%%" &.&&*0-88>N_B??C?:??>:>?C?A?FHGIKPSPVUZVTTTPOMOUcqΨpR?:8775/12.1./*)+++*.+++%!&&"%)!%"#)!"*%&)*&%!$!(!&!#&%%%#!&!!!"""!)$"#!""#%"#!!!"!!&!!"!%($&&+#$(-#!%!&.#&.&-+/<?CB??>?<:??:BBEFGMMPSTVUWUURSPOMMM\nӬtWA88251/11310*0-.*))(+(%&(%(*&&!#&*%!%!$"!&%#"$!""!%"!#$!$%#!!#%"##!!!!#!#"!"!"!"&%&%"#($!$!)$"$#(+15:J]58>>?B<><>A>AAB?85?BBDMJJOSPTVWWVVTUROKHPYiͮyYH<53/20/-++,*+&-0/+'*+*%'(&!%)&"#()'().!*#"&$&"##&""($$"(!!($)##!#$"!!!"""%(!&"&&!&!!&!!%$##'#$#%&&&0-27IX<>CBB>8??:?:?>BADB?:?><>?BEGJMMPPTVWWWUUSRMMLOPa~ƭyZL?355222222.+0/,(--)%(%#**+(%"#$%* $"(**#!$&$!%!$#!"""$(%#""&$&%$!"##$""!"$!($"""!"!#&%! !$%&*%#%$()-)(-87HNGB?>?>>>:?C>>?>8:????ECA?A>:<><><<7D??FA?B<8>A??EDHIOPSUVWZWWVTURMLJHKO\n~͵ycMF:883581/.10+.-2--/++-/")++&&&&&+(#$&!*%&")%!#$#!!!!!&$#("#""!$!!!%##!#"#!$+"!%#"$"#"!!%&"!$((&+&%/+1:<>::<8?B?ABADFIMPPSVWZYVWURPPMMJJL\tָkYH>:322./032/..10)*0..*(#&++$&+&&)&)*#$&!"!#%$$&$"!"!!$!($#"!!!##!!!!#!$"&!&!&%!"#("##!$"&++*#*+&&*1:A::?>??:C:>??CCDKLPRRTWZZWWZUSMPMLJM^{㳤yiPB:<533//2&.3+-*/+...+0'()*) %%)&(#)%'#%%#&+"#%%&!"$&%&"!%!#&&&$$&)&$#%"%!#"!!$"!#"%
+!! $"$##!!!"%"&#$%#&!$$)!#%&+'./.22??A?A?>:CC?D:B???D??ADBFA??C?A?DFIILMMTSTWZYYVTURPMMLSb~ԵtWC775551010++/++)-#**)-' ()&**(+&(('(+$""%##$$#%!"##%!"$$$!!#!&"#!!!&)!!!##$###!"!&&"%)&"&&! &!%&"#!*#&*$$(&&./55CCAD???E?>?A::B??EEG?B?A<<<8>?ACGIGJMPUVZWVWTYUVPPMLOWdЯgM?850-22.0.22/(1-(2.+*++***#+&)"%((&%-$&$&$(($!!"#"&%$"!!!&"""##*"!!#"&&!#!#"&!
+!!&$$!%$!!""""#%&&+!*%"&&&&&&"$#")("&"$&$!+.0-0>DA???:<:88?>>AAAB>BCB<>>C?8?BBD>>?<:?BCB?CC??:><>:???B??AGHGLPTWVWYYWYYVPRPPMR^y⺛~^I:85123011/1-,'0**((&-)(.+(*+%&&%$&&!"%" $#"!($##"#"#%%!#""#$"#!#"!"!#"!$#&%$&&&""*!&$(!!"$%/)&+.)/+++)+"#!"&$$"%(""#"')%$%!"#"")*)))./0?83?>E:?DCC>?<<:>A?FHFLMPSWWWZWYZYUSMMPPP\uƦgL?5852///010//0+1.-.*++&$-)-%*(+)(%(%*#&*!&"&"#"%&""!$#$$!#&!!#$"!!!$%""%&!
+!#""#"$&(%.%("!$%(%+)*&!"!#&*1*+--((+-)(&%$!#")&!!++%+%$")(!#&$0)CC???>?BBB?:?:?A:FE?>G:>??>AA<:???8?A?A?8?:>CAFILMRSSYWYZWWYVRPRPS\g^M?>5200//3/0510+(.*).))*%++&&&/"*%$!#%#%&$""!#+#"!(#!%!"!#&$"#$!!#"&&&&.)(*&-0$)!$().&(+1+.+.0&&&""!"%++270135522313../2.++&&&%$%($#+&"(+)&(#(&+(-.#283885AAA?B??>BADEBGKMOPPVWWYYYWVTRPSPT`ϪiPB<775/2/.2+(*+(-/+./-++)$(*--*&$+)(#%$%!"""""##$$"%$"""$!&$(%"!!"##!"&!""""$#%##&**(&*))&(+&.+-++/---/+./*(&$!#!)!&%1$&/1/588:8325775511100+))#&)(&$##.)*%#+2+*+023(*118822757>G>?:?>EA?:8A>?B:7BE??ABD??:>B>?DHFKKMORRWVZZZZZWTUUSUUZyڳiRE<871230-125.1+-21-+%+('*+& &)!"&$&& $$$&"$%#!%""!#""!"!!!#!#&!""#"!!
+!#$!$#"&*%)&!+/++(&*&"").*!-0/.-**$%"""%&(&22357875257728/05/.-&%2/1)&"(#&"+1+&&*)++*)/12/7836<:9>826831,/2*.10+)++*,+&'&-*%-&')&)$ $% $#$"&$#!#!&!#"#!!##!#%#!"!!$$$&!!&#&+(+0*(+.0*.-+&(&("%&*+-1211.**)*!!"$#$#&*&&(-*1855883337<878352..0./+.*+)//0*+.+2++-+1+-1-5219586<88;7>ABECBC??A>?>C?:CB?ACB:?>?A?BAD>E?AABEBAABA??BBA:FDGIMMPTUWYZZWZWVURPRTYgɥaLC:??<:8?FDFKMMMUUUYVZWWYWVRRSUWd~ШiRA?9515.*12*-/-.02*%*-/++*-&*+*)!"(%%&,$&!(#$"%+$&"!#!!$%!&##($!"!$!#%&!
+!##"&!&+/-1/20/221+*+&+((&)&+00.0.*+*&$&%&$*++/112::558:5:8<525-2:55<8523/152&)/031*+--225355548889685=98<9<:CF?>?F?CB76773102/-2*'.10-+*+,))(()#('')&'"$!!%)%!#"#"!!&"!!"$$%!##$!!!"""!&%%$)10/5332//2)++&&*.*+&)1--/.00$%&$!""%!)++50.3358887:88887733/2201321221222-++/2/225/3234538::<988775>:55HDGD>B?D8BAA?<<FCDB?>DC8?8??AC?DCBGE??>?B<>?A?>FJMRWWWW\\\ZVVVSTRU^iʡ^OCA957502/2/1.062+-,*.,$%+**/((%&$'$&%&& "#(&!##%(#!&+(%!!!#!"%$#&"%
+"%).*/730/10*/-+&++2%%++.++&+-*(&&!(%&2(*.553138811553883/3335.*2.+*+1/.10./+/05,+11621/3/22:7587683-2388>??FACEA:?>?AB7>AAC>::D>:B?>>?>AABADECAC??FEBHLIPPUWWWWZ\]ZWVTSSWc}⯌kTFC<:830113//**-.++++--)-+)(.())%%#&$#&%$$#"!%#"!!##$!#"!"
+!%(#$&&32/..12/+.0.++-2*02--*-)++(&%$"$&&*)00*.212352235202:1135-/0/.021/++()-*(*1.021-1/25.12512.325853531585JHFEDBAD?BDBAC?A?B?>?A??>?>AACBA?ACDCA??>A<<<>CEIJMOSWWYZ\\\Z]YUTWSU\puZJ?:534235/*-/.0-+,,-.%'($#!$-((%('((+'%&%#%!#$"#%%""%!!""!#!""!"$$"#"!#!"#$$
+
+!!$##*&*).2.1520.00/.++(..(+-2-)++&"#!#!!&-+*0//2555733322351/*+-+&+-...+(++*(-%.+()-,013-1021+3/0,522/38.12271???>BHBA?>?>A???>BB??<>?BDEEJMKPTUWWZZZYYYWVUSS]jɣ|bE?:8334370325/1/10)+&*+-($(&))+$)%%*&$"!&&%$%&""$#"$#&""#!!"$$"%%!"$%!!
+
+#%(+&/021.031)01-+./-.1-)*+.+++)$!&!#"!$&(+-+.).+011251.21+//.&+-0010+(+&+-*$+-))+-.**)./.112237**052--33102212?BBB:>D?C?:??AB????AFGHKMPTVYWZZ]ZZWWUVSS]g˪ePF<581352+*.2+0.30-*+(*%&*)+-+&*&$((&&&(%$&&!&&%($#%"%#"##$##$
+
+&%&&(+10.-/.00-&-+11++2+)+.$($&"$(#!(($)++233302210-/5200/0%)3//)++&+-!+."&)0&(++0/0302+!0.05)&28/*5+0218/.ACADCB?A?BC>><>>8??AA>BDCEDB>??C?A?????DBFDCBCEC??B?AA??FCGMPUSUWWWZ\]^ZWUSSTU\mtZJ?8:9322121/*/.-+,.--$-.+(+)&$.)%%&('#**%"%&")#"&##""!#"#))"!!#$!"%"((&1200212+..+(+/.-2/+/+%2-00(#"$)""""$%&)+&-/-021/02/+/-/00+.)+(*%-//()%)&+(/*+*(!(+))+-0+../,.&/105--+(+&.&)(??BBBEB?B???ACCB?<>?AACGIMOPVWYWZ]\ZWWUTUUVZi֤^MF<::852222..-+/.*-/(&*+++(-"&(+*))!$(#&&"%$!$###!"""#!!($%&&""$!#"!!"!%%())+-*+..//+..-0++--/11/--++))+-)&+##$!#&(-(.221//.//+/-/-++&+++()+-(+./&()+#+&.+&&**+)+--1*&+#++.-1*)()&.-*+1.-BFCBCD:AA><><>?BA??DFA????EB?>>?>A???ADCCBEG>AA>A?E?DGJMRSUZZW\]]\ZZTVSSYap깒tRK??<55352/0-.&.2+(&+&+)*/$.-/+&"+**((+(()""&$!%&"$""&#!&!$!!"!!!$"
+"#%+&)-1200221+--../--+-./-*-*%((+&(#&&!!&(21+13--+5.*")/+++)+&./#)&)*()%+&&+%)&%-%*((&+&&-%-//0--&.-.*(.+*-&+*#/-+ABCDHB>AADD??A<:<>CACAFCABAB?DEGKLPRUWZ\\\Z\ZWWWTTW]kǞy\I?>:7252500000/-*-+*/0+%&&&*+-+)&(+&$&&)&$!"$$!!"#"!!!!!"#!#"#"&(**+/+112..0-.//.02313.30/*++)(+((*%#"!"+)**+&(*+2.251+./)+*-++*)(+-)+)+"(#*&*!%&%)$+)*+)(/**.&*++.++)&+$#+&+)#+*&1A???>D:BABHCCBBDDFDCBABEHJMSMUSWYZ]]ZZWURTSRZgФ|`OA<925.12521.0.'+&&+,+++,+%'&(-**&$"+)(%"&(&$&&!!#"$!!#$!!##$!%!$&-)+.121200-/0//*.**)/2///.++&+*+("&()(%""!*(&*(+-&(0.+$--+++*./+)%&&)//+&(())(*#&&&&&)+**%&&-++/!*+-$!(#!$&,+&*&+*/?DDBFCBFCH>?A??>?DGMMMRTTYZ]Z]]ZWYWUURZbw㳎jMF?:2735523..2/./.+**+-+++(+&&+$()&!"&(*0("$+"""#!!!!""%%%&!&&%#$&&&+-2+-102././0010-0/.02/+++*+.(++)&%($##"!!##&(-++..)+.31*5**)&&&%&!#&)($&%(*&"&(&(&*&)(($*+**))*-%&%&%*(#+++*+#$++??HA>>A?A:?BAB?ACCDHPMPSTWYZ\\\ZYZWWUSW\nětWM><::841331023-.-*+-/"'(+((+-*'&!%"&)&(&(#$&"""!!##$%!!!%"&%)+1/235/0131/20/.-.+0-.+)+-&*++**++.*(*)*(&+"$!%%&&&(+-+(/.)+-+/&+$(+1++&&&/*$#+*+-)#&%)&$#/3++&&!+"$$""')(&'$&&$.&&%%#&.-AB?:HJDDBDC???>BB:?>BAGGIKOSTWYZZ]\ZZYWWRUSZgϡ~ZLA:75-25200//+/,+)*/+(),()$&+)))-(#!%&%%$$$"##""&"##!"
+"&%$*.12-0032100-0-+0/.++--*+.++)+()*+(&.*+#($$"!"&$&&+(*-+.-+()&)*++&&$*+&!&&))(%*"&&$#+)!&*$%)*(%/&&$%(*#()*#'*&+)+%&<:BCEFD?A?C?BBCC?CDCA?BDEIIKKPRSWYZ^]\\\ZWUSSTWeר`LEA:555820170.-/-.&+**&*.**&))**&!.%%+#&"%&$&%#%(#)#"!"%&"
+
+%!#()./1/0252012+--.220++-+(+)+-+(*)-+-/+-+&))&&!#"&)%+$+*+*+!%&*&)&&!*)%&&&)+-""#()$)#"&"&%&&&"$-&&)(&)&+&$)))&/&?A?BCDAEBB?BC?A?AEB?A>:?BDBEAA??ACBFJMKPPSVZZZ^\]ZYYYUWVY^q麐kTG@;:73653/)--'*//2+)-*%&-$*+)')+)##&&'**%%%#&%""%#!%"!$%"!"!"
+#!#&01100/-012+02/.+&+..+-+)--.+-+%&+-+/+(&&%&%&!#&&%$&$!+()%#)(++(&*&&(&(*!$%&$!!"#&!.")&&$*+*&%"((.&&&(&(*')&% '$&&$&""+1(&>ACG?ABB?>?ACEJKKSSTWZZ\\]\ZYVVUSUZmqYGC:::6352./.10*)+(.-/(+*+*$)*)*+)#')%&"&&$"%$$"#&""!!&$$!!""!
+ !&&((10/0002../0.-.01/)+.--*&*&*-+.(+)(()+"&+*%-+&!##%#$$$$"%(!))&+%&)*#)&$%)$!&&$*!&)")&$!*"%-+&*$"&)&&%%* %&*())"#%)#&$#!<>BBAACAFEIA?<>ACELKJPTSUW\\]Y]ZZWUSPWZgʟ|^MAA8775552//0+0/.&*.2).++.+(+++)&*+&&&&#$&&&$"""!!"!#$!#!!!$"
+
+
+
+"&&+/+0/23521/+++&.-01-+)+*&-)&&(+))*.()&&++&&$$%&(#!)&%%&$%&*%&%%!%(*&&%%%%&$#))%&$&"(&$!#%%&)&"0#%*&!#&+#&%!/"*$+$&$(#%$#ACC?CDCCE>C?>?>D??GIMPRTWZZ\ZZ^\ZYTPVVZd|^SE?>:8553051.-+/2+*++0*+++$(+*+/%)&(&"&$("&#("$#%%##!$%$&#!!"
+
+(#&--253520/..//0..+.++++...+-*+*(+-)*(&(&&()))&)#&&%#!!%%*(/+$%+%*&$&!#$$%$!&!%&$$)+&$#"(&$&$%-&($!###)&%&%&%""><:CAC?>CFCCD?>>>BBEB?DFF??DBDDB?C???>:5765:20*+--..+..-)*-%,)**%(*%$'*$)("($&&%""%"#"#"$"$&&&"!!""!
+
+#&//.&/3-000.1++-+%&(&&-)-+.+*&()*(++&&&+)*&&(*$&-)(+(($*&!$*)$%&("$+)*&&%&&&$$&&%%+$&$%#&&&%%&$"#$&!&&)$&+*&#&+#'+<8BAB?ACFC>C??E?AA:?B?>??<85225201/*0++)*++-+&*&**&*+/)-$&)*&!&""#!%$()"$!!#$!!!!##
+!%+./0222+125/0.*(-+)(&++*.+-.)--/.+.-+/+(+*+&*$%%&&&&)$%"#$!""$&%!"#$#%*$"!#!%!#!"&#"$(%(+%#$&""!%"($++::>CEAEDAAB>AB?BDE>AA:EB:?>ACDFDBBAABA?>?<?FKKJMPPV\ZZZZZYYTSUTUZa|Ҫ}aMB><93211210+//++-++(%+&),+))(+&&&*)'$&(!(&%#%&(%##%$$####%&$&!"$20/.1.0-12/12+-((.*&++/*+--+*)--))(+*&&/&1*(%%#&)&!$($$&&&%%"!#!)!"!$"$($#"""%#&$(&$("$!)&)"!!"!" >?CBA:ECBDDA?B?DA?ABACC?EF??DDBB?>???A??BCFJLMPTUWZZ^\]\YWUTVUUbwಅeQF?<;65220110+--*.-0/--*(&*())(*)'*+&)()&&*)%&&(#%#!#%"""!#%"!$%%#).//-..0/0.0../.++.+++.*)+--.+.++*)))&))+#&()$*#%&"#")$#%$!#""!"%&"!%&&$#!$%&)#$&$&%%"$ ??CB??CAB?CAD?????B<:?DEGMPPTVWZ^]\ZZYYVUPWWaq彌iSC<8<83537/52/-.))-))++++-.++%%)"()1*&&&+&%!$(&*#!!"#!$#$&""!!!
+
+
+"!&+&.00310./--/.+())++*+.*)0-/-*.0++-*)&*(*%)++!$$&((%&&!!!(%#$#)#"#""%#!%$$$!%#"&%%(#%$##&(%??>E??<>E<3523312/2.*../+/-++++*(*++)%%&&%&%!(+$$%#&"$(%$%*!"$""%#"!!""#!$$$%!#!&%-2152-2++.++.-++(*%)*()*%*++-)*(*)-()($&)&%&&(!#$#$&$#!$!#"!!"#!%%&$!(%#&#""&+)&%%*#(%$*)&"#$!??:ABCAHFILRVUUYZZZ]ZZZWSVRR^eşuZKE:965543220.-+/*+*-)*)+*(+,')(+*((#%$& (&+$$)*&$$"!"$"#""%&%#!!$!
+##%./-.2-.--.1005*&-++)++%)1)/.)&+*)+(&&-+&&"*+&%##&!$#!"!$!$$!!$!)""#%$"%&&'!!! #%"!::CB>?ABBBBC?B??AE???CEC?GGB?AA>A?AA<>???CCDKPPPTVWYZ\]ZZWWVRTUYdyӡ}]MGC88853131/-0+10/.,+))+((&*)((,,*&!#%%(&))%&$#&!#&$!"!"!#%!!"#!%"&!%"&(/1./..-.-+.---.-%-/-**+*++*-++(*+++++*#(&)()$%$#"$$$!#&"%$$$!#!"!$%##)$# #>>>BC??ABB?A?<:CACBA?BCCDB?>??>D<>?A::7330/52+/.+0.(++0-/&&&%++%-++(*$&&)&%&)&&$!$$&!$%!"#"$##!"$+++/2/.+&.010/--.*&+2+&%&(&)+++-++++*)&%"(((!&(#!"#""&#"!"!#!&!#!&&%&%"!!#"#&*??AEHKKOPUTWZZ^^^]YWUTSTW^k鹈gRGA?:83570/012/-*-+++++*+-++))$)(*&&&(&)*#)(#$"&"$$$"&$!"!!$%"#!%!
+$+*--20/..-.+--.+02+*+++))+()+-+++-+#(&(+&)("%#$&!""""!"""&$""!#%$#&%""!!&!*<:7?BBCBCB?FEHLMPVUYZZ]]Z\ZWYWSWWZikTKC><853121.+./-+-+'(./.,)&%)(*/&)+$$(%&+)&+$&""&$&%"*!!%$!#$$!#!
+
+ $$+-0//121*1221/020.-++*(&)+--.+(&)*+))&%&$(&%#"%#!"!"!%"$#!#!&"%#&((#&"#&!#$)(%!!!!%# #E?BC>C??BDBBABC?>A>7?CCBCCCCBCCDCA??<>>?AABFFMMOPWWWYZ\]^YWVVWSUZe˙t\J?>:5521210...(.0+++/.*)+**-1+'$()(&&&%))%%&$%&&"((&""!!!#!
+
+!$*112.000./1././++*-++0-+++*&&$&+)++-)%$+*%%&("!"$"!!"!!#"!"!!$"!#$!""#!2<<7C?ADDE?<:?<>?AC>A<:5531/12/-+++++--1+)++++)*+*&&&)-***&(&.*&"&&"%%&$"""%(*#!!!!!#!#!#
+
+
+!!&+-/..102/10//.1--))(+)&*&+-))0$()&**)+*-)%(%%!&&$$!##&!%$$%%!!"$""&"??>?A?ABE8>8B>?DHGMORWWW\\\^\ZZYVUTSU^qۯ^SE<:<75202011/*(0---/$-1))+**&%**(&-.%"#&$&&*&%&("!""#%$!!!"#!!!#"#%$+-001121.////0.-/.+++-+&*)*(-.+&&&.+((%&*"")!###%#!!"!!!$!$!""!!##!&!%"(<?A?CDD?